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))