NovaBryan/EVE_Dump
Log | Files | 📦 下载最新源码 (.zip) | Refs | README

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