BVB Source Codes

CRYENGINE Show ObjManDrawEntity.cpp Source code

Return Download CRYENGINE: download ObjManDrawEntity.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:   statobjmandraw.cpp
  5. //  Version:     v1.00
  6. //  Created:     28/5/2001 by Vladimir Kajalin
  7. //  Compilers:   Visual Studio.NET
  8. //  Description: Render all entities in the sector together with shadows
  9. // -------------------------------------------------------------------------
  10. //  History:
  11. //
  12. ////////////////////////////////////////////////////////////////////////////
  13.  
  14. #include "StdAfx.h"
  15. #include <CryAnimation/ICryAnimation.h>
  16.  
  17. #include "terrain.h"
  18. #include "StatObj.h"
  19. #include "ObjMan.h"
  20. #include "VisAreas.h"
  21. #include "terrain_sector.h"
  22. #include "3dEngine.h"
  23. #include "PolygonClipContext.h"
  24. #include "3dEngine.h"
  25. #include "LightEntity.h"
  26. #include "DecalManager.h"
  27. #include "ObjectsTree.h"
  28. #include "Brush.h"
  29.  
  30. void CObjManager::RenderDecalAndRoad(IRenderNode* pEnt, PodArray<CDLight*>* pAffectingLights,
  31.                                      const Vec3& vAmbColor, const AABB& objBox,
  32.                                      float fEntDistance,
  33.                                      bool bSunOnly, bool nCheckOcclusion,
  34.                                      const SRenderingPassInfo& passInfo)
  35. {
  36.         FUNCTION_PROFILER_3DENGINE;
  37.  
  38. #ifdef _DEBUG
  39.         const char* szName = pEnt->GetName();
  40.         const char* szClassName = pEnt->GetEntityClassName();
  41. #endif // _DEBUG
  42.  
  43.         // do not draw if marked to be not drawn or already drawn in this frame
  44.         auto nRndFlags = pEnt->GetRndFlags();
  45.  
  46.         if (nRndFlags & ERF_HIDDEN)
  47.                 return;
  48.  
  49.         EERType eERType = pEnt->GetRenderNodeType();
  50.  
  51.         // detect bad objects
  52.         float fEntLengthSquared = objBox.GetSize().GetLengthSquared();
  53.         if (eERType != eERType_Light || !_finite(fEntLengthSquared))
  54.         {
  55.                 if (fEntLengthSquared > MAX_VALID_OBJECT_VOLUME || !_finite(fEntLengthSquared) || fEntLengthSquared <= 0)
  56.                 {
  57.                         Warning("CObjManager::RenderObject: Object has invalid bbox: %s,%s, Radius = %.2f, Center = (%.1f,%.1f,%.1f)",
  58.                                 pEnt->GetName(), pEnt->GetEntityClassName(), sqrt_tpl(fEntLengthSquared) * 0.5f,
  59.                                 pEnt->GetBBox().GetCenter().x, pEnt->GetBBox().GetCenter().y, pEnt->GetBBox().GetCenter().z);
  60.                         return; // skip invalid objects - usually only objects with invalid very big scale will reach this point
  61.                 }
  62.         }
  63.         else
  64.                 pAffectingLights = NULL;
  65.  
  66.         // allocate RNTmpData for potentially visible objects
  67.         if (!Get3DEngine()->CheckAndCreateRenderNodeTempData(&pEnt->m_pTempData, pEnt, passInfo))
  68.         {
  69.                 return;
  70.         }
  71.  
  72.         if (nCheckOcclusion && pEnt->m_pOcNode)
  73.                 if (GetObjManager()->IsBoxOccluded(objBox, fEntDistance * passInfo.GetInverseZoomFactor(), &pEnt->m_pTempData->userData.m_OcclState,
  74.                                                    pEnt->m_pOcNode->m_pVisArea != NULL, eoot_OBJECT, passInfo))
  75.                         return;
  76.  
  77.         CVisArea* pVisArea = (CVisArea*)pEnt->GetEntityVisArea();
  78.  
  79.         const Vec3& vCamPos = passInfo.GetCamera().GetPosition();
  80.  
  81.         // test only near/big occluders - others will be tested on tree nodes level
  82.         if (!objBox.IsContainPoint(vCamPos))
  83.                 if (eERType == eERType_Light || fEntDistance < pEnt->m_fWSMaxViewDist * GetCVars()->e_OcclusionCullingViewDistRatio)
  84.                         if (IsBoxOccluded(objBox, fEntDistance * passInfo.GetInverseZoomFactor(), &pEnt->m_pTempData->userData.m_OcclState, pVisArea != NULL, eoot_OBJECT, passInfo))
  85.                                 return;
  86.  
  87.         SRendParams DrawParams;
  88.         DrawParams.pTerrainTexInfo = NULL;
  89.         DrawParams.dwFObjFlags = 0;
  90.         DrawParams.fDistance = fEntDistance;
  91.         DrawParams.AmbientColor = vAmbColor;
  92.         DrawParams.pRenderNode = pEnt;
  93.         DrawParams.nAfterWater = IsAfterWater(objBox.GetCenter(), vCamPos, passInfo) ? 1 : 0;
  94.  
  95.         // draw bbox
  96.         if (GetCVars()->e_BBoxes)// && eERType != eERType_Light)
  97.         {
  98.                 RenderObjectDebugInfo(pEnt, fEntDistance, passInfo);
  99.         }
  100.  
  101.         DrawParams.dwFObjFlags |= FOB_TRANS_MASK;
  102.  
  103.         DrawParams.m_pVisArea = pVisArea;
  104.  
  105.         DrawParams.nMaterialLayers = pEnt->GetMaterialLayers();
  106.  
  107.         pEnt->Render(DrawParams, passInfo);
  108. }
  109.  
  110. void CObjManager::RenderVegetation(CVegetation* pEnt, PodArray<CDLight*>* pAffectingLights,
  111.                                    const AABB& objBox,
  112.                                    float fEntDistance,
  113.                                    bool bSunOnly, SSectorTextureSet* pTerrainTexInfo, bool nCheckOcclusion,
  114.                                    const SRenderingPassInfo& passInfo)
  115. {
  116.         FUNCTION_PROFILER_3DENGINE;
  117.  
  118. #ifdef _DEBUG
  119.         const char* szName = pEnt->GetName();
  120.         const char* szClassName = pEnt->GetEntityClassName();
  121. #endif // _DEBUG
  122.  
  123.         // check cvars
  124.         assert(passInfo.RenderVegetation());
  125.  
  126.         // check-allocate RNTmpData for visible objects
  127.         if (!Get3DEngine()->CheckAndCreateRenderNodeTempData(&pEnt->m_pTempData, pEnt, passInfo))
  128.         {
  129.                 return;
  130.         }
  131.  
  132.         if (nCheckOcclusion && pEnt->m_pOcNode)
  133.                 if (GetObjManager()->IsBoxOccluded(objBox, fEntDistance * passInfo.GetInverseZoomFactor(), &pEnt->m_pTempData->userData.m_OcclState,
  134.                                                    pEnt->m_pOcNode->m_pVisArea != NULL, eoot_OBJECT, passInfo))
  135.                         return;
  136.  
  137.         const CLodValue lodValue = pEnt->ComputeLod(pEnt->m_pTempData->userData.nWantedLod, passInfo);
  138.  
  139.         if (GetCVars()->e_LodTransitionTime && passInfo.IsGeneralPass())
  140.         {
  141.                 // Render current lod and (if needed) previous lod and perform time based lod transition using dissolve
  142.  
  143.                 CLodValue arrlodVals[2];
  144.                 int nLodsNum = ComputeDissolve(lodValue, pEnt, fEntDistance, &arrlodVals[0]);
  145.  
  146.                 for (int i = 0; i < nLodsNum; i++)
  147.                         pEnt->Render(passInfo, arrlodVals[i], pTerrainTexInfo);
  148.         }
  149.         else
  150.         {
  151.                 pEnt->Render(passInfo, lodValue, pTerrainTexInfo);
  152.         }
  153. }
  154.  
  155. void CObjManager::RenderObject(IRenderNode* pEnt, PodArray<CDLight*>* pAffectingLights,
  156.                                const Vec3& vAmbColor, const AABB& objBox,
  157.                                float fEntDistance,
  158.                                bool bSunOnly, EERType eERType,
  159.                                const SRenderingPassInfo& passInfo)
  160. {
  161.         FUNCTION_PROFILER_3DENGINE;
  162.  
  163.         const CVars* pCVars = GetCVars();
  164.  
  165. #ifdef _DEBUG
  166.         const char* szName = pEnt->GetName();
  167.         const char* szClassName = pEnt->GetEntityClassName();
  168. #endif // _DEBUG
  169.  
  170.         // do not draw if marked to be not drawn or already drawn in this frame
  171.         auto nRndFlags = pEnt->GetRndFlags();
  172.  
  173.         if (nRndFlags & ERF_HIDDEN)
  174.                 return;
  175.  
  176. #ifndef _RELEASE
  177.         if (!passInfo.RenderEntities() && pEnt->GetOwnerEntity())
  178.                 return;
  179.         // check cvars
  180.         switch (eERType)
  181.         {
  182.         case eERType_Brush:
  183.                 if (!passInfo.RenderBrushes()) return;
  184.                 break;
  185.         case eERType_Vegetation:
  186.                 assert(0);
  187.                 break;
  188.         case eERType_ParticleEmitter:
  189.                 if (!passInfo.RenderParticles()) return;
  190.                 break;
  191.         case eERType_Decal:
  192.                 if (!passInfo.RenderDecals()) return;
  193.                 break;
  194.         case eERType_WaterWave:
  195.                 if (!passInfo.RenderWaterWaves()) return;
  196.                 break;
  197.         case eERType_WaterVolume:
  198.                 if (!passInfo.RenderWaterVolumes()) return;
  199.                 break;
  200.         case eERType_Light:
  201.                 if (!GetCVars()->e_DynamicLights || !passInfo.RenderEntities()) return;
  202.                 break;
  203.         case eERType_Road:
  204.                 if (!passInfo.RenderRoads()) return;
  205.                 break;
  206.         case eERType_Cloud:
  207.         case eERType_DistanceCloud:
  208.         case eERType_CloudBlocker:
  209.                 if (!passInfo.RenderClouds()) return;
  210.                 break;
  211.         case eERType_MergedMesh:
  212.                 if (!passInfo.RenderMergedMeshes()) return;
  213.                 break;
  214.         default:
  215.                 if (!passInfo.RenderEntities()) return;
  216.                 break;
  217.         }
  218.  
  219.         // detect bad objects
  220.         float fEntLengthSquared = objBox.GetSize().GetLengthSquared();
  221.         if (eERType != eERType_Light || !_finite(fEntLengthSquared))
  222.         {
  223.                 if (fEntLengthSquared > MAX_VALID_OBJECT_VOLUME || !_finite(fEntLengthSquared) || fEntLengthSquared <= 0)
  224.                 {
  225.                         Warning("CObjManager::RenderObject: Object has invalid bbox: %s, %s, Radius = %.2f, Center = (%.1f,%.1f,%.1f)",
  226.                                 pEnt->GetName(), pEnt->GetEntityClassName(), sqrt_tpl(fEntLengthSquared) * 0.5f,
  227.                                 pEnt->GetBBox().GetCenter().x, pEnt->GetBBox().GetCenter().y, pEnt->GetBBox().GetCenter().z);
  228.                         return; // skip invalid objects - usually only objects with invalid very big scale will reach this point
  229.                 }
  230.         }
  231.         else
  232.                 pAffectingLights = NULL;
  233. #endif
  234.  
  235.         if (pEnt->m_dwRndFlags & ERF_COLLISION_PROXY || pEnt->m_dwRndFlags & ERF_RAYCAST_PROXY)
  236.         {
  237.                 // Collision proxy is visible in Editor while in editing mode.
  238.                 if (!gEnv->IsEditor() || !gEnv->IsEditing())
  239.                 {
  240.                         if (GetCVars()->e_DebugDraw == 0)
  241.                                 return; //true;
  242.                 }
  243.         }
  244.  
  245.         // allocate RNTmpData for potentially visible objects
  246.         if (!Get3DEngine()->CheckAndCreateRenderNodeTempData(&pEnt->m_pTempData, pEnt, passInfo))
  247.         {
  248.                 return;
  249.         }
  250.  
  251.         PrefetchLine(pEnt->m_pTempData, 0); //m_pRNTmpData is >128 bytes, prefetching data used in dissolveref here
  252.  
  253. #if CRY_PLATFORM_DESKTOP
  254.         // detect already culled occluder
  255.         if ((nRndFlags & ERF_GOOD_OCCLUDER))
  256.         {
  257.                 if (pEnt->m_pTempData->userData.m_OcclState.nLastOccludedMainFrameID == passInfo.GetMainFrameID())
  258.                         return;
  259.  
  260.                 if (pCVars->e_CoverageBufferDrawOccluders)
  261.                 {
  262.                         return;
  263.                 }
  264.         }
  265. #endif
  266.  
  267.         CVisArea* pVisArea = (CVisArea*)pEnt->GetEntityVisArea();
  268.  
  269.         const Vec3& vCamPos = passInfo.GetCamera().GetPosition();
  270.  
  271.         // test only near/big occluders - others will be tested on tree nodes level
  272.         // Note: Not worth prefetch on rCam or objBox as both have been recently used by calling functions & will be in cache - Rich S
  273.         if (!(nRndFlags & ERF_RENDER_ALWAYS) && !objBox.IsContainPoint(vCamPos))
  274.                 if (eERType == eERType_Light || fEntDistance < pEnt->m_fWSMaxViewDist * pCVars->e_OcclusionCullingViewDistRatio)
  275.                         if (IsBoxOccluded(objBox, fEntDistance * passInfo.GetInverseZoomFactor(), &pEnt->m_pTempData->userData.m_OcclState, pVisArea != NULL, eoot_OBJECT, passInfo))
  276.                                 return;
  277.  
  278.         SRendParams DrawParams;
  279.         DrawParams.pTerrainTexInfo = NULL;
  280.         DrawParams.dwFObjFlags = 0;
  281.         DrawParams.fDistance = fEntDistance;
  282.         DrawParams.AmbientColor = vAmbColor;
  283.         DrawParams.pRenderNode = pEnt;
  284.         DrawParams.nEditorSelectionID = pEnt->m_nEditorSelectionID;
  285.         //DrawParams.pInstance = pEnt;
  286.  
  287.         if (eERType != eERType_Light && (pEnt->m_nInternalFlags & IRenderNode::REQUIRES_NEAREST_CUBEMAP))
  288.         {
  289.                 Vec4 envProbMults = Vec4(1.0f, 1.0f, 1.0f, 1.0f);
  290.                 uint16 nCubemapTexId = 0;
  291.                 if (!(nCubemapTexId = CheckCachedNearestCubeProbe(pEnt, &envProbMults)) || !pCVars->e_CacheNearestCubePicking)
  292.                         nCubemapTexId = GetNearestCubeProbe(pAffectingLights, pVisArea, objBox, true, &envProbMults);
  293.  
  294.                 SRenderNodeTempData::SUserData* pUserDataRN = (pEnt->m_pTempData) ? &pEnt->m_pTempData->userData : 0;
  295.                 if (pUserDataRN)
  296.                 {
  297.                         pUserDataRN->nCubeMapId = nCubemapTexId;
  298.                         pUserDataRN->vEnvironmentProbeMults = envProbMults;
  299.                 }
  300.  
  301.                 DrawParams.nTextureID = nCubemapTexId;
  302.         }
  303.  
  304.         DrawParams.nAfterWater = IsAfterWater(objBox.GetCenter(), vCamPos, passInfo) ? 1 : 0;
  305.  
  306.         if (nRndFlags & ERF_SELECTED)
  307.                 DrawParams.dwFObjFlags |= FOB_SELECTED;
  308.  
  309.         // draw bbox
  310. #if !defined(_RELEASE)
  311.         if (pCVars->e_BBoxes)// && eERType != eERType_Light)
  312.         {
  313.                 RenderObjectDebugInfo(pEnt, fEntDistance, passInfo);
  314.         }
  315. #endif
  316.  
  317.         DrawParams.dwFObjFlags |= FOB_TRANS_MASK;
  318.  
  319.         if (pEnt->m_dwRndFlags & ERF_NO_DECALNODE_DECALS)
  320.                 DrawParams.dwFObjFlags |= FOB_DYNAMIC_OBJECT;
  321.  
  322.         if (pEnt->GetRndFlags() & ERF_HUD_REQUIRE_DEPTHTEST)
  323.         {
  324.                 DrawParams.nCustomFlags |= COB_HUD_REQUIRE_DEPTHTEST;
  325.         }
  326.         if (pEnt->GetRndFlags() & ERF_DISABLE_MOTION_BLUR)
  327.         {
  328.                 DrawParams.nCustomFlags |= COB_DISABLE_MOTIONBLUR;
  329.         }
  330.         if (pEnt->GetRndFlags() & ERF_FORCE_POST_3D_RENDER)
  331.         {
  332.                 DrawParams.nCustomFlags |= COB_POST_3D_RENDER;
  333.         }
  334.  
  335.         DrawParams.m_pVisArea = pVisArea;
  336.  
  337.         DrawParams.nClipVolumeStencilRef = 0;
  338.         if (pEnt->m_pTempData && pEnt->m_pTempData->userData.m_pClipVolume)
  339.                 DrawParams.nClipVolumeStencilRef = pEnt->m_pTempData->userData.m_pClipVolume->GetStencilRef();
  340.  
  341.         DrawParams.nMaterialLayers = pEnt->GetMaterialLayers();
  342.         DrawParams.lodValue = pEnt->ComputeLod(pEnt->m_pTempData->userData.nWantedLod, passInfo);
  343.  
  344.         if (GetCVars()->e_LodTransitionTime && passInfo.IsGeneralPass() && pEnt->GetRenderNodeType() == eERType_RenderProxy)
  345.         {
  346.                 // Render current lod and (if needed) previous lod and perform time based lod transition using dissolve
  347.  
  348.                 CLodValue arrlodVals[2];
  349.                 int nLodsNum = ComputeDissolve(DrawParams.lodValue, pEnt, fEntDistance, &arrlodVals[0]);
  350.  
  351.                 for (int i = 0; i < nLodsNum; i++)
  352.                 {
  353.                         DrawParams.lodValue = arrlodVals[i];
  354.                         pEnt->Render(DrawParams, passInfo);
  355.                 }
  356.         }
  357.         else
  358.         {
  359.                 pEnt->Render(DrawParams, passInfo);
  360.         }
  361. }
  362.  
  363. void CObjManager::RenderAllObjectDebugInfo()
  364. {
  365.         m_arrRenderDebugInfo.CoalesceMemory();
  366.         for (size_t i = 0; i < m_arrRenderDebugInfo.size(); ++i)
  367.         {
  368.                 SObjManRenderDebugInfo& rRenderDebugInfo = m_arrRenderDebugInfo[i];
  369.                 if (rRenderDebugInfo.pEnt)
  370.                         RenderObjectDebugInfo_Impl(rRenderDebugInfo.pEnt, rRenderDebugInfo.fEntDistance);
  371.         }
  372.         m_arrRenderDebugInfo.resize(0);
  373. }
  374.  
  375. void CObjManager::RemoveFromRenderAllObjectDebugInfo(IRenderNode* pEnt)
  376. {
  377.         for (size_t i = 0; i < m_arrRenderDebugInfo.size(); ++i)
  378.         {
  379.                 SObjManRenderDebugInfo& rRenderDebugInfo = m_arrRenderDebugInfo[i];
  380.                 if (rRenderDebugInfo.pEnt == pEnt)
  381.                 {
  382.                         rRenderDebugInfo.pEnt = NULL;
  383.                         break;
  384.                 }
  385.         }
  386. }
  387.  
  388. void CObjManager::RenderObjectDebugInfo_Impl(IRenderNode* pEnt, float fEntDistance)
  389. {
  390.  
  391.         if (GetCVars()->e_BBoxes > 0)
  392.         {
  393.                 ColorF color(1, 1, 1, 1);
  394.  
  395.                 if (GetCVars()->e_BBoxes == 2 && pEnt->GetRndFlags() & ERF_SELECTED)
  396.                 {
  397.                         color.a *= clamp_tpl(pEnt->GetImportance(), 0.5f, 1.f);
  398.                         float fFontSize = max(2.f - fEntDistance * 0.01f, 1.f);
  399.  
  400.                         string sLabel = pEnt->GetDebugString();
  401.                         if (sLabel.empty())
  402.                         {
  403.                                 sLabel.Format("%s/%s", pEnt->GetName(), pEnt->GetEntityClassName());
  404.                         }
  405.                         IRenderAuxText::DrawLabelEx(pEnt->GetBBox().GetCenter(), fFontSize, (float*)&color, true, true, sLabel.c_str());
  406.                 }
  407.  
  408.                 IRenderAuxGeom* pRenAux = GetRenderer()->GetIRenderAuxGeom();
  409.                 pRenAux->SetRenderFlags(SAuxGeomRenderFlags());
  410.                 AABB rAABB = pEnt->GetBBox();
  411.                 const float Bias = GetCVars()->e_CoverageBufferAABBExpand;
  412.                 if (Bias < 0.f)
  413.                         rAABB.Expand((rAABB.max - rAABB.min) * Bias - Vec3(Bias, Bias, Bias));
  414.                 else
  415.                         rAABB.Expand(Vec3(Bias, Bias, Bias));
  416.  
  417.                 pRenAux->DrawAABB(rAABB, false, color, eBBD_Faceted);
  418.         }
  419. }
  420.  
  421. bool CObjManager::RayRenderMeshIntersection(IRenderMesh* pRenderMesh, const Vec3& vInPos, const Vec3& vInDir, Vec3& vOutPos, Vec3& vOutNormal, bool bFastTest, IMaterial* pMat)
  422. {
  423.         FUNCTION_PROFILER_3DENGINE;
  424.  
  425.         struct MeshLock
  426.         {
  427.                 MeshLock(IRenderMesh* m = 0) : mesh(m)
  428.                 {
  429.                         if (m) m->LockForThreadAccess();
  430.                 }
  431.                 ~MeshLock()
  432.                 {
  433.                         if (mesh)
  434.                         {
  435.                                 mesh->UnlockStream(VSF_GENERAL);
  436.                                 mesh->UnlockIndexStream();
  437.                                 mesh->UnLockForThreadAccess();
  438.                         }
  439.                 }
  440.         private:
  441.                 IRenderMesh* mesh;
  442.         };
  443.  
  444.         MeshLock rmLock(pRenderMesh);
  445.  
  446.         // get position offset and stride
  447.         int nPosStride = 0;
  448.         byte* pPos = pRenderMesh->GetPosPtr(nPosStride, FSL_READ);
  449.  
  450.         // get indices
  451.         vtx_idx* pInds = pRenderMesh->GetIndexPtr(FSL_READ);
  452.         int nInds = pRenderMesh->GetIndicesCount();
  453.         assert(nInds % 3 == 0);
  454.  
  455.         float fClosestHitDistance = -1;
  456.  
  457.         Lineseg l0(vInPos + vInDir, vInPos - vInDir);
  458.         Lineseg l1(vInPos - vInDir, vInPos + vInDir);
  459.  
  460.         Vec3 vHitPoint(0, 0, 0);
  461.  
  462.         //      bool b2DTest = fabs(vInDir.x)<0.001f && fabs(vInDir.y)<0.001f;
  463.  
  464.         // test tris
  465.         TRenderChunkArray& Chunks = pRenderMesh->GetChunks();
  466.         for (int nChunkId = 0; nChunkId < Chunks.size(); nChunkId++)
  467.         {
  468.                 CRenderChunk* pChunk = &Chunks[nChunkId];
  469.                 if (pChunk->m_nMatFlags & MTL_FLAG_NODRAW || !pChunk->pRE)
  470.                         continue;
  471.  
  472.                 if (pMat)
  473.                 {
  474.                         const SShaderItem& shaderItem = pMat->GetShaderItem(pChunk->m_nMatID);
  475.                         if (!shaderItem.m_pShader || shaderItem.m_pShader->GetFlags() & EF_NODRAW)
  476.                                 continue;
  477.                 }
  478.  
  479.                 AABB triBox;
  480.  
  481.                 int nLastIndexId = pChunk->nFirstIndexId + pChunk->nNumIndices;
  482.                 for (int i = pChunk->nFirstIndexId; i < nLastIndexId; i += 3)
  483.                 {
  484.                         assert((int)pInds[i + 0] < pRenderMesh->GetVerticesCount());
  485.                         assert((int)pInds[i + 1] < pRenderMesh->GetVerticesCount());
  486.                         assert((int)pInds[i + 2] < pRenderMesh->GetVerticesCount());
  487.  
  488.                         // get vertices
  489.                         const Vec3 v0 = (*(Vec3*)&pPos[nPosStride * pInds[i + 0]]);
  490.                         const Vec3 v1 = (*(Vec3*)&pPos[nPosStride * pInds[i + 1]]);
  491.                         const Vec3 v2 = (*(Vec3*)&pPos[nPosStride * pInds[i + 2]]);
  492.                         /*
  493.                               if(b2DTest)
  494.                               {
  495.                                 triBox.min = triBox.max = v0;
  496.                                 triBox.Add(v1);
  497.                                 triBox.Add(v2);
  498.                                 if(     vInPos.x < triBox.min.x || vInPos.x > triBox.max.x || vInPos.y < triBox.min.y || vInPos.y > triBox.max.y )
  499.                                   continue;
  500.                               }
  501.                          */
  502.                         // make line triangle intersection
  503.                         if (Intersect::Lineseg_Triangle(l0, v0, v1, v2, vHitPoint) ||
  504.                             Intersect::Lineseg_Triangle(l1, v0, v1, v2, vHitPoint))
  505.                         {
  506.                                 if (bFastTest)
  507.                                         return (true);
  508.  
  509.                                 float fDist = vHitPoint.GetDistance(vInPos);
  510.                                 if (fDist < fClosestHitDistance || fClosestHitDistance < 0)
  511.                                 {
  512.                                         fClosestHitDistance = fDist;
  513.                                         vOutPos = vHitPoint;
  514.                                         vOutNormal = (v1 - v0).Cross(v2 - v0);
  515.                                 }
  516.                         }
  517.                 }
  518.         }
  519.  
  520.         if (fClosestHitDistance >= 0)
  521.         {
  522.                 vOutNormal.Normalize();
  523.                 return true;
  524.         }
  525.  
  526.         return false;
  527. }
  528.  
  529. bool CObjManager::RayStatObjIntersection(IStatObj* pStatObj, const Matrix34& objMatrix, IMaterial* pMat,
  530.                                          Vec3 vStart, Vec3 vEnd, Vec3& vClosestHitPoint, float& fClosestHitDistance, bool bFastTest)
  531. {
  532.         assert(pStatObj);
  533.  
  534.         CStatObj* pCStatObj = (CStatObj*)pStatObj;
  535.  
  536.         if (!pCStatObj || pCStatObj->m_nFlags & STATIC_OBJECT_HIDDEN)
  537.                 return false;
  538.  
  539.         Matrix34 matInv = objMatrix.GetInverted();
  540.         Vec3 vOSStart = matInv.TransformPoint(vStart);
  541.         Vec3 vOSEnd = matInv.TransformPoint(vEnd);
  542.         Vec3 vOSHitPoint(0, 0, 0), vOSHitNorm(0, 0, 0);
  543.  
  544.         Vec3 vBoxHitPoint;
  545.         if (!Intersect::Ray_AABB(Ray(vOSStart, vOSEnd - vOSStart), pCStatObj->GetAABB(), vBoxHitPoint))
  546.                 return false;
  547.  
  548.         bool bHitDetected = false;
  549.  
  550.         if (IRenderMesh* pRenderMesh = pStatObj->GetRenderMesh())
  551.         {
  552.                 if (CObjManager::RayRenderMeshIntersection(pRenderMesh, vOSStart, vOSEnd - vOSStart, vOSHitPoint, vOSHitNorm, bFastTest, pMat))
  553.                 {
  554.                         bHitDetected = true;
  555.                         Vec3 vHitPoint = objMatrix.TransformPoint(vOSHitPoint);
  556.                         float fDist = vHitPoint.GetDistance(vStart);
  557.                         if (fDist < fClosestHitDistance)
  558.                         {
  559.                                 fClosestHitDistance = fDist;
  560.                                 vClosestHitPoint = vHitPoint;
  561.                         }
  562.                 }
  563.         }
  564.         else
  565.         {
  566.                 // multi-sub-objects
  567.                 for (int s = 0, num = pCStatObj->SubObjectCount(); s < num; s++)
  568.                 {
  569.                         IStatObj::SSubObject& subObj = pCStatObj->SubObject(s);
  570.                         if (subObj.pStatObj && !subObj.bHidden && subObj.nType == STATIC_SUB_OBJECT_MESH)
  571.                         {
  572.                                 Matrix34 subObjMatrix = objMatrix * subObj.tm;
  573.                                 if (RayStatObjIntersection(subObj.pStatObj, subObjMatrix, pMat, vStart, vEnd, vClosestHitPoint, fClosestHitDistance, bFastTest))
  574.                                         bHitDetected = true;
  575.                         }
  576.                 }
  577.         }
  578.  
  579.         return bHitDetected;
  580. }
  581.  
downloadObjManDrawEntity.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