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[pdDef.DOLL_PARTS.BODY].isPrepared: PD.Yield(frameNice=False) bodyTex = projectedDecalModifier.mapD[pdDef.DOLL_PARTS.BODY] self._Bake(bodyTex, (0.0, 0.0, 2.0, 1.0)) self._ExpandOpaque(pdDef.DOLL_PARTS.BODY, bodyTex) elif projectedDecalModifier.mapD.get(pdDef.DOLL_PARTS.BODY): del projectedDecalModifier.mapD[pdDef.DOLL_PARTS.BODY] if projectedDecalModifier.decalData.headEnabled: while not projectedDecalModifier.mapD[pdDef.DOLL_PARTS.HEAD].isPrepared: PD.Yield(frameNice=False) headTex = projectedDecalModifier.mapD[pdDef.DOLL_PARTS.HEAD] self._Bake(headTex, (-0.5, 0.0, 2.0, 2.0)) self._ExpandOpaque(pdDef.DOLL_PARTS.HEAD, headTex) elif projectedDecalModifier.mapD.get(pdDef.DOLL_PARTS.HEAD): del projectedDecalModifier.mapD[pdDef.DOLL_PARTS.HEAD] self.bakeScene = None self.isReady = True
def SetupStubble(meshes, name, stubblePath, adding = True): ret = [] stubbleName = '{0}Stubble'.format(name) stubbleMeshes = (mesh for mesh in meshes if mesh.name.startswith(pdDef.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(): pdCf.Yield() mesh.decalAreas.append(stubbleArea) ret.append(mesh) if SkinSpotLightShadows.instance: SkinSpotLightShadows.instance.CreateEffectParamsForMesh(mesh, False) for instance in 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 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 BakeDecalToModifier(self, decal, projectedDecalModifier): """ Pre: Decal is an instance of ProjectedDecal Avatar has been created for baking Post: projectedDecalModifier.decalData contains the given decal and diffuse maps on the modifier contain textures for body and head. Summary: Bakes out the decal using currently set avatar, the targets for outputted textures are the diffuse maps for body and head in the modifier. """ 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 PreloadEffect(path): effect = trinity.Tr2Effect() effect.effectFilePath = path while effect.effectResource.isLoading: pdCf.Yield() effect.RebuildCachedData() return effect
def PreloadEffect(path): """ Helper for preloading effect: create it, wait on blue, rebuild it. """ effect = trinity.Tr2Effect() effect.effectFilePath = path while effect.effectResource.isLoading: pdCf.Yield() effect.RebuildCachedData() return effect
def LoadFromRes(self, resPath): """ Loads the doll from the given resPath and applies it to its avatar if it has one. """ self.doll = pdImpl.Doll(PaperDollCharacter.__DEFAULT_NAME) while not self.factory.IsLoaded: pdCf.Yield() self.doll.Load(resPath, self.factory) if self.avatar: self.doll.Update(self.factory, self.avatar)
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: pdCf.Yield() effect.PopulateParameters() PortraitTools.TweakDiffuseSampler(effect)
def _ExpandOpaque(self, bodyPart, targetTex): """ Using pre-generated masks, we bleed the opaque accross the edges defined by said masks. This reduces visible seams when the tattoos have been projected in object space so that their pixels in UV space aren't continuous. """ 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 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: pdCf.Yield() else: raise Exception('Candidates are empty!')
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: pdCf.Yield() name = effect.name.lower() effect.PopulateParameters() pdCcf.SetOrAddMap(effect, 'HairNoise', 'res:/Texture/Global/noise1d.dds') pdCcf.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 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: pdCf.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 SetDecal_t(self, avatar, decal, setTexture, setMask): """ Sets decal texture and mask map defined in 'decal' to all meshes in the avatar, except for the meshes that have their names in 'ignoreTargets' Precondition: The effect _must_ have loaded prior to calling this function. """ 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 pdCcF.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 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 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 pdCcF.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 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 = pdCcf.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 static in cell.statics: if SkinSpotLightShadows.instance is not None: 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: pdCf.Yield() SetupCurve(area.effect) area.effect.RebuildCachedData() if frontMainLightIndex < len(values): p = pdCcf.FindOrAddVec4(area.effect, 'ShadowSelector') p.value = values[frontMainLightIndex]
def WaitForUpdate(self): """ Wait until the doll Update has finished. """ while self.doll.busyUpdating: pdCf.Yield()
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 = pdDef.SKINNED_AVATAR_SINGLEPASS_DOUBLE_PATH if wasDouble else pdDef.SKINNED_AVATAR_SINGLEPASS_SINGLE_PATH effect.effectFilePath = ApplySuffix(fxPath[:-3], fxSuffix) while effect.effectResource.isLoading: pdCf.Yield() effect.PopulateParameters() pdCcf.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(pdDef.DOLL_PARTS.HEAD) if pdDef.GENDER_ROOT: if gender == pdDef.GENDER.FEMALE: headFolderGeneric = 'res:/Graphics/Character/Female/Paperdoll/head/Head_Generic' else: headFolderGeneric = 'res:/Graphics/Character/Male/Paperdoll/head/Head_Generic' elif gender == pdDef.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) if scattering: if headFolder != '' and blue.paths.exists(headFolder + '/SkinMap.' + suffix): pdCcf.SetOrAddMap(effect, 'SkinMap', headFolder + '/SkinMap.' + suffix) else: pdCcf.SetOrAddMap(effect, 'SkinMap', headFolderGeneric + '/SkinMap.' + suffix) if wrinkleFx is not None: pdCcf.SetOrAddMap(effect, 'WrinkleZoneMap', pdDef.FEMALE_WRINKLE_FACEZONE_PREFIX + suffix) if headFolder != '' and blue.paths.exists(headFolder + '/WrinkleNormal.' + suffix): pdCcf.SetOrAddMap(effect, 'WrinkleNormalMap', headFolder + '/WrinkleNormal.' + suffix) else: pdCcf.SetOrAddMap(effect, 'WrinkleNormalMap', headFolderGeneric + '/WrinkleNormal.' + suffix) if headFolder != '' and blue.paths.exists(headFolder + '/WrinkleNormalCorrection.' + suffix): pdCcf.SetOrAddMap(effect, 'WrinkleNormalCorrectionMap', headFolder + '/WrinkleNormalCorrection.' + suffix) else: pdCcf.SetOrAddMap(effect, 'WrinkleNormalCorrectionMap', headFolderGeneric + '/WrinkleNormalCorrection.' + suffix) if headFolder != '' and blue.paths.exists(headFolder + '/WrinkleDiffuse.' + suffix): pdCcf.SetOrAddMap(effect, 'WrinkleDiffuseMap', headFolder + '/WrinkleDiffuse.' + suffix) else: pdCcf.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(pdDef.SKINNED_AVATAR_EYEWETNESS_SHADER[:-3], fxSuffix) elif name.startswith('c_tongue'): effect.effectFilePath = ApplySuffix(pdDef.SKINNED_AVATAR_TONGUE_SHADER[:-3], fxSuffix) elif name.startswith('c_teeth'): effect.effectFilePath = ApplySuffix(pdDef.SKINNED_AVATAR_TEETH_SHADER[:-3], fxSuffix) elif name.startswith('c_eyes'): effect.effectFilePath = ApplySuffix(pdDef.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 = pdDef.EYE_SHADER_REFLECTION_CUBE_PATH effect.resources.append(res) AddEyeCube(effect)
def SetupFloorDropShadow(scene, doYield = True): """ Very specialized function for something very specific to portrait mode: take over the meshes in the scene, which should just be a floor, and hook up a shader that will blend a dropshadow. That shader needs to know the location of the doll(-feet), so there is also some curve binding. Call this after the doll has been created for the first time. """ if scene is None or SkinSpotLightShadows.instance is None: return def SetupCurve(effect): """ Find the bones for the foot, and set up a curve binding that will send their positions to effect parameters. """ 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 = pdCcf.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 SkinSpotLightShadows.instance is not None: 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: pdCf.Yield() SetupCurve(area.effect) area.effect.RebuildCachedData() if frontMainLightIndex < len(values): p = pdCcf.FindOrAddVec4(area.effect, 'ShadowSelector') p.value = values[frontMainLightIndex]
def CreateRenderJobsForLight(self, light): """ Create a renderjob to render out the shadow map for this light, and blur it for VSM; optionally also show it on the screen for debugging. """ 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 pdCf.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 pdCf.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()