Avoid overflow in UnitMotion.
ComputeTargetPosition called Dot() with large enough vectors that it overflowed. Avoid that by not actually doing the full dot product. Reported by: Itms Fixes #5852 Differential Revision: https://code.wildfiregames.com/D3061 This was SVN commit r24152.
This commit is contained in:
parent
055a659685
commit
bb8456691b
@ -204,6 +204,7 @@ public:
|
||||
|
||||
/**
|
||||
* Compute the dot product of this vector with another.
|
||||
* Likely to overflow if both vectors are large-ish (around the 200 range).
|
||||
*/
|
||||
fixed Dot(const CFixedVector2D& v) const
|
||||
{
|
||||
@ -219,6 +220,16 @@ public:
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return -1, 0 or 1 if this and @v face respectively opposite directions, perpendicular, or same directions.
|
||||
*/
|
||||
int RelativeOrientation(const CFixedVector2D& v) const
|
||||
{
|
||||
i64 x = MUL_I64_I32_I32(X.GetInternalValue(), v.X.GetInternalValue());
|
||||
i64 y = MUL_I64_I32_I32(Y.GetInternalValue(), v.Y.GetInternalValue());
|
||||
return x > -y ? 1 : x < -y ? -1 : 0;
|
||||
}
|
||||
|
||||
CFixedVector2D Perpendicular() const
|
||||
{
|
||||
return CFixedVector2D(Y, -X);
|
||||
|
@ -1149,7 +1149,7 @@ bool CCmpUnitMotion::ComputeTargetPosition(CFixedVector2D& out, const MoveReques
|
||||
|
||||
// Check if we anticipate the target to go through us, in which case we shouldn't anticipate
|
||||
// (or e.g. units fleeing might suddenly turn around towards their attacker).
|
||||
if ((out - cmpPosition->GetPosition2D()).Dot(tempPos - cmpPosition->GetPosition2D()) >= fixed::Zero())
|
||||
if ((out - cmpPosition->GetPosition2D()).RelativeOrientation(tempPos - cmpPosition->GetPosition2D()) >= 0)
|
||||
out = tempPos;
|
||||
}
|
||||
}
|
||||
|
@ -342,13 +342,13 @@ static bool SquareSAT(const CFixedVector2D& a, const CFixedVector2D& axis, const
|
||||
fixed hh = halfSize.Y;
|
||||
|
||||
CFixedVector2D p = axis.Perpendicular();
|
||||
if (p.Dot((u.Multiply(hw) + v.Multiply(hh)) - a) <= fixed::Zero())
|
||||
if (p.RelativeOrientation(u.Multiply(hw) + v.Multiply(hh) - a) <= 0)
|
||||
return true;
|
||||
if (p.Dot((u.Multiply(hw) - v.Multiply(hh)) - a) <= fixed::Zero())
|
||||
if (p.RelativeOrientation(u.Multiply(hw) - v.Multiply(hh) - a) <= 0)
|
||||
return true;
|
||||
if (p.Dot((-u.Multiply(hw) - v.Multiply(hh)) - a) <= fixed::Zero())
|
||||
if (p.RelativeOrientation(-u.Multiply(hw) - v.Multiply(hh) - a) <= 0)
|
||||
return true;
|
||||
if (p.Dot((-u.Multiply(hw) + v.Multiply(hh)) - a) <= fixed::Zero())
|
||||
if (p.RelativeOrientation(-u.Multiply(hw) + v.Multiply(hh) - a) <= 0)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
|
Loading…
Reference in New Issue
Block a user