gwnavruntime/dynamicnavmesh/earclippingtriangulator.h Source File

earclippingtriangulator.h
Go to the documentation of this file.
1 /*
2 * Copyright 2015 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 /*
9 * Copyright 2011 Autodesk, Inc. All rights reserved.
10 * Use of this software is subject to the terms of the Autodesk license agreement provided at the time of installation or download,
11 * or which otherwise accompanies this software in either electronic or hard copy form.
12 */
13 
14 #ifndef Navigation_EarClippingTriangulator_H
15 #define Navigation_EarClippingTriangulator_H
16 
19 
20 
21 namespace Kaim
22 {
23 
24 class DynamicTriangulation;
25 class WorkingMemory;
26 
27 class EarClippingTriangulatorInputPolygon
28 {
29  KY_DEFINE_NEW_DELETE_OPERATORS(Stat_Default_Mem)
30 public:
31  EarClippingTriangulatorInputPolygon(MemoryHeap* heap = KY_NULL) : m_pointIndices(heap), m_edgeUserData(heap) {}
32 public:
33  KyArrayDH_POD<KyUInt32> m_pointIndices;
34  KyArrayDH_POD<void*> m_edgeUserData;
35 };
36 
37 class EarClippingTriangulatorInputPolygonWithHoles
38 {
39  KY_DEFINE_NEW_DELETE_OPERATORS(Stat_Default_Mem)
40 public:
41  EarClippingTriangulatorInputPolygonWithHoles(MemoryHeap* heap = Memory::GetGlobalHeap()) : m_points(heap), m_exterior(heap), m_holes(heap) {}
42  void Clear()
43  {
44  m_points.Clear();
45  m_holes.Clear();
46  m_exterior.m_pointIndices.Clear();
47  m_exterior.m_edgeUserData.Clear();
48  }
49 public:
50  KyArrayDH_POD<Vec2i> m_points;
51  EarClippingTriangulatorInputPolygon m_exterior;
52  KyArrayDH<EarClippingTriangulatorInputPolygon> m_holes;
53 };
54 
55 class EarClippingTriangulator
56 {
57  KY_DEFINE_NEW_DELETE_OPERATORS(Stat_Default_Mem)
58 public:
59  typedef KyUInt16 PolygonVertexIdx;
60  static const PolygonVertexIdx PolygonVertexIdx_Invalid = KyUInt16MAXVAL;
61 
62  class PolygonVertex
63  {
64  public:
65  enum Type
66  {
67  TYPE_CONVEX = 0,
68  TYPE_REFLEX = 1,
69  TYPE_EAR = 2,
70  TYPE_UNKNOWN
71  };
72 
73  PolygonVertex() :
74  m_posIdx(KyUInt16MAXVAL),
75  m_vertexType((KyUInt16)TYPE_UNKNOWN),
76  m_nextPolygonVertexIdx(PolygonVertexIdx_Invalid),
77  m_prevPolygonVertexIdx(PolygonVertexIdx_Invalid),
78  m_duplicateVertexIdx(PolygonVertexIdx_Invalid),
79  m_edgeGoingFromNextToMe(KY_NULL)
80  {}
81 
82  Type GetVertexType() const { return (Type)m_vertexType; }
83  void SetVertexType(Type vertexType) { m_vertexType = KyUInt16(vertexType); }
84  KyUInt16 m_posIdx;
85  KyUInt16 m_vertexType;
86  PolygonVertexIdx m_nextPolygonVertexIdx;
87  PolygonVertexIdx m_prevPolygonVertexIdx;
88  PolygonVertexIdx m_duplicateVertexIdx;
89  void* m_edgeGoingFromNextToMe;
90  };
91 
92 
93 public:
94  EarClippingTriangulator(const EarClippingTriangulatorInputPolygonWithHoles& input, KyArrayDH<PolygonVertex>& workingArray,
95  DynamicTriangulation& output, MemoryHeap* heap = Memory::GetGlobalHeap()) :
96  m_heap(heap),
97  m_input(&input),
98  m_output(&output),
99  m_polygonVertices(&workingArray) {}
100 
101  KyResult BuildPolygonAndLinkHolesToExterior();
102  KyResult Triangulate();
103 
104  enum TriangulateStepResult { TriangulateStepResult_Finish, TriangulateStepResult_GoOn };
105  KyResult TriangulateStep(TriangulateStepResult& triangulateStepResult, KyUInt16& currentVertexCountInPolygon,
106  PolygonVertexIdx& firstValidVertexIdx, KyUInt32 maxTestCount);
107 public:
108 
109  class HoleIdxWithMaxXVertexIdx
110  {
111  public:
112  HoleIdxWithMaxXVertexIdx() : m_toConnectIdx(PolygonVertexIdx_Invalid) {}
113  Vec2i m_posToConnect;
114  PolygonVertexIdx m_toConnectIdx;
115  };
116 
117  class FindVertexIdxResult
118  {
119  public:
120  enum ResultType { NOTFOUND, INTERSECTION_ON_VERTEX, INTERSECTION_ON_EDGE };
121 
122  FindVertexIdxResult () : m_resultType(NOTFOUND), m_intersectionPolygonVertexIdx(PolygonVertexIdx_Invalid), m_xIntersection(KyInt32MAXVAL) {}
123 
124  void SetVertexIntersection(KyInt32 xIntersection, PolygonVertexIdx intersectionPolygonVertexIdx)
125  {
126  m_resultType = INTERSECTION_ON_VERTEX;
127  m_xIntersection = xIntersection;
128  m_intersectionPolygonVertexIdx = intersectionPolygonVertexIdx;
129  }
130 
131  void SetEdgeIntersection(const Vec2i& edgeStart, const Vec2i& edgeEnd, PolygonVertexIdx intersectionPolygonVertexIdx)
132  {
133  m_resultType = INTERSECTION_ON_EDGE;
134  m_edgeStart = edgeStart;
135  m_edgeEnd = edgeEnd;
136  m_intersectionPolygonVertexIdx = intersectionPolygonVertexIdx;
137  }
138 
139  ResultType m_resultType;
140  PolygonVertexIdx m_intersectionPolygonVertexIdx;
141  KyInt32 m_xIntersection;
142  Vec2i m_edgeStart;
143  Vec2i m_edgeEnd;
144  };
145 
146  KY_INLINE bool HasDuplicate(PolygonVertexIdx polygonVertexIdx) const { return (*m_polygonVertices)[polygonVertexIdx].m_duplicateVertexIdx != polygonVertexIdx; }
147  KY_INLINE PolygonVertex::Type GetPolygonVertexType(const Vec2i& prevPos, const Vec2i& currentPos, const Vec2i& nextPos) const
148  {
149  const KyInt32 crossProduct = (nextPos - currentPos) ^ (prevPos - currentPos);
150  return crossProduct > 0 ? PolygonVertex::TYPE_CONVEX : PolygonVertex::TYPE_REFLEX;
151  }
152 
153  void FillPolygonVerticesForExterior(PolygonVertexIdx& currentNewPolygonVertexIdx);
154  void FillPolygonVerticesForHole(const EarClippingTriangulatorInputPolygon& holePolygon, HoleIdxWithMaxXVertexIdx& currentHoleMinX, PolygonVertexIdx& currentNewPolygonVertexIdx);
155 
156  KyResult LinkHoleToExterior(HoleIdxWithMaxXVertexIdx& currentHoleMinX, PolygonVertexIdx& currentNewPolygonVertexIdx);
157  KyUInt32 FindAndClipEar(PolygonVertexIdx& firstValidVertexIdx, KyUInt32& vertexTestedCount); // return the number of removed PolygonVertices
158 
159  void FindPolygonVertexIdxToLinkTo(KyUInt32 posToConnectIdx, FindVertexIdxResult& result);
160  void FindPolygonVertexIdxToLinkToForEdgeIntersection(KyUInt32 posToConnectIdx, FindVertexIdxResult& result);
161  PolygonVertexIdx FindBestCandidateForHoleConnection(KyUInt32 posToConnectIdx);
162  bool IsInAngularSectorOfVertex(const Vec2i& posToConnect, const PolygonVertex* polygonVertex) const;
163 
164 
165  bool IsPolygonVertexAnEar(const PolygonVertex* polygonVertex, KyUInt32& vertexTestedCount) const;
166  void UpdateVertexConvexStatus(PolygonVertex* polygonVertex);
167 
168  void PrintInputPolygonForDebug();
169 
170  static bool DoesPreviousEdgeIntersectsXAxisBeforeCurrentEdge(const Vec2i& prevEdgeStart, const Vec2i& prevEdgeEnd, const Vec2i& currEdgeStart, const Vec2i& currEdgeEnd);
171 public:
172  MemoryHeap* m_heap;
173  const EarClippingTriangulatorInputPolygonWithHoles* m_input;
174  DynamicTriangulation* m_output;
175  KyArrayDH<PolygonVertex>* m_polygonVertices; // the "linked" polygon structure
176 };
177 
178 } // namespace Kaim
179 
180 #endif //Navigation_EarClippingTriangulator_H
KyInt32 KyResult
Defines a type that can be returned by methods or functions in the Gameware Navigation SDK to indicat...
Definition: types.h:254
int KyInt32
Type used internally to represent a 32-bit integer.
Definition: types.h:35
#define KY_NULL
Null value.
Definition: types.h:247
#define KyInt32MAXVAL
The maximum value that can be stored in the KyInt32 variable type.
Definition: types.h:224
Definition: gamekitcrowddispersion.h:20
#define KY_DEFINE_NEW_DELETE_OPERATORS(MemStat)
This macro defines new and delete operators.
Definition: memory.h:137
#define KyUInt16MAXVAL
The maximum value that can be stored in the KyUInt16 variable type.
Definition: types.h:230
unsigned short KyUInt16
Type used internally to represent an unsigned 16-bit integer.
Definition: types.h:40
unsigned int KyUInt32
Type used internally to represent an unsigned 32-bit integer.
Definition: types.h:36