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)