public struct AABB
{
public Vector2 _center;
public Vector2 _extents;
public Color _debugColor;
public Rectangle XNARec
{
get
{
return new Rectangle
(
(int)(_center.X - _extents.X),
(int)(_center.Y - _extents.Y),
(int)_extents.X * 2,
(int)_extents.Y * 2
);
}
}
public float Right
{
get { return _center.X + _extents.X; }
}
public float Left
{
get { return _center.X - _extents.X; }
}
public AABB(Vector2 center, Vector2 extents)
{
_center = center;
_extents = extents;
_debugColor = Color.Black;
}
public bool IsColliding(AABB b)
{
return AABB.TestAABBCollision(this, b);
}
public static bool TestAABBCollision(AABB a, AABB b)
{
if (Math.Abs(a._center.X - b._center.X) > a._extents.X + b._extents.X) return false;
if (Math.Abs(a._center.Y - b._center.Y) > a._extents.Y + b._extents.Y) return false;
return true;
}
public bool IsColliding(AABB b, ref Vector2 MTV)
{
return AABB.TestAABBCollision(this, b, ref MTV);
}
public static bool TestAABBCollision(AABB a, AABB b, ref Vector2 MTV)
{
if (Math.Abs(a._center.X - b._center.X) > a._extents.X + b._extents.X)
{
MTV = new Vector2((a._extents.X + b._extents.X) - Math.Abs(a._center.X - b._center.X), 0);
return false;
}
if (Math.Abs(a._center.Y - b._center.Y) > a._extents.Y + b._extents.Y)
{
MTV = new Vector2(0, (a._extents.Y + b._extents.Y) - Math.Abs(a._center.Y - b._center.Y));
return false;
}
MTV = new Vector2((a._extents.X + b._extents.X) - Math.Abs(a._center.X - b._center.X),
(a._extents.Y + b._extents.Y) - Math.Abs(a._center.Y - b._center.Y));
//MTV = new Vector2((a._extents.X + b._extents.X) - (a._center.X - b._center.X),
// (a._extents.Y + b._extents.Y) - (a._center.Y - b._center.Y));
if (a._center.X > b._center.X)
{
MTV.X = -((a._extents.X + b._extents.X) - Math.Abs(a._center.X - b._center.X));
}
else
{
MTV.X = (a._extents.X + b._extents.X) - Math.Abs(a._center.X - b._center.X);
}
if (a._center.Y > b._center.Y)
{
MTV.Y = -((a._extents.Y + b._extents.Y) - Math.Abs(a._center.Y - b._center.Y));
}
else
{
MTV.Y = (a._extents.Y + b._extents.Y) - Math.Abs(a._center.Y - b._center.Y);
}
if (Math.Abs(MTV.X) > Math.Abs(MTV.Y))
{
MTV.X = 0f;
}
else
{
MTV.Y = 0f;
}
//MTV = new Vector2(1, 1);
return true;
}
public void DrawDebug(Texture2D t, SpriteBatch sb)
{
sb.Draw(t,
new Vector2(_center.X, _center.Y),
XNARec,
_debugColor,
0f, _extents, 1f, SpriteEffects.None, 0f);
}
}