62 lines
1.6 KiB
C
62 lines
1.6 KiB
C
|
tween_t tween() {
|
||
|
tween_t tw = {0};
|
||
|
return tw;
|
||
|
}
|
||
|
|
||
|
float tween_update(tween_t *tw, float dt) {
|
||
|
if (!array_count(tw->keyframes)) return 0.0f;
|
||
|
|
||
|
for (size_t i = 0; i < array_count(tw->keyframes) - 1; ++i) {
|
||
|
tween_keyframe_t *kf1 = &tw->keyframes[i];
|
||
|
tween_keyframe_t *kf2 = &tw->keyframes[i + 1];
|
||
|
if (tw->time >= kf1->t && tw->time <= kf2->t) {
|
||
|
float localT = (tw->time - kf1->t) / (kf2->t - kf1->t);
|
||
|
float easedT = ease(localT, kf1->easing_mode);
|
||
|
tw->result = mix3(kf1->v, kf2->v, easedT);
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
float done = (tw->time / tw->duration);
|
||
|
tw->time += dt;
|
||
|
return clampf(done, 0.0f, 1.0f);
|
||
|
}
|
||
|
|
||
|
void tween_reset(tween_t *tw) {
|
||
|
tw->time = 0.0f;
|
||
|
}
|
||
|
|
||
|
void tween_destroy(tween_t *tw) {
|
||
|
tween_t tw_ = {0};
|
||
|
array_free(tw->keyframes);
|
||
|
*tw = tw_;
|
||
|
}
|
||
|
|
||
|
static inline
|
||
|
int tween_comp_keyframes(const void *a, const void *b) {
|
||
|
float t1 = ((const tween_keyframe_t*)a)->t;
|
||
|
float t2 = ((const tween_keyframe_t*)b)->t;
|
||
|
return (t1 > t2) - (t1 < t2);
|
||
|
}
|
||
|
|
||
|
void tween_keyframe_set(tween_t *tw, float t, int mode, vec3 v) {
|
||
|
tween_keyframe_t keyframe = { mode, t, v };
|
||
|
array_push(tw->keyframes, keyframe);
|
||
|
array_sort(tw->keyframes, tween_comp_keyframes);
|
||
|
tw->duration = array_back(tw->keyframes)->t;
|
||
|
}
|
||
|
|
||
|
void tween_keyframe_unset(tween_t *tw, float t) { /*@todo: untested*/
|
||
|
int id = -1;
|
||
|
for (int i = 0; i < array_count(tw->keyframes); i++) {
|
||
|
if (tw->keyframes[i].t == t) {
|
||
|
id = i;
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if (id == -1) return;
|
||
|
array_erase_slow(tw->keyframes, id);
|
||
|
tw->duration = array_back(tw->keyframes)->t;
|
||
|
}
|