def DoBake_t(self, projectedDecalModifier): while self.doingDecal or self.doingAvatar: PD.Yield() self.bakeScene = trinity.WodBakingScene() self.bakeScene.Avatar = self.__avatar if projectedDecalModifier.decalData.bodyEnabled: while not projectedDecalModifier.mapD[ PD.DOLL_PARTS.BODY].isPrepared: PD.Yield(frameNice=False) bodyTex = projectedDecalModifier.mapD[PD.DOLL_PARTS.BODY] self._Bake(bodyTex, (0.0, 0.0, 2.0, 1.0)) self._ExpandOpaque(PD.DOLL_PARTS.BODY, bodyTex) elif projectedDecalModifier.mapD.get(PD.DOLL_PARTS.BODY): del projectedDecalModifier.mapD[PD.DOLL_PARTS.BODY] if projectedDecalModifier.decalData.headEnabled: while not projectedDecalModifier.mapD[ PD.DOLL_PARTS.HEAD].isPrepared: PD.Yield(frameNice=False) headTex = projectedDecalModifier.mapD[PD.DOLL_PARTS.HEAD] self._Bake(headTex, (-0.5, 0.0, 2.0, 2.0)) self._ExpandOpaque(PD.DOLL_PARTS.HEAD, headTex) elif projectedDecalModifier.mapD.get(PD.DOLL_PARTS.HEAD): del projectedDecalModifier.mapD[PD.DOLL_PARTS.HEAD] self.bakeScene = None self.isReady = True
def _StartTest(self): BenchmarkTest._StartTest(self) pdc = PD.PaperDollCharacter(self.factory) pdc.doll = PD.Doll('TestDoll') if self.resPath: pdc.doll.Load(self.resPath, self.factory) pdc.doll.overrideLod = self.startLOD spawnKey = 'Spawning doll at LOD {0}'.format(self.startLOD) self.results.PunchIn(spawnKey) pdc.Spawn(self.scene, usePrepass=self.usePrepass) while pdc.doll.busyUpdating: PD.Yield() self.results.PunchOut(spawnKey) while pdc.doll.overrideLod != self.endLOD: nextLOD = pdc.doll.overrideLod + self.lodDelta spawnKey = 'Switching from LOD {0} to LOD {1}'.format(pdc.doll.overrideLod, nextLOD) self.results.PunchIn(spawnKey) pdc.doll.overrideLod = nextLOD pdc.Update() while pdc.doll.busyUpdating: PD.Yield() self.results.PunchOut(spawnKey) PD.Yield()
def HighlightPreview(self, isMale = True): import time self.previewingHighlight = True start = time.time() self.highlightGhost.Start(self.avatar) self.bodyHighlightGhost.Start(self.avatar) if self.mode == 'sculpt': sequence = [10.1, 11.1, 17, 13, 1, 15, 2, 3, 4, 12, 18, 5, 14.1, 7, 9.1, 8, 6] for i, each in enumerate(sequence): self.highlightGhost.SetActiveZoneColor((2.0, 2.0, 2.0, each * 10 / 255.0)) while time.time() < start + (i + 1) / 3.0: PD.Yield(frameNice=False) else: numZones = 0 if self.mode == 'hair': numZones = 2 if isMale: numZones = 3 elif self.mode == 'bodyselect': numZones = 5 elif self.mode == 'makeup': numZones = 3 for i in range(numZones + 1): if self.mode == 'bodyselect': self.bodyHighlightGhost.SetActiveZoneColor((1.0, 1.0, 1.0, i * 10 / 255.0)) else: self.highlightGhost.SetActiveZoneColor((2.0, 2.0, 2.0, i * 10 / 255.0)) while time.time() < start + i / 3.0: PD.Yield(frameNice=False) self.highlightGhost.Stop() self.bodyHighlightGhost.Stop() self.previewingHighlight = False
def _StartTest(self): BenchmarkTest._StartTest(self) self.points = zip(range(self.numChars / 2) * 2, [0] * self.numChars, [0] * (self.numChars / 2) + [1] * (self.numChars / 2)) self.SpawnDolls(0, self.maxLOD0) self.SpawnDolls(1, self.maxLOD1) self.SpawnDolls(2, self.maxLOD2) PD.Yield() while PD.LodQueue.instance.queue: PD.Yield() if not self.debugMode: del self.paperDollCharacters[:]
def ExecuteTest(self, onTestExecution=None): """ Executes the currently set test, note that test execution happens in a tasklet. If onTestExecution is given, it is a function accepting a test and will be called prior to each test iteration """ def OnTestEnd(): result = self.test.GetResult() self.results[self.currentIteration] = result if self.currentIteration < self.iterations - 1: if onTestExecution: onTestExecution(self.test) if self.clearCacheOnEachIteration: self.ClearCaches() self.test.Execute(callBack=OnTestEnd) self.currentIteration += 1 if onTestExecution: onTestExecution(self.test) self.results.PunchIn(self.test.__class__) if self.clearCacheOnEachIteration: self.ClearCaches() self.test.Execute(callBack=OnTestEnd) while self.currentIteration < self.iterations - 1: PD.Yield() self.results.PunchOut(self.test.__class__)
def SetShader_t(self, avatar, targetsToIgnore, shaderres, allTargets=False): try: effect = trinity.Tr2Effect() effect.effectFilePath = shaderres while effect.effectResource.isLoading: PD.Yield() for mesh in avatar.visualModel.meshes: areasList = [ mesh.opaqueAreas, mesh.decalAreas, mesh.transparentAreas ] if allTargets or mesh.name not in targetsToIgnore: for areas in areasList: for area in areas: transformUV = None for p in area.effect.parameters: if p.name == 'TransformUV0': transformUV = p.value break area.effect.effectFilePath = shaderres area.effect.PopulateParameters() area.effect.RebuildCachedData() for p in area.effect.parameters: if p.name == 'TransformUV0': p.value = transformUV break except TaskletExit: raise
def MakeEffect(self): """ Creates an instance of AuraEffect and configures its resources. MakeEffect is always called in the context of a tasklet. """ self.effect = trinity.Tr2Effect() self.effect.effectFilePath = AURA_EFFECT_RES_PATH while self.effect.effectResource.isLoading: PD.Yield() self.effect.PopulateParameters() blurMask = blue.resMan.GetResource( 'res:/Graphics/Decals/caustics4.dds') auraTexture = blue.resMan.GetResource( 'res:/Graphics/Decals/caustics4.dds') setCount = 0 for resource in self.effect.resources: if resource.name == 'BlurMask': resource.SetResource(blurMask) setCount += 1 elif resource.name == 'AuraTexture': resource.SetResource(auraTexture) setCount += 1 if setCount == 2: break self.effect.RebuildCachedData()
def PreloadEffect(path): effect = trinity.Tr2Effect() effect.effectFilePath = path while effect.effectResource.isLoading: PD.Yield() effect.RebuildCachedData() return effect
def LoadFromRes(self, resPath): self.doll = PD.Doll(PaperDollCharacter.__DEFAULT_NAME) while not self.factory.IsLoaded: PD.Yield() self.doll.Load(resPath, self.factory) if self.avatar: self.doll.Update(self.factory, self.avatar)
def ActOnRandomModifier(self, fun, candidates): limit = len(candidates) if limit > 0: ridx = random.randint(0, limit) - 1 modifier = candidates[ridx] fun(modifier) print 'Modifier chosen is %s' % modifier.name self.pdc.doll.Update(self.pdc.factory, self.pdc.avatar) while self.pdc.doll.busyUpdating: PD.Yield() else: raise Exception('Candidates are empty!')
def BindHeroClothShader(effect, useDXT5n): path = effect.effectFilePath.lower() if 'clothavatar' not in path or 'clothavatarhair' in path: return suffix = '_dxt5n.fx' if useDXT5n else '.fx' effect.effectFilePath = ApplySuffix( 'res:/Graphics/Effect/Managed/Interior/Avatar/ClothAvatarLinear', suffix) while effect.effectResource.isLoading: PD.Yield() effect.PopulateParameters() PortraitTools.TweakDiffuseSampler(effect)
def RunSymmetricalSingleDollLODTest(coldCache=True, iterations=20, respaths=None, printStatistics=True): def fun(): results = PerformanceTestResults() key = 'Loading Factory' results.PunchIn(key) sTime = blue.os.GetWallclockTime() factory = PD.Factory() if respaths: factory.clothSimulationActive = True factory.WaitUntilLoaded() eTime = blue.os.GetWallclockTime() results.PunchOut(key) scene = SetupScene(usePrepass=True) onTestExecution = None if respaths: respathsIterator = itertools.cycle(respaths) def onTestExecution(x): x.resPath = respathsIterator.next() try: bm = Benchmarker(factory, scene, usePrepass=True) bm.clearCacheOnEachIteration = coldCache bm.iterations = iterations test0 = SingleDollTest(0, 2) bm.SetTest(test0) bm.ExecuteTest(onTestExecution) if printStatistics: import pprint pprint.pprint(bm.GetAnalyzedResults()) test1 = SingleDollTest(2, 0) bm.SetTest(test1) bm.ExecuteTest(onTestExecution) if printStatistics: pprint.pprint(bm.GetAnalyzedResults()) pprint.pprint(results) finally: trinity.renderJobs.UnscheduleByName(DEFAULT_PREPASS_RENDERJOB_NAME) testTasklet = uthread.new(fun) uthread.schedule(testTasklet) try: while testTasklet.alive: PD.Yield() except RuntimeError: PD.BeFrameNice()
def _ExpandOpaque(self, bodyPart, targetTex): eoMaskPath = 'res:/graphics/character/global/tattoomask/{0}_opaque_mask_{1}.dds'.format( self._gender, bodyPart) eoMaskRes = blue.resMan.GetResource(eoMaskPath) fx = trinity.Tr2Effect() fx.effectFilePath = EO_SHADERRES while eoMaskRes.isLoading or fx.effectResource.isLoading: PD.Yield() tex = trinity.TriTexture2DParameter() tex.name = 'Mask' tex.SetResource(eoMaskRes) fx.resources.append(tex) v = trinity.Tr2Vector2Parameter() v.name = 'gMaskSize' v.value = (eoMaskRes.width, eoMaskRes.height) fx.parameters.append(v) tex = trinity.TriTexture2DParameter() tex.name = 'Texture' tex.SetResource(targetTex) fx.resources.append(tex) v = trinity.Tr2Vector2Parameter() v.name = 'gTextureSize' v.value = (targetTex.width, targetTex.height) fx.parameters.append(v) fx.RebuildCachedData() vp = trinity.TriViewport() vp.width = targetTex.width vp.height = targetTex.height expandedRT = trinity.Tr2RenderTarget( vp.width, vp.height, 1, trinity.PIXEL_FORMAT.B8G8R8A8_UNORM) rj = trinity.CreateRenderJob('Expanding Opaque') rj.PushRenderTarget(expandedRT) rj.SetProjection(trinity.TriProjection()) rj.SetView(trinity.TriView()) rj.SetViewport(vp) rj.PushDepthStencil(None) rj.Clear((0.0, 0.0, 0.0, 0.0)) rj.SetStdRndStates(trinity.RM_FULLSCREEN) rj.SetRenderState(trinity.D3DRS_SEPARATEALPHABLENDENABLE, 1) rj.SetRenderState(trinity.D3DRS_SRCBLENDALPHA, trinity.TRIBLEND_ONE) rj.SetRenderState(trinity.D3DRS_DESTBLENDALPHA, trinity.TRIBLEND_ZERO) rj.RenderEffect(fx) rj.SetRenderTarget(targetTex.wrappedRenderTarget) rj.RenderTexture(expandedRT) rj.PopRenderTarget() rj.PopDepthStencil() rj.ScheduleChained() rj.WaitForFinish()
def RunCrowdSpawnTest(coldCache=True, iterations=20, respaths=None, maxLodQueueActive=1, debugMode=False, nrPerLod=None): def fun(): results = PerformanceTestResults() key = 'Loading Factory' results.PunchIn(key) sTime = blue.os.GetWallclockTime() factory = PD.Factory() if respaths: factory.clothSimulationActive = True factory.WaitUntilLoaded() eTime = blue.os.GetWallclockTime() results.PunchOut(key) scene = SetupScene(usePrepass=True) onTestExecution = None try: import pprint bm = Benchmarker(factory, scene, usePrepass=True) bm.clearCacheOnEachIteration = coldCache bm.iterations = 1 if debugMode else iterations totalDolls = sum(nrPerLod) if nrPerLod else 32 lod0Dolls = nrPerLod[0] if nrPerLod else 8 lod1Dolls = nrPerLod[1] if nrPerLod else 8 test0 = MultiDollTest(totalDolls, lod0Dolls, lod1Dolls, maxLodQueueActive=1, resPaths=respaths, debugMode=debugMode) bm.SetTest(test0) bm.ExecuteTest(onTestExecution) pprint.pprint(bm.GetAnalyzedResults()) finally: if not debugMode: trinity.renderJobs.UnscheduleByName( DEFAULT_PREPASS_RENDERJOB_NAME) testTasklet = uthread.new(fun) uthread.schedule(testTasklet) try: while testTasklet.alive: PD.Yield() except RuntimeError: PD.BeFrameNice()
def RunIncarnaCrowdTest(coldCache=True, iterations=20, respaths=None, maxLodQueueActive=1, debugMode=False): def fun(): results = PerformanceTestResults() key = 'Loading Factory' results.PunchIn(key) sTime = blue.os.GetWallclockTime() factory = PD.Factory() if respaths: factory.clothSimulationActive = True factory.WaitUntilLoaded() eTime = blue.os.GetWallclockTime() results.PunchOut(key) scene = SetupScene( sceneFile= 'res:/Graphics/Character/Global/DataUsedForTests/referenceEstablishment.red', usePrepass=True) onTestExecution = None try: import pprint bm = Benchmarker(factory, scene, usePrepass=True) bm.clearCacheOnEachIteration = coldCache bm.iterations = 1 if debugMode else iterations test0 = MultiDollTest(32, 8, 16, maxLodQueueActive=1, resPaths=respaths, debugMode=debugMode) bm.SetTest(test0) bm.ExecuteTest(onTestExecution) pprint.pprint(bm.GetAnalyzedResults()) finally: if not debugMode: trinity.renderJobs.UnscheduleByName( DEFAULT_PREPASS_RENDERJOB_NAME) testTasklet = uthread.new(fun) uthread.schedule(testTasklet) try: while testTasklet.alive: PD.Yield() except RuntimeError: PD.BeFrameNice()
def SetupStubble(meshes, name, stubblePath, adding=True): ret = [] stubbleName = '{0}Stubble'.format(name) stubbleMeshes = (mesh for mesh in meshes if mesh.name.startswith(PD.DOLL_PARTS.HEAD)) for mesh in stubbleMeshes: if adding: if any( map(lambda x: 'stubble' in x.name.lower(), mesh.decalAreas)): ret.append(mesh) continue c_skin_areas = ( area for area in mesh.opaqueAreas if area.effect.name.lower().startswith('c_skin_')) for area in c_skin_areas: stubbleArea = trinity.Tr2MeshArea() stubbleArea.name = stubbleName stubbleArea.index = area.index stubbleArea.count = area.count stubbleArea.effect = trinity.Load(stubblePath) for resource in stubbleArea.effect.resources: if resource.name == 'LengthTexture': while resource.resource.IsLoading(): PD.Yield() mesh.decalAreas.append(stubbleArea) ret.append(mesh) if PD.SkinSpotLightShadows.instance: PD.SkinSpotLightShadows.instance.CreateEffectParamsForMesh( mesh, False) for instance in PD.SkinLightmapRenderer.instances: if instance(): instance().BindLightmapShader(mesh) else: targetAreasToRemove = [ area for area in mesh.decalAreas if area.name == stubbleName ] for ta in targetAreasToRemove: mesh.decalAreas.remove(ta) return ret
def BindHeroShader(effect, isOptimized, suffix): if not isOptimized: effect.effectFilePath = 'res:/Graphics/Effect/Managed/Interior/Avatar/skinnedavatarbrdf_detailed' + suffix else: effect.effectFilePath = 'res:/Graphics/Effect/Managed/Interior/Avatar/avatarbrdfcombined_detailed' + suffix while effect.effectResource.isLoading: PD.Yield() effect.PopulateParameters() for res in effect.resources: if res.name == 'NormalDetailMap': res.resourcePath = 'res:/Texture/Global/NormalNoise_N.dds' break for par in effect.parameters: if par.name == 'NormalDetailStrength': par.value = 0.25 if par.name == 'NormalDetailTiling': par.value = 50.0
def MakeEffect(self): self.effect = trinity.Tr2Effect() self.effect.effectFilePath = AURA_EFFECT_RES_PATH while self.effect.effectResource.isLoading: PD.Yield() self.effect.PopulateParameters() blurMask = blue.resMan.GetResource('res:/Graphics/Decals/caustics4.dds') auraTexture = blue.resMan.GetResource('res:/Graphics/Decals/caustics4.dds') setCount = 0 for resource in self.effect.resources: if resource.name == 'BlurMask': resource.SetResource(blurMask) setCount += 1 elif resource.name == 'AuraTexture': resource.SetResource(auraTexture) setCount += 1 if setCount == 2: break self.effect.RebuildCachedData()
def SetDecal_t(self, avatar, decal, setTexture, setMask): if decal is None: return while self.doingAvatar or decal.BusyLoading(): PD.Yield(frameNice=False) for mesh in iter(avatar.visualModel.meshes): for effect in PD.GetEffectsFromMesh(mesh): effect.StartUpdate() for p in effect.parameters: valuesToSet = None if p.name == 'TattooYawPitchRoll': valuesToSet = decal.GetYPR() elif p.name == 'TattooPosition': valuesToSet = decal.GetPositionAndScale() elif p.name == 'TattooOptions': valuesToSet = decal.GetOptions() elif p.name == 'TattooDimensions': valuesToSet = decal.GetDimensions() elif p.name == 'TattooAspectRatio' and hasattr( decal, 'aspectRatio'): valuesToSet = decal.aspectRatio elif p.name == 'TattooPickingLayer': valuesToSet = decal.layer if type(valuesToSet) == tuple: valLen = len(valuesToSet) if valLen < len(p.value): valuesToSet = valuesToSet + p.value[valLen:] if valuesToSet: p.value = valuesToSet resourceNameFound = False if setTexture: resourceNameFound = self.SetTexture_t( 'TattooTextureMap', decal.textureResource, effect) if setMask and resourceNameFound: resourceNameFound = self.SetTexture_t( 'TattooTextureMask', decal.maskResource, effect) effect.RebuildCachedData() effect.EndUpdate()
def ExecuteTest(self, onTestExecution=None): def OnTestEnd(): result = self.test.GetResult() self.results[self.currentIteration] = result if self.currentIteration < self.iterations - 1: if onTestExecution: onTestExecution(self.test) if self.clearCacheOnEachIteration: self.ClearCaches() self.test.Execute(callBack=OnTestEnd) self.currentIteration += 1 if onTestExecution: onTestExecution(self.test) self.results.PunchIn(self.test.__class__) if self.clearCacheOnEachIteration: self.ClearCaches() self.test.Execute(callBack=OnTestEnd) while self.currentIteration < self.iterations - 1: PD.Yield() self.results.PunchOut(self.test.__class__)
def BakeDecalToModifier(self, decal, projectedDecalModifier): while self.doingAvatar: PD.Yield(frameNice=False) if type(self.__avatar) is not trinity.Tr2IntSkinnedObject: raise TypeError('DecalBaker::DoPrepare - Avatar is not set!') if type(decal) is not ProjectedDecal: raise TypeError( 'DecalBaker::BakeDecalToModifier - decal is not an instance of PaperDoll::ProjectedDecal!' ) self.isReady = False self.doingDecal = False if projectedDecalModifier.decalData != decal: projectedDecalModifier.decalData = decal def PrepareDecal_t(): self.doingDecal = True self.SetDecal_t(self.__avatar, decal, True, True) self.doingDecal = False self.decalSettingTasklet = uthread.new(PrepareDecal_t) self.CreateTargetsOnModifier(projectedDecalModifier) self.bakingTasklet = uthread.new(self.DoBake_t, projectedDecalModifier)
def BindHeroHairShader(effect, suffix): path = effect.effectFilePath.lower() if path.find('hair') == -1: return False if path.find('clothavatarhair') != -1: effect.effectFilePath = ApplySuffix( 'res:/Graphics/Effect/Managed/Interior/Avatar/clothavatarhair_detailed', suffix) else: effect.effectFilePath = ApplySuffix( 'res:/Graphics/Effect/Managed/Interior/Avatar/skinnedavatarhair_detailed', suffix) while effect.effectResource.isLoading: PD.Yield() name = effect.name.lower() effect.PopulateParameters() PD.SetOrAddMap(effect, 'HairNoise', 'res:/Texture/Global/noise1d.dds') PD.SetOrAddMap( effect, 'TangentMap', 'res:/Texture/Global/50gray.dds' if not name.startswith('c_hair_head') else 'res:/Texture/Global/HeadTangents.dds') PortraitTools.TweakDiffuseSampler(effect) return True
def BindSkinShader(effect, wrinkleFx, scattering, buildDataManager, gender, use_png, fxSuffix): name = effect.name.lower() path = effect.effectFilePath.lower() if name.startswith('c_skin'): wasDouble = 'double' in path fxPath = PD.SKINNED_AVATAR_SINGLEPASS_DOUBLE_PATH if wasDouble else PD.SKINNED_AVATAR_SINGLEPASS_SINGLE_PATH effect.effectFilePath = ApplySuffix(fxPath[:-3], fxSuffix) while effect.effectResource.isLoading: PD.Yield() effect.PopulateParameters() PD.SetOrAddMap(effect, 'BeckmannLookup', 'res:/Texture/Global/beckmannSpecular.dds') PortraitTools.TweakDiffuseSampler(effect) suffix = 'tga' if use_png and not legacy_r_drive.loadFromContent: suffix = 'png' headMods = buildDataManager.GetModifiersByCategory( PD.DOLL_PARTS.HEAD) if PD.GENDER_ROOT: if gender == PD.GENDER.FEMALE: headFolderGeneric = 'res:/Graphics/Character/Female/Paperdoll/head/Head_Generic' else: headFolderGeneric = 'res:/Graphics/Character/Male/Paperdoll/head/Head_Generic' elif gender == PD.GENDER.FEMALE: headFolderGeneric = 'res:/Graphics/Character/Modular/Female/head/Head_Generic' else: headFolderGeneric = 'res:/Graphics/Character/Modular/Male/head/Head_Generic' headFolder = headFolderGeneric for hm in headMods: headFolder = os.path.dirname(hm.redfile) resFile = blue.ResFile() if scattering: if headFolder != '' and resFile.FileExists(headFolder + '/SkinMap.' + suffix): PD.SetOrAddMap(effect, 'SkinMap', headFolder + '/SkinMap.' + suffix) else: PD.SetOrAddMap(effect, 'SkinMap', headFolderGeneric + '/SkinMap.' + suffix) if wrinkleFx is not None: PD.SetOrAddMap(effect, 'WrinkleZoneMap', PD.FEMALE_WRINKLE_FACEZONE_PREFIX + suffix) if headFolder != '' and resFile.FileExists(headFolder + '/WrinkleNormal.' + suffix): PD.SetOrAddMap(effect, 'WrinkleNormalMap', headFolder + '/WrinkleNormal.' + suffix) else: PD.SetOrAddMap( effect, 'WrinkleNormalMap', headFolderGeneric + '/WrinkleNormal.' + suffix) if headFolder != '' and resFile.FileExists( headFolder + '/WrinkleNormalCorrection.' + suffix): PD.SetOrAddMap( effect, 'WrinkleNormalCorrectionMap', headFolder + '/WrinkleNormalCorrection.' + suffix) else: PD.SetOrAddMap( effect, 'WrinkleNormalCorrectionMap', headFolderGeneric + '/WrinkleNormalCorrection.' + suffix) if headFolder != '' and resFile.FileExists(headFolder + '/WrinkleDiffuse.' + suffix): PD.SetOrAddMap(effect, 'WrinkleDiffuseMap', headFolder + '/WrinkleDiffuse.' + suffix) else: PD.SetOrAddMap( effect, 'WrinkleDiffuseMap', headFolderGeneric + '/WrinkleDiffuse.' + suffix) wrinkleFx.append(effect) elif name.startswith('c_standard'): def AddClothingCube(effect): for res in effect.resources: if res.name == 'ClothingReflectionCube': return res = trinity.TriTextureCubeParameter() res.name = 'ClothingReflectionCube' res.resourcePath = 'res:/Texture/Global/GenericReflection_cube.dds' effect.resources.append(res) AddClothingCube(effect) elif name.startswith('c_eyewetness'): effect.effectFilePath = ApplySuffix( PD.SKINNED_AVATAR_EYEWETNESS_SHADER[:-3], fxSuffix) elif name.startswith('c_tongue'): effect.effectFilePath = ApplySuffix( PD.SKINNED_AVATAR_TONGUE_SHADER[:-3], fxSuffix) elif name.startswith('c_teeth'): effect.effectFilePath = ApplySuffix( PD.SKINNED_AVATAR_TEETH_SHADER[:-3], fxSuffix) elif name.startswith('c_eyes'): effect.effectFilePath = ApplySuffix( PD.SKINNED_AVATAR_EYE_SHADER[:-3], fxSuffix) def AddEyeCube(effect): for res in effect.resources: if res.name == 'EyeReflectionCube': return res = trinity.TriTextureCubeParameter() res.name = 'EyeReflectionCube' res.resourcePath = PD.EYE_SHADER_REFLECTION_CUBE_PATH effect.resources.append(res) AddEyeCube(effect)
def CreateRenderJobsForLight(self, light): self.lights.append(light) if not SkinSpotLightShadows.REUSE_ENGINE_MAPS: light.shadowCasterTypes = 0 else: light.shadowResolution = 1024 ignoreLight = False if self.lightFilter is not None and light.name not in self.lightFilter: ignoreLight = True elif len( self.lights ) > SkinSpotLightShadows.MAX_LIGHTS or light.coneAlphaOuter > 89: ignoreLight = True if ignoreLight: light.importanceScale = 0 light.importanceBias = -9999 light.shadowCasterTypes = 0 return light.importanceScale = 0 light.importanceBias = -len(self.lights) if SkinSpotLightShadows.REUSE_ENGINE_MAPS: self.RTs[light] = light.GetShadowTextureRes() rj = trinity.CreateRenderJob('render shadowmap ' + str(light)) self.jobs[light] = [rj] cb = trinity.TriStepPythonCB() cb.name = 'UpdateViewProjForLight' cb.SetCallback( lambda: self.UpdateViewProjForLight(None, None, light, None)) rj.steps.append(cb) rj.ScheduleRecurring() return rj = trinity.CreateRenderJob('render shadowmap ' + str(light)) renderTarget = None while self.width > 8: renderTarget = trinity.Tr2RenderTarget(self.width, self.height, 1, self.format) if renderTarget is None or not renderTarget.isValid: renderTarget = None self.width /= 2 self.height /= 2 PD.Yield() else: break self.RTs[light] = renderTarget depthStencil = None while self.width > 8: depthStencil = trinity.Tr2DepthStencil( self.width, self.height, trinity.DEPTH_STENCIL_FORMAT.D24S8) if depthStencil is None or not depthStencil.isValid: depthStencil = None self.width /= 2 self.height /= 2 PD.Yield() else: break if not renderTarget or not depthStencil or not renderTarget.isValid or not depthStencil.isValid: return v = None rj.PushViewport() rj.PushRenderTarget(renderTarget) rj.PushDepthStencil(depthStencil) clearColor = (100.0, 1.0, 1.0, 1.0) rj.Clear(clearColor, 1.0) vp = trinity.TriViewport() vp.x = 0 vp.y = 0 vp.width = self.width vp.height = self.height rj.PushProjection() rj.PushViewTransform() rj.SetViewport(vp) cb = trinity.TriStepPythonCB() cb.name = 'UpdateViewProjForLight' rj.steps.append(cb) stepProj = rj.SetProjection(trinity.TriProjection()) stepView = rj.SetView(trinity.TriView()) self.UpdateViewProjForLight(stepView, stepProj, light, v) cb.SetCallback( lambda: self.UpdateViewProjForLight(stepView, stepProj, light, v)) def applyVisualizer(doIt): for meshData in self.meshes.itervalues(): if doIt: meshData.applyShadowEffect() else: meshData.applyOriginalEffect() cb = trinity.TriStepPythonCB() cb.name = 'applyVisualizer(True)' cb.SetCallback(lambda: applyVisualizer(True)) rj.steps.append(cb) rj.RenderScene(self.scene) cb = trinity.TriStepPythonCB() cb.name = 'applyVisualizer(False)' cb.SetCallback(lambda: applyVisualizer(False)) rj.steps.append(cb) rj.PopDepthStencil() rj.PopRenderTarget() rj.PopViewTransform().name = 'TriStepPopViewTransform Restoring state' rj.PopViewport() rj.PopProjection() if SkinSpotLightShadows.renderJob is not None and SkinSpotLightShadows.renderJob.object is not None: step = trinity.TriStepRunJob() step.job = rj SkinSpotLightShadows.renderJob.object.steps.insert(0, step) else: self.jobs[light] = [rj] rj.ScheduleRecurring(insertFront=True) if self.debugVisualize: rj2 = trinity.CreateRenderJob('visualize shadowmap ' + str(light)) if light not in self.jobs: self.jobs[light] = [rj2] else: self.jobs[light].append(rj2) rj2.PushDepthStencil(None) size = 200 vp2 = trinity.TriViewport() vp2.x = 10 vp2.y = 10 + (size + 10) * (len(self.lights) - 1) vp2.width = size vp2.height = size rj2.PushViewport() rj2.PushProjection() rj2.PushViewTransform() rj2.SetViewport(vp2) rj2.SetStdRndStates(trinity.RM_FULLSCREEN) rj2.RenderTexture(renderTarget) rj2.PopViewTransform() rj2.PopProjection() rj2.PopViewport() rj2.PopDepthStencil() rj2.ScheduleRecurring()
def SetupFloorDropShadow(scene, doYield=True): if scene is None or SkinSpotLightShadows.instance is None: return def SetupCurve(effect): doll = scene.dynamics[0] if doll is None: return setName = 'Dropshadow foot tracker' set = None for s in doll.curveSets: if s.name == setName: set = s set.curves.removeAt(-1) set.bindings.removeAt(-1) break else: set = trinity.TriCurveSet() set.name = setName doll.curveSets.append(set) bones = ['LeftFoot', 'RightFoot'] for bone in bones: curve = trinity.Tr2BoneMatrixCurve() curve.skinnedObject = doll curve.bone = bone curve.name = bone param = PD.FindOrAddVec4(effect, bone) bind = trinity.TriValueBinding() bind.destinationObject = param bind.destinationAttribute = 'value' bind.sourceObject = curve bind.sourceAttribute = 'currentValue' bind.name = bone set.curves.append(curve) set.bindings.append(bind) set.Play() lights = scene.lights frontMainLightIndex = 0 for light in lights: if light.name == 'FrontMain': frontMainLightIndex = lights.index(light) break values = [(1, 0, 0, 0), (0, 1, 0, 0), (0, 0, 1, 0), (0, 0, 0, 1)] for cell in scene.cells: for system in cell.systems: for static in system.statics: if PD.SkinSpotLightShadows.instance is not None: PD.SkinSpotLightShadows.instance.CreateEffectParamsForMesh( static, isClothMesh=False) for area in static.enlightenAreas: area.effect.effectFilePath = 'res:/Graphics/Effect/Managed/Interior/Avatar/PortraitDropShadow.fx' if doYield: while area.effect.effectResource.isLoading: PD.Yield() SetupCurve(area.effect) area.effect.RebuildCachedData() if frontMainLightIndex < len(values): p = PD.FindOrAddVec4(area.effect, 'ShadowSelector') p.value = values[frontMainLightIndex]
def WaitForUpdate(self): while self.doll.busyUpdating: PD.Yield()