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

particlebounds.py (6745B)


      1 #Embedded file name: C:\BuildAgent\work\20d73f1b24eed06e\eve\release\V24.01\packages\trinutils\particlebounds.py
      2 from __future__ import absolute_import
      3 import logging
      4 import greatergranny.grannyutils as grannyutils
      5 import remotefilecache
      6 import uthread2 as ut
      7 import trinutils.trinparser as trinparser
      8 import yamlext
      9 try:
     10     import blue
     11     import trinity
     12     import geo2
     13 except ImportError:
     14     trinity = None
     15     blue = None
     16     geo2 = None
     17 
     18 logger = logging.getLogger(__name__)
     19 
     20 def YamlStrToTrinObj(yamlstr):
     21     trinobj = trinparser.DictToTrinityParser(yamlext.loads(yamlstr))
     22     trinity.WaitForResourceLoads()
     23     return trinobj
     24 
     25 
     26 class MeshLoadError(Exception):
     27 
     28     def __init__(self, meshpath):
     29         msg = 'Mesh failed to load: %s' % meshpath
     30         Exception.__init__(self, msg)
     31 
     32 
     33 def HasParticleSystem(node):
     34     psys = node.Find('trinity.Tr2ParticleSystem')
     35     if psys:
     36         return True
     37     return False
     38 
     39 
     40 def _GetMaxPartSize(et):
     41     if not et.mesh.geometry.isGood:
     42         raise MeshLoadError(et.mesh.geometryResPath)
     43     geoSize = et.mesh.geometry.GetBoundingBox(0)
     44     gs = geo2.Vec3Distance(geoSize[0], geoSize[1])
     45     for em in et.Find('trinity.Tr2DynamicEmitter'):
     46         for each in em.generators:
     47             if each.name == 'sizeDynamic' or each.name == 'size':
     48                 return max(each.minRange + each.maxRange) * gs
     49 
     50     for em in et.Find('trinity.Tr2StaticEmitter'):
     51         for ps in em.Find('trinity.Tr2ParticleSystem'):
     52             for each in ps.elements:
     53                 if each.name == 'size':
     54                     remotefilecache.prefetch_single_file(em.geometryResourcePath)
     55                     return grannyutils.GetMaxPartSize(blue.paths.ResolvePath(em.geometryResourcePath), each.usageIndex, em.meshIndex) * gs
     56 
     57     logger.warning('No Particle Emitters found for %s' % et.name)
     58 
     59 
     60 class ParticleBoundsSimulation(object):
     61 
     62     def __init__(self, trinobj, pumpBlue = False, passes = 2, time = 3.0):
     63         trinity.WaitForResourceLoads()
     64         self._passes = passes
     65         self._time = time
     66         self.redNodeMutated = trinobj.CopyTo()
     67         self.redNodeCopy = trinobj.CopyTo()
     68         self.systems = self.redNodeMutated.Find('trinity.Tr2ParticleSystem')
     69         self.curveSets = self.redNodeMutated.Find('trinity.TriCurveSet')
     70         self.activeIndex = [0]
     71         self._ets = []
     72         self._staticMeshes = []
     73         self.started = [False]
     74         self._pumpBlue = pumpBlue
     75         self._CollectMeshes()
     76 
     77     def _CollectMeshes(self):
     78 
     79         def _FilterMesh(et):
     80             return isinstance(et.mesh, trinity.Tr2InstancedMesh) and ('unit_plane' or 'unitplane' in et.mesh.geometryResPath)
     81 
     82         def _CollectTransforms(tf, indices):
     83             if _FilterMesh(tf):
     84                 if isinstance(tf.mesh.instanceGeometryResource, trinity.TriGeometryRes):
     85                     self._staticMeshes.append(tf.mesh)
     86                 else:
     87                     self._ets.append({'et': tf,
     88                      'mesh': tf.mesh,
     89                      'min': (0.0, 0.0, 0.0),
     90                      'max': (0.0, 0.0, 0.0),
     91                      'partSize': _GetMaxPartSize(tf) / 2,
     92                      'hierarchy': indices})
     93             for ci in range(len(tf.children)):
     94                 child = tf.children[ci]
     95                 clst = list(indices)
     96                 clst.append(ci)
     97                 _CollectTransforms(child, clst)
     98 
     99         for ci in range(len(self.redNodeMutated.children)):
    100             child = self.redNodeMutated.children[ci]
    101             _CollectTransforms(child, [ci])
    102 
    103     def GetTrinobj(self):
    104         self.RunSimulation()
    105         self.FixPSBB()
    106         self._EnableParticleSorting()
    107         self._UpdateStaticBoundingBoxes()
    108         return self.redNodeCopy
    109 
    110     def _UpdateStaticBoundingBoxes(self):
    111         for each in self._staticMeshes:
    112             self._UpdateStaticBoundingBox(each)
    113 
    114     def _UpdateStaticBoundingBox(self, mesh):
    115         geoSize = mesh.instanceGeometryResource.GetBoundingBox(0)
    116         size = grannyutils.GetMaxPartSize(blue.paths.ResolvePath(mesh.instanceGeometryResPath), 0, mesh.meshIndex) / 2
    117         mesh.minBounds = (geoSize[0][0] - size, geoSize[0][1] - size, geoSize[0][2] - size)
    118         mesh.maxBounds = (geoSize[1][0] + size, geoSize[1][1] + size, geoSize[1][2] + size)
    119 
    120     def _PumpBlue(self):
    121         while self._pumpBlue:
    122             blue.os.Pump()
    123             ut.Yield()
    124 
    125     def _EnableParticleSorting(self):
    126         for ps in self.systems:
    127             ps.requiresSorting = True
    128 
    129     def _GetRedNodeCopyTransform(self, transformEntry):
    130         indices = transformEntry['hierarchy']
    131         tf = self.redNodeCopy
    132         for i in indices:
    133             tf = tf.children[i]
    134 
    135         return tf
    136 
    137     def FixPSBB(self):
    138         for d in self._ets:
    139             mps = d['partSize']
    140             tf = self._GetRedNodeCopyTransform(d)
    141             tf.mesh.minBounds = [d['min'][0] - mps, d['min'][1] - mps, d['min'][2] - mps]
    142             tf.mesh.maxBounds = [d['max'][0] + mps, d['max'][1] + mps, d['max'][2] + mps]
    143 
    144     def AccumulateBounds(self):
    145         for d in self._ets:
    146             ps = d['mesh'].instanceGeometryResource
    147             d['max'] = max(ps.aabbMax, d['max'])
    148             d['min'] = min(ps.aabbMin, d['min'])
    149 
    150     def RunSimulation(self):
    151         trinity.settings.SetValue('frustumCullingDisabled', 1)
    152         trinity.settings.SetValue('eveSpaceSceneVisibilityThreshold', 0)
    153         trinity.settings.SetValue('eveSpaceSceneLowDetailThreshold', 0)
    154         trinity.settings.SetValue('eveSpaceSceneMediumDetailThreshold', 0)
    155         trinity.settings.SetValue('eveSpaceSceneLODFactor', 0)
    156         ut.StartTasklet(self._PumpBlue)
    157         from . import sceneutils
    158         scene = sceneutils.GetOrCreateScene()
    159         scene.objects.append(self.redNodeMutated)
    160         self._EnableParticleSorting()
    161         rj = trinity.CreateRenderJob('CallbackJob')
    162         projection = trinity.TriProjection()
    163         projection.PerspectiveFov(1, 1, 1, 10000000)
    164         rj.steps.append(trinity.TriStepSetProjection(projection))
    165         view = trinity.TriView()
    166         view.SetLookAtPosition((50000, 0, 0), (0, 0, 0), (0, 1, 0))
    167         rj.steps.append(trinity.TriStepSetView(view))
    168         rj.steps.append(trinity.TriStepUpdate(scene))
    169         rj.steps.append(trinity.TriStepRenderScene(scene))
    170         rj.steps.append(trinity.TriStepPythonCB(self.AccumulateBounds))
    171         rj.ScheduleRecurring()
    172         for i in range(self._passes):
    173             self.activeIndex[0] = i
    174             for cs in self.curveSets:
    175                 cs.Play()
    176 
    177             for sys in self.systems:
    178                 sys.ClearParticles()
    179 
    180             self.started[0] = True
    181             ut.SleepSim(self._time)
    182 
    183         rj.UnscheduleRecurring()
    184         self._pumpBlue = False