public static XMVector BaryCentricV(XMVector q0, XMVector q1, XMVector q2, XMVector f, XMVector g) { Debug.Assert(f.Y == f.X && f.Z == f.X && f.W == f.X, "Reviewed"); Debug.Assert(g.Y == g.X && g.Z == g.X && g.W == g.X, "Reviewed"); XMVector epsilon = XMVector.FromSplatConstant(1, 16); XMVector s = XMVector.Add(f, g); XMVector result; if (XMVector4.InBounds(s, epsilon)) { result = q0; } else { XMVector q01 = XMQuaternion.SlerpV(q0, q1, s); XMVector q02 = XMQuaternion.SlerpV(q0, q2, s); XMVector gs = s.Reciprocal(); gs = XMVector.Multiply(g, gs); result = XMQuaternion.SlerpV(q01, q02, gs); } return(result); }
public static XMVector FresnelTerm(XMVector cosIncidentAngle, XMVector refractionIndex) { Debug.Assert(!XMVector4.IsInfinite(cosIncidentAngle), "Reviewed"); //// Result = 0.5f * (g - c)^2 / (g + c)^2 * ((c * (g + c) - 1)^2 / (c * (g - c) + 1)^2 + 1) where //// c = CosIncidentAngle //// g = sqrt(c^2 + RefractionIndex^2 - 1) XMVector g = XMVector.MultiplyAdd(refractionIndex, refractionIndex, XMGlobalConstants.NegativeOne); g = XMVector.MultiplyAdd(cosIncidentAngle, cosIncidentAngle, g); g = g.Abs().Sqrt(); XMVector s = XMVector.Add(g, cosIncidentAngle); XMVector d = XMVector.Subtract(g, cosIncidentAngle); XMVector v0 = XMVector.Multiply(d, d); XMVector v1 = XMVector.Multiply(s, s).Reciprocal(); v0 = XMVector.Multiply(XMGlobalConstants.OneHalf, v0); v0 = XMVector.Multiply(v0, v1); XMVector v2 = XMVector.MultiplyAdd(cosIncidentAngle, s, XMGlobalConstants.NegativeOne); XMVector v3 = XMVector.MultiplyAdd(cosIncidentAngle, d, XMGlobalConstants.One); v2 = XMVector.Multiply(v2, v2); v3 = XMVector.Multiply(v3, v3); v3 = v3.Reciprocal(); v2 = XMVector.MultiplyAdd(v2, v3, XMGlobalConstants.One); return(XMVector.Multiply(v0, v2).Saturate()); }
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 = XMVector4.Dot(incident, normal); result = XMVector.Add(result, result); result = XMVector.NegativeMultiplySubtract(result, normal, incident); return(result); }
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)); }
public static XMVector SlerpV(XMVector q0, XMVector q1, XMVector t) { Debug.Assert(t.Y == t.X && t.Z == t.X && t.W == t.X, "Reviewed"); //// Result = Q0 * sin((1.0 - t) * Omega) / sin(Omega) + Q1 * sin(t * Omega) / sin(Omega) XMVector oneMinusEpsilon = XMVector.FromFloat(1.0f - 0.00001f, 1.0f - 0.00001f, 1.0f - 0.00001f, 1.0f - 0.00001f); XMVector cosOmega = XMQuaternion.Dot(q0, q1); XMVector zero = XMVector.Zero; XMVector control = XMVector.Less(cosOmega, zero); XMVector sign = XMVector.Select(XMGlobalConstants.One, XMGlobalConstants.NegativeOne, control); cosOmega = XMVector.Multiply(cosOmega, sign); control = XMVector.Less(cosOmega, oneMinusEpsilon); XMVector sinOmega = XMVector .NegativeMultiplySubtract(cosOmega, cosOmega, XMGlobalConstants.One) .Sqrt(); XMVector omega = XMVector.ATan2(sinOmega, cosOmega); XMVector signMask = XMVector.SignMask; XMVector v01 = XMVector.ShiftLeft(t, zero, 2); signMask = XMVector.ShiftLeft(signMask, zero, 3); v01 = XMVector.XorInt(v01, signMask); v01 = XMVector.Add(XMGlobalConstants.IdentityR0, v01); XMVector invSinOmega = sinOmega.Reciprocal(); XMVector s0 = XMVector .Multiply(v01, omega) .Sin(); s0 = XMVector.Multiply(s0, invSinOmega); s0 = XMVector.Select(v01, s0, control); XMVector s1 = XMVector.SplatY(s0); s0 = XMVector.SplatX(s0); s1 = XMVector.Multiply(s1, sign); XMVector result = XMVector.Multiply(q0, s0); result = XMVector.MultiplyAdd(q1, s1, result); return(result); }
public static XMVector SrgbToRgb(XMVector srgb) { XMVector cutoff = XMVector.FromFloat(0.04045f, 0.04045f, 0.04045f, 1.0f); XMVector invLinear = XMVector.FromFloat(1.0f / 12.92f, 1.0f / 12.92f, 1.0f / 12.92f, 1.0f); XMVector scale = XMVector.FromFloat(1.0f / 1.055f, 1.0f / 1.055f, 1.0f / 1.055f, 1.0f); XMVector bias = XMVector.FromFloat(0.055f, 0.055f, 0.055f, 0.0f); XMVector gamma = XMVector.FromFloat(2.4f, 2.4f, 2.4f, 1.0f); XMVector v = srgb.Saturate(); XMVector v0 = XMVector.Multiply(v, invLinear); XMVector v1 = XMVector.Pow(XMVector.Multiply(XMVector.Add(v, bias), scale), gamma); XMVector select = XMVector.Greater(v, cutoff); v = XMVector.Select(v0, v1, select); return(XMVector.Select(srgb, v, XMGlobalConstants.Select1110)); }
public static void SquadSetup(out XMVector a, out XMVector b, out XMVector c, XMVector q0, XMVector q1, XMVector q2, XMVector q3) { XMVector ls12 = XMQuaternion.LengthSquare(XMVector.Add(q1, q2)); XMVector ld12 = XMQuaternion.LengthSquare(XMVector.Subtract(q1, q2)); XMVector sq2 = q2.Negate(); XMVector control1 = XMVector.Less(ls12, ld12); sq2 = XMVector.Select(q2, sq2, control1); XMVector ls01 = XMQuaternion.LengthSquare(XMVector.Add(q0, q1)); XMVector ld01 = XMQuaternion.LengthSquare(XMVector.Subtract(q0, q1)); XMVector sq0 = q0.Negate(); XMVector ls23 = XMQuaternion.LengthSquare(XMVector.Add(sq2, q3)); XMVector ld23 = XMQuaternion.LengthSquare(XMVector.Subtract(sq2, q3)); XMVector sq3 = q3.Negate(); XMVector control0 = XMVector.Less(ls01, ld01); XMVector control2 = XMVector.Less(ls23, ld23); sq0 = XMVector.Select(q0, sq0, control0); sq3 = XMVector.Select(q3, sq3, control2); XMVector invQ1 = XMQuaternion.Inverse(q1); XMVector invQ2 = XMQuaternion.Inverse(sq2); XMVector ln_q0 = XMQuaternion.Ln(XMQuaternion.Multiply(invQ1, sq0)); XMVector ln_q2 = XMQuaternion.Ln(XMQuaternion.Multiply(invQ1, sq2)); XMVector ln_q1 = XMQuaternion.Ln(XMQuaternion.Multiply(invQ2, q1)); XMVector ln_q3 = XMQuaternion.Ln(XMQuaternion.Multiply(invQ2, sq3)); XMVector negativeOneQuarter = XMVector.FromSplatConstant(-1, 2); XMVector expQ02 = XMVector.Multiply(XMVector.Add(ln_q0, ln_q2), negativeOneQuarter); XMVector expQ13 = XMVector.Multiply(XMVector.Add(ln_q1, ln_q3), negativeOneQuarter); expQ02 = XMQuaternion.Exp(expQ02); expQ13 = XMQuaternion.Exp(expQ13); a = XMQuaternion.Multiply(q1, expQ02); b = XMQuaternion.Multiply(sq2, expQ13); c = sq2; }
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 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 XMVector Orthogonal(XMVector v) { XMVector zero = XMVector.Zero; XMVector z = XMVector.SplatZ(v); XMVector yzyy = new XMVector(v.Y, v.Z, v.Y, v.Y); XMVector negativeV = XMVector.Subtract(zero, v); XMVector z_isNegative = XMVector.Less(z, zero); XMVector yzyyIsNegative = XMVector.Less(yzyy, zero); XMVector s = XMVector.Add(yzyy, z); XMVector d = XMVector.Subtract(yzyy, z); XMVector select = XMVector.EqualInt(z_isNegative, yzyyIsNegative); XMVector r0 = new XMVector(s.X, negativeV.X, negativeV.X, negativeV.X); XMVector r1 = new XMVector(d.X, v.X, v.X, v.X); return(XMVector.Select(r1, r0, select)); }
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)); }
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 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 BoundingSphere CreateMerged(BoundingSphere s1, BoundingSphere s2) { XMVector center1 = s1.center; float r1 = s1.radius; XMVector center2 = s2.center; float r2 = s2.radius; XMVector v = XMVector.Subtract(center2, center1); XMVector dist = XMVector3.Length(v); float d = dist.X; if (r1 + r2 >= d) { if (r1 - r2 >= d) { return(s1); } else if (r2 - r1 >= d) { return(s2); } } XMVector n = XMVector.Divide(v, dist); float t1 = Math.Min(-r1, d - r2); float t2 = Math.Max(r1, d + r2); float t_5 = (t2 - t1) * 0.5f; XMVector n_center = XMVector.Add(center1, XMVector.Multiply(n, XMVector.Replicate(t_5 + t1))); return(new BoundingSphere(n_center, t_5)); }
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)); } }