public BoundingBox Transform(float scale, XMVector rotation, XMVector translation) { Debug.Assert(Internal.XMQuaternionIsUnit(rotation), "Reviewed"); // Load center and extents. XMVector boxCenter = this.center; XMVector boxExtents = this.extents; XMVector vectorScale = XMVector.Replicate(scale); // Compute and transform the corners and find new min/max bounds. XMVector corner = XMVector.MultiplyAdd(boxExtents, CollisionGlobalConstants.BoxOffsets[0], boxCenter); corner = XMVector3.Rotate(corner * vectorScale, rotation) + translation; XMVector min, max; min = max = corner; for (int i = 1; i < BoundingBox.CornerCount; i++) { corner = XMVector.MultiplyAdd(boxExtents, CollisionGlobalConstants.BoxOffsets[i], boxCenter); corner = XMVector3.Rotate(corner * vectorScale, rotation) + translation; min = XMVector.Min(min, corner); max = XMVector.Max(max, corner); } // Store center and extents. return(new BoundingBox((min + max) * 0.5f, (max - min) * 0.5f)); }
public BoundingBox Transform(XMMatrix m) { // Load center and extents. XMVector boxCenter = this.center; XMVector boxExtents = this.extents; // Compute and transform the corners and find new min/max bounds. XMVector corner = XMVector.MultiplyAdd(boxExtents, CollisionGlobalConstants.BoxOffsets[0], boxCenter); corner = XMVector3.Transform(corner, m); XMVector min, max; min = max = corner; for (int i = 1; i < BoundingBox.CornerCount; i++) { corner = XMVector.MultiplyAdd(boxExtents, CollisionGlobalConstants.BoxOffsets[i], boxCenter); corner = XMVector3.Transform(corner, m); min = XMVector.Min(min, corner); max = XMVector.Max(max, corner); } // Store center and extents. return(new BoundingBox((min + max) * 0.5f, (max - min) * 0.5f)); }
public static BoundingBox CreateFromPoints(XMFloat3[] points) { if (points == null) { throw new ArgumentNullException("points"); } if (points.Length == 0) { throw new ArgumentOutOfRangeException("points"); } // Find the minimum and maximum x, y, and z XMVector v_min, v_max; v_min = v_max = points[0]; for (int i = 1; i < points.Length; i++) { XMVector point = points[i]; v_min = XMVector.Min(v_min, point); v_max = XMVector.Max(v_max, point); } // Store center and extents. return(new BoundingBox((v_min + v_max) * 0.5f, (v_max - v_min) * 0.5f)); }
public BoundingSphere Transform(XMMatrix m) { // Load the center of the sphere. XMVector v_center = this.center; // Transform the center of the sphere. XMVector c = XMVector3.Transform(v_center, m); XMVector dX = XMVector3.Dot(((XMVector *)&m)[0], ((XMVector *)&m)[0]); XMVector dY = XMVector3.Dot(((XMVector *)&m)[1], ((XMVector *)&m)[1]); XMVector dZ = XMVector3.Dot(((XMVector *)&m)[2], ((XMVector *)&m)[2]); XMVector d = XMVector.Max(dX, XMVector.Max(dY, dZ)); BoundingSphere result; // Store the center sphere. result.center = c; // Scale the radius of the pshere. float scale = (float)Math.Sqrt(d.X); result.radius = this.radius * scale; return(result); }
public static BoundingBox CreateFromPoints(XMVector pt1, XMVector pt2) { XMVector min = XMVector.Min(pt1, pt2); XMVector max = XMVector.Max(pt1, pt2); // Store center and extents. return(new BoundingBox((min + max) * 0.5f, (max - min) * 0.5f)); }
public bool Intersects(XMVector origin, XMVector direction, out float distance) { Debug.Assert(Internal.XMVector3IsUnit(direction), "Reviewed"); // Load the box. XMVector v_center = this.center; XMVector v_extents = this.extents; // Adjust ray origin to be relative to center of the box. XMVector t_origin = v_center - origin; // Compute the dot product againt each axis of the box. // Since the axii are (1,0,0), (0,1,0), (0,0,1) no computation is necessary. XMVector axisDotOrigin = t_origin; XMVector axisDotDirection = direction; // if (fabs(AxisDotDirection) <= Epsilon) the ray is nearly parallel to the slab. XMVector isParallel = XMVector.LessOrEqual(axisDotDirection.Abs(), CollisionGlobalConstants.RayEpsilon); // Test against all three axii simultaneously. XMVector inverseAxisDotDirection = axisDotDirection.Reciprocal(); XMVector t1 = (axisDotOrigin - v_extents) * inverseAxisDotDirection; XMVector t2 = (axisDotOrigin + v_extents) * inverseAxisDotDirection; // Compute the max of min(t1,t2) and the min of max(t1,t2) ensuring we don't // use the results from any directions parallel to the slab. XMVector t_min = XMVector.Select(XMVector.Min(t1, t2), CollisionGlobalConstants.FltMin, isParallel); XMVector t_max = XMVector.Select(XMVector.Max(t1, t2), CollisionGlobalConstants.FltMax, isParallel); // t_min.x = maximum( t_min.x, t_min.y, t_min.z ); // t_max.x = minimum( t_max.x, t_max.y, t_max.z ); t_min = XMVector.Max(t_min, XMVector.SplatY(t_min)); // x = max(x,y) t_min = XMVector.Max(t_min, XMVector.SplatZ(t_min)); // x = max(max(x,y),z) t_max = XMVector.Min(t_max, XMVector.SplatY(t_max)); // x = min(x,y) t_max = XMVector.Min(t_max, XMVector.SplatZ(t_max)); // x = min(min(x,y),z) // if ( t_min > t_max ) return false; XMVector noIntersection = XMVector.Greater(XMVector.SplatX(t_min), XMVector.SplatX(t_max)); // if ( t_max < 0.0f ) return false; noIntersection = XMVector.OrInt(noIntersection, XMVector.Less(XMVector.SplatX(t_max), XMGlobalConstants.Zero)); // if (IsParallel && (-Extents > AxisDotOrigin || Extents < AxisDotOrigin)) return false; XMVector parallelOverlap = axisDotOrigin.InBounds(v_extents); noIntersection = XMVector.OrInt(noIntersection, XMVector.AndComplementInt(isParallel, parallelOverlap)); if (!Internal.XMVector3AnyTrue(noIntersection)) { // Store the x-component to *pDist t_min.StoreFloat(out distance); return(true); } distance = 0.0f; return(false); }
public static XMVector RgbToHsv(XMVector rgb) { XMVector r = XMVector.SplatX(rgb); XMVector g = XMVector.SplatY(rgb); XMVector b = XMVector.SplatZ(rgb); XMVector min = XMVector.Min(r, XMVector.Min(g, b)); XMVector v = XMVector.Max(r, XMVector.Max(g, b)); XMVector d = XMVector.Subtract(v, min); XMVector s = XMVector3.NearEqual(v, XMGlobalConstants.Zero, XMGlobalConstants.Epsilon) ? XMGlobalConstants.Zero : XMVector.Divide(d, v); if (XMVector3.Less(d, XMGlobalConstants.Epsilon)) { // Achromatic, assume H of 0 XMVector hv = XMVector.Select(v, XMGlobalConstants.Zero, XMGlobalConstants.Select1000); XMVector hva = XMVector.Select(rgb, hv, XMGlobalConstants.Select1110); return(XMVector.Select(s, hva, XMGlobalConstants.Select1011)); } else { XMVector h; if (XMVector3.Equal(r, v)) { // Red is max h = XMVector.Divide(XMVector.Subtract(g, b), d); if (XMVector3.Less(g, b)) { h = XMVector.Add(h, XMGlobalConstants.Six); } } else if (XMVector3.Equal(g, v)) { // Green is max h = XMVector.Divide(XMVector.Subtract(b, r), d); h = XMVector.Add(h, XMGlobalConstants.Two); } else { // Blue is max h = XMVector.Divide(XMVector.Subtract(r, g), d); h = XMVector.Add(h, XMGlobalConstants.Four); } h = XMVector.Divide(h, XMGlobalConstants.Six); XMVector hv = XMVector.Select(v, h, XMGlobalConstants.Select1000); XMVector hva = XMVector.Select(rgb, hv, XMGlobalConstants.Select1110); return(XMVector.Select(s, hva, XMGlobalConstants.Select1011)); } }
public static void FastIntersectFrustumPlane( XMVector point0, XMVector point1, XMVector point2, XMVector point3, XMVector point4, XMVector point5, XMVector point6, XMVector point7, XMVector plane, out XMVector outside, out XMVector inside) { // Find the min/max projection of the frustum onto the plane normal. XMVector min, max, dist; min = max = XMVector3.Dot(plane, point0); dist = XMVector3.Dot(plane, point1); min = XMVector.Min(min, dist); max = XMVector.Max(max, dist); dist = XMVector3.Dot(plane, point2); min = XMVector.Min(min, dist); max = XMVector.Max(max, dist); dist = XMVector3.Dot(plane, point3); min = XMVector.Min(min, dist); max = XMVector.Max(max, dist); dist = XMVector3.Dot(plane, point4); min = XMVector.Min(min, dist); max = XMVector.Max(max, dist); dist = XMVector3.Dot(plane, point5); min = XMVector.Min(min, dist); max = XMVector.Max(max, dist); dist = XMVector3.Dot(plane, point6); min = XMVector.Min(min, dist); max = XMVector.Max(max, dist); dist = XMVector3.Dot(plane, point7); min = XMVector.Min(min, dist); max = XMVector.Max(max, dist); XMVector planeDist = -XMVector.SplatW(plane); // Outside the plane? outside = XMVector.Greater(min, planeDist); // Fully inside the plane? inside = XMVector.Less(max, planeDist); }
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 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 XMVector RgbToHsl(XMVector rgb) { XMVector r = XMVector.SplatX(rgb); XMVector g = XMVector.SplatY(rgb); XMVector b = XMVector.SplatZ(rgb); XMVector min = XMVector.Min(r, XMVector.Min(g, b)); XMVector max = XMVector.Max(r, XMVector.Max(g, b)); XMVector l = XMVector.Multiply(XMVector.Add(min, max), XMGlobalConstants.OneHalf); XMVector d = XMVector.Subtract(max, min); XMVector la = XMVector.Select(rgb, l, XMGlobalConstants.Select1110); if (XMVector3.Less(d, XMGlobalConstants.Epsilon)) { // Achromatic, assume H and S of 0 return(XMVector.Select(la, XMGlobalConstants.Zero, XMGlobalConstants.Select1100)); } else { XMVector s; XMVector h; XMVector d2 = XMVector.Add(min, max); if (XMVector3.Greater(l, XMGlobalConstants.OneHalf)) { // d / (2-max-min) s = XMVector.Divide(d, XMVector.Subtract(XMGlobalConstants.Two, d2)); } else { // d / (max+min) s = XMVector.Divide(d, d2); } if (XMVector3.Equal(r, max)) { // Red is max h = XMVector.Divide(XMVector.Subtract(g, b), d); } else if (XMVector3.Equal(g, max)) { // Green is max h = XMVector.Divide(XMVector.Subtract(b, r), d); h = XMVector.Add(h, XMGlobalConstants.Two); } else { // Blue is max h = XMVector.Divide(XMVector.Subtract(r, g), d); h = XMVector.Add(h, XMGlobalConstants.Four); } h = XMVector.Divide(h, XMGlobalConstants.Six); if (XMVector3.Less(h, XMGlobalConstants.Zero)) { h = XMVector.Add(h, XMGlobalConstants.One); } XMVector lha = XMVector.Select(la, h, XMGlobalConstants.Select1100); return(XMVector.Select(s, lha, XMGlobalConstants.Select1011)); } }
private void ComputeBoundingBox(SdkMeshRawFile rawFile, SdkMeshRawMesh rawMesh) { //this.BoundingBoxCenter = rawMesh.BoundingBoxCenter; //this.BoundingBoxExtents = rawMesh.BoundingBoxExtents; XMVector lower = XMVector.Replicate(float.MaxValue); XMVector upper = XMVector.Replicate(float.MinValue); int indsize; if (rawFile.IndexBufferHeaders[rawMesh.IndexBuffer].IndexType == SdkMeshIndexType.IndexType32Bit) { indsize = 4; } else { indsize = 2; } for (int subset = 0; subset < rawMesh.NumSubsets; subset++) { SdkMeshRawSubset pSubset = rawFile.Subsets[rawMesh.SubsetsIndices[subset]]; SdkMeshPrimitiveType primType = pSubset.PrimitiveType; Debug.Assert(primType == SdkMeshPrimitiveType.TriangleList, "Only triangle lists are handled."); if (primType != SdkMeshPrimitiveType.TriangleList) { continue; } int indexCount = (int)pSubset.IndexCount; int indexStart = (int)pSubset.IndexStart; byte[] ind = rawFile.IndexBufferBytes[rawMesh.IndexBuffer]; byte[] verts = rawFile.VertexBufferBytes[rawMesh.VertexBuffers[0]]; int stride = (int)rawFile.VertexBufferHeaders[rawMesh.VertexBuffers[0]].StrideBytes; for (int vertind = indexStart; vertind < indexStart + indexCount; vertind++) { int current_ind; if (indsize == 2) { current_ind = BitConverter.ToInt16(ind, vertind * 2); } else { current_ind = BitConverter.ToInt32(ind, vertind * 4); } float x = BitConverter.ToSingle(verts, stride * current_ind); float y = BitConverter.ToSingle(verts, stride * current_ind + 4); float z = BitConverter.ToSingle(verts, stride * current_ind + 8); lower = XMVector.Min(new XMVector(x, y, z, 1.0f), lower); upper = XMVector.Max(new XMVector(x, y, z, 1.0f), upper); } } XMVector half = upper - lower; half *= 0.5f; this.BoundingBoxCenter = lower + half; this.BoundingBoxExtents = half; }
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)); }