Implement bone matrix computation

This commit is contained in:
Camden Dixie O'Brien committed 2025-10-01 21:05:52 +01:00
1 parent e81061ad22
commit 998d5e88e1
6 files changed
+132

No files matched your search

+1
View File
@@ -37,6 +37,7 @@ add_shaders(shaders
)
add_executable(demo
animation.c
gpu.c
linear_alg.c
main.c
+50
View File
@@ -0,0 +1,50 @@
#include "animation.h"
#include <assert.h>
#include <stdlib.h>
static mat4_t bone_transform(bone_t bone)
{
return mat4_mul(
mat4_translate_vec3(bone.translation),
mat4_mul(
mat4_rotate_quaternion(bone.rotation),
mat4_scale_vec3(bone.scale)));
}
static void compute_bone_matrices(
size_t bone_count, const bone_t *bones,
const mat4_t *inverse_bind_matrices, mat4_t *matrices)
{
matrices[0] = bone_transform(bones[0]);
for (unsigned i = 1; i < bone_count; ++i) {
const mat4_t transform = bone_transform(bones[i]);
assert(bones[i].parent < bone_count);
matrices[i] = mat4_mul(matrices[bones[i].parent], transform);
}
for (unsigned i = 0; i < bone_count; ++i)
matrices[i] = mat4_mul(matrices[i], inverse_bind_matrices[i]);
}
animation_state_t animation_init(const model_t *model)
{
mat4_t *bone_matrices = calloc(model->bone_count, sizeof(mat4_t));
assert(bone_matrices != nullptr);
return (animation_state_t) { .bone_matrices = bone_matrices };
}
void animation_cleanup(animation_state_t *state)
{
if (state->bone_matrices != nullptr) {
free(state->bone_matrices);
state->bone_matrices = nullptr;
}
}
void animation_update(animation_state_t state, const model_t *model)
{
compute_bone_matrices(
model->bone_count, model->bones, model->inverse_bind_matrices,
state.bone_matrices);
}
+15
View File
@@ -0,0 +1,15 @@
#ifndef ANIMATION_H
#define ANIMATION_H
#include "model.h"
typedef struct {
mat4_t *bone_matrices;
} animation_state_t;
animation_state_t animation_init(const model_t *model);
void animation_cleanup(animation_state_t *state);
void animation_update(animation_state_t state, const model_t *model);
#endif
+57
View File
@@ -74,3 +74,60 @@ mat4_t mat4_perspective(float aspect, float fov, float near, float far)
{ 0, 0, -far * near / (far - near), 0 },
};
}
mat4_t mat4_translate_vec3(vec3_t v)
{
return (mat4_t) {
{ 1, 0, 0, 0 },
{ 0, 1, 0, 0 },
{ 0, 0, 1, 0 },
{ v.x, v.y, v.z, 1 },
};
}
mat4_t mat4_scale_vec3(vec3_t v)
{
return (mat4_t) {
{ v.x, 0, 0, 0 },
{ 0, v.y, 0, 0 },
{ 0, 0, v.z, 0 },
{ 0, 0, 0, 1 },
};
}
mat4_t mat4_rotate_quaternion(vec4_t q)
{
const float xx = q.x * q.x;
const float xy = q.x * q.y;
const float xz = q.x * q.z;
const float xw = q.x * q.w;
const float yy = q.y * q.y;
const float yz = q.y * q.z;
const float yw = q.y * q.w;
const float zz = q.z * q.z;
const float zw = q.z * q.w;
return (mat4_t) {
{
1 - 2 * (yy + zz),
2 * (xy + zw),
2 * (xz - yw),
0,
},
{
2 * (xy - zw),
1 - 2 * (xx + zz),
2 * (yz + xw),
0,
},
{
2 * (xz + yw),
2 * (yz - xw),
1 - 2 * (xx + yy),
0,
},
{ 0, 0, 0, 1 },
};
}
+3
View File
@@ -80,5 +80,8 @@ vec3_t vec3_cross(vec3_t v, vec3_t u);
mat4_t mat4_mul(mat4_t m, mat4_t n);
mat4_t mat4_lookat(vec3_t camera, vec3_t target, vec3_t up);
mat4_t mat4_perspective(float aspect, float fov, float near, float far);
mat4_t mat4_translate_vec3(vec3_t v);
mat4_t mat4_scale_vec3(vec3_t v);
mat4_t mat4_rotate_quaternion(vec4_t q);
#endif
+6
View File
@@ -1,3 +1,4 @@
#include "animation.h"
#include "gpu.h"
#include "model_format_glb.h"
@@ -71,6 +72,10 @@ int main(int argc, char *argv[])
gpu_ctx_t gpu;
gpu_init(&gpu, &gpu_config, model);
// Initialise animation
animation_state_t anim = animation_init(&model);
animation_update(anim, &model);
const vec3_t cam = { 0, 4, -4 };
const vec3_t tgt = { 0, 0.5, 0 };
mvp_t mvp = {
@@ -107,6 +112,7 @@ int main(int argc, char *argv[])
}
// Clean up
animation_cleanup(&anim);
gpu_cleanup(&gpu);
model_cleanup(&model);
glfwDestroyWindow(window);