NovaBryan/EVE_Dump
Log | Files | 📦 下载最新源码 (.zip) | Refs | README

mapLayoutHandler.py (14712B)


      1 #Embedded file name: C:\BuildAgent\work\20d73f1b24eed06e\eve\release\V24.01\eve\client\script\ui\shared\mapView\layout\mapLayoutHandler.py
      2 import weakref
      3 from eve.client.script.ui.shared.mapView import mapViewConst
      4 from eve.client.script.ui.shared.mapView.layout.mapLayoutConstellations import MapLayoutConstellations
      5 from eve.client.script.ui.shared.mapView.layout.mapLayoutRegions import MapLayoutRegions
      6 from eve.client.script.ui.shared.mapView.layout.mapLayoutSolarSystems import MapLayoutSolarSystems
      7 from eve.client.script.ui.shared.mapView.mapViewConst import VIEWMODE_LAYOUT_REGIONS, VIEWMODE_LAYOUT_CONSTELLATIONS, VIEWMODE_LAYOUT_SOLARSYSTEM, JUMPBRIDGE_CURVE_SCALE, JUMPBRIDGE_TYPE, WORKFORCE_TRANSPORT_CONFIG_TYPE, WORKFORCE_TRANSPORT_STATE_TYPE
      8 from eve.client.script.ui.shared.mapView.mapViewUtil import ScaleSolarSystemValue
      9 from eve.common.script.util.systemExclusions import IsValidDestination
     10 import uthread
     11 import blue
     12 import geo2
     13 layoutClassMapping = {VIEWMODE_LAYOUT_SOLARSYSTEM: MapLayoutSolarSystems,
     14  VIEWMODE_LAYOUT_REGIONS: MapLayoutRegions,
     15  VIEWMODE_LAYOUT_CONSTELLATIONS: MapLayoutConstellations}
     16 
     17 class MapViewLayoutNode(object):
     18     dirty = False
     19 
     20     def __init__(self, particleID, solarSystemID, position, system):
     21         self.particleID = particleID
     22         self.solarSystemID = solarSystemID
     23         self.system = system
     24         self.lineData = set()
     25         self.position = position
     26         self.oldPosition = None
     27         self.animPosition = None
     28 
     29     def AddLineData(self, lineData):
     30         self.lineData.add(lineData)
     31 
     32     def SetPosition(self, position):
     33         self.position = position
     34 
     35     def UpdateAnimPosition(self, ndt):
     36         self.animPosition = geo2.Vec3Lerp(self.oldPosition, self.position, ndt)
     37 
     38 
     39 class MapViewLayoutHandler(object):
     40     starParticles = None
     41     extraStarParticlesController = None
     42     jumpLineSet = None
     43     workforceTransportLineSet = None
     44     layoutDirty = False
     45     starGateAdjusted = None
     46     expandedSolarSystemID = None
     47     lineAdjustmentOffset = {}
     48     morph_to_index = 0
     49     transformTime = 500.0
     50     currentLayout = None
     51 
     52     def StopHandler(self):
     53         try:
     54             self.updateThread.kill()
     55         except:
     56             pass
     57 
     58     def __init__(self, mapView):
     59         self.mapView = weakref.proxy(mapView)
     60         self.nodesByParticleID = {}
     61         self.nodesBySolarSystemID = {}
     62         self.dirtyNodesBySolarSystemID = {}
     63         self.layouts = {}
     64 
     65     def __del__(self):
     66         self.nodesByParticleID = None
     67         self.nodesBySolarSystemID = None
     68         self.dirtyNodesBySolarSystemID = None
     69         self.layouts = None
     70 
     71     def __len__(self):
     72         return len(self.nodesByParticleID)
     73 
     74     def ClearCache(self):
     75         for layoutType, mapLayout in self.layouts.iteritems():
     76             mapLayout.ClearCache()
     77 
     78         self.currentLayout = None
     79 
     80     def ReloadLayout(self):
     81         layoutType, args, kwds = self.currentLayout
     82         forcePrime = True
     83         self._LoadLayout(layoutType, forcePrime, *args, **kwds)
     84 
     85     def LoadLayout(self, layoutType, *args, **kwds):
     86         forcePrime = False
     87         if self.currentLayout == (layoutType, args, kwds):
     88             return
     89         self._LoadLayout(layoutType, forcePrime, *args, **kwds)
     90 
     91     def _LoadLayout(self, layoutType, forcePrime, *args, **kwds):
     92         self.currentLayout = (layoutType, args, kwds)
     93         if layoutType not in self.layouts:
     94             self.layouts[layoutType] = layoutClassMapping[layoutType](self)
     95         mapLayout = self.layouts[layoutType]
     96         mapLayout.PrimeLayout(forcePrime, *args, **kwds)
     97         self.mapLayout = mapLayout
     98         for solarSystemID, position in mapLayout.positionsBySolarSystemID.iteritems():
     99             if solarSystemID in self.nodesBySolarSystemID:
    100                 mapNode = self.nodesBySolarSystemID[solarSystemID]
    101                 if not mapNode.position or not geo2.Vec3Equal(mapNode.position, position):
    102                     mapNode.oldPosition = mapNode.position or position
    103                     mapNode.SetPosition(position)
    104                     self.dirtyNodesBySolarSystemID[solarSystemID] = mapNode
    105 
    106         if self.dirtyNodesBySolarSystemID:
    107             self.Update()
    108 
    109     def Update(self):
    110         uthread.new(self._Update)
    111 
    112     def _Update(self):
    113         if not self.mapView or self.mapView.destroyed:
    114             return
    115         if not (self.jumpLineSet and self.starParticles):
    116             return
    117         self.mapView.LayoutChangeStarting(self.dirtyNodesBySolarSystemID)
    118         self.mapView.UpdateMarkersFilter()
    119         adjustLines, dirtyNodes = self.AdjustStarGateLines()
    120         for mapNode in dirtyNodes:
    121             if mapNode.solarSystemID not in self.dirtyNodesBySolarSystemID:
    122                 mapNode.oldPosition = mapNode.position
    123                 self.dirtyNodesBySolarSystemID[mapNode.solarSystemID] = mapNode
    124 
    125         is_initializing = self.mapView.waiting_for_layout_change
    126         self.mapView.LayoutAnimationStarted(self.dirtyNodesBySolarSystemID)
    127         self.AnimateNodes(self.dirtyNodesBySolarSystemID, adjustLines, self.mapView, initializing=is_initializing)
    128         self.mapView.LayoutChangeCompleted(self.dirtyNodesBySolarSystemID)
    129         self.dirtyNodesBySolarSystemID = {}
    130 
    131     def AnimateNodes(self, nodesBySolarSystemID, adjustLines, mapView, initializing = False):
    132         start = blue.os.GetWallclockTime()
    133         ndt = 0.0
    134         dirtyLines = set()
    135         worldUp = geo2.Vector(0.0, -1.0, 0.0)
    136         while ndt != 1.0:
    137             try:
    138                 if initializing:
    139                     ndt = 1.0
    140                 else:
    141                     ndt = min(blue.os.TimeDiffInMs(start, blue.os.GetWallclockTime()) / self.transformTime, 1.0)
    142                 for mapNode in nodesBySolarSystemID.itervalues():
    143                     mapNode.UpdateAnimPosition(ndt)
    144                     dirtyLines.update(mapNode.lineData)
    145                     self.starParticles.SetItemElement(mapNode.particleID, 0, mapNode.animPosition)
    146                     self.extraStarParticlesController.SetItemElement(mapNode.particleID, 0, mapNode.animPosition)
    147 
    148                 for lineData in dirtyLines:
    149                     self.UpdateLinePosition(lineData, adjustLines, worldUp)
    150 
    151                 self.starParticles.UpdateData()
    152                 self.extraStarParticlesController.UpdateStarParticleData()
    153                 self.jumpLineSet.SubmitChanges()
    154                 if self.workforceTransportLineSet:
    155                     self.workforceTransportLineSet.SubmitChanges()
    156                 mapView.LayoutChanging(ndt, nodesBySolarSystemID)
    157                 blue.pyos.synchro.Yield()
    158             except ReferenceError:
    159                 return
    160 
    161     def UpdateLinePosition(self, lineData, adjustLines, worldUp):
    162         fromMapNode = self.GetNodeBySolarSystemID(lineData.fromSolarSystemID)
    163         fromPosition = fromMapNode.animPosition or fromMapNode.position
    164         toMapNode = self.GetNodeBySolarSystemID(lineData.toSolarSystemID)
    165         toPosition = toMapNode.animPosition or toMapNode.position
    166         if lineData.lineID in adjustLines:
    167             fromPosition = geo2.Vec3Add(fromPosition, adjustLines[lineData.lineID][0])
    168             toPosition = geo2.Vec3Add(toPosition, adjustLines[lineData.lineID][2])
    169         if lineData.jumpType in (WORKFORCE_TRANSPORT_STATE_TYPE, WORKFORCE_TRANSPORT_CONFIG_TYPE):
    170             if lineData.jumpType == WORKFORCE_TRANSPORT_CONFIG_TYPE:
    171                 curveScale = 0.5
    172             else:
    173                 curveScale = 1.25
    174             self.workforceTransportLineSet.ChangeLinePositionCrt(lineData.lineID, fromPosition, toPosition)
    175             self.UpdateCurvedLinePosition(fromPosition, lineData, toPosition, worldUp, self.workforceTransportLineSet, curveScale)
    176         else:
    177             self.jumpLineSet.ChangeLinePositionCrt(lineData.lineID, fromPosition, toPosition)
    178             if lineData.jumpType == JUMPBRIDGE_TYPE:
    179                 self.UpdateCurvedLinePosition(fromPosition, lineData, toPosition, worldUp, self.jumpLineSet)
    180 
    181     def UpdateCurvedLinePosition(self, fromPosition, lineData, toPosition, worldUp, lineSet, curveScale = 1.0):
    182         linkVec = geo2.Vec3Subtract(toPosition, fromPosition)
    183         normLinkVec = geo2.Vec3Normalize(linkVec)
    184         rightVec = geo2.Vec3Cross(worldUp, normLinkVec)
    185         upVec = geo2.Vec3Cross(rightVec, normLinkVec)
    186         offsetVec = geo2.Vec3Scale(geo2.Vec3Normalize(upVec), geo2.Vec3Length(linkVec) * curveScale)
    187         midPos = geo2.Vec3Scale(geo2.Vec3Add(toPosition, fromPosition), 0.5)
    188         splinePos = geo2.Vec3Add(midPos, offsetVec)
    189         lineSet.ChangeLineIntermediateCrt(lineData.lineID, splinePos)
    190 
    191     def SetExpandedSolarSystemID(self, solarSystemID = None):
    192         self.expandedSolarSystemID = solarSystemID
    193         self.Update()
    194 
    195     def RegisterStarParticles(self, starParticles):
    196         self.starParticles = weakref.proxy(starParticles)
    197 
    198     def RegisterExtraStarParticles(self, extraStarParticles):
    199         self.extraStarParticlesController = weakref.proxy(extraStarParticles)
    200 
    201     def RegisterJumpLineSet(self, jumpLineSet):
    202         self.jumpLineSet = weakref.proxy(jumpLineSet)
    203 
    204     def RegisterTransitLineSet(self, workforceTransportLineSet):
    205         self.workforceTransportLineSet = weakref.proxy(workforceTransportLineSet)
    206 
    207     def HasNode(self, solarSystemID):
    208         if not IsValidDestination(solarSystemID):
    209             return False
    210         else:
    211             return solarSystemID in self.nodesBySolarSystemID
    212 
    213     def CreateSolarSystemNode(self, particleID, solarSystemID, position, system):
    214         if not IsValidDestination(solarSystemID):
    215             return None
    216         else:
    217             node = MapViewLayoutNode(particleID, solarSystemID, position, system)
    218             self.nodesByParticleID[particleID] = node
    219             self.nodesBySolarSystemID[solarSystemID] = node
    220             return node
    221 
    222     def GetNodesIter(self):
    223         return self.nodesByParticleID.itervalues()
    224 
    225     def GetNodesByParticleID(self):
    226         return self.nodesByParticleID
    227 
    228     def GetNodeByParticleID(self, particleID):
    229         return self.nodesByParticleID.get(particleID, None)
    230 
    231     def GetNodeBySolarSystemID(self, solarSystemID):
    232         return self.nodesBySolarSystemID.get(solarSystemID, None)
    233 
    234     def GetNodesBySolarSystemIDs(self, solarSystemIDs):
    235         return [ self.nodesBySolarSystemID[solarSystemID] for solarSystemID in solarSystemIDs if solarSystemID in self.nodesBySolarSystemID ]
    236 
    237     def GetLineData(self):
    238         lineIDs = set()
    239         for solarSystemID, mapNode in self.nodesBySolarSystemID.iteritems():
    240             for lineData in mapNode.lineData:
    241                 if lineData.lineID in lineIDs:
    242                     continue
    243                 lineIDs.add(lineData.lineID)
    244                 yield lineData
    245 
    246     def AdjustStarGateLines(self):
    247         adjustLines = {}
    248         dirtyNodes = set()
    249         if self.starGateAdjusted != self.expandedSolarSystemID and self.lineAdjustmentOffset:
    250             self.starGateAdjusted = None
    251             for lineID, (fromSolarSystemID, toSolarSystemID, offsetFromPosition, offsetToPosition, jumpType) in self.lineAdjustmentOffset.iteritems():
    252                 fromMapNode = self.GetNodeBySolarSystemID(fromSolarSystemID)
    253                 toMapNode = self.GetNodeBySolarSystemID(toSolarSystemID)
    254                 adjustLines[lineID] = ((0, 0, 0),
    255                  offsetFromPosition,
    256                  (0, 0, 0),
    257                  offsetToPosition)
    258                 dirtyNodes.add(fromMapNode)
    259                 dirtyNodes.add(toMapNode)
    260 
    261         if self.expandedSolarSystemID:
    262             applyOffset = self.GetStarGateLineOffsets(self.expandedSolarSystemID)
    263             self.starGateAdjusted = self.expandedSolarSystemID
    264             for lineID, (fromSolarSystemID, toSolarSystemID, offsetFromPosition, offsetToPosition, jumpType) in applyOffset.iteritems():
    265                 if lineID in self.lineAdjustmentOffset:
    266                     oldOffsetFromPosition = self.lineAdjustmentOffset[lineID][2]
    267                     oldOffsetToPosition = self.lineAdjustmentOffset[lineID][3]
    268                 else:
    269                     oldOffsetFromPosition = oldOffsetToPosition = (0, 0, 0)
    270                 fromMapNode = self.GetNodeBySolarSystemID(fromSolarSystemID)
    271                 toMapNode = self.GetNodeBySolarSystemID(toSolarSystemID)
    272                 adjustLines[lineID] = (offsetFromPosition,
    273                  oldOffsetFromPosition,
    274                  offsetToPosition,
    275                  oldOffsetToPosition)
    276                 dirtyNodes.add(fromMapNode)
    277                 dirtyNodes.add(toMapNode)
    278 
    279             self.lineAdjustmentOffset = applyOffset
    280         return (adjustLines, dirtyNodes)
    281 
    282     def GetStarGateLineOffsets(self, solarSystemID):
    283         fromSystemInfo = cfg.mapSolarSystemContentCache[solarSystemID]
    284         adjustLines = {}
    285         mapNode = self.GetNodeBySolarSystemID(solarSystemID)
    286         if not mapNode:
    287             return adjustLines
    288         for lineData in mapNode.lineData:
    289             if solarSystemID == lineData.fromSolarSystemID:
    290                 otherSystemInfo = cfg.mapSolarSystemContentCache[lineData.toSolarSystemID]
    291             else:
    292                 otherSystemInfo = cfg.mapSolarSystemContentCache[lineData.fromSolarSystemID]
    293             fromStargateVector = None
    294             for each in fromSystemInfo.stargates:
    295                 if fromSystemInfo.stargates[each].destination in otherSystemInfo.stargates:
    296                     fromStargate = fromSystemInfo.stargates[each]
    297                     fromStargateVector = (fromStargate.position.x, fromStargate.position.y, fromStargate.position.z)
    298                     break
    299 
    300             if fromStargateVector:
    301                 stargateOffset = geo2.Vec3Scale(fromStargateVector, ScaleSolarSystemValue(mapViewConst.SCALING_SOLARSYSTEMINWORLDMAP))
    302                 if solarSystemID == lineData.fromSolarSystemID:
    303                     adjustLines[lineData.lineID] = (lineData.fromSolarSystemID,
    304                      lineData.toSolarSystemID,
    305                      stargateOffset,
    306                      (0, 0, 0),
    307                      lineData.jumpType)
    308                 else:
    309                     adjustLines[lineData.lineID] = (lineData.fromSolarSystemID,
    310                      lineData.toSolarSystemID,
    311                      (0, 0, 0),
    312                      stargateOffset,
    313                      lineData.jumpType)
    314 
    315         return adjustLines
    316 
    317     def GetDistanceBetweenSolarSystems(self, fromSolarSystemID, toSolarSystemID):
    318         fromMapNode = self.GetNodeBySolarSystemID(fromSolarSystemID)
    319         toMapNode = self.GetNodeBySolarSystemID(toSolarSystemID)
    320         if fromMapNode and toMapNode:
    321             return geo2.Vec3Length(geo2.Vec3Subtract(fromMapNode.position, toMapNode.position))