Simulant  21.12-574
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  const MeshPtr &mesh(DetailLevel detail_level) const;
59  const MeshPtr& best_mesh(DetailLevel detail_level) const;
60  const 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  UniqueIDKey make_key() const override {
101  return make_unique_id_key(id());
102  }
103 
104  const MeshPtr& find_mesh(DetailLevel level) const {
105  /* Find the most suitable mesh at the specified level. This will search downwards
106  * from the level to NEAREST and return the first non-null result */
107  return effective_meshes_[level];
108  }
109 
110  // Used for animated meshes
111  std::shared_ptr<VertexData> interpolated_vertex_data_;
112 
113  /* Meshes specified for each level */
114  MeshPtr meshes_[DETAIL_LEVEL_MAX];
115 
116  /* Quick lookup for which mesh is active at a detail level */
117  MeshPtr effective_meshes_[DETAIL_LEVEL_MAX];
118 
119  void recalc_effective_meshes();
120 
121  bool has_animated_mesh_ = false;
122 
123  std::shared_ptr<KeyFrameAnimationState> animation_state_;
124 
125  MeshChangedCallback signal_mesh_changed_;
126 
127  MaterialSlot material_slot_ = MATERIAL_SLOT0;
128 
129  void update(float dt) override;
130 
131  sig::connection submesh_created_connection_;
132  sig::connection submesh_destroyed_connection_;
133 
134  void refresh_animation_state(uint32_t current_frame, uint32_t next_frame, float interp);
135 
136  /* Only available if the base mesh has a skeleton */
137  std::unique_ptr<Rig> rig_;
138  void add_rig(const Skeleton* skeleton);
139  sig::connection mesh_skeleton_added_;
140 
141 public:
142  S_DEFINE_PROPERTY(animation_state, &Actor::animation_state_);
143  S_DEFINE_PROPERTY(rig, &Actor::rig_);
144 };
145 
146 
147 }
148 
149 #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:106
smlt::Stage
Definition: stage.h:80
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:34
smlt::ChainNameable
Definition: nameable.h:34
smlt::AABB
Definition: aabb.h:22
smlt::StageNode
Definition: stage_node.h:62
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:330