Simulant  21.12-574
A portable game engine for Windows, OSX, Linux, Dreamcast, and PSP
stage_node.h
1 #pragma once
2 
3 #include "./tree_node.h"
4 #include "../interfaces/nameable.h"
5 #include "../interfaces/printable.h"
6 #include "../interfaces/transformable.h"
7 #include "../interfaces/updateable.h"
8 #include "../interfaces/boundable.h"
9 #include "../behaviours/behaviour.h"
10 #include "../interfaces/has_auto_id.h"
11 #include "../generic/data_carrier.h"
12 #include "../shadows.h"
13 #include "../generic/manual_object.h"
14 #include "../coroutines/helpers.h"
15 #include "../partitioner.h"
16 
17 #include "iterators/sibling_iterator.h"
18 #include "iterators/child_iterator.h"
19 #include "iterators/descendent_iterator.h"
20 #include "iterators/ancestor_iterator.h"
21 
22 namespace smlt {
23 
24 class RenderableFactory;
25 class Seconds;
26 
27 typedef sig::signal<void (AABB)> BoundsUpdatedSignal;
28 typedef sig::signal<void ()> CleanedUpSignal;
29 
30 /* Used for multiple levels of detail when rendering stage nodes */
31 
32 enum DetailLevel {
33  DETAIL_LEVEL_NEAREST = 0,
34  DETAIL_LEVEL_NEAR,
35  DETAIL_LEVEL_MID,
36  DETAIL_LEVEL_FAR,
37  DETAIL_LEVEL_FARTHEST,
38  DETAIL_LEVEL_MAX
39 };
40 
41 enum StageNodeType {
42  STAGE_NODE_TYPE_STAGE,
43  STAGE_NODE_TYPE_CAMERA,
44  STAGE_NODE_TYPE_ACTOR,
45  STAGE_NODE_TYPE_LIGHT,
46  STAGE_NODE_TYPE_PARTICLE_SYSTEM,
47  STAGE_NODE_TYPE_GEOM,
48  STAGE_NODE_TYPE_MESH_INSTANCER,
49  STAGE_NODE_TYPE_OTHER
50 };
51 
52 class StageNode:
53  public virtual DestroyableObject,
54  public TreeNode,
55  public virtual Nameable,
56  public Printable,
57  public Transformable,
58  public Updateable,
59  public virtual BoundableEntity,
60  public Organism,
61  public HasAutoID<StageNode>,
62  public virtual TwoPhaseConstructed {
63 
64  DEFINE_SIGNAL(BoundsUpdatedSignal, signal_bounds_updated);
65 
66  // Fired when the node is cleaned up later, following destroy
67  DEFINE_SIGNAL(CleanedUpSignal, signal_cleaned_up);
68 
69 private:
70  /* This is ugly, but it's here for performance to avoid
71  * a map lookup when staging writes to the partitioner */
72  friend class Partitioner;
73  bool partitioner_dirty_ = false;
74  bool partitioner_added_ = false;
75 
76 public:
78  friend class StageNode;
79 
81  root_(root) {}
82 
83  StageNode* root_;
84 
85  public:
86  SiblingIterator<false> begin() {
87  return SiblingIterator<false>(root_);
88  }
89 
91  return SiblingIterator<false>(root_, nullptr);
92  }
93  };
94 
96  friend class StageNode;
97 
99  root_(root) {}
100 
101  StageNode* root_;
102 
103  public:
104  ChildIterator<false> begin() {
105  return ChildIterator<false>((StageNode*) root_);
106  }
107 
108  ChildIterator<false> end() {
109  return ChildIterator<false>(root_, nullptr);
110  }
111  };
112 
114  friend class StageNode;
115 
117  root_(root) {}
118 
119  StageNode* root_;
120 
121  public:
122  DescendentIterator<false> begin() {
123  return DescendentIterator<false>((StageNode*) root_);
124  }
125 
127  return DescendentIterator<false>(root_, nullptr);
128  }
129  };
130 
132  friend class StageNode;
133 
135  root_(root) {}
136 
137  StageNode* root_;
138 
139  public:
140  AncestorIterator<false> begin() {
141  return AncestorIterator<false>((StageNode*) root_);
142  }
143 
145  return AncestorIterator<false>(root_, nullptr);
146  }
147  };
148 
149  AncestorIteratorPair each_ancestor() {
150  return AncestorIteratorPair(this);
151  }
152 
153  DescendentIteratorPair each_descendent() {
154  return DescendentIteratorPair(this);
155  }
156 
157  SiblingIteratorPair each_sibling() {
158  return SiblingIteratorPair(this);
159  }
160 
161  ChildIteratorPair each_child() {
162  return ChildIteratorPair(this);
163  }
164 
165  std::string repr() const override {
166  return name();
167  }
168 
169  StageNode(Stage* stage, StageNodeType node_type);
170 
171  virtual ~StageNode();
172 
173  StageNodeType node_type() const;
174 
179  void link_position(StageNode* other);
180 
181  /* Without a parent, these are the same as move_to/rotate_to. With a parent
182  * this applies a relative position / rotation to the parent position / rotation
183  * so the node appears where you want */
184  void move_to_absolute(const Vec3& position);
185  void move_to_absolute(float x, float y, float z);
186  void rotate_to_absolute(const Quaternion& rotation);
187  void rotate_to_absolute(const Degrees& degrees, float x, float y, float z);
188 
189  Vec3 absolute_position() const;
190  Quaternion absolute_rotation() const;
191  Vec3 absolute_scaling() const;
192  Mat4 absolute_transformation() const;
193 
194  bool is_visible() const;
195 
196  bool is_intended_visible() const { return is_visible_; }
197  void set_visible(bool visible);
198 
199  Property<generic::DataCarrier StageNode::*> data = { this, &StageNode::data_ };
200  Property<Stage* StageNode::*> stage = { this, &StageNode::stage_ };
201 
202  template<typename T>
203  void set_parent(const UniqueID<T>& id) {
204  set_parent(id.fetch());
205  }
206 
207  void set_parent(TreeNode* node);
208 
209  smlt::Promise<void> destroy_after(const Seconds& seconds);
210 
211  void update(float dt) override;
212  void late_update(float dt) override;
213  void fixed_update(float step) override;
214 
215  bool parent_is_stage() const;
216 
217  void clean_up() override;
218 
219  const AABB transformed_aabb() const override;
220 
221  /* Control shading on the stage node (behaviour depends on the type of node) */
222  ShadowCast shadow_cast() const { return shadow_cast_; }
223  void set_shadow_cast(ShadowCast cast) {
224  shadow_cast_ = cast;
225  }
226 
227  ShadowReceive shadow_receive() const { return shadow_receive_; }
228  void set_shadow_receive(ShadowReceive receive) { shadow_receive_ = receive; }
229 
230  StageNode* find_descendent_with_name(const std::string& name);
231 
232  /* Return a list of renderables to pass into the render queue */
233  virtual void _get_renderables(
234  batcher::RenderQueue* render_queue,
235  const CameraPtr camera,
236  const DetailLevel detail_level
237  ) = 0;
238 
239  void set_cullable(bool v);
240  bool is_cullable() const;
241 
242  /* Returns a sortable key unique to this node, this is
243  * generated by the UniqueID<T> of the subclass */
244  UniqueIDKey key() const {
245  return make_key();
246  }
247 
248 protected:
249  virtual UniqueIDKey make_key() const = 0;
250 
251  // Faster than properties, useful for subclasses where a clean API isn't as important
252  Stage* get_stage() const { return stage_; }
253 
254  void on_transformation_changed() override;
255  void on_parent_set(TreeNode* oldp, TreeNode* newp) override;
256 
257  virtual void update_transformation_from_parent();
258 
259  void recalc_bounds_if_necessary() const;
260  void mark_transformed_aabb_dirty();
261 
262  void mark_absolute_transformation_dirty();
263 private:
264  AABB calculate_transformed_aabb() const;
265 
266  Stage* stage_ = nullptr;
267  StageNode* parent_stage_node_ = nullptr;
268 
269  StageNodeType node_type_ = STAGE_NODE_TYPE_ACTOR;
270 
271  generic::DataCarrier data_;
272 
273  StageNode* linked_position_node_ = nullptr;
274  sig::connection linked_position_node_destroyed_;
275 
276  bool is_visible_ = true;
277  bool self_and_parents_visible_ = true;
278  void recalc_visibility();
279 
280  Vec3 absolute_position_;
281  Quaternion absolute_rotation_;
282  Vec3 absolute_scale_ = Vec3(1, 1, 1);
283 
284  mutable Mat4 absolute_transformation_;
285  mutable bool absolute_transformation_is_dirty_ = true;
286 
287  /* Mutable so that AABB accesses can be const, but we delay
288  * calculation until access */
289  mutable AABB transformed_aabb_;
290  mutable bool transformed_aabb_dirty_ = false;
291 
292  // By default, always cast and receive shadows
293  ShadowCast shadow_cast_ = SHADOW_CAST_ALWAYS;
294  ShadowReceive shadow_receive_ = SHADOW_RECEIVE_ALWAYS;
295 
296  /* Whether or not this node should be culled by the partitioner (e.g. when offscreen) */
297  bool cullable_ = true;
298 
299  /* Passed to coroutines and used to detect when the object has been destroyed */
300  std::shared_ptr<bool> alive_marker_ = std::make_shared<bool>(true);
301 };
302 
303 
304 class ContainerNode : public StageNode {
305 public:
306  ContainerNode(Stage* stage, StageNodeType node_type):
307  StageNode(stage, node_type) {}
308 
309  /* Containers don't directly have renderables, but their children do */
310  void _get_renderables(batcher::RenderQueue*, const CameraPtr, const DetailLevel) override {
311 
312  }
313 
314  virtual ~ContainerNode() {}
315 };
316 
317 }
318 
319 #include "iterators/sibling_iterator.inc"
320 #include "iterators/child_iterator.inc"
321 #include "iterators/descendent_iterator.inc"
322 #include "iterators/ancestor_iterator.inc"
323 
324 
smlt::DescendentIterator
Definition: descendent_iterator.h:11
smlt::TreeNode
Definition: tree_node.h:17
smlt::StageNode::ChildIteratorPair
Definition: stage_node.h:95
smlt::StageNode::AncestorIteratorPair
Definition: stage_node.h:131
smlt::Printable
Definition: printable.h:7
smlt::StageNode::DescendentIteratorPair
Definition: stage_node.h:113
smlt::Organism
Definition: behaviour.h:132
smlt::StageNode::link_position
void link_position(StageNode *other)
Definition: stage_node.cpp:23
smlt::SiblingIterator
Definition: sibling_iterator.h:11
smlt::Stage
Definition: stage.h:80
smlt::Updateable
The Updateable class.
Definition: updateable.h:13
smlt::Partitioner
Definition: partitioner.h:55
smlt
Definition: animation.cpp:25
smlt::TwoPhaseConstructed
Definition: managed.h:47
smlt::batcher::RenderQueue
Definition: render_queue.h:156
smlt::StageNode::SiblingIteratorPair
Definition: stage_node.h:77
smlt::ContainerNode
Definition: stage_node.h:304
smlt::DestroyableObject
Definition: manual_object.h:9
smlt::StageNode
Definition: stage_node.h:62
smlt::AncestorIterator
Definition: ancestor_iterator.h:11
smlt::HasAutoID
Definition: has_auto_id.h:8
smlt::Transformable
The Transformable class.
Definition: transformable.h:17
smlt::default_init_ptr< Camera >
smlt::BoundableEntity
The BoundableEntity class.
Definition: boundable.h:49
smlt::ChildIterator
Definition: child_iterator.h:11
smlt::Promise< void >
Definition: helpers.h:141
smlt::sig::signal
Definition: signal.h:330
smlt::Nameable
The Nameable class.
Definition: nameable.h:12