#include "gltf.hpp" #include #include #include "utils.hpp" const vec3 scale (0.00800000037997961); 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]; uint16_t* indices_start = (uint16_t*)(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]; float* positions_start = (float*)(positions_buffer.data() + positions_offset); mesh_part.positions.resize(positions_length / (sizeof(float) * 3)); 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; } } // { // 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); // } }