scenecontainer.py (22543B)
1 #Embedded file name: C:\BuildAgent\work\20d73f1b24eed06e\eve\release\V24.01\eve\client\script\ui\control\scenecontainer.py 2 import logging 3 import blue 4 import geo2 5 import locks 6 import math 7 import trinity 8 from carbon.common.lib import bitmapjob 9 from carbonui import uiconst 10 from carbonui.control.window import Window 11 from carbonui.primitives.base import Base 12 from carbonui.primitives.container import Container 13 from carbonui.primitives.frame import Frame 14 from carbonui.uicore import uicore 15 from carbonui.util.various_unsorted import GetWindowAbove 16 from eve.client.script.ui.camera.baseCamera import Camera 17 from eve.client.script.ui.camera.cameraUtil import GetCameraSensitivityMultiplier 18 from eve.client.script.ui.camera.sceneContainerCamera import SceneContainerCamera 19 from signals import Signal 20 STENCIL_MAP_DEFAULT = 'res:/UI/Texture/circleStencil.dds' 21 STENCIL_MAP_NONE = '' 22 log = logging.getLogger(__name__) 23 24 class SceneContainer(Base): 25 __guid__ = 'form.SceneContainer' 26 __renderObject__ = trinity.Tr2Sprite2dRenderJob 27 __notifyevents__ = ['ProcessWindowUnstacked', 'ProcessWindowStacked'] 28 default_minZoom = 10.0 29 default_maxZoom = 3000.0 30 31 def ApplyAttributes(self, attributes): 32 self.viewport = trinity.TriViewport() 33 self.viewport.x = 0 34 self.viewport.y = 0 35 self.viewport.width = 1 36 self.viewport.height = 1 37 self.viewport.minZ = 0.0 38 self.viewport.maxZ = 1.0 39 self.projection = trinity.TriProjection() 40 self.bracketCurveSet = trinity.TriCurveSet() 41 self.renderJob = None 42 self.frontClip = 1.0 43 self.backClip = 350000.0 44 self.fov = 1.0 45 self.minPitch = None 46 self.maxPitch = None 47 self.scene = None 48 self.offscreen = False 49 self.PrepareCamera() 50 self._reloadLock = locks.Lock() 51 Base.ApplyAttributes(self, attributes) 52 self.minZoom = attributes.Get('minZoom', self.default_minZoom) 53 self.maxZoom = attributes.Get('maxZoom', self.default_maxZoom) 54 sm.RegisterNotify(self) 55 56 def ProcessWindowStacked(self, wnd, stack): 57 if GetWindowAbove(self) == wnd: 58 wnd.UnregisterSceneContainer(self) 59 stack.RegisterSceneContainer(self) 60 61 def ProcessWindowUnstacked(self, wnd, stack): 62 if GetWindowAbove(self) == wnd: 63 stack.UnregisterSceneContainer(self) 64 wnd.RegisterSceneContainer(self) 65 66 def SetParent(self, parent, idx = None): 67 Base.SetParent(self, parent, idx) 68 wnd = GetWindowAbove(self) 69 if wnd: 70 stack = wnd.GetStack() 71 if stack: 72 stack.RegisterSceneContainer(self) 73 else: 74 wnd.RegisterSceneContainer(self) 75 76 def Startup(self, *args): 77 self.DisplayScene() 78 79 def PrepareSpaceScene(self, maxPitch = None, scenePath = None, offscreen = False, resetZoom = True): 80 self.offscreen = offscreen 81 if scenePath is None: 82 self.scene = trinity.EveSpaceScene() 83 else: 84 self.scene = trinity.Load(scenePath) 85 self.frontClip = 1.0 86 self.backClip = 400000.0 87 self.fov = 1.0 88 self.minPitch = None 89 self.maxPitch = maxPitch 90 self.SetupCamera(resetZoom=resetZoom) 91 self.DisplaySpaceScene() 92 93 def CreateBracketCurveSet(self): 94 self.bracketCurveSet.Play() 95 if self.bracketCurveSet not in self.scene.curveSets: 96 self.scene.curveSets.append(self.bracketCurveSet) 97 98 def PrepareInteriorScene(self, backgroundImage = None, useShadows = True, shadowResolution = 1024, startOpacity = 1.0, sceneFile = None): 99 if not sceneFile: 100 sceneFile = 'res:/Graphics/Interior/characterCreation/Preview.red' 101 self.scene = trinity.Load(sceneFile) 102 self.scene.renderShadows = useShadows 103 self.scene.shadowSize = shadowResolution 104 self.frontClip = 0.1 105 self.backClip = 10.0 106 self.fov = 0.3 107 self.minPitch = -0.6 + math.pi / 2 108 self.maxPitch = 0.6 + math.pi / 2 109 self.SetupCamera() 110 blue.resMan.Wait() 111 self.DisplayInteriorScene(backgroundImage=backgroundImage, startOpacity=startOpacity) 112 113 def PrepareCharacterCreationScene(self): 114 self.scene = trinity.Load('res:/Graphics/Interior/characterCreation/Preview.red') 115 self.scene.shadowSize = 512 116 blue.resMan.Wait() 117 118 def SetupCamera(self, resetZoom = True): 119 if self.destroyed: 120 return 121 self.camera.nearClip = self.frontClip 122 self.camera.farClip = self.backClip 123 self.camera.fov = self.fov 124 if resetZoom or not 0.0 <= self.camera.GetZoomLinear() <= 1.0: 125 self.camera.SetZoomLinear(0.5) 126 self.camera.kMinPitch = self.minPitch if self.minPitch is not None else Camera.kMinPitch 127 self.camera.kMaxPitch = self.maxPitch if self.maxPitch is not None else Camera.kMaxPitch 128 129 def PrepareCamera(self): 130 self.camera = SceneContainerCamera() 131 self.camera.OnActivated() 132 133 def DisplaySpaceScene(self, blendMode = None): 134 from trinity.sceneRenderJobSpaceEmbedded import CreateEmbeddedRenderJobSpace 135 self.renderJob = CreateEmbeddedRenderJobSpace() 136 if self.destroyed: 137 return 138 rj = self.renderJob 139 rj.CreateBasicRenderSteps() 140 self.CreateBracketCurveSet() 141 rj.SetActiveCamera(view=self.camera.viewMatrix, projection=self.camera.projectionMatrix) 142 rj.SetCameraProjection(self.camera.projectionMatrix) 143 rj.SetCameraView(self.camera.viewMatrix) 144 rj.SetScene(self.scene) 145 rj.SetViewport(self.viewport) 146 if not self.viewport: 147 return 148 sm.GetService('sceneManager').RegisterJob(rj) 149 try: 150 rj.DoPrepareResources() 151 except trinity.ALError: 152 pass 153 154 if blendMode: 155 step = trinity.TriStepSetStdRndStates() 156 step.renderingMode = blendMode 157 rj.AddStep('SET_BLENDMODE', step) 158 rj.Enable(False) 159 rj.SetSettingsBasedOnPerformancePreferences() 160 if self and not self.destroyed: 161 self.renderObject.renderJob = self.renderJob 162 163 def DisplayScene(self, addClearStep = False, addBitmapStep = False, backgroundImage = None): 164 self.renderJob = trinity.CreateRenderJob('SceneInScene') 165 self.renderJob.SetViewport(self.viewport) 166 self.renderJob.SetProjection(self.camera.projectionMatrix) 167 self.renderJob.SetView(self.camera.viewMatrix) 168 self.renderJob.Update(self.scene) 169 if addClearStep: 170 self.renderJob.Clear(None, 1.0) 171 if addBitmapStep: 172 if backgroundImage is None: 173 backgroundImage = 'res:/UI/Texture/preview/asset_preview_background.png' 174 step = bitmapjob.makeBitmapStep(backgroundImage, scaleToFit=False, color=(1.0, 1.0, 1.0, 1.0)) 175 self.renderJob.steps.append(step) 176 self.renderJob.RenderScene(self.scene) 177 self.renderObject.renderJob = self.renderJob 178 179 def DisplayInteriorScene(self, backgroundImage = None, startOpacity = 1.0): 180 from trinity.sceneRenderJobCharacters import CreateSceneRenderJobCharacters 181 self.renderJob = CreateSceneRenderJobCharacters('SceneInScene') 182 self.renderJob.SetStartOpacity(startOpacity) 183 self.renderJob.CreateBasicRenderSteps() 184 self.renderJob.SetScene(self.scene) 185 while self.viewport.width == 1 or self.viewport.height == 1: 186 blue.synchro.Yield() 187 188 if backgroundImage: 189 step = bitmapjob.makeBitmapStep(backgroundImage, scaleToFit=False, color=(1.0, 1.0, 1.0, 1.0), targetSize=(self.viewport.width, self.viewport.height)) 190 self.renderJob.AddStep('RENDER_BACKDROP', step) 191 self.renderJob.EnableScatter(False) 192 self.renderJob.EnableSculpting(False) 193 self.renderJob.SetViewport(self.viewport) 194 self.renderJob.SetSettingsBasedOnPerformancePreferences() 195 self.renderJob.Enable(False) 196 self.renderJob.SetCameraProjection(self.camera.projectionMatrix) 197 self.renderJob.SetCameraView(self.camera.viewMatrix) 198 self.renderObject.renderJob = self.renderJob 199 200 def SetStencilMap(self, path = STENCIL_MAP_DEFAULT): 201 if hasattr(self.renderJob, 'SetStencil'): 202 self.renderJob.SetStencil(path) 203 204 def AddToScene(self, model, clear = 1): 205 if model is None: 206 log.warning('SceneContainer: Trying to load a None model to the scene') 207 return 208 if self.scene is None: 209 log.warning('SceneContainer: Trying to load a model to a None scene') 210 return 211 if clear: 212 del self.scene.objects[:] 213 self.scene.objects.append(model) 214 log.info('SceneContainer: Model added to scene') 215 self.scene.UpdateScene(blue.os.GetSimTime()) 216 log.info('SceneContainer: Scene updated') 217 218 def RemoveFromScene(self, model): 219 self.scene.objects.remove(model) 220 log.info('SceneContainer: Model added to scene') 221 self.scene.UpdateScene(blue.os.GetSimTime()) 222 log.info('SceneContainer: Scene updated') 223 224 def ClearScene(self): 225 self.scene.UpdateScene(blue.os.GetSimTime()) 226 del self.scene.objects[:] 227 228 def _OnResize(self): 229 self.UpdateViewPort() 230 231 def UpdateViewPort(self, *args): 232 l, t, w, h = self.GetAbsoluteViewport() 233 if not h: 234 return 235 if not self.offscreen: 236 l = uicore.ScaleDpi(l) 237 t = uicore.ScaleDpi(t) 238 w = uicore.ScaleDpi(w) 239 h = uicore.ScaleDpi(h) 240 self.viewport.x = l 241 self.viewport.y = t 242 self.viewport.width = w 243 self.viewport.height = h 244 self.camera.UpdateViewportSize(w, h) 245 if hasattr(self.renderJob, 'UpdateViewport'): 246 self.renderJob.UpdateViewport(self.viewport) 247 248 def OnResize_(self, k, v): 249 self.UpdateViewPort() 250 251 def UpdateAlignment(self, *args): 252 ret = Base.UpdateAlignment(self, *args) 253 self.UpdateViewPort() 254 return ret 255 256 def _OnClose(self, *args): 257 with self._reloadLock: 258 self.clearStep = None 259 self.viewport = None 260 self.projection = None 261 if self.camera: 262 self.camera.OnDeactivated() 263 self.camera = None 264 self.scene = None 265 if hasattr(self.renderJob, 'Disable'): 266 self.renderJob.Disable() 267 self.renderJob = None 268 269 def AnimEntry(self, yaw0 = 1.1 * math.pi, pitch0 = 0.0, yaw1 = 1.25 * math.pi, pitch1 = -0.5, duration = 2.0): 270 if self.destroyed: 271 return 272 self.camera.StopUpdateThreads() 273 pitch0 = self._ConvertPitch(pitch0) 274 pitch1 = self._ConvertPitch(pitch1) 275 uicore.animations.MorphScalar(self, 'zoom', 1.0, self.zoom, duration=duration) 276 uicore.animations.MorphScalar(self.camera, 'yaw', yaw0, yaw1, duration=duration) 277 uicore.animations.MorphScalar(self.camera, 'pitch', pitch0, pitch1, duration=duration) 278 279 def _ConvertPitch(self, pitch): 280 return math.pi / 2 - pitch 281 282 def GetOrbit(self): 283 return (0.0, 0.0) 284 285 def SetOrbit(self, yaw, pitch): 286 self.camera.SetYaw(yaw) 287 self.camera.SetPitch(pitch) 288 289 orbit = property(GetOrbit, SetOrbit) 290 291 def OrbitParent(self, dx, dy): 292 self.StopAnimations() 293 fov = self.camera.fov 294 cameraSpeed = 0.02 295 self.camera.Orbit(dx * fov * cameraSpeed, dy * fov * cameraSpeed) 296 297 def GetZoom(self): 298 if self.camera: 299 return self.camera.GetZoomLinear() 300 else: 301 return 0.0 302 303 def SetZoom(self, value): 304 if self.camera: 305 self.camera.SetZoomLinear(value) 306 307 zoom = property(GetZoom, SetZoom) 308 309 def SetMinMaxZoom(self, minZoom, maxZoom): 310 self.camera.minZoom = maxZoom 311 self.camera.maxZoom = minZoom 312 313 def Zoom(self, dz): 314 self.StopAnimations() 315 self.camera.Zoom(dz) 316 317 318 class SceneWindowTest(Window): 319 __guid__ = 'form.SceneWindowTest' 320 321 def ApplyAttributes(self, attributes): 322 Window.ApplyAttributes(self, attributes) 323 sc = SceneContainer(Frame(parent=self.sr.main, padding=(6, 6, 6, 6), color=(1.0, 1.0, 1.0, 0.5))) 324 sc.Startup() 325 nav = SceneContainerBaseNavigation(Container(parent=self.sr.main, left=6, top=6, width=6, height=6, idx=0, state=uiconst.UI_NORMAL)) 326 nav.Startup(sc) 327 self.sr.navigation = nav 328 self.sr.sceneContainer = sc 329 330 def OnResizeUpdate(self, *args): 331 self.sr.sceneContainer.UpdateViewPort() 332 333 334 class SceneContainerBaseNavigation(Container): 335 __guid__ = 'form.SceneContainerBaseNavigation' 336 isTabStop = 1 337 on_zoom = Signal('on_zoom') 338 on_drop_data = Signal('on_drop_data') 339 on_mouse_down = Signal('on_mouse_down') 340 on_mouse_up = Signal('on_mouse_down') 341 on_dbl_click = Signal('on_dbl_click') 342 343 def Startup(self, sceneContainer): 344 self.sr.sceneContainer = sceneContainer 345 self.sr.cookie = uicore.event.RegisterForTriuiEvents(uiconst.UI_MOUSEUP, self._OnGlobalMouseUp) 346 self.sr.cookie2 = uicore.event.RegisterForTriuiEvents(uiconst.UI_MOUSEDOWN, self._OnGlobalMouseDown) 347 348 def _OnClose(self, *args): 349 if self.sr.cookie: 350 uicore.event.UnregisterForTriuiEvents(self.sr.cookie) 351 self.sr.cookie = None 352 if self.sr.cookie2: 353 uicore.event.UnregisterForTriuiEvents(self.sr.cookie2) 354 self.sr.cookie2 = None 355 356 def SetMinMaxZoom(self, minZoom, maxZoom): 357 self.sr.sceneContainer.SetMinMaxZoom(minZoom, maxZoom) 358 359 def OnMouseWheel(self, *args): 360 modifier = uicore.mouseInputHandler.GetCameraZoomModifier() 361 self.sr.sceneContainer.Zoom(modifier * uicore.uilib.dz * 0.001) 362 363 def OnMouseMove(self, *args): 364 if self.destroyed or uicore.IsDragging(): 365 return 366 dx = GetMouseDX() 367 dy = GetMouseDY() 368 onlyLMB = uicore.uilib.leftbtn and not uicore.uilib.rightbtn 369 onlyRMB = uicore.uilib.rightbtn and not uicore.uilib.leftbtn 370 isRotate = onlyLMB or onlyRMB 371 if isRotate: 372 self.sr.sceneContainer.OrbitParent(dx, dy) 373 if uicore.uilib.leftbtn and uicore.uilib.rightbtn: 374 advancedInspectionOn = False 375 camera = self.sr.sceneContainer.camera 376 if hasattr(self.sr.sceneContainer.camera, 'GetCurrentInspectionStatus'): 377 advancedInspectionOn = advancedInspectionOn or camera.GetCurrentInspectionStatus() 378 if not advancedInspectionOn: 379 modifier = uicore.mouseInputHandler.GetCameraZoomModifier() 380 self.sr.sceneContainer.Zoom(modifier * -dy * 0.01) 381 self.sr.sceneContainer.OrbitParent(dx, 0.0) 382 else: 383 kRotate = 0.005 * self.sr.sceneContainer.camera.fov 384 camera.Rotate(kRotate * dx, kRotate * dy) 385 386 def _OnGlobalMouseUp(self, wnd, msgID, btn, *args): 387 camera = self.sr.sceneContainer.camera 388 if btn and btn[0] == uiconst.MOUSERIGHT: 389 if self.sr.sceneContainer and camera: 390 if hasattr(camera, 'SetCurrentInspectionStatus'): 391 camera.SetCurrentInspectionStatus(False) 392 self.on_zoom(False) 393 camera.rotationOfInterest = geo2.QuaternionIdentity() 394 if btn and btn[0] == uiconst.MOUSELEFT and camera: 395 camera.ResetRotate() 396 if hasattr(camera, 'GetAdvancedInspectionModeStatus'): 397 if camera.GetAdvancedInspectionModeStatus(): 398 if camera.GetCurrentInspectionStatus(): 399 self.sr.sceneContainer.camera.SetFovTarget(camera.fov * 2) 400 return 1 401 402 def _OnGlobalMouseDown(self, wnd, msgID, btn, *args): 403 camera = self.sr.sceneContainer.camera 404 if type(wnd) != type(self): 405 return 1 406 if btn and btn[0] == uiconst.MOUSERIGHT and camera and not uicore.uilib.leftbtn: 407 if self.sr.sceneContainer: 408 if hasattr(camera, 'GetAdvancedInspectionModeStatus'): 409 if camera.GetAdvancedInspectionModeStatus(): 410 camera.SetCurrentInspectionStatus(True) 411 self.on_zoom(True) 412 if btn and btn[0] == uiconst.MOUSELEFT and camera: 413 if hasattr(camera, 'GetAdvancedInspectionModeStatus'): 414 if camera.GetAdvancedInspectionModeStatus(): 415 if camera.GetCurrentInspectionStatus(): 416 self.sr.sceneContainer.camera.SetFovTarget(camera.fov / 2) 417 return 1 418 419 def OnDropData(self, dragSource, dragData): 420 self.on_drop_data(dragSource, dragData) 421 422 def OnMouseDown(self, button, *args): 423 super(SceneContainerBaseNavigation, self).OnMouseDown(button, *args) 424 self.on_mouse_down(button) 425 426 def OnMouseUp(self, button, *args): 427 super(SceneContainerBaseNavigation, self).OnMouseUp(button, *args) 428 self.on_mouse_up(button) 429 430 def OnDblClick(self, *args): 431 self.on_dbl_click(*args) 432 433 434 class SceneContainerBrackets(Base): 435 __guid__ = 'form.SceneContainerBrackets' 436 __renderObject__ = trinity.Tr2Sprite2dRenderJob 437 438 def ApplyAttributes(self, attributes): 439 Base.ApplyAttributes(self, attributes) 440 self.viewport = trinity.TriViewport() 441 self.viewport.x = 0 442 self.viewport.y = 0 443 self.viewport.width = 1 444 self.viewport.height = 1 445 self.viewport.minZ = 0.0 446 self.viewport.maxZ = 1.0 447 self.projection = trinity.TriProjection() 448 self.frontClip = 1.0 449 self.backClip = 350000.0 450 self.fov = 1.0 451 self.minPitch = None 452 self.maxPitch = None 453 self.minZoom = 0.0 454 self.maxZoom = 1.0 455 self.scene = trinity.EveSpaceScene() 456 self.transform = trinity.EveRootTransform() 457 self.scene.objects.append(self.transform) 458 self.PrepareCamera() 459 self.DisplayScene() 460 self.CreateBracketCurveSet() 461 self.UpdateViewPort() 462 463 def SetParent(self, parent, idx = None): 464 Base.SetParent(self, parent, idx) 465 wnd = GetWindowAbove(self) 466 if wnd: 467 wnd.RegisterSceneContainer(self) 468 469 def PrepareCamera(self): 470 self.camera = SceneContainerCamera() 471 self.camera.OnActivated() 472 self.camera.frontClip = self.frontClip 473 self.camera.backClip = self.backClip 474 self.camera.fov = self.fov 475 self.camera.zoom = 0.7 476 477 def GetTranslationsForSolarsystemIDs(self, solarSystemIDs): 478 xAv = yAv = zAv = 0 479 scale = 1e+16 480 for solarsystemID in solarSystemIDs: 481 systemCenter = cfg.mapSystemCache[solarsystemID].center 482 xAv += systemCenter.x 483 yAv += systemCenter.y 484 zAv += systemCenter.z 485 486 numSystems = len(solarSystemIDs) 487 xAv /= numSystems 488 yAv /= numSystems 489 zAv /= numSystems 490 translations = [] 491 for solarsystemID in solarSystemIDs: 492 systemCenter = cfg.mapSystemCache[solarsystemID].center 493 translations.append(((systemCenter.x - xAv) / scale, (systemCenter.y - yAv) / scale, (systemCenter.z - zAv) / scale)) 494 495 return translations 496 497 def CreateBracketTransform(self, translation): 498 tr = trinity.EveTransform() 499 tr.translation = translation 500 self.transform.children.append(tr) 501 return tr 502 503 def AnimRotateFrom(self, yaw, pitch, zoom, duration): 504 curve = trinity.Tr2CurveEulerRotation() 505 curve.yaw.AddKey(0.0, math.radians(yaw)) 506 curve.yaw.AddKey(duration, 0.0) 507 curve.pitch.AddKey(0.0, math.radians(pitch)) 508 curve.pitch.AddKey(duration, 0.0) 509 self.transform.rotationCurve = trinity.Tr2RotationAdapter() 510 self.transform.rotationCurve.curve = curve 511 512 def DisplayScene(self): 513 self.renderJob = trinity.CreateRenderJob() 514 self.renderJob.SetViewport(self.viewport) 515 self.renderJob.SetView(self.camera.viewMatrix) 516 self.renderJob.SetProjection(self.camera.projectionMatrix) 517 self.renderJob.Update(self.scene) 518 self.renderJob.RenderScene(self.scene) 519 self.renderObject.renderJob = self.renderJob 520 521 def CreateBracketCurveSet(self): 522 self.bracketCurveSet = trinity.TriCurveSet() 523 self.bracketCurveSet.Play() 524 step = trinity.TriStepUpdate() 525 step.object = self.bracketCurveSet 526 step.name = 'Update brackets' 527 self.renderJob.steps.append(step) 528 529 def _OnResize(self): 530 self.UpdateViewPort() 531 532 def UpdateViewPort(self, *args): 533 l, t, w, h = self.GetAbsoluteViewport() 534 log.info('SceneContainerBrackets::UpdateViewPort', l, t, w, h) 535 if not w and not h: 536 return 537 self.viewport.width = uicore.ScaleDpi(w) 538 self.viewport.height = uicore.ScaleDpi(h) 539 log.info('new viewport dimensions', self.viewport.x, self.viewport.y, self.viewport.width, self.viewport.height) 540 log.info('projection', self.fov, self.viewport.GetAspectRatio(), self.frontClip, self.backClip) 541 self.camera.UpdateViewportSize(uicore.ScaleDpi(w), uicore.ScaleDpi(h)) 542 543 def _OnClose(self, *args): 544 self.clearStep = None 545 self.viewport = None 546 self.projection = None 547 if self.camera: 548 self.camera.OnDeactivated() 549 self.camera = None 550 self.scene = None 551 if hasattr(self.renderJob, 'Disable'): 552 self.renderJob.Disable() 553 self.renderJob = None 554 555 def GetOrbit(self): 556 return (0.0, 0.0) 557 558 def SetOrbit(self, yaw, pitch): 559 self.camera.SetYaw(yaw) 560 self.camera.SetPitch(pitch) 561 562 orbit = property(GetOrbit, SetOrbit) 563 564 def OrbitParent(self, dx, dy): 565 self.StopAnimations() 566 fov = self.camera.fov 567 cameraSpeed = 0.01 568 self.camera.Orbit(dx * fov * cameraSpeed, dy * fov * cameraSpeed) 569 570 def GetZoom(self): 571 return self.camera.GetZoomLinear() 572 573 def SetZoom(self, value): 574 self.camera.SetZoomLinear(value) 575 576 zoom = property(GetZoom, SetZoom) 577 578 def SetMinMaxZoom(self, minZoom, maxZoom): 579 self.camera.minZoom = maxZoom 580 self.camera.maxZoom = minZoom 581 582 def Zoom(self, dz): 583 self.camera.Zoom(dz) 584 585 586 def GetMouseDY(): 587 return uicore.uilib.dy * GetCameraSensitivityMultiplier() 588 589 590 def GetMouseDX(): 591 return uicore.uilib.dx * GetCameraSensitivityMultiplier()