/// <summary> /// Calculates the overlap between two <see cref="ColliderProjection"/>s. /// <para>If at least one projection of two <see cref="ICollider"/>s does not overlap, /// the colliders do not intersect.</para> /// </summary> /// <param name="a">The first <see cref="ColliderProjection"/>.</param> /// <param name="b">The second <see cref="ColliderProjection"/>.</param> /// <returns>The total overlap between the two projections.</returns> public static float GetOverlap(ColliderProjection a, ColliderProjection b) { if ((a.Min <= b.Max) && (b.Min <= a.Max)) { return(Math.Min(a.Max, b.Max) - Math.Max(a.Min, b.Min)); } return(0); }
bool TestPair(IPhysicsBody a, IPhysicsBody b, out Vector2 mtv) { Assert.Ref(a, b); // collisions will be tested in a localized space, originating at the least common sector of both colliders // (i think? this is easier than setting the origin at the collider vertex closest to 0,0) WorldPoint origin = WorldPoint.LeastCommonSector(a.Position, b.Position); Vector2 posA = a.Position.PixelDistance(origin); Vector2 posB = b.Position.PixelDistance(origin); // we're also returning the minimum translation vector float minOverlap = float.MaxValue; mtv = Vector2.Zero; // test seperating axes foreach (Vector2 axis in GetAllSeperatingAxes(a.Collider, b.Collider)) { // project colliders on this seperating axis ColliderProjection projA = a.Collider.Project(posA, axis); ColliderProjection projB = b.Collider.Project(posB, axis); // find the overlap. if there is none, we're not colliding and can get out now float overlap = ColliderProjection.GetOverlap(projA, projB); if (overlap > 0) { // otherwise, update the mtv if it's a smaller overlap than before if (overlap < minOverlap) { minOverlap = overlap; mtv = axis; } } else { return(false); } } // make sure mtv isn't negative Vector2 diff = posA - posB; if (diff.Dot(mtv) < 0) { mtv = -mtv; } // scale mtv by the smallest overlap, and we're done mtv *= minOverlap; return(true); }