diff options
author | Philipp Oeser <info@graphics-engineer.com> | 2020-03-27 11:54:43 +0300 |
---|---|---|
committer | Philipp Oeser <info@graphics-engineer.com> | 2020-03-27 11:58:21 +0300 |
commit | d0b0a0a894e0a8c030128e62cab1b8169d344bf2 (patch) | |
tree | a62a1b2babdd67de1618549b13bf2c130c8f556c /source/blender/editors/animation | |
parent | 6eb1004d50b8b80c67fd867efae8c3a66f5f0cec (diff) |
Fix T74927: Slow playback using Auto Normalization
Caused by rBedb3b7a323a1.
Using evaluate_fcurve_only_curve actually causes quite a bit of slowdown
[6x] compared to bezier forward differencing [which was used prior to
rBedb3b7a323a1]. But full fcurve evaluation is desired with Dynamic
Interpolation Effects [Back/Elastic] since their min/max will not be
captured with forward differencing.
So now gain back speed [using bezier forward differencing] and only do
the full fcurve evaluation for dynamic interpolation effects.
Maniphest Tasks: T74927
Differential Revision: https://developer.blender.org/D7196
Diffstat (limited to 'source/blender/editors/animation')
-rw-r--r-- | source/blender/editors/animation/anim_draw.c | 45 |
1 files changed, 39 insertions, 6 deletions
diff --git a/source/blender/editors/animation/anim_draw.c b/source/blender/editors/animation/anim_draw.c index bcb9ddc5889..96fd2e94a5e 100644 --- a/source/blender/editors/animation/anim_draw.c +++ b/source/blender/editors/animation/anim_draw.c @@ -441,12 +441,45 @@ static float normalization_factor_get(Scene *scene, FCurve *fcu, short flag, flo min_coord = min_ff(min_coord, prev_bezt->vec[1][1]); } else { - float step_size = (bezt->vec[1][0] - prev_bezt->vec[1][0]) / resol; - for (int j = 0; j <= resol; j++) { - float eval_time = prev_bezt->vec[1][0] + step_size * j; - float eval_value = evaluate_fcurve_only_curve(fcu, eval_time); - max_coord = max_ff(max_coord, eval_value); - min_coord = min_ff(min_coord, eval_value); + if (!ELEM(prev_bezt->ipo, BEZT_IPO_BACK, BEZT_IPO_ELASTIC)) { + /* Calculate min/max using bezier forward differencing. */ + float data[120]; + float v1[2], v2[2], v3[2], v4[2]; + + v1[0] = prev_bezt->vec[1][0]; + v1[1] = prev_bezt->vec[1][1]; + v2[0] = prev_bezt->vec[2][0]; + v2[1] = prev_bezt->vec[2][1]; + + v3[0] = bezt->vec[0][0]; + v3[1] = bezt->vec[0][1]; + v4[0] = bezt->vec[1][0]; + v4[1] = bezt->vec[1][1]; + + correct_bezpart(v1, v2, v3, v4); + + BKE_curve_forward_diff_bezier( + v1[0], v2[0], v3[0], v4[0], data, resol, sizeof(float) * 3); + BKE_curve_forward_diff_bezier( + v1[1], v2[1], v3[1], v4[1], data + 1, resol, sizeof(float) * 3); + + for (int j = 0; j <= resol; ++j) { + const float *fp = &data[j * 3]; + max_coord = max_ff(max_coord, fp[1]); + min_coord = min_ff(min_coord, fp[1]); + } + } + else { + /* Calculate min/max using full fcurve evaluation. + * [slower than bezier forward differencing but evaluates Back/Elastic interpolation + * as well].*/ + float step_size = (bezt->vec[1][0] - prev_bezt->vec[1][0]) / resol; + for (int j = 0; j <= resol; j++) { + float eval_time = prev_bezt->vec[1][0] + step_size * j; + float eval_value = evaluate_fcurve_only_curve(fcu, eval_time); + max_coord = max_ff(max_coord, eval_value); + min_coord = min_ff(min_coord, eval_value); + } } } } |