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
|
add_executable(demo
|
||||||
|
animation.c
|
||||||
gpu.c
|
gpu.c
|
||||||
linear_alg.c
|
linear_alg.c
|
||||||
main.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 },
|
{ 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_mul(mat4_t m, mat4_t n);
|
||||||
mat4_t mat4_lookat(vec3_t camera, vec3_t target, vec3_t up);
|
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_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
|
#endif
|
||||||
@@ -1,3 +1,4 @@
|
|||||||
|
#include "animation.h"
|
||||||
#include "gpu.h"
|
#include "gpu.h"
|
||||||
#include "model_format_glb.h"
|
#include "model_format_glb.h"
|
||||||
|
|
||||||
@@ -71,6 +72,10 @@ int main(int argc, char *argv[])
|
|||||||
gpu_ctx_t gpu;
|
gpu_ctx_t gpu;
|
||||||
gpu_init(&gpu, &gpu_config, model);
|
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 cam = { 0, 4, -4 };
|
||||||
const vec3_t tgt = { 0, 0.5, 0 };
|
const vec3_t tgt = { 0, 0.5, 0 };
|
||||||
mvp_t mvp = {
|
mvp_t mvp = {
|
||||||
@@ -107,6 +112,7 @@ int main(int argc, char *argv[])
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Clean up
|
// Clean up
|
||||||
|
animation_cleanup(&anim);
|
||||||
gpu_cleanup(&gpu);
|
gpu_cleanup(&gpu);
|
||||||
model_cleanup(&model);
|
model_cleanup(&model);
|
||||||
glfwDestroyWindow(window);
|
glfwDestroyWindow(window);
|
||||||
|
|||||||
Reference in new issue
Block a user