From 663f7bc5f4c51c62b94bc6331aff26355cfde630 Mon Sep 17 00:00:00 2001 From: lisyarus Date: Sat, 16 Mar 2024 17:37:57 +0300 Subject: [PATCH] Support retrieving extra properties & raw mesh from gltf mesh --- libs/gfx/include/psemek/gfx/gltf_mesh.hpp | 5 +++ libs/gfx/include/psemek/gfx/gltf_parser.hpp | 3 +- libs/gfx/source/gltf_mesh.cpp | 45 +++++++++++++++++++-- 3 files changed, 48 insertions(+), 5 deletions(-) diff --git a/libs/gfx/include/psemek/gfx/gltf_mesh.hpp b/libs/gfx/include/psemek/gfx/gltf_mesh.hpp index 5cabbc04..5d004f8b 100644 --- a/libs/gfx/include/psemek/gfx/gltf_mesh.hpp +++ b/libs/gfx/include/psemek/gfx/gltf_mesh.hpp @@ -3,6 +3,7 @@ #include #include #include +#include #include #include @@ -17,11 +18,15 @@ namespace psemek::gfx { gfx::drawable * drawable; std::optional material; + + util::span const> vertices; + util::span const> triangles; }; virtual gltf_asset::material const & material(std::size_t index) const = 0; virtual gfx::texture_2d const & texture(std::size_t index) const = 0; virtual util::span mesh(std::string_view name) const = 0; + virtual gltf_asset::extra const * mesh_property(std::string_view mesh_name, std::string_view property_name) const = 0; virtual ~gltf_mesh() {} }; diff --git a/libs/gfx/include/psemek/gfx/gltf_parser.hpp b/libs/gfx/include/psemek/gfx/gltf_parser.hpp index 08923379..59394afd 100644 --- a/libs/gfx/include/psemek/gfx/gltf_parser.hpp +++ b/libs/gfx/include/psemek/gfx/gltf_parser.hpp @@ -6,6 +6,7 @@ #include #include #include +#include #include #include @@ -19,7 +20,7 @@ namespace psemek::gfx struct gltf_asset { using extra = std::variant, std::string>; - using extras_map = std::unordered_map; + using extras_map = std::unordered_map; struct node { diff --git a/libs/gfx/source/gltf_mesh.cpp b/libs/gfx/source/gltf_mesh.cpp index b3d0bbaf..105e7fec 100644 --- a/libs/gfx/source/gltf_mesh.cpp +++ b/libs/gfx/source/gltf_mesh.cpp @@ -1,4 +1,5 @@ #include +#include #include #include #include @@ -21,6 +22,9 @@ namespace psemek::gfx std::size_t index_offset; GLenum index_type; + std::vector> vertices; + std::vector> triangles; + void draw() const override { vao.bind(); @@ -46,16 +50,32 @@ namespace psemek::gfx util::span mesh(std::string_view name) const override { if (auto it = meshes_.find(name); it != meshes_.end()) - return it->second; + return it->second.primitives; return {}; } + gltf_asset::extra const * mesh_property(std::string_view mesh_name, std::string_view property_name) const override + { + if (auto it = meshes_.find(mesh_name); it != meshes_.end()) + if (auto jt = it->second.extras.find(property_name); jt != it->second.extras.end()) + return &(jt->second); + return nullptr; + } + private: + struct mesh_data + { + std::vector primitives; + gltf_asset::extras_map extras; + std::vector> vertices; + std::vector> triangles; + }; + std::vector materials_; std::vector textures_; std::vector buffers_; std::vector> drawables_; - std::unordered_map> meshes_; + std::unordered_map meshes_; }; gltf_mesh_impl::gltf_mesh_impl(gltf_asset const & asset, std::function uri_loader) @@ -91,6 +111,7 @@ namespace psemek::gfx continue; auto & target_mesh = meshes_[node.name]; + target_mesh.extras = node.extras; auto const & mesh = asset.meshes[*node.mesh]; @@ -111,11 +132,12 @@ namespace psemek::gfx drawable.index_count = indices_accessor.count; } - std::pair> attributes[3] = + std::pair> attributes[] = { {0, primitive.position}, {1, primitive.normal}, {2, primitive.texcoord}, + {3, primitive.color}, }; for (auto const & attribute : attributes) @@ -130,7 +152,22 @@ namespace psemek::gfx gl::VertexAttribPointer(attribute.first, attribute_size(accessor.type), accessor.component_type, accessor.normalized, 0, reinterpret_cast(view.offset)); } - target_mesh.push_back({&drawable, primitive.material}); + { + auto indices = accessor_range(asset, primitive.indices); + for (auto it = indices.it_begin; it != indices.it_end;) + { + auto i0 = *it++; + auto i1 = *it++; + auto i2 = *it++; + drawable.triangles.push_back({i0, i1, i2}); + } + } + + if (primitive.position) + for (auto const & p : accessor_range>(asset, *primitive.position)) + drawable.vertices.push_back(p); + + target_mesh.primitives.push_back({&drawable, primitive.material, drawable.vertices, drawable.triangles}); } } }