Пример #1
0
        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));
        }
Пример #2
0
        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);
            }
        }
Пример #3
0
        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);
        }
Пример #4
0
 public static XMVector AngleBetweenNormals(XMVector n1, XMVector n2)
 {
     return(XMVector3
            .Dot(n1, n2)
            .Clamp(XMGlobalConstants.NegativeOne, XMGlobalConstants.One)
            .ACos());
 }
Пример #5
0
        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));
        }
Пример #6
0
        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);
        }
Пример #7
0
        public static XMVector FromPointNormal(XMVector point, XMVector normal)
        {
            XMVector w = XMVector3
                         .Dot(point, normal)
                         .Negate();

            return(XMVector.Select(w, normal, XMGlobalConstants.Select1110));
        }
Пример #8
0
        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));
        }
Пример #9
0
        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));
        }
Пример #10
0
        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));
        }
Пример #11
0
        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));
        }
Пример #12
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));
            }
        }
Пример #13
0
        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);
        }
Пример #14
0
        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);
        }
Пример #15
0
        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));
        }
Пример #16
0
        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));
        }
Пример #17
0
        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));
        }
Пример #18
0
        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));
        }
Пример #19
0
        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());
        }
Пример #20
0
        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));
        }
Пример #21
0
        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));
        }
Пример #22
0
        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));
        }
Пример #23
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);
        }
Пример #24
0
        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);
        }
Пример #25
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);
        }
Пример #26
0
        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);
        }
Пример #27
0
        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));
        }
Пример #28
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));
            }
        }
Пример #29
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));
        }
Пример #30
0
        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));
        }