Пример #1
0
        public ContainmentType Contains(BoundingBox box)
        {
            XMVector centerA  = this.center;
            XMVector extentsA = this.extents;

            XMVector centerB  = box.center;
            XMVector extentsB = box.extents;

            XMVector minA = centerA - extentsA;
            XMVector maxA = centerA + extentsA;

            XMVector minB = centerB - extentsB;
            XMVector maxB = centerB + extentsB;

            // for each i in (x, y, z) if a_min(i) > b_max(i) or b_min(i) > a_max(i) then return false
            XMVector disjoint = XMVector.OrInt(XMVector.Greater(minA, maxB), XMVector.Greater(minB, maxA));

            if (Internal.XMVector3AnyTrue(disjoint))
            {
                return(ContainmentType.Disjoint);
            }

            // for each i in (x, y, z) if a_min(i) <= b_min(i) and b_max(i) <= a_max(i) then A contains B
            XMVector inside = XMVector.AndInt(XMVector.LessOrEqual(minA, minB), XMVector.LessOrEqual(maxB, maxA));

            return(Internal.XMVector3AllTrue(inside) ? ContainmentType.Contains : ContainmentType.Intersects);
        }
Пример #2
0
        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);
        }
        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);
        }
        public ContainmentType Contains(BoundingBox 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 insideAll = XMVector.TrueInt;

            XMVector offset = boxCenter - v_center;

            for (int i = 0; i < BoundingBox.CornerCount; i++)
            {
                XMVector c = XMVector.MultiplyAdd(boxExtents, CollisionGlobalConstants.BoxOffsets[i], offset);
                XMVector d = XMVector3.LengthSquare(c);

                insideAll = XMVector.AndInt(insideAll, XMVector.LessOrEqual(d, radiusSq));
            }

            return(XMVector3.EqualInt(insideAll, XMVector.TrueInt) ? ContainmentType.Contains : ContainmentType.Intersects);
        }
Пример #5
0
        public ContainmentType ContainedBy(
            XMVector plane0,
            XMVector plane1,
            XMVector plane2,
            XMVector plane3,
            XMVector plane4,
            XMVector plane5)
        {
            // Load the box.
            XMVector v_center  = this.center;
            XMVector v_extents = this.extents;

            // Set w of the center to one so we can dot4 with a plane.
            v_center.W = 1.0f;

            XMVector outside, inside;

            // Test against each plane.
            Internal.FastIntersectAxisAlignedBoxPlane(v_center, v_extents, plane0, out outside, out inside);

            XMVector anyOutside = outside;
            XMVector allInside  = inside;

            Internal.FastIntersectAxisAlignedBoxPlane(v_center, v_extents, plane1, out outside, out inside);
            anyOutside = XMVector.OrInt(anyOutside, outside);
            allInside  = XMVector.AndInt(allInside, inside);

            Internal.FastIntersectAxisAlignedBoxPlane(v_center, v_extents, plane2, out outside, out inside);
            anyOutside = XMVector.OrInt(anyOutside, outside);
            allInside  = XMVector.AndInt(allInside, inside);

            Internal.FastIntersectAxisAlignedBoxPlane(v_center, v_extents, plane3, out outside, out inside);
            anyOutside = XMVector.OrInt(anyOutside, outside);
            allInside  = XMVector.AndInt(allInside, inside);

            Internal.FastIntersectAxisAlignedBoxPlane(v_center, v_extents, plane4, out outside, out inside);
            anyOutside = XMVector.OrInt(anyOutside, outside);
            allInside  = XMVector.AndInt(allInside, inside);

            Internal.FastIntersectAxisAlignedBoxPlane(v_center, v_extents, plane5, out outside, out inside);
            anyOutside = XMVector.OrInt(anyOutside, outside);
            allInside  = XMVector.AndInt(allInside, inside);

            // If the box is outside any plane it is outside.
            if (XMVector4.EqualInt(anyOutside, XMVector.TrueInt))
            {
                return(ContainmentType.Disjoint);
            }

            // If the box is inside all planes it is inside.
            if (XMVector4.EqualInt(allInside, XMVector.TrueInt))
            {
                return(ContainmentType.Contains);
            }

            // The box is not inside all planes or outside a plane, it may intersect.
            return(ContainmentType.Intersects);
        }
        public bool Intersects(XMVector origin, XMVector direction, out float distance)
        {
            Debug.Assert(Internal.XMVector3IsUnit(direction), "Reviewed");

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

            // l is the vector from the ray origin to the center of the sphere.
            XMVector l = v_center - origin;

            // s is the projection of the l onto the ray direction.
            XMVector s = XMVector3.Dot(l, direction);

            XMVector l2 = XMVector3.Dot(l, l);

            XMVector r2 = v_radius * v_radius;

            // m2 is squared distance from the center of the sphere to the projection.
            XMVector m2 = l2 - (s * s);

            XMVector noIntersection;

            // If the ray origin is outside the sphere and the center of the sphere is
            // behind the ray origin there is no intersection.
            noIntersection = XMVector.AndInt(XMVector.Less(s, XMGlobalConstants.Zero), XMVector.Greater(l2, r2));

            // If the squared distance from the center of the sphere to the projection
            // is greater than the radius squared the ray will miss the sphere.
            noIntersection = XMVector.OrInt(noIntersection, XMVector.Greater(m2, r2));

            // The ray hits the sphere, compute the nearest intersection point.
            XMVector q  = (r2 - m2).Sqrt();
            XMVector t1 = s - q;
            XMVector t2 = s + q;

            XMVector originInside = XMVector.LessOrEqual(l2, r2);
            XMVector t            = XMVector.Select(t1, t2, originInside);

            if (XMVector4.NotEqualInt(noIntersection, XMVector.TrueInt))
            {
                // Store the x-component to *pDist.
                t.StoreFloat(out distance);
                return(true);
            }

            distance = 0.0f;
            return(false);
        }
        public ContainmentType Contains(BoundingFrustum fr)
        {
            if (!fr.Intersects(this))
            {
                return(ContainmentType.Disjoint);
            }

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

            XMVector v_origin      = fr.Origin;
            XMVector v_orientation = fr.Orientation;

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

            // Build the corners of the frustum.
            XMVector v_rightTop    = new XMVector(fr.RightSlope, fr.TopSlope, 1.0f, 0.0f);
            XMVector v_rightBottom = new XMVector(fr.RightSlope, fr.BottomSlope, 1.0f, 0.0f);
            XMVector v_leftTop     = new XMVector(fr.LeftSlope, fr.TopSlope, 1.0f, 0.0f);
            XMVector v_leftBottom  = new XMVector(fr.LeftSlope, fr.BottomSlope, 1.0f, 0.0f);
            XMVector v_near        = XMVector.Replicate(fr.Near);
            XMVector v_far         = XMVector.Replicate(fr.Far);

            XMVector[] corners = new XMVector[BoundingFrustum.CornerCount];
            corners[0] = v_rightTop * v_near;
            corners[1] = v_rightBottom * v_near;
            corners[2] = v_leftTop * v_near;
            corners[3] = v_leftBottom * v_near;
            corners[4] = v_rightTop * v_far;
            corners[5] = v_rightBottom * v_far;
            corners[6] = v_leftTop * v_far;
            corners[7] = v_leftBottom * v_far;

            XMVector insideAll = XMVector.TrueInt;

            for (int i = 0; i < BoundingFrustum.CornerCount; i++)
            {
                XMVector c = XMVector3.Rotate(corners[i], v_orientation) + v_origin;
                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);
        }
Пример #8
0
        public ContainmentType Contains(BoundingSphere sh)
        {
            XMVector sphereCenter = sh.Center;
            XMVector sphereRadius = XMVector.Replicate(sh.Radius);

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

            XMVector boxMin = boxCenter - boxExtents;
            XMVector boxMax = boxCenter + boxExtents;

            //// Find the distance to the nearest point on the box.
            //// for each i in (x, y, z)
            //// if (SphereCenter(i) < BoxMin(i)) d2 += (SphereCenter(i) - BoxMin(i)) ^ 2
            //// else if (SphereCenter(i) > BoxMax(i)) d2 += (SphereCenter(i) - BoxMax(i)) ^ 2

            XMVector d = XMGlobalConstants.Zero;

            // Compute d for each dimension.
            XMVector lessThanMin    = XMVector.Less(sphereCenter, boxMin);
            XMVector greaterThanMax = XMVector.Greater(sphereCenter, boxMax);

            XMVector minDelta = sphereCenter - boxMin;
            XMVector maxDelta = sphereCenter - boxMax;

            // Choose value for each dimension based on the comparison.
            d = XMVector.Select(d, minDelta, lessThanMin);
            d = XMVector.Select(d, maxDelta, greaterThanMax);

            // Use a dot-product to square them and sum them together.
            XMVector d2 = XMVector3.Dot(d, d);

            if (XMVector3.Greater(d2, XMVector.Multiply(sphereRadius, sphereRadius)))
            {
                return(ContainmentType.Disjoint);
            }

            XMVector insideAll = XMVector.LessOrEqual(boxMin + sphereRadius, sphereCenter);

            insideAll = XMVector.AndInt(insideAll, XMVector.LessOrEqual(sphereCenter, boxMax - sphereRadius));
            insideAll = XMVector.AndInt(insideAll, XMVector.Greater(boxMax - boxMin, sphereRadius));

            return(XMVector3.EqualInt(insideAll, XMVector.TrueInt) ? ContainmentType.Contains : ContainmentType.Intersects);
        }
Пример #9
0
        public static XMVector PointOnPlaneInsideTriangle(XMVector p, XMVector v0, XMVector v1, XMVector v2)
        {
            // Compute the triangle normal.
            XMVector n = XMVector3.Cross(v2 - v0, v1 - v0);

            // Compute the cross products of the vector from the base of each edge to
            // the point with each edge vector.
            XMVector c0 = XMVector3.Cross(p - v0, v1 - v0);
            XMVector c1 = XMVector3.Cross(p - v1, v2 - v1);
            XMVector c2 = XMVector3.Cross(p - v2, v0 - v2);

            // If the cross product points in the same direction as the normal the the
            // point is inside the edge (it is zero if is on the edge).
            XMVector zero    = XMGlobalConstants.Zero;
            XMVector inside0 = XMVector.GreaterOrEqual(XMVector3.Dot(c0, n), zero);
            XMVector inside1 = XMVector.GreaterOrEqual(XMVector3.Dot(c1, n), zero);
            XMVector inside2 = XMVector.GreaterOrEqual(XMVector3.Dot(c2, n), zero);

            // If the point inside all of the edges it is inside.
            return(XMVector.AndInt(XMVector.AndInt(inside0, inside1), inside2));
        }
Пример #10
0
        public ContainmentType Contains(XMVector v0, XMVector v1, XMVector v2)
        {
            if (!this.Intersects(v0, v1, v2))
            {
                return(ContainmentType.Disjoint);
            }

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

            XMVector d      = XMVector.Subtract(v0, boxCenter).Abs();
            XMVector inside = XMVector.LessOrEqual(d, boxExtents);

            d      = XMVector.Subtract(v1, boxCenter).Abs();
            inside = XMVector.AndInt(inside, XMVector.LessOrEqual(d, boxExtents));

            d      = XMVector.Subtract(v2, boxCenter).Abs();
            inside = XMVector.AndInt(inside, XMVector.LessOrEqual(d, boxExtents));

            return(XMVector3.EqualInt(inside, XMVector.TrueInt) ? ContainmentType.Contains : ContainmentType.Intersects);
        }
        public ContainmentType Contains(XMVector v0, XMVector v1, XMVector v2)
        {
            if (!this.Intersects(v0, v1, v2))
            {
                return(ContainmentType.Disjoint);
            }

            XMVector v_center      = this.center;
            XMVector v_radius      = XMVector.Replicate(this.radius);
            XMVector radiusSquared = XMVector.Multiply(v_radius, v_radius);

            XMVector distanceSquared = XMVector3.LengthSquare(v0 - v_center);
            XMVector inside          = XMVector.LessOrEqual(distanceSquared, radiusSquared);

            distanceSquared = XMVector3.LengthSquare(v1 - v_center);
            inside          = XMVector.AndInt(inside, XMVector.LessOrEqual(distanceSquared, radiusSquared));

            distanceSquared = XMVector3.LengthSquare(v2 - v_center);
            inside          = XMVector.AndInt(inside, XMVector.LessOrEqual(distanceSquared, radiusSquared));

            return(XMVector3.EqualInt(inside, XMVector.TrueInt) ? ContainmentType.Contains : ContainmentType.Intersects);
        }
Пример #12
0
        public ContainmentType Contains(BoundingFrustum fr)
        {
            if (!fr.Intersects(this))
            {
                return(ContainmentType.Disjoint);
            }

            XMFloat3[] corners = fr.GetCorners();

            XMVector v_center  = this.center;
            XMVector v_extents = this.extents;

            XMVector inside = XMVector.TrueInt;

            for (int i = 0; i < BoundingFrustum.CornerCount; i++)
            {
                XMVector point = corners[i];
                XMVector d     = XMVector.Subtract(point, v_center).Abs();
                inside = XMVector.AndInt(inside, XMVector.LessOrEqual(d, v_extents));
            }

            return(XMVector3.EqualInt(inside, XMVector.TrueInt) ? ContainmentType.Contains : ContainmentType.Intersects);
        }
Пример #13
0
        public static ContainmentType ContainedBy(
            XMVector v0,
            XMVector v1,
            XMVector v2,
            XMVector plane0,
            XMVector plane1,
            XMVector plane2,
            XMVector plane3,
            XMVector plane4,
            XMVector plane5)
        {
            XMVector one = XMGlobalConstants.One;

            // Set w of the points to one so we can dot4 with a plane.
            XMVector tV0 = new XMVector(v0.X, v0.Y, v0.Z, one.W);
            XMVector tV1 = new XMVector(v1.X, v1.Y, v1.Z, one.W);
            XMVector tV2 = new XMVector(v2.X, v2.Y, v2.Z, one.W);

            XMVector outside, inside;

            // Test against each plane.
            Internal.FastIntersectTrianglePlane(tV0, tV1, tV2, plane0, out outside, out inside);

            XMVector anyOutside = outside;
            XMVector allInside  = inside;

            Internal.FastIntersectTrianglePlane(tV0, tV1, tV2, plane1, out outside, out inside);
            anyOutside = XMVector.OrInt(anyOutside, outside);
            allInside  = XMVector.AndInt(allInside, inside);

            Internal.FastIntersectTrianglePlane(tV0, tV1, tV2, plane2, out outside, out inside);
            anyOutside = XMVector.OrInt(anyOutside, outside);
            allInside  = XMVector.AndInt(allInside, inside);

            Internal.FastIntersectTrianglePlane(tV0, tV1, tV2, plane3, out outside, out inside);
            anyOutside = XMVector.OrInt(anyOutside, outside);
            allInside  = XMVector.AndInt(allInside, inside);

            Internal.FastIntersectTrianglePlane(tV0, tV1, tV2, plane4, out outside, out inside);
            anyOutside = XMVector.OrInt(anyOutside, outside);
            allInside  = XMVector.AndInt(allInside, inside);

            Internal.FastIntersectTrianglePlane(tV0, tV1, tV2, plane5, out outside, out inside);
            anyOutside = XMVector.OrInt(anyOutside, outside);
            allInside  = XMVector.AndInt(allInside, inside);

            // If the triangle is outside any plane it is outside.
            if (XMVector4.EqualInt(anyOutside, XMVector.TrueInt))
            {
                return(ContainmentType.Disjoint);
            }

            // If the triangle is inside all planes it is inside.
            if (XMVector4.EqualInt(allInside, XMVector.TrueInt))
            {
                return(ContainmentType.Contains);
            }

            // The triangle is not inside all planes or outside a plane, it may intersect.
            return(ContainmentType.Intersects);
        }