sandbox
Loading...
Searching...
No Matches
mesh.hpp
1// SPDX-License-Identifier: MIT
2#ifndef LIBSBX_GRAPHICS_PIPELINE_MESH_HPP_
3#define LIBSBX_GRAPHICS_PIPELINE_MESH_HPP_
4
5#include <memory>
6#include <vector>
7#include <string>
8#include <unordered_map>
9
10#include <libsbx/utility/hashed_string.hpp>
11#include <libsbx/utility/exception.hpp>
12#include <libsbx/utility/assert.hpp>
13
14#include <libsbx/math/volume.hpp>
15
16#include <libsbx/graphics/buffers/buffer.hpp>
17#include <libsbx/graphics/buffers/storage_buffer.hpp>
18
19#include <libsbx/graphics/commands/command_buffer.hpp>
20
21#include <libsbx/graphics/pipeline/vertex_input_description.hpp>
22
23#include <libsbx/graphics/resource_storage.hpp>
24
25namespace sbx::graphics {
26
27struct submesh {
28 std::uint32_t index_count;
29 std::uint32_t index_offset;
30 std::uint32_t vertex_count;
31 std::uint32_t vertex_offset;
32 math::volume bounds;
33 math::matrix4x4 local_transform;
35 std::uint32_t material_index;
36}; // struct submesh
37
38template<vertex Vertex>
39class mesh {
40
41public:
42
43 using vertex_type = Vertex;
44
45 using index_type = std::uint32_t;
46
47 struct mesh_data {
48 std::vector<vertex_type> vertices;
49 std::vector<index_type> indices;
50 std::vector<graphics::submesh> submeshes;
51 math::volume bounds;
52 }; // struct mesh_data
53
54 mesh(const std::vector<vertex_type>& vertices, const std::vector<index_type>& indices, const math::volume& bounds = math::volume{});
55
56 mesh(std::vector<vertex_type>&& vertices, std::vector<index_type>&& indices, const math::volume& bounds = math::volume{});
57
58 mesh(const mesh& other) noexcept = delete;
59
60 virtual ~mesh();
61
62 auto render(graphics::command_buffer& command_buffer, std::uint32_t instance_count = 1u) const -> void;
63
64 auto render_submesh(graphics::command_buffer& command_buffer, std::uint32_t submesh_index, std::uint32_t instance_count = 1u) const -> void;
65
66 auto address() const -> std::uint64_t;
67
68 auto bind(graphics::command_buffer& command_buffer) const -> void;
69
70 auto render_submesh_indirect(graphics::storage_buffer& buffer, std::uint32_t offset, std::uint32_t submesh_index, std::uint32_t instance_count = 1u) const -> void;
71
72 auto submeshes() const noexcept -> const std::vector<graphics::submesh>&;
73
74 auto submesh_index(const utility::hashed_string& name) const -> std::uint32_t {
75 const auto entry = std::ranges::find(_submeshes, name, &graphics::submesh::name);
76
77 if (entry == _submeshes.end()) {
78 throw utility::runtime_error{"Submesh '{}' not found", name.str()};
79 }
80
81 return std::distance(_submeshes.begin(), entry);
82 }
83
84 auto submesh(std::uint32_t submesh_index) const -> const graphics::submesh& {
85 utility::assert_that(submesh_index < _submeshes.size(), fmt::format("Trying to access out of bounds submesh {} of mesh with {} submeshes", submesh_index, _submeshes.size()));
86 return _submeshes.at(submesh_index);
87 }
88
89 auto submesh(const utility::hashed_string& name) const -> const graphics::submesh& {
90 return submesh(submesh_index(name));
91 }
92
93 auto submesh_bounds(std::uint32_t submesh_index) const -> const math::volume& {
94 return submesh(submesh_index).bounds;
95 }
96
97 auto submesh_bounds(const utility::hashed_string& name) const -> const math::volume& {
98 return submesh(submesh_index(name)).bounds;
99 }
100
101 auto submesh_local_transform(std::uint32_t submesh_index) const -> const math::matrix4x4& {
102 return submesh(submesh_index).local_transform;
103 }
104
105 auto submesh_local_transform(const utility::hashed_string& name) const -> const math::matrix4x4& {
106 return submesh(submesh_index(name)).local_transform;
107 }
108
109 auto submesh_names() const -> std::unordered_map<utility::hashed_string, std::uint32_t> {
110 auto names = std::unordered_map<utility::hashed_string, std::uint32_t>{};
111
112 for (std::size_t i = 0; i < _submeshes.size(); ++i) {
113 names.emplace(_submeshes[i].name, static_cast<std::uint32_t>(i));
114 }
115
116 return names;
117 }
118
119 auto bounds() const -> const math::volume& {
120 return _bounds;
121 }
122
123 auto vertex_count() const noexcept -> std::uint32_t {
124 return _vertex_count;
125 }
126
127 auto index_count() const noexcept -> std::uint32_t {
128 return _index_count;
129 }
130
131protected:
132
133 mesh(mesh_data&& mesh_data);
134
135 auto _upload_vertices(const std::vector<vertex_type>& vertices, const std::vector<index_type>& indices) -> void;
136
137 auto _upload_vertices(std::vector<vertex_type>&& vertices, std::vector<index_type>&& indices) -> void;
138
139 auto _calculate_bounds_from_submeshes(math::volume&& bounds) const -> math::volume;
140
141 buffer_handle _vertex_buffer;
142 buffer_handle _index_buffer;
143
144 std::vector<graphics::submesh> _submeshes;
145 std::uint32_t _vertex_count;
146 std::uint32_t _index_count;
147
148 math::volume _bounds;
149
150}; // class mesh
151
152} // namespace sbx::graphics
153
154#include <libsbx/graphics/pipeline/mesh.ipp>
155
156#endif // LIBSBX_GRAPHICS_PIPELINE_MESH_HPP_
Definition: command_buffer.hpp:15
Definition: mesh.hpp:39
Definition: matrix4x4.hpp:26
Definition: volume.hpp:14
Definition: hashed_string.hpp:17
Definition: mesh.hpp:47
Definition: mesh.hpp:27
Definition: exception.hpp:18