diff options
author | omnisci3nce <omniscient.oce@gmail.com> | 2024-04-27 18:15:56 +1000 |
---|---|---|
committer | omnisci3nce <omniscient.oce@gmail.com> | 2024-04-27 18:15:56 +1000 |
commit | 69b1487e3e063cbecba96706c550d417b2f24e37 (patch) | |
tree | 9e31e292ef1cbb6775c52d14bae1f536a1f51906 /src/resources | |
parent | 93c8d40b39fe55a626e66d412450fb4cca1f993b (diff) |
getting us compiling on windows
Diffstat (limited to 'src/resources')
-rw-r--r-- | src/resources/gltf.c | 810 | ||||
-rw-r--r-- | src/resources/obj.c | 595 |
2 files changed, 711 insertions, 694 deletions
diff --git a/src/resources/gltf.c b/src/resources/gltf.c index 81992d1..022bf95 100644 --- a/src/resources/gltf.c +++ b/src/resources/gltf.c @@ -12,7 +12,7 @@ #include "mem.h" #include "path.h" #include "render.h" -#include "render_backend.h" +// #include "render_backend.h" #include "render_types.h" #include "str.h" @@ -26,7 +26,6 @@ typedef struct face face; KITC_DECL_TYPED_ARRAY(vec3) KITC_DECL_TYPED_ARRAY(vec2) -KITC_DECL_TYPED_ARRAY(u32) KITC_DECL_TYPED_ARRAY(vec4u) KITC_DECL_TYPED_ARRAY(vec4) KITC_DECL_TYPED_ARRAY(face) @@ -49,7 +48,7 @@ model_handle model_load_gltf(struct core *core, const char *path, bool invert_te model model = { 0 }; model.name = str8_cstr_view(path); model.meshes = mesh_darray_new(1); - model.materials = material_darray_new(1); + // model.materials = material_darray_new(1); bool success = model_load_gltf_str(file_string, path, relative_path.path, &model, invert_texture_y); @@ -79,403 +78,414 @@ void assert_path_type_matches_component_type(cgltf_animation_path_type target_pa 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); - 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; - cgltf_result result = cgltf_parse_file(&options, filepath, &data); - if (result != cgltf_result_success) { - WARN("gltf load failed"); - // TODO: cleanup arrays(allocate all from arena ?) - return false; - } - - 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); - } - } - - // --- Materials - TRACE("Num materials %d", data->materials_count); - size_t num_materials = data->materials_count; - for (size_t m = 0; m < num_materials; m++) { - cgltf_material gltf_material = data->materials[m]; - material our_material = DEFAULT_MATERIAL; - - strcpy(our_material.name, gltf_material.name); - - cgltf_pbr_metallic_roughness pbr = gltf_material.pbr_metallic_roughness; - if (gltf_material.has_pbr_metallic_roughness) { - // we will use base color texture like blinn phong - cgltf_texture_view diff_tex_view = pbr.base_color_texture; - - char diffuse_map_path[1024]; - snprintf(diffuse_map_path, sizeof(diffuse_map_path), "%s/%s", relative_path.buf, - diff_tex_view.texture->image->uri); - - strcpy(our_material.diffuse_tex_path, diffuse_map_path); - texture diffuse_texture = texture_data_load(our_material.diffuse_tex_path, false); - texture_data_upload(&diffuse_texture); - our_material.diffuse_texture = diffuse_texture; - - cgltf_texture_view specular_tex_view = pbr.metallic_roughness_texture; - - char specular_map_path[1024]; - snprintf(specular_map_path, sizeof(specular_map_path), "%s/%s", relative_path.buf, - specular_tex_view.texture->image->uri); - - strcpy(our_material.specular_tex_path, specular_map_path); - texture specular_texture = texture_data_load(our_material.specular_tex_path, false); - texture_data_upload(&specular_texture); - our_material.specular_texture = specular_texture; - } - - material_darray_push(out_model->materials, our_material); - } - - // --- Meshes - TRACE("Num meshes %d", data->meshes_count); - size_t num_meshes = data->meshes_count; - for (size_t m = 0; m < num_meshes; m++) { - cgltf_primitive primitive = data->meshes[m].primitives[0]; - DEBUG("Found %d attributes", primitive.attributes_count); - // DEBUG("Number of this primitive %d", primitive.) - - for (int a = 0; a < data->meshes[m].primitives[0].attributes_count; a++) { - cgltf_attribute attribute = data->meshes[m].primitives[0].attributes[a]; - if (attribute.type == cgltf_attribute_type_position) { - TRACE("Load positions from accessor"); - - cgltf_accessor *accessor = attribute.data; - assert(accessor->component_type == cgltf_component_type_r_32f); - // CASSERT_MSG(accessor->type == cgltf_type_vec3, "Vertex positions should be a vec3"); - - TRACE("Loading %d vec3 components", accessor->count); - - for (cgltf_size v = 0; v < accessor->count; ++v) { - vec3 pos; - cgltf_accessor_read_float(accessor, v, &pos.x, 3); - vec3_darray_push(tmp_positions, pos); - } - - } else if (attribute.type == cgltf_attribute_type_normal) { - TRACE("Load normals from accessor"); - - cgltf_accessor *accessor = attribute.data; - assert(accessor->component_type == cgltf_component_type_r_32f); - // CASSERT_MSG(accessor->type == cgltf_type_vec3, "Normal vectors should be a vec3"); - - for (cgltf_size v = 0; v < accessor->count; ++v) { - vec3 pos; - cgltf_accessor_read_float(accessor, v, &pos.x, 3); - vec3_darray_push(tmp_normals, pos); - } - - } else if (attribute.type == cgltf_attribute_type_texcoord) { - TRACE("Load texture coordinates from accessor"); - cgltf_accessor *accessor = attribute.data; - assert(accessor->component_type == cgltf_component_type_r_32f); - // CASSERT_MSG(accessor->type == cgltf_type_vec2, "Texture coordinates should be a vec2"); - - for (cgltf_size v = 0; v < accessor->count; ++v) { - vec2 tex; - bool success = cgltf_accessor_read_float(accessor, v, &tex.x, 2); - if (!success) { - ERROR("Error loading tex coord"); - } - vec2_darray_push(tmp_uvs, tex); - } - } else if (attribute.type == cgltf_attribute_type_joints) { - TRACE("Load joint indices from accessor"); - cgltf_accessor *accessor = attribute.data; - assert(accessor->component_type == cgltf_component_type_r_16u); - assert(accessor->type == cgltf_type_vec4); - 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); - joint_indices.x = (u32)joints_as_floats.x; - 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 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) { - 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); - } - } else { - WARN("Unhandled cgltf_attribute_type: %s. skipping..", attribute.name); - } - } - - 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)); - mesh.indices_len = indices->count; - - // store indices - for (cgltf_size i = 0; i < indices->count; ++i) { - cgltf_uint ei; - cgltf_accessor_read_uint(indices, i, &ei, 1); - mesh.indices[i] = 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 { - mesh.has_indices = false; - return false; // TODO - } - - 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); - vec4u_darray_clear(tmp_joint_indices); - vec4_darray_clear(tmp_weights); - joint_darray_clear(tmp_joints); - } - - 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); - } - - // 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); - } - } - - return true; + return false; + // 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); + // // FIXME + // // 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; + // cgltf_result result = cgltf_parse_file(&options, filepath, &data); + // if (result != cgltf_result_success) { + // WARN("gltf load failed"); + // // TODO: cleanup arrays(allocate all from arena ?) + // return false; + // } + + // 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); + // } + // } + + // // --- Materials + // TRACE("Num materials %d", data->materials_count); + // size_t num_materials = data->materials_count; + // for (size_t m = 0; m < num_materials; m++) { + // cgltf_material gltf_material = data->materials[m]; + // material our_material = DEFAULT_MATERIAL; + + // strcpy(our_material.name, gltf_material.name); + + // cgltf_pbr_metallic_roughness pbr = gltf_material.pbr_metallic_roughness; + // if (gltf_material.has_pbr_metallic_roughness) { + // // we will use base color texture like blinn phong + // cgltf_texture_view diff_tex_view = pbr.base_color_texture; + + // char diffuse_map_path[1024]; + // snprintf(diffuse_map_path, sizeof(diffuse_map_path), "%s/%s", relative_path.buf, + // diff_tex_view.texture->image->uri); + + // strcpy(our_material.diffuse_tex_path, diffuse_map_path); + // texture diffuse_texture = texture_data_load(our_material.diffuse_tex_path, false); + // texture_data_upload(&diffuse_texture); + // our_material.diffuse_texture = diffuse_texture; + + // cgltf_texture_view specular_tex_view = pbr.metallic_roughness_texture; + + // char specular_map_path[1024]; + // snprintf(specular_map_path, sizeof(specular_map_path), "%s/%s", relative_path.buf, + // specular_tex_view.texture->image->uri); + + // strcpy(our_material.specular_tex_path, specular_map_path); + // texture specular_texture = texture_data_load(our_material.specular_tex_path, false); + // texture_data_upload(&specular_texture); + // our_material.specular_texture = specular_texture; + // } + + // // material_darray_push(out_model->materials, our_material); + // } + + // // --- Meshes + // TRACE("Num meshes %d", data->meshes_count); + // size_t num_meshes = data->meshes_count; + // for (size_t m = 0; m < num_meshes; m++) { + // cgltf_primitive primitive = data->meshes[m].primitives[0]; + // DEBUG("Found %d attributes", primitive.attributes_count); + // // DEBUG("Number of this primitive %d", primitive.) + + // for (int a = 0; a < data->meshes[m].primitives[0].attributes_count; a++) { + // cgltf_attribute attribute = data->meshes[m].primitives[0].attributes[a]; + // if (attribute.type == cgltf_attribute_type_position) { + // TRACE("Load positions from accessor"); + + // cgltf_accessor *accessor = attribute.data; + // assert(accessor->component_type == cgltf_component_type_r_32f); + // // CASSERT_MSG(accessor->type == cgltf_type_vec3, "Vertex positions should be a vec3"); + + // TRACE("Loading %d vec3 components", accessor->count); + + // for (cgltf_size v = 0; v < accessor->count; ++v) { + // vec3 pos; + // cgltf_accessor_read_float(accessor, v, &pos.x, 3); + // vec3_darray_push(tmp_positions, pos); + // } + + // } else if (attribute.type == cgltf_attribute_type_normal) { + // TRACE("Load normals from accessor"); + + // cgltf_accessor *accessor = attribute.data; + // assert(accessor->component_type == cgltf_component_type_r_32f); + // // CASSERT_MSG(accessor->type == cgltf_type_vec3, "Normal vectors should be a vec3"); + + // for (cgltf_size v = 0; v < accessor->count; ++v) { + // vec3 pos; + // cgltf_accessor_read_float(accessor, v, &pos.x, 3); + // vec3_darray_push(tmp_normals, pos); + // } + + // } else if (attribute.type == cgltf_attribute_type_texcoord) { + // TRACE("Load texture coordinates from accessor"); + // cgltf_accessor *accessor = attribute.data; + // assert(accessor->component_type == cgltf_component_type_r_32f); + // // CASSERT_MSG(accessor->type == cgltf_type_vec2, "Texture coordinates should be a + // vec2"); + + // for (cgltf_size v = 0; v < accessor->count; ++v) { + // vec2 tex; + // bool success = cgltf_accessor_read_float(accessor, v, &tex.x, 2); + // if (!success) { + // ERROR("Error loading tex coord"); + // } + // vec2_darray_push(tmp_uvs, tex); + // } + // } else if (attribute.type == cgltf_attribute_type_joints) { + // TRACE("Load joint indices from accessor"); + // cgltf_accessor *accessor = attribute.data; + // assert(accessor->component_type == cgltf_component_type_r_16u); + // assert(accessor->type == cgltf_type_vec4); + // 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); + // joint_indices.x = (u32)joints_as_floats.x; + // 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 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) { + // 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); + // } + // } else { + // WARN("Unhandled cgltf_attribute_type: %s. skipping..", attribute.name); + // } + // } + + // 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; + // // } + // // } + // } + + // // 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); + // // } + // // } + + // cgltf_accessor *indices = primitive.indices; + // if (primitive.indices > 0) { + // WARN("indices!"); + // mesh.has_indices = true; + + // mesh.indices = malloc(indices->count * sizeof(u32)); + // mesh.indices_len = indices->count; + + // // store indices + // for (cgltf_size i = 0; i < indices->count; ++i) { + // cgltf_uint ei; + // cgltf_accessor_read_uint(indices, i, &ei, 1); + // mesh.indices[i] = 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 { + // mesh.has_indices = false; + // return false; // TODO + // } + + // 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); + // vec4u_darray_clear(tmp_joint_indices); + // vec4_darray_clear(tmp_weights); + // joint_darray_clear(tmp_joints); + // } + + // 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); + // } + + // // 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); + // } + // } + + // return true; } /* diff --git a/src/resources/obj.c b/src/resources/obj.c index ea73ffa..888e16e 100644 --- a/src/resources/obj.c +++ b/src/resources/obj.c @@ -18,7 +18,7 @@ #include "mem.h" #include "path.h" #include "render.h" -#include "render_backend.h" +// #include "render_backend.h" #include "render_types.h" #include "str.h" @@ -55,7 +55,7 @@ model_handle model_load_obj(core *core, const char *path, bool invert_textures_y model model = { 0 }; model.name = str8_cstr_view(path); model.meshes = mesh_darray_new(1); - model.materials = material_darray_new(1); + // model.materials = material_darray_new(1); bool success = model_load_obj_str(file_string, relative_path.path, &model, invert_textures_y); @@ -76,151 +76,157 @@ bool model_load_obj_str(const char *file_string, str8 relative_path, model *out_ bool invert_textures_y) { TRACE("Load OBJ 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); - face_darray *tmp_faces = face_darray_new(1000); - // TODO: In the future I'd like these temporary arrays to be allocated from an arena provided - // by the function one level up, model_load_obj. That way we can just `return false;` anywhere in - // this code to indicate an error, and be sure that all that memory will be cleaned up without - // having to call vec3_darray_free in every single error case before returning. - - // Other state - bool object_set = false; - bool material_loaded = false; - char current_material_name[64]; - - char *pch; - char *rest = file_string; - pch = strtok_r((char *)file_string, "\n", &rest); - - int line_num = 0; - char last_char_type = 'a'; - - while (pch != NULL) { - line_num++; - char line_header[128]; - int offset = 0; - - // skip whitespace - char *p = pch; - - skip_space(pch); - - if (*p == '\0') { - /* the string is empty */ - } else { - // read the first word of the line - int res = sscanf(pch, "%s %n", line_header, &offset); - /* printf("header: %s, offset : %d res: %d\n",line_header, offset, res); */ - if (res != 1) { - break; - } - - if (strcmp(line_header, "o") == 0 || strcmp(line_header, "g") == 0) { - // if we're currently parsing one - if (!object_set) { - object_set = true; - } else { - create_submesh(out_model->meshes, tmp_positions, tmp_normals, tmp_uvs, tmp_faces, - out_model->materials, material_loaded, current_material_name); - object_set = false; - } - } else if (strcmp(line_header, "v") == 0) { - // special logic: if we went from faces back to vertices trigger a mesh output. - // PS: I hate OBJ - if (last_char_type == 'f') { - create_submesh(out_model->meshes, tmp_positions, tmp_normals, tmp_uvs, tmp_faces, - out_model->materials, material_loaded, current_material_name); - object_set = false; - } - - last_char_type = 'v'; - vec3 vertex; - sscanf(pch + offset, "%f %f %f", &vertex.x, &vertex.y, &vertex.z); - - vec3_darray_push(tmp_positions, vertex); - } else if (strcmp(line_header, "vt") == 0) { - last_char_type = 't'; - vec2 uv; - char copy[1024]; - memcpy(copy, pch + offset, strlen(pch + offset) + 1); - char *p = pch + offset; - while (isspace((unsigned char)*p)) ++p; - - // I can't remember what is going on here - memset(copy, 0, 1024); - memcpy(copy, pch + offset, strlen(pch + offset) + 1); - int res = sscanf(copy, "%f %f", &uv.x, &uv.y); - memset(copy, 0, 1024); - memcpy(copy, pch + offset, strlen(pch + offset) + 1); - if (res != 1) { - // da frick? some .obj files have 3 uvs instead of 2 - f32 dummy; - int res2 = sscanf(copy, "%f %f %f", &uv.x, &uv.y, &dummy); - } - - if (invert_textures_y) { - uv.y = -uv.y; // flip Y axis to be consistent with how other PNGs are being handled - // `texture_load` will flip it again - } - vec2_darray_push(tmp_uvs, uv); - } else if (strcmp(line_header, "vn") == 0) { - last_char_type = 'n'; - vec3 normal; - sscanf(pch + offset, "%f %f %f", &normal.x, &normal.y, &normal.z); - vec3_darray_push(tmp_normals, normal); - } else if (strcmp(line_header, "f") == 0) { - last_char_type = 'f'; - struct face f; - sscanf(pch + offset, "%d/%d/%d %d/%d/%d %d/%d/%d", &f.vertex_indices[0], &f.uv_indices[0], - &f.normal_indices[0], &f.vertex_indices[1], &f.uv_indices[1], &f.normal_indices[1], - &f.vertex_indices[2], &f.uv_indices[2], &f.normal_indices[2]); - // printf("f %d/%d/%d %d/%d/%d %d/%d/%d\n", f.vertex_indices[0], f.uv_indices[0], - // f.normal_indices[0], - // f.vertex_indices[1], f.uv_indices[1], f.normal_indices[1], - // f.vertex_indices[2], f.uv_indices[2], f.normal_indices[2]); - face_darray_push(tmp_faces, f); - } else if (strcmp(line_header, "mtllib") == 0) { - char filename[1024]; - sscanf(pch + offset, "%s", filename); - char mtllib_path[1024]; - snprintf(mtllib_path, sizeof(mtllib_path), "%s/%s", relative_path.buf, filename); - if (!load_material_lib(mtllib_path, relative_path, out_model->materials)) { - ERROR("couldnt load material lib"); - return false; - } - } else if (strcmp(line_header, "usemtl") == 0) { - material_loaded = true; - sscanf(pch + offset, "%s", current_material_name); - } - } - - pch = strtok_r(NULL, "\n", &rest); - } - - // last mesh or if one wasnt created with 'o' directive - if (face_darray_len(tmp_faces) > 0) { - TRACE("Last leftover mesh"); - create_submesh(out_model->meshes, tmp_positions, tmp_normals, tmp_uvs, tmp_faces, - out_model->materials, material_loaded, current_material_name); - } - - // Free data - free((char *)file_string); - vec3_darray_free(tmp_positions); - vec3_darray_free(tmp_normals); - vec2_darray_free(tmp_uvs); - face_darray_free(tmp_faces); - TRACE("Freed temporary OBJ loading data"); - - if (mesh_darray_len(out_model->meshes) > 256) { - printf("num meshes: %ld\n", mesh_darray_len(out_model->meshes)); - } - - // TODO: bounding box calculation for each mesh - // TODO: bounding box calculation for model + // // 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); + // face_darray *tmp_faces = face_darray_new(1000); + // // TODO: In the future I'd like these temporary arrays to be allocated from an arena provided + // // by the function one level up, model_load_obj. That way we can just `return false;` anywhere + // in + // // this code to indicate an error, and be sure that all that memory will be cleaned up without + // // having to call vec3_darray_free in every single error case before returning. + + // // Other state + // bool object_set = false; + // bool material_loaded = false; + // char current_material_name[64]; + + // char *pch; + // char *rest = file_string; + // pch = strtok_r((char *)file_string, "\n", &rest); + + // int line_num = 0; + // char last_char_type = 'a'; + + // while (pch != NULL) { + // line_num++; + // char line_header[128]; + // int offset = 0; + + // // skip whitespace + // char *p = pch; + + // skip_space(pch); + + // if (*p == '\0') { + // /* the string is empty */ + // } else { + // // read the first word of the line + // int res = sscanf(pch, "%s %n", line_header, &offset); + // /* printf("header: %s, offset : %d res: %d\n",line_header, offset, res); */ + // if (res != 1) { + // break; + // } + + // if (strcmp(line_header, "o") == 0 || strcmp(line_header, "g") == 0) { + // // if we're currently parsing one + // if (!object_set) { + // object_set = true; + // } else { + // create_submesh(out_model->meshes, tmp_positions, tmp_normals, tmp_uvs, tmp_faces, + // NULL, // out_model->materials, + // material_loaded, current_material_name); + // object_set = false; + // } + // } else if (strcmp(line_header, "v") == 0) { + // // special logic: if we went from faces back to vertices trigger a mesh output. + // // PS: I hate OBJ + // if (last_char_type == 'f') { + // create_submesh(out_model->meshes, tmp_positions, tmp_normals, tmp_uvs, tmp_faces, + // NULL, // FIXME: out_model->materials, + // material_loaded, current_material_name); + // object_set = false; + // } + + // last_char_type = 'v'; + // vec3 vertex; + // sscanf(pch + offset, "%f %f %f", &vertex.x, &vertex.y, &vertex.z); + + // vec3_darray_push(tmp_positions, vertex); + // } else if (strcmp(line_header, "vt") == 0) { + // last_char_type = 't'; + // vec2 uv; + // char copy[1024]; + // memcpy(copy, pch + offset, strlen(pch + offset) + 1); + // char *p = pch + offset; + // while (isspace((unsigned char)*p)) ++p; + + // // I can't remember what is going on here + // memset(copy, 0, 1024); + // memcpy(copy, pch + offset, strlen(pch + offset) + 1); + // int res = sscanf(copy, "%f %f", &uv.x, &uv.y); + // memset(copy, 0, 1024); + // memcpy(copy, pch + offset, strlen(pch + offset) + 1); + // if (res != 1) { + // // da frick? some .obj files have 3 uvs instead of 2 + // f32 dummy; + // int res2 = sscanf(copy, "%f %f %f", &uv.x, &uv.y, &dummy); + // } + + // if (invert_textures_y) { + // uv.y = -uv.y; // flip Y axis to be consistent with how other PNGs are being handled + // // `texture_load` will flip it again + // } + // vec2_darray_push(tmp_uvs, uv); + // } else if (strcmp(line_header, "vn") == 0) { + // last_char_type = 'n'; + // vec3 normal; + // sscanf(pch + offset, "%f %f %f", &normal.x, &normal.y, &normal.z); + // vec3_darray_push(tmp_normals, normal); + // } else if (strcmp(line_header, "f") == 0) { + // last_char_type = 'f'; + // struct face f; + // sscanf(pch + offset, "%d/%d/%d %d/%d/%d %d/%d/%d", &f.vertex_indices[0], + // &f.uv_indices[0], + // &f.normal_indices[0], &f.vertex_indices[1], &f.uv_indices[1], + // &f.normal_indices[1], &f.vertex_indices[2], &f.uv_indices[2], + // &f.normal_indices[2]); + // // printf("f %d/%d/%d %d/%d/%d %d/%d/%d\n", f.vertex_indices[0], f.uv_indices[0], + // // f.normal_indices[0], + // // f.vertex_indices[1], f.uv_indices[1], f.normal_indices[1], + // // f.vertex_indices[2], f.uv_indices[2], f.normal_indices[2]); + // face_darray_push(tmp_faces, f); + // } else if (strcmp(line_header, "mtllib") == 0) { + // char filename[1024]; + // sscanf(pch + offset, "%s", filename); + // char mtllib_path[1024]; + // snprintf(mtllib_path, sizeof(mtllib_path), "%s/%s", relative_path.buf, filename); + // if (!load_material_lib(mtllib_path, relative_path, out_model->materials)) { + // ERROR("couldnt load material lib"); + // return false; + // } + // } else if (strcmp(line_header, "usemtl") == 0) { + // material_loaded = true; + // sscanf(pch + offset, "%s", current_material_name); + // } + // } + + // pch = strtok_r(NULL, "\n", &rest); + // } + + // // last mesh or if one wasnt created with 'o' directive + // if (face_darray_len(tmp_faces) > 0) { + // TRACE("Last leftover mesh"); + // create_submesh(out_model->meshes, tmp_positions, tmp_normals, tmp_uvs, tmp_faces, + // NULL, // TODO: out_model->materials, + // material_loaded, current_material_name); + // } + + // // Free data + // free((char *)file_string); + // vec3_darray_free(tmp_positions); + // vec3_darray_free(tmp_normals); + // vec2_darray_free(tmp_uvs); + // face_darray_free(tmp_faces); + // TRACE("Freed temporary OBJ loading data"); + + // if (mesh_darray_len(out_model->meshes) > 256) { + // printf("num meshes: %ld\n", mesh_darray_len(out_model->meshes)); + // } + + // // TODO: bounding box calculation for each mesh + // // TODO: bounding box calculation for model return true; } @@ -232,158 +238,159 @@ bool model_load_obj_str(const char *file_string, str8 relative_path, model *out_ void create_submesh(mesh_darray *meshes, vec3_darray *tmp_positions, vec3_darray *tmp_normals, vec2_darray *tmp_uvs, face_darray *tmp_faces, material_darray *materials, bool material_loaded, char current_material_name[256]) { - size_t num_verts = face_darray_len(tmp_faces) * 3; - vertex_darray *out_vertices = vertex_darray_new(num_verts); - - face_darray_iter face_iter = face_darray_iter_new(tmp_faces); - struct face *f; - - while ((f = face_darray_iter_next(&face_iter))) { - for (int j = 0; j < 3; j++) { - vertex vert = { 0 }; - vert.position = tmp_positions->data[f->vertex_indices[j] - 1]; - if (vec3_darray_len(tmp_normals) == 0) { - vert.normal = vec3_create(0.0, 0.0, 0.0); - } else { - vert.normal = tmp_normals->data[f->normal_indices[j] - 1]; - } - vert.uv = tmp_uvs->data[f->uv_indices[j] - 1]; - vertex_darray_push(out_vertices, vert); - } - } - - DEBUG("Loaded submesh\n vertices: %zu\n uvs: %zu\n normals: %zu\n faces: %zu", - vec3_darray_len(tmp_positions), vec2_darray_len(tmp_uvs), vec3_darray_len(tmp_normals), - face_darray_len(tmp_faces)); - - // Clear current object faces - face_darray_clear(tmp_faces); - - mesh m = { .vertices = out_vertices }; - if (material_loaded) { - // linear scan to find material - bool found = false; - DEBUG("Num of materials : %ld", material_darray_len(materials)); - material_darray_iter mat_iter = material_darray_iter_new(materials); - blinn_phong_material *cur_material; - while ((cur_material = material_darray_iter_next(&mat_iter))) { - if (strcmp(cur_material->name, current_material_name) == 0) { - DEBUG("Found match"); - m.material_index = mat_iter.current_idx - 1; - found = true; - break; - } - } - - if (!found) { - // TODO: default material - m.material_index = 0; - DEBUG("Set default material"); - } - } - mesh_darray_push(meshes, m); + // size_t num_verts = face_darray_len(tmp_faces) * 3; + // vertex_darray *out_vertices = vertex_darray_new(num_verts); + + // face_darray_iter face_iter = face_darray_iter_new(tmp_faces); + // struct face *f; + + // while ((f = face_darray_iter_next(&face_iter))) { + // for (int j = 0; j < 3; j++) { + // vertex vert = { 0 }; + // vert.position = tmp_positions->data[f->vertex_indices[j] - 1]; + // if (vec3_darray_len(tmp_normals) == 0) { + // vert.normal = vec3_create(0.0, 0.0, 0.0); + // } else { + // vert.normal = tmp_normals->data[f->normal_indices[j] - 1]; + // } + // vert.uv = tmp_uvs->data[f->uv_indices[j] - 1]; + // vertex_darray_push(out_vertices, vert); + // } + // } + + // DEBUG("Loaded submesh\n vertices: %zu\n uvs: %zu\n normals: %zu\n faces: %zu", + // vec3_darray_len(tmp_positions), vec2_darray_len(tmp_uvs), vec3_darray_len(tmp_normals), + // face_darray_len(tmp_faces)); + + // // Clear current object faces + // face_darray_clear(tmp_faces); + + // mesh m = { .vertices = out_vertices }; + // if (material_loaded) { + // // linear scan to find material + // bool found = false; + // DEBUG("Num of materials : %ld", material_darray_len(materials)); + // material_darray_iter mat_iter = material_darray_iter_new(materials); + // blinn_phong_material *cur_material; + // while ((cur_material = material_darray_iter_next(&mat_iter))) { + // if (strcmp(cur_material->name, current_material_name) == 0) { + // DEBUG("Found match"); + // m.material_index = mat_iter.current_idx - 1; + // found = true; + // break; + // } + // } + + // if (!found) { + // // TODO: default material + // m.material_index = 0; + // DEBUG("Set default material"); + // } + // } + // mesh_darray_push(meshes, m); } bool load_material_lib(const char *path, str8 relative_path, material_darray *materials) { TRACE("BEGIN load material lib at %s", path); - const char *file_string = string_from_file(path); - if (file_string == NULL) { - ERROR("couldnt load %s", path); - return false; - } - - char *pch; - char *saveptr; - pch = strtok_r((char *)file_string, "\n", &saveptr); - - material current_material = DEFAULT_MATERIAL; - - bool material_set = false; - - while (pch != NULL) { - char line_header[128]; - int offset = 0; - // read the first word of the line - int res = sscanf(pch, "%s %n", line_header, &offset); - if (res != 1) { - break; - } - - // When we see "newmtl", start a new material, or flush the previous one - if (strcmp(line_header, "newmtl") == 0) { - if (material_set) { - // a material was being parsed, so flush that one and start a new one - material_darray_push(materials, current_material); - DEBUG("pushed material with name %s", current_material.name); - WARN("Reset current material"); - current_material = DEFAULT_MATERIAL; - } else { - material_set = true; - } - // scan the new material name - char material_name[64]; - sscanf(pch + offset, "%s", current_material.name); - DEBUG("material name %s\n", current_material.name); - // current_material.name = material_name; - } else if (strcmp(line_header, "Ka") == 0) { - // ambient - sscanf(pch + offset, "%f %f %f", ¤t_material.ambient_colour.x, - ¤t_material.ambient_colour.y, ¤t_material.ambient_colour.z); - } else if (strcmp(line_header, "Kd") == 0) { - // diffuse - sscanf(pch + offset, "%f %f %f", ¤t_material.diffuse.x, ¤t_material.diffuse.y, - ¤t_material.diffuse.z); - } else if (strcmp(line_header, "Ks") == 0) { - // specular - sscanf(pch + offset, "%f %f %f", ¤t_material.specular.x, ¤t_material.specular.y, - ¤t_material.specular.z); - } else if (strcmp(line_header, "Ns") == 0) { - // specular exponent - sscanf(pch + offset, "%f", ¤t_material.spec_exponent); - } else if (strcmp(line_header, "map_Kd") == 0) { - char diffuse_map_filename[1024]; - sscanf(pch + offset, "%s", diffuse_map_filename); - char diffuse_map_path[1024]; - snprintf(diffuse_map_path, sizeof(diffuse_map_path), "%s/%s", relative_path.buf, - diffuse_map_filename); - printf("load from %s\n", diffuse_map_path); - - // -------------- - texture diffuse_texture = texture_data_load(diffuse_map_path, true); - current_material.diffuse_texture = diffuse_texture; - strcpy(current_material.diffuse_tex_path, diffuse_map_path); - texture_data_upload(¤t_material.diffuse_texture); - // -------------- - } else if (strcmp(line_header, "map_Ks") == 0) { - // char specular_map_path[1024] = "assets/"; - // sscanf(pch + offset, "%s", specular_map_path + 7); - char specular_map_filename[1024]; - sscanf(pch + offset, "%s", specular_map_filename); - char specular_map_path[1024]; - snprintf(specular_map_path, sizeof(specular_map_path), "%s/%s", relative_path.buf, - specular_map_filename); - printf("load from %s\n", specular_map_path); - // -------------- - texture specular_texture = texture_data_load(specular_map_path, true); - current_material.specular_texture = specular_texture; - strcpy(current_material.specular_tex_path, specular_map_path); - texture_data_upload(¤t_material.specular_texture); - // -------------- - } else if (strcmp(line_header, "map_Bump") == 0) { - // TODO - } - - pch = strtok_r(NULL, "\n", &saveptr); - } - - TRACE("end load material lib"); - - // last mesh or if one wasnt created with 'o' directive - // TRACE("Last leftover material"); - material_darray_push(materials, current_material); - - INFO("Loaded %ld materials", material_darray_len(materials)); + // const char *file_string = string_from_file(path); + // if (file_string == NULL) { + // ERROR("couldnt load %s", path); + // return false; + // } + + // char *pch; + // char *saveptr; + // pch = strtok_r((char *)file_string, "\n", &saveptr); + + // material current_material = DEFAULT_MATERIAL; + + // bool material_set = false; + + // while (pch != NULL) { + // char line_header[128]; + // int offset = 0; + // // read the first word of the line + // int res = sscanf(pch, "%s %n", line_header, &offset); + // if (res != 1) { + // break; + // } + + // // When we see "newmtl", start a new material, or flush the previous one + // if (strcmp(line_header, "newmtl") == 0) { + // if (material_set) { + // // a material was being parsed, so flush that one and start a new one + // material_darray_push(materials, current_material); + // DEBUG("pushed material with name %s", current_material.name); + // WARN("Reset current material"); + // current_material = DEFAULT_MATERIAL; + // } else { + // material_set = true; + // } + // // scan the new material name + // char material_name[64]; + // sscanf(pch + offset, "%s", current_material.name); + // DEBUG("material name %s\n", current_material.name); + // // current_material.name = material_name; + // } else if (strcmp(line_header, "Ka") == 0) { + // // ambient + // sscanf(pch + offset, "%f %f %f", ¤t_material.ambient_colour.x, + // ¤t_material.ambient_colour.y, ¤t_material.ambient_colour.z); + // } else if (strcmp(line_header, "Kd") == 0) { + // // diffuse + // sscanf(pch + offset, "%f %f %f", ¤t_material.diffuse.x, ¤t_material.diffuse.y, + // ¤t_material.diffuse.z); + // } else if (strcmp(line_header, "Ks") == 0) { + // // specular + // sscanf(pch + offset, "%f %f %f", ¤t_material.specular.x, + // ¤t_material.specular.y, + // ¤t_material.specular.z); + // } else if (strcmp(line_header, "Ns") == 0) { + // // specular exponent + // sscanf(pch + offset, "%f", ¤t_material.spec_exponent); + // } else if (strcmp(line_header, "map_Kd") == 0) { + // char diffuse_map_filename[1024]; + // sscanf(pch + offset, "%s", diffuse_map_filename); + // char diffuse_map_path[1024]; + // snprintf(diffuse_map_path, sizeof(diffuse_map_path), "%s/%s", relative_path.buf, + // diffuse_map_filename); + // printf("load from %s\n", diffuse_map_path); + + // // -------------- + // texture diffuse_texture = texture_data_load(diffuse_map_path, true); + // current_material.diffuse_texture = diffuse_texture; + // strcpy(current_material.diffuse_tex_path, diffuse_map_path); + // texture_data_upload(¤t_material.diffuse_texture); + // // -------------- + // } else if (strcmp(line_header, "map_Ks") == 0) { + // // char specular_map_path[1024] = "assets/"; + // // sscanf(pch + offset, "%s", specular_map_path + 7); + // char specular_map_filename[1024]; + // sscanf(pch + offset, "%s", specular_map_filename); + // char specular_map_path[1024]; + // snprintf(specular_map_path, sizeof(specular_map_path), "%s/%s", relative_path.buf, + // specular_map_filename); + // printf("load from %s\n", specular_map_path); + // // -------------- + // texture specular_texture = texture_data_load(specular_map_path, true); + // current_material.specular_texture = specular_texture; + // strcpy(current_material.specular_tex_path, specular_map_path); + // texture_data_upload(¤t_material.specular_texture); + // // -------------- + // } else if (strcmp(line_header, "map_Bump") == 0) { + // // TODO + // } + + // pch = strtok_r(NULL, "\n", &saveptr); + // } + + // TRACE("end load material lib"); + + // // last mesh or if one wasnt created with 'o' directive + // // TRACE("Last leftover material"); + // material_darray_push(materials, current_material); + + // INFO("Loaded %ld materials", material_darray_len(materials)); TRACE("END load material lib"); return true; } |