2022-12-27 17:54:39 -06:00
|
|
|
#include "anim.h"
|
|
|
|
#include "log.h"
|
2023-05-12 13:22:05 -05:00
|
|
|
#include "stb_ds.h"
|
2022-12-27 17:54:39 -06:00
|
|
|
|
2024-04-26 16:04:31 -05:00
|
|
|
void animation_run(struct animation *anim, float now)
|
2023-12-04 13:38:37 -06:00
|
|
|
{
|
2024-04-26 16:04:31 -05:00
|
|
|
float elapsed = now - anim->time;
|
|
|
|
elapsed = fmod(elapsed,2);
|
|
|
|
if (!anim->channels) return;
|
|
|
|
|
|
|
|
for (int i = 0; i < arrlen(anim->channels); i++) {
|
|
|
|
struct anim_channel *ch = anim->channels+i;
|
|
|
|
HMM_Vec4 s = sample_sampler(ch->sampler, elapsed);
|
|
|
|
*(ch->target) = s;
|
|
|
|
}
|
2023-12-04 13:38:37 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
HMM_Vec4 sample_cubicspline(sampler *sampler, float t, int prev, int next)
|
|
|
|
{
|
2024-04-26 16:04:31 -05:00
|
|
|
return (HMM_Vec4)HMM_SLerp(HMM_QV4(sampler->data[prev]), t, HMM_QV4(sampler->data[next]));
|
2023-12-04 13:38:37 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
HMM_Vec4 sample_sampler(sampler *sampler, float time)
|
|
|
|
{
|
2024-04-26 16:04:31 -05:00
|
|
|
if (arrlen(sampler->data) == 0) return v4zero;
|
2024-01-01 17:30:42 -06:00
|
|
|
if (arrlen(sampler->data) == 1) return sampler->data[0];
|
2023-12-04 13:38:37 -06:00
|
|
|
int previous_time=0;
|
|
|
|
int next_time=0;
|
|
|
|
|
|
|
|
for (int i = 1; i < arrlen(sampler->times); i++) {
|
|
|
|
if (time < sampler->times[i]) {
|
2024-04-26 16:04:31 -05:00
|
|
|
previous_time = i-1;
|
|
|
|
next_time = i;
|
2023-12-04 13:38:37 -06:00
|
|
|
break;
|
|
|
|
}
|
2023-05-12 13:22:05 -05:00
|
|
|
}
|
2024-04-26 16:04:31 -05:00
|
|
|
|
2023-12-04 13:38:37 -06:00
|
|
|
float td = sampler->times[next_time]-sampler->times[previous_time];
|
|
|
|
float t = (time - sampler->times[previous_time])/td;
|
|
|
|
|
|
|
|
switch(sampler->type) {
|
|
|
|
case LINEAR:
|
2024-01-01 17:30:42 -06:00
|
|
|
return HMM_LerpV4(sampler->data[previous_time],time,sampler->data[next_time]);
|
2023-12-04 13:38:37 -06:00
|
|
|
break;
|
|
|
|
case STEP:
|
|
|
|
return sampler->data[previous_time];
|
|
|
|
break;
|
|
|
|
case CUBICSPLINE:
|
|
|
|
return sample_cubicspline(sampler,t, previous_time, next_time);
|
|
|
|
break;
|
2024-01-01 17:30:42 -06:00
|
|
|
case SLERP:
|
|
|
|
return (HMM_Vec4)HMM_SLerp(sampler->data[previous_time].quat, time, sampler->data[next_time].quat);
|
|
|
|
break;
|
2023-05-12 13:22:05 -05:00
|
|
|
}
|
2023-12-21 17:21:01 -06:00
|
|
|
return sample_cubicspline(sampler,t, previous_time, next_time);
|
2023-02-02 17:52:15 -06:00
|
|
|
}
|