shipSceneContainer.py (14549B)
1 #Embedded file name: C:\BuildAgent\work\20d73f1b24eed06e\eve\release\V24.01\eve\client\script\ui\shared\fitting\shipSceneContainer.py 2 import math 3 import eveui 4 import geo2 5 from eve.client.script.ui.control.scenecontainer import SceneContainer 6 from eveSpaceObject import spaceobjanimation 7 import evetypes 8 from fsdBuiltData.common.graphicIDs import GetSofFactionName 9 from iconrendering2.renderers.renderer_hologram import ApplyIsisEffect 10 import log 11 from eve.client.script.environment.model.turretSet import TurretSet, StructureMoonMiningTurretSet 12 import trinity 13 import uthread 14 import blue 15 from inventorycommon.util import IsModularShip 16 from uthread2.callthrottlers import CallCombiner 17 from evegraphics.controllers.clientControllerRegistry import ChangeControllerStateFromSlimItem 18 from evegraphics.CosmeticsLoader import CosmeticsLoader 19 from shipcosmetics.client.fittingsgateway.fittingsSignals import on_ship_cosmetics_changed 20 import telemetry 21 import logging 22 from eve.client.script.environment.spaceObject.spaceObject import modify_dna 23 from eve.client.script.environment.spaceObject.cosmeticsManager import CosmeticsManager 24 from cosmetics.common.structures.const import StructurePaintSlot 25 from cosmetics.common.structures.fitting import StructurePaintwork 26 import paints.data.dataLoader as dl 27 from inventorycommon.const import categoryStructure 28 from eve.common.script.sys.idCheckers import IsStructure, IsShipType 29 from cosmetics.common.ships.skins.static_data.slot_configuration import is_skinnable_ship 30 from cosmetics.common.ships.skins.static_data.skin_type import ShipSkinType 31 logger = logging.getLogger(__name__) 32 33 class ShipSceneContainer(SceneContainer): 34 __notifyevents__ = ['ProcessFittingWindowStartMinimize', 35 'ProcessFittingWindowEndMinimize', 36 'OnSessionChanged', 37 'OnCorpLogoReady', 38 'OnAllianceLogoReady'] 39 40 @telemetry.ZONE_METHOD 41 def ApplyAttributes(self, attributes): 42 SceneContainer.ApplyAttributes(self, attributes) 43 self.controller = attributes.controller 44 self.model = None 45 if hasattr(self.controller, 'on_new_itemID'): 46 self.controller.on_new_itemID.connect(self.ReloadShipWhenChangingShips) 47 if hasattr(self.controller, 'on_subsystem_fitted'): 48 self.controller.on_subsystem_fitted.connect(self.ReloadShipModelWithoutAnimation) 49 if hasattr(self.controller, 'on_hardpoints_fitted'): 50 self.controller.on_hardpoints_fitted.connect(self.UpdateHardpoints) 51 if hasattr(self.controller, 'on_module_online_state'): 52 self.controller.on_module_online_state.connect(self.ProcessOnlineStateChange) 53 if hasattr(self.controller, 'on_skin_material_changed'): 54 self.controller.on_skin_material_changed.connect(self.OnSkinChanged) 55 if hasattr(self.controller, 'on_stance_activated'): 56 self.controller.on_stance_activated.connect(self.OnStanceActive) 57 on_ship_cosmetics_changed.connect(self.OnShipCosmeticsChanged) 58 self.CreateActiveShipModelThrottled = CallCombiner(self.CreateActiveShipModel, 1.0) 59 sm.RegisterNotify(self) 60 61 def LoadShipModel(self): 62 uthread.new(self.ReloadShipModel) 63 64 def _SetModelOffsetWhenReady(self, model): 65 if model is None: 66 return 67 maxDelay = 2.0 68 currentDelay = 0.0 69 checkDelay = 50.0 70 while not max(model.generatedShapeEllipsoidRadius) != -1: 71 if self.destroyed: 72 return 73 if currentDelay > maxDelay: 74 return 75 blue.synchro.SleepWallclock(checkDelay) 76 currentDelay += checkDelay / 1000.0 77 78 modelOffset = getattr(model, 'generatedShapeEllipsoidCenter', (0.0, 0.0, 0.0)) 79 locatorSets = getattr(model, 'locatorSets', None) 80 if locatorSets: 81 lookAtLocator = locatorSets.FindByName('camera_look_at') 82 if lookAtLocator is not None and len(lookAtLocator.locators) > 0: 83 modelOffset = lookAtLocator.locators[0][0] 84 if model.translationCurve is None: 85 model.translationCurve = trinity.Tr2CurveConstant() 86 invertedModelOffset = geo2.Vec3Scale(modelOffset, -1.0) 87 model.translationCurve.value = invertedModelOffset 88 89 def PrepareSpaceScene(self, maxPitch = None, scenePath = None, offscreen = False, resetZoom = True): 90 super(ShipSceneContainer, self).PrepareSpaceScene(maxPitch=None, scenePath='res:/dx9/scene/fitting/fitting.red', resetZoom=True, offscreen=False) 91 if IsStructure(evetypes.GetCategoryID(self.controller.typeID)): 92 self.scene.sunDirection = (0.6198, -0.1016, -0.7781) 93 self.scene.nebulaIntensity = 1.25 94 self.scene.reflectionIntensity = 1.55 95 self.scene.sunDiffuseColor = (1.0, 96 205.0 / 255.0, 97 170.0 / 255.0, 98 1.0) 99 self.scene.postprocess.taa = None 100 101 @eveui.skip_if_destroyed 102 def OnSkinChanged(self): 103 if self.controller.itemID != session.shipid: 104 return 105 self.ReloadShipModel(animate=False) 106 107 def _get_material_name(self, slot): 108 if slot is not None: 109 return dl.get_paint_material_name(slot) 110 111 def OnShipCosmeticsChanged(self, _, cosmetics_types): 112 if self.controller.itemID != session.shipid: 113 return 114 enabledCosmetics = sm.GetService('cosmeticsSvc').get_enabled_ship_cosmetics(session.shipid) 115 cosmeticsLoader = CosmeticsLoader((CosmeticsLoader.ALLIANCE, CosmeticsLoader.CORP)) 116 uthread.new(cosmeticsLoader.SetCosmeticsOnShip, self.model, enabledCosmetics) 117 118 def OnCorpLogoReady(self, _corpID, _size): 119 self._UpdateShipCosmetics() 120 121 def OnAllianceLogoReady(self, _allianceID, _size): 122 self._UpdateShipCosmetics() 123 124 def OnSessionChanged(self, _isremote, _session, change): 125 if 'corpid' in change or 'allianceid' in change: 126 self._UpdateShipCosmetics() 127 128 def _UpdateShipCosmetics(self): 129 enabledCosmetics = sm.GetService('cosmeticsSvc').get_enabled_ship_cosmetics(session.shipid) 130 self.OnShipCosmeticsChanged(session.shipid, enabledCosmetics) 131 132 @eveui.skip_if_destroyed 133 def ReloadShipModelWithoutAnimation(self, *args, **kwargs): 134 self.ReloadShipModel(animate=False) 135 136 @eveui.skip_if_destroyed 137 def ReloadShipWhenChangingShips(self, shipID, oldShipID, shipTypeID, oldShipTypeID): 138 animate = True 139 if self.controller.IsSimulated() and shipTypeID == oldShipTypeID: 140 animate = False 141 self.ReloadShipModel(animate=animate) 142 143 def _SearchAndRemoveObservers(self): 144 while len(self.model.observers) > 0: 145 self.model.observers.pop() 146 147 emitters = [ observer.name for observer in self.model.Find('trinity.TriObserverLocal') ] 148 childContainers = self.model.effectChildren.Find('trinity.EveChildContainer') 149 for container in childContainers: 150 if hasattr(container, 'observers'): 151 while len(container.observers) > 0: 152 popped = container.observers.pop() 153 if popped.name in emitters: 154 emitters.remove(popped.name) 155 156 if len(emitters) == 0: 157 break 158 159 @telemetry.ZONE_METHOD 160 def ReloadShipModel(self, throttle = False, animate = True): 161 if self.destroyed: 162 return 163 with self._reloadLock: 164 self.model = None 165 if throttle: 166 self.model = self.CreateActiveShipModelThrottled() 167 else: 168 self.model = self.CreateActiveShipModel() 169 if not self.model: 170 try: 171 if IsModularShip(self.controller.typeID) and self.controller.IsSimulated(): 172 del self.scene.objects[:] 173 except Exception: 174 pass 175 176 return 177 if IsStructure(evetypes.GetCategoryID(self.controller.typeID)): 178 sof = sm.GetService('sofService').spaceObjectFactory 179 dna = self.model.dna 180 paintwork = sm.GetService('cosmeticsSvc').get_structure_cosmetic_state(session.structureid, session.solarsystemid, force_refresh=False) 181 if paintwork is not None: 182 mat1 = self._get_material_name(paintwork.get_slot(StructurePaintSlot.PRIMARY)) 183 mat2 = self._get_material_name(paintwork.get_slot(StructurePaintSlot.SECONDARY)) 184 mat3 = self._get_material_name(paintwork.get_slot(StructurePaintSlot.DETAILING)) 185 dna = modify_dna(base_dna=dna, mat1=mat1, mat2=mat2, mat3=mat3, isStructure=True) 186 self.model = sof.BuildFromDNA(dna) 187 self._SearchAndRemoveObservers() 188 trinity.WaitForResourceLoads() 189 self.model.FreezeHighDetailMesh() 190 self.ModifyCameraToFitShip(animate, self.model) 191 self.AddToScene(self.model) 192 if self.controller.IsSimulated(): 193 ApplyIsisEffect(self.model) 194 if self.controller.ControllerForCategory() != const.categoryStructure: 195 self._AddGridToScene(self.scene, self.model) 196 if animate: 197 self.AnimEntry(yaw1=1.2 * math.pi, pitch0=0.3, pitch1=0.5) 198 shipTypeID = self.controller.typeID 199 stanceBtnControllerClass = self.controller.GetStanceBtnControllerClass() 200 if stanceBtnControllerClass is None: 201 return 202 stanceID = stanceBtnControllerClass().get_ship_stance(self.controller.itemID, shipTypeID) 203 if not self.controller.IsSimulated(): 204 slimItem = sm.GetService('michelle').GetItem(self.controller.itemID) 205 if slimItem is not None: 206 ChangeControllerStateFromSlimItem(shipTypeID, self.model, slimItem) 207 cosmeticsLoader = CosmeticsLoader((CosmeticsLoader.ALLIANCE, CosmeticsLoader.CORP)) 208 cosmeticsLoader.Load(self.model, slimItem) 209 spaceobjanimation.SetShipAnimationStance(self.model, stanceID) 210 spaceobjanimation.TriggerDefaultStates(self.model) 211 enabledCosmetics = sm.GetService('cosmeticsSvc').get_enabled_ship_cosmetics(session.shipid) 212 cosmeticsLoader = CosmeticsLoader((CosmeticsLoader.ALLIANCE, CosmeticsLoader.CORP)) 213 uthread.new(cosmeticsLoader.SetCosmeticsOnShip, self.model, enabledCosmetics) 214 if self.controller.IsSimulated(): 215 for eachEffect in getattr(self.model, 'effectChildren', []): 216 eachEffect.display = False 217 218 else: 219 self.UpdateHardpoints(self.model) 220 221 def _AddGridToScene(self, scene, shipModel): 222 rad = shipModel.GetBoundingSphereRadius() 223 scaling = (4, 4, 4) 224 translation = (0, -rad / 2, 0) 225 grid = trinity.Load('res:/dx9/model/UI/ScanGrid.red') 226 grid.scaling = scaling 227 grid.translation = translation 228 scene.objects.append(grid) 229 grid2 = trinity.Load('res:/dx9/model/UI/ScanGrid.red') 230 grid2.rotation = (0, 0, 1, 0) 231 grid2.scaling = scaling 232 grid2.translation = translation 233 scene.objects.append(grid2) 234 235 def ModifyCameraToFitShip(self, animate, shipModel): 236 camera = self.camera 237 if shipModel is not None and hasattr(shipModel, 'GetBoundingSphereCenter'): 238 rad = shipModel.GetBoundingSphereRadius() + geo2.Vec3Length(shipModel.GetBoundingSphereCenter()) 239 else: 240 rad = 1000.0 241 minZoom = rad + camera.nearClip 242 alpha = camera.fov / 2.0 243 maxZoom = min(self.backClip - rad, rad * (1 / math.tan(alpha)) * 2) 244 oldZoomDistance = self.minZoom + (self.maxZoom - self.minZoom) * self.zoom 245 defaultZoom = minZoom / (maxZoom - minZoom) 246 self.SetMinMaxZoom(minZoom, maxZoom) 247 if animate or oldZoomDistance < minZoom or oldZoomDistance > maxZoom: 248 self.SetZoom(defaultZoom) 249 250 @telemetry.ZONE_METHOD 251 def CreateActiveShipModel(self): 252 newModel = self.controller.model 253 if not newModel: 254 return 255 if hasattr(newModel, 'ChainAnimationEx'): 256 newModel.ChainAnimationEx('NormalLoop', 0, 0, 1.0) 257 newModel.display = 1 258 newModel.name = str(self.controller.itemID) 259 translation = trinity.Tr2CurveConstant() 260 newModel.translationCurve = translation 261 translation.value = geo2.Vec3Scale(newModel.GetBoundingSphereCenter(), -1) 262 uthread.new(self._SetModelOffsetWhenReady, newModel) 263 return newModel 264 265 @telemetry.ZONE_METHOD 266 @eveui.skip_if_destroyed 267 def UpdateHardpoints(self, newModel = None): 268 if newModel is None: 269 newModel = self.GetSceneShip() 270 if newModel is None: 271 log.LogError('UpdateHardpoints - No model!') 272 return 273 factionName = GetSofFactionName(evetypes.GetGraphicID(self.controller.typeID)) 274 fittetTurretSets = TurretSet.FitTurrets(self.controller.itemID, newModel, factionName) 275 for ts in fittetTurretSets.values(): 276 if isinstance(ts, StructureMoonMiningTurretSet): 277 ts.Display() 278 279 @telemetry.ZONE_METHOD 280 def GetSceneShip(self): 281 for model in self.scene.objects: 282 if getattr(model, 'name', None) == str(self.controller.itemID): 283 return model 284 285 @telemetry.ZONE_METHOD 286 def PlayDeploymentAnimation(self, slot, dogmaItem): 287 sceneShip = self.GetSceneShip() 288 if sceneShip is not None: 289 for turret in getattr(sceneShip, 'turretSets', []): 290 if turret.slotNumber != slot: 291 continue 292 if dogmaItem.IsOnline(): 293 turret.EnterStateIdle() 294 else: 295 turret.EnterStateDeactive() 296 break 297 298 @eveui.skip_if_destroyed 299 def OnStanceActive(self, stanceID): 300 spaceobjanimation.SetShipAnimationStance(self.GetSceneShip(), stanceID) 301 302 def _OnClose(self, *args): 303 sm.UnregisterNotify(self) 304 SceneContainer._OnClose(self) 305 306 @eveui.skip_if_destroyed 307 def ProcessOnlineStateChange(self, dogmaItem): 308 if self.destroyed: 309 return 310 slot = dogmaItem.flagID - const.flagHiSlot0 + 1 311 if slot is not None: 312 self.PlayDeploymentAnimation(slot, dogmaItem) 313 314 def ProcessFittingWindowStartMinimize(self): 315 self.Hide() 316 317 def ProcessFittingWindowEndMinimize(self): 318 self.Show()