prosperon/source/engine/anim.c

58 lines
1.7 KiB
C
Raw Permalink Normal View History

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-01-01 17:30:42 -06:00
void sampler_add(sampler *s, float time, HMM_Vec4 val)
2023-12-04 13:38:37 -06:00
{
2024-01-01 17:30:42 -06:00
arrput(s->times,time);
arrput(s->data,val);
2023-12-04 13:38:37 -06:00
}
HMM_Vec4 sample_cubicspline(sampler *sampler, float t, int prev, int next)
{
float t2 = t*t;
float t3 = t2*t;
float td = sampler->times[next]-sampler->times[prev];
HMM_Vec4 v = HMM_MulV4F(sampler->data[prev*3+1], (2*t3-3*t2+1));
v = HMM_AddV4(v, HMM_MulV4F(sampler->data[prev*3+2], td*(t3-2*t2+t)));
v = HMM_AddV4(v, HMM_MulV4F(sampler->data[next*3+1], 3*t2-2*t3));
v = HMM_AddV4(v, HMM_MulV4F(sampler->data[next*3], td*(t3-t2)));
return v;
}
HMM_Vec4 sample_sampler(sampler *sampler, float time)
{
2024-01-01 17:30:42 -06:00
if (arrlen(sampler->data) == 0) return (HMM_Vec4){0,0,0,0};
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]) {
previous_time = sampler->times[i-1];
next_time = sampler->times[i];
break;
}
2023-05-12 13:22:05 -05:00
}
2022-12-28 16:50:54 -06: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
}
return sample_cubicspline(sampler,t, previous_time, next_time);
}