diff --git a/source/simulation2/components/CCmpPathfinder_Common.h b/source/simulation2/components/CCmpPathfinder_Common.h index 4d750ecfba..13a604988d 100644 --- a/source/simulation2/components/CCmpPathfinder_Common.h +++ b/source/simulation2/components/CCmpPathfinder_Common.h @@ -72,6 +72,49 @@ struct AsyncShortPathRequest entity_id_t notify; }; +// A vertex around the corners of an obstruction +// (paths will be sequences of these vertexes) +struct Vertex +{ + enum + { + UNEXPLORED, + OPEN, + CLOSED, + }; + + CFixedVector2D p; + fixed g, h; + u16 pred; + u8 status; + u8 quadInward : 4; // the quadrant which is inside the shape (or NONE) + u8 quadOutward : 4; // the quadrants of the next point on the path which this vertex must be in, given 'pred' +}; + +// Obstruction edges (paths will not cross any of these). +// Defines the two points of the edge. +struct Edge +{ + CFixedVector2D p0, p1; +}; + +// Axis-aligned obstruction squares (paths will not cross any of these). +// Defines the opposing corners of an axis-aligned square +// (from which four individual edges can be trivially computed), requiring p0 <= p1 +struct Square +{ + CFixedVector2D p0, p1; +}; + +// Axis-aligned obstruction edges. +// p0 defines one end; c1 is either the X or Y coordinate of the other end, +// depending on the context in which this is used. +struct EdgeAA +{ + CFixedVector2D p0; + fixed c1; +}; + /** * Implementation of ICmpPathfinder */ @@ -122,6 +165,21 @@ public: u16 m_MaxSameTurnMoves; // max number of moves that can be created and processed in the same turn + // memory optimizations: those vectors are created once, reused for all calculations; + std::vector edgesUnaligned; + std::vector edgesLeft; + std::vector edgesRight; + std::vector edgesBottom; + std::vector edgesTop; + + // List of obstruction vertexes (plus start/end points); we'll try to find paths through + // the graph defined by these vertexes + std::vector vertexes; + // List of collision edges - paths must never cross these. + // (Edges are one-sided so intersections are fine in one direction, but not the other direction.) + std::vector edges; + std::vector edgeSquares; // axis-aligned squares; equivalent to 4 edges + bool m_DebugOverlay; std::vector m_DebugOverlayShortPathLines; AtlasOverlay* m_AtlasOverlay; diff --git a/source/simulation2/components/CCmpPathfinder_Vertex.cpp b/source/simulation2/components/CCmpPathfinder_Vertex.cpp index 6ed042c064..ee8cdd2658 100644 --- a/source/simulation2/components/CCmpPathfinder_Vertex.cpp +++ b/source/simulation2/components/CCmpPathfinder_Vertex.cpp @@ -362,12 +362,12 @@ static void AddTerrainEdges(std::vector& edges, std::vector& verte } // XXX rewrite this stuff - + std::vector segmentsR; + std::vector segmentsL; for (int j = j0; j < j1; ++j) { - std::vector segmentsR; - std::vector segmentsL; - + segmentsR.clear(); + segmentsL.clear(); for (int i = i0; i <= i1; ++i) { bool a = IS_PASSABLE(grid.get(i, j+1), passClass); @@ -420,12 +420,12 @@ static void AddTerrainEdges(std::vector& edges, std::vector& verte } } } - + std::vector segmentsU; + std::vector segmentsD; for (int i = i0; i < i1; ++i) { - std::vector segmentsU; - std::vector segmentsD; - + segmentsU.clear(); + segmentsD.clear(); for (int j = j0; j <= j1; ++j) { bool a = IS_PASSABLE(grid.get(i+1, j), passClass); @@ -487,10 +487,6 @@ static void SplitAAEdges(const CFixedVector2D& a, std::vector& edgesLeft, std::vector& edgesRight, std::vector& edgesBottom, std::vector& edgesTop) { - edgesLeft.reserve(squares.size()); - edgesRight.reserve(squares.size()); - edgesBottom.reserve(squares.size()); - edgesTop.reserve(squares.size()); for (const Square& square : squares) { @@ -594,8 +590,8 @@ void CCmpPathfinder::ComputeShortPath(const IObstructionTestFilter& filter, // List of collision edges - paths must never cross these. // (Edges are one-sided so intersections are fine in one direction, but not the other direction.) - std::vector edges; - std::vector edgeSquares; // axis-aligned squares; equivalent to 4 edges + edges.clear(); + edgeSquares.clear(); // axis-aligned squares; equivalent to 4 edges // Create impassable edges at the max-range boundary, so we can't escape the region // where we're meant to be searching @@ -609,7 +605,7 @@ void CCmpPathfinder::ComputeShortPath(const IObstructionTestFilter& filter, // List of obstruction vertexes (plus start/end points); we'll try to find paths through // the graph defined by these vertexes - std::vector vertexes; + vertexes.clear(); // Add the start point to the graph CFixedVector2D posStart(x0, z0); @@ -833,11 +829,11 @@ void CCmpPathfinder::ComputeShortPath(const IObstructionTestFilter& filter, if (edgeSquares.size() > 8) std::partial_sort(edgeSquares.begin(), edgeSquares.begin() + 8, edgeSquares.end(), SquareSort(vertexes[curr.id].p)); - std::vector edgesUnaligned; - std::vector edgesLeft; - std::vector edgesRight; - std::vector edgesBottom; - std::vector edgesTop; + edgesUnaligned.clear(); + edgesLeft.clear(); + edgesRight.clear(); + edgesBottom.clear(); + edgesTop.clear(); SplitAAEdges(vertexes[curr.id].p, edges, edgeSquares, edgesUnaligned, edgesLeft, edgesRight, edgesBottom, edgesTop); // Check the lines to every other vertex