From e1cbdd1d61ffb04ae156fe67923ec5e0871021f1 Mon Sep 17 00:00:00 2001 From: ladevieq Date: Sun, 15 Aug 2021 23:17:06 +0200 Subject: Improve gltf loading --- src/gltf.cpp | 91 +++++++++++++++++++++++++++++++++++++++-------------------- src/scene.cpp | 42 +++++++++++++++++++-------- src/utils.cpp | 2 +- 3 files changed, 92 insertions(+), 43 deletions(-) (limited to 'src') diff --git a/src/gltf.cpp b/src/gltf.cpp index 055f2a6..6b39ff4 100644 --- a/src/gltf.cpp +++ b/src/gltf.cpp @@ -7,17 +7,15 @@ const vec3 scale (0.00800000037997961); -mesh gltf::load(std::filesystem::path &path, std::string &filename) { +node gltf::load(std::filesystem::path &path, std::string &filename) { std::fstream f(path / filename); json gltf_json; f >> gltf_json; - auto scene_index = gltf_json["scene"].get(); - auto scenes = gltf_json["scenes"]; - auto scene = scenes[scene_index]; + auto &scene = gltf_json["scenes"][0]; - auto buffers = gltf_json["buffers"]; + auto &buffers = gltf_json["buffers"]; auto buffer_index = 0; auto buffers_content = std::vector>(buffers.size()); for (auto &buffer: buffers) { @@ -26,66 +24,95 @@ mesh gltf::load(std::filesystem::path &path, std::string &filename) { buffer_index++; } - auto nodes = gltf_json["nodes"]; - auto gltf_mesh = mesh(); - for (auto &node: nodes) { - gltf_mesh.nodes.push_back(std::vector()); - load_node(gltf_json, node, buffers_content, gltf_mesh); + auto meshes = load_meshes(gltf_json, buffers_content); + + node root_node; + auto &root_children = scene["nodes"]; + uint32_t root_children_count = scene["nodes"].size(); + root_node.children.resize(root_children_count); + + for (size_t child_index = 0; child_index < root_children_count; child_index++) { + load_node(gltf_json, root_children[child_index].get(), root_node.children[child_index], meshes); + } + + return std::move(root_node); +} + +void gltf::load_node(json &gltf_json, uint32_t index, node &parent, std::vector &meshes) { + auto &gltf_node = gltf_json["nodes"][index]; + + if (gltf_node.contains("children")) { + auto &children = gltf_node["children"]; + uint32_t children_count = gltf_node["children"]; + parent.children.resize(children_count); + + for (size_t child_index = 0; child_index < children_count; child_index++) { + load_node(gltf_json, children[child_index].get(), parent.children[child_index], meshes); + } } - // return std::move(gltf_mesh); - return gltf_mesh; + if (gltf_node.contains("mesh")) { + parent.mesh = std::make_optional(meshes[gltf_node["mesh"].get()]); + } } -void gltf::load_node(json &gltf_json, json &node, std::vector> &buffers_content, mesh& gltf_mesh) { - auto mesh_index = node["mesh"].get(); - auto mesh = gltf_json["meshes"][mesh_index]; - auto primitives = mesh["primitives"]; +std::vector gltf::load_meshes(json &gltf_json, std::vector> &buffers_content) { + auto &gltf_meshes = gltf_json["meshes"]; + auto meshes_count = gltf_meshes.size(); + std::vector meshes { meshes_count }; + + for(size_t mesh_index = 0; mesh_index < meshes_count; mesh_index++) { + auto &gltf_mesh = gltf_meshes[mesh_index]; + auto &primitives = gltf_mesh["primitives"]; + auto &mesh = meshes[mesh_index]; - for (auto &primitive: primitives) { - gltf_mesh.nodes.back().push_back(mesh_part()); - load_primitive(gltf_json, primitive, buffers_content, gltf_mesh); + for (auto& primitive: primitives) { + mesh.parts.emplace_back(load_primitive(gltf_json, primitive, buffers_content)); + } } + + return std::move(meshes); } -void gltf::load_primitive(json &gltf_json, json &primitive, std::vector> &buffers_content, mesh& gltf_mesh) { - auto accessors = gltf_json["accessors"]; - auto &mesh_part = gltf_mesh.nodes.back().back(); +mesh_part gltf::load_primitive(json &gltf_json, json &primitive, std::vector> &buffers_content) { + auto part = mesh_part(); + auto &accessors = gltf_json["accessors"]; { auto indices_accessor_index = primitive["indices"].get(); auto indices_view_index = accessors[indices_accessor_index]["bufferView"].get(); - auto indices_view = gltf_json["bufferViews"][indices_view_index]; + auto &indices_view = gltf_json["bufferViews"][indices_view_index]; auto indices_buffer_index = indices_view["buffer"].get(); auto indices_offset = indices_view["byteOffset"].get(); auto indices_length = indices_view["byteLength"].get(); - auto indices_buffer = buffers_content[indices_buffer_index]; + auto &indices_buffer = buffers_content[indices_buffer_index]; uint16_t* indices_start = (uint16_t*)(indices_buffer.data() + indices_offset); - mesh_part.indices.resize(indices_length / sizeof(uint16_t)); + part.indices.resize(indices_length / sizeof(uint16_t)); - std::memcpy(mesh_part.indices.data(), indices_start, indices_length); + std::memcpy(part.indices.data(), indices_start, indices_length); } { auto positions_accessor_index = primitive["attributes"]["POSITION"].get(); auto positions_view_index = accessors[positions_accessor_index]["bufferView"].get(); - auto positions_view = gltf_json["bufferViews"][positions_view_index]; + auto &positions_view = gltf_json["bufferViews"][positions_view_index]; auto positions_buffer_index = positions_view["buffer"].get(); auto positions_offset = positions_view["byteOffset"].get(); auto positions_length = positions_view["byteLength"].get(); - auto positions_buffer = buffers_content[positions_buffer_index]; + auto &positions_buffer = buffers_content[positions_buffer_index]; float* positions_start = (float*)(positions_buffer.data() + positions_offset); - mesh_part.positions.resize(positions_length / (sizeof(float) * 3)); + size_t positions_count = positions_length / (sizeof(float) * 3); + part.positions.resize(positions_count); - for (size_t i = 0; i < positions_length / (sizeof(float) * 3); i++) { - mesh_part.positions[i] = vec3(positions_start[i * 3], positions_start[i * 3 + 1], positions_start[i * 3 + 2]) * scale; + for (size_t i = 0; i < positions_count; i++) { + part.positions[i] = vec3(positions_start[i * 3], positions_start[i * 3 + 1], positions_start[i * 3 + 2]) * scale; } } @@ -105,4 +132,6 @@ void gltf::load_primitive(json &gltf_json, json &primitive, std::vector +#include #include "utils.hpp" #include "gltf.hpp" @@ -69,23 +70,42 @@ scene::scene(camera cam, uint32_t width, uint32_t height) :meta(cam, width, height){ + // auto bistro_interior_path = std::filesystem::path("../models/BistroInterior"); + // auto bistro_interior_filename = std::string("BistroInterior.gltf"); + // auto root_node = gltf::load(bistro_interior_path, bistro_interior_filename); + auto sponza_path = std::filesystem::path("../models/sponza"); auto sponza_filename = std::string("Sponza.gltf"); - auto mesh = gltf::load(sponza_path, sponza_filename); + auto root_node = gltf::load(sponza_path, sponza_filename); + + std::queue nodes_to_load {}; + nodes_to_load.push(root_node); + + while(nodes_to_load.size() != 0) { + auto &node = nodes_to_load.front(); - auto node = mesh.nodes[0]; - for (auto& mesh_part: node) { - for (size_t i = 0; i < mesh_part.indices.size(); i += 3) { - auto i1 = mesh_part.indices[i]; - auto i2 = mesh_part.indices[i + 1]; - auto i3 = mesh_part.indices[i + 2]; + if (node.mesh) { + auto &mesh = node.mesh.value(); + for (auto& mesh_part: mesh.parts) { + for (size_t i = 0; i < mesh_part.indices.size(); i += 3) { + auto i1 = mesh_part.indices[i]; + auto i2 = mesh_part.indices[i + 1]; + auto i3 = mesh_part.indices[i + 2]; - auto v1 = vertex { .position = mesh_part.positions[i1] }; - auto v2 = vertex { .position = mesh_part.positions[i2] }; - auto v3 = vertex { .position = mesh_part.positions[i3] }; + auto v1 = vertex { .position = mesh_part.positions[i1] }; + auto v2 = vertex { .position = mesh_part.positions[i2] }; + auto v3 = vertex { .position = mesh_part.positions[i3] }; - triangles.emplace_back(v1, v2, v3); + triangles.emplace_back(v1, v2, v3); + } + } } + + for (auto &node: node.children) { + nodes_to_load.push(node); + } + + nodes_to_load.pop(); } // random_scene(); diff --git a/src/utils.cpp b/src/utils.cpp index 6557ebc..2a9bdf5 100644 --- a/src/utils.cpp +++ b/src/utils.cpp @@ -37,7 +37,7 @@ std::vector read_file(const char* path) { return {}; } - return file_content; + return std::move(file_content); } std::vector read_file(std::string& path) { -- cgit v1.3