BVB Source Codes

CRYENGINE Show DecalRenderNode.cpp Source code

Return Download CRYENGINE: download DecalRenderNode.cpp Source code - Download CRYENGINE Source code - Type:.cpp
  1. // Copyright 2001-2016 Crytek GmbH / Crytek Group. All rights reserved.
  2.  
  3. #include "StdAfx.h"
  4. #include "DecalRenderNode.h"
  5. #include "VisAreas.h"
  6. #include "ObjMan.h"
  7. #include "MatMan.h"
  8. #include "terrain.h"
  9.  
  10. int CDecalRenderNode::m_nFillBigDecalIndicesCounter = 0;
  11.  
  12. CDecalRenderNode::CDecalRenderNode()
  13.         : m_pos(0, 0, 0)
  14.         , m_localBounds(Vec3(-1, -1, -1), Vec3(1, 1, 1))
  15.         , m_pMaterial(NULL)
  16.         , m_updateRequested(false)
  17.         , m_decalProperties()
  18.         , m_decals()
  19.         , m_nLastRenderedFrameId(0)
  20.         , m_nLayerId(0)
  21.         , m_physEnt(0)
  22. {
  23.         GetInstCount(GetRenderNodeType())++;
  24.  
  25.         m_Matrix.SetIdentity();
  26. }
  27.  
  28. CDecalRenderNode::~CDecalRenderNode()
  29. {
  30.         GetInstCount(GetRenderNodeType())--;
  31.  
  32.         DeleteDecals();
  33.         Get3DEngine()->FreeRenderNodeState(this);
  34.         if (m_physEnt)
  35.                 gEnv->pPhysicalWorld->DestroyPhysicalEntity(m_physEnt);
  36. }
  37.  
  38. const SDecalProperties* CDecalRenderNode::GetDecalProperties() const
  39. {
  40.         return &m_decalProperties;
  41. }
  42.  
  43. void CDecalRenderNode::DeleteDecals()
  44. {
  45.         for (size_t i(0); i < m_decals.size(); ++i)
  46.                 delete m_decals[i];
  47.  
  48.         m_decals.resize(0);
  49. }
  50.  
  51. void CDecalRenderNode::CreatePlanarDecal()
  52. {
  53.         CryEngineDecalInfo decalInfo;
  54.  
  55.         // necessary params
  56.         decalInfo.vPos = m_decalProperties.m_pos;
  57.         decalInfo.vNormal = m_decalProperties.m_normal;
  58.         decalInfo.fSize = m_decalProperties.m_radius;
  59.         decalInfo.pExplicitRightUpFront = &m_decalProperties.m_explicitRightUpFront;
  60.         cry_strcpy(decalInfo.szMaterialName, m_pMaterial->GetName());
  61.         decalInfo.sortPrio = m_decalProperties.m_sortPrio;
  62.  
  63.         // default for all other
  64.         decalInfo.pIStatObj = NULL;
  65.         decalInfo.ownerInfo.pRenderNode = NULL;
  66.         decalInfo.fLifeTime = 1.0f; // default life time for rendering, decal won't grow older as we don't update it
  67.         decalInfo.vHitDirection = Vec3(0, 0, 0);
  68.         decalInfo.fGrowTime = 0;
  69.         decalInfo.preventDecalOnGround = true;
  70.         decalInfo.fAngle = 0;
  71.  
  72.         CDecal* pDecal(new CDecal);
  73.         if (m_p3DEngine->CreateDecalInstance(decalInfo, pDecal))
  74.                 m_decals.push_back(pDecal);
  75.         else
  76.                 delete pDecal;
  77. }
  78.  
  79. void CDecalRenderNode::CreateDecalOnStaticObjects()
  80. {
  81.         CTerrain* pTerrain(GetTerrain());
  82.         CVisAreaManager* pVisAreaManager(GetVisAreaManager());
  83.         PodArray<SRNInfo> decalReceivers;
  84.  
  85.         if (pTerrain && m_pOcNode && !m_pOcNode->m_pVisArea)
  86.                 pTerrain->GetObjectsAround(m_decalProperties.m_pos, m_decalProperties.m_radius, &decalReceivers, true, false);
  87.         else if (pVisAreaManager && m_pOcNode && m_pOcNode->m_pVisArea)
  88.                 pVisAreaManager->GetObjectsAround(m_decalProperties.m_pos, m_decalProperties.m_radius, &decalReceivers, true);
  89.  
  90.         // delete vegetations
  91.         for (int nRecId(0); nRecId < decalReceivers.Count(); ++nRecId)
  92.         {
  93.                 EERType eType = decalReceivers[nRecId].pNode->GetRenderNodeType();
  94.                 if (eType != eERType_Brush && eType != eERType_RenderProxy)
  95.                 {
  96.                         decalReceivers.DeleteFastUnsorted(nRecId);
  97.                         nRecId--;
  98.                 }
  99.         }
  100.  
  101.         for (int nRecId(0); nRecId < decalReceivers.Count(); ++nRecId)
  102.         {
  103.                 CryEngineDecalInfo decalInfo;
  104.  
  105.                 // necessary params
  106.                 decalInfo.vPos = m_decalProperties.m_pos;
  107.                 decalInfo.vNormal = m_decalProperties.m_normal;
  108.                 decalInfo.vHitDirection = -m_decalProperties.m_normal;
  109.                 decalInfo.fSize = m_decalProperties.m_radius;
  110.                 decalInfo.pExplicitRightUpFront = &m_decalProperties.m_explicitRightUpFront;
  111.                 cry_strcpy(decalInfo.szMaterialName, m_pMaterial->GetName());
  112.                 decalInfo.sortPrio = m_decalProperties.m_sortPrio;
  113.  
  114.                 if (GetCVars()->e_DecalsMerge)
  115.                         decalInfo.ownerInfo.pDecalReceivers = &decalReceivers;
  116.                 else
  117.                         decalInfo.ownerInfo.pRenderNode = decalReceivers[nRecId].pNode;
  118.  
  119.                 decalInfo.ownerInfo.nRenderNodeSlotId = 0;
  120.                 decalInfo.ownerInfo.nRenderNodeSlotSubObjectId = -1;
  121.  
  122.                 // default for all other
  123.                 decalInfo.pIStatObj = NULL;
  124.                 decalInfo.fLifeTime = 1.0f; // default life time for rendering, decal won't grow older as we don't update it
  125.                 decalInfo.fGrowTime = 0;
  126.                 decalInfo.preventDecalOnGround = false;
  127.                 decalInfo.fAngle = 0;
  128.  
  129.                 IStatObj* pMainStatObj = decalInfo.ownerInfo.pRenderNode->GetEntityStatObj();
  130.                 if (!pMainStatObj)
  131.                         continue;
  132.  
  133.                 // in case of multi-sub-objects, spawn decal on each visible sub-object
  134.                 int nSubObjCount = pMainStatObj->GetSubObjectCount();
  135.                 if (!GetCVars()->e_DecalsMerge && nSubObjCount)
  136.                 {
  137.                         for (int nSubObjId = 0; nSubObjId < nSubObjCount; nSubObjId++)
  138.                         {
  139.                                 CStatObj::SSubObject* const __restrict pSubObj = (CStatObj::SSubObject*)pMainStatObj->GetSubObject(nSubObjId);
  140.                                 if (CStatObj* const __restrict pSubStatObj = (CStatObj*)pSubObj->pStatObj)
  141.                                         if (pSubObj->nType == STATIC_SUB_OBJECT_MESH && !pSubObj->bHidden && !(pSubStatObj->m_nFlags & STATIC_OBJECT_HIDDEN))
  142.                                         {
  143.                                                 CDecal* pDecal(new CDecal);
  144.                                                 decalInfo.ownerInfo.nRenderNodeSlotSubObjectId = nSubObjId;
  145.  
  146.                                                 if (m_p3DEngine->CreateDecalInstance(decalInfo, pDecal))
  147.                                                 {
  148.                                                         m_decals.push_back(pDecal);
  149.                                                         assert(!GetCVars()->e_DecalsMerge || pDecal->m_eDecalType == eDecalType_WS_Merged);
  150.                                                 }
  151.                                                 else
  152.                                                 {
  153.                                                         delete pDecal;
  154.                                                 }
  155.                                         }
  156.                         }
  157.                 }
  158.                 else
  159.                 {
  160.                         CDecal* pDecal(new CDecal);
  161.                         if (m_p3DEngine->CreateDecalInstance(decalInfo, pDecal))
  162.                         {
  163.                                 m_decals.push_back(pDecal);
  164.                                 assert(!GetCVars()->e_DecalsMerge || pDecal->m_eDecalType == eDecalType_WS_Merged);
  165.                         }
  166.                         else
  167.                         {
  168.                                 delete pDecal;
  169.                         }
  170.                 }
  171.  
  172.                 if (GetCVars()->e_DecalsMerge)
  173.                         break;
  174.         }
  175. }
  176.  
  177. void CDecalRenderNode::CreateDecalOnTerrain()
  178. {
  179.         float terrainHeight(GetTerrain()->GetZApr(m_decalProperties.m_pos.x, m_decalProperties.m_pos.y, m_nSID));
  180.         float terrainDelta(m_decalProperties.m_pos.z - terrainHeight);
  181.         if (terrainDelta < m_decalProperties.m_radius && terrainDelta > -0.5f)
  182.         {
  183.                 CryEngineDecalInfo decalInfo;
  184.  
  185.                 // necessary params
  186.                 decalInfo.vPos = Vec3(m_decalProperties.m_pos.x, m_decalProperties.m_pos.y, terrainHeight);
  187.                 decalInfo.vNormal = Vec3(0, 0, 1);
  188.                 decalInfo.vHitDirection = Vec3(0, 0, -1);
  189.                 decalInfo.fSize = m_decalProperties.m_radius;// - terrainDelta;
  190.                 decalInfo.pExplicitRightUpFront = &m_decalProperties.m_explicitRightUpFront;
  191.                 cry_strcpy(decalInfo.szMaterialName, m_pMaterial->GetName());
  192.                 decalInfo.sortPrio = m_decalProperties.m_sortPrio;
  193.  
  194.                 // default for all other
  195.                 decalInfo.pIStatObj = NULL;
  196.                 decalInfo.ownerInfo.pRenderNode = 0;
  197.                 decalInfo.fLifeTime = 1.0f; // default life time for rendering, decal won't grow older as we don't update it
  198.                 decalInfo.fGrowTime = 0;
  199.                 decalInfo.preventDecalOnGround = false;
  200.                 decalInfo.fAngle = 0;
  201.  
  202.                 CDecal* pDecal(new CDecal);
  203.                 if (m_p3DEngine->CreateDecalInstance(decalInfo, pDecal))
  204.                         m_decals.push_back(pDecal);
  205.                 else
  206.                         delete pDecal;
  207.         }
  208. }
  209.  
  210. void CDecalRenderNode::CreateDecals()
  211. {
  212.         DeleteDecals();
  213.  
  214.         if (m_decalProperties.m_deferred)
  215.                 return;
  216.  
  217.         IMaterial* pMaterial(GetMaterial());
  218.  
  219.         assert(0 != pMaterial && "CDecalRenderNode::CreateDecals() -- Invalid Material!");
  220.         if (!pMaterial)
  221.                 return;
  222.  
  223.         switch (m_decalProperties.m_projectionType)
  224.         {
  225.         case SDecalProperties::ePlanar:
  226.                 {
  227.                         CreatePlanarDecal();
  228.                         break;
  229.                 }
  230.         case SDecalProperties::eProjectOnStaticObjects:
  231.                 {
  232.                         CreateDecalOnStaticObjects();
  233.                         break;
  234.                 }
  235.         case SDecalProperties::eProjectOnTerrain:
  236.                 {
  237.                         CreateDecalOnTerrain();
  238.                         break;
  239.                 }
  240.         case SDecalProperties::eProjectOnTerrainAndStaticObjects:
  241.                 {
  242.                         CreateDecalOnStaticObjects();
  243.                         CreateDecalOnTerrain();
  244.                         break;
  245.                 }
  246.         default:
  247.                 {
  248.                         assert(!"CDecalRenderNode::CreateDecals() : Unsupported decal projection type!");
  249.                         break;
  250.                 }
  251.         }
  252. }
  253.  
  254. void CDecalRenderNode::ProcessUpdateRequest()
  255. {
  256.         if (!m_updateRequested || m_nFillBigDecalIndicesCounter >= GetCVars()->e_DecalsMaxUpdatesPerFrame)
  257.                 return;
  258.  
  259.         CreateDecals();
  260.         m_updateRequested = false;
  261. }
  262.  
  263. void CDecalRenderNode::UpdateAABBFromRenderMeshes()
  264. {
  265.         if (m_decalProperties.m_projectionType == SDecalProperties::eProjectOnStaticObjects ||
  266.             m_decalProperties.m_projectionType == SDecalProperties::eProjectOnTerrain ||
  267.             m_decalProperties.m_projectionType == SDecalProperties::eProjectOnTerrainAndStaticObjects)
  268.         {
  269.                 AABB WSBBox;
  270.                 WSBBox.Reset();
  271.                 for (size_t i(0); i < m_decals.size(); ++i)
  272.                 {
  273.                         CDecal* pDecal(m_decals[i]);
  274.                         if (pDecal && pDecal->m_pRenderMesh && pDecal->m_eDecalType != eDecalType_OS_OwnersVerticesUsed)
  275.                         {
  276.                                 AABB aabb;
  277.                                 pDecal->m_pRenderMesh->GetBBox(aabb.min, aabb.max);
  278.                                 if (pDecal->m_eDecalType == eDecalType_WS_Merged || pDecal->m_eDecalType == eDecalType_WS_OnTheGround)
  279.                                 {
  280.                                         aabb.min += pDecal->m_vPos;
  281.                                         aabb.max += pDecal->m_vPos;
  282.                                 }
  283.                                 WSBBox.Add(aabb);
  284.                         }
  285.                 }
  286.  
  287.                 if (!WSBBox.IsReset())
  288.                         m_WSBBox = WSBBox;
  289.         }
  290. }
  291.  
  292. //special check for def decals forcing
  293. bool CDecalRenderNode::CheckForceDeferred()
  294. {
  295.         if (m_pMaterial != NULL)
  296.         {
  297.                 SShaderItem& sItem = m_pMaterial->GetShaderItem(0);
  298.                 if (sItem.m_pShaderResources != NULL)
  299.                 {
  300.                         float fCosA = m_decalProperties.m_normal.GetNormalized().Dot(Vec3(0, 0, 1));
  301.                         if (fCosA > 0.5f)
  302.                                 return false;
  303.  
  304.                         if (SEfResTexture* pEnvRes0 = sItem.m_pShaderResources->GetTexture(EFTT_ENV))
  305.                         {
  306.                                 if (pEnvRes0->m_Sampler.m_pITex == NULL)
  307.                                 {
  308.                                         m_decalProperties.m_projectionType = SDecalProperties::ePlanar;
  309.                                         m_decalProperties.m_deferred = true;
  310.                                         return true;
  311.                                 }
  312.                         }
  313.                         else
  314.                         {
  315.                                 m_decalProperties.m_projectionType = SDecalProperties::ePlanar;
  316.                                 m_decalProperties.m_deferred = true;
  317.                                 return true;
  318.                         }
  319.                 }
  320.         }
  321.         return false;
  322. }
  323.  
  324. void CDecalRenderNode::SetDecalProperties(const SDecalProperties& properties)
  325. {
  326.         // update bounds
  327.         m_localBounds = AABB(-properties.m_radius * Vec3(1, 1, 1), properties.m_radius * Vec3(1, 1, 1));
  328.  
  329.         // register material
  330.         m_pMaterial = GetMatMan()->LoadMaterial(properties.m_pMaterialName, false);
  331.  
  332.         // copy decal properties
  333.         m_decalProperties = properties;
  334.         m_decalProperties.m_pMaterialName = 0; // reset this as it's assumed to be a temporary pointer only, refer to m_materialID to get material
  335.  
  336.         // request update
  337.         m_updateRequested = true;
  338.  
  339.         bool bForced = 0;
  340.  
  341.         // TOOD: Revive support for planar decals in new pipeline
  342.         if (properties.m_deferred || (GetCVars()->e_DecalsDeferredStatic
  343.                                       /*&& (m_decalProperties.m_projectionType != SDecalProperties::ePlanar && m_decalProperties.m_projectionType != SDecalProperties::eProjectOnTerrain)*/))
  344.         {
  345.                 m_decalProperties.m_projectionType = SDecalProperties::ePlanar;
  346.                 m_decalProperties.m_deferred = true;
  347.         }
  348.  
  349.         if (GetCVars()->e_DecalsForceDeferred)
  350.         {
  351.                 if (CheckForceDeferred())
  352.                         bForced = true;
  353.         }
  354.  
  355.         // set matrix
  356.         m_Matrix.SetRotation33(m_decalProperties.m_explicitRightUpFront);
  357.         Matrix33 matScale;
  358.         if (bForced && !properties.m_deferred)
  359.                 matScale.SetScale(Vec3(properties.m_radius, properties.m_radius, properties.m_radius * 0.05f));
  360.         else
  361.                 matScale.SetScale(Vec3(properties.m_radius, properties.m_radius, properties.m_radius * properties.m_depth));
  362.  
  363.         m_Matrix = m_Matrix * matScale;
  364.         m_Matrix.SetTranslation(properties.m_pos);
  365.  
  366.         bool hasPhys = false;
  367.         if (m_pMaterial && m_pMaterial->GetSurfaceTypeId() &&
  368.             (properties.m_projectionType == SDecalProperties::eProjectOnTerrainAndStaticObjects || properties.m_projectionType == SDecalProperties::eProjectOnTerrain))
  369.         {
  370.                 IGeometry* pGeom = 0;
  371.                 IGeomManager* pGeoman = gEnv->pPhysicalWorld->GetGeomManager();
  372.                 const float thickness = 0.01f;
  373.                 geom_world_data gwd[2];
  374.                 gwd[0].offset = m_Matrix.GetTranslation();
  375.                 gwd[0].v = m_Matrix.TransformVector(Vec3(0, 0, 1));
  376.                 primitives::cylinder cyl;
  377.  
  378.                 Vec2_tpl<uint16> sz;
  379.                 int* idAtlas;
  380.                 if (m_pMaterial->GetFlags() & MTL_FLAG_TRACEABLE_TEXTURE && m_pMaterial->GetShaderItem().m_pShaderResources)
  381.                         if (SEfResTexture* pTex = m_pMaterial->GetShaderItem().m_pShaderResources->GetTexture(EFTT_DIFFUSE))
  382.                                 if (ITexture* pITex = pTex->m_Sampler.m_pITex)
  383.                                         if (ColorB* data = (ColorB*)pITex->GetLowResSystemCopy(sz.x, sz.y, &idAtlas))
  384.                                         {
  385.                                                 const int lp = 5;
  386.                                                 Vec2i szKrn((int)sz.x / lp, (int)sz.y / lp), rszKrn((1 << 23) / szKrn.x, (1 << 23) / szKrn.y);
  387.                                                 Vec2 rsz(1.0f / sz.x, 1.0f / sz.y);
  388.  
  389.                                                 auto RunningSum = [](uint8* psrc, uint8* pdst, int stride, int w, int wk, int rwk, int rwkShift)
  390.                                                 {
  391.                                                         int i, sum;
  392.                                                         uint8* p0 = psrc, * p1 = psrc;
  393.                                                         for (i = 0, sum = 0; i*2 < wk + 1; sum += *p1, p1 += stride, ++i)
  394.                                                                 ;
  395.                                                         for (; i < wk; sum += *p1, p1 += stride, pdst += stride, ++i)
  396.                                                                 *pdst = sum * rwk >> rwkShift;
  397.                                                         for (; i < w; (sum += *p1) -= *p0, p0 += stride, p1 += stride, pdst += stride, ++i)
  398.                                                                 *pdst = sum * rwk >> rwkShift;
  399.                                                         for (; i*2 < w * 2 + wk; sum -= *p0, p0 += stride, pdst += stride, ++i)
  400.                                                                 *pdst = sum * rwk >> rwkShift;
  401.                                                 };
  402.  
  403.                                                 uint8* buf0 = new uint8[sz.x * sz.y], * buf1 = new uint8[sz.x * sz.y], * buf2 = new uint8[sz.x * sz.y];
  404.                                                 for (int i = sz.x * sz.y - 1; i >= 0; i--)
  405.                                                         buf0[i] = data[i].a;
  406.                                                 for (int iy = 0; iy < sz.y; iy++)       // low-pass along x
  407.                                                         RunningSum(buf0 + iy * sz.x, buf1 + iy * sz.x, 1, sz.x, szKrn.x, rszKrn.x, 23);
  408.                                                 for (int ix = 0; ix < sz.x; ix++)       // low-pass along y, set to 1 if resulting alpha>0.5
  409.                                                         RunningSum(buf1 + ix, buf0 + ix, sz.x, sz.y, szKrn.y, rszKrn.y, 23 + 7);
  410.                                                 for (int iy = 0; iy < sz.y; iy++)       // count neighbors (+self) along x
  411.                                                         RunningSum(buf0 + iy * sz.x, buf1 + iy * sz.x, 1, sz.x, 3, 1, 0);
  412.                                                 for (int ix = 0; ix < sz.x; ix++)       // ..repeat along y
  413.                                                         RunningSum(buf1 + ix, buf2 + ix, sz.x, sz.y, 3, 1, 0);
  414.                                                 int nVtx = 0;
  415.                                                 for (int i = sz.x * sz.y - 1; i >= 0; nVtx += buf0[i] & isneg((int)buf2[i] - 6), i--)
  416.                                                         ;       // count filled points with less than 5 filled neighbors
  417.                                                 ptitem2d* pts = new ptitem2d[nVtx];
  418.                                                 for (int iy = 0, i = 0, j = 0; iy < sz.y; iy++)
  419.                                                         for (int ix = 0; ix < sz.x; ix++, i++)
  420.                                                                 if (buf0[i] && buf2[i] < 6)
  421.                                                                         pts[j++].pt.set((ix + 0.5f) * 2 * rsz.x - 1, 1 - (iy + 0.5f) * 2 * rsz.y);
  422.  
  423.                                                 edgeitem* edges = new edgeitem[nVtx * 2], * pedge;
  424.                                                 int nEdges = gEnv->pPhysicalWorld->GetPhysUtils()->qhull2d(pts, nVtx, edges, 16);
  425.                                                 for (pedge = edges; nEdges && !pedge->next; pedge++)
  426.                                                         ;
  427.                                                 Vec3* vtx = new Vec3[nEdges * 2];
  428.                                                 Vec3_tpl<uint16>* tri = new Vec3_tpl<uint16>[(nEdges - 1) * 4];
  429.                                                 for (int i = 0; i < nEdges; i++, pedge = pedge->next)
  430.                                                 {
  431.                                                         Vec3 pt = m_Matrix.TransformVector(Vec3(pedge->pvtx->pt));
  432.                                                         vtx[i] = pt - gwd[0].v * thickness;
  433.                                                         vtx[i + nEdges] = pt + gwd[0].v * thickness;
  434.                                                 }
  435.                                                 for (int i = 0; i < nEdges - 2; i++)
  436.                                                 {
  437.                                                         tri[i].Set(0, i + 2, i + 1);
  438.                                                         tri[i + nEdges - 2].Set(nEdges, nEdges + i + 1, nEdges + i + 2);
  439.                                                 }
  440.                                                 for (int i = 0; i < nEdges; i++)
  441.                                                 {
  442.                                                         int i1 = i + 1 & (i + 1 - nEdges) >> 31;
  443.                                                         tri[(nEdges - 2) * 2 + i * 2].Set(i, i1, i + nEdges);
  444.                                                         tri[(nEdges - 2) * 2 + i * 2 + 1].Set(nEdges + i1, nEdges + i, i1);
  445.                                                 }
  446.                                                 pGeom = pGeoman->CreateMesh(vtx, &tri[0].x, 0, 0, (nEdges - 1) * 4, mesh_SingleBB | mesh_no_filter | mesh_no_vtx_merge, 0);
  447.  
  448.                                                 delete[] tri, delete[] vtx, delete[] edges, delete[] pts;
  449.                                                 delete[] buf2, delete[] buf1, delete[] buf0;
  450.                                         }
  451.  
  452.                 if (!pGeom)
  453.                 {
  454.                         cyl.center.zero();
  455.                         cyl.axis = gwd[0].v;
  456.                         cyl.hh = thickness;
  457.                         cyl.r = m_Matrix.TransformVector(Vec3(1, 0, 0)).len();
  458.                         pGeom = pGeoman->CreatePrimitive(primitives::cylinder::type, &cyl);
  459.                 }
  460.                 phys_geometry* pgeom = pGeoman->RegisterGeometry(pGeom, m_pMaterial->GetSurfaceType()->GetId());
  461.                 pGeom->Release();
  462.                 --pgeom->nRefCount;
  463.  
  464.                 primitives::box bbox;
  465.                 pGeom->GetBBox(&bbox);
  466.                 Matrix33 Rabs;
  467.                 Vec3 center = gwd[0].offset + bbox.center, size = (Rabs = bbox.Basis.T()).Fabs() * bbox.size;
  468.                 IPhysicalEntity* pentBuf[16], ** pents = pentBuf;
  469.                 int useStatics = properties.m_projectionType == SDecalProperties::eProjectOnTerrainAndStaticObjects;
  470.                 int nEnts = gEnv->pPhysicalWorld->GetEntitiesInBox(center - size, center + size, pents, ent_terrain | ent_static & - useStatics, 16);
  471.                 float t[2] = { 0, 0 }, tmax = m_Matrix.TransformVector(Vec3(0, 0, 1)).len();
  472.  
  473.                 pe_status_pos sp;
  474.                 for (int i = 0; i < nEnts; i++)
  475.                         for (sp.ipart = 0; pents[i]->GetStatus(&sp); sp.ipart++)
  476.                                 if (sp.flagsOR & geom_colltype0)
  477.                                 {
  478.                                         gwd[1].R = Matrix33(sp.q);
  479.                                         gwd[1].offset = sp.pos;
  480.                                         gwd[1].scale = sp.scale;
  481.                                         for (int j = 0; j < 2; j++)
  482.                                         {
  483.                                                 geom_contact* pcont;
  484.                                                 if (pGeom->Intersect(sp.pGeom, gwd, gwd + 1, 0, pcont))
  485.                                                         t[j] = min(tmax, max(t[j], (float)pcont->t));
  486.                                                 gwd[0].v.Flip();
  487.                                         }
  488.                                 }
  489.                 if (pGeom->GetType() == GEOM_TRIMESH)
  490.                 {
  491.                         mesh_data* md = (mesh_data*)pGeom->GetData();
  492.                         for (int i = 0; i*2 < md->nVertices; i++)
  493.                         {
  494.                                 md->pVertices[i] -= gwd[0].v * t[0];
  495.                                 md->pVertices[i + (md->nVertices >> 1)] += gwd[0].v * t[1];
  496.                         }
  497.                         pGeom->SetData(md);
  498.                 }
  499.                 else
  500.                 {
  501.                         cyl.hh += (t[0] + t[1]) * 0.5f;
  502.                         cyl.center += gwd[0].v * ((t[1] - t[0]) * 0.5f);
  503.                         pGeom->SetData(&cyl);
  504.                 }
  505.  
  506.                 pe_params_pos pp;
  507.                 pp.pos = gwd[0].offset;
  508.                 pe_params_flags pf;
  509.                 pf.flagsOR = pef_disabled; // disabled ents are moved to the end of the cell list - needed to check mat updates the last
  510.                 if (!m_physEnt)
  511.                         m_physEnt = gEnv->pPhysicalWorld->CreatePhysicalEntity(PE_STATIC, &pf);
  512.                 pe_action_remove_all_parts arap;
  513.                 m_physEnt->Action(&arap);
  514.                 m_physEnt->SetParams(&pp);
  515.                 pe_geomparams gp;
  516.                 gp.flags = geom_mat_substitutor;
  517.                 gp.flagsCollider = 1 + useStatics * 2;
  518.                 m_physEnt->AddGeometry(pgeom, &gp);
  519.                 pf.flagsAND = ~pef_traceable;
  520.                 m_physEnt->SetParams(&pf);
  521.                 pf.flagsOR = pef_traceable;
  522.                 m_physEnt->SetParams(&pf); // triggers list update according to pef_disabled
  523.                 hasPhys = true;
  524.         }
  525.         if (m_physEnt && !hasPhys)
  526.         {
  527.                 gEnv->pPhysicalWorld->DestroyPhysicalEntity(m_physEnt);
  528.                 m_physEnt = 0;
  529.         }
  530. }
  531.  
  532. IRenderNode* CDecalRenderNode::Clone() const
  533. {
  534.         CDecalRenderNode* pDestDecal = new CDecalRenderNode();
  535.  
  536.         // CDecalRenderNode member vars
  537.         pDestDecal->m_pos = m_pos;
  538.         pDestDecal->m_localBounds = m_localBounds;
  539.         pDestDecal->m_pMaterial = m_pMaterial;
  540.         pDestDecal->m_updateRequested = true;
  541.         pDestDecal->m_decalProperties = m_decalProperties;
  542.         pDestDecal->m_WSBBox = m_WSBBox;
  543.         pDestDecal->m_Matrix = m_Matrix;
  544.         pDestDecal->m_nLayerId = m_nLayerId;
  545.  
  546.         //IRenderNode member vars
  547.         //      We cannot just copy over due to issues with the linked list of IRenderNode objects
  548.         CopyIRenderNodeData(pDestDecal);
  549.  
  550.         return pDestDecal;
  551. }
  552.  
  553. void CDecalRenderNode::SetMatrix(const Matrix34& mat)
  554. {
  555.         m_pos = mat.GetTranslation();
  556.  
  557.         if (m_decalProperties.m_projectionType == SDecalProperties::ePlanar)
  558.                 m_WSBBox.SetTransformedAABB(m_Matrix, AABB(-Vec3(1, 1, 0.5f), Vec3(1, 1, 0.5f)));
  559.         else
  560.                 m_WSBBox.SetTransformedAABB(m_Matrix, AABB(-Vec3(1, 1, 1), Vec3(1, 1, 1)));
  561.  
  562.         Get3DEngine()->RegisterEntity(this);
  563. }
  564.  
  565. void CDecalRenderNode::SetMatrixFull(const Matrix34& mat)
  566. {
  567.         m_Matrix = mat;
  568.         m_pos = mat.GetTranslation();
  569.  
  570.         if (m_decalProperties.m_projectionType == SDecalProperties::ePlanar)
  571.                 m_WSBBox.SetTransformedAABB(m_Matrix, AABB(-Vec3(1, 1, 0.5f), Vec3(1, 1, 0.5f)));
  572.         else
  573.                 m_WSBBox.SetTransformedAABB(m_Matrix, AABB(-Vec3(1, 1, 1), Vec3(1, 1, 1)));
  574. }
  575.  
  576. const char* CDecalRenderNode::GetEntityClassName() const
  577. {
  578.         return "Decal";
  579. }
  580.  
  581. const char* CDecalRenderNode::GetName() const
  582. {
  583.         return "Decal";
  584. }
  585.  
  586. void CDecalRenderNode::Render(const SRendParams& rParam, const SRenderingPassInfo& passInfo)
  587. {
  588.         FUNCTION_PROFILER_3DENGINE;
  589.  
  590.         if (!passInfo.RenderDecals())
  591.                 return; // false;
  592.  
  593.         // Calculate distance fading once as it's the same for
  594.         // all decals belonging to this node, regardless of type
  595.         float fDistFading = SATURATE((1.f - rParam.fDistance / m_fWSMaxViewDist) * DIST_FADING_FACTOR);
  596.  
  597.         if (m_decalProperties.m_deferred)
  598.         {
  599.                 if (passInfo.IsShadowPass())
  600.                         return; // otherwise causing flickering with GI
  601.  
  602.                 SDeferredDecal newItem;
  603.                 newItem.fAlpha = fDistFading;
  604.                 newItem.pMaterial = m_pMaterial;
  605.                 newItem.projMatrix = m_Matrix;
  606.                 newItem.nSortOrder = m_decalProperties.m_sortPrio;
  607.                 newItem.nFlags = DECAL_STATIC;
  608.                 GetRenderer()->EF_AddDeferredDecal(newItem, passInfo);
  609.                 return;
  610.         }
  611.  
  612.         // update last rendered frame id
  613.         m_nLastRenderedFrameId = passInfo.GetMainFrameID();
  614.  
  615.         bool bUpdateAABB = m_updateRequested;
  616.  
  617.         if (passInfo.IsGeneralPass())
  618.                 ProcessUpdateRequest();
  619.  
  620.         float waterLevel(m_p3DEngine->GetWaterLevel());
  621.         for (size_t i(0); i < m_decals.size(); ++i)
  622.         {
  623.                 CDecal* pDecal(m_decals[i]);
  624.                 if (pDecal && 0 != pDecal->m_pMaterial)
  625.                 {
  626.                         pDecal->m_vAmbient.x = rParam.AmbientColor.r;
  627.                         pDecal->m_vAmbient.y = rParam.AmbientColor.g;
  628.                         pDecal->m_vAmbient.z = rParam.AmbientColor.b;
  629.                         bool bAfterWater = CObjManager::IsAfterWater(pDecal->m_vWSPos, passInfo.GetCamera().GetPosition(), passInfo, waterLevel);
  630.                         pDecal->Render(0, bAfterWater, fDistFading, rParam.fDistance, passInfo);
  631.                 }
  632.         }
  633.  
  634.         // terrain decal meshes are created only during rendering so only after that bbox can be computed
  635.         if (bUpdateAABB)
  636.                 UpdateAABBFromRenderMeshes();
  637.  
  638.         //      return true;
  639. }
  640.  
  641. IPhysicalEntity* CDecalRenderNode::GetPhysics() const
  642. {
  643.         return 0;
  644. }
  645.  
  646. void CDecalRenderNode::SetPhysics(IPhysicalEntity*)
  647. {
  648. }
  649.  
  650. void CDecalRenderNode::SetMaterial(IMaterial* pMat)
  651. {
  652.         for (size_t i(0); i < m_decals.size(); ++i)
  653.         {
  654.                 CDecal* pDecal(m_decals[i]);
  655.                 if (pDecal)
  656.                         pDecal->m_pMaterial = pMat;
  657.         }
  658.  
  659.         m_pMaterial = pMat;
  660.  
  661.         //special check for def decals forcing
  662.         if (GetCVars()->e_DecalsForceDeferred)
  663.         {
  664.                 CheckForceDeferred();
  665.         }
  666.  
  667. }
  668.  
  669. void CDecalRenderNode::Precache()
  670. {
  671.         ProcessUpdateRequest();
  672. }
  673.  
  674. void CDecalRenderNode::GetMemoryUsage(ICrySizer* pSizer) const
  675. {
  676.         SIZER_COMPONENT_NAME(pSizer, "DecalNode");
  677.         pSizer->AddObject(this, sizeof(*this));
  678.         pSizer->AddObject(m_decals);
  679. }
  680.  
  681. void CDecalRenderNode::CleanUpOldDecals()
  682. {
  683.         if (m_nLastRenderedFrameId != 0 && // was rendered at least once
  684.             (int)GetRenderer()->GetFrameID(false) > (int)m_nLastRenderedFrameId + GetCVars()->e_DecalsMaxValidFrames)
  685.         {
  686.                 DeleteDecals();
  687.                 m_nLastRenderedFrameId = 0;
  688.                 m_updateRequested = true; // make sure if rendered again, that the decal is recreated
  689.         }
  690. }
  691.  
  692. void CDecalRenderNode::OffsetPosition(const Vec3& delta)
  693. {
  694.         if (m_pTempData) m_pTempData->OffsetPosition(delta);
  695.         m_pos += delta;
  696.         m_WSBBox.Move(delta);
  697.         m_Matrix.SetTranslation(m_Matrix.GetTranslation() + delta);
  698. }
  699.  
  700. void CDecalRenderNode::FillBBox(AABB& aabb)
  701. {
  702.         aabb = CDecalRenderNode::GetBBox();
  703. }
  704.  
  705. EERType CDecalRenderNode::GetRenderNodeType()
  706. {
  707.         return eERType_Decal;
  708. }
  709.  
  710. float CDecalRenderNode::GetMaxViewDist()
  711. {
  712.         float fMatScale = m_Matrix.GetColumn0().GetLength();
  713.  
  714.         if (GetMinSpecFromRenderNodeFlags(m_dwRndFlags) == CONFIG_DETAIL_SPEC)
  715.                 return max(GetCVars()->e_ViewDistMin, fMatScale * 0.75f * GetCVars()->e_ViewDistRatioDetail * GetViewDistRatioNormilized());
  716.  
  717.         return(max(GetCVars()->e_ViewDistMin, fMatScale * 0.75f * GetCVars()->e_ViewDistRatio * GetViewDistRatioNormilized()));
  718. }
  719.  
  720. Vec3 CDecalRenderNode::GetPos(bool bWorldOnly) const
  721. {
  722.         return m_pos;
  723. }
  724.  
  725. IMaterial* CDecalRenderNode::GetMaterial(Vec3* pHitPos) const
  726. {
  727.         return m_pMaterial;
  728. }
  729.  
downloadDecalRenderNode.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