sandbox
Loading...
Searching...
No Matches
mesh.hpp
1// SPDX-License-Identifier: MIT
2#ifndef LIBSBX_MODELS_MESH_HPP_
3#define LIBSBX_MODELS_MESH_HPP_
4
5#include <array>
6#include <filesystem>
7#include <span>
8
10#include <libsbx/utility/enum.hpp>
11#include <libsbx/utility/crc32.hpp>
12
13#include <libsbx/math/volume.hpp>
14#include <libsbx/math/sphere.hpp>
15#include <libsbx/math/vector4.hpp>
16#include <libsbx/math/uuid.hpp>
17
18#include <libsbx/io/loader_factory.hpp>
19
20#include <libsbx/graphics/pipeline/mesh.hpp>
21#include <libsbx/graphics/buffers/buffer.hpp>
22
23#include <libsbx/models/vertex3d.hpp>
24#include <libsbx/models/vertex_stream.hpp>
25
26namespace sbx::models {
27
28class mesh : public graphics::mesh<vertex3d>, public io::loader_factory<mesh, graphics::mesh<vertex3d>::mesh_data> {
29
31
32public:
33
35
36 mesh(const std::vector<vertex3d>& vertices, const std::vector<std::uint32_t>& indices, const math::volume& bounds = math::volume{});
37
38 mesh(std::vector<vertex3d>&& vertices, std::vector<std::uint32_t>&& indices, const math::volume& bounds = math::volume{});
39
40 mesh(mesh_data&& data);
41
42 mesh(const std::filesystem::path& path, std::uint32_t lod_count = 1u);
43
44 ~mesh() override;
45
46 auto set_stream(vertex_stream stream, std::span<const math::vector4> data) -> void;
47
48 auto stream_address(vertex_stream stream) const -> graphics::buffer::address_type;
49
50 auto available_streams() const noexcept -> const utility::bit_field<vertex_stream>&;
51
52 auto has_streams(const utility::bit_field<vertex_stream>& required) const noexcept -> bool;
53
54private:
55
56 auto _upload_streams(std::array<std::vector<math::vector4>, vertex_stream_count>& streams) -> void;
57
58 static constexpr auto file_magic = utility::make_magic<std::uint64_t>("SBXSTMSH");
59 static constexpr auto file_version = std::uint16_t{3u};
60 static constexpr auto binary_file_extention = std::string_view{".sbxstmsh"};
61
62 enum class file_flags : std::uint16_t {
63 none = 0,
64 compressed = utility::bit_v<0>, // reserved for future zstd block compression
65 quantized = utility::bit_v<1>, // reserved for future vertex quantization
66 has_streams = utility::bit_v<2>, // per-vertex stream payload follows the vertex/index block
67 }; // enum class file_flags
68
69 struct alignas(8) file_header {
70 std::uint64_t magic;
71 std::uint16_t version;
72 std::uint16_t flags;
73 std::uint32_t vertex_count;
74 std::uint32_t index_count;
75 std::uint32_t submesh_count;
76 std::uint32_t vertex_stride;
77 std::uint32_t index_stride;
78 std::uint32_t uncompressed_size;
79 std::uint32_t compressed_size;
80 }; // struct file_header
81
82 static_assert(sizeof(file_header) == 40u, "file_header layout changed");
83
84 struct alignas(4) file_bounds {
85 std::float_t aabb_min[3];
86 std::float_t aabb_max[3];
87 std::float_t sphere_center[3];
88 std::float_t sphere_radius;
89 }; // struct file_bounds
90
91 static_assert(sizeof(file_bounds) == 40u, "file_bounds layout changed");
92
93 struct alignas(8) file_submesh {
94 char name[64];
95 std::uint32_t material_index;
96 std::uint32_t vertex_offset;
97 std::uint32_t vertex_count;
98 std::uint32_t index_offset;
99 std::uint32_t index_count;
100 std::float_t aabb_min[3];
101 std::float_t aabb_max[3];
102 std::float_t local_transform[16];
103 std::uint32_t lod_level;
104 std::uint32_t lod_group;
105 }; // struct file_submesh
106
107 static_assert(sizeof(file_submesh) == 184u, "file_submesh layout changed");
108
109 struct alignas(2) file_vertex {
110 std::int16_t position[3];
111 std::int16_t normal[2];
112 std::int16_t uv[2];
113 std::int16_t tangent[2];
114 std::int8_t tangent_w;
115 std::uint8_t _pad;
116 }; // struct file_vertex
117
118 static_assert(sizeof(file_vertex) == 20u, "file_vertex layout changed");
119
120 static auto _load(const std::filesystem::path& path, std::uint32_t lod_count) -> mesh_data;
121
122 static auto _generate_lods(mesh_data& data, std::uint32_t lod_count) -> void;
123
124 static auto _load_binary(const std::filesystem::path& path) -> mesh_data;
125
126 static auto _process(const std::filesystem::path& path, const mesh_data& data) -> void;
127
128 std::array<graphics::buffer_handle, vertex_stream_count> _stream_buffers{};
129 utility::bit_field<vertex_stream> _available_streams{};
130
131}; // class mesh
132
133struct mesh_handle : public math::uuid {
134
135 constexpr mesh_handle()
136 : math::uuid{math::uuid::nil()} { }
137
138 constexpr explicit mesh_handle(const math::uuid& id)
139 : math::uuid{id} { }
140
141 constexpr auto is_valid() const noexcept -> bool {
142 return (*this) != math::uuid::nil();
143 }
144
145 constexpr auto operator==(const mesh_handle& other) const noexcept -> bool = default;
146
147}; // struct mesh_handle
148
149} // namespace sbx::models
150
151#endif // LIBSBX_MODELS_MESH_HPP_
Definition: mesh.hpp:43
Definition: loader_factory.hpp:13
Definition: uuid.hpp:15
Definition: volume.hpp:14
Definition: mesh.hpp:28
Definition: enum.hpp:43
Definition: mesh.hpp:51
Definition: mesh.hpp:133