#include "gltf_loader.h" #include "spdlog/spdlog.h" enum class SceneFileType { GLTF, GLB, UNKNOWN, }; bool load_gltf(const std::string_view path, iris::Scene &scene) { tinygltf::Model model; tinygltf::TinyGLTF loader; std::string error; std::string warning; SceneFileType file_type = [&path] { if (path.find_last_of(".") != std::string::npos) { std::string_view extension = path.substr(path.find_last_of(".") + 1); if (extension == "glb") { return SceneFileType::GLB; } else if (extension == "gltf") { return SceneFileType::GLTF; } } return SceneFileType::UNKNOWN; }(); switch (file_type) { case SceneFileType::GLTF: if (!loader.LoadASCIIFromFile(&model, &error, &warning, path.data())) { spdlog::error("Failed to load glTF file: {}", error); return false; } break; case SceneFileType::GLB: if (!loader.LoadBinaryFromFile(&model, &error, &warning, path.data())) { spdlog::error("Failed to load glTF file: {}", error); return false; } break; case SceneFileType::UNKNOWN: spdlog::error("Unknown file type: {}", path); return false; } spdlog::info("loaded glTF file {} has:\n" "{} accessors\n" "{} animations\n" "{} buffers\n" "{} bufferViews\n" "{} materials\n" "{} meshes\n" "{} nodes\n" "{} textures\n" "{} images\n" "{} skins\n" "{} samplers\n" "{} cameras\n" "{} scenes\n" "{} lights", path, model.accessors.size(), model.animations.size(), model.buffers.size(), model.bufferViews.size(), model.materials.size(), model.meshes.size(), model.nodes.size(), model.textures.size(), model.images.size(), model.skins.size(), model.samplers.size(), model.cameras.size(), model.scenes.size(), model.lights.size()); for (const auto &mesh : model.meshes) { iris::Mesh iris_mesh; 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); 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); } scene.meshes.push_back(iris_mesh); } return true; }