Exemplo n.º 1
0
 /// <summary>
 /// Get the axis-aligned <see cref="BoundingBox"/> which contains all <see cref="OrientedBoundingBox"/> corners.
 /// </summary>
 /// <returns>The axis-aligned BoundingBox of this OrientedBoundingBox.</returns>
 public BoundingBox GetBoundingBox()
 {
     return(BoundingBox.FromPoints(GetCorners()));
 }
Exemplo n.º 2
0
        /// <summary>
        /// Check the intersection between an <see cref="OrientedBoundingBox"/> and <see cref="BoundingBox"/>
        /// </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="OrientedBoundingBox"/> must not have any scaling applied to it.
        /// Anyway, scaling using Scale method will keep this method accurate.
        /// </remarks>
        public ContainmentType Contains(ref BoundingBox box)
        {
            var cornersCheck = Contains(box.GetCorners());

            if (cornersCheck != ContainmentType.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;

            Matrix.Invert(ref Transformation, out var R);
            var AR = new Matrix();      // 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 Vector3(Vector3.Dot(vSepWS, RotA[0]), Vector3.Dot(vSepWS, RotA[1]), Vector3.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    = Vector3.Dot(SizeB, new Vector3(AR[i, 0], AR[i, 1], AR[i, 2]));
                Separation = Math.Abs(vSepA[i]);

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

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

                if (Separation > ExtentA + ExtentB)
                {
                    return(ContainmentType.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(ContainmentType.Disjoint);
                    }
                }
            }

            // No separating axis found, the boxes overlap
            return(ContainmentType.Intersects);
        }