Пример #1
0
        /// <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);
        }
Пример #2
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);
        }