CORGI
An open source project by FPL.
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Groups Pages
animation.h
Go to the documentation of this file.
1 // Copyright 2015 Google Inc. All rights reserved.
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 #ifndef CORGI_COMPONENT_LIBRARY_ANIMATION_H_
16 #define CORGI_COMPONENT_LIBRARY_ANIMATION_H_
17 
18 #include "breadboard/event.h"
19 #include "corgi/component.h"
20 #include "library_components_generated.h"
21 #include "motive/anim_table.h"
22 #include "motive/engine.h"
23 #include "motive/motivator.h"
24 
25 /// @brief Namespace for Motive library.
26 namespace motive {
27 class RigAnim;
28 }
29 
30 /// @brief Namespace for CORGI library.
31 namespace corgi {
32 namespace component_library {
33 
34 BREADBOARD_DECLARE_EVENT(kAnimationCompleteEventId)
35 
36 /// @file
37 /// @addtogroup corgi_component_library
38 /// @{
39 
40 /// @struct AnimationData
41 ///
42 /// @brief The Component data structure that corresponds to each Entity that
43 /// is registered with the AnimationComponent. It contains all the information
44 /// for each Entity's animation.
45 struct AnimationData {
46  AnimationData()
47  : anim_table_object(-1),
48  last_anim_idx(-1),
49  previous_time_remaining(motive::kMotiveTimeEndless),
50  debug_state(AnimationDebugState_None),
51  debug_bone(motive::kInvalidBoneIdx) {}
52 
53  /// @var motivator
54  ///
55  /// @brief Holds and processes the animaton. Calls can be made to
56  /// `motivator.GlobalTransforms()` to get an array of matrices: one for
57  /// each bone in the animation.
58  motive::RigMotivator motivator;
59 
60  /// @var anim_table_object
61  ///
62  /// @brief Specifies the object-type query parameter for the AnimTable,
63  /// which is used to index the first array of the AnimTable.
65 
66  /// @var last_anim_idx
67  ///
68  /// @brief Tracks the index of the last animation that was played by
69  /// `AnimateFromTable()`.
71 
72  /// @var previous_time_remaining
73  ///
74  /// @brief The amount of time remaning from the previous animation. This
75  /// can be used for firing animation events.
76  motive::MotiveTime previous_time_remaining;
77 
78  /// @var debug_state
79  ///
80  /// @brief The debug information output to the log every frame, for this
81  /// animating object. You probably want this to be None for all but one
82  /// animating object, since it outputs a lot of data.
83  AnimationDebugState debug_state;
84 
85  /// @var debug_bone
86  ///
87  /// @brief When `debug_state` outputs bone-specific information, this
88  /// member specifies the bone. Ignored otherwise.
89  motive::BoneIndex debug_bone;
90 };
91 
92 /// @class AnimationComponent
93 ///
94 /// @brief A Component that provides an elegant way to handle Entity animation
95 /// by interacting with the Motive animation library.
96 class AnimationComponent : public Component<AnimationData> {
97  public:
98  /// @brief Deconstructor of the Animation component.
99  virtual ~AnimationComponent() {}
100 
101  /// @brief Updates all Motivators in the AnimationData, as well as, any other
102  /// Motivators that were initialized with AnimationComponent's MotiveEngine.
103  ///
104  /// @param[in] delta_time An corgi::WorldTime representing the delta time
105  /// since the last call to UpdateAllEntities.
106  virtual void UpdateAllEntities(corgi::WorldTime delta_time);
107 
108  /// @brief Deserialize a flat binary buffer to create and populate an Entity
109  /// from raw data.
110  ///
111  /// @param[in,out] entity An EntityRef reference that points to an Entity that
112  /// is being added from the raw data.
113  /// @param[in] data A void pointer to the raw FlatBuffer data.
114  virtual void AddFromRawData(corgi::EntityRef& entity, const void* data);
115 
116  /// @brief Serializes an AnimationComponent's data for a given Entity.
117  ///
118  /// @param[in] entity An EntityRef reference to an Entity whose corresponding
119  /// AnimationData will be serialized.
120  ///
121  /// @return Returns a RawDataUniquePtr to the start of the raw data in a
122  /// flat binary buffer.
123  virtual RawDataUniquePtr ExportRawData(const corgi::EntityRef& entity) const;
124 
125  /// @brief Begin playback of a given RigAnim on a given Entity.
126  ///
127  /// @param[in] entity A const EntityRef reference to an Entity that the
128  /// RigAnim `anim` should be applied on.
129  ///
130  /// @warning This method asserts that `entity` must also have a
131  /// RenderMeshComponent in order for the animation to be applied.
132  ///
133  /// @param[in] anim A const motive::RigAnim reference to the animation that
134  /// should be applied on `entity`.
135  void Animate(const corgi::EntityRef& entity, const motive::RigAnim& anim);
136 
137  /// @brief Query the AnimTable for an animation and then play it.
138  ///
139  /// @param[in] entity A const EntityRef reference to the Entity whose
140  /// corresponding animation should be started.
141  /// @param[in] anim_idx An int index of the animation that should be
142  /// started.
143  ///
144  /// @return Returns `true` if a new animation was successfully started.
145  /// Otherwise, it returns `false` if the animation could not be found in
146  /// the AnimTable.
147  bool AnimateFromTable(const corgi::EntityRef& entity, int anim_idx);
148 
149  /// @brief Check if a certain animation exists with a given index in the
150  /// AnimTable for a given Entity.
151  ///
152  /// @param[in] entity A const EntityRef reference to the Entity whose
153  /// corresponding animation should be checked.
154  /// @param[in] anim_idx An int index of the animation whose existence should
155  /// be checked.
156  ///
157  /// @return Returns `true` if the animation exists in the AnimTable with
158  /// `anim_idx`. Returns `false` if the animation is not found in the
159  /// AnimTable.
160  bool HasAnim(const corgi::EntityRef& entity, int anim_idx) const {
161  const AnimationData* data = Data<AnimationData>(entity);
162  return anim_table_.Query(data->anim_table_object, anim_idx) != nullptr;
163  }
164 
165  /// @brief Get the length of an Entity's animation, given an animation index.
166  ///
167  /// @param[in] entity A const EntityRef reference to the Entity whose
168  /// corresponding animation's length should be returned.
169  /// @param[in] anim_idx An int index of the animation whose length should be
170  /// returned.
171  ///
172  /// @return Returns the length of the animation, if it exists. Otherwise, it
173  /// returns 0.
174  motive::MotiveTime AnimLength(const corgi::EntityRef& entity,
175  int anim_idx) const {
176  const AnimationData* data = Data<AnimationData>(entity);
177  const motive::RigAnim* anim =
178  anim_table_.Query(data->anim_table_object, anim_idx);
179  return anim == nullptr ? 0 : anim->end_time();
180  }
181 
182  /// @brief Get the index of the last animation that was played.
183  ///
184  /// @param[in] entity A const EntityRef reference to the entity whose index
185  /// should be returned.
186  ///
187  /// @return Returns the index of the last animation that was played via
188  /// `AnimateFromTable()`, or returns -1 if no animation has ever been played
189  /// using that function.
190  int LastAnimIdx(const corgi::EntityRef& entity) const {
191  return Data<AnimationData>(entity)->last_anim_idx;
192  }
193 
194  /// @brief Get a reference to the engine that can be used for external
195  /// Motivators as well. For the greatest efficiency, there should only be one
196  /// MotiveEngine.
197  ///
198  /// @return Returns a reference to the MotiveEngine for this
199  /// AnimationComponent.
200  motive::MotiveEngine& engine() { return engine_; }
201 
202  /// @brief Get a const reference to the engine that can be used for
203  /// external Motivators as well. For the greatest efficiency,
204  /// there should only be one MotiveEngine.
205  ///
206  /// @return Returns a const reference to the MotiveEngine for this
207  /// AnimationComponent.
208  const motive::MotiveEngine& engine() const { return engine_; }
209 
210  /// @brief Get a reference to the animation table that is queried when
211  /// `AnimateFromTable()` is called.
212  ///
213  /// @return Returns a reference to the AnimTable for this AnimationComponent.
214  motive::AnimTable& anim_table() { return anim_table_; }
215 
216  /// @brief Get a const reference to the animation table that is queried when
217  /// `AnimateFromTable()` is called.
218  ///
219  /// @return Returns a const reference to the AnimTable for this
220  /// AnimationComponent.
221  const motive::AnimTable& anim_table() const { return anim_table_; }
222 
223  private:
224  /// @brief Sets the motivator up for any of the animations on the `object`.
225  void InitializeMotivator(const corgi::EntityRef& entity);
226 
227  /// @var engine_
228  ///
229  /// @brief Holds MotiveProcessors that, in turn, hold the animation state.
230  /// Calling AdvanceFrame() on this updates all the animations at once.
231  motive::MotiveEngine engine_;
232 
233  /// @var anim_table_
234  ///
235  /// @brief Holds a table of animations.
236  /// It is a simple array of arrays. The top array is indexed by
237  /// `anim_table_object` in `AnimationData`. The bottom array is indexed by
238  /// `anim_idx` in the `AnimateFromTable()` call.
239  motive::AnimTable anim_table_;
240 };
241 /// @}
242 
243 } // component_library
244 } // corgi
245 
248 
249 #endif // CORGI_COMPONENT_LIBRARY_ANIMATION_H_
std::unique_ptr< uint8_t, std::function< void(uint8_t *)> > RawDataUniquePtr
A pointer type for exported raw data.
Definition: component_interface.h:63
int last_anim_idx
Tracks the index of the last animation that was played by AnimateFromTable().
Definition: animation.h:70
motive::MotiveTime previous_time_remaining
The amount of time remaning from the previous animation. This can be used for firing animation events...
Definition: animation.h:76
bool HasAnim(const corgi::EntityRef &entity, int anim_idx) const
Check if a certain animation exists with a given index in the AnimTable for a given Entity...
Definition: animation.h:160
motive::BoneIndex debug_bone
When debug_state outputs bone-specific information, this member specifies the bone. Ignored otherwise.
Definition: animation.h:89
A Component is an object that encapsulates all data and logic for Entities of a particular type...
Definition: component.h:43
AnimationDebugState debug_state
The debug information output to the log every frame, for this animating object. You probably want thi...
Definition: animation.h:83
motive::AnimTable & anim_table()
Get a reference to the animation table that is queried when AnimateFromTable() is called...
Definition: animation.h:214
motive::MotiveEngine & engine()
Get a reference to the engine that can be used for external Motivators as well. For the greatest effi...
Definition: animation.h:200
int WorldTime
A typedef that represents time in the game.
Definition: entity_common.h:49
bool AnimateFromTable(const corgi::EntityRef &entity, int anim_idx)
Query the AnimTable for an animation and then play it.
virtual void UpdateAllEntities(corgi::WorldTime delta_time)
Updates all Motivators in the AnimationData, as well as, any other Motivators that were initialized w...
motive::RigMotivator motivator
Holds and processes the animaton. Calls can be made to motivator.GlobalTransforms() to get an array o...
Definition: animation.h:58
const motive::AnimTable & anim_table() const
Get a const reference to the animation table that is queried when AnimateFromTable() is called...
Definition: animation.h:221
A Component that provides an elegant way to handle Entity animation by interacting with the Motive an...
Definition: animation.h:96
virtual void AddFromRawData(corgi::EntityRef &entity, const void *data)
Deserialize a flat binary buffer to create and populate an Entity from raw data.
int LastAnimIdx(const corgi::EntityRef &entity) const
Get the index of the last animation that was played.
Definition: animation.h:190
A reference object for pointing into the vector pool. It acts as a pointer for vector pool elements a...
Definition: vector_pool.h:72
The Component data structure that corresponds to each Entity that is registered with the AnimationCom...
Definition: animation.h:45
const motive::MotiveEngine & engine() const
Get a const reference to the engine that can be used for external Motivators as well. For the greatest efficiency, there should only be one MotiveEngine.
Definition: animation.h:208
void Animate(const corgi::EntityRef &entity, const motive::RigAnim &anim)
Begin playback of a given RigAnim on a given Entity.
virtual ~AnimationComponent()
Deconstructor of the Animation component.
Definition: animation.h:99
#define CORGI_REGISTER_COMPONENT(ComponentType, DataType)
Definition: component_id_lookup.h:48
int anim_table_object
Specifies the object-type query parameter for the AnimTable, which is used to index the first array o...
Definition: animation.h:64
motive::MotiveTime AnimLength(const corgi::EntityRef &entity, int anim_idx) const
Get the length of an Entity's animation, given an animation index.
Definition: animation.h:174
virtual RawDataUniquePtr ExportRawData(const corgi::EntityRef &entity) const
Serializes an AnimationComponent's data for a given Entity.