17 static const KyUInt32 MaxVertexEdgeLinkCount = 8;
24 enum EdgeInOrOut { EDGE_IN = 0, EDGE_OUT = 1 };
26 void Init(EdgeInOrOut edgeInOrOut, BoundaryEdge* edge)
29 m_edgeInOrOut = edgeInOrOut;
30 m_vertexIdxInEdge = (edgeInOrOut == EDGE_IN) ? 1 : 0;
33 void Apply(BoundaryVertex* center)
35 m_edge->m_vertex[m_vertexIdxInEdge] = center;
36 KY_ASSERT(m_edge->m_orientation < 4);
37 if (m_edgeInOrOut == EDGE_OUT)
38 center->m_outs[m_edge->m_orientation] = m_edge;
40 center->m_ins[m_edge->m_orientation] = m_edge;
44 EdgeInOrOut m_edgeInOrOut;
53 SquarePixel() { Setup(
nullptr, 0,
false); }
55 void Setup(BoundaryPixel* boundaryPixel,
KyUInt32 pixelIdxInSquare,
bool isOutsideCellBox)
57 m_boundaryPixel = boundaryPixel;
58 m_connected[0] =
nullptr;
59 m_connected[1] =
nullptr;
60 m_pixelIdxInSquare = pixelIdxInSquare;
61 m_isInPattern =
false;
62 m_isOutsideCellBox = isOutsideCellBox;
80 void PushVertexEdgeLinks(VertexEdgeLink* vertexEdgeLinks,
KyUInt32& vertexEdgeLinksCount)
const
83 CardinalDir edgeOut_IdxInPixel = GetNextCardinalDir_CCW(edgeIn_IdxInPixel);
85 BoundaryEdge* edgeIn = m_boundaryPixel->m_edges[edgeIn_IdxInPixel];
86 if (edgeIn !=
nullptr)
88 KY_ASSERT(vertexEdgeLinksCount < MaxVertexEdgeLinkCount);
89 VertexEdgeLink& link = vertexEdgeLinks[vertexEdgeLinksCount++];
90 link.Init(VertexEdgeLink::EDGE_IN, edgeIn);
93 BoundaryEdge* edgeOut = m_boundaryPixel->m_edges[edgeOut_IdxInPixel];
94 if (edgeOut !=
nullptr)
96 KY_ASSERT(vertexEdgeLinksCount < MaxVertexEdgeLinkCount);
97 VertexEdgeLink& link = vertexEdgeLinks[vertexEdgeLinksCount++];
98 link.Init(VertexEdgeLink::EDGE_OUT, edgeOut);
102 BoundaryPixel* m_boundaryPixel;
103 SquarePixel* m_connected[2];
106 bool m_isOutsideCellBox;
110 class SquarePixelColumn
114 SquarePixelColumn(
KyUInt32 squarePixelsCapacityAtInit = 50)
116 if (squarePixelsCapacityAtInit == 0)
117 squarePixelsCapacityAtInit = 50;
118 m_squarePixels.Resize(squarePixelsCapacityAtInit);
121 ~SquarePixelColumn() {}
123 void Setup(
KyUInt32 idxInSquare,
const NavBoundaryPos& pos,
const BoxOfArrays<BoundaryPixel>::Column& boundaryPixelColumn,
bool isOutsideNavBox)
126 m_squarePixels.Clear();
127 m_squarePixels.Resize(boundaryPixelColumn.m_count);
128 for (NavRasterFloorIdx floorIdx = 0; floorIdx < boundaryPixelColumn.m_count; ++floorIdx)
129 m_squarePixels[floorIdx].Setup(&boundaryPixelColumn.m_values[floorIdx], idxInSquare, isOutsideNavBox);
133 KyArrayTLS_POD<SquarePixel> m_squarePixels;
137 class ConnectionSquare
141 KY_INLINE
void SetupSquarePixelColumn(
KyUInt32 idxInSquare, const NavBoundaryPos& pos, const BoxOfArrays<BoundaryPixel>::Column& boundaryPixelColumn,
bool isOutsideNavBox)
143 m_columns[idxInSquare].Setup(idxInSquare, pos, boundaryPixelColumn, isOutsideNavBox);
146 SquarePixelColumn m_columns[4];
150 class ConnectedPattern
154 enum { CCW = 0, CW = 1 };
156 ConnectedPattern() : m_count(0)
159 m_pixels[i] =
nullptr;
162 void Init(SquarePixel* firstSquarePixel)
165 firstSquarePixel->m_isInPattern =
true;
166 m_pixels[0] = firstSquarePixel;
172 SquarePixel* squarePixel = firstSquarePixel;
175 squarePixel = squarePixel->m_connected[i];
176 if (squarePixel ==
nullptr || squarePixel->m_isInPattern ==
true)
178 squarePixel->m_isInPattern =
true;
180 m_pixels[m_count] = squarePixel;
188 KY_ASSERT(m_count != 0);
189 static const KyFloat32 florCountInv[4] = { 1.f, 0.5f, 0.333333333333f, 0.25f };
192 for (
KyUInt32 i = 0; i < m_count; ++i)
194 KY_ASSERT(m_pixels[i] !=
nullptr);
195 altitude += m_pixels[i]->m_boundaryPixel->m_navRasterPixel->m_altitude;
197 altitude *= florCountInv[m_count-1];
201 bool IsFullyOutsideCellBox()
203 KY_ASSERT(m_count != 0);
204 for (
KyUInt32 i = 0; i < m_count; ++i)
206 if (m_pixels[i]->m_isOutsideCellBox ==
false)
214 bool isBlocked[4] = {
false,
false,
false,
false };
215 bool isDeadEnd[4] = {
false,
false,
false,
false };
216 for (
KyUInt32 pixelIdx = 0; pixelIdx < m_count; ++pixelIdx)
218 SquarePixel* squarePixel = m_pixels[pixelIdx];
219 KY_ASSERT(squarePixel !=
nullptr);
221 BoundaryPixel* boundaryPixel = squarePixel->m_boundaryPixel;
222 KY_ASSERT(boundaryPixel !=
nullptr);
228 const BoundaryEdge* edges[4] =
230 boundaryPixel->m_edges[ dir ],
231 boundaryPixel->m_edges[(dir+1)%4],
232 boundaryPixel->m_edges[(dir+2)%4],
233 boundaryPixel->m_edges[(dir+3)%4]
236 if (edges[0] !=
nullptr && edges[1] !=
nullptr && edges[2] !=
nullptr)
238 isDeadEnd[pixelIdx] =
true;
239 if (edges[3] !=
nullptr)
246 if (isDeadEnd[pixelIdx] ==
false)
254 if (squarePixel->m_boundaryPixel->m_edges[ dir ] !=
nullptr &&
255 squarePixel->m_boundaryPixel->m_edges[GetOppositeCardinalDir(dir)]!= nullptr )
270 KyUInt32 rightEdgeIdx = (squarePixel->m_pixelIdxInSquare + 2) % 4;
271 KyUInt32 upEdgeIdx = (squarePixel->m_pixelIdxInSquare + 3) % 4;
272 KyUInt32 rightVtxIdx = (squarePixel->m_pixelIdxInSquare + 3) % 4;
273 KyUInt32 upVtxIdx = (squarePixel->m_pixelIdxInSquare);
275 if (isBlocked[rightVtxIdx] ==
false && squarePixel->m_boundaryPixel->m_edges[rightEdgeIdx])
276 isBlocked[rightVtxIdx] =
true;
278 if (isBlocked[upVtxIdx] ==
false && squarePixel->m_boundaryPixel->m_edges[upEdgeIdx])
279 isBlocked[upVtxIdx] =
true;
289 if (isDeadEnd[j] && isDeadEnd[(j+1)%4])
294 for (
KyUInt32 pixelIdx = 0; pixelIdx < m_count; ++pixelIdx)
296 if (isDeadEnd[pixelIdx])
299 SquarePixel* squarePixel = m_pixels[pixelIdx];
300 KY_ASSERT(squarePixel !=
nullptr);
302 SquarePixel* neighborCCW = squarePixel->m_connected[CCW];
303 if (neighborCCW !=
nullptr)
305 KyUInt32 ccwVtxIdx = (squarePixel->m_pixelIdxInSquare);
306 if (isBlocked[ccwVtxIdx] &&
307 neighborCCW->m_boundaryPixel->m_floorColor == squarePixel->m_boundaryPixel->m_floorColor &&
308 neighborCCW->m_boundaryPixel->m_connexIdx == squarePixel->m_boundaryPixel->m_connexIdx )
312 SquarePixel* neighborCW = squarePixel->m_connected[CW];
313 if (neighborCW !=
nullptr)
315 KyUInt32 cwVtxIdx = (squarePixel->m_pixelIdxInSquare + 3) % 4;
316 if (isBlocked[cwVtxIdx] &&
317 neighborCW->m_boundaryPixel->m_floorColor == squarePixel->m_boundaryPixel->m_floorColor &&
318 neighborCW->m_boundaryPixel->m_connexIdx == squarePixel->m_boundaryPixel->m_connexIdx )
326 SquarePixel* m_pixels[4];
std::uint32_t KyUInt32
uint32_t
Definition: types.h:29
KyUInt32 CardinalDir
Defines a type that refers to one of the cardinal points on the compass:
Definition: cardinaldir.h:15
#define KY_DEFINE_NEW_DELETE_OPERATORS(MemStat)
This macro defines new and delete operators.
Definition: memory.h:132
The Autodesk Navigation namespace.
Definition: gamekitcrowddispersion.cpp:17
float KyFloat32
float
Definition: types.h:32