12 #ifndef Navigation_BreadthFirstSearchTraversal_H
13 #define Navigation_BreadthFirstSearchTraversal_H
26 class NavMeshElementBlob;
39 template <
class Visitor>
40 class BreadthFirstSearchTraversal
45 BreadthFirstSearchTraversal(
46 QueryUtils& queryUtils, const
CellBox& cellBox, Visitor& visitor) :
47 m_activeData(queryUtils.m_database->GetActiveData()),
49 m_openNodes(queryUtils.GetWorkingMemory()),
50 m_triangleStatus(queryUtils.GetWorkingMemory(), cellBox),
53 KY_INLINE
void Clear()
55 m_openNodes.MakeEmpty();
56 m_triangleStatus.MakeEmpty();
59 KY_INLINE
bool IsInitialized()
const {
return m_openNodes.IsInitialized() && m_triangleStatus.IsInitialized(); }
62 inline TraversalResult SetStartTriangle(
const NavTriangleRawPtr& triangleRawPtr);
64 TraversalResult AddTriangleIfNeverEncountered(
const NavTriangleRawPtr& triangleRawPtr);
66 TraversalResult Search();
68 KY_INLINE
void SetVisitedNodeContainer(WorkingMemArray<NavTriangleRawPtr>* visitedNodes) { m_visitedNodes = visitedNodes; }
71 ActiveData* m_activeData;
75 WorkingMemDeque<NavTriangleRawPtr> m_openNodes;
77 TriangleStatusInGrid m_triangleStatus;
78 WorkingMemArray<NavTriangleRawPtr>* m_visitedNodes;
81 template <
class Visitor>
82 TraversalResult BreadthFirstSearchTraversal<Visitor>:: SetStartTriangle(
const NavTriangleRawPtr& triangleRawPtr)
84 if (m_visitor->ShouldVisitTriangle(triangleRawPtr) ==
false)
85 return TraversalResult_DONE;
87 if (
KY_FAILED(m_openNodes.PushBack(triangleRawPtr)))
88 return TraversalResult_LACK_OF_MEMORY_FOR_OPEN_NODES;
91 if (m_triangleStatus.IsInitialized() ==
false)
92 return TraversalResult_LACK_OF_MEMORY_FOR_CLOSED_NODES;
94 return m_triangleStatus.OpenNodeIfNew(*m_activeData, triangleRawPtr, unused);
97 template <
class Visitor>
98 TraversalResult BreadthFirstSearchTraversal<Visitor>::Search()
100 bool doesStoreVisited = m_visitedNodes !=
KY_NULL;
102 NavTriangleRawPtr currentTrianglerRawPtr;
104 while (!m_openNodes.IsEmpty())
106 m_openNodes.Front(currentTrianglerRawPtr);
107 m_openNodes.PopFront();
109 m_visitor->Visit(currentTrianglerRawPtr, m_triangleStatus);
111 if (doesStoreVisited)
113 if (
KY_FAILED(m_visitedNodes->PushBack(currentTrianglerRawPtr)))
114 return TraversalResult_LACK_OF_MEMORY_FOR_VISITED_NODES;
117 if (m_visitor->IsSearchFinished())
118 return TraversalResult_DONE;
120 if (m_visitor->ShouldVisitNeighborTriangle(currentTrianglerRawPtr, 0))
122 const TraversalResult rc = AddTriangleIfNeverEncountered(m_visitor->GetNeighborTriangle(currentTrianglerRawPtr, 0));
123 if (rc != TraversalResult_DONE)
127 if (m_visitor->ShouldVisitNeighborTriangle(currentTrianglerRawPtr, 1))
129 const TraversalResult rc = AddTriangleIfNeverEncountered(m_visitor->GetNeighborTriangle(currentTrianglerRawPtr, 1));
130 if (rc != TraversalResult_DONE)
134 if (m_visitor->ShouldVisitNeighborTriangle(currentTrianglerRawPtr, 2))
136 const TraversalResult rc = AddTriangleIfNeverEncountered(m_visitor->GetNeighborTriangle(currentTrianglerRawPtr, 2));
137 if (rc != TraversalResult_DONE)
142 return TraversalResult_DONE;
145 template <
class Visitor>
146 TraversalResult BreadthFirstSearchTraversal<Visitor>::AddTriangleIfNeverEncountered(
const NavTriangleRawPtr& triangleRawPtr)
149 TraversalResult result = m_triangleStatus.OpenNodeIfNew(*m_activeData, triangleRawPtr, nodeIsNew);
150 if (result != TraversalResult_DONE)
153 if (nodeIsNew &&
KY_FAILED(m_openNodes.PushBack(triangleRawPtr)))
154 return TraversalResult_LACK_OF_MEMORY_FOR_OPEN_NODES;
156 return TraversalResult_DONE;
161 #endif // Navigation_BreadthFirstSearchTraversal_H
Box2i CellBox
A type that represents a bounding box around cells in a 2D grid.
Definition: navmeshtypes.h:34
#define KY_FAILED(expression)
Shorthand for Kaim::Result::Fail().
Definition: types.h:274
#define KY_NULL
Null value.
Definition: types.h:247
Definition: gamekitcrowddispersion.h:20
#define KY_DEFINE_NEW_DELETE_OPERATORS(MemStat)
This macro defines new and delete operators.
Definition: memory.h:137