Exemplo n.º 1
0
        /// <summary>
        /// Performs an AABB AABB collision check.
        /// </summary>
        /// <param name="a">First AABB.</param>
        /// <param name="b">Second AABB.</param>
        /// <returns></returns>
        private static Collision AABBAABB(BoundingBox a, BoundingBox b)
        {
            // Minimum Translation Vector
            // ==========================
            float   minimumTranslationVectorDistance = float.MaxValue; // Set current minimum distance (max float value so next value is always less)
            Vector3 minimumTranslationVectorAxis     = new Vector3();  // Axis along which to travel with the minimum distance
            var     containment      = a.Contains(b);
            var     normal           = Vector3.Zero;
            float   penetrationDepth = 0f;

            if (containment == ContainmentType.Disjoint)
            {
                return(new Collision(false, normal, penetrationDepth));
            }

            // Axes of potential separation
            // ============================
            // - Each shape must be projected on these axes to test for intersection:
            //
            // (1, 0, 0)                    A0 (= B0) [X Axis]
            // (0, 1, 0)                    A1 (= B1) [Y Axis]
            // (0, 0, 1)                    A1 (= B2) [Z Axis]

            // [X Axis]
            if (!SAT(Vector3.Right, a.Min.X, a.Max.X, b.Min.X, b.Max.X, ref minimumTranslationVectorAxis, ref minimumTranslationVectorDistance))
            {
                return(new Collision(false, normal, penetrationDepth));
            }
            // [Y Axis]
            if (!SAT(Vector3.Up, a.Min.Y, a.Max.Y, b.Min.Y, b.Max.Y, ref minimumTranslationVectorAxis, ref minimumTranslationVectorDistance))
            {
                return(new Collision(false, normal, penetrationDepth));
            }
            // [Z Axis]
            if (!SAT(Vector3.Back, a.Min.Z, a.Max.Z, b.Min.Z, b.Max.Z, ref minimumTranslationVectorAxis, ref minimumTranslationVectorDistance))
            {
                return(new Collision(false, normal, penetrationDepth));
            }

            // Calculate Minimum Translation Vector (MTV) [normal * penetration]
            normal = Vector3.Normalize(minimumTranslationVectorAxis);

            // Multiply the penetration depth by itself plus a small increment
            // When the penetration is resolved using MTV, it will no longer intersect
            penetrationDepth = MathF.Sqrt(minimumTranslationVectorDistance) * 1.001f;

            return(new Collision(true, normal, penetrationDepth));
        }