Ejemplo n.º 1
0
        private void GetBoxToPlanePVertexNVertex(ref MyBoundingBox box, ref MyVector3 planeNormal, out MyVector3 p, out MyVector3 n)
        {
            p = box.Minimum;
            if (planeNormal.X >= 0)
            {
                p.X = box.Maximum.X;
            }
            if (planeNormal.Y >= 0)
            {
                p.Y = box.Maximum.Y;
            }
            if (planeNormal.Z >= 0)
            {
                p.Z = box.Maximum.Z;
            }

            n = box.Maximum;
            if (planeNormal.X >= 0)
            {
                n.X = box.Minimum.X;
            }
            if (planeNormal.Y >= 0)
            {
                n.Y = box.Minimum.Y;
            }
            if (planeNormal.Z >= 0)
            {
                n.Z = box.Minimum.Z;
            }
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Constructs a <see cref="MyBoundingSphere"/> from a given box.
        /// </summary>
        /// <param name="box">The box that will designate the extents of the sphere.</param>
        /// <returns>The newly constructed bounding sphere.</returns>
        public static MyBoundingSphere FromBox(MyBoundingBox box)
        {
            MyBoundingSphere result;

            FromBox(ref box, out result);
            return(result);
        }
Ejemplo n.º 3
0
        /// <summary>
        /// Constructs a <see cref="MyBoundingSphere"/> from a given box.
        /// </summary>
        /// <param name="box">The box that will designate the extents of the sphere.</param>
        /// <param name="result">When the method completes, the newly constructed bounding sphere.</param>
        public static void FromBox(ref MyBoundingBox box, out MyBoundingSphere result)
        {
            MyVector3.Lerp(ref box.Minimum, ref box.Maximum, 0.5f, out result.Center);

            float x = box.Minimum.X - box.Maximum.X;
            float y = box.Minimum.Y - box.Maximum.Y;
            float z = box.Minimum.Z - box.Maximum.Z;

            float distance = (float)(Math.Sqrt((x * x) + (y * y) + (z * z)));

            result.Radius = distance * 0.5f;
        }
Ejemplo n.º 4
0
        /// <summary>
        /// Determines whether there is an intersection between a <see cref="MyRay"/> and a <see cref="MyOrientedBoundingBox"/>.
        /// </summary>
        /// <param name="ray">The ray to test.</param>
        /// <param name="point">When the method completes, contains the point of intersection,
        /// or <see cref="MyVector3.Zero"/> if there was no intersection.</param>
        /// <returns>Whether the two objects intersected.</returns>
        public bool Intersects(ref MyRay ray, out MyVector3 point)
        {
            // Put ray in box space
            MyMatrix invTrans;
            MyMatrix.Invert(ref Transformation, out invTrans);

            MyRay bRay;
            MyVector3.TransformNormal(ref ray.Direction, ref invTrans, out bRay.Direction);
            MyVector3.TransformCoordinate(ref ray.Position, ref invTrans, out bRay.Position);

            //Perform a regular ray to BoundingBox check
            var bb = new MyBoundingBox(-Extents, Extents);
            var intersects = MyCollision.RayIntersectsBox(ref bRay, ref bb, out point);

            //Put the result intersection back to world
            if (intersects)
                MyVector3.TransformCoordinate(ref point, ref Transformation, out point);

            return intersects;
        }
Ejemplo n.º 5
0
        /// <summary>
        /// Determines the intersection relationship between the frustum and a bounding box.
        /// </summary>
        /// <param name="box">The box.</param>
        /// <returns>Type of the containment</returns>
        public MyContainmentType Contains(ref MyBoundingBox box)
        {
            MyVector3 p, n;
            MyPlane   plane;
            var       result = MyContainmentType.Contains;

            for (int i = 0; i < 6; i++)
            {
                plane = GetPlane(i);
                GetBoxToPlanePVertexNVertex(ref box, ref plane.Normal, out p, out n);
                if (MyCollision.PlaneIntersectsPoint(ref plane, ref p) == MyPlaneIntersectionType.Back)
                {
                    return(MyContainmentType.Disjoint);
                }

                if (MyCollision.PlaneIntersectsPoint(ref plane, ref n) == MyPlaneIntersectionType.Back)
                {
                    result = MyContainmentType.Intersects;
                }
            }
            return(result);
        }
Ejemplo n.º 6
0
        /// <summary>
        /// Merge an OrientedBoundingBox B into another OrientedBoundingBox A, by expanding A to contain B and keeping A orientation.
        /// </summary>
        /// <param name="A">The <see cref="MyOrientedBoundingBox"/> to merge into it.</param>
        /// <param name="B">The <see cref="MyOrientedBoundingBox"/> to be merged</param>
        /// <param name="NoMatrixScaleApplied">
        /// If true, the method will use a fast algorithm which is inapplicable if a scale is applied to the transformation matrix of the OrientedBoundingBox.
        /// </param>
        /// <remarks>
        /// Unlike merging axis aligned boxes, The operation is not interchangeable, because it keeps A orientation and merge B into it.
        /// </remarks>
        public static void Merge(ref MyOrientedBoundingBox A, ref MyOrientedBoundingBox B, bool NoMatrixScaleApplied = false)
        {
            MyMatrix AtoB_Matrix = GetBoxToBoxMatrix(ref A, ref B, NoMatrixScaleApplied);

            //Get B corners in A Space
            var bCorners = B.GetLocalCorners();
            MyVector3.TransformCoordinate(bCorners, ref AtoB_Matrix, bCorners);

            //Get A local Bounding Box
            var A_LocalBB = new MyBoundingBox(-A.Extents, A.Extents);

            //Find B BoundingBox in A Space
            var B_LocalBB = MyBoundingBox.FromPoints(bCorners);

            //Merger A and B local Bounding Boxes
            MyBoundingBox mergedBB;
            MyBoundingBox.Merge(ref B_LocalBB, ref A_LocalBB, out mergedBB);

            //Find the new Extents and Center, Transform Center back to world
            var newCenter = mergedBB.Minimum + (mergedBB.Maximum - mergedBB.Minimum) / 2f;
            A.Extents = mergedBB.Maximum - newCenter;
            MyVector3.TransformCoordinate(ref newCenter, ref A.Transformation, out newCenter);
            A.Transformation.TranslationVector = newCenter;
        }
Ejemplo n.º 7
0
 /// <summary>
 /// Determines whether the current objects contains a <see cref="MyBoundingBox"/>.
 /// </summary>
 /// <param name="box">The box to test.</param>
 /// <returns>The type of containment the two objects have.</returns>
 public MyContainmentType Contains(ref MyBoundingBox box)
 {
     return(MyCollision.SphereContainsBox(ref this, ref box));
 }
Ejemplo n.º 8
0
 /// <summary>
 /// Determines if there is an intersection between the current object and a <see cref="MyBoundingBox"/>.
 /// </summary>
 /// <param name="box">The box to test.</param>
 /// <returns>Whether the two objects intersected.</returns>
 public bool Intersects(MyBoundingBox box)
 {
     return(Intersects(ref box));
 }
Ejemplo n.º 9
0
 /// <summary>
 /// Determines if there is an intersection between the current object and a <see cref="MyBoundingBox"/>.
 /// </summary>
 /// <param name="box">The box to test.</param>
 /// <returns>Whether the two objects intersected.</returns>
 public bool Intersects(ref MyBoundingBox box)
 {
     return(MyCollision.BoxIntersectsSphere(ref box, ref this));
 }
Ejemplo n.º 10
0
 /// <summary>
 /// Get the vector shift which when added to camera position will do the effect of zoom to extents (zoom to fit) operation,
 /// so all the passed points will fit in the current view.
 /// </summary>
 /// <param name="boundingBox">The bounding box.</param>
 /// <returns>The zoom to fit vector</returns>
 public MyVector3 GetZoomToExtentsShiftVector(ref MyBoundingBox boundingBox)
 {
     return(GetZoomToExtentsShiftDistance(boundingBox.GetCorners()) * pNear.Normal);
 }
Ejemplo n.º 11
0
 /// <summary>
 /// Get the distance which when added to camera position along the lookat direction will do the effect of zoom to extents (zoom to fit) operation,
 /// so all the passed points will fit in the current view.
 /// if the returned value is positive, the camera will move toward the lookat direction (ZoomIn).
 /// if the returned value is negative, the camera will move in the reverse direction of the lookat direction (ZoomOut).
 /// </summary>
 /// <param name="boundingBox">The bounding box.</param>
 /// <returns>The zoom to fit distance</returns>
 public float GetZoomToExtentsShiftDistance(ref MyBoundingBox boundingBox)
 {
     return(GetZoomToExtentsShiftDistance(boundingBox.GetCorners()));
 }
Ejemplo n.º 12
0
 /// <summary>
 /// Checks whether the current BoundingFrustum intersects a BoundingBox.
 /// </summary>
 /// <param name="box">The box.</param>
 /// <param name="result"><c>true</c> if the current BoundingFrustum intersects a BoundingSphere.</param>
 public void Intersects(ref MyBoundingBox box, out bool result)
 {
     result = Contains(ref box) != MyContainmentType.Disjoint;
 }
Ejemplo n.º 13
0
 /// <summary>
 /// Checks whether the current BoundingFrustum intersects a BoundingBox.
 /// </summary>
 /// <param name="box">The box.</param>
 /// <returns><c>true</c> if the current BoundingFrustum intersects a BoundingSphere.</returns>
 public bool Intersects(ref MyBoundingBox box)
 {
     return(Contains(ref box) != MyContainmentType.Disjoint);
 }
Ejemplo n.º 14
0
 /// <summary>
 /// Determines the intersection relationship between the frustum and a bounding box.
 /// </summary>
 /// <param name="box">The box.</param>
 /// <param name="result">Type of the containment.</param>
 public void Contains(ref MyBoundingBox box, out MyContainmentType result)
 {
     result = Contains(ref box);
 }
Ejemplo n.º 15
0
        /// <summary>
        /// Check the intersection between an <see cref="MyOrientedBoundingBox"/> and <see cref="MyBoundingBox"/>
        /// </summary>
        /// <param name="box">The BoundingBox to test.</param>
        /// <returns>The type of containment the two objects have.</returns>
        /// <remarks>
        /// For accuracy, The transformation matrix for the <see cref="MyOrientedBoundingBox"/> must not have any scaling applied to it.
        /// Anyway, scaling using Scale method will keep this method accurate.
        /// </remarks>
        public MyContainmentType Contains(ref MyBoundingBox box)
        {
            var cornersCheck = Contains(box.GetCorners());
            if (cornersCheck != MyContainmentType.Disjoint)
                return cornersCheck;

            var boxCenter = box.Minimum + (box.Maximum - box.Minimum) / 2f;
            var boxExtents = box.Maximum - boxCenter;

            var SizeA = Extents;
            var SizeB = boxExtents;
            var RotA = GetRows(ref Transformation);

            float ExtentA, ExtentB, Separation;
            int i, k;

            MyMatrix R;                   // Rotation from B to A
            MyMatrix.Invert(ref Transformation, out R);
            var AR = new MyMatrix();      // absolute values of R matrix, to use with box extents

            for (i = 0; i < 3; i++)
                for (k = 0; k < 3; k++)
                {
                    AR[i, k] = Math.Abs(R[i, k]);
                }


            // Vector separating the centers of Box B and of Box A	
            var vSepWS = boxCenter - Center;
            // Rotated into Box A's coordinates
            var vSepA = new MyVector3(MyVector3.Dot(vSepWS, RotA[0]), MyVector3.Dot(vSepWS, RotA[1]), MyVector3.Dot(vSepWS, RotA[2]));

            // Test if any of A's basis vectors separate the box
            for (i = 0; i < 3; i++)
            {
                ExtentA = SizeA[i];
                ExtentB = MyVector3.Dot(SizeB, new MyVector3(AR[i, 0], AR[i, 1], AR[i, 2]));
                Separation = Math.Abs(vSepA[i]);

                if (Separation > ExtentA + ExtentB)
                    return MyContainmentType.Disjoint;
            }

            // Test if any of B's basis vectors separate the box
            for (k = 0; k < 3; k++)
            {
                ExtentA = MyVector3.Dot(SizeA, new MyVector3(AR[0, k], AR[1, k], AR[2, k]));
                ExtentB = SizeB[k];
                Separation = Math.Abs(MyVector3.Dot(vSepA, new MyVector3(R[0, k], R[1, k], R[2, k])));

                if (Separation > ExtentA + ExtentB)
                    return MyContainmentType.Disjoint;
            }

            // Now test Cross Products of each basis vector combination ( A[i], B[k] )
            for (i = 0; i < 3; i++)
                for (k = 0; k < 3; k++)
                {
                    int i1 = (i + 1) % 3, i2 = (i + 2) % 3;
                    int k1 = (k + 1) % 3, k2 = (k + 2) % 3;
                    ExtentA = SizeA[i1] * AR[i2, k] + SizeA[i2] * AR[i1, k];
                    ExtentB = SizeB[k1] * AR[i, k2] + SizeB[k2] * AR[i, k1];
                    Separation = Math.Abs(vSepA[i2] * R[i1, k] - vSepA[i1] * R[i2, k]);
                    if (Separation > ExtentA + ExtentB)
                        return MyContainmentType.Disjoint;
                }

            // No separating axis found, the boxes overlap	
            return MyContainmentType.Intersects;
        }
Ejemplo n.º 16
0
 /// <summary>
 /// Get the axis-aligned <see cref="MyBoundingBox"/> which contains all <see cref="MyOrientedBoundingBox"/> corners.
 /// </summary>
 /// <returns>The axis-aligned BoundingBox of this OrientedBoundingBox.</returns>
 public MyBoundingBox GetBoundingBox()
 {
     return MyBoundingBox.FromPoints(GetCorners());
 }
Ejemplo n.º 17
0
 /// <summary>
 /// Determines if there is an intersection between the current object and a <see cref="MyBoundingBox"/>.
 /// </summary>
 /// <param name="box">The box to test.</param>
 /// <returns>Whether the two objects intersected.</returns>
 public MyPlaneIntersectionType Intersects(ref MyBoundingBox box)
 {
     return(MyCollision.PlaneIntersectsBox(ref this, ref box));
 }
Ejemplo n.º 18
0
 /// <summary>
 /// Determines if there is an intersection between the current object and a <see cref="MyBoundingBox"/>.
 /// </summary>
 /// <param name="box">The box to test.</param>
 /// <param name="point">When the method completes, contains the point of intersection,
 /// or <see cref="MyVector3.Zero"/> if there was no intersection.</param>
 /// <returns>Whether the two objects intersected.</returns>
 public bool Intersects(ref MyBoundingBox box, out MyVector3 point)
 {
     return(MyCollision.RayIntersectsBox(ref this, ref box, out point));
 }
Ejemplo n.º 19
0
 /// <summary>
 /// Determines if there is an intersection between the current object and a <see cref="MyBoundingBox"/>.
 /// </summary>
 /// <param name="box">The box to test.</param>
 /// <param name="distance">When the method completes, contains the distance of the intersection,
 /// or 0 if there was no intersection.</param>
 /// <returns>Whether the two objects intersected.</returns>
 public bool Intersects(ref MyBoundingBox box, out float distance)
 {
     return(MyCollision.RayIntersectsBox(ref this, ref box, out distance));
 }
Ejemplo n.º 20
0
 /// <summary>
 /// Determines the intersection relationship between the frustum and a bounding box.
 /// </summary>
 /// <param name="box">The box.</param>
 /// <returns>Type of the containment</returns>
 public MyContainmentType Contains(MyBoundingBox box)
 {
     return(Contains(ref box));
 }
Ejemplo n.º 21
0
 /// <summary>
 /// Creates an <see cref="MyOrientedBoundingBox"/> from a BoundingBox.
 /// </summary>
 /// <param name="bb">The BoundingBox to create from.</param>
 /// <remarks>
 /// Initially, the OBB is axis-aligned box, but it can be rotated and transformed later.
 /// </remarks>
 public MyOrientedBoundingBox(MyBoundingBox bb)
 {
     var Center = bb.Minimum + (bb.Maximum - bb.Minimum) / 2f;
     Extents = bb.Maximum - Center;
     Transformation = MyMatrix.Translation(Center);
 }