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

renderer_spaceobject.py (11025B)


      1 #Embedded file name: C:\BuildAgent\work\20d73f1b24eed06e\eve\release\V24.01\packages\iconrendering2\renderers\renderer_spaceobject.py
      2 from __future__ import absolute_import
      3 import trinity
      4 import eveSpaceObject.spaceobjanimation as soanimation
      5 import iconrendering2.const
      6 from iconrendering2.const import Language, IconViewMode, IconRenderFormat, VIEW_MODE_CAMERA_ANGLES, VIEW_MODE_SUN_DIRECTIONS
      7 from .utils_scene import *
      8 from .utils_renderer import RenderToBitmapFromScene
      9 from .renderer_base import IconRenderer, RenderException
     10 
     11 class SpaceObjectIconRenderer(IconRenderer):
     12 
     13     def __init__(self, sofFactory, scenePath, dna, language = Language.ENGLISH):
     14         super(SpaceObjectIconRenderer, self).__init__(language)
     15         self._sofFactory = sofFactory
     16         self._scenePath = scenePath
     17         self._dna = dna
     18         self._scene = None
     19         self._object = None
     20         self._shaderModel = trinity.GetShaderModel()
     21 
     22     def __str__(self):
     23         return 'Space Object Icon Renderer <%s>' % hex(id(self))
     24 
     25     def _PrepareRender(self):
     26         self._shaderModel = trinity.GetShaderModel()
     27         trinity.SetShaderModel('SM_3_0_DEPTH')
     28         trinity.GetVariableStore().RegisterVariable('EveSpaceSceneShadowMap', trinity.TriTextureRes())
     29         if self._scenePath:
     30             self._scene = blue.resMan.LoadObject(self._scenePath)
     31         else:
     32             self._scene = trinity.EveSpaceScene()
     33         self._object = self._sofFactory.BuildFromDNA(self._dna)
     34         self._initialScale = None
     35         if self._object:
     36             self._InitializeObject()
     37             self._scene.objects.append(self._object)
     38             WaitForGeometryLoad(self._object, context=self._dna)
     39             self._scene.UpdateScene(blue.os.GetTime())
     40 
     41     def _FinishRender(self):
     42         del self._object
     43         self._object = None
     44         del self._scene
     45         self._scene = None
     46         trinity.SetShaderModel(self._shaderModel)
     47 
     48     def _Render(self, renderInfo):
     49         if not self._scene or not self._object:
     50             raise RenderException('Could not render icon %s' % renderInfo.outputPath, renderInfo.outputPath)
     51         view, projection = self._PrepareSceneForRender(renderInfo)
     52         self._PrepareObjectForRender(renderInfo)
     53         self._DoRendering(renderInfo, view, projection)
     54 
     55     def _DoRendering(self, renderInfo, view, projection):
     56         supersampleQuality = 1
     57         outlineColor = renderInfo.outlineColor if iconrendering2.const.OUTLINE_THICKNESS > 0 else None
     58         if renderInfo.renderFormat == IconRenderFormat.JPG or renderInfo.background == None and not renderInfo.backgroundTransparent:
     59             outlineColor = None
     60         originalSize = renderInfo.renderSize
     61         originalBackground = renderInfo.background
     62         if outlineColor:
     63             supersampleQuality = 0
     64             renderInfo.background = None
     65             renderInfo.backgroundTransparent = True
     66         waitTime = 0 if not renderInfo.metadata else renderInfo.metadata.get('animationOffset', 0)
     67         if renderInfo.backgroundTransparent:
     68             prevColor = renderInfo.backgroundColor
     69             renderInfo.backgroundColor = (1.0, 0.0, 0.0)
     70             bitmapR = RenderToBitmapFromScene(renderInfo, self._scene, view, projection, waitTime=waitTime)
     71             renderInfo.backgroundColor = (0.0, 1.0, 0.0)
     72             bitmapG = RenderToBitmapFromScene(renderInfo, self._scene, view, projection, waitTime=waitTime)
     73             renderInfo.backgroundColor = (0.0, 0.0, 1.0)
     74             bitmapB = RenderToBitmapFromScene(renderInfo, self._scene, view, projection, waitTime=waitTime)
     75             renderInfo.backgroundColor = prevColor
     76             bitmap = _CreateAlpha(bitmapR, bitmapG, bitmapB)
     77             bitmap.Save(renderInfo.outputPath)
     78         else:
     79             bitmap = RenderToBitmapFromScene(renderInfo, self._scene, view, projection, waitTime=waitTime, supersampleQuality=supersampleQuality)
     80             bitmap.Save(renderInfo.outputPath)
     81         if renderInfo.metadata and renderInfo.metadata.get('viewMode', IconViewMode.FREE) == IconViewMode.TOP:
     82             from PIL import Image
     83             img = Image.open(renderInfo.outputPath)
     84             img = img.rotate(90.0)
     85             img.save(renderInfo.outputPath)
     86         if outlineColor:
     87             from .utils_renderer import ApplyOutline
     88             backgroundPath = blue.paths.ResolvePath(originalBackground) if originalBackground else None
     89             ApplyOutline(renderInfo.outputPath, originalSize, outlineColor, iconrendering2.const.OUTLINE_THICKNESS, iconrendering2.const.OUTLINE_HARDLINES, backgroundPath)
     90 
     91     def _InitializeObject(self):
     92         if hasattr(self._object, 'FreezeHighDetailMesh'):
     93             self._object.FreezeHighDetailMesh()
     94         perlinCurves = self._object.Find('trinity.TriPerlinCurve')
     95         for curve in perlinCurves:
     96             curve.scale = 0.0
     97 
     98         if hasattr(self._object, 'modelRotationCurve'):
     99             self._object.modelRotationCurve = None
    100         if hasattr(self._object, 'modelTranslationCurve'):
    101             self._object.modelTranslationCurve = None
    102         if hasattr(self._object, 'rotationCurve'):
    103             self._object.rotationCurve = None
    104         if hasattr(self._object, 'translationCurve'):
    105             self._object.translationCurve = None
    106         if hasattr(self._object, 'boosters'):
    107             self._object.boosters = None
    108         if hasattr(self._object, 'scaling'):
    109             self._initialScale = self._object.scaling
    110 
    111     def _PrepareObjectForRender(self, renderInfo):
    112         if renderInfo.metadata:
    113             controllerVariables = renderInfo.metadata.get('stateControllerVariables', [])
    114             if len(controllerVariables) > 0 and hasattr(self._object, 'SetControllerVariable'):
    115                 for var, value in controllerVariables.iteritems():
    116                     self._object.SetControllerVariable(var, value)
    117 
    118             playCurveSets = renderInfo.metadata.get('playCurveSets', False)
    119             if playCurveSets:
    120                 curveSets = self._object.Find('trinity.TriCurveSet')
    121                 for curveSet in curveSets:
    122                     if not curveSet.isPlaying:
    123                         curveSet.Play()
    124                     curveSet.scaledTime = 0.0
    125 
    126             if hasattr(self._object, 'scaling') and self._initialScale:
    127                 scaleFactor = renderInfo.metadata.get('scaleFactor', 1.0)
    128                 if scaleFactor != 1.0:
    129                     self._object.scaling = (self._initialScale[0] * scaleFactor, self._initialScale[1] * scaleFactor, self._initialScale[2] * scaleFactor)
    130         soanimation.TriggerDefaultStates(self._object)
    131 
    132     @staticmethod
    133     def GetDefaultSunDirection(obj, view):
    134         from iconrendering2.metadata import DEFAULT_SUN_DIRECTION
    135         sunDirection = DEFAULT_SUN_DIRECTION
    136         if isinstance(obj, (trinity.EveStation2, trinity.EveMobile)):
    137             eyePos = (view.transform[0][3], view.transform[1][3], view.transform[2][3])
    138             lookAt = (view.transform[0][2], view.transform[1][2], view.transform[2][2])
    139             sunDirection = geo2.Vec3Normalize(geo2.Vec3Subtract(eyePos, lookAt))
    140         return sunDirection
    141 
    142     def _PrepareSceneForRender(self, renderInfo):
    143         view, projection = GetViewProjectionForObject(self._object, self._scene)
    144         sunDirection = None
    145         if renderInfo.metadata:
    146             viewMode = renderInfo.metadata.get('viewMode', IconViewMode.FREE)
    147             if viewMode == IconViewMode.FREE:
    148                 sunDirection = renderInfo.metadata.get('sunDirection', None)
    149                 if all((x in renderInfo.metadata for x in ['projection', 'view'])):
    150                     projData = renderInfo.metadata['projection']
    151                     projection.PerspectiveFov(projData['fov'], projData['aspectRatio'], projData['zn'], projData['zf'])
    152                     view.SetLookAtPosition(renderInfo.metadata['view']['eye'], renderInfo.metadata['view']['at'], renderInfo.metadata['view']['up'])
    153             else:
    154                 angle = VIEW_MODE_CAMERA_ANGLES[viewMode]
    155                 sunDirection = VIEW_MODE_SUN_DIRECTIONS[viewMode]
    156                 boundingSphereRadius = self._object.GetBoundingSphereRadius()
    157                 if self._object.mesh is not None:
    158                     geometry = self._object.mesh.geometry
    159                     boundingSphereCenter = self._object.GetBoundingSphereCenter()
    160                     view, projection = GetViewAndProjectionUsingMeshGeometry(geometry, scene=self._scene, boundingSphereRadius=boundingSphereRadius, boundingSphereCenter=boundingSphereCenter, cameraAngle=angle)
    161         if sunDirection is None:
    162             sunDirection = self.GetDefaultSunDirection(self._object, view)
    163         self._scene.sunDirection = sunDirection
    164         self._scene.backgroundRenderingEnabled = not renderInfo.backgroundTransparent
    165         return (view, projection)
    166 
    167 
    168 def _CreateAlpha(rBmp, gBmp, bBmp):
    169     outputBmp = trinity.Tr2HostBitmap(rBmp.width, rBmp.height, 1, trinity.PIXEL_FORMAT.B8G8R8A8_UNORM)
    170     rTriCol = trinity.TriColor()
    171     gTriCol = trinity.TriColor()
    172     bTriCol = trinity.TriColor()
    173     BLACKALPHA0 = 0
    174     HUERANGE = 60
    175     REDHUE = 0
    176     GREENHUE = 120
    177     BLUEHUE = 240
    178     for px in range(rBmp.width):
    179         for py in range(rBmp.height):
    180             rPixelValue = rBmp.GetPixel(px, py)
    181             gPixelValue = gBmp.GetPixel(px, py)
    182             bPixelValue = bBmp.GetPixel(px, py)
    183             rTriCol.FromInt(rPixelValue)
    184             gTriCol.FromInt(gPixelValue)
    185             bTriCol.FromInt(bPixelValue)
    186             rh, rs, rv = rTriCol.GetHSV()
    187             gh, gs, gv = gTriCol.GetHSV()
    188             bh, bs, bv = bTriCol.GetHSV()
    189             if (rTriCol.r, rTriCol.g, rTriCol.b) == (1.0, 0.0, 0.0) and (gTriCol.r, gTriCol.g, gTriCol.b) == (0.0, 1.0, 0.0) and (bTriCol.r, bTriCol.g, bTriCol.b) == (0.0, 0.0, 1.0):
    190                 outputBmp.SetPixel(px, py, BLACKALPHA0)
    191             elif GREENHUE - HUERANGE < gh < GREENHUE + HUERANGE and (360 - HUERANGE < rh <= 360 or REDHUE <= rh < REDHUE + HUERANGE) and BLUEHUE - HUERANGE < bh < BLUEHUE + HUERANGE:
    192                 if gv == 1.0 and bv == 1.0 and rv == 1.0:
    193                     gTriCol.SetRGB(gTriCol.r, rTriCol.g, gTriCol.b, 1.0)
    194                     ch, cs, cv = gTriCol.GetHSV()
    195                     gTriCol.a = cv
    196                     if cv != 0:
    197                         gTriCol.r = min(1.0, gTriCol.r * 1.0 / cv)
    198                         gTriCol.g = min(1.0, gTriCol.g * 1.0 / cv)
    199                         gTriCol.b = min(1.0, gTriCol.b * 1.0 / cv)
    200                     else:
    201                         gTriCol.r = 1.0
    202                         gTriCol.g = 1.0
    203                         gTriCol.b = 1.0
    204                     outputBmp.SetPixel(px, py, gTriCol.AsInt())
    205                 else:
    206                     gTriCol.SetRGB(gTriCol.r, rTriCol.g, gTriCol.b, 1.0 - gv)
    207                     outputBmp.SetPixel(px, py, gTriCol.AsInt())
    208             else:
    209                 gTriCol.a = 1.0
    210                 outputBmp.SetPixel(px, py, gTriCol.AsInt())
    211 
    212     return outputBmp