opynsim
Unofficial C++ Documentation
Loading...
Searching...
No Matches
mesh.h
Go to the documentation of this file.
1#pragma once
2
14
15#include <cstddef>
16#include <cstdint>
17#include <functional>
18#include <initializer_list>
19#include <iosfwd>
20#include <optional>
21#include <ranges>
22#include <span>
23#include <type_traits>
24#include <vector>
25
26namespace osc { struct AABB; }
27namespace osc { class SubMeshDescriptor; }
28namespace osc { struct Transform; }
29namespace osc { class VertexFormat; }
30
31namespace osc
32{
33 class Mesh {
34 public:
36
37 // affects how the backend renderer ultimately renders this mesh data
38 // (e.g. would tell the OpenGL backend to draw with GL_LINES vs. GL_TRIANGLES)
41
42 // vertex data: reassigning this causes attributes (normals, texture
43 // coordinates, colors, and tangents) to be resized
44 bool has_vertices() const;
45 size_t num_vertices() const;
46 std::vector<Vector3> vertices() const;
47 void set_vertices(std::span<const Vector3>);
48 void set_vertices(std::initializer_list<Vector3> il)
49 {
50 set_vertices(std::span<const Vector3>{il});
51 }
52 void transform_vertices(const std::function<Vector3(Vector3)>&);
55
56 // attribute: you can only set an equal amount of normals to the number of
57 // vertices (or zero, which means "clear them")
58 bool has_normals() const;
59 std::vector<Vector3> normals() const;
60 void set_normals(std::span<const Vector3>);
61 void set_normals(std::initializer_list<Vector3> il)
62 {
63 set_normals(std::span<const Vector3>{il});
64 }
65 void transform_normals(const std::function<Vector3(Vector3)>&);
66
67 // attribute: you can only set an equal amount of texture coordinates to
68 // the number of vertices (or zero, which means "clear them")
69 bool has_tex_coords() const;
70 std::vector<Vector2> tex_coords() const;
71 void set_tex_coords(std::span<const Vector2>);
72 void set_tex_coords(std::initializer_list<Vector2> il)
73 {
74 set_tex_coords(std::span<const Vector2>{il});
75 }
76 void transform_tex_coords(const std::function<Vector2(Vector2)>&);
77
78 // attribute: you can only set an equal amount of colors to the number of
79 // vertices (or zero, which means "clear them")
80 std::vector<Color> colors() const;
81 void set_colors(std::span<const Color>);
82 void set_colors(std::initializer_list<Color> il)
83 {
84 set_colors(std::span<const Color>{il});
85 }
86
87 // attribute: you can only set an equal amount of tangents to the number of
88 // vertices (or zero, which means "clear them")
89 std::vector<Vector4> tangents() const;
90 void set_tangents(std::span<const Vector4>);
91 void set_tangents(std::initializer_list<Vector4> il)
92 {
93 set_tangents(std::span<const Vector4>{il});
94 }
95
96 // indices into the vertex data: tells the backend which primitives
97 // to draw in which order from the underlying vertex buffer
98 //
99 // all meshes _must_ be indexed: even if you're just drawing a single triangle
100 size_t num_indices() const;
103 void set_indices(std::initializer_list<uint32_t> il)
104 {
106 }
107 void for_each_indexed_vertex(const std::function<void(Vector3)>&) const;
108 void for_each_indexed_triangle(const std::function<void(Triangle)>&) const;
110 std::vector<Vector3> indexed_vertices() const;
111
112 // Returns the local-space bounds of this mesh, if it contains at least
113 // one primitive. Automatically recalculated from the indexed data
114 // whenever `set_vertices`, `set_indices`, or `set_vertex_buffer_data`
115 // is called.
116 //
117 // Returns `std::nullopt` if the mesh contains no primitives (e.g. when
118 // it's empty).
119 const std::optional<AABB>& bounds() const;
120
121 // Returns the local-space centroid of the bounds of this mesh, if it
122 // contains at least one primitive.
123 //
124 // Returns `std::nullopt` if the mesh contains no primitives (e.g. when
125 // it's empty).
126 std::optional<Vector3> centroid() const;
127
128 // clear all data in the mesh, such that the mesh then behaves as-if it were
129 // just default-initialized
130 void clear();
131
132 // advanced api: submeshes
133 //
134 // enables describing sub-parts of the vertex buffer as independently-renderable
135 // meshes. This is handy if (e.g.) you want to upload all of your mesh data
136 // in one shot, or if you want to apply different materials to different parts
137 // of the mesh, without having to create a bunch of separate vertex buffers
141 template<std::ranges::input_range Range>
142 requires std::constructible_from<SubMeshDescriptor, std::ranges::range_value_t<Range>>
151
152 // advanced api: vertex attribute querying/layout/reformatting
153 //
154 // enables working with the actual layout of data on the CPU/GPU, so that
155 // callers can (e.g.) upload all of their vertex data in one shot (rather than
156 // calling each of the 'basic' methods above one-by-one, etc.)
157 size_t num_vertex_attributes() const;
160 size_t vertex_buffer_stride() const;
162 template<std::ranges::contiguous_range Range>
169
170 // recalculates the normals of the mesh from its triangles
171 //
172 // - does nothing if the mesh's topology is != MeshTopology::Triangles
173 // - the normals of shared vertices are averaged (i.e. smooth-shaded)
174 // - creates a normal vertex attribute if tangents aren't assigned yet
176
177 // recalculates the tangents of the mesh from its triangles + normals + texture coordinates
178 //
179 // - does nothing if the mesh's topology != MeshTopology::Triangles
180 // - does nothing if the mesh has no normals
181 // - does nothing if the mesh has no texture coordinates
182 // - creates a tangent vertex attribute if tangents aren't assigned yet
184
185 friend bool operator==(const Mesh&, const Mesh&) = default;
186 friend std::ostream& operator<<(std::ostream&, const Mesh&);
187 private:
188 friend class GraphicsBackend;
189 friend struct std::hash<Mesh>;
190
191 class Impl;
193 };
194
195 std::ostream& operator<<(std::ostream&, const Mesh&);
196}
197
198template<>
199struct std::hash<osc::Mesh> final {
200 size_t operator()(const osc::Mesh& mesh) const noexcept
201 {
202 return std::hash<const osc::Mesh::Impl*>{}(mesh.impl_.get());
203 }
204};
Definition copy_on_upd_shared_value.h:16
Definition flags.h:20
Definition mesh_indices_view.h:22
Definition mesh.h:33
void for_each_indexed_vertex(const std::function< void(Vector3)> &) const
std::vector< Vector4 > tangents() const
MeshIndicesView indices() const
void recalculate_tangents()
const VertexFormat & vertex_format() const
void set_normals(std::span< const Vector3 >)
MeshTopology topology() const
friend class GraphicsBackend
Definition mesh.h:188
bool has_normals() const
void set_colors(std::span< const Color >)
void set_tex_coords(std::initializer_list< Vector2 > il)
Definition mesh.h:72
void set_topology(MeshTopology)
const SubMeshDescriptor & submesh_descriptor_at(size_t) const
void transform_vertices(const Matrix4x4 &)
std::vector< Vector3 > indexed_vertices() const
size_t num_vertices() const
bool has_tex_coords() const
void transform_vertices(const std::function< Vector3(Vector3)> &)
void set_vertices(std::initializer_list< Vector3 > il)
Definition mesh.h:48
friend bool operator==(const Mesh &, const Mesh &)=default
void set_tangents(std::span< const Vector4 >)
void set_tex_coords(std::span< const Vector2 >)
void transform_vertices(const Transform &)
void set_tangents(std::initializer_list< Vector4 > il)
Definition mesh.h:91
void set_vertex_buffer_data(const Range &range, MeshUpdateFlags flags=MeshUpdateFlag::Default)
Definition mesh.h:164
size_t num_vertex_attributes() const
void set_submesh_descriptors(const Range &submesh_descriptors)
Definition mesh.h:143
void clear()
void set_indices(MeshIndicesView, MeshUpdateFlags=MeshUpdateFlag::Default)
std::vector< Color > colors() const
Triangle get_triangle_at(size_t first_index_offset) const
void set_vertex_buffer_params(size_t num_vertices, const VertexFormat &)
std::vector< Vector2 > tex_coords() const
void set_indices(std::initializer_list< uint32_t > il)
Definition mesh.h:103
const std::optional< AABB > & bounds() const
void set_normals(std::initializer_list< Vector3 > il)
Definition mesh.h:61
size_t vertex_buffer_stride() const
void set_vertex_buffer_data(std::span< const uint8_t >, MeshUpdateFlags=MeshUpdateFlag::Default)
void set_vertices(std::span< const Vector3 >)
size_t num_indices() const
void transform_normals(const std::function< Vector3(Vector3)> &)
std::optional< Vector3 > centroid() const
void recalculate_normals()
bool has_vertices() const
void for_each_indexed_triangle(const std::function< void(Triangle)> &) const
void set_colors(std::initializer_list< Color > il)
Definition mesh.h:82
void push_submesh_descriptor(const SubMeshDescriptor &)
friend std::ostream & operator<<(std::ostream &, const Mesh &)
size_t num_submesh_descriptors() const
void clear_submesh_descriptors()
std::vector< Vector3 > normals() const
std::vector< Vector3 > vertices() const
void transform_tex_coords(const std::function< Vector2(Vector2)> &)
Definition sub_mesh_descriptor.h:9
Definition vertex_format.h:16
Definition bit_castable.h:13
Definition custom_decoration_generator.h:5
std::ostream & operator<<(std::ostream &, const Object &)
Vector< float, 2 > Vector2
Definition vector.h:636
MeshTopology
Definition mesh_topology.h:8
Vector< float, 3 > Vector3
Definition vector.h:644
constexpr U to(T &&value)
Definition conversion.h:56
Definition transform.h:11
Definition triangle.h:9
size_t operator()(const osc::Mesh &mesh) const noexcept
Definition mesh.h:200