예제 #1
0
        public static KeyframeTrack FromMatrices(IList <Single> times, IEnumerable <Matrix4> transforms)
        {
            var track = new KeyframeTrack();

            var translations = transforms.Select(m => m.ExtractTranslation()).ToList();
            var rotations    = transforms.Select(m => m.ExtractRotation()).ToList();
            var scales       = transforms.Select(m => m.ExtractScale()).ToList();

            // Quaternion sign fixup
            // The same rotation can be represented by both q and -q. However the Slerp path
            // will be different; one will go the long away around, the other the short away around.
            // Replace quaterions to ensure that Slerp will take the short path.
            float flip = 1.0f;

            for (var i = 0; i < rotations.Count - 1; i++)
            {
                var r0  = rotations[i];
                var r1  = rotations[i + 1];
                var dot = QuatHelpers.Dot(r0, r1 * flip);

                if (dot < 0.0f)
                {
                    flip = -flip;
                }

                rotations[i + 1] *= flip;
            }

            for (var i = 0; i < times.Count; i++)
            {
                track.AddTranslation(times[i], translations[i]);
                track.AddRotation(times[i], rotations[i]);
                var scaleShear = new Matrix3(
                    scales[i][0], 0.0f, 0.0f,
                    0.0f, scales[i][1], 0.0f,
                    0.0f, 0.0f, scales[i][2]
                    );
                track.AddScaleShear(times[i], scaleShear);
            }

            return(track);
        }
예제 #2
0
        public static KeyframeTrack FromMatrices(IList <Single> times, IEnumerable <Matrix4> transforms)
        {
            var track = new KeyframeTrack();

            var translations = transforms.Select(m => m.ExtractTranslation()).ToList();
            var rotations    = transforms.Select(m => m.ExtractRotation()).ToList();
            var scales       = transforms.Select(m => m.ExtractScale()).ToList();

            // Quaternion sign fixup
            // The same rotation can be represented by both q and -q. However the Slerp path
            // will be different; one will go the long away around, the other the short away around.
            // Replace quaterions to ensure that Slerp will take the short path.
            for (var i = 1; i < rotations.Count; i++)
            {
                var r0  = rotations[i - 1];
                var r1  = rotations[i];
                var dot = Vector3.Dot(r0.Xyz, r1.Xyz);
                var ang = Math.Acos(dot);
                if (dot < -0.0001f)
                {
                    rotations[i] = new Quaternion(-r1.X, -r1.Y, -r1.Z, -r1.W);
                }
            }

            for (var i = 0; i < times.Count; i++)
            {
                track.AddTranslation(times[i], translations[i]);
                track.AddRotation(times[i], rotations[i]);
                var scaleShear = new Matrix3(
                    scales[i][0], 0.0f, 0.0f,
                    0.0f, scales[i][1], 0.0f,
                    0.0f, 0.0f, scales[i][2]
                    );
                track.AddScaleShear(times[i], scaleShear);
            }

            return(track);
        }