BVB Source Codes

CRYENGINE Show VisAreaMan.cpp Source code

Return Download CRYENGINE: download VisAreaMan.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:     18/12/2002 by Vladimir Kajalin
  7. //  Compilers:   Visual Studio.NET
  8. //  Description: Visibility areas
  9. // -------------------------------------------------------------------------
  10. //  History:
  11. //
  12. ////////////////////////////////////////////////////////////////////////////
  13.  
  14. #include "StdAfx.h"
  15. #include <CryAnimation/ICryAnimation.h>
  16.  
  17. #include "StatObj.h"
  18. #include "ObjMan.h"
  19. #include "VisAreas.h"
  20. #include "terrain_sector.h"
  21. #include "3dEngine.h"
  22. #include "3dEngine.h"
  23. #include "terrain.h"
  24. #include <CryMath/AABBSV.h>
  25.  
  26. #define DEFAULT_INITIAL_PORTALS   1
  27. #define DEFAULT_INITIAL_VISAREAS  1
  28. #define DEFAULT_INITIAL_OCCLAREAS 1
  29.  
  30. CVisAreaManager::CVisAreaManager()
  31. {
  32.         m_pCurPortal = m_pCurArea = 0;
  33.         m_bOutdoorVisible = false;
  34.         m_bSkyVisible = false;
  35.         m_bSunIsNeeded = false;
  36.         m_bOceanVisible = false;
  37.         m_pAABBTree = NULL;
  38.  
  39.         m_visAreas.PreAllocate(DEFAULT_INITIAL_VISAREAS);
  40.         m_visAreaColdData.PreAllocate(DEFAULT_INITIAL_VISAREAS);
  41.  
  42.         m_portals.PreAllocate(DEFAULT_INITIAL_PORTALS);
  43.         m_portalColdData.PreAllocate(DEFAULT_INITIAL_PORTALS);
  44.  
  45.         m_occlAreas.PreAllocate(DEFAULT_INITIAL_OCCLAREAS);
  46.         m_occlAreaColdData.PreAllocate(DEFAULT_INITIAL_OCCLAREAS);
  47.  
  48.         m_segVisAreas.Clear();
  49.         m_segPortals.Clear();
  50.         m_segOcclAreas.Clear();
  51. }
  52.  
  53. void CVisAreaManager::DeleteAllVisAreas()
  54. {
  55.         for (int i = 0; i < m_lstVisAreas.Count(); i++)
  56.         {
  57.                 if (m_visAreas.Find(m_lstVisAreas[i]) >= 0)
  58.                 {
  59.                         delete m_lstVisAreas[i];
  60.                 }
  61.                 else
  62.                 {
  63.                         delete m_lstVisAreas[i]->GetColdData();
  64.                         delete m_lstVisAreas[i];
  65.                 }
  66.         }
  67.  
  68.         m_visAreas.Clear();
  69.         m_visAreaColdData.Clear();
  70.         m_lstVisAreas.Clear();
  71.  
  72.         for (int i = 0; i < m_lstPortals.Count(); i++)
  73.         {
  74.                 if (m_portals.Find(m_lstPortals[i]) >= 0)
  75.                 {
  76.                         delete m_lstPortals[i];
  77.                 }
  78.                 else
  79.                 {
  80.                         delete m_lstPortals[i]->GetColdData();
  81.                         delete m_lstPortals[i];
  82.                 }
  83.         }
  84.  
  85.         m_portals.Clear();
  86.         m_portalColdData.Clear();
  87.         m_lstPortals.Clear();
  88.  
  89.         for (int i = 0; i < m_lstOcclAreas.Count(); i++)
  90.         {
  91.                 if (m_occlAreas.Find(m_lstOcclAreas[i]) >= 0)
  92.                 {
  93.                         delete m_lstOcclAreas[i];
  94.                 }
  95.                 else
  96.                 {
  97.                         delete m_lstOcclAreas[i]->GetColdData();
  98.                         delete m_lstOcclAreas[i];
  99.                 }
  100.         }
  101.  
  102.         m_occlAreas.Clear();
  103.         m_occlAreaColdData.Clear();
  104.         m_lstOcclAreas.Clear();
  105.  
  106.         stl::free_container(CVisArea::m_lUnavailableAreas);
  107. }
  108.  
  109. void SAABBTreeNode::OffsetPosition(const Vec3& delta)
  110. {
  111.         nodeBox.Move(delta);
  112.         if (!nodeAreas.Count())
  113.         {
  114.                 for (int i = 0; i < 2; i++)
  115.                 {
  116.                         if (arrChilds[i])
  117.                                 arrChilds[i]->OffsetPosition(delta);
  118.                 }
  119.         }
  120. }
  121.  
  122. CVisAreaManager::~CVisAreaManager()
  123. {
  124.         DeleteAllVisAreas();
  125.  
  126.         delete m_pAABBTree;
  127.         m_pAABBTree = NULL;
  128. }
  129.  
  130. SAABBTreeNode::SAABBTreeNode(PodArray<CVisArea*>& lstAreas, AABB box, int nRecursion)
  131. {
  132.         memset(this, 0, sizeof(*this));
  133.  
  134.         nodeBox = box;
  135.  
  136.         nRecursion++;
  137.         if (nRecursion > 8 || lstAreas.Count() < 8)
  138.         {
  139.                 nodeAreas.AddList(lstAreas);
  140.                 return;
  141.         }
  142.  
  143.         PodArray<CVisArea*> lstAreas0, lstAreas1;
  144.         Vec3 vSize = nodeBox.GetSize();
  145.         Vec3 vCenter = nodeBox.GetCenter();
  146.  
  147.         AABB nodeBox0 = nodeBox;
  148.         AABB nodeBox1 = nodeBox;
  149.  
  150.         if (vSize.x >= vSize.y && vSize.x >= vSize.z)
  151.         {
  152.                 nodeBox0.min.x = vCenter.x;
  153.                 nodeBox1.max.x = vCenter.x;
  154.         }
  155.         else if (vSize.y >= vSize.x && vSize.y >= vSize.z)
  156.         {
  157.                 nodeBox0.min.y = vCenter.y;
  158.                 nodeBox1.max.y = vCenter.y;
  159.         }
  160.         else
  161.         {
  162.                 nodeBox0.min.z = vCenter.z;
  163.                 nodeBox1.max.z = vCenter.z;
  164.         }
  165.  
  166.         for (int i = 0; i < lstAreas.Count(); i++)
  167.         {
  168.                 if (Overlap::AABB_AABB(nodeBox0, *lstAreas[i]->GetAABBox()))
  169.                         lstAreas0.Add(lstAreas[i]);
  170.  
  171.                 if (Overlap::AABB_AABB(nodeBox1, *lstAreas[i]->GetAABBox()))
  172.                         lstAreas1.Add(lstAreas[i]);
  173.         }
  174.  
  175.         if (lstAreas0.Count())
  176.                 arrChilds[0] = new SAABBTreeNode(lstAreas0, nodeBox0, nRecursion);
  177.  
  178.         if (lstAreas1.Count())
  179.                 arrChilds[1] = new SAABBTreeNode(lstAreas1, nodeBox1, nRecursion);
  180. }
  181.  
  182. SAABBTreeNode::~SAABBTreeNode()
  183. {
  184.         delete arrChilds[0];
  185.         delete arrChilds[1];
  186. }
  187.  
  188. SAABBTreeNode* SAABBTreeNode::GetTopNode(const AABB& box, void** pNodeCache)
  189. {
  190.         AABB boxClip = box;
  191.         boxClip.ClipToBox(nodeBox);
  192.  
  193.         SAABBTreeNode* pNode = this;
  194.         if (pNodeCache)
  195.         {
  196.                 pNode = (SAABBTreeNode*)*pNodeCache;
  197.                 if (!pNode || !pNode->nodeBox.ContainsBox(boxClip))
  198.                         pNode = this;
  199.         }
  200.  
  201.         // Find top node containing box.
  202.         for (;; )
  203.         {
  204.                 int i;
  205.                 for (i = 0; i < 2; i++)
  206.                 {
  207.                         if (pNode->arrChilds[i] && pNode->arrChilds[i]->nodeBox.ContainsBox(boxClip))
  208.                         {
  209.                                 pNode = pNode->arrChilds[i];
  210.                                 break;
  211.                         }
  212.                 }
  213.                 if (i == 2)
  214.                         break;
  215.         }
  216.  
  217.         if (pNodeCache)
  218.                 *(SAABBTreeNode**)pNodeCache = pNode;
  219.         return pNode;
  220. }
  221.  
  222. bool SAABBTreeNode::IntersectsVisAreas(const AABB& box)
  223. {
  224.         if (nodeBox.IsIntersectBox(box))
  225.         {
  226.                 if (nodeAreas.Count())
  227.                 {
  228.                         // leaf
  229.                         for (int i = 0; i < nodeAreas.Count(); i++)
  230.                         {
  231.                                 if (nodeAreas[i]->m_bActive && nodeAreas[i]->m_boxArea.IsIntersectBox(box))
  232.                                         return true;
  233.                         }
  234.                 }
  235.                 else
  236.                 {
  237.                         // node
  238.                         for (int i = 0; i < 2; i++)
  239.                                 if (arrChilds[i])
  240.                                         if (arrChilds[i]->IntersectsVisAreas(box))
  241.                                                 return true;
  242.                 }
  243.         }
  244.         return false;
  245. }
  246.  
  247. int SAABBTreeNode::ClipOutsideVisAreas(Sphere& sphere, Vec3 const& vNormal)
  248. {
  249.         int nClipped = 0;
  250.  
  251.         if (sphere.radius > FLT_MAX * 0.01f || Overlap::Sphere_AABB(sphere, nodeBox))
  252.         {
  253.                 if (nodeAreas.Count())
  254.                 {
  255.                         // leaf
  256.                         for (int i = 0; i < nodeAreas.Count(); i++)
  257.                         {
  258.                                 if (nodeAreas[i]->m_bActive && Overlap::Sphere_AABB(sphere, nodeAreas[i]->m_boxArea))
  259.                                         nClipped += nodeAreas[i]->ClipToVisArea(false, sphere, vNormal);
  260.                         }
  261.                 }
  262.                 else
  263.                 {
  264.                         // node
  265.                         for (int i = 0; i < 2; i++)
  266.                                 if (arrChilds[i])
  267.                                         nClipped += arrChilds[i]->ClipOutsideVisAreas(sphere, vNormal);
  268.                 }
  269.         }
  270.  
  271.         return nClipped;
  272. }
  273.  
  274. void CVisAreaManager::UpdateAABBTree()
  275. {
  276.         delete m_pAABBTree;
  277.         PodArray<CVisArea*> lstAreas;
  278.         lstAreas.AddList(m_lstPortals);
  279.         lstAreas.AddList(m_lstVisAreas);
  280.  
  281.         AABB nodeBox;
  282.         nodeBox.min = Vec3(1000000, 1000000, 1000000);
  283.         nodeBox.max = -nodeBox.min;
  284.         for (int i = 0; i < lstAreas.Count(); i++)
  285.                 nodeBox.Add(*lstAreas[i]->GetAABBox());
  286.  
  287.         m_pAABBTree = new SAABBTreeNode(lstAreas, nodeBox);
  288. }
  289.  
  290. bool CVisAreaManager::IsEntityVisible(IRenderNode* pEnt)
  291. {
  292.         if (GetCVars()->e_Portals == 3)
  293.                 return true;
  294.  
  295.         if (!pEnt->GetEntityVisArea())
  296.                 return IsOutdoorAreasVisible();
  297.  
  298.         return true;
  299. }
  300.  
  301. void CVisAreaManager::SetCurAreas(const SRenderingPassInfo& passInfo)
  302. {
  303.         m_pCurArea = 0;
  304.         m_pCurPortal = 0;
  305.  
  306.         if (!GetCVars()->e_Portals)
  307.                 return;
  308.  
  309.         if (!m_pAABBTree)
  310.                 UpdateAABBTree();
  311.  
  312.         CVisArea* pFound = m_pAABBTree->FindVisarea(passInfo.GetCamera().GetOccPos());
  313.  
  314. #ifdef _DEBUG
  315.  
  316.         // find camera portal id
  317.         for (int v = 0; v < m_lstPortals.Count(); v++)
  318.                 if (m_lstPortals[v]->m_bActive && m_lstPortals[v]->IsPointInsideVisArea(passInfo.GetCamera().GetOccPos()))
  319.                 {
  320.                         m_pCurPortal = m_lstPortals[v];
  321.                         break;
  322.                 }
  323.  
  324.         // if not inside any portal - try to find area
  325.         if (!m_pCurPortal)
  326.         {
  327.                 //              int nFoundAreasNum = 0;
  328.  
  329.                 // find camera area
  330.                 for (int nVolumeId = 0; nVolumeId < m_lstVisAreas.Count(); nVolumeId++)
  331.                 {
  332.                         if (m_lstVisAreas[nVolumeId]->IsPointInsideVisArea(passInfo.GetCamera().GetOccPos()))
  333.                         {
  334.                                 //                      nFoundAreasNum++;
  335.                                 m_pCurArea = m_lstVisAreas[nVolumeId];
  336.                                 break;
  337.                         }
  338.                 }
  339.  
  340.                 //              if(nFoundAreasNum>1) // if more than one area found - set cur area to undefined
  341.                 {
  342.                         // todo: try to set joining portal as current
  343.                         //      m_pCurArea = 0;
  344.                 }
  345.         }
  346.  
  347.         assert(pFound == m_pCurArea || pFound == m_pCurPortal);
  348.  
  349. #endif // _DEBUG
  350.  
  351.         if (pFound)
  352.         {
  353.                 if (pFound->IsPortal())
  354.                         m_pCurPortal = pFound;
  355.                 else
  356.                         m_pCurArea = pFound;
  357.         }
  358.  
  359.         // camera is in outdoors
  360.         m_lstActiveEntransePortals.Clear();
  361.         if (!m_pCurArea && !m_pCurPortal)
  362.                 MakeActiveEntransePortalsList(&passInfo.GetCamera(), m_lstActiveEntransePortals, 0, passInfo);
  363.  
  364.         /*
  365.            if(m_pCurArea)
  366.            {
  367.             IVisArea * arrAreas[8];
  368.             int nres = m_pCurArea->GetVisAreaConnections(arrAreas, 8);
  369.             nres=nres;
  370.            }
  371.            DefineTrees();*/
  372.  
  373.         /*      if(GetCVars()->e_Portals == 4)
  374.            {
  375.             if(m_pCurPortal)
  376.             {
  377.               IVisArea * arrAreas[64];
  378.               int nConnections = m_pCurPortal->GetVisAreaConnections(arrAreas,64);
  379.               PrintMessage("CurPortal = %s, nConnections = %d", m_pCurPortal->m_sName, nConnections);
  380.             }
  381.  
  382.             if(m_pCurArea)
  383.             {
  384.               IVisArea * arrAreas[64];
  385.               int nConnections = m_pCurArea->GetVisAreaConnections(arrAreas,64);
  386.               PrintMessage("CurArea = %s, nRes = %d", m_pCurArea->m_sName, nConnections);
  387.             }
  388.            }*/
  389. }
  390.  
  391. bool CVisAreaManager::IsSkyVisible()
  392. {
  393.         return m_bSkyVisible;
  394. }
  395.  
  396. bool CVisAreaManager::IsOceanVisible()
  397. {
  398.         return m_bOceanVisible;
  399. }
  400.  
  401. bool CVisAreaManager::IsOutdoorAreasVisible()
  402. {
  403.         if (!m_pCurArea && !m_pCurPortal)
  404.         {
  405.                 m_bOutdoorVisible = true;
  406.                 return m_bOutdoorVisible; // camera not in the areas
  407.         }
  408.  
  409.         if (m_pCurPortal && m_pCurPortal->m_lstConnections.Count() == 1)
  410.         {
  411.                 m_bOutdoorVisible = true;
  412.                 return m_bOutdoorVisible; // camera is in exit portal
  413.         }
  414.  
  415.         if (m_bOutdoorVisible)
  416.                 return true; // exit is visible
  417.  
  418.         // note: outdoor camera is no modified in this case
  419.         return false;
  420. }
  421.  
  422. /*void CVisAreaManager::SetAreaFogVolume(CTerrain * pTerrain, CVisArea * pVisArea)
  423.    {
  424.    pVisArea->m_pFogVolume=0;
  425.    for(int f=0; f<Get3DEngine()->GetFogVolumes().Count(); f++)
  426.    {
  427.     const Vec3 & v1Min = Get3DEngine()->GetFogVolumes()[f].box.min;
  428.     const Vec3 & v1Max = Get3DEngine()->GetFogVolumes()[f].box.max;
  429.     const Vec3 & v2Min = pVisArea->m_boxArea.min;
  430.     const Vec3 & v2Max = pVisArea->m_boxArea.max;
  431.  
  432.     if(v1Max.x>v2Min.x && v2Max.x>v1Min.x)
  433.     if(v1Max.y>v2Min.y && v2Max.y>v1Min.y)
  434.     if(v1Max.z>v2Min.z && v2Max.z>v1Min.z)
  435.     if(!Get3DEngine()->GetFogVolumes()[f].bOcean)
  436.     {
  437.       Vec3 arrVerts3d[8] =
  438.       {
  439.         Vec3(v1Min.x,v1Min.y,v1Min.z),
  440.         Vec3(v1Min.x,v1Max.y,v1Min.z),
  441.         Vec3(v1Max.x,v1Min.y,v1Min.z),
  442.         Vec3(v1Max.x,v1Max.y,v1Min.z),
  443.         Vec3(v1Min.x,v1Min.y,v1Max.z),
  444.         Vec3(v1Min.x,v1Max.y,v1Max.z),
  445.         Vec3(v1Max.x,v1Min.y,v1Max.z),
  446.         Vec3(v1Max.x,v1Max.y,v1Max.z)
  447.       };
  448.  
  449.       bool bIntersect = false;
  450.       for(int i=0; i<8; i++)
  451.         if(pVisArea->IsPointInsideVisArea(arrVerts3d[i]))
  452.         {
  453.           bIntersect = true;
  454.           break;
  455.         }
  456.  
  457.       if(!bIntersect)
  458.         if(pVisArea->IsPointInsideVisArea((v1Min+v1Max)*0.5f))
  459.           bIntersect = true;
  460.  
  461.       if(!bIntersect)
  462.       {
  463.         for(int i=0; i<pVisArea->m_lstShapePoints.Count(); i++)
  464.           if(Get3DEngine()->GetFogVolumes()[f].IsInsideBBox(pVisArea->m_lstShapePoints[i]))
  465.           {
  466.             bIntersect = true;
  467.             break;
  468.           }
  469.       }
  470.  
  471.       if(!bIntersect)
  472.       {
  473.         Vec3 vCenter = (pVisArea->m_boxArea.min+pVisArea->m_boxArea.max)*0.5f;
  474.         if(Get3DEngine()->GetFogVolumes()[f].IsInsideBBox(vCenter))
  475.           bIntersect = true;
  476.       }
  477.  
  478.       if(bIntersect)
  479.       {
  480.         pVisArea->m_pFogVolume = &Get3DEngine()->GetFogVolumes()[f];
  481.         Get3DEngine()->GetFogVolumes()[f].bIndoorOnly = true;
  482.         pTerrain->UnregisterFogVolumeFromOutdoor(&Get3DEngine()->GetFogVolumes()[f]);
  483.         break;
  484.       }
  485.     }
  486.    }
  487.    }*/
  488.  
  489. void CVisAreaManager::PortalsDrawDebug()
  490. {
  491.         UpdateConnections();
  492.         /*
  493.            if(m_pCurArea)
  494.            {
  495.             for(int p=0; p<m_pCurArea->m_lstConnections.Count(); p++)
  496.             {
  497.               CVisArea * pPortal = m_pCurArea->m_lstConnections[p];
  498.               float fBlink = gEnv->pTimer->GetFrameStartTime().GetPeriodicFraction(1.0f)>0.5f ? 1.0f : 0.0f;
  499.               float fError = pPortal->IsPortalValid() ? 1.0f : fBlink;
  500.               GetRenderer()->SetMaterialColor(fError,fError*(pPortal->m_lstConnections.Count()<2),0,0.25f);
  501.               DrawBBox(pPortal->m_boxArea.min, pPortal->m_boxArea.max, DPRIM_SOLID_BOX);
  502.               GetRenderer()->DrawLabel((pPortal->m_boxArea.min+ pPortal->m_boxArea.max)*0.5f,
  503.                 2,pPortal->m_sName);
  504.             }
  505.            }
  506.            else*/
  507.         {
  508.                 // debug draw areas
  509.                 GetRenderer()->SetMaterialColor(0, 1, 0, 0.25f);
  510.                 Vec3 oneVec(1, 1, 1);
  511.                 for (int v = 0; v < m_lstVisAreas.Count(); v++)
  512.                 {
  513.                         DrawBBox(m_lstVisAreas[v]->m_boxArea.min, m_lstVisAreas[v]->m_boxArea.max); //, DPRIM_SOLID_BOX);
  514.                         IRenderAuxText::DrawLabelEx((m_lstVisAreas[v]->m_boxArea.min + m_lstVisAreas[v]->m_boxArea.max) * 0.5f, 1, (float*)&oneVec, 0, 1, m_lstVisAreas[v]->GetName());
  515.  
  516.                         GetRenderer()->SetMaterialColor(0, 1, 0, 0.25f);
  517.                         DrawBBox(m_lstVisAreas[v]->m_boxStatics, Col_LightGray);
  518.                 }
  519.  
  520.                 // debug draw portals
  521.                 for (int v = 0; v < m_lstPortals.Count(); v++)
  522.                 {
  523.                         CVisArea* pPortal = m_lstPortals[v];
  524.  
  525.                         float fBlink = gEnv->pTimer->GetFrameStartTime().GetPeriodicFraction(1.0f) > 0.5f ? 1.0f : 0.0f;
  526.                         float fError = pPortal->IsPortalValid() ? 1.f : fBlink;
  527.  
  528.                         ColorB col(
  529.                           (int)clamp_tpl(fError * 255.0f, 0.0f, 255.0f),
  530.                           (int)clamp_tpl(fError * (pPortal->m_lstConnections.Count() < 2) * 255.0f, 0.0f, 255.0f),
  531.                           0,
  532.                           64);
  533.                         DrawBBox(pPortal->m_boxArea.min, pPortal->m_boxArea.max, col);
  534.  
  535.                         IRenderAuxText::DrawLabelEx((pPortal->m_boxArea.min + pPortal->m_boxArea.max) * 0.5f, 1, (float*)&oneVec, 0, 1, pPortal->GetName());
  536.  
  537.                         Vec3 vCenter = (pPortal->m_boxArea.min + pPortal->m_boxArea.max) * 0.5f;
  538.                         DrawBBox(vCenter - Vec3(0.1f, 0.1f, 0.1f), vCenter + Vec3(0.1f, 0.1f, 0.1f));
  539.  
  540.                         int nConnections = pPortal->m_lstConnections.Count();
  541.                         if (nConnections == 1)
  542.                                 col = ColorB(0, 255, 0, 64);
  543.                         else
  544.                                 col = ColorB(0, 0, 255, 64);
  545.  
  546.                         for (int i = 0; i < nConnections && i < 2; i++)
  547.                                 DrawLine(vCenter, vCenter + pPortal->m_vConnNormals[i], col);
  548.  
  549.                         DrawBBox(pPortal->m_boxStatics.min, pPortal->m_boxStatics.max, col);
  550.                 }
  551.  
  552.                 /*
  553.                     // debug draw area shape
  554.                     GetRenderer()->SetMaterialColor(0,0,1,0.25f);
  555.                     for(int v=0; v<m_lstVisAreas.Count(); v++)
  556.                     for(int p=0; p<m_lstVisAreas[v]->m_lstShapePoints.Count(); p++)
  557.                       GetRenderer()->DrawLabel(m_lstVisAreas[v]->m_lstShapePoints[p], 2,"%d", p);
  558.                     for(int v=0; v<m_lstPortals.Count(); v++)
  559.                     for(int p=0; p<m_lstPortals[v]->m_lstShapePoints.Count(); p++)
  560.                       GetRenderer()->DrawLabel(m_lstPortals[v]->m_lstShapePoints[p], 2,"%d", p);*/
  561.         }
  562. }
  563.  
  564. void CVisAreaManager::DrawVisibleSectors(const SRenderingPassInfo& passInfo)
  565. {
  566.         FUNCTION_PROFILER_3DENGINE;
  567.  
  568.         for (int i = 0; i < m_lstVisibleAreas.Count(); i++)
  569.         {
  570.                 CVisArea* pArea = m_lstVisibleAreas[i];
  571.                 Vec3 vAmbColor = pArea->GetFinalAmbientColor();
  572.                 if (pArea->m_pObjectsTree)
  573.                         for (int c = 0; c < pArea->m_lstCurCamerasLen; c++)
  574.                         {
  575.                                 passInfo.GetRendItemSorter().IncreaseOctreeCounter();
  576.                                 // create a new RenderingPassInfo object, which a camera matching the visarea
  577.                                 pArea->m_pObjectsTree->Render_Object_Nodes(false, OCTREENODE_RENDER_FLAG_OBJECTS, vAmbColor, SRenderingPassInfo::CreateTempRenderingInfo(CVisArea::s_tmpCameras[pArea->m_lstCurCamerasIdx + c], passInfo));
  578.                         }
  579.         }
  580.  
  581.         passInfo.GetRendItemSorter().IncreaseGroupCounter();
  582. }
  583.  
  584. void CVisAreaManager::PhysicalizeInBox(const AABB& bbox)
  585. {
  586.         for (int i = 0; i < m_lstVisAreas.Count(); i++)
  587.         {
  588.                 CVisArea* pArea = m_lstVisAreas[i];
  589.                 if (pArea && pArea->m_pObjectsTree && Overlap::AABB_AABB(*pArea->GetAABBox(), bbox))
  590.                 {
  591.                         pArea->m_pObjectsTree->PhysicalizeInBox(bbox);
  592.                 }
  593.         }
  594.         for (int i = 0; i < m_lstPortals.Count(); i++)
  595.         {
  596.                 CVisArea* pArea = m_lstPortals[i];
  597.                 if (pArea && pArea->m_pObjectsTree && Overlap::AABB_AABB(*pArea->GetAABBox(), bbox))
  598.                 {
  599.                         pArea->m_pObjectsTree->PhysicalizeInBox(bbox);
  600.                 }
  601.         }
  602. }
  603. void CVisAreaManager::DephysicalizeInBox(const AABB& bbox)
  604. {
  605.         for (int i = 0; i < m_lstVisAreas.Count(); i++)
  606.         {
  607.                 CVisArea* pArea = m_lstVisAreas[i];
  608.                 if (pArea && pArea->m_pObjectsTree && Overlap::AABB_AABB(*pArea->GetAABBox(), bbox))
  609.                 {
  610.                         pArea->m_pObjectsTree->DephysicalizeInBox(bbox);
  611.                 }
  612.         }
  613.         for (int i = 0; i < m_lstPortals.Count(); i++)
  614.         {
  615.                 CVisArea* pArea = m_lstPortals[i];
  616.                 if (pArea && pArea->m_pObjectsTree && Overlap::AABB_AABB(*pArea->GetAABBox(), bbox))
  617.                 {
  618.                         pArea->m_pObjectsTree->DephysicalizeInBox(bbox);
  619.                 }
  620.         }
  621. }
  622.  
  623. void CVisAreaManager::CheckVis(const SRenderingPassInfo& passInfo)
  624. {
  625.         FUNCTION_PROFILER_3DENGINE;
  626.  
  627.         if (passInfo.IsGeneralPass())
  628.         {
  629.                 m_bOutdoorVisible = false;
  630.                 m_bSkyVisible = false;
  631.                 m_bOceanVisible = false;
  632.                 CVisArea::s_tmpCameras.Clear();
  633.         }
  634.  
  635.         m_lstOutdoorPortalCameras.Clear();
  636.         m_lstVisibleAreas.Clear();
  637.         m_bSunIsNeeded = false;
  638.  
  639.         SetCurAreas(passInfo);
  640.  
  641.         CCamera camRoot = passInfo.GetCamera();
  642.         camRoot.m_ScissorInfo.x1 = 0;
  643.         camRoot.m_ScissorInfo.y1 = 0;
  644.         camRoot.m_ScissorInfo.x2 = GetRenderer()->GetWidth(); // todo: use values from camera
  645.         camRoot.m_ScissorInfo.y2 = GetRenderer()->GetHeight();
  646.  
  647.         if (GetCVars()->e_Portals == 3)
  648.         {
  649.                 // draw everything for debug
  650.                 for (int i = 0; i < m_lstVisAreas.Count(); i++)
  651.                         if (camRoot.IsAABBVisible_F(AABB(m_lstVisAreas[i]->m_boxArea.min, m_lstVisAreas[i]->m_boxArea.max)))
  652.                                 m_lstVisAreas[i]->PreRender(0, camRoot, 0, m_pCurPortal, &m_bOutdoorVisible, &m_lstOutdoorPortalCameras, &m_bSkyVisible, &m_bOceanVisible, m_lstVisibleAreas, passInfo);
  653.  
  654.                 for (int i = 0; i < m_lstPortals.Count(); i++)
  655.                         if (camRoot.IsAABBVisible_F(AABB(m_lstPortals[i]->m_boxArea.min, m_lstPortals[i]->m_boxArea.max)))
  656.                                 m_lstPortals[i]->PreRender(0, camRoot, 0, m_pCurPortal, &m_bOutdoorVisible, &m_lstOutdoorPortalCameras, &m_bSkyVisible, &m_bOceanVisible, m_lstVisibleAreas, passInfo);
  657.         }
  658.         else
  659.         {
  660.                 if (passInfo.IsRecursivePass())
  661.                 {
  662.                         // use another starting point for reflections
  663.                         CVisArea* pVisArea = (CVisArea*)GetVisAreaFromPos(camRoot.GetOccPos());
  664.                         if (pVisArea)
  665.                                 pVisArea->PreRender(3, camRoot, 0, m_pCurPortal, &m_bOutdoorVisible, &m_lstOutdoorPortalCameras, &m_bSkyVisible, &m_bOceanVisible, m_lstVisibleAreas, passInfo);
  666.                 }
  667.                 else if (m_pCurArea)
  668.                 {
  669.                         // camera inside some sector
  670.                         m_pCurArea->PreRender(GetCVars()->e_PortalsMaxRecursion, camRoot, 0, m_pCurPortal, &m_bOutdoorVisible, &m_lstOutdoorPortalCameras, &m_bSkyVisible, &m_bOceanVisible, m_lstVisibleAreas, passInfo);
  671.  
  672.                         for (int ii = 0; ii < m_lstOutdoorPortalCameras.Count(); ii++) // process all exit portals
  673.                         {
  674.                                 // for each portal build list of potentially visible entrances into other areas
  675.                                 MakeActiveEntransePortalsList(&m_lstOutdoorPortalCameras[ii], m_lstActiveEntransePortals, (CVisArea*)m_lstOutdoorPortalCameras[ii].m_pPortal, passInfo);
  676.                                 for (int i = 0; i < m_lstActiveEntransePortals.Count(); i++) // entrance into another building is visible
  677.                                         m_lstActiveEntransePortals[i]->PreRender(i == 0 ? 5 : 1,
  678.                                                                                  m_lstOutdoorPortalCameras[ii], 0, m_pCurPortal, 0, 0, 0, 0, m_lstVisibleAreas, passInfo);
  679.                         }
  680.  
  681.                         // reset scissor if skybox is visible also thru skyboxonly portal
  682.                         if (m_bSkyVisible && m_lstOutdoorPortalCameras.Count() == 1)
  683.                                 m_lstOutdoorPortalCameras[0].m_ScissorInfo.x1 =
  684.                                   m_lstOutdoorPortalCameras[0].m_ScissorInfo.x2 =
  685.                                     m_lstOutdoorPortalCameras[0].m_ScissorInfo.y1 =
  686.                                       m_lstOutdoorPortalCameras[0].m_ScissorInfo.y2 = 0;
  687.                 }
  688.                 else if (m_pCurPortal)
  689.                 {
  690.                         // camera inside some portal
  691.                         m_pCurPortal->PreRender(GetCVars()->e_PortalsMaxRecursion - 1, camRoot, 0, m_pCurPortal, &m_bOutdoorVisible, &m_lstOutdoorPortalCameras, &m_bSkyVisible, &m_bOceanVisible, m_lstVisibleAreas, passInfo);
  692.  
  693.                         if (m_pCurPortal->m_lstConnections.Count() == 1)
  694.                                 m_lstOutdoorPortalCameras.Clear(); // camera in outdoor
  695.  
  696.                         if (m_pCurPortal->m_lstConnections.Count() == 1 || m_lstOutdoorPortalCameras.Count())
  697.                         {
  698.                                 // if camera is in exit portal or exit is visible
  699.                                 MakeActiveEntransePortalsList(m_lstOutdoorPortalCameras.Count() ? &m_lstOutdoorPortalCameras[0] : &camRoot,
  700.                                                               m_lstActiveEntransePortals,
  701.                                                               m_lstOutdoorPortalCameras.Count() ? (CVisArea*)m_lstOutdoorPortalCameras[0].m_pPortal : m_pCurPortal, passInfo);
  702.                                 for (int i = 0; i < m_lstActiveEntransePortals.Count(); i++) // entrance into another building is visible
  703.                                         m_lstActiveEntransePortals[i]->PreRender(i == 0 ? 5 : 1,
  704.                                                                                  m_lstOutdoorPortalCameras.Count() ? m_lstOutdoorPortalCameras[0] : camRoot, 0, m_pCurPortal, 0, 0, 0, 0, m_lstVisibleAreas, passInfo);
  705.                                 //                              m_lstOutdoorPortalCameras.Clear();  // otherwise ocean in fleet was not scissored
  706.                         }
  707.                 }
  708.                 else if (m_lstActiveEntransePortals.Count())
  709.                 {
  710.                         // camera in outdoors - process visible entrance portals
  711.                         for (int i = 0; i < m_lstActiveEntransePortals.Count(); i++)
  712.                                 m_lstActiveEntransePortals[i]->PreRender(5, camRoot, 0, m_lstActiveEntransePortals[i], &m_bOutdoorVisible, &m_lstOutdoorPortalCameras, &m_bSkyVisible, &m_bOceanVisible, m_lstVisibleAreas, passInfo);
  713.                         m_lstActiveEntransePortals.Clear();
  714.  
  715.                         // do not recurse to another building since we already processed all potential entrances
  716.                         m_lstOutdoorPortalCameras.Clear(); // use default camera
  717.                         m_bOutdoorVisible = true;
  718.                 }
  719.         }
  720.  
  721.         if (GetCVars()->e_Portals == 2)
  722.                 PortalsDrawDebug();
  723. }
  724.  
  725. void CVisAreaManager::ActivatePortal(const Vec3& vPos, bool bActivate, const char* szEntityName)
  726. {
  727.         //  bool bFound = false;
  728.  
  729.         for (int v = 0; v < m_lstPortals.Count(); v++)
  730.         {
  731.                 AABB aabb;
  732.                 aabb.min = m_lstPortals[v]->m_boxArea.min - Vec3(0.5f, 0.5f, 0.1f);
  733.                 aabb.max = m_lstPortals[v]->m_boxArea.max + Vec3(0.5f, 0.5f, 0.0f);
  734.  
  735.                 if (Overlap::Point_AABB(vPos, aabb))
  736.                 {
  737.                         m_lstPortals[v]->m_bActive = bActivate;
  738.  
  739.                         // switch to PrintComment once portals activation is working stable
  740.                         PrintMessage("I3DEngine::ActivatePortal(): Portal %s is %s by entity %s at position(%.1f,%.1f,%.1f)",
  741.                                      m_lstPortals[v]->GetName(), bActivate ? "Enabled" : "Disabled", szEntityName, vPos.x, vPos.y, vPos.z);
  742.  
  743.                         //      bFound = true;
  744.                 }
  745.         }
  746.  
  747.         /*
  748.            if(!bFound)
  749.            {
  750.            PrintComment("I3DEngine::ActivatePortal(): Portal not found for entity %s at position(%.1f,%.1f,%.1f)",
  751.             szEntityName, vPos.x, vPos.y, vPos.z);
  752.            }
  753.          */
  754. }
  755. /*
  756.    bool CVisAreaManager::IsEntityInVisibleArea(IRenderNodeState * pRS)
  757.    {
  758.    if( pRS && pRS->plstVisAreaId && pRS->plstVisAreaId->Count() )
  759.    {
  760.     PodArray<int> * pVisAreas = pRS->plstVisAreaId;
  761.     for(int n=0; n<pVisAreas->Count(); n++)
  762.       if( m_lstVisAreas[pVisAreas->GetAt(n)].m_nVisFrameId==passInfo.GetFrameID() )
  763.         break;
  764.  
  765.     if(n==pVisAreas->Count())
  766.       return false; // no visible areas
  767.    }
  768.    else
  769.     return false; // entity is not inside
  770.  
  771.    return true;
  772.    }    */
  773.  
  774. bool CVisAreaManager::IsValidVisAreaPointer(CVisArea* pVisArea)
  775. {
  776.         if (m_lstVisAreas.Find(pVisArea) < 0 &&
  777.             m_lstPortals.Find(pVisArea) < 0 &&
  778.             m_lstOcclAreas.Find(pVisArea) < 0)
  779.                 return false;
  780.  
  781.         return true;
  782. }
  783.  
  784. //This is only called from the editor, so pVisArea will not be pool allocated by type
  785. bool CVisAreaManager::DeleteVisArea(CVisArea* pVisArea)
  786. {
  787.         bool bFound = false;
  788.         if (m_lstVisAreas.Delete(pVisArea) || m_lstPortals.Delete(pVisArea) || m_lstOcclAreas.Delete(pVisArea))
  789.         {
  790.                 delete pVisArea;
  791.                 bFound = true;
  792.         }
  793.  
  794.         m_lstActiveOcclVolumes.Delete(pVisArea);
  795.         m_lstIndoorActiveOcclVolumes.Delete(pVisArea);
  796.         m_lstActiveEntransePortals.Delete(pVisArea);
  797.  
  798.         m_pCurArea = 0;
  799.         m_pCurPortal = 0;
  800.         UpdateConnections();
  801.  
  802.         delete m_pAABBTree;
  803.         m_pAABBTree = NULL;
  804.  
  805.         return bFound;
  806. }
  807.  
  808. /*void CVisAreaManager::LoadVisAreaShapeFromXML(XmlNodeRef pDoc)
  809.    {
  810.    for(int i=0; i<m_lstVisAreas.Count(); i++)
  811.    {
  812.     delete m_lstVisAreas[i];
  813.     m_lstVisAreas.Delete(i);
  814.     i--;
  815.    }
  816.  
  817.    for(int i=0; i<m_lstPortals.Count(); i++)
  818.    {
  819.     delete m_lstPortals[i];
  820.     m_lstPortals.Delete(i);
  821.     i--;
  822.    }
  823.  
  824.    // fill list of volumes of shape points
  825.    XmlNodeRef pObjectsNode = pDoc->findChild("Objects");
  826.    if (pObjectsNode)
  827.    {
  828.     for (int i = 0; i < pObjectsNode->getChildCount(); i++)
  829.     {
  830.       XmlNodeRef pNode = pObjectsNode->getChild(i);
  831.       if (pNode->isTag("Object"))
  832.       {
  833.         const char * pType = pNode->getAttr("Type");
  834.         if (strstr(pType,"OccluderArea") || strstr(pType,"VisArea") || strstr(pType,"Portal"))
  835.         {
  836.           CVisArea * pArea = new CVisArea();
  837.  
  838.           pArea->m_boxArea.max=SetMinBB();
  839.           pArea->m_boxArea.min=SetMaxBB();
  840.  
  841.           // set name
  842.           strcpy(pArea->m_sName, pNode->getAttr("Name"));
  843.           strlwr(pArea->m_sName);
  844.  
  845.           // set height
  846.           pNode->getAttr("Height",pArea->m_fHeight);
  847.  
  848.           // set ambient color
  849.           pNode->getAttr("AmbientColor", pArea->m_vAmbColor);
  850.  
  851.           // set dynamic ambient color
  852.    //                                   pNode->getAttr("DynAmbientColor", pArea->m_vDynAmbColor);
  853.  
  854.           // set SkyOnly flag
  855.           pNode->getAttr("SkyOnly", pArea->m_bSkyOnly);
  856.  
  857.           // set AfectedByOutLights flag
  858.           pNode->getAttr("AffectedBySun", pArea->m_bAfectedByOutLights);
  859.  
  860.           // set ViewDistRatio
  861.           pNode->getAttr("ViewDistRatio", pArea->m_fViewDistRatio);
  862.  
  863.           // set DoubleSide flag
  864.           pNode->getAttr("DoubleSide", pArea->m_bDoubleSide);
  865.  
  866.           // set UseInIndoors flag
  867.           pNode->getAttr("UseInIndoors", pArea->m_bUseInIndoors);
  868.  
  869.           if(strstr(pType, "OccluderArea"))
  870.             m_lstOcclAreas.Add(pArea);
  871.           else if(strstr(pArea->m_sName,"portal") || strstr(pType,"Portal"))
  872.             m_lstPortals.Add(pArea);
  873.           else
  874.             m_lstVisAreas.Add(pArea);
  875.  
  876.           // load vertices
  877.           XmlNodeRef pPointsNode = pNode->findChild("Points");
  878.           if (pPointsNode)
  879.           for (int i = 0; i < pPointsNode->getChildCount(); i++)
  880.           {
  881.             XmlNodeRef pPointNode = pPointsNode->getChild(i);
  882.  
  883.             Vec3 vPos;
  884.             if (pPointNode->isTag("Point") && pPointNode->getAttr("Pos", vPos))
  885.             {
  886.               pArea->m_lstShapePoints.Add(vPos);
  887.               pArea->m_boxArea.max.CheckMax(vPos);
  888.               pArea->m_boxArea.min.CheckMin(vPos);
  889.               pArea->m_boxArea.max.CheckMax(vPos+Vec3(0,0,pArea->m_fHeight));
  890.               pArea->m_boxArea.min.CheckMin(vPos+Vec3(0,0,pArea->m_fHeight));
  891.             }
  892.           }
  893.           pArea->UpdateGeometryBBox();
  894.         }
  895.       }
  896.     }
  897.    }
  898.  
  899.    // load area boxes to support old way
  900.    //   LoadVisAreaBoxFromXML(pDoc);
  901.    }*/
  902.  
  903. //THIS SHOULD ONLY BE CALLED BY THE EDITOR
  904. void CVisAreaManager::UpdateVisArea(CVisArea* pArea, const Vec3* pPoints, int nCount, const char* szName, const SVisAreaInfo& info)
  905. {
  906.         // on first update there will be nothing to delete, area will be added into list only in this function
  907.         m_lstPortals.Delete(pArea);
  908.         m_lstVisAreas.Delete(pArea);
  909.         m_lstOcclAreas.Delete(pArea);
  910.  
  911.         SGenericColdData* pColdData = pArea->GetColdData();
  912.         if (pColdData != NULL)
  913.         {
  914.                 delete pArea->GetColdData();
  915.                 pArea->SetColdDataPtr(NULL);
  916.         }
  917.  
  918.         SGenericColdData* pColdDataPtr = NULL;
  919.  
  920.         char sTemp[64];
  921.         cry_strcpy(sTemp, szName);
  922.         _strlwr_s(sTemp, sizeof(sTemp));
  923.         strlwr(sTemp);
  924.  
  925.         bool bPortal = false;
  926.         bool bVisArea = false;
  927.         bool bOcclArea = false;
  928.  
  929.         //TODO: Refactor with code below so it's not horrible
  930.         if (strstr(sTemp, "portal"))
  931.         {
  932.                 pColdDataPtr = new SPortalColdData();
  933.                 bPortal = true;
  934.         }
  935.         else if (strstr(sTemp, "visarea"))
  936.         {
  937.                 pColdDataPtr = new SGenericColdData();
  938.                 bVisArea = true;
  939.         }
  940.         else if (strstr(sTemp, "occlarea"))
  941.         {
  942.                 pColdDataPtr = new SGenericColdData();
  943.                 bOcclArea = true;
  944.         }
  945.         else
  946.         {
  947.                 pColdDataPtr = new SGenericColdData();
  948.         }
  949.  
  950.         assert(pColdDataPtr);
  951.         pArea->SetColdDataPtr(pColdDataPtr);
  952.  
  953.         pArea->Update(pPoints, nCount, sTemp, info);
  954.  
  955.         if (bPortal)
  956.         {
  957.                 if (pArea->m_lstConnections.Count() == 1)
  958.                         pArea->UpdateGeometryBBox();
  959.  
  960.                 m_lstPortals.Add(pArea);
  961.         }
  962.         else if (bVisArea)
  963.         {
  964.                 m_lstVisAreas.Add(pArea);
  965.         }
  966.         else if (bOcclArea)
  967.         {
  968.                 m_lstOcclAreas.Add(pArea);
  969.         }
  970.  
  971.         UpdateConnections();
  972.  
  973.         // disable terrain culling for tunnels
  974.         pArea->UpdateOcclusionFlagInTerrain();
  975.  
  976.         delete m_pAABBTree;
  977.         m_pAABBTree = NULL;
  978. }
  979.  
  980. void CVisAreaManager::UpdateConnections()
  981. {
  982.         // Reset connectivity
  983.         for (int p = 0; p < m_lstPortals.Count(); p++)
  984.                 m_lstPortals[p]->m_lstConnections.Clear();
  985.  
  986.         for (int v = 0; v < m_lstVisAreas.Count(); v++)
  987.                 m_lstVisAreas[v]->m_lstConnections.Clear();
  988.  
  989.         // Init connectivity - check intersection of all areas and portals
  990.         for (int p = 0; p < m_lstPortals.Count(); p++)
  991.         {
  992.                 for (int v = 0; v < m_lstVisAreas.Count(); v++)
  993.                 {
  994.                         if (m_lstVisAreas[v]->IsPortalIntersectAreaInValidWay(m_lstPortals[p]))
  995.                         {
  996.                                 // if bboxes intersect
  997.                                 m_lstVisAreas[v]->m_lstConnections.Add(m_lstPortals[p]);
  998.                                 m_lstPortals[p]->m_lstConnections.Add(m_lstVisAreas[v]);
  999.  
  1000.                                 // set portal direction
  1001.                                 Vec3 vNormal = m_lstVisAreas[v]->GetConnectionNormal(m_lstPortals[p]);
  1002.                                 if (m_lstPortals[p]->m_lstConnections.Count() <= 2)
  1003.                                         m_lstPortals[p]->m_vConnNormals[m_lstPortals[p]->m_lstConnections.Count() - 1] = vNormal;
  1004.                         }
  1005.                 }
  1006.         }
  1007. }
  1008.  
  1009. void CVisAreaManager::MoveObjectsIntoList(PodArray<SRNInfo>* plstVisAreasEntities, const AABB& boxArea, bool bRemoveObjects)
  1010. {
  1011.         for (int p = 0; p < m_lstPortals.Count(); p++)
  1012.         {
  1013.                 if (m_lstPortals[p]->m_pObjectsTree && Overlap::AABB_AABB(m_lstPortals[p]->m_boxArea, boxArea))
  1014.                         m_lstPortals[p]->m_pObjectsTree->MoveObjectsIntoList(plstVisAreasEntities, bRemoveObjects ? NULL : &boxArea, bRemoveObjects);
  1015.         }
  1016.  
  1017.         for (int v = 0; v < m_lstVisAreas.Count(); v++)
  1018.         {
  1019.                 if (m_lstVisAreas[v]->m_pObjectsTree && Overlap::AABB_AABB(m_lstVisAreas[v]->m_boxArea, boxArea))
  1020.                         m_lstVisAreas[v]->m_pObjectsTree->MoveObjectsIntoList(plstVisAreasEntities, bRemoveObjects ? NULL : &boxArea, bRemoveObjects);
  1021.         }
  1022. }
  1023.  
  1024. bool CVisAreaManager::IntersectsVisAreas(const AABB& box, void** pNodeCache)
  1025. {
  1026.         FUNCTION_PROFILER_3DENGINE;
  1027.  
  1028.         if (!m_pAABBTree)
  1029.                 UpdateAABBTree();
  1030.         SAABBTreeNode* pTopNode = m_pAABBTree->GetTopNode(box, pNodeCache);
  1031.         return pTopNode->IntersectsVisAreas(box);
  1032. }
  1033.  
  1034. bool CVisAreaManager::ClipOutsideVisAreas(Sphere& sphere, Vec3 const& vNormal, void* pNodeCache)
  1035. {
  1036.         FUNCTION_PROFILER_3DENGINE;
  1037.  
  1038.         if (!m_pAABBTree)
  1039.                 UpdateAABBTree();
  1040.         AABB box(sphere.center - Vec3(sphere.radius), sphere.center + Vec3(sphere.radius));
  1041.         SAABBTreeNode* pTopNode = m_pAABBTree->GetTopNode(box, &pNodeCache);
  1042.         return pTopNode->ClipOutsideVisAreas(sphere, vNormal) > 0;
  1043. }
  1044.  
  1045. //This is used by the editor. Use the visareas pool for all areas, so prefetching
  1046. //      is still safe.
  1047. CVisArea* CVisAreaManager::CreateVisArea(VisAreaGUID visGUID)
  1048. {
  1049.         return new CVisArea(visGUID);
  1050. }
  1051.  
  1052. bool CVisAreaManager::IsEntityVisAreaVisibleReqursive(CVisArea* pVisArea, int nMaxReqursion, PodArray<CVisArea*>* pUnavailableAreas, const CDLight* pLight, const SRenderingPassInfo& passInfo)
  1053. {
  1054.         int nAreaId = pUnavailableAreas->Count();
  1055.         pUnavailableAreas->Add(pVisArea);
  1056.  
  1057.         bool bFound = false;
  1058.         if (pVisArea)
  1059.         {
  1060.                 // check is lsource area was rendered in prev frame
  1061.                 if (abs(pVisArea->m_nRndFrameId - passInfo.GetFrameID()) > 2)
  1062.                 {
  1063.                         if (nMaxReqursion > 1)
  1064.                                 for (int n = 0; n < pVisArea->m_lstConnections.Count(); n++)
  1065.                                 {
  1066.                                         // loop other sectors
  1067.                                         CVisArea* pNeibArea = (CVisArea*)pVisArea->m_lstConnections[n];
  1068.                                         if (-1 == pUnavailableAreas->Find(pNeibArea) &&
  1069.                                             (!pLight || Overlap::Sphere_AABB(Sphere(pLight->m_Origin, pLight->m_fRadius), *pNeibArea->GetAABBox())))
  1070.                                                 if (IsEntityVisAreaVisibleReqursive(pNeibArea, nMaxReqursion - 1, pUnavailableAreas, pLight, passInfo))
  1071.                                                 {
  1072.                                                         bFound = true;
  1073.                                                         break;
  1074.                                                 } //if visible
  1075.                                 }     // for
  1076.                 }
  1077.                 else
  1078.                         bFound = true;
  1079.         }
  1080.         else if (IsOutdoorAreasVisible())                  //Indirect - outdoor can be a problem!
  1081.                 bFound = true;
  1082.  
  1083.         pUnavailableAreas->Delete(nAreaId);
  1084.         return bFound;
  1085. }
  1086.  
  1087. bool CVisAreaManager::IsEntityVisAreaVisible(IRenderNode* pEnt, int nMaxReqursion, const CDLight* pLight, const SRenderingPassInfo& passInfo)
  1088. {
  1089.         if (!pEnt)
  1090.                 return false;
  1091.  
  1092.         PodArray<CVisArea*>& lUnavailableAreas = m_tmpLstUnavailableAreas;
  1093.         lUnavailableAreas.Clear();
  1094.  
  1095.         lUnavailableAreas.PreAllocate(nMaxReqursion, 0);
  1096.  
  1097.         return IsEntityVisAreaVisibleReqursive((CVisArea*)pEnt->GetEntityVisArea(), nMaxReqursion, &lUnavailableAreas, pLight, passInfo);
  1098.         /*
  1099.            if(pEnt->GetEntityVisArea())
  1100.            {
  1101.             if(pEnt->GetEntityVisArea())//->IsPortal())
  1102.             { // check is lsource area was rendered in prev frame
  1103.               CVisArea * pVisArea = pEnt->GetEntityVisArea();
  1104.               int nRndFrameId = passInfo.GetFrameID();
  1105.               if(abs(pVisArea->m_nRndFrameId - nRndFrameId)>2)
  1106.               {
  1107.                 if(!nCheckNeighbors)
  1108.                   return false; // this area is not visible
  1109.  
  1110.                 // try neibhour areas
  1111.                 bool bFound = false;
  1112.                 if(pEnt->GetEntityVisArea()->IsPortal())
  1113.                 {
  1114.                   CVisArea * pPort = pEnt->GetEntityVisArea();
  1115.                   for(int n=0; n<pPort->m_lstConnections.Count(); n++)
  1116.                   { // loop other sectors
  1117.                     CVisArea * pNeibArea = (CVisArea*)pPort->m_lstConnections[n];
  1118.                     if(abs(pNeibArea->m_nRndFrameId - passInfo.GetFrameID())<=2)
  1119.                     {
  1120.                       bFound=true;
  1121.                       break;
  1122.                     }
  1123.                   }
  1124.                 }
  1125.                 else
  1126.                 {
  1127.                   for(int t=0; !bFound && t<pVisArea->m_lstConnections.Count(); t++)
  1128.                   { // loop portals
  1129.                     CVisArea * pPort = (CVisArea*)pVisArea->m_lstConnections[t];
  1130.                     if(abs(pPort->m_nRndFrameId - passInfo.GetFrameID())<=2)
  1131.                     {
  1132.                       bFound=true;
  1133.                       break;
  1134.                     }
  1135.  
  1136.                     for(int n=0; n<pPort->m_lstConnections.Count(); n++)
  1137.                     { // loop other sectors
  1138.                       CVisArea * pNeibArea = (CVisArea*)pPort->m_lstConnections[n];
  1139.                       if(abs(pNeibArea->m_nRndFrameId - passInfo.GetFrameID())<=2)
  1140.                       {
  1141.                         bFound=true;
  1142.                         break;
  1143.                       }
  1144.                     }
  1145.                   }
  1146.                 }
  1147.  
  1148.                 if(!bFound)
  1149.                   return false;
  1150.  
  1151.                 return true;
  1152.               }
  1153.             }
  1154.             else
  1155.               return false; // not visible
  1156.            }
  1157.            else if(!IsOutdoorAreasVisible())
  1158.             return false;
  1159.  
  1160.            return true;
  1161.          */
  1162. }
  1163.  
  1164. int __cdecl CVisAreaManager__CmpDistToPortal(const void* v1, const void* v2)
  1165. {
  1166.         CVisArea* p1 = *((CVisArea**)v1);
  1167.         CVisArea* p2 = *((CVisArea**)v2);
  1168.  
  1169.         if (!p1 || !p2)
  1170.                 return 0;
  1171.  
  1172.         if (p1->m_fDistance > p2->m_fDistance)
  1173.                 return 1;
  1174.         else if (p1->m_fDistance < p2->m_fDistance)
  1175.                 return -1;
  1176.  
  1177.         return 0;
  1178. }
  1179.  
  1180. void CVisAreaManager::MakeActiveEntransePortalsList(const CCamera* pCamera, PodArray<CVisArea*>& lstActiveEntransePortals, CVisArea* pThisPortal, const SRenderingPassInfo& passInfo)
  1181. {
  1182.         lstActiveEntransePortals.Clear();
  1183.         float fZoomFactor = pCamera ? (0.2f + 0.8f * (RAD2DEG(pCamera->GetFov()) / 90.f)) : 1.f;
  1184.  
  1185.         for (int nPortalId = 0; nPortalId < m_lstPortals.Count(); nPortalId++)
  1186.         {
  1187.                 CVisArea* pPortal = m_lstPortals[nPortalId];
  1188.  
  1189.                 if (pPortal->m_lstConnections.Count() == 1 && pPortal != pThisPortal && pPortal->IsActive() && !pPortal->m_bSkyOnly)
  1190.                 {
  1191.                         if (!pCamera || pCamera->IsAABBVisible_F(pPortal->m_boxStatics))
  1192.                         {
  1193.                                 Vec3 vNormal = pPortal->m_lstConnections[0]->GetConnectionNormal(pPortal);
  1194.                                 Vec3 vCenter = (pPortal->m_boxArea.min + pPortal->m_boxArea.max) * 0.5f;
  1195.                                 if (vNormal.Dot(vCenter - (pCamera ? pCamera->GetPosition() : passInfo.GetCamera().GetPosition())) < 0)
  1196.                                         continue;
  1197.                                 /*
  1198.                                         if(pCurPortal)
  1199.                                         {
  1200.                                           vNormal = pCurPortal->m_vConnNormals[0];
  1201.                                           if(vNormal.Dot(vCenter - curCamera.GetPosition())<0)
  1202.                                             continue;
  1203.                                         }
  1204.                                  */
  1205.                                 pPortal->m_fDistance = pPortal->m_boxArea.GetDistance(pCamera ? pCamera->GetPosition() : passInfo.GetCamera().GetPosition());
  1206.  
  1207.                                 float fRadius = (pPortal->m_boxArea.max - pPortal->m_boxArea.min).GetLength() * 0.5f;
  1208.                                 if (pPortal->m_fDistance * fZoomFactor > fRadius * pPortal->m_fViewDistRatio * GetFloatCVar(e_ViewDistRatioPortals) / 60.f)
  1209.                                         continue;
  1210.  
  1211.                                 SPortalColdData* pColdData = static_cast<SPortalColdData*>(pPortal->GetColdData());
  1212.  
  1213.                                 // test occlusion
  1214.                                 if (GetObjManager()->IsBoxOccluded(pPortal->m_boxStatics, pPortal->m_fDistance, &pColdData->m_occlusionTestClient, false, eoot_PORTAL, passInfo))
  1215.                                         continue;
  1216.  
  1217.                                 lstActiveEntransePortals.Add(pPortal);
  1218.  
  1219.                                 //                              if(GetCVars()->e_Portals==3)
  1220.                                 //                              DrawBBox(pPortal->m_boxStatics.min, pPortal->m_boxStatics.max);
  1221.                         }
  1222.                 }
  1223.         }
  1224.  
  1225.         // sort by distance
  1226.         if (lstActiveEntransePortals.Count())
  1227.         {
  1228.                 qsort(&lstActiveEntransePortals[0], lstActiveEntransePortals.Count(),
  1229.                       sizeof(lstActiveEntransePortals[0]), CVisAreaManager__CmpDistToPortal);
  1230.                 //              m_pCurPortal = lstActiveEntransePortals[0];
  1231.         }
  1232. }
  1233.  
  1234. void CVisAreaManager::MergeCameras(CCamera& cam1, const CCamera& cam2, const SRenderingPassInfo& passInfo)
  1235. {
  1236.         assert(0); // under development
  1237.         /*      {
  1238.             float fDotLR1 =  cam1.GetFrustumPlane(FR_PLANE_LEFT )->n.Dot(cam1.GetFrustumPlane(FR_PLANE_RIGHT)->n);
  1239.             float fDotRL2 =  cam2.GetFrustumPlane(FR_PLANE_RIGHT)->n.Dot(cam2.GetFrustumPlane(FR_PLANE_LEFT)->n);
  1240.             int y=0;
  1241.            }
  1242.          */
  1243.         // left-right
  1244.         float fDotLR = cam1.GetFrustumPlane(FR_PLANE_LEFT)->n.Dot(cam2.GetFrustumPlane(FR_PLANE_RIGHT)->n);
  1245.         float fDotRL = cam1.GetFrustumPlane(FR_PLANE_RIGHT)->n.Dot(cam2.GetFrustumPlane(FR_PLANE_LEFT)->n);
  1246.         if (fabs(fDotLR) < fabs(fDotRL))
  1247.         {
  1248.                 cam1.SetFrustumPlane(FR_PLANE_RIGHT, *cam2.GetFrustumPlane(FR_PLANE_RIGHT));
  1249.                 cam1.SetPPVertex(2, cam2.GetPPVertex(2));
  1250.                 cam1.SetPPVertex(3, cam2.GetPPVertex(3));
  1251.         }
  1252.         else
  1253.         {
  1254.                 cam1.SetFrustumPlane(FR_PLANE_LEFT, *cam2.GetFrustumPlane(FR_PLANE_LEFT));
  1255.                 cam1.SetPPVertex(0, cam2.GetPPVertex(0));
  1256.                 cam1.SetPPVertex(1, cam2.GetPPVertex(1));
  1257.         }
  1258.  
  1259.         /*
  1260.            {
  1261.            float fDotLR1 =  cam1.GetFrustumPlane(FR_PLANE_LEFT )->n.Dot(cam1.GetFrustumPlane(FR_PLANE_RIGHT)->n);
  1262.            float fDotRL2 =  cam2.GetFrustumPlane(FR_PLANE_RIGHT)->n.Dot(cam2.GetFrustumPlane(FR_PLANE_LEFT)->n);
  1263.            int y=0;
  1264.            }*/
  1265.         /*
  1266.            // top-bottom
  1267.            float fDotTB =  cam1.GetFrustumPlane(FR_PLANE_TOP   )->n.Dot(cam2.GetFrustumPlane(FR_PLANE_BOTTOM)->n);
  1268.            float fDotBT =  cam1.GetFrustumPlane(FR_PLANE_BOTTOM)->n.Dot(cam2.GetFrustumPlane(FR_PLANE_TOP   )->n);
  1269.  
  1270.            if(fDotTB>fDotBT)
  1271.             cam1.SetFrustumPlane(FR_PLANE_BOTTOM, *cam2.GetFrustumPlane(FR_PLANE_BOTTOM));
  1272.            else
  1273.             cam1.SetFrustumPlane(FR_PLANE_TOP,    *cam2.GetFrustumPlane(FR_PLANE_TOP));
  1274.          */
  1275.         cam1.SetFrustumPlane(FR_PLANE_NEAR, *passInfo.GetCamera().GetFrustumPlane(FR_PLANE_NEAR));
  1276.         cam1.SetFrustumPlane(FR_PLANE_FAR, *passInfo.GetCamera().GetFrustumPlane(FR_PLANE_FAR));
  1277.  
  1278.         cam1.SetFrustumPlane(FR_PLANE_TOP, *passInfo.GetCamera().GetFrustumPlane(FR_PLANE_TOP));
  1279.         cam1.SetFrustumPlane(FR_PLANE_BOTTOM, *passInfo.GetCamera().GetFrustumPlane(FR_PLANE_BOTTOM));
  1280.  
  1281.         //cam1.UpdateFrustum();
  1282.         /*
  1283.            if(GetCVars()->e_Portals==4)
  1284.            {
  1285.             GetRenderer()->SetMaterialColor(1,1,1,1);
  1286.             DrawBBox(pVerts[0],pVerts[1],DPRIM_LINE);
  1287.             GetRenderer()->DrawLabel(pVerts[0],2,"0");
  1288.             DrawBBox(pVerts[1],pVerts[2],DPRIM_LINE);
  1289.             GetRenderer()->DrawLabel(pVerts[1],2,"1");
  1290.             DrawBBox(pVerts[2],pVerts[3],DPRIM_LINE);
  1291.             GetRenderer()->DrawLabel(pVerts[2],2,"2");
  1292.             DrawBBox(pVerts[3],pVerts[0],DPRIM_LINE);
  1293.             GetRenderer()->DrawLabel(pVerts[3],2,"3");
  1294.            }*/
  1295. }
  1296.  
  1297. void CVisAreaManager::DrawOcclusionAreasIntoCBuffer(const SRenderingPassInfo& passInfo)
  1298. {
  1299.         FUNCTION_PROFILER_3DENGINE;
  1300.  
  1301.         m_lstActiveOcclVolumes.Clear();
  1302.         m_lstIndoorActiveOcclVolumes.Clear();
  1303.  
  1304.         float fZoomFactor = 0.2f + 0.8f * (RAD2DEG(passInfo.GetCamera().GetFov()) / 90.f);
  1305.         float fDistRatio = GetFloatCVar(e_OcclusionVolumesViewDistRatio) / fZoomFactor;
  1306.  
  1307.         if (GetCVars()->e_OcclusionVolumes)
  1308.                 for (int i = 0; i < m_lstOcclAreas.Count(); i++)
  1309.                 {
  1310.                         CVisArea* pArea = m_lstOcclAreas[i];
  1311.                         if (passInfo.GetCamera().IsAABBVisible_E(pArea->m_boxArea))
  1312.                         {
  1313.                                 float fRadius = (pArea->m_boxArea.min - pArea->m_boxArea.max).GetLength();
  1314.                                 Vec3 vPos = (pArea->m_boxArea.min + pArea->m_boxArea.max) * 0.5f;
  1315.                                 float fDist = passInfo.GetCamera().GetPosition().GetDistance(vPos);
  1316.                                 if (fDist < fRadius * pArea->m_fViewDistRatio * fDistRatio && pArea->m_lstShapePoints.Count() >= 2)
  1317.                                 {
  1318.                                         int nRecursiveLevel = passInfo.GetRecursiveLevel();
  1319.                                         if (!pArea->m_arrOcclCamera[nRecursiveLevel])
  1320.                                                 pArea->m_arrOcclCamera[nRecursiveLevel] = new CCamera;
  1321.                                         *pArea->m_arrOcclCamera[nRecursiveLevel] = passInfo.GetCamera();
  1322.  
  1323.                                         SActiveVerts activeVerts;
  1324.  
  1325.                                         if (pArea->m_lstShapePoints.Count() == 4)
  1326.                                         {
  1327.                                                 activeVerts.arrvActiveVerts[0] = pArea->m_lstShapePoints[0];
  1328.                                                 activeVerts.arrvActiveVerts[1] = pArea->m_lstShapePoints[1];
  1329.                                                 activeVerts.arrvActiveVerts[2] = pArea->m_lstShapePoints[2];
  1330.                                                 activeVerts.arrvActiveVerts[3] = pArea->m_lstShapePoints[3];
  1331.                                         }
  1332.                                         else
  1333.                                         {
  1334.                                                 activeVerts.arrvActiveVerts[0] = pArea->m_lstShapePoints[0];
  1335.                                                 activeVerts.arrvActiveVerts[1] = pArea->m_lstShapePoints[0] + Vec3(0, 0, pArea->m_fHeight);
  1336.                                                 activeVerts.arrvActiveVerts[2] = pArea->m_lstShapePoints[1] + Vec3(0, 0, pArea->m_fHeight);
  1337.                                                 activeVerts.arrvActiveVerts[3] = pArea->m_lstShapePoints[1];
  1338.                                         }
  1339.  
  1340.                                         Plane plane;
  1341.                                         plane.SetPlane(activeVerts.arrvActiveVerts[0], activeVerts.arrvActiveVerts[2], activeVerts.arrvActiveVerts[1]);
  1342.  
  1343.                                         if (plane.DistFromPlane(passInfo.GetCamera().GetPosition()) < 0)
  1344.                                         {
  1345.                                                 std::swap(activeVerts.arrvActiveVerts[0], activeVerts.arrvActiveVerts[3]);
  1346.                                                 std::swap(activeVerts.arrvActiveVerts[1], activeVerts.arrvActiveVerts[2]);
  1347.                                         }
  1348.                                         else if (!pArea->m_bDoubleSide)
  1349.                                                 continue;
  1350.  
  1351.                                         //                              GetRenderer()->SetMaterialColor(1,0,0,1);
  1352.                                         pArea->UpdatePortalCameraPlanes(*pArea->m_arrOcclCamera[passInfo.GetRecursiveLevel()], activeVerts.arrvActiveVerts, false, passInfo);
  1353.  
  1354.                                         // make far plane never clip anything
  1355.  
  1356.                                         Plane newNearPlane;
  1357.                                         newNearPlane.SetPlane(activeVerts.arrvActiveVerts[0], activeVerts.arrvActiveVerts[2], activeVerts.arrvActiveVerts[1]);
  1358.                                         pArea->m_arrOcclCamera[passInfo.GetRecursiveLevel()]->SetFrustumPlane(FR_PLANE_NEAR, newNearPlane);
  1359.  
  1360.                                         Plane newFarPlane;
  1361.                                         newFarPlane.SetPlane(Vec3(0, 1, -1024), Vec3(1, 0, -1024), Vec3(0, 0, -1024));
  1362.                                         pArea->m_arrOcclCamera[passInfo.GetRecursiveLevel()]->SetFrustumPlane(FR_PLANE_FAR, newFarPlane);
  1363.                                         //pArea->m_arrOcclCamera[m_nRenderStackLevel]->UpdateFrustum();
  1364.  
  1365.                                         m_lstActiveOcclVolumes.Add(pArea);
  1366.                                         pArea->m_fDistance = fDist;
  1367.                                 }
  1368.                         }
  1369.                 }
  1370.  
  1371.         if (m_lstActiveOcclVolumes.Count())
  1372.         {
  1373.                 // sort occluders by distance to the camera
  1374.                 qsort(&m_lstActiveOcclVolumes[0], m_lstActiveOcclVolumes.Count(),
  1375.                       sizeof(m_lstActiveOcclVolumes[0]), CVisAreaManager__CmpDistToPortal);
  1376.  
  1377.                 // remove occluded occluders
  1378.                 for (int i = m_lstActiveOcclVolumes.Count() - 1; i >= 0; i--)
  1379.                 {
  1380.                         CVisArea* pArea = m_lstActiveOcclVolumes[i];
  1381.                         AABB extrudedBox = pArea->m_boxStatics;
  1382.                         extrudedBox.min -= Vec3(VEC_EPSILON, VEC_EPSILON, VEC_EPSILON);
  1383.                         extrudedBox.max += Vec3(VEC_EPSILON, VEC_EPSILON, VEC_EPSILON);
  1384.                         if (IsOccludedByOcclVolumes(extrudedBox, passInfo))
  1385.                                 m_lstActiveOcclVolumes.Delete(i);
  1386.                 }
  1387.  
  1388.                 // put indoor occluders into separate list
  1389.                 for (int i = m_lstActiveOcclVolumes.Count() - 1; i >= 0; i--)
  1390.                 {
  1391.                         CVisArea* pArea = m_lstActiveOcclVolumes[i];
  1392.                         if (pArea->m_bUseInIndoors)
  1393.                                 m_lstIndoorActiveOcclVolumes.Add(pArea);
  1394.                 }
  1395.  
  1396.                 if (GetCVars()->e_Portals == 4)
  1397.                 {
  1398.                         // show really active occluders
  1399.                         for (int i = 0; i < m_lstActiveOcclVolumes.Count(); i++)
  1400.                         {
  1401.                                 CVisArea* pArea = m_lstActiveOcclVolumes[i];
  1402.                                 GetRenderer()->SetMaterialColor(0, 1, 0, 1);
  1403.                                 DrawBBox(pArea->m_boxStatics.min, pArea->m_boxStatics.max);
  1404.                         }
  1405.                 }
  1406.         }
  1407. }
  1408.  
  1409. /*
  1410.    void CVisAreaManager::CompileObjects()
  1411.    {
  1412.    // areas
  1413.    for(int v=0; v<m_lstVisAreas.Count(); v++)
  1414.     m_lstVisAreas[v]->CompileObjects(STATIC_OBJECTS);
  1415.  
  1416.    // portals
  1417.    for(int v=0; v<m_lstPortals.Count(); v++)
  1418.     m_lstPortals[v]->CompileObjects(STATIC_OBJECTS);
  1419.    }
  1420.  */
  1421. /*
  1422.    void CVisAreaManager::CheckUnload()
  1423.    {
  1424.    m_nLoadedSectors=0;
  1425.  
  1426.    // areas
  1427.    for(int v=0; v<m_lstVisAreas.Count(); v++)
  1428.     m_nLoadedSectors += m_lstVisAreas[v]->CheckUnload();
  1429.  
  1430.    // portals
  1431.    for(int v=0; v<m_lstPortals.Count(); v++)
  1432.     m_nLoadedSectors += m_lstPortals[v]->CheckUnload();
  1433.    }
  1434.  */
  1435. void CVisAreaManager::GetStreamingStatus(int& nLoadedSectors, int& nTotalSectors)
  1436. {
  1437.         nLoadedSectors = 0;//m_nLoadedSectors;
  1438.         nTotalSectors = m_lstPortals.Count() + m_lstVisAreas.Count();
  1439. }
  1440.  
  1441. void CVisAreaManager::GetMemoryUsage(ICrySizer* pSizer) const
  1442. {
  1443.         // areas
  1444.         for (int v = 0; v < m_lstVisAreas.Count(); v++)
  1445.                 m_lstVisAreas[v]->GetMemoryUsage(pSizer);
  1446.  
  1447.         // portals
  1448.         for (int v = 0; v < m_lstPortals.Count(); v++)
  1449.                 m_lstPortals[v]->GetMemoryUsage(pSizer);
  1450.  
  1451.         // occl areas
  1452.         for (int v = 0; v < m_lstOcclAreas.Count(); v++)
  1453.                 m_lstOcclAreas[v]->GetMemoryUsage(pSizer);
  1454.  
  1455.         pSizer->AddObject(this, sizeof(*this));
  1456. }
  1457.  
  1458. void CVisAreaManager::PrecacheLevel(bool bPrecacheAllVisAreas, Vec3* pPrecachePoints, int nPrecachePointsNum)
  1459. {
  1460.         CryLog("Precaching the level ...");
  1461.         //  gEnv->pLog->UpdateLoadingScreen(0);
  1462.  
  1463.         float fPrecacheTimeStart = GetTimer()->GetAsyncCurTime();
  1464.  
  1465.         GetRenderer()->EnableSwapBuffers((GetCVars()->e_PrecacheLevel >= 2) ? true : false);
  1466.  
  1467.         uint32 dwPrecacheLocations = 0;
  1468.  
  1469.         Vec3 arrCamDir[6] =
  1470.         {
  1471.                 Vec3(1,  0,  0),
  1472.                 Vec3(-1, 0,  0),
  1473.                 Vec3(0,  1,  0),
  1474.                 Vec3(0,  -1, 0),
  1475.                 Vec3(0,  0,  1),
  1476.                 Vec3(0,  0,  -1)
  1477.         };
  1478.  
  1479.         //loop over all sectors and place a light in the middle of the sector
  1480.         for (int v = 0; v < m_lstVisAreas.Count() && bPrecacheAllVisAreas; v++)
  1481.         {
  1482.                 GetRenderer()->EF_Query(EFQ_IncrementFrameID);
  1483.  
  1484.                 ++dwPrecacheLocations;
  1485.  
  1486.                 // find real geometry bbox
  1487.                 /*              bool bGeomFound = false;
  1488.                     Vec3 vBoxMin(100000.f,100000.f,100000.f);
  1489.                     Vec3 vBoxMax(-100000.f,-100000.f,-100000.f);
  1490.                     for(int s=0; s<ENTITY_LISTS_NUM; s++)
  1491.                     for(int e=0; e<m_lstVisAreas[v]->m_lstEntities[s].Count(); e++)
  1492.                     {
  1493.                       AABB aabbBox = m_lstVisAreas[v]->m_lstEntities[s][e].aabbBox;
  1494.                       vBoxMin.CheckMin(aabbBox.min);
  1495.                       vBoxMax.CheckMax(aabbBox.max);
  1496.                       bGeomFound = true;
  1497.                     }*/
  1498.  
  1499.                 Vec3 vAreaCenter = m_lstVisAreas[v]->m_boxArea.GetCenter();
  1500.                 CryLog("  Precaching VisArea %s", m_lstVisAreas[v]->GetName());
  1501.  
  1502.                 //place camera in the middle of a sector and render sector from different directions
  1503.                 for (int i = 0; i < 6 /*&& bGeomFound*/; i++)
  1504.                 {
  1505.                         GetRenderer()->BeginFrame();
  1506.  
  1507.                         // setup camera
  1508.                         CCamera cam = gEnv->pSystem->GetViewCamera();
  1509.                         Matrix33 mat = Matrix33::CreateRotationVDir(arrCamDir[i], 0);
  1510.                         cam.SetMatrix(mat);
  1511.                         cam.SetPosition(vAreaCenter);
  1512.                         cam.SetFrustum(GetRenderer()->GetWidth(), GetRenderer()->GetHeight(), gf_PI / 2, cam.GetNearPlane(), cam.GetFarPlane());
  1513.                         //                      Get3DEngine()->SetupCamera(cam);
  1514.  
  1515.                         Get3DEngine()->RenderWorld(SHDF_ZPASS | SHDF_ALLOWHDR | SHDF_ALLOWPOSTPROCESS | SHDF_ALLOW_WATER | SHDF_ALLOW_AO, SRenderingPassInfo::CreateGeneralPassRenderingInfo(cam), "PrecacheVisAreas");
  1516.  
  1517.                         GetRenderer()->RenderDebug();
  1518.                         GetRenderer()->EndFrame();
  1519.  
  1520.                         if (GetCVars()->e_PrecacheLevel >= 2)
  1521.                                 CrySleep(200);
  1522.                 }
  1523.         }
  1524.  
  1525.         CryLog("Precached %u visarea sectors", dwPrecacheLocations);
  1526.  
  1527.         //--------------------------------------------------------------------------------------
  1528.         //----                  PRE-FETCHING OF RENDER-DATA IN OUTDOORS                     ----
  1529.         //--------------------------------------------------------------------------------------
  1530.  
  1531.         // loop over all cam-position in the level and render this part of the level from 6 different directions
  1532.         for (int p = 0; pPrecachePoints && p < nPrecachePointsNum; p++) //loop over outdoor-camera position
  1533.         {
  1534.                 CryLog("  Precaching PrecacheCamera point %d of %d", p, nPrecachePointsNum);
  1535.                 for (int i = 0; i < 6; i++) //loop over 6 camera orientations
  1536.                 {
  1537.                         GetRenderer()->BeginFrame();
  1538.  
  1539.                         // setup camera
  1540.                         CCamera cam = gEnv->pSystem->GetViewCamera();
  1541.                         Matrix33 mat = Matrix33::CreateRotationVDir(arrCamDir[i], 0);
  1542.                         cam.SetMatrix(mat);
  1543.                         cam.SetPosition(pPrecachePoints[p]);
  1544.                         cam.SetFrustum(GetRenderer()->GetWidth(), GetRenderer()->GetHeight(), gf_PI / 2, cam.GetNearPlane(), cam.GetFarPlane());
  1545.  
  1546.                         Get3DEngine()->RenderWorld(SHDF_ZPASS | SHDF_ALLOWHDR | SHDF_ALLOWPOSTPROCESS | SHDF_ALLOW_WATER | SHDF_ALLOW_AO, SRenderingPassInfo::CreateGeneralPassRenderingInfo(cam), "PrecacheOutdoor");
  1547.  
  1548.                         GetRenderer()->RenderDebug();
  1549.                         GetRenderer()->EndFrame();
  1550.  
  1551.                         if (GetCVars()->e_PrecacheLevel >= 2)
  1552.                                 CrySleep(1000);
  1553.                 }
  1554.         }
  1555.  
  1556.         CryLog("Precached %d PrecacheCameraXX points", nPrecachePointsNum);
  1557.  
  1558.         GetRenderer()->EnableSwapBuffers(true);
  1559.  
  1560.         float fPrecacheTime = GetTimer()->GetAsyncCurTime() - fPrecacheTimeStart;
  1561.         CryLog("Level Precache finished in %.2f seconds", fPrecacheTime);
  1562. }
  1563.  
  1564. void CVisAreaManager::GetObjectsAround(Vec3 vExploPos, float fExploRadius, PodArray<SRNInfo>* pEntList, bool bSkip_ERF_NO_DECALNODE_DECALS, bool bSkipDynamicObjects)
  1565. {
  1566.         AABB aabbBox(vExploPos - Vec3(fExploRadius, fExploRadius, fExploRadius), vExploPos + Vec3(fExploRadius, fExploRadius, fExploRadius));
  1567.  
  1568.         CVisArea* pVisArea = (CVisArea*)GetVisAreaFromPos(vExploPos);
  1569.  
  1570.         if (pVisArea && pVisArea->m_pObjectsTree)
  1571.                 pVisArea->m_pObjectsTree->MoveObjectsIntoList(pEntList, &aabbBox, false, true, bSkip_ERF_NO_DECALNODE_DECALS, bSkipDynamicObjects);
  1572.         /*
  1573.            // find static objects around
  1574.            for(int i=0; pVisArea && i<pVisArea->m_lstEntities[STATIC_OBJECTS].Count(); i++)
  1575.            {
  1576.             IRenderNode * pRenderNode = pVisArea->m_lstEntities[STATIC_OBJECTS][i].pNode;
  1577.             if(bSkip_ERF_NO_DECALNODE_DECALS && pRenderNode->GetRndFlags()&ERF_NO_DECALNODE_DECALS)
  1578.               continue;
  1579.  
  1580.             if(pRenderNode->GetRenderNodeType() == eERType_Decal)
  1581.               continue;
  1582.  
  1583.             if(Overlap::Sphere_AABB(Sphere(vExploPos,fExploRadius), pRenderNode->GetBBox()))
  1584.               if(pEntList->Find(pRenderNode)<0)
  1585.                 pEntList->Add(pRenderNode);
  1586.            }*/
  1587. }
  1588.  
  1589. void CVisAreaManager::IntersectWithBox(const AABB& aabbBox, PodArray<CVisArea*>* plstResult, bool bOnlyIfVisible)
  1590. {
  1591.         for (int p = 0; p < m_lstPortals.Count(); p++)
  1592.         {
  1593.                 if (m_lstPortals[p]->m_boxArea.min.x<aabbBox.max.x&& m_lstPortals[p]->m_boxArea.max.x> aabbBox.min.x &&
  1594.                     m_lstPortals[p]->m_boxArea.min.y<aabbBox.max.y&& m_lstPortals[p]->m_boxArea.max.y> aabbBox.min.y)
  1595.                 {
  1596.                         plstResult->Add(m_lstPortals[p]);
  1597.                 }
  1598.         }
  1599.  
  1600.         for (int v = 0; v < m_lstVisAreas.Count(); v++)
  1601.         {
  1602.                 if (m_lstVisAreas[v]->m_boxArea.min.x<aabbBox.max.x&& m_lstVisAreas[v]->m_boxArea.max.x> aabbBox.min.x &&
  1603.                     m_lstVisAreas[v]->m_boxArea.min.y<aabbBox.max.y&& m_lstVisAreas[v]->m_boxArea.max.y> aabbBox.min.y)
  1604.                 {
  1605.                         plstResult->Add(m_lstVisAreas[v]);
  1606.                 }
  1607.         }
  1608. }
  1609.  
  1610. void CVisAreaManager::AddLightSourceReqursive(CDLight* pLight, CVisArea* pArea, const int32 nDeepness, const SRenderingPassInfo& passInfo)
  1611. {
  1612.         if (pArea->m_pObjectsTree)
  1613.                 pArea->m_pObjectsTree->AddLightSource(pLight, passInfo);
  1614.  
  1615.         if (1 < nDeepness)
  1616.                 for (int v = 0; v < pArea->m_lstConnections.Count(); v++)
  1617.                 {
  1618.                         CVisArea* pConArea = pArea->m_lstConnections[v];
  1619.                         AddLightSourceReqursive(pLight, pConArea, nDeepness - 1, passInfo);
  1620.                 }
  1621. }
  1622.  
  1623. void CVisAreaManager::AddLightSource(CDLight* pLight, const SRenderingPassInfo& passInfo)
  1624. {
  1625.         CVisArea* pLightArea = (CVisArea*)GetVisAreaFromPos(pLight->m_Origin);
  1626.  
  1627.         bool bThisAreaInly = (pLight->m_Flags & DLF_THIS_AREA_ONLY) != 0;
  1628.  
  1629.         if (pLightArea)
  1630.         {
  1631.                 int nPortal = pLightArea->IsPortal() ? 1 : 0;
  1632.                 AddLightSourceReqursive(pLight, pLightArea, nPortal + (bThisAreaInly ? 2 : 3), passInfo);
  1633.         }
  1634.         else if (!bThisAreaInly)
  1635.         {
  1636.                 AABB lightBox(
  1637.                   pLight->m_Origin - Vec3(pLight->m_fRadius, pLight->m_fRadius, pLight->m_fRadius),
  1638.                   pLight->m_Origin + Vec3(pLight->m_fRadius, pLight->m_fRadius, pLight->m_fRadius));
  1639.                 PodArray<CVisArea*>& arrAreas = m_tmpLstLightBoxAreas;
  1640.                 arrAreas.Clear();
  1641.                 m_pVisAreaManager->IntersectWithBox(lightBox, &arrAreas, true);
  1642.                 for (int i = 0; i < arrAreas.Count(); i++)
  1643.                         if (arrAreas[i]->IsPortal() && arrAreas[i]->IsConnectedToOutdoor())
  1644.                         {
  1645.                                 pLightArea = arrAreas[i];
  1646.                                 int nPortal = pLightArea->IsPortal() ? 1 : 0;
  1647.                                 AddLightSourceReqursive(pLight, pLightArea, nPortal + (bThisAreaInly ? 2 : 3), passInfo);
  1648.                         }
  1649.         }
  1650. }
  1651.  
  1652. int CVisAreaManager::GetNumberOfVisArea() const
  1653. {
  1654.         return m_lstPortals.size() + m_lstVisAreas.size();
  1655. }
  1656.  
  1657. IVisArea* CVisAreaManager::GetVisAreaById(int nID) const
  1658. {
  1659.         if (nID < 0)
  1660.                 return NULL;
  1661.  
  1662.         if (nID < (int)m_lstPortals.size())
  1663.         {
  1664.                 return m_lstPortals[nID];
  1665.         }
  1666.         nID -= m_lstPortals.size();
  1667.         if (nID < (int)m_lstVisAreas.size())
  1668.         {
  1669.                 return m_lstVisAreas[nID];
  1670.         }
  1671.  
  1672.         return NULL;
  1673. }
  1674.  
  1675. //////////////////////////////////////////////////////////////////////////
  1676. void CVisAreaManager::AddListener(IVisAreaCallback* pListener)
  1677. {
  1678.         if (m_lstCallbacks.Find(pListener) < 0)
  1679.                 m_lstCallbacks.Add(pListener);
  1680. }
  1681.  
  1682. //////////////////////////////////////////////////////////////////////////
  1683. void CVisAreaManager::RemoveListener(IVisAreaCallback* pListener)
  1684. {
  1685.         m_lstCallbacks.Delete(pListener);
  1686. }
  1687.  
  1688. void CVisAreaManager::CloneRegion(const AABB& region, const Vec3& offset, float zRotation)
  1689. {
  1690.         PodArray<Vec3> points;
  1691.  
  1692.         PodArray<CVisArea*> visAreas;
  1693.         IntersectWithBox(region, &visAreas, false);
  1694.  
  1695.         Vec3 localOrigin = region.GetCenter();
  1696.         Matrix34 l2w(Matrix33::CreateRotationZ(zRotation));
  1697.         l2w.SetTranslation(offset);
  1698.  
  1699.         int numAreas = visAreas.size();
  1700.         for (int i = 0; i < numAreas; ++i)
  1701.         {
  1702.                 CVisArea* pSrcArea = visAreas[i];
  1703.                 CVisArea* pCloneArea = CreateVisArea(0);
  1704.  
  1705.                 SVisAreaInfo info;
  1706.                 info.fHeight = pSrcArea->m_fHeight;
  1707.                 info.vAmbientColor = pSrcArea->m_vAmbientColor;
  1708.                 info.bAffectedByOutLights = pSrcArea->m_bAffectedByOutLights;
  1709.                 info.bIgnoreSkyColor = pSrcArea->m_bIgnoreSky;
  1710.                 info.bSkyOnly = pSrcArea->m_bSkyOnly;
  1711.                 info.fViewDistRatio = pSrcArea->m_fViewDistRatio;
  1712.                 info.bDoubleSide = pSrcArea->m_bDoubleSide;
  1713.                 info.bUseDeepness = pSrcArea->m_bUseDeepness;
  1714.                 info.bUseInIndoors = pSrcArea->m_bUseInIndoors;
  1715.                 info.bOceanIsVisible = pSrcArea->m_bOceanVisible;
  1716.                 info.bIgnoreGI = pSrcArea->m_bIgnoreGI;
  1717.                 info.bIgnoreOutdoorAO = pSrcArea->m_bIgnoreOutdoorAO;
  1718.  
  1719.                 points = pSrcArea->m_lstShapePoints;
  1720.                 int numPoints = points.size();
  1721.                 for (int p = 0; p < numPoints; ++p)
  1722.                 {
  1723.                         Vec3& point = points[p];
  1724.  
  1725.                         point -= localOrigin;
  1726.                         point = l2w * point;
  1727.                 }
  1728.  
  1729.                 const char* pName = pSrcArea->m_pVisAreaColdData->m_sName;
  1730.  
  1731.                 UpdateVisArea(pCloneArea, &points[0], numPoints, pName, info);
  1732.         }
  1733. }
  1734.  
  1735. void CVisAreaManager::ClearRegion(const AABB& region)
  1736. {
  1737.         PodArray<CVisArea*> visAreas;
  1738.         IntersectWithBox(region, &visAreas, false);
  1739.  
  1740.         bool updated = false;
  1741.  
  1742.         // What we're doing here is basically just what's done in DeleteVisArea, but this
  1743.         // should be a pooled vis area, so we don't want to actually delete it.  Instead we
  1744.         // just unregister them and let the pool cleanup actually destruct them.
  1745.         int numAreas = visAreas.size();
  1746.         for (int i = 0; i < numAreas; ++i)
  1747.         {
  1748.                 CVisArea* pVisArea = visAreas[i];
  1749.  
  1750.                 // IntersectWithBox only checks x and y, but we want to also make sure it's in the z
  1751.                 if (pVisArea->m_boxArea.min.z < region.max.z && pVisArea->m_boxArea.max.z > region.min.z)
  1752.                 {
  1753.                         bool deletedVis = m_lstVisAreas.Delete(pVisArea);
  1754.                         bool deletedPortal = m_lstPortals.Delete(pVisArea);
  1755.                         bool deletedOccluder = m_lstOcclAreas.Delete(pVisArea);
  1756.  
  1757.                         CRY_ASSERT_MESSAGE(!deletedVis || (m_visAreas.Find(pVisArea) >= 0), "Should only clear pooled vis areas, going to leak");
  1758.                         CRY_ASSERT_MESSAGE(!deletedPortal || (m_portals.Find(pVisArea) >= 0), "Should only clear pooled portals, going to leak");
  1759.                         CRY_ASSERT_MESSAGE(!deletedOccluder || (m_occlAreas.Find(pVisArea) >= 0), "Should only clear pooled occluders, going to leak");
  1760.  
  1761.                         if (deletedVis || deletedPortal || deletedOccluder)
  1762.                         {
  1763.                                 updated = true;
  1764.                         }
  1765.  
  1766.                         m_lstActiveOcclVolumes.Delete(pVisArea);
  1767.                         m_lstIndoorActiveOcclVolumes.Delete(pVisArea);
  1768.                         m_lstActiveEntransePortals.Delete(pVisArea);
  1769.                 }
  1770.         }
  1771.  
  1772.         if (updated)
  1773.         {
  1774.                 m_pCurArea = NULL;
  1775.                 m_pCurPortal = NULL;
  1776.                 UpdateConnections();
  1777.  
  1778.                 delete m_pAABBTree;
  1779.                 m_pAABBTree = NULL;
  1780.         }
  1781. }
  1782.  
  1783. void CVisAreaManager::MarkAllSectorsAsUncompiled(const IRenderNode* pRenderNode)
  1784. {
  1785.         for (int p = 0; p < m_lstPortals.Count(); p++)
  1786.         {
  1787.                 if (m_lstPortals[p]->m_pObjectsTree)
  1788.                         m_lstPortals[p]->m_pObjectsTree->MarkAsUncompiled(pRenderNode);
  1789.         }
  1790.  
  1791.         for (int v = 0; v < m_lstVisAreas.Count(); v++)
  1792.         {
  1793.                 if (m_lstVisAreas[v]->m_pObjectsTree)
  1794.                         m_lstVisAreas[v]->m_pObjectsTree->MarkAsUncompiled(pRenderNode);
  1795.         }
  1796. }
  1797.  
  1798. void CVisAreaManager::ActivateObjectsLayer(uint16 nLayerId, bool bActivate, bool bPhys, IGeneralMemoryHeap* pHeap, const AABB& layerBox)
  1799. {
  1800.         {
  1801.                 uint32 dwSize = m_lstVisAreas.Count();
  1802.  
  1803.                 for (uint32 dwI = 0; dwI < dwSize; ++dwI)
  1804.                         if (m_lstVisAreas[dwI]->m_pObjectsTree)
  1805.                                 m_lstVisAreas[dwI]->m_pObjectsTree->ActivateObjectsLayer(nLayerId, bActivate, bPhys, pHeap, layerBox);
  1806.         }
  1807.  
  1808.         {
  1809.                 uint32 dwSize = m_lstPortals.Count();
  1810.  
  1811.                 for (uint32 dwI = 0; dwI < dwSize; ++dwI)
  1812.                         if (m_lstPortals[dwI]->m_pObjectsTree)
  1813.                                 m_lstPortals[dwI]->m_pObjectsTree->ActivateObjectsLayer(nLayerId, bActivate, bPhys, pHeap, layerBox);
  1814.         }
  1815. }
  1816.  
  1817. void CVisAreaManager::GetObjects(PodArray<IRenderNode*>& lstObjects, const AABB* pBBox)
  1818. {
  1819.         {
  1820.                 uint32 dwSize = m_lstVisAreas.Count();
  1821.  
  1822.                 for (uint32 dwI = 0; dwI < dwSize; ++dwI)
  1823.                         if (m_lstVisAreas[dwI]->m_pObjectsTree)
  1824.                                 m_lstVisAreas[dwI]->m_pObjectsTree->GetObjects(lstObjects, pBBox);
  1825.         }
  1826.  
  1827.         {
  1828.                 uint32 dwSize = m_lstPortals.Count();
  1829.  
  1830.                 for (uint32 dwI = 0; dwI < dwSize; ++dwI)
  1831.                         if (m_lstPortals[dwI]->m_pObjectsTree)
  1832.                                 m_lstPortals[dwI]->m_pObjectsTree->GetObjects(lstObjects, pBBox);
  1833.         }
  1834. }
  1835.  
  1836. void CVisAreaManager::GetObjectsByFlags(uint dwFlags, PodArray<IRenderNode*>& lstObjects)
  1837. {
  1838.         {
  1839.                 uint32 dwSize = m_lstVisAreas.Count();
  1840.  
  1841.                 for (uint32 dwI = 0; dwI < dwSize; ++dwI)
  1842.                         if (m_lstVisAreas[dwI]->m_pObjectsTree)
  1843.                                 m_lstVisAreas[dwI]->m_pObjectsTree->GetObjectsByFlags(dwFlags, lstObjects);
  1844.         }
  1845.  
  1846.         {
  1847.                 uint32 dwSize = m_lstPortals.Count();
  1848.  
  1849.                 for (uint32 dwI = 0; dwI < dwSize; ++dwI)
  1850.                         if (m_lstPortals[dwI]->m_pObjectsTree)
  1851.                                 m_lstPortals[dwI]->m_pObjectsTree->GetObjectsByFlags(dwFlags, lstObjects);
  1852.         }
  1853. }
  1854.  
  1855. void CVisAreaManager::GenerateStatObjAndMatTables(std::vector<IStatObj*>* pStatObjTable, std::vector<IMaterial*>* pMatTable, std::vector<IStatInstGroup*>* pStatInstGroupTable, SHotUpdateInfo* pExportInfo)
  1856. {
  1857.         {
  1858.                 uint32 dwSize = m_lstVisAreas.Count();
  1859.                 for (uint32 dwI = 0; dwI < dwSize; ++dwI)
  1860.                         if (m_lstVisAreas[dwI]->m_pObjectsTree)
  1861.                                 m_lstVisAreas[dwI]->m_pObjectsTree->GenerateStatObjAndMatTables(pStatObjTable, pMatTable, pStatInstGroupTable, pExportInfo);
  1862.         }
  1863.  
  1864.         {
  1865.                 uint32 dwSize = m_lstPortals.Count();
  1866.                 for (uint32 dwI = 0; dwI < dwSize; ++dwI)
  1867.                         if (m_lstPortals[dwI]->m_pObjectsTree)
  1868.                                 m_lstPortals[dwI]->m_pObjectsTree->GenerateStatObjAndMatTables(pStatObjTable, pMatTable, pStatInstGroupTable, pExportInfo);
  1869.         }
  1870. }
  1871.  
  1872. bool CVisAreaManager::IsAABBVisibleFromPoint(AABB& box, Vec3 pos)
  1873. {
  1874.         CVisArea* pAreaBox = (CVisArea*)GetVisAreaFromPos(box.GetCenter());
  1875.         CVisArea* pAreaPos = (CVisArea*)GetVisAreaFromPos(pos);
  1876.  
  1877.         if (!pAreaBox && !pAreaPos)
  1878.                 return true; // no indoors involved
  1879.  
  1880.         PodArray<CVisArea*> arrPortals;
  1881.         int nRecursion = 0;
  1882.         Shadowvolume sv;
  1883.         NAABB_SV::AABB_ReceiverShadowVolume(pos, box, sv);
  1884.  
  1885.         bool bRes = FindShortestPathToVisArea(pAreaPos, pAreaBox, arrPortals, nRecursion, sv);
  1886.  
  1887.         IRenderAuxText::DrawLabelF(box.GetCenter(), 2, "-%s-", bRes ? "Y" : "N");
  1888.         IRenderAuxText::DrawLabel(pos, 2, "-X-");
  1889.         DrawLine(pos, box.GetCenter());
  1890.         DrawBBox(box, bRes ? Col_White : Col_NavyBlue);
  1891.  
  1892.         return bRes;
  1893. }
  1894.  
  1895. bool CVisAreaManager::FindShortestPathToVisArea(CVisArea* pThisArea, CVisArea* pTargetArea, PodArray<CVisArea*>& arrVisitedAreas, int& nRecursion, const Shadowvolume& sv)
  1896. {
  1897.         // skip double processing
  1898.         if (arrVisitedAreas.Find(pThisArea) >= 0)
  1899.                 return false;
  1900.  
  1901.         // check if point to box frustum intersects pThisArea visarea
  1902.         if (pThisArea && !NAABB_SV::Is_AABB_In_ShadowVolume(sv, *pThisArea->GetAABBox()))
  1903.                 return false;
  1904.  
  1905.         // check if box visarea reached
  1906.         if (pThisArea == pTargetArea)
  1907.                 return true;
  1908.  
  1909.         // register as already processed
  1910.         arrVisitedAreas.Add(pThisArea);
  1911.  
  1912.         // recurse to connections
  1913.         if (pThisArea)
  1914.         {
  1915.                 for (int p = 0; p < pThisArea->m_lstConnections.Count(); p++)
  1916.                         if (FindShortestPathToVisArea(pThisArea->m_lstConnections[p], pTargetArea, arrVisitedAreas, nRecursion, sv))
  1917.                                 return true;
  1918.  
  1919.                 if (pThisArea->IsPortal() && pThisArea->m_lstConnections.Count() == 1 && !pThisArea->m_bSkyOnly)
  1920.                         if (FindShortestPathToVisArea(NULL, pTargetArea, arrVisitedAreas, nRecursion, sv))
  1921.                                 return true;
  1922.         }
  1923.         else
  1924.         {
  1925.                 for (int p = 0; p < m_lstPortals.Count(); p++)
  1926.                         if (m_lstPortals[p]->IsPortal() && m_lstPortals[p]->m_lstConnections.Count() == 1 && !m_lstPortals[p]->m_bSkyOnly)
  1927.                                 if (FindShortestPathToVisArea(m_lstPortals[p], pTargetArea, arrVisitedAreas, nRecursion, sv))
  1928.                                         return true;
  1929.         }
  1930.  
  1931.         return false;
  1932. }
  1933.  
  1934. CVisArea* CVisAreaManager::CreateTypeVisArea()
  1935. {
  1936.         CVisArea* pNewVisArea = new CVisArea();
  1937.         SGenericColdData* pColdData = &m_visAreaColdData.AddNew();
  1938.  
  1939.         m_visAreas.Add(pNewVisArea);
  1940.         pColdData->ResetGenericData();
  1941.         pNewVisArea->SetColdDataPtr(pColdData);
  1942.  
  1943.         return pNewVisArea;
  1944. }
  1945.  
  1946. CVisArea* CVisAreaManager::CreateTypePortal()
  1947. {
  1948.         CVisArea* pNewPortal = new CVisArea();
  1949.         SPortalColdData* pColdData = &m_portalColdData.AddNew();
  1950.  
  1951.         m_portals.Add(pNewPortal);
  1952.         pColdData->ResetPortalData();
  1953.         pNewPortal->SetColdDataPtr(pColdData);
  1954.  
  1955.         return pNewPortal;
  1956. }
  1957.  
  1958. CVisArea* CVisAreaManager::CreateTypeOcclArea()
  1959. {
  1960.         CVisArea* pNewOcclArea = new CVisArea();
  1961.         SGenericColdData* pColdData = &m_occlAreaColdData.AddNew();
  1962.  
  1963.         m_occlAreas.Add(pNewOcclArea);
  1964.         pColdData->ResetGenericData();
  1965.         pNewOcclArea->SetColdDataPtr(pColdData);
  1966.  
  1967.         return pNewOcclArea;
  1968. }
  1969.  
  1970. void CVisAreaManager::InitAABBTree()
  1971. {
  1972.         IF (!m_pAABBTree, 0)
  1973.         {
  1974.                 UpdateAABBTree();
  1975.         }
  1976. }
  1977.  
  1978. //////////////////////////////////////////////////////////////////////
  1979. // Segmented World
  1980. void CVisAreaManager::ReleaseInactiveSegments()
  1981. {
  1982.         for (int i = 0; i < m_arrDeletedVisArea.Count(); i++)
  1983.         {
  1984.                 int nSlotID = m_arrDeletedVisArea[i];
  1985.  
  1986.                 SAFE_DELETE(m_visAreas[nSlotID]->m_pObjectsTree);
  1987.         }
  1988.         m_arrDeletedVisArea.Clear();
  1989.         for (int i = 0; i < m_arrDeletedPortal.Count(); i++)
  1990.         {
  1991.                 int nSlotID = m_arrDeletedPortal[i];
  1992.                 SAFE_DELETE(m_portals[nSlotID]->m_pObjectsTree);
  1993.         }
  1994.         m_arrDeletedPortal.Clear();
  1995.         for (int i = 0; i < m_arrDeletedOcclArea.Count(); i++)
  1996.         {
  1997.                 int nSlotID = m_arrDeletedOcclArea[i];
  1998.                 SAFE_DELETE(m_occlAreas[nSlotID]->m_pObjectsTree);
  1999.         }
  2000.         m_arrDeletedOcclArea.Clear();
  2001. }
  2002.  
  2003. bool CVisAreaManager::CreateSegment(int nSID)
  2004. {
  2005.         if (nSID >= m_visAreaSegmentData.Count())
  2006.         {
  2007.                 m_visAreaSegmentData.PreAllocate(nSID + 1, nSID + 1);
  2008.                 m_portalSegmentData.PreAllocate(nSID + 1, nSID + 1);
  2009.                 if (GetCVars()->e_OcclusionVolumes)
  2010.                         m_occlAreaSegmentData.PreAllocate(nSID + 1, nSID + 1);
  2011.         }
  2012.  
  2013.         return true;
  2014. }
  2015.  
  2016. bool CVisAreaManager::DeleteSegment(int nSID, bool bDeleteNow)
  2017. {
  2018.         if (nSID < 0 || (size_t)nSID >= m_visAreaSegmentData.size())
  2019.                 return false;
  2020.  
  2021.         DeleteVisAreaSegment(nSID, m_visAreaSegmentData, m_lstVisAreas, m_visAreas, m_arrDeletedVisArea);
  2022.         DeleteVisAreaSegment(nSID, m_portalSegmentData, m_lstPortals, m_portals, m_arrDeletedPortal);
  2023.         if (GetCVars()->e_OcclusionVolumes)
  2024.                 DeleteVisAreaSegment(nSID, m_occlAreaSegmentData, m_lstOcclAreas, m_occlAreas, m_arrDeletedOcclArea);
  2025.  
  2026.         if (bDeleteNow)
  2027.                 ReleaseInactiveSegments();
  2028.  
  2029.         return true;
  2030. }
  2031.  
  2032. void CVisAreaManager::DeleteVisAreaSegment(int nSID,
  2033.                                            PodArray<CVisAreaSegmentData>& visAreaSegmentData,
  2034.                                            PodArray<CVisArea*>& lstVisAreas,
  2035.                                            PodArray<CVisArea*, ReservedVisAreaBytes>& visAreas,
  2036.                                            PodArray<int>& deletedVisAreas)
  2037. {
  2038.         std::vector<int>& visAreasInSegment = visAreaSegmentData[nSID].m_visAreaIndices;
  2039.         for (size_t i = 0; i < visAreasInSegment.size(); i++)
  2040.         {
  2041.                 int index = visAreasInSegment[i];
  2042.                 assert(index >= 0 && index < visAreas.Count());
  2043.                 CSWVisArea* pVisArea = (CSWVisArea*)visAreas[index];
  2044.                 if (pVisArea->Unique())
  2045.                 {
  2046.                         lstVisAreas.Delete(pVisArea);
  2047.                         deletedVisAreas.push_back(index);
  2048.                 }
  2049.                 pVisArea->Release();           
  2050.         }
  2051.         visAreasInSegment.clear();
  2052. }
  2053.  
  2054. CVisArea* CVisAreaManager::FindVisAreaByGuid(VisAreaGUID guid, PodArray<CVisArea*>& lstVisAreas)
  2055. {
  2056.         if (!guid)
  2057.         {
  2058.                 for (int i = 0; i < lstVisAreas.Count(); i++)
  2059.                 {
  2060.                         if (lstVisAreas[i] && guid == lstVisAreas[i]->m_nVisGUID)
  2061.                                 return lstVisAreas[i];
  2062.                 }
  2063.         }
  2064.  
  2065.         return NULL;
  2066. }
  2067.  
  2068. void CVisAreaManager::OffsetPosition(const Vec3& delta)
  2069. {
  2070.         for (int i = 0; i < m_lstVisAreas.Count(); i++)
  2071.                 m_lstVisAreas[i]->OffsetPosition(delta);
  2072.  
  2073.         for (int i = 0; i < m_lstPortals.Count(); i++)
  2074.                 m_lstPortals[i]->OffsetPosition(delta);
  2075.  
  2076.         for (int i = 0; i < m_lstOcclAreas.Count(); i++)
  2077.                 m_lstOcclAreas[i]->OffsetPosition(delta);
  2078.  
  2079.         if (m_pAABBTree)
  2080.                 m_pAABBTree->OffsetPosition(delta);
  2081. }
  2082.  
downloadVisAreaMan.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