Simulant  21.12-194
A portable game engine for Windows, OSX, Linux, Dreamcast, and PSP
actor.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 ENTITY_H
20 #define ENTITY_H
21 
22 #include "../generic/identifiable.h"
23 #include "../generic/managed.h"
24 
25 #include "../signals/signal.h"
26 
27 #include "stage_node.h"
28 #include "../interfaces.h"
29 #include "../meshes/mesh.h"
30 #include "../sound.h"
31 #include "../generic/manual_object.h"
32 
33 #include "../renderers/batching/render_queue.h"
34 #include "../renderers/batching/renderable.h"
35 
36 namespace smlt {
37 
38 class KeyFrameAnimationState;
39 class Rig;
40 
41 class Actor :
42  public TypedDestroyableObject<Actor, Stage>,
43  public StageNode,
44  public virtual Boundable,
45  public generic::Identifiable<ActorID>,
46  public AudioSource,
48  public ChainNameable<Actor> {
49 
50 public:
51  Actor(Stage* stage, SoundDriver *sound_driver);
52  Actor(Stage* stage, SoundDriver *sound_driver, MeshID mesh);
53  virtual ~Actor();
54 
55  const AABB& aabb() const override;
56 
57  MeshID mesh_id(DetailLevel detail_level) const;
58  MeshPtr mesh(DetailLevel detail_level) const;
59  MeshPtr best_mesh(DetailLevel detail_level) const;
60  MeshPtr base_mesh() const;
61 
62  bool has_mesh(DetailLevel detail_level) const;
63  bool has_any_mesh() const;
64  bool has_multiple_meshes() const;
65 
66  void set_mesh(MeshID mesh, DetailLevel detail_level=DETAIL_LEVEL_NEAREST);
67 
68  typedef sig::signal<void (ActorID)> MeshChangedCallback;
69 
70  MeshChangedCallback& signal_mesh_changed() { return signal_mesh_changed_; }
71 
72  /* Returns true if the nearest detail level mesh is animated. */
73  bool has_animated_mesh() const {
74  return has_animated_mesh_;
75  }
76 
77  void clean_up() override {
78  StageNode::clean_up();
79  }
80 
81  void _get_renderables(batcher::RenderQueue* render_queue, const CameraPtr camera, const DetailLevel detail_level) override;
82 
83  void use_material_slot(MaterialSlot var) {
84  material_slot_ = var;
85  }
86 
87  MaterialSlot active_material_slot() const {
88  return material_slot_;
89  }
90 
91  /*
92  * Returns true if the attached base mesh has a skeleton
93  * and so can be overridden by the rig
94  */
95  bool is_rigged() const {
96  return bool(rig_);
97  }
98 
99 private:
100  MeshPtr find_mesh(DetailLevel level) const {
101  /* Find the most suitable mesh at the specified level. This will search downwards
102  * from the level to NEAREST and return the first non-null result */
103  return effective_meshes_[level];
104  }
105 
106  // Used for animated meshes
107  std::shared_ptr<VertexData> interpolated_vertex_data_;
108 
109  /* Meshes specified for each level */
110  MeshPtr meshes_[DETAIL_LEVEL_MAX];
111 
112  /* Quick lookup for which mesh is active at a detail level */
113  MeshPtr effective_meshes_[DETAIL_LEVEL_MAX];
114 
115  void recalc_effective_meshes();
116 
117  bool has_animated_mesh_ = false;
118 
119  std::shared_ptr<KeyFrameAnimationState> animation_state_;
120 
121  MeshChangedCallback signal_mesh_changed_;
122 
123  MaterialSlot material_slot_ = MATERIAL_SLOT0;
124 
125  void update(float dt) override;
126 
127  sig::connection submesh_created_connection_;
128  sig::connection submesh_destroyed_connection_;
129 
130  void refresh_animation_state(uint32_t current_frame, uint32_t next_frame, float interp);
131 
132  /* Only available if the base mesh has a skeleton */
133  std::unique_ptr<Rig> rig_;
134  void add_rig(const Skeleton* skeleton);
135  sig::connection mesh_skeleton_added_;
136 
137 public:
138  S_DEFINE_PROPERTY(animation_state, &Actor::animation_state_);
139  S_DEFINE_PROPERTY(rig, &Actor::rig_);
140 };
141 
142 
143 }
144 
145 #endif // ENTITY_H
smlt::Actor
Definition: actor.h:48
smlt::sig::Connection
Definition: signal.h:65
smlt::Skeleton
Definition: skeleton.h:94
smlt::AudioSource
Definition: sound.h:103
smlt::Stage
Definition: stage.h:92
smlt
Definition: animation.cpp:25
smlt::HasMutableRenderPriority
Definition: renderable.h:38
smlt::batcher::RenderQueue
Definition: render_queue.h:156
smlt::generic::Identifiable
Definition: identifiable.h:26
smlt::UniqueID< MeshPtr >
smlt::TypedDestroyableObject
Definition: manual_object.h:33
smlt::ChainNameable
Definition: nameable.h:34
smlt::AABB
Definition: aabb.h:22
smlt::StageNode
Definition: stage_node.h:61
smlt::default_init_ptr< Camera >
smlt::SoundDriver
Definition: sound_driver.h:74
smlt::Boundable
The Boundable class.
Definition: boundable.h:12
smlt::sig::signal
Definition: signal.h:319