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

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