summaryrefslogtreecommitdiff
path: root/src/resources/gltf.c
diff options
context:
space:
mode:
authoromniscient <17525998+omnisci3nce@users.noreply.github.com>2024-08-13 20:29:27 +1000
committeromniscient <17525998+omnisci3nce@users.noreply.github.com>2024-08-13 20:29:27 +1000
commit567d384b698151e287e31140709c93f1b92e6db4 (patch)
treee00975124d3f002a8aaa22e85475d913c6950346 /src/resources/gltf.c
parent13949ca02bcf9fcdfcc48ea7949f617553a260b6 (diff)
loading joints and animations
Diffstat (limited to 'src/resources/gltf.c')
-rw-r--r--src/resources/gltf.c504
1 files changed, 233 insertions, 271 deletions
diff --git a/src/resources/gltf.c b/src/resources/gltf.c
index aa4fba5..f788043 100644
--- a/src/resources/gltf.c
+++ b/src/resources/gltf.c
@@ -34,12 +34,13 @@ typedef struct face face;
KITC_DECL_TYPED_ARRAY(Vec3)
KITC_DECL_TYPED_ARRAY(Vec2)
KITC_DECL_TYPED_ARRAY(Vec4u)
+KITC_DECL_TYPED_ARRAY(Vec4i)
KITC_DECL_TYPED_ARRAY(Vec4)
KITC_DECL_TYPED_ARRAY(face)
-size_t GLTF_LoadMaterials(cgltf_data *data, Str8 relative_path, Material_darray *out_materials);
+size_t GLTF_LoadMaterials(cgltf_data* data, Str8 relative_path, Material_darray* out_materials);
-ModelHandle ModelLoad_gltf(const char *path, bool invert_texture_y) {
+ModelHandle ModelLoad_gltf(const char* path, bool invert_texture_y) {
size_t arena_size = MB(1);
arena scratch = arena_create(malloc(arena_size), arena_size);
@@ -48,10 +49,10 @@ ModelHandle ModelLoad_gltf(const char *path, bool invert_texture_y) {
if (!relative_path.has_value) {
WARN("Couldnt get a relative path for the path to use for loading materials & textures later");
}
- const char *file_string = string_from_file(path);
+ const char* file_string = string_from_file(path);
ModelHandle handle;
- Model *model = Model_pool_alloc(&g_core.models, &handle);
+ Model* model = Model_pool_alloc(&g_core.models, &handle);
model->name = Str8_cstr_view(path);
bool success =
@@ -68,7 +69,7 @@ ModelHandle ModelLoad_gltf(const char *path, bool invert_texture_y) {
}
void assert_path_type_matches_component_type(cgltf_animation_path_type target_path,
- cgltf_accessor *output) {
+ cgltf_accessor* output) {
if (target_path == cgltf_animation_path_type_rotation) {
assert(output->component_type == cgltf_component_type_r_32f);
assert(output->type == cgltf_type_vec4);
@@ -77,7 +78,7 @@ void assert_path_type_matches_component_type(cgltf_animation_path_type target_pa
// TODO: Brainstorm how I can make this simpler and break it up into more testable pieces
-void load_position_components(Vec3_darray *positions, cgltf_accessor *accessor) {
+void load_position_components(Vec3_darray* positions, cgltf_accessor* accessor) {
TRACE("Loading %d vec3 position components", accessor->count);
CASSERT_MSG(accessor->component_type == cgltf_component_type_r_32f,
"Positions components are floats");
@@ -90,7 +91,7 @@ void load_position_components(Vec3_darray *positions, cgltf_accessor *accessor)
}
}
-void load_normal_components(Vec3_darray *normals, cgltf_accessor *accessor) {
+void load_normal_components(Vec3_darray* normals, cgltf_accessor* accessor) {
TRACE("Loading %d vec3 normal components", accessor->count);
CASSERT_MSG(accessor->component_type == cgltf_component_type_r_32f,
"Normal vector components are floats");
@@ -103,7 +104,7 @@ void load_normal_components(Vec3_darray *normals, cgltf_accessor *accessor) {
}
}
-void load_texcoord_components(Vec2_darray *texcoords, cgltf_accessor *accessor) {
+void load_texcoord_components(Vec2_darray* texcoords, cgltf_accessor* accessor) {
TRACE("Load texture coordinates from accessor");
CASSERT(accessor->component_type == cgltf_component_type_r_32f);
CASSERT_MSG(accessor->type == cgltf_type_vec2, "Texture coordinates should be a vec2");
@@ -118,7 +119,7 @@ void load_texcoord_components(Vec2_darray *texcoords, cgltf_accessor *accessor)
}
}
-void load_joint_index_components(Vec4u_darray *joint_indices, cgltf_accessor *accessor) {
+void load_joint_index_components(Vec4u_darray* joint_indices, cgltf_accessor* accessor) {
TRACE("Load joint indices from accessor");
CASSERT(accessor->component_type == cgltf_component_type_r_16u);
CASSERT_MSG(accessor->type == cgltf_type_vec4, "Joint indices should be a vec4");
@@ -136,26 +137,24 @@ void load_joint_index_components(Vec4u_darray *joint_indices, cgltf_accessor *ac
}
}
-bool model_load_gltf_str(const char *file_string, const char *filepath, Str8 relative_path,
- Model *out_model, bool invert_textures_y) {
+bool model_load_gltf_str(const char* file_string, const char* filepath, Str8 relative_path,
+ Model* out_model, bool invert_textures_y) {
TRACE("Load GLTF from string");
// Setup temps
- Vec3_darray *tmp_positions = Vec3_darray_new(1000);
- Vec3_darray *tmp_normals = Vec3_darray_new(1000);
- Vec2_darray *tmp_uvs = Vec2_darray_new(1000);
- Vec4u_darray *tmp_joint_indices = Vec4u_darray_new(1000);
- Vec4_darray *tmp_weights = Vec4_darray_new(1000);
- Material_darray *tmp_materials = Material_darray_new(1);
- Mesh_darray *tmp_meshes = Mesh_darray_new(1);
- u32_darray *tmp_material_indexes = u32_darray_new(1);
- Joint_darray *tmp_joints = Joint_darray_new(256);
-
- // FIXME
- // vertex_bone_data_darray *tmp_vertex_bone_data = vertex_bone_data_darray_new(1000);
+ 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);
+ Vec4_darray* tmp_weights = Vec4_darray_new(1000);
+ Material_darray* tmp_materials = Material_darray_new(1);
+ Mesh_darray* tmp_meshes = Mesh_darray_new(1);
+ u32_darray* tmp_material_indexes = u32_darray_new(1);
+
+ Joint_darray* joints = Joint_darray_new(256);
cgltf_options options = { 0 };
- cgltf_data *data = NULL;
+ cgltf_data* data = NULL;
cgltf_result result = cgltf_parse_file(&options, filepath, &data);
if (result != cgltf_result_success) {
WARN("gltf load failed");
@@ -166,53 +165,63 @@ bool model_load_gltf_str(const char *file_string, const char *filepath, Str8 rel
cgltf_load_buffers(&options, data, filepath);
DEBUG("loaded buffers");
- // // --- Skin
- // size_t num_skins = data->skins_count;
- // bool is_skinned = false;
- // if (num_skins == 1) {
- // is_skinned = true;
- // } else if (num_skins > 1) {
- // WARN("GLTF files with more than 1 skin are not supported");
- // return false;
- // }
-
- // if (is_skinned) {
- // cgltf_skin *gltf_skin = data->skins;
- // DEBUG("loading skin %s", gltf_skin->name);
- // 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];
-
- // joint joint_i = { .name = "testjoint" };
- // if (joint_node->children_count > 0 && !joint_node->has_translation &&
- // !joint_node->has_rotation) {
- // WARN("joint Node with index %d is the root node", i);
- // joint_i.transform_components = TRANSFORM_DEFAULT;
- // } else {
- // TRACE("Storing joint transform");
- // joint_i.transform_components = TRANSFORM_DEFAULT;
- // if (joint_node->has_translation) {
- // memcpy(&joint_i.transform_components.position, &joint_node->translation, 3 *
- // sizeof(f32));
- // }
- // if (joint_node->has_rotation) {
- // memcpy(&joint_i.transform_components.rotation, &joint_node->rotation, 4 *
- // sizeof(f32));
- // }
- // // 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);
- // }
- // }
+ // --- Skin
+ size_t num_skins = data->skins_count;
+ bool is_skinned = false;
+ if (num_skins == 1) {
+ is_skinned = true;
+ } else if (num_skins > 1) {
+ WARN("GLTF files with more than 1 skin are not supported");
+ return false;
+ }
+
+ if (is_skinned) {
+ cgltf_skin* gltf_skin = data->skins;
+ DEBUG("loading skin %s", gltf_skin->name);
+ size_t num_joints = gltf_skin->joints_count;
+ DEBUG("# Joints %d", num_joints);
+
+ // Create our data that will be placed onto the model
+ Armature armature = { .arena = arena_create(malloc(MB(1)), MB(1)) };
+ printf("Skin %s\n", gltf_skin->name);
+ armature.label = "test_skin";
+ // armature.label = Clone_cstr(&armature.arena, gltf_skin->name);
+ armature.joints = joints; // ! Make sure not to free this
+
+ 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++) {
+ TRACE("Joint %d", i);
+ cgltf_node* joint_node = gltf_skin->joints[i];
+ Joint joint_i = { .debug_label = "test_joint" };
+
+ if (joint_node->children_count > 0 && !joint_node->has_translation &&
+ !joint_node->has_rotation) {
+ WARN("joint Node with index %d is the root node", i);
+ joint_i.transform_components = TRANSFORM_DEFAULT;
+ } else {
+ TRACE("Storing joint transform");
+ joint_i.transform_components = TRANSFORM_DEFAULT;
+ if (joint_node->has_translation) {
+ memcpy(&joint_i.transform_components.position, &joint_node->translation, 3 * sizeof(f32));
+ }
+ if (joint_node->has_rotation) {
+ memcpy(&joint_i.transform_components.rotation, &joint_node->rotation, 4 * sizeof(f32));
+ }
+ if (joint_node->has_scale) {
+ memcpy(&joint_i.transform_components.scale, &joint_node->scale, 3 * sizeof(f32));
+ }
+ }
+ 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(armature.joints, joint_i);
+ }
+
+ out_model->armature = armature;
+ out_model->has_joints = true;
+ }
// --- Materials
size_t num_materials = GLTF_LoadMaterials(data, relative_path, tmp_materials);
@@ -231,33 +240,31 @@ bool model_load_gltf_str(const char *file_string, const char *filepath, Str8 rel
for (cgltf_size a = 0; a < primitive.attributes_count; a++) {
cgltf_attribute attribute = primitive.attributes[a];
if (attribute.type == cgltf_attribute_type_position) {
- cgltf_accessor *accessor = attribute.data;
+ cgltf_accessor* accessor = attribute.data;
load_position_components(tmp_positions, accessor);
} else if (attribute.type == cgltf_attribute_type_normal) {
- cgltf_accessor *accessor = attribute.data;
+ cgltf_accessor* accessor = attribute.data;
load_normal_components(tmp_normals, accessor);
} else if (attribute.type == cgltf_attribute_type_texcoord) {
- cgltf_accessor *accessor = attribute.data;
+ cgltf_accessor* accessor = attribute.data;
load_texcoord_components(tmp_uvs, accessor);
} else if (attribute.type == cgltf_attribute_type_joints) {
TRACE("Load joint indices from accessor");
- cgltf_accessor *accessor = attribute.data;
+ cgltf_accessor* accessor = attribute.data;
load_joint_index_components(tmp_joint_indices, accessor);
} else if (attribute.type == cgltf_attribute_type_weights) {
- // FIXME: weights
- // TRACE("Load joint weights from accessor");
- // cgltf_accessor *accessor = attribute.data;
- // assert(accessor->component_type == cgltf_component_type_r_32f);
- // assert(accessor->type == cgltf_type_vec4);
-
- // for (cgltf_size v = 0; v < accessor->count; ++v) {
- // vec4 weights;
- // cgltf_accessor_read_float(accessor, v, &weights.x, 4);
- // 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);
- // }
+ TRACE("Load joint weights from accessor");
+ cgltf_accessor* accessor = attribute.data;
+ CASSERT(accessor->component_type == cgltf_component_type_r_32f);
+ CASSERT(accessor->type == cgltf_type_vec4);
+
+ for (cgltf_size v = 0; v < accessor->count; ++v) {
+ Vec4 weights;
+ cgltf_accessor_read_float(accessor, v, &weights.x, 4);
+ 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 {
WARN("Unhandled cgltf_attribute_type: %s. skipping..", attribute.name);
}
@@ -280,28 +287,8 @@ bool model_load_gltf_str(const char *file_string, const char *filepath, Str8 rel
TRACE("Vertex data has been loaded");
- // // FIXME
- // // 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);
- // // }
- // // }
-
- bool has_indices = false;
- Vertex_darray *geo_vertices = Vertex_darray_new(3);
- u32_darray *geo_indices = u32_darray_new(0);
+ Vertex_darray* geo_vertices = Vertex_darray_new(3);
+ u32_darray* geo_indices = u32_darray_new(0);
// Store vertices
printf("Positions %d Normals %d UVs %d\n", tmp_positions->len, tmp_normals->len,
@@ -311,19 +298,25 @@ bool model_load_gltf_str(const char *file_string, const char *filepath, Str8 rel
bool has_normals = tmp_normals->len > 0;
bool has_uvs = tmp_uvs->len > 0;
for (u32 v_i = 0; v_i < tmp_positions->len; v_i++) {
- Vertex v = { .static_3d = {
- .position = tmp_positions->data[v_i],
- .normal = has_normals ? tmp_normals->data[v_i] : VEC3_ZERO,
- .tex_coords = has_uvs ? tmp_uvs->data[v_i] : vec2_create(0., 0.),
- } };
+ Vertex v = { 0 };
+ if (is_skinned) {
+ v.skinned_3d.position = tmp_positions->data[v_i];
+ v.skinned_3d.normal = has_normals ? tmp_normals->data[v_i] : VEC3_ZERO,
+ v.skinned_3d.tex_coords = has_uvs ? tmp_uvs->data[v_i] : vec2_create(0., 0.);
+ v.skinned_3d.bone_ids = tmp_joint_indices->data[v_i];
+ v.skinned_3d.bone_weights = tmp_weights->data[v_i];
+ } else {
+ v.static_3d.position = tmp_positions->data[v_i];
+ v.static_3d.normal = has_normals ? tmp_normals->data[v_i] : VEC3_ZERO,
+ v.static_3d.tex_coords = has_uvs ? tmp_uvs->data[v_i] : vec2_create(0., 0.);
+ }
Vertex_darray_push(geo_vertices, v);
- }
+ };
// Store indices
- cgltf_accessor *indices = primitive.indices;
+ cgltf_accessor* indices = primitive.indices;
if (primitive.indices > 0) {
WARN("indices! %d", indices->count);
- has_indices = true;
// store indices
for (cgltf_size i = 0; i < indices->count; ++i) {
@@ -332,169 +325,139 @@ bool model_load_gltf_str(const char *file_string, const char *filepath, Str8 rel
u32_darray_push(geo_indices, ei);
}
- // fetch and store vertices for each index
- // for (cgltf_size i = 0; i < indices->count; ++i) {
- // Vertex vert;
- // cgltf_uint index = mesh.indices[i];
- // vert.position = tmp_positions->data[index];
- // 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 {
- // has_indices = false;
- // return false; // TODO: handle this
- // }
-
- Geometry *geometry = malloc(sizeof(Geometry));
- geometry->format = VERTEX_STATIC_3D;
+ Geometry* geometry = malloc(sizeof(Geometry));
+ geometry->format = is_skinned ? VERTEX_SKINNED : VERTEX_STATIC_3D;
geometry->has_indices = true;
geometry->vertices = geo_vertices;
geometry->indices = geo_indices;
geometry->index_count = geo_indices->len;
Mesh m = Mesh_Create(geometry, false);
+ if (is_skinned) {
+ m.is_skinned = true;
+ }
Mesh_darray_push(tmp_meshes, m);
Vec3_darray_clear(tmp_positions);
Vec3_darray_clear(tmp_normals);
Vec2_darray_clear(tmp_uvs);
- Vec4u_darray_clear(tmp_joint_indices);
+ Vec4i_darray_clear(tmp_joint_indices);
Vec4_darray_clear(tmp_weights);
+ } else {
+ WARN("No indices found. Ignoring mesh...");
}
}
- // for (int i = 0; i < out_model->meshes->len; i++) {
- // u32 mat_idx = out_model->meshes->data[i].material_index;
- // printf("Mesh %d Mat index %d Mat name %s\n", i, mat_idx,
- // out_model->materials->data[mat_idx].name);
- // }
-
- // TODO: GLTF_LoadAnimations()
- // // Animations
- // TRACE("Num animations %d", data->animations_count);
- // size_t num_animations = data->animations_count;
- // if (num_animations > 0) {
- // // Create an arena for all animation related data
- // #define ANIMATION_STORAGE_ARENA_SIZE (1024 * 1024 * 1024)
- // char *animation_backing_storage = malloc(ANIMATION_STORAGE_ARENA_SIZE);
- // // We'll store data on this arena so we can easily free it all at once later
- // out_model->animation_data_arena =
- // arena_create(animation_backing_storage, ANIMATION_STORAGE_ARENA_SIZE);
- // arena *arena = &out_model->animation_data_arena;
-
- // if (!out_model->animations) {
- // out_model->animations = animation_clip_darray_new(num_animations);
- // }
-
- // for (int anim_idx = 0; anim_idx < data->animations_count; anim_idx++) {
- // cgltf_animation animation = data->animations[anim_idx];
- // animation_clip clip = { 0 };
-
- // for (size_t c = 0; c < animation.channels_count; c++) {
- // cgltf_animation_channel channel = animation.channels[c];
-
- // animation_sampler *sampler = arena_alloc(arena, sizeof(animation_sampler));
-
- // animation_sampler **target_property;
- // keyframe_kind data_type;
-
- // switch (channel.target_path) {
- // case cgltf_animation_path_type_rotation:
- // target_property = &clip.rotation;
- // data_type = KEYFRAME_ROTATION;
- // break;
- // case cgltf_animation_path_type_translation:
- // target_property = &clip.translation;
- // data_type = KEYFRAME_TRANSLATION;
- // break;
- // case cgltf_animation_path_type_scale:
- // target_property = &clip.scale;
- // data_type = KEYFRAME_SCALE;
- // break;
- // case cgltf_animation_path_type_weights:
- // target_property = &clip.weights;
- // data_type = KEYFRAME_WEIGHTS;
- // WARN("Morph target weights arent supported yet");
- // return false;
- // default:
- // WARN("unsupported animation type");
- // return false;
- // }
- // *target_property = sampler;
-
- // sampler->current_index = 0;
- // printf("1 %d index\n", sampler->current_index);
- // sampler->animation.interpolation = INTERPOLATION_LINEAR;
-
- // // keyframe times
- // size_t n_frames = channel.sampler->input->count;
- // assert(channel.sampler->input->component_type == cgltf_component_type_r_32f);
- // // FIXME: CASSERT_MSG function "Expected animation sampler input component to be
- // type f32
- // // (keyframe times)");
- // f32 *times = arena_alloc(arena, n_frames * sizeof(f32));
- // sampler->animation.n_timestamps = n_frames;
- // sampler->animation.timestamps = times;
- // cgltf_accessor_unpack_floats(channel.sampler->input, times, n_frames);
-
- // assert_path_type_matches_component_type(channel.target_path,
- // channel.sampler->output);
-
- // // keyframe values
- // size_t n_values = channel.sampler->output->count;
- // assert(n_frames == n_values);
-
- // keyframes keyframes = { 0 };
- // keyframes.kind = KEYFRAME_ROTATION;
- // keyframes.count = n_values;
- // keyframes.values = arena_alloc(arena, n_values * sizeof(keyframe));
- // for (cgltf_size v = 0; v < channel.sampler->output->count; ++v) {
- // switch (data_type) {
- // case KEYFRAME_ROTATION: {
- // quat rot;
- // cgltf_accessor_read_float(channel.sampler->output, v, &rot.x, 4);
- // // printf("Quat %f %f %f %f\n", rot.x, rot.y, rot.z, rot.w);
- // keyframes.values[v].rotation = rot;
- // break;
- // }
- // case KEYFRAME_TRANSLATION: {
- // vec3 trans;
- // cgltf_accessor_read_float(channel.sampler->output, v, &trans.x, 3);
- // keyframes.values[v].translation = trans;
- // break;
- // }
- // case KEYFRAME_SCALE: {
- // vec3 scale;
- // cgltf_accessor_read_float(channel.sampler->output, v, &scale.x, 3);
- // keyframes.values[v].scale = scale;
- // break;
- // }
- // case KEYFRAME_WEIGHTS: {
- // // TODO
- // break;
- // }
- // }
- // }
- // sampler->animation.values = keyframes;
-
- // sampler->min = channel.sampler->input->min[0];
- // sampler->max = channel.sampler->input->max[0];
-
- // // clip.rotation = sampler;
- // // printf("%d timestamps\n", sampler->animation.n_timestamps);
- // // printf("%d index\n", sampler->current_index);
- // }
-
- // WARN("stuff %ld", clip.rotation->animation.n_timestamps);
- // animation_clip_darray_push(out_model->animations, clip);
- // }
+ // --- Animations
+ size_t num_animations = data->animations_count;
+ TRACE("Num animations %d", num_animations);
+
+ if (num_animations > 0) {
+ if (!out_model->animations) {
+ out_model->animations = AnimationClip_darray_new(num_animations);
+ }
+ arena* arena = &out_model->armature.arena;
+
+ for (int anim_idx = 0; anim_idx < data->animations_count; anim_idx++) {
+ cgltf_animation animation = data->animations[anim_idx];
+ AnimationClip clip = { 0 };
+
+ // for each animation, loop through all the channels
+ for (size_t c = 0; c < animation.channels_count; c++) {
+ cgltf_animation_channel channel = animation.channels[c];
+
+ AnimationSampler* sampler = arena_alloc(arena, sizeof(AnimationSampler));
+
+ AnimationSampler** target_property;
+ KeyframeKind data_type;
+
+ switch (channel.target_path) {
+ case cgltf_animation_path_type_rotation:
+ target_property = &clip.rotation;
+ data_type = KEYFRAME_ROTATION;
+ break;
+ case cgltf_animation_path_type_translation:
+ target_property = &clip.translation;
+ data_type = KEYFRAME_TRANSLATION;
+ break;
+ case cgltf_animation_path_type_scale:
+ target_property = &clip.scale;
+ data_type = KEYFRAME_SCALE;
+ break;
+ case cgltf_animation_path_type_weights:
+ target_property = &clip.weights;
+ data_type = KEYFRAME_WEIGHTS;
+ WARN("Morph target weights arent supported yet");
+ return false;
+ default:
+ WARN("unsupported animation type");
+ return false;
+ }
+
+ sampler->current_index = 0;
+ // printf("1 %d index\n", sampler->current_index);
+ sampler->animation.interpolation = INTERPOLATION_LINEAR; // NOTE: hardcoded for now
+
+ // Keyframe times
+ size_t n_frames = channel.sampler->input->count;
+ assert(channel.sampler->input->component_type == cgltf_component_type_r_32f);
+ CASSERT_MSG(channel.sampler->input->component_type == cgltf_component_type_r_32f,
+ "Expected animation sampler input component to be type f32");
+ f32* times = arena_alloc(arena, n_frames * sizeof(f32));
+ sampler->animation.n_timestamps = n_frames;
+ sampler->animation.timestamps = times;
+ cgltf_accessor_unpack_floats(channel.sampler->input, times, n_frames);
+
+ // assert_path_type_matches_component_type(channel.target_path,
+ // channel.sampler->output);
+
+ // Keyframe values
+ size_t n_values = channel.sampler->output->count;
+ CASSERT_MSG(n_frames == n_values, "keyframe times = keyframe values");
+
+ Keyframes keyframes = { 0 };
+ keyframes.kind = data_type;
+ keyframes.count = n_values;
+ keyframes.values = arena_alloc(arena, n_values * sizeof(Keyframe));
+ for (cgltf_size v = 0; v < channel.sampler->output->count; ++v) {
+ switch (data_type) {
+ case KEYFRAME_ROTATION: {
+ Quat rot;
+ cgltf_accessor_read_float(channel.sampler->output, v, &rot.x, 4);
+ printf("Quat %f %f %f %f\n", rot.x, rot.y, rot.z, rot.w);
+ keyframes.values[v].rotation = rot;
+ break;
+ }
+ case KEYFRAME_TRANSLATION: {
+ Vec3 trans;
+ cgltf_accessor_read_float(channel.sampler->output, v, &trans.x, 3);
+ keyframes.values[v].translation = trans;
+ break;
+ }
+ case KEYFRAME_SCALE: {
+ Vec3 scale;
+ cgltf_accessor_read_float(channel.sampler->output, v, &scale.x, 3);
+ keyframes.values[v].scale = scale;
+ break;
+ }
+ case KEYFRAME_WEIGHTS: {
+ // TODO: morph weights
+ break;
+ }
+ }
+ }
+ sampler->animation.values = keyframes;
+ sampler->min = channel.sampler->input->min[0];
+ sampler->max = channel.sampler->input->max[0];
+
+ *target_property = sampler;
+ printf("%d timestamps\n", sampler->animation.n_timestamps);
+ printf("%d index\n", sampler->current_index);
+ }
+
+ AnimationClip_darray_push(out_model->animations, clip);
+ }
+ }
}
num_meshes = tmp_meshes->len;
@@ -505,7 +468,7 @@ bool model_load_gltf_str(const char *file_string, const char *filepath, Str8 rel
out_model->materials = malloc(num_materials * sizeof(MaterialHandle));
out_model->material_count = num_materials;
- MaterialHandle *mat_handles = calloc(num_materials, sizeof(MaterialHandle));
+ MaterialHandle* mat_handles = calloc(num_materials, sizeof(MaterialHandle));
for (u32 mat_i = 0; mat_i < num_materials; mat_i++) {
mat_handles[mat_i] =
Material_pool_insert(Render_GetMaterialPool(), &tmp_materials->data[mat_i]);
@@ -524,10 +487,10 @@ bool model_load_gltf_str(const char *file_string, const char *filepath, Str8 rel
return true;
}
-const char *bool_yes_no(bool pred) { return pred ? "Yes" : "No"; }
+const char* bool_yes_no(bool pred) { return pred ? "Yes" : "No"; }
// Loads all materials
-size_t GLTF_LoadMaterials(cgltf_data *data, Str8 relative_path, Material_darray *out_materials) {
+size_t GLTF_LoadMaterials(cgltf_data* data, Str8 relative_path, Material_darray* out_materials) {
size_t num_materials = data->materials_count;
TRACE("Num materials %d", num_materials);
for (size_t m = 0; m < num_materials; m++) {
@@ -562,7 +525,6 @@ size_t GLTF_LoadMaterials(cgltf_data *data, Str8 relative_path, Material_darray
// -- metallic
cgltf_texture_view metal_rough_tex_view = pbr.metallic_roughness_texture;
- // bool has_metal_
printf("Metal factor: %f\n", pbr.metallic_factor);
printf("Roughness factor: %f\n", pbr.roughness_factor);
if (metal_rough_tex_view.texture != NULL) {