diff options
author | Sybren A. Stüvel <sybren@blender.org> | 2020-05-01 15:44:16 +0300 |
---|---|---|
committer | Sybren A. Stüvel <sybren@blender.org> | 2020-05-01 16:38:45 +0300 |
commit | f651548c2e15f0e7f0ec9a7ab6b94c7e3cd08d1c (patch) | |
tree | 8bf22baac6f3891c7f720e03d19f97b10a61e97a /source/blender/blenkernel/intern/fcurve.c | |
parent | 75370684fa89103c097487d5cda8390ffb6cbc8e (diff) |
Cleanup: Animation, refactored FCurve extrapolation
Variables have been renamed so that they refer to the endpoint and its
neighbor (rather than `bezt`, `prevbezt`, or `lastbezt`), and
unnecessary variables have been removed. By returning early the code
flow is also easier to understand.
No functional changes.
Diffstat (limited to 'source/blender/blenkernel/intern/fcurve.c')
-rw-r--r-- | source/blender/blenkernel/intern/fcurve.c | 168 |
1 files changed, 64 insertions, 104 deletions
diff --git a/source/blender/blenkernel/intern/fcurve.c b/source/blender/blenkernel/intern/fcurve.c index 0ce5cce27dc..f49d1adb8cd 100644 --- a/source/blender/blenkernel/intern/fcurve.c +++ b/source/blender/blenkernel/intern/fcurve.c @@ -1417,130 +1417,90 @@ static void berekeny(float f1, float f2, float f3, float f4, float *o, int b) static float fcurve_eval_keyframes_before_first(FCurve *fcu, BezTriple *bezts, float evaltime) { - BezTriple *bezt, *prevbezt; - float dx, fac; - float cvalue = 0.0f; + BezTriple *endpoint_bezt = bezts; /* The first keyframe. */ + BezTriple *neighbor_bezt = endpoint_bezt + 1; /* The second keyframe. */ - /* get pointers */ - prevbezt = bezts; - bezt = prevbezt + 1; + if (endpoint_bezt->ipo == BEZT_IPO_CONST || fcu->extend == FCURVE_EXTRAPOLATE_CONSTANT || + (fcu->flag & FCURVE_DISCRETE_VALUES) != 0) { + /* Constant (BEZT_IPO_HORIZ) extrapolation or constant interpolation, so just extend first + * keyframe's value. */ + return endpoint_bezt->vec[1][1]; + } - /* before or on first keyframe */ - if ((fcu->extend == FCURVE_EXTRAPOLATE_LINEAR) && (prevbezt->ipo != BEZT_IPO_CONST) && - !(fcu->flag & FCURVE_DISCRETE_VALUES)) { - /* linear or bezier interpolation */ - if (prevbezt->ipo == BEZT_IPO_LIN) { - /* Use the next center point instead of our own handle for - * linear interpolated extrapolate - */ - if (fcu->totvert == 1) { - cvalue = prevbezt->vec[1][1]; - } - else { - bezt = prevbezt + 1; - dx = prevbezt->vec[1][0] - evaltime; - fac = bezt->vec[1][0] - prevbezt->vec[1][0]; - - /* prevent division by zero */ - if (fac) { - fac = (bezt->vec[1][1] - prevbezt->vec[1][1]) / fac; - cvalue = prevbezt->vec[1][1] - (fac * dx); - } - else { - cvalue = prevbezt->vec[1][1]; - } - } + if (endpoint_bezt->ipo == BEZT_IPO_LIN) { + /* Use the next center point instead of our own handle for linear interpolated extrapolate. */ + if (fcu->totvert == 1) { + return endpoint_bezt->vec[1][1]; } - else { - /* Use the first handle (earlier) of first BezTriple to calculate the - * gradient and thus the value of the curve at evaltime - */ - dx = prevbezt->vec[1][0] - evaltime; - fac = prevbezt->vec[1][0] - prevbezt->vec[0][0]; - /* prevent division by zero */ - if (fac) { - fac = (prevbezt->vec[1][1] - prevbezt->vec[0][1]) / fac; - cvalue = prevbezt->vec[1][1] - (fac * dx); - } - else { - cvalue = prevbezt->vec[1][1]; - } + float dx = endpoint_bezt->vec[1][0] - evaltime; + float fac = neighbor_bezt->vec[1][0] - endpoint_bezt->vec[1][0]; + + /* Prevent division by zero. */ + if (fac == 0.0f) { + return endpoint_bezt->vec[1][1]; } + + fac = (neighbor_bezt->vec[1][1] - endpoint_bezt->vec[1][1]) / fac; + return endpoint_bezt->vec[1][1] - (fac * dx); } - else { - /* constant (BEZT_IPO_HORIZ) extrapolation or constant interpolation, - * so just extend first keyframe's value - */ - cvalue = prevbezt->vec[1][1]; + + /* Use the first handle (earlier) of first BezTriple to calculate the gradient and thus the value + * of the curve at evaltime. */ + float dx = endpoint_bezt->vec[1][0] - evaltime; + float fac = endpoint_bezt->vec[1][0] - endpoint_bezt->vec[0][0]; + + /* Prevent division by zero. */ + if (fac == 0.0f) { + return endpoint_bezt->vec[1][1]; } - return cvalue; + fac = (endpoint_bezt->vec[1][1] - endpoint_bezt->vec[0][1]) / fac; + return endpoint_bezt->vec[1][1] - (fac * dx); } static float fcurve_eval_keyframes_after_last(FCurve *fcu, BezTriple *bezts, float evaltime) { - BezTriple *prevbezt, *lastbezt; - float dx, fac; - unsigned int a; - float cvalue = 0.0f; + BezTriple *endpoint_bezt = bezts + fcu->totvert - 1; /* The last keyframe. */ + BezTriple *neighbor_bezt = endpoint_bezt - 1; /* The second to last keyframe. */ - /* get pointers */ - a = fcu->totvert - 1; - prevbezt = bezts; - lastbezt = prevbezt + a; + if (endpoint_bezt->ipo == BEZT_IPO_CONST || fcu->extend == FCURVE_EXTRAPOLATE_CONSTANT || + (fcu->flag & FCURVE_DISCRETE_VALUES) != 0) { + /* Constant (BEZT_IPO_HORIZ) extrapolation or constant interpolation, so just extend last + * keyframe's value. */ + return endpoint_bezt->vec[1][1]; + } - /* after or on last keyframe */ - if ((fcu->extend == FCURVE_EXTRAPOLATE_LINEAR) && (lastbezt->ipo != BEZT_IPO_CONST) && - !(fcu->flag & FCURVE_DISCRETE_VALUES)) { - /* linear or bezier interpolation */ - if (lastbezt->ipo == BEZT_IPO_LIN) { - /* Use the next center point instead of our own handle for - * linear interpolated extrapolate - */ - if (fcu->totvert == 1) { - cvalue = lastbezt->vec[1][1]; - } - else { - prevbezt = lastbezt - 1; - dx = evaltime - lastbezt->vec[1][0]; - fac = lastbezt->vec[1][0] - prevbezt->vec[1][0]; - - /* prevent division by zero */ - if (fac) { - fac = (lastbezt->vec[1][1] - prevbezt->vec[1][1]) / fac; - cvalue = lastbezt->vec[1][1] + (fac * dx); - } - else { - cvalue = lastbezt->vec[1][1]; - } - } + if (endpoint_bezt->ipo == BEZT_IPO_LIN) { + /* Use the next center point instead of our own handle for linear interpolated extrapolate. */ + if (fcu->totvert == 1) { + return endpoint_bezt->vec[1][1]; } - else { - /* Use the gradient of the second handle (later) of last BezTriple to calculate the - * gradient and thus the value of the curve at evaltime - */ - dx = evaltime - lastbezt->vec[1][0]; - fac = lastbezt->vec[2][0] - lastbezt->vec[1][0]; - /* prevent division by zero */ - if (fac) { - fac = (lastbezt->vec[2][1] - lastbezt->vec[1][1]) / fac; - cvalue = lastbezt->vec[1][1] + (fac * dx); - } - else { - cvalue = lastbezt->vec[1][1]; - } + float dx = evaltime - endpoint_bezt->vec[1][0]; + float fac = endpoint_bezt->vec[1][0] - neighbor_bezt->vec[1][0]; + + /* Prevent division by zero. */ + if (fac == 0.0f) { + return endpoint_bezt->vec[1][1]; } + + fac = (endpoint_bezt->vec[1][1] - neighbor_bezt->vec[1][1]) / fac; + return endpoint_bezt->vec[1][1] + (fac * dx); } - else { - /* constant (BEZT_IPO_HORIZ) extrapolation or constant interpolation, - * so just extend last keyframe's value - */ - cvalue = lastbezt->vec[1][1]; + + /* Use the gradient of the second handle (later) of last BezTriple to calculate the gradient and + * thus the value of the curve at evaltime */ + float dx = evaltime - endpoint_bezt->vec[1][0]; + float fac = endpoint_bezt->vec[2][0] - endpoint_bezt->vec[1][0]; + + /* Prevent division by zero. */ + if (fac == 0.0f) { + return endpoint_bezt->vec[1][1]; } - return cvalue; + fac = (endpoint_bezt->vec[2][1] - endpoint_bezt->vec[1][1]) / fac; + return endpoint_bezt->vec[1][1] + (fac * dx); } /* Calculate F-Curve value for 'evaltime' using BezTriple keyframes */ |