Last active
June 3, 2022 01:35
-
-
Save Faultz/e175bb69c1f95344f1222efd81152d81 to your computer and use it in GitHub Desktop.
Animation class for C++
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include "stdafx.h" | |
#define clamp(x, low, high) (((x) > (high)) ? (high) : (((x) < (low)) ? (low) : (x))) | |
animations g_anim; | |
void animation_data::process_animation() | |
{ | |
float elapsed_time = static_cast<float>(move - start_data); | |
float delta_time = static_cast<float>(get_time_now() - start_time); | |
float scale = clamp(delta_time / duration, 0.0f, 1.0f); | |
float progression = static_cast<float>(elapsed_time * interpolate(scale)); | |
*data = start_data + progression; | |
if (get_time_now() >= end_time) | |
{ | |
for (int i = 0; i < g_anim.animation_stack.size(); i++) | |
{ | |
if (this->id == g_anim.animation_stack[i].id) | |
{ | |
auto callback = g_anim.animation_stack[i].callback; | |
if (callback) | |
callback(); | |
g_anim.animation_stack.erase(g_anim.animation_stack.begin() + i); | |
} | |
} | |
} | |
} | |
void animation_data::add_animation(const char* name, void(*callback)(), float(*interpolate)(float), float* data, int* move, int duration) | |
{ | |
if (animations::already_added(name)) | |
return; | |
animation_data newAnim = animation_data(); | |
newAnim.id = hash(name); | |
newAnim.interpolate = interpolate; | |
newAnim.start_time = get_time_now(); | |
newAnim.duration = duration; | |
newAnim.end_time = newAnim.start_time + newAnim.duration; | |
newAnim.data = data; | |
newAnim.move = *(float*)move; | |
newAnim.start_data = *(float*)newAnim.data; | |
newAnim.callback = callback; | |
g_anim.animation_stack.push_back(newAnim); | |
} | |
void animations::add_animation(const char* name, void(*callback)(), float(*interpolate)(float), float* data, float move, clock_t duration) | |
{ | |
if (*data == move || interpolate == nullptr) return; | |
animation_data::add_animation(name, callback, interpolate, (float*)data, (int*)&move, duration); | |
} | |
void animations::add_animation(const char* name, void(*callback)(), float(*interpolate)(float), int* data, int move, clock_t duration) | |
{ | |
if (*data == move || interpolate == nullptr) return; | |
animation_data::add_animation(name, callback, interpolate, (float*)data, &move, duration); | |
} | |
void animations::add_animation(const char* name, void(*callback)(), float(*interpolate)(float), vec2_t* data, vec2_t move, clock_t duration) | |
{ | |
if (*data == move || interpolate == nullptr) return; | |
animation_data::add_animation(name, callback, interpolate, (float*)&data->x, (int*)&move.x, duration); | |
animation_data::add_animation(va("%s_2", name), callback, interpolate, (float*)&data->y, (int*)&move.y, duration); | |
} | |
void animations::add_animation(const char* name, void(*callback)(), float(*interpolate)(float), vec3_t* data, vec3_t move, clock_t duration) | |
{ | |
if (*data == move || interpolate == nullptr) return; | |
animation_data::add_animation(name, callback, interpolate, (float*)&data->x, (int*)&move.x, duration); | |
animation_data::add_animation(va("%s_1", name), callback, interpolate, (float*)&data->y, (int*)&move.y, duration); | |
animation_data::add_animation(va("%s_2", name), callback, interpolate, (float*)&data->z, (int*)&move.z, duration); | |
} | |
void animations::run_frame() | |
{ | |
for (animation_data anim : animation_stack) | |
anim.process_animation(); | |
} | |
animation_data* animations::find_anim(anim_id id) | |
{ | |
for (auto anim : g_anim.animation_stack) | |
if (anim.id == id) | |
return &anim; | |
return nullptr; | |
} | |
animation_data* animations::find_anim(const char* id_name) | |
{ | |
const auto& hashed_id = hash(id_name); | |
for (auto anim : g_anim.animation_stack) | |
if (anim.id == hashed_id) | |
return &anim; | |
return nullptr; | |
} | |
bool animations::already_added(anim_id id) | |
{ | |
for (int i = 0; i < g_anim.animation_stack.size(); i++) | |
{ | |
if (g_anim.animation_stack[i].id == id) | |
return true; | |
} | |
return false; | |
} | |
bool animations::already_added(const char* id_name) | |
{ | |
for (int i = 0; i < g_anim.animation_stack.size(); i++) | |
{ | |
if (g_anim.animation_stack[i].id == hash(id_name)) | |
return true; | |
} | |
return false; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#pragma once | |
typedef uint32_t anim_id; | |
class animation_data | |
{ | |
public: | |
anim_id id; | |
int start_time; | |
int move_time; | |
int end_time; | |
void(*callback)(); | |
float(*interpolate)(float val); | |
float* data; | |
float start_data; | |
float move; | |
int duration; | |
void process_animation(); | |
static void add_animation(const char* name, void(*callback)(), float(*interpolate)(float), float* data, int* move, int duration); | |
}; | |
class animations | |
{ | |
public: | |
~animations() | |
{ | |
animation_stack.clear(); | |
} | |
void add_animation(const char* name, void(*callback)(), float(*interpolate)(float), float* data, float move, clock_t duration); | |
void add_animation(const char* name, void(*callback)(), float(*interpolate)(float), int* data, int move, clock_t duration); | |
void add_animation(const char* name, void(*callback)(), float(*interpolate)(float), vec2_t* data, vec2_t move, clock_t duration); | |
void add_animation(const char* name, void(*callback)(), float(*interpolate)(float), vec3_t* data, vec3_t move, clock_t duration); | |
void run_frame(); | |
animation_data* find_anim(anim_id id); | |
animation_data* find_anim(const char* id_name); | |
static bool already_added(anim_id id); | |
static bool already_added(const char* id_name); | |
std::vector<animation_data> animation_stack; | |
}; | |
extern animations g_anim; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#pragma once | |
inline uint32_t hash(const char* str) | |
{ | |
uint64_t hash = 0xCBF29CE484222325; | |
while(*str) | |
{ | |
hash = | |
(hash ^ uint32_t((*str >= 'A' && *str <= 'Z') ? *str - ('A' - 'a') : *str)) * 0x100000001B3; | |
str++; | |
} | |
return hash; | |
} | |
namespace easing | |
{ | |
#pragma once | |
constexpr float m_pi = 3.14159265358979323846; | |
inline float linear(const float t) | |
{ | |
return t; | |
} | |
inline float in_sine(const float t) | |
{ | |
return sinf(1.5707963 * t); | |
} | |
inline float out_sine(float t) | |
{ | |
return 1 + sinf(1.5707963 * (--t)); | |
} | |
inline float in_out_sine(const float t) | |
{ | |
return 0.5 * (1 + sinf(3.1415926 * (t - 0.5))); | |
} | |
inline float inquad(const float t) | |
{ | |
return t * t; | |
} | |
inline float out_quad(const float t) | |
{ | |
return t * (2 - t); | |
} | |
inline float in_out_quad(const float t) | |
{ | |
return t < 0.5 ? 2 * t * t : t * (4 - 2 * t) - 1; | |
} | |
inline float in_cubic(const float t) | |
{ | |
return t * t * t; | |
} | |
inline float out_cubic(float t) | |
{ | |
return 1 + (--t) * t * t; | |
} | |
inline float in_out_cubic(float t) | |
{ | |
return t < 0.5 ? 4 * t * t * t : 1 + (--t) * (2 * (--t)) * (2 * t); | |
} | |
inline float in_quart(float t) | |
{ | |
t *= t; | |
return t * t; | |
} | |
inline float out_quart(float t) | |
{ | |
t = (--t) * t; | |
return 1 - t * t; | |
} | |
inline float in_out_quart(float t) | |
{ | |
if (t < 0.5) | |
{ | |
t *= t; | |
return 8 * t * t; | |
} | |
else | |
{ | |
t = (--t) * t; | |
return 1 - 8 * t * t; | |
} | |
} | |
inline float in_quint(const float t) | |
{ | |
const float t2 = t * t; | |
return t * t2 * t2; | |
} | |
inline float out_quint(float t) | |
{ | |
const float t2 = (--t) * t; | |
return 1 + t * t2 * t2; | |
} | |
inline float in_out_quint(float t) | |
{ | |
float t2; | |
if (t < 0.5) | |
{ | |
t2 = t * t; | |
return 16 * t * t2 * t2; | |
} | |
else | |
{ | |
t2 = (--t) * t; | |
return 1 + 16 * t * t2 * t2; | |
} | |
} | |
inline float in_expo(const float t) | |
{ | |
return (powf(2, 8 * t) - 1) / 255; | |
} | |
inline float out_expo(const float t) | |
{ | |
return 1 - powf(2, -8 * t); | |
} | |
inline float in_out_expo(const float t) | |
{ | |
if (t < 0.5) | |
{ | |
return (powf(2, 16 * t) - 1) / 510; | |
} | |
else | |
{ | |
return 1 - 0.5 * powf(2, -16 * (t - 0.5)); | |
} | |
} | |
inline float in_circ(const float t) | |
{ | |
return 1 - sqrtf(1 - t); | |
} | |
inline float out_circ(const float t) | |
{ | |
return sqrtf(t); | |
} | |
inline float in_out_circ(const float t) | |
{ | |
if (t < 0.5) | |
{ | |
return (1 - sqrtf(1 - 2 * t)) * 0.5; | |
} | |
else | |
{ | |
return (1 + sqrtf(2 * t - 1)) * 0.5; | |
} | |
} | |
inline float in_back(const float t) | |
{ | |
return t * t * (2.70158 * t - 1.70158); | |
} | |
inline float out_back(float t) | |
{ | |
return 1 + (--t) * t * (2.70158 * t + 1.70158); | |
} | |
inline float in_out_back(float t) | |
{ | |
if (t < 0.5) | |
{ | |
return t * t * (7 * t - 2.5) * 2; | |
} | |
else | |
{ | |
return 1 + (--t) * t * 2 * (7 * t + 2.5); | |
} | |
} | |
inline float in_elastic(const float t) | |
{ | |
const float t2 = t * t; | |
return t2 * t2 * sinf(t * m_pi * 4.5); | |
} | |
inline float out_elastic(const float t) | |
{ | |
const float t2 = (t - 1) * (t - 1); | |
return 1 - t2 * t2 * cosf(t * m_pi * 4.5); | |
} | |
inline float in_out_elastic(const float t) | |
{ | |
float t2; | |
if (t < 0.45) | |
{ | |
t2 = t * t; | |
return 8 * t2 * t2 * sinf(t * m_pi * 9); | |
} | |
else if (t < 0.55) | |
{ | |
return 0.5 + 0.75 * sinf(t * m_pi * 4); | |
} | |
else | |
{ | |
t2 = (t - 1) * (t - 1); | |
return 1 - 8 * t2 * t2 * sinf(t * m_pi * 9); | |
} | |
} | |
inline float in_bounce(const float t) | |
{ | |
return powf(2, 6 * (t - 1)) * fabsf(sinf(t * m_pi * 3.5)); | |
} | |
inline float out_bounce(const float t) | |
{ | |
return 1 - powf(2, -6 * t) * fabsf(cosf(t * m_pi * 3.5)); | |
} | |
inline float in_out_bounce(const float t) | |
{ | |
if (t < 0.5) | |
{ | |
return 8 * powf(2, 8 * (t - 1)) * fabsf(sinf(t * m_pi * 7)); | |
} | |
else | |
{ | |
return 1 - 8 * powf(2, -8 * t) * fabsf(sinf(t * m_pi * 7)); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment