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.
This commit is contained in:
parent
e158fbf934
commit
89b3dcaf82
|
@ -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 */
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue