23 static const KyUInt32 SWEEPLINE_CLIPPING_EXTERIOR_POLYGON_BIT = 1 << 30;
24 static const KyUInt32 SWEEPLINE_CLIPPING_HOLE_POLYGON_BIT = 1 << 29;
31 EdgePoints(
const Vec2i& start,
const Vec2i& end) : m_start(start), m_end(end) {}
33 bool operator==(
const EdgePoints& rhs)
const {
return m_start == rhs.m_start && m_end == rhs.m_end; }
34 bool operator!=(
const EdgePoints& rhs)
const {
return !operator==(rhs); }
37 KyInt32 ComputePointLocation(
const Vec2i& P)
const {
return Side(P, m_start, m_end); }
39 KY_INLINE
bool IsAnExtremityWithThisXValue(
KyInt32 x,
KyInt32& out_y)
const
41 if (m_start.x == x) { out_y = m_start.y;
return true; }
42 if (m_end.x == x) { out_y = m_end.y;
return true; }
47 const Vec2i& operator[](
KyUInt32 idx)
const { KY_ASSERT(idx <= 1);
return (&m_start)[idx]; }
54 class InputEdgeProperty
68 EDGE_FROM_TAGVOLUME = 7,
69 EDGE_FROM_UNKNOWN_ORIGIN
73 KY_INLINE InputEdgeProperty() { SetDefault(); }
74 KY_INLINE
void SetDefault()
76 m_edgeOrigin = EDGE_FROM_UNKNOWN_ORIGIN;
81 m_coordinatesFlipped =
false;
84 bool IsConnexBoundary()
const {
return (m_ownerIndex & SWEEPLINE_CLIPPING_EXTERIOR_POLYGON_BIT) != 0; }
85 bool IsHole()
const {
return (m_ownerIndex & SWEEPLINE_CLIPPING_HOLE_POLYGON_BIT) != 0; }
87 bool operator <(
const InputEdgeProperty& rhs)
const {
return m_ownerIndex < rhs.m_ownerIndex; }
88 bool operator ==(
const InputEdgeProperty& rhs)
const {
return m_ownerIndex == rhs.m_ownerIndex; }
91 EdgeOrigin m_edgeOrigin;
97 bool m_coordinatesFlipped;
106 const Vec2i& A()
const {
return m_extremities.m_start; }
107 const Vec2i& B()
const {
return m_extremities.m_end; }
110 EdgePoints m_extremities;
111 InputEdgeProperty m_property;
115 struct BasicLessHalfEdge
117 KY_INLINE
bool operator()(
const InputEdge& edge1,
const InputEdge& edge2)
const
119 if (edge1.A() != edge2.A())
120 return edge1.A() < edge2.A();
122 return edge1.B() < edge2.B();
130 InputEdgePiece() : m_parentEdge(
nullptr), m_count(0), m_index(0) {}
131 InputEdgePiece(
const EdgePoints& subSegment,
const InputEdge& parentEdge) : m_extremities(subSegment), m_parentEdge(&parentEdge), m_count(0), m_index(0) {}
133 const InputEdgeProperty& ParentProperty()
const {
return m_parentEdge->m_property; }
135 inline bool operator==(
const InputEdgePiece& other)
const
137 return A() == other.A() && B() == other.B() && GetCount() == other.GetCount();
140 inline bool operator<(
const InputEdgePiece& other)
const
142 if (A().x != other.A().x)
143 return A().x < other.A().x;
145 if (A().y != other.A().y)
146 return A().y < other.A().y;
149 return CrossProduct_15bits(AB(), other.AB()) > 0;
152 bool operator!=(
const InputEdgePiece& edge)
const {
return !((*this) == edge); }
153 bool operator>=(
const InputEdgePiece& edge)
const {
return !((*this) < edge); }
157 bool IsVertical()
const {
return A().x == B().x; }
158 KyInt32 GetCount()
const {
return m_count; }
159 const Vec2i& GetEdgeStart()
const {
return m_extremities.m_start; }
160 const Vec2i& GetEdgeEnd()
const {
return m_extremities.m_end; }
162 const Vec2i& A()
const {
return m_extremities.m_start; }
163 const Vec2i& B()
const {
return m_extremities.m_end; }
164 Vec2i AB()
const {
return B() - A(); }
166 const Vec2i& GetOriginalStart()
const
170 const KyInt32 swappedPropertyCount =
Isel(m_extremities.m_start.x - m_extremities.m_end.x, -m_count , m_count);
171 const KyInt32 extremityIdx =
Isel(swappedPropertyCount, 1, 0);
172 return m_extremities[extremityIdx];
175 const Vec2i& GetOriginalEnd()
const
179 const KyInt32 swappedPropertyCount =
Isel(m_extremities.m_start.x - m_extremities.m_end.x, -m_count , m_count);
180 const KyInt32 extremityIdx =
Isel(swappedPropertyCount, 0, 1);
181 return m_extremities[extremityIdx];
185 EdgePoints m_extremities;
186 const InputEdge* m_parentEdge;
194 class SweepLineOutputEdgePiece;
201 KyArrayPOD<Vec2i> m_points;
202 KyArrayPOD<const SweepLineOutputEdgePiece*> m_edges;
205 class MergedPolygonWithHoles
209 MergedPolygonWithHoles() {}
212 MergedPolygon m_exterior;
213 KyArray<MergedPolygon> m_holes;
216 class TriangulatorOutput
222 MergedPolygon m_referencePolygon;
223 KyArrayPOD<const SweepLineOutputEdgePiece*> m_inputEdgePiece;
224 KyArrayPOD<
KyUInt32> m_triangleEdgeIndices;
225 KyArrayPOD<
KyUInt32> m_startVertexOfEdges;
226 KyArrayPOD<
KyUInt32> m_pairEdgeIndices;
234 IndexedPos(
const Vec2i& pos,
KyUInt32 index) : m_pos(pos), m_index(index) {}
240 class IndexedPosSorter
243 KY_INLINE
bool operator() (
const IndexedPos& hotPoint1,
const IndexedPos& hotPoint2)
const
245 return hotPoint1.m_pos < hotPoint2.m_pos;
249 class EdgePointsComparatorAtX
252 inline EdgePointsComparatorAtX() : m_x(0), m_justBefore(nullptr){}
253 inline EdgePointsComparatorAtX(
KyInt32 x,
KyInt32* justBefore =
nullptr) : m_x(x), m_justBefore(justBefore){}
255 inline bool operator()(
const EdgePoints& edge1,
const EdgePoints& edge2)
const
257 KY_ASSERT(edge1.m_start != edge2.m_start || edge1.m_start.x == m_x);
258 KY_ASSERT(edge1.m_start.x <= m_x && edge1.m_end.x >= m_x);
259 KY_ASSERT(edge2.m_start.x <= m_x && edge2.m_end.x >= m_x);
261 const KyInt32 edge1Miny = FastMin(edge1.m_start.y, edge1.m_end.y);
262 const KyInt32 edge1Maxy = FastMax(edge1.m_start.y, edge1.m_end.y);
264 const KyInt32 edge2Miny = FastMin(edge2.m_start.y, edge2.m_end.y);
265 const KyInt32 edge2Maxy = FastMax(edge2.m_start.y, edge2.m_end.y);
267 if (edge1Maxy < edge2Miny)
270 if (edge1Miny > edge2Maxy)
277 KyInt32 yValueOfPointAtXOnEdge1 = 0;
278 KyInt32 yValueOfPointAtXOnEdge2 = 0;
280 bool edge1_at_x = edge1.IsAnExtremityWithThisXValue(m_x, yValueOfPointAtXOnEdge1);
281 bool edge2_at_x = edge2.IsAnExtremityWithThisXValue(m_x, yValueOfPointAtXOnEdge2);
283 if (edge1_at_x ==
false || edge2_at_x ==
false)
285 KY_LOG_ERROR_IF(edge2.m_start == edge1.m_start, (
"We know that should not happen when this function is called, except if both of them are on the m_x axis"));
291 KyInt32 edge1StartPosFromEdge2 = edge2.ComputePointLocation(edge1.m_start);
292 KyInt32 edge1EndPosFromEdge2 = edge2.ComputePointLocation(edge1.m_end);
293 if (edge1StartPosFromEdge2 == edge1EndPosFromEdge2)
296 return edge1StartPosFromEdge2 == -1;
302 KyInt32 edge2StartPosFromEdge1 = edge1.ComputePointLocation(edge2.m_start);
308 KY_LOG_ERROR_IF(edge2StartPosFromEdge1 == 0, (
"Error in comparator object"));
310 return edge2StartPosFromEdge1 == 1;
315 if (yValueOfPointAtXOnEdge1 != yValueOfPointAtXOnEdge2)
316 return yValueOfPointAtXOnEdge1 < yValueOfPointAtXOnEdge2;
321 bool edge1SlopeLessThanEdge2Slope = CrossProduct_15bits(edge1.m_end - edge1.m_start, edge2.m_end - edge2.m_start) > 0;
322 return edge1SlopeLessThanEdge2Slope == (m_justBefore ==
nullptr || (*m_justBefore) == 0);
330 class InputEdgePieceComp
333 inline bool operator() (
const InputEdgePiece& i1,
const InputEdgePiece& i2)
const
335 const EdgePoints& edge1 = i1.m_extremities;
336 const EdgePoints& edge2 = i2.m_extremities;
338 if (edge1.m_start != edge2.m_start)
339 return edge1.m_start < edge2.m_start;
341 EdgePointsComparatorAtX lhe(edge1.m_start.x);
342 return lhe(edge1, edge2);
std::uint32_t KyUInt32
uint32_t
Definition: types.h:29
KyInt32 Isel(KyInt32 a, KyInt32 x, KyInt32 y)
If a is greater than 0, returns x.
Definition: fastmath.h:26
Indicates that another NavHalfEdge in the same NavFloor but in different Connex lies adjacent to the ...
Definition: navmeshtypes.h:57
#define KY_DEFINE_NEW_DELETE_OPERATORS(MemStat)
This macro defines new and delete operators.
Definition: memory.h:132
Indicates that this NavHalfEdge lies on the border of its NavFloor and its NavCell.
Definition: navmeshtypes.h:54
Indicates that this NavHalfEdge lies on the border of its NavFloor and its NavCell.
Definition: navmeshtypes.h:51
KyInt32 Side(const Vec2i &P, const Vec2i &A, const Vec2i &B)
P relative to AB: left=1, on=0, right=-1.
Definition: vec2i.h:150
The Autodesk Navigation namespace.
Definition: gamekitcrowddispersion.cpp:17
Indicates that this NavHalfEdge lies on the border of its NavFloor.
Definition: navmeshtypes.h:55
Indicates that this NavHalfEdge lies on an external border of the NavMesh.
Definition: navmeshtypes.h:56
std::int32_t KyInt32
int32_t
Definition: types.h:24
Indicates that this NavHalfEdge lies on the border of its NavFloor and its NavCell.
Definition: navmeshtypes.h:52
Indicates that this NavHalfEdge lies on the border of its NavFloor and its NavCell.
Definition: navmeshtypes.h:53
#define KyUInt32MAXVAL
KyUInt32 max value
Definition: types.h:68