gwnavruntime/querysystem/workingmemcontainers/astarnodeindexingrid.h Source File

astarnodeindexingrid.h
Go to the documentation of this file.
1 /*
2 * Copyright 2016 Autodesk, Inc. All rights reserved.
3 * Use of this software is subject to the terms of the Autodesk license agreement and any attachments or Appendices thereto provided at the time of installation or download,
4 * or which otherwise accompanies this software in either electronic or hard copy form, or which is signed by you and accepted by Autodesk.
5 */
6 
7 
8 #pragma once
9 
13 
14 
15 namespace Kaim
16 {
17 
18 class AStarContextConfig
19 {
20 public:
21  AStarContextConfig() : m_abstractGraphTraversalMode(PATHFINDER_DO_NOT_TRAVERSE_ABSTRACT_GRAPHS) {}
22 
23  bool CanUseAbstractGraphs() const;
24 
25 public:
26  PathFinderAbstractGraphTraversalMode m_abstractGraphTraversalMode;
27  CellBox m_activeDataCellBox;
28  KyArray<CellBox>* m_additionalActiveDataCellBoxes;
29 };
30 
31 class AstarNodeIndexInGrid
32 {
33 public:
34  // AstarIndex on 32bits
35  KY_INLINE KyUInt32 GetNumberOfWordsForNodeIndices(KyUInt32 numberOfNodes) { return numberOfNodes; }
36 
37  struct NavGraphToNodeIndices
38  {
39  KY_INLINE AStarNodeIndex GetAStarNodeIndex(NavGraphVertexIdx navGraphVertexIdx) const { return GetNodeIndices()[navGraphVertexIdx]; }
40  KY_INLINE void SetAStarNodeIndex(NavGraphVertexIdx navGraphVertexIdx, AStarNodeIndex index) { GetNodeIndices()[navGraphVertexIdx] = index; }
41 
42  KY_INLINE AStarNodeIndex* GetNodeIndices() const { return (AStarNodeIndex*)((char*)this + m_offsetToNodeIndices); }
43 
44  KY_INLINE bool IsValid() const { return m_offsetToNodeIndices != KyUInt32MAXVAL; }
45  KyUInt32 m_offsetToNodeIndices;
46  };
47 
48  struct AbstractGraphToNodeIndices
49  {
50  KY_INLINE AStarNodeIndex GetAStarNodeIndex(AbstractGraphNodeIdx abstractGraphNodeIdx) const { return GetNodeIndices()[abstractGraphNodeIdx]; }
51  KY_INLINE void SetAStarNodeIndex(AbstractGraphNodeIdx abstractGraphNodeIdx, AStarNodeIndex index) { GetNodeIndices()[abstractGraphNodeIdx] = index; }
52 
53  KY_INLINE AStarNodeIndex* GetNodeIndices() const { return (AStarNodeIndex*)((char*)this + m_offsetToNodeIndices); }
54 
55  KY_INLINE bool IsValid() const { return m_offsetToNodeIndices != KyUInt32MAXVAL; }
56  KyUInt32 m_offsetToNodeIndices;
57  };
58 
59  struct NavFloorToNodeIndices
60  {
61  KY_INLINE AStarNodeIndex GetAStarNodeIndex(NavHalfEdgeIdx navHalfEdgeIdx) const { return GetNodeIndices()[navHalfEdgeIdx]; }
62  KY_INLINE void SetAStarNodeIndex(NavHalfEdgeIdx navHalfEdgeIdx, AStarNodeIndex index) { GetNodeIndices()[navHalfEdgeIdx] = index; }
63 
64  KY_INLINE AStarNodeIndex* GetNodeIndices() const { return (AStarNodeIndex*)((char*)this + m_offsetToNodeIndices); }
65  KY_INLINE bool IsValid() const { return m_offsetToNodeIndices != KyUInt32MAXVAL; }
66 
67  KyUInt32 m_offsetToNodeIndices;
68  };
69 
70  struct CellPosToNavFloors
71  {
72  KY_INLINE bool IsValid() const { return m_offSetToNavFloorToNodeIndices != KyUInt32MAXVAL; }
73  KY_INLINE NavFloorToNodeIndices* GetNavFloorToNodeIndices() const { return (NavFloorToNodeIndices*)((char*)this + m_offSetToNavFloorToNodeIndices); }
74 
75  KyUInt32 m_offSetToNavFloorToNodeIndices;
76  KyUInt32 m_navMeshChangeIdx;
77  };
78 
79 public:
80  AstarNodeIndexInGrid() : m_numberOfNavGraph(0), m_numberOfAbstractGraph(0), m_navGraphChangeIdx(0), m_abstractGraphChangeIdx(0), m_currentOffsetFromBuffer(0) {}
81 
82  AstarNodeIndexInGrid(WorkingMemory* workingMemory, ActiveData* activeData, const AStarContextConfig& astarContextConfig) { Init(workingMemory, activeData, astarContextConfig); }
83 
84  void Init(WorkingMemory* workingMemory, ActiveData* activeData, const AStarContextConfig& astarContextConfig);
85 
86  void ReleaseWorkingMemoryBuffer();
87 
88  KyUInt32 GetAvailableSizeInBytes() const;
89 
90  bool IsEnoughPlaceForAllocation(KyUInt32 sizeInBytes);
91 
92  bool TryToResize();
93 
94  void MakeEmpty();
95 
96  void* AllocateInBufferAndMemsetTo1(KyUInt32 totalSizeToNewOffSet);
97 
98  AStarNodeIndex* AllocateAstarNodeIndices(KyUInt32 numberOfEdges);
99 
100  CellPosToNavFloors* AllocateCellPosToNavFloors(KyUInt32 numberOfCell);
101  NavFloorToNodeIndices* AllocateNavFloorToNodeIndex(KyUInt32 numberOfFloors);
102  NavGraphToNodeIndices* AllocateNavGraphToNodeIndex(KyUInt32 numberOfGraphs);
103  AbstractGraphToNodeIndices* AllocateAbstractGraphToNodeIndex(KyUInt32 numberOfAbstractGraphs);
104 
105  bool IsInside(const CellPos& cellPos);
106  CellPosToNavFloors* GetCellPosToNavFloors(const CellPos& cellPos);
107 
108  KyResult GetNavFloorToNodeIndices(ActiveData* activeData, const NavFloorRawPtr& navFloorRawPtr, NavFloorToNodeIndices*& nodeIndices);
109  KyResult GetNavGraphToNodeIndices(const NavGraphVertexRawPtr& navGraphVertexRawPtr, NavGraphToNodeIndices*& nodeIndices);
110  KyResult GetAbstractGraphToNodeIndices(const AbstractGraphNodeRawPtr& abstractGraphNodeRawPtr, AbstractGraphToNodeIndices*& nodeIndices);
111 
112  NavGraphToNodeIndices* GetNavGraphToNodeIndices_Unsafe(const NavGraphVertexRawPtr& navGraphVertexRawPtr);
113  NavFloorToNodeIndices* GetNavFloorToNodeIndices_Unsafe(const NavFloorRawPtr& navFloorRawPtr);
114  AbstractGraphToNodeIndices* GetAbstractGraphToNodeIndices_Unsafe(const AbstractGraphNodeRawPtr& abstractGraphNodeRawPtr);
115 
116  bool IsInitialized() const { return m_buffer.IsInitialized(); }
117  bool HasVisitedNavDataChanged(Database* database);
118 
119 private:
120  NavGraphToNodeIndices* GetNavGraphToNodeIndicesBuffer();
121  AbstractGraphToNodeIndices* GetAbstractGraphToNodeIndicesBuffer();
122  CellPosToNavFloors* GetCellPosToNavFloorsBuffer();
123 
124 public:
125  WorkingMemContainerBase m_buffer;
126 
127  KyUInt32 m_numberOfNavGraph;
128  KyUInt32 m_numberOfAbstractGraph;
129 
130  KyUInt32 m_navGraphChangeIdx; // set at Init() only.
131  KyUInt32 m_abstractGraphChangeIdx; // set at Init() only.
132 
133  KyUInt32 m_currentOffsetFromBuffer;
134  CellBox m_activeDataCellBox;
135  KyArray<CellBox> m_additionalActiveDataCellBoxes; // only used if m_numberOfAbstractGraph != 0
136 };
137 
138 KY_INLINE void AstarNodeIndexInGrid::ReleaseWorkingMemoryBuffer() { m_buffer.ReleaseBuffer(); }
139 
140 KY_INLINE KyUInt32 AstarNodeIndexInGrid::GetAvailableSizeInBytes() const { return m_buffer.GetBufferSize() - m_currentOffsetFromBuffer; }
141 
142 KY_INLINE bool AstarNodeIndexInGrid::IsEnoughPlaceForAllocation(KyUInt32 sizeInBytes)
143 {
144  while (GetAvailableSizeInBytes() < sizeInBytes)
145  {
146  if (TryToResize() == false)
147  return false;
148  }
149 
150  return true;
151 }
152 
153 KY_INLINE AStarNodeIndex* AstarNodeIndexInGrid::AllocateAstarNodeIndices(KyUInt32 numberOfEdges)
154 {
155  return (AStarNodeIndex*)AllocateInBufferAndMemsetTo1(sizeof(KyUInt32) * GetNumberOfWordsForNodeIndices(numberOfEdges));
156 }
157 
158 KY_INLINE AstarNodeIndexInGrid::NavFloorToNodeIndices* AstarNodeIndexInGrid::AllocateNavFloorToNodeIndex(KyUInt32 numberOfFloors)
159 {
160  return (NavFloorToNodeIndices*)AllocateInBufferAndMemsetTo1(sizeof(NavFloorToNodeIndices) * numberOfFloors);
161 }
162 
163 KY_INLINE AstarNodeIndexInGrid::NavGraphToNodeIndices* AstarNodeIndexInGrid::AllocateNavGraphToNodeIndex(KyUInt32 numberOfGraphs)
164 {
165  return (NavGraphToNodeIndices*)AllocateInBufferAndMemsetTo1(sizeof(NavGraphToNodeIndices) * numberOfGraphs);
166 }
167 
168 KY_INLINE AstarNodeIndexInGrid::AbstractGraphToNodeIndices* AstarNodeIndexInGrid::AllocateAbstractGraphToNodeIndex(KyUInt32 numberOfAbstractGraphs)
169 {
170  return (AbstractGraphToNodeIndices*)AllocateInBufferAndMemsetTo1(sizeof(AbstractGraphToNodeIndices) * numberOfAbstractGraphs);
171 }
172 
173 KY_INLINE AstarNodeIndexInGrid::CellPosToNavFloors* AstarNodeIndexInGrid::AllocateCellPosToNavFloors(KyUInt32 numberOfCell)
174 {
175  return (CellPosToNavFloors*)AllocateInBufferAndMemsetTo1(sizeof(CellPosToNavFloors) * numberOfCell);
176 }
177 
178 
179 KY_INLINE AstarNodeIndexInGrid::NavGraphToNodeIndices* AstarNodeIndexInGrid::GetNavGraphToNodeIndicesBuffer()
180 { return (NavGraphToNodeIndices*)m_buffer.GetBuffer(); }
181 
182 KY_INLINE AstarNodeIndexInGrid::AbstractGraphToNodeIndices* AstarNodeIndexInGrid::GetAbstractGraphToNodeIndicesBuffer()
183 { return (AbstractGraphToNodeIndices*) (GetNavGraphToNodeIndicesBuffer() + m_numberOfNavGraph); }
184 
185 KY_INLINE AstarNodeIndexInGrid::CellPosToNavFloors* AstarNodeIndexInGrid::GetCellPosToNavFloorsBuffer()
186 { return (CellPosToNavFloors*) (GetAbstractGraphToNodeIndicesBuffer() + m_numberOfAbstractGraph); }
187 
188 KY_INLINE bool AstarNodeIndexInGrid::IsInside(const CellPos& cellPos)
189 {
190  if (m_activeDataCellBox.DoesContain(cellPos))
191  return true;
192 
193  for (KyUInt32 i = 0; i < m_additionalActiveDataCellBoxes.GetCount(); ++i)
194  if (m_additionalActiveDataCellBoxes[i].DoesContain(cellPos))
195  return true;
196 
197  return false;
198 }
199 
200 KY_INLINE AstarNodeIndexInGrid::CellPosToNavFloors* AstarNodeIndexInGrid::GetCellPosToNavFloors(const CellPos& cellPos)
201 {
202  CellPosToNavFloors* memoryStartForGrid = GetCellPosToNavFloorsBuffer();
203  if (m_numberOfAbstractGraph == 0 || m_activeDataCellBox.DoesContain(cellPos) == true)
204  return memoryStartForGrid + m_activeDataCellBox.GetRowMajorIndex(cellPos);
205  else
206  {
207  KyUInt32 base = (m_activeDataCellBox.CountX() * m_activeDataCellBox.CountY());
208  for(KyUInt32 i = 0; i < m_additionalActiveDataCellBoxes.GetCount(); ++i)
209  {
210  const CellBox& destCellBox = m_additionalActiveDataCellBoxes[i];
211  if (m_additionalActiveDataCellBoxes[i].DoesContain(cellPos) == true)
212  return memoryStartForGrid + base + destCellBox.GetRowMajorIndex(cellPos);
213  else
214  base += (destCellBox.CountX() * destCellBox.CountY());
215  }
216  }
217 
218  return nullptr;
219 }
220 
221 KY_INLINE AstarNodeIndexInGrid::NavGraphToNodeIndices* AstarNodeIndexInGrid::GetNavGraphToNodeIndices_Unsafe(const NavGraphVertexRawPtr& navGraphVertexRawPtr)
222 {
223  NavGraphToNodeIndices* memoryStartForGraphs = GetNavGraphToNodeIndicesBuffer();
224  return &memoryStartForGraphs[navGraphVertexRawPtr.GetNavGraph()->m_idxInTheActiveDataBuffer];
225 }
226 
227 KY_INLINE AstarNodeIndexInGrid::NavFloorToNodeIndices* AstarNodeIndexInGrid::GetNavFloorToNodeIndices_Unsafe(const NavFloorRawPtr& navFloorRawPtr)
228 {
229  KY_DEBUG_ASSERTN(IsInside(navFloorRawPtr.GetCellPos()), ("Invalid CellBox"));
230 
231  NavFloor* navFloor = navFloorRawPtr.GetNavFloor();
232  const CellPos& cellPos = navFloor->GetCellPos();
233 
234  CellPosToNavFloors* cellPosToNavFloors = GetCellPosToNavFloors(cellPos);
235  KY_DEBUG_ASSERTN(cellPosToNavFloors->IsValid(), ("Bad usage of UnSafe function"));
236 
237  NavFloorToNodeIndices& navFloorToNodeIndices = cellPosToNavFloors->GetNavFloorToNodeIndices()[navFloor->GetIndexInCollection()];
238  KY_DEBUG_ASSERTN(navFloorToNodeIndices.IsValid(), ("Bad usage of UnSafe function"));
239 
240  return &navFloorToNodeIndices;
241 }
242 
243 KY_INLINE AstarNodeIndexInGrid::AbstractGraphToNodeIndices* AstarNodeIndexInGrid::GetAbstractGraphToNodeIndices_Unsafe(const AbstractGraphNodeRawPtr& abstractGraphNodeRawPtr)
244 {
245  AbstractGraphToNodeIndices* memoryStartForAbstractGraphs = GetAbstractGraphToNodeIndicesBuffer();
246  return &memoryStartForAbstractGraphs[abstractGraphNodeRawPtr.m_abstractGraph->m_abstractGraphIdx];
247 }
248 
249 }
250 
251 
252 
KyUInt32 NavGraphVertexIdx
An index that uniquely identifies a single vertex within the set of vertices owned by a NavGraph...
Definition: navgraphtypes.h:45
Box2i CellBox
A type that represents a bounding box around cells in a 2D grid.
Definition: navmeshtypes.h:31
Vec2i CellPos
A type that represents the position of a cell within a 2D grid.
Definition: navmeshtypes.h:30
std::uint32_t KyUInt32
uint32_t
Definition: types.h:29
KyUInt32 NavHalfEdgeIdx
An index that uniquely identifies a single edge of a triangle within the set of edges owned by a NavF...
Definition: navmeshtypes.h:84
Navigation return code class.
Definition: types.h:108
The Autodesk Navigation namespace.
Definition: gamekitcrowddispersion.cpp:17
#define KyUInt32MAXVAL
KyUInt32 max value
Definition: types.h:68