public KeyframeTrack ToKeyframes()
        {
            var track = new KeyframeTrack();

            OrientationCurve.CurveData.ExportKeyframes(track, AnimationCurveData.ExportType.Rotation);
            PositionCurve.CurveData.ExportKeyframes(track, AnimationCurveData.ExportType.Position);
            ScaleShearCurve.CurveData.ExportKeyframes(track, AnimationCurveData.ExportType.ScaleShear);

            return(track);
        }
        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);
        }
Exemple #3
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);
        }
        public static TransformTrack FromKeyframes(KeyframeTrack keyframes)
        {
            var track = new TransformTrack();

            track.Flags = 0;

            var translateTimes = keyframes.Keyframes.Where(f => f.Value.HasTranslation).Select(f => f.Key).ToList();
            var translations   = keyframes.Keyframes.Where(f => f.Value.HasTranslation).Select(f => f.Value.Translation).ToList();

            if (translateTimes.Count == 1)
            {
                var posCurve = new D3Constant32f();
                posCurve.CurveDataHeader_D3Constant32f = new CurveDataHeader {
                    Format = (int)CurveFormat.D3Constant32f, Degree = 2
                };
                posCurve.Controls = new float[3] {
                    translations[0].X, translations[0].Y, translations[0].Z
                };
                track.PositionCurve = new AnimationCurve {
                    CurveData = posCurve
                };
            }
            else
            {
                var posCurve = new DaK32fC32f();
                posCurve.CurveDataHeader_DaK32fC32f = new CurveDataHeader {
                    Format = (int)CurveFormat.DaK32fC32f, Degree = 2
                };
                posCurve.SetKnots(translateTimes);
                posCurve.SetPoints(translations);
                track.PositionCurve = new AnimationCurve {
                    CurveData = posCurve
                };
            }

            var rotationTimes = keyframes.Keyframes.Where(f => f.Value.HasRotation).Select(f => f.Key).ToList();
            var rotations     = keyframes.Keyframes.Where(f => f.Value.HasRotation).Select(f => f.Value.Rotation).ToList();

            if (rotationTimes.Count == 1)
            {
                var rotCurve = new D4Constant32f();
                rotCurve.CurveDataHeader_D4Constant32f = new CurveDataHeader {
                    Format = (int)CurveFormat.D4Constant32f, Degree = 2
                };
                rotCurve.Controls = new float[4] {
                    rotations[0].X, rotations[0].Y, rotations[0].Z, rotations[0].W
                };
                track.OrientationCurve = new AnimationCurve {
                    CurveData = rotCurve
                };
            }
            else
            {
                var rotCurve = new DaK32fC32f();
                rotCurve.CurveDataHeader_DaK32fC32f = new CurveDataHeader {
                    Format = (int)CurveFormat.DaK32fC32f, Degree = 2
                };
                rotCurve.SetKnots(rotationTimes);
                rotCurve.SetQuaternions(rotations);
                track.OrientationCurve = new AnimationCurve {
                    CurveData = rotCurve
                };
            }

            var scaleTimes = keyframes.Keyframes.Where(f => f.Value.HasScaleShear).Select(f => f.Key).ToList();
            var scales     = keyframes.Keyframes.Where(f => f.Value.HasScaleShear).Select(f => f.Value.ScaleShear).ToList();

            if (scaleTimes.Count == 1)
            {
                var scaleCurve = new DaConstant32f();
                scaleCurve.CurveDataHeader_DaConstant32f = new CurveDataHeader {
                    Format = (int)CurveFormat.DaConstant32f, Degree = 2
                };
                var m = scales[0];
                scaleCurve.Controls = new List <float>
                {
                    m[0, 0], m[0, 1], m[0, 2],
                    m[1, 0], m[1, 1], m[1, 2],
                    m[2, 0], m[2, 1], m[2, 2]
                };
                track.ScaleShearCurve = new AnimationCurve {
                    CurveData = scaleCurve
                };
            }
            else
            {
                var scaleCurve = new DaK32fC32f();
                scaleCurve.CurveDataHeader_DaK32fC32f = new CurveDataHeader {
                    Format = (int)CurveFormat.DaK32fC32f, Degree = 2
                };
                scaleCurve.SetKnots(scaleTimes);
                scaleCurve.SetMatrices(scales);
                track.ScaleShearCurve = new AnimationCurve {
                    CurveData = scaleCurve
                };
            }

            return(track);
        }