BVB Source Codes

CRYENGINE Show OffGridLinks.cpp Source code

Return Download CRYENGINE: download OffGridLinks.cpp Source code - Download CRYENGINE Source code - Type:.cpp
  1. // Copyright 2001-2016 Crytek GmbH / Crytek Group. All rights reserved.
  2.  
  3. #include "StdAfx.h"
  4. #include "OffGridLinks.h"
  5.  
  6. #include "../NavigationSystem/NavigationSystem.h"
  7. #include "Tile.h"
  8.  
  9. // This needs to be static because OffMeshNavigationManager expects all link ids to be
  10. // unique, and there is one of these per navigation mesh.
  11. MNM::OffMeshLinkID MNM::OffMeshNavigation::s_linkIDGenerator = MNM::Constants::eOffMeshLinks_InvalidOffMeshLinkID;
  12.  
  13. void MNM::OffMeshNavigation::TileLinks::CopyLinks(TriangleLink* links, uint16 linkCount)
  14. {
  15.         if (triangleLinkCount != linkCount)
  16.         {
  17.                 SAFE_DELETE_ARRAY(triangleLinks);
  18.  
  19.                 triangleLinkCount = linkCount;
  20.  
  21.                 if (linkCount)
  22.                         triangleLinks = new TriangleLink[linkCount];
  23.         }
  24.  
  25.         if (linkCount)
  26.                 memcpy(triangleLinks, links, sizeof(TriangleLink) * linkCount);
  27. }
  28.  
  29. void MNM::OffMeshNavigation::AddLink(NavigationMesh& navigationMesh, const TriangleID startTriangleID, const TriangleID endTriangleID, OffMeshLinkID& linkID)
  30. {
  31.         // We only support 1024 links per tile
  32.         const int kMaxTileLinks = 1024;
  33.  
  34.         //////////////////////////////////////////////////////////////////////////
  35.         /// Figure out the tile to operate on.
  36.         MNM::TileID tileID = MNM::ComputeTileID(startTriangleID);
  37.  
  38.         //////////////////////////////////////////////////////////////////////////
  39.         // Attempt to find the current link data for this tile or create one if not already cached
  40.         TileLinks& tileLinks = m_tilesLinks[tileID];
  41.         assert(tileLinks.triangleLinkCount + 1 < kMaxTileLinks);
  42.  
  43.         //////////////////////////////////////////////////////////////////////////
  44.         // Find if we have entries for this triangle, if not insert at the end
  45.         uint16 triangleIdx = tileLinks.triangleLinkCount;  // Default to end
  46.         {
  47.                 for (uint16 idx = 0; idx < tileLinks.triangleLinkCount; ++idx)
  48.                 {
  49.                         if (tileLinks.triangleLinks[idx].startTriangleID == startTriangleID)
  50.                         {
  51.                                 triangleIdx = idx;
  52.                                 break;
  53.                         }
  54.                 }
  55.         }
  56.  
  57.         //////////////////////////////////////////////////////////////////////////
  58.         // If a valid link ID has been passed in, use it instead of generating a new one
  59.         // This can occur when re-adding existing links to a modified mesh.
  60.         if (linkID == MNM::Constants::eOffMeshLinks_InvalidOffMeshLinkID)
  61.         {
  62.                 // Generate new link id
  63.                 // NOTE: Zero is an invalid link ID
  64.                 while (++s_linkIDGenerator == MNM::Constants::eOffMeshLinks_InvalidOffMeshLinkID)
  65.                         ;
  66.                 linkID = s_linkIDGenerator;
  67.         }
  68.         // A link ID should never be larger than the latest generated
  69.         assert(linkID <= s_linkIDGenerator);
  70.  
  71.         //////////////////////////////////////////////////////////////////////////
  72.         // Begin insert/copy process
  73.         TriangleLink tempTriangleLinks[kMaxTileLinks];
  74.  
  75.         // If not the first index, copy the current links up to the target index
  76.         // into the temporary buffer
  77.         if (triangleIdx > 0)
  78.         {
  79.                 memcpy(tempTriangleLinks, tileLinks.triangleLinks, sizeof(TriangleLink) * triangleIdx);
  80.         }
  81.  
  82.         // Insert the new link
  83.         tempTriangleLinks[triangleIdx].startTriangleID = startTriangleID;
  84.         tempTriangleLinks[triangleIdx].endTriangleID = endTriangleID;
  85.         tempTriangleLinks[triangleIdx].linkID = linkID;
  86.  
  87.         // Now copy the remaining links after the insert, including the one just overwritten
  88.         const int diffCount = tileLinks.triangleLinkCount - triangleIdx;
  89.         if (diffCount > 0)
  90.         {
  91.                 memcpy(&tempTriangleLinks[triangleIdx + 1], &tileLinks.triangleLinks[triangleIdx], sizeof(TriangleLink) * diffCount);
  92.         }
  93.  
  94.         // Now copy the update list back into the source
  95.         tileLinks.CopyLinks(tempTriangleLinks, tileLinks.triangleLinkCount + 1);
  96.  
  97.         //////////////////////////////////////////////////////////////////////////
  98.         // Now add/update the link on the tile
  99.         // NOTE: triangleLinkCount will have been updated due to the previous copy
  100.         if (triangleIdx < (tileLinks.triangleLinkCount - 1))
  101.         {
  102.                 // Update index value for all link entries for this triangle after this insert
  103.                 // since we shifted the indices with the memcpy
  104.                 TriangleID currentTriangleID = startTriangleID;
  105.                 for (uint16 idx = triangleIdx + 1; idx < tileLinks.triangleLinkCount; ++idx)
  106.                 {
  107.                         if (tileLinks.triangleLinks[idx].startTriangleID != currentTriangleID)
  108.                         {
  109.                                 currentTriangleID = tileLinks.triangleLinks[idx].startTriangleID;
  110.                                 navigationMesh.navMesh.UpdateOffMeshLinkForTile(tileID, currentTriangleID, idx);
  111.                         }
  112.                 }
  113.         }
  114.         else
  115.         {
  116.                 // Add the new link to the off-mesh link to the tile itself
  117.                 navigationMesh.navMesh.AddOffMeshLinkToTile(tileID, startTriangleID, triangleIdx);
  118.         }
  119. }
  120.  
  121. void MNM::OffMeshNavigation::RemoveLink(NavigationMesh& navigationMesh, const TriangleID boundTriangleID, const OffMeshLinkID linkID)
  122. {
  123.         MNM::TileID tileID = ComputeTileID(boundTriangleID);
  124.  
  125.         TTilesLinks::iterator tileLinksIt = m_tilesLinks.find(tileID);
  126.  
  127.         if (tileLinksIt != m_tilesLinks.end())
  128.         {
  129.                 const int maxTileLinks = 1024;
  130.                 TriangleLink tempTriangleLinks[maxTileLinks];
  131.  
  132.                 TileLinks& tileLinks = tileLinksIt->second;
  133.  
  134.                 //Note: Should be ok to copy this way, we are not going to have many links per tile...
  135.                 uint16 copyCount = 0;
  136.                 for (uint16 triIdx = 0; triIdx < tileLinks.triangleLinkCount; ++triIdx)
  137.                 {
  138.                         TriangleLink& triangleLink = tileLinks.triangleLinks[triIdx];
  139.                         if (triangleLink.linkID != linkID)
  140.                         {
  141.                                 // Retain link
  142.                                 tempTriangleLinks[copyCount] = triangleLink;
  143.                                 copyCount++;
  144.                         }
  145.                 }
  146.  
  147.                 // Copy the retained links to the cached link list
  148.                 tileLinks.CopyLinks(tempTriangleLinks, copyCount);
  149.  
  150.                 //Update triangle off-mesh indices
  151.                 uint16 boundTriangleLeftLinks = 0;
  152.                 TriangleID currentTriangleID(0);
  153.                 for (uint16 triIdx = 0; triIdx < tileLinks.triangleLinkCount; ++triIdx)
  154.                 {
  155.                         TriangleLink& triangleLink = tileLinks.triangleLinks[triIdx];
  156.  
  157.                         if (currentTriangleID != triangleLink.startTriangleID)
  158.                         {
  159.                                 currentTriangleID = triangleLink.startTriangleID;
  160.                                 navigationMesh.navMesh.UpdateOffMeshLinkForTile(tileID, currentTriangleID, triIdx);
  161.                         }
  162.                         boundTriangleLeftLinks += (currentTriangleID == boundTriangleID) ? 1 : 0;
  163.                 }
  164.  
  165.                 if (!boundTriangleLeftLinks)
  166.                 {
  167.                         navigationMesh.navMesh.RemoveOffMeshLinkFromTile(tileID, boundTriangleID);
  168.                 }
  169.         }
  170. }
  171.  
  172. void MNM::OffMeshNavigation::InvalidateLinks(const TileID tileID)
  173. {
  174.         // Remove all links associated with the provided tile ID
  175.  
  176.         TTilesLinks::iterator tileIt = m_tilesLinks.find(tileID);
  177.         if (tileIt != m_tilesLinks.end()) // notice: if this iterator points to end(), it means that we never attempted to add a link to given tile
  178.         {
  179.                 m_tilesLinks.erase(tileIt);
  180.         }
  181. }
  182.  
  183. MNM::OffMeshNavigation::QueryLinksResult MNM::OffMeshNavigation::GetLinksForTriangle(const TriangleID triangleID, const uint16 index) const
  184. {
  185.         const MNM::TileID& tileID = ComputeTileID(triangleID);
  186.  
  187.         TTilesLinks::const_iterator tileCit = m_tilesLinks.find(tileID);
  188.  
  189.         if (tileCit != m_tilesLinks.end())
  190.         {
  191.                 const TileLinks& tileLinks = tileCit->second;
  192.                 if (index < tileLinks.triangleLinkCount)
  193.                 {
  194.                         TriangleLink* pFirstTriangle = &tileLinks.triangleLinks[index];
  195.                         uint16 linkCount = 1;
  196.  
  197.                         for (uint16 triIdx = index + 1; triIdx < tileLinks.triangleLinkCount; ++triIdx)
  198.                         {
  199.                                 if (tileLinks.triangleLinks[triIdx].startTriangleID == triangleID)
  200.                                 {
  201.                                         linkCount++;
  202.                                 }
  203.                                 else
  204.                                 {
  205.                                         break;
  206.                                 }
  207.                         }
  208.  
  209.                         return QueryLinksResult(pFirstTriangle, linkCount);
  210.                 }
  211.  
  212.         }
  213.  
  214.         return QueryLinksResult(NULL, 0);
  215. }
  216.  
  217. #if DEBUG_MNM_ENABLED
  218.  
  219. MNM::OffMeshNavigation::ProfileMemoryStats MNM::OffMeshNavigation::GetMemoryStats(ICrySizer* pSizer) const
  220. {
  221.         ProfileMemoryStats memoryStats;
  222.  
  223.         // Tile links memory
  224.         size_t previousSize = pSizer->GetTotalSize();
  225.         for (TTilesLinks::const_iterator tileIt = m_tilesLinks.begin(); tileIt != m_tilesLinks.end(); ++tileIt)
  226.         {
  227.                 pSizer->AddObject(&(tileIt->second), tileIt->second.triangleLinkCount * sizeof(TriangleLink));
  228.         }
  229.         pSizer->AddHashMap(m_tilesLinks);
  230.  
  231.         memoryStats.offMeshTileLinksMemory += (pSizer->GetTotalSize() - previousSize);
  232.  
  233.         //Object size
  234.         previousSize = pSizer->GetTotalSize();
  235.         pSizer->AddObjectSize(this);
  236.  
  237.         memoryStats.totalSize = pSizer->GetTotalSize() - previousSize;
  238.  
  239.         return memoryStats;
  240. }
  241.  
  242. #endif
  243.  
downloadOffGridLinks.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