From 61d96cf09e2e125f36a94a4c64ed5682fda0df1c Mon Sep 17 00:00:00 2001 From: omnisci3nce <17525998+omnisci3nce@users.noreply.github.com> Date: Sun, 7 Apr 2024 21:46:51 +1000 Subject: its bending but not deforming as expected, looks like rotating around model origin --- examples/skinned_animation/ex_skinned_animation.c | 29 +++++++++++++---------- src/animation.c | 10 ++++---- src/maths/maths.h | 8 ++++--- src/renderer/render.c | 14 ++++++++++- src/resources/gltf.c | 9 +++---- 5 files changed, 45 insertions(+), 25 deletions(-) diff --git a/examples/skinned_animation/ex_skinned_animation.c b/examples/skinned_animation/ex_skinned_animation.c index 43eb715..d0e305e 100644 --- a/examples/skinned_animation/ex_skinned_animation.c +++ b/examples/skinned_animation/ex_skinned_animation.c @@ -64,8 +64,8 @@ int main() { const f32 camera_zoom_speed = 0.10; // animation - // animation_clip track = cube->animations->data[0]; - // f64 total_time = 0.0; + animation_clip track = simple_skin->animations->data[0]; + f64 total_time = 0.0; while (!should_exit(core)) { input_update(&core->input); @@ -73,17 +73,21 @@ int main() { currentFrame = glfwGetTime(); deltaTime = currentFrame - lastFrame; lastFrame = currentFrame; - // total_time += deltaTime; + total_time += deltaTime; // printf("delta time %f\n", deltaTime); - // f64 t = fmod(total_time, 1.0); + f64 t = fmod(total_time, track.rotation->max); // INFO("Total time: %f", t); vec3 translation = VEC3_ZERO; - if (key_is_pressed(KEYCODE_W) || key_is_pressed(KEYCODE_KEY_UP)) { + if (key_is_pressed(KEYCODE_W)) { translation = vec3_mult(game.camera.front, camera_zoom_speed); + } else if (key_is_pressed(KEYCODE_KEY_UP)) { + translation = vec3_mult(game.camera.up, camera_lateral_speed); + } else if (key_is_pressed(KEYCODE_KEY_DOWN)) { + translation = vec3_mult(game.camera.up, -camera_lateral_speed); } else if (key_is_pressed(KEYCODE_S) || key_is_pressed(KEYCODE_KEY_DOWN)) { translation = vec3_mult(game.camera.front, -camera_zoom_speed); - } else if (key_is_pressed(KEYCODE_A) || key_is_pressed(KEYCODE_KEY_LEFT)) { + } else if (key_is_pressed(KEYCODE_A)) { vec3 lateral = vec3_normalise(vec3_cross(game.camera.front, game.camera.up)); translation = vec3_mult(lateral, -camera_lateral_speed); } else if (key_is_pressed(KEYCODE_D) || key_is_pressed(KEYCODE_KEY_RIGHT)) { @@ -94,14 +98,15 @@ int main() { render_frame_begin(&core->renderer); - mat4 model = mat4_translation(VEC3_ZERO); - // quat rot = animation_sample(track.rotation, t).rotation; - quat rot = quat_ident(); - transform tf = transform_create(VEC3_ZERO, rot, 1.0); + // bone rotation + quat rot = animation_sample(track.rotation, t).rotation; - draw_skinned_model(&core->renderer, &game.camera, simple_skin, tf, &our_scene); + m->bones->data[1].transform_components.rotation = rot; + + // quat rot = quat_ident(); + transform tf = transform_create(VEC3_ZERO, quat_ident(), 1.0); - // gfx_backend_draw_frame(&core->renderer, &game.camera, model, NULL); + draw_skinned_model(&core->renderer, &game.camera, simple_skin, tf, &our_scene); render_frame_end(&core->renderer); } diff --git a/src/animation.c b/src/animation.c index de7e9a2..7a79529 100644 --- a/src/animation.c +++ b/src/animation.c @@ -6,14 +6,14 @@ keyframe animation_sample(animation_sampler *sampler, f32 t) { size_t previous_index = 0; f32 previous_time = 0.0; // look forwards - DEBUG("%d\n", sampler->animation.values.kind); - TRACE("Here %d", sampler->animation.n_timestamps); - for (u32 i = 1; i < sampler->animation.n_timestamps; i++) { + // DEBUG("%d\n", sampler->animation.values.kind); + TRACE("Total timestamps %d", sampler->animation.n_timestamps); + for (u32 i = 0; i < sampler->animation.n_timestamps; i++) { f32 current_time = sampler->animation.timestamps[i]; if (current_time > t) { break; } - previous_time = current_time; + previous_time = sampler->animation.timestamps[i]; previous_index = i; } @@ -28,7 +28,7 @@ keyframe animation_sample(animation_sampler *sampler, f32 t) { f32 time_diff = sampler->animation.timestamps[next_index] - sampler->animation.timestamps[previous_index]; - f32 percent = (t - sampler->animation.timestamps[next_index]) / time_diff; + f32 percent = (t - previous_time) / time_diff; quat interpolated_rot = quat_slerp(sampler->animation.values.values[previous_index].rotation, diff --git a/src/maths/maths.h b/src/maths/maths.h index 76531f2..911b9b7 100644 --- a/src/maths/maths.h +++ b/src/maths/maths.h @@ -302,7 +302,7 @@ static inline mat4 mat4_look_at(vec3 position, vec3 target, vec3 up) { #define TRANSFORM_DEFAULT \ ((transform){ .position = VEC3_ZERO, \ - .rotation = (quat){ .x = 0., .y = 0., .z = 0., .w = 0. }, \ + .rotation = (quat){ .x = 0., .y = 0., .z = 0., .w = 1. }, \ .scale = 1.0, \ .is_dirty = false }) @@ -311,8 +311,10 @@ static transform transform_create(vec3 pos, quat rot, f32 scale) { } static inline mat4 transform_to_mat(transform *tf) { - // TODO: rotation - return mat4_mult(mat4_translation(tf->position), mat4_scale(tf->scale)); + mat4 scale = mat4_scale(tf->scale); + mat4 rotation = mat4_rotation(tf->rotation); + mat4 translation = mat4_translation(tf->position); + return mat4_mult(translation, mat4_mult(rotation, scale)); } // --- Sizing asserts diff --git a/src/renderer/render.c b/src/renderer/render.c index 42f6ee4..d7e2d48 100644 --- a/src/renderer/render.c +++ b/src/renderer/render.c @@ -1,6 +1,7 @@ #include #include #include +#include "animation.h" #include "maths_types.h" #include "mem.h" #define STB_IMAGE_IMPLEMENTATION @@ -192,8 +193,19 @@ void draw_skinned_mesh(renderer* ren, mesh* mesh, transform tf, material* mat, m // for now assume correct ordering mat4* bone_transforms = malloc(n_bones * sizeof(mat4)); + mat4 parent = mat4_ident(); for (int bone_i = 0; bone_i < n_bones; bone_i++) { - bone_transforms[bone_i] = mat4_ident(); + transform tf = mesh->bones->data[bone_i].transform_components; + mat4 local = transform_to_mat(&mesh->bones->data[bone_i].transform_components); + bone_transforms[bone_i] = mat4_mult(parent, local); + parent = bone_transforms[bone_i]; + } + + // premultiply the inverses + for (int bone_i = 0; bone_i < n_bones; bone_i++) { + joint j = mesh->bones->data[bone_i]; + // bone_transforms[bone_i] = mat4_mult(bone_transforms[bone_i], j.inverse_bind_matrix); + bone_transforms[bone_i] = mat4_mult(bone_transforms[bone_i], j.inverse_bind_matrix); } glUniformMatrix4fv(glGetUniformLocation(lighting_shader.program_id, "boneMatrices"), n_bones, diff --git a/src/resources/gltf.c b/src/resources/gltf.c index 7efd2bb..7668a49 100644 --- a/src/resources/gltf.c +++ b/src/resources/gltf.c @@ -89,7 +89,7 @@ bool model_load_gltf_str(const char *file_string, const char *filepath, str8 rel vec4u_darray *tmp_joint_indices = vec4u_darray_new(1000); vec4_darray *tmp_weights = vec4_darray_new(1000); joint_darray *tmp_joints = joint_darray_new(256); - vertex_bone_data_darray* tmp_vertex_bone_data = vertex_bone_data_darray_new(1000); + vertex_bone_data_darray *tmp_vertex_bone_data = vertex_bone_data_darray_new(1000); cgltf_options options = { 0 }; cgltf_data *data = NULL; @@ -276,7 +276,7 @@ bool model_load_gltf_str(const char *file_string, const char *filepath, str8 rel mesh mesh = { 0 }; mesh.vertices = vertex_darray_new(10); - mesh.vertex_bone_data =vertex_bone_data_darray_new(1); + mesh.vertex_bone_data = vertex_bone_data_darray_new(1); if (primitive.material != NULL) { for (int i = 0; i < material_darray_len(out_model->materials); i++) { @@ -297,7 +297,8 @@ bool model_load_gltf_str(const char *file_string, const char *filepath, str8 rel vertex_bone_data data; data.joints = tmp_joint_indices->data[i]; data.weights = tmp_weights->data[i]; - vertex_bone_data_darray_push(tmp_vertex_bone_data, data); // Push the temp data that aligns with raw vertices + vertex_bone_data_darray_push(tmp_vertex_bone_data, + data); // Push the temp data that aligns with raw vertices } for (int i = 0; i < tmp_joints->len; i++) { joint data = tmp_joints->data[i]; @@ -330,7 +331,7 @@ bool model_load_gltf_str(const char *file_string, const char *filepath, str8 rel vertex_darray_push(mesh.vertices, vert); if (is_skinned) { - vertex_bone_data vbd = tmp_vertex_bone_data->data[index]; // create a copy + vertex_bone_data vbd = tmp_vertex_bone_data->data[index]; // create a copy vertex_bone_data_darray_push(mesh.vertex_bone_data, vbd); } // for each vertex do the bone data -- cgit v1.2.3-70-g09d2