Simulant  21.12-194
A portable game engine for Windows, OSX, Linux, Dreamcast, and PSP
stage.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 STAGE_H
20 #define STAGE_H
21 
22 #include <functional>
23 
24 #include "generic/object_manager.h"
25 #include "generic/managed.h"
26 #include "generic/generic_tree.h"
27 #include "generic/data_carrier.h"
28 #include "threads/atomic.h"
29 
30 #include "managers/window_holder.h"
31 
32 #include "nodes/skies/skybox_manager.h"
33 #include "nodes/sprites/sprite_manager.h"
34 #include "nodes/actor.h"
35 #include "nodes/geom.h"
36 #include "nodes/particle_system.h"
37 #include "nodes/stage_node.h"
38 #include "nodes/light.h"
39 #include "nodes/mesh_instancer.h"
40 #include "nodes/stage_node_manager.h"
41 
42 #include "types.h"
43 #include "asset_manager.h"
44 
45 #include "macros.h"
46 #include "stage_manager.h"
47 
48 namespace smlt {
49 
50 namespace ui {
51  class UIManager;
52 }
53 
54 class Partitioner;
55 
56 class Debug;
57 class Sprite;
58 
59 typedef StageNodeManager<StageNodePool, ActorID, Actor> ActorManager;
60 typedef StageNodeManager<StageNodePool, GeomID, Geom> GeomManager;
61 typedef StageNodeManager<StageNodePool, LightID, Light> LightManager;
62 typedef StageNodeManager<StageNodePool, ParticleSystemID, ParticleSystem> ParticleSystemManager;
63 typedef StageNodeManager<StageNodePool, CameraID, Camera> CameraManager;
64 typedef StageNodeManager<StageNodePool, MeshInstancerID, MeshInstancer> MeshInstancerManager;
65 
66 typedef sig::signal<void (const ActorID&)> ActorCreatedSignal;
67 typedef sig::signal<void (const ActorID&)> ActorDestroyedSignal;
68 
69 typedef sig::signal<void (GeomID)> GeomCreatedSignal;
70 typedef sig::signal<void (GeomID)> GeomDestroyedSignal;
71 
72 typedef sig::signal<void (ParticleSystemID)> ParticleSystemCreatedSignal;
73 typedef sig::signal<void (ParticleSystemID)> ParticleSystemDestroyedSignal;
74 
75 typedef sig::signal<void (CameraID)> CameraCreatedSignal;
76 typedef sig::signal<void (CameraID)> CameraDestroyedSignal;
77 
78 typedef sig::signal<void (CameraID, Viewport)> StagePreRenderSignal;
79 typedef sig::signal<void (CameraID, Viewport)> StagePostRenderSignal;
80 
81 typedef sig::signal<void (MeshInstancerID)> MeshInstancerCreatedSignal;
82 typedef sig::signal<void (MeshInstancerID)> MeshInstancerDestroyedSignal;
83 
84 extern const Colour DEFAULT_LIGHT_COLOUR;
85 
86 class Stage:
87  public TypedDestroyableObject<Stage, StageManager>,
88  public ContainerNode,
89  public generic::Identifiable<StageID>,
90  public Loadable,
91  public ChainNameable<Stage>,
92  public RefCounted<Stage> {
93 
94  DEFINE_SIGNAL(MeshInstancerCreatedSignal, signal_mesh_instancer_created);
95  DEFINE_SIGNAL(MeshInstancerDestroyedSignal, signal_mesh_instancer_destroyed);
96 
97  DEFINE_SIGNAL(ParticleSystemCreatedSignal, signal_particle_system_created);
98  DEFINE_SIGNAL(ParticleSystemDestroyedSignal, signal_particle_system_destroyed);
99 
100  DEFINE_SIGNAL(StagePreRenderSignal, signal_stage_pre_render);
101  DEFINE_SIGNAL(StagePostRenderSignal, signal_stage_post_render);
102 
103  /* Necessary to access asset_manager before the assets Property<> is initialized */
104  friend class ui::UIManager;
105 
106 public:
107  Stage(
108  StageManager *parent,
109  StageNodePool* node_pool,
110  AvailablePartitioner partitioner
111  );
112 
113  virtual ~Stage();
114 
115  ActorPtr new_actor();
116  ActorPtr new_actor_with_name(const std::string& name);
117 
118  ActorPtr new_actor_with_mesh(MeshID mid);
119  ActorPtr new_actor_with_name_and_mesh(const std::string& name, MeshID mid);
120 
121  ActorPtr new_actor_with_parent(ActorID parent);
122  ActorPtr new_actor_with_parent_and_mesh(ActorID parent, MeshID mid);
123  ActorPtr new_actor_with_parent_and_mesh(SpriteID parent, MeshID mid);
124  ActorPtr actor(ActorID e);
125  ActorPtr actor(ActorID e) const;
126  bool has_actor(ActorID e) const;
127  void destroy_actor(ActorID e);
128  std::size_t actor_count() const;
129 
137 
144 
151 
156  std::size_t mesh_instancer_count() const;
157 
163  bool has_mesh_instancer(MeshInstancerID mid) const;
164 
165  CameraPtr new_camera();
166  CameraPtr new_camera_with_orthographic_projection(double left=0, double right=0, double bottom=0, double top=0, double near=-1.0, double far=1.0);
167  CameraPtr new_camera_for_ui();
168  CameraPtr new_camera_for_viewport(const Viewport& vp);
169  CameraPtr camera(CameraID c);
170  void destroy_camera(CameraID cid);
171  uint32_t camera_count() const;
172  bool has_camera(CameraID id) const;
173  void destroy_all_cameras();
174 
175  GeomPtr new_geom_with_mesh(MeshID mid, const GeomCullerOptions& culler_options=GeomCullerOptions());
176  GeomPtr new_geom_with_mesh_at_position(
177  MeshID mid, const Vec3& position,
178  const Quaternion& rotation=Quaternion(),
179  const Vec3& scale=Vec3(1, 1, 1),
180  const GeomCullerOptions& culler_options=GeomCullerOptions()
181  );
182  GeomPtr geom(const GeomID gid) const;
183  bool has_geom(GeomID geom_id) const;
184  void destroy_geom(GeomID geom_id);
185  std::size_t geom_count() const;
186 
187  ParticleSystemPtr new_particle_system(ParticleScriptID particle_script);
188  ParticleSystemPtr new_particle_system_with_parent(ParticleScriptID particle_script, ActorID parent);
189  ParticleSystemPtr particle_system(ParticleSystemID pid);
190  bool has_particle_system(ParticleSystemID pid) const;
191  void destroy_particle_system(ParticleSystemID pid);
192  std::size_t particle_system_count() const;
193 
194  LightPtr new_light_as_directional(const Vec3& direction=Vec3(1, -0.5, 0), const smlt::Colour& colour=DEFAULT_LIGHT_COLOUR);
195  LightPtr new_light_as_point(const Vec3& position=Vec3(), const smlt::Colour& colour=DEFAULT_LIGHT_COLOUR);
196 
197  LightPtr light(LightID light);
198  void destroy_light(LightID light_id);
199  std::size_t light_count() const;
200 
201  smlt::Colour ambient_light() const { return ambient_light_; }
202  void set_ambient_light(const smlt::Colour& c) { ambient_light_ = c; }
203 
204  void move(float x, float y, float z) {
205  _S_UNUSED(x);
206  _S_UNUSED(y);
207  _S_UNUSED(z);
208 
209  throw std::logic_error("You cannot move the stage");
210  }
211 
212  bool init() override;
213  void clean_up() override;
214 
215  // Updateable interface
216  void update(float dt) override;
217 
218  ActorCreatedSignal& signal_actor_created() { return signal_actor_created_; }
219  ActorDestroyedSignal& signal_actor_destroyed() { return signal_actor_destroyed_; }
220 
221  GeomCreatedSignal& signal_geom_created() { return signal_geom_created_; }
222  GeomDestroyedSignal& signal_geom_destroyed() { return signal_geom_destroyed_; }
223 
224  CameraCreatedSignal& signal_camera_created() { return signal_camera_created_; }
225  CameraDestroyedSignal& signal_camera_destroyed() { return signal_camera_destroyed_; }
226 
227  sig::signal<void (LightID)>& signal_light_created() { return signal_light_created_; }
228  sig::signal<void (LightID)>& signal_light_destroyed() { return signal_light_destroyed_; }
229 
230  const AABB& aabb() const override { return aabb_; }
231  const AABB transformed_aabb() const override { return aabb_; }
232 
233  /* Enables the debug actor to allow drawing of debug lines and points */
234  Debug* enable_debug(bool v=true);
235 
236  /* Implementation for TypedDestroyableObject (INTERNAL) */
237  void destroy_object(Actor* object);
238  void destroy_object(Light* object);
239  void destroy_object(Camera* object);
240  void destroy_object(Geom* object);
241  void destroy_object(ParticleSystem* object);
242  void destroy_object(MeshInstancer* object);
243 
244  void destroy_object_immediately(Actor* object);
245  void destroy_object_immediately(Light* object);
246  void destroy_object_immediately(Camera* object);
247  void destroy_object_immediately(Geom* object);
248  void destroy_object_immediately(ParticleSystem* object);
249  void destroy_object_immediately(MeshInstancer* object);
250 
251  bool is_part_of_active_pipeline() const {
252  return active_pipeline_count_ > 0;
253  }
254 
255 private:
256  StageNodePool* node_pool_ = nullptr;
257 
258  AABB aabb_;
259 
260  ActorCreatedSignal signal_actor_created_;
261  ActorDestroyedSignal signal_actor_destroyed_;
262 
263  GeomCreatedSignal signal_geom_created_;
264  GeomDestroyedSignal signal_geom_destroyed_;
265 
266  CameraCreatedSignal signal_camera_created_;
267  CameraDestroyedSignal signal_camera_destroyed_;
268 
269  sig::signal<void (LightID)> signal_light_created_;
270  sig::signal<void (LightID)> signal_light_destroyed_;
271 
272  sig::signal<void (SpriteID)> signal_sprite_created_;
273  sig::signal<void (SpriteID)> signal_sprite_destroyed_;
274 
275  std::shared_ptr<Partitioner> partitioner_;
276 
277  void set_partitioner(AvailablePartitioner partitioner);
278 
279  std::shared_ptr<Debug> debug_;
280 
281  //FIXME: All managers should be composition rather than inheritence,
282  // like this one!
283  std::shared_ptr<AssetManager> asset_manager_;
284  std::unique_ptr<ui::UIManager> ui_;
285 
286  unicode name_;
287 
288  smlt::Colour ambient_light_ = smlt::Colour(0.3, 0.3, 0.3, 1.0);
289 
290  std::unique_ptr<GeomManager> geom_manager_;
291  std::unique_ptr<SkyManager> sky_manager_;
292  std::unique_ptr<SpriteManager> sprite_manager_;
293  std::unique_ptr<MeshInstancerManager> mesh_instancer_manager_;
294  std::unique_ptr<ActorManager> actor_manager_;
295  std::unique_ptr<ParticleSystemManager> particle_system_manager_;
296  std::unique_ptr<LightManager> light_manager_;
297  std::unique_ptr<CameraManager> camera_manager_;
298 
299  generic::DataCarrier data_;
300 
301  friend class Pipeline;
302  thread::Atomic<uint8_t> active_pipeline_count_ = {0};
303 
304 private:
305  friend class StageManager;
306 
307  void on_actor_created(ActorID actor_id);
308  void on_actor_destroyed(ActorID actor_id);
309 
310  void clean_up_dead_objects();
311 
312 public:
313  Property<decltype(&Stage::debug_)> debug = {this, &Stage::debug_};
314  Property<decltype(&Stage::partitioner_)> partitioner = {this, &Stage::partitioner_};
315  Property<decltype(&Stage::asset_manager_)> assets = {this, &Stage::asset_manager_};
316  Property<decltype(&Stage::data_)> data = {this, &Stage::data_};
317  Property<decltype(&Stage::ui_)> ui = {this, &Stage::ui_};
318  Property<decltype(&Stage::sky_manager_)> skies = {this, &Stage::sky_manager_};
319  Property<decltype(&Stage::sprite_manager_)> sprites = {this, &Stage::sprite_manager_};
320 };
321 
322 }
323 #endif // SUBSCENE_H
smlt::Actor
Definition: actor.h:48
smlt::Property
Definition: property.h:202
smlt::ui::UIManager
Definition: ui_manager.h:54
smlt::Geom
The Geom class.
Definition: geom.h:64
smlt::Vec3
Definition: vec3.h:23
smlt::Stage::has_mesh_instancer
bool has_mesh_instancer(MeshInstancerID mid) const
Checks to see if this MeshInstancer exists.
Definition: stage.cpp:249
smlt::Quaternion
Definition: quaternion.h:24
smlt::Stage
Definition: stage.h:92
smlt::RefCounted
Definition: managed.h:65
smlt
Definition: animation.cpp:25
smlt::GeomCullerOptions
Definition: geom.h:40
smlt::Light
Definition: light.h:35
smlt::Polylist
Definition: polylist.h:67
smlt::ParticleSystem
Definition: particle_system.h:43
smlt::generic::Identifiable
Definition: identifiable.h:26
smlt::ContainerNode
Definition: stage_node.h:285
smlt::UniqueID< MeshPtr >
smlt::thread::Atomic< uint8_t >
smlt::TypedDestroyableObject
Definition: manual_object.h:33
smlt::Camera
Definition: camera.h:21
smlt::Stage::new_mesh_instancer
MeshInstancerPtr new_mesh_instancer(MeshID mid)
Creates a new MeshInstancer from a mesh and returns it.
Definition: stage.cpp:211
smlt::Pipeline
Definition: pipeline.h:21
smlt::MeshInstancer
The MeshInstancer class.
Definition: mesh_instancer.h:44
smlt::Stage::mesh_instancer_count
std::size_t mesh_instancer_count() const
Returns the number of MeshInstancers in the stage.
Definition: stage.cpp:245
smlt::Loadable
Definition: loadable.h:26
smlt::ChainNameable
Definition: nameable.h:34
smlt::AABB
Definition: aabb.h:22
unicode
Definition: unicode.h:35
smlt::Stage::mesh_instancer
MeshInstancerPtr mesh_instancer(MeshInstancerID mid)
Returns the MeshInstancerPtr associated with the ID.
Definition: stage.cpp:241
smlt::StageManager
Definition: stage_manager.h:42
smlt::default_init_ptr< Actor >
smlt::Debug
Definition: debug.h:28
smlt::generic::DataCarrier
Definition: data_carrier.h:37
smlt::Stage::destroy_mesh_instancer
bool destroy_mesh_instancer(MeshInstancerID mid)
Destroys a MeshInstancer by its ID.
Definition: stage.cpp:231
smlt::Colour
Definition: colour.h:29
smlt::Viewport
Definition: viewport.h:44
smlt::sig::signal
Definition: signal.h:319