Index: source/simulation2/helpers/Pathfinding.h =================================================================== --- source/simulation2/helpers/Pathfinding.h +++ source/simulation2/helpers/Pathfinding.h @@ -142,6 +142,11 @@ const int NAVCELLS_PER_TILE = 4; /** + * A modifier in calculating the position of outer box points for static obstructions. + */ + const fixed STATIC_OBSTRUCTION_OUTER_PATH_MODIFIER = fixed::FromFloat(6.0f); + + /** * Size of a navcell in metres ( = TERRAIN_TILE_SIZE / NAVCELLS_PER_TILE) */ const fixed NAVCELL_SIZE = fixed::FromInt((int)TERRAIN_TILE_SIZE) / Pathfinding::NAVCELLS_PER_TILE; Index: source/simulation2/helpers/VertexPathfinder.cpp =================================================================== --- source/simulation2/helpers/VertexPathfinder.cpp +++ source/simulation2/helpers/VertexPathfinder.cpp @@ -555,6 +555,9 @@ entity_pos_t pathfindClearance = request.clearance; + // Outer path clearance buffer + fixed pathOuterClearance = request.clearance.Multiply(Pathfinding::STATIC_OBSTRUCTION_OUTER_PATH_MODIFIER); + // Convert each obstruction square into collision edges and search graph vertexes for (size_t i = 0; i < squares.size(); ++i) { @@ -568,8 +571,11 @@ // Expand the vertexes by the moving unit's collision radius, to find the // closest we can get to it - CFixedVector2D hd0(squares[i].hw + pathfindClearance + EDGE_EXPAND_DELTA, squares[i].hh + pathfindClearance + EDGE_EXPAND_DELTA); - CFixedVector2D hd1(squares[i].hw + pathfindClearance + EDGE_EXPAND_DELTA, -(squares[i].hh + pathfindClearance + EDGE_EXPAND_DELTA)); + fixed expansionW = squares[i].hw + EDGE_EXPAND_DELTA; + fixed expansionH = squares[i].hh + EDGE_EXPAND_DELTA; + + CFixedVector2D hd0(expansionW + pathfindClearance, expansionH + pathfindClearance); + CFixedVector2D hd1(expansionW + pathfindClearance, -(expansionH + pathfindClearance)); // Check whether this is an axis-aligned square bool aa = (u.X == fixed::FromInt(1) && u.Y == fixed::Zero() && v.X == fixed::Zero() && v.Y == fixed::FromInt(1)); @@ -578,26 +584,67 @@ vert.status = Vertex::UNEXPLORED; vert.quadInward = QUADRANT_NONE; vert.quadOutward = QUADRANT_ALL; + + // Create new vectors for outer corners of the current square + // Note the extra condition (i >= staticShapesNb); it 'should' + // result in less conditional checks when false. vert.p.X = center.X - hd0.Dot(u); vert.p.Y = center.Y + hd0.Dot(v); if (aa) vert.quadInward = QUADRANT_BR; m_Vertexes.push_back(vert); - if (vert.p.X < rangeXMin) rangeXMin = vert.p.X; - if (vert.p.Y < rangeZMin) rangeZMin = vert.p.Y; - if (vert.p.X > rangeXMax) rangeXMax = vert.p.X; - if (vert.p.Y > rangeZMax) rangeZMax = vert.p.Y; + if (i >= staticShapesNb){ + if (vert.p.X < rangeXMin) rangeXMin = vert.p.X; + if (vert.p.Y < rangeZMin) rangeZMin = vert.p.Y; + if (vert.p.X > rangeXMax) rangeXMax = vert.p.X; + if (vert.p.Y > rangeZMax) rangeZMax = vert.p.Y; + } vert.p.X = center.X - hd1.Dot(u); vert.p.Y = center.Y + hd1.Dot(v); if (aa) vert.quadInward = QUADRANT_TR; m_Vertexes.push_back(vert); - if (vert.p.X < rangeXMin) rangeXMin = vert.p.X; - if (vert.p.Y < rangeZMin) rangeZMin = vert.p.Y; - if (vert.p.X > rangeXMax) rangeXMax = vert.p.X; - if (vert.p.Y > rangeZMax) rangeZMax = vert.p.Y; + if (i >= staticShapesNb){ + if (vert.p.X < rangeXMin) rangeXMin = vert.p.X; + if (vert.p.Y < rangeZMin) rangeZMin = vert.p.Y; + if (vert.p.X > rangeXMax) rangeXMax = vert.p.X; + if (vert.p.Y > rangeZMax) rangeZMax = vert.p.Y; + } vert.p.X = center.X + hd0.Dot(u); vert.p.Y = center.Y - hd0.Dot(v); if (aa) vert.quadInward = QUADRANT_TL; m_Vertexes.push_back(vert); - if (vert.p.X < rangeXMin) rangeXMin = vert.p.X; - if (vert.p.Y < rangeZMin) rangeZMin = vert.p.Y; - if (vert.p.X > rangeXMax) rangeXMax = vert.p.X; - if (vert.p.Y > rangeZMax) rangeZMax = vert.p.Y; + if (i >= staticShapesNb){ + if (vert.p.X < rangeXMin) rangeXMin = vert.p.X; + if (vert.p.Y < rangeZMin) rangeZMin = vert.p.Y; + if (vert.p.X > rangeXMax) rangeXMax = vert.p.X; + if (vert.p.Y > rangeZMax) rangeZMax = vert.p.Y; + } vert.p.X = center.X + hd1.Dot(u); vert.p.Y = center.Y - hd1.Dot(v); if (aa) vert.quadInward = QUADRANT_BL; m_Vertexes.push_back(vert); - if (vert.p.X < rangeXMin) rangeXMin = vert.p.X; - if (vert.p.Y < rangeZMin) rangeZMin = vert.p.Y; - if (vert.p.X > rangeXMax) rangeXMax = vert.p.X; - if (vert.p.Y > rangeZMax) rangeZMax = vert.p.Y; + if (i >= staticShapesNb){ + if (vert.p.X < rangeXMin) rangeXMin = vert.p.X; + if (vert.p.Y < rangeZMin) rangeZMin = vert.p.Y; + if (vert.p.X > rangeXMax) rangeXMax = vert.p.X; + if (vert.p.Y > rangeZMax) rangeZMax = vert.p.Y; + } + + // Additionally, compute the outer corner vertices + if (i < staticShapesNb) + { + CFixedVector2D hd0Outer(expansionW + pathOuterClearance, expansionH + pathOuterClearance); + CFixedVector2D hd1Outer(expansionW + pathOuterClearance, -(expansionH + pathOuterClearance)); + + vert.p.X = center.X - hd0Outer.Dot(u); vert.p.Y = center.Y + hd0Outer.Dot(v); if (aa) vert.quadInward = QUADRANT_BR; m_Vertexes.push_back(vert); + if (vert.p.X < rangeXMin) rangeXMin = vert.p.X; + if (vert.p.Y < rangeZMin) rangeZMin = vert.p.Y; + if (vert.p.X > rangeXMax) rangeXMax = vert.p.X; + if (vert.p.Y > rangeZMax) rangeZMax = vert.p.Y; + vert.p.X = center.X - hd1Outer.Dot(u); vert.p.Y = center.Y + hd1Outer.Dot(v); if (aa) vert.quadInward = QUADRANT_TR; m_Vertexes.push_back(vert); + if (vert.p.X < rangeXMin) rangeXMin = vert.p.X; + if (vert.p.Y < rangeZMin) rangeZMin = vert.p.Y; + if (vert.p.X > rangeXMax) rangeXMax = vert.p.X; + if (vert.p.Y > rangeZMax) rangeZMax = vert.p.Y; + vert.p.X = center.X + hd0Outer.Dot(u); vert.p.Y = center.Y - hd0Outer.Dot(v); if (aa) vert.quadInward = QUADRANT_TL; m_Vertexes.push_back(vert); + if (vert.p.X < rangeXMin) rangeXMin = vert.p.X; + if (vert.p.Y < rangeZMin) rangeZMin = vert.p.Y; + if (vert.p.X > rangeXMax) rangeXMax = vert.p.X; + if (vert.p.Y > rangeZMax) rangeZMax = vert.p.Y; + vert.p.X = center.X + hd1Outer.Dot(u); vert.p.Y = center.Y - hd1Outer.Dot(v); if (aa) vert.quadInward = QUADRANT_BL; m_Vertexes.push_back(vert); + if (vert.p.X < rangeXMin) rangeXMin = vert.p.X; + if (vert.p.Y < rangeZMin) rangeZMin = vert.p.Y; + if (vert.p.X > rangeXMax) rangeXMax = vert.p.X; + if (vert.p.Y > rangeZMax) rangeZMax = vert.p.Y; + } + // Add the edges: