spaceSubwayEffect.py (17410B)
1 #Embedded file name: C:\BuildAgent\work\20d73f1b24eed06e\eve\release\V24.01\packages\evegraphics\spaceSubway\spaceSubwayEffect.py 2 import trinity 3 import blue 4 import logging 5 import uthread2 6 from eveexceptions import ExceptionEater 7 from evegraphics.graphicEffects.skinChange import ChangeSkin 8 from evegraphics.spaceSubway.const import GetRegionValue 9 import fsdBuiltData.client.travelEffects as travelEffects 10 from uthread2.delayedcalls import call_after_simtime_delay 11 log = logging.getLogger(__name__) 12 13 def ReCurvenizeObject(obj): 14 if obj is None: 15 return 16 obj.translationCurve = CreateTranslationAdapter(obj.translationCurve) 17 obj.rotationCurve = CreateRotationAdapter(obj.rotationCurve) 18 if obj.modelRotationCurve is None: 19 obj.modelRotationCurve = trinity.Tr2RotationAdapter() 20 if obj.modelTranslationCurve is None: 21 obj.modelTranslationCurve = trinity.Tr2TranslationAdapter() 22 23 24 def CreateTranslationAdapter(curve): 25 adapter = trinity.Tr2TranslationAdapter() 26 if hasattr(curve, 'GetVectorAt'): 27 value = curve.GetVectorAt(blue.os.GetSimTime()) 28 adapter.value = (value.x, value.y, value.z) 29 elif hasattr(curve, 'value'): 30 adapter.value = curve.value 31 elif hasattr(curve, 'currentValue'): 32 adapter.value = curve.currentValue 33 return adapter 34 35 36 def CreateRotationAdapter(curve): 37 adapter = trinity.Tr2RotationAdapter() 38 if hasattr(curve, 'GetQuaternionAt'): 39 value = curve.GetQuaternionAt(blue.os.GetSimTime()) 40 adapter.value = (value.x, 41 value.y, 42 value.z, 43 value.w) 44 elif hasattr(curve, 'value'): 45 adapter.value = curve.value 46 elif hasattr(curve, 'currentValue'): 47 adapter.value = curve.currentValue 48 adapter.UpdateQuaternion(blue.os.GetSimTime()) 49 return adapter 50 51 52 class SpaceSubwayCamera(object): 53 54 def __init__(self): 55 self.lastPosition = None 56 self.lastFov = None 57 self.lastPointOfInterest = None 58 self.updateThread = None 59 self.isUpdating = False 60 61 @property 62 def position(self): 63 raise NotImplementedError() 64 65 @position.setter 66 def position(self, newPos): 67 raise NotImplementedError() 68 69 @property 70 def fov(self): 71 raise NotImplementedError() 72 73 @fov.setter 74 def fov(self, newFov): 75 raise NotImplementedError() 76 77 @property 78 def pointOfInterest(self): 79 raise NotImplementedError() 80 81 @pointOfInterest.setter 82 def pointOfInterest(self, newPointOfInterest): 83 raise NotImplementedError() 84 85 def Link(self, pos, poi, fov): 86 self.isUpdating = True 87 self.updateThread = uthread2.start_tasklet(self.UpdateCamera, pos, poi, fov) 88 89 def UpdateCamera(self, pos, poi, fov): 90 log.info('Started updating jump camera') 91 while self.isUpdating: 92 newPos = pos.GetValue() if pos else self.position 93 newPoi = poi.GetValue() if poi else self.pointOfInterest 94 with ExceptionEater('Got error while updating camera'): 95 if newPos != (0, 0, 0) and newPoi != (0, 0, 0) and newPos != newPoi: 96 self.SetPositionAndPointOfInterest(newPos, newPoi) 97 self.fov = fov.GetValue() if fov else self.fov 98 uthread2.Yield() 99 100 log.info('Stopped updating jump camera') 101 102 def SetPositionAndPointOfInterest(self, newPos, newPoi): 103 self.position = newPos 104 self.pointOfInterest = newPoi 105 106 def UnLink(self): 107 self.isUpdating = False 108 109 110 class SpaceSubwayEffect(object): 111 112 def __init__(self): 113 self.originScene = None 114 self.currentScene = None 115 self.ship = None 116 self.origin = None 117 self.skinChangeModels = [] 118 self.multiEffect = None 119 self.tunnelEffect = None 120 self.transitionScene = None 121 self.destinationScene = None 122 self.hidingEffect = None 123 self.shipHideDelay = 0 124 self.currentEffect = None 125 self.regionValue = None 126 self.security = 0 127 self.inTransitionScene = False 128 129 def __CleanScene(self, scene, callback = None): 130 if scene: 131 if self.origin and self.origin in scene.objects: 132 scene.objects.fremove(self.origin) 133 if self.multiEffect and self.multiEffect in scene.objects: 134 scene.objects.fremove(self.multiEffect) 135 if self.ship and self.ship in scene.objects: 136 scene.objects.fremove(self.ship) 137 if self.tunnelEffect and self.tunnelEffect in scene.objects: 138 scene.objects.fremove(self.tunnelEffect) 139 if self.hidingEffect and self.hidingEffect in scene.objects: 140 scene.objects.fremove(self.hidingEffect) 141 for m in self.skinChangeModels: 142 if m in scene.objects: 143 scene.objects.fremove(m) 144 145 if callback: 146 callback() 147 148 def _CleanScene(self, scene, callback = None): 149 uthread2.start_tasklet(self.__CleanScene, scene, callback) 150 151 def Cleanup(self): 152 log.info('Cleaning up') 153 154 def inner(): 155 self.originScene = None 156 self.transitionScene = None 157 self.destinationScene = None 158 self.currentScene = None 159 self.origin = None 160 self.ship = None 161 self.tunnelEffect = None 162 self.hidingEffect = None 163 if self.multiEffect: 164 for curveSet in self.multiEffect.curveSets: 165 for curveKey in curveSet.Find('trinity.Tr2ObjectFollowCurveKey'): 166 curveKey.object = None 167 168 self.multiEffect = None 169 self.currentEffect = None 170 self.regionValue = None 171 self.security = 0 172 self.shipHideDelay = 0 173 self.skinChangeModels = [] 174 175 self._CleanScene(self.originScene) 176 self._CleanScene(self.transitionScene) 177 self._CleanScene(self.destinationScene, callback=inner) 178 179 def GetTunnelEffect(self): 180 if self.tunnelEffect is None: 181 self.tunnelEffect = trinity.Load(travelEffects.GetEffect(self.currentEffect)) 182 return self.tunnelEffect 183 184 def GetMultiEffect(self): 185 if self.multiEffect is None: 186 self.multiEffect = trinity.Load(travelEffects.GetMultiEffect(self.currentEffect)) 187 return self.multiEffect 188 189 def GetTransitionScene(self): 190 if self.transitionScene is None: 191 self.transitionScene = trinity.Load(travelEffects.GetTransitionScene(self.currentEffect)) 192 return self.transitionScene 193 194 def GetHidingEffect(self): 195 if self.hidingEffect is None: 196 hidingEffectResPath = travelEffects.GetHidingEffectPath(self.currentEffect) 197 if hidingEffectResPath is not None: 198 self.hidingEffect = trinity.Load(hidingEffectResPath) 199 if isinstance(self.hidingEffect, trinity.EveTransform): 200 root = trinity.EveRootTransform() 201 root.children.append(self.hidingEffect) 202 self.hidingEffect = root 203 return self.hidingEffect 204 205 def GetShipHideDelay(self): 206 return travelEffects.GetShipHideDelay(self.currentEffect) 207 208 def GetHidingEffectDuration(self): 209 return travelEffects.GetHidingEffectDuration(self.currentEffect) 210 211 def CreateOriginEffect(self, originOrientation): 212 originEffect = travelEffects.GetOriginEffect(self.currentEffect) 213 origin = None 214 if originEffect: 215 origin = trinity.Load(originEffect) 216 if not origin: 217 log.info('Creating a fake gate for %s' % self.currentEffect) 218 origin = trinity.EveEffectRoot2() 219 origin.name = 'FakeGate' 220 origin.boundingSphereRadius = max(origin.boundingSphereRadius, 5000) 221 origin.translationCurve = trinity.Tr2TranslationAdapter() 222 origin.translationCurve.value = self.ship.translationCurve.value 223 origin.rotationCurve = trinity.Tr2RotationAdapter() 224 origin.rotationCurve.value = self.ship.rotationCurve.value 225 if originOrientation is not None and isinstance(originOrientation, tuple): 226 origin.rotationCurve.value = originOrientation 227 if self.originScene is not None: 228 self.originScene.objects.append(origin) 229 return origin 230 231 def IsWithinSystem(self): 232 return travelEffects.IsJumpWithinSystem(self.currentEffect) 233 234 def SetLook(self, nebulaPath, security, propagateToEffect = False): 235 self.regionValue = GetRegionValue(nebulaPath) 236 self.security = security 237 if propagateToEffect: 238 self.PropagateLookToEffect() 239 240 def PropagateLookToEffect(self): 241 self.tunnelEffect.SetControllerVariable('RegionLook', self.regionValue) 242 self.tunnelEffect.SetControllerVariable('SecurityLook', self.security) 243 244 def SetDestinationScene(self, scene): 245 self.destinationScene = scene 246 247 def SetEffect(self, effect): 248 self.currentEffect = effect 249 self.transitionScene = self.GetTransitionScene() 250 self.multiEffect = self.GetMultiEffect() 251 self.tunnelEffect = self.GetTunnelEffect() 252 self.hidingEffect = self.GetHidingEffect() 253 self.shipHideDelay = self.GetShipHideDelay() 254 255 def SetOriginScene(self, scene): 256 self.originScene = scene 257 self.currentScene = scene 258 259 def IsValid(self): 260 if self.currentEffect is None: 261 log.error('No effect is playing') 262 return False 263 if self.multiEffect is None: 264 log.error('No multiEffect loaded for %s', self.currentEffect) 265 return False 266 if self.tunnelEffect is None: 267 log.error('No tunnelEffect loaded for %s', self.currentEffect) 268 return False 269 return True 270 271 def HideJumpingShip(self, ship, originOrientation = None, callback = None): 272 log.info('Hiding jumping ship') 273 if self.hidingEffect is not None: 274 log.info('Playing ship hide effect') 275 self.hidingEffect.translationCurve = ship.translationCurve 276 if originOrientation is not None: 277 if hasattr(self.hidingEffect, 'rotationCurve'): 278 self.hidingEffect.rotationCurve = trinity.Tr2RotationAdapter() 279 self.hidingEffect.rotationCurve.value = originOrientation 280 else: 281 self.hidingEffect.rotation = originOrientation 282 self.hidingEffect.scaling = tuple([ship.boundingSphereRadius] * 3) 283 self.originScene.objects.append(self.hidingEffect) 284 for curveSet in getattr(self.hidingEffect, 'curveSets', []): 285 curveSet.Stop() 286 287 for curveSet in getattr(self.hidingEffect, 'curveSets', []): 288 curveSet.Play() 289 290 if hasattr(self.hidingEffect, 'StartControllers'): 291 self.hidingEffect.StartControllers() 292 293 def HideShip(ship): 294 log.info('Hiding ship') 295 if ship: 296 ship.display = False 297 for model in self.skinChangeModels: 298 model.display = False 299 300 def RemoveEffect(scene, effect, callback = None): 301 log.info('Removing hiding effect') 302 if effect and scene and effect in scene.objects: 303 scene.objects.fremove(effect) 304 if callback: 305 callback() 306 307 call_after_simtime_delay(HideShip, self.GetShipHideDelay(), ship) 308 call_after_simtime_delay(RemoveEffect, self.GetHidingEffectDuration(), self.originScene, self.hidingEffect, callback) 309 310 def StartEffectForOwner(self, origin, ship, originOrientation = None): 311 if not self.IsValid(): 312 return 313 if ship: 314 try: 315 self.HideJumpingShip(ship, originOrientation) 316 except Exception as e: 317 log.exception('Got an exception while hiding the jumping ship %s', e) 318 319 self.ship = ship 320 ReCurvenizeObject(self.ship) 321 self.origin = origin 322 if self.origin is None: 323 self.origin = self.CreateOriginEffect(originOrientation) 324 ReCurvenizeObject(self.origin) 325 self.tunnelEffect.translationCurve = trinity.Tr2TranslationAdapter() 326 self.tunnelEffect.rotationCurve = trinity.Tr2RotationAdapter() 327 self.multiEffect.SetParameter('ship', self.ship) 328 self.multiEffect.SetParameter('origin', self.origin) 329 self.multiEffect.SetParameter('tunnel', self.tunnelEffect) 330 self.AddToScene(self.originScene) 331 for curveSet in self.multiEffect.curveSets: 332 self.LinkCurveSetToOrigin(curveSet) 333 334 self.SetupCamera() 335 for controller in self.multiEffect.controllers: 336 controller.RegisterCallback('gotoTransitionScene', self.Callback('Transition Scene', self.TurnOnTransitionScene)) 337 controller.RegisterCallback('gotoDestinationScene', self.Callback('Destination Scene', self.TurnOnEndScene)) 338 controller.RegisterCallback('attachCamera', self.Callback('Attach Camera', self.AttachCamera)) 339 controller.RegisterCallback('detachCamera', self.Callback('Detach Camera', self.DetachCamera)) 340 controller.RegisterCallback('cleanup', self.Callback('Cleanup', self.Cleanup)) 341 342 self.PropagateLookToEffect() 343 self.multiEffect.StartControllers() 344 self.multiEffect.SetControllerVariable('tunneltrigger', 1.0) 345 if self.IsWithinSystem(): 346 self.destinationScene = self.originScene 347 call_after_simtime_delay(self.Stop, 5) 348 349 def Callback(self, description, func): 350 351 def startTasklet(): 352 log.info('Starting tasklet %s' % description) 353 uthread2.StartTasklet(func) 354 355 return startTasklet 356 357 def Stop(self): 358 log.info('Stopping space subway effect') 359 multiEffect = self.GetMultiEffect() 360 if multiEffect is not None: 361 multiEffect.SetControllerVariable('tunneltrigger', 0.0) 362 363 def Terminate(self): 364 if self.currentEffect is None: 365 return 366 self.DetachCamera() 367 368 def GetCamera(self): 369 raise NotImplementedError('GetCamera needs to be implemented in child classes') 370 371 def LinkCurveSetToOrigin(self, curveSet): 372 for curveKey in curveSet.Find('trinity.Tr2ObjectFollowCurveKey'): 373 curveKey.object = self.origin 374 375 def SetupCamera(self): 376 cam = self.GetCamera() 377 if cam is None: 378 return 379 initialCameraPosParameter = self.multiEffect.externalParameters.FindByName('initialCameraPos') 380 initialCameraTargetParameter = self.multiEffect.externalParameters.FindByName('initialCameraTarget') 381 if initialCameraTargetParameter: 382 initialCameraTargetParameter.SetValue(self.GetCamera().pointOfInterest) 383 if initialCameraPosParameter: 384 initialCameraPosParameter.SetValue(self.GetCamera().position) 385 386 def AttachCamera(self): 387 log.info('Attaching to camera') 388 pos = self.multiEffect.externalParameters.FindByName('cameraPos') 389 poi = self.multiEffect.externalParameters.FindByName('cameraTarget') 390 fov = self.multiEffect.externalParameters.FindByName('cameraFOV') 391 cam = self.GetCamera() 392 if cam is None: 393 return 394 cam.Link(pos, poi, fov) 395 396 def DetachCamera(self): 397 log.info('Detaching from camera') 398 cam = self.GetCamera() 399 if cam is not None: 400 log.info('Unlinking from camera curves') 401 cam.UnLink() 402 403 def AddToScene(self, scene): 404 if self.multiEffect is not None: 405 scene.objects.append(self.multiEffect) 406 if self.tunnelEffect is not None: 407 scene.objects.append(self.tunnelEffect) 408 409 def TurnOnTransitionScene(self): 410 log.info('Turning on transition scene') 411 self.AddToScene(self.transitionScene) 412 if self.ship is not None: 413 self.transitionScene.objects.append(self.ship) 414 for m in self.skinChangeModels: 415 self.transitionScene.objects.append(m) 416 417 self.PropagateLookToEffect() 418 self.SetScene(self.transitionScene) 419 self.currentScene = self.transitionScene 420 self._CleanScene(self.originScene) 421 self.inTransitionScene = True 422 423 def TurnOnEndScene(self): 424 log.info('Turning on end scene') 425 self.AddToScene(self.destinationScene) 426 self.PropagateLookToEffect() 427 self.SetScene(self.destinationScene) 428 self.currentScene = self.destinationScene 429 self._CleanScene(self.transitionScene) 430 431 def SetScene(self, scene): 432 raise NotImplementedError() 433 434 def ChangeSkin(self, newModel): 435 if self.ship is None: 436 return 437 self.skinChangeModels.append(newModel) 438 ChangeSkin(self.ship, newModel, self.currentScene) 439 newModel.translationCurve = self.ship.translationCurve 440 newModel.rotationCurve = self.ship.rotationCurve 441 newModel.modelTranslationCurve = self.ship.modelTranslationCurve 442 newModel.modelRotationCurve = self.ship.modelRotationCurve 443 self.ship = newModel 444 445 def IsShakeEnabled(self): 446 return True 447 448 def SetShake(self, shakeToggled): 449 if self.multiEffect is not None: 450 self.multiEffect.SetControllerVariable('TunnelShake', float(shakeToggled))