예제 #1
0
        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);
        }
예제 #2
0
        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());
        }
예제 #3
0
        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));
            }
        }
예제 #4
0
        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);
        }
예제 #5
0
        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));
        }
예제 #6
0
        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);
        }
예제 #7
0
        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));
        }
예제 #8
0
        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;
        }
예제 #9
0
        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);
        }
예제 #10
0
        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));
        }
예제 #11
0
        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));
        }
예제 #13
0
        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);
        }
예제 #14
0
        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));
            }
        }
예제 #15
0
        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));
        }
예제 #17
0
        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));
            }
        }