BVB Source Codes

CRYENGINE Show terrain_hmap_occlusion.cpp Source code

Return Download CRYENGINE: download terrain_hmap_occlusion.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: Draw static objects (vegetations)
  9. // -------------------------------------------------------------------------
  10. //  History:
  11. //
  12. ////////////////////////////////////////////////////////////////////////////
  13.  
  14. #include "StdAfx.h"
  15.  
  16. #ifdef SUPP_HMAP_OCCL
  17.  
  18.         #include "terrain.h"
  19.         #include "StatObj.h"
  20.         #include "ObjMan.h"
  21.         #include "VisAreas.h"
  22.         #include "terrain_sector.h"
  23.         #include "3dEngine.h"
  24.         #include "PolygonClipContext.h"
  25.  
  26. bool CHeightMap::IsBoxOccluded
  27. (
  28.   const AABB& objBox,
  29.   float fDistance,
  30.   bool bTerrainNode,
  31.   OcclusionTestClient* const __restrict pOcclTestVars,
  32.   int nSID,
  33.   const SRenderingPassInfo& passInfo
  34. )
  35. {
  36.         // test occlusion by heightmap
  37.         //      FUNCTION_PROFILER_3DENGINE;
  38.         assert(pOcclTestVars);
  39.  
  40.         // define top face of the box
  41.         Vec3 vTopMax = objBox.max;
  42.         Vec3 vTopMin = objBox.min;
  43.         vTopMin.z = vTopMax.z;
  44.  
  45.         // skip testing huge boxes
  46.         IF ((vTopMax.x - vTopMin.x) > 100000 || (vTopMax.y - vTopMin.y) > 100000, false)
  47.         {
  48.                 pOcclTestVars->nTerrainOccLastFrame = 0;
  49.                 return false;
  50.         }
  51.  
  52.         const Vec3 vCamPos = passInfo.GetCamera().GetPosition();
  53.  
  54.         // return 'not occluded' if camera is inside of box
  55.         IF (vCamPos.x <= vTopMax.x && vCamPos.x >= vTopMin.x && vCamPos.y <= vTopMax.y && vCamPos.y >= vTopMin.y, false)
  56.         {
  57.                 pOcclTestVars->nTerrainOccLastFrame = 0;
  58.                 return false;
  59.         }
  60.  
  61.         // when camera is underground - number of steps allowed to skip
  62.         int nMaxTestsToScip = (GetVisAreaManager()->m_pCurPortal) ? 3 : 10000;
  63.  
  64.         CVars* const __restrict pCVars = GetCVars();
  65.  
  66.         // density of tests in meters for this object
  67.         float fMaxStep = fDistance * GetFloatCVar(e_TerrainOcclusionCullingPrecision);
  68.  
  69.         // if object was visible last time - try last known visible point first
  70.         if (!pOcclTestVars->vLastVisPoint.IsZero())
  71.         {
  72.                 Vec3 vTmp(0, 0, 0);
  73.                 if (!Intersect(vCamPos, pOcclTestVars->vLastVisPoint, fDistance, nMaxTestsToScip, vTmp, nSID))
  74.                 {
  75.                         pOcclTestVars->nTerrainOccLastFrame = 0;
  76.                         return false;
  77.                 }
  78.                 else
  79.                         pOcclTestVars->vLastVisPoint.zero();
  80.         }
  81.  
  82.         // do many rays for near objects and only one for far/small objects
  83.         if ((fMaxStep < (vTopMax.x - vTopMin.x) * GetFloatCVar(e_TerrainOcclusionCullingPrecisionDistRatio) ||
  84.              fMaxStep < (vTopMax.y - vTopMin.y) * GetFloatCVar(e_TerrainOcclusionCullingPrecisionDistRatio)) &&
  85.             objBox.min.x != objBox.max.x && objBox.min.y != objBox.max.y)
  86.         {
  87.                 // split fox top surface into round number of parts
  88.                 float dx = (vTopMax.x - vTopMin.x);
  89.                 while (dx > fMaxStep)
  90.                         dx *= 0.5f;
  91.                 float dy = (vTopMax.y - vTopMin.y);
  92.                 while (dy > fMaxStep)
  93.                         dy *= 0.5f;
  94.  
  95.                 // avoid dead loops
  96.                 dy = max(dy, 0.001f);
  97.                 dx = max(dx, 0.001f);
  98.  
  99.                 bool bCameraAbove = vCamPos.z > vTopMax.z;
  100.  
  101.                 if (bCameraAbove && !bTerrainNode)
  102.                 {
  103.                         for (float y = vTopMin.y; y <= vTopMax.y; y += dy)
  104.                                 for (float x = vTopMin.x; x <= vTopMax.x; x += dx)
  105.                                         if (!Intersect(vCamPos, Vec3(x, y, vTopMax.z), fDistance, nMaxTestsToScip, pOcclTestVars->vLastVisPoint, nSID))
  106.                                         {
  107.                                                 pOcclTestVars->nTerrainOccLastFrame = 0;
  108.                                                 return false;
  109.                                         }
  110.                 }
  111.                 else
  112.                 {
  113.                         // test only needed edges, note: there are duplicated checks on the corners
  114.  
  115.                         if ((vCamPos.x > vTopMin.x) == bCameraAbove) // test min x side
  116.                                 for (float y = vTopMin.y; y <= vTopMax.y; y += dy)
  117.                                         if (!Intersect(vCamPos, Vec3(vTopMin.x, y, vTopMax.z), fDistance, nMaxTestsToScip, pOcclTestVars->vLastVisPoint, nSID))
  118.                                         {
  119.                                                 pOcclTestVars->nTerrainOccLastFrame = 0;
  120.                                                 return false;
  121.                                         }
  122.  
  123.                         if ((vCamPos.x < vTopMax.x) == bCameraAbove) // test max x side
  124.                                 for (float y = vTopMax.y; y >= vTopMin.y; y -= dy)
  125.                                         if (!Intersect(vCamPos, Vec3(vTopMax.x, y, vTopMax.z), fDistance, nMaxTestsToScip, pOcclTestVars->vLastVisPoint, nSID))
  126.                                         {
  127.                                                 pOcclTestVars->nTerrainOccLastFrame = 0;
  128.                                                 return false;
  129.                                         }
  130.  
  131.                         if ((vCamPos.y > vTopMin.y) == bCameraAbove) // test min y side
  132.                                 for (float x = vTopMax.x; x >= vTopMin.x; x -= dx)
  133.                                         if (!Intersect(vCamPos, Vec3(x, vTopMin.y, vTopMax.z), fDistance, nMaxTestsToScip, pOcclTestVars->vLastVisPoint, nSID))
  134.                                         {
  135.                                                 pOcclTestVars->nTerrainOccLastFrame = 0;
  136.                                                 return false;
  137.                                         }
  138.  
  139.                         if ((vCamPos.y < vTopMax.y) == bCameraAbove) // test max y side
  140.                                 for (float x = vTopMin.x; x <= vTopMax.x; x += dx)
  141.                                         if (!Intersect(vCamPos, Vec3(x, vTopMax.y, vTopMax.z), fDistance, nMaxTestsToScip, pOcclTestVars->vLastVisPoint, nSID))
  142.                                         {
  143.                                                 pOcclTestVars->nTerrainOccLastFrame = 0;
  144.                                                 return false;
  145.                                         }
  146.                 }
  147.                 pOcclTestVars->nLastOccludedMainFrameID = passInfo.GetMainFrameID();
  148.                 pOcclTestVars->nTerrainOccLastFrame = 1;
  149.                 return true;
  150.         }
  151.         else
  152.         {
  153.                 // select random point on top surface, once visible point is found - it will be stored in vLastVisPoint and used for future tests
  154.                 Vec3 vTopMid(0, 0, vTopMin.z);
  155.                 float t;
  156.                 t = cry_random(0.0f, 1.0f);
  157.                 vTopMid.x = vTopMin.x * t + vTopMax.x * (1.f - t);
  158.                 t = cry_random(0.0f, 1.0f);
  159.                 vTopMid.y = vTopMin.y * t + vTopMax.y * (1.f - t);
  160.  
  161.                 if (Intersect(vCamPos, vTopMid, fDistance, nMaxTestsToScip, pOcclTestVars->vLastVisPoint, nSID))
  162.                 {
  163.                         pOcclTestVars->nLastOccludedMainFrameID = passInfo.GetMainFrameID();
  164.                         pOcclTestVars->nTerrainOccLastFrame = 1;
  165.                         return true;
  166.                 }
  167.         }
  168.         pOcclTestVars->nTerrainOccLastFrame = 0;
  169.         return false;
  170. }
  171.  
  172. bool CHeightMap::Intersect(Vec3 vStartPoint, Vec3 vStopPoint, float _fDist, int nMaxTestsToScip, Vec3& vLastVisPoint, int nSID)
  173. {
  174.         //  FUNCTION_PROFILER_3DENGINE;
  175.  
  176.         // convert x and y into heightmap space, keep z in world space
  177.         float fHMSize = (float)CTerrain::GetTerrainSize() / CTerrain::GetHeightMapUnitSize();
  178.         float fInvUnitSize = CTerrain::GetInvUnitSize();
  179.         vStopPoint.x *= fInvUnitSize;
  180.         vStopPoint.y *= fInvUnitSize;
  181.         vStartPoint.x *= fInvUnitSize;
  182.         vStartPoint.y *= fInvUnitSize;
  183.  
  184.         // clamp start
  185.         if (vStartPoint.x < 0 || vStartPoint.y < 0 || vStartPoint.x >= fHMSize || vStartPoint.y >= fHMSize)
  186.         {
  187.                 AABB boxHM(Vec3(0, 0, 0), Vec3(fHMSize, fHMSize, fHMSize));
  188.                 Lineseg ls(vStartPoint, vStopPoint);
  189.                 Vec3 vRes;
  190.                 if (Intersect::Lineseg_AABB(ls, boxHM, vRes) == 0x01)
  191.                         vStartPoint = vRes;
  192.                 else
  193.                 {
  194.                         vLastVisPoint.Set(vStopPoint.x / fInvUnitSize, vStopPoint.y / fInvUnitSize, vStopPoint.z);
  195.                         return false;
  196.                 }
  197.         }
  198.  
  199.         // clamp end
  200.         if (vStopPoint.x < 0 || vStopPoint.y < 0 || vStopPoint.x >= fHMSize || vStopPoint.y >= fHMSize)
  201.         {
  202.                 AABB boxHM(Vec3(0, 0, 0), Vec3(fHMSize, fHMSize, fHMSize));
  203.                 Lineseg ls(vStopPoint, vStartPoint);
  204.                 Vec3 vRes;
  205.                 if (Intersect::Lineseg_AABB(ls, boxHM, vRes) == 0x01)
  206.                         vStopPoint = vRes;
  207.                 else
  208.                 {
  209.                         vLastVisPoint.Set(vStopPoint.x / fInvUnitSize, vStopPoint.y / fInvUnitSize, vStopPoint.z);
  210.                         return false;
  211.                 }
  212.         }
  213.  
  214.         float fUnitSizeRatio = 2.f * CTerrain::GetInvUnitSize();
  215.  
  216.         CVars* const __restrict pCVars = GetCVars();
  217.  
  218.         float fInitStepSize = pCVars->e_TerrainOcclusionCullingStepSize * fUnitSizeRatio;
  219.  
  220.         float fStepSize = fInitStepSize;
  221.         Vec3 vDir = (vStopPoint - vStartPoint);
  222.         float fFullDist = vDir.GetLength();
  223.         vDir.Normalize();
  224.         float fPos = 0;
  225.  
  226.         float fMaxUndegroundDist = min(fFullDist, (float)nMaxTestsToScip * fInitStepSize);
  227.  
  228.         for (; fPos < fMaxUndegroundDist; fPos += fStepSize)
  229.         {
  230.                 Vec3 vPos = vStartPoint + vDir * fPos;
  231.                 if (!IsPointUnderGround(fastround_positive(vPos.x), fastround_positive(vPos.y), vPos.z, nSID))
  232.                         break;
  233.         }
  234.  
  235.         float fMaxEndUnitsToSkip = min((float)nMaxTestsToScip, 4.f * fInitStepSize);
  236.  
  237.         fFullDist -= fMaxEndUnitsToSkip;
  238.  
  239.         if (fFullDist > pCVars->e_TerrainOcclusionCullingMaxDist * fUnitSizeRatio)
  240.                 fFullDist = pCVars->e_TerrainOcclusionCullingMaxDist * fUnitSizeRatio;
  241.  
  242.         for (; fPos < fFullDist; fPos += fStepSize)
  243.         {
  244.                 Vec3 vPos = vStartPoint + vDir * fPos;
  245.                 if (IsPointUnderGround(fastround_positive(vPos.x), fastround_positive(vPos.y), vPos.z, nSID))
  246.                 {
  247.                         vLastVisPoint.Set(0, 0, 0);
  248.                         return true;
  249.                 }
  250.  
  251.                 fStepSize *= GetFloatCVar(e_TerrainOcclusionCullingStepSizeDelta);
  252.         }
  253.  
  254.         vLastVisPoint.Set(vStopPoint.x / fInvUnitSize, vStopPoint.y / fInvUnitSize, vStopPoint.z);
  255.         return false;
  256. }
  257. #endif// SUPP_HMAP_OCCL
  258.  
downloadterrain_hmap_occlusion.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