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

postProcess.py (11918B)


      1 #Embedded file name: C:\BuildAgent\work\20d73f1b24eed06e\eve\release\V24.01\packages\evegraphics\environments\postProcess.py
      2 import copy
      3 import logging
      4 import blue
      5 import evegraphics.settings as gfxsettings
      6 import trinity
      7 import uthread2
      8 from evegraphics.environments import BaseEnvironmentObject
      9 from fsdBuiltData.common.graphicIDs import GetAlbedoColor
     10 log = logging.getLogger(__name__)
     11 FOG_PARAMETER = 'fog'
     12 INTENSITY_THRESHOLD = 1e-06
     13 FOG_FADE_IN_TIME_MS = 1500.0
     14 READ_ONLY_POSTPROCESS_MEMBERS = ['luts',
     15  'whiteTemperature',
     16  'whiteTint',
     17  'colorSaturation',
     18  'colorContrast',
     19  'colorGamma',
     20  'colorGain',
     21  'colorOffset']
     22 
     23 class PostProcess(BaseEnvironmentObject):
     24     __defaultValues__ = None
     25     __postProcessParameters__ = None
     26 
     27     def __init__(self, postProcess, unsetPostprocess, lerpValues, useSunColor):
     28         super(PostProcess, self).__init__()
     29         self._postProcess = postProcess
     30         self._unsetPostprocess = unsetPostprocess
     31         self._intensity = 0
     32         self._setup = False
     33         self._size = (0, 0, 0)
     34         self._midpoint = (0, 0, 0)
     35         self._fadeTaskelt = None
     36         self._lerpValues = lerpValues
     37         lerpParameters = [ name for name in self._lerpValues.keys() ]
     38         self._lerpParameters = {}
     39         self.usedPostProcessParameters = self._FindUsedPostProcessParameters(lerpParameters, lerpValues)
     40         self._usedLerpParameters = self._lerpParameters
     41         self._useSunColor = useSunColor
     42 
     43     @property
     44     def postProcess(self):
     45         return self._postProcess
     46 
     47     @postProcess.setter
     48     def postProcess(self, value):
     49         self._postProcess = value
     50         self._updateLerpParamsAndValues()
     51 
     52     def _updateLerpParamsAndValues(self):
     53         from evegraphics.environments.environmentItemFactory import CreateLerpFromPostProcess
     54         self._resetUnsetPostProcess()
     55         self._lerpValues = CreateLerpFromPostProcess(self._unsetPostprocess, self._postProcess)
     56         self._lerpParameters = {}
     57         self.usedPostProcessParameters = self._FindUsedPostProcessParameters(self._lerpValues.keys(), self._lerpValues)
     58         self._usedLerpParameters = self._lerpParameters
     59 
     60     def _resetUnsetPostProcess(self):
     61         unsetPostprocess = trinity.Tr2PostProcess2()
     62         for parameter in PostProcess.GetTr2PostProcess2Members():
     63             if getattr(self._postProcess, parameter, None) is not None:
     64                 setattr(unsetPostprocess, parameter, type(getattr(self._postProcess, parameter))())
     65 
     66         self._unsetPostprocess = unsetPostprocess
     67 
     68     def Setup(self):
     69         pass
     70 
     71     def IsDisabled(self):
     72         return gfxsettings.Get(gfxsettings.GFX_POST_PROCESSING_QUALITY) == 0
     73 
     74     def GetDefaultValues(self):
     75         if PostProcess.__defaultValues__ is None:
     76             PostProcess.__defaultValues__ = trinity.Load('res:/dx9/default/postprocess.red')
     77         return PostProcess.__defaultValues__
     78 
     79     @classmethod
     80     def GetTr2PostProcess2Members(cls):
     81         if PostProcess.__postProcessParameters__ is None:
     82             pp = trinity.Tr2PostProcess2()
     83             PostProcess.__postProcessParameters__ = [ attr for attr in pp.__members__ if not attr.startswith('_') and attr not in READ_ONLY_POSTPROCESS_MEMBERS ]
     84         return PostProcess.__postProcessParameters__
     85 
     86     def ApplyLerpValues(self):
     87         if self._usedLerpParameters and self.postProcess is not None and self.scenePostProcess is not None:
     88             for key, value in self._lerpValues.iteritems():
     89                 if value is None:
     90                     continue
     91                 member = getattr(self.scenePostProcess, key)
     92                 if member is None:
     93                     continue
     94                 for subKey, subValue in value.iteritems():
     95                     if subValue is None:
     96                         continue
     97                     min, max = subValue
     98                     if max is not None:
     99                         setattr(member, subKey, max)
    100 
    101     def ApplyToScene(self):
    102         if self.scenePostProcess is not None:
    103             if self.IsDisabled():
    104                 return
    105             if self.postProcess.godRays is not None and self._useSunColor and self.InClientMode():
    106                 flareGraphicID = cfg.mapSystemCache[session.solarsystemid].sunFlareGraphicID
    107                 rayColor = GetAlbedoColor(flareGraphicID)
    108                 self.postProcess.godRays.godRayColor = (rayColor[0],
    109                  rayColor[1],
    110                  rayColor[2],
    111                  rayColor[3])
    112             for member in self.GetTr2PostProcess2Members():
    113                 try:
    114                     if member not in self.usedPostProcessParameters:
    115                         continue
    116                     newPPVal = getattr(self.postProcess, member, None)
    117                     if newPPVal is not None:
    118                         copyTo = getattr(newPPVal, 'CopyTo', None)
    119                         setattr(self.scenePostProcess, member, copyTo() if copyTo is not None else newPPVal)
    120                 except ValueError as ex:
    121                     log.error('Error when applying post processing to scene' + ex.message)
    122 
    123     @property
    124     def intensity(self):
    125         return self._intensity
    126 
    127     @intensity.setter
    128     def intensity(self, v):
    129         self.testWrapper(v)
    130 
    131     def testWrapper(self, v):
    132         if self._setup and abs(self._intensity - v) < INTENSITY_THRESHOLD:
    133             return
    134         self._intensity = v
    135         for parentKey, parentValue in self._usedLerpParameters.iteritems():
    136             for postProcessObjectKey in parentValue:
    137                 minValue, maxValue = self._lerpValues[parentKey][postProcessObjectKey]
    138                 if minValue is None or maxValue is None:
    139                     continue
    140                 value = minValue + self._intensity * (maxValue - minValue)
    141                 postProcessMember = getattr(self.scenePostProcess, parentKey)
    142                 if postProcessMember is not None:
    143                     setattr(postProcessMember, postProcessObjectKey, value)
    144 
    145         self._setup = True
    146 
    147     @property
    148     def size(self):
    149         return self._size
    150 
    151     @size.setter
    152     def size(self, v):
    153         if all([ old == new for old, new in zip(self._size, v) ]):
    154             return
    155         self._size = v
    156         setattr(self.scenePostProcess.fog, 'areaSize', (self._size[0], self._size[1], self._size[2]))
    157 
    158     @property
    159     def midpoint(self):
    160         return self._midpoint
    161 
    162     @midpoint.setter
    163     def midpoint(self, v):
    164         if all([ old == new for old, new in zip(self._midpoint, v) ]):
    165             return
    166         self._midpoint = v
    167         setattr(self.scenePostProcess.fog, 'areaCenter', self._midpoint)
    168 
    169     def GetLockedAttributes(self):
    170         lockedAttributes = dict()
    171         lockedAttributes['lockedLerp'] = copy.deepcopy(self._lerpParameters)
    172         lockedPostProcess = []
    173         for member in self.GetTr2PostProcess2Members():
    174             if getattr(self.postProcess, member, None) is None:
    175                 continue
    176             lockedPostProcess.append(member)
    177 
    178         lockedAttributes['lockedPostProcess'] = lockedPostProcess
    179         if FOG_PARAMETER in self._lerpParameters and len(self._lerpParameters['fog']) > 0:
    180             lockedAttributes['lockedLerp']['fog'] += ['areaCenter', 'areaSize', 'intensity']
    181         return lockedAttributes
    182 
    183     @property
    184     def scenePostProcess(self):
    185         return getattr(self.scene, 'postprocess', None)
    186 
    187     def SetIgnoredAttributes(self, attributes):
    188         usedPostProcessParameters = list()
    189         for member in self.GetTr2PostProcess2Members():
    190             memVal = getattr(self.postProcess, member, None)
    191             if memVal is None or member in attributes['lockedPostProcess']:
    192                 continue
    193             usedPostProcessParameters.append(member)
    194 
    195         self.usedPostProcessParameters = usedPostProcessParameters
    196         usedLerpParameters = dict()
    197         lockedLerpAttributes = attributes['lockedLerp']
    198         for k, v in self._lerpParameters.iteritems():
    199             if k not in lockedLerpAttributes:
    200                 usedLerpParameters[k] = v
    201                 continue
    202             lockedValuesForKey = lockedLerpAttributes[k]
    203             for value in v:
    204                 if value not in lockedValuesForKey:
    205                     if k not in usedLerpParameters:
    206                         usedLerpParameters[k] = []
    207                     usedLerpParameters[k].append(value)
    208 
    209         self._usedLerpParameters = usedLerpParameters
    210 
    211     def LinkToDistanceField(self, distanceFieldEnvironmentItem):
    212         if self.IsDisabled() or self.scenePostProcess is None:
    213             return
    214         distanceFieldEnvironmentItem.AddPyBinding('Intensity', self, 'intensity', distanceFieldEnvironmentItem.distanceCurve, 'currentValue')
    215         if FOG_PARAMETER in self.usedPostProcessParameters:
    216             distanceFieldEnvironmentItem.AddPyBinding('FogCenter', self, 'midpoint', distanceFieldEnvironmentItem.distanceField, 'midpoint')
    217             distanceFieldEnvironmentItem.AddPyBinding('FogSize', self, 'size', distanceFieldEnvironmentItem.distanceField, 'dimensions')
    218             self._fadeTaskelt = uthread2.start_tasklet(self._DoFogFadeIn)
    219 
    220     def _DoFogFadeIn(self):
    221         time0 = blue.os.GetSimTime()
    222         fadeIn = 0.0
    223         if not hasattr(self.scenePostProcess, 'fog') or not hasattr(self.postProcess, 'fog'):
    224             log.error('Missing fog postprocess member when attempting to start fog fade in ')
    225         self.scenePostProcess.fog.intensity = 0.0
    226         maxFogValue = min(1.0, self.postProcess.fog.intensity)
    227         while fadeIn < maxFogValue:
    228             blue.synchro.Yield()
    229             timeNow = blue.os.GetSimTime()
    230             diff = blue.os.TimeDiffInMs(time0, timeNow)
    231             fadeIn = max(0.0, min(1.0, diff / FOG_FADE_IN_TIME_MS))
    232             fadeIn = fadeIn * fadeIn * (3 - 2 * fadeIn)
    233             if self.scenePostProcess is not None and hasattr(self.scenePostProcess, 'fog'):
    234                 self.scenePostProcess.fog.intensity = fadeIn
    235             else:
    236                 raise AttributeError('Missing fog on scene post process when fading in')
    237 
    238         self._fadeTaskelt = None
    239 
    240     def Refresh(self):
    241         if self.IsDisabled():
    242             return
    243         for key, value in self.usedPostProcessParameters.iteritems():
    244             setattr(self.scenePostProcess, key, value)
    245 
    246     def TearDown(self):
    247         if self.postProcess and self.scenePostProcess is not None:
    248             defaultValues = self.GetDefaultValues()
    249             for member in self.GetTr2PostProcess2Members():
    250                 try:
    251                     if member not in self.usedPostProcessParameters:
    252                         continue
    253                     guard = 'GUARD_VALUE'
    254                     defaultPPMember = getattr(defaultValues, member, guard)
    255                     if defaultPPMember is guard:
    256                         continue
    257                     if self.scenePostProcess is not None:
    258                         setattr(self.scenePostProcess, member, defaultPPMember)
    259                 except ValueError as ex:
    260                     log.error('Error when tearing down post processing and setting them to default values with ex ' + ex.message)
    261 
    262         self._intensity = 0
    263         self._setup = False
    264         self._size = (0, 0, 0)
    265         self._midpoint = (0, 0, 0)
    266         if self._fadeTaskelt is not None:
    267             self._fadeTaskelt.kill()
    268             self._fadeTaskelt = None
    269         self.scene = None
    270 
    271     def _FindUsedPostProcessParameters(self, lerpParameters, lerpValues):
    272         for k in lerpParameters:
    273             self._lerpParameters[k] = []
    274             for key in lerpValues[k].keys():
    275                 self._lerpParameters[k].append(key)
    276 
    277         usedPostProcessParameters = list()
    278         for member in self.GetTr2PostProcess2Members():
    279             memVal = getattr(self.postProcess, member, None)
    280             if memVal is None:
    281                 continue
    282             usedPostProcessParameters.append(member)
    283 
    284         return usedPostProcessParameters