diff --git a/MLEM/Extensions/NumberExtensions.cs b/MLEM/Extensions/NumberExtensions.cs
index ecb4a3b..96c50ef 100644
--- a/MLEM/Extensions/NumberExtensions.cs
+++ b/MLEM/Extensions/NumberExtensions.cs
@@ -201,22 +201,34 @@ namespace MLEM.Extensions {
}
///
- /// Returns the amount that the rectangle is penetrating the rectangle by.
+ /// Calculates the amount that the rectangle is penetrating the rectangle by.
/// If a penetration on both axes is occuring, the one with the lower value is returned.
/// This is useful for collision detection, as it can be used to push colliding objects out of each other.
///
/// The rectangle to do the penetration
/// The rectangle that should be penetrated
- /// A penetration vector, or if the rectangles don't intersect
- public static Vector2 Penetrate(this RectangleF rect, RectangleF other) {
- var intersection = RectangleF.Intersect(rect, other);
- if (intersection.IsEmpty)
- return Vector2.Zero;
- if (intersection.Width < intersection.Height) {
- return new Vector2(rect.Center.X < other.Center.X ? intersection.Width : -intersection.Width, 0);
- } else {
- return new Vector2(0, rect.Center.Y < other.Center.Y ? intersection.Height : -intersection.Height);
+ /// The direction that the penetration occured in
+ /// The amount that the penetration occured by, in the direction of
+ /// Whether or not a penetration occured
+ public static bool Penetrate(this RectangleF rect, RectangleF other, out Vector2 normal, out float penetration) {
+ var (offsetX, offsetY) = other.Center - rect.Center;
+ var overlapX = rect.Width / 2 + other.Width / 2 - Math.Abs(offsetX);
+ if (overlapX > 0) {
+ var overlapY = rect.Height / 2 + other.Height / 2 - Math.Abs(offsetY);
+ if (overlapY > 0) {
+ if (overlapX < overlapY) {
+ normal = new Vector2(offsetX < 0 ? -1 : 1, 0);
+ penetration = overlapX;
+ } else {
+ normal = new Vector2(0, offsetY < 0 ? -1 : 1);
+ penetration = overlapY;
+ }
+ return true;
+ }
}
+ normal = Vector2.Zero;
+ penetration = 0;
+ return false;
}
}