1
0
forked from 0ad/0ad

Change the shape rasterization to not use DistanceToSquare, which often called sqrt. This apparently reduces total turn time by as much as 5% (!)

Refs #3368

This was SVN commit r17207.
This commit is contained in:
wraitii 2015-11-08 17:24:59 +00:00
parent cb025bb725
commit fe040c695f
3 changed files with 53 additions and 4 deletions

View File

@ -114,6 +114,46 @@ fixed Geometry::DistanceToSquare(CFixedVector2D point, CFixedVector2D u, CFixedV
}
}
// Same as above except it does not use Length.
// For explanations refer to DistanceToSquare
fixed Geometry::DistanceToSquareSquared(CFixedVector2D point, CFixedVector2D u, CFixedVector2D v, CFixedVector2D halfSize, bool countInsideAsZero)
{
fixed du = point.Dot(u);
fixed dv = point.Dot(v);
fixed hw = halfSize.X;
fixed hh = halfSize.Y;
if (-hw < du && du < hw) // regions B, I, G
{
fixed closest = (dv.Absolute() - hh).Multiply(dv.Absolute() - hh); // horizontal edges
if (-hh < dv && dv < hh) // region I
closest = countInsideAsZero ? fixed::Zero() : std::min(closest, (du.Absolute() - hw).Multiply(du.Absolute() - hw)); // vertical edges
return closest;
}
else if (-hh < dv && dv < hh) // regions D, E
{
return (du.Absolute() - hw).Multiply(du.Absolute() - hw); // vertical edges
}
else // regions A, C, F, H
{
CFixedVector2D corner;
if (du < fixed::Zero()) // A, F
corner -= u.Multiply(hw);
else // C, H
corner += u.Multiply(hw);
if (dv < fixed::Zero()) // F, H
corner -= v.Multiply(hh);
else // A, C
corner += v.Multiply(hh);
CFixedVector2D result(corner-point);
return (result.X.Multiply(result.X) + result.Y.Multiply(result.Y));
}
}
CFixedVector2D Geometry::NearestPointOnSquare(CFixedVector2D point, CFixedVector2D u, CFixedVector2D v, CFixedVector2D halfSize)
{
/*

View File

@ -71,6 +71,12 @@ fixed DistanceToSquare(CFixedVector2D point,
CFixedVector2D u, CFixedVector2D v, CFixedVector2D halfSize,
bool countInsideAsZero = false);
/**
* Similar to above but never uses sqrt, so it returns the squared distance.
*/
fixed DistanceToSquareSquared(CFixedVector2D point,
CFixedVector2D u, CFixedVector2D v, CFixedVector2D halfSize,
bool countInsideAsZero = false);
/**
* Returns a point on the boundary of the given rotated rectangle
* that is closest (or equally closest) to the given point

View File

@ -54,6 +54,9 @@ void SimRasterize::RasterizeRectWithClearance(Spans& spans,
if (j1 <= j0)
return; // empty bounds - this shouldn't happen
rasterClearance = rasterClearance.Multiply(rasterClearance);
spans.reserve(j1 - j0);
for (i16 j = j0; j < j1; ++j)
@ -66,28 +69,28 @@ void SimRasterize::RasterizeRectWithClearance(Spans& spans,
i16 spanI1 = std::numeric_limits<i16>::min();
for (i16 i = i0; i < i1; ++i)
{
if (Geometry::DistanceToSquare(
if (Geometry::DistanceToSquareSquared(
CFixedVector2D(cellSize*i, cellSize*j) - CFixedVector2D(shape.x, shape.z),
shape.u, shape.v, CFixedVector2D(shape.hw, shape.hh), true) > rasterClearance)
{
continue;
}
if (Geometry::DistanceToSquare(
if (Geometry::DistanceToSquareSquared(
CFixedVector2D(cellSize*(i+1), cellSize*j) - CFixedVector2D(shape.x, shape.z),
shape.u, shape.v, CFixedVector2D(shape.hw, shape.hh), true) > rasterClearance)
{
continue;
}
if (Geometry::DistanceToSquare(
if (Geometry::DistanceToSquareSquared(
CFixedVector2D(cellSize*i, cellSize*(j+1)) - CFixedVector2D(shape.x, shape.z),
shape.u, shape.v, CFixedVector2D(shape.hw, shape.hh), true) > rasterClearance)
{
continue;
}
if (Geometry::DistanceToSquare(
if (Geometry::DistanceToSquareSquared(
CFixedVector2D(cellSize*(i+1), cellSize*(j+1)) - CFixedVector2D(shape.x, shape.z),
shape.u, shape.v, CFixedVector2D(shape.hw, shape.hh), true) > rasterClearance)
{