Simulant  21.12-194
A portable game engine for Windows, OSX, Linux, Dreamcast, and PSP
mesh.h
1 /* * Copyright (c) 2011-2017 Luke Benstead https://simulant-engine.appspot.com
2  *
3  * This file is part of Simulant.
4  *
5  * Simulant is free software: you can redistribute it and/or modify
6  * it under the terms of the GNU Lesser General Public License as published by
7  * the Free Software Foundation, either version 3 of the License, or
8  * (at your option) any later version.
9  *
10  * Simulant is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  * GNU Lesser General Public License for more details.
14  *
15  * You should have received a copy of the GNU Lesser General Public License
16  * along with Simulant. If not, see <http://www.gnu.org/licenses/>.
17  */
18 
19 #ifndef NEWMESH_H
20 #define NEWMESH_H
21 
22 #include <cstdint>
23 #include <vector>
24 #include <unordered_map>
25 #include <set>
26 #include <memory>
27 #include <list>
28 
29 #include "submesh.h"
30 
31 #include "../interfaces/boundable.h"
32 #include "../generic/managed.h"
33 #include "../generic/identifiable.h"
34 #include "../generic/property.h"
35 
36 #include "../loadable.h"
37 #include "../asset.h"
38 #include "../vertex_data.h"
39 #include "../types.h"
40 #include "../interfaces.h"
41 #include "../animation.h"
42 
43 namespace smlt {
44 
45 class AssetManager;
46 class AdjacencyInfo;
47 class Renderer;
48 class Rig;
49 class Skeleton;
50 class Debug;
51 
52 enum MeshAnimationType {
53  MESH_ANIMATION_TYPE_NONE,
54  MESH_ANIMATION_TYPE_VERTEX_MORPH,
55  MESH_ANIMATION_TYPE_SKELETAL
56 };
57 
58 
59 typedef sig::signal<void (Mesh*, MeshAnimationType, uint32_t)> SignalAnimationEnabled;
60 
61 
62 /* When enabling animations you must pass MeshFrameData which holds all the data necessary to
63  * produce a frame
64  */
66 public:
67  virtual ~FrameUnpacker() {}
68 
69  /*
70  * Used to interpolate the rig (if any) or do
71  * any other kind of preparation during update()
72  */
73  virtual void prepare_unpack(
74  uint32_t current_frame,
75  uint32_t next_frame,
76  float t, Rig* const rig,
77  Debug* const debug=nullptr
78  ) = 0;
79 
80  /* Used before rendering to generate the output
81  * vertices with the given Rig (if any) and interpolated
82  * value */
83  virtual void unpack_frame(
84  const uint32_t current_frame,
85  const uint32_t next_frame,
86  const float t,
87  Rig* const rig,
88  VertexData* const out,
89  Debug* const debug=nullptr
90  ) = 0;
91 };
92 
93 typedef std::shared_ptr<FrameUnpacker> FrameUnpackerPtr;
94 
95 
97 public:
98  typedef std::vector<std::shared_ptr<SubMesh>> container_type;
99  typedef typename container_type::iterator iterator_type;
100 
101 private:
102  friend class Mesh;
103  SubMeshIteratorPair(container_type& container):
104  container_(container) {
105 
106  }
107 
108  container_type& container_;
109 
110 public:
111  iterator_type begin() {
112  return container_.begin();
113  }
114 
115  iterator_type end() {
116  return container_.end();
117  }
118 };
119 
120 class Mesh :
121  public virtual Boundable,
122  public Asset,
123  public Loadable,
124  public RefCounted<Mesh>,
125  public generic::Identifiable<MeshID>,
126  public KeyFrameAnimated,
127  public ChainNameable<Mesh> {
128 
129  DEFINE_SIGNAL(SignalAnimationEnabled, signal_animation_enabled);
130 
131 public:
138  Mesh(
139  MeshID id,
140  AssetManager* asset_manager,
141  VertexDataPtr vertex_data
142  );
143 
149  Mesh(
150  MeshID id,
151  AssetManager* asset_manager,
152  VertexSpecification vertex_specification
153  );
154 
155  virtual ~Mesh();
156 
157  void reset(VertexDataPtr vertex_data);
158  void reset(VertexSpecification vertex_specification);
159 
160  /* Add a skeleton to this mesh, returns False if
161  * the mesh already had a skeleton, otherwise returns true */
162  bool add_skeleton(uint32_t num_joints);
163 
164  /* Returns true if the Mesh has had a skeleton added */
165  bool has_skeleton() const;
166 
175  const std::string& name,
176  MaterialID material,
177  MeshArrangement arrangement=MESH_ARRANGEMENT_TRIANGLES
178  );
179 
189  const std::string& name,
190  MaterialID material,
191  IndexType index_type,
192  MeshArrangement arrangement=MESH_ARRANGEMENT_TRIANGLES
193  );
194 
204  const std::string& name,
205  MaterialID material,
206  IndexDataPtr index_data,
207  MeshArrangement arrangement=MESH_ARRANGEMENT_TRIANGLES
208  );
209 
210  SubMeshPtr new_submesh_as_capsule(
211  const std::string& name,
212  MaterialID material,
213  float diameter,
214  float length,
215  std::size_t segment_count,
216  std::size_t vertical_segment_count,
217  std::size_t ring_count
218  );
219 
220  SubMeshPtr new_submesh_as_sphere(const std::string& name,
221  MaterialID material,
222  float diameter,
223  std::size_t slices,
224  std::size_t stacks
225  );
226 
227  SubMeshPtr new_submesh_as_icosphere(const std::string& name,
228  MaterialID material,
229  float diameter,
230  uint32_t subdivisions
231  );
232 
233  SubMeshPtr new_submesh_as_rectangle(
234  const std::string& name,
235  MaterialID material,
236  float width,
237  float height,
238  const Vec3& offset=Vec3()
239  );
240 
241  SubMeshPtr new_submesh_as_cube(
242  const std::string& name,
243  MaterialID material,
244  float size
245  );
246 
247  SubMeshPtr new_submesh_as_box(
248  const std::string& name,
249  MaterialID material,
250  float width,
251  float height,
252  float depth,
253  const Vec3& offset=Vec3()
254  );
255 
256  uint32_t submesh_count() const { return submeshes_.size(); }
257  bool has_submesh(const std::string& name) const;
258  SubMeshPtr find_submesh(const std::string& name) const;
259  SubMeshPtr first_submesh() const;
260 
261  void destroy_submesh(const std::string& name);
262 
263  void set_material(MaterialPtr material);
264  void set_diffuse(const smlt::Colour& colour);
265 
266  void reverse_winding();
267 
268  const AABB& aabb() const;
269  void normalize(); //Scales the mesh so it has a radius of 1.0
270  void transform_vertices(const smlt::Mat4& transform);
271 
272  SubMeshIteratorPair each_submesh();
273 
274  void enable_animation(MeshAnimationType animation_type, uint32_t animation_frames, FrameUnpackerPtr data);
275  bool is_animated() const { return animation_type_ != MESH_ANIMATION_TYPE_NONE; }
276  uint32_t animation_frames() const { return animation_frames_; }
277  MeshAnimationType animation_type() const { return animation_type_; }
278 
279  /* Generates adjacency information for this mesh. This is necessary for stencil shadowing
280  * to work */
281  void generate_adjacency_info();
282  bool has_adjacency_info() const { return bool(adjacency_); }
283 
284 public:
285  // Signals
286 
287  typedef sig::signal<void (Skeleton*)> SkeletonAddedSignal;
291 
292  DEFINE_SIGNAL(SkeletonAddedSignal, signal_skeleton_added);
293 
294  SubMeshCreatedCallback& signal_submesh_created() { return signal_submesh_created_; }
295  SubMeshDestroyedCallback& signal_submesh_destroyed() { return signal_submesh_destroyed_; }
296  SubMeshMaterialChangedCallback& signal_submesh_material_changed() { return signal_submesh_material_changed_; }
297 
298 private:
299  friend class SubMesh;
300  friend class Actor;
301 
302  Skeleton* skeleton_ = nullptr;
303 
304  VertexDataPtr vertex_data_;
305  MeshAnimationType animation_type_ = MESH_ANIMATION_TYPE_NONE;
306  uint32_t animation_frames_ = 0;
307  FrameUnpackerPtr animated_frame_data_;
308 
309  std::vector<std::shared_ptr<SubMesh>> submeshes_;
310 
311  SubMeshCreatedCallback signal_submesh_created_;
312  SubMeshDestroyedCallback signal_submesh_destroyed_;
313  SubMeshMaterialChangedCallback signal_submesh_material_changed_;
314 
315  void rebuild_aabb();
316  AABB aabb_;
317 
318  /* Automatically maintain adjacency info for submeshes or not */
319  bool maintain_adjacency_info_ = true;
320  std::unique_ptr<AdjacencyInfo> adjacency_;
321 
322  void vertex_data_updated();
323  void submesh_index_data_updated(SubMesh* sm);
324  sig::connection done_connection_;
325 
326 public:
327  /* Returns a nullptr if there is no adjacecy info */
328  S_DEFINE_PROPERTY(adjacency_info, &Mesh::adjacency_);
329 
330  S_DEFINE_PROPERTY(vertex_data, &Mesh::vertex_data_);
331 
332  /* Returns a nullptr if there is no skeleton */
333  S_DEFINE_PROPERTY(skeleton, &Mesh::skeleton_);
334 };
335 
336 }
337 
338 #endif // NEWMESH_H
smlt::Actor
Definition: actor.h:48
smlt::VertexData
Definition: vertex_data.h:57
smlt::Mat4
Definition: mat4.h:25
smlt::VertexSpecification
Definition: types.h:121
smlt::SubMeshIteratorPair
Definition: mesh.h:96
smlt::sig::Connection
Definition: signal.h:65
smlt::Vec3
Definition: vec3.h:23
smlt::Skeleton
Definition: skeleton.h:94
smlt::Mesh::set_diffuse
void set_diffuse(const smlt::Colour &colour)
Override vertex colour on all vertices.
Definition: mesh.cpp:694
smlt::RefCounted
Definition: managed.h:65
smlt
Definition: animation.cpp:25
smlt::Mesh::new_submesh
SubMeshPtr new_submesh(const std::string &name, MaterialID material, MeshArrangement arrangement=MESH_ARRANGEMENT_TRIANGLES)
Create a new ranged submesh with the specified material.
Definition: mesh.cpp:221
smlt::Mesh::set_material
void set_material(MaterialPtr material)
Apply material to all submeshes.
Definition: mesh.cpp:665
smlt::generic::Identifiable
Definition: identifiable.h:26
smlt::UniqueID< MeshPtr >
smlt::Mesh
Definition: mesh.h:127
smlt::FrameUnpacker
Definition: mesh.h:65
smlt::Loadable
Definition: loadable.h:26
smlt::ChainNameable
Definition: nameable.h:34
smlt::AABB
Definition: aabb.h:22
smlt::KeyFrameAnimated
Definition: animation.h:40
smlt::Rig
Definition: rig.h:50
smlt::Asset
Definition: asset.h:37
smlt::Debug
Definition: debug.h:28
smlt::Boundable
The Boundable class.
Definition: boundable.h:12
smlt::SubMesh
Definition: submesh.h:42
smlt::Colour
Definition: colour.h:29
smlt::AssetManager
Definition: asset_manager.h:100
smlt::Mesh::Mesh
Mesh(MeshID id, AssetManager *asset_manager, VertexDataPtr vertex_data)
Definition: mesh.cpp:38
smlt::Mesh::reverse_winding
void reverse_winding()
Reverse the winding of all submeshes.
Definition: mesh.cpp:712
smlt::sig::signal
Definition: signal.h:319