From ae0ea5fb65b0340eabf4e9e424ba79787600dc1b Mon Sep 17 00:00:00 2001 From: ladevieq Date: Fri, 19 Aug 2022 12:13:16 +0200 Subject: Generate BVH using new mesh data structure --- include/mesh.hpp | 8 ++++ src/gltf.cpp | 4 +- src/main.cpp | 2 +- src/mesh.cpp | 2 +- src/scene.cpp | 128 ++++++++++++++++++++++++++++++++----------------------- 5 files changed, 87 insertions(+), 57 deletions(-) diff --git a/include/mesh.hpp b/include/mesh.hpp index 34f2df8..03dbcfc 100644 --- a/include/mesh.hpp +++ b/include/mesh.hpp @@ -68,6 +68,14 @@ public: [[nodiscard]] inline uint32_t triangle_count() const { return index_count / 3; }; [[nodiscard]] inline uint32_t vertices_count() const { return vertex_count; }; + [[nodiscard]] inline const std::vector& get_submeshes() const { return submeshes; }; + + [[nodiscard]] inline const std::vector& get_attribute(enum ATTRIBUTE_TYPE attribute_type) const { + return attributes[(uint32_t)attribute_type]; + }; + + [[nodiscard]] inline const std::vector& get_indices() const { return indices; } + static void register_mesh(const Mesh& mesh); diff --git a/src/gltf.cpp b/src/gltf.cpp index 8f266f2..a05237c 100644 --- a/src/gltf.cpp +++ b/src/gltf.cpp @@ -82,11 +82,11 @@ Mesh::submesh gltf::load_primitive(const json &primitive) { submesh.attributes[ATTRIBUTE_TYPE::POSITION] = load_attribute(primitive["attributes"]["POSITION"]); if (primitive["attributes"].contains("NORMAL")) { - submesh.attributes[ATTRIBUTE_TYPE::POSITION] = load_attribute(primitive["attributes"]["NORMAL"]); + submesh.attributes[ATTRIBUTE_TYPE::NORMAL] = load_attribute(primitive["attributes"]["NORMAL"]); } if (primitive["attributes"].contains("TEXCOORD_0")) { - submesh.attributes[ATTRIBUTE_TYPE::POSITION] = load_attribute(primitive["attributes"]["TEXCOORD_0"]); + submesh.attributes[ATTRIBUTE_TYPE::UV_0] = load_attribute(primitive["attributes"]["TEXCOORD_0"]); } submesh.index_count = gltf_json["accessors"][primitive["indices"].get()]["count"].get(); diff --git a/src/main.cpp b/src/main.cpp index 2f53dd6..576b709 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -71,7 +71,7 @@ void render(scene& main_scene, vkrenderer& renderer) { // capture from that device. See the documentation below for a longer // explanation if(rdoc_api) rdoc_api->StartFrameCapture(NULL, NULL); - main_scene.scene_buffer->write(&main_scene.meta, 0, sizeof(main_scene.meta)); + main_scene.scene_buffer->write(&main_scene.meta, renderer.frame_index() * sizeof(main_scene.meta), sizeof(main_scene.meta)); // ImDrawData* draw_data = ImGui::GetDrawData(); diff --git a/src/mesh.cpp b/src/mesh.cpp index c9b5358..3cebc52 100644 --- a/src/mesh.cpp +++ b/src/mesh.cpp @@ -7,7 +7,7 @@ void Mesh::add_submesh(const submesh& submesh) { submeshes.emplace_back(submesh_info { (uint32_t)attributes[ATTRIBUTE_TYPE::POSITION].size() / position_components, (uint32_t)indices.size(), - submesh.index_count, + submesh.index_count / 3, 0 }); diff --git a/src/scene.cpp b/src/scene.cpp index 990e00e..4093ff7 100644 --- a/src/scene.cpp +++ b/src/scene.cpp @@ -73,59 +73,80 @@ scene::scene(const camera& cam, uint32_t width, uint32_t height) std::vector packed_nodes; // auto root_node = gltf::load("../models/BistroInterior", "BistroInterior.gltf"); - auto model = gltf("../models/sponza/Sponza.gltf"); + auto gltf_model = gltf("../models/sponza/Sponza.gltf"); std::vector triangles; - // size_t triangles_offset = 0; - // size_t vertices_offset = 0; - // std::queue nodes_to_load {}; - // nodes_to_load.push(model.root_node); - - // while(!nodes_to_load.empty()) { - // auto &node = nodes_to_load.front(); - - // if (node.mesh != nullptr) { - // auto &mesh = node.mesh.value(); - - // indices.resize(indices.size() + (size_t)mesh.triangle_count() * 3); - // positions.resize(positions.size() + (size_t)mesh.vertex_count() * 3); - // normals.resize(normals.size() + (size_t)mesh.vertex_count() * 3); - // uvs.resize(uvs.size() + (size_t)mesh.vertex_count() * 2); - - - // for (auto& mesh_part: mesh.parts) { - // std::memcpy(positions.data() + vertices_offset * 3, mesh_part.positions.data(), mesh_part.positions.size() * sizeof(float)); - // std::memcpy(normals.data() + vertices_offset * 3, mesh_part.normals.data(), mesh_part.normals.size() * sizeof(float)); - // std::memcpy(uvs.data() + vertices_offset * 2, mesh_part.uvs.data(), mesh_part.uvs.size() * sizeof(float)); - - // for (size_t i = 0; i < mesh_part.indices.size(); i += 3) { - // size_t i1 = mesh_part.indices[i]; - // size_t i2 = mesh_part.indices[i + 1]; - // size_t i3 = mesh_part.indices[i + 2]; - - // auto p1 = vec3(mesh_part.positions[i1 * 3], mesh_part.positions[i1 * 3 + 1], mesh_part.positions[i1 * 3 + 2]); - // auto p2 = vec3(mesh_part.positions[i2 * 3], mesh_part.positions[i2 * 3 + 1], mesh_part.positions[i2 * 3 + 2]); - // auto p3 = vec3(mesh_part.positions[i3 * 3], mesh_part.positions[i3 * 3 + 1], mesh_part.positions[i3 * 3 + 2]); - - // indices[triangles_offset * 3 + i] = (i1 + vertices_offset) | (0xff000000 & (materials.size() << 8)); - // indices[triangles_offset * 3 + i + 1] = (i2 + vertices_offset) | (0xff000000 & (materials.size() << 16)); - // indices[triangles_offset * 3 + i + 2] = (i3 + vertices_offset) | (0xff000000 & (materials.size() << 24)); - - // triangles.emplace_back(p1, p2, p3); - // materials.push_back(mesh_part.mat); - // } - - // triangles_offset += mesh_part.triangles_count; - // vertices_offset += mesh_part.vertices_count; - // } - // } - - // for (auto &new_node: node.children) { - // nodes_to_load.push(new_node); - // } - - // nodes_to_load.pop(); - // } + size_t triangles_offset = 0; + size_t vertices_offset = 0; + std::queue nodes_to_load {}; + nodes_to_load.push(gltf_model.root_node); + + while(!nodes_to_load.empty()) { + auto &node = nodes_to_load.front(); + + if (node.mesh != nullptr) { + const auto* mesh = node.mesh; + const auto& mesh_positions = mesh->get_attribute(ATTRIBUTE_TYPE::POSITION); + const auto& mesh_indices = mesh->get_indices(); + + indices.resize(indices.size() + (size_t)mesh->triangle_count() * 3); + positions.resize(vertices_offset + (size_t)mesh->vertices_count() * Mesh::attribute_components(ATTRIBUTE_TYPE::POSITION)); + normals.resize(vertices_offset + (size_t)mesh->vertices_count() * Mesh::attribute_components(ATTRIBUTE_TYPE::NORMAL)); + uvs.resize(vertices_offset + (size_t)mesh->vertices_count() * Mesh::attribute_components(ATTRIBUTE_TYPE::UV_0)); + + std::memcpy( + positions.data() + vertices_offset * Mesh::attribute_components(ATTRIBUTE_TYPE::POSITION), + positions.data(), + (size_t)mesh->vertices_count() * Mesh::attribute_components(ATTRIBUTE_TYPE::POSITION) + ); + + std::memcpy( + normals.data() + vertices_offset * Mesh::attribute_components(ATTRIBUTE_TYPE::NORMAL), + mesh->get_attribute(ATTRIBUTE_TYPE::NORMAL).data(), + (size_t)mesh->vertices_count() * Mesh::attribute_components(ATTRIBUTE_TYPE::NORMAL) + ); + + std::memcpy( + uvs.data() + vertices_offset * Mesh::attribute_components(ATTRIBUTE_TYPE::UV_0), + mesh->get_attribute(ATTRIBUTE_TYPE::UV_0).data(), + (size_t)mesh->vertices_count() * Mesh::attribute_components(ATTRIBUTE_TYPE::UV_0) + ); + + // Add offset to indices in order to have absolute indices + for (const auto& submesh: mesh->get_submeshes()) { + for (size_t element_index = 0; element_index < submesh.element_count; element_index++) { + auto global_index = submesh.index_offset + element_index * 3; + size_t i1 = mesh_indices[global_index]; + size_t i2 = mesh_indices[global_index + 1]; + size_t i3 = mesh_indices[global_index + 2]; + + triangles.emplace_back( + vec3 { mesh_positions[i1 * 3], mesh_positions[i1 * 3 + 1], mesh_positions[i1 * 3 + 2] }, + vec3 { mesh_positions[i2 * 3], mesh_positions[i2 * 3 + 1], mesh_positions[i2 * 3 + 2] }, + vec3 { mesh_positions[i3 * 3], mesh_positions[i3 * 3 + 1], mesh_positions[i3 * 3 + 2] } + ); + + auto triangle_offset = triangles_offset * 3 + global_index; + auto vertex_offset = vertices_offset + submesh.vertex_offset; + + indices[triangle_offset] = (i1 + vertex_offset); // | (0xff000000 & (materials.size() << 8)); + indices[triangle_offset + 1] = (i2 + vertex_offset); // | (0xff000000 & (materials.size() << 16)); + indices[triangle_offset + 2] = (i3 + vertex_offset); // | (0xff000000 & (materials.size() << 24)); + + // materials.push_back(submesh.mat); + } + } + + triangles_offset += mesh->triangle_count(); + vertices_offset += mesh->vertices_count(); + } + + for (auto &new_node: node.children) { + nodes_to_load.push(new_node); + } + + nodes_to_load.pop(); + } // random_scene(); @@ -133,8 +154,9 @@ scene::scene(const camera& cam, uint32_t width, uint32_t height) // bvh builder(spheres, packed_nodes); scene_buffer = vkrenderer::create_buffer(sizeof(meta) * vkrenderer::virtual_frames_count); - // TODO: Write to correct offset - // vkrenderer::update_buffer(scene_buffer, &meta, 0, sizeof(meta)); + scene_buffer->write(&meta, 0, sizeof(meta)); + scene_buffer->write(&meta, sizeof(meta), sizeof(meta)); + scene_buffer->write(&meta, sizeof(meta) * 2, sizeof(meta)); indices_buffer = vkrenderer::create_buffer(indices.size() * sizeof(indices[0])); indices_buffer->write(indices.data(), 0, indices.size() * sizeof(indices[0])); -- cgit v1.3