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

spaceCamera.py (14443B)


      1 #Embedded file name: C:\BuildAgent\work\20d73f1b24eed06e\eve\release\V24.01\eve\client\script\ui\camera\spaceCamera.py
      2 from math import sin, cos
      3 from eve.client.script.parklife import states as state
      4 from eve.client.script.ui.camera.cameraBase import CameraBase
      5 from eve.client.script.ui.camera.cameraUtil import GetCameraMaxLookAtRange
      6 from destructionEffect import destructionType as destructionEffectType
      7 import evecamera
      8 import audio2
      9 import blue
     10 import trinity
     11 import uthread
     12 import destiny
     13 import localization
     14 import telemetry
     15 import evecamera.shaker as shaker
     16 import evecamera.utils as camutils
     17 import evecamera.cameratarget as camtarget
     18 import evecamera.animation as camanim
     19 import evegraphics.settings as gfxsettings
     20 import evespacescene
     21 from player_messaging.client.ui_message import message_player
     22 SIZEFACTOR = 1e-07
     23 TRANSLATION_MAX = 1000000.0
     24 
     25 class SpaceCamera(CameraBase):
     26     cameraID = 'default'
     27     __notifyevents__ = ['OnSpecialFX',
     28      'DoBallClear',
     29      'DoBallRemove',
     30      'OnSessionChanged',
     31      'OnSetDevice',
     32      'OnGraphicSettingsChanged',
     33      'DoBallsRemove',
     34      'DoSimClockRebase',
     35      'OnBallparkSetState']
     36 
     37     def __init__(self):
     38         CameraBase.__init__(self)
     39         sm.RegisterNotify(self)
     40         self.ResetConfiguration()
     41         self.noise = gfxsettings.Get(gfxsettings.UI_CAMERA_SHAKE_ENABLED)
     42         self.UpdateCameraBobbing()
     43         self.checkDistToEgoThread = None
     44         self.cachedCameraTranslation = -1
     45         self.shakeController = shaker.ShakeController(self)
     46         self.animationController = camanim.AnimationController(self)
     47         self.lookingAt = None
     48 
     49     def UpdateCameraBobbing(self):
     50         self.idleMove = gfxsettings.Get(gfxsettings.UI_CAMERA_BOBBING_ENABLED)
     51 
     52     def ResetConfiguration(self):
     53         self.fieldOfView = evecamera.FOV_MAX
     54         self.friction = evecamera.DEFAULT_FRICTION
     55         self.maxSpeed = evecamera.DEFAULT_MAX_SPEED
     56         self.frontClip = evecamera.DEFAULT_FRONT_CLIP
     57         self.backClip = evecamera.DEFAULT_BACK_CLIP
     58         self.idleScale = evecamera.DEFAULT_IDLE_SCALE
     59         self.translationFromParent = -30.0
     60         self.idleSpeed = 0.5
     61         self.noiseScale = -2.010956
     62         self.noiseScaleCurve = trinity.Tr2CurveScalar()
     63         self.noiseScaleCurve.AddKey(0.0, 0.0, trinity.Tr2CurveInterpolation.LINEAR)
     64         self.noiseScaleCurve.AddKey(0.5, -2.2945609, trinity.Tr2CurveInterpolation.LINEAR)
     65         self.noiseScaleCurve.AddKey(5.0, 0.0, trinity.Tr2CurveInterpolation.LINEAR)
     66         self.zoomCurve = trinity.Tr2CurveScalar()
     67         self.zoomCurve.AddKey(0.0, evecamera.FOV_MAX, trinity.Tr2CurveInterpolation.HERMITE, 0.0, 1.0, trinity.Tr2CurveTangentType.FREE_SPLIT)
     68         self.zoomCurve.AddKey(0.224, evecamera.FOV_MAX, trinity.Tr2CurveInterpolation.HERMITE, 0.0, -7.0, trinity.Tr2CurveTangentType.FREE_SPLIT)
     69         self.zoomCurve.AddKey(0.45, evecamera.FOV_MAX, trinity.Tr2CurveInterpolation.HERMITE, 0.0, -9.0, trinity.Tr2CurveTangentType.FREE_SPLIT)
     70         self.zoomCurve.AddKey(0.6, evecamera.FOV_MAX, trinity.Tr2CurveInterpolation.HERMITE, 0.0, 20.0, trinity.Tr2CurveTangentType.FREE_SPLIT)
     71         self.zoomCurve.AddKey(0.0, evecamera.FOV_MAX, trinity.Tr2CurveInterpolation.HERMITE, 0.0, 1.0, trinity.Tr2CurveTangentType.FREE_SPLIT)
     72 
     73     def DoBallClear(self, solitem):
     74         cameraParent = self.GetCameraParent()
     75         if cameraParent is not None:
     76             cameraParent.parent = None
     77 
     78     @telemetry.ZONE_METHOD
     79     def DoBallsRemove(self, pythonBalls, isRelease):
     80         for ball, slimItem, terminal in pythonBalls:
     81             self.DoBallRemove(ball, slimItem, terminal)
     82 
     83     def DoBallRemove(self, ball, slimItem, terminal):
     84         if session.shipid is not None:
     85             lookingAtID = self.GetLookAtItemID()
     86             if lookingAtID is not None and ball.id == lookingAtID:
     87                 if ball.destructionEffectId != destructionEffectType.NONE and ball.id != session.shipid:
     88                     uthread.new(self._HandleTargetKilled, ball)
     89                 else:
     90                     uthread.new(self._AdjustLookAtTarget, ball)
     91             elif self.cameraInterestID == ball.id and ball.destructionEffectId is not destructionEffectType.NONE:
     92                 uthread.new(self._HandleTargetKilled, ball)
     93 
     94     def DoSimClockRebase(self, times):
     95         self.animationController.DoSimClockRebase(times)
     96 
     97     def _HandleTargetKilled(self, ball):
     98         delay = ball.GetExplosionLookAtDelay()
     99         blue.synchro.SleepSim(delay)
    100         lookingAtID = self.GetLookAtItemID()
    101         if lookingAtID == ball.id:
    102             self.LookAt(session.shipid)
    103         if self.cameraInterestID == ball.id:
    104             self.Track(None)
    105 
    106     def _AdjustLookAtTarget(self, ball):
    107         if session.shipid is None:
    108             return
    109         cameraParent = self.GetCameraParent()
    110         lookingAtID = self.GetLookAtItemID()
    111         if cameraParent and cameraParent.parent and cameraParent.parent == ball.model:
    112             cameraParent.parent = None
    113         if lookingAtID and ball.id == lookingAtID and lookingAtID != session.shipid:
    114             self.LookAt(session.shipid)
    115 
    116     def OnSpecialFX(self, shipID, moduleID, moduleTypeID, targetID, otherTypeID, guid, isOffensive, start, active, duration = -1, repeat = None, startTime = None, timeFromStart = 0, graphicInfo = None):
    117         if guid == 'effects.Warping':
    118             if shipID == session.shipid:
    119                 if self.GetLookAtItemID() is not None and self.GetLookAtItemID() != session.shipid:
    120                     self.LookAt(session.shipid)
    121 
    122     def OnSetDevice(self, *args):
    123         if session.stationid:
    124             return
    125         blue.synchro.Yield()
    126         self.translationFromParent = self.CheckTranslationFromParent(self.translationFromParent)
    127 
    128     def OnBallparkSetState(self, *args):
    129         uthread.new(self.LookAt, session.shipid, self.cachedCameraTranslation, smooth=False)
    130 
    131     def OnSessionChanged(self, isRemote, sess, change):
    132         if 'shipid' in change:
    133             oldID = change['shipid'][0]
    134             newID = change['shipid'][1]
    135             bp = sm.GetService('michelle').GetBallpark()
    136             if bp is None:
    137                 return
    138             if newID is not None and newID not in bp.slimItems and oldID is not None:
    139                 self.lookingAt = newID
    140             else:
    141                 self.LookAt(newID, self.cachedCameraTranslation)
    142 
    143     def _GetTrackableCurve(self, itemID):
    144         item = sm.StartService('michelle').GetBall(itemID)
    145         if item is None or getattr(item, 'model', None) is None:
    146             return
    147         if item.model.__bluetype__ in evespacescene.EVESPACE_TRINITY_CLASSES:
    148             behavior = trinity.EveLocalPositionBehavior.centerBounds
    149             tracker = trinity.EveLocalPositionCurve(behavior)
    150             tracker.parent = item.model
    151             return tracker
    152         return item
    153 
    154     def Track(self, itemID, **kwargs):
    155         self.cameraInterestID = itemID
    156         cameraInterest = self.GetCameraInterest()
    157         if itemID is None:
    158             cameraInterest.translationCurve = None
    159         trackable = self._GetTrackableCurve(itemID)
    160         cameraInterest.translationCurve = trackable
    161 
    162     def GetTrackItemID(self):
    163         return self.cameraInterestID
    164 
    165     def _AbortLookAtOther(self):
    166         self.ResetCamera()
    167         self.checkDistToEgoThread = None
    168 
    169     def _CheckDistanceToEgo(self):
    170         while self.checkDistToEgoThread is not None:
    171             if self.lookingAt is not None:
    172                 lookingAtItem = sm.GetService('michelle').GetBall(self.lookingAt)
    173                 if lookingAtItem is None or lookingAtItem.surfaceDist > GetCameraMaxLookAtRange():
    174                     self._AbortLookAtOther()
    175             blue.synchro.Yield()
    176 
    177     def _LookingAtSelf(self):
    178         scene = sm.GetService('sceneManager').GetRegisteredScene('default')
    179         if scene and scene.cameraAttachments.FindByName('dustfield'):
    180             scene.cameraAttachments.FindByName('dustfield').display = True
    181         self.checkDistToEgoThread = None
    182 
    183     def _IsLookingAtOtherOK(self, item):
    184         obs = sm.GetService('target').IsObserving()
    185         if item is None:
    186             return False
    187         if item.mode == destiny.DSTBALL_WARP:
    188             return False
    189         if not obs and item.surfaceDist > GetCameraMaxLookAtRange():
    190             message_player(localization.GetByLabel('UI/Camera/OutsideLookingRange'))
    191             return False
    192         return True
    193 
    194     def _LookingAtOther(self):
    195         scene = sm.GetService('sceneManager').GetRegisteredScene('default')
    196         if scene is not None:
    197             if scene.cameraAttachments.FindByName('dustfield'):
    198                 scene.cameraAttachments.FindByName('dustfield').display = False
    199         if self.checkDistToEgoThread is None:
    200             self.checkDistToEgoThread = uthread.pool('MenuSvc>checkDistToEgoThread', self._CheckDistanceToEgo)
    201         return True
    202 
    203     def LookAt(self, itemID, setZ = None, resetCamera = False, smooth = True, **kwargs):
    204         item = sm.StartService('michelle').GetBallAndWaitForModel(itemID)
    205         if not hasattr(item, 'GetModel') or item.GetModel() is None:
    206             return
    207         itemIdIsMyShip = itemID == session.shipid
    208         if itemIdIsMyShip:
    209             self._LookingAtSelf()
    210         elif self._IsLookingAtOtherOK(item):
    211             self._LookingAtOther()
    212         else:
    213             return
    214         cameraParent = self.GetCameraParent()
    215         if cameraParent is None:
    216             return
    217         self.GetCameraInterest().translationCurve = None
    218         sm.GetService('stateSvc').SetState(itemID, state.lookingAt, 1)
    219         self.lookingAt = itemID
    220         cache = itemIdIsMyShip
    221         item.LookAtMe()
    222         if itemIdIsMyShip is False:
    223             sm.ScatterEvent('OnCameraLookAt', False, itemID)
    224         trackableItem = self._GetTrackableCurve(itemID)
    225         if not smooth:
    226             self.animationController.Schedule(camutils.SetTranslationCurve(trackableItem))
    227             self.animationController.Schedule(camutils.LookAt_Pan(setZ, 0.0, cache=cache))
    228         else:
    229             self._DoAnimatedLookAt(item, setZ, resetCamera, trackableItem, cache=cache)
    230 
    231     def _DoAnimatedLookAt(self, item, setZ = None, resetCamera = False, trackableItem = None, cache = False):
    232         if item.model.__bluetype__ not in evespacescene.EVESPACE_TRINITY_CLASSES:
    233             self.animationController.Schedule(camutils.SetTranslationCurve(trackableItem))
    234             return
    235         behavior = trinity.EveLocalPositionBehavior.centerBounds
    236         tracker = trinity.EveLocalPositionCurve(behavior)
    237         tracker.parent = item.model
    238         self.animationController.Schedule(camutils.LookAt_Translation(tracker))
    239         self.animationController.Schedule(camutils.LookAt_FOV(resetCamera))
    240         self.animationController.Schedule(camutils.LookAt_Pan(setZ, cache=cache))
    241 
    242     def PanCameraBy(self, percentage, time = 0.0, cache = False):
    243         beg = self.translationFromParent
    244         end = beg + beg * percentage
    245         self.PanCamera(beg, end, time, cache)
    246 
    247     def PanCamera(self, cambeg = None, camend = None, time = 0.5, cache = False, source = None):
    248         cacheTranslation = cache and self.GetLookAtItemID() == session.shipid
    249         self.animationController.Schedule(camutils.PanCamera(cambeg, camend, time, cacheTranslation, source))
    250 
    251     def TranslateFromParentAccelerated(self, begin, end, durationSec, accelerationPower = 2.0):
    252         self.animationController.Schedule(camutils.PanCameraAccelerated(begin, end, durationSec, accelerationPower))
    253 
    254     def ClearAnimations(self):
    255         self.animationController.ClearAll()
    256 
    257     def CacheCameraTranslation(self):
    258         self.cachedCameraTranslation = self.translationFromParent
    259 
    260     def ClearCameraParent(self):
    261         if self.cameraParent:
    262             self.cameraParent.translationCurve = None
    263             self.cameraParent = None
    264 
    265     def GetCameraParent(self):
    266         if self.cameraParent is None:
    267             self.cameraParent = camtarget.CameraTarget(self)
    268         return self.cameraParent
    269 
    270     def GetCameraInterest(self):
    271         if self.cameraInterest is None:
    272             self.cameraInterest = camtarget.CameraTarget(self, 'interest')
    273         return self.cameraInterest
    274 
    275     def ResetCamera(self, *args):
    276         sm.ScatterEvent('OnCameraLookAt', True, session.shipid)
    277         self.LookAt(session.shipid, resetCamera=True)
    278 
    279     def GetLookAtItemID(self):
    280         return self.lookingAt
    281 
    282     def _GetTranslationFromParentForItem(self, itemID):
    283         ballpark = sm.GetService('michelle').GetBallpark()
    284         if ballpark is None:
    285             return
    286         ball = ballpark.GetBall(itemID)
    287         ball, model, ballRadius = ball, getattr(ball, 'model', None), getattr(ball, 'radius', None)
    288         if model is None:
    289             return
    290         rad = None
    291         if model.__bluetype__ in evespacescene.EVESPACE_TRINITY_CLASSES:
    292             rad = model.GetBoundingSphereRadius()
    293             zoomMultiplier = 1.1 * camutils.GetARZoomMultiplier(trinity.GetAspectRatio())
    294             return (rad + self.frontClip) * zoomMultiplier + 2
    295         if len(getattr(model, 'children', [])) > 0:
    296             rad = ball.model.children[0].GetBoundingSphereRadius()
    297         if rad is None or rad <= 0.0:
    298             rad = ballRadius
    299         camangle = self.fieldOfView * 0.5
    300         return max(15.0, rad / sin(camangle) * cos(camangle))
    301 
    302     def CheckTranslationFromParent(self, distance, distanceIsScale = False):
    303         mn, mx = self._GetMinMaxTranslationFromParent()
    304         if distanceIsScale:
    305             distance = mn * distance
    306         retval = max(mn, min(distance, mx))
    307         return retval
    308 
    309     def _GetMinMaxTranslationFromParent(self):
    310         lookingAt = self.GetLookAtItemID() or session.shipid
    311         mn = self._GetTranslationFromParentForItem(lookingAt)
    312         mx = TRANSLATION_MAX
    313         return (mn, mx)
    314 
    315     def ShakeCamera(self, magnitude, position, key = None):
    316         behavior = camutils.CreateBehaviorFromMagnitudeAndPosition(magnitude, position, self)
    317         if behavior is None:
    318             return
    319         behavior.key = key
    320         self.shakeController.DoCameraShake(behavior)
    321 
    322     def OnGraphicSettingsChanged(self, changes):
    323         if gfxsettings.UI_CAMERA_SHAKE_ENABLED in changes:
    324             self.shakeController.Enable(gfxsettings.Get(gfxsettings.UI_CAMERA_SHAKE_ENABLED))
    325         if gfxsettings.UI_CAMERA_BOBBING_ENABLED in changes:
    326             self.UpdateCameraBobbing()