renderDrivers.py (8058B)
1 #Embedded file name: C:\BuildAgent\work\20d73f1b24eed06e\eve\release\V24.01\eve\client\script\paperDoll\renderDrivers.py 2 from __future__ import absolute_import 3 import trinity 4 import types 5 import uthread 6 from eve.common.script.paperDoll import paperDollCommonFunctions as pdCf 7 from . import commonClientFunctions as pdCcf 8 import eve.common.script.paperDoll.paperDollDefinitions as pdDef 9 from . import paperDollPortrait as pdPor 10 11 class RenderDriver: 12 13 def __init__(self): 14 self._chainedRenderDriver = None 15 16 def SetChainedRenderDriver(self, chainedRenderDriver): 17 if not isinstance(chainedRenderDriver, RenderDriver): 18 return False 19 if self._chainedRenderDriver: 20 self._chainedRenderDriver = chainedRenderDriver 21 return 22 self._chainedRenderDriver = chainedRenderDriver 23 imethods = [ (n, getattr(self, n), getattr(chainedRenderDriver, n)) for n in dir(self) if not n.startswith('_') and n != 'SetChainedRenderDriver' and type(getattr(self, n)) is types.MethodType and hasattr(chainedRenderDriver, n) ] 24 for i in xrange(len(imethods)): 25 imethodPair = imethods[i] 26 imName = imethodPair[0] 27 thisObjIM = imethodPair[1] 28 nextObjIM = imethodPair[2] 29 thisObjIM = setattr(self, imName, self._CallChainedDeco(thisObjIM.__func__, nextObjIM.__func__)) 30 31 def _CallChainedDeco(self, first, second): 32 33 def wrapped(*args, **kwargs): 34 extraArgs = kwargs 35 newArgs = first(self, *args, **kwargs) 36 if newArgs is not None: 37 extraArgs.update(newArgs) 38 second(self._chainedRenderDriver, *args, **extraArgs) 39 40 return wrapped 41 42 def OnBeginUpdate(self, doll): 43 pass 44 45 def OnModifierUVChanged(self, modifier): 46 pass 47 48 def OnModifierRedfileLoaded(self, modifier, redfilePath): 49 pass 50 51 def OnApplyMorphTargets(self, meshes, morphTargets): 52 pass 53 54 def ApplyShaders(self, doll, meshes): 55 pass 56 57 def OnFinalizeAvatar(self, visualModel, avatar, updateRuleBundle, doll, factory): 58 pass 59 60 def OnEndUpdate(self, avatar, visualModel, doll, factory, **kwargs): 61 pass 62 63 64 class RenderDriverNCC(RenderDriver): 65 66 def __init__(self): 67 RenderDriver.__init__(self) 68 self.wrinkleFx = None 69 70 def OnBeginUpdate(self, doll): 71 pass 72 73 def OnModifierUVChanged(self, modifier): 74 pass 75 76 def OnModifierRedfileLoaded(self, modifier, redfilePath): 77 pass 78 79 def OnApplyMorphTargets(self, meshes, morphTargets): 80 pass 81 82 def ApplyShaders(self, doll, meshes): 83 self.wrinkleFx = [] 84 if not meshes: 85 return 86 skinLightmapRendererActive = lambda : doll.skinLightmapRenderer is not None 87 tasklets = [] 88 asyncMeshes = {} 89 for mesh in iter(meshes): 90 if skinLightmapRendererActive(): 91 asyncMeshes[mesh] = False 92 if pdDef.DOLL_PARTS.HEAD in mesh.name: 93 t = uthread.new(self.SetInteriorShader, *(asyncMeshes, 94 mesh, 95 self.wrinkleFx, 96 doll)) 97 else: 98 t = uthread.new(self.SetInteriorShader, *(asyncMeshes, 99 mesh, 100 None, 101 doll)) 102 tasklets.append(t) 103 uthread.schedule(t) 104 105 pdCf.WaitForAll(tasklets, lambda x: x.alive) 106 for mesh in asyncMeshes.iterkeys(): 107 if skinLightmapRendererActive() and asyncMeshes[mesh]: 108 doll.skinLightmapRenderer.BindLightmapShader(mesh) 109 110 def SetInteriorShader(self, asyncMeshes, mesh, wrinkleFx, doll): 111 fx = pdCcf.GetEffectsFromMesh(mesh) 112 tasklets = [] 113 for f in iter(fx): 114 t = uthread.new(self.SetInteriorShaderForFx_t, *(f, 115 asyncMeshes, 116 mesh, 117 wrinkleFx, 118 doll)) 119 tasklets.append(t) 120 121 pdCf.WaitForAll(tasklets, lambda x: x.alive) 122 t = uthread.new(self.SetDecalClip, mesh) 123 pdCf.WaitForAll([t], lambda x: x.alive) 124 125 def SetDecalClip(self, mesh): 126 effects = [] 127 if type(mesh) is trinity.Tr2Mesh: 128 for area in mesh.decalAreas: 129 effects += pdCcf.GetEffectsFromAreaList([area]) 130 131 for f in effects: 132 f.StartUpdate() 133 f.PopulateParameters() 134 pm = f.parameters.FindByName('DecalClip') 135 if pm: 136 pm.value = 1.0 137 f.EndUpdate() 138 139 def SetInteriorShaderForFx_t(self, effect, asyncMeshes, mesh, wrinkleFx, doll): 140 path = effect.effectFilePath.lower() 141 if 'masked.fx' in path: 142 return 143 if self.BindCustomShader(effect, doll.useFastShader, doll): 144 return 145 if asyncMeshes: 146 asyncMeshes[mesh] = True 147 suffix = '.fx' 148 if doll.useFastShader and ('_fast.fx' in path or path in pdDef.SHADERS_THAT_CAN_SWITCH_TO_FAST_SHADER_MODE): 149 suffix = '_fast.fx' 150 if doll.useDXT5N and ('_dxt5n.fx' in path or path in pdDef.SHADERS_TO_ENABLE_DXT5N): 151 suffix = '{0}_dxt5n.fx'.format(suffix[:-3]) 152 self.BindInteriorShader(effect, wrinkleFx, doll, suffix) 153 154 def BindCustomShader(self, effect, useFastShaders, doll): 155 name = effect.name.lower() 156 if name.startswith('c_custom') or name.startswith('c_s2'): 157 pdPor.PortraitTools.BindCustomShaders(effect, useFastShaders, doll) 158 return True 159 return False 160 161 def BindClothShaders(self, mesh, doll, isHair): 162 if doll.currentLOD <= 0: 163 fx = pdCcf.GetEffectsFromMesh(mesh) 164 for f in iter(fx): 165 f.StartUpdate() 166 try: 167 isHair = pdPor.PortraitTools.BindHeroHairShader(f, '.fx') or isHair 168 if doll.currentLOD <= pdDef.LOD_SKIN: 169 pdPor.PortraitTools.BindHeroClothShader(f, doll.useDXT5N) 170 finally: 171 f.EndUpdate() 172 173 return isHair 174 175 def BindInteriorShader(self, effect, wrinkleFx, doll, suffix): 176 effect.StartUpdate() 177 try: 178 path = effect.effectFilePath.lower() 179 if pdDef.DOLL_PARTS.HAIR not in path: 180 if doll.currentLOD >= 0: 181 if 'skinnedavatarbrdf' not in path: 182 effect.effectFilePath = '{0}{1}'.format(pdDef.INTERIOR_AVATAR_EFFECT_FILE_PATH[:-3], suffix) 183 if not effect.resources.FindByName('FresnelLookupMap'): 184 res = trinity.TriTextureParameter() 185 res.name = 'FresnelLookupMap' 186 res.resourcePath = pdDef.FRESNEL_LOOKUP_MAP 187 effect.resources.append(res) 188 elif doll.currentLOD == pdDef.LOD_A: 189 pass 190 elif doll.currentLOD in [pdDef.LOD_SKIN]: 191 pdPor.PortraitTools.BindSkinShader(effect, wrinkleFx, scattering=False, buildDataManager=doll.buildDataManager, gender=doll.gender, use_png=pdDef.USE_PNG, fxSuffix=suffix) 192 pdPor.PortraitTools.BindLinearAvatarBRDF(effect, suffix) 193 elif doll.currentLOD == pdDef.LOD_SCATTER_SKIN: 194 pdPor.PortraitTools.BindSkinShader(effect, wrinkleFx, scattering=True, buildDataManager=doll.buildDataManager, gender=doll.gender, use_png=pdDef.USE_PNG, fxSuffix=suffix) 195 pdPor.PortraitTools.BindLinearAvatarBRDF(effect, suffix) 196 elif doll.currentLOD <= 0: 197 pdPor.PortraitTools.BindHeroHairShader(effect, suffix) 198 finally: 199 effect.EndUpdate() 200 201 def OnFinalizeAvatar(self, visualModel, avatar, updateRuleBundle, doll, factory): 202 if updateRuleBundle.meshesChanged: 203 if self.wrinkleFx: 204 pdPor.PortraitTools().SetupWrinkleMapControls(avatar, self.wrinkleFx, doll) 205 206 def OnEndUpdate(self, avatar, visualModel, doll, factory, **kwargs): 207 pass