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); }
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); }
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); }
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); }
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)); }
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); }
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); }
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); }