skeleton animation

This commit is contained in:
John Alanbrook 2024-08-10 04:06:44 -05:00
parent f5a89915eb
commit a29ce7e8d0
3 changed files with 29 additions and 13 deletions

View file

@ -1933,7 +1933,6 @@ JSC_CCALL(transform_rotate,
transform *t = js2transform(self);
HMM_Quat rot = HMM_QFromAxisAngle_LH(axis, js2angle(argv[1]));
t->rotation = HMM_MulQ(t->rotation,rot);
printf("rotation is now %g,%g,%g,%g\n", t->rotation.e[0], t->rotation.e[1], t->rotation.e[2], t->rotation.e[3]);
t->dirty = true;
)
@ -2960,7 +2959,7 @@ JSC_SCALL(os_gltf_skin,
goto CLEANUP;
}
ret = skin2js(make_gltf_skin(data->skins+0));
ret = skin2js(make_gltf_skin(data->skins+0, data));
CLEANUP:
cgltf_free(data);

View file

@ -164,7 +164,14 @@ void packFloats(float *src, float *dest, int srcLength) {
}
}
animation *gltf_anim(cgltf_animation *anim)
static md5joint *node2joint(skin *sk, cgltf_node *n, cgltf_skin *skin)
{
int k = 0;
while (skin->joints[k] != n && k < skin->joints_count) k++;
return sk->joints+k;
}
animation *gltf_anim(cgltf_animation *anim, skin *sk, cgltf_skin *skin)
{
animation *ret = calloc(sizeof(*ret), 1);
animation an = *ret;
@ -200,7 +207,7 @@ animation *gltf_anim(cgltf_animation *anim)
for (int i = 0; i < anim->channels_count; i++) {
cgltf_animation_channel ch = anim->channels[i];
struct anim_channel ach = (struct anim_channel){0};
md5joint *md = NULL;
md5joint *md = node2joint(sk, ch.target_node, skin);
switch(ch.target_path) {
case cgltf_animation_path_type_translation:
ach.target = &md->pos;
@ -218,10 +225,13 @@ animation *gltf_anim(cgltf_animation *anim)
arrput(an.channels, ach);
}
an.time = 0;
*ret = an;
return ret;
}
skin *make_gltf_skin(cgltf_skin *skin)
skin *make_gltf_skin(cgltf_skin *skin, cgltf_data *data)
{
int n = cgltf_accessor_unpack_floats(skin->inverse_bind_matrices, NULL, 0);
struct skin *sk = NULL;
@ -236,10 +246,13 @@ skin *make_gltf_skin(cgltf_skin *skin)
for (int i = 0; i < skin->joints_count; i++) {
cgltf_node *n = skin->joints[i];
int idx = n-skin->skeleton;
int parent_idx = n->parent-skin->skeleton;
md5joint *j = sk->joints+idx;
j->parent = sk->joints+parent_idx;
md5joint *j = sk->joints+i;
if (n == skin->skeleton)
j->parent = NULL;
else
j->parent = node2joint(sk, n->parent, skin);
for (int i = 0; i < 3; i++) {
j->pos.e[i] = n->translation[i];
j->scale.e[i] = n->scale[i];
@ -248,17 +261,20 @@ skin *make_gltf_skin(cgltf_skin *skin)
j->rot.e[i] = n->rotation[i];
}
sk->anim = gltf_anim(data->animations+0, sk, skin);
return sk;
}
void skin_calculate(skin *sk)
{
animation_run(sk->anim, apptime());
for (int i = 0; i < arrlen(sk->joints); i++) {
md5joint *md = sk->joints+i;
HMM_Mat4 local = HMM_M4TRS(md->pos.xyz, md->rot, md->scale.xyz);
md->t = HMM_M4TRS(md->pos.xyz, md->rot, md->scale.xyz);
if (md->parent)
local = HMM_MulM4(md->parent->t, local);
md->t = local;
md->t = HMM_MulM4(md->parent->t, md->t);
sk->binds[i] = HMM_MulM4(md->t, sk->invbind[i]);
}
}

View file

@ -35,10 +35,11 @@ typedef struct skin {
md5joint *joints;
HMM_Mat4 *invbind;
HMM_Mat4 binds[50]; /* binds = joint * invbind */
animation *anim;
} skin;
sg_buffer accessor2buffer(cgltf_accessor *a, int type);
skin *make_gltf_skin(cgltf_skin *skin);
skin *make_gltf_skin(cgltf_skin *skin, cgltf_data *data);
void skin_calculate(skin *sk);
sg_buffer float_buffer(float *f, int v);