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

directionalScanHandler.py (15838B)


      1 #Embedded file name: C:\BuildAgent\work\20d73f1b24eed06e\eve\release\V24.01\eve\client\script\ui\inflight\scannerFiles\directionalScanHandler.py
      2 import math
      3 import weakref
      4 import blue
      5 import geo2
      6 from eve.client.script.environment import nodemanager
      7 import evecamera
      8 import trinity
      9 import uthread
     10 from carbon.common.script.util.mathCommon import GetLesserAngleBetweenYaws
     11 from carbonui.uianimations import animations
     12 from eve.client.script.ui.inflight.scannerFiles.directionalScanUtil import SCANMODE_CAMERA, IsDscanConeShown, GetScanAngle
     13 from eve.client.script.ui.inflight.scannerFiles.scannerUtil import COLOR_DSCAN
     14 from eve.client.script.ui.shared.mapView import mapViewUtil
     15 from eve.client.script.ui.shared.mapView.dockPanelConst import DOCKPANELID_SOLARSYSTEMMAP
     16 from eve.client.script.ui.shared.mapView.mapViewUtil import CreatePlanarLineSet
     17 from eve.common.lib.appConst import AU
     18 from carbonui.uicore import uicore
     19 LINE_WIDTH = 3500.0
     20 MAX_SCANRANGE = 14.3 * const.AU
     21 CONE_ROTATION_SPEED = math.pi / 2
     22 CAMERAUPDATE_MAP_TO_SPACE = 1
     23 CAMERAUPDATE_SPACE_TO_MAP = 2
     24 TR2TM_NONE = 0
     25 TR2TM_LOOK_AT_CAMERA = 3
     26 
     27 class MapViewDirectionalScanHandler(object):
     28     __notifyevents__ = ['OnDirectionalScannerRangeChanged',
     29      'OnDirectionalScannerAngleChanged',
     30      'OnDirectionalScannerScanModeChanged',
     31      'OnDirectionalScannerShowCone',
     32      'OnDirectionalScanComplete']
     33     _systemMapHandler = None
     34     lineSetScaling = 1000000.0
     35     debugLineSet = None
     36     dScanTransform = None
     37     dScanSubTransform = None
     38     dScanLineSet = None
     39 
     40     def __init__(self, systemMapHandler):
     41         self.systemMapHandler = systemMapHandler
     42         sm.RegisterNotify(self)
     43         self.viewStateService = sm.GetService('viewState')
     44         self.sceneManager = sm.GetService('sceneManager')
     45         self.scanRange = settings.user.ui.Get('dir_scanrange', MAX_SCANRANGE / 1000.0) * 1000.0
     46         self.scanMode = None
     47         self.scanAngle = math.degrees(GetScanAngle())
     48         self.coneLineSets = []
     49         self.scanConeTransform = None
     50         self.scanConeHalfTransform = None
     51         self.scanConeFullTransform = None
     52         self._isConstructing = False
     53         uthread.new(self.DrawDirectionalScanCone)
     54 
     55     def StopHandler(self):
     56         sm.UnregisterNotify(self)
     57         if self.dScanTransform:
     58             uicore.animations.MorphVector3(self.dScanTransform, 'scaling', startVal=self.dScanTransform.scaling, endVal=(0, 0, 0), duration=0.2, callback=self._RemoveFromScene)
     59         else:
     60             self._RemoveFromScene()
     61 
     62     def ScanEffect(self):
     63         if not all((self.scanConeTransform, self.scanConeHalfTransform, self.scanConeFullTransform)):
     64             return
     65         scanLinesCurveSet = nodemanager.FindNode(self.scanConeTransform, 'ScanPart_01', 'trinity.TriCurveSet')
     66         if scanLinesCurveSet:
     67             duration = scanLinesCurveSet.GetMaxCurveDuration()
     68             scanLinesCurveSet.Play()
     69             scanLinesCurveSet.StopAfterWithCallback(duration, self._ScanEffectReturn)
     70         scanLinesCurveSet = nodemanager.FindNode(self.scanConeHalfTransform, 'ScanPart_01', 'trinity.TriCurveSet')
     71         if scanLinesCurveSet:
     72             duration = scanLinesCurveSet.GetMaxCurveDuration()
     73             scanLinesCurveSet.Play()
     74             scanLinesCurveSet.StopAfterWithCallback(duration, self._ScanEffectHalfReturn)
     75         scanLinesCurveSet = nodemanager.FindNode(self.scanConeFullTransform, 'ScanPart_01', 'trinity.TriCurveSet')
     76         if scanLinesCurveSet:
     77             duration = scanLinesCurveSet.GetMaxCurveDuration()
     78             scanLinesCurveSet.Play()
     79             scanLinesCurveSet.StopAfterWithCallback(duration, self._ScanEffectFullReturn)
     80 
     81     def _ScanEffectReturn(self):
     82         scanLinesCurveSet = nodemanager.FindNode(self.scanConeTransform, 'ScanPart_02', 'trinity.TriCurveSet')
     83         if scanLinesCurveSet:
     84             scanLinesCurveSet.Play()
     85 
     86     def _ScanEffectHalfReturn(self):
     87         scanLinesCurveSet = nodemanager.FindNode(self.scanConeHalfTransform, 'ScanPart_02', 'trinity.TriCurveSet')
     88         if scanLinesCurveSet:
     89             scanLinesCurveSet.Play()
     90 
     91     def _ScanEffectFullReturn(self):
     92         scanLinesCurveSet = nodemanager.FindNode(self.scanConeFullTransform, 'ScanPart_02', 'trinity.TriCurveSet')
     93         if scanLinesCurveSet:
     94             scanLinesCurveSet.Play()
     95 
     96     def _RemoveFromScene(self):
     97         if self.systemMapHandler:
     98             if self.dScanTransform in self.systemMapHandler.systemMapTransform.children:
     99                 self.systemMapHandler.systemMapTransform.children.remove(self.dScanTransform)
    100         self.dScanTransform = None
    101         self.dScanSubTransform = None
    102         self.dScanUpdateTimer = None
    103         self.systemMapHandler = None
    104 
    105     def GetPosition(self):
    106         if self.dScanTransform:
    107             return self.dScanTransform.translation
    108 
    109     def OnDirectionalScannerRangeChanged(self, scanRange):
    110         self.scanRange = scanRange
    111         self.DrawDirectionalScanCone()
    112 
    113     def OnDirectionalScannerAngleChanged(self, scanAngle):
    114         self.scanAngle = math.degrees(scanAngle)
    115         self.DrawDirectionalScanCone()
    116 
    117     def OnDirectionalScannerScanModeChanged(self, newScanMode):
    118         if newScanMode != self.scanMode:
    119             self.scanMode = newScanMode
    120             self.DrawDirectionalScanCone()
    121             if newScanMode == SCANMODE_CAMERA:
    122                 self._SetScanModeCamera()
    123             self.OnCameraUpdate()
    124 
    125     def _SetScanModeCamera(self):
    126         endRotation = self.GetSystemMapCameraRotation()
    127         duration = self.GetRotationDurationFromQuaternions(self.dScanTransform.rotation, endRotation)
    128         self.systemMapHandler.mapView.LookAtEgoMarker(duration)
    129         animations.MorphQuaternion(self.dScanTransform, 'rotation', startVal=self.dScanTransform.rotation, endVal=endRotation, duration=duration)
    130 
    131     def OnDirectionalScannerShowCone(self, displayState):
    132         if self.dScanSubTransform:
    133             self.dScanSubTransform.display = displayState
    134 
    135     def OnDirectionalScanComplete(self, *args):
    136         self.ScanEffect()
    137 
    138     def GetSystemMapCamera(self):
    139         return self.systemMapHandler.mapView.camera
    140 
    141     def GetSystemMapCameraRotation(self):
    142         camera = self.GetSystemMapCamera()
    143         return camera.GetRotationQuat()
    144 
    145     def GetSpaceCameraViewVector(self):
    146         spaceCamera = self.GetSpaceCamera()
    147         return spaceCamera.GetLookAtDirection()
    148 
    149     def GetPointOfInterestOverride(self):
    150         return self.dScanTransform.worldTransform[3][:3]
    151 
    152     def SetScanTarget(self, scanVector):
    153         oldScanVector = self.GetSpaceCameraViewVector()
    154         animations.StopAnimation(self.dScanTransform, 'rotation')
    155         duration = self.GetRotationDurationFromVectors(oldScanVector, scanVector)
    156         self.AlignSpaceCameraToViewVector(scanVector, duration)
    157 
    158     @apply
    159     def spaceCameraOrbit():
    160 
    161         def fget(self):
    162             spaceCamera = self.GetSpaceCamera()
    163             return (spaceCamera.GetYaw(), spaceCamera.GetPitch())
    164 
    165         def fset(self, yaw_pitch):
    166             y, p = yaw_pitch
    167             spaceCamera = self.GetSpaceCamera()
    168             spaceCamera.SetYaw(y)
    169             spaceCamera.SetPitch(p)
    170 
    171         return property(**locals())
    172 
    173     @apply
    174     def systemMapHandler():
    175 
    176         def fget(self):
    177             if self._systemMapHandler:
    178                 return self._systemMapHandler()
    179 
    180         def fset(self, value):
    181             if value:
    182                 self._systemMapHandler = weakref.ref(value)
    183             else:
    184                 self._systemMapHandler = None
    185 
    186         return property(**locals())
    187 
    188     def DrawDirectionalScanCone(self):
    189         if self._isConstructing or not self.systemMapHandler:
    190             return
    191         scanAngle = self.scanAngle
    192         scanRange = float(self.scanRange)
    193         if self.dScanLineSet is None:
    194             self._ConstructConesAndLines()
    195         self.dScanLineSet.ClearLines()
    196         self.scanConeHalfTransform.display = False
    197         self.scanConeFullTransform.display = False
    198         self.scanConeTransform.display = False
    199         if scanAngle < 180.0:
    200             self.ShowCone(scanAngle, scanRange)
    201         elif scanAngle < 360.0:
    202             self.ShowHalfSphere(scanRange)
    203         else:
    204             self.ShowSphere(scanRange)
    205         self.dScanLineSet.SubmitChanges()
    206 
    207     def _ConstructConesAndLines(self):
    208         self._isConstructing = True
    209         self._ConstructCones()
    210         self._ConstructLineSet()
    211         blue.synchro.Yield()
    212         self._isConstructing = False
    213 
    214     def ShowSphere(self, scanRange):
    215         self.scanConeFullTransform.scaling = (-scanRange, -scanRange, -scanRange)
    216         self.scanConeFullTransform.display = True
    217 
    218     def ShowHalfSphere(self, scanRange):
    219         self.scanConeHalfTransform.scaling = (-scanRange, -scanRange, -scanRange)
    220         self.scanConeHalfTransform.display = True
    221 
    222     def ShowCone(self, scanAngle, scanRange):
    223         scanAngleRad = math.radians(scanAngle)
    224         scanAngleCos = math.cos(scanAngleRad * 0.5)
    225         centerLineDistance = AU
    226         while centerLineDistance < scanRange:
    227             step = centerLineDistance * scanAngleCos
    228             radius = math.tan(scanAngleRad * 0.5) * step
    229             mapViewUtil.DrawCircle(self.dScanLineSet, (0, step / self.lineSetScaling, 0), radius / self.lineSetScaling, arcSegments=2, lineWidth=LINE_WIDTH, startColor=COLOR_DSCAN, endColor=COLOR_DSCAN)
    230             centerLineDistance += 2 * AU
    231 
    232         self.DrawConeSphereLineSegments(scanAngleRad, scanRange)
    233         z = scanRange * scanAngleCos
    234         endCapAngle = scanAngleRad * 0.5
    235         radius = scanRange * math.sin(endCapAngle)
    236         self.scanConeTransform.scaling = (radius * 2, z, radius * 2)
    237         self.scanConeTransform.display = True
    238 
    239     def DrawConeSphereLineSegments(self, scanAngleRad, scanRange):
    240         pCenter = (0, scanRange / self.lineSetScaling, 0)
    241         mat = geo2.MatrixRotationZ(scanAngleRad * 0.45)
    242         p1 = geo2.Vec3Transform(pCenter, mat)
    243         mat = geo2.MatrixRotationZ(scanAngleRad * 0.25)
    244         p2 = geo2.Vec3Transform(pCenter, mat)
    245         mat = geo2.MatrixRotationZ(scanAngleRad * 0.04)
    246         p3 = geo2.Vec3Transform(pCenter, mat)
    247         lineWidth = LINE_WIDTH * scanAngleRad * 3.0 * (scanRange / MAX_SCANRANGE)
    248         numSegments = 8
    249         for i in xrange(numSegments):
    250             self.DrawSpheredLineRotated(p1, p2, p3, float(i) / numSegments, lineWidth)
    251 
    252     def DrawSpheredLineRotated(self, p1, p2, p3, angle, lineWidth):
    253         mat = geo2.MatrixRotationY(angle * 2 * math.pi)
    254         p1 = geo2.Vec3Transform(p1, mat)
    255         p2 = geo2.Vec3Transform(p2, mat)
    256         p3 = geo2.Vec3Transform(p3, mat)
    257         self.dScanLineSet.AddSpheredLineCrt(p1, (0, 0, 0, 0), p2, COLOR_DSCAN, (0, 0, 0), lineWidth)
    258         self.dScanLineSet.AddSpheredLineCrt(p2, COLOR_DSCAN, p3, (0, 0, 0, 0), (0, 0, 0), lineWidth)
    259 
    260     def _ConstructCones(self):
    261         self.dScanTransform = trinity.EveTransform()
    262         self.dScanTransform.name = 'dScanTransform'
    263         self.systemMapHandler.systemMapTransform.children.append(self.dScanTransform)
    264         self.systemMapHandler.SetupMyPositionTracker(self.dScanTransform)
    265         self.dScanSubTransform = trinity.EveTransform()
    266         self.dScanSubTransform.name = 'dScanSubTransform'
    267         self.dScanSubTransform.display = IsDscanConeShown()
    268         self.dScanTransform.children.append(self.dScanSubTransform)
    269         self.scanConeTransform = trinity.Load('res:/dx9/model/UI/scancone.red')
    270         self.scanConeTransform.rotation = geo2.QuaternionRotationSetYawPitchRoll(0.0, -math.pi / 2, 0.0)
    271         self.dScanSubTransform.children.append(self.scanConeTransform)
    272         self.scanConeHalfTransform = trinity.Load('res:/dx9/model/UI/scanconehalfsphere.red')
    273         self.dScanSubTransform.children.append(self.scanConeHalfTransform)
    274         self.scanConeFullTransform = trinity.Load('res:/dx9/model/UI/scanconesphere.red')
    275         self.dScanSubTransform.children.append(self.scanConeFullTransform)
    276 
    277     def _ConstructLineSet(self):
    278         self.dScanLineSet = CreatePlanarLineSet(texturePath='res:/dx9/texture/ui/linePlanarSmoothAdditive.dds')
    279         self.dScanLineSet.scaling = (self.lineSetScaling, self.lineSetScaling, self.lineSetScaling)
    280         self.dScanLineSet.rotation = geo2.QuaternionRotationSetYawPitchRoll(0.0, -math.pi / 2, 0.0)
    281         self.dScanLineSet.additive = True
    282         self.dScanSubTransform.children.append(self.dScanLineSet)
    283 
    284     def GetSpaceCamera(self):
    285         cam = self.sceneManager.GetActiveSpaceCamera()
    286         if cam is None or cam.cameraID == evecamera.CAM_JUMP:
    287             return
    288         return cam
    289 
    290     def OnCameraUpdate(self):
    291         if not self.dScanTransform or not self.GetSpaceCamera():
    292             return
    293         isAnimatingCone = animations.IsAnimating(self.dScanTransform, 'rotation')
    294         if self.scanMode == SCANMODE_CAMERA:
    295             isDscanShortcutActive = uicore.cmd.IsCombatCommandLoaded('CmdRefreshDirectionalScan')
    296             isMapActive = self.IsSolarSystemMapActive()
    297             if not isDscanShortcutActive and (isMapActive or isAnimatingCone):
    298                 viewVector = self.GetConeDirection()
    299                 if viewVector:
    300                     self.AlignSpaceCameraToViewVector(viewVector)
    301             else:
    302                 viewVector = self.GetSpaceCameraViewVector()
    303                 mapCamera = self.GetSystemMapCamera()
    304                 mapCamera.SetViewVector(viewVector)
    305             rotation = self.GetSystemMapCameraRotation()
    306         else:
    307             spaceCamera = self.GetSpaceCamera()
    308             rotation = spaceCamera.GetRotationQuat()
    309         if not isAnimatingCone:
    310             self.SetConeRotation(rotation)
    311 
    312     def GetConeDirection(self):
    313         quat = self.GetConeRotation()
    314         if quat:
    315             return geo2.QuaternionTransformVector(quat, (0, 0, 1))
    316 
    317     def IsSolarSystemMapActive(self):
    318         wnd = uicore.registry.GetActive()
    319         return wnd and wnd.name == DOCKPANELID_SOLARSYSTEMMAP
    320 
    321     def SetConeRotation(self, rotation):
    322         self.dScanTransform.rotation = rotation
    323 
    324     def GetConeRotation(self):
    325         if self.dScanTransform:
    326             return self.dScanTransform.rotation
    327 
    328     def AlignSpaceCameraToViewVector(self, viewVector, duration = None, callback = None, sleep = False):
    329         yaw1, pitch1 = self.GetYawPitchFromDirection(viewVector)
    330         cam = self.GetSpaceCamera()
    331         if duration:
    332             yaw0 = cam.GetYaw()
    333             pitch0 = cam.GetPitch()
    334             yawDiff = GetLesserAngleBetweenYaws(yaw0, yaw1)
    335             yaw1 = yaw0 + yawDiff
    336             animations.MorphScalar(cam, 'yaw', yaw0, yaw1, duration=duration)
    337             animations.MorphScalar(cam, 'pitch', pitch0, pitch1, duration=duration)
    338         else:
    339             animations.StopAnimation(cam, 'yaw')
    340             animations.StopAnimation(cam, 'pitch')
    341             cam.yaw = yaw1
    342             cam.pitch = pitch1
    343 
    344     def GetYawPitchFromDirection(self, viewVector):
    345         viewVector = geo2.Vec3Negate(viewVector)
    346         rotation = geo2.QuaternionRotationArc((0, 0, 1), viewVector)
    347         y, p, _ = geo2.QuaternionRotationGetYawPitchRoll(rotation)
    348         p = -p + math.pi / 2
    349         return (y, p)
    350 
    351     def GetRotationDurationFromVectors(self, startVec, endVec):
    352         dotProduct = geo2.Vec3Dot(startVec, endVec)
    353         try:
    354             angle = math.acos(dotProduct)
    355         except ValueError:
    356             angle = 0.5
    357 
    358         minTime = 0.2
    359         maxTime = 0.5
    360         return max(minTime, min(minTime + (maxTime - minTime) * angle / CONE_ROTATION_SPEED, maxTime))
    361 
    362     def GetRotationDurationFromQuaternions(self, startRotation, endRotation):
    363         startVec = geo2.QuaternionTransformVector(startRotation, (0, 0, 1))
    364         endVec = geo2.QuaternionTransformVector(endRotation, (0, 0, 1))
    365         return self.GetRotationDurationFromVectors(startVec, endVec)