sceneManager.py (38344B)
1 #Embedded file name: C:\BuildAgent\work\20d73f1b24eed06e\eve\release\V24.01\eve\client\script\parklife\sceneManager.py 2 import logging 3 import sys 4 import blue 5 import uthread 6 from carbon.common.script.sys.service import Service 7 from carbonui import uiconst 8 from carbonui.primitives.containerAutoSize import ContainerAutoSize 9 from carbonui.uicore import uicore 10 from eve.client.script.environment.spaceObject.ExplosionManager import ExplosionManager 11 from eve.client.script.parklife.sceneManagerConsts import SCENE_TYPE_CHARACTER_CREATION, SCENE_TYPE_SPACE, SYSTEM_WIDE_CLOUD_NAME 12 from eve.client.script.ui.control.eveLabel import EveCaptionLarge, EveLabelLarge 13 from eve.common.script.sys import idCheckers 14 from evecamera import INSPACE_CAMERAS, CAM_SHIPORBIT_RESTRICTED, CAM_VCS_CONSUMER, INSPACE_CAMERA_MODES 15 from evecamera.locationalcamera import get_orbit_camera_by_solar_system 16 from evegraphics.explosions.spaceObjectExplosionManager import SpaceObjectExplosionManager 17 import evegraphics.settings as gfxsettings 18 from eve.common.script.sys.idCheckers import IsKnownSpaceSystem, IsAbyssalSpaceSystem 19 from eve.client.script.ui.camera import get_camera_class 20 from eve.client.script.ui.camera.baseCamera import DestinyBallInvalid 21 from eve.client.script.ui.camera.baseSpaceCamera import BaseSpaceCamera 22 from eve.client.script.ui.camera.cameraBase import CameraBase 23 from eve.client.script.ui.view.viewStateConst import ViewState 24 from fsdBuiltData.common.graphicIDs import GetGraphicFile 25 import locks 26 import log 27 import telemetry 28 import trinity 29 from localization import GetByLabel 30 from trinity.sceneRenderJobSpace import DEFAULT_POSTPROCESS_PATH 31 stdlog = logging.getLogger(__name__) 32 MAX_INVALID_CAMERA_FRAMES = 10 33 34 class SceneContext(): 35 36 def __init__(self, scene = None, camera = None, sceneKey = 'default', sceneType = None, renderJob = None): 37 self.scene = scene 38 self.camera = camera 39 self.sceneKey = sceneKey 40 self.sceneType = sceneType 41 self.renderJob = renderJob 42 43 44 def GetSceneManager(): 45 return sm.GetService('sceneManager') 46 47 48 class SceneManager(Service): 49 __guid__ = 'svc.sceneManager' 50 __exportedcalls__ = {'LoadScene': [], 51 'GetScene': []} 52 __startupdependencies__ = ['settings', 'device'] 53 __notifyevents__ = ['OnGraphicSettingsChanged', 54 'OnSessionChanged', 55 'OnCameraLookAt', 56 'OnViewStateChanged'] 57 58 def Run(self, ms): 59 Service.Run(self, ms) 60 self.registeredScenes = {} 61 self.registeredCameras = {} 62 self.sceneLoadedEvents = {} 63 self.cameraBeforeRestriction = None 64 self.registeredJobs = [] 65 self.cameraOffsetOverride = None 66 self.characterBackdropUIRoot = None 67 self.ProcessImportsAndCreateScenes() 68 self.primaryJob = SceneContext() 69 self.secondaryJob = None 70 self.loadingClearJob = trinity.CreateRenderJob() 71 self.loadingClearJob.name = 'loadingClear' 72 self.loadingClearJob.Clear((0, 0, 0, 1)) 73 self.loadingClearJob.enabled = False 74 self.overlaySceneKeys = [ViewState.StarMap, 75 ViewState.SystemMap, 76 ViewState.StarMapNew, 77 ViewState.SystemMapNew, 78 ViewState.Planet, 79 ViewState.ShipTree, 80 ViewState.DockPanel] 81 self.overlayForcePostProcessing = {ViewState.StarMap: 0, 82 ViewState.SystemMap: 0} 83 self._sharedResources = {} 84 self.routeVisualizer = None 85 self.podDeathScene = None 86 self._persistedSpaceObjects = {} 87 self._updateCameras = [] 88 self._cameraInvalidFrameCounts = {} 89 if '/skiprun' not in blue.pyos.GetArg(): 90 self._EnableLoadingClear() 91 limit = gfxsettings.Get(gfxsettings.GFX_LOD_QUALITY) * 30 92 self.explosionManager = ExplosionManager(limit) 93 self.currentFadeIntensity = 0.0 94 self.currentDesaturateLevel = 1.0 95 self.enable3DView = True 96 97 def ProcessImportsAndCreateScenes(self): 98 from trinity.sceneRenderJobSpace import CreateSceneRenderJobSpace 99 from trinity.sceneRenderJobCharacters import CreateSceneRenderJobCharacters 100 self.fisRenderJob = CreateSceneRenderJobSpace('SpaceScenePrimary') 101 self.characterRenderJob = CreateSceneRenderJobCharacters() 102 self._CreateJobCharCreation() 103 self._CreateJobFiS() 104 105 def _UpdateSecondaryCameras(self): 106 for camera in self._updateCameras: 107 self._UpdateCamera(camera) 108 109 def _UpdateActiveCamera(self): 110 cam = self.GetActiveCamera() 111 if cam: 112 self._UpdateCamera(cam) 113 self._UpdateSecondaryCameras() 114 115 def _UpdateCamera(self, camera): 116 try: 117 camera._Update() 118 except DestinyBallInvalid as e: 119 self._OnCameraUpdateInvalid(camera, e) 120 except Exception: 121 stdlog.error('Unexpected exception raised from UpdateCamera', exc_info=1, extra={'sample_rate': 0.01}) 122 else: 123 self._cameraInvalidFrameCounts.pop(camera, None) 124 125 def _OnCameraUpdateInvalid(self, camera, exc): 126 count = self._cameraInvalidFrameCounts.get(camera, 0) + 1 127 self._cameraInvalidFrameCounts[camera] = count 128 if count == MAX_INVALID_CAMERA_FRAMES: 129 stdlog.warning('Camera failed to update for %s frames, resetting it. e=%s', count, exc) 130 self._ResetCamera(camera) 131 132 def _ResetCamera(self, camera): 133 resetCameraPosition = getattr(camera, 'ResetCameraPosition', None) 134 if resetCameraPosition is None: 135 return 136 try: 137 resetCameraPosition() 138 except Exception: 139 stdlog.exception('Failed to reset camera %s', camera) 140 141 def RegisterForCameraUpdate(self, camera): 142 if camera not in self._updateCameras: 143 self._updateCameras.append(camera) 144 145 def UnregisterForCameraUpdate(self, camera): 146 if camera in self._updateCameras: 147 self._updateCameras.remove(camera) 148 149 def _EnableLoadingClear(self): 150 if not self.loadingClearJob.enabled: 151 self.loadingClearJob.enabled = True 152 trinity.renderJobs.recurring.insert(0, self.loadingClearJob) 153 154 def _DisableLoadingClear(self): 155 if self.loadingClearJob.enabled: 156 self.loadingClearJob.enabled = False 157 trinity.renderJobs.recurring.remove(self.loadingClearJob) 158 159 def RefreshJob(self, camera): 160 sceneType = self.primaryJob.sceneType 161 if sceneType == SCENE_TYPE_CHARACTER_CREATION: 162 self.primaryJob.renderJob.SetActiveCamera(camera) 163 uicore.uilib.SetSceneView(camera.viewMatrix, camera.projectionMatrix) 164 165 def DeactivateFISCamera(self): 166 currCam = self.GetActivePrimaryCamera() 167 if currCam and hasattr(currCam, 'OnDeactivated'): 168 currCam.OnDeactivated() 169 170 def _CreateJobCharCreation(self): 171 self.characterRenderJob.CreateBasicRenderSteps() 172 self.characterRenderJob.EnableScatter(True) 173 self.characterRenderJob.EnableSculpting(True) 174 self.characterRenderJob.Set2DBackdropUIRoot(self.characterBackdropUIRoot) 175 self.characterRenderJob.AddStep('UPDATE_SECONDARY_CAMERAS', trinity.TriStepPythonCB(self._UpdateSecondaryCameras)) 176 177 def _CreateJobFiS(self, rj = None): 178 if rj is None: 179 rj = self.fisRenderJob 180 rj.CreateBasicRenderSteps() 181 rj.SetCameraCallback(self._UpdateActiveCamera) 182 183 def GetFisRenderJob(self): 184 return self.fisRenderJob 185 186 def GetFiSPostProcess(self): 187 return self.fisRenderJob.postProcess 188 189 def OnGraphicSettingsChanged(self, changes): 190 if len(gfxsettings.GFX_SETTINGS.intersection(changes)) == 0: 191 return 192 self.fisRenderJob.SetSettingsBasedOnPerformancePreferences() 193 self.characterRenderJob.SetSettingsBasedOnPerformancePreferences() 194 activeScene = self.GetActiveScene() 195 if activeScene is not None and isinstance(activeScene, trinity.EveSpaceScene): 196 self.fisRenderJob.SetScene(activeScene) 197 if self.HasSecondaryScene(): 198 self.secondaryJob.renderJob.SetSettingsBasedOnPerformancePreferences() 199 for each in self.registeredJobs: 200 each.object.SetSettingsBasedOnPerformancePreferences() 201 202 if gfxsettings.GFX_LOD_QUALITY in changes: 203 limit = gfxsettings.Get(gfxsettings.GFX_LOD_QUALITY) * 30 204 self.explosionManager.SetLimit(limit) 205 if gfxsettings.UI_CAMERA_OFFSET in changes: 206 self.UpdateCameraOffset() 207 if session.userid is not None: 208 effectsEnabled = gfxsettings.Get(gfxsettings.UI_EFFECTS_ENABLED) 209 if gfxsettings.UI_TRAILS_ENABLED in changes or gfxsettings.UI_EFFECTS_ENABLED in changes: 210 trailsEnabled = effectsEnabled and gfxsettings.Get(gfxsettings.UI_TRAILS_ENABLED) 211 trinity.settings.SetValue('eveSpaceObjectTrailsEnabled', trailsEnabled) 212 213 @telemetry.ZONE_METHOD 214 def OnSessionChanged(self, isremote, session, change): 215 if 'locationid' in change: 216 newLocationID = change['locationid'][1] 217 if idCheckers.IsSolarSystem(newLocationID) and self.primaryJob.sceneType != SCENE_TYPE_SPACE: 218 log.LogWarn('SceneManager: I detected a session change into space but no one has bothered to update my scene type!') 219 self.SetSceneType(SCENE_TYPE_SPACE) 220 SpaceObjectExplosionManager.ClearWaiters() 221 222 @telemetry.ZONE_METHOD 223 def SetSceneType(self, sceneType): 224 if self.primaryJob.sceneType == sceneType: 225 return 226 if sceneType != SCENE_TYPE_SPACE: 227 self.DeactivateFISCamera() 228 self.primaryJob = SceneContext(sceneType=sceneType) 229 if sceneType == SCENE_TYPE_CHARACTER_CREATION: 230 log.LogInfo('Setting up character creation scene rendering') 231 self.primaryJob.renderJob = self.characterRenderJob 232 self.fisRenderJob.SetActiveScene(None) 233 self.fisRenderJob.Disable() 234 self._DisableLoadingClear() 235 self.characterRenderJob.Enable() 236 elif sceneType == SCENE_TYPE_SPACE: 237 log.LogInfo('Setting up space scene rendering') 238 self.primaryJob.renderJob = self.fisRenderJob 239 self.characterRenderJob.SetScene(None) 240 self.characterRenderJob.Disable() 241 for each in self.registeredJobs: 242 if hasattr(each.object, 'UseFXAA'): 243 each.object.UseFXAA(False) 244 245 self._DisableLoadingClear() 246 if not self.HasSecondaryScene(): 247 self.fisRenderJob.Enable() 248 249 @telemetry.ZONE_METHOD 250 def Initialize(self, scene): 251 self.primaryJob = SceneContext(scene=scene, renderJob=self.fisRenderJob) 252 253 def CreateCharacterBackdropUIRoot(self): 254 if self.characterBackdropUIRoot: 255 return 256 self.characterBackdropUIRoot = uicore.uilib.CreateRootObject(name='ccBackgroundUI', renderJob=None, state=uiconst.UI_DISABLED) 257 self.characterRenderJob.Set2DBackdropUIRoot(self.characterBackdropUIRoot) 258 259 def _ApplyCamera(self, jobContext, camera, **kwargs): 260 if jobContext == self.primaryJob: 261 currCam = self.GetActivePrimaryCamera() 262 else: 263 currCam = self.GetActiveSecondaryCamera() 264 jobContext.camera = camera 265 if jobContext.renderJob is not None: 266 if isinstance(camera, CameraBase): 267 jobContext.renderJob.SetActiveCamera(camera.GetTrinityCamera()) 268 elif isinstance(camera, trinity.EveCamera): 269 jobContext.renderJob.SetActiveCamera(camera) 270 else: 271 jobContext.renderJob.SetActiveCamera(None, camera.viewMatrix, camera.projectionMatrix) 272 if hasattr(camera, 'cameraID'): 273 sm.ScatterEvent('OnActiveCameraChanged', camera.cameraID) 274 if camera.cameraID in INSPACE_CAMERAS: 275 self.UpdateSceneCameraReferences(camera) 276 if hasattr(camera, 'OnActivated'): 277 try: 278 camera.OnActivated(lastCamera=currCam, **kwargs) 279 except Exception: 280 stdlog.exception('Camera %s failed to activate, resetting it', camera) 281 self._ResetCamera(camera) 282 283 if currCam and hasattr(currCam, 'OnDeactivated') and currCam != camera: 284 currCam.OnDeactivated() 285 self.UpdateBracketProjectionCamera() 286 287 def OnCameraLookAt(self, isEgo, itemID): 288 scene = self.GetRegisteredScene('default') 289 if scene is None: 290 return 291 for each in scene.cameraAttachments: 292 try: 293 each.display = isEgo 294 except AttributeError: 295 pass 296 297 def UpdateSceneCameraReferences(self, camera): 298 scene = self.GetRegisteredScene('default') 299 if not scene: 300 return 301 for distanceField in scene.distanceFields: 302 distanceField.cameraView = camera.viewMatrix 303 304 def UpdateBracketProjectionCamera(self): 305 camera = self.GetActiveCamera() 306 if camera: 307 uicore.uilib.SetSceneCamera(camera) 308 309 def SetPrimaryCamera(self, cameraID, force = False, **kwargs): 310 activeCam = self.GetActivePrimaryCamera() 311 if activeCam and activeCam.cameraID == cameraID and not force: 312 return activeCam 313 camera = self.GetOrCreateCamera(cameraID) 314 self._ApplyCamera(self.primaryJob, camera, **kwargs) 315 return camera 316 317 def SetSecondaryCamera(self, cameraID, **kwargs): 318 activeCam = self.GetActiveSecondaryCamera() 319 if activeCam and activeCam.cameraID == cameraID: 320 return activeCam 321 camera = self.GetOrCreateCamera(cameraID) 322 self._ApplyCamera(self.secondaryJob, camera, **kwargs) 323 return camera 324 325 def HasSecondaryScene(self): 326 return self.secondaryJob is not None 327 328 @telemetry.ZONE_METHOD 329 def SetSecondaryScene(self, scene, sceneKey, sceneType): 330 if sceneType == SCENE_TYPE_SPACE: 331 newJob = not self.HasSecondaryScene() 332 if newJob: 333 from trinity.sceneRenderJobSpace import CreateSceneRenderJobSpace 334 self.secondaryJob = SceneContext(scene=scene, sceneKey=sceneKey, sceneType=sceneType) 335 self.secondaryJob.renderJob = CreateSceneRenderJobSpace('SpaceSceneSecondary') 336 self._CreateJobFiS(self.secondaryJob.renderJob) 337 else: 338 self.secondaryJob.scene = scene 339 self.secondaryJob.sceneKey = sceneKey 340 if sceneKey in self.overlayForcePostProcessing: 341 self.secondaryJob.renderJob.overrideSettings.postProcessingQuality = self.overlayForcePostProcessing[sceneKey] 342 self.secondaryJob.renderJob.overrideSettings.antiAliasingQuality = gfxsettings.AA_QUALITY_DISABLED 343 self.secondaryJob.renderJob.overrideSettings.enableUpscaling = False 344 else: 345 self.secondaryJob.renderJob.overrideSettings.postProcessingQuality = None 346 self.secondaryJob.renderJob.overrideSettings.antiAliasingQuality = None 347 self.secondaryJob.renderJob.overrideSettings.enableUpscaling = None 348 if newJob: 349 self.secondaryJob.renderJob.Enable() 350 self.secondaryJob.renderJob.SetActiveScene(scene, sceneKey) 351 352 def ClearSecondaryScene(self): 353 if not self.HasSecondaryScene(): 354 return 355 if self.secondaryJob.renderJob is not None: 356 self.secondaryJob.renderJob.Disable() 357 self.secondaryJob = None 358 359 def SetActiveScene(self, scene, sceneKey = None): 360 sceneType = SCENE_TYPE_CHARACTER_CREATION 361 if getattr(scene, '__bluetype__', None) == 'trinity.EveSpaceScene': 362 sceneType = SCENE_TYPE_SPACE 363 if sceneKey in self.overlaySceneKeys: 364 fadeObject = self.GetFadeObject(scene=self.primaryJob.scene) 365 if fadeObject is not None: 366 fadeObject.intensity = 0.0 367 self.primaryJob.renderJob.SuspendRendering() 368 self.SetSecondaryScene(scene, sceneKey, sceneType) 369 elif sceneType == SCENE_TYPE_SPACE: 370 self.primaryJob.sceneKey = sceneKey 371 self.primaryJob.scene = scene 372 self.primaryJob.renderJob.SetActiveScene(scene, sceneKey) 373 else: 374 self.primaryJob.scene = scene 375 self.primaryJob.renderJob.SetScene(scene) 376 self.UpdateBracketProjectionCamera() 377 378 def RefreshSecondarySceneToRenderJob(self): 379 self.secondaryJob.renderJob.SetScene(self.secondaryJob.scene) 380 381 def RegisterJob(self, job): 382 wr = blue.BluePythonWeakRef(job) 383 384 def ClearDereferenced(): 385 self.registeredJobs.remove(wr) 386 387 wr.callback = ClearDereferenced 388 self.registeredJobs.append(wr) 389 390 def GetRegisteredCamera(self, key): 391 if key in self.registeredCameras: 392 return self.registeredCameras[key] 393 self.LogNotice('No camera registered for:', key, self.registeredCameras) 394 395 def GetActiveSpaceCamera(self): 396 return self.GetActivePrimaryCamera() 397 398 def GetActivePrimaryCamera(self): 399 return self.primaryJob.camera 400 401 def GetActiveCamera(self): 402 if self.HasSecondaryScene(): 403 return self.GetActiveSecondaryCamera() 404 return self.GetActivePrimaryCamera() 405 406 def GetActiveSecondaryCamera(self): 407 return self.secondaryJob.camera 408 409 def UnregisterCamera(self, key): 410 if key in self.registeredCameras: 411 self.LogNotice('sceneManager::UnregisterCamera', key, self.registeredCameras[key]) 412 cam = self.registeredCameras[key] 413 if cam == self.GetActiveCamera(): 414 sm.ScatterEvent('OnActiveCameraChanged', None) 415 if cam and hasattr(cam, 'OnDeactivated'): 416 cam.OnDeactivated() 417 del self.registeredCameras[key] 418 419 def RegisterCamera(self, camera): 420 cameraID = camera.cameraID 421 if cameraID in self.registeredCameras: 422 return 423 self.LogNotice('sceneManager::RegisterCamera', cameraID, camera) 424 self.registeredCameras[camera.cameraID] = camera 425 camera.centerOffset = self.GetCameraOffset() 426 427 def GetCameraOffset(self): 428 if self.cameraOffsetOverride: 429 return self.cameraOffsetOverride * -0.01 430 elif gfxsettings.IsInitialized(gfxsettings.SETTINGS_GROUP_UI): 431 return gfxsettings.Get(gfxsettings.UI_CAMERA_OFFSET) * -0.01 432 else: 433 return 0.0 434 435 def SetCameraOffsetOverride(self, cameraOffsetOverride): 436 self.cameraOffsetOverride = cameraOffsetOverride 437 self.UpdateCameraOffset() 438 439 def UpdateCameraOffset(self): 440 offset = self.GetCameraOffset() 441 for cam in self.registeredCameras.itervalues(): 442 cam.centerOffset = offset 443 444 sm.ScatterEvent('OnSetCameraOffset', offset) 445 446 def UnregisterScene(self, key, ignoreCamera = False): 447 if key in self.registeredScenes: 448 del self.registeredScenes[key] 449 if not ignoreCamera and key == 'default': 450 cam = self.GetActivePrimaryCamera() 451 if cam: 452 cam.OnDeactivated() 453 454 def RegisterScene(self, scene, key): 455 self.registeredScenes[key] = scene 456 self._Update3DViewDisplayState() 457 458 def GetRegisteredScene(self, key, defaultOnActiveScene = False, allowBlocking = True): 459 if key in self.registeredScenes: 460 return self.registeredScenes[key] 461 if self.IsLoadingScene(key) and allowBlocking: 462 self.sceneLoadedEvents[key].wait() 463 return self.registeredScenes[key] 464 if defaultOnActiveScene: 465 return self.primaryJob.scene 466 467 def IsLoadingScene(self, key): 468 return key in self.sceneLoadedEvents and not self.sceneLoadedEvents[key].is_set() 469 470 def SetRegisteredScenes(self, key): 471 if key == 'default' and 'transition' in self.registeredScenes: 472 key = 'transition' 473 if key in ('default', 'transition') and self.HasSecondaryScene(): 474 if self.primaryJob.renderJob.enabled: 475 self.primaryJob.renderJob.Start() 476 else: 477 self.primaryJob.renderJob.Enable() 478 self.ClearSecondaryScene() 479 scene = self.registeredScenes.get(key, None) 480 self.SetActiveScene(scene, key) 481 482 def GetActiveScene(self): 483 if self.HasSecondaryScene(): 484 return self.secondaryJob.scene 485 return self.primaryJob.scene 486 487 def Get2DBackdropScene(self): 488 return self.characterBackdropUIRoot.GetRenderObject() 489 490 @telemetry.ZONE_METHOD 491 def Show2DBackdropScene(self, updateRenderJob = False): 492 self.showUIBackdropScene = True 493 if updateRenderJob: 494 self.characterRenderJob.Set2DBackdropUIRoot(self.characterBackdropUIRoot) 495 496 @telemetry.ZONE_METHOD 497 def Hide2DBackdropScene(self, updateRenderJob = False): 498 self.showUIBackdropScene = False 499 if updateRenderJob: 500 self.characterRenderJob.Set2DBackdropUIRoot(None) 501 502 def GetScene(self, location = None): 503 if location is None: 504 location = (session.solarsystemid2, session.constellationid, session.regionid) 505 return self.GetResPathForLocation(location) 506 507 def GetResPathForLocation(self, location): 508 resPath = None 509 if IsAbyssalSpaceSystem(location[0]): 510 resPath = sm.GetService('abyss').get_nebula_res_path() 511 if resPath is None: 512 return cfg.GetNebula(*location) 513 return resPath 514 515 def GetSceneForSystem(self, solarSystemID): 516 _, regionID, constellationID, _, _ = sm.GetService('map').GetParentLocationID(solarSystemID) 517 return self.GetScene((solarSystemID, constellationID, regionID)) 518 519 def GetNebulaPathForSystem(self, solarSystemID): 520 scene = trinity.Load(self.GetSceneForSystem(solarSystemID)) 521 return scene.envMapResPath 522 523 def ReplaceNebulaFromResPath(self, nebulaGraphicsResPath): 524 newScene = trinity.Load(nebulaGraphicsResPath) 525 scene = self.GetRegisteredScene('default') 526 scene.backgroundEffect = newScene.backgroundEffect 527 scene.envMapResPath = newScene.envMapResPath 528 scene.envMap1ResPath = newScene.envMap1ResPath 529 scene.envMap2ResPath = newScene.envMap2ResPath 530 531 def DeriveTextureFromSceneName(self, scenePath): 532 scene = trinity.Load(scenePath) 533 if scene is None: 534 return {} 535 d = {'envMap1ResPath': scene.envMap1ResPath, 536 'lowQualityNebulaResPath': scene.lowQualityNebulaResPath, 537 'lowQualityNebulaMixResPath': scene.lowQualityNebulaMixResPath} 538 return d 539 540 def CleanupSpaceResources(self): 541 self._sharedResources = {} 542 543 def RegisterPersistentUIObject(self, key, object): 544 if key in self._persistedSpaceObjects: 545 self.RemovePersistentUIObject(key) 546 self._persistedSpaceObjects[key] = object 547 scene = self.GetRegisteredScene('default', False) 548 if scene is not None: 549 scene.uiObjects.append(object) 550 551 def GetPersistentUIObject(self, key): 552 obj = None 553 if key in self._persistedSpaceObjects: 554 obj = self._persistedSpaceObjects[obj] 555 return obj 556 557 def RemovePersistentUIObject(self, key): 558 obj = self._persistedSpaceObjects[key] 559 scene = self.GetRegisteredScene('default', False) 560 if scene is not None: 561 scene.uiObjects.fremove(obj) 562 del self._persistedSpaceObjects[key] 563 564 def _GetSharedResource(self, path, key = None): 565 comboKey = (path, key) 566 if comboKey not in self._sharedResources: 567 self._sharedResources[comboKey] = trinity.Load(path) 568 return self._sharedResources[comboKey] 569 570 def _PrepareBackgroundLandscapes(self, scene, solarSystemID, constellationID = None): 571 starSeed = 0 572 securityStatus = 1 573 if constellationID is None: 574 constellationID = sm.GetService('map').GetConstellationForSolarSystem(solarSystemID) 575 if bool(solarSystemID) and bool(constellationID): 576 starSeed = int(constellationID) 577 securityStatus = sm.GetService('map').GetSecurityStatus(solarSystemID) 578 scene.starfield = self._GetSharedResource('res:/dx9/scene/starfield/spritestars.red') 579 if scene.starfield is not None: 580 scene.starfield.seed = starSeed 581 scene.starfield.minDist = 40 582 scene.starfield.maxDist = 80 583 if IsKnownSpaceSystem(solarSystemID): 584 scene.starfield.numStars = 500 + int(250 * securityStatus) 585 else: 586 scene.starfield.numStars = 0 587 588 def _SetupUniverseStars(self, scene, solarsystemID): 589 if gfxsettings.Get(gfxsettings.UI_EFFECTS_ENABLED) and solarsystemID is not None: 590 universe = self._GetSharedResource('res:/dx9/scene/starfield/universe.red') 591 scene.backgroundObjects.append(universe) 592 here = sm.GetService('map').GetItem(solarsystemID) 593 if here: 594 scale = 10000000000.0 595 position = (here.x / scale, here.y / scale, -here.z / scale) 596 universe.children[0].translation = position 597 598 def AddPersistentUIObjects(self, scene): 599 for spaceObject in self._persistedSpaceObjects.values(): 600 if spaceObject not in scene.uiObjects: 601 scene.uiObjects.append(spaceObject) 602 603 def ApplySolarsystemAttributes(self, scene, solarsystemID = None): 604 if solarsystemID is None: 605 solarsystemID = session.solarsystemid 606 if not scene.cameraAttachments.FindByName('dustfield'): 607 dustfield = self._GetSharedResource('res:/dx9/scene/dustfield.red') 608 dustfield.name = 'dustfield' 609 scene.cameraAttachments.append(dustfield) 610 scene.sunDiffuseColor = (1.5, 1.5, 1.5, 1.0) 611 if hasattr(cfg.mapSolarSystemContentCache[solarsystemID], 'systemWideCloud'): 612 systemWideCloudGID = cfg.mapSolarSystemContentCache[solarsystemID].systemWideCloud 613 if systemWideCloudGID > 0: 614 systemWideCloudGraphicPath = GetGraphicFile(systemWideCloudGID) 615 systemWideCloud = self._GetSharedResource(systemWideCloudGraphicPath) 616 if systemWideCloud is not None: 617 systemWideCloud.name = SYSTEM_WIDE_CLOUD_NAME 618 systemWideCloud.StartControllers() 619 scene.objects.append(systemWideCloud) 620 self._SetupUniverseStars(scene, solarsystemID) 621 self._PrepareBackgroundLandscapes(scene, solarsystemID) 622 623 def ApplySceneInflightAttributes(self, scene, bp = None): 624 if bp is None: 625 bp = sm.GetService('michelle').GetBallpark() 626 scene.ballpark = bp 627 628 def SetVignette(self, vignette, vignetteSettings): 629 index = 0 630 if isinstance(vignette, trinity.Tr2PPVignetteEffect): 631 index = 1 632 for nametuple, value in vignetteSettings.iteritems(): 633 setattr(vignette, nametuple[index], value) 634 635 def GetVignetteObject(self, vignetteSettings, scene = None, create = False): 636 if scene is None: 637 scene = self.GetActiveScene() 638 if isinstance(scene, trinity.EveSpaceScene): 639 if scene.postprocess is not None and scene.postprocess.vignette is not None: 640 return scene.postprocess.vignette 641 if create: 642 if scene.postprocess is None: 643 scene.postprocess = trinity.Load(DEFAULT_POSTPROCESS_PATH) 644 if scene.postprocess.vignette is None: 645 scene.postprocess.vignette = trinity.Tr2PPVignetteEffect() 646 self.SetVignette(scene.postprocess.vignette, vignetteSettings) 647 return scene.postprocess.vignette 648 649 def GetFadeObject(self, scene = None, create = False): 650 if scene is None: 651 scene = self.GetActiveScene() 652 if isinstance(scene, trinity.EveSpaceScene): 653 if scene.postprocess is not None and scene.postprocess.fade is not None: 654 return scene.postprocess.fade 655 if create: 656 if scene.postprocess is None: 657 scene.postprocess = trinity.Load(DEFAULT_POSTPROCESS_PATH) 658 if scene.postprocess.fade is None: 659 scene.postprocess.fade = trinity.Tr2PPFadeEffect() 660 return scene.postprocess.fade 661 662 def GetDesaturateObject(self, scene = None, create = False): 663 if scene is None: 664 scene = self.GetActiveScene() 665 if scene is None: 666 return 667 if isinstance(scene, trinity.EveSpaceScene): 668 if scene.postprocess is not None and scene.postprocess.desaturate is not None: 669 return scene.postprocess.desaturate 670 if create: 671 if scene.postprocess is None: 672 scene.postprocess = trinity.Load(DEFAULT_POSTPROCESS_PATH) 673 if scene.postprocess.desaturate is None: 674 scene.postprocess.desaturate = trinity.Tr2PPDesaturateEffect() 675 return scene.postprocess.desaturate 676 677 def ApplyScene(self, scene, registerKey = None): 678 fadeObject = self.GetFadeObject(scene=scene, create=True) 679 desaturateObject = self.GetDesaturateObject(scene=scene, create=True) 680 if fadeObject: 681 fadeObject.intensity = self.currentFadeIntensity 682 if desaturateObject: 683 desaturateObject.intensity = self.currentDesaturateLevel 684 if registerKey is not None: 685 self.RegisterScene(scene, registerKey) 686 self.SetActiveScene(scene, registerKey) 687 sm.ScatterEvent('OnLoadScene', scene, registerKey) 688 689 def GetOrCreateCamera(self, cameraID): 690 if cameraID in self.registeredCameras: 691 return self.GetRegisteredCamera(cameraID) 692 else: 693 return self._CreateAndRegisterCamera(cameraID) 694 695 def _CreateAndRegisterCamera(self, key, **kwargs): 696 cameraCls = get_camera_class(key) 697 camera = cameraCls(**kwargs) 698 self.RegisterCamera(camera) 699 return camera 700 701 @telemetry.ZONE_METHOD 702 def LoadScene(self, scenefile, registerKey = None, applyScene = True): 703 scene = None 704 try: 705 if registerKey: 706 self.sceneLoadedEvents[registerKey] = locks.Event(registerKey) 707 self.SetSceneType(SCENE_TYPE_SPACE) 708 sceneFromFile = trinity.Load(scenefile) 709 if sceneFromFile is None: 710 return 711 scene = sceneFromFile 712 if applyScene: 713 self.ApplyScene(scene, registerKey) 714 except Exception: 715 log.LogException('sceneManager::LoadScene') 716 sys.exc_clear() 717 finally: 718 if registerKey and registerKey in self.sceneLoadedEvents: 719 self.sceneLoadedEvents.pop(registerKey).set() 720 721 return (scene, None) 722 723 def ApplySpaceScene(self): 724 scene = self.primaryJob.scene 725 if not scene: 726 return 727 self.ApplySolarsystemAttributes(scene) 728 self.ApplySceneInflightAttributes(scene) 729 self.AddPersistentUIObjects(scene) 730 731 def SwitchToRestrictedCamera(self, minZoom = None, maxZoom = None, minPitch = BaseSpaceCamera.kMinPitch, maxPitch = BaseSpaceCamera.kMaxPitch, isRotationEnabled = True, initialZoomDistance = None): 732 lastCamera = self.GetActivePrimaryCamera() 733 if lastCamera and lastCamera.cameraID != CAM_SHIPORBIT_RESTRICTED: 734 if lastCamera.cameraID in INSPACE_CAMERAS: 735 self.cameraBeforeRestriction = lastCamera.cameraID 736 self.SetPrimaryCamera(CAM_SHIPORBIT_RESTRICTED, force=True) 737 restrictedCam = self.GetActivePrimaryCamera() 738 restrictedCam.Lock(minZoom, maxZoom, minPitch, maxPitch, isRotationEnabled) 739 restrictedCam.LookAt(session.shipid) 740 if initialZoomDistance is not None: 741 restrictedCam.SetZoomDistance(initialZoomDistance) 742 743 def SwitchFromRestrictedCamera(self): 744 newCamera = get_orbit_camera_by_solar_system(session.solarsystemid) 745 if self.cameraBeforeRestriction is not None and self.cameraBeforeRestriction in INSPACE_CAMERA_MODES: 746 newCamera = self.cameraBeforeRestriction 747 activeCamera = self.GetActivePrimaryCamera() 748 activeCameraID = activeCamera.cameraID if activeCamera else None 749 if activeCameraID == CAM_SHIPORBIT_RESTRICTED: 750 activeCamera.Unlock() 751 self.SetPrimaryCamera(newCamera) 752 elif settings.char.ui.Get('spaceCameraID', None) == CAM_SHIPORBIT_RESTRICTED: 753 settings.char.ui.Set('spaceCameraID', newCamera) 754 self.cameraBeforeRestriction = None 755 756 def GetVirtualCamera(self): 757 return self.GetOrCreateCamera(CAM_VCS_CONSUMER) 758 759 def SwitchToVirtualCamera(self): 760 lastCamera = self.GetActivePrimaryCamera() 761 if lastCamera and lastCamera.cameraID == CAM_VCS_CONSUMER: 762 return 763 self.cameraBeforeVirtual = lastCamera.cameraID 764 self.SetPrimaryCamera(CAM_VCS_CONSUMER, force=True) 765 766 def SwitchFromVirtualCamera(self): 767 lastCamera = self.GetActivePrimaryCamera() 768 if not lastCamera or lastCamera.cameraID != CAM_VCS_CONSUMER: 769 self.cameraBeforeVirtual = None 770 return 771 if self.cameraBeforeVirtual is not None: 772 camera = self.SetPrimaryCamera(self.cameraBeforeVirtual) 773 else: 774 orbitCamera = get_orbit_camera_by_solar_system(session.solarsystemid) 775 camera = self.SetPrimaryCamera(orbitCamera) 776 self.cameraBeforeVirtual = None 777 778 def SnapLastCameraToVirtualCamera(self): 779 if self.cameraBeforeVirtual: 780 virtualCamera = self.GetVirtualCamera() 781 camera = self.GetOrCreateCamera(self.cameraBeforeVirtual) 782 camera.eyePosition = virtualCamera.eyePosition 783 camera.atPosition = virtualCamera.atPosition 784 785 def EnableRestrictedCameraRotation(self): 786 activeCamera = self.GetActivePrimaryCamera() 787 if activeCamera and activeCamera.cameraID == CAM_SHIPORBIT_RESTRICTED: 788 activeCamera.EnableRotation() 789 790 def FadeOut(self, duration, sleep = False): 791 self.FadeTo(duration, fromValue=1.0, toValue=0.0, sleep=sleep) 792 793 def FadeIn(self, duration, color = (0.0, 0.0, 0.0, 1.0), sleep = False): 794 self.FadeTo(duration, color, fromValue=0.0, toValue=1.0, sleep=sleep) 795 796 def FadeTo(self, duration, color = None, fromValue = 0.0, toValue = 1.0, sleep = False): 797 fadeObject = self.GetFadeObject(create=True) 798 self.currentFadeIntensity = toValue 799 if fadeObject is not None: 800 if color is not None: 801 fadeObject.color = color 802 uicore.animations.MorphScalar(fadeObject, 'intensity', startVal=fromValue, endVal=toValue, duration=duration, sleep=sleep) 803 804 def FadeVignetteToIntensityAndOpacity(self, duration, vignetteSettings, color = None, fromIntensity = 0.0, toIntensity = 1.0, fromOpacity = 0.0, toOpacity = 1.0, sleep = False): 805 vignetteObject = self.GetVignetteObject(vignetteSettings, create=True) 806 self.currentFadeIntensity = toIntensity 807 if vignetteObject is not None: 808 if color is not None: 809 vignetteObject.color = color 810 uicore.animations.MorphScalar(vignetteObject, 'intensity', startVal=fromIntensity, endVal=toIntensity, duration=duration, sleep=sleep) 811 uicore.animations.MorphScalar(vignetteObject, 'opacity', startVal=fromOpacity, endVal=toOpacity, duration=duration, sleep=sleep) 812 813 def Saturate(self, duration, saturateLevel): 814 uthread.new(self._Saturate, duration, saturateLevel) 815 816 def _Saturate(self, duration, saturateLevel): 817 effect = self.GetDesaturateObject(create=True) 818 if effect is not None: 819 level = effect.intensity 820 self.currentDesaturateLevel = saturateLevel 821 uicore.animations.MorphScalar(effect, 'intensity', startVal=level, endVal=saturateLevel, duration=duration) 822 823 def ToggleEnable3DView(self): 824 self.enable3DView = not self.enable3DView 825 self._Update3DViewDisplayState() 826 827 def _Update3DViewDisplayState(self): 828 scenesToToggle = ['default', 'hangar', 'transition'] 829 for sceneName in scenesToToggle: 830 if sceneName in self.registeredScenes: 831 self.registeredScenes[sceneName].display = self.enable3DView 832 833 if hasattr(self, 'hidden3DViewWarningContainer') and self.hidden3DViewWarningContainer is not None: 834 self.hidden3DViewWarningContainer.Close() 835 self.hidden3DViewWarningContainer = None 836 if not self.enable3DView: 837 self.hidden3DViewWarningContainer = Toggled3DViewWarning(parent=uicore.desktop, name='exterior_view_hider') 838 self.hidden3DViewWarningContainer.Show() 839 uicore.animations.FadeOut(self.hidden3DViewWarningContainer, 4.0, timeOffset=20.0, callback=self.hidden3DViewWarningContainer.Hide) 840 841 def OnViewStateChanged(self, from_view, to_view): 842 self._Update3DViewDisplayState() 843 if from_view != ViewState.CharacterCreation and to_view == ViewState.CharacterSelector: 844 self.SetActiveScene(trinity.EveSpaceScene()) 845 self.ClearSecondaryScene() 846 847 def SwitchFromRestrictedCameraOnReset(self): 848 self.cameraBeforeVirtual = None 849 self.cameraBeforeRestriction = None 850 self.SwitchFromRestrictedCamera() 851 852 853 class Toggled3DViewWarning(ContainerAutoSize): 854 default_align = uiconst.CENTERTOP 855 default_state = uiconst.UI_DISABLED 856 857 def ApplyAttributes(self, attributes): 858 super(Toggled3DViewWarning, self).ApplyAttributes(attributes) 859 mainCont = ContainerAutoSize(parent=self, align=uiconst.CENTERTOP, alignMode=uiconst.TOTOP, top=230, width=400, bgColor=(0.1, 0.1, 0.1, 0.5)) 860 EveCaptionLarge(parent=mainCont, align=uiconst.TOTOP, text='<center>%s</center>' % GetByLabel('UI/Shared/ExteriorViewDisabled'), padding=(4, 4, 4, 4)) 861 command = uicore.cmd.commandMap.GetCommandByName('CmdToggle3DView') 862 EveLabelLarge(parent=mainCont, align=uiconst.TOTOP, text='<center>%s</center>' % GetByLabel('UI/Shared/PressToRestoreView', shortcut=command.GetShortcutAsString()), padding=(4, 4, 4, 4))