summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/animation.h8
-rw-r--r--src/maths/maths_types.h6
-rw-r--r--src/renderer/render.c62
-rw-r--r--src/renderer/render_types.h2
-rw-r--r--src/resources/gltf.c83
5 files changed, 107 insertions, 54 deletions
diff --git a/src/animation.h b/src/animation.h
index 18d3ba9..9d5d03b 100644
--- a/src/animation.h
+++ b/src/animation.h
@@ -31,6 +31,7 @@ typedef struct keyframes {
typedef struct joint {
char* name; // optional
transform transform_components;
+ mat4 inverse_bind_matrix;
mat4 local_transform;
} joint;
@@ -61,4 +62,11 @@ typedef struct animation_clip {
animation_sampler* weights;
} animation_clip;
+typedef struct skinned_animation {
+ mat4* joint_matrices;
+ size_t n_joints;
+} skinned_animation;
+
+// void animation_update_joint_matrices(animation_clip* )
+
void animation_play(animation_clip* clip); \ No newline at end of file
diff --git a/src/maths/maths_types.h b/src/maths/maths_types.h
index 6d38fc7..53cac55 100644
--- a/src/maths/maths_types.h
+++ b/src/maths/maths_types.h
@@ -64,4 +64,8 @@ typedef struct transform {
typedef struct vec4i {
i32 x, y, z, w;
-} vec4i; \ No newline at end of file
+} vec4i;
+
+typedef struct vec4u {
+ u32 x, y, z, w;
+} vec4u; \ No newline at end of file
diff --git a/src/renderer/render.c b/src/renderer/render.c
index e420043..42f6ee4 100644
--- a/src/renderer/render.c
+++ b/src/renderer/render.c
@@ -97,6 +97,7 @@ void default_material_init() {
}
void model_destroy(model* model) {
+ TRACE("Freeing all data for model %s", model->name);
arena_free_all(&model->animation_data_arena);
arena_free_storage(&model->animation_data_arena);
mesh_darray_free(model->meshes);
@@ -175,19 +176,31 @@ void draw_skinned_mesh(renderer* ren, mesh* mesh, transform tf, material* mat, m
// bind textures
bind_texture(lighting_shader, &mat->diffuse_texture, 0); // bind to slot 0
bind_texture(lighting_shader, &mat->specular_texture, 1); // bind to slot 1
- uniform_f32(lighting_shader.program_id, "material.shininess", 32.);
- // upload model transform
+ // Uniforms
+ uniform_f32(lighting_shader.program_id, "material.shininess", 32.);
mat4 trans = mat4_translation(tf.position);
mat4 rot = mat4_rotation(tf.rotation);
mat4 scale = mat4_scale(tf.scale);
mat4 model_tf = mat4_mult(trans, mat4_mult(rot, scale));
-
uniform_mat4f(lighting_shader.program_id, "model", &model_tf);
- // upload view & projection matrices
uniform_mat4f(lighting_shader.program_id, "view", view);
uniform_mat4f(lighting_shader.program_id, "projection", proj);
+ // bone transforms
+ size_t n_bones = mesh->bones->len;
+
+ // for now assume correct ordering
+ mat4* bone_transforms = malloc(n_bones * sizeof(mat4));
+ for (int bone_i = 0; bone_i < n_bones; bone_i++) {
+ bone_transforms[bone_i] = mat4_ident();
+ }
+
+ glUniformMatrix4fv(glGetUniformLocation(lighting_shader.program_id, "boneMatrices"), n_bones,
+ GL_FALSE, &bone_transforms->data[0]);
+
+ free(bone_transforms);
+
// draw triangles
u32 num_vertices = vertex_darray_len(mesh->vertices);
draw_primitives(CEL_PRIMITIVE_TOPOLOGY_TRIANGLE, 0, num_vertices);
@@ -201,11 +214,11 @@ void draw_skinned_model(renderer* ren, camera* cam, model* model, transform tf,
set_shader(ren->skinned);
// set camera uniform
- uniform_vec3f(ren->blinn_phong.program_id, "viewPos", &cam->position);
+ uniform_vec3f(ren->skinned.program_id, "viewPos", &cam->position);
// set light uniforms
- dir_light_upload_uniforms(ren->blinn_phong, &scene->dir_light);
+ dir_light_upload_uniforms(ren->skinned, &scene->dir_light);
for (int i = 0; i < scene->n_point_lights; i++) {
- point_light_upload_uniforms(ren->blinn_phong, &scene->point_lights[i], '0' + i);
+ point_light_upload_uniforms(ren->skinned, &scene->point_lights[i], '0' + i);
}
for (size_t i = 0; i < mesh_darray_len(model->meshes); i++) {
@@ -213,7 +226,8 @@ void draw_skinned_model(renderer* ren, camera* cam, model* model, transform tf,
if (vertex_darray_len(m->vertices) == 0) {
continue;
}
- material* mat = &model->materials->data[m->material_index];
+ // material* mat = &model->materials->data[m->material_index];
+ material* mat = &DEFAULT_MATERIAL;
draw_skinned_mesh(ren, m, tf, mat, &view, &proj);
}
}
@@ -272,21 +286,28 @@ void model_upload_meshes(renderer* ren, model* model) {
// + j].uv.y;
// }
// }
- size_t vertex_size = mesh.is_skinned
- ? sizeof(vec3) * 2 + sizeof(vec2) + sizeof(u32) * 4 + sizeof(vec4)
- : sizeof(vec3) * 2 + sizeof(vec2);
- if (!mesh.is_skinned) {
- printf("sizeof(vertex) -> %ld, vertex_size -> %ld\n", sizeof(vertex), vertex_size);
+ size_t static_vertex_size = 2 * sizeof(vec3) + sizeof(vec2);
+ size_t skinned_vertex_size = 2 * sizeof(vec3) + sizeof(vec2) + 4 * sizeof(u32) + sizeof(vec4);
+ size_t vertex_size = mesh.is_skinned ? skinned_vertex_size : static_vertex_size;
+
+ TRACE("sizeof(vertex) -> %ld, vertex_size -> %ld\n", sizeof(vertex), vertex_size);
+ if (mesh.is_skinned) {
+ assert(vertex_size == (12 + 12 + 8 + 16 + 16));
+ } else {
assert(vertex_size == sizeof(vertex));
+ assert(vertex_size == 8 * sizeof(float));
}
size_t buffer_size = vertex_size * num_vertices;
u8* bytes = malloc(buffer_size);
for (int i = 0; i < num_vertices; i++) {
u8* p = bytes + vertex_size * i;
- u8* bone_data_offset = p + sizeof(u32) * 4 + sizeof(vec4);
+ u8* bone_data_offset = p + static_vertex_size;
memcpy(p, &mesh.vertices->data[i], sizeof(vertex));
- memcpy(bone_data_offset, &mesh.vertex_bone_data->data[i], sizeof(vertex_bone_data));
+ if (mesh.is_skinned) {
+ // printf("")
+ memcpy(bone_data_offset, &mesh.vertex_bone_data->data[i], sizeof(vertex_bone_data));
+ }
}
// 4. upload data
@@ -295,17 +316,22 @@ void model_upload_meshes(renderer* ren, model* model) {
// 5. cont. set mesh vertex layout
glBindVertexArray(model->meshes->data[mesh_i].vao);
// position attribute
- glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void*)0);
+ glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, vertex_size, (void*)0);
glEnableVertexAttribArray(0);
// normal vector attribute
- glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void*)(3 * sizeof(float)));
+ glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, vertex_size, (void*)(3 * sizeof(float)));
glEnableVertexAttribArray(1);
// tex coords
- glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, 8 * sizeof(float), (void*)(6 * sizeof(float)));
+ glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, vertex_size, (void*)(6 * sizeof(float)));
glEnableVertexAttribArray(2);
// skinning (optional)
if (mesh.is_skinned) {
+ glEnableVertexAttribArray(3);
+ glVertexAttribIPointer(3, 4, GL_INT, vertex_size, (void*)(8 * sizeof(float)));
+
+ glEnableVertexAttribArray(4);
+ glVertexAttribPointer(4, 4, GL_FLOAT, GL_FALSE, vertex_size, (void*)(12 * sizeof(float)));
}
}
diff --git a/src/renderer/render_types.h b/src/renderer/render_types.h
index 61571e1..bfed18d 100644
--- a/src/renderer/render_types.h
+++ b/src/renderer/render_types.h
@@ -120,7 +120,7 @@ typedef struct vertex {
} vertex;
typedef struct vertex_bone_data {
- vec4i joints; /** @brief 4 indices of joints that influence vectors position */
+ vec4u joints; /** @brief 4 indices of joints that influence vectors position */
vec4 weights; /** @brief weight (0,1) of each joint */
} vertex_bone_data;
diff --git a/src/resources/gltf.c b/src/resources/gltf.c
index c7c1f55..7efd2bb 100644
--- a/src/resources/gltf.c
+++ b/src/resources/gltf.c
@@ -28,7 +28,7 @@ typedef struct face face;
KITC_DECL_TYPED_ARRAY(vec3)
KITC_DECL_TYPED_ARRAY(vec2)
KITC_DECL_TYPED_ARRAY(u32)
-KITC_DECL_TYPED_ARRAY(vec4i)
+KITC_DECL_TYPED_ARRAY(vec4u)
KITC_DECL_TYPED_ARRAY(vec4)
KITC_DECL_TYPED_ARRAY(face)
// KITC_DECL_TYPED_ARRAY(joint)
@@ -86,9 +86,10 @@ bool model_load_gltf_str(const char *file_string, const char *filepath, str8 rel
vec3_darray *tmp_positions = vec3_darray_new(1000);
vec3_darray *tmp_normals = vec3_darray_new(1000);
vec2_darray *tmp_uvs = vec2_darray_new(1000);
- vec4i_darray *tmp_joint_indices = vec4i_darray_new(1000);
+ 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);
cgltf_options options = { 0 };
cgltf_data *data = NULL;
@@ -118,6 +119,8 @@ bool model_load_gltf_str(const char *file_string, const char *filepath, str8 rel
size_t num_joints = gltf_skin->joints_count;
DEBUG("# Joints %d", num_joints);
+ cgltf_accessor *gltf_inverse_bind_matrices = gltf_skin->inverse_bind_matrices;
+
// for each one we'll spit out a joint
for (size_t i = 0; i < num_joints; i++) {
cgltf_node *joint_node = gltf_skin->joints[i];
@@ -139,6 +142,8 @@ bool model_load_gltf_str(const char *file_string, const char *filepath, str8 rel
// TODO: support scaling as vec instead of float
}
joint_i.local_transform = transform_to_mat(&joint_i.transform_components);
+ cgltf_accessor_read_float(gltf_inverse_bind_matrices, i, &joint_i.inverse_bind_matrix.data[0],
+ 16);
joint_darray_push(tmp_joints, joint_i);
}
}
@@ -238,7 +243,7 @@ bool model_load_gltf_str(const char *file_string, const char *filepath, str8 rel
cgltf_accessor *accessor = attribute.data;
assert(accessor->component_type == cgltf_component_type_r_16u);
assert(accessor->type == cgltf_type_vec4);
- vec4i joint_indices;
+ vec4u joint_indices;
vec4 joints_as_floats;
for (cgltf_size v = 0; v < accessor->count; ++v) {
cgltf_accessor_read_float(accessor, v, &joints_as_floats.x, 4);
@@ -246,9 +251,9 @@ bool model_load_gltf_str(const char *file_string, const char *filepath, str8 rel
joint_indices.y = (u32)joints_as_floats.y;
joint_indices.z = (u32)joints_as_floats.z;
joint_indices.w = (u32)joints_as_floats.w;
- // printf("Joints affecting %d %d %d %d\n", joint_indices.x, joint_indices.y,
- // joint_indices.z, joint_indices.w);
- vec4i_darray_push(tmp_joint_indices, joint_indices);
+ printf("Joints affecting vertex %d : %d %d %d %d\n", v, joint_indices.x, joint_indices.y,
+ joint_indices.z, joint_indices.w);
+ vec4u_darray_push(tmp_joint_indices, joint_indices);
}
} else if (attribute.type == cgltf_attribute_type_weights) {
@@ -260,7 +265,8 @@ bool model_load_gltf_str(const char *file_string, const char *filepath, str8 rel
for (cgltf_size v = 0; v < accessor->count; ++v) {
vec4 weights;
cgltf_accessor_read_float(accessor, v, &weights.x, 4);
- // printf("Weights affecting %f %f %f %f\n", weights.x, weights.y, weights.z, weights.w);
+ printf("Weights affecting vertex %d : %f %f %f %f\n", v, weights.x, weights.y, weights.z,
+ weights.w);
vec4_darray_push(tmp_weights, weights);
}
} else {
@@ -270,9 +276,38 @@ 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);
+
+ if (primitive.material != NULL) {
+ for (int i = 0; i < material_darray_len(out_model->materials); i++) {
+ printf("%s vs %s \n", primitive.material->name, out_model->materials->data[i].name);
+ if (strcmp(primitive.material->name, out_model->materials->data[i].name) == 0) {
+ TRACE("Found material");
+ mesh.material_index = i;
+ break;
+ }
+ }
+ }
+
+ if (is_skinned) {
+ mesh.is_skinned = true;
+ // mesh.vertex_bone_data = vertex_bone_data_darray_new(tmp_joint_indices->len);
+ mesh.bones = joint_darray_new(tmp_joints->len);
+ for (int i = 0; i < tmp_joint_indices->len; i++) {
+ 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
+ }
+ for (int i = 0; i < tmp_joints->len; i++) {
+ joint data = tmp_joints->data[i];
+ joint_darray_push(mesh.bones, data);
+ }
+ }
cgltf_accessor *indices = primitive.indices;
if (primitive.indices > 0) {
+ WARN("indices!");
mesh.has_indices = true;
mesh.indices = malloc(indices->count * sizeof(u32));
@@ -293,45 +328,25 @@ bool model_load_gltf_str(const char *file_string, const char *filepath, str8 rel
vert.normal = tmp_normals->data[index];
vert.uv = tmp_uvs->data[index];
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_darray_push(mesh.vertex_bone_data, vbd);
+ }
+ // for each vertex do the bone data
}
} else {
mesh.has_indices = false;
return false; // TODO
}
- if (primitive.material != NULL) {
- for (int i = 0; i < material_darray_len(out_model->materials); i++) {
- printf("%s vs %s \n", primitive.material->name, out_model->materials->data[i].name);
- if (strcmp(primitive.material->name, out_model->materials->data[i].name) == 0) {
- TRACE("Found material");
- mesh.material_index = i;
- break;
- }
- }
- }
-
- if (is_skinned) {
- mesh.vertex_bone_data = vertex_bone_data_darray_new(tmp_joint_indices->len);
- mesh.bones = joint_darray_new(tmp_joints->len);
- for (int i = 0; i < tmp_joint_indices->len; i++) {
- vertex_bone_data data;
- data.joints = tmp_joint_indices->data[i];
- data.weights =tmp_weights->data[i];
- vertex_bone_data_darray_push(mesh.vertex_bone_data, data);
- }
- for (int i = 0; i < tmp_joints->len; i++) {
- joint data = tmp_joints->data[i];
- joint_darray_push(mesh.bones, data);
- }
- }
-
mesh_darray_push(out_model->meshes, mesh);
// clear data for each mesh
vec3_darray_clear(tmp_positions);
vec3_darray_clear(tmp_normals);
vec2_darray_free(tmp_uvs);
- vec4i_darray_clear(tmp_joint_indices);
+ vec4u_darray_clear(tmp_joint_indices);
vec4_darray_clear(tmp_weights);
joint_darray_clear(tmp_joints);
}