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); }
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); }