mapCamera.py (8618B)
1 #Embedded file name: C:\BuildAgent\work\20d73f1b24eed06e\eve\release\V24.01\eve\client\script\ui\camera\mapCamera.py 2 import math 3 import evecamera 4 import mathext 5 from carbonui.uianimations import animations 6 from eve.client.script.ui.camera.baseCamera import Camera 7 from eve.client.script.ui.camera.cameraUtil import GetDurationByDistance 8 import geo2 9 from eve.client.script.ui.shared.mapView import mapViewConst 10 from eve.client.script.ui.shared.mapView.mapViewConst import DEFAULT_MAP_EYE_Y, MAX_MAP_PAN_EYE_POS_X, MAX_MAP_PAN_EYE_POS_Z 11 from eve.client.script.ui.shared.mapView.mapViewSettings import map2dEyeDistYSetting 12 from logmodule import LogException 13 from threadutils import throttled 14 15 class MapCamera(Camera): 16 default_kMinPitch = 0.01 17 cameraID = evecamera.CAM_MAP 18 maxZoom = mapViewConst.MIN_CAMERA_DISTANCE 19 minZoom = mapViewConst.MAX_CAMERA_DISTANCE 20 default_eyePosition = (0, DEFAULT_MAP_EYE_Y, -50) 21 kOrbitSpeed = 10.0 22 kOrbitStopAngle = 0.001 23 kZoomStopDist = 0.001 24 kPanStopDist = 0.01 25 kMaxPitch = math.pi / 2 26 kMinPitch = 0.01 27 is2dCamera = False 28 29 def __init__(self): 30 Camera.__init__(self) 31 self.viewport = None 32 self._aspectRatio = 1.0 33 self.callback = None 34 self.sceneCursor = (0, 0, 0) 35 self._isAttached = True 36 self._centerOffsetEnabled = False 37 38 def Update(self): 39 Camera.Update(self) 40 if self.callback: 41 try: 42 self.callback() 43 except Exception as e: 44 LogException(e) 45 46 self._EnforceMaximumDistance() 47 48 def _EnforceMaximumDistance(self): 49 dist = geo2.Vec3Length(self.eyePosition) 50 maxDist = 2 * self.minZoom 51 if dist > maxDist: 52 direction = geo2.Vec3Normalize(self.eyePosition) 53 newEye = geo2.Vec3Scale(direction, maxDist) 54 diff = geo2.Vec3Subtract(self.eyePosition, newEye) 55 self.SetEyePosition(newEye) 56 self.SetAtPosition(geo2.Vec3Subtract(self._atPosition, diff)) 57 58 def UpdateViewportSize(self, width, height): 59 self._aspectRatio = float(width) / height 60 61 def GetAspectRatio(self): 62 return self._aspectRatio 63 64 def GetViewport(self): 65 return self.viewport 66 67 def SetViewport(self, viewport): 68 self.viewport = viewport 69 70 def SetUpdateCallback(self, callback): 71 self.callback = callback 72 73 def LookAtMarker(self, markerObject, duration = None, animate = True, zoomDistance = None): 74 atPos = markerObject.GetDisplayPosition() 75 if atPos: 76 self.LookAtPoint(atPos, duration, animate, zoomDistance) 77 78 def LookAtPoint(self, atPos, duration = None, animate = True, zoomDistance = None): 79 self.StopUpdateThreads() 80 if not self.IsAttached() and not self.is2dCamera: 81 self._ResetAtPosition(atPos) 82 eyePos = self.GetLookAtEyePosition(atPos, zoomDistance) 83 if animate: 84 if not duration: 85 duration = GetDurationByDistance(self.atPosition, atPos, 0.3, 0.6, 500) 86 self.TransitTo(atPos, eyePos, duration=duration) 87 else: 88 self.atPosition = atPos 89 self.eyePosition = eyePos 90 self._isAttached = True 91 92 def GetLookAtEyePosition(self, atPos, zoomDistance): 93 if zoomDistance: 94 diff = geo2.Vec3Scale(geo2.Vec3Normalize(self.GetLookAtDirection()), zoomDistance) 95 return geo2.Vec3Add(atPos, diff) 96 else: 97 diff = geo2.Vec3Subtract(atPos, self.atPosition) 98 return geo2.Vec3Add(self.eyePosition, diff) 99 100 def _ResetAtPosition(self, atPos): 101 distance = -geo2.Vec3Distance(self.eyePosition, atPos) 102 lookVec = geo2.Vec3Scale(self.GetLookAtDirection(), distance) 103 self.SetAtPosition(geo2.Vec3Add(self._eyePosition, lookVec)) 104 105 def Pan(self, dx = 0, dy = 0, dz = 0): 106 if self.IsAttached(): 107 self._SetDetached() 108 k = self.GetPanSpeed() 109 Camera.Pan(self, k * dx, k * dy, k * dz) 110 111 def PanAxis(self, axis, amount): 112 k = self.GetPanSpeed() 113 Camera.PanAxis(self, axis, k * amount) 114 if self.IsAttached(): 115 self._SetDetached() 116 117 def _ClampPanTarget(self): 118 panTargetValues = [] 119 for idx, value in enumerate(self.panTarget): 120 maxAllowedTargetValue, minAllowedTargetValue = self._GetMaxAndMinPanValues(idx) 121 if maxAllowedTargetValue is None: 122 panTargetValues.append(value) 123 continue 124 clampedValue = mathext.clamp(value, minAllowedTargetValue, maxAllowedTargetValue) 125 panTargetValues.append(clampedValue) 126 127 self.panTarget = geo2.Vector(panTargetValues) 128 129 def _GetMaxAndMinPanValues(self, idx): 130 if idx == 0: 131 maxPan = MAX_MAP_PAN_EYE_POS_X 132 elif idx == 2: 133 maxPan = MAX_MAP_PAN_EYE_POS_Z 134 else: 135 return (None, None) 136 eyePosForIdx = self.eyePosition[idx] 137 maxAllowedTargetValue = maxPan - eyePosForIdx 138 minAllowedTargetValue = -maxPan - eyePosForIdx 139 return (maxAllowedTargetValue, minAllowedTargetValue) 140 141 def _SetDetached(self): 142 self.StopUpdateThreads() 143 self._isAttached = False 144 self.sceneCursor = self.GetAtPosition() 145 146 def GetZoomDistanceForMap(self): 147 if self.is2dCamera: 148 return self.GetZoomDistance() 149 elif self.IsAttached(): 150 return self.GetZoomDistance() 151 else: 152 return self.GetDistanceToCursor() 153 154 def GetZoomDistance(self): 155 if self.is2dCamera and self._eyeTransitOffset: 156 currentEyePos = geo2.Vec3Add(self._eyeTransitOffset, self._eyePosition) 157 dist = geo2.Vec3Distance(currentEyePos, self.GetZoomToPoint()) 158 if not math.isinf(dist): 159 return dist 160 return super(MapCamera, self).GetZoomDistance() 161 162 def GetDistanceToCursor(self): 163 if self.is2dCamera: 164 return self.eyePosition[1] * 0.5 165 return geo2.Vec3Distance(self.eyePosition, self.sceneCursor) 166 167 def GetPanSpeed(self): 168 return 0.0001 + 0.001 * self.GetDistanceToCursor() ** 0.9 169 170 def IsAttached(self): 171 return self._isAttached 172 173 def EnableCenterOffset(self): 174 self._centerOffsetEnabled = True 175 176 def DisableCenterOffset(self): 177 self._centerOffsetEnabled = False 178 179 def GetCenterOffset(self): 180 if self._centerOffsetEnabled: 181 return self.centerOffset 182 else: 183 return 0.0 184 185 def Zoom(self, dz): 186 if self.IsInTransit(): 187 return 188 Camera.Zoom(self, dz) 189 190 def PanImmediate(self, dx, dy, dz): 191 k = self.GetPanSpeed() 192 pan = geo2.Add(geo2.Add(geo2.Scale(self.GetXAxis(), dx * k), geo2.Scale(self.GetYAxis(), dy * k)), geo2.Scale(self.GetZAxis(), dz * k)) 193 self.eyePosition = geo2.Add(self._eyePosition, pan) 194 self.atPosition = geo2.Add(self._atPosition, pan) 195 196 def OrbitImmediate(self, yaw, pitch): 197 self.pitch = self.pitch + pitch 198 self.yaw = self.yaw + yaw 199 self.StopOrbitUpdate() 200 201 def SetEyePosition(self, value): 202 super(MapCamera, self).SetEyePosition(value) 203 self.RecordEyeDist() 204 205 @throttled(1.5) 206 def RecordEyeDist(self): 207 if self.is2dCamera: 208 eyePos = self.GetEyePosition() 209 if eyePos and eyePos[1] > 0: 210 map2dEyeDistYSetting.set(eyePos[1]) 211 212 def Make2DCamera(self): 213 self.kMinPitch = 0.005 214 self.is2dCamera = True 215 self.StopUpdateThreads() 216 if self.yaw < -math.pi: 217 newYaw = -2 * math.pi 218 else: 219 newYaw = 0.0 220 yawDiff = self.yaw - newYaw 221 pitchDiff = self.pitch - self.kMinPitch 222 if abs(yawDiff) > 0.2 or abs(pitchDiff) > 0.1: 223 duration = 1.0 224 else: 225 duration = 0.1 226 animations.MorphScalar(self, 'yaw', self.yaw, newYaw, duration=duration) 227 animations.MorphScalar(self, 'pitch', self.pitch, self.kMinPitch, duration=duration, sleep=True) 228 self.SetMinMaxZoom(mapViewConst.MAX_CAMERA_DISTANCE_2DVIEW, mapViewConst.MIN_CAMERA_DISTANCE_2DVIEW) 229 self.EnforceMaxZoom() 230 self.EnforceMinZoom() 231 232 def Make3DCamera(self): 233 self.kMinPitch = self.default_kMinPitch 234 self.is2dCamera = False 235 self.SetMinMaxZoom(mapViewConst.MAX_CAMERA_DISTANCE, 1) 236 self.EnforceMinZoom() 237 self.EnforceMaxZoom() 238 239 def Orbit(self, dx = 0, dy = 0): 240 if self.is2dCamera: 241 return 242 return super(MapCamera, self).Orbit(dx, dy)