Changeset View
Changeset View
Standalone View
Standalone View
source/simulation2/helpers/Rasterize.cpp
Show All 19 Lines | |||||
#include "Rasterize.h" | #include "Rasterize.h" | ||||
#include "simulation2/helpers/Geometry.h" | #include "simulation2/helpers/Geometry.h" | ||||
void SimRasterize::RasterizeRectWithClearance(Spans& spans, | void SimRasterize::RasterizeRectWithClearance(Spans& spans, | ||||
const ICmpObstructionManager::ObstructionSquare& shape, | const ICmpObstructionManager::ObstructionSquare& shape, | ||||
entity_pos_t clearance, entity_pos_t cellSize) | entity_pos_t clearance, entity_pos_t cellSize) | ||||
{ | { | ||||
// A long-standing issue with the pathfinding has been that the long-range one | // Rasterise only navcells which are strictly inside the shape (+ clearance), so that navcells are more permissive than real obstructions. | ||||
// uses a AA navcell grid, while the short-range uses an accurate vector representation. | // This makes the vertex pathfinder less permissive than the long-range pathfinder, which avoids stuck units. | ||||
// This means we could get paths accepted by one but not both pathfinders. | entity_pos_t rasterClearance = clearance; | ||||
// Since the new pathfinder, the short-range pathfinder's representation was usually | |||||
// encompassing the rasterisation of the long-range one for a building. | |||||
// This means that we could never get quite as close as the long-range pathfinder wanted. | |||||
// This could mean units tried going through impassable paths. | |||||
// To fix this, we need to make sure that the short-range pathfinder is always mostly | |||||
// included in the rasterisation. The easiest way is to rasterise more, thus this variable | |||||
// Since this is a very complicated subject, check out logs on 31/10/2015 for more detailled info. | |||||
// or ask wraitii about it. | |||||
// If the short-range pathfinder is sufficiently changed, this could become unnecessary and thus removed. | |||||
// A side effect is that the basic clearance has been set to 0.8, so removing this constant should be done | |||||
// in parallel with setting clearance back to 1 for the default passability class (though this isn't strictly necessary). | |||||
// Also: the code detecting foundation obstruction in CcmpObstructionManager had to be changed similarly. | |||||
entity_pos_t rasterClearance = clearance + Pathfinding::CLEARANCE_EXTENSION_RADIUS; | |||||
// Get the bounds of cells that might possibly be within the shape | // Get the bounds of cells that might possibly be within the shape | ||||
// (We'll then test each of those cells more precisely) | // (We'll then test each of those cells more precisely) | ||||
CFixedVector2D shapeHalfSize(CFixedVector2D(shape.hw, shape.hh)); | CFixedVector2D shapeHalfSize(CFixedVector2D(shape.hw, shape.hh)); | ||||
CFixedVector2D halfSize(shape.hw + rasterClearance, shape.hh + rasterClearance); | CFixedVector2D halfSize(shape.hw + rasterClearance, shape.hh + rasterClearance); | ||||
CFixedVector2D halfBound = Geometry::GetHalfBoundingBox(shape.u, shape.v, halfSize); | CFixedVector2D halfBound = Geometry::GetHalfBoundingBox(shape.u, shape.v, halfSize); | ||||
i16 i0 = ((shape.x - halfBound.X) / cellSize).ToInt_RoundToNegInfinity(); | i16 i0 = ((shape.x - halfBound.X) / cellSize).ToInt_RoundToNegInfinity(); | ||||
i16 j0 = ((shape.z - halfBound.Y) / cellSize).ToInt_RoundToNegInfinity(); | i16 j0 = ((shape.z - halfBound.Y) / cellSize).ToInt_RoundToNegInfinity(); | ||||
i16 i1 = ((shape.x + halfBound.X) / cellSize).ToInt_RoundToInfinity(); | i16 i1 = ((shape.x + halfBound.X) / cellSize).ToInt_RoundToInfinity(); | ||||
i16 j1 = ((shape.z + halfBound.Y) / cellSize).ToInt_RoundToInfinity(); | i16 j1 = ((shape.z + halfBound.Y) / cellSize).ToInt_RoundToInfinity(); | ||||
if (j1 <= j0) | if (j1 <= j0) | ||||
return; // empty bounds - this shouldn't happen | return; // empty bounds - this shouldn't happen | ||||
rasterClearance = rasterClearance.Multiply(rasterClearance); | rasterClearance = rasterClearance.Multiply(rasterClearance); | ||||
spans.reserve(j1 - j0); | spans.reserve(j1 - j0); | ||||
for (i16 j = j0; j < j1; ++j) | for (i16 j = j0; j < j1; ++j) | ||||
{ | { | ||||
// Find the min/max range of cells that are strictly inside the square+rasterClearance. | // Find the min/max range of cells that are strictly inside the square+rasterClearance. | ||||
// (Since the square+rasterClearance is a convex shape, we can just test each | // (Since the square+rasterClearance is a convex shape, we can just test each | ||||
▲ Show 20 Lines • Show All 59 Lines • Show Last 20 Lines |
Wildfire Games · Phabricator