Esempio n. 1
0
        public static QuaternionF Slerp(QuaternionF start, QuaternionF end, float blend)
        {
            // Clone to avoid modifying the parameters
            var q1 = start.Clone();
            var q2 = end.Clone();

            // if either input is zero, return the other.
            if (Math.Abs(q1.Magnitude() - 0) < 0.0001)
            {
                return(Math.Abs(q2.Magnitude() - 0) < 0.0001 ? Identity : q2);
            }
            if (Math.Abs(q2.Magnitude() - 0) < 0.0001)
            {
                return(q1);
            }

            var cosHalfAngle = q1.Dot(q2);

            if (cosHalfAngle >= 1 || cosHalfAngle <= -1)
            {
                return(q1);
            }

            if (cosHalfAngle < 0)
            {
                q2.Vector    = -q2.Vector;
                q2.Scalar    = -q2.Scalar;
                cosHalfAngle = -cosHalfAngle;
            }

            float blendA;
            float blendB;

            if (cosHalfAngle < 0.99)
            {
                // do proper slerp for big angles
                var halfAngle           = (float)Math.Acos(cosHalfAngle);
                var sinHalfAngle        = (float)Math.Sin(halfAngle);
                var oneOverSinHalfAngle = 1 / sinHalfAngle;
                blendA = (float)Math.Sin(halfAngle * (1 - blend)) * oneOverSinHalfAngle;
                blendB = (float)Math.Sin(halfAngle * blend) * oneOverSinHalfAngle;
            }
            else
            {
                // do lerp if angle is really small.
                blendA = 1 - blend;
                blendB = blend;
            }

            var result = new QuaternionF(blendA * q1.Vector + blendB * q2.Vector, blendA * q1.W + blendB * q2.W);

            return(result.Magnitude() > 0 ? result.Normalise() : Identity);
        }
Esempio n. 2
0
        public static QuaternionF Lerp(QuaternionF start, QuaternionF end, float blend)
        {
            // Clone to avoid modifying the parameters
            var q1 = start.Clone();
            var q2 = end.Clone();

            // if either input is zero, return the other.
            if (Math.Abs(q1.Magnitude() - 0) < 0.0001)
            {
                return(Math.Abs(q2.Magnitude() - 0) < 0.0001 ? Identity : q2);
            }
            if (Math.Abs(q2.Magnitude() - 0) < 0.0001)
            {
                return(q1);
            }

            var blendA = 1 - blend;
            var blendB = blend;

            var result = new QuaternionF(blendA * q1.Vector + blendB * q2.Vector, blendA * q1.W + blendB * q2.W);

            return(result.Magnitude() > 0 ? result.Normalise() : Identity);
        }
Esempio n. 3
0
        public static QuaternionF Slerp(QuaternionF start, QuaternionF end, float blend)
        {
            // Clone to avoid modifying the parameters
            var q1 = start.Clone();
            var q2 = end.Clone();

            // if either input is zero, return the other.
            if (Math.Abs(q1.Magnitude() - 0) < 0.0001) return Math.Abs(q2.Magnitude() - 0) < 0.0001 ? Identity : q2;
            if (Math.Abs(q2.Magnitude() - 0) < 0.0001) return q1;

            var cosHalfAngle = q1.Dot(q2);

            if (cosHalfAngle >= 1 || cosHalfAngle <= -1) return q1;

            if (cosHalfAngle < 0)
            {
                q2.Vector = -q2.Vector;
                q2.Scalar = -q2.Scalar;
                cosHalfAngle = -cosHalfAngle;
            }

            float blendA;
            float blendB;
            if (cosHalfAngle < 0.99)
            {
                // do proper slerp for big angles
                var halfAngle = (float) Math.Acos(cosHalfAngle);
                var sinHalfAngle = (float)Math.Sin(halfAngle);
                var oneOverSinHalfAngle = 1 / sinHalfAngle;
                blendA = (float) Math.Sin(halfAngle * (1 - blend)) * oneOverSinHalfAngle;
                blendB = (float) Math.Sin(halfAngle * blend) * oneOverSinHalfAngle;
            }
            else
            {
                // do lerp if angle is really small.
                blendA = 1 - blend;
                blendB = blend;
            }

            var result = new QuaternionF(blendA * q1.Vector + blendB * q2.Vector, blendA * q1.W + blendB * q2.W);
            return result.Magnitude() > 0 ? result.Normalise() : Identity;
        }
Esempio n. 4
0
        public static QuaternionF Lerp(QuaternionF start, QuaternionF end, float blend)
        {
            // Clone to avoid modifying the parameters
            var q1 = start.Clone();
            var q2 = end.Clone();

            // if either input is zero, return the other.
            if (Math.Abs(q1.Magnitude() - 0) < 0.0001) return Math.Abs(q2.Magnitude() - 0) < 0.0001 ? Identity : q2;
            if (Math.Abs(q2.Magnitude() - 0) < 0.0001) return q1;

            var blendA = 1 - blend;
            var blendB = blend;

            var result = new QuaternionF(blendA * q1.Vector + blendB * q2.Vector, blendA * q1.W + blendB * q2.W);
            return result.Magnitude() > 0 ? result.Normalise() : Identity;
        }