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