BVB Source Codes

CRYENGINE Show GraphNodeManager.cpp Source code

Return Download CRYENGINE: download GraphNodeManager.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 "GraphNodeManager.h"
  5.  
  6. inline IAISystem::tNavCapMask TypeFromTypeIndex(int typeIndex)
  7. {
  8.         return IAISystem::tNavCapMask(1 << typeIndex);
  9. }
  10.  
  11. inline int CGraphNodeManager::TypeSizeFromTypeIndex(unsigned typeIndex) const
  12. {
  13.         return m_typeSizes[typeIndex];
  14. }
  15.  
  16. bool Match(IAISystem::tNavCapMask type, IAISystem::tNavCapMask mask)
  17. {
  18.         return (type & mask) != 0;
  19. }
  20.  
  21. CGraphNodeManager::CGraphNodeManager() :
  22.         m_freeBuckets(IAISystem::NAV_TYPE_COUNT, BucketHeader::InvalidNextFreeBucketIdx)
  23. {
  24.         static_assert((sizeof(GraphNode_Unset) % 4) == 0 && sizeof(GraphNode_Unset) < 1024, "Invalid type size!");
  25.         static_assert((sizeof(GraphNode_Triangular) % 4) == 0 && sizeof(GraphNode_Triangular) < 1024, "Invalid type size!");
  26.         static_assert((sizeof(GraphNode_WaypointHuman) % 4) == 0 && sizeof(GraphNode_WaypointHuman) < 1024, "Invalid type size!");
  27.         static_assert((sizeof(GraphNode_Waypoint3DSurface) % 4) == 0 && sizeof(GraphNode_Waypoint3DSurface) < 1024, "Invalid type size!");
  28.         static_assert((sizeof(GraphNode_Flight) % 4) == 0 && sizeof(GraphNode_Flight) < 1024, "Invalid type size!");
  29.         static_assert((sizeof(GraphNode_Volume) % 4) == 0 && sizeof(GraphNode_Volume) < 1024, "Invalid type size!");
  30.         static_assert((sizeof(GraphNode_Road) % 4) == 0 && sizeof(GraphNode_Road) < 1024, "Invalid type size!");
  31.         static_assert((sizeof(GraphNode_SmartObject) % 4) == 0 && sizeof(GraphNode_SmartObject) < 1024, "Invalid type size!");
  32.         static_assert((sizeof(GraphNode_Free2D) % 4) == 0 && sizeof(GraphNode_Free2D) < 1024, "Invalid type size!");
  33.         static_assert((sizeof(GraphNode_CustomNav) % 4) == 0 && sizeof(GraphNode_CustomNav) < 1024, "Invalid type size!");
  34.  
  35.         m_typeSizes[0] = sizeof(GraphNode_Unset);
  36.         m_typeSizes[1] = sizeof(GraphNode_Triangular);
  37.         m_typeSizes[2] = sizeof(GraphNode_WaypointHuman);
  38.         m_typeSizes[3] = sizeof(GraphNode_Waypoint3DSurface);
  39.         m_typeSizes[4] = sizeof(GraphNode_Flight);
  40.         m_typeSizes[5] = sizeof(GraphNode_Volume);
  41.         m_typeSizes[6] = sizeof(GraphNode_Road);
  42.         m_typeSizes[7] = sizeof(GraphNode_SmartObject);
  43.         m_typeSizes[8] = sizeof(GraphNode_Free2D);
  44.         m_typeSizes[9] = sizeof(GraphNode_CustomNav);
  45. }
  46.  
  47. CGraphNodeManager::~CGraphNodeManager()
  48. {
  49.         Clear(~0);
  50. }
  51.  
  52. void CGraphNodeManager::Clear(IAISystem::tNavCapMask typeMask)
  53. {
  54.         for (int i = 0, count = int(m_buckets.size()); i < count; ++i)
  55.         {
  56.                 if (m_buckets[i] && Match(m_buckets[i]->type, typeMask))
  57.                 {
  58.                         delete[] (reinterpret_cast<char*>(m_buckets[i]));
  59.                         m_buckets[i] = 0;
  60.                 }
  61.         }
  62.  
  63.         for (unsigned i = 0, numTypes = m_freeBuckets.size(); i < numTypes; ++i)
  64.         {
  65.                 IAISystem::tNavCapMask type = TypeFromTypeIndex(i);
  66.  
  67.                 if (Match(type, typeMask))
  68.                 {
  69.                         m_freeBuckets[i] = BucketHeader::InvalidNextFreeBucketIdx;
  70.                 }
  71.         }
  72. }
  73.  
  74. unsigned CGraphNodeManager::CreateNode(IAISystem::tNavCapMask type, const Vec3& pos, unsigned ID)
  75. {
  76.         static_assert(BUCKET_SIZE <= 255, "Invalid bucket size!");
  77.  
  78.         int typeIndex = TypeIndexFromType(type);
  79.         if (typeIndex < 0)
  80.                 return 0;
  81.  
  82.         if (typeIndex >= (int)m_freeBuckets.size())
  83.         {
  84.                 m_freeBuckets.resize(typeIndex + 1, BucketHeader::InvalidNextFreeBucketIdx);
  85.         }
  86.  
  87.         const int typeSize = TypeSizeFromTypeIndex(typeIndex);
  88.  
  89.         uint16 freeBucketIdx = m_freeBuckets[typeIndex];
  90.  
  91.         if (freeBucketIdx == BucketHeader::InvalidNextFreeBucketIdx)
  92.         {
  93.                 int bucketAllocationSize = sizeof(BucketHeader) + typeSize * BUCKET_SIZE;
  94.                 BucketHeader* pHeader = reinterpret_cast<BucketHeader*>(new char[bucketAllocationSize]);
  95.                 pHeader->type = type.GetFullMask();
  96.                 pHeader->nextAvailable = 0;
  97.                 uint8* pNodes = (uint8*)(pHeader + 1);
  98.                 for (int i = 0; i < BUCKET_SIZE - 1; ++i)
  99.                         pNodes[i * typeSize] = (i + 1);
  100.                 pNodes[(BUCKET_SIZE - 1) * typeSize] = BucketHeader::InvalidNextAvailableIdx;
  101.                 pHeader->nextFreeBucketIdx = BucketHeader::InvalidNextFreeBucketIdx;
  102.                 pHeader->SetNodeSize(typeSize);
  103.                 pHeader->nodes = (uint8*)(pHeader + 1);
  104.  
  105.                 freeBucketIdx = (uint16)m_buckets.size();
  106.                 m_buckets.resize((size_t)(freeBucketIdx + 1));
  107.                 m_buckets[freeBucketIdx] = pHeader;
  108.                 m_freeBuckets[typeIndex] = freeBucketIdx;
  109.         }
  110.  
  111.         BucketHeader* freeBucket = m_buckets[freeBucketIdx];
  112.  
  113.         int allocIdx = freeBucket->nextAvailable;
  114.         assert(allocIdx < BUCKET_SIZE);
  115.  
  116.         freeBucket->nextAvailable = freeBucket->nodes[allocIdx * typeSize];
  117.  
  118.         if (freeBucket->nextAvailable == BucketHeader::InvalidNextAvailableIdx)
  119.         {
  120.                 m_freeBuckets[typeIndex] = freeBucket->nextFreeBucketIdx;
  121.                 freeBucket->nextFreeBucketIdx = BucketHeader::InvalidNextFreeBucketIdx;
  122.         }
  123.  
  124.         GraphNode* pNode = reinterpret_cast<GraphNode*>(freeBucket->nodes + allocIdx * typeSize);
  125.  
  126.         IAISystem::ENavigationType actualType = (IAISystem::ENavigationType)(unsigned)type;
  127.         switch (actualType)
  128.         {
  129.         case IAISystem::NAV_UNSET:
  130.                 pNode = new(pNode) GraphNode_Unset(actualType, pos, ID);
  131.                 break;
  132.         case IAISystem::NAV_TRIANGULAR:
  133.                 pNode = new(pNode) GraphNode_Triangular(actualType, pos, ID);
  134.                 break;
  135.         case IAISystem::NAV_WAYPOINT_HUMAN:
  136.                 pNode = new(pNode) GraphNode_WaypointHuman(actualType, pos, ID);
  137.                 break;
  138.         case IAISystem::NAV_WAYPOINT_3DSURFACE:
  139.                 pNode = new(pNode) GraphNode_Waypoint3DSurface(actualType, pos, ID);
  140.                 break;
  141.         case IAISystem::NAV_FLIGHT:
  142.                 pNode = new(pNode) GraphNode_Flight(actualType, pos, ID);
  143.                 break;
  144.         case IAISystem::NAV_VOLUME:
  145.                 pNode = new(pNode) GraphNode_Volume(actualType, pos, ID);
  146.                 break;
  147.         case IAISystem::NAV_ROAD:
  148.                 pNode = new(pNode) GraphNode_Road(actualType, pos, ID);
  149.                 break;
  150.         case IAISystem::NAV_SMARTOBJECT:
  151.                 pNode = new(pNode) GraphNode_SmartObject(actualType, pos, ID);
  152.                 break;
  153.         case IAISystem::NAV_FREE_2D:
  154.                 pNode = new(pNode) GraphNode_Free2D(actualType, pos, ID);
  155.                 break;
  156.         case IAISystem::NAV_CUSTOM_NAVIGATION:
  157.                 pNode = new(pNode) GraphNode_CustomNav(actualType, pos, ID);
  158.                 break;
  159.         }
  160.  
  161.         assert(pNode->nRefCount == 0);
  162.  
  163.         return ((freeBucketIdx << BUCKET_SIZE_SHIFT) + allocIdx) + 1;
  164. }
  165.  
  166. void CGraphNodeManager::DestroyNode(unsigned index)
  167. {
  168.         // GraphNodes are optimized for size, and we avoid a virtual table by not having a virtual destructor.
  169.  
  170.         GraphNode* pNode = GetNode(index);
  171.         switch (pNode->navType)
  172.         {
  173.         case IAISystem::NAV_UNSET:
  174.                 static_cast<GraphNode_Unset*>(pNode)->~GraphNode_Unset();
  175.                 break;
  176.         case IAISystem::NAV_TRIANGULAR:
  177.                 static_cast<GraphNode_Triangular*>(pNode)->~GraphNode_Triangular();
  178.                 break;
  179.         case IAISystem::NAV_WAYPOINT_HUMAN:
  180.                 static_cast<GraphNode_WaypointHuman*>(pNode)->~GraphNode_WaypointHuman();
  181.                 break;
  182.         case IAISystem::NAV_WAYPOINT_3DSURFACE:
  183.                 static_cast<GraphNode_Waypoint3DSurface*>(pNode)->~GraphNode_Waypoint3DSurface();
  184.                 break;
  185.         case IAISystem::NAV_FLIGHT:
  186.                 static_cast<GraphNode_Flight*>(pNode)->~GraphNode_Flight();
  187.                 break;
  188.         case IAISystem::NAV_VOLUME:
  189.                 static_cast<GraphNode_Volume*>(pNode)->~GraphNode_Volume();
  190.                 break;
  191.         case IAISystem::NAV_ROAD:
  192.                 static_cast<GraphNode_Road*>(pNode)->~GraphNode_Road();
  193.                 break;
  194.         case IAISystem::NAV_SMARTOBJECT:
  195.                 static_cast<GraphNode_SmartObject*>(pNode)->~GraphNode_SmartObject();
  196.                 break;
  197.         case IAISystem::NAV_FREE_2D:
  198.                 static_cast<GraphNode_Free2D*>(pNode)->~GraphNode_Free2D();
  199.                 break;
  200.         case IAISystem::NAV_CUSTOM_NAVIGATION:
  201.                 static_cast<GraphNode_CustomNav*>(pNode)->~GraphNode_CustomNav();
  202.                 break;
  203.         default:
  204.                 break;
  205.         }
  206.  
  207.         // Push node onto bucket free list
  208.         uint16 bucketIdx = (index - 1) / BUCKET_SIZE;
  209.         uint8 idxInBucket = (index - 1) % BUCKET_SIZE;
  210.         int typeIndex = TypeIndexFromType(pNode->navType);
  211.  
  212.         BucketHeader* pBucket = m_buckets[bucketIdx];
  213.         if (pBucket->nextAvailable == BucketHeader::InvalidNextAvailableIdx)
  214.         {
  215.                 pBucket->nextFreeBucketIdx = m_freeBuckets[typeIndex];
  216.                 m_freeBuckets[typeIndex] = bucketIdx;
  217.         }
  218.  
  219.         pBucket->nodes[idxInBucket * TypeSizeFromTypeIndex(typeIndex)] = pBucket->nextAvailable;
  220.         pBucket->nextAvailable = idxInBucket;
  221. }
  222.  
  223. size_t CGraphNodeManager::NodeMemorySize() const
  224. {
  225.         size_t mem = 0;
  226.  
  227.         for (int i = 0, count = int(m_buckets.size()); i < count; ++i)
  228.         {
  229.                 if (!m_buckets[i])
  230.                         continue;
  231.  
  232.                 unsigned typeSize = TypeSizeFromTypeIndex(TypeIndexFromType(m_buckets[i]->type));
  233.                 mem += sizeof(BucketHeader) + typeSize * BUCKET_SIZE;
  234.         }
  235.         return mem;
  236. }
  237.  
  238. void CGraphNodeManager::GetMemoryStatistics(ICrySizer* pSizer)
  239. {
  240.         pSizer->AddContainer(m_buckets);
  241.  
  242.         for (size_t i = 0; i < m_buckets.size(); ++i)
  243.         {
  244.                 if (m_buckets[i])
  245.                 {
  246.                         size_t typeSize = TypeSizeFromTypeIndex(TypeIndexFromType(m_buckets[i]->type));
  247.                         pSizer->AddObject(m_buckets[i], sizeof(BucketHeader) + typeSize * BUCKET_SIZE);
  248.                 }
  249.         }
  250. }
  251.  
downloadGraphNodeManager.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