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