Add easing functions
This commit is contained in:
@@ -57,6 +57,7 @@ set(BreezeHeaders
|
|||||||
breeze/core/logger.h
|
breeze/core/logger.h
|
||||||
|
|
||||||
breeze/math/vec2i.h
|
breeze/math/vec2i.h
|
||||||
|
breeze/math/easings.h
|
||||||
|
|
||||||
breeze/memory/memory.h
|
breeze/memory/memory.h
|
||||||
breeze/memory/stack_alloc.h
|
breeze/memory/stack_alloc.h
|
||||||
|
|||||||
@@ -4,6 +4,7 @@
|
|||||||
#include "breeze/core/logger.h"
|
#include "breeze/core/logger.h"
|
||||||
|
|
||||||
#include "breeze/math/vec2i.h"
|
#include "breeze/math/vec2i.h"
|
||||||
|
#include "breeze/math/easings.h"
|
||||||
|
|
||||||
#include "breeze/memory/memory.h"
|
#include "breeze/memory/memory.h"
|
||||||
#include "breeze/memory/stack_alloc.h"
|
#include "breeze/memory/stack_alloc.h"
|
||||||
|
|||||||
227
engine/breeze/math/easings.h
Normal file
227
engine/breeze/math/easings.h
Normal file
@@ -0,0 +1,227 @@
|
|||||||
|
#ifndef BREEZE_EASINGS_H
|
||||||
|
#define BREEZE_EASINGS_H
|
||||||
|
|
||||||
|
#include <math.h>
|
||||||
|
|
||||||
|
// From: https://easings.net/
|
||||||
|
typedef enum BzEaseType {
|
||||||
|
BZ_EASE_NONE,
|
||||||
|
BZ_EASE_IN_SINE,
|
||||||
|
BZ_EASE_OUT_SINE,
|
||||||
|
BZ_EASE_INOUT_SINE,
|
||||||
|
BZ_EASE_IN_QUAD,
|
||||||
|
BZ_EASE_OUT_QUAD,
|
||||||
|
BZ_EASE_INOUT_QUAD,
|
||||||
|
BZ_EASE_IN_CUBIC,
|
||||||
|
BZ_EASE_OUT_CUBIC,
|
||||||
|
BZ_EASE_INOUT_CUBIC,
|
||||||
|
BZ_EASE_IN_QUART,
|
||||||
|
BZ_EASE_OUT_QUART,
|
||||||
|
BZ_EASE_INOUT_QUART,
|
||||||
|
BZ_EASE_IN_QUINT,
|
||||||
|
BZ_EASE_OUT_QUINT,
|
||||||
|
BZ_EASE_INOUT_QUINT,
|
||||||
|
BZ_EASE_IN_EXPO,
|
||||||
|
BZ_EASE_OUT_EXPO,
|
||||||
|
BZ_EASE_INOUT_EXPO,
|
||||||
|
BZ_EASE_IN_CIRC,
|
||||||
|
BZ_EASE_OUT_CIRC,
|
||||||
|
BZ_EASE_INOUT_CIRC,
|
||||||
|
BZ_EASE_IN_BACK,
|
||||||
|
BZ_EASE_OUT_BACK,
|
||||||
|
BZ_EASE_INOUT_BACK,
|
||||||
|
BZ_EASE_IN_ELASTIC,
|
||||||
|
BZ_EASE_OUT_ELASTIC,
|
||||||
|
BZ_EASE_INOUT_ELASTIC,
|
||||||
|
BZ_EASE_IN_BOUNCE,
|
||||||
|
BZ_EASE_OUT_BOUNCE,
|
||||||
|
BZ_EASE_INOUT_BOUNCE,
|
||||||
|
} BzEaseType;
|
||||||
|
|
||||||
|
static f32 bzEaseNone(f32 x) {
|
||||||
|
return x;
|
||||||
|
}
|
||||||
|
|
||||||
|
static f32 bzEaseInSine(f32 x) {
|
||||||
|
return 1 - cosf((x * M_PI) / 2.0f);
|
||||||
|
}
|
||||||
|
static f32 bzEaseOutSine(f32 x) {
|
||||||
|
return sinf((x * M_PI) / 2.0f);
|
||||||
|
}
|
||||||
|
f32 bzEaseInOutSine(f32 x) {
|
||||||
|
return -(-cosf(M_PI * x) - 1) / 2.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
static f32 bzEaseInQuad(f32 x) {
|
||||||
|
return x * x;
|
||||||
|
}
|
||||||
|
static f32 bzEaseOutQuad(f32 x) {
|
||||||
|
return 1 - (1 - x) * (1 - x);
|
||||||
|
}
|
||||||
|
static f32 bzEaseInOutQuad(f32 x) {
|
||||||
|
return x < 0.5f ? 2.0f * x * x : 1 - powf(-2.0f * x + 2, 2) / 2.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
static f32 bzEaseInCubic(f32 x) {
|
||||||
|
return x * x * x;
|
||||||
|
}
|
||||||
|
static f32 bzEaseOutCubic(f32 x) {
|
||||||
|
return 1 - powf(1 - x, 3);
|
||||||
|
}
|
||||||
|
static f32 bzEaseInOutCubic(f32 x) {
|
||||||
|
return x < 0.5 ? 4 * x * x * x : 1 - powf(-2.0f * x + 2, 3) / 2.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
static f32 bzEaseInQuart(f32 x) {
|
||||||
|
return x * x * x * x;
|
||||||
|
}
|
||||||
|
static f32 bzEaseOutQuart(f32 x) {
|
||||||
|
return 1 - powf(1 - x, 4);
|
||||||
|
}
|
||||||
|
static f32 bzEaseInOutQuart(f32 x) {
|
||||||
|
return x < 0.5 ? 8 * x * x * x * x : 1 - powf(-2 * x + 2, 4) / 2.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
static f32 bzEaseInQuint(f32 x) {
|
||||||
|
return x * x * x * x * x;
|
||||||
|
}
|
||||||
|
static f32 bzEaseOutQuint(f32 x) {
|
||||||
|
return 1 - powf(1 - x, 5);
|
||||||
|
}
|
||||||
|
static f32 bzEaseInOutQuint(f32 x) {
|
||||||
|
return x < 0.5 ? 16 * x * x * x * x * x : 1 - powf(-2 * x + 2, 5) / 2.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
static f32 bzEaseInExpo(f32 x) {
|
||||||
|
return x == 0 ? 0 : powf(2, 10 * x - 10);
|
||||||
|
}
|
||||||
|
static f32 bzEaseOutExpo(f32 x) {
|
||||||
|
return x == 1 ? 1 : 1 - powf(2, -10 * x);
|
||||||
|
}
|
||||||
|
static f32 bzEaseInOutExpo(f32 x) {
|
||||||
|
if (x == 0) return 0;
|
||||||
|
if (x == 1) return 1;
|
||||||
|
return x < 0.5 ? powf(2, 20 * x - 10) / 2.0 : (2 - powf(2, -20 * x + 10)) / 2.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static f32 bzEaseInCirc(f32 x) {
|
||||||
|
return 1 - sqrtf(1 - powf(x, 2));
|
||||||
|
}
|
||||||
|
static f32 bzEaseOutCirc(f32 x) {
|
||||||
|
return sqrtf(1 - powf(x - 1, 2));
|
||||||
|
}
|
||||||
|
static f32 bzEaseInOutCirc(f32 x) {
|
||||||
|
return x < 0.5
|
||||||
|
? (1 - sqrtf(1 - powf(2 * x, 2))) / 2
|
||||||
|
: (sqrtf(1 - powf(-2 * x + 2, 2)) + 1) / 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
static f32 bzEaseInBack(f32 x) {
|
||||||
|
const f32 c1 = 1.70158f;
|
||||||
|
const f32 c3 = c1 + 1;
|
||||||
|
|
||||||
|
return (c3 * x * x * x) - (c1 * x * x);
|
||||||
|
}
|
||||||
|
static f32 bzEaseOutBack(f32 x) {
|
||||||
|
const f32 c1 = 1.70158f;
|
||||||
|
const f32 c3 = c1 + 1;
|
||||||
|
|
||||||
|
return 1 + (c3 * powf(x - 1, 3)) + (c1 * powf(x - 1, 2));
|
||||||
|
}
|
||||||
|
static f32 bzEaseInOutBack(f32 x) {
|
||||||
|
const f32 c1 = 1.70158f;
|
||||||
|
const f32 c2 = c1 * 1.525;
|
||||||
|
|
||||||
|
return x < 0.5
|
||||||
|
? (powf(2 * x, 2) * ((c2 + 1) * 2 * x - c2)) / 2.0f
|
||||||
|
: (powf(2 * x - 2, 2) * ((c2 + 1) * (x * 2 - 2) + c2) + 2) / 2.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
static f32 bzEaseInElastic(f32 x) {
|
||||||
|
const f32 c4 = (2 * M_PI) / 3.0f;
|
||||||
|
|
||||||
|
if (x == 0) return 0;
|
||||||
|
if (x == 1) return 1;
|
||||||
|
|
||||||
|
return -powf(2, 10 * x - 10) * sinf((x * 10 - 10.75) * c4);
|
||||||
|
}
|
||||||
|
static f32 bzEaseOutElastic(f32 x) {
|
||||||
|
const f32 c4 = (2 * M_PI) / 3.0f;
|
||||||
|
|
||||||
|
if (x == 0) return 0;
|
||||||
|
if (x == 1) return 1;
|
||||||
|
|
||||||
|
return powf(2, -10 * x) * sinf((x * 10 - 0.75) * c4) + 1;
|
||||||
|
}
|
||||||
|
static f32 bzEaseInOutElastic(f32 x) {
|
||||||
|
const f32 c5 = (2 * M_PI) / 4.5f;
|
||||||
|
|
||||||
|
if (x == 0) return 0;
|
||||||
|
if (x == 1) return 1;
|
||||||
|
|
||||||
|
return x < 0.5 ?
|
||||||
|
-(powf(2, 20 * x - 10) * sinf((20 * x - 11.125) * c5)) / 2.0f :
|
||||||
|
(powf(2, -20 * x + 10) * sinf((20 * x - 11.125) * c5)) / 2.0f + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static f32 bzEaseOutBounce(f32 x);
|
||||||
|
static f32 bzEaseInBounce(f32 x) {
|
||||||
|
return 1 - bzEaseOutBounce(1 - x);
|
||||||
|
}
|
||||||
|
static f32 bzEaseOutBounce(f32 x) {
|
||||||
|
const f32 n1 = 7.5625;
|
||||||
|
const f32 d1 = 2.75;
|
||||||
|
|
||||||
|
if (x < 1 / d1) {
|
||||||
|
return n1 * x * x;
|
||||||
|
} else if (x < 2 / d1) {
|
||||||
|
return (x -= 1.5f / d1, n1 * x * x + 0.75f);
|
||||||
|
} else if (x < 2.5 / d1) {
|
||||||
|
return (x -= 2.25 / d1, n1 * x * x + 0.9375);
|
||||||
|
} else {
|
||||||
|
return (x -= 2.625 / d1, n1 * x * x + 0.984375);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
static f32 bzEaseInOutBounce(f32 x) {
|
||||||
|
return x < 0.5
|
||||||
|
? (1 - bzEaseOutBounce(1 - 2 * x)) / 2.0f
|
||||||
|
: (1 + bzEaseOutBounce(2 * x - 1)) / 2.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
static f32 bzEase(BzEaseType easeType, f32 x) {
|
||||||
|
switch (easeType) {
|
||||||
|
case BZ_EASE_NONE: return bzEaseNone(x);
|
||||||
|
case BZ_EASE_IN_SINE: return bzEaseInSine(x);
|
||||||
|
case BZ_EASE_OUT_SINE: return bzEaseOutSine(x);
|
||||||
|
case BZ_EASE_INOUT_SINE: return bzEaseInOutSine(x);
|
||||||
|
case BZ_EASE_IN_QUAD: return bzEaseInQuad(x);
|
||||||
|
case BZ_EASE_OUT_QUAD: return bzEaseOutQuad(x);
|
||||||
|
case BZ_EASE_INOUT_QUAD: return bzEaseInOutQuad(x);
|
||||||
|
case BZ_EASE_IN_CUBIC: return bzEaseInCubic(x);
|
||||||
|
case BZ_EASE_OUT_CUBIC: return bzEaseOutCubic(x);
|
||||||
|
case BZ_EASE_INOUT_CUBIC: return bzEaseInOutCubic(x);
|
||||||
|
case BZ_EASE_IN_QUART: return bzEaseInQuart(x);
|
||||||
|
case BZ_EASE_OUT_QUART: return bzEaseOutQuart(x);
|
||||||
|
case BZ_EASE_INOUT_QUART: return bzEaseInOutQuart(x);
|
||||||
|
case BZ_EASE_IN_QUINT: return bzEaseInQuint(x);
|
||||||
|
case BZ_EASE_OUT_QUINT: return bzEaseOutQuint(x);
|
||||||
|
case BZ_EASE_INOUT_QUINT: return bzEaseInOutQuint(x);
|
||||||
|
case BZ_EASE_IN_EXPO: return bzEaseInExpo(x);
|
||||||
|
case BZ_EASE_OUT_EXPO: return bzEaseOutExpo(x);
|
||||||
|
case BZ_EASE_INOUT_EXPO: return bzEaseInOutExpo(x);
|
||||||
|
case BZ_EASE_IN_CIRC: return bzEaseInCirc(x);
|
||||||
|
case BZ_EASE_OUT_CIRC: return bzEaseOutCirc(x);
|
||||||
|
case BZ_EASE_INOUT_CIRC: return bzEaseInOutCirc(x);
|
||||||
|
case BZ_EASE_IN_BACK: return bzEaseInBack(x);
|
||||||
|
case BZ_EASE_OUT_BACK: return bzEaseOutBack(x);
|
||||||
|
case BZ_EASE_INOUT_BACK: return bzEaseInOutBack(x);
|
||||||
|
case BZ_EASE_IN_ELASTIC: return bzEaseInElastic(x);
|
||||||
|
case BZ_EASE_OUT_ELASTIC: return bzEaseOutElastic(x);
|
||||||
|
case BZ_EASE_INOUT_ELASTIC: return bzEaseInOutElastic(x);
|
||||||
|
case BZ_EASE_IN_BOUNCE: return bzEaseInBounce(x);
|
||||||
|
case BZ_EASE_OUT_BOUNCE: return bzEaseOutBounce(x);
|
||||||
|
case BZ_EASE_INOUT_BOUNCE: return bzEaseInOutBounce(x);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif //BREEZE_EASINGS_H
|
||||||
@@ -22,3 +22,6 @@ target_link_libraries(pan_test LINK_PRIVATE Breeze)
|
|||||||
|
|
||||||
add_executable(ui_test ui_test.c)
|
add_executable(ui_test ui_test.c)
|
||||||
target_link_libraries(ui_test LINK_PRIVATE Breeze)
|
target_link_libraries(ui_test LINK_PRIVATE Breeze)
|
||||||
|
|
||||||
|
add_executable(ease_test ease_test.c)
|
||||||
|
target_link_libraries(ease_test LINK_PRIVATE Breeze)
|
||||||
59
engine/tests/ease_test.c
Normal file
59
engine/tests/ease_test.c
Normal file
@@ -0,0 +1,59 @@
|
|||||||
|
#define BZ_ENTRYPOINT
|
||||||
|
#include <breeze.h>
|
||||||
|
|
||||||
|
#include <raylib.h>
|
||||||
|
#include <rlImGui.h>
|
||||||
|
|
||||||
|
bool init(int *game) {
|
||||||
|
rlImGuiSetup(true);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void render(float dt, int *game) {
|
||||||
|
|
||||||
|
static f32 x = 0;
|
||||||
|
|
||||||
|
x += dt * 2;
|
||||||
|
|
||||||
|
//f32 eased = bzEase(BZ_EASE_INOUT_SINE, x);
|
||||||
|
f32 eased = bzEase(BZ_EASE_OUT_ELASTIC, x);
|
||||||
|
|
||||||
|
Rectangle rect = {
|
||||||
|
500, 500, 200, 400
|
||||||
|
};
|
||||||
|
Vector2 origin = {rect.width * 0.5f, rect.height};
|
||||||
|
|
||||||
|
BeginDrawing();
|
||||||
|
ClearBackground(WHITE);
|
||||||
|
|
||||||
|
f32 rotation = 45 * (1 - eased);
|
||||||
|
DrawRectanglePro(rect, origin, rotation, RED);
|
||||||
|
|
||||||
|
|
||||||
|
if (IsKeyReleased(KEY_SPACE)) {
|
||||||
|
x = 0.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
rlImGuiBegin();
|
||||||
|
|
||||||
|
igBegin("Easing", NULL, 0);
|
||||||
|
igText("x: %.2f", x);
|
||||||
|
igText("eased: %.2f", eased);
|
||||||
|
igText("rotation: %.2f", rotation);
|
||||||
|
if (igSmallButton("Reset")) {
|
||||||
|
x = 0.0f;
|
||||||
|
}
|
||||||
|
igEnd();
|
||||||
|
|
||||||
|
rlImGuiEnd();
|
||||||
|
EndDrawing();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool bzMain(BzAppDesc *appDesc, int argc, const char **argv) {
|
||||||
|
appDesc->init = (BzAppInitFunc) init;
|
||||||
|
appDesc->render = (BzAppRenderFunc) render;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user