Changeset View
Changeset View
Standalone View
Standalone View
0ad/source/simulation2/helpers/Geometry.cpp
Show All 21 Lines | |||||
namespace Geometry | namespace Geometry | ||||
{ | { | ||||
// TODO: all of these things could be optimised quite easily | // TODO: all of these things could be optimised quite easily | ||||
CFixedVector2D GetHalfBoundingBox(const CFixedVector2D& u, const CFixedVector2D& v, const CFixedVector2D& halfSize) | CFixedVector2D GetHalfBoundingBox(const CFixedVector2D& u, const CFixedVector2D& v, const CFixedVector2D& halfSize) | ||||
{ | { | ||||
return CFixedVector2D( | return CFixedVector2D( | ||||
u.X.Multiply(halfSize.X).Absolute() + v.X.Multiply(halfSize.Y).Absolute(), | u.getX().Multiply(halfSize.getX()).Absolute() + v.getX().Multiply(halfSize.getY()).Absolute(), | ||||
u.Y.Multiply(halfSize.X).Absolute() + v.Y.Multiply(halfSize.Y).Absolute() | u.getY().Multiply(halfSize.getX()).Absolute() + v.getY().Multiply(halfSize.getY()).Absolute() | ||||
); | ); | ||||
} | } | ||||
fixed DistanceToSquare(const CFixedVector2D& point, const CFixedVector2D& u, const CFixedVector2D& v, const CFixedVector2D& halfSize, bool countInsideAsZero) | fixed DistanceToSquare(const CFixedVector2D& point, const CFixedVector2D& u, const CFixedVector2D& v, const CFixedVector2D& halfSize, bool countInsideAsZero) | ||||
{ | { | ||||
/* | /* | ||||
* Relative to its own coordinate system, we have a square like: | * Relative to its own coordinate system, we have a square like: | ||||
* | * | ||||
Show All 20 Lines | fixed DistanceToSquare(const CFixedVector2D& point, const CFixedVector2D& u, const CFixedVector2D& v, const CFixedVector2D& halfSize, bool countInsideAsZero) | ||||
* | * | ||||
*/ | */ | ||||
// By symmetry (taking absolute values), we work only in the 0-B-C-E quadrant | // By symmetry (taking absolute values), we work only in the 0-B-C-E quadrant | ||||
// du, dv are the location of the point in the square's coordinate system | // du, dv are the location of the point in the square's coordinate system | ||||
fixed du = point.Dot(u).Absolute(); | fixed du = point.Dot(u).Absolute(); | ||||
fixed dv = point.Dot(v).Absolute(); | fixed dv = point.Dot(v).Absolute(); | ||||
fixed hw = halfSize.X; | fixed hw = halfSize.getX(); | ||||
fixed hh = halfSize.Y; | fixed hh = halfSize.getY(); | ||||
if (du < hw) // regions B, I, G | if (du < hw) // regions B, I, G | ||||
{ | { | ||||
if (dv < hh) // region I | if (dv < hh) // region I | ||||
return countInsideAsZero ? fixed::Zero() : std::min(hw - du, hh - dv); | return countInsideAsZero ? fixed::Zero() : std::min(hw - du, hh - dv); | ||||
else | else | ||||
return dv - hh; | return dv - hh; | ||||
} | } | ||||
Show All 10 Lines | |||||
// Same as above except it does not use Length | // Same as above except it does not use Length | ||||
// For explanations refer to DistanceToSquare | // For explanations refer to DistanceToSquare | ||||
fixed DistanceToSquareSquared(const CFixedVector2D& point, const CFixedVector2D& u, const CFixedVector2D& v, const CFixedVector2D& halfSize, bool countInsideAsZero) | fixed DistanceToSquareSquared(const CFixedVector2D& point, const CFixedVector2D& u, const CFixedVector2D& v, const CFixedVector2D& halfSize, bool countInsideAsZero) | ||||
{ | { | ||||
fixed du = point.Dot(u).Absolute(); | fixed du = point.Dot(u).Absolute(); | ||||
fixed dv = point.Dot(v).Absolute(); | fixed dv = point.Dot(v).Absolute(); | ||||
fixed hw = halfSize.X; | fixed hw = halfSize.getX(); | ||||
fixed hh = halfSize.Y; | fixed hh = halfSize.getY(); | ||||
if (du < hw) // regions B, I, G | if (du < hw) // regions B, I, G | ||||
{ | { | ||||
if (dv < hh) // region I | if (dv < hh) // region I | ||||
return countInsideAsZero ? fixed::Zero() : std::min((hw - du).Square(), (hh - dv).Square()); | return countInsideAsZero ? fixed::Zero() : std::min((hw - du).Square(), (hh - dv).Square()); | ||||
else | else | ||||
return (dv - hh).Square(); // horizontal edges | return (dv - hh).Square(); // horizontal edges | ||||
} | } | ||||
Show All 33 Lines | CFixedVector2D NearestPointOnSquare(const CFixedVector2D& point, const CFixedVector2D& u, const CFixedVector2D& v, const CFixedVector2D& halfSize) | ||||
* So we just need to check all of the regions to work out which calculations to apply. | * So we just need to check all of the regions to work out which calculations to apply. | ||||
* | * | ||||
*/ | */ | ||||
// du, dv are the location of the point in the square's coordinate system | // du, dv are the location of the point in the square's coordinate system | ||||
fixed du = point.Dot(u); | fixed du = point.Dot(u); | ||||
fixed dv = point.Dot(v); | fixed dv = point.Dot(v); | ||||
fixed hw = halfSize.X; | fixed hw = halfSize.getX(); | ||||
fixed hh = halfSize.Y; | fixed hh = halfSize.getY(); | ||||
if (-hw < du && du < hw) // regions B, G; or regions D, E inside the square | if (-hw < du && du < hw) // regions B, G; or regions D, E inside the square | ||||
{ | { | ||||
if (-hh < dv && dv < hh && (du.Absolute() - hw).Absolute() < (dv.Absolute() - hh).Absolute()) // regions D, E | if (-hh < dv && dv < hh && (du.Absolute() - hw).Absolute() < (dv.Absolute() - hh).Absolute()) // regions D, E | ||||
{ | { | ||||
if (du >= fixed::Zero()) // E | if (du >= fixed::Zero()) // E | ||||
return u.Multiply(hw) + v.Multiply(dv); | return u.Multiply(hw) + v.Multiply(dv); | ||||
else // D | else // D | ||||
Show All 34 Lines | |||||
{ | { | ||||
/* | /* | ||||
* The shortest distance between two non colliding squares equals the distance between a corner | * The shortest distance between two non colliding squares equals the distance between a corner | ||||
* and other square. Thus calculating all 8 those distances and taking the smallest. | * and other square. Thus calculating all 8 those distances and taking the smallest. | ||||
* For colliding squares we simply return 0. When one of the points is inside the other square | * For colliding squares we simply return 0. When one of the points is inside the other square | ||||
* we depend on DistanceToSquare's countInsideAsZero. When no point is inside the other square, | * we depend on DistanceToSquare's countInsideAsZero. When no point is inside the other square, | ||||
* it is enough to check that two adjacent edges of one square does not collide with the other square. | * it is enough to check that two adjacent edges of one square does not collide with the other square. | ||||
*/ | */ | ||||
fixed hw1 = halfSize1.X; | fixed hw1 = halfSize1.getX(); | ||||
fixed hh1 = halfSize1.Y; | fixed hh1 = halfSize1.getY(); | ||||
fixed hw2 = halfSize2.X; | fixed hw2 = halfSize2.getX(); | ||||
fixed hh2 = halfSize2.Y; | fixed hh2 = halfSize2.getY(); | ||||
if (TestRaySquare(relativePos + u1.Multiply(hw1) + v1.Multiply(hh1), relativePos - u1.Multiply(hw1) + v1.Multiply(hh1), u2, v2, halfSize2) || | if (TestRaySquare(relativePos + u1.Multiply(hw1) + v1.Multiply(hh1), relativePos - u1.Multiply(hw1) + v1.Multiply(hh1), u2, v2, halfSize2) || | ||||
TestRaySquare(relativePos + u1.Multiply(hw1) + v1.Multiply(hh1), relativePos + u1.Multiply(hw1) - v1.Multiply(hh1), u2, v2, halfSize2)) | TestRaySquare(relativePos + u1.Multiply(hw1) + v1.Multiply(hh1), relativePos + u1.Multiply(hw1) - v1.Multiply(hh1), u2, v2, halfSize2)) | ||||
return fixed::Zero(); | return fixed::Zero(); | ||||
return std::min(std::min(std::min( | return std::min(std::min(std::min( | ||||
DistanceToSquare(relativePos + u1.Multiply(hw1) + v1.Multiply(hh1), u2, v2, halfSize2, true), | DistanceToSquare(relativePos + u1.Multiply(hw1) + v1.Multiply(hh1), u2, v2, halfSize2, true), | ||||
DistanceToSquare(relativePos + u1.Multiply(hw1) - v1.Multiply(hh1), u2, v2, halfSize2, true)), | DistanceToSquare(relativePos + u1.Multiply(hw1) - v1.Multiply(hh1), u2, v2, halfSize2, true)), | ||||
std::min( | std::min( | ||||
DistanceToSquare(relativePos - u1.Multiply(hw1) + v1.Multiply(hh1), u2, v2, halfSize2, true), | DistanceToSquare(relativePos - u1.Multiply(hw1) + v1.Multiply(hh1), u2, v2, halfSize2, true), | ||||
DistanceToSquare(relativePos - u1.Multiply(hw1) - v1.Multiply(hh1), u2, v2, halfSize2, true))), | DistanceToSquare(relativePos - u1.Multiply(hw1) - v1.Multiply(hh1), u2, v2, halfSize2, true))), | ||||
std::min(std::min( | std::min(std::min( | ||||
DistanceToSquare(relativePos + u2.Multiply(hw2) + v2.Multiply(hh2), u1, v1, halfSize1, true), | DistanceToSquare(relativePos + u2.Multiply(hw2) + v2.Multiply(hh2), u1, v1, halfSize1, true), | ||||
DistanceToSquare(relativePos + u2.Multiply(hw2) - v2.Multiply(hh2), u1, v1, halfSize1, true)), | DistanceToSquare(relativePos + u2.Multiply(hw2) - v2.Multiply(hh2), u1, v1, halfSize1, true)), | ||||
std::min( | std::min( | ||||
DistanceToSquare(relativePos - u2.Multiply(hw2) + v2.Multiply(hh2), u1, v1, halfSize1, true), | DistanceToSquare(relativePos - u2.Multiply(hw2) + v2.Multiply(hh2), u1, v1, halfSize1, true), | ||||
DistanceToSquare(relativePos - u2.Multiply(hw2) - v2.Multiply(hh2), u1, v1, halfSize1, true)))); | DistanceToSquare(relativePos - u2.Multiply(hw2) - v2.Multiply(hh2), u1, v1, halfSize1, true)))); | ||||
} | } | ||||
fixed MaxDistanceToSquare(const CFixedVector2D& point, const CFixedVector2D& u, const CFixedVector2D& v, const CFixedVector2D& halfSize, bool countInsideAsZero) | fixed MaxDistanceToSquare(const CFixedVector2D& point, const CFixedVector2D& u, const CFixedVector2D& v, const CFixedVector2D& halfSize, bool countInsideAsZero) | ||||
{ | { | ||||
fixed hw = halfSize.X; | fixed hw = halfSize.getX(); | ||||
fixed hh = halfSize.Y; | fixed hh = halfSize.getY(); | ||||
if (point.Dot(u).Absolute() < hw && point.Dot(v).Absolute() < hh && countInsideAsZero) | if (point.Dot(u).Absolute() < hw && point.Dot(v).Absolute() < hh && countInsideAsZero) | ||||
return fixed::Zero(); | return fixed::Zero(); | ||||
/* | /* | ||||
* The maximum distance from a point to an edge of a square equals the greatest distance | * The maximum distance from a point to an edge of a square equals the greatest distance | ||||
* from the point to the a corner. Thus calculating all and taking the greatest. | * from the point to the a corner. Thus calculating all and taking the greatest. | ||||
*/ | */ | ||||
return std::max(std::max( | return std::max(std::max( | ||||
(point + u.Multiply(hw) + v.Multiply(hh)).Length(), | (point + u.Multiply(hw) + v.Multiply(hh)).Length(), | ||||
(point + u.Multiply(hw) - v.Multiply(hh)).Length()), | (point + u.Multiply(hw) - v.Multiply(hh)).Length()), | ||||
std::max( | std::max( | ||||
(point - u.Multiply(hw) + v.Multiply(hh)).Length(), | (point - u.Multiply(hw) + v.Multiply(hh)).Length(), | ||||
(point - u.Multiply(hw) - v.Multiply(hh)).Length())); | (point - u.Multiply(hw) - v.Multiply(hh)).Length())); | ||||
} | } | ||||
fixed MaxDistanceSquareToSquare(const CFixedVector2D& relativePos, const CFixedVector2D& u1, const CFixedVector2D& v1, const CFixedVector2D& halfSize1, const CFixedVector2D& u2, const CFixedVector2D& v2, const CFixedVector2D& halfSize2) | fixed MaxDistanceSquareToSquare(const CFixedVector2D& relativePos, const CFixedVector2D& u1, const CFixedVector2D& v1, const CFixedVector2D& halfSize1, const CFixedVector2D& u2, const CFixedVector2D& v2, const CFixedVector2D& halfSize2) | ||||
{ | { | ||||
/* | /* | ||||
* The maximum distance from an edge of a square to the edge of another square | * The maximum distance from an edge of a square to the edge of another square | ||||
* equals the greatest distance from the any of the 16 corner corner distances. | * equals the greatest distance from the any of the 16 corner corner distances. | ||||
*/ | */ | ||||
fixed hw1 = halfSize1.X; | fixed hw1 = halfSize1.getX(); | ||||
fixed hh1 = halfSize1.Y; | fixed hh1 = halfSize1.getY(); | ||||
return std::max(std::max( | return std::max(std::max( | ||||
MaxDistanceToSquare(relativePos + u1.Multiply(hw1) + v1.Multiply(hh1), u2, v2, halfSize2, true), | MaxDistanceToSquare(relativePos + u1.Multiply(hw1) + v1.Multiply(hh1), u2, v2, halfSize2, true), | ||||
MaxDistanceToSquare(relativePos + u1.Multiply(hw1) - v1.Multiply(hh1), u2, v2, halfSize2, true)), | MaxDistanceToSquare(relativePos + u1.Multiply(hw1) - v1.Multiply(hh1), u2, v2, halfSize2, true)), | ||||
std::max(MaxDistanceToSquare(relativePos - u1.Multiply(hw1) + v1.Multiply(hh1), u2, v2, halfSize2, true), | std::max(MaxDistanceToSquare(relativePos - u1.Multiply(hw1) + v1.Multiply(hh1), u2, v2, halfSize2, true), | ||||
MaxDistanceToSquare(relativePos - u1.Multiply(hw1) - v1.Multiply(hh1), u2, v2, halfSize2, true))); | MaxDistanceToSquare(relativePos - u1.Multiply(hw1) - v1.Multiply(hh1), u2, v2, halfSize2, true))); | ||||
} | } | ||||
bool TestRaySquare(const CFixedVector2D& a, const CFixedVector2D& b, const CFixedVector2D& u, const CFixedVector2D& v, const CFixedVector2D& halfSize) | bool TestRaySquare(const CFixedVector2D& a, const CFixedVector2D& b, const CFixedVector2D& u, const CFixedVector2D& v, const CFixedVector2D& halfSize) | ||||
{ | { | ||||
/* | /* | ||||
* We only consider collisions to be when the ray goes from outside to inside the shape (and possibly out again). | * We only consider collisions to be when the ray goes from outside to inside the shape (and possibly out again). | ||||
* Various cases to consider: | * Various cases to consider: | ||||
* 'a' inside, 'b' inside -> no collision | * 'a' inside, 'b' inside -> no collision | ||||
* 'a' inside, 'b' outside -> no collision | * 'a' inside, 'b' outside -> no collision | ||||
* 'a' outside, 'b' inside -> collision | * 'a' outside, 'b' inside -> collision | ||||
* 'a' outside, 'b' outside -> depends; use separating axis theorem: | * 'a' outside, 'b' outside -> depends; use separating axis theorem: | ||||
* if the ray's bounding box is outside the square -> no collision | * if the ray's bounding box is outside the square -> no collision | ||||
* if the whole square is on the same side of the ray -> no collision | * if the whole square is on the same side of the ray -> no collision | ||||
* otherwise -> collision | * otherwise -> collision | ||||
* (Points on the edge are considered 'inside'.) | * (Points on the edge are considered 'inside'.) | ||||
*/ | */ | ||||
fixed hw = halfSize.X; | fixed hw = halfSize.getX(); | ||||
fixed hh = halfSize.Y; | fixed hh = halfSize.getY(); | ||||
fixed au = a.Dot(u); | fixed au = a.Dot(u); | ||||
fixed av = a.Dot(v); | fixed av = a.Dot(v); | ||||
if (-hw <= au && au <= hw && -hh <= av && av <= hh) | if (-hw <= au && au <= hw && -hh <= av && av <= hh) | ||||
return false; // a is inside | return false; // a is inside | ||||
fixed bu = b.Dot(u); | fixed bu = b.Dot(u); | ||||
Show All 18 Lines | if ((s1 < fixed::Zero()) != sign || (s2 < fixed::Zero()) != sign || (s3 < fixed::Zero()) != sign) | ||||
return true; // ray cuts through the square | return true; // ray cuts through the square | ||||
return false; | return false; | ||||
} | } | ||||
// Exactly like TestRaySquare with u=(1,0), v=(0,1) | // Exactly like TestRaySquare with u=(1,0), v=(0,1) | ||||
bool TestRayAASquare(const CFixedVector2D& a, const CFixedVector2D& b, const CFixedVector2D& halfSize) | bool TestRayAASquare(const CFixedVector2D& a, const CFixedVector2D& b, const CFixedVector2D& halfSize) | ||||
{ | { | ||||
fixed hw = halfSize.X; | fixed hw = halfSize.getX(); | ||||
fixed hh = halfSize.Y; | fixed hh = halfSize.getY(); | ||||
if (-hw <= a.X && a.X <= hw && -hh <= a.Y && a.Y <= hh) | if (-hw <= a.getX() && a.getX() <= hw && -hh <= a.getY() && a.getY() <= hh) | ||||
return false; // a is inside | return false; // a is inside | ||||
if (-hw <= b.X && b.X <= hw && -hh <= b.Y && b.Y <= hh) // TODO: isn't this subsumed by the next checks? | if (-hw <= b.getX() && b.getX() <= hw && -hh <= b.getY() && b.getY() <= hh) // TODO: isn't this subsumed by the next checks? | ||||
return true; // a is outside, b is inside | return true; // a is outside, b is inside | ||||
if ((a.X < -hw && b.X < -hw) || (a.X > hw && b.X > hw) || (a.Y < -hh && b.Y < -hh) || (a.Y > hh && b.Y > hh)) | if ((a.getX() < -hw && b.getX() < -hw) || (a.getX() > hw && b.getX() > hw) || (a.getY() < -hh && b.getY() < -hh) || (a.getY() > hh && b.getY() > hh)) | ||||
return false; // ab is entirely above/below/side the square | return false; // ab is entirely above/below/side the square | ||||
CFixedVector2D abp = (b - a).Perpendicular(); | CFixedVector2D abp = (b - a).Perpendicular(); | ||||
fixed s0 = abp.Dot(CFixedVector2D(hw, hh) - a); | fixed s0 = abp.Dot(CFixedVector2D(hw, hh) - a); | ||||
fixed s1 = abp.Dot(CFixedVector2D(hw, -hh) - a); | fixed s1 = abp.Dot(CFixedVector2D(hw, -hh) - a); | ||||
fixed s2 = abp.Dot(CFixedVector2D(-hw, -hh) - a); | fixed s2 = abp.Dot(CFixedVector2D(-hw, -hh) - a); | ||||
fixed s3 = abp.Dot(CFixedVector2D(-hw, hh) - a); | fixed s3 = abp.Dot(CFixedVector2D(-hw, hh) - a); | ||||
if (s0.IsZero() || s1.IsZero() || s2.IsZero() || s3.IsZero()) | if (s0.IsZero() || s1.IsZero() || s2.IsZero() || s3.IsZero()) | ||||
return true; // ray intersects the corner | return true; // ray intersects the corner | ||||
bool sign = (s0 < fixed::Zero()); | bool sign = (s0 < fixed::Zero()); | ||||
if ((s1 < fixed::Zero()) != sign || (s2 < fixed::Zero()) != sign || (s3 < fixed::Zero()) != sign) | if ((s1 < fixed::Zero()) != sign || (s2 < fixed::Zero()) != sign || (s3 < fixed::Zero()) != sign) | ||||
return true; // ray cuts through the square | return true; // ray cuts through the square | ||||
return false; | return false; | ||||
} | } | ||||
/** | /** | ||||
* Separating axis test; returns true if the square defined by u/v/halfSize at the origin | * Separating axis test; returns true if the square defined by u/v/halfSize at the origin | ||||
* is not entirely on the clockwise side of a line in direction 'axis' passing through 'a' | * is not entirely on the clockwise side of a line in direction 'axis' passing through 'a' | ||||
*/ | */ | ||||
static bool SquareSAT(const CFixedVector2D& a, const CFixedVector2D& axis, const CFixedVector2D& u, const CFixedVector2D& v, const CFixedVector2D& halfSize) | static bool SquareSAT(const CFixedVector2D& a, const CFixedVector2D& axis, const CFixedVector2D& u, const CFixedVector2D& v, const CFixedVector2D& halfSize) | ||||
{ | { | ||||
fixed hw = halfSize.X; | fixed hw = halfSize.getX(); | ||||
fixed hh = halfSize.Y; | fixed hh = halfSize.getY(); | ||||
CFixedVector2D p = axis.Perpendicular(); | CFixedVector2D p = axis.Perpendicular(); | ||||
if (p.RelativeOrientation(u.Multiply(hw) + v.Multiply(hh) - a) <= 0) | if (p.RelativeOrientation(u.Multiply(hw) + v.Multiply(hh) - a) <= 0) | ||||
return true; | return true; | ||||
if (p.RelativeOrientation(u.Multiply(hw) - v.Multiply(hh) - a) <= 0) | if (p.RelativeOrientation(u.Multiply(hw) - v.Multiply(hh) - a) <= 0) | ||||
return true; | return true; | ||||
if (p.RelativeOrientation(-u.Multiply(hw) - v.Multiply(hh) - a) <= 0) | if (p.RelativeOrientation(-u.Multiply(hw) - v.Multiply(hh) - a) <= 0) | ||||
return true; | return true; | ||||
if (p.RelativeOrientation(-u.Multiply(hw) + v.Multiply(hh) - a) <= 0) | if (p.RelativeOrientation(-u.Multiply(hw) + v.Multiply(hh) - a) <= 0) | ||||
return true; | return true; | ||||
return false; | return false; | ||||
} | } | ||||
bool TestSquareSquare( | bool TestSquareSquare( | ||||
const CFixedVector2D& c0, const CFixedVector2D& u0, const CFixedVector2D& v0, const CFixedVector2D& halfSize0, | const CFixedVector2D& c0, const CFixedVector2D& u0, const CFixedVector2D& v0, const CFixedVector2D& halfSize0, | ||||
const CFixedVector2D& c1, const CFixedVector2D& u1, const CFixedVector2D& v1, const CFixedVector2D& halfSize1) | const CFixedVector2D& c1, const CFixedVector2D& u1, const CFixedVector2D& v1, const CFixedVector2D& halfSize1) | ||||
{ | { | ||||
// TODO: need to test this carefully | // TODO: need to test this carefully | ||||
CFixedVector2D corner0a = c0 + u0.Multiply(halfSize0.X) + v0.Multiply(halfSize0.Y); | CFixedVector2D corner0a = c0 + u0.Multiply(halfSize0.getX()) + v0.Multiply(halfSize0.getY()); | ||||
CFixedVector2D corner0b = c0 - u0.Multiply(halfSize0.X) - v0.Multiply(halfSize0.Y); | CFixedVector2D corner0b = c0 - u0.Multiply(halfSize0.getX()) - v0.Multiply(halfSize0.getY()); | ||||
CFixedVector2D corner1a = c1 + u1.Multiply(halfSize1.X) + v1.Multiply(halfSize1.Y); | CFixedVector2D corner1a = c1 + u1.Multiply(halfSize1.getX()) + v1.Multiply(halfSize1.getY()); | ||||
CFixedVector2D corner1b = c1 - u1.Multiply(halfSize1.X) - v1.Multiply(halfSize1.Y); | CFixedVector2D corner1b = c1 - u1.Multiply(halfSize1.getX()) - v1.Multiply(halfSize1.getY()); | ||||
// Do a SAT test for each square vs each edge of the other square | // Do a SAT test for each square vs each edge of the other square | ||||
if (!SquareSAT(corner0a - c1, -u0, u1, v1, halfSize1)) | if (!SquareSAT(corner0a - c1, -u0, u1, v1, halfSize1)) | ||||
return false; | return false; | ||||
if (!SquareSAT(corner0a - c1, v0, u1, v1, halfSize1)) | if (!SquareSAT(corner0a - c1, v0, u1, v1, halfSize1)) | ||||
return false; | return false; | ||||
if (!SquareSAT(corner0b - c1, u0, u1, v1, halfSize1)) | if (!SquareSAT(corner0b - c1, u0, u1, v1, halfSize1)) | ||||
return false; | return false; | ||||
▲ Show 20 Lines • Show All 85 Lines • Show Last 20 Lines |
Wildfire Games · Phabricator