gwnavruntime/queries/utils/breadthfirstsearchedgecollisionvisitor.h Source File

breadthfirstsearchedgecollisionvisitor.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 #pragma once
8 
10 
11 namespace Kaim
12 {
13 
14 // class BreadthFirstSearchEdgeCollisionVisitor
15 //
16 // Template parameter EdgeIntersector must have the following function:
17 // bool DoesIntersectEdge(const Vec3f& startEdgePos, const Vec3f& endEdgePos)
18 template<class TraverseLogic, class EdgeIntersector>
19 class BreadthFirstSearchEdgeCollisionVisitor
20 {
21  KY_DEFINE_NEW_DELETE_OPERATORS(MemStat_Query)
22 
23 public:
24  BreadthFirstSearchEdgeCollisionVisitor(void* traverseLogicUserData, const CellBox& cellBox, EdgeIntersector& edgeIntersector)
25  : m_edgeIntersector(&edgeIntersector)
26  , m_traverseLogicUserData(traverseLogicUserData)
27  , m_collisionFound(false)
28  , m_cellBox(cellBox)
29  {
30  m_shouldVisitNeighborTriangle[0] = true;
31  m_shouldVisitNeighborTriangle[1] = true;
32  m_shouldVisitNeighborTriangle[2] = true;
33  }
34 
35  bool IsSearchFinished() { return m_collisionFound; }
36  bool ShouldVisitNeighborTriangle(const NavTriangleRawPtr&, KyUInt32 indexOfNeighborTriangle) { return m_shouldVisitNeighborTriangle[indexOfNeighborTriangle]; }
37  bool ShouldVisitTriangle(const NavTriangleRawPtr& triangleRawPtr) { return m_cellBox.DoesContain(triangleRawPtr.GetCellPos()); }
38 
39  NavTriangleRawPtr GetNeighborTriangle(const NavTriangleRawPtr&, KyUInt32 indexOfNeighborTriangle) { return m_neighborTriangle[indexOfNeighborTriangle]; }
40 
41  void Visit(const NavTriangleRawPtr& triangleRawPtr, const TriangleStatusInGrid& triangleStatus)
42  {
43  CoordPos64 v0, v1, v2;
44  CoordPos64* vertex[4] = {&v0, &v1, &v2, &v0};
45  NavHalfEdgeRawPtr halfEdgeRawPtr[3];
46  NavHalfEdge halfEdge[3];
47  bool isACrossableEdges[3];
48  bool neighborTriangleAlreadyVisited[3];
49  bool doesIntersectsEdges[3];
50  bool isNeighborInCellBox[3];
51 
52  const NavHalfEdgeIdx firstNavHalfEdgeIdx = NavFloorBlob::NavTriangleIdxToFirstNavHalfEdgeIdx(triangleRawPtr.GetTriangleIdx());
53  NavFloor* navFloor = triangleRawPtr.GetNavFloor();
54 
55  for (KyUInt32 i = 0; i < 3; ++i)
56  halfEdgeRawPtr[i].Set(navFloor, firstNavHalfEdgeIdx + i);
57 
58  triangleRawPtr.GetVerticesCoordPos64(v0, v1, v2);
59 
60  const NavFloorBlob& navFloorBlob = *navFloor->GetNavFloorBlob();
61  const NavHalfEdge* m_navHalfEdges = navFloorBlob.m_navHalfEdges.GetValues();
62 
63  for (KyUInt32 i = 0; i < 3; ++i)
64  halfEdge[i] = m_navHalfEdges[firstNavHalfEdgeIdx + i];
65 
66  for (KyUInt32 i = 0; i < 3; ++i)
67  {
68  NavHalfEdgeRawPtr pairHalfEdgeRawPtr;
69  isACrossableEdges[i] = halfEdgeRawPtr[i].IsHalfEdgeCrossable<TraverseLogic>(m_traverseLogicUserData, halfEdge[i], &navFloorBlob, pairHalfEdgeRawPtr);
70 
71  if (isACrossableEdges[i])
72  {
73  isNeighborInCellBox[i] = m_cellBox.DoesContain(pairHalfEdgeRawPtr.GetCellPos());
74 
75  bool inSameFloor = halfEdge[i].GetHalfEdgeType() == EDGETYPE_PAIRED || halfEdge[i].GetHalfEdgeType() == EDGETYPE_CONNEXBOUNDARY;
76  m_neighborTriangle[i].Set(pairHalfEdgeRawPtr.GetNavFloor(), NavFloorBlob::NavHalfEdgeIdxToTriangleIdx(pairHalfEdgeRawPtr.GetHalfEdgeIdx()));
77 
78  if (inSameFloor)
79  neighborTriangleAlreadyVisited[i] = triangleStatus.IsTriangleOpen_Unsafe(m_neighborTriangle[i]);
80  else
81  neighborTriangleAlreadyVisited[i] = triangleStatus.IsTriangleOpen(m_neighborTriangle[i]);
82  }
83  else
84  {
85  isNeighborInCellBox[i] = true;
86  neighborTriangleAlreadyVisited[i] = false;
87  }
88  }
89 
90  for (KyUInt32 i = 0; i < 3; ++i)
91  doesIntersectsEdges[i] = neighborTriangleAlreadyVisited[i] || m_edgeIntersector->DoesIntersectEdge(*vertex[i], *vertex[i + 1]);
92 
93  m_collisionFound = (isACrossableEdges[0] == false && doesIntersectsEdges[0]) ||
94  (isACrossableEdges[1] == false && doesIntersectsEdges[1]) ||
95  (isACrossableEdges[2] == false && doesIntersectsEdges[2]);
96 
97  for (KyUInt32 i = 0; i < 3; ++i)
98  {
99  m_shouldVisitNeighborTriangle[i] = (isACrossableEdges[i] && !neighborTriangleAlreadyVisited[i] && doesIntersectsEdges[i] && isNeighborInCellBox[i]);
100  }
101  }
102 
103 public:
104  EdgeIntersector* m_edgeIntersector;
105  void* m_traverseLogicUserData;
106  bool m_collisionFound;
107 
108 private:
109  CellBox m_cellBox;
110  bool m_shouldVisitNeighborTriangle[3];
111  NavTriangleRawPtr m_neighborTriangle[3];
112 };
113 
114 }
115 
116 
117 
Box2i CellBox
A type that represents a bounding box around cells in a 2D grid.
Definition: navmeshtypes.h:31
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
Indicates that another NavHalfEdge in the same NavFloor but in different Connex lies adjacent to the ...
Definition: navmeshtypes.h:57
static NavHalfEdgeIdx NavTriangleIdxToFirstNavHalfEdgeIdx(NavTriangleIdx idx)
Retrieves the first NavHalfEdgeIdx of NavTriangle specified by the input NavTriangleIdx.
Definition: navfloorblob.inl:23
#define KY_DEFINE_NEW_DELETE_OPERATORS(MemStat)
This macro defines new and delete operators.
Definition: memory.h:132
Vec2LL CoordPos64
A type that represents the position of a point within the 2D integer grid.
Definition: navmeshtypes.h:16
The Autodesk Navigation namespace.
Definition: gamekitcrowddispersion.cpp:17
static NavTriangleIdx NavHalfEdgeIdxToTriangleIdx(NavHalfEdgeIdx idx)
Retrieves the index of the triangle that contains the edge specified the input NavHalfEdgeIdx.
Definition: navfloorblob.inl:22
Indicates that another NavHalfEdge in the same Connex lies adjacent to the NavHalfEdge.
Definition: navmeshtypes.h:58