Example #1
0
        /// <summary>
        /// Intersectses this instance.
        /// </summary>
        /// <param name="center">The center.</param>
        /// <param name="radius">The radius.</param>
        /// <param name="boxCollider">The box collider.</param>
        /// <returns>true if intersects</returns>
        private bool Intersects(Vector3 center, float radius, BoundingOrientedBox boxCollider)
        {
            Vector2 circleDistance = Vector2.Zero;

            circleDistance.X = Math.Abs(center.Z - boxCollider.Center.Z);
            circleDistance.Y = Math.Abs(center.Y - boxCollider.Center.Y);

            if (circleDistance.X > (boxCollider.HalfExtent.Z + radius))
            {
                return(false);
            }
            if (circleDistance.Y > (boxCollider.HalfExtent.Y + radius))
            {
                return(false);
            }

            if (circleDistance.X <= (boxCollider.HalfExtent.Z))
            {
                return(true);
            }
            if (circleDistance.Y <= (boxCollider.HalfExtent.Y))
            {
                return(true);
            }

            var cornerDistanceSq = Math.Sqrt(circleDistance.X - boxCollider.HalfExtent.Z) +
                                   Math.Sqrt(circleDistance.Y - boxCollider.HalfExtent.Y);

            return(cornerDistanceSq <= (Math.Sqrt(radius)));
        }
        public ContainmentType Contains(BoundingOrientedBox box)
        {
            if (!box.Intersects(this))
            {
                return(ContainmentType.Disjoint);
            }

            XMVector v_center = this.center;
            XMVector v_radius = XMVector.Replicate(this.radius);
            XMVector radiusSq = v_radius * v_radius;

            XMVector boxCenter      = box.Center;
            XMVector boxExtents     = box.Extents;
            XMVector boxOrientation = box.Orientation;

            Debug.Assert(Internal.XMQuaternionIsUnit(boxOrientation), "Reviewed");

            XMVector insideAll = XMVector.TrueInt;

            for (int i = 0; i < BoundingOrientedBox.CornerCount; i++)
            {
                XMVector c = XMVector3.Rotate(boxExtents * CollisionGlobalConstants.BoxOffsets[i], boxOrientation) + boxCenter;
                XMVector d = XMVector3.LengthSquare(XMVector.Subtract(v_center, c));
                insideAll = XMVector.AndInt(insideAll, XMVector.LessOrEqual(d, radiusSq));
            }

            return(XMVector3.EqualInt(insideAll, XMVector.TrueInt) ? ContainmentType.Contains : ContainmentType.Intersects);
        }
Example #3
0
        /// <summary>
        /// Intersectses the sphere with box.
        /// </summary>
        /// <param name="center">The center.</param>
        /// <param name="radius">The radius.</param>
        /// <param name="boxCollider">The box collider.</param>
        /// <returns>
        /// True if intersects
        /// </returns>
        public CollisionType CheckCollisionType(Vector3 center, float radius, BoundingOrientedBox boxCollider, string tag)
        {
            CollisionType res = CollisionType.NONE;

            bool collides = this.Intersects(center, radius, boxCollider);

            if (collides)
            {
                if (tag.Equals(KILLERTAG))
                {
                    res = CollisionType.KILLER;
                }
                else
                {
                    Vector2 CB = new Vector2(boxCollider.Center.Z - center.Z, boxCollider.Center.Y - center.Y);
                    CB.Normalize();

                    var angle = Vector2.Angle(-Vector2.UnitY, CB);

                    if (angle > -rad30 && angle < rad30)
                    {
                        res = CollisionType.GROUND;
                    }
                    else
                    {
                        res = CollisionType.KILLER;
                    }
                }
            }

            return(res);
        }
        public ContainmentType Contains(BoundingOrientedBox box)
        {
            if (!box.Intersects(this))
            {
                return(ContainmentType.Disjoint);
            }

            XMVector boxCenter  = this.center;
            XMVector boxExtents = this.extents;

            // Subtract off the AABB center to remove a subtract below
            XMVector o_center = box.Center - boxCenter;

            XMVector o_extents     = box.Extents;
            XMVector o_orientation = box.Orientation;

            Debug.Assert(Internal.XMQuaternionIsUnit(o_orientation), "Reviewed");

            XMVector inside = XMVector.TrueInt;

            for (int i = 0; i < BoundingOrientedBox.CornerCount; i++)
            {
                XMVector c = XMVector3.Rotate(o_extents * CollisionGlobalConstants.BoxOffsets[i], o_orientation) + o_center;
                XMVector d = c.Abs();
                inside = XMVector.AndInt(inside, XMVector.LessOrEqual(d, boxExtents));
            }

            return(XMVector3.EqualInt(inside, XMVector.TrueInt) ? ContainmentType.Contains : ContainmentType.Intersects);
        }
Example #5
0
        protected override void Initialize()
        {
            // Create a box that is centered on the origin and extends from (-3, -3, -3) to (3, 3, 3)
            box = new BoundingOrientedBox(Vector3.Zero, new Vector3(3), Quaternion.Identity);

            // Create our frustum to simulate a camera sitting at the origin, looking down the X axis, with a 16x9
            // aspect ratio, a near plane of 1, and a far plane of 5
            Matrix frustumView = Matrix.CreateLookAt(Vector3.Zero, Vector3.UnitX, Vector3.Up);
            Matrix frustumProjection = Matrix.CreatePerspectiveFieldOfView(MathHelper.PiOver4, 16f / 9f, 1f, 5f);
            frustum = new BoundingFrustum(frustumView * frustumProjection);

            // Create a sphere that is centered on the origin and has a radius of 3
            sphere = new BoundingSphere(Vector3.Zero, 3f);
        }
Example #6
0
        protected override void Initialize()
        {
            // Create a box that is centered on the origin and extends from (-3, -3, -3) to (3, 3, 3)
            box = new BoundingOrientedBox(Vector3.Zero, new Vector3(3), Quaternion.Identity);

            // Create our frustum to simulate a camera sitting at the origin, looking down the X axis, with a 16x9
            // aspect ratio, a near plane of 1, and a far plane of 5
            Matrix frustumView       = Matrix.CreateLookAt(Vector3.Zero, Vector3.UnitX, Vector3.Up);
            Matrix frustumProjection = Matrix.CreatePerspectiveFieldOfView(MathHelper.PiOver4, 16f / 9f, 1f, 5f);

            frustum = new BoundingFrustum(frustumView * frustumProjection);

            // Create a sphere that is centered on the origin and has a radius of 3
            sphere = new BoundingSphere(Vector3.Zero, 3f);
        }
Example #7
0
        /// <summary>
        /// Determines whether the given BoundingOrientedBox contains/intersects/is disjoint from the triangle
        /// (v0,v1,v2)
        /// </summary>
        public static ContainmentType Contains(ref BoundingOrientedBox obox, ref Vector3 v0, ref Vector3 v1, ref Vector3 v2)
        {
            // Transform the triangle into the local space of the box, so we can use a
            // faster axis-aligned box test.
            // Note than when transforming more than one point, using an intermediate matrix
            // is faster than doing multiple quaternion transforms directly.
            Quaternion qinv;
            Quaternion.Conjugate(ref obox.Orientation, out qinv);

            Matrix minv;
            Matrix.CreateFromQuaternion(ref qinv, out minv);

            Triangle localTri = new Triangle();
            localTri.V0 = Vector3.TransformNormal(v0 - obox.Center, minv);
            localTri.V1 = Vector3.TransformNormal(v1 - obox.Center, minv);
            localTri.V2 = Vector3.TransformNormal(v2 - obox.Center, minv);

            return OriginBoxContains(ref obox.HalfExtent, ref localTri);
        }
Example #8
0
        public void RunTests()
        {
            Random random = new Random(1);

            for (int i = 0; i < 10000; i++)
            {
                TestRandomObjects(
                    random, new BoundingOrientedBoxOps(), new BoundingOrientedBoxOps(),
                    (b1, b2) => b1.Contains(ref b2), (b1, b2) => b1.Intersects(ref b2));

                TestRandomObjects(
                    random, new BoundingOrientedBoxOps(), new BoundingBoxOps(),
                    (b1, b2) => b1.Contains(ref b2), (b1, b2) => b1.Intersects(ref b2));

                TestRandomObjects(
                    random, new BoundingBoxOps(), new BoundingOrientedBoxOps(),
                    (b1, b2) => BoundingOrientedBox.Contains(ref b1, ref b2), (b1, b2) => b2.Intersects(ref b1));

                TestRandomObjects(
                    random, new BoundingBoxOps(), new BoundingBoxOps(),
                    (b1, b2) => b1.Contains(b2), (b1, b2) => b1.Intersects(b2));

                TestRandomObjects(
                    random, new BoundingSphereOps(), new TriangleOps(),
                    (b, t) => TriangleTest.Contains(ref b, ref t),
                    (b, t) => TriangleTest.Intersects(ref b, ref t));

                TestRandomObjects(
                    random, new BoundingBoxOps(), new TriangleOps(),
                    (b, t) => TriangleTest.Contains(ref b, ref t),
                    (b, t) => TriangleTest.Intersects(ref b, ref t.V0, ref t.V1, ref t.V2));

                TestRandomObjects(
                    random, new BoundingOrientedBoxOps(), new TriangleOps(),
                    (b, t) => TriangleTest.Contains(ref b, ref t),
                    (b, t) => TriangleTest.Intersects(ref b, ref t.V0, ref t.V1, ref t.V2));
            }
            Console.WriteLine("Passed: {0} Failed: {1}", TestsPassed, TestsFailed);
            Debug.WriteLine("Passed: {0} Failed: {1}", TestsPassed, TestsFailed);
        }
 /// <summary>
 /// Renders the outline of an oriented bounding box
 /// </summary>
 /// <param name="box">Oriented bounding box to render</param>
 /// <param name="color">Color of the box lines</param>
 public void DrawWireBox(BoundingOrientedBox box, Color color)
 {
     DrawWireShape(box.GetCorners(), cubeIndices, color);
 }
Example #10
0
        // Set up initial bounding shapes for the primary (static) and secondary (moving)
        // bounding shapes along with relevant camera position information.
        protected override void Initialize()
        {
            Console.WriteLine("DEBUG - Game Initialize!");

            debugDraw = new DebugDraw(GraphicsDevice);

            Components.Add(new FrameRateCounter(this));

            // Primary frustum
            Matrix m1 = Matrix.CreatePerspectiveFieldOfView(MathHelper.PiOver4, 1.77778F, 0.5f, 10.0f);
            Matrix m2 = Matrix.CreateTranslation(new Vector3(0, 0, -7));
            primaryFrustum = new BoundingFrustum(Matrix.Multiply(m2, m1));
            cameraOrigins[FrustumGroupIndex] = Vector3.Zero;

            // Primary axis-aligned box
            primaryAABox.Min = new Vector3(CAMERA_SPACING - 3, -4, -5);
            primaryAABox.Max = new Vector3(CAMERA_SPACING + 3, 4, 5);
            cameraOrigins[AABoxGroupIndex] = new Vector3(CAMERA_SPACING, 0, 0);

            // Primary oriented box
            primaryOBox.Center = new Vector3(-CAMERA_SPACING, 0, 0);
            primaryOBox.HalfExtent = new Vector3(3, 4, 5);
            primaryOBox.Orientation = Quaternion.CreateFromYawPitchRoll(0.8f, 0.7f, 0);
            cameraOrigins[OBoxGroupIndex] = primaryOBox.Center;

            // Primary sphere
            primarySphere.Center = new Vector3(0, 0, -CAMERA_SPACING);
            primarySphere.Radius = 5;
            cameraOrigins[SphereGroupIndex] = primarySphere.Center;

            // Primary ray
            primaryRay.Position = new Vector3(0, 0, CAMERA_SPACING);
            primaryRay.Direction = Vector3.UnitZ;
            cameraOrigins[RayGroupIndex] = primaryRay.Position;

            // Initialize all of the secondary objects with default values
            Vector3 half = new Vector3(0.5F, 0.5F, 0.5F);
            for (int i = 0; i < NumGroups; i++)
            {
                secondarySpheres[i] = new BoundingSphere(Vector3.Zero, 1.0f);
                secondaryOBoxes[i] = new BoundingOrientedBox(Vector3.Zero, half, Quaternion.Identity);
                secondaryAABoxes[i] = new BoundingBox(-half, half);
                secondaryTris[i] = new Triangle();
            }

            rayHitResult = null;

            currentCamera = 3;
            cameraOrtho = false;
            cameraYaw = (float)Math.PI * 0.75F;
            cameraPitch = MathHelper.PiOver4;
            cameraDistance = 20;
            cameraTarget = cameraOrigins[0];

            paused = false;

            base.Initialize();
        }
        private void Animate(double fTime)
        {
            float t = (float)(fTime * 0.2);

            float camera0OriginX = this.cameraOrigins[0].X;
            float camera1OriginX = this.cameraOrigins[1].X;
            float camera2OriginX = this.cameraOrigins[2].X;
            float camera3OriginX = this.cameraOrigins[3].X;
            float camera3OriginZ = this.cameraOrigins[3].Z;

            // animate sphere 0 around the frustum
            {
                BoundingSphere sphere = this.secondarySpheres[0].Sphere;

                sphere.Center = new XMFloat3
                {
                    X = 10 * XMScalar.Sin(3 * t),
                    Y = 7 * XMScalar.Cos(5 * t),
                    Z = sphere.Center.Z
                };

                this.secondarySpheres[0].Sphere = sphere;
            }

            // animate oriented box 0 around the frustum
            {
                BoundingOrientedBox box = this.secondaryOrientedBoxes[0].Box;

                box.Center = new XMFloat3
                {
                    X = 8 * XMScalar.Sin(3.5f * t),
                    Y = 5 * XMScalar.Cos(5.1f * t),
                    Z = box.Center.Z
                };

                box.Orientation = XMQuaternion.RotationRollPitchYaw(t * 1.4f, t * 0.2f, t);

                this.secondaryOrientedBoxes[0].Box = box;
            }

            // animate aligned box 0 around the frustum
            {
                BoundingBox box = this.secondaryAABoxes[0].Box;

                box.Center = new XMFloat3
                {
                    X = 10 * XMScalar.Sin(2.1f * t),
                    Y = 7 * XMScalar.Cos(3.8f * t),
                    Z = box.Center.Z
                };

                this.secondaryAABoxes[0].Box = box;
            }

            // animate sphere 1 around the aligned box
            {
                BoundingSphere sphere = this.secondarySpheres[1].Sphere;

                sphere.Center = new XMFloat3
                {
                    X = 8 * XMScalar.Sin(2.9f * t) + camera1OriginX,
                    Y = 8 * XMScalar.Cos(4.6f * t),
                    Z = 8 * XMScalar.Cos(1.6f * t)
                };

                this.secondarySpheres[1].Sphere = sphere;
            }

            // animate oriented box 1 around the aligned box
            {
                BoundingOrientedBox box = this.secondaryOrientedBoxes[1].Box;

                box.Center = new XMFloat3
                {
                    X = 8 * XMScalar.Sin(3.2f * t) + camera1OriginX,
                    Y = 8 * XMScalar.Cos(2.1f * t),
                    Z = 8 * XMScalar.Sin(1.6f * t)
                };

                box.Orientation = XMQuaternion.RotationRollPitchYaw(t * 0.7f, t * 1.3f, t);

                this.secondaryOrientedBoxes[1].Box = box;
            }

            // animate aligned box 1 around the aligned box
            {
                BoundingBox box = this.secondaryAABoxes[1].Box;

                box.Center = new XMFloat3
                {
                    X = 8 * XMScalar.Sin(1.1f * t) + camera1OriginX,
                    Y = 8 * XMScalar.Cos(5.8f * t),
                    Z = 8 * XMScalar.Cos(3.0f * t)
                };

                this.secondaryAABoxes[1].Box = box;
            }

            // animate sphere 2 around the oriented box
            {
                BoundingSphere sphere = this.secondarySpheres[2].Sphere;

                sphere.Center = new XMFloat3
                {
                    X = 8 * XMScalar.Sin(2.2f * t) + camera2OriginX,
                    Y = 8 * XMScalar.Cos(4.3f * t),
                    Z = 8 * XMScalar.Cos(1.8f * t)
                };

                this.secondarySpheres[2].Sphere = sphere;
            }

            // animate oriented box 2 around the oriented box
            {
                BoundingOrientedBox box = this.secondaryOrientedBoxes[2].Box;

                box.Center = new XMFloat3
                {
                    X = 8 * XMScalar.Sin(3.7f * t) + camera2OriginX,
                    Y = 8 * XMScalar.Cos(2.5f * t),
                    Z = 8 * XMScalar.Sin(1.1f * t)
                };

                box.Orientation = XMQuaternion.RotationRollPitchYaw(t * 0.9f, t * 1.8f, t);

                this.secondaryOrientedBoxes[2].Box = box;
            }

            // animate aligned box 2 around the oriented box
            {
                BoundingBox box = this.secondaryAABoxes[2].Box;

                box.Center = new XMFloat3
                {
                    X = 8 * XMScalar.Sin(1.3f * t) + camera2OriginX,
                    Y = 8 * XMScalar.Cos(5.2f * t),
                    Z = 8 * XMScalar.Cos(3.5f * t)
                };

                this.secondaryAABoxes[2].Box = box;
            }

            // triangle points in local space - equilateral triangle with radius of 2
            XMVector trianglePointA = new(0, 2, 0, 0);
            XMVector trianglePointB = new(1.732f, -1, 0, 0);
            XMVector trianglePointC = new(-1.732f, -1, 0, 0);

            XMMatrix triangleCoords;
            XMMatrix translation;

            // animate triangle 0 around the frustum
            triangleCoords = XMMatrix.RotationRollPitchYaw(t * 1.4f, t * 2.5f, t);
            translation    = XMMatrix.Translation(
                5 * XMScalar.Sin(5.3f * t) + camera0OriginX,
                5 * XMScalar.Cos(2.3f * t),
                5 * XMScalar.Sin(3.4f * t));
            triangleCoords = XMMatrix.Multiply(triangleCoords, translation);
            this.secondaryTriangles[0].PointA = XMVector3.Transform(trianglePointA, triangleCoords);
            this.secondaryTriangles[0].PointB = XMVector3.Transform(trianglePointB, triangleCoords);
            this.secondaryTriangles[0].PointC = XMVector3.Transform(trianglePointC, triangleCoords);

            // animate triangle 1 around the aligned box
            triangleCoords = XMMatrix.RotationRollPitchYaw(t * 1.4f, t * 2.5f, t);
            translation    = XMMatrix.Translation(
                8 * XMScalar.Sin(5.3f * t) + camera1OriginX,
                8 * XMScalar.Cos(2.3f * t),
                8 * XMScalar.Sin(3.4f * t));
            triangleCoords = XMMatrix.Multiply(triangleCoords, translation);
            this.secondaryTriangles[1].PointA = XMVector3.Transform(trianglePointA, triangleCoords);
            this.secondaryTriangles[1].PointB = XMVector3.Transform(trianglePointB, triangleCoords);
            this.secondaryTriangles[1].PointC = XMVector3.Transform(trianglePointC, triangleCoords);

            // animate triangle 2 around the oriented box
            triangleCoords = XMMatrix.RotationRollPitchYaw(t * 1.4f, t * 2.5f, t);
            translation    = XMMatrix.Translation(
                8 * XMScalar.Sin(5.3f * t) + camera2OriginX,
                8 * XMScalar.Cos(2.3f * t),
                8 * XMScalar.Sin(3.4f * t));
            triangleCoords = XMMatrix.Multiply(triangleCoords, translation);
            this.secondaryTriangles[2].PointA = XMVector3.Transform(trianglePointA, triangleCoords);
            this.secondaryTriangles[2].PointB = XMVector3.Transform(trianglePointB, triangleCoords);
            this.secondaryTriangles[2].PointC = XMVector3.Transform(trianglePointC, triangleCoords);

            // animate primary ray (this is the only animated primary object)
            this.primaryRay.Direction = new XMVector(XMScalar.Sin(t * 3), 0, XMScalar.Cos(t * 3), 0);

            // animate sphere 3 around the ray
            {
                BoundingSphere sphere = this.secondarySpheres[3].Sphere;

                sphere.Center = new XMFloat3(camera3OriginX - 3, 0.5f * XMScalar.Sin(t * 5), camera3OriginZ);

                this.secondarySpheres[3].Sphere = sphere;
            }

            // animate aligned box 3 around the ray
            {
                BoundingBox box = this.secondaryAABoxes[3].Box;

                box.Center = new XMFloat3(camera3OriginX + 3, 0.5f * XMScalar.Sin(t * 4), camera3OriginZ);

                this.secondaryAABoxes[3].Box = box;
            }

            // animate oriented box 3 around the ray
            {
                BoundingOrientedBox box = this.secondaryOrientedBoxes[3].Box;

                box.Center      = new XMFloat3(camera3OriginX, 0.5f * XMScalar.Sin(t * 4.5f), camera3OriginZ + 3);
                box.Orientation = XMQuaternion.RotationRollPitchYaw(t * 0.9f, t * 1.8f, t);

                this.secondaryOrientedBoxes[3].Box = box;
            }

            // animate triangle 3 around the ray
            triangleCoords = XMMatrix.RotationRollPitchYaw(t * 1.4f, t * 2.5f, t);
            translation    = XMMatrix.Translation(
                camera3OriginX,
                0.5f * XMScalar.Cos(4.3f * t),
                camera3OriginZ - 3);
            triangleCoords = XMMatrix.Multiply(triangleCoords, translation);
            this.secondaryTriangles[3].PointA = XMVector3.Transform(trianglePointA, triangleCoords);
            this.secondaryTriangles[3].PointB = XMVector3.Transform(trianglePointB, triangleCoords);
            this.secondaryTriangles[3].PointC = XMVector3.Transform(trianglePointC, triangleCoords);
        }
 public bool Intersects(BoundingOrientedBox box)
 {
     return(box.Intersects(this));
 }
 public static BoundingSphere CreateFromOrientedBox(BoundingOrientedBox box)
 {
     // Bounding box orientation is irrelevant because a sphere is rotationally invariant
     return(new BoundingSphere(box.Center, XMVector3.Length(box.Extents).X));
 }
Example #14
0
 /// <summary>
 /// Determines whether the given BoundingOrientedBox contains/intersects/is disjoint from the
 /// given triangle.
 /// </summary>
 public static ContainmentType Contains(ref BoundingOrientedBox obox, ref Triangle triangle)
 {
     return Contains(ref obox, ref triangle.V0, ref triangle.V1, ref triangle.V2);
 }
        /// <summary>
        /// Intersectses this instance.
        /// </summary>
        /// <param name="center">The center.</param>
        /// <param name="radius">The radius.</param>
        /// <param name="boxCollider">The box collider.</param>
        /// <returns>true if intersects</returns>
        private bool Intersects(Vector3 center, float radius, BoundingOrientedBox boxCollider)
        {
            Vector2 circleDistance = Vector2.Zero;
            circleDistance.X = Math.Abs(center.Z - boxCollider.Center.Z);
            circleDistance.Y = Math.Abs(center.Y - boxCollider.Center.Y);

            if (circleDistance.X > (boxCollider.HalfExtent.Z + radius)) { return false; }
            if (circleDistance.Y > (boxCollider.HalfExtent.Y + radius)) { return false; }

            if (circleDistance.X <= (boxCollider.HalfExtent.Z)) { return true; }
            if (circleDistance.Y <= (boxCollider.HalfExtent.Y)) { return true; }

            var cornerDistanceSq = Math.Sqrt(circleDistance.X - boxCollider.HalfExtent.Z) +
                                Math.Sqrt(circleDistance.Y - boxCollider.HalfExtent.Y);

            return (cornerDistanceSq <= (Math.Sqrt(radius)));
        }
        /// <summary>
        /// Intersectses the sphere with box.
        /// </summary>
        /// <param name="center">The center.</param>
        /// <param name="radius">The radius.</param>
        /// <param name="boxCollider">The box collider.</param>
        /// <returns>
        /// True if intersects
        /// </returns>
        public CollisionType CheckCollisionType(Vector3 center, float radius, BoundingOrientedBox boxCollider, string tag)
        {
            CollisionType res = CollisionType.NONE;

            bool collides = this.Intersects(center, radius, boxCollider);

            if (collides)
            {
                if (tag.Equals(KILLERTAG))
                {
                    res = CollisionType.KILLER;
                }
                else
                {
                    Vector2 CB = new Vector2(boxCollider.Center.Z - center.Z, boxCollider.Center.Y - center.Y);
                    CB.Normalize();

                    var angle = Vector2.Angle(-Vector2.UnitY, CB);

                    if (angle > -rad30 && angle < rad30)
                    {
                        res = CollisionType.GROUND;
                    }
                    else
                    {
                        res = CollisionType.KILLER;
                    }
                }
            }

            return res;
        }