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); transform *t = js2transform(self);
HMM_Quat rot = HMM_QFromAxisAngle_LH(axis, js2angle(argv[1])); HMM_Quat rot = HMM_QFromAxisAngle_LH(axis, js2angle(argv[1]));
t->rotation = HMM_MulQ(t->rotation,rot); 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; t->dirty = true;
) )
@ -2960,7 +2959,7 @@ JSC_SCALL(os_gltf_skin,
goto CLEANUP; goto CLEANUP;
} }
ret = skin2js(make_gltf_skin(data->skins+0)); ret = skin2js(make_gltf_skin(data->skins+0, data));
CLEANUP: CLEANUP:
cgltf_free(data); 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 *ret = calloc(sizeof(*ret), 1);
animation an = *ret; animation an = *ret;
@ -200,7 +207,7 @@ animation *gltf_anim(cgltf_animation *anim)
for (int i = 0; i < anim->channels_count; i++) { for (int i = 0; i < anim->channels_count; i++) {
cgltf_animation_channel ch = anim->channels[i]; cgltf_animation_channel ch = anim->channels[i];
struct anim_channel ach = (struct anim_channel){0}; struct anim_channel ach = (struct anim_channel){0};
md5joint *md = NULL; md5joint *md = node2joint(sk, ch.target_node, skin);
switch(ch.target_path) { switch(ch.target_path) {
case cgltf_animation_path_type_translation: case cgltf_animation_path_type_translation:
ach.target = &md->pos; ach.target = &md->pos;
@ -218,10 +225,13 @@ animation *gltf_anim(cgltf_animation *anim)
arrput(an.channels, ach); arrput(an.channels, ach);
} }
an.time = 0;
*ret = an; *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); int n = cgltf_accessor_unpack_floats(skin->inverse_bind_matrices, NULL, 0);
struct skin *sk = NULL; struct skin *sk = NULL;
@ -236,10 +246,13 @@ skin *make_gltf_skin(cgltf_skin *skin)
for (int i = 0; i < skin->joints_count; i++) { for (int i = 0; i < skin->joints_count; i++) {
cgltf_node *n = skin->joints[i]; cgltf_node *n = skin->joints[i];
int idx = n-skin->skeleton; md5joint *j = sk->joints+i;
int parent_idx = n->parent-skin->skeleton;
md5joint *j = sk->joints+idx; if (n == skin->skeleton)
j->parent = sk->joints+parent_idx; j->parent = NULL;
else
j->parent = node2joint(sk, n->parent, skin);
for (int i = 0; i < 3; i++) { for (int i = 0; i < 3; i++) {
j->pos.e[i] = n->translation[i]; j->pos.e[i] = n->translation[i];
j->scale.e[i] = n->scale[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]; j->rot.e[i] = n->rotation[i];
} }
sk->anim = gltf_anim(data->animations+0, sk, skin);
return sk; return sk;
} }
void skin_calculate(skin *sk) void skin_calculate(skin *sk)
{ {
animation_run(sk->anim, apptime());
for (int i = 0; i < arrlen(sk->joints); i++) { for (int i = 0; i < arrlen(sk->joints); i++) {
md5joint *md = 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) if (md->parent)
local = HMM_MulM4(md->parent->t, local); md->t = HMM_MulM4(md->parent->t, md->t);
md->t = local;
sk->binds[i] = HMM_MulM4(md->t, sk->invbind[i]); sk->binds[i] = HMM_MulM4(md->t, sk->invbind[i]);
} }
} }

View file

@ -35,10 +35,11 @@ typedef struct skin {
md5joint *joints; md5joint *joints;
HMM_Mat4 *invbind; HMM_Mat4 *invbind;
HMM_Mat4 binds[50]; /* binds = joint * invbind */ HMM_Mat4 binds[50]; /* binds = joint * invbind */
animation *anim;
} skin; } skin;
sg_buffer accessor2buffer(cgltf_accessor *a, int type); 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); void skin_calculate(skin *sk);
sg_buffer float_buffer(float *f, int v); sg_buffer float_buffer(float *f, int v);