예제 #1
0
        public bool Intersects(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);

            return(XMVector3.LessOrEqual(d2, XMVector.Multiply(sphereRadius, sphereRadius)));
        }
        public ContainmentType Contains(XMVector point)
        {
            XMVector v_center = this.center;
            XMVector v_radius = XMVector.Replicate(this.radius);

            XMVector distanceSquared = XMVector3.LengthSquare(point - v_center);
            XMVector radiusSquared   = XMVector.Multiply(v_radius, v_radius);

            return(XMVector3.LessOrEqual(distanceSquared, radiusSquared) ? ContainmentType.Contains : ContainmentType.Disjoint);
        }
예제 #3
0
        public static BoundingBox CreateFromSphere(BoundingSphere sh)
        {
            XMVector sp_Center = sh.Center;
            XMVector sh_Radius = XMVector.Replicate(sh.Radius);

            XMVector min = XMVector.Subtract(sp_Center, sh_Radius);
            XMVector max = XMVector.Add(sp_Center, sh_Radius);

            Debug.Assert(XMVector3.LessOrEqual(min, max), "Reviewed");

            return(new BoundingBox((min + max) * 0.5f, (max - min) * 0.5f));
        }
예제 #4
0
        public static BoundingBox CreateMerged(BoundingBox b1, BoundingBox b2)
        {
            XMVector b1_Center  = b1.center;
            XMVector b1_Extents = b1.extents;

            XMVector b2_Center  = b2.center;
            XMVector b2_Extents = b2.extents;

            XMVector min = XMVector.Subtract(b1_Center, b1_Extents);

            min = XMVector.Min(min, XMVector.Subtract(b2_Center, b2_Extents));

            XMVector max = XMVector.Add(b1_Center, b1_Extents);

            max = XMVector.Max(max, XMVector.Add(b2_Center, b2_Extents));

            Debug.Assert(XMVector3.LessOrEqual(min, max), "Reviewed");

            return(new BoundingBox((min + max) * 0.5f, (max - min) * 0.5f));
        }
        public bool Intersects(BoundingSphere sh)
        {
            // Load A.
            XMVector v_centerA = this.center;
            XMVector v_radiusA = XMVector.Replicate(this.radius);

            // Load B.
            XMVector v_centerB = sh.center;
            XMVector v_radiusB = XMVector.Replicate(sh.radius);

            // Distance squared between centers.
            XMVector delta           = v_centerB - v_centerA;
            XMVector distanceSquared = XMVector3.LengthSquare(delta);

            // Sum of the radii squared.
            XMVector radiusSquared = XMVector.Add(v_radiusA, v_radiusB);

            radiusSquared = XMVector.Multiply(radiusSquared, radiusSquared);

            return(XMVector3.LessOrEqual(distanceSquared, radiusSquared));
        }
예제 #6
0
        public static bool Intersects(XMVector origin, XMVector direction, XMVector v0, XMVector v1, XMVector v2, out float uCoordinate, out float vCoordinate, out float distance)
        {
            Debug.Assert(Internal.XMVector3IsUnit(direction), "Reviewed");

            XMVector zero = XMGlobalConstants.Zero;

            XMVector e1 = v1 - v0;
            XMVector e2 = v2 - v0;

            // p = Direction ^ e2;
            XMVector p = XMVector3.Cross(direction, e2);

            // det = e1 * p;
            XMVector det = XMVector3.Dot(e1, p);

            XMVector u, v, t;

            if (XMVector3.GreaterOrEqual(det, CollisionGlobalConstants.RayEpsilon))
            {
                // Determinate is positive (front side of the triangle).
                XMVector s = origin - v0;

                // u = s * p;
                u = XMVector3.Dot(s, p);

                XMVector noIntersection = XMVector.Less(u, zero);
                noIntersection = XMVector.OrInt(noIntersection, XMVector.Greater(u, det));

                // q = s ^ e1;
                XMVector q = XMVector3.Cross(s, e1);

                // v = Direction * q;
                v = XMVector3.Dot(direction, q);

                noIntersection = XMVector.OrInt(noIntersection, XMVector.Less(v, zero));
                noIntersection = XMVector.OrInt(noIntersection, XMVector.Greater(u + v, det));

                // t = e2 * q;
                t = XMVector3.Dot(e2, q);

                noIntersection = XMVector.OrInt(noIntersection, XMVector.Less(t, zero));

                if (XMVector4.EqualInt(noIntersection, XMVector.TrueInt))
                {
                    uCoordinate = 0.0f;
                    vCoordinate = 0.0f;
                    distance    = 0.0f;
                    return(false);
                }
            }
            else if (XMVector3.LessOrEqual(det, CollisionGlobalConstants.RayNegEpsilon))
            {
                // Determinate is negative (back side of the triangle).
                XMVector s = origin - v0;

                // u = s * p;
                u = XMVector3.Dot(s, p);

                XMVector noIntersection = XMVector.Greater(u, zero);
                noIntersection = XMVector.OrInt(noIntersection, XMVector.Less(u, det));

                // q = s ^ e1;
                XMVector q = XMVector3.Cross(s, e1);

                // v = Direction * q;
                v = XMVector3.Dot(direction, q);

                noIntersection = XMVector.OrInt(noIntersection, XMVector.Greater(v, zero));
                noIntersection = XMVector.OrInt(noIntersection, XMVector.Less(u + v, det));

                // t = e2 * q;
                t = XMVector3.Dot(e2, q);

                noIntersection = XMVector.OrInt(noIntersection, XMVector.Greater(t, zero));

                if (XMVector4.EqualInt(noIntersection, XMVector.TrueInt))
                {
                    uCoordinate = 0.0f;
                    vCoordinate = 0.0f;
                    distance    = 0.0f;
                    return(false);
                }
            }
            else
            {
                // Parallel ray.
                uCoordinate = 0.0f;
                vCoordinate = 0.0f;
                distance    = 0.0f;
                return(false);
            }

            // (u / det) and (v / dev) are the barycentric coordinates of the intersection.

            u = XMVector.Divide(u, det);
            v = XMVector.Divide(v, det);
            t = XMVector.Divide(t, det);

            // Store the x-component to *pDist
            u.StoreFloat(out uCoordinate);
            v.StoreFloat(out vCoordinate);
            t.StoreFloat(out distance);

            return(true);
        }