Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlexander Gavrilov <angavrilov@gmail.com>2017-11-01 21:34:30 +0300
committerAlexander Gavrilov <angavrilov@gmail.com>2017-11-01 21:57:39 +0300
commit8bdc391c5488228dfe9c9e995277d67558293f08 (patch)
treeee7296ec1348a36546357f62271c0324d86e0e0a /source/blender/blenkernel/intern/fcurve.c
parent88356a24422faf45d6355b449b3855e6904edf51 (diff)
Implement a new automatic handle algorithm to produce smooth F-Curves.
The legacy algorithm only considers two adjacent points when computing the bezier handles, which cannot produce satisfactory results. Animators are often forced to manually adjust all curves. The new approach instead solves a system of equations to trace a cubic spline with continuous second derivative through the whole segment of auto points, delimited at ends by keyframes with handles set by other requirements. This algorithm also adjusts Vector handles that face ordinary bezier keyframes to achieve zero acceleration at the Vector keyframe, instead of simply pointing it at the adjacent point. Original idea and implementation by Benoit Bolsee <benoit.bolsee@online.be>; code mostly rewritten to improve code clarity and extensibility. Reviewers: aligorith Differential Revision: https://developer.blender.org/D2884
Diffstat (limited to 'source/blender/blenkernel/intern/fcurve.c')
-rw-r--r--source/blender/blenkernel/intern/fcurve.c21
1 files changed, 20 insertions, 1 deletions
diff --git a/source/blender/blenkernel/intern/fcurve.c b/source/blender/blenkernel/intern/fcurve.c
index c9f1f288182..382b26abbc6 100644
--- a/source/blender/blenkernel/intern/fcurve.c
+++ b/source/blender/blenkernel/intern/fcurve.c
@@ -956,7 +956,7 @@ void calchandles_fcurve(FCurve *fcu)
if (bezt->vec[2][0] < bezt->vec[1][0]) bezt->vec[2][0] = bezt->vec[1][0];
/* calculate auto-handles */
- BKE_nurb_handle_calc(bezt, prev, next, true);
+ BKE_nurb_handle_calc(bezt, prev, next, true, fcu->auto_smoothing);
/* for automatic ease in and out */
if (BEZT_IS_AUTOH(bezt) && !cycle) {
@@ -965,9 +965,16 @@ void calchandles_fcurve(FCurve *fcu)
/* set both handles to have same horizontal value as keyframe */
if (fcu->extend == FCURVE_EXTRAPOLATE_CONSTANT) {
bezt->vec[0][1] = bezt->vec[2][1] = bezt->vec[1][1];
+ /* remember that these keyframes are special, they don't need to be adjusted */
+ bezt->f5 = HD_AUTOTYPE_SPECIAL;
}
}
}
+
+ /* avoid total smoothing failure on duplicate keyframes (can happen during grab) */
+ if (prev && prev->vec[1][0] >= bezt->vec[1][0]) {
+ prev->f5 = bezt->f5 = HD_AUTOTYPE_SPECIAL;
+ }
/* advance pointers for next iteration */
prev = bezt;
@@ -981,6 +988,18 @@ void calchandles_fcurve(FCurve *fcu)
bezt++;
}
+
+ /* if cyclic extrapolation and Auto Clamp has triggered, ensure it is symmetric */
+ if (cycle && (first->f5 != HD_AUTOTYPE_NORMAL || last->f5 != HD_AUTOTYPE_NORMAL)) {
+ first->vec[0][1] = first->vec[2][1] = first->vec[1][1];
+ last->vec[0][1] = last->vec[2][1] = last->vec[1][1];
+ first->f5 = last->f5 = HD_AUTOTYPE_SPECIAL;
+ }
+
+ /* do a second pass for auto handle: compute the handle to have 0 accelaration step */
+ if (fcu->auto_smoothing != FCURVE_SMOOTH_NONE) {
+ BKE_nurb_handle_smooth_fcurve(fcu->bezt, fcu->totvert, cycle);
+ }
}
void testhandles_fcurve(FCurve *fcu, const bool use_handle)