From 3dd870b001bef62aaa501257352d968d1346c7f2 Mon Sep 17 00:00:00 2001 From: ladevieq Date: Sun, 25 Jul 2021 11:58:01 +0200 Subject: Use a different buffer for scene info, geometry, bvh and load gltf --- src/gltf.cpp | 104 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 104 insertions(+) create mode 100644 src/gltf.cpp (limited to 'src/gltf.cpp') diff --git a/src/gltf.cpp b/src/gltf.cpp new file mode 100644 index 0000000..0e74aaf --- /dev/null +++ b/src/gltf.cpp @@ -0,0 +1,104 @@ +#include "gltf.hpp" + +#include +#include + +#include "utils.hpp" + +mesh 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 buffers = gltf_json["buffers"]; + auto buffer_index = 0; + auto buffers_content = std::vector>(buffers.size()); + for (auto &buffer: buffers) { + auto buffer_path = (path / buffer["uri"].get()).string(); + buffers_content[buffer_index] = read_file(buffer_path); + 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); + } + + // return std::move(gltf_mesh); + return gltf_mesh; +} + +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"]; + + for (auto &primitive: primitives) { + gltf_mesh.nodes.back().push_back(mesh_part()); + load_primitive(gltf_json, primitive, buffers_content, gltf_mesh); + } +} + +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(); + + { + 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_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]; + void* indices_start = indices_buffer.data() + indices_offset; + + mesh_part.indices.resize(indices_length / sizeof(uint16_t)); + + std::memcpy(mesh_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_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]; + void* positions_start = positions_buffer.data() + positions_offset; + + mesh_part.positions.resize(positions_length / (sizeof(float) * 3)); + + std::memcpy(mesh_part.positions.data(), positions_start, positions_length); + } + + { + auto normals_accessor_index = primitive["attributes"]["NORMAL"].get(); + auto normals_view_index = accessors[normals_accessor_index]["bufferView"].get(); + auto normals_view = gltf_json["bufferViews"][normals_view_index]; + + auto normals_buffer_index = normals_view["buffer"].get(); + auto normals_offset = normals_view["byteOffset"].get(); + auto normals_length = normals_view["byteLength"].get(); + + auto normals_buffer = buffers_content[normals_buffer_index]; + void* normals_start = normals_buffer.data() + normals_offset; + + mesh_part.normals.resize(normals_length / (sizeof(float) * 3)); + + std::memcpy(mesh_part.normals.data(), normals_start, normals_length); + } +} -- cgit v1.3