Simulant  21.09-46
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  /* We copy the container because submeshes are often
103  * altered in a loop, and as they're shared pointers
104  * we can copy the container and maintain the submeshes
105  * for the lifetime of the iterator */
106 
107  friend class Mesh;
108  SubMeshIteratorPair(const container_type& container):
109  container_(container) {
110 
111  }
112 
113  container_type container_;
114 
115 public:
116  iterator_type begin() {
117  return container_.begin();
118  }
119 
120  iterator_type end() {
121  return container_.end();
122  }
123 };
124 
125 class Mesh :
126  public virtual Boundable,
127  public Asset,
128  public Loadable,
129  public RefCounted<Mesh>,
130  public generic::Identifiable<MeshID>,
131  public KeyFrameAnimated,
132  public ChainNameable<Mesh> {
133 
134  DEFINE_SIGNAL(SignalAnimationEnabled, signal_animation_enabled);
135 
136 public:
143  Mesh(
144  MeshID id,
145  AssetManager* asset_manager,
146  VertexDataPtr vertex_data
147  );
148 
154  Mesh(
155  MeshID id,
156  AssetManager* asset_manager,
157  VertexSpecification vertex_specification
158  );
159 
160  virtual ~Mesh();
161 
162  void reset(VertexDataPtr vertex_data);
163  void reset(VertexSpecification vertex_specification);
164 
165  /* Add a skeleton to this mesh, returns False if
166  * the mesh already had a skeleton, otherwise returns true */
167  bool add_skeleton(uint32_t num_joints);
168 
169  /* Returns true if the Mesh has had a skeleton added */
170  bool has_skeleton() const;
171 
172  SubMeshPtr new_submesh_with_material(
173  const std::string& name,
174  MaterialID material,
175  MeshArrangement arrangement=MESH_ARRANGEMENT_TRIANGLES,
176  IndexType=INDEX_TYPE_16_BIT
177  );
178 
179  SubMeshPtr new_submesh_with_material(
180  const std::string& name,
181  MaterialID material,
182  IndexDataPtr index_data,
183  MeshArrangement arrangement=MESH_ARRANGEMENT_TRIANGLES
184  );
185 
186  SubMeshPtr new_submesh(
187  const std::string& name,
188  MeshArrangement arrangement=MESH_ARRANGEMENT_TRIANGLES,
189  IndexType=INDEX_TYPE_16_BIT
190  );
191 
192  SubMeshPtr new_submesh(
193  const std::string& name,
194  IndexDataPtr index_data,
195  MeshArrangement arrangement=MESH_ARRANGEMENT_TRIANGLES
196  );
197 
198  SubMeshPtr new_submesh_as_capsule(
199  const std::string& name,
200  MaterialID material,
201  float diameter,
202  float length,
203  std::size_t segment_count,
204  std::size_t vertical_segment_count,
205  std::size_t ring_count
206  );
207 
208  SubMeshPtr new_submesh_as_sphere(const std::string& name,
209  MaterialID material,
210  float diameter,
211  std::size_t slices,
212  std::size_t stacks
213  );
214 
215  SubMeshPtr new_submesh_as_icosphere(const std::string& name,
216  MaterialID material,
217  float diameter,
218  uint32_t subdivisions
219  );
220 
221  SubMeshPtr new_submesh_as_rectangle(
222  const std::string& name,
223  MaterialID material,
224  float width,
225  float height,
226  const Vec3& offset=Vec3()
227  );
228 
229  SubMeshPtr new_submesh_as_cube(
230  const std::string& name,
231  MaterialID material,
232  float size
233  );
234 
235  SubMeshPtr new_submesh_as_box(
236  const std::string& name,
237  MaterialID material,
238  float width,
239  float height,
240  float depth,
241  const Vec3& offset=Vec3()
242  );
243 
244  uint32_t submesh_count() const { return submeshes_.size(); }
245  bool has_submesh(const std::string& name) const;
246  SubMeshPtr find_submesh(const std::string& name) const;
247  SubMeshPtr first_submesh() const;
248 
249  void destroy_submesh(const std::string& name);
250 
251  void set_material(MaterialPtr material);
252  void set_diffuse(const smlt::Colour& colour);
253 
254  void reverse_winding();
255 
256  const AABB& aabb() const;
257  void normalize(); //Scales the mesh so it has a radius of 1.0
258  void transform_vertices(const smlt::Mat4& transform);
259 
260  SubMeshIteratorPair each_submesh() const;
261 
262  void enable_animation(MeshAnimationType animation_type, uint32_t animation_frames, FrameUnpackerPtr data);
263  bool is_animated() const { return animation_type_ != MESH_ANIMATION_TYPE_NONE; }
264  uint32_t animation_frames() const { return animation_frames_; }
265  MeshAnimationType animation_type() const { return animation_type_; }
266 
267  /* Generates adjacency information for this mesh. This is necessary for stencil shadowing
268  * to work */
269  void generate_adjacency_info();
270  bool has_adjacency_info() const { return bool(adjacency_); }
271 
272 public:
273  // Signals
274 
275  typedef sig::signal<void (Skeleton*)> SkeletonAddedSignal;
279 
280  DEFINE_SIGNAL(SkeletonAddedSignal, signal_skeleton_added);
281 
282  SubMeshCreatedCallback& signal_submesh_created() { return signal_submesh_created_; }
283  SubMeshDestroyedCallback& signal_submesh_destroyed() { return signal_submesh_destroyed_; }
284  SubMeshMaterialChangedCallback& signal_submesh_material_changed() { return signal_submesh_material_changed_; }
285 
286 private:
287  friend class SubMesh;
288  friend class Actor;
289 
290  Skeleton* skeleton_ = nullptr;
291 
292  VertexDataPtr vertex_data_;
293  MeshAnimationType animation_type_ = MESH_ANIMATION_TYPE_NONE;
294  uint32_t animation_frames_ = 0;
295  FrameUnpackerPtr animated_frame_data_;
296 
297  std::vector<std::shared_ptr<SubMesh>> submeshes_;
298 
299  SubMeshCreatedCallback signal_submesh_created_;
300  SubMeshDestroyedCallback signal_submesh_destroyed_;
301  SubMeshMaterialChangedCallback signal_submesh_material_changed_;
302 
303  void rebuild_aabb();
304  AABB aabb_;
305 
306  /* Automatically maintain adjacency info for submeshes or not */
307  bool maintain_adjacency_info_ = true;
308  std::unique_ptr<AdjacencyInfo> adjacency_;
309 
310  void vertex_data_updated();
311  void submesh_index_data_updated(SubMesh* sm);
312  sig::connection done_connection_;
313 
314 public:
315  /* Returns a nullptr if there is no adjacecy info */
316  S_DEFINE_PROPERTY(adjacency_info, &Mesh::adjacency_);
317 
318  S_DEFINE_PROPERTY(vertex_data, &Mesh::vertex_data_);
319 
320  /* Returns a nullptr if there is no skeleton */
321  S_DEFINE_PROPERTY(skeleton, &Mesh::skeleton_);
322 };
323 
324 }
325 
326 #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:92
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:696
smlt::RefCounted
Definition: managed.h:65
smlt
Definition: animation.cpp:25
smlt::Mesh::set_material
void set_material(MaterialPtr material)
Apply material to all submeshes.
Definition: mesh.cpp:667
smlt::generic::Identifiable
Definition: identifiable.h:26
smlt::UniqueID< MeshPtr >
smlt::Mesh
Definition: mesh.h:132
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:29
smlt::Colour
Definition: colour.h:29
smlt::AssetManager
Definition: asset_manager.h:96
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:714
smlt::sig::signal
Definition: signal.h:319