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

tacticalCamera.py (14661B)


      1 #Embedded file name: C:\BuildAgent\work\20d73f1b24eed06e\eve\release\V24.01\eve\client\script\ui\camera\tacticalCamera.py
      2 import geo2
      3 from eve.client.script.parklife import states
      4 from eve.client.script.ui.camera.baseSpaceCamera import BaseSpaceCamera
      5 from eve.client.script.ui.camera.cameraUtil import GetDurationByDistance, GetBallPosition, GetBall, GetBallMaxZoom, IsBallWarping, CheckShowModelTurrets, VectorLerper, GetCameraInertiaMultiplier, IsAutoTrackingEnabled, PositionAnimatorDetached, PositionAnimatorAttached
      6 import evecamera
      7 from carbonui.uicore import uicore
      8 DEFAULT_EYEDIST = 40000
      9 FREE_ORBIT_DIST = 250
     10 LOOKAT_DIST = 50000
     11 
     12 class TacticalCamera(BaseSpaceCamera):
     13     name = 'TacticalCamera'
     14     __notifyevents__ = BaseSpaceCamera.__notifyevents__ + ['OnStateChange']
     15     cameraID = evecamera.CAM_TACTICAL
     16     kOrbitSpeed = 5.0
     17     default_fov = 1.0
     18     default_atPosition = (0, 0, 0)
     19     default_eyePosition = (-DEFAULT_EYEDIST, DEFAULT_EYEDIST, DEFAULT_EYEDIST)
     20     maxFov = 1.0
     21     minFov = 0.3
     22 
     23     def __init__(self):
     24         BaseSpaceCamera.__init__(self)
     25         self.lastLookAtID = None
     26         self.sceneCursor = (0, 0, 0)
     27         self.positionAnimator = PositionAnimatorDetached(self)
     28         self.trackBall = None
     29         self.trackBallMorpher = VectorLerper()
     30 
     31     def GetLookAtItemID(self):
     32         if self.IsAttached():
     33             return self.GetItemID()
     34         else:
     35             return None
     36 
     37     def IsAttached(self):
     38         return self.positionAnimator.IsAttached()
     39 
     40     def LookAt(self, itemID, allowSwitchCamera = True, **kwargs):
     41         if not self.IsManualControlEnabled():
     42             return
     43         if self.CheckObjectTooFar(itemID) and itemID != self.ego:
     44             self.Track(itemID)
     45             return
     46         self.StopTracking()
     47         if itemID == self.GetItemID():
     48             self.ResetFOV()
     49             if itemID != self.ego:
     50                 self.LookAt(self.ego)
     51             return
     52         self.StopUpdateThreads()
     53         self.ResetFOV()
     54         ball = GetBall(itemID)
     55         if not ball:
     56             return
     57         CheckShowModelTurrets(ball)
     58         duration = self.AnimateLookAt(ball)
     59         self._SetLookAtBall(ball, duration=duration)
     60         if ball.id == self.ego and hasattr(ball, 'GetModel') and ball.GetModel() is None:
     61             ball.RegisterForModelLoad(self.UpdateMaxZoom)
     62         sm.ScatterEvent('OnCameraLookAt', itemID == self.ego, itemID)
     63 
     64     def AnimateLookAt(self, ball):
     65         eyePos1 = self.GetLookAtEyePos(ball)
     66         duration = self.AnimLookAtTransit(ball, eyePos1)
     67         return duration
     68 
     69     def AnimLookAtTransit(self, ball, eyePos1):
     70         ballPos = GetBallPosition(ball)
     71         self.SetAppropriateAtPositionForRotation(ballPos)
     72         duration = GetDurationByDistance(self.positionAnimator.GetAtPosition(), ballPos, minTime=0.3, maxTime=0.6)
     73         self.TransitTo(ballPos, eyePos1, duration=duration, smoothing=0.0)
     74         return duration
     75 
     76     def GetLookAtEyePos(self, ball):
     77         distance = self.GetLookAtDistance(ball)
     78         lookVec = geo2.Vec3Scale(self.GetLookAtDirection(), distance)
     79         eyePos1 = geo2.Vec3Add(GetBallPosition(ball), lookVec)
     80         return eyePos1
     81 
     82     def GetLookAtDistance(self, ball):
     83         if self.IsAttached():
     84             distance = self.GetZoomDistance()
     85         else:
     86             distance = geo2.Vec3Distance(self.eyePosition, GetBallPosition(ball))
     87         maxZoom = GetBallMaxZoom(ball, self.nearClip)
     88         distance = max(maxZoom, min(distance, self.minZoom))
     89         return distance
     90 
     91     def _SetLookAtBall(self, ball, duration = 0.6):
     92         if ball:
     93             self.positionAnimator = PositionAnimatorAttached(self, ball, duration)
     94             self.UpdateMaxZoom()
     95             self.lastLookAtID = ball.id
     96             sm.GetService('stateSvc').SetState(ball.id, states.lookingAt, True)
     97         else:
     98             self.positionAnimator = PositionAnimatorDetached(self)
     99 
    100     def OnDeactivated(self):
    101         BaseSpaceCamera.OnDeactivated(self)
    102         self._SetLookAtBall(None)
    103         self.StopTracking()
    104 
    105     def UpdateMaxZoom(self):
    106         ball = self.GetZoomToBall()
    107         if ball:
    108             maxZoom = GetBallMaxZoom(ball, self.nearClip)
    109             if maxZoom < self.minZoom:
    110                 self.SetMaxZoom(maxZoom)
    111 
    112     def GetZoomToBall(self):
    113         if self.trackBall:
    114             return self.trackBall
    115         if self.positionAnimator.ball:
    116             return self.positionAnimator.ball
    117 
    118     def Pan(self, dx = None, dy = None, dz = None):
    119         if not self.IsManualControlEnabled():
    120             return
    121         if self.IsActiveOrTrackingShipWarping():
    122             return
    123         self.StopTracking()
    124         if self.IsAttached():
    125             self.Detach()
    126         k = self.GetPanSpeed()
    127         BaseSpaceCamera.Pan(self, k * dx, k * dy, k * dz)
    128 
    129     def PanImmediate(self, dx, dy, dz):
    130         if not self.IsManualControlEnabled():
    131             return
    132         if self.IsActiveOrTrackingShipWarping():
    133             return
    134         pan = geo2.Add(geo2.Add(geo2.Scale(self.GetXAxis(), dx), geo2.Scale(self.GetYAxis(), dy)), geo2.Scale(self.GetZAxis(), dz))
    135         self.eyePosition = geo2.Add(self._eyePosition, pan)
    136         self.atPosition = geo2.Add(self._atPosition, pan)
    137 
    138     def OrbitImmediate(self, yaw, pitch):
    139         self.pitch = self.pitch + pitch
    140         self.yaw = self.yaw + yaw
    141         self.StopOrbitUpdate()
    142 
    143     def StopTracking(self):
    144         self.Track(None)
    145 
    146     def IsTracking(self):
    147         return self.trackBall is not None or not self.trackBallMorpher.IsDone()
    148 
    149     def GetPanSpeed(self):
    150         return 0.01 + 0.001 * self.GetDistanceToCursor() ** 0.9
    151 
    152     def Detach(self):
    153         if self.IsActiveOrTrackingShipWarping():
    154             return
    155         self.StopUpdateThreads()
    156         self.positionAnimator = PositionAnimatorDetached(self)
    157         if self.lastLookAtID:
    158             self.lastLookAtID = None
    159             self.sceneCursor = self.atPosition
    160         self.SetAtPosToFixedDistance()
    161         sm.ScatterEvent('OnCameraLookAt', False, None)
    162 
    163     def SetAtPosToFixedDistance(self):
    164         self.SetAtPosition(geo2.Vec3AddD(self._eyePosition, geo2.Vec3Scale(self.GetLookAtDirectionWithOffset(), -100.0)))
    165 
    166     def GetDistanceToCursor(self):
    167         return geo2.Vec3Distance(self.eyePosition, self.sceneCursor)
    168 
    169     def ResetCamera(self, *args):
    170         self.LookAt(self.ego)
    171 
    172     def OnActivated(self, lastCamera = None, itemID = None, duration = None, **kwargs):
    173         if self.positionAnimator:
    174             self.positionAnimator.Reset()
    175         BaseSpaceCamera.OnActivated(self, **kwargs)
    176         settings.char.ui.Set('spaceCameraID', evecamera.CAM_TACTICAL)
    177         if lastCamera:
    178             distance = max(self.maxZoom, min(geo2.Vec3Length(self.eyePosition), self.minZoom))
    179             if lastCamera.cameraID in (evecamera.CAM_SHIPORBIT,
    180              evecamera.CAM_UNDOCK,
    181              evecamera.CAM_ENTERSPACE,
    182              evecamera.CAM_SHIPORBIT_ABYSSAL_SPACE,
    183              evecamera.CAM_SHIPORBIT_HAZARD):
    184                 self._ResetEyeAndAtPosition(lastCamera.eyePosition, lastCamera.atPosition, distance)
    185             elif lastCamera.cameraID == evecamera.CAM_JUMP and sm.GetService('subway').Enabled():
    186                 duration = lastCamera.transitionDelay
    187                 direction = lastCamera.GetLookAtDirection()
    188                 d = self.eyePosition
    189                 self.Transit(lastCamera.atPosition, lastCamera.eyePosition, (0, 0, 0), geo2.Vec3Scale(direction, self.GetZoomDistanceByZoomProportion(lastCamera.GetZoom())), duration=duration, callback=lambda : self.AfterJumpCallback(d))
    190             else:
    191                 animate = lastCamera.cameraID not in (evecamera.CAM_SHIPPOV, evecamera.CAM_HANGAR)
    192                 self._ResetEyeAndAtPosition(self.eyePosition, self.atPosition, distance, animate)
    193             targetBall = GetBall(lastCamera.GetItemID())
    194             if targetBall:
    195                 self._SetLookAtBall(targetBall)
    196             if lastCamera.cameraID != evecamera.CAM_SHIPPOV:
    197                 self.fov = lastCamera.fov
    198             self.ResetFOV()
    199         else:
    200             if not itemID:
    201                 itemID = self.ego
    202             self._SetLookAtBall(GetBall(itemID))
    203             self.SetEyePosition(self.default_eyePosition)
    204 
    205     def AfterJumpCallback(self, desiredEyePosition):
    206         self.EnableManualControl()
    207         desiredDistance = geo2.Vec3Length(desiredEyePosition)
    208         desiredDirection = geo2.Vec3Normalize(desiredEyePosition)
    209         desiredEyePosition = geo2.Vec3Scale(desiredDirection, max(self.maxZoom, min(self.minZoom, desiredDistance)))
    210         self.Transit((0, 0, 0), self.eyePosition, (0, 0, 0), desiredEyePosition, duration=0.5)
    211 
    212     def _GetNewDirection(self, direction):
    213         y = geo2.Vec2Length((direction[0], direction[2]))
    214         direction = (direction[0], y, direction[2])
    215         direction = geo2.Vec3Normalize(direction)
    216         return direction
    217 
    218     def _ResetEyeAndAtPosition(self, eyePos0, atPos0, distance = LOOKAT_DIST, animate = True, duration = None):
    219         direction = self._GetNewDirection(geo2.Vec3Subtract(eyePos0, atPos0))
    220         eyePos1 = geo2.Vec3Add(atPos0, geo2.Vec3Scale(direction, distance))
    221         if animate:
    222             if duration is None:
    223                 duration = GetDurationByDistance(eyePos0, eyePos1, 0.4, 0.6)
    224             atPos1 = atPos0
    225             diff = geo2.Vec3Scale(geo2.Vec3Direction(atPos0, eyePos0), distance / 5)
    226             atPos0 = geo2.Vec3Add(atPos0, diff)
    227             self.Transit(atPos0, eyePos0, atPos1, eyePos1, duration=duration, callback=self.EnableManualControl)
    228         else:
    229             self.SetAtPosition(atPos0)
    230             self.SetEyePosition(eyePos1)
    231 
    232     def Update(self):
    233         BaseSpaceCamera.Update(self)
    234         if not session.solarsystemid:
    235             return
    236         if self.IsActiveOrTrackingShipWarping() and not self.IsAttached():
    237             self.LookAt(self.ego)
    238         if self.positionAnimator.GetItemID():
    239             self.positionAnimator.Update()
    240             if self.IsTracking():
    241                 atPos = self.GetTrackingAtPosition()
    242             else:
    243                 atPos = self.positionAnimator.GetAtPosition()
    244             self.SetAtPosition(atPos)
    245             self.SetEyePosition(self.positionAnimator.GetEyePosition())
    246         if self.IsAttached():
    247             self._EnforceMaximumDistanceAttached()
    248         else:
    249             self._EnforceMaximumDistanceDetached()
    250 
    251     def _EnforceMaximumDistanceAttached(self):
    252         dist = geo2.Vec3Length(self.positionAnimator.GetAtPosition())
    253         if dist > evecamera.LOOKATRANGE_MAX_NEW and not self.IsInTransit():
    254             self.LookAt(self.ego)
    255 
    256     def GetTrackingAtPosition(self):
    257         if self.trackBall:
    258             ballPos = GetBallPosition(self.trackBall)
    259         else:
    260             ballPos = self.positionAnimator.GetAtPosition()
    261         if geo2.Vec3Length(ballPos) > evecamera.LOOKATRANGE_MAX_NEW:
    262             direction = geo2.Vec3Normalize(geo2.Vec3Subtract(ballPos, self.eyePosition))
    263             ballPos = geo2.Vec3Add(self.eyePosition, geo2.Vec3Scale(direction, evecamera.LOOKATRANGE_MAX_NEW))
    264         return self.trackBallMorpher.GetValue(self.atPosition, ballPos)
    265 
    266     def IsActiveOrTrackingShipWarping(self):
    267         return IsBallWarping(self.GetItemID()) or IsBallWarping(self.ego)
    268 
    269     def GetItemID(self):
    270         return self.positionAnimator.GetItemID()
    271 
    272     def _EnforceMaximumDistanceDetached(self):
    273         dist = geo2.Vec3Length(self.eyePosition)
    274         if dist > evecamera.LOOKATRANGE_MAX_NEW and not self.IsInTransit():
    275             direction = geo2.Vec3Normalize(self.eyePosition)
    276             newEye = geo2.Vec3Scale(direction, evecamera.LOOKATRANGE_MAX_NEW)
    277             diff = geo2.Vec3Subtract(self.eyePosition, newEye)
    278             self.SetEyePosition(newEye)
    279             self.SetAtPosition(geo2.Vec3Subtract(self._atPosition, diff))
    280 
    281     def OnCurrentShipWarping(self):
    282         if self.isActive:
    283             self.LookAt(self.ego)
    284 
    285     def Track(self, itemID = None, **kwargs):
    286         if itemID is None and not self.trackBall:
    287             return
    288         ball = GetBall(itemID)
    289         if ball and ball not in (self.positionAnimator.ball, self.trackBall):
    290             self._TrackItem(ball)
    291         else:
    292             self._TrackNothing()
    293         self.UpdateMaxZoom()
    294         sm.ScatterEvent('OnCameraTrack', itemID)
    295 
    296     def _TrackNothing(self):
    297         self.trackBallMorpher.Reset(0.5 / GetCameraInertiaMultiplier())
    298         self.trackBall = None
    299 
    300     def _TrackItem(self, ball):
    301         self.trackBallMorpher.Reset(3.0 / GetCameraInertiaMultiplier())
    302         ballPos = GetBallPosition(ball)
    303         self.StopUpdateThreads()
    304         self.SetAppropriateAtPositionForRotation(ballPos)
    305         self.trackBall = ball
    306 
    307     def SetAppropriateAtPositionForRotation(self, atPos):
    308         distanceToNewAtPos = geo2.Vec3Distance(self.eyePosition, atPos)
    309         distanceToNewAtPos = min(evecamera.LOOKATRANGE_MAX_NEW, distanceToNewAtPos)
    310         lookVec = geo2.Vec3Scale(self.GetLookAtDirection(), distanceToNewAtPos)
    311         newAtPos = geo2.Vec3Subtract(self.eyePosition, lookVec)
    312         if newAtPos != self._eyePosition:
    313             self.SetAtPosition(newAtPos)
    314 
    315     def OnBallRemoved(self, ball):
    316         if self.positionAnimator and ball == self.positionAnimator.ball:
    317             self.Detach()
    318         if ball == self.trackBall:
    319             self.StopTracking()
    320 
    321     def OnStateChange(self, itemID, flag, flagState, *args):
    322         if not self.isActive:
    323             return
    324         if flagState and flag == states.selected and IsAutoTrackingEnabled():
    325             if not uicore.cmd.IsSomeCombatCommandLoaded():
    326                 self.Track(itemID)
    327 
    328     def Orbit(self, *args):
    329         if self.IsTracking() and self.IsBeyondZoomDistance():
    330             self.StopTracking()
    331             self.AnimLookAtTransit(self.positionAnimator.ball, self.eyePosition)
    332         else:
    333             BaseSpaceCamera.Orbit(self, *args)
    334 
    335     def IsBeyondZoomDistance(self):
    336         return self.GetZoomDistance() > self.minZoom
    337 
    338     def Zoom(self, dz):
    339         if self.IsTracking() and self.trackBall and self.CheckObjectTooFar(self.trackBall.id):
    340             return
    341         BaseSpaceCamera.Zoom(self, dz)
    342 
    343     def GetAtPositionClosestToShip(self):
    344         if self.IsAttached():
    345             return self.atPosition
    346         distanceToShip = self.GetLookAtDistance(GetBall(self.ego))
    347         distFromLookAt = geo2.Vec3Scale(self.GetLookAtDirection(), distanceToShip)
    348         closestAtPosition = geo2.Vector(self.eyePosition) - distFromLookAt
    349         if closestAtPosition == self.eyePosition:
    350             closestAtPosition = self.atPosition
    351         return closestAtPosition