2020-08-26 15:38:01 +08:00
|
|
|
#pragma once
|
2022-10-02 04:29:51 +08:00
|
|
|
#include <blah_common.h>
|
|
|
|
#include <blah_calc.h>
|
2020-08-26 15:38:01 +08:00
|
|
|
|
|
|
|
namespace Blah
|
|
|
|
{
|
|
|
|
using Easer = float (*)(float);
|
|
|
|
|
|
|
|
enum class Easers
|
|
|
|
{
|
2021-03-21 17:08:28 +08:00
|
|
|
Linear,
|
2022-02-13 04:19:53 +08:00
|
|
|
QuadIn, QuadOut, QuadInOut,
|
|
|
|
CubeIn, CubeOut, CubeInOut,
|
|
|
|
QuartIn, QuartOut, QuartInOut,
|
|
|
|
QuintIn, QuintOut, QuintInOut,
|
|
|
|
SineIn, SineOut, SineInOut,
|
|
|
|
CircIn, CircOut, CircInOut,
|
|
|
|
ExpIn, ExpOut, ExpInOut,
|
2020-08-26 15:38:01 +08:00
|
|
|
ElasticIn, ElasticOut, ElasticInOut,
|
2022-02-13 04:19:53 +08:00
|
|
|
BackIn, BackOut, BackInOut,
|
|
|
|
BounceIn, BounceOut, BounceInOut,
|
2021-05-07 12:48:06 +08:00
|
|
|
Count
|
2020-08-26 15:38:01 +08:00
|
|
|
};
|
|
|
|
|
|
|
|
namespace Ease
|
|
|
|
{
|
|
|
|
/*
|
|
|
|
Adapted from functions here: https://github.com/warrenm/AHEasing/blob/master/AHEasing/easing.c
|
|
|
|
For previews go here: https://easings.net/
|
|
|
|
*/
|
|
|
|
|
2021-03-21 17:08:28 +08:00
|
|
|
constexpr float linear(float t)
|
2020-08-26 15:38:01 +08:00
|
|
|
{
|
|
|
|
return t;
|
|
|
|
}
|
|
|
|
|
2021-03-21 17:08:28 +08:00
|
|
|
constexpr float quad_in(float t)
|
2020-08-26 15:38:01 +08:00
|
|
|
{
|
|
|
|
return t * t;
|
|
|
|
}
|
|
|
|
|
2021-03-21 17:08:28 +08:00
|
|
|
constexpr float quad_out(float t)
|
2020-08-26 15:38:01 +08:00
|
|
|
{
|
|
|
|
return -(t * (t - 2));
|
|
|
|
}
|
|
|
|
|
2021-03-21 17:08:28 +08:00
|
|
|
constexpr float quad_in_out(float t)
|
2020-08-26 15:38:01 +08:00
|
|
|
{
|
|
|
|
if (t < 0.5f)
|
|
|
|
return 2 * t * t;
|
|
|
|
else
|
|
|
|
return (-2 * t * t) + (4 * t) - 1;
|
|
|
|
}
|
|
|
|
|
2021-03-21 17:08:28 +08:00
|
|
|
constexpr float cube_in(float t)
|
2020-08-26 15:38:01 +08:00
|
|
|
{
|
|
|
|
return t * t * t;
|
|
|
|
}
|
|
|
|
|
2021-03-21 17:08:28 +08:00
|
|
|
constexpr float cube_out(float t)
|
2020-08-26 15:38:01 +08:00
|
|
|
{
|
|
|
|
float f = (t - 1);
|
|
|
|
return f * f * f + 1;
|
|
|
|
}
|
|
|
|
|
2021-03-21 17:08:28 +08:00
|
|
|
constexpr float cube_in_out(float t)
|
2020-08-26 15:38:01 +08:00
|
|
|
{
|
|
|
|
if (t < 0.5f)
|
|
|
|
return 4 * t * t * t;
|
|
|
|
else
|
|
|
|
{
|
|
|
|
float f = ((2 * t) - 2);
|
|
|
|
return 0.5f * f * f * f + 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-03-21 17:08:28 +08:00
|
|
|
constexpr float quart_in(float t)
|
2020-08-26 15:38:01 +08:00
|
|
|
{
|
|
|
|
return t * t * t * t;
|
|
|
|
}
|
|
|
|
|
2021-03-21 17:08:28 +08:00
|
|
|
constexpr float quart_out(float t)
|
2020-08-26 15:38:01 +08:00
|
|
|
{
|
|
|
|
float f = (t - 1);
|
|
|
|
return f * f * f * (1 - t) + 1;
|
|
|
|
}
|
|
|
|
|
2021-03-21 17:08:28 +08:00
|
|
|
constexpr float quart_in_out(float t)
|
2020-08-26 15:38:01 +08:00
|
|
|
{
|
|
|
|
if (t < 0.5f)
|
|
|
|
return 8 * t * t * t * t;
|
|
|
|
else
|
|
|
|
{
|
|
|
|
float f = (t - 1);
|
|
|
|
return -8 * f * f * f * f + 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-03-21 17:08:28 +08:00
|
|
|
constexpr float quint_in(float t)
|
2020-08-26 15:38:01 +08:00
|
|
|
{
|
|
|
|
return t * t * t * t * t;
|
|
|
|
}
|
|
|
|
|
2021-03-21 17:08:28 +08:00
|
|
|
constexpr float quint_out(float t)
|
2020-08-26 15:38:01 +08:00
|
|
|
{
|
|
|
|
float f = (t - 1);
|
|
|
|
return f * f * f * f * f + 1;
|
|
|
|
}
|
|
|
|
|
2021-03-21 17:08:28 +08:00
|
|
|
constexpr float quint_in_out(float t)
|
2020-08-26 15:38:01 +08:00
|
|
|
{
|
|
|
|
if (t < 0.5f)
|
|
|
|
return 16 * t * t * t * t * t;
|
|
|
|
else
|
|
|
|
{
|
|
|
|
float f = ((2 * t) - 2);
|
|
|
|
return 0.5f * f * f * f * f * f + 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-08-28 10:11:22 +08:00
|
|
|
inline float sine_in(float t)
|
2020-08-26 15:38:01 +08:00
|
|
|
{
|
|
|
|
return Calc::sin((t - 1) * Calc::PI * 0.5f) + 1;
|
|
|
|
}
|
|
|
|
|
2020-08-28 10:11:22 +08:00
|
|
|
inline float sine_out(float t)
|
2020-08-26 15:38:01 +08:00
|
|
|
{
|
|
|
|
return Calc::sin(t * (Calc::PI * 0.5f));
|
|
|
|
}
|
|
|
|
|
2020-08-28 10:11:22 +08:00
|
|
|
inline float sine_in_out(float t)
|
2020-08-26 15:38:01 +08:00
|
|
|
{
|
|
|
|
return 0.5f * (1 - Calc::cos(t * Calc::PI));
|
|
|
|
}
|
|
|
|
|
2020-08-28 10:11:22 +08:00
|
|
|
inline float circ_in(float t)
|
2020-08-26 15:38:01 +08:00
|
|
|
{
|
|
|
|
return 1 - Calc::sqrt(1 - (t * t));
|
|
|
|
}
|
|
|
|
|
2020-08-28 10:11:22 +08:00
|
|
|
inline float circ_out(float t)
|
2020-08-26 15:38:01 +08:00
|
|
|
{
|
|
|
|
return Calc::sqrt((2 - t) * t);
|
|
|
|
}
|
|
|
|
|
2020-08-28 10:11:22 +08:00
|
|
|
inline float circ_in_out(float t)
|
2020-08-26 15:38:01 +08:00
|
|
|
{
|
|
|
|
if (t < 0.5f)
|
|
|
|
return 0.5f * (1 - Calc::sqrt(1 - 4 * (t * t)));
|
|
|
|
else
|
|
|
|
return 0.5f * (Calc::sqrt(-((2 * t) - 3) * ((2 * t) - 1)) + 1);
|
|
|
|
}
|
|
|
|
|
2020-08-28 10:11:22 +08:00
|
|
|
inline float exp_in(float t)
|
2020-08-26 15:38:01 +08:00
|
|
|
{
|
|
|
|
return (t == 0) ? 0 : Calc::pow(2, 10 * (t - 1));
|
|
|
|
}
|
|
|
|
|
2020-08-28 10:11:22 +08:00
|
|
|
inline float exp_out(float t)
|
2020-08-26 15:38:01 +08:00
|
|
|
{
|
|
|
|
return (t == 1) ? 1 : 1 - Calc::pow(2, -10 * t);
|
|
|
|
}
|
|
|
|
|
2020-08-28 10:11:22 +08:00
|
|
|
inline float exp_in_out(float t)
|
2020-08-26 15:38:01 +08:00
|
|
|
{
|
|
|
|
if (t == 0 || t == 1)
|
|
|
|
return t;
|
|
|
|
|
|
|
|
if (t < 0.5f)
|
|
|
|
return 0.5f * Calc::pow(2, (20 * t) - 10);
|
|
|
|
else
|
|
|
|
return -0.5f * Calc::pow(2, (-20 * t) + 10) + 1;
|
|
|
|
}
|
|
|
|
|
2020-08-28 10:11:22 +08:00
|
|
|
inline float elastic_in(float t)
|
2020-08-26 15:38:01 +08:00
|
|
|
{
|
|
|
|
return Calc::sin(13 * (Calc::PI * 0.5f) * t) * Calc::pow(2, 10 * (t - 1));
|
|
|
|
}
|
|
|
|
|
2020-08-28 10:11:22 +08:00
|
|
|
inline float elastic_out(float t)
|
2020-08-26 15:38:01 +08:00
|
|
|
{
|
|
|
|
return Calc::sin(-13 * (Calc::PI * 0.5f) * (t + 1)) * Calc::pow(2, -10 * t) + 1;
|
|
|
|
}
|
|
|
|
|
2020-08-28 10:11:22 +08:00
|
|
|
inline float elastic_in_out(float t)
|
2020-08-26 15:38:01 +08:00
|
|
|
{
|
|
|
|
if (t < 0.5f)
|
|
|
|
return 0.5f * Calc::sin(13 * (Calc::PI * 0.5f) * (2 * t)) * Calc::pow(2, 10 * ((2 * t) - 1));
|
|
|
|
else
|
|
|
|
return 0.5f * (Calc::sin(-13 * (Calc::PI * 0.5f) * ((2 * t - 1) + 1)) * Calc::pow(2, -10 * (2 * t - 1)) + 2);
|
|
|
|
}
|
|
|
|
|
2020-08-28 10:11:22 +08:00
|
|
|
inline float back_in(float t)
|
2020-08-26 15:38:01 +08:00
|
|
|
{
|
|
|
|
return t * t * t - t * Calc::sin(t * Calc::PI);
|
|
|
|
}
|
|
|
|
|
2020-08-28 10:11:22 +08:00
|
|
|
inline float back_out(float t)
|
2020-08-26 15:38:01 +08:00
|
|
|
{
|
|
|
|
float f = (1 - t);
|
|
|
|
return 1 - (f * f * f - f * Calc::sin(f * Calc::PI));
|
|
|
|
}
|
|
|
|
|
2020-08-28 10:11:22 +08:00
|
|
|
inline float back_in_out(float t)
|
2020-08-26 15:38:01 +08:00
|
|
|
{
|
|
|
|
if (t < 0.5f)
|
|
|
|
{
|
|
|
|
float f = 2 * t;
|
|
|
|
return 0.5f * (f * f * f - f * Calc::sin(f * Calc::PI));
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
float f = (1 - (2 * t - 1));
|
|
|
|
return 0.5f * (1 - (f * f * f - f * Calc::sin(f * Calc::PI))) + 0.5f;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-03-21 17:08:28 +08:00
|
|
|
constexpr float bounce_out(float t)
|
2020-08-26 15:38:01 +08:00
|
|
|
{
|
|
|
|
if (t < 4 / 11.0f)
|
|
|
|
return (121 * t * t) / 16.0f;
|
|
|
|
else if (t < 8 / 11.0f)
|
|
|
|
return (363 / 40.0f * t * t) - (99 / 10.0f * t) + 17 / 5.0f;
|
|
|
|
else if (t < 9 / 10.0f)
|
|
|
|
return (4356 / 361.0f * t * t) - (35442 / 1805.0f * t) + 16061 / 1805.0f;
|
|
|
|
else
|
|
|
|
return (54 / 5.0f * t * t) - (513 / 25.0f * t) + 268 / 25.0f;
|
|
|
|
}
|
|
|
|
|
2021-03-21 17:08:28 +08:00
|
|
|
constexpr float bounce_in(float t)
|
2020-08-26 15:38:01 +08:00
|
|
|
{
|
|
|
|
return 1 - bounce_out(1 - t);
|
|
|
|
}
|
|
|
|
|
2021-03-21 17:08:28 +08:00
|
|
|
constexpr float bounce_in_out(float t)
|
2020-08-26 15:38:01 +08:00
|
|
|
{
|
|
|
|
if (t < 0.5f)
|
|
|
|
return 0.5f * bounce_in(t * 2);
|
|
|
|
else
|
|
|
|
return 0.5f * bounce_out(t * 2 - 1) + 0.5f;
|
|
|
|
}
|
|
|
|
|
2020-08-28 10:11:22 +08:00
|
|
|
inline Easer get(Easers e)
|
2020-08-26 15:38:01 +08:00
|
|
|
{
|
|
|
|
switch (e)
|
|
|
|
{
|
2021-03-21 17:08:28 +08:00
|
|
|
case Easers::Linear: return &linear;
|
|
|
|
|
2020-08-26 15:38:01 +08:00
|
|
|
case Easers::CubeIn: return &cube_in;
|
|
|
|
case Easers::CubeOut: return &cube_out;
|
|
|
|
case Easers::CubeInOut: return &cube_in_out;
|
|
|
|
|
|
|
|
case Easers::QuadIn: return &quad_in;
|
|
|
|
case Easers::QuadOut: return &quad_out;
|
|
|
|
case Easers::QuadInOut: return &quad_in_out;
|
|
|
|
|
|
|
|
case Easers::QuartIn: return &quart_in;
|
|
|
|
case Easers::QuartOut: return &quart_out;
|
|
|
|
case Easers::QuartInOut: return &quart_in_out;
|
|
|
|
|
|
|
|
case Easers::QuintIn: return &quint_in;
|
|
|
|
case Easers::QuintOut: return &quint_out;
|
|
|
|
case Easers::QuintInOut: return &quint_in_out;
|
|
|
|
|
|
|
|
case Easers::SineIn: return &sine_in;
|
|
|
|
case Easers::SineOut: return &sine_out;
|
|
|
|
case Easers::SineInOut: return &sine_in_out;
|
|
|
|
|
|
|
|
case Easers::CircIn: return &circ_in;
|
|
|
|
case Easers::CircOut: return &circ_out;
|
|
|
|
case Easers::CircInOut: return &circ_in_out;
|
|
|
|
|
|
|
|
case Easers::ExpIn: return &exp_in;
|
|
|
|
case Easers::ExpOut: return &exp_out;
|
|
|
|
case Easers::ExpInOut: return &exp_in_out;
|
|
|
|
|
|
|
|
case Easers::ElasticIn: return &elastic_in;
|
|
|
|
case Easers::ElasticOut: return &elastic_out;
|
|
|
|
case Easers::ElasticInOut: return &elastic_in_out;
|
|
|
|
|
|
|
|
case Easers::BackIn: return &back_in;
|
|
|
|
case Easers::BackOut: return &back_out;
|
|
|
|
case Easers::BackInOut: return &back_in_out;
|
|
|
|
|
|
|
|
case Easers::BounceIn: return &bounce_in;
|
|
|
|
case Easers::BounceOut: return &bounce_out;
|
|
|
|
case Easers::BounceInOut: return &bounce_in_out;
|
2021-05-07 12:48:06 +08:00
|
|
|
case Easers::Count:
|
2020-08-26 15:38:01 +08:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2021-05-10 08:23:02 +08:00
|
|
|
BLAH_ASSERT(false, "Invalid Easer Type");
|
2020-08-26 15:38:01 +08:00
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
|
2020-08-28 10:11:22 +08:00
|
|
|
inline const char* name(Easers e)
|
2020-08-26 15:38:01 +08:00
|
|
|
{
|
|
|
|
switch (e)
|
|
|
|
{
|
2021-03-21 17:08:28 +08:00
|
|
|
case Easers::Linear: return "Linear";
|
2020-08-26 15:38:01 +08:00
|
|
|
case Easers::CubeIn: return "CubeIn";
|
|
|
|
case Easers::CubeOut: return "CubeOut";
|
|
|
|
case Easers::CubeInOut: return "CubeInOut";
|
|
|
|
case Easers::QuadIn: return "QuadIn";
|
|
|
|
case Easers::QuadOut: return "QuadOut";
|
|
|
|
case Easers::QuadInOut: return "QuadInOut";
|
|
|
|
case Easers::QuartIn: return "QuartIn";
|
|
|
|
case Easers::QuartOut: return "QuartOut";
|
|
|
|
case Easers::QuartInOut: return "QuartInOut";
|
|
|
|
case Easers::QuintIn: return "QuintIn";
|
|
|
|
case Easers::QuintOut: return "QuintOut";
|
|
|
|
case Easers::QuintInOut: return "QuintInOut";
|
|
|
|
case Easers::SineIn: return "SineIn";
|
|
|
|
case Easers::SineOut: return "SineOut";
|
|
|
|
case Easers::SineInOut: return "SineInOut";
|
|
|
|
case Easers::CircIn: return "CircIn";
|
|
|
|
case Easers::CircOut: return "CircOut";
|
|
|
|
case Easers::CircInOut: return "CircInOut";
|
|
|
|
case Easers::ExpIn: return "ExpIn";
|
|
|
|
case Easers::ExpOut: return "ExpOut";
|
|
|
|
case Easers::ExpInOut: return "ExpInOut";
|
|
|
|
case Easers::ElasticIn: return "ElasticIn";
|
|
|
|
case Easers::ElasticOut: return "ElasticOut";
|
|
|
|
case Easers::ElasticInOut: return "ElasticInOut";
|
|
|
|
case Easers::BackIn: return "BackIn";
|
|
|
|
case Easers::BackOut: return "BackOut";
|
|
|
|
case Easers::BackInOut: return "BackInOut";
|
|
|
|
case Easers::BounceIn: return "BounceIn";
|
|
|
|
case Easers::BounceOut: return "BounceOut";
|
|
|
|
case Easers::BounceInOut: return "BounceInOut";
|
2021-05-07 12:48:06 +08:00
|
|
|
case Easers::Count:
|
2020-08-26 15:38:01 +08:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
return "<Invalid>";
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|