2014-03-22 02:50:24 +13:00
|
|
|
/*
|
|
|
|
* Copyright © 2001 Robert Penner
|
|
|
|
* All rights reserved.
|
|
|
|
*
|
|
|
|
* Redistribution and use in source and binary forms, with or without
|
|
|
|
* modification, are permitted provided that the following conditions are met:
|
|
|
|
*
|
|
|
|
* * Redistributions of source code must retain the above copyright
|
|
|
|
* notice, this list of conditions and the following disclaimer.
|
|
|
|
*
|
|
|
|
* * Redistributions in binary form must reproduce the above copyright
|
|
|
|
* notice, this list of conditions and the following disclaimer in the
|
|
|
|
* documentation and/or other materials provided with the distribution.
|
|
|
|
*
|
|
|
|
* * Neither the name of the author nor the names of contributors may be
|
|
|
|
* used to endorse or promote products derived from this software without
|
|
|
|
* specific prior written permission.
|
|
|
|
*
|
|
|
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
|
|
|
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
|
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
|
|
|
* ARE DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
|
|
|
|
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
|
|
|
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
|
|
|
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
|
|
|
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
|
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
|
|
|
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
|
|
*/
|
|
|
|
|
2014-03-25 08:00:51 +11:00
|
|
|
/** \file blender/blenlib/intern/easing.c
|
2014-03-22 02:50:24 +13:00
|
|
|
* \ingroup bli
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include <math.h>
|
|
|
|
|
2014-03-25 08:00:51 +11:00
|
|
|
#include "BLI_math_base.h"
|
|
|
|
|
|
|
|
#include "BLI_easing.h" /* own include */
|
|
|
|
|
|
|
|
#include "BLI_strict_flags.h"
|
2014-03-22 02:50:24 +13:00
|
|
|
|
|
|
|
|
|
|
|
float BackEaseIn(float time, float begin, float change, float duration, float overshoot)
|
|
|
|
{
|
2014-03-24 13:31:14 +11:00
|
|
|
if (overshoot == 0.0f)
|
2014-03-22 02:50:24 +13:00
|
|
|
overshoot = 1.70158f;
|
|
|
|
time /= duration;
|
|
|
|
return change * time * time * ((overshoot + 1) * time - overshoot) + begin;
|
|
|
|
}
|
|
|
|
|
|
|
|
float BackEaseOut(float time, float begin, float change, float duration, float overshoot)
|
|
|
|
{
|
2014-03-24 13:31:14 +11:00
|
|
|
if (overshoot == 0.0f)
|
2014-03-22 02:50:24 +13:00
|
|
|
overshoot = 1.70158f;
|
|
|
|
time = time / duration - 1;
|
|
|
|
return change * (time * time * ((overshoot + 1) * time + overshoot) + 1) + begin;
|
|
|
|
}
|
|
|
|
|
|
|
|
float BackEaseInOut(float time, float begin, float change, float duration, float overshoot)
|
|
|
|
{
|
2014-03-24 13:31:14 +11:00
|
|
|
if (overshoot == 0.0f)
|
2014-03-22 02:50:24 +13:00
|
|
|
overshoot = 1.70158f;
|
|
|
|
overshoot *= 1.525f;
|
2014-03-24 13:31:14 +11:00
|
|
|
if ((time /= duration / 2) < 1.0f) {
|
2014-03-22 02:50:24 +13:00
|
|
|
return change / 2 * (time * time * ((overshoot + 1) * time - overshoot)) + begin;
|
|
|
|
}
|
2014-03-24 13:31:14 +11:00
|
|
|
time -= 2.0f;
|
2014-03-22 02:50:24 +13:00
|
|
|
return change / 2 * (time * time * ((overshoot + 1) * time + overshoot) + 2) + begin;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
float BounceEaseOut(float time, float begin, float change, float duration)
|
|
|
|
{
|
|
|
|
time /= duration;
|
|
|
|
if (time < (1 / 2.75f)) {
|
|
|
|
return change * (7.5625f * time * time) + begin;
|
|
|
|
}
|
|
|
|
else if (time < (2 / 2.75f)) {
|
|
|
|
time -= (1.5f / 2.75f);
|
|
|
|
return change * ((7.5625f * time) * time + 0.75f) + begin;
|
|
|
|
}
|
|
|
|
else if (time < (2.5f / 2.75f)) {
|
|
|
|
time -= (2.25f / 2.75f);
|
|
|
|
return change * ((7.5625f * time) * time + 0.9375f) + begin;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
time -= (2.625f / 2.75f);
|
2014-03-24 13:31:14 +11:00
|
|
|
return change * ((7.5625f * time) * time + 0.984375f) + begin;
|
2014-03-22 02:50:24 +13:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
float BounceEaseIn(float time, float begin, float change, float duration)
|
|
|
|
{
|
|
|
|
return change - BounceEaseOut(duration - time, 0, change, duration) + begin;
|
|
|
|
}
|
|
|
|
|
|
|
|
float BounceEaseInOut(float time, float begin, float change, float duration)
|
|
|
|
{
|
|
|
|
if (time < duration / 2)
|
|
|
|
return BounceEaseIn(time * 2, 0, change, duration) * 0.5f + begin;
|
|
|
|
else
|
|
|
|
return BounceEaseOut(time * 2 - duration, 0, change, duration) * 0.5f + change * 0.5f + begin;
|
|
|
|
}
|
|
|
|
|
|
|
|
float CircEaseIn(float time, float begin, float change, float duration)
|
|
|
|
{
|
|
|
|
time /= duration;
|
2014-03-24 13:31:14 +11:00
|
|
|
return -change * (sqrtf(1 - time * time) - 1) + begin;
|
2014-03-22 02:50:24 +13:00
|
|
|
}
|
|
|
|
|
|
|
|
float CircEaseOut(float time, float begin, float change, float duration)
|
|
|
|
{
|
|
|
|
time = time / duration - 1;
|
2014-03-24 13:31:14 +11:00
|
|
|
return change * sqrtf(1 - time * time) + begin;
|
2014-03-22 02:50:24 +13:00
|
|
|
}
|
|
|
|
|
|
|
|
float CircEaseInOut(float time, float begin, float change, float duration)
|
|
|
|
{
|
2014-03-24 13:31:14 +11:00
|
|
|
if ((time /= duration / 2) < 1.0f)
|
|
|
|
return -change / 2 * (sqrtf(1 - time * time) - 1) + begin;
|
|
|
|
time -= 2.0f;
|
|
|
|
return change / 2 * (sqrtf(1 - time * time) + 1) + begin;
|
2014-03-22 02:50:24 +13:00
|
|
|
}
|
|
|
|
|
|
|
|
float CubicEaseIn(float time, float begin, float change, float duration)
|
|
|
|
{
|
|
|
|
time /= duration;
|
|
|
|
return change * time * time * time + begin;
|
|
|
|
}
|
|
|
|
|
|
|
|
float CubicEaseOut(float time, float begin, float change, float duration)
|
|
|
|
{
|
|
|
|
time = time / duration - 1;
|
|
|
|
return change * (time * time * time + 1) + begin;
|
|
|
|
}
|
|
|
|
|
|
|
|
float CubicEaseInOut(float time, float begin, float change, float duration)
|
|
|
|
{
|
2014-03-24 13:31:14 +11:00
|
|
|
if ((time /= duration / 2) < 1.0f)
|
2014-03-22 02:50:24 +13:00
|
|
|
return change / 2 * time * time * time + begin;
|
2014-03-24 13:31:14 +11:00
|
|
|
time -= 2.0f;
|
2014-03-22 02:50:24 +13:00
|
|
|
return change / 2 * (time * time * time + 2) + begin;
|
|
|
|
}
|
|
|
|
|
|
|
|
float ElasticEaseIn(float time, float begin, float change, float duration, float amplitude, float period)
|
|
|
|
{
|
|
|
|
float s;
|
|
|
|
|
2014-03-24 13:31:14 +11:00
|
|
|
if (time == 0.0f)
|
2014-03-22 02:50:24 +13:00
|
|
|
return begin;
|
|
|
|
|
2014-03-24 13:31:14 +11:00
|
|
|
if ((time /= duration) == 1.0f)
|
2014-03-22 02:50:24 +13:00
|
|
|
return begin + change;
|
|
|
|
|
|
|
|
if (!period)
|
|
|
|
period = duration * 0.3f;
|
|
|
|
|
2014-03-24 12:57:18 +11:00
|
|
|
if (!amplitude || amplitude < fabsf(change)) {
|
2014-03-22 02:50:24 +13:00
|
|
|
amplitude = change;
|
|
|
|
s = period / 4;
|
|
|
|
}
|
|
|
|
else
|
2014-03-24 13:31:14 +11:00
|
|
|
s = period / (2 * (float)M_PI) * asinf(change / amplitude);
|
2014-03-22 02:50:24 +13:00
|
|
|
|
2014-03-24 13:31:14 +11:00
|
|
|
time -= 1.0f;
|
|
|
|
return -(amplitude * powf(2, 10 * time) * sinf((time * duration - s) * (2 * (float)M_PI) / period)) + begin;
|
2014-03-22 02:50:24 +13:00
|
|
|
}
|
|
|
|
|
|
|
|
float ElasticEaseOut(float time, float begin, float change, float duration, float amplitude, float period)
|
|
|
|
{
|
|
|
|
float s;
|
|
|
|
|
2014-03-24 13:31:14 +11:00
|
|
|
if (time == 0.0f)
|
2014-03-22 02:50:24 +13:00
|
|
|
return begin;
|
2014-03-24 13:31:14 +11:00
|
|
|
if ((time /= duration) == 1.0f)
|
2014-03-22 02:50:24 +13:00
|
|
|
return begin + change;
|
|
|
|
if (!period)
|
|
|
|
period = duration * 0.3f;
|
2014-03-24 12:57:18 +11:00
|
|
|
if (!amplitude || amplitude < fabsf(change)) {
|
2014-03-22 02:50:24 +13:00
|
|
|
amplitude = change;
|
|
|
|
s = period / 4;
|
|
|
|
}
|
|
|
|
else
|
2014-03-24 13:31:14 +11:00
|
|
|
s = period / (2 * (float)M_PI) * asinf(change / amplitude);
|
2014-03-22 02:50:24 +13:00
|
|
|
|
2014-03-24 13:31:14 +11:00
|
|
|
return (amplitude * powf(2, -10 * time) * sinf((time * duration - s) * (2 * (float)M_PI) / period) + change + begin);
|
2014-03-22 02:50:24 +13:00
|
|
|
}
|
|
|
|
|
|
|
|
float ElasticEaseInOut(float time, float begin, float change, float duration, float amplitude, float period)
|
|
|
|
{
|
|
|
|
float s;
|
|
|
|
|
2014-03-24 13:31:14 +11:00
|
|
|
if (time == 0.0f)
|
2014-03-22 02:50:24 +13:00
|
|
|
return begin;
|
2014-03-24 13:31:14 +11:00
|
|
|
if ((time /= duration / 2) == 2.0f)
|
2014-03-22 02:50:24 +13:00
|
|
|
return begin + change;
|
|
|
|
if (!period)
|
|
|
|
period = duration * (0.3f * 1.5f);
|
2014-03-24 12:57:18 +11:00
|
|
|
if (!amplitude || amplitude < fabsf(change)) {
|
2014-03-22 02:50:24 +13:00
|
|
|
amplitude = change;
|
|
|
|
s = period / 4;
|
|
|
|
}
|
|
|
|
else
|
2014-03-24 13:31:14 +11:00
|
|
|
s = period / (2 * (float)M_PI) * asinf(change / amplitude);
|
|
|
|
if (time < 1.0f) {
|
|
|
|
time -= 1.0f;
|
|
|
|
return -0.5f * (amplitude * powf(2, 10 * time) * sinf((time * duration - s) * (2 * (float)M_PI) / period)) + begin;
|
2014-03-22 02:50:24 +13:00
|
|
|
}
|
|
|
|
|
2014-03-24 13:31:14 +11:00
|
|
|
time -= 1.0f;
|
|
|
|
return amplitude * powf(2, -10 * time) * sinf((time * duration - s) * (2 * (float)M_PI) / period) * 0.5f + change + begin;
|
2014-03-22 02:50:24 +13:00
|
|
|
}
|
|
|
|
|
|
|
|
float ExpoEaseIn(float time, float begin, float change, float duration)
|
|
|
|
{
|
2014-03-24 13:31:14 +11:00
|
|
|
return (time == 0.0f) ? begin : change * powf(2, 10 * (time / duration - 1)) + begin;
|
2014-03-22 02:50:24 +13:00
|
|
|
}
|
|
|
|
|
|
|
|
float ExpoEaseOut(float time, float begin, float change, float duration)
|
|
|
|
{
|
2014-03-24 13:31:14 +11:00
|
|
|
return (time == duration) ? begin + change : change * (-powf(2, -10 * time / duration) + 1) + begin;
|
2014-03-22 02:50:24 +13:00
|
|
|
}
|
|
|
|
|
|
|
|
float ExpoEaseInOut(float time, float begin, float change, float duration)
|
|
|
|
{
|
2014-03-24 13:31:14 +11:00
|
|
|
if (time == 0.0f)
|
2014-03-22 02:50:24 +13:00
|
|
|
return begin;
|
|
|
|
if (time == duration)
|
|
|
|
return begin + change;
|
|
|
|
if ((time /= duration / 2) < 1)
|
2014-03-24 13:31:14 +11:00
|
|
|
return change / 2 * powf(2, 10 * (time - 1)) + begin;
|
|
|
|
time -= 1.0f;
|
|
|
|
return change / 2 * (-powf(2, -10 * time) + 2) + begin;
|
2014-03-22 02:50:24 +13:00
|
|
|
}
|
|
|
|
|
|
|
|
float LinearEase(float time, float begin, float change, float duration)
|
|
|
|
{
|
|
|
|
return change * time / duration + begin;
|
|
|
|
}
|
|
|
|
|
|
|
|
float QuadEaseIn(float time, float begin, float change, float duration)
|
|
|
|
{
|
|
|
|
time /= duration;
|
|
|
|
return change * time * time + begin;
|
|
|
|
}
|
|
|
|
|
|
|
|
float QuadEaseOut(float time, float begin, float change, float duration)
|
|
|
|
{
|
|
|
|
time /= duration;
|
|
|
|
return -change * time * (time - 2) + begin;
|
|
|
|
}
|
|
|
|
|
|
|
|
float QuadEaseInOut(float time, float begin, float change, float duration)
|
|
|
|
{
|
2014-03-24 13:31:14 +11:00
|
|
|
if ((time /= duration / 2) < 1.0f)
|
2014-03-22 02:50:24 +13:00
|
|
|
return change / 2 * time * time + begin;
|
2014-03-24 13:31:14 +11:00
|
|
|
time -= 1.0f;
|
2014-03-22 02:50:24 +13:00
|
|
|
return -change / 2 * (time * (time - 2) - 1) + begin;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
float QuartEaseIn(float time, float begin, float change, float duration)
|
|
|
|
{
|
|
|
|
time /= duration;
|
|
|
|
return change * time * time * time * time + begin;
|
|
|
|
}
|
|
|
|
|
|
|
|
float QuartEaseOut(float time, float begin, float change, float duration)
|
|
|
|
{
|
|
|
|
time = time / duration - 1;
|
|
|
|
return -change * (time * time * time * time - 1) + begin;
|
|
|
|
}
|
|
|
|
|
|
|
|
float QuartEaseInOut(float time, float begin, float change, float duration)
|
|
|
|
{
|
2014-03-24 13:31:14 +11:00
|
|
|
if ((time /= duration / 2) < 1.0f)
|
2014-03-22 02:50:24 +13:00
|
|
|
return change / 2 * time * time * time * time + begin;
|
2014-03-24 13:31:14 +11:00
|
|
|
time -= 2.0f;
|
2014-03-24 12:59:36 +11:00
|
|
|
return -change / 2 * ( time * time * time * time - 2) + begin;
|
2014-03-22 02:50:24 +13:00
|
|
|
}
|
|
|
|
|
|
|
|
float QuintEaseIn(float time, float begin, float change, float duration)
|
|
|
|
{
|
|
|
|
time /= duration;
|
|
|
|
return change * time * time * time * time * time + begin;
|
|
|
|
}
|
|
|
|
float QuintEaseOut(float time, float begin, float change, float duration)
|
|
|
|
{
|
|
|
|
time = time / duration - 1;
|
|
|
|
return change * (time * time * time * time * time + 1) + begin;
|
|
|
|
}
|
|
|
|
float QuintEaseInOut(float time, float begin, float change, float duration)
|
|
|
|
{
|
2014-03-24 13:31:14 +11:00
|
|
|
if ((time /= duration / 2) < 1.0f)
|
2014-03-24 12:59:36 +11:00
|
|
|
return change / 2 * time * time * time * time * time + begin;
|
2014-03-24 13:31:14 +11:00
|
|
|
time -= 2.0f;
|
2014-03-22 02:50:24 +13:00
|
|
|
return change / 2 * (time * time * time * time * time + 2) + begin;
|
|
|
|
}
|
|
|
|
|
|
|
|
float SineEaseIn(float time, float begin, float change, float duration)
|
|
|
|
{
|
2014-03-24 13:31:14 +11:00
|
|
|
return -change * cosf(time / duration * (float)M_PI_2) + change + begin;
|
2014-03-22 02:50:24 +13:00
|
|
|
}
|
|
|
|
|
|
|
|
float SineEaseOut(float time, float begin, float change, float duration)
|
|
|
|
{
|
2014-03-24 13:31:14 +11:00
|
|
|
return change * sinf(time / duration * (float)M_PI_2) + begin;
|
2014-03-22 02:50:24 +13:00
|
|
|
}
|
|
|
|
|
|
|
|
float SineEaseInOut(float time, float begin, float change, float duration)
|
|
|
|
{
|
2014-03-24 13:31:14 +11:00
|
|
|
return -change / 2 * (cosf((float)M_PI * time / duration) - 1) + begin;
|
2014-03-22 02:50:24 +13:00
|
|
|
}
|