diff options
author | Chuyan Zhang <chuyan@ucsb.edu> | 2024-10-04 18:13:57 -0700 |
---|---|---|
committer | Chuyan Zhang <chuyan@ucsb.edu> | 2024-10-04 18:13:57 -0700 |
commit | 9c2c152c3926490a632fe32ad2ac7682ea7cbd74 (patch) | |
tree | fce47b92670d04fdd62e5c3beab669870d58efcf | |
parent | f7d8c400a629076d1de501739ea9faa2189bdca2 (diff) | |
download | iris-9c2c152c3926490a632fe32ad2ac7682ea7cbd74.tar.gz iris-9c2c152c3926490a632fe32ad2ac7682ea7cbd74.zip |
WIP glTF loader
-rw-r--r-- | src/gltf_loader.cpp | 105 | ||||
-rw-r--r-- | 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 <concepts> 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<float> 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<const float *>(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<const uint32_t *>(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]<typename T>() -> T requires std::integral<T> { + const T *index_data = reinterpret_cast<const T *>(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()<int8_t>()); + } + 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()<uint8_t>()); + } + break; + case TINYGLTF_COMPONENT_TYPE_SHORT: + for (size_t i = 0; i < index_accessor.count; i++) { + iris_mesh.indices.push_back(extract_index.operator()<int16_t>()); + } + 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()<uint16_t>()); + } + break; + case TINYGLTF_COMPONENT_TYPE_INT: + for (size_t i = 0; i < index_accessor.count; i++) { + iris_mesh.indices.push_back(extract_index.operator()<int32_t>()); + } + 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()<uint32_t>()); + } + 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<const float *>(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<typename T> struct Mesh { std::string name; - std::vector<T> vertices; + std::vector<float> vertices; + std::vector<float> normals; std::vector<uint32_t> indices; }; @@ -28,7 +28,7 @@ struct Camera { }; struct Scene { - std::vector<Mesh<float>> meshes; + std::vector<Mesh> meshes; std::vector<Material> materials; std::vector<Texture> textures; |