I am creating a custom animation editor that lets users modify the animation curves of various components. One component I am having trouble with is the rotation of an object. I allow the user to edit the rotation's euler components (actually just the z rotation since the editor is for 2D). When generating the final animation, I convert the euler animation curve to a set of four quaternion curves.
The problem is that the tangents of the euler curve do not seem to correspond to the quaternion.
Here is the animation curve for the z component of a curve:
If I calculate my quaternion curve by adding the keys the following way, the animation jumps around erratically (this example is adding the middle keyframe):
If I add the quaternion key without using the euler z curve's tangents, the animation interpolates smoothly, but doesn't follow the swings of the curve:
Obviously the tangents of the euler curve do not correspond with the tangents of the calculated quaternion curve.
My question is how do I create a quaternion animation curve based on the euler animation curve, with properly translated tangents?
The quaternion is a math representation of a single rotation of some angle around an arbitrary axis, where x, y and z are the normalized vector that defines the axis orientation multiplied by sin(angle/2) and w is cos(angle/2). Since sin(0) is zero, the axis orientation becomes critical for small angles, and the interpolation functions may produce incredibly wrong orientations at these points.
float angle = 0; Vector3 axis = Vector3.zero; // get the angle/axis equivalent of "rotation" rotation.ToAngleAxis(out angle, out axis); localRotationXKeyframes.Add(new Keyframe(time, axis.x)); localRotationYKeyframes.Add(new Keyframe(time, axis.y)); localRotationZKeyframes.Add(new Keyframe(time, axis.z)); localRotationWKeyframes.Add(new Keyframe(time, angle));
You will have to convert it back to quaternions using Quaternion.AngleAxis, of course.
EDITED Paying a little more attention to your animation curve, I noticed that it strongly depends on the mid-point tangent. As a rule of thumb, you should add points for each curvature inflection - the top and bottom points, in this case:
This avoids problems with the tangents, since they are always zero at these points.