There has already been discussion of this in this thread, but now that I have 10 posts and can use links according to rules I thought it’s better to create a new thread to avoid confusion with the addon.
It’s quite obvious that automatic handles for bezier curves in blender leave much to be desired, so as a start I picked up an old patch by Benoit Bolsee that improves F-Curve smoothing, and mostly rewrote the code to clean it up and add more features.
Since I’m not an animator, I need feedback to evaluate the design and address concerns about breaking backward compatibility: are there cases where it would break old animations or workflows, how significant is the improvement and so on.
Test build:
Although this change is proposed for 2.8, I upload a build based on master (i.e. compatible with upcoming 2.79) to GraphicAll (Windows / Linux) for ease of testing.
The Cyclic Extrapolation related feature is always applied to the curves (although it will only actually update when the curve is modified). However the new handle smoothing mode needs to be enabled for every F-Curve imported from previous versions. The Smoothed Auto Handles setting is located below the curve color selection box. Curves created in this build get it enabled by default. The option supports Copy To Selected and Alt-click to set it on all selected curves.
Key technical ideas:
- Instead of considering only the two neighboring points when computing auto handles, motion is interpolated by tracing cubic splines with continuous velocity and acceleration through the whole stretch of adjacent Auto key points.
A very good property of this approach is that adding redundant keys (keyframing interpolated object position without changing it), doesn’t change the curve at all, unless other factors like Auto Clamp intervene.
- The intent of Auto Clamp can probably be summarized as: the curve only changes direction at keyframes. To achieve this it has to apply constraints to the position of handles. An obvious one is that handles at extremes must be horizontal.
A less obvious constraint is that handles cannot overshoot neighboring key points, because that causes the curve to change direction in an S-like shape between keys and even overshoot the extreme like that.
- Vector handles that point at a non-Vector handle are also handled by the algorithm, so instead of pointing directly at the neighboring key, they are modified to achieve zero acceleration curve in the vicinity of the Vector key.
- When Cyclic Extrapolation is applied to the curve, and the first and last keyframes are automatic, the curve is smoothed across the cycle boundary so that the loop is as seamless as possible.
Since cyclic extrapolation is implemented as an f-curve modifier, which normally are supposed to run after handles are already determined, this is something of a hack code-wise, and the F-Curve smoothing code only accomodates the simplest confuguration of the modifier options. Enabling any limits on the number of loop iterations, range of the modifier, or its intensity, disables the new cyclic behavior.
Known limitations and bugs:
- In order to simplify the generic 2D bezier spline used for F-Curves by Blender to a 1D cubic with meaningful and easily computed velocity and acceleration, the handles are always placed at the 1/3 and 2/3 points between keyframes in the time dimension.
Fortunately, a surprisingly simple addition to the border condition equations allows computing a smooth curve even when it ends at manually modified handles with arbitrary X positions (unless they overshoot the adjacent keys - can’t really get a really smooth curve with that). However this is one of the aforementioned cases where inserting new keyframes in the interval between the manual and its nearest automatic key will change the curve.
- Auto Clamp constraints are applied using a heuristic approach not based on any known and mathematically proven way of solving optimization with constraints problems. Thus potentially it might arrive at suboptimal solutions in difficult cases, which normally manifests itself as abrupt significant jumps in handle positions triggered by tiny changes in some point positions.
- The code might (but obviously shouldn’t) act weirdly in complex cases like different types of handles on the two sides of one key point, or when Cyclic Extrapolation is used on a curve that has different handle types on the first and last keyframes.