Пример #1
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));
            }
        }
Пример #2
0
        public static XMVector TransformCoord(XMVector v, XMMatrix m)
        {
            XMVector y = XMVector.SplatY(v);
            XMVector x = XMVector.SplatX(v);

            XMVector result = XMVector.MultiplyAdd(y, ((XMVector *)&m)[1], ((XMVector *)&m)[3]);

            result = XMVector.MultiplyAdd(x, ((XMVector *)&m)[0], result);

            XMVector w = XMVector.SplatW(result);

            return(XMVector.Divide(result, w));
        }
Пример #3
0
        public static XMVector Inverse(XMVector q)
        {
            XMVector zero = XMVector.Zero;

            XMVector l         = XMVector4.LengthSquare(q);
            XMVector conjugate = XMQuaternion.Conjugate(q);

            XMVector control = XMVector.LessOrEqual(l, XMGlobalConstants.Epsilon);

            XMVector result = XMVector.Divide(conjugate, l);

            result = XMVector.Select(result, zero, control);

            return(result);
        }
Пример #4
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));
        }
Пример #5
0
        public static XMVector Ln(XMVector q)
        {
            XMVector oneMinusEpsilon = XMVector.FromFloat(1.0f - 0.00001f, 1.0f - 0.00001f, 1.0f - 0.00001f, 1.0f - 0.00001f);

            XMVector qw       = XMVector.SplatW(q);
            XMVector q0       = XMVector.Select(XMGlobalConstants.Select1110, q, XMGlobalConstants.Select1110);
            XMVector controlW = qw.InBounds(oneMinusEpsilon);

            XMVector theta    = qw.ACos();
            XMVector sinTheta = theta.Sin();

            XMVector s = XMVector.Divide(theta, sinTheta);

            XMVector result = XMVector.Multiply(q0, s);

            result = XMVector.Select(q0, result, controlW);

            return(result);
        }
Пример #6
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);
        }
Пример #7
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);
        }
Пример #8
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));
        }
Пример #10
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));
        }
Пример #11
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));
            }
        }
Пример #12
0
        public static bool Intersects(XMVector origin, XMVector direction, XMVector v0, XMVector v1, XMVector v2, out float uCoordinate, out float vCoordinate, out float distance)
        {
            Debug.Assert(Internal.XMVector3IsUnit(direction), "Reviewed");

            XMVector zero = XMGlobalConstants.Zero;

            XMVector e1 = v1 - v0;
            XMVector e2 = v2 - v0;

            // p = Direction ^ e2;
            XMVector p = XMVector3.Cross(direction, e2);

            // det = e1 * p;
            XMVector det = XMVector3.Dot(e1, p);

            XMVector u, v, t;

            if (XMVector3.GreaterOrEqual(det, CollisionGlobalConstants.RayEpsilon))
            {
                // Determinate is positive (front side of the triangle).
                XMVector s = origin - v0;

                // u = s * p;
                u = XMVector3.Dot(s, p);

                XMVector noIntersection = XMVector.Less(u, zero);
                noIntersection = XMVector.OrInt(noIntersection, XMVector.Greater(u, det));

                // q = s ^ e1;
                XMVector q = XMVector3.Cross(s, e1);

                // v = Direction * q;
                v = XMVector3.Dot(direction, q);

                noIntersection = XMVector.OrInt(noIntersection, XMVector.Less(v, zero));
                noIntersection = XMVector.OrInt(noIntersection, XMVector.Greater(u + v, det));

                // t = e2 * q;
                t = XMVector3.Dot(e2, q);

                noIntersection = XMVector.OrInt(noIntersection, XMVector.Less(t, zero));

                if (XMVector4.EqualInt(noIntersection, XMVector.TrueInt))
                {
                    uCoordinate = 0.0f;
                    vCoordinate = 0.0f;
                    distance    = 0.0f;
                    return(false);
                }
            }
            else if (XMVector3.LessOrEqual(det, CollisionGlobalConstants.RayNegEpsilon))
            {
                // Determinate is negative (back side of the triangle).
                XMVector s = origin - v0;

                // u = s * p;
                u = XMVector3.Dot(s, p);

                XMVector noIntersection = XMVector.Greater(u, zero);
                noIntersection = XMVector.OrInt(noIntersection, XMVector.Less(u, det));

                // q = s ^ e1;
                XMVector q = XMVector3.Cross(s, e1);

                // v = Direction * q;
                v = XMVector3.Dot(direction, q);

                noIntersection = XMVector.OrInt(noIntersection, XMVector.Greater(v, zero));
                noIntersection = XMVector.OrInt(noIntersection, XMVector.Less(u + v, det));

                // t = e2 * q;
                t = XMVector3.Dot(e2, q);

                noIntersection = XMVector.OrInt(noIntersection, XMVector.Greater(t, zero));

                if (XMVector4.EqualInt(noIntersection, XMVector.TrueInt))
                {
                    uCoordinate = 0.0f;
                    vCoordinate = 0.0f;
                    distance    = 0.0f;
                    return(false);
                }
            }
            else
            {
                // Parallel ray.
                uCoordinate = 0.0f;
                vCoordinate = 0.0f;
                distance    = 0.0f;
                return(false);
            }

            // (u / det) and (v / dev) are the barycentric coordinates of the intersection.

            u = XMVector.Divide(u, det);
            v = XMVector.Divide(v, det);
            t = XMVector.Divide(t, det);

            // Store the x-component to *pDist
            u.StoreFloat(out uCoordinate);
            v.StoreFloat(out vCoordinate);
            t.StoreFloat(out distance);

            return(true);
        }
        public static BoundingSphere CreateFromPoints(XMFloat3[] points)
        {
            if (points == null)
            {
                throw new ArgumentNullException("points");
            }

            if (points.Length == 0)
            {
                throw new ArgumentOutOfRangeException("points");
            }

            // Find the points with minimum and maximum x, y, and z
            XMVector minX, maxX, minY, maxY, minZ, maxZ;

            minX = maxX = minY = maxY = minZ = maxZ = points[0];

            for (int i = 1; i < points.Length; i++)
            {
                XMVector point = points[i];

                float px = point.X;
                float py = point.Y;
                float pz = point.Z;

                if (px < minX.X)
                {
                    minX = point;
                }

                if (px > maxX.X)
                {
                    maxX = point;
                }

                if (py < minY.Y)
                {
                    minY = point;
                }

                if (py > maxY.Y)
                {
                    maxY = point;
                }

                if (pz < minZ.Z)
                {
                    minZ = point;
                }

                if (pz > maxZ.Z)
                {
                    maxZ = point;
                }
            }

            // Use the min/max pair that are farthest apart to form the initial sphere.
            XMVector deltaX = maxX - minX;
            XMVector distX  = XMVector3.Length(deltaX);

            XMVector deltaY = maxY - minY;
            XMVector distY  = XMVector3.Length(deltaY);

            XMVector deltaZ = maxZ - minZ;
            XMVector distZ  = XMVector3.Length(deltaZ);

            XMVector v_center;
            XMVector v_radius;

            if (XMVector3.Greater(distX, distY))
            {
                if (XMVector3.Greater(distX, distZ))
                {
                    // Use min/max x.
                    v_center = XMVector.Lerp(maxX, minX, 0.5f);
                    v_radius = distX * 0.5f;
                }
                else
                {
                    // Use min/max z.
                    v_center = XMVector.Lerp(maxZ, minZ, 0.5f);
                    v_radius = distZ * 0.5f;
                }
            }
            else
            {
                //// Y >= X

                if (XMVector3.Greater(distY, distZ))
                {
                    // Use min/max y.
                    v_center = XMVector.Lerp(maxY, minY, 0.5f);
                    v_radius = distY * 0.5f;
                }
                else
                {
                    // Use min/max z.
                    v_center = XMVector.Lerp(maxZ, minZ, 0.5f);
                    v_radius = distZ * 0.5f;
                }
            }

            // Add any points not inside the sphere.
            for (int i = 0; i < points.Length; i++)
            {
                XMVector point = points[i];

                XMVector delta = point - v_center;

                XMVector dist = XMVector3.Length(delta);

                if (XMVector3.Greater(dist, v_radius))
                {
                    // Adjust sphere to include the new point.
                    v_radius  = (v_radius + dist) * 0.5f;
                    v_center += (XMVector.Replicate(1.0f) - XMVector.Divide(v_radius, dist)) * delta;
                }
            }

            return(new BoundingSphere(v_center, v_radius.X));
        }