blah/include/blah_ease.h

339 lines
7.6 KiB
C
Raw Normal View History

2020-08-26 15:38:01 +08:00
#pragma once
#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,
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,
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;
}
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>";
}
}
}