BVB Source Codes

CRYENGINE Show StatObjRend.cpp Source code

Return Download CRYENGINE: download StatObjRend.cpp Source code - Download CRYENGINE Source code - Type:.cpp
  1. // Copyright 2001-2016 Crytek GmbH / Crytek Group. All rights reserved.
  2.  
  3. // -------------------------------------------------------------------------
  4. //  File name:   statobjrend.cpp
  5. //  Version:     v1.00
  6. //  Created:     28/5/2001 by Vladimir Kajalin
  7. //  Compilers:   Visual Studio.NET
  8. //  Description: prepare and add render element into renderer
  9. // -------------------------------------------------------------------------
  10. //  History:
  11. //
  12. ////////////////////////////////////////////////////////////////////////////
  13.  
  14. #include "StdAfx.h"
  15.  
  16. #include "StatObj.h"
  17. #include "../RenderDll/Common/Shadow_Renderer.h"
  18. #include "IndexedMesh.h"
  19. #include "VisAreas.h"
  20. #include <CryMath/GeomQuery.h>
  21. #include "DeformableNode.h"
  22. #include "MatMan.h"
  23.  
  24. void CStatObj::Render(const SRendParams& rParams, const SRenderingPassInfo& passInfo)
  25. {
  26.         FUNCTION_PROFILER_3DENGINE;
  27.  
  28.         if (m_nFlags & STATIC_OBJECT_HIDDEN)
  29.                 return;
  30.  
  31. #ifndef _RELEASE
  32.         int nMaxDrawCalls = GetCVars()->e_MaxDrawCalls;
  33.         if (nMaxDrawCalls > 0)
  34.         {
  35.                 // Don't calculate the number of drawcalls every single time a statobj is rendered.
  36.                 // This creates a flickering effect with objects appearing and disappearing indicating that the limit has been reached.
  37.                 static int nCurrObjCounter = 0;
  38.                 if (((nCurrObjCounter++) & 31) == 1)
  39.                 {
  40.                         if (GetRenderer()->GetCurrentNumberOfDrawCalls() > nMaxDrawCalls)
  41.                                 return;
  42.                 }
  43.         }
  44. #endif // _RELEASE
  45.  
  46.         CRenderObject* pObj = GetRenderer()->EF_GetObject_Temp(passInfo.ThreadID());
  47.         FillRenderObject(rParams, rParams.pRenderNode, m_pMaterial, NULL, pObj, passInfo);
  48.  
  49. #ifdef SEG_WORLD
  50.         if (GetISystem()->GetIConsole()->GetCVar("sw_debugInfo")->GetIVal() == 4)
  51.         {
  52.                 //////////////////////////////////////////////////////////////////////////
  53.                 // Show colored sw object.
  54.                 //////////////////////////////////////////////////////////////////////////
  55.  
  56.                 ColorB clr = ColorB(0, 255, 0, 255);
  57.                 if (rParams.nCustomFlags & COB_SW_GLOBAL)
  58.                 {
  59.                         clr = ColorB(255, 0, 0, 255);
  60.                 }
  61.                 else if (rParams.nCustomFlags & COB_SW_CROSSSEG)
  62.                 {
  63.                         clr = ColorB(0, 0, 255, 255);
  64.                 }
  65.  
  66.                 if (pObj)
  67.                 {
  68.                         pObj->m_II.m_AmbColor = ColorF(clr.r / 155.0f, clr.g / 155.0f, clr.b / 155.0f, 1);
  69.                         pObj->m_nMaterialLayers = 0;
  70.                 }
  71.         }
  72. #endif //SEG_WORLD
  73.  
  74.         RenderInternal(pObj, rParams.nSubObjHideMask, rParams.lodValue, passInfo);
  75. }
  76.  
  77. void CStatObj::RenderStreamingDebugInfo(CRenderObject* pRenderObject)
  78. {
  79. #ifndef _RELEASE
  80.         //      CStatObj * pStreamable = m_pParentObject ? m_pParentObject : this;
  81.  
  82.         CStatObj* pStreamable = (m_pLod0 != 0) ? (CStatObj*)m_pLod0 : this;
  83.  
  84.         int nKB = 0;
  85.  
  86.         if (pStreamable->m_pRenderMesh)
  87.                 nKB += pStreamable->m_nRenderMeshMemoryUsage;
  88.  
  89.         for (int nLod = 1; pStreamable->m_pLODs && nLod < MAX_STATOBJ_LODS_NUM; nLod++)
  90.         {
  91.                 CStatObj* pLod = (CStatObj*)pStreamable->m_pLODs[nLod];
  92.  
  93.                 if (!pLod)
  94.                         continue;
  95.  
  96.                 if (pLod->m_pRenderMesh)
  97.                         nKB += pLod->m_nRenderMeshMemoryUsage;
  98.         }
  99.  
  100.         nKB >>= 10;
  101.  
  102.         if (nKB > GetCVars()->e_StreamCgfDebugMinObjSize)
  103.         {
  104.                 //              nKB = GetStreamableContentMemoryUsage(true) >> 10;
  105.  
  106.                 char* pComment = 0;
  107.  
  108.                 pStreamable = pStreamable->m_pParentObject ? pStreamable->m_pParentObject : pStreamable;
  109.  
  110.                 if (!pStreamable->m_bCanUnload)
  111.                         pComment = "No stream";
  112.                 else if (!pStreamable->m_bLodsAreLoadedFromSeparateFile && pStreamable->m_nLoadedLodsNum)
  113.                         pComment = "Single";
  114.                 else if (pStreamable->m_nLoadedLodsNum > 1)
  115.                         pComment = "Split";
  116.                 else
  117.                         pComment = "No LODs";
  118.  
  119.                 int nDiff = SATURATEB(int(float(nKB - GetCVars()->e_StreamCgfDebugMinObjSize) / max((int)1, GetCVars()->e_StreamCgfDebugMinObjSize) * 255));
  120.                 DrawBBoxLabeled(m_AABB, pRenderObject->m_II.m_Matrix, ColorB(nDiff, 255 - nDiff, 0, 255),
  121.                                 "%.2f mb, %s", 1.f / 1024.f * (float)nKB, pComment);
  122.         }
  123. #endif //_RELEASE
  124. }
  125.  
  126. //////////////////////////////////////////////////////////////////////
  127. void CStatObj::RenderCoverInfo(CRenderObject* pRenderObject)
  128. {
  129.         for (int i = 0; i < GetSubObjectCount(); ++i)
  130.         {
  131.                 const IStatObj::SSubObject* subObject = GetSubObject(i);
  132.                 if (subObject->nType != STATIC_SUB_OBJECT_DUMMY)
  133.                         continue;
  134.                 if (strstr(subObject->name, "$cover") == 0)
  135.                         continue;
  136.  
  137.                 Vec3 localBoxMin = -subObject->helperSize * 0.5f;
  138.                 Vec3 localBoxMax = subObject->helperSize * 0.5f;
  139.  
  140.                 GetRenderer()->GetIRenderAuxGeom()->DrawAABB(
  141.                   AABB(localBoxMin, localBoxMax),
  142.                   pRenderObject->m_II.m_Matrix * subObject->localTM,
  143.                   true, ColorB(192, 0, 255, 255),
  144.                   eBBD_Faceted);
  145.         }
  146. }
  147.  
  148. //////////////////////////////////////////////////////////////////////
  149. void CStatObj::FillRenderObject(const SRendParams& rParams, IRenderNode* pRenderNode, IMaterial* pMaterial,
  150.                                 SInstancingInfo* pInstInfo, CRenderObject*& pObj, const SRenderingPassInfo& passInfo)
  151. {
  152.  
  153.         //  FUNCTION_PROFILER_3DENGINE;
  154.  
  155.         ////////////////////////////////////////////////////////////////////////////////////////////////////
  156.         // Specify transformation
  157.         ////////////////////////////////////////////////////////////////////////////////////////////////////
  158.  
  159.         IRenderer* pRend = GetRenderer();
  160.  
  161.         assert(pObj);
  162.         if (!pObj)
  163.                 return;
  164.  
  165.         pObj->m_pRenderNode = pRenderNode;
  166.         pObj->m_editorSelectionID = rParams.nEditorSelectionID;
  167.  
  168.         SRenderObjData* pOD = NULL;
  169.         if (rParams.pFoliage || rParams.pInstance || rParams.m_pVisArea || pInstInfo || rParams.nVisionParams || rParams.nHUDSilhouettesParams ||
  170.             rParams.pLayerEffectParams || rParams.nSubObjHideMask != 0)
  171.         {
  172.                 pOD = pObj->GetObjData();
  173.  
  174.                 pOD->m_pSkinningData = rParams.pFoliage ? rParams.pFoliage->GetSkinningData(*rParams.pMatrix, passInfo) : NULL;
  175.                 if (pOD->m_pSkinningData)
  176.                         pObj->m_ObjFlags |= FOB_SKINNED;
  177.  
  178.                 //if (pInstInfo)
  179.                 //  pOD->m_pInstancingInfo = &pInstInfo->arrMats;
  180.  
  181.                 pOD->m_uniqueObjectId = reinterpret_cast<uintptr_t>(rParams.pInstance);
  182.                 pOD->m_pLayerEffectParams = rParams.pLayerEffectParams;
  183.                 pOD->m_nVisionParams = rParams.nVisionParams;
  184.                 pOD->m_nHUDSilhouetteParams = rParams.nHUDSilhouettesParams;
  185.  
  186.                 if (rParams.nSubObjHideMask != 0 && (m_pMergedRenderMesh != NULL))
  187.                 {
  188.                         // Only pass SubObject hide mask for merged objects, because they have a correct correlation between Hide Mask and Render Chunks.
  189.                         pOD->m_nSubObjHideMask = rParams.nSubObjHideMask;
  190.                         pObj->m_ObjFlags |= FOB_MESH_SUBSET_INDICES;
  191.                 }
  192.         }
  193.  
  194.         ////////////////////////////////////////////////////////////////////////////////////////////////////
  195.         // Set flags
  196.         ////////////////////////////////////////////////////////////////////////////////////////////////////
  197.  
  198.         pObj->m_ObjFlags |= FOB_TRANS_MASK;
  199.         pObj->m_ObjFlags |= rParams.dwFObjFlags;
  200.         //  SRenderObjData *pObjData = NULL;
  201.  
  202.         if (rParams.nTextureID >= 0)
  203.                 pObj->m_nTextureID = rParams.nTextureID;
  204.  
  205.         assert(rParams.pMatrix);
  206.         {
  207.                 pObj->m_II.m_Matrix = *rParams.pMatrix;
  208.         }
  209.  
  210.         pObj->m_II.m_AmbColor = rParams.AmbientColor;
  211.         pObj->m_nClipVolumeStencilRef = rParams.nClipVolumeStencilRef;
  212.  
  213.         pObj->m_ObjFlags |= FOB_INSHADOW;
  214.         pObj->m_fAlpha = rParams.fAlpha;
  215.         pObj->m_DissolveRef = rParams.nDissolveRef;
  216.  
  217.         ////////////////////////////////////////////////////////////////////////////////////////////////////
  218.         // Process bending
  219.         ////////////////////////////////////////////////////////////////////////////////////////////////////
  220.         if (pRenderNode && pRenderNode->GetRndFlags() & ERF_RECVWIND)
  221.         {
  222.                 // This can be different for CVegetation class render nodes
  223.                 pObj->m_vegetationBendingData.scale = 1.0f; //#TODO Read it from RenderNode?
  224.                 pObj->m_vegetationBendingData.verticalRadius = GetRadiusVert();
  225.         }
  226.  
  227.         ////////////////////////////////////////////////////////////////////////////////////////////////////
  228.         // Set render quality
  229.         ////////////////////////////////////////////////////////////////////////////////////////////////////
  230.  
  231.         pObj->m_fDistance = rParams.fDistance;
  232.  
  233.         {
  234.                 //clear, when exchange the state of pLightMapInfo to NULL, the pObj parameters must be update...
  235.                 pObj->m_nSort = fastround_positive(rParams.fDistance * 2.0f);
  236.         }
  237.  
  238.         ////////////////////////////////////////////////////////////////////////////////////////////////////
  239.         // Add render elements
  240.         ////////////////////////////////////////////////////////////////////////////////////////////////////
  241.         if (rParams.pMaterial)
  242.                 pMaterial = rParams.pMaterial;
  243.  
  244.         // prepare multi-layer stuff to render object
  245.         if (!rParams.nMaterialLayersBlend && rParams.nMaterialLayers)
  246.         {
  247.                 uint8 nFrozenLayer = (rParams.nMaterialLayers & MTL_LAYER_FROZEN) ? MTL_LAYER_FROZEN_MASK : 0;
  248.                 uint8 nWetLayer = (rParams.nMaterialLayers & MTL_LAYER_WET) ? MTL_LAYER_WET_MASK : 0;
  249.                 pObj->m_nMaterialLayers = (uint32) (nFrozenLayer << 24) | (nWetLayer << 16);
  250.         }
  251.         else
  252.                 pObj->m_nMaterialLayers = rParams.nMaterialLayersBlend;
  253.  
  254.         if (rParams.pTerrainTexInfo && (rParams.dwFObjFlags & (FOB_BLEND_WITH_TERRAIN_COLOR /* | FOB_AMBIENT_OCCLUSION*/)))
  255.         {
  256.                 pObj->m_nTextureID = rParams.pTerrainTexInfo->nTex0;
  257.                 //pObj->m_nTextureID1 = rParams.pTerrainTexInfo->nTex1;
  258.                 if (!pOD)
  259.                 {
  260.                         pOD = pObj->GetObjData();
  261.                 }
  262.                 pOD->m_fTempVars[0] = rParams.pTerrainTexInfo->fTexOffsetX;
  263.                 pOD->m_fTempVars[1] = rParams.pTerrainTexInfo->fTexOffsetY;
  264.                 pOD->m_fTempVars[2] = rParams.pTerrainTexInfo->fTexScale;
  265.                 pOD->m_fTempVars[3] = 0;
  266.                 pOD->m_fTempVars[4] = 0;
  267.         }
  268.  
  269.         if (rParams.nCustomData || rParams.nCustomFlags)
  270.         {
  271.                 if (!pOD)
  272.                 {
  273.                         pOD = pObj->GetObjData();
  274.                 }
  275.  
  276.                 pOD->m_nCustomData = rParams.nCustomData;
  277.                 pOD->m_nCustomFlags = rParams.nCustomFlags;
  278.  
  279.                 if (rParams.nCustomFlags & COB_CLOAK_HIGHLIGHT)
  280.                 {
  281.                         pOD->m_fTempVars[5] = rParams.fCustomData[0];
  282.                 }
  283.                 else if (rParams.nCustomFlags & COB_POST_3D_RENDER)
  284.                 {
  285.                         memcpy(&pOD->m_fTempVars[5], &rParams.fCustomData[0], sizeof(float) * 4);
  286.                         pObj->m_fAlpha = 1.0f; // Use the alpha in the post effect instead of here
  287.                         pOD->m_fTempVars[9] = rParams.fAlpha;
  288.                 }
  289.         }
  290.  
  291.         if (rParams.pFoliage)
  292.                 pObj->m_ObjFlags |= FOB_DYNAMIC_OBJECT;
  293.  
  294.         if (rParams.nAfterWater)
  295.                 pObj->m_ObjFlags |= FOB_AFTER_WATER;
  296.         else
  297.                 pObj->m_ObjFlags &= ~FOB_AFTER_WATER;
  298.  
  299.         pObj->m_pRenderNode = rParams.pRenderNode;
  300.         pObj->m_pCurrMaterial = pMaterial;
  301.  
  302.         if (Get3DEngine()->IsTessellationAllowed(pObj, passInfo))
  303.         {
  304.                 // Allow this RO to be tessellated, however actual tessellation will be applied if enabled in material
  305.                 pObj->m_ObjFlags |= FOB_ALLOW_TESSELLATION;
  306.         }
  307. }
  308.  
  309. //////////////////////////////////////////////////////////////////////////
  310. bool CStatObj::RenderDebugInfo(CRenderObject* pObj, const SRenderingPassInfo& passInfo)
  311. {
  312. #ifndef _RELEASE
  313.  
  314.         if (!passInfo.IsGeneralPass())
  315.                 return false;
  316.  
  317.         IMaterial* pMaterial = pObj->m_pCurrMaterial;
  318.  
  319.         IRenderAuxGeom* pAuxGeom = GetRenderer()->GetIRenderAuxGeom();
  320.         if (!pAuxGeom)
  321.                 return false;
  322.  
  323.         Matrix34 tm = pObj->m_II.m_Matrix;
  324.  
  325.         // Convert "camera space" to "world space"
  326.         if (pObj->m_ObjFlags & FOB_NEAREST)
  327.         {
  328.                 tm.AddTranslation(gEnv->pRenderer->GetCamera().GetPosition());
  329.         }
  330.  
  331.         bool bOnlyBoxes = GetCVars()->e_DebugDraw == -1;
  332.  
  333.         int e_DebugDraw = GetCVars()->e_DebugDraw;
  334.         string e_DebugDrawFilter = GetCVars()->e_DebugDrawFilter->GetString();
  335.         bool bHasHelperFilter = e_DebugDrawFilter != "";
  336.         bool bFiltered = false;
  337.  
  338.         if (e_DebugDraw == 1)
  339.         {
  340.                 string name;
  341.                 if (!m_szGeomName.empty())
  342.                         name = m_szGeomName.c_str();
  343.                 else
  344.                         name = PathUtil::GetFile(m_szFileName.c_str());
  345.  
  346.                 bFiltered = name.find(e_DebugDrawFilter) == string::npos;
  347.         }
  348.  
  349.         if ((GetCVars()->e_DebugDraw == 1 || bOnlyBoxes) && !bFiltered)
  350.         {
  351.                 if (!m_bMerged)
  352.                         pAuxGeom->DrawAABB(m_AABB, tm, false, ColorB(0, 255, 255, 128), eBBD_Faceted);
  353.                 else
  354.                         pAuxGeom->DrawAABB(m_AABB, tm, false, ColorB(255, 200, 0, 128), eBBD_Faceted);
  355.         }
  356.  
  357.         bool bNoText = e_DebugDraw < 0;
  358.         if (e_DebugDraw < 0)
  359.                 e_DebugDraw = -e_DebugDraw;
  360.  
  361.         if (m_nRenderTrisCount > 0 && !bOnlyBoxes && !bFiltered)
  362.         {
  363.                 // cgf's name and tris num
  364.  
  365.                 int nThisLod = 0;
  366.                 if (m_pLod0 && m_pLod0->m_pLODs)
  367.                 {
  368.                         for (int i = 0; i < MAX_STATOBJ_LODS_NUM; i++)
  369.                         {
  370.                                 if (m_pLod0->m_pLODs[i] == this)
  371.                                 {
  372.                                         nThisLod = i;
  373.                                         break;
  374.                                 }
  375.                         }
  376.                 }
  377.  
  378.                 const int nMaxUsableLod = (m_pLod0 != 0) ? m_pLod0->m_nMaxUsableLod : m_nMaxUsableLod;
  379.                 const int nRealNumLods = (m_pLod0 != 0) ? m_pLod0->m_nLoadedLodsNum : m_nLoadedLodsNum;
  380.  
  381.                 int nNumLods = nRealNumLods;
  382.                 if (nNumLods > nMaxUsableLod + 1)
  383.                         nNumLods = nMaxUsableLod + 1;
  384.  
  385.                 int nLod = nThisLod;
  386.                 if (nLod > nNumLods - 1)
  387.                         nLod = nNumLods - 1;
  388.  
  389.                 Vec3 pos = tm.TransformPoint(m_AABB.GetCenter());
  390.                 float color[4] = { 1, 1, 1, 1 };
  391.                 int nMats = m_pRenderMesh ? m_pRenderMesh->GetChunks().size() : 0;
  392.                 int nRenderMats = 0;
  393.  
  394.                 if (nMats)
  395.                 {
  396.                         for (int i = 0; i < nMats; ++i)
  397.                         {
  398.                                 CRenderChunk& rc = m_pRenderMesh->GetChunks()[i];
  399.                                 if (rc.pRE && rc.nNumIndices && rc.nNumVerts && ((rc.m_nMatFlags & MTL_FLAG_NODRAW) == 0))
  400.                                         ++nRenderMats;
  401.                         }
  402.                 }
  403.  
  404.                 switch (e_DebugDraw)
  405.                 {
  406.                 case 1:
  407.                         {
  408.                                 const char* shortName = "";
  409.                                 if (!m_szGeomName.empty())
  410.                                         shortName = m_szGeomName.c_str();
  411.                                 else
  412.                                         shortName = PathUtil::GetFile(m_szFileName.c_str());
  413.                                 if (nNumLods > 1)
  414.                                         IRenderAuxText::DrawLabelExF(pos, 1.3f, color, true, true, "%s\n%d (LOD %d/%d)", shortName, m_nRenderTrisCount, nLod, nNumLods);
  415.                                 else
  416.                                         IRenderAuxText::DrawLabelExF(pos, 1.3f, color, true, true, "%s\n%d", shortName, m_nRenderTrisCount);
  417.                         }
  418.                         break;
  419.  
  420.                 case 2:
  421.                         {
  422.                                 //////////////////////////////////////////////////////////////////////////
  423.                                 // Show colored poly count.
  424.                                 //////////////////////////////////////////////////////////////////////////
  425.                                 int fMult = 1;
  426.                                 int nTris = m_nRenderTrisCount;
  427.                                 ColorB clr = ColorB(0, 0, 0, 255);
  428.                                 if (nTris >= 20000 * fMult)
  429.                                         clr = ColorB(255, 0, 0, 255);
  430.                                 else if (nTris >= 10000 * fMult)
  431.                                         clr = ColorB(255, 255, 0, 255);
  432.                                 else if (nTris >= 5000 * fMult)
  433.                                         clr = ColorB(0, 255, 0, 255);
  434.                                 else if (nTris >= 2500 * fMult)
  435.                                         clr = ColorB(0, 255, 255, 255);
  436.                                 else if (nTris > 1250 * fMult)
  437.                                         clr = ColorB(0, 0, 255, 255);
  438.  
  439.                                 if (pMaterial)
  440.                                         pMaterial = GetMatMan()->GetDefaultHelperMaterial();
  441.                                 if (pObj)
  442.                                 {
  443.                                         pObj->m_II.m_AmbColor = ColorF(clr.r / 155.0f, clr.g / 155.0f, clr.b / 155.0f, 1);
  444.                                         pObj->m_nMaterialLayers = 0;
  445.                                         pObj->m_ObjFlags |= FOB_SELECTED;
  446.                                 }
  447.  
  448.                                 if (!bNoText)
  449.                                         IRenderAuxText::DrawLabelExF(pos, 1.3f, color, true, true, "%d", m_nRenderTrisCount);
  450.  
  451.                                 return false;
  452.                                 //////////////////////////////////////////////////////////////////////////
  453.                         }
  454.                 case 3:
  455.                         {
  456.                                 //////////////////////////////////////////////////////////////////////////
  457.                                 // Show Lods
  458.                                 //////////////////////////////////////////////////////////////////////////
  459.                                 ColorB clr;
  460.                                 if (nNumLods < 2)
  461.                                 {
  462.                                         if (m_nRenderTrisCount <= GetCVars()->e_LodMinTtris || nRealNumLods > 1)
  463.                                         {
  464.                                                 clr = ColorB(50, 50, 50, 255);
  465.                                         }
  466.                                         else
  467.                                         {
  468.                                                 clr = ColorB(255, 0, 0, 255);
  469.                                                 float fAngle = gEnv->pTimer->GetFrameStartTime().GetPeriodicFraction(1.0f) * gf_PI2;
  470.                                                 clr.g = 127 + (int)(sinf(fAngle) * 120);  // flashing color
  471.                                         }
  472.                                 }
  473.                                 else
  474.                                 {
  475.                                         if (nLod == 0)
  476.                                                 clr = ColorB(255, 0, 0, 255);
  477.                                         else if (nLod == 1)
  478.                                                 clr = ColorB(0, 255, 0, 255);
  479.                                         else if (nLod == 2)
  480.                                                 clr = ColorB(0, 0, 255, 255);
  481.                                         else if (nLod == 3)
  482.                                                 clr = ColorB(0, 255, 255, 255);
  483.                                         else if (nLod == 4)
  484.                                                 clr = ColorB(255, 255, 0, 255);
  485.                                         else if (nLod == 5)
  486.                                                 clr = ColorB(255, 0, 255, 255);
  487.                                         else
  488.                                                 clr = ColorB(255, 255, 255, 255);
  489.                                 }
  490.  
  491.                                 if (pMaterial)
  492.                                         pMaterial = GetMatMan()->GetDefaultHelperMaterial();
  493.                                 if (pObj)
  494.                                 {
  495.                                         pObj->m_II.m_AmbColor = ColorF(clr.r / 180.0f, clr.g / 180.0f, clr.b / 180.0f, 1);
  496.                                         pObj->m_nMaterialLayers = 0;
  497.                                         pObj->m_ObjFlags |= FOB_SELECTED;
  498.                                 }
  499.  
  500.                                 if (pObj && nNumLods > 1 && !bNoText)
  501.                                 {
  502.                                         const int nLod0 = GetMinUsableLod();
  503.                                         const int maxLod = GetMaxUsableLod();
  504.                                         const bool bRenderNodeValid(pObj && pObj->m_pRenderNode && ((UINT_PTR)(void*)(pObj->m_pRenderNode) > 0));
  505.                                         IRenderNode* pRN = (IRenderNode*)pObj->m_pRenderNode;
  506.                                         IRenderAuxText::DrawLabelExF(pos, 1.3f, color, true, true, "%d [%d;%d] (%d/%.1f)",
  507.                                                            nLod, nLod0, maxLod,
  508.                                                            bRenderNodeValid ? pRN->GetLodRatio() : -1, pObj->m_fDistance);
  509.                                 }
  510.  
  511.                                 return false;
  512.                                 //////////////////////////////////////////////////////////////////////////
  513.                         }
  514.                 case 4:
  515.                         {
  516.                                 // Show texture usage.
  517.                                 if (m_pRenderMesh)
  518.                                 {
  519.                                         int nTexMemUsage = m_pRenderMesh->GetTextureMemoryUsage(pMaterial);
  520.                                         IRenderAuxText::DrawLabelExF(pos, 1.3f, color, true, true, "%d", nTexMemUsage / 1024);    // in KByte
  521.                                 }
  522.                         }
  523.                         break;
  524.  
  525.                 case 5:
  526.                         {
  527.                                 //////////////////////////////////////////////////////////////////////////
  528.                                 // Show Num Render materials.
  529.                                 //////////////////////////////////////////////////////////////////////////
  530.                                 ColorB clr(0, 0, 0, 0);
  531.                                 if (nRenderMats == 1)
  532.                                         clr = ColorB(0, 0, 255, 255);
  533.                                 else if (nRenderMats == 2)
  534.                                         clr = ColorB(0, 255, 255, 255);
  535.                                 else if (nRenderMats == 3)
  536.                                         clr = ColorB(0, 255, 0, 255);
  537.                                 else if (nRenderMats == 4)
  538.                                         clr = ColorB(255, 0, 255, 255);
  539.                                 else if (nRenderMats == 5)
  540.                                         clr = ColorB(255, 255, 0, 255);
  541.                                 else if (nRenderMats >= 6)
  542.                                         clr = ColorB(255, 0, 0, 255);
  543.                                 else if (nRenderMats >= 11)
  544.                                         clr = ColorB(255, 255, 255, 255);
  545.  
  546.                                 if (pMaterial)
  547.                                         pMaterial = GetMatMan()->GetDefaultHelperMaterial();
  548.                                 if (pObj)
  549.                                 {
  550.                                         pObj->m_II.m_AmbColor = ColorF(clr.r / 155.0f, clr.g / 155.0f, clr.b / 155.0f, 1);
  551.                                         pObj->m_nMaterialLayers = 0;
  552.                                         pObj->m_ObjFlags |= FOB_SELECTED;
  553.                                 }
  554.  
  555.                                 if (!bNoText)
  556.                                         IRenderAuxText::DrawLabelExF(pos, 1.3f, color, true, true, "%d", nRenderMats);
  557.                         }
  558.                         break;
  559.  
  560.                 case 6:
  561.                         {
  562.                                 if (pMaterial)
  563.                                         pMaterial = GetMatMan()->GetDefaultHelperMaterial();
  564.  
  565.                                 ColorF col(1, 1, 1, 1);
  566.                                 if (pObj)
  567.                                 {
  568.                                         pObj->m_nMaterialLayers = 0;
  569.                                         col = pObj->m_II.m_AmbColor;
  570.                                 }
  571.  
  572.                                 IRenderAuxText::DrawLabelExF(pos, 1.3f, color, true, true, "%d,%d,%d,%d", (int)(col.r * 255.0f), (int)(col.g * 255.0f), (int)(col.b * 255.0f), (int)(col.a * 255.0f));
  573.                         }
  574.                         break;
  575.  
  576.                 case 7:
  577.                         if (m_pRenderMesh)
  578.                         {
  579.                                 int nTexMemUsage = m_pRenderMesh->GetTextureMemoryUsage(pMaterial);
  580.                                 IRenderAuxText::DrawLabelExF(pos, 1.3f, color, true, true, "%d,%d,%d", m_nRenderTrisCount, nRenderMats, nTexMemUsage / 1024);
  581.                         }
  582.                         break;
  583.  
  584.                 case 16:
  585.                         {
  586.                                 // Draw stats for object selected by debug gun
  587.                                 if (GetRenderer()->IsDebugRenderNode((IRenderNode*)pObj->m_pRenderNode))
  588.                                 {
  589.                                         const char* shortName = PathUtil::GetFile(m_szFileName.c_str());
  590.  
  591.                                         int texMemUsage = 0;
  592.  
  593.                                         if (m_pRenderMesh)
  594.                                         {
  595.                                                 texMemUsage = m_pRenderMesh->GetTextureMemoryUsage(pMaterial);
  596.                                         }
  597.  
  598.                                         pAuxGeom->DrawAABB(m_AABB, tm, false, ColorB(0, 255, 255, 128), eBBD_Faceted);
  599.  
  600.                                         float yellow[4] = { 1.f, 1.f, 0.f, 1.f };
  601.  
  602.                                         const float yOffset = 165.f;
  603.                                         const float xOffset = 970.f;
  604.  
  605.                                         if (m_pParentObject == NULL)
  606.                                         {
  607.                                                 IRenderAuxText::Draw2dLabel(xOffset, 40.f, 1.5f, yellow, false, "%s", shortName);
  608.  
  609.                                                 IRenderAuxText::Draw2dLabel(xOffset, yOffset, 1.5f, color, false,
  610.                                                                    //"Mesh: %s\n"
  611.                                                                    "LOD: %d/%d\n"
  612.                                                                    "Num Instances: %d\n"
  613.                                                                    "Num Tris: %d\n"
  614.                                                                    "Tex Mem usage: %.2f kb\n"
  615.                                                                    "Mesh Mem usage: %.2f kb\n"
  616.                                                                    "Num Materials: %d\n"
  617.                                                                    "Mesh Type: %s\n",
  618.                                                                    //shortName,
  619.                                                                    nLod, nNumLods,
  620.                                                                    m_nUsers,
  621.                                                                    m_nRenderTrisCount,
  622.                                                                    texMemUsage / 1024.f,
  623.                                                                    m_nRenderMeshMemoryUsage / 1024.f,
  624.                                                                    nRenderMats,
  625.                                                                    m_pRenderMesh->GetTypeName());
  626.                                         }
  627.                                         else
  628.                                         {
  629.                                                 for (int i = 0; i < m_pParentObject->SubObjectCount(); i++)
  630.                                                 {
  631.                                                         //find subobject position
  632.                                                         if (m_pParentObject->SubObject(i).pStatObj == this)
  633.                                                         {
  634.                                                                 //only render the header once
  635.                                                                 if (i == 0)
  636.                                                                 {
  637.                                                                         IRenderAuxText::Draw2dLabel(600.f, 40.f, 2.f, yellow, false, "Debug Gun: %s", shortName);
  638.                                                                 }
  639.                                                                 float y = yOffset + ((i % 4) * 150.f);
  640.                                                                 float x = xOffset - (floor(i / 4.f) * 200.f);
  641.  
  642.                                                                 IRenderAuxText::Draw2dLabel(x, y, 1.5f, color, false,
  643.                                                                                    "Sub Mesh: %s\n"
  644.                                                                                    "LOD: %d/%d\n"
  645.                                                                                    "Num Instances: %d\n"
  646.                                                                                    "Num Tris: %d\n"
  647.                                                                                    "Tex Mem usage: %.2f kb\n"
  648.                                                                                    "Mesh Mem usage: %.2f kb\n"
  649.                                                                                    "Num Materials: %d\n"
  650.                                                                                    "Mesh Type: %s\n",
  651.                                                                                    m_szGeomName.c_str() ? m_szGeomName.c_str() : "UNKNOWN",
  652.                                                                                    nLod, nNumLods,
  653.                                                                                    m_nUsers,
  654.                                                                                    m_nRenderTrisCount,
  655.                                                                                    texMemUsage / 1024.f,
  656.                                                                                    m_nRenderMeshMemoryUsage / 1024.f,
  657.                                                                                    nRenderMats,
  658.                                                                                    m_pRenderMesh->GetTypeName());
  659.  
  660.                                                                 break;
  661.                                                         }
  662.                                                 }
  663.                                         }
  664.                                 }
  665.                         }
  666.                         break;
  667.  
  668.                 case 19:  // Displays the triangle count of physic proxies.
  669.                         if (!bNoText)
  670.                         {
  671.                                 int nPhysTrisCount = 0;
  672.                                 for (int j = 0; j < MAX_PHYS_GEOMS_TYPES; ++j)
  673.                                 {
  674.                                         if (GetPhysGeom(j))
  675.                                                 nPhysTrisCount += GetPhysGeom(j)->pGeom->GetPrimitiveCount();
  676.                                 }
  677.  
  678.                                 if (nPhysTrisCount == 0)
  679.                                         color[3] = 0.1f;
  680.  
  681.                                 IRenderAuxText::DrawLabelExF(pos, 1.3f, color, true, true, "%d", nPhysTrisCount);
  682.                         }
  683.                         return false;
  684.  
  685.                 case 22:
  686.                         {
  687.                                 // Show texture usage.
  688.                                 if (m_pRenderMesh)
  689.                                 {
  690.                                         IRenderAuxText::DrawLabelExF(pos, 1.3f, color, true, true, "[LOD %d: %d]", nLod, m_pRenderMesh->GetVerticesCount());
  691.                                 }
  692.                         }
  693.                         break;
  694.                 case 23:
  695.                         {
  696.                                 if (pObj && pObj->m_pRenderNode)
  697.                                 {
  698.                                         IRenderNode* pRenderNode = (IRenderNode*)pObj->m_pRenderNode;
  699.                                         const bool bCastsShadow = (pRenderNode->GetRndFlags() & ERF_CASTSHADOWMAPS) != 0;
  700.                                         ColorF clr = bCastsShadow ? ColorF(1.f, 0.f, 0.f, 1.0f) : ColorF(0.f, 1.f, 0.f, 1.f);
  701.  
  702.                                         int nIndices = 0;
  703.                                         int nIndicesNoShadow = 0;
  704.  
  705.                                         // figure out how many primitives actually cast shadows
  706.                                         if (pMaterial && bCastsShadow)
  707.                                         {
  708.                                                 for (int i = 0; i < nMats; ++i)
  709.                                                 {
  710.                                                         CRenderChunk& rc = m_pRenderMesh->GetChunks()[i];
  711.                                                         if (rc.pRE && rc.nNumIndices && rc.nNumVerts && ((rc.m_nMatFlags & MTL_FLAG_NODRAW) == 0))
  712.                                                         {
  713.                                                                 SShaderItem& ShaderItem = pMaterial->GetShaderItem(rc.m_nMatID);
  714.                                                                 IRenderShaderResources* pR = ShaderItem.m_pShaderResources;
  715.  
  716.                                                                 if (pR && (pR->GetResFlags() & MTL_FLAG_NOSHADOW))
  717.                                                                         nIndicesNoShadow += rc.nNumIndices;
  718.  
  719.                                                                 nIndices += rc.nNumIndices;
  720.                                                         }
  721.                                                 }
  722.  
  723.                                                 Vec3 red, green;
  724.                                                 ColorF(1.f, 0.f, 0.f, 1.0f).toHSV(red.x, red.y, red.z);
  725.                                                 ColorF(0.f, 1.f, 0.f, 1.0f).toHSV(green.x, green.y, green.z);
  726.  
  727.                                                 Vec3 c = Vec3::CreateLerp(red, green, (float)nIndicesNoShadow / max(nIndices, 1));
  728.                                                 clr.fromHSV(c.x, c.y, c.z);
  729.  
  730.                                                 pMaterial = GetMatMan()->GetDefaultHelperMaterial();
  731.                                         }
  732.  
  733.                                         pObj->m_II.m_AmbColor = clr;
  734.                                         pObj->m_nMaterialLayers = 0;
  735.                                         pObj->m_ObjFlags |= FOB_SELECTED;
  736.                                 }
  737.                                 return false;
  738.                         }
  739.                 }
  740.         }
  741.  
  742.         if (GetCVars()->e_DebugDraw == 15 && !bOnlyBoxes)
  743.         {
  744.                 // helpers
  745.                 for (int i = 0; i < (int)m_subObjects.size(); i++)
  746.                 {
  747.                         SSubObject* pSubObject = &(m_subObjects[i]);
  748.                         if (pSubObject->nType == STATIC_SUB_OBJECT_MESH && pSubObject->pStatObj)
  749.                                 continue;
  750.  
  751.                         if (bHasHelperFilter)
  752.                         {
  753.                                 if (pSubObject->name.find(e_DebugDrawFilter) == string::npos)
  754.                                         continue;
  755.                         }
  756.  
  757.                         // make object matrix
  758.                         Matrix34 tMat = tm * pSubObject->tm;
  759.                         Vec3 pos = tMat.GetTranslation();
  760.  
  761.                         // draw axes
  762.                         float s = 0.02f;
  763.                         ColorB col(0, 255, 255, 255);
  764.                         pAuxGeom->DrawAABB(AABB(Vec3(-s, -s, -s), Vec3(s, s, s)), tMat, false, col, eBBD_Faceted);
  765.                         pAuxGeom->DrawLine(pos + s * tMat.GetColumn1(), col, pos + 3.f * s * tMat.GetColumn1(), col);
  766.  
  767.                         // text
  768.                         float color[4] = { 0, 1, 1, 1 };
  769.                         IRenderAuxText::DrawLabelEx(pos, 1.3f, color, true, true, pSubObject->name.c_str());
  770.                 }
  771.         }
  772.  
  773.         if (Get3DEngine()->IsDebugDrawListEnabled())
  774.         {
  775.                 I3DEngine::SObjectInfoToAddToDebugDrawList objectInfo;
  776.                 if (pObj->m_pRenderNode)
  777.                 {
  778.                         objectInfo.pName = ((IRenderNode*)pObj->m_pRenderNode)->GetName();
  779.                         objectInfo.pClassName = ((IRenderNode*)pObj->m_pRenderNode)->GetEntityClassName();
  780.                 }
  781.                 else
  782.                 {
  783.                         objectInfo.pName = "";
  784.                         objectInfo.pClassName = "";
  785.                 }
  786.                 objectInfo.pFileName = m_szFileName.c_str();
  787.                 if (m_pRenderMesh && pObj->m_pCurrMaterial)
  788.                         objectInfo.texMemory = m_pRenderMesh->GetTextureMemoryUsage(pObj->m_pCurrMaterial);
  789.                 else
  790.                         objectInfo.texMemory = 0;
  791.                 objectInfo.numTris = m_nRenderTrisCount;
  792.                 objectInfo.numVerts = m_nLoadedVertexCount;
  793.                 objectInfo.meshMemory = m_nRenderMeshMemoryUsage;
  794.                 objectInfo.pMat = &tm;
  795.                 objectInfo.pBox = &m_AABB;
  796.                 objectInfo.type = I3DEngine::DLOT_STATOBJ;
  797.                 objectInfo.pRenderNode = (IRenderNode*)(pObj->m_pRenderNode);
  798.                 Get3DEngine()->AddObjToDebugDrawList(objectInfo);
  799.         }
  800.  
  801. #endif //_RELEASE
  802.         return false;
  803. }
  804.  
  805. //
  806. // StatObj functions.
  807. //
  808.  
  809. float CStatObj::GetExtent(EGeomForm eForm)
  810. {
  811.         int nSubCount = m_subObjects.size();
  812.         if (!nSubCount)
  813.         {
  814.                 return m_pRenderMesh ? m_pRenderMesh->GetExtent(eForm) : 0.f;
  815.         }
  816.  
  817.         CGeomExtent& ext = m_Extents.Make(eForm);
  818.         if (!ext)
  819.         {
  820.                 // Create parts for main and sub-objects.
  821.                 ext.ReserveParts(1 + nSubCount);
  822.  
  823.                 ext.AddPart(m_pRenderMesh ? m_pRenderMesh->GetExtent(eForm) : 0.f);
  824.  
  825.                 // Evaluate sub-objects.
  826.                 for (int i = 0; i < nSubCount; i++)
  827.                 {
  828.                         IStatObj::SSubObject* pSub = &m_subObjects[i];
  829.                         if (pSub->nType == STATIC_SUB_OBJECT_MESH && pSub->pStatObj)
  830.                         {
  831.                                 float fExt = pSub->pStatObj->GetExtent(eForm);
  832.                                 fExt *= ScaleExtent(eForm, pSub->tm);
  833.                                 ext.AddPart(fExt);
  834.                         }
  835.                         else
  836.                                 ext.AddPart(0.f);
  837.                 }
  838.         }
  839.         return ext.TotalExtent();
  840. }
  841.  
  842. void CStatObj::GetRandomPos(PosNorm& ran, CRndGen& seed, EGeomForm eForm) const
  843. {
  844.         if (!m_subObjects.empty())
  845.         {
  846.                 CGeomExtent const& ext = m_Extents[eForm];
  847.                 int iSubObj = ext.RandomPart(seed);
  848.                 if (iSubObj-- > 0)
  849.                 {
  850.                         IStatObj::SSubObject const* pSub = &m_subObjects[iSubObj];
  851.                         assert(pSub && pSub->pStatObj);
  852.                         pSub->pStatObj->GetRandomPos(ran, seed, eForm);
  853.                         ran <<= pSub->tm;
  854.                         return;
  855.                 }
  856.         }
  857.         if (m_pRenderMesh)
  858.                 m_pRenderMesh->GetRandomPos(ran, seed, eForm);
  859.         else
  860.                 ran.zero();
  861. }
  862.  
  863. SMeshLodInfo CStatObj::ComputeAndStoreLodDistances()
  864. {
  865.         SMeshLodInfo lodInfo;
  866.         lodInfo.Clear();
  867.  
  868.         lodInfo.fGeometricMean = m_fGeometricMeanFaceArea;
  869.         lodInfo.nFaceCount = m_nRenderTrisCount;
  870.  
  871.         if (GetFlags() & STATIC_OBJECT_COMPOUND)
  872.         {
  873.                 for (uint i = 0; i < m_subObjects.size(); ++i)
  874.                 {
  875.                         if (m_subObjects[i].nType == STATIC_SUB_OBJECT_MESH && m_subObjects[i].bShadowProxy == false && m_subObjects[i].pStatObj != NULL)
  876.                         {
  877.                                 CStatObj* pStatObj = static_cast<CStatObj*>(m_subObjects[i].pStatObj);
  878.  
  879.                                 SMeshLodInfo subLodInfo = pStatObj->ComputeAndStoreLodDistances();
  880.  
  881.                                 lodInfo.Merge(subLodInfo);
  882.                         }
  883.                 }
  884.         }
  885.  
  886.         m_fLodDistance = sqrt(lodInfo.fGeometricMean);
  887.         return lodInfo;
  888. }
  889.  
  890. SMeshLodInfo CStatObj::ComputeGeometricMean() const
  891. {
  892.         SMeshLodInfo lodInfo;
  893.         lodInfo.Clear();
  894.  
  895.         lodInfo.fGeometricMean = m_fGeometricMeanFaceArea;
  896.         lodInfo.nFaceCount = m_nRenderTrisCount;
  897.  
  898.         if (GetFlags() & STATIC_OBJECT_COMPOUND)
  899.         {
  900.                 for (uint i = 0; i < m_subObjects.size(); ++i)
  901.                 {
  902.                         if (m_subObjects[i].nType == STATIC_SUB_OBJECT_MESH && m_subObjects[i].bShadowProxy == false && m_subObjects[i].pStatObj != NULL)
  903.                         {
  904.                                 SMeshLodInfo subLodInfo = static_cast<const CStatObj*>(m_subObjects[i].pStatObj)->ComputeGeometricMean();
  905.  
  906.                                 lodInfo.Merge(subLodInfo);
  907.                         }
  908.                 }
  909.         }
  910.  
  911.         return lodInfo;
  912. }
  913.  
  914. int CStatObj::ComputeLodFromScale(float fScale, float fLodRatioNormalized, float fEntDistance, bool bFoliage, bool bForPrecache)
  915. {
  916.         assert(!m_pLod0);
  917.  
  918.         int nNewLod = 0;
  919.  
  920.         // use legacy LOD calculation, without an IRenderNode
  921.         nNewLod = (int)(fEntDistance * (fLodRatioNormalized * fLodRatioNormalized) / (max(GetCVars()->e_LodRatio * min(GetRadius() * fScale, GetFloatCVar(e_LodCompMaxSize)), 0.001f)));
  922.  
  923.         const int nMinLod = GetMinUsableLod();
  924.         nNewLod += nMinLod;
  925.  
  926.         int nMaxUsableLod = min((int)m_nMaxUsableLod, GetCVars()->e_LodMax);
  927.         if (!nMaxUsableLod && bForPrecache)
  928.                 nMaxUsableLod = 1;
  929.  
  930.         nNewLod = bFoliage ? 0 : CLAMP(nNewLod, 0, nMaxUsableLod);
  931.  
  932.         return nNewLod;
  933. }
  934.  
  935. //////////////////////////////////////////////////////////////////////////
  936. void CStatObj::DebugDraw(const SGeometryDebugDrawInfo& info)
  937. {
  938.         if (m_nFlags & STATIC_OBJECT_COMPOUND && !m_bMerged)
  939.         {
  940.                 // Draw sub objects.
  941.                 for (int i = 0; i < (int)m_subObjects.size(); i++)
  942.                 {
  943.                         if (!m_subObjects[i].pStatObj || m_subObjects[i].bHidden || m_subObjects[i].nType != STATIC_SUB_OBJECT_MESH)
  944.                                 continue;
  945.  
  946.                         SGeometryDebugDrawInfo subInfo = info;
  947.                         subInfo.tm = info.tm * m_subObjects[i].tm;
  948.                         m_subObjects[i].pStatObj->DebugDraw(subInfo);
  949.                 }
  950.         }
  951.         else if (m_pRenderMesh)
  952.         {
  953.                 m_pRenderMesh->DebugDraw(info, ~0);
  954.         }
  955.         else
  956.         {
  957.                 // No RenderMesh in here, so probably no geometry in highest LOD, find it in lower LODs
  958.                 if (m_pLODs)
  959.                 {
  960.                         assert(m_nMaxUsableLod < MAX_STATOBJ_LODS_NUM);
  961.                         for (int nLod = 0; nLod <= (int)m_nMaxUsableLod; nLod++)
  962.                         {
  963.                                 if (m_pLODs[nLod] && m_pLODs[nLod]->m_pRenderMesh)
  964.                                 {
  965.                                         m_pLODs[nLod]->m_pRenderMesh->DebugDraw(info, ~0);
  966.                                         break;
  967.                                 }
  968.                         }
  969.                 }
  970.         }
  971. }
  972.  
  973. ///////////////////////////////////////////////////////////////////////////////
  974. ///////////////////////////////////////////////////////////////////////////////
  975. void CStatObj::RenderInternal(CRenderObject* pRenderObject, hidemask nSubObjectHideMask, const CLodValue& lodValue, const SRenderingPassInfo& passInfo)
  976. {
  977.         FUNCTION_PROFILER_3DENGINE;
  978.  
  979.         if (m_nFlags & STATIC_OBJECT_HIDDEN)
  980.                 return;
  981.  
  982.         m_nLastDrawMainFrameId = passInfo.GetMainFrameID();
  983.         if (m_pParentObject)
  984.                 m_pParentObject->m_nLastDrawMainFrameId = passInfo.GetMainFrameID();
  985.  
  986.         hidemask *pMask = !nSubObjectHideMask ? &m_nInitialSubObjHideMask : &nSubObjectHideMask;
  987.         if (!!*pMask)
  988.         {
  989.                 if ((m_pMergedRenderMesh != NULL) && !(pRenderObject->m_ObjFlags & FOB_MESH_SUBSET_INDICES)) // If not already set by per-instance hide mask.
  990.                 {
  991.                         SRenderObjData* pOD = pRenderObject->GetObjData();
  992.  
  993.                         // Only pass SubObject hide mask for merged objects, because they have a correct correlation between Hide Mask and Render Chunks.
  994.                         pOD->m_nSubObjHideMask = *pMask;
  995.                         pRenderObject->m_ObjFlags |= FOB_MESH_SUBSET_INDICES;
  996.                 }
  997.         }
  998.  
  999.         if (pRenderObject->m_pRenderNode)
  1000.         {
  1001.                 IRenderNode* pRN = (IRenderNode*)pRenderObject->m_pRenderNode;
  1002.                 if (m_bEditor)
  1003.                 {
  1004.                         if (pRN->m_dwRndFlags & ERF_SELECTED)
  1005.                         {
  1006.                                 m_nSelectedFrameId = passInfo.GetMainFrameID();
  1007.                                 if (m_pParentObject)
  1008.                                         m_pParentObject->m_nSelectedFrameId = passInfo.GetMainFrameID();
  1009.                                 pRenderObject->m_ObjFlags |= FOB_SELECTED;
  1010.                         }
  1011.                         else
  1012.                                 pRenderObject->m_ObjFlags &= ~FOB_SELECTED;
  1013.  
  1014.                         if (!gEnv->IsEditing() && pRN->m_dwRndFlags & ERF_RAYCAST_PROXY)
  1015.                         {
  1016.                                 return;
  1017.                         }
  1018.                 }
  1019.                 else
  1020.                 {
  1021.                         if (pRN->m_dwRndFlags & ERF_RAYCAST_PROXY)
  1022.                         {
  1023.                                 return;
  1024.                         }
  1025.                 }
  1026.         }
  1027.  
  1028. #ifdef SEG_WORLD
  1029.         if (GetISystem()->GetIConsole()->GetCVar("sw_debugInfo")->GetIVal() == 4)
  1030.         {
  1031.                 pRenderObject->m_ObjFlags |= FOB_SELECTED;
  1032.         }
  1033. #endif //SEG_WORLD
  1034.  
  1035.         if ((m_nFlags & STATIC_OBJECT_COMPOUND) && !m_bMerged)
  1036.         {
  1037.                 //////////////////////////////////////////////////////////////////////////
  1038.                 // Render SubMeshes if present.
  1039.                 //////////////////////////////////////////////////////////////////////////
  1040.                 if (m_nSubObjectMeshCount > 0)
  1041.                 {
  1042.                         CRenderObject* pRenderObjectB = NULL;
  1043.  
  1044.                         if (lodValue.DissolveRefB() != 255)
  1045.                         {
  1046.                                 pRenderObject->m_DissolveRef = lodValue.DissolveRefA();
  1047.  
  1048.                                 if (pRenderObject->m_DissolveRef)
  1049.                                 {
  1050.                                         if (!(pRenderObject->m_ObjFlags & FOB_DISSOLVE))
  1051.                                                 pRenderObject->m_ObjFlags &= ~FOB_UPDATED_RTMASK;
  1052.                                         pRenderObject->m_ObjFlags |= FOB_DISSOLVE;
  1053.  
  1054.                                         pRenderObject->m_ObjFlags |= FOB_DISSOLVE_OUT;
  1055.                                 }
  1056.                                 else
  1057.                                 {
  1058.                                         if ((pRenderObject->m_ObjFlags & FOB_DISSOLVE))
  1059.                                                 pRenderObject->m_ObjFlags &= ~FOB_UPDATED_RTMASK;
  1060.                                         pRenderObject->m_ObjFlags &= ~FOB_DISSOLVE;
  1061.                                 }
  1062.  
  1063.                                 if (lodValue.LodB() != -1)
  1064.                                 {
  1065.                                         pRenderObjectB = GetRenderer()->EF_DuplicateRO(pRenderObject, passInfo);
  1066.                                         pRenderObjectB->m_ObjFlags &= ~FOB_DISSOLVE_OUT;
  1067.                                 }
  1068.                         }
  1069.                         else
  1070.                         {
  1071.                                 pRenderObject->m_DissolveRef = 0;
  1072.                                 if ((pRenderObject->m_ObjFlags & FOB_DISSOLVE))
  1073.                                         pRenderObject->m_ObjFlags &= ~FOB_UPDATED_RTMASK;
  1074.                                 pRenderObject->m_ObjFlags &= ~(FOB_DISSOLVE | FOB_DISSOLVE_OUT);
  1075.                         }
  1076.  
  1077.                         hidemaskOneBit nBitIndex = hidemask1;
  1078.                         Matrix34A renderTM = pRenderObject->m_II.m_Matrix;
  1079.                         for (int32 i = 0, subObjectsSize = m_subObjects.size(); i < subObjectsSize; ++i, nBitIndex <<= 1)
  1080.                         {
  1081.                                 const SSubObject& subObj = m_subObjects[i];
  1082.                                 if (subObj.nType == STATIC_SUB_OBJECT_MESH)  // all the meshes are at the beginning of the array.
  1083.                                 {
  1084.                                         CStatObj* const __restrict pStatObj = (CStatObj*)subObj.pStatObj;
  1085.  
  1086.                                         if (pStatObj &&
  1087.                                                 (pStatObj->m_nRenderTrisCount >= 2) &&
  1088.                                                 !(pStatObj->m_nFlags & STATIC_OBJECT_HIDDEN) &&
  1089.                                                 !(*pMask & nBitIndex)
  1090.                                                 )
  1091.                                         {
  1092.                                                 PrefetchLine(pRenderObject, 0);
  1093.                                                
  1094.                                                 if (lodValue.LodA() >= 0)
  1095.                                                 {
  1096.                                                 RenderSubObject(pRenderObject, lodValue.LodA(), i, renderTM, passInfo);
  1097.                                                 }
  1098.  
  1099.                                                 if (pRenderObjectB && lodValue.LodB()>=0)
  1100.                                                 {
  1101.                                                         PrefetchLine(pRenderObjectB, 0);
  1102.                                                         RenderSubObject(pRenderObjectB, lodValue.LodB(), i, renderTM, passInfo);
  1103.                                                 }
  1104.                                         }
  1105.                                 }
  1106.                                 else
  1107.                                 {
  1108.                                         break;
  1109.                                 }
  1110.                         }
  1111.  
  1112.                         if (GetCVars()->e_DebugDraw)
  1113.                         {
  1114.                                 RenderDebugInfo(pRenderObject, passInfo);
  1115.                         }
  1116.                 }
  1117.  
  1118.                 //////////////////////////////////////////////////////////////////////////
  1119.         }
  1120.         else
  1121.         {
  1122.                 // draw mesh, don't even try to render childs
  1123.                 if (lodValue.LodA() >= 0)
  1124.                 {
  1125.                 RenderObjectInternal(pRenderObject, lodValue.LodA(), lodValue.DissolveRefA(), true, passInfo);
  1126.                 }
  1127.  
  1128.                 if (lodValue.DissolveRefB() != 255 && lodValue.LodB()>=0) // check here since we're passing in A's ref.
  1129.                 {
  1130.                         pRenderObject = GetRenderer()->EF_DuplicateRO(pRenderObject, passInfo);
  1131.                         RenderObjectInternal(pRenderObject, lodValue.LodB(), lodValue.DissolveRefA(), false, passInfo);
  1132.                 }
  1133.         }
  1134. }
  1135.  
  1136. ///////////////////////////////////////////////////////////////////////////////
  1137. void CStatObj::RenderSubObject(CRenderObject* pRenderObject, int nLod,
  1138.         int nSubObjId, const Matrix34A& renderTM, const SRenderingPassInfo& passInfo)
  1139. {
  1140.         const SSubObject& subObj = m_subObjects[nSubObjId];
  1141.  
  1142.         CStatObj* const __restrict pStatObj = (CStatObj*)subObj.pStatObj;
  1143.  
  1144.         if (pStatObj == NULL)
  1145.                 return;
  1146.  
  1147.         SRenderObjData* pOD = 0;
  1148.         if (subObj.pFoliage)
  1149.         {
  1150.                 pRenderObject = GetRenderer()->EF_DuplicateRO(pRenderObject, passInfo);
  1151.                 pOD = pRenderObject->GetObjData();
  1152.                 pOD->m_pSkinningData = subObj.pFoliage->GetSkinningData(pRenderObject->m_II.m_Matrix, passInfo);
  1153.                 pOD->m_uniqueObjectId = reinterpret_cast<uintptr_t>(subObj.pFoliage);
  1154.                 pRenderObject->m_ObjFlags |= FOB_SKINNED | FOB_DYNAMIC_OBJECT;
  1155.                 ((CStatObjFoliage*)subObj.pFoliage)->m_pRenderObject = pRenderObject;
  1156.         }
  1157.  
  1158.         if (subObj.bIdentityMatrix)
  1159.         {
  1160.                 pStatObj->RenderSubObjectInternal(pRenderObject, nLod, passInfo);
  1161.         }
  1162.         else
  1163.         {
  1164.                 pRenderObject = GetRenderer()->EF_DuplicateRO(pRenderObject, passInfo);
  1165.                 pRenderObject->m_II.m_Matrix = renderTM * subObj.tm;
  1166.                 SRenderObjData* pRenderObjectData = pRenderObject->GetObjData();
  1167.                 pRenderObjectData->m_uniqueObjectId = pRenderObjectData->m_uniqueObjectId + nSubObjId;
  1168.  
  1169.                 pStatObj->RenderSubObjectInternal(pRenderObject, nLod, passInfo);
  1170.         }
  1171. }
  1172.  
  1173. ///////////////////////////////////////////////////////////////////////////////
  1174. void CStatObj::RenderSubObjectInternal(CRenderObject* pRenderObject, int nLod, const SRenderingPassInfo& passInfo)
  1175. {
  1176.         assert(!(m_nFlags & STATIC_OBJECT_HIDDEN));
  1177.         assert(m_nRenderTrisCount);
  1178.  
  1179.         m_nLastDrawMainFrameId = passInfo.GetMainFrameID();
  1180.         if (m_pParentObject && (m_nFlags & STATIC_OBJECT_MULTIPLE_PARENTS))
  1181.                 m_pParentObject->m_nLastDrawMainFrameId = passInfo.GetMainFrameID();
  1182.  
  1183.         assert(!m_pParentObject || m_pParentObject->m_nLastDrawMainFrameId == passInfo.GetMainFrameID());
  1184.  
  1185.         assert(!(m_nFlags & STATIC_OBJECT_COMPOUND));
  1186.  
  1187.         nLod = CLAMP(nLod, GetMinUsableLod(), (int)m_nMaxUsableLod);
  1188.         assert(nLod < MAX_STATOBJ_LODS_NUM);
  1189.  
  1190.         // Skip rendering of this suboject if it is marked as deformable
  1191.         if (GetCVars()->e_MergedMeshes == 1 && nLod == 0 && m_isDeformable)
  1192.                 return;
  1193.  
  1194.         // try next lod's if selected one is not ready
  1195.         if ((!nLod && m_pRenderMesh && m_pRenderMesh->CanRender()) || !GetCVars()->e_Lods)
  1196.         {
  1197.                 PrefetchLine(pRenderObject, 0);
  1198.                 RenderRenderMesh(pRenderObject, NULL, passInfo);
  1199.         }
  1200.         else
  1201.         {
  1202.                 if (m_pLODs && m_pLODs[nLod])
  1203.                 {
  1204.                         m_pLODs[nLod]->m_nLastDrawMainFrameId = passInfo.GetMainFrameID();
  1205.                         if (m_pLODs[nLod]->m_pParentObject)
  1206.                                 m_pLODs[nLod]->m_pParentObject->m_nLastDrawMainFrameId = passInfo.GetMainFrameID();
  1207.  
  1208.                         if ((nLod + 1) < MAX_STATOBJ_LODS_NUM && m_pLODs[nLod + 1])
  1209.                         {
  1210.                                 m_pLODs[nLod + 1]->m_nLastDrawMainFrameId = passInfo.GetMainFrameID();
  1211.                                 if (m_pLODs[nLod + 1]->m_pParentObject)
  1212.                                         m_pLODs[nLod + 1]->m_pParentObject->m_nLastDrawMainFrameId = passInfo.GetMainFrameID();
  1213.                         }
  1214.                 }
  1215.  
  1216.                 if (m_pLODs)
  1217.                         for (; nLod <= (int)m_nMaxUsableLod; nLod++)
  1218.                         {
  1219.                                 if (m_pLODs[nLod] && m_pLODs[nLod]->m_pRenderMesh && m_pLODs[nLod]->m_pRenderMesh->CanRender())
  1220.                                 {
  1221.                                         PrefetchLine(pRenderObject, 0);
  1222.                                         m_pLODs[nLod]->RenderRenderMesh(pRenderObject, NULL, passInfo);
  1223.                                         break;
  1224.                                 }
  1225.                         }
  1226.         }
  1227. }
  1228.  
  1229. ///////////////////////////////////////////////////////////////////////////////
  1230. void CStatObj::RenderObjectInternal(CRenderObject* pRenderObject, int nTargetLod, uint8 uLodDissolveRef, bool dissolveOut, const SRenderingPassInfo& passInfo)
  1231. {
  1232.         if (nTargetLod == -1 || uLodDissolveRef == 255)
  1233.         {
  1234.                 return;
  1235.         }
  1236.  
  1237.         int nLod = CLAMP(nTargetLod, GetMinUsableLod(), (int)m_nMaxUsableLod);
  1238.         assert(nLod < MAX_STATOBJ_LODS_NUM);
  1239.  
  1240.         // Skip rendering of this suboject if it is marked as deformable
  1241.         if (GetCVars()->e_MergedMeshes == 1 && nTargetLod == 0 && m_isDeformable)
  1242.                 return;
  1243.  
  1244.         if (passInfo.IsShadowPass() && passInfo.GetShadowMapType() == SRenderingPassInfo::SHADOW_MAP_CACHED && pRenderObject->m_pRenderNode)
  1245.         {
  1246.                 IShadowCaster* pCaster = static_cast<IShadowCaster*>(pRenderObject->m_pRenderNode);
  1247.                 pCaster->m_cStaticShadowLod = nLod;
  1248.         }
  1249.  
  1250.         pRenderObject->m_DissolveRef = uLodDissolveRef;
  1251.  
  1252.         if (pRenderObject->m_DissolveRef)
  1253.         {
  1254.                 if (!(pRenderObject->m_ObjFlags & FOB_DISSOLVE))
  1255.                         pRenderObject->m_ObjFlags &= ~FOB_UPDATED_RTMASK;
  1256.                 pRenderObject->m_ObjFlags |= FOB_DISSOLVE;
  1257.  
  1258.                 if (dissolveOut)
  1259.                         pRenderObject->m_ObjFlags |= FOB_DISSOLVE_OUT;
  1260.         }
  1261.         else
  1262.         {
  1263.                 if ((pRenderObject->m_ObjFlags & FOB_DISSOLVE))
  1264.                         pRenderObject->m_ObjFlags &= ~FOB_UPDATED_RTMASK;
  1265.                 pRenderObject->m_ObjFlags &= ~FOB_DISSOLVE;
  1266.         }
  1267.  
  1268.         // try next lod's if selected one is not ready
  1269.         if ((!nLod && m_pRenderMesh && m_pRenderMesh->CanRender()) || !GetCVars()->e_Lods)
  1270.         {
  1271.                 PrefetchLine(pRenderObject, 0);
  1272.                 RenderRenderMesh(pRenderObject, NULL, passInfo);
  1273.         }
  1274.         else
  1275.         {
  1276.                 if (m_pLODs && m_pLODs[nLod])
  1277.                 {
  1278.                         m_pLODs[nLod]->m_nLastDrawMainFrameId = passInfo.GetMainFrameID();
  1279.                         if (m_pLODs[nLod]->m_pParentObject)
  1280.                                 m_pLODs[nLod]->m_pParentObject->m_nLastDrawMainFrameId = passInfo.GetMainFrameID();
  1281.  
  1282.                         if ((nLod + 1) < MAX_STATOBJ_LODS_NUM && m_pLODs[nLod + 1])
  1283.                         {
  1284.                                 m_pLODs[nLod + 1]->m_nLastDrawMainFrameId = passInfo.GetMainFrameID();
  1285.                                 if (m_pLODs[nLod + 1]->m_pParentObject)
  1286.                                         m_pLODs[nLod + 1]->m_pParentObject->m_nLastDrawMainFrameId = passInfo.GetMainFrameID();
  1287.                         }
  1288.                 }
  1289.  
  1290.                 if (m_pLODs)
  1291.                         for (; nLod <= (int)m_nMaxUsableLod; nLod++)
  1292.                         {
  1293.                                 if (m_pLODs[nLod] && m_pLODs[nLod]->m_pRenderMesh && m_pLODs[nLod]->m_pRenderMesh->CanRender())
  1294.                                 {
  1295.                                         PrefetchLine(pRenderObject, 0);
  1296.                                         m_pLODs[nLod]->RenderRenderMesh(pRenderObject, NULL, passInfo);
  1297.                                         break;
  1298.                                 }
  1299.                         }
  1300.         }
  1301. }
  1302.  
  1303. ///////////////////////////////////////////////////////////////////////////////
  1304. void CStatObj::RenderRenderMesh(CRenderObject* pRenderObject, SInstancingInfo* pInstInfo, const SRenderingPassInfo& passInfo)
  1305. {
  1306. #if !defined(_RELEASE)
  1307.         //DEBUG - filter which stat objs are rendered
  1308.         if (GetCVars()->e_statObjRenderFilterMode && GetCVars()->e_pStatObjRenderFilterStr && GetCVars()->e_pStatObjRenderFilterStr[0])
  1309.         {
  1310.                 if (GetCVars()->e_statObjRenderFilterMode == 1)
  1311.                 {
  1312.                         //only render elems containing str
  1313.                         if (!strstr(m_szFileName.c_str(), GetCVars()->e_pStatObjRenderFilterStr))
  1314.                         {
  1315.                                 return;
  1316.                         }
  1317.                 }
  1318.                 else if (GetCVars()->e_statObjRenderFilterMode == 2)
  1319.                 {
  1320.                         //exclude elems containing str
  1321.                         if (strstr(m_szFileName.c_str(), GetCVars()->e_pStatObjRenderFilterStr))
  1322.                         {
  1323.                                 return;
  1324.                         }
  1325.                 }
  1326.         }
  1327.  
  1328.         if (GetCVars()->e_DebugDraw && (!GetCVars()->e_DebugDrawShowOnlyCompound || (m_bSubObject || m_pParentObject)))
  1329.         {
  1330.                 int nLod = 0;
  1331.                 if (m_pLod0 && m_pLod0->m_pLODs)
  1332.                         for (; nLod < MAX_STATOBJ_LODS_NUM; nLod++)
  1333.                         {
  1334.                                 if (m_pLod0->m_pLODs[nLod] == this)
  1335.                                 {
  1336.                                         m_pRenderMesh->SetMeshLod(nLod);
  1337.                                         break;
  1338.                                 }
  1339.                         }
  1340.  
  1341.                 if (GetCVars()->e_DebugDrawShowOnlyLod >= 0)
  1342.                         if (GetCVars()->e_DebugDrawShowOnlyLod != nLod)
  1343.                                 return;
  1344.  
  1345.                 if (RenderDebugInfo(pRenderObject, passInfo))
  1346.                         return;
  1347.  
  1348.                 if (m_bSubObject)
  1349.                         pRenderObject = gEnv->pRenderer->EF_DuplicateRO(pRenderObject, passInfo);
  1350.         }
  1351.  
  1352.         if (!passInfo.IsShadowPass())
  1353.         {
  1354.                 if (GetCVars()->e_StreamCgfDebug == 1)
  1355.                 {
  1356.                         RenderStreamingDebugInfo(pRenderObject);
  1357.                 }
  1358.  
  1359.                 if (GetCVars()->e_CoverCgfDebug == 1)
  1360.                 {
  1361.                         RenderCoverInfo(pRenderObject);
  1362.                 }
  1363.         }
  1364. #endif
  1365.  
  1366.         if (m_pRenderMesh)
  1367.         {
  1368.                 CRenderObject* pObj = pRenderObject;
  1369. #if !defined(_RELEASE)
  1370.                 if (m_isProxyTooBig)
  1371.                 {
  1372.                         pObj = GetRenderer()->EF_DuplicateRO(pRenderObject, passInfo);
  1373.                         pObj->m_pCurrMaterial = m_pMaterial;
  1374.                 }
  1375. #endif
  1376.                 m_pRenderMesh->Render(pObj, passInfo);
  1377.         }
  1378. }
  1379.  
  1380. ///////////////////////////////////////////////////////////////////////////////
  1381. int CStatObj::GetMaxUsableLod()
  1382. {
  1383.         int maxUsable = m_pLod0 ? max((int)m_nMaxUsableLod, (int)m_pLod0->m_nMaxUsableLod) : (int)m_nMaxUsableLod;
  1384.         return min(maxUsable, GetCVars()->e_LodMax);
  1385. }
  1386.  
  1387. ///////////////////////////////////////////////////////////////////////////////
  1388. int CStatObj::GetMinUsableLod()
  1389. {
  1390.         int minUsable = m_pLod0 ? max((int)m_nMinUsableLod0, (int)m_pLod0->m_nMinUsableLod0) : (int)m_nMinUsableLod0;
  1391.         return max(minUsable, GetCVars()->e_LodMin);
  1392. }
  1393.  
  1394. ///////////////////////////////////////////////////////////////////////////////
  1395. int CStatObj::FindNearesLoadedLOD(int nLodIn, bool bSearchUp)
  1396. {
  1397.         // make sure requested lod is loaded
  1398.         /*  if(CStatObj * pObjForStreamIn = nLodIn ? m_pLODs[nLodIn] : this)
  1399.         {
  1400.         bool bRenderNodeValid(rParams.pRenderNode && ((int)(void*)(rParams.pRenderNode)>0) && rParams.pRenderNode->m_fWSMaxViewDist);
  1401.         float fImportance = bRenderNodeValid ? (1.f - (rParams.fDistance / rParams.pRenderNode->m_fWSMaxViewDist)) : 0.5f;
  1402.         pObjForStreamIn->UpdateStreamingPrioriryInternal(fImportance);
  1403.         }*/
  1404.  
  1405.         // if requested lod is not ready - find nearest ready one
  1406.         int nLod = nLodIn;
  1407.  
  1408.         if (nLod == 0 && !GetRenderMesh())
  1409.                 nLod++;
  1410.  
  1411.         while (nLod && nLod < MAX_STATOBJ_LODS_NUM && (!m_pLODs || !m_pLODs[nLod] || !m_pLODs[nLod]->GetRenderMesh()))
  1412.                 nLod++;
  1413.  
  1414.         if (nLod >(int)m_nMaxUsableLod)
  1415.         {
  1416.                 if (bSearchUp)
  1417.                 {
  1418.                         nLod = min((int)m_nMaxUsableLod, nLodIn);
  1419.  
  1420.                         while (nLod && (!m_pLODs || !m_pLODs[nLod] || !m_pLODs[nLod]->GetRenderMesh()))
  1421.                                 nLod--;
  1422.  
  1423.                         if (nLod == 0 && !GetRenderMesh())
  1424.                                 nLod--;
  1425.                 }
  1426.                 else
  1427.                 {
  1428.                         nLod = -1;
  1429.                 }
  1430.         }
  1431.  
  1432.         return nLod;
  1433. }
  1434.  
  1435. //////////////////////////////////////////////////////////////////////////
  1436. int CStatObj::AddRef()
  1437. {
  1438.         return CryInterlockedIncrement(&m_nUsers);
  1439. }
  1440.  
downloadStatObjRend.cpp Source code - Download CRYENGINE Source code
Related Source Codes/Software:
postal - 2017-06-11
reactide - Reactide is the first dedicated IDE for React web ... 2017-06-11
rkt - rkt is a pod-native container engine for Linux. It... 2017-06-11
uWebSockets - Tiny WebSockets https://for... 2017-06-11
realworld - TodoMVC for the RealWorld - Exemplary fullstack Me... 2017-06-11
CRYENGINE - CRYENGINE is a powerful real-time game development... 2017-06-11
goreplay - GoReplay is an open-source tool for capturing and ... 2017-06-10
pyenv - Simple Python version management 2017-06-10
redux-saga - An alternative side effect model for Redux apps ... 2017-06-10
angular-starter - 2017-06-10

 Back to top