public static void FastIntersectOrientedBoxPlane( XMVector center, XMVector extents, XMVector axis0, XMVector axis1, XMVector axis2, XMVector plane, out XMVector outside, out XMVector inside) { // Compute the distance to the center of the box. XMVector dist = XMVector4.Dot(center, plane); // Project the axes of the box onto the normal of the plane. Half the // length of the projection (sometime called the "radius") is equal to // h(u) * abs(n dot b(u))) + h(v) * abs(n dot b(v)) + h(w) * abs(n dot b(w)) // where h(i) are extents of the box, n is the plane normal, and b(i) are the // axes of the box. XMVector radius = XMVector3.Dot(plane, axis0); radius.Y = XMVector3.Dot(plane, axis1).Y; radius.Z = XMVector3.Dot(plane, axis2).Z; radius = XMVector3.Dot(extents, radius.Abs()); // Outside the plane? outside = XMVector.Greater(dist, radius); // Fully inside the plane? inside = XMVector.Less(dist, -radius); }
public PlaneIntersectionType Intersects(XMVector plane) { Debug.Assert(Internal.XMPlaneIsUnit(plane), "Reviewed"); // 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; Internal.FastIntersectAxisAlignedBoxPlane(v_center, v_extents, plane, out outside, out inside); // If the box is outside any plane it is outside. if (XMVector4.EqualInt(outside, XMVector.TrueInt)) { return(PlaneIntersectionType.Front); } // If the box is inside all planes it is inside. if (XMVector4.EqualInt(inside, XMVector.TrueInt)) { return(PlaneIntersectionType.Back); } // The box is not inside all planes or outside a plane it intersects. return(PlaneIntersectionType.Intersecting); }
public static bool XMVector3AllTrue(XMVector v) { // Duplicate the fourth element from the first element. XMVector c = new XMVector(v.X, v.Y, v.Z, v.X); return(XMVector4.EqualIntR(c, XMVector.TrueInt).IsAllTrue); }
public static PlaneIntersectionType Intersects(XMVector v0, XMVector v1, XMVector v2, XMVector plane) { XMVector one = XMGlobalConstants.One; Debug.Assert(Internal.XMPlaneIsUnit(plane), "Reviewed"); // 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; Internal.FastIntersectTrianglePlane(tV0, tV1, tV2, plane, out outside, out inside); // If the triangle is outside any plane it is outside. if (XMVector4.EqualInt(outside, XMVector.TrueInt)) { return(PlaneIntersectionType.Front); } // If the triangle is inside all planes it is inside. if (XMVector4.EqualInt(inside, XMVector.TrueInt)) { return(PlaneIntersectionType.Back); } // The triangle is not inside all planes or outside a plane it intersects. return(PlaneIntersectionType.Intersecting); }
public PlaneIntersectionType Intersects(XMVector plane) { Debug.Assert(Internal.XMPlaneIsUnit(plane), "Reviewed"); // Load the sphere. XMVector v_center = this.center; XMVector v_radius = XMVector.Replicate(this.radius); // Set w of the center to one so we can dot4 with a plane. v_center.W = 1.0f; XMVector outside, inside; Internal.FastIntersectSpherePlane(v_center, v_radius, plane, out outside, out inside); // If the sphere is outside any plane it is outside. if (XMVector4.EqualInt(outside, XMVector.TrueInt)) { return(PlaneIntersectionType.Front); } // If the sphere is inside all planes it is inside. if (XMVector4.EqualInt(inside, XMVector.TrueInt)) { return(PlaneIntersectionType.Back); } // The sphere is not inside all planes or outside a plane it intersects. return(PlaneIntersectionType.Intersecting); }
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 static void FastIntersectSpherePlane(XMVector center, XMVector radius, XMVector plane, out XMVector outside, out XMVector inside) { XMVector dist = XMVector4.Dot(center, plane); // Outside the plane? outside = XMVector.Greater(dist, radius); // Fully inside the plane? inside = XMVector.Less(dist, -radius); }
public bool Intersects(XMVector v0, XMVector v1, XMVector v2) { // Load the sphere. XMVector v_center = this.center; XMVector v_radius = XMVector.Replicate(this.radius); // Compute the plane of the triangle (has to be normalized). XMVector n = XMVector3.Normalize(XMVector3.Cross(v1 - v0, v2 - v0)); // Assert that the triangle is not degenerate. Debug.Assert(!XMVector3.Equal(n, XMGlobalConstants.Zero), "Reviewed"); // Find the nearest feature on the triangle to the sphere. XMVector dist = XMVector3.Dot(v_center - v0, n); // If the center of the sphere is farther from the plane of the triangle than // the radius of the sphere, then there cannot be an intersection. XMVector noIntersection = XMVector.Less(dist, -v_radius); noIntersection = XMVector.OrInt(noIntersection, XMVector.Greater(dist, v_radius)); // Project the center of the sphere onto the plane of the triangle. XMVector point = v_center - (n * dist); // Is it inside all the edges? If so we intersect because the distance // to the plane is less than the radius. XMVector intersection = Internal.PointOnPlaneInsideTriangle(point, v0, v1, v2); // Find the nearest point on each edge. XMVector radiusSq = v_radius * v_radius; // Edge 0,1 point = Internal.PointOnLineSegmentNearestPoint(v0, v1, v_center); // If the distance to the center of the sphere to the point is less than // the radius of the sphere then it must intersect. intersection = XMVector.OrInt(intersection, XMVector.LessOrEqual(XMVector3.LengthSquare(v_center - point), radiusSq)); // Edge 1,2 point = Internal.PointOnLineSegmentNearestPoint(v1, v2, v_center); // If the distance to the center of the sphere to the point is less than // the radius of the sphere then it must intersect. intersection = XMVector.OrInt(intersection, XMVector.LessOrEqual(XMVector3.LengthSquare(v_center - point), radiusSq)); // Edge 2,0 point = Internal.PointOnLineSegmentNearestPoint(v2, v0, v_center); // If the distance to the center of the sphere to the point is less than // the radius of the sphere then it must intersect. intersection = XMVector.OrInt(intersection, XMVector.LessOrEqual(XMVector3.LengthSquare(v_center - point), radiusSq)); return(XMVector4.EqualInt(XMVector.AndComplementInt(intersection, noIntersection), XMVector.TrueInt)); }
internal void TransformFrame(SdkMeshFile file, XMMatrix parentWorld, double time) { // Get the tick data XMMatrix mLocalTransform; int tick = file.GetAnimationKeyFromTime(time); if (this.AnimationFrameIndex == -1) { mLocalTransform = this.Matrix; } else { SdkMeshAnimationFrame animationFrame = file.AnimationFrames[this.AnimationFrameIndex]; SdkMeshAnimationKey animationKey = animationFrame.AnimationKeys[tick]; // turn it into a matrix (Ignore scaling for now) XMFloat3 parentPos = animationKey.Translation; XMMatrix mTranslate = XMMatrix.Translation(parentPos.X, parentPos.Y, parentPos.Z); XMVector quat = animationKey.Orientation; if (XMVector4.Equal(quat, XMVector.Zero)) { quat = XMQuaternion.Identity; } quat = XMQuaternion.Normalize(quat); XMMatrix mQuat = XMMatrix.RotationQuaternion(quat); mLocalTransform = mQuat * mTranslate; } // Transform ourselves XMMatrix mLocalWorld = mLocalTransform * parentWorld; this.TransformedFrameMatrix = mLocalWorld; this.WorldPoseFrameMatrix = mLocalWorld; // Transform our siblings if (this.SiblingFrameIndex != -1) { file.Frames[this.SiblingFrameIndex].TransformFrame(file, parentWorld, time); } // Transform our children if (this.ChildFrameIndex != -1) { file.Frames[this.ChildFrameIndex].TransformFrame(file, mLocalWorld, time); } }
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 static void FastIntersectAxisAlignedBoxPlane(XMVector center, XMVector extents, XMVector plane, out XMVector outside, out XMVector inside) { // Compute the distance to the center of the box. XMVector dist = XMVector4.Dot(center, plane); // Project the axes of the box onto the normal of the plane. Half the // length of the projection (sometime called the "radius") is equal to // h(u) * abs(n dot b(u))) + h(v) * abs(n dot b(v)) + h(w) * abs(n dot b(w)) // where h(i) are extents of the box, n is the plane normal, and b(i) are the // axes of the box. In this case b(i) = [(1,0,0), (0,1,0), (0,0,1)]. XMVector radius = XMVector3.Dot(extents, plane.Abs()); // Outside the plane? outside = XMVector.Greater(dist, radius); // Fully inside the plane? inside = XMVector.Less(dist, -radius); }
public static void FastIntersectTrianglePlane(XMVector v0, XMVector v1, XMVector v2, XMVector plane, out XMVector outside, out XMVector inside) { // Plane0 XMVector dist0 = XMVector4.Dot(v0, plane); XMVector dist1 = XMVector4.Dot(v1, plane); XMVector dist2 = XMVector4.Dot(v2, plane); XMVector minDist = XMVector.Min(dist0, dist1); minDist = XMVector.Min(minDist, dist2); XMVector maxDist = XMVector.Max(dist0, dist1); maxDist = XMVector.Max(maxDist, dist2); XMVector zero = XMGlobalConstants.Zero; // Outside the plane? outside = XMVector.Greater(minDist, zero); // Fully inside the plane? inside = XMVector.Less(maxDist, zero); }
public static bool XMPlaneIsUnit(XMVector plane) { XMVector difference = XMVector3.Length(plane) - XMVector.One; return(XMVector4.Less(difference.Abs(), Internal.UnitPlaneEpsilon)); }
public static bool Intersects(XMVector a0, XMVector a1, XMVector a2, XMVector b0, XMVector b1, XMVector b2) { XMVector selectY = XMVector.FromInt((uint)XMSelection.Select0, (uint)XMSelection.Select1, (uint)XMSelection.Select0, (uint)XMSelection.Select0); XMVector selectZ = XMVector.FromInt((uint)XMSelection.Select0, (uint)XMSelection.Select0, (uint)XMSelection.Select1, (uint)XMSelection.Select0); XMVector select0111 = XMVector.FromInt((uint)XMSelection.Select0, (uint)XMSelection.Select1, (uint)XMSelection.Select1, (uint)XMSelection.Select1); XMVector select1011 = XMVector.FromInt((uint)XMSelection.Select1, (uint)XMSelection.Select0, (uint)XMSelection.Select1, (uint)XMSelection.Select1); XMVector select1101 = XMVector.FromInt((uint)XMSelection.Select1, (uint)XMSelection.Select1, (uint)XMSelection.Select0, (uint)XMSelection.Select1); XMVector zero = XMGlobalConstants.Zero; // Compute the normal of triangle A. XMVector n1 = XMVector3.Cross(a1 - a0, a2 - a0); // Assert that the triangle is not degenerate. Debug.Assert(!XMVector3.Equal(n1, zero), "Reviewed"); // Test points of B against the plane of A. XMVector b_dist = XMVector3.Dot(n1, b0 - a0); b_dist = XMVector.Select(b_dist, XMVector3.Dot(n1, b1 - a0), selectY); b_dist = XMVector.Select(b_dist, XMVector3.Dot(n1, b2 - a0), selectZ); // Ensure robustness with co-planar triangles by zeroing small distances. XMComparisonRecord b_distIsZeroCR; XMVector b_distIsZero = XMVector.GreaterR(out b_distIsZeroCR, CollisionGlobalConstants.RayEpsilon, b_dist.Abs()); b_dist = XMVector.Select(b_dist, zero, b_distIsZero); XMComparisonRecord b_distIsLessCR; XMVector b_distIsLess = XMVector.GreaterR(out b_distIsLessCR, zero, b_dist); XMComparisonRecord b_distIsGreaterCR; XMVector b_distIsGreater = XMVector.GreaterR(out b_distIsGreaterCR, b_dist, zero); // If all the points are on the same side we don't intersect. if (b_distIsLessCR.IsAllTrue || b_distIsGreaterCR.IsAllTrue) { return(false); } // Compute the normal of triangle B. XMVector n2 = XMVector3.Cross(b1 - b0, b2 - b0); // Assert that the triangle is not degenerate. Debug.Assert(!XMVector3.Equal(n2, zero), "Reviewed"); // Test points of A against the plane of B. XMVector a_dist = XMVector3.Dot(n2, a0 - b0); a_dist = XMVector.Select(a_dist, XMVector3.Dot(n2, a1 - b0), selectY); a_dist = XMVector.Select(a_dist, XMVector3.Dot(n2, a2 - b0), selectZ); // Ensure robustness with co-planar triangles by zeroing small distances. XMComparisonRecord a_distIsZeroCR; XMVector a_distIsZero = XMVector.GreaterR(out a_distIsZeroCR, CollisionGlobalConstants.RayEpsilon, b_dist.Abs()); a_dist = XMVector.Select(a_dist, zero, a_distIsZero); XMComparisonRecord a_distIsLessCR; XMVector a_distIsLess = XMVector.GreaterR(out a_distIsLessCR, zero, a_dist); XMComparisonRecord a_distIsGreaterCR; XMVector a_distIsGreater = XMVector.GreaterR(out a_distIsGreaterCR, a_dist, zero); // If all the points are on the same side we don't intersect. if (a_distIsLessCR.IsAllTrue || a_distIsGreaterCR.IsAllTrue) { return(false); } // Special case for co-planar triangles. if (a_distIsZeroCR.IsAllTrue || b_distIsZeroCR.IsAllTrue) { XMVector axis, dist, minDist; // Compute an axis perpindicular to the edge (points out). axis = XMVector3.Cross(n1, a1 - a0); dist = XMVector3.Dot(axis, a0); // Test points of B against the axis. minDist = XMVector3.Dot(b0, axis); minDist = XMVector.Min(minDist, XMVector3.Dot(b1, axis)); minDist = XMVector.Min(minDist, XMVector3.Dot(b2, axis)); if (XMVector4.GreaterOrEqual(minDist, dist)) { return(false); } // Edge (A1, A2) axis = XMVector3.Cross(n1, a2 - a1); dist = XMVector3.Dot(axis, a1); minDist = XMVector3.Dot(b0, axis); minDist = XMVector.Min(minDist, XMVector3.Dot(b1, axis)); minDist = XMVector.Min(minDist, XMVector3.Dot(b2, axis)); if (XMVector4.GreaterOrEqual(minDist, dist)) { return(false); } // Edge (A2, A0) axis = XMVector3.Cross(n1, a0 - a2); dist = XMVector3.Dot(axis, a2); minDist = XMVector3.Dot(b0, axis); minDist = XMVector.Min(minDist, XMVector3.Dot(b1, axis)); minDist = XMVector.Min(minDist, XMVector3.Dot(b2, axis)); if (XMVector4.GreaterOrEqual(minDist, dist)) { return(false); } // Edge (B0, B1) axis = XMVector3.Cross(n2, b1 - b0); dist = XMVector3.Dot(axis, b0); minDist = XMVector3.Dot(a0, axis); minDist = XMVector.Min(minDist, XMVector3.Dot(a1, axis)); minDist = XMVector.Min(minDist, XMVector3.Dot(a2, axis)); if (XMVector4.GreaterOrEqual(minDist, dist)) { return(false); } // Edge (B1, B2) axis = XMVector3.Cross(n2, b2 - b1); dist = XMVector3.Dot(axis, b1); minDist = XMVector3.Dot(a0, axis); minDist = XMVector.Min(minDist, XMVector3.Dot(a1, axis)); minDist = XMVector.Min(minDist, XMVector3.Dot(a2, axis)); if (XMVector4.GreaterOrEqual(minDist, dist)) { return(false); } // Edge (B2,B0) axis = XMVector3.Cross(n2, b0 - b2); dist = XMVector3.Dot(axis, b2); minDist = XMVector3.Dot(a0, axis); minDist = XMVector.Min(minDist, XMVector3.Dot(a1, axis)); minDist = XMVector.Min(minDist, XMVector3.Dot(a2, axis)); if (XMVector4.GreaterOrEqual(minDist, dist)) { return(false); } return(true); } //// Find the single vertex of A and B (ie the vertex on the opposite side //// of the plane from the other two) and reorder the edges so we can compute //// the signed edge/edge distances. //// //// if ( (V0 >= 0 && V1 < 0 && V2 < 0) || //// (V0 > 0 && V1 <= 0 && V2 <= 0) || //// (V0 <= 0 && V1 > 0 && V2 > 0) || //// (V0 < 0 && V1 >= 0 && V2 >= 0) ) then V0 is singular; //// //// If our singular vertex is not on the positive side of the plane we reverse //// the triangle winding so that the overlap comparisons will compare the //// correct edges with the correct signs. XMVector a_distIsLessEqual = XMVector.OrInt(a_distIsLess, a_distIsZero); XMVector a_distIsGreaterEqual = XMVector.OrInt(a_distIsGreater, a_distIsZero); XMVector aa0, aa1, aa2; bool b_positiveA; if (Internal.XMVector3AllTrue(XMVector.Select(a_distIsGreaterEqual, a_distIsLess, select0111)) || Internal.XMVector3AllTrue(XMVector.Select(a_distIsGreater, a_distIsLessEqual, select0111))) { // A0 is singular, crossing from positive to negative. aa0 = a0; aa1 = a1; aa2 = a2; b_positiveA = true; } else if (Internal.XMVector3AllTrue(XMVector.Select(a_distIsLessEqual, a_distIsGreater, select0111)) || Internal.XMVector3AllTrue(XMVector.Select(a_distIsLess, a_distIsGreaterEqual, select0111))) { // A0 is singular, crossing from negative to positive. aa0 = a0; aa1 = a2; aa2 = a1; b_positiveA = false; } else if (Internal.XMVector3AllTrue(XMVector.Select(a_distIsGreaterEqual, a_distIsLess, select1011)) || Internal.XMVector3AllTrue(XMVector.Select(a_distIsGreater, a_distIsLessEqual, select1011))) { // A1 is singular, crossing from positive to negative. aa0 = a1; aa1 = a2; aa2 = a0; b_positiveA = true; } else if (Internal.XMVector3AllTrue(XMVector.Select(a_distIsLessEqual, a_distIsGreater, select1011)) || Internal.XMVector3AllTrue(XMVector.Select(a_distIsLess, a_distIsGreaterEqual, select1011))) { // A1 is singular, crossing from negative to positive. aa0 = a1; aa1 = a0; aa2 = a2; b_positiveA = false; } else if (Internal.XMVector3AllTrue(XMVector.Select(a_distIsGreaterEqual, a_distIsLess, select1101)) || Internal.XMVector3AllTrue(XMVector.Select(a_distIsGreater, a_distIsLessEqual, select1101))) { // A2 is singular, crossing from positive to negative. aa0 = a2; aa1 = a0; aa2 = a1; b_positiveA = true; } else if (Internal.XMVector3AllTrue(XMVector.Select(a_distIsLessEqual, a_distIsGreater, select1101)) || Internal.XMVector3AllTrue(XMVector.Select(a_distIsLess, a_distIsGreaterEqual, select1101))) { // A2 is singular, crossing from negative to positive. aa0 = a2; aa1 = a1; aa2 = a0; b_positiveA = false; } else { Debug.Assert(false, "Reviewed"); return(false); } XMVector b_distIsLessEqual = XMVector.OrInt(b_distIsLess, b_distIsZero); XMVector b_distIsGreaterEqual = XMVector.OrInt(b_distIsGreater, b_distIsZero); XMVector bb0, bb1, bb2; bool b_positiveB; if (Internal.XMVector3AllTrue(XMVector.Select(b_distIsGreaterEqual, b_distIsLess, select0111)) || Internal.XMVector3AllTrue(XMVector.Select(b_distIsGreater, b_distIsLessEqual, select0111))) { // B0 is singular, crossing from positive to negative. bb0 = b0; bb1 = b1; bb2 = b2; b_positiveB = true; } else if (Internal.XMVector3AllTrue(XMVector.Select(b_distIsLessEqual, b_distIsGreater, select0111)) || Internal.XMVector3AllTrue(XMVector.Select(b_distIsLess, b_distIsGreaterEqual, select0111))) { // B0 is singular, crossing from negative to positive. bb0 = b0; bb1 = b2; bb2 = b1; b_positiveB = false; } else if (Internal.XMVector3AllTrue(XMVector.Select(b_distIsGreaterEqual, b_distIsLess, select1011)) || Internal.XMVector3AllTrue(XMVector.Select(b_distIsGreater, b_distIsLessEqual, select1011))) { // B1 is singular, crossing from positive to negative. bb0 = b1; bb1 = b2; bb2 = b0; b_positiveB = true; } else if (Internal.XMVector3AllTrue(XMVector.Select(b_distIsLessEqual, b_distIsGreater, select1011)) || Internal.XMVector3AllTrue(XMVector.Select(b_distIsLess, b_distIsGreaterEqual, select1011))) { // B1 is singular, crossing from negative to positive. bb0 = b1; bb1 = b0; bb2 = b2; b_positiveB = false; } else if (Internal.XMVector3AllTrue(XMVector.Select(b_distIsGreaterEqual, b_distIsLess, select1101)) || Internal.XMVector3AllTrue(XMVector.Select(b_distIsGreater, b_distIsLessEqual, select1101))) { // B2 is singular, crossing from positive to negative. bb0 = b2; bb1 = b0; bb2 = b1; b_positiveB = true; } else if (Internal.XMVector3AllTrue(XMVector.Select(b_distIsLessEqual, b_distIsGreater, select1101)) || Internal.XMVector3AllTrue(XMVector.Select(b_distIsLess, b_distIsGreaterEqual, select1101))) { // B2 is singular, crossing from negative to positive. bb0 = b2; bb1 = b1; bb2 = b0; b_positiveB = false; } else { Debug.Assert(false, "Reviewed"); return(false); } XMVector delta0, delta1; // Reverse the direction of the test depending on whether the singular vertices are // the same sign or different signs. if (b_positiveA ^ b_positiveB) { delta0 = bb0 - aa0; delta1 = aa0 - bb0; } else { delta0 = aa0 - bb0; delta1 = bb0 - aa0; } // Check if the triangles overlap on the line of intersection between the // planes of the two triangles by finding the signed line distances. XMVector dist0 = XMVector3.Dot(delta0, XMVector3.Cross(bb2 - bb0, aa2 - aa0)); if (XMVector4.Greater(dist0, zero)) { return(false); } XMVector dist1 = XMVector3.Dot(delta1, XMVector3.Cross(bb1 - bb0, aa1 - aa0)); if (XMVector4.Greater(dist1, zero)) { return(false); } return(true); }
public bool Intersects(XMVector v0, XMVector v1, XMVector v2) { XMVector zero = XMGlobalConstants.Zero; // Load the box. XMVector v_center = this.center; XMVector v_extents = this.extents; XMVector boxMin = v_center - v_extents; XMVector boxMax = v_center + v_extents; // Test the axes of the box (in effect test the AAB against the minimal AAB // around the triangle). XMVector triMin = XMVector.Min(XMVector.Min(v0, v1), v2); XMVector triMax = XMVector.Max(XMVector.Max(v0, v1), v2); // for each i in (x, y, z) if a_min(i) > b_max(i) or b_min(i) > a_max(i) then disjoint XMVector disjoint = XMVector.OrInt(XMVector.Greater(triMin, boxMax), XMVector.Greater(boxMin, triMax)); if (Internal.XMVector3AnyTrue(disjoint)) { return(false); } // Test the plane of the triangle. XMVector normal = XMVector3.Cross(v1 - v0, v2 - v0); XMVector dist = XMVector3.Dot(normal, v0); // Assert that the triangle is not degenerate. Debug.Assert(!XMVector3.Equal(normal, zero), "Reviewed"); // for each i in (x, y, z) if n(i) >= 0 then v_min(i)=b_min(i), v_max(i)=b_max(i) // else v_min(i)=b_max(i), v_max(i)=b_min(i) XMVector normalSelect = XMVector.Greater(normal, zero); XMVector v_min = XMVector.Select(boxMax, boxMin, normalSelect); XMVector v_max = XMVector.Select(boxMin, boxMax, normalSelect); // if n dot v_min + d > 0 || n dot v_max + d < 0 then disjoint XMVector minDist = XMVector3.Dot(v_min, normal); XMVector maxDist = XMVector3.Dot(v_max, normal); XMVector noIntersection = XMVector.Greater(minDist, dist); noIntersection = XMVector.OrInt(noIntersection, XMVector.Less(maxDist, dist)); // Move the box center to zero to simplify the following tests. XMVector tV0 = v0 - v_center; XMVector tV1 = v1 - v_center; XMVector tV2 = v2 - v_center; // Test the edge/edge axes (3*3). XMVector e0 = tV1 - tV0; XMVector e1 = tV2 - tV1; XMVector e2 = tV0 - tV2; // Make w zero. e0.W = zero.W; e1.W = zero.W; e2.W = zero.W; XMVector axis; XMVector p0, p1, p2; XMVector min, max; XMVector radius; //// Axis == (1,0,0) x e0 = (0, -e0.z, e0.y) axis = new XMVector(e1.W, -e0.Z, e1.Y, e1.X); p0 = XMVector3.Dot(tV0, axis); //// p1 = XMVector3Dot( V1, Axis ); // p1 = p0; p2 = XMVector3.Dot(tV2, axis); min = XMVector.Min(p0, p2); max = XMVector.Max(p0, p2); radius = XMVector3.Dot(v_extents, axis.Abs()); noIntersection = XMVector.OrInt(noIntersection, XMVector.Greater(min, radius)); noIntersection = XMVector.OrInt(noIntersection, XMVector.Less(max, -radius)); //// Axis == (1,0,0) x e1 = (0, -e1.z, e1.y) axis = new XMVector(e1.W, -e1.Z, e1.Y, e1.X); p0 = XMVector3.Dot(tV0, axis); p1 = XMVector3.Dot(tV1, axis); //// p2 = XMVector3Dot( V2, Axis ); // p2 = p1; min = XMVector.Min(p0, p1); max = XMVector.Max(p0, p1); radius = XMVector3.Dot(v_extents, axis.Abs()); noIntersection = XMVector.OrInt(noIntersection, XMVector.Greater(min, radius)); noIntersection = XMVector.OrInt(noIntersection, XMVector.Less(max, -radius)); //// Axis == (1,0,0) x e2 = (0, -e2.z, e2.y) axis = new XMVector(e2.W, -e2.Z, e2.Y, e2.X); p0 = XMVector3.Dot(tV0, axis); p1 = XMVector3.Dot(tV1, axis); //// p2 = XMVector3Dot( V2, Axis ); // p2 = p0; min = XMVector.Min(p0, p1); max = XMVector.Max(p0, p1); radius = XMVector3.Dot(v_extents, axis.Abs()); noIntersection = XMVector.OrInt(noIntersection, XMVector.Greater(min, radius)); noIntersection = XMVector.OrInt(noIntersection, XMVector.Less(max, -radius)); //// Axis == (0,1,0) x e0 = (e0.z, 0, -e0.x) axis = new XMVector(e0.Z, e0.W, -e0.X, e0.Y); p0 = XMVector3.Dot(tV0, axis); //// p1 = XMVector3Dot( V1, Axis ); // p1 = p0; p2 = XMVector3.Dot(tV2, axis); min = XMVector.Min(p0, p2); max = XMVector.Max(p0, p2); radius = XMVector3.Dot(v_extents, axis.Abs()); noIntersection = XMVector.OrInt(noIntersection, XMVector.Greater(min, radius)); noIntersection = XMVector.OrInt(noIntersection, XMVector.Less(max, -radius)); //// Axis == (0,1,0) x e1 = (e1.z, 0, -e1.x) axis = new XMVector(e1.Z, e1.W, -e1.X, e1.Y); p0 = XMVector3.Dot(tV0, axis); p1 = XMVector3.Dot(tV1, axis); //// p2 = XMVector3Dot( V2, Axis ); // p2 = p1; min = XMVector.Min(p0, p1); max = XMVector.Max(p0, p1); radius = XMVector3.Dot(v_extents, axis.Abs()); noIntersection = XMVector.OrInt(noIntersection, XMVector.Greater(min, radius)); noIntersection = XMVector.OrInt(noIntersection, XMVector.Less(max, -radius)); //// Axis == (0,0,1) x e2 = (e2.z, 0, -e2.x) axis = new XMVector(e2.Z, e2.W, -e2.X, e2.Y); p0 = XMVector3.Dot(tV0, axis); p1 = XMVector3.Dot(tV1, axis); //// p2 = XMVector3Dot( V2, Axis ); // p2 = p0; min = XMVector.Min(p0, p1); max = XMVector.Max(p0, p1); radius = XMVector3.Dot(v_extents, axis.Abs()); noIntersection = XMVector.OrInt(noIntersection, XMVector.Greater(min, radius)); noIntersection = XMVector.OrInt(noIntersection, XMVector.Less(max, -radius)); //// Axis == (0,0,1) x e0 = (-e0.y, e0.x, 0) axis = new XMVector(-e0.Y, e0.X, e0.W, e0.Z); p0 = XMVector3.Dot(tV0, axis); //// p1 = XMVector3Dot( V1, Axis ); // p1 = p0; p2 = XMVector3.Dot(tV2, axis); min = XMVector.Min(p0, p2); max = XMVector.Max(p0, p2); radius = XMVector3.Dot(v_extents, axis.Abs()); noIntersection = XMVector.OrInt(noIntersection, XMVector.Greater(min, radius)); noIntersection = XMVector.OrInt(noIntersection, XMVector.Less(max, -radius)); //// Axis == (0,0,1) x e1 = (-e1.y, e1.x, 0) axis = new XMVector(-e1.Y, e1.X, e1.W, e1.Z); p0 = XMVector3.Dot(tV0, axis); p1 = XMVector3.Dot(tV1, axis); //// p2 = XMVector3Dot( V2, Axis ); // p2 = p1; min = XMVector.Min(p0, p1); max = XMVector.Max(p0, p1); radius = XMVector3.Dot(v_extents, axis.Abs()); noIntersection = XMVector.OrInt(noIntersection, XMVector.Greater(min, radius)); noIntersection = XMVector.OrInt(noIntersection, XMVector.Less(max, -radius)); //// Axis == (0,0,1) x e2 = (-e2.y, e2.x, 0) axis = new XMVector(-e2.Y, e2.X, e2.W, e2.Z); p0 = XMVector3.Dot(tV0, axis); p1 = XMVector3.Dot(tV1, axis); //// p2 = XMVector3Dot( V2, Axis ); // p2 = p0; min = XMVector.Min(p0, p1); max = XMVector.Max(p0, p1); radius = XMVector3.Dot(v_extents, axis.Abs()); noIntersection = XMVector.OrInt(noIntersection, XMVector.Greater(min, radius)); noIntersection = XMVector.OrInt(noIntersection, XMVector.Less(max, -radius)); return(XMVector4.NotEqualInt(noIntersection, XMVector.TrueInt)); }
public static bool XMVector3IsUnit(XMVector v) { XMVector difference = XMVector3.Length(v) - XMVector.One; return(XMVector4.Less(difference.Abs(), Internal.UnitVectorEpsilon)); }
public static bool XMQuaternionIsUnit(XMVector q) { XMVector difference = XMVector4.Length(q) - XMVector.One; return(XMVector4.Less(difference.Abs(), Internal.UnitQuaternionEpsilon)); }
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); }
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); }
private void RenderShadowMap(out XMFloat4X4 mViewProjLight, out XMFloat3 vLightDir) { var context = this.deviceResources.D3DContext; D3D11Rect[] oldRects = context.RasterizerStageGetScissorRects(); D3D11Viewport[] oldVp = context.RasterizerStageGetViewports(); D3D11Rect[] rects = new D3D11Rect[1] { new D3D11Rect(0, (int)g_fShadowMapWidth, 0, (int)g_fShadowMapHeight) }; context.RasterizerStageSetScissorRects(rects); D3D11Viewport[] vp = new D3D11Viewport[1] { new D3D11Viewport(0, 0, g_fShadowMapWidth, g_fShadowMapHeight, 0.0f, 1.0f) }; context.RasterizerStageSetViewports(vp); // Set our scene render target & keep original depth buffer D3D11RenderTargetView[] pRTVs = new D3D11RenderTargetView[2]; context.OutputMergerSetRenderTargets(pRTVs, this.g_pDepthStencilTextureDSV); // Clear the render target context.ClearDepthStencilView(this.g_pDepthStencilTextureDSV, D3D11ClearOptions.Depth | D3D11ClearOptions.Stencil, 1.0f, 0); // Get the projection & view matrix from the camera class XMFloat3 up = new XMFloat3(0, 1, 0); XMFloat4 vLight = new XMFloat4(0.0f, 0.0f, 0.0f, 1.0f); XMFloat4 vLightLookAt = new XMFloat4(0.0f, -0.5f, 1.0f, 0.0f); vLightLookAt = vLight.ToVector() + vLightLookAt.ToVector(); vLight = XMVector4.Transform(vLight, this.LightWorldMatrix); vLightLookAt = XMVector4.Transform(vLightLookAt, this.LightWorldMatrix); vLightDir = XMVector.Subtract(vLightLookAt, vLight); XMMatrix mProj = XMMatrix.OrthographicOffCenterLH(-8.5f, 9, -15, 11, -20, 20); XMMatrix mView = XMMatrix.LookAtLH(vLight, vLightLookAt, up); mViewProjLight = mView * mProj; // Setup the constant buffer for the scene vertex shader ConstantBufferConstants pConstants = new ConstantBufferConstants { WorldViewProjection = mViewProjLight.ToMatrix().Transpose(), WorldViewProjLight = mViewProjLight.ToMatrix().Transpose(), ShadowMapDimensions = new XMFloat4( g_fShadowMapWidth, g_fShadowMapHeight, 1.0f / g_fShadowMapWidth, 1.0f / g_fShadowMapHeight), LightDir = new XMFloat4(vLightDir.X, vLightDir.Y, vLightDir.Z, 0.0f), SunWidth = this.SunWidth }; context.UpdateSubresource(this.g_pcbConstants, 0, null, pConstants, 0, 0); context.VertexShaderSetConstantBuffers(g_iConstantsConstantBufferBind, new[] { this.g_pcbConstants }); context.PixelShaderSetConstantBuffers(g_iConstantsConstantBufferBind, new[] { this.g_pcbConstants }); // Set the shaders context.VertexShaderSetShader(this.g_pShadowMapVS, null); context.PixelShaderSetShader(null, null); // Set the vertex buffer format context.InputAssemblerSetInputLayout(this.g_pSceneVertexLayout); // Render the scene this.g_Poles.Render(0, -1, -1); // reset the old viewport etc. context.RasterizerStageSetScissorRects(oldRects); context.RasterizerStageSetViewports(oldVp); }