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