コード例 #1
0
        /// <summary>
        /// Check for collisions between two bodies at a certain range of z-coordinates (height).
        /// </summary>
        /// <param name="b1">The first body to check.</param>
        /// <param name="b2">The second body to check.</param>
        /// <param name="mtv">The MTV of the layered collision.</param>
        /// <returns>The MTV of the intersection.</returns>
        private CollisionData GetLayeredCollision(Body b1, Body b2, CollisionData mtv)
        {
            // If there is no layered collision between the bodies, stop here.
            if (!mtv.HasCollision) { return mtv; }

            // Get the dynamic and static body.
            Body a = b1.IsStatic ? b2 : b1;
            Body b = (a == b1) ? b2 : b1;

            // Get the min and max heights for both bodies.
            Vector2 h1 = new Vector2(a.Shape.BottomDepth, a.Shape.GetTopDepth(a.LayeredPosition));
            Vector2 h2 = new Vector2(b.Shape.BottomDepth, b.Shape.GetTopDepth(a.LayeredPosition));

            // Get min and max heights for possible collisions between the bodies.
            Vector2 heights = Calculator.GetMiddleValues(h1, h2);

            // If there were no matching heights found, no collision possible.
            if ((heights.X < 0 && heights.Y > 0) || (h2.Y - h1.X) < 3) { return mtv; }

            //A collision has been found.
            mtv.HasCollision = true;

            // Return the MTV.
            return mtv;
        }
コード例 #2
0
        /// <summary>
        /// Check for collision between two bodies where one is coming from above the other.
        /// This is a preemptive step due to the use of body velocity to project future positions.
        /// </summary>
        /// <param name="b1">The first body to check.</param>
        /// <param name="b2">The second body to check.</param>
        /// <param name="mtv">The MTV of the collision.</param>
        /// <returns>Whether there was a ground collision or not, from the first body's perspective</returns>
        private bool CheckGroundCollision(Body b1, Body b2, CollisionData mtv)
        {
            // The first body has to be dynamic or if there is no layered collision between the bodies, stop here.
            if (!mtv.HasCollision) { return false; }

            // Get the dynamic and static body.
            Body a = b1.IsStatic ? b2 : b1;
            Body b = (a == b1) ? b2 : b1;

            // Both bodies' depth positions.
            Vector2 h1 = new Vector2(a.Shape.BottomDepth, a.Shape.TopDepth);
            Vector2 h2 = new Vector2(b.Shape.BottomDepth, b.Shape.GetTopDepth(a.LayeredPosition));

            // The difference in height.
            double diff = h1.X - h2.Y;

            // If the distance between the bodies is either greater than the threshold or less than the velocity needed to collide, no collision.
            if (diff > Math.Max(-a.Velocity.Z + _Gravity, 0) || (h2.Y - h1.X) > 2) { return false; }

            // There must be a ground collision after all.
            return true;
        }
コード例 #3
0
        /// <summary>
        /// Pull two bodies that are intersecting apart by using the MTV.
        /// </summary>
        /// <param name="b1">The first body to check.</param>
        /// <param name="b2">The second body to check.</param>
        /// <param name="mtv">The MTV of the collision.</param>
        private void ClearIntersection(Body b1, Body b2, CollisionData mtv)
        {
            // If the MTV is null, stop here.
            if (!mtv.HasCollision) { return; }

            // Add the MTV to the first body and subtract it from the second. Only move dynamic bodies!
            if (!b1.IsStatic)
            {
                b1.Shape.LayeredPosition = b1.Shape.LayeredPosition + mtv.Axis * mtv.Overlap;
                b1.Velocity = Vector3.Zero;
            }
            if (!b2.IsStatic)
            {
                b2.Shape.LayeredPosition = b2.Shape.LayeredPosition - mtv.Axis * mtv.Overlap;
                b2.Velocity = Vector3.Zero;
            }
        }
コード例 #4
0
        /// <summary>
        /// Do a narrow phase collision check between two shapes by using SAT (Separating Axis Theorem).
        /// If a collision has occurred, get the MTV (Minimum Translation Vector) of the two intersecting shapes.
        /// </summary>
        /// <param name="s1">The first shape to check.</param>
        /// <param name="s2">The second shape to check.</param>
        /// <returns>The MTV of the intersection.</returns>
        public CollisionData NarrowPhase(Shape s1, Shape s2)
        {
            // The minimum amount of overlap. Start real high.
            float overlap = float.MaxValue;
            //The collision data.
            CollisionData data = new CollisionData(s1, s2);
            // The smallest axis found.
            Vector2 smallest = Vector2.Zero;

            try
            {
                // Get the axes of both bodies.
                Vector2[][] axes = new Vector2[][] { s1.GetAxes(), s2.GetAxes() };

                // Iterate over the axes of both bodies.
                foreach (Vector2[] v in axes)
                {
                    // Iterate over both bodies' axes.
                    foreach (Vector2 a in v)
                    {
                        // Project both bodies onto the axis.
                        Vector2 p1 = s1.Project(a);
                        Vector2 p2 = s2.Project(a);

                        // Get the overlap.
                        float o = Calculator.GetOverlap(p1, p2);

                        // Do the projections overlap?
                        if (o == -1)
                        {
                            // We can guarantee that the shapes do not overlap.
                            return data;
                        }
                        else
                        {
                            // Check for minimum.
                            if (o < overlap)
                            {
                                // Store the minimum overlap and the axis it was projected upon. Make sure that the separation vector is pointing the right way.
                                overlap = o;
                                smallest = a;
                            }
                        }
                    }
                }
            }
            catch (Exception e)
            {
                Console.WriteLine(this + ": Narrow Phase Error. (" + e + ")");
            }

            // We now know that every axis had an overlap on it, which means we can guarantee an intersection between the bodies.
            data.HasCollision = true;
            data.Axis = smallest;
            data.Overlap = overlap;

            //Return the collision data.
            return data;
        }