AABB transform shortcut + sweep test
parent
9704072ab2
commit
10db4f95c8
|
@ -66,6 +66,8 @@ namespace MoonWorks.Collision.Fixed
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static readonly Fix64 Half = Fix64.FromFraction(1, 2);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Efficiently transforms the AABB by a Transform2D.
|
/// Efficiently transforms the AABB by a Transform2D.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -74,11 +76,42 @@ namespace MoonWorks.Collision.Fixed
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
public static AABB2D Transformed(AABB2D aabb, Transform2D transform)
|
public static AABB2D Transformed(AABB2D aabb, Transform2D transform)
|
||||||
{
|
{
|
||||||
var two = new Fix64(2);
|
if (transform.IsAxisAligned)
|
||||||
var center = (aabb.Min + aabb.Max) / two;
|
{
|
||||||
var extent = (aabb.Max - aabb.Min) / two;
|
var min = aabb.Min * transform.Scale + transform.Position;
|
||||||
|
var max = aabb.Max * transform.Scale + transform.Position;
|
||||||
|
|
||||||
var newCenter = Vector2.Transform(center, transform.TransformMatrix);
|
Fix64 minX, minY, maxX, maxY;
|
||||||
|
|
||||||
|
if (min.X <= max.X)
|
||||||
|
{
|
||||||
|
minX = min.X;
|
||||||
|
maxX = max.X;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
minX = max.X;
|
||||||
|
maxX = min.X;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (min.Y <= max.Y)
|
||||||
|
{
|
||||||
|
minY = min.Y;
|
||||||
|
maxY = max.Y;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
minY = max.Y;
|
||||||
|
maxY = min.Y;
|
||||||
|
}
|
||||||
|
|
||||||
|
return new AABB2D(minX, minY, maxX, maxY);
|
||||||
|
}
|
||||||
|
|
||||||
|
var center = (aabb.Min + aabb.Max) * Half;
|
||||||
|
var extent = aabb.Max - center;
|
||||||
|
|
||||||
|
var newCenter = Vector2.Transform(center, transform.TransformMatrix);
|
||||||
var newExtent = Vector2.TransformNormal(extent, AbsoluteMatrix(transform.TransformMatrix));
|
var newExtent = Vector2.TransformNormal(extent, AbsoluteMatrix(transform.TransformMatrix));
|
||||||
|
|
||||||
return new AABB2D(newCenter - newExtent, newCenter + newExtent);
|
return new AABB2D(newCenter - newExtent, newCenter + newExtent);
|
||||||
|
@ -152,6 +185,69 @@ namespace MoonWorks.Collision.Fixed
|
||||||
return a.Left < b.Right && a.Right > b.Left && a.Top < b.Bottom && a.Bottom > b.Top;
|
return a.Left < b.Right && a.Right > b.Left && a.Top < b.Bottom && a.Bottom > b.Top;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// FIXME: this is broken
|
||||||
|
public static bool SweepTest(AABB2D a, AABB2D b, Vector2 aMovement, Vector2 bMovement, out Fix64 normalizedTime)
|
||||||
|
{
|
||||||
|
if (TestOverlap(a, b))
|
||||||
|
{
|
||||||
|
normalizedTime = Fix64.Zero;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
normalizedTime = Fix64.One;
|
||||||
|
|
||||||
|
var relativeVelocity = bMovement - aMovement;
|
||||||
|
|
||||||
|
Vector2 entry = Vector2.Zero;
|
||||||
|
if (a.Max.X < b.Min.X && relativeVelocity.X < 0)
|
||||||
|
{
|
||||||
|
entry.X = (a.Max.X - b.Min.X) / relativeVelocity.X;
|
||||||
|
}
|
||||||
|
else if (b.Max.X < a.Min.X && relativeVelocity.X > 0)
|
||||||
|
{
|
||||||
|
entry.X = (a.Min.X - b.Max.X) / relativeVelocity.X;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (a.Max.Y < b.Min.Y && relativeVelocity.Y < 0)
|
||||||
|
{
|
||||||
|
entry.Y = (a.Max.Y - b.Min.Y) / relativeVelocity.Y;
|
||||||
|
}
|
||||||
|
else if (b.Max.Y > a.Min.Y && relativeVelocity.Y > 0)
|
||||||
|
{
|
||||||
|
entry.Y = (a.Min.Y - b.Max.Y) / relativeVelocity.Y;
|
||||||
|
}
|
||||||
|
|
||||||
|
Vector2 exit = new Vector2(Fix64.MaxValue, Fix64.MaxValue);
|
||||||
|
if (b.Max.X > a.Min.X && relativeVelocity.X < 0)
|
||||||
|
{
|
||||||
|
exit.X = (a.Min.X - b.Max.X) / relativeVelocity.X;
|
||||||
|
}
|
||||||
|
else if (a.Max.X > b.Min.X && relativeVelocity.X > 0)
|
||||||
|
{
|
||||||
|
exit.Y = (a.Max.X - b.Min.X) / relativeVelocity.X;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (b.Max.Y > a.Min.Y && relativeVelocity.Y < 0)
|
||||||
|
{
|
||||||
|
exit.Y = (a.Min.Y - b.Max.Y) / relativeVelocity.Y;
|
||||||
|
}
|
||||||
|
else if (a.Max.Y > b.Min.Y && relativeVelocity.Y > 0)
|
||||||
|
{
|
||||||
|
exit.Y = (a.Max.Y - b.Min.Y) / relativeVelocity.Y;
|
||||||
|
}
|
||||||
|
|
||||||
|
Fix64 firstTime = Fix64.Max(entry.X, entry.Y);
|
||||||
|
Fix64 lastTime = Fix64.Min(exit.X, exit.Y);
|
||||||
|
|
||||||
|
if (firstTime <= lastTime && firstTime > 0)
|
||||||
|
{
|
||||||
|
normalizedTime = firstTime;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
public override bool Equals(object obj)
|
public override bool Equals(object obj)
|
||||||
{
|
{
|
||||||
return obj is AABB2D aabb && Equals(aabb);
|
return obj is AABB2D aabb && Equals(aabb);
|
||||||
|
|
Loading…
Reference in New Issue