summaryrefslogtreecommitdiff
path: root/src/gltf_loader.cpp
diff options
context:
space:
mode:
authorLeon Kang <2090093273@qq.com>2024-10-03 21:04:37 -0700
committerLeon Kang <2090093273@qq.com>2024-10-03 21:04:37 -0700
commit1f47c662a07ec83d4033b1a5f4b48dd8dfa58b7b (patch)
treecfb8941b80d1bc672bf25dba3ca716a1e0bc0823 /src/gltf_loader.cpp
parentc1ceb18d1c6d8af1266fc9cb9233e2328dd4d723 (diff)
parente59529d3f55b9128f798a7f02a7288f96bdaf9a4 (diff)
downloadiris-1f47c662a07ec83d4033b1a5f4b48dd8dfa58b7b.tar.gz
iris-1f47c662a07ec83d4033b1a5f4b48dd8dfa58b7b.zip
Merge branch 'main' into windows-build
Diffstat (limited to 'src/gltf_loader.cpp')
-rw-r--r--src/gltf_loader.cpp96
1 files changed, 96 insertions, 0 deletions
diff --git a/src/gltf_loader.cpp b/src/gltf_loader.cpp
new file mode 100644
index 0000000..2b3818f
--- /dev/null
+++ b/src/gltf_loader.cpp
@@ -0,0 +1,96 @@
+#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<float> 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<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);
+
+ 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;
+} \ No newline at end of file