From 9c2c152c3926490a632fe32ad2ac7682ea7cbd74 Mon Sep 17 00:00:00 2001 From: Chuyan Zhang Date: Fri, 4 Oct 2024 18:13:57 -0700 Subject: WIP glTF loader --- src/gltf_loader.cpp | 105 +++++++++++++++++++++++++++++++++++++++++++++++----- src/render_assets.h | 6 +-- 2 files changed, 99 insertions(+), 12 deletions(-) diff --git a/src/gltf_loader.cpp b/src/gltf_loader.cpp index 2b3818f..142b69f 100644 --- a/src/gltf_loader.cpp +++ b/src/gltf_loader.cpp @@ -1,5 +1,6 @@ #include "gltf_loader.h" #include "spdlog/spdlog.h" +#include enum class SceneFileType { GLTF, @@ -75,22 +76,108 @@ bool load_gltf(const std::string_view path, iris::Scene &scene) { model.lights.size()); for (const auto &mesh : model.meshes) { - iris::Mesh iris_mesh; + iris::Mesh iris_mesh { + .name = mesh.name, + .vertices = {}, + .indices = {}, + }; for (const auto &primitive : mesh.primitives) { - const auto &position_accessor = model.accessors[primitive.attributes.at("POSITION")]; - const auto &position_buffer_view = model.bufferViews[position_accessor.bufferView]; - const auto &position_buffer = model.buffers[position_buffer_view.buffer]; - const auto &position_data = reinterpret_cast(position_buffer.data.data() + position_buffer_view.byteOffset + position_accessor.byteOffset); - const auto &index_accessor = model.accessors[primitive.indices]; const auto &index_buffer_view = model.bufferViews[index_accessor.bufferView]; const auto &index_buffer = model.buffers[index_buffer_view.buffer]; - const auto &index_data = reinterpret_cast(index_buffer.data.data() + index_buffer_view.byteOffset + index_accessor.byteOffset); + const uint8_t *index_data_ptr = index_buffer.data.data() + index_buffer_view.byteOffset + index_accessor.byteOffset; + + auto extract_index = [&index_data_ptr]() -> T requires std::integral { + const T *index_data = reinterpret_cast(index_data_ptr); + index_data_ptr += sizeof(T); + return *index_data; + }; + switch (index_accessor.componentType) { + case TINYGLTF_COMPONENT_TYPE_BYTE: + for (size_t i = 0; i < index_accessor.count; i++) { + iris_mesh.indices.push_back(extract_index.operator()()); + } + break; + case TINYGLTF_COMPONENT_TYPE_UNSIGNED_BYTE: + for (size_t i = 0; i < index_accessor.count; i++) { + iris_mesh.indices.push_back(extract_index.operator()()); + } + break; + case TINYGLTF_COMPONENT_TYPE_SHORT: + for (size_t i = 0; i < index_accessor.count; i++) { + iris_mesh.indices.push_back(extract_index.operator()()); + } + break; + case TINYGLTF_COMPONENT_TYPE_UNSIGNED_SHORT: + for (size_t i = 0; i < index_accessor.count; i++) { + iris_mesh.indices.push_back(extract_index.operator()()); + } + break; + case TINYGLTF_COMPONENT_TYPE_INT: + for (size_t i = 0; i < index_accessor.count; i++) { + iris_mesh.indices.push_back(extract_index.operator()()); + } + break; + case TINYGLTF_COMPONENT_TYPE_UNSIGNED_INT: + for (size_t i = 0; i < index_accessor.count; i++) { + iris_mesh.indices.push_back(extract_index.operator()()); + } + break; + default: + spdlog::error("Unsupported index component type: {}", index_accessor.componentType); + return false; + } + + switch (primitive.mode) { + case TINYGLTF_MODE_TRIANGLES: { + // All float ? + for (const auto &[attrib_name, accessor_index] : primitive.attributes) { + const auto &accessor = model.accessors[accessor_index]; + const auto &buffer_view = model.bufferViews[accessor.bufferView]; + const auto &buffer = model.buffers[buffer_view.buffer]; + const float *data = reinterpret_cast(buffer.data.data() + buffer_view.byteOffset + accessor.byteOffset); - iris_mesh.vertices.insert(iris_mesh.vertices.end(), position_data, position_data + position_accessor.count * 3); - iris_mesh.indices.insert(iris_mesh.indices.end(), index_data, index_data + index_accessor.count); + // TODO: support other types. Currently only float3 is supported + if (accessor.type != TINYGLTF_TYPE_VEC3 || accessor.componentType != TINYGLTF_COMPONENT_TYPE_FLOAT) { + spdlog::error("Unsupported POSITION type: {}, {}", accessor.type, accessor.componentType); + return false; + } + + // spdlog::info("attribute: {}, count: {}", attrib_name, accessor.count); + if (attrib_name == "POSITION") { + spdlog::info("loading POSITION, count {}", accessor.count); + for (size_t i = 0; i < accessor.count; i++) { + iris_mesh.vertices.push_back(data[i * 3 + 0]); + iris_mesh.vertices.push_back(data[i * 3 + 1]); + iris_mesh.vertices.push_back(data[i * 3 + 2]); + } + } else if (attrib_name == "NORMAL") { + spdlog::info("loading NORMAL, count {}", accessor.count); + for (size_t i = 0; i < accessor.count; i++) { + iris_mesh.vertices.push_back(data[i * 3 + 0]); + iris_mesh.vertices.push_back(data[i * 3 + 1]); + iris_mesh.vertices.push_back(data[i * 3 + 2]); + } + // TODO reorder normals correctly + } else if (attrib_name == "TEXCOORD_0") { + spdlog::info("loading TEXCOORD_0, count {}", accessor.count); + for (size_t i = 0; i < accessor.count; i++) { + iris_mesh.vertices.push_back(data[i * 2 + 0]); + iris_mesh.vertices.push_back(data[i * 2 + 1]); + } + } else { + spdlog::warn("Unsupported attribute: {}", attrib_name); + } + } + } + // TODO add support for other modes + default: + spdlog::error("Unsupported primitive mode: {}", primitive.mode); + return false; + } } scene.meshes.push_back(iris_mesh); } + return true; } \ No newline at end of file diff --git a/src/render_assets.h b/src/render_assets.h index 763bf76..d8e166b 100644 --- a/src/render_assets.h +++ b/src/render_assets.h @@ -7,10 +7,10 @@ namespace iris { -template struct Mesh { std::string name; - std::vector vertices; + std::vector vertices; + std::vector normals; std::vector indices; }; @@ -28,7 +28,7 @@ struct Camera { }; struct Scene { - std::vector> meshes; + std::vector meshes; std::vector materials; std::vector textures; -- cgit v1.2.3-70-g09d2