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

cameraUtil.py (12986B)


      1 #Embedded file name: C:\BuildAgent\work\20d73f1b24eed06e\eve\release\V24.01\eve\client\script\ui\camera\cameraUtil.py
      2 import logging
      3 import math
      4 import traceback
      5 import blue
      6 import geo2
      7 import destiny
      8 import evespacescene
      9 import trinity
     10 import uthread
     11 from carbonui.primitives.base import ScaleDpiF
     12 from carbonui.uicore import uicore
     13 from carbon.common.lib.const import SEC
     14 from evecamera import LOOKATRANGE_MAX_NEW
     15 from evecamera.utils import GetARZoomMultiplier
     16 from evegraphics import settings as gfxsettings
     17 from eveservices.menu import GetMenuService
     18 FOV_MIN = 0.55
     19 FOV_MAX = 1.1
     20 log = logging.getLogger(__name__)
     21 
     22 def IsBobbingEnabled():
     23     return gfxsettings.Get(gfxsettings.UI_CAMERA_BOBBING_ENABLED)
     24 
     25 
     26 def GetCameraMaxLookAtRange():
     27     return LOOKATRANGE_MAX_NEW
     28 
     29 
     30 def GetPanVectorForZoomToCursor(viewport, fov):
     31     th = math.radians(90 * fov / 2.0)
     32     dist = viewport.width / (2.0 * math.tan(th))
     33     u = ScaleDpiF(uicore.uilib.x)
     34     x = -u + viewport.x + viewport.width / 2
     35     v = ScaleDpiF(uicore.uilib.y)
     36     y = v - viewport.y - viewport.height / 2
     37     return geo2.Vec3Normalize((x, y, dist))
     38 
     39 
     40 def SetShipDirection(camera):
     41     scene = sm.GetService('sceneManager').GetRegisteredScene('default')
     42     proj = camera.projectionMatrix.transform
     43     view = camera.viewMatrix.transform
     44     pickDir = scene.PickInfinity(uicore.ScaleDpi(uicore.uilib.x), uicore.ScaleDpi(uicore.uilib.y), proj, view)
     45     if pickDir:
     46         bp = sm.GetService('michelle').GetRemotePark()
     47         if bp is not None:
     48             try:
     49                 x, y, z = pickDir[0], pickDir[1], pickDir[2]
     50                 bp.CmdGotoDirection(x, y, z)
     51                 sm.GetService('tacticalNavigation').NotifyOfMoveTowardsPointCommand(pickDir)
     52                 GetMenuService().ClearAlignTargets()
     53                 sm.GetService('flightPredictionSvc').GotoDirection(pickDir)
     54             except RuntimeError as e:
     55                 if e.args[0] != 'MonikerSessionCheckFailure':
     56                     raise e
     57 
     58 
     59 def GetZoomDz():
     60     dz = CheckInvertZoom(uicore.uilib.dz)
     61     return GetPowerOfWithSign(dz)
     62 
     63 
     64 def CheckInvertZoom(dz):
     65     if gfxsettings.Get(gfxsettings.UI_INVERT_CAMERA_ZOOM):
     66         return -dz
     67     return dz
     68 
     69 
     70 def GetPowerOfWithSign(value, power = 1.1):
     71     return math.copysign(math.fabs(value) ** power, value)
     72 
     73 
     74 def GetCameraInertiaMultiplier():
     75     multiplier = gfxsettings.Get(gfxsettings.UI_CAMERA_INERTIA)
     76     if multiplier < 0:
     77         return 1.0 / (1.0 - multiplier)
     78     else:
     79         return 1.0 + multiplier
     80 
     81 
     82 def GetCameraSensitivityMultiplier():
     83     multiplier = gfxsettings.Get(gfxsettings.UI_CAMERA_SENSITIVITY)
     84     if multiplier < 0:
     85         return 1.0 / (1.0 - multiplier)
     86     else:
     87         return 1.0 + multiplier
     88 
     89 
     90 def GetDurationByDistance(pos0, pos1, minTime = 0.3, maxTime = 1.0, k = 100000.0):
     91     dist = geo2.Vec3Distance(pos0, pos1)
     92     duration = max(minTime, min(minTime + (maxTime - minTime) * dist / k, maxTime))
     93     return duration
     94 
     95 
     96 def GetBallRadius(ball):
     97     model = GetBallModel(ball)
     98     if model and model.__bluetype__ in evespacescene.EVESPACE_TRINITY_CLASSES:
     99         rad = model.GetBoundingSphereRadius()
    100     elif model and len(getattr(model, 'children', [])) > 0:
    101         rad = model.children[0].GetBoundingSphereRadius()
    102     else:
    103         rad = None
    104     if rad is None or rad <= 0.0:
    105         rad = ball.radius * 1.1
    106     return rad
    107 
    108 
    109 def GetBallModel(ball):
    110     try:
    111         return ball.GetModel()
    112     except AttributeError:
    113         return None
    114 
    115 
    116 def GetBallPosition(ball):
    117     ballID = ball.id
    118     if not ball.ballpark:
    119         log.warning('Attempting to use position of a released ball, returning (0, 0, 0) ballID=%s\n%s', ballID, traceback.format_stack())
    120         return (0, 0, 0)
    121     else:
    122         return _GetBallPosition(ball)
    123 
    124 
    125 def _GetModelLookAtOffset(model):
    126     elpc = trinity.EveLocalPositionCurve()
    127     elpc.parent = model
    128     elpc.behavior = trinity.EveLocalPositionBehavior.centerBounds
    129     locatorSets = getattr(model, 'locatorSets', None)
    130     if locatorSets:
    131         lookAtLocator = locatorSets.FindByName('camera_look_at')
    132         if lookAtLocator is not None and len(lookAtLocator.locators) > 0:
    133             elpc.behavior = trinity.EveLocalPositionBehavior.offsetPosition
    134             elpc.positionOffset = lookAtLocator.locators[0][0]
    135     return elpc
    136 
    137 
    138 def GetModelLookAtOffset(model):
    139     offset = _GetModelLookAtOffset(model)
    140     v = offset.GetVectorAt(blue.os.GetSimTime())
    141     return (v.x, v.y, v.z)
    142 
    143 
    144 def _GetBallPosition(ball):
    145     if getattr(ball, 'model', None) and not isinstance(ball.model, trinity.EvePlanet):
    146         elpc = _GetModelLookAtOffset(ball.model)
    147         elpc.parentPositionCurve = ball
    148         elpc.parentRotationCurve = ball
    149         vec = elpc.GetVectorAt(blue.os.GetSimTime())
    150     else:
    151         vec = ball.GetVectorAt(blue.os.GetSimTime())
    152     return (vec.x, vec.y, vec.z)
    153 
    154 
    155 def GetSpeedDirection(ball):
    156     if getattr(ball, 'model', None) and hasattr(ball.model.rotationCurve, 'value'):
    157         quat = ball.model.rotationCurve.value
    158     else:
    159         quat = ball.GetQuaternionAt(blue.os.GetSimTime())
    160         quat = (quat.x,
    161          quat.y,
    162          quat.z,
    163          quat.w)
    164     return geo2.QuaternionTransformVector(quat, (0, 0, 1))
    165 
    166 
    167 def GetBall(itemID):
    168     bp = sm.GetService('michelle').GetBallpark()
    169     if not bp:
    170         return None
    171     return bp.GetBall(itemID)
    172 
    173 
    174 def GetBallWaitForModel(ballID):
    175     ball = None
    176     while ball is None:
    177         ball = GetBall(ballID)
    178         blue.synchro.Yield()
    179 
    180     while not getattr(ball, 'model', None):
    181         blue.synchro.Yield()
    182 
    183     blue.synchro.Yield()
    184     return ball
    185 
    186 
    187 def GetBallMaxZoom(ball, nearClip):
    188     rad = GetBallRadius(ball)
    189     zoomMultiplier = 1.5 * GetARZoomMultiplier(trinity.GetAspectRatio())
    190     return (rad + nearClip) * zoomMultiplier + 2
    191 
    192 
    193 def IsBallWarping(itemID):
    194     ball = GetBall(itemID)
    195     if not ball:
    196         return False
    197     return ball.mode == destiny.DSTBALL_WARP
    198 
    199 
    200 def IsAutoTrackingEnabled():
    201     return settings.char.ui.Get('orbitCameraAutoTracking', False)
    202 
    203 
    204 def IsDynamicCameraMovementEnabled():
    205     return gfxsettings.Get(gfxsettings.UI_CAMERA_DYNAMIC_CAMERA_MOVEMENT)
    206 
    207 
    208 def CheckShowModelTurrets(ball):
    209     if hasattr(ball, 'LookAtMe'):
    210         uthread.new(ball.LookAtMe)
    211 
    212 
    213 def IsNanVector3(values):
    214     for value in values:
    215         if math.isnan(value):
    216             return True
    217 
    218     return False
    219 
    220 
    221 def IsInfVector3(values):
    222     for value in values:
    223         if math.fabs(value) > 1e+38:
    224             return True
    225 
    226     return False
    227 
    228 
    229 MAX_SPACE_CAMERA_COORDINATE = 1000000000000.0
    230 
    231 def IsValidSpaceCameraPosition(values):
    232     return all((math.fabs(value) <= MAX_SPACE_CAMERA_COORDINATE for value in values))
    233 
    234 
    235 def SolveQuadratic(a, b, c):
    236     d = math.sqrt(b ** 2 - 4 * a * c)
    237     x1 = -2 * c / (b + d)
    238     x2 = -2 * c / (b - d)
    239     return max(x1, x2)
    240 
    241 
    242 def GetFullscreenProjectionViewAndViewport():
    243     viewport = trinity.device.viewport
    244     camera = sm.GetService('sceneManager').GetActiveCamera()
    245     return (camera.projectionMatrix, camera.viewMatrix, viewport)
    246 
    247 
    248 def GetInitialLookAtDistance(maxZoom, minZoom, objRadius = None):
    249     kPower = 0.95
    250     a = 1.0 / minZoom ** kPower
    251     b = FOV_MIN / 2.0
    252     r = objRadius or maxZoom
    253     r = max(objRadius, maxZoom)
    254     c = -r
    255     radius = SolveQuadratic(a, b, c)
    256     return radius
    257 
    258 
    259 def GetPixelSizeAcrossEst(position, radius, camPos, projectionMatrix):
    260     viewPort = trinity.device.viewport
    261     dist = max(geo2.Vec3Distance(position, camPos), 1e-05)
    262     ratio = radius / dist
    263     return ratio * projectionMatrix[0][0] * viewPort.width
    264 
    265 
    266 class Vector3Chaser(object):
    267 
    268     def __init__(self, speed = 1.0):
    269         self._value = (0, 0, 0)
    270         self._targetValue = None
    271         self._speed = speed
    272         self._updateTime = None
    273 
    274     def GetValue(self):
    275         if self._updateTime != blue.os.GetTime():
    276             self.Update()
    277         return self._value
    278 
    279     def SetTargetValue(self, value, speed = None):
    280         if IsNanVector3(value):
    281             log.warning('Camera: Attempting to set an invalid value: %s\n%s', repr(value), traceback.format_stack())
    282             return
    283         self._targetValue = value
    284         if speed is not None:
    285             self._speed = speed
    286 
    287     def Update(self):
    288         self._updateTime = blue.os.GetTime()
    289         if not self._targetValue or self._targetValue == self._value:
    290             return
    291         if self._speed == 0.0:
    292             return
    293         dt = 1.0 / blue.os.fps
    294         diff = geo2.Vec3Subtract(self._targetValue, self._value)
    295         prop = dt * (1.0 * self._speed)
    296         prop = min(1.0, prop)
    297         dV = geo2.Vec3Scale(diff, prop)
    298         self._value = geo2.Vec3Add(self._value, dV)
    299         if prop == 1.0:
    300             self._targetValue = None
    301 
    302     def ResetValue(self, speed = None):
    303         if speed is None:
    304             self._value = (0, 0, 0)
    305             self._targetValue = None
    306         else:
    307             self.SetTargetValue((0, 0, 0), speed)
    308 
    309 
    310 class VectorLerper(object):
    311     __notifyevents__ = ['DoSimClockRebase']
    312 
    313     def __init__(self, duration = 1.0):
    314         sm.RegisterNotify(self)
    315         self.duration = duration
    316         self.Reset()
    317 
    318     def Reset(self, duration = None):
    319         if duration:
    320             self.duration = duration
    321         self._v0 = (0, 0, 0)
    322         self._v1 = (0, 0, 0)
    323         self.startTime = blue.os.GetSimTime()
    324 
    325     def SetStartValue(self, value):
    326         self._v0 = value
    327 
    328     def GetValue(self, v0 = None, v1 = None):
    329         if v0 is None:
    330             v0 = self._v0
    331         t = self.GetTime()
    332         if self._IsTimePastDuration(t):
    333             self._v1 = v1
    334         elif hasattr(v0, '__iter__'):
    335             self._v1 = geo2.Lerp(v0, v1, t / self.duration)
    336         else:
    337             self._v1 = v0 + (v1 - v0) * t
    338         return self._v1
    339 
    340     def GetLastValue(self):
    341         return self._v1
    342 
    343     def IsDone(self):
    344         t = self.GetTime()
    345         return self._IsTimePastDuration(t)
    346 
    347     def _IsTimePastDuration(self, t):
    348         return t >= self.duration
    349 
    350     def GetTime(self):
    351         return (blue.os.GetSimTime() - self.startTime) / float(SEC)
    352 
    353     def DoSimClockRebase(self, rebaseTimes):
    354         oldSimTime, newSimTime = rebaseTimes
    355         delta = newSimTime - oldSimTime
    356         self.startTime += delta
    357 
    358 
    359 class PositionAnimatorDetached(object):
    360 
    361     def __init__(self, camera):
    362         self.camera = camera
    363         self.ball = None
    364         self.positionDiff = (0, 0, 0)
    365         self.ballPosLast = None
    366         self.SetAbstractBall()
    367 
    368     def GetAtPosition(self):
    369         return geo2.Vec3Add(self.camera._atPosition, self.positionDiff)
    370 
    371     def Update(self):
    372         if not self.ball:
    373             return
    374         ballPos = GetBallPosition(self.ball)
    375         if self.ballPosLast:
    376             self.positionDiff = geo2.Vec3SubtractD(ballPos, self.ballPosLast)
    377         self.ballPosLast = ballPos
    378 
    379     def GetEyePosition(self):
    380         return geo2.Vec3Add(self.camera._eyePosition, self.positionDiff)
    381 
    382     def _SetBall(self, ball, animate, duration):
    383         self.positionDiff = (0, 0, 0)
    384         self.ballPosLast = None
    385         self.ball = ball
    386         self.Update()
    387 
    388     def SetAbstractBall(self, animate = True, duration = 0.6):
    389         bp = self._GetBallpark()
    390         if not bp:
    391             return
    392         pos = bp.GetCurrentEgoPos()
    393         if self.ball:
    394             pos = geo2.Vec3AddD(pos, GetBallPosition(self.ball))
    395         ball = bp.AddClientSideBall(pos)
    396         self._SetBall(ball, animate, 0.0)
    397 
    398     def _GetBallpark(self):
    399         michelle = sm.GetServiceIfRunning('michelle')
    400         if not michelle:
    401             return None
    402         return michelle.GetBallpark()
    403 
    404     def IsAttached(self):
    405         return False
    406 
    407     def GetItemID(self):
    408         if self.ball:
    409             return self.ball.id
    410 
    411     def Reset(self):
    412         self._SetBall(None, False, 0)
    413 
    414 
    415 class PositionAnimatorAttached(object):
    416 
    417     def __init__(self, camera, ball, duration):
    418         self.camera = camera
    419         self.ball = ball
    420         self.atPosition = camera._atPosition
    421         self.atPositionDiff = (0, 0, 0)
    422         self.SetBall(ball, duration)
    423 
    424     def GetAtPosition(self):
    425         return self.atPosition
    426 
    427     def Update(self):
    428         if not self.ball:
    429             return (0, 0, 0)
    430         atPosLast = self.atPosition
    431         if self.GetItemID() == self.camera.ego:
    432             self.atPosition = (0, 0, 0)
    433         else:
    434             self.atPosition = GetBallPosition(self.ball)
    435         self.atPositionDiff = geo2.Vec3SubtractD(self.atPosition, atPosLast)
    436 
    437     def GetEyePosition(self):
    438         ret = self.camera._eyePosition
    439         if self.GetItemID() != session.shipid:
    440             ret = geo2.Vec3AddD(ret, self.atPositionDiff)
    441         return ret
    442 
    443     def SetBall(self, ball, duration = 0.6):
    444         self._SetBall(ball, duration)
    445 
    446     def _SetBall(self, ball, duration):
    447         self.ball = ball
    448 
    449     def GetItemID(self):
    450         if self.ball:
    451             return self.ball.id
    452 
    453     def IsAttached(self):
    454         return True
    455 
    456     def Reset(self):
    457         self._SetBall(None, 0)