From 1866dd531dffc4084dfaf261591bc7ac2a376d67 Mon Sep 17 00:00:00 2001 From: Chuyan Zhang Date: Fri, 4 Oct 2024 22:43:11 -0700 Subject: add basic gltf loader --- src/gltf_loader.cpp | 67 +++++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 49 insertions(+), 18 deletions(-) (limited to 'src/gltf_loader.cpp') diff --git a/src/gltf_loader.cpp b/src/gltf_loader.cpp index 142b69f..bf64740 100644 --- a/src/gltf_loader.cpp +++ b/src/gltf_loader.cpp @@ -1,6 +1,6 @@ #include "gltf_loader.h" #include "spdlog/spdlog.h" -#include +#include enum class SceneFileType { GLTF, @@ -79,6 +79,8 @@ bool load_gltf(const std::string_view path, iris::Scene &scene) { iris::Mesh iris_mesh { .name = mesh.name, .vertices = {}, + .normals = {}, + .texcoords = {}, .indices = {}, }; for (const auto &primitive : mesh.primitives) { @@ -87,7 +89,7 @@ bool load_gltf(const std::string_view path, iris::Scene &scene) { const auto &index_buffer = model.buffers[index_buffer_view.buffer]; 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 { + auto extract = [&index_data_ptr]() -> T { const T *index_data = reinterpret_cast(index_data_ptr); index_data_ptr += sizeof(T); return *index_data; @@ -95,32 +97,32 @@ bool load_gltf(const std::string_view path, iris::Scene &scene) { 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()()); + iris_mesh.indices.push_back(extract.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()()); + iris_mesh.indices.push_back(extract.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()()); + iris_mesh.indices.push_back(extract.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()()); + iris_mesh.indices.push_back(extract.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()()); + iris_mesh.indices.push_back(extract.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()()); + iris_mesh.indices.push_back(extract.operator()()); } break; default: @@ -135,7 +137,12 @@ bool load_gltf(const std::string_view path, iris::Scene &scene) { 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); + const uint8_t *data = buffer.data.data() + buffer_view.byteOffset + accessor.byteOffset; + auto extract_data = [&data]() -> T { + const T *typed_data = reinterpret_cast(data); + data += sizeof(T); + return *typed_data; + }; // TODO: support other types. Currently only float3 is supported if (accessor.type != TINYGLTF_TYPE_VEC3 || accessor.componentType != TINYGLTF_COMPONENT_TYPE_FLOAT) { @@ -146,24 +153,20 @@ bool load_gltf(const std::string_view path, iris::Scene &scene) { // spdlog::info("attribute: {}, count: {}", attrib_name, accessor.count); if (attrib_name == "POSITION") { spdlog::info("loading POSITION, count {}", accessor.count); + iris_mesh.p_min = glm::vec3(accessor.minValues[0], accessor.minValues[1], accessor.minValues[2]); + iris_mesh.p_max = glm::vec3(accessor.maxValues[0], accessor.maxValues[1], accessor.maxValues[2]); 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]); + iris_mesh.vertices.push_back(extract_data.operator()()); } } 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]); + iris_mesh.normals.push_back(extract_data.operator()()); } - // 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]); + iris_mesh.texcoords.push_back(extract_data.operator()()); } } else { spdlog::warn("Unsupported attribute: {}", attrib_name); @@ -179,5 +182,33 @@ bool load_gltf(const std::string_view path, iris::Scene &scene) { scene.meshes.push_back(iris_mesh); } + // TODO load materials and textures + + for (const tinygltf::Camera &camera : model.cameras) { + iris::Camera iris_camera { + .position = glm::vec3(0.0f), + .direction = glm::vec3(0.0f), + .up = glm::vec3(0.0f, 1.0f, 0.0f), + }; + spdlog::info("Camera: {}, type: {}", camera.name, camera.type); + if (camera.type == "perspective") { + const auto &perspective = camera.perspective; + iris_camera.intrinsic_tag = iris::Camera::Tag::Perspective; + iris_camera.intrinsic.perspective.fovx = 2 * glm::atan(glm::tan(perspective.yfov / 2) * perspective.aspectRatio); + iris_camera.intrinsic.perspective.fovy = perspective.yfov; + iris_camera.intrinsic.perspective.aspect = perspective.aspectRatio; + iris_camera.intrinsic.perspective.znear = perspective.znear; + iris_camera.intrinsic.perspective.zfar = perspective.zfar; + } else { + const auto &orthographic = camera.orthographic; + iris_camera.intrinsic_tag = iris::Camera::Tag::Orthographic; + iris_camera.intrinsic.orthographic.xmag = orthographic.xmag; + iris_camera.intrinsic.orthographic.ymag = orthographic.ymag; + iris_camera.intrinsic.orthographic.znear = orthographic.znear; + iris_camera.intrinsic.orthographic.zfar = orthographic.zfar; + } + scene.camera = iris_camera; + } + return true; } \ No newline at end of file -- cgit v1.2.3-70-g09d2