Implement bone matrix computation
This commit is contained in:
1 parent
e81061ad22
commit
998d5e88e1
6 files changed
+132
No files matched your search
@@ -37,6 +37,7 @@ add_shaders(shaders
|
||||
)
|
||||
|
||||
add_executable(demo
|
||||
animation.c
|
||||
gpu.c
|
||||
linear_alg.c
|
||||
main.c
|
||||
|
||||
+50
@@ -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
@@ -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
|
||||
@@ -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 },
|
||||
};
|
||||
}
|
||||
@@ -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
|
||||
@@ -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);
|
||||
|
||||
Reference in new issue
Block a user