diff options
author | Campbell Barton <ideasman42@gmail.com> | 2014-04-28 23:31:50 +0400 |
---|---|---|
committer | Campbell Barton <ideasman42@gmail.com> | 2014-04-28 23:40:46 +0400 |
commit | 89b3dcaf822bf750b87f5e48c8498dd2d6e1515b (patch) | |
tree | 5bf111735f194888198620bc266d1fd278f67d34 | |
parent | e158fbf9349379e137a5cdb840c36dba170372d1 (diff) |
f-curve easing: Adjustments to Robert Penner elastic easing
Compensate for the clamped amplitude by blending the elastic effect.
Allows for a subtle elastic effect which wasn't possible before.
-rw-r--r-- | source/blender/blenkernel/intern/fcurve.c | 2 | ||||
-rw-r--r-- | source/blender/blenlib/intern/easing.c | 61 |
2 files changed, 52 insertions, 11 deletions
diff --git a/source/blender/blenkernel/intern/fcurve.c b/source/blender/blenkernel/intern/fcurve.c index 281b4f589e1..65b9d2159df 100644 --- a/source/blender/blenkernel/intern/fcurve.c +++ b/source/blender/blenkernel/intern/fcurve.c @@ -2083,7 +2083,7 @@ static float fcurve_eval_keyframes(FCurve *fcu, BezTriple *bezts, float evaltime const float change = bezt->vec[1][1] - prevbezt->vec[1][1]; const float duration = bezt->vec[1][0] - prevbezt->vec[1][0]; const float time = evaltime - prevbezt->vec[1][0]; - const float amplitude = prevbezt->amplitude + fabsf(change); /* see T39405 */ + const float amplitude = prevbezt->amplitude; const float period = prevbezt->period; /* value depends on interpolation mode */ diff --git a/source/blender/blenlib/intern/easing.c b/source/blender/blenlib/intern/easing.c index 7233a26cb4d..6b702fe85dc 100644 --- a/source/blender/blenlib/intern/easing.c +++ b/source/blender/blenlib/intern/easing.c @@ -38,6 +38,8 @@ #include "BLI_strict_flags.h" +/* blend if (amplitude < fabsf(change) */ +#define USE_ELASTIC_BLEND float BLI_easing_back_ease_in(float time, float begin, float change, float duration, float overshoot) { @@ -141,76 +143,115 @@ float BLI_easing_cubic_ease_in_out(float time, float begin, float change, float return change / 2 * (time * time * time + 2) + begin; } +#ifdef USE_ELASTIC_BLEND +/** + * When the amplitude is less then the change, we need to blend + * \a f when we're close to the crossing point (int time), else we get an ugly sharp falloff. + */ +static float elastic_blend(float time, float change, float amplitude, float period, float f) +{ + if (change) { + /* Looks like a magic number, + * but this is a part of the sine curve we need to blend from */ + const float t = fabsf(period) / (32 * (float)M_PI); + if (amplitude) { + f *= amplitude / fabsf(change); + } + else { + f = 0.0f; + } + + if (fabsf(time) < t) { + float l = fabsf(time) / t; + f = (f * l) + (1.0f - l); + } + } + + return f; +} +#endif + float BLI_easing_elastic_ease_in(float time, float begin, float change, float duration, float amplitude, float period) { float s; + float f = 1.0f; if (time == 0.0f) return begin; if ((time /= duration) == 1.0f) return begin + change; - + time -= 1.0f; if (!period) period = duration * 0.3f; - if (!amplitude || amplitude < fabsf(change)) { +#ifdef USE_ELASTIC_BLEND + f = elastic_blend(time, change, amplitude, period, f); +#endif amplitude = change; s = period / 4; } else s = period / (2 * (float)M_PI) * asinf(change / amplitude); - time -= 1.0f; - return -(amplitude * powf(2, 10 * time) * sinf((time * duration - s) * (2 * (float)M_PI) / period)) + begin; + return (-f * (amplitude * powf(2, 10 * time) * sinf((time * duration - s) * (2 * (float)M_PI) / period))) + begin; } float BLI_easing_elastic_ease_out(float time, float begin, float change, float duration, float amplitude, float period) { float s; + float f = 1.0f; if (time == 0.0f) return begin; if ((time /= duration) == 1.0f) return begin + change; + time = -time; if (!period) period = duration * 0.3f; if (!amplitude || amplitude < fabsf(change)) { +#ifdef USE_ELASTIC_BLEND + f = elastic_blend(time, change, amplitude, period, f); +#endif amplitude = change; s = period / 4; } else s = period / (2 * (float)M_PI) * asinf(change / amplitude); - time = -time; - return (amplitude * powf(2, 10 * time) * sinf((time * duration - s) * (2 * (float)M_PI) / period) + change + begin); + return (f * (amplitude * powf(2, 10 * time) * sinf((time * duration - s) * (2 * (float)M_PI) / period))) + change + begin; } float BLI_easing_elastic_ease_in_out(float time, float begin, float change, float duration, float amplitude, float period) { float s; + float f = 1.0f; if (time == 0.0f) return begin; if ((time /= duration / 2) == 2.0f) return begin + change; + time -= 1.0f; if (!period) period = duration * (0.3f * 1.5f); if (!amplitude || amplitude < fabsf(change)) { +#ifdef USE_ELASTIC_BLEND + f = elastic_blend(time, change, amplitude, period, f); +#endif amplitude = change; s = period / 4; } else s = period / (2 * (float)M_PI) * asinf(change / amplitude); - time -= 1.0f; - if (time < 0.0f) { - return -0.5f * (amplitude * powf(2, 10 * time) * sinf((time * duration - s) * (2 * (float)M_PI) / period)) + begin; + f *= -0.5f; + return (f * (amplitude * powf(2, 10 * time) * sinf((time * duration - s) * (2 * (float)M_PI) / period))) + begin; } else { time = -time; - return (0.5f * amplitude * powf(2, 10 * time) * sinf((time * duration - s) * (2 * (float)M_PI) / period)) + change + begin; + f *= 0.5f; + return (f * (amplitude * powf(2, 10 * time) * sinf((time * duration - s) * (2 * (float)M_PI) / period))) + change + begin; } } |