Unravel Engine C++ Reference
Loading...
Searching...
No Matches
mesh.h
Go to the documentation of this file.
1#pragma once
2#include <engine/engine_export.h>
3
4#include <base/basetypes.hpp>
5#include <graphics/graphics.h>
6#include <hpp/span.hpp>
7#include <math/math.h>
8
9#include <map>
10#include <memory>
11#include <vector>
12
13namespace unravel
14{
15class camera;
16
17namespace triangle_flags
18{
19enum e
20{
21 none = 0,
23};
24} // namespace triangle_flags
25
26enum class mesh_status
27{
31};
32
34{
35 bottom,
36 center,
37 top
38};
39
45{
46public:
51 {
53 uint32_t vertex_index = 0;
55 float weight = 0.0f;
56 };
57 using vertex_influence_array_t = std::vector<vertex_influence>;
58
71 using bone_influence_array_t = std::vector<bone_influence>;
72
77 {
79 std::vector<int32_t> influences;
81 std::vector<float> weights;
83 int32_t palette;
86 };
87 using vertex_data_array_t = std::vector<vertex_data>;
88
94 void add_bone(const bone_influence& bone);
95
99 void remove_empty_bones();
100
108 void build_vertex_table(uint32_t vertex_count,
109 const std::vector<uint32_t>& vertex_remap,
110 vertex_data_array_t& table);
111
117 void remap_vertices(const std::vector<uint32_t>& remap);
118
124 auto get_bones() const -> const bone_influence_array_t&;
125
132
139 auto has_bones() const -> bool;
140
142 {
143 const bone_influence* bone{};
144 int index{-1};
145 };
146
153 auto find_bone_by_id(const std::string& id) const -> bone_query;
154
159
163 void clear();
164
165private:
167};
168
173{
174public:
175 using bone_index_map_t = std::map<uint32_t, uint32_t>;
176
182 bone_palette(uint32_t paletteSize);
183
192 auto get_skinning_matrices(const std::vector<math::transform>& node_transforms,
193 const skin_bind_data& bind_data) const -> const std::vector<math::mat4>&;
194
195 auto get_skinning_matrices(const std::vector<math::mat4>& node_transforms, const skin_bind_data& bind_data) const
196 -> const std::vector<math::mat4>&;
197
208 int32_t& current_space,
209 int32_t& common_base,
210 int32_t& additional_bones);
211
218 void assign_bones(bone_index_map_t& bones, std::vector<uint32_t>& faces);
219 void assign_bones(std::vector<bool>& bones, std::vector<uint32_t>& faces);
220
226 void assign_bones(const std::vector<uint32_t>& bones);
227
234 auto translate_bone_to_palette(uint32_t bone_index) const -> uint32_t;
235
241 auto get_maximum_blend_index() const -> int32_t;
242
248 auto get_maximum_size() const -> uint32_t;
249
256 auto get_data_group() const -> uint32_t;
257
263 auto get_influenced_faces() -> std::vector<uint32_t>&;
264
270 auto get_bones() const -> const std::vector<uint32_t>&;
271
277 void set_maximum_blend_index(int index);
278
284 void set_data_group(uint32_t group);
285
290
291protected:
295 std::vector<uint32_t> bones_;
297 std::vector<uint32_t> faces_;
304};
305
309class mesh
310{
311public:
316 struct submesh
317 {
319 uint32_t data_group_id{0};
321 int32_t vertex_start{-1};
323 uint32_t vertex_count{0};
325 int32_t face_start{-1};
327 uint32_t face_count{0};
328
329 std::string node_id{};
330
332
333 bool skinned{};
334 };
335
336 struct info
337 {
339 uint32_t vertices = 0;
341 uint32_t primitives = 0;
343 uint32_t submeshes = 0;
345 uint32_t data_groups = 0;
346 };
347
351 struct triangle
352 {
354 uint32_t data_group_id = 0;
356 std::array<uint32_t, 3> indices = {0, 0, 0};
358 uint8_t flags = 0;
359 };
360
361 using triangle_array_t = std::vector<triangle>;
362 using submesh_array_t = std::vector<submesh*>;
363 using bone_palette_array_t = std::vector<bone_palette>;
364 using submesh_array_indices_t = std::vector<size_t>;
365 using submesh_array_map_t = std::map<uint32_t, submesh_array_indices_t>;
366
367 using data_group_submesh_map_t = std::map<uint32_t, submesh_array_t>;
368 using byte_array_t = std::vector<uint8_t>;
369
371 {
373 std::string name;
377 std::vector<std::unique_ptr<armature_node>> children;
379 std::vector<uint32_t> submeshes;
380
381 int index{-1};
382 };
383
388 {
392 std::vector<uint8_t> vertex_data;
394 uint32_t vertex_count = 0;
398 uint32_t triangle_count = 0;
400 std::vector<mesh::submesh> submeshes;
402 uint32_t material_count = 0;
406 std::unique_ptr<armature_node> root_node = nullptr;
407
409 };
410
414 mesh();
415
419 ~mesh();
420
424 void dispose();
425
434 void bind_render_buffers_for_submesh(const submesh* submesh);
435
443 auto prepare_mesh(const gfx::vertex_layout& vertex_format) -> bool;
444
454 auto set_vertex_source(void* source, uint32_t vertex_count, const gfx::vertex_layout& source_format) -> bool;
455 auto set_vertex_source(byte_array_t&& source, uint32_t vertex_count, const gfx::vertex_layout& source_format)
456 -> bool;
457
458 auto set_bounding_box(const math::bbox& box) -> bool;
459
460 auto set_submeshes(const std::vector<submesh>& submeshes) -> bool;
461
469 auto set_primitives(triangle_array_t&& triangles) -> bool;
470
478 auto bind_skin(const skin_bind_data& bind_data) -> bool;
479
487 auto bind_armature(std::unique_ptr<armature_node>& root) -> bool;
488
489 auto load_mesh(load_data&& data) -> bool;
490
504 auto create_plane(const gfx::vertex_layout& format,
505 float width,
506 float height,
507 uint32_t width_segments,
508 uint32_t height_segments,
509 mesh_create_origin origin,
510 bool hardware_copy = true) -> bool;
511
527 auto create_cube(const gfx::vertex_layout& format,
528 float width,
529 float height,
530 float depth,
531 uint32_t width_segments,
532 uint32_t height_segments,
533 uint32_t depth_segments,
534 mesh_create_origin origin,
535 bool hardware_copy = true) -> bool;
536
537 auto create_rounded_cube(const gfx::vertex_layout& format,
538 float width,
539 float height,
540 float depth,
541 uint32_t width_segments,
542 uint32_t height_segments,
543 uint32_t depth_segments,
544 mesh_create_origin origin,
545 bool hardware_copy = true) -> bool;
546
559 auto create_sphere(const gfx::vertex_layout& format,
560 float radius,
561 uint32_t stacks,
562 uint32_t slices,
563 mesh_create_origin origin,
564 bool hardware_copy = true) -> bool;
565
579 auto create_cylinder(const gfx::vertex_layout& format,
580 float radius,
581 float height,
582 uint32_t stacks,
583 uint32_t slices,
584 mesh_create_origin origin,
585 bool hardware_copy = true) -> bool;
586
600 auto create_capsule(const gfx::vertex_layout& format,
601 float radius,
602 float height,
603 uint32_t stacks,
604 uint32_t slices,
605 mesh_create_origin origin,
606 bool hardware_copy = true) -> bool;
607
622 auto create_cone(const gfx::vertex_layout& format,
623 float radius,
624 float radius_tip,
625 float height,
626 uint32_t stacks,
627 uint32_t slices,
628 mesh_create_origin origin,
629 bool hardware_copy = true) -> bool;
630
644 auto create_torus(const gfx::vertex_layout& format,
645 float outer_radius,
646 float inner_radius,
647 uint32_t bands,
648 uint32_t sides,
649 mesh_create_origin origin,
650 bool hardware_copy = true) -> bool;
651
660 auto create_teapot(const gfx::vertex_layout& format, bool hardware_copy = true) -> bool;
661
670 auto create_icosahedron(const gfx::vertex_layout& format, bool hardware_copy = true) -> bool;
671
680 auto create_dodecahedron(const gfx::vertex_layout& format, bool hardware_copy = true) -> bool;
681
691 auto create_icosphere(const gfx::vertex_layout& format, int tesselation_level, bool hardware_copy = true) -> bool;
692
703 auto end_prepare(bool hardware_copy = true, bool build_buffers = true, bool weld = false, bool optimize = false)
704 -> bool;
705
711 void build_vb(bool hardware_copy = true);
712
718 void build_ib(bool hardware_copy = true);
719
727 auto generate_adjacency(std::vector<uint32_t>& adjacency) -> bool;
728
734 auto get_face_count() const -> uint32_t;
735
741 auto get_vertex_count() const -> uint32_t;
742
748 auto get_system_vb() -> uint8_t*;
749
755 auto get_system_ib() -> uint32_t*;
756
762 auto get_vertex_format() const -> const gfx::vertex_layout&;
763
769 auto get_skin_bind_data() const -> const skin_bind_data&;
770
776 auto get_bone_palettes() const -> const bone_palette_array_t&;
777
783 auto get_armature() const -> const std::unique_ptr<armature_node>&;
784
792 auto calculate_screen_rect(const math::transform& world, const camera& cam) const -> irect32_t;
793
800 auto get_submeshes() const -> const submesh_array_t&;
801 auto get_submesh(uint32_t submesh_index = 0) const -> const mesh::submesh&;
807 auto get_bounds() const -> const math::bbox&;
808
814 auto get_status() const -> mesh_status;
815
821 auto get_data_groups_count() const -> size_t;
822
828 auto get_submeshes_count() const -> size_t;
829 auto get_skinned_submeshes_count() const -> size_t;
830 auto get_skinned_submeshes_indices(uint32_t data_group_id) const -> const submesh_array_indices_t&;
831
832
833 auto get_non_skinned_submeshes_count() const -> size_t;
834 auto get_non_skinned_submeshes_indices(uint32_t data_group_id) const -> const submesh_array_indices_t&;
835
836
837 auto get_submesh_index(const submesh* s) const -> int;
838
840 {
841 enum flags
842 {
843 source_contains_normal = 0x1,
844 source_contains_binormal = 0x2,
845 source_contains_tangent = 0x4
846 };
847
849 uint8_t* vertex_source{nullptr};
851 bool owns_source{false};
855 std::vector<uint32_t> vertex_records;
863 uint32_t triangle_count{0};
865 uint32_t vertex_count{0};
867 std::vector<submesh> submeshes;
869 bool compute_normals{false};
871 bool compute_binormals{false};
873 bool compute_tangents{false};
875 bool compute_barycentric{false};
876
877 bool check_for_degenerates{false};
878
879 bool compute_per_triangle_material_data{false};
880 };
881
882protected:
884 {
886 int32_t cache_position{-1};
888 float vertex_score{0.0f};
890 uint32_t unused_triangle_references{0};
892 std::vector<uint32_t> triangle_references;
893 };
894
896 {
898 float triangle_score{0.0f};
900 bool added{false};
901 };
902
904 {
906 const math::vec3* vertex1{nullptr};
908 const math::vec3* vertex2{nullptr};
909 };
910
912 {
914 uint32_t data_group_id{0};
915 };
916
917 using submesh_key_map_t = std::map<mesh_submesh_key, submesh*>;
918 using submesh_key_array_t = std::vector<mesh_submesh_key>;
919
920 struct weld_key
921 {
923 uint8_t* vertex{nullptr};
927 float tolerance{};
928 };
929
935
937 {
939 face_influences* influences{nullptr};
941 uint32_t data_group_id{0};
942 };
943
944 using bone_combination_map_t = std::map<bone_combination_key, std::vector<uint32_t>*>;
945
946 friend auto operator<(const adjacent_edge_key& key1, const adjacent_edge_key& key2) -> bool;
947 friend auto operator<(const mesh_submesh_key& key1, const mesh_submesh_key& key2) -> bool;
948 friend auto operator<(const weld_key& key1, const weld_key& key2) -> bool;
949 friend auto operator<(const bone_combination_key& key1, const bone_combination_key& key2) -> bool;
950
951 void check_for_degenerates();
952
960 auto generate_vertex_components(bool weld) -> bool;
961
970 auto generate_vertex_normals(uint32_t* adjacency_ptr, std::vector<uint32_t>* remap_array_ptr = nullptr) -> bool;
971
979 auto generate_vertex_barycentrics(uint32_t* adjacency) -> bool;
980
987 auto generate_vertex_tangents() -> bool;
988
997 auto weld_vertices(float tolerance = 0.000001f, std::vector<uint32_t>* vertex_remap_ptr = nullptr) -> bool;
998
1005 auto sort_mesh_data() -> bool;
1006
1016 static void build_optimized_index_buffer(const submesh* submesh,
1017 uint32_t* source_buffer_ptr,
1018 uint32_t* destination_buffer_ptr,
1019 uint32_t minimum_vertex,
1020 uint32_t maximum_vertex);
1021
1028 static auto find_vertex_optimizer_score(const optimizer_vertex_info* vertex_info_ptr) -> float;
1029
1030protected:
1032 bool force_tangent_generation_ = false;
1034 bool force_normal_generation_ = false;
1036 bool force_barycentric_generation_ = false;
1038 bool disable_final_sort_ = false;
1039
1041 uint8_t* system_vb_ = nullptr;
1045 uint32_t* system_ib_ = nullptr;
1049 std::shared_ptr<void> hardware_vb_;
1051 std::shared_ptr<void> hardware_ib_;
1052
1055
1058 size_t skinned_submesh_count_{};
1059
1062 size_t non_skinned_submesh_count_{};
1063
1066
1068 bool hardware_mesh_ = true;
1070 bool optimize_mesh_ = false;
1074 uint32_t face_count_ = 0;
1076 uint32_t vertex_count_ = 0;
1077
1082
1088 std::unique_ptr<armature_node> root_ = nullptr;
1089};
1090
1091} // namespace unravel
General purpose transformation class designed to maintain each component of the transformation separa...
Definition transform.hpp:27
Outlines a collection of bones that influence a given set of faces/vertices in the mesh.
Definition mesh.h:173
std::map< uint32_t, uint32_t > bone_index_map_t
Definition mesh.h:175
auto get_bones() const -> const std::vector< uint32_t > &
Retrieves the indices of the bones referenced by this palette.
Definition mesh.cpp:2731
auto get_maximum_size() const -> uint32_t
Retrieves the maximum size of the palette.
Definition mesh.cpp:2716
bone_index_map_t bones_lut_
< Sorted list of bones in this palette.
Definition mesh.h:293
void clear_influenced_faces()
Clears out the temporary face influences array.
Definition mesh.cpp:2726
uint32_t data_group_id_
The maximum size of the palette.
Definition mesh.h:299
void assign_bones(bone_index_map_t &bones, std::vector< uint32_t > &faces)
Assigns the specified bones (and faces) to this bone palette.
Definition mesh.cpp:2572
std::vector< uint32_t > faces_
The data group identifier used to separate the mesh data into submeshes relevant tothis bone palette.
Definition mesh.h:297
auto get_maximum_blend_index() const -> int32_t
Retrieves the maximum vertex blend index for this palette.
Definition mesh.cpp:2706
auto get_influenced_faces() -> std::vector< uint32_t > &
Retrieves the list of faces assigned to this palette.
Definition mesh.cpp:2721
auto get_skinning_matrices(const std::vector< math::transform > &node_transforms, const skin_bind_data &bind_data) const -> const std::vector< math::mat4 > &
Gathers the bone/palette information and matrices ready for drawing the skinned mesh.
Definition mesh.cpp:2523
uint32_t maximum_size_
The maximum vertex blend index for this palette.
Definition mesh.h:301
void compute_palette_fit(bone_index_map_t &input, int32_t &current_space, int32_t &common_base, int32_t &additional_bones)
Determines the relevant "fit" information that can be used to discover if and how the specified combi...
Definition mesh.cpp:2651
void set_data_group(uint32_t group)
Sets the identifier of the data group assigned to the submesh of the mesh reserved for this bone pale...
Definition mesh.cpp:2701
void set_maximum_blend_index(int index)
Sets the maximum vertex blend index for this palette.
Definition mesh.cpp:2711
int32_t maximum_blend_index_
Definition mesh.h:303
auto translate_bone_to_palette(uint32_t bone_index) const -> uint32_t
Translates the specified bone index into its associated position in the palette.
Definition mesh.cpp:2688
bone_palette(uint32_t paletteSize)
Constructs a bone palette with the given size.
Definition mesh.cpp:2516
auto get_data_group() const -> uint32_t
Retrieves the identifier of the data group assigned to the submesh of the mesh reserved for this bone...
Definition mesh.cpp:2696
std::vector< uint32_t > bones_
List of faces assigned to this palette.
Definition mesh.h:295
Class representing a camera. Contains functionality for manipulating and updating a camera....
Definition camera.h:35
Main class representing a 3D mesh with support for different LODs, submeshes, and skinning.
Definition mesh.h:310
gfx::vertex_layout vertex_format_
The final system memory copy of the index buffer.
Definition mesh.h:1043
bone_palette_array_t bone_palettes_
List of armature nodes.
Definition mesh.h:1086
std::shared_ptr< void > hardware_vb_
The actual hardware index buffer resource.
Definition mesh.h:1049
submesh_array_map_t non_skinned_submesh_indices_
Definition mesh.h:1061
auto set_vertex_source(void *source, uint32_t vertex_count, const gfx::vertex_layout &source_format) -> bool
Sets the source of the vertex buffer to pull data from while preparing the mesh.
submesh_array_t mesh_submeshes_
Indices in the subset array which are skinned.
Definition mesh.h:1054
std::vector< mesh_submesh_key > submesh_key_array_t
Definition mesh.h:918
std::map< uint32_t, submesh_array_indices_t > submesh_array_map_t
Definition mesh.h:365
std::vector< uint8_t > byte_array_t
Definition mesh.h:368
math::bbox bbox_
Total number of faces in the prepared mesh.
Definition mesh.h:1072
data_group_submesh_map_t data_groups_
Whether the mesh uses a hardware vertex/index buffer.
Definition mesh.h:1065
std::shared_ptr< void > hardware_ib_
The actual list of submeshes maintained by this mesh.
Definition mesh.h:1051
submesh_array_map_t skinned_submesh_indices_
Definition mesh.h:1057
skin_bind_data skin_bind_data_
List of unique combinations of bones to use during rendering.
Definition mesh.h:1084
preparation_data preparation_data_
Data describing how the mesh should be bound as a skin with supplied bone matrices.
Definition mesh.h:1081
std::vector< size_t > submesh_array_indices_t
Definition mesh.h:364
std::map< mesh_submesh_key, submesh * > submesh_key_map_t
Definition mesh.h:917
std::vector< bone_palette > bone_palette_array_t
Definition mesh.h:363
std::vector< submesh * > submesh_array_t
Definition mesh.h:362
std::map< uint32_t, submesh_array_t > data_group_submesh_map_t
Definition mesh.h:367
std::vector< triangle > triangle_array_t
Definition mesh.h:361
submesh_key_array_t triangle_data_
The actual hardware vertex buffer resource.
Definition mesh.h:1047
std::map< bone_combination_key, std::vector< uint32_t > * > bone_combination_map_t
Definition mesh.h:944
Structure describing how a skinned mesh should be bound to any bones that influence its vertices.
Definition mesh.h:45
void build_vertex_table(uint32_t vertex_count, const std::vector< uint32_t > &vertex_remap, vertex_data_array_t &table)
Constructs a list of bone influences and weights for each vertex based on the binding data provided.
Definition mesh.cpp:2425
void remap_vertices(const std::vector< uint32_t > &remap)
Remaps the vertex references stored in the binding based on the supplied remap array.
Definition mesh.cpp:2394
auto get_bones() const -> const bone_influence_array_t &
Retrieves a list of all bones that influence the skin in some way.
Definition mesh.cpp:2474
std::vector< vertex_data > vertex_data_array_t
Definition mesh.h:87
auto find_bone_by_id(const std::string &id) const -> bone_query
Finds a bone by its unique identifier.
Definition mesh.cpp:2489
void clear()
Clears out the bone information stored in this object.
Definition mesh.cpp:2389
auto has_bones() const -> bool
Checks whether the skin data has any bones.
Definition mesh.cpp:2484
void remove_empty_bones()
Removes any bones that do not contain any influences.
Definition mesh.cpp:2364
std::vector< vertex_influence > vertex_influence_array_t
Definition mesh.h:57
std::vector< bone_influence > bone_influence_array_t
Definition mesh.h:71
void clear_vertex_influences()
Releases memory allocated for vertex influences in each stored bone.
Definition mesh.cpp:2381
void add_bone(const bone_influence &bone)
Adds influence information for a specific bone.
Definition mesh.cpp:2359
bgfx::VertexLayout vertex_layout
Definition vertex_decl.h:8
Definition bbox.cpp:5
mesh_status
Definition mesh.h:27
auto operator<(const mesh::adjacent_edge_key &key1, const mesh::adjacent_edge_key &key2) -> bool
Definition mesh.cpp:1536
@ box
Box type reflection probe.
mesh_create_origin
Definition mesh.h:34
Storage for box vector values and wraps up common functionality.
Definition bbox.h:21
std::vector< uint32_t > submeshes
Definition mesh.h:379
std::string name
< Name of the armature node.
Definition mesh.h:373
math::transform local_transform
Children nodes of this armature node.
Definition mesh.h:375
std::vector< std::unique_ptr< armature_node > > children
submesh indices affected by this node
Definition mesh.h:377
bone_palette::bone_index_map_t bones
< List of unique bones that influence a given number of faces.
Definition mesh.h:933
Struct used for mesh construction.
Definition mesh.h:388
triangle_array_t triangle_data
Total number of triangles.
Definition mesh.h:396
std::vector< mesh::submesh > submeshes
Total number of materials.
Definition mesh.h:400
std::vector< uint8_t > vertex_data
Total number of vertices.
Definition mesh.h:392
gfx::vertex_layout vertex_format
< The format of the vertex data.
Definition mesh.h:390
skin_bind_data skin_data
Root node of the armature.
Definition mesh.h:404
std::vector< uint32_t > triangle_references
Definition mesh.h:892
std::vector< uint32_t > vertex_records
Final vertex buffer currently being prepared.
Definition mesh.h:855
triangle_array_t triangle_data
Total number of triangles currently stored.
Definition mesh.h:861
gfx::vertex_layout source_format
Records the location in the vertex buffer that each vertex has been placed during data insertion.
Definition mesh.h:853
std::vector< submesh > submeshes
Whether to compute vertex normals.
Definition mesh.h:867
byte_array_t vertex_data
Additional descriptive information about the vertices.
Definition mesh.h:857
byte_array_t vertex_flags
Stores the current face/triangle data.
Definition mesh.h:859
Structure describing an individual "piece" of the mesh, often grouped by material,...
Definition mesh.h:317
Structure describing data for a single triangle in the mesh.
Definition mesh.h:352
gfx::vertex_layout format
Tolerance for welding vertices.
Definition mesh.h:925
Describes the vertices that are connected to the referenced bone and how much influence it has on the...
Definition mesh.h:63
std::string bone_id
< The unique identifier of the bone.
Definition mesh.h:65
math::transform bind_pose_transform
List of vertices influenced by the bone.
Definition mesh.h:67
vertex_influence_array_t influences
Definition mesh.h:69
Contains per-vertex influence and weight information.
Definition mesh.h:77
int32_t palette
The index of the original vertex.
Definition mesh.h:83
std::vector< int32_t > influences
< List of bones that influence this vertex.
Definition mesh.h:79
std::vector< float > weights
Index of the palette to which this vertex has been assigned.
Definition mesh.h:81
Describes how a bone influences a specific vertex.
Definition mesh.h:51
uint32_t vertex_index
< The index of the vertex influenced by the bone.
Definition mesh.h:53