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 +++++++++++++++++++++++++++++++++++++++-------------- src/render_assets.h | 34 +++++++++++++++++++++++---- xmake.lua | 6 ++++- 3 files changed, 84 insertions(+), 23 deletions(-) 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 diff --git a/src/render_assets.h b/src/render_assets.h index 2dfff07..8c28ead 100644 --- a/src/render_assets.h +++ b/src/render_assets.h @@ -9,10 +9,14 @@ namespace iris { struct Mesh { std::string name; - std::vector vertices; - std::vector normals; - std::vector texcoords; + std::vector vertices; + std::vector normals; + std::vector texcoords; std::vector indices; + + // AABB + glm::vec3 p_min; + glm::vec3 p_max; }; struct Material { @@ -23,6 +27,28 @@ struct Texture { }; struct Camera { + enum struct Tag { + Perspective, + Orthographic, + } intrinsic_tag; + struct PerspectiveCamera { + float fovx; + float fovy; + float aspect; + float znear; + float zfar; + }; + + struct OrthographicCamera { + float xmag; + float ymag; + float znear; + float zfar; + }; + union { + PerspectiveCamera perspective; + OrthographicCamera orthographic; + } intrinsic; glm::vec3 position; glm::vec3 direction; glm::vec3 up; @@ -33,7 +59,7 @@ struct Scene { std::vector materials; std::vector textures; - Camera camera_position; + Camera camera; }; } // namespace iris \ No newline at end of file diff --git a/xmake.lua b/xmake.lua index 1171462..e634221 100644 --- a/xmake.lua +++ b/xmake.lua @@ -57,13 +57,17 @@ target("stb") set_kind("headeronly") add_includedirs(path.join(ext_dir, "stb"), {public = true}) +target("glm") + set_kind("headeronly") + add_includedirs(path.join(ext_dir, "glm"), {public = true}) + -- Main executable target target("iris_renderer") set_kind("binary") add_files(path.join(src_dir, "**.cpp")) -- Link external libraries - add_deps("argparse", "imgui", "tinygltf", "tinyobjloader", "stb") + add_deps("argparse", "imgui", "tinygltf", "tinyobjloader", "stb", "glm") -- Add libraries add_packages("vulkansdk", "glfw", "fmt", "vulkan-memory-allocator", "spdlog", "glm") -- cgit v1.2.3-70-g09d2