portraitManager.py (14916B)
1 #Embedded file name: C:\BuildAgent\work\20d73f1b24eed06e\eve\release\V24.01\eve\client\script\ui\login\charcreation_new\portraitManager.py 2 import uthread 3 import telemetry 4 import utillib 5 from eve.common.script.util import paperDollUtil 6 import blue 7 import math 8 import geo2 9 from carbon.common.script.util import mathUtil 10 import eve.common.lib.appConst as const 11 from carbonui import uiconst 12 from carbonui.primitives.sprite import StreamingVideoSprite, Sprite 13 from carbonui.uicore import uicore 14 import evegraphics.settings as gfxsettings 15 import charactercreator.const as ccConst 16 import charactercreator.client.animparams as animparams 17 from eve.client.script.ui.login.charcreation_new.portraitMaker import PortraitMaker 18 from eve.client.script.ui.login.charcreation_new import ccUtil 19 from eve.client.script.ui.login.charcreation_new.sceneManager import GetCharacterCreationSceneManager 20 ccPortraitManager = None 21 22 def GetCharacterCreationPortraitManager(): 23 global ccPortraitManager 24 if ccPortraitManager is None: 25 ccPortraitManager = CharacterCreationPortraitManager() 26 return ccPortraitManager 27 28 29 class CharacterCreationPortraitManager(object): 30 31 def __init__(self): 32 self.characterSvc = sm.GetService('character') 33 self.animateToStoredPortraitThread = None 34 self.animatingToPortraitID = None 35 self.portraitInfo = {} 36 self.facePortraits = {} 37 self.activePortraitIndex = 0 38 self.activePortrait = None 39 self.backdropPath = None 40 self.alreadyLoadedOldPortraitData = False 41 self.poseID = 0 42 43 def Initialize(self): 44 self.alreadyLoadedOldPortraitData = False 45 46 def TearDown(self): 47 self.animateToStoredPortraitThread = None 48 self.animatingToPortraitID = None 49 50 def Cleanup(self): 51 pass 52 53 @telemetry.ZONE_METHOD 54 def ClearFacePortrait(self, *args): 55 self.facePortraits = [None] * ccConst.NUM_PORTRAITS 56 self.portraitInfo = [None] * ccConst.NUM_PORTRAITS 57 self.activePortraitIndex = 0 58 self.activePortrait = None 59 60 @telemetry.ZONE_METHOD 61 def GetPortraitInfo(self, portraitID): 62 return self.portraitInfo[portraitID] 63 64 @telemetry.ZONE_METHOD 65 def SetActivePortrait(self, portraitNo, *args): 66 self.activePortraitIndex = portraitNo 67 self.activePortrait = self.facePortraits[portraitNo] 68 69 @telemetry.ZONE_METHOD 70 def GetActivePortrait(self): 71 return self.activePortrait 72 73 @telemetry.ZONE_METHOD 74 def GetActivePortraitInfo(self): 75 return self.portraitInfo[self.activePortraitIndex] 76 77 @telemetry.ZONE_METHOD 78 def SetFacePortrait(self, photo, portraitNo, *args): 79 self.facePortraits[portraitNo] = photo 80 self.SetActivePortrait(portraitNo) 81 82 @telemetry.ZONE_METHOD 83 def SetBackdrop(self, backdropPath): 84 self.backdropPath = backdropPath 85 86 @telemetry.ZONE_METHOD 87 def GetBackdrop(self): 88 return self.backdropPath 89 90 @telemetry.ZONE_METHOD 91 def SetPoseID(self, poseID): 92 self.poseID = poseID 93 94 @telemetry.ZONE_METHOD 95 def GetPoseID(self): 96 return self.poseID 97 98 @telemetry.ZONE_METHOD 99 def CapturePortrait(self, portraitID, camera, poseData, lightingID, lightColorID, lightIntensity): 100 self.portraitInfo[portraitID] = utillib.KeyVal(cameraPosition=camera.GetPosition(), cameraFieldOfView=camera.fieldOfView, cameraPoi=camera.GetPointOfInterest(), backgroundID=self.GetCurrentBackgroundID(), lightID=lightingID, lightColorID=lightColorID, lightIntensity=lightIntensity, poseData=poseData) 101 maker = PortraitMaker(camera, self.backdropPath) 102 self.activePortrait = maker.GetPortraitTexture(portraitID) 103 return self.activePortrait 104 105 @telemetry.ZONE_METHOD 106 def GetPortraitSnapshotPath(self, portraitID): 107 return blue.paths.ResolvePathForWriting(u'cache:/Pictures/Portraits/PortraitSnapshot_%s_%s.jpg' % (portraitID, session.userid)) 108 109 def AnimateToStoredPortrait(self, newPortraitID, charID): 110 if self.portraitInfo[newPortraitID] is None: 111 return 112 if self.animateToStoredPortraitThread and self.animateToStoredPortraitThread.alive: 113 if self.animatingToPortraitID == newPortraitID: 114 return 115 self.animateToStoredPortraitThread.kill() 116 self.animateToStoredPortraitThread = uthread.new(self.AnimateToStoredPortrait_thread, newPortraitID, charID) 117 118 def AnimateToStoredPortrait_thread(self, newPortraitID, charID): 119 portraitInfo = self.portraitInfo[newPortraitID] 120 if portraitInfo is None: 121 return 122 newParams = self.GetControlParametersFromPortraitID(newPortraitID, charID) 123 if newParams is None: 124 return 125 oldParams = self.GetControlParametersFromPortraitID(None, charID) 126 if len(oldParams) < 1 or len(newParams) < 1: 127 return 128 sceneManager = GetCharacterCreationSceneManager() 129 self.animatingToPortraitID = newPortraitID 130 thereIsCamera = sceneManager.camera is not None 131 oldCameraPos = None 132 oldCameraPoi = None 133 if thereIsCamera: 134 oldCameraPos = sceneManager.camera.cameraPosition 135 oldCameraPoi = sceneManager.camera.poi 136 start, ndt = blue.os.GetWallclockTime(), 0.0 137 moveCamera = sceneManager.ShouldMoveCamera(portraitInfo.cameraPosition, portraitInfo.cameraPoi) 138 while ndt != 1.0: 139 timeValue = min(blue.os.TimeDiffInMs(start, blue.os.GetWallclockTime()) / 250.0, 1.0) 140 ndt = math.sin(timeValue * math.pi - math.pi / 2.0) / 2.0 + 0.5 141 params = [] 142 for shortKey, keyAndValue in oldParams.iteritems(): 143 longKey, value = keyAndValue 144 if shortKey == 'HeadLookTarget': 145 lerpedValue = geo2.Lerp(value, newParams[shortKey][1], ndt) 146 elif shortKey == 'PortraitPoseNumber': 147 continue 148 else: 149 lerpedValue = mathUtil.Lerp(value, newParams[shortKey][1], ndt) 150 params.append([longKey, lerpedValue]) 151 152 self.characterSvc.SetControlParametersFromList(params, charID) 153 if thereIsCamera and moveCamera: 154 posValue = geo2.Lerp(oldCameraPos, portraitInfo.cameraPosition, ndt) 155 poiValue = geo2.Lerp(oldCameraPoi, portraitInfo.cameraPoi, ndt) 156 sceneManager.cameraPos = posValue 157 sceneManager.cameraPoi = poiValue 158 sceneManager.camera.PlacePortraitCamera(sceneManager.cameraPos, sceneManager.cameraPoi) 159 blue.pyos.synchro.Yield() 160 161 xFactor, yFactor = sceneManager.camera.GetCorrectCameraXandYFactors(portraitInfo.cameraPosition, portraitInfo.cameraPoi) 162 sceneManager.camera.xFactor = sceneManager.camera.xTarget = xFactor 163 sceneManager.camera.yFactor = sceneManager.camera.yTarget = yFactor 164 sceneManager.lightingID = portraitInfo.lightID 165 sceneManager.lightIntensity = portraitInfo.lightIntensity 166 sceneManager.lightColorID = portraitInfo.lightColorID 167 shouldSnapPortrait = False 168 path = self.GetBackgroundPathFromID(portraitInfo.backgroundID) 169 if path in self.GetAvailableBackgroundsPaths(): 170 self.backdropPath = path 171 elif not gfxsettings.Get(gfxsettings.UI_NCC_GREEN_SCREEN): 172 shouldSnapPortrait = True 173 self.poseID = int(portraitInfo.poseData['PortraitPoseNumber']) 174 self.characterSvc.SetControlParametersFromList([['ControlParameters|PortraitPoseNumber', float(self.poseID)]], charID) 175 self.UpdateBackdrop() 176 sceneManager.UpdateLights() 177 sm.ScatterEvent('OnPortraitPicked') 178 if shouldSnapPortrait and uicore.layer.charactercreation.controller.step: 179 uicore.layer.charactercreation.controller.step.CapturePortrait(newPortraitID) 180 181 def GetControlParametersFromPortraitID(self, portraitID, charID): 182 PREFIX = 'ControlParameters|' 183 params = {} 184 if portraitID is not None: 185 portraitInfo = self.portraitInfo[portraitID] 186 if portraitInfo is None: 187 return {} 188 return self.GetControlParametersFromPoseData(portraitInfo.poseData) 189 avatar = self.characterSvc.GetSingleCharactersAvatar(charID) 190 if avatar is None: 191 return {} 192 for controlParameter in paperDollUtil.FACIAL_POSE_PARAMETERS.__dict__.iterkeys(): 193 if controlParameter.startswith('_'): 194 continue 195 longKey = PREFIX + controlParameter 196 network = animparams.GetParamsPerAvatar(avatar, charID) 197 value = network.GetControlParameterValue(longKey) 198 params[controlParameter] = (longKey, value) 199 200 return params 201 202 def GetControlParametersFromPoseData(self, poseData, fromDB = False): 203 if poseData is None: 204 return {} 205 if fromDB: 206 allParameterKeys = poseData.__keys__ 207 else: 208 allParameterKeys = poseData.keys() 209 params = {} 210 PREFIX = 'ControlParameters|' 211 for key in allParameterKeys: 212 if key in ('headLookTargetX', 'headLookTargetY', 'headLookTargetZ', 'cameraX', 'cameraY', 'cameraZ'): 213 continue 214 value = poseData[key] 215 if fromDB: 216 key = key.replace(key[0], key[0].upper(), 1) 217 params[key] = (PREFIX + key, value) 218 219 if fromDB: 220 params['HeadLookTarget'] = (PREFIX + 'HeadLookTarget', (poseData['headLookTargetX'], poseData['headLookTargetY'], poseData['headLookTargetZ'])) 221 return params 222 223 @telemetry.ZONE_METHOD 224 def GetBackgroundPathFromID(self, bgID): 225 if bgID < const.NCC_MIN_NORMAL_BACKGROUND_ID: 226 return 'res:/UI/Texture/CharacterCreation/backdrops/Background_' + str(bgID) + '.dds' 227 resourceRow = cfg.paperdollPortraitResources.Get(bgID) 228 if resourceRow: 229 return resourceRow.resPath 230 231 def GetAvailableBackgroundsPaths(self): 232 bgOptions = [] 233 if gfxsettings.Get(gfxsettings.UI_NCC_GREEN_SCREEN): 234 bgOptions += ccConst.greenscreenBackgroundOptions 235 authoredBackgrounds = self.characterSvc.GetAvailableBackgrounds() 236 for eachResource in authoredBackgrounds: 237 path = eachResource.resPath 238 bgOptions.append(path) 239 240 return bgOptions 241 242 @telemetry.ZONE_METHOD 243 def GetCurrentBackgroundID(self): 244 authoredBackground = self.characterSvc.GetPortraitResourceByPath(self.backdropPath) 245 if authoredBackground: 246 return authoredBackground.portraitResourceID 247 ID = self.backdropPath.split('_')[-1].split('.')[0] 248 try: 249 ID = int(ID) 250 except ValueError: 251 return None 252 253 return ID 254 255 @telemetry.ZONE_METHOD 256 def FetchOldPortraitData(self, charID): 257 sceneManager = GetCharacterCreationSceneManager() 258 PREFIX = 'ControlParameters|' 259 cache = self.characterSvc.GetCachedPortraitInfo(charID) 260 if cache is not None: 261 sceneManager.lightingID = cache.lightID 262 sceneManager.lightColorID = cache.lightColorID 263 sceneManager.lightIntensity = cache.lightIntensity 264 path = self.GetBackgroundPathFromID(cache.backgroundID) 265 if path in self.GetAvailableBackgroundsPaths(): 266 self.SetBackdrop(path) 267 self.poseID = cache.poseData['PortraitPoseNumber'] 268 sceneManager.cameraPos = cache.cameraPosition 269 sceneManager.cameraPoi = cache.cameraPoi 270 sceneManager.cameraFov = cache.cameraFieldOfView 271 params = [] 272 for key in cache.poseData: 273 params.append((PREFIX + key, cache.poseData[key])) 274 275 if len(params): 276 self.characterSvc.SetControlParametersFromList(params, charID) 277 else: 278 portraitData = sm.GetService('cc').GetPortraitData(charID) 279 if portraitData is not None: 280 sceneManager.lightingID = portraitData.lightID 281 sceneManager.lightColorID = portraitData.lightColorID 282 sceneManager.lightIntensity = portraitData.lightIntensity 283 path = self.GetBackgroundPathFromID(portraitData.backgroundID) 284 if path in self.GetAvailableBackgroundsPaths(): 285 self.SetBackdrop(path) 286 self.poseID = portraitData.portraitPoseNumber 287 sceneManager.cameraPos = (portraitData.cameraX, portraitData.cameraY, portraitData.cameraZ) 288 sceneManager.cameraPoi = (portraitData.cameraPoiX, portraitData.cameraPoiY, portraitData.cameraPoiZ) 289 sceneManager.cameraFov = portraitData.cameraFieldOfView 290 params = self.GetControlParametersFromPoseData(portraitData, fromDB=True).values() 291 self.characterSvc.SetControlParametersFromList(params, charID) 292 self.alreadyLoadedOldPortraitData = True 293 294 @telemetry.ZONE_METHOD 295 def UpdateBackdrop(self): 296 uiRoot = sm.GetService('sceneManager').characterBackdropUIRoot 297 if not uiRoot: 298 return 299 uiRoot.Flush() 300 stepID = uicore.layer.charactercreation.controller.stepID 301 if gfxsettings.Get(gfxsettings.UI_NCC_GREEN_SCREEN): 302 Sprite(name='greenScreenSprite', parent=uiRoot, align=uiconst.TOALL, texturePath='res:/UI/Texture/CharacterCreation/backdrops/Background_1001_thumb.dds') 303 elif stepID == ccConst.PORTRAITSTEP: 304 activeBackdrop = self.GetBackdrop() 305 if activeBackdrop: 306 height, width = self.GetBackgroundWidthAndHeight(ratio=1.0) 307 Sprite(name='bgSprite', parent=uiRoot, align=uiconst.CENTER, pos=(0, 308 0, 309 width, 310 height), texturePath=activeBackdrop) 311 elif stepID == ccConst.CUSTOMIZATIONSTEP: 312 videoPath = 'res:/UI/Texture/Classes/CharacterSelection/EmpireSelection/customizeBG.webm' 313 self.ConstructBackgroundVideo(uiRoot, videoPath, ratio=16.0 / 9.0) 314 elif stepID in (ccConst.NAMINGSTEP, ccConst.DOLLSTEP): 315 videoPath = 'res:/UI/Texture/Classes/CharacterSelection/EmpireSelection/backgroundVideo.webm' 316 self.ConstructBackgroundVideo(uiRoot, videoPath, ratio=16.0 / 9.0) 317 318 def ConstructBackgroundVideo(self, uiRoot, videoPath, ratio): 319 height, width = self.GetBackgroundWidthAndHeight(ratio) 320 StreamingVideoSprite(parent=uiRoot, align=uiconst.CENTER, pos=(0, 321 0, 322 width, 323 height), videoPath=videoPath, videoLoop=True) 324 325 def GetBackgroundWidthAndHeight(self, ratio): 326 w, h = ccUtil.GetDpiScaledWidthAndHeight() 327 if float(w) / h <= ratio: 328 width = h * ratio 329 height = h 330 else: 331 width = w 332 height = w / ratio 333 return (height, width)