public static XMVector Unproject( XMVector v, float viewportX, float viewportY, float viewportWidth, float viewportHeight, float viewportMinZ, float viewportMaxZ, XMMatrix projection, XMMatrix view, XMMatrix world) { XMVector d = XMVector.FromFloat(-1.0f, 1.0f, 0.0f, 0.0f); XMVector scale = new XMVector(viewportWidth * 0.5f, -viewportHeight * 0.5f, viewportMaxZ - viewportMinZ, 1.0f); scale = scale.Reciprocal(); XMVector offset = new XMVector(-viewportX, -viewportY, -viewportMinZ, 0.0f); offset = XMVector.MultiplyAdd(scale, offset, d); XMMatrix transform = XMMatrix.Multiply(world, view); transform = XMMatrix.Multiply(transform, projection); transform = transform.Inverse(); XMVector result = XMVector.MultiplyAdd(v, scale, offset); return(XMVector3.TransformCoord(result, transform)); }
public static XMVector RefractV(XMVector incident, XMVector normal, XMVector refractionIndex) { //// Result = RefractionIndex * Incident - Normal * (RefractionIndex * dot(Incident, Normal) + //// sqrt(1 - RefractionIndex * RefractionIndex * (1 - dot(Incident, Normal) * dot(Incident, Normal)))) XMVector zero = XMVector.Zero; XMVector incidentDotNornal = XMVector3.Dot(incident, normal); // R = 1.0f - RefractionIndex * RefractionIndex * (1.0f - IDotN * IDotN) XMVector r = XMVector.NegativeMultiplySubtract(incidentDotNornal, incidentDotNornal, XMGlobalConstants.One); r = XMVector.Multiply(r, refractionIndex); r = XMVector.NegativeMultiplySubtract(r, refractionIndex, XMGlobalConstants.One); if (r.X <= zero.X && r.Y <= zero.Y && r.Z <= zero.Z && r.W <= zero.W) { // Total internal reflection return(zero); } else { // R = RefractionIndex * IDotN + sqrt(R) r = r.Sqrt(); r = XMVector.MultiplyAdd(refractionIndex, incidentDotNornal, r); // Result = RefractionIndex * Incident - Normal * R XMVector result = XMVector.Multiply(refractionIndex, incident); result = XMVector.NegativeMultiplySubtract(normal, r, result); return(result); } }
public static XMVector Project( XMVector v, float viewportX, float viewportY, float viewportWidth, float viewportHeight, float viewportMinZ, float viewportMaxZ, XMMatrix projection, XMMatrix view, XMMatrix world) { float halfViewportWidth = viewportWidth * 0.5f; float halfViewportHeight = viewportHeight * 0.5f; XMVector scale = new XMVector(halfViewportWidth, -halfViewportHeight, viewportMaxZ - viewportMinZ, 0.0f); XMVector offset = new XMVector(viewportX + halfViewportWidth, viewportY + halfViewportHeight, viewportMinZ, 0.0f); XMMatrix transform = XMMatrix.Multiply(world, view); transform = XMMatrix.Multiply(transform, projection); XMVector result = XMVector3.TransformCoord(v, transform); result = XMVector.MultiplyAdd(result, scale, offset); return(result); }
public static XMVector AngleBetweenNormals(XMVector n1, XMVector n2) { return(XMVector3 .Dot(n1, n2) .Clamp(XMGlobalConstants.NegativeOne, XMGlobalConstants.One) .ACos()); }
public static XMVector ClampLength(XMVector v, float lengthMin, float lengthMax) { XMVector clampMax = XMVector.Replicate(lengthMax); XMVector clampMin = XMVector.Replicate(lengthMin); return(XMVector3.ClampLengthV(v, clampMin, clampMax)); }
public static void ComponentsFromNormal(out XMVector parallel, out XMVector perpendicular, XMVector v, XMVector normal) { XMVector scale = XMVector3.Dot(v, normal); XMVector parallelV = XMVector.Multiply(normal, scale); parallel = parallelV; perpendicular = XMVector.Subtract(v, parallelV); }
public static XMVector FromPointNormal(XMVector point, XMVector normal) { XMVector w = XMVector3 .Dot(point, normal) .Negate(); return(XMVector.Select(w, normal, XMGlobalConstants.Select1110)); }
public static XMVector NormalizeEst(XMVector p) { //// XMPlaneNormalizeEst uses a reciprocal estimate and //// returns QNaN on zero and infinite vectors. XMVector result = XMVector3.ReciprocalLengthEst(p); return(XMVector.Multiply(p, result)); }
public static XMVector RotationAxis(XMVector axis, float angle) { Debug.Assert(!XMVector3.Equal(axis, XMGlobalConstants.Zero), "Reviewed"); Debug.Assert(!XMVector3.IsInfinite(axis), "Reviewed"); XMVector normal = XMVector3.Normalize(axis); return(XMQuaternion.RotationNormal(normal, angle)); }
public static XMVector YuvToRgb(XMVector yuv) { XMVector scale1 = XMVector.FromFloat(0.0f, -0.395f, 2.032f, 0.0f); XMVector scale2 = XMVector.FromFloat(1.140f, -0.581f, 0.0f, 0.0f); XMMatrix m = new XMMatrix(XMGlobalConstants.One, scale1, scale2, XMGlobalConstants.Zero); XMVector clr = XMVector3.Transform(yuv, m); return(XMVector.Select(yuv, clr, XMGlobalConstants.Select1110)); }
public static XMVector YuvToRgbHD(XMVector yuv) { XMVector scale1 = XMVector.FromFloat(0.0f, -0.2153f, 2.1324f, 0.0f); XMVector scale2 = XMVector.FromFloat(1.2803f, -0.3806f, 0.0f, 0.0f); XMMatrix m = new XMMatrix(XMGlobalConstants.One, scale1, scale2, XMGlobalConstants.Zero); XMVector clr = XMVector3.Transform(yuv, m); return(XMVector.Select(yuv, clr, XMGlobalConstants.Select1110)); }
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 XMVector Reflect(XMVector incident, XMVector normal) { //// Result = Incident - (2 * dot(Incident, Normal)) * Normal XMVector result = XMVector3.Dot(incident, normal); result = XMVector.Add(result, result); result = XMVector.NegativeMultiplySubtract(result, normal, incident); return(result); }
public static XMVector NormalizeEst(XMVector v) { //// XMVector3NormalizeEst uses a reciprocal estimate and //// returns QNaN on zero and infinite vectors. XMVector result; result = XMVector3.ReciprocalLength(v); result = XMVector.Multiply(v, result); return(result); }
public static XMVector RgbToYuvHD(XMVector rgb) { XMVector scale0 = XMVector.FromFloat(0.2126f, -0.0997f, 0.6150f, 0.0f); XMVector scale1 = XMVector.FromFloat(0.7152f, -0.3354f, -0.5586f, 0.0f); XMVector scale2 = XMVector.FromFloat(0.0722f, 0.4351f, -0.0564f, 0.0f); XMMatrix m = new XMMatrix(scale0, scale1, scale2, XMGlobalConstants.Zero); XMVector clr = XMVector3.Transform(rgb, m); return(XMVector.Select(rgb, clr, XMGlobalConstants.Select1110)); }
public static XMVector RgbToYuv(XMVector rgb) { XMVector scale0 = XMVector.FromFloat(0.299f, -0.147f, 0.615f, 0.0f); XMVector scale1 = XMVector.FromFloat(0.587f, -0.289f, -0.515f, 0.0f); XMVector scale2 = XMVector.FromFloat(0.114f, 0.436f, -0.100f, 0.0f); XMMatrix m = new XMMatrix(scale0, scale1, scale2, XMGlobalConstants.Zero); XMVector clr = XMVector3.Transform(rgb, m); return(XMVector.Select(rgb, clr, XMGlobalConstants.Select1110)); }
public static XMVector XyzToRgb(XMVector xyz) { XMVector scale0 = XMVector.FromFloat(2.3706743f, -0.5138850f, 0.0052982f, 0.0f); XMVector scale1 = XMVector.FromFloat(-0.9000405f, 1.4253036f, -0.0146949f, 0.0f); XMVector scale2 = XMVector.FromFloat(-0.4706338f, 0.0885814f, 1.0093968f, 0.0f); XMVector scale = XMVector.FromFloat(0.17697f, 0.17697f, 0.17697f, 0.0f); XMMatrix m = new XMMatrix(scale0, scale1, scale2, XMGlobalConstants.Zero); XMVector clr = XMVector3.Transform(XMVector.Multiply(xyz, scale), m); return(XMVector.Select(xyz, clr, XMGlobalConstants.Select1110)); }
public static XMVector RgbToXyz(XMVector rgb) { XMVector scale0 = XMVector.FromFloat(0.4887180f, 0.1762044f, 0.0000000f, 0.0f); XMVector scale1 = XMVector.FromFloat(0.3106803f, 0.8129847f, 0.0102048f, 0.0f); XMVector scale2 = XMVector.FromFloat(0.2006017f, 0.0108109f, 0.9897952f, 0.0f); XMVector scale = XMVector.FromFloat(1.0f / 0.17697f, 1.0f / 0.17697f, 1.0f / 0.17697f, 0.0f); XMMatrix m = new XMMatrix(scale0, scale1, scale2, XMGlobalConstants.Zero); XMVector clr = XMVector.Multiply(XMVector3.Transform(rgb, m), scale); return(XMVector.Select(rgb, clr, XMGlobalConstants.Select1110)); }
public static XMVector AngleBetweenVectors(XMVector v1, XMVector v2) { XMVector l1 = XMVector3.ReciprocalLength(v1); XMVector l2 = XMVector3.ReciprocalLength(v2); XMVector dot = XMVector3.Dot(v1, v2); l1 = XMVector.Multiply(l1, l2); return(XMVector .Multiply(dot, l1) .Clamp(XMGlobalConstants.NegativeOne, XMGlobalConstants.One) .ACos()); }
public static XMVector FromPoints(XMVector point1, XMVector point2, XMVector point3) { XMVector v21 = XMVector.Subtract(point1, point2); XMVector v31 = XMVector.Subtract(point1, point3); XMVector n = XMVector3.Cross(v21, v31); n = XMVector3.Normalize(n); XMVector d = XMPlane .DotNormal(n, point1) .Negate(); return(XMVector.Select(d, n, XMGlobalConstants.Select1110)); }
public static XMVector Normalize(XMVector v) { XMVector result = XMVector3.Length(v); float length = result.X; // Prevent divide by zero if (length > 0) { length = 1.0f / length; } return(new XMVector( v.X * length, v.Y * length, v.Z * length, v.W * length)); }
public static XMVector IntersectLine(XMVector p, XMVector linePoint1, XMVector linePoint2) { XMVector v1 = XMVector3.Dot(p, linePoint1); XMVector v2 = XMVector3.Dot(p, linePoint2); XMVector d = XMVector.Subtract(v1, v2); XMVector vt = XMPlane.DotCoord(p, linePoint1); vt = XMVector.Divide(vt, d); XMVector point = XMVector.Subtract(linePoint2, linePoint1); point = XMVector.MultiplyAdd(point, vt, linePoint1); XMVector control = XMVector.NearEqual(d, XMGlobalConstants.Zero, XMGlobalConstants.Epsilon); return(XMVector.Select(point, XMGlobalConstants.QNaN, control)); }
public static void IntersectPlane(out XMVector linePoint1, out XMVector linePoint2, XMVector p1, XMVector p2) { XMVector v1 = XMVector3.Cross(p2, p1); XMVector lengthSq = XMVector3.LengthSquare(v1); XMVector v2 = XMVector3.Cross(p2, v1); XMVector p1W = XMVector.SplatW(p1); XMVector point = XMVector.Multiply(v2, p1W); XMVector v3 = XMVector3.Cross(v1, p1); XMVector p2W = XMVector.SplatW(p2); point = XMVector.MultiplyAdd(v3, p2W, point); XMVector lineP1 = XMVector.Divide(point, lengthSq); XMVector lineP2 = XMVector.Add(lineP1, v1); XMVector control = XMVector.LessOrEqual(lengthSq, XMGlobalConstants.Epsilon); linePoint1 = XMVector.Select(lineP1, XMGlobalConstants.QNaN, control); linePoint2 = XMVector.Select(lineP2, XMGlobalConstants.QNaN, control); }
public static XMVector Exp(XMVector q) { XMVector theta = XMVector3.Length(q); XMVector sinTheta; XMVector cosTheta; theta.SinCos(out sinTheta, out cosTheta); XMVector s = XMVector.Divide(sinTheta, theta); XMVector result = XMVector.Multiply(q, s); XMVector zero = XMVector.Zero; XMVector control = XMVector.NearEqual(theta, zero, XMGlobalConstants.Epsilon); result = XMVector.Select(result, q, control); result = XMVector.Select(cosTheta, result, XMGlobalConstants.Select1110); return(result); }
private static XMVector HueToClr(XMVector p, XMVector q, XMVector h) { XMVector oneSixth = XMVector.FromFloat(1.0f / 6.0f, 1.0f / 6.0f, 1.0f / 6.0f, 1.0f / 6.0f); XMVector twoThirds = XMVector.FromFloat(2.0f / 3.0f, 2.0f / 3.0f, 2.0f / 3.0f, 2.0f / 3.0f); XMVector t = h; if (XMVector3.Less(t, XMGlobalConstants.Zero)) { t = XMVector.Add(t, XMGlobalConstants.One); } if (XMVector3.Greater(t, XMGlobalConstants.One)) { t = XMVector.Subtract(t, XMGlobalConstants.One); } if (XMVector3.Less(t, oneSixth)) { // p + (q - p) * 6 * t XMVector t1 = XMVector.Subtract(q, p); XMVector t2 = XMVector.Multiply(XMGlobalConstants.Six, t); return(XMVector.MultiplyAdd(t1, t2, p)); } if (XMVector3.Less(t, XMGlobalConstants.OneHalf)) { return(q); } if (XMVector3.Less(t, twoThirds)) { // p + (q - p) * 6 * (2/3 - t) XMVector t1 = XMVector.Subtract(q, p); XMVector t2 = XMVector.Multiply(XMGlobalConstants.Six, XMVector.Subtract(twoThirds, t)); return(XMVector.MultiplyAdd(t1, t2, p)); } return(p); }
public static XMVector ClampLengthV(XMVector v, XMVector lengthMin, XMVector lengthMax) { Debug.Assert(lengthMin.Y == lengthMin.X && lengthMin.Z == lengthMin.X, "Reviewed"); Debug.Assert(lengthMax.Y == lengthMax.X && lengthMax.Z == lengthMax.X, "Reviewed"); Debug.Assert(XMVector3.GreaterOrEqual(lengthMin, XMGlobalConstants.Zero), "Reviewed"); Debug.Assert(XMVector3.GreaterOrEqual(lengthMax, XMGlobalConstants.Zero), "Reviewed"); Debug.Assert(XMVector3.GreaterOrEqual(lengthMax, lengthMin), "Reviewed"); XMVector lengthSq = XMVector3.LengthSquare(v); XMVector zero = XMVector.Zero; XMVector reciprocalLength = lengthSq.ReciprocalSqrt(); XMVector infiniteLength = XMVector.EqualInt(lengthSq, XMGlobalConstants.Infinity); XMVector zeroLength = XMVector.EqualInt(lengthSq, zero); XMVector normal = XMVector.Multiply(v, reciprocalLength); XMVector length = XMVector.Multiply(lengthSq, reciprocalLength); XMVector select = XMVector.EqualInt(infiniteLength, zeroLength); length = XMVector.Select(lengthSq, length, select); normal = XMVector.Select(lengthSq, normal, select); XMVector controlMax = XMVector.Greater(length, lengthMax); XMVector controlMin = XMVector.Less(length, lengthMin); XMVector clampLength = XMVector.Select(length, lengthMax, controlMax); clampLength = XMVector.Select(clampLength, lengthMin, controlMin); XMVector result = XMVector.Multiply(normal, clampLength); // Preserve the original vector (with no precision loss) if the length falls within the given range XMVector control = XMVector.EqualInt(controlMax, controlMin); result = XMVector.Select(result, v, control); return(result); }
public static XMVector XyzToSrgb(XMVector xyz) { XMVector scale0 = XMVector.FromFloat(3.2406f, -0.9689f, 0.0557f, 0.0f); XMVector scale1 = XMVector.FromFloat(-1.5372f, 1.8758f, -0.2040f, 0.0f); XMVector scale2 = XMVector.FromFloat(-0.4986f, 0.0415f, 1.0570f, 0.0f); XMVector cutoff = XMVector.FromFloat(0.0031308f, 0.0031308f, 0.0031308f, 0.0f); XMVector exp = XMVector.FromFloat(1.0f / 2.4f, 1.0f / 2.4f, 1.0f / 2.4f, 1.0f); XMMatrix m = new XMMatrix(scale0, scale1, scale2, XMGlobalConstants.Zero); XMVector lclr = XMVector3.Transform(xyz, m); XMVector sel = XMVector.Greater(lclr, cutoff); // clr = 12.92 * lclr for lclr <= 0.0031308f XMVector smallC = XMVector.Multiply(lclr, XMGlobalConstants.MsrgbScale); // clr = (1+a)*pow(lclr, 1/2.4) - a for lclr > 0.0031308 (where a = 0.055) XMVector largeC = XMVector.Subtract(XMVector.Multiply(XMGlobalConstants.MsrgbA1, XMVector.Pow(lclr, exp)), XMGlobalConstants.MsrgbA); XMVector clr = XMVector.Select(smallC, largeC, sel); return(XMVector.Select(xyz, clr, XMGlobalConstants.Select1110)); }
public static XMVector HslToRgb(XMVector hsl) { XMVector oneThird = XMVector.FromFloat(1.0f / 3.0f, 1.0f / 3.0f, 1.0f / 3.0f, 1.0f / 3.0f); XMVector s = XMVector.SplatY(hsl); XMVector l = XMVector.SplatZ(hsl); if (XMVector3.NearEqual(s, XMGlobalConstants.Zero, XMGlobalConstants.Epsilon)) { // Achromatic return(XMVector.Select(hsl, l, XMGlobalConstants.Select1110)); } else { XMVector h = XMVector.SplatX(hsl); XMVector q; if (XMVector3.Less(l, XMGlobalConstants.OneHalf)) { q = XMVector.Multiply(l, XMVector.Add(XMGlobalConstants.One, s)); } else { q = XMVector.Subtract(XMVector.Add(l, s), XMVector.Multiply(l, s)); } XMVector p = XMVector.Subtract(XMVector.Multiply(XMGlobalConstants.Two, l), q); XMVector r = XMColor.HueToClr(p, q, XMVector.Add(h, oneThird)); XMVector g = XMColor.HueToClr(p, q, h); XMVector b = XMColor.HueToClr(p, q, XMVector.Subtract(h, oneThird)); XMVector rg = XMVector.Select(g, r, XMGlobalConstants.Select1000); XMVector ba = XMVector.Select(hsl, b, XMGlobalConstants.Select1110); return(XMVector.Select(ba, rg, XMGlobalConstants.Select1100)); } }
public static XMVector SrgbToXyz(XMVector srgb) { XMVector scale0 = XMVector.FromFloat(0.4124f, 0.2126f, 0.0193f, 0.0f); XMVector scale1 = XMVector.FromFloat(0.3576f, 0.7152f, 0.1192f, 0.0f); XMVector scale2 = XMVector.FromFloat(0.1805f, 0.0722f, 0.9505f, 0.0f); XMVector cutoff = XMVector.FromFloat(0.04045f, 0.04045f, 0.04045f, 0.0f); XMVector exp = XMVector.FromFloat(2.4f, 2.4f, 2.4f, 1.0f); XMVector sel = XMVector.Greater(srgb, cutoff); // lclr = clr / 12.92 XMVector smallC = XMVector.Divide(srgb, XMGlobalConstants.MsrgbScale); // lclr = pow( (clr + a) / (1+a), 2.4 ) XMVector largeC = XMVector.Pow(XMVector.Divide(XMVector.Add(srgb, XMGlobalConstants.MsrgbA), XMGlobalConstants.MsrgbA1), exp); XMVector lclr = XMVector.Select(smallC, largeC, sel); XMMatrix m = new XMMatrix(scale0, scale1, scale2, XMGlobalConstants.Zero); XMVector clr = XMVector3.Transform(lclr, m); return(XMVector.Select(srgb, clr, XMGlobalConstants.Select1110)); }
public static XMVector LinePointDistance(XMVector linePoint1, XMVector linePoint2, XMVector point) { //// Given a vector PointVector from LinePoint1 to Point and a vector //// LineVector from LinePoint1 to LinePoint2, the scaled distance //// PointProjectionScale from LinePoint1 to the perpendicular projection //// of PointVector onto the line is defined as: //// //// PointProjectionScale = dot(PointVector, LineVector) / LengthSq(LineVector) XMVector pointVector = XMVector.Subtract(point, linePoint1); XMVector lineVector = XMVector.Subtract(linePoint2, linePoint1); XMVector lengthSq = XMVector3.LengthSquare(lineVector); XMVector pointProjectionScale = XMVector3.Dot(pointVector, lineVector); pointProjectionScale = XMVector.Divide(pointProjectionScale, lengthSq); XMVector distanceVector = XMVector.Multiply(lineVector, pointProjectionScale); distanceVector = XMVector.Subtract(pointVector, distanceVector); return(XMVector3.Length(distanceVector)); }