Motive Animation System
An open source project by FPL.
 All Classes Functions Variables Typedefs Friends Pages
anim.h
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 MOTIVE_ANIM_H
16 #define MOTIVE_ANIM_H
17 
18 #include <vector>
19 #include "motive/init.h"
20 #include "motive/math/compact_spline.h"
21 
22 namespace motive {
23 
24 /// @class MatrixAnim
25 /// @brief Animation for a MatrixMotivator. Drives a single bone's transform.
26 class MatrixAnim {
27  public:
28  struct Spline {
29  Spline() : spline(nullptr) {}
30  ~Spline() {
31  CompactSpline::Destroy(spline);
32  spline = nullptr;
33  }
34  CompactSpline* spline;
35  SplineInit init;
36  };
37 
38  explicit MatrixAnim(int expected_num_ops = 0) : ops_(expected_num_ops) {}
39 
40  /// For construction. Allocates storage for spline data, and returns it.
41  /// @param num_splines Total number of splines in the animation. Not all ops
42  /// use a spline (some are const ops).
43  Spline* Construct(int num_splines) {
44  if (num_splines == 0) return nullptr;
45 
46  // Note: It's important that the `splines_` array is not moved, since
47  // `ops_` points into it.
48  // TODO: Revisit this layout to eliminate the internal pointers, making it
49  // more robust.
50  splines_.resize(num_splines);
51  return splines_.data();
52  }
53 
54  /// Return the op array. Non-const version is for construction.
55  MatrixOpArray& ops() { return ops_; }
56 
57  /// Return the op array. Const version is to initialize a MatrixMotivator.
58  const MatrixOpArray& ops() const { return ops_; }
59 
60  private:
61  /// Initialization structure for a MatrixMotivator.
62  /// When initialized with this struct, the MatrixMotivator will play back
63  /// the animation described in this class.
64  MatrixOpArray ops_;
65 
66  /// Hold spline animation data that is referenced by `init_`.
67  std::vector<Spline> splines_;
68 };
69 
70 /// @class RigAnim
71 /// @brief Animation for a RigMotivator. Drives a fully rigged model.
72 class RigAnim {
73  public:
74  RigAnim() : end_time_(0), repeat_(false) {}
75 
76  /// Initialize the basic data. After calling this function, `InitMatrixAnim()`
77  /// should be called once for every bone in the animation.
78  void Init(const char* anim_name, BoneIndex num_bones, bool record_names);
79 
80  /// For construction. Return the `idx`th bone's animation for initialization.
81  /// @param idx The bone whose animation you want to initialize.
82  /// @param parent If no parent exists, pass in kInvalidBoneIdx.
83  /// @param bone_name For debugging. Recorded if `record_names` was true in
84  /// `Init()`.
85  MatrixAnim& InitMatrixAnim(BoneIndex idx, BoneIndex parent,
86  const char* bone_name);
87 
88  /// Return the animation of the `idx`th bone. Each bone animates a matrix.
89  const MatrixAnim& Anim(BoneIndex idx) const {
90  assert(idx < anims_.size());
91  return anims_[idx];
92  }
93 
94  /// Number of bones. Bones are arranged in an hierarchy. Each bone animates
95  /// a matrix. The matrix describes the transform of the bone from its parent.
96  BoneIndex NumBones() const { return static_cast<BoneIndex>(anims_.size()); }
97 
98  /// For debugging. If `record_names` was specified in `Init()`, the names of
99  /// the bones are stored. Very useful when an animation is applied to a mesh
100  /// that doesn't match: with the bone names you can determine whether the
101  /// mesh or the animation is out of date.
102  const char* BoneName(BoneIndex idx) const {
103  return idx < bone_names_.size() ? bone_names_[idx].c_str() : "unknown";
104  }
105 
106  /// Total number of matrix operations across all MatrixAnims in this RigAnim.
107  int NumOps() const;
108 
109  /// Gets the splines and constants that drive the operations in `ops`,
110  /// for the specified bone. If an operation is not driven by the bone,
111  /// return the default value for that op in `constants`.
112  ///
113  /// If the bone has multiple operations that match `ops[i]`, return the
114  /// first one.
115  ///
116  /// @param bone The bone whose operations you want to pull data for.
117  /// @param ops And array of length `num_ops` with the operations you're
118  /// interested in.
119  /// @params num_ops Length of the `ops` array.
120  /// @params splines Output array, length `num_ops`. For each element of
121  /// `ops`, receives the driving spline, or nullptr if that
122  /// operation is not driven by a spline.
123  /// @params constants Output array, length `num_ops`. For each element of
124  /// `ops`, receives the constant value of that operation,
125  /// if no spline drives that operation.
126  void GetSplinesAndConstants(BoneIndex bone, const MatrixOperationType* ops,
127  int num_ops, const CompactSpline** splines,
128  float* constants) const;
129 
130  /// For debugging. The number of lines in the header. You call them separately
131  /// in case you want to prefix or append extra columns.
132  int NumCsvHeaderLines() const { return 2; }
133 
134  /// Output a line of comma-separated-values that has header information for
135  /// the CSV data output by RigMotivator::CsvValues().
136  std::string CsvHeaderForDebugging(int line) const;
137 
138  /// Amount of time required by this animation. Time units are set by the
139  /// caller. If animation repeats, returns infinity.
140  /// TODO: Add function to return non-repeated end time, even when repeatable.
141  MotiveTime end_time() const { return end_time_; }
142 
143  /// For construction. The end time should be set to the maximal end time of
144  /// all the `anims_`.
145  void set_end_time(MotiveTime t) { end_time_ = t; }
146 
147  /// Returns an array of length NumBones() representing the bone heirarchy.
148  /// `bone_parents()[i]` is the bone index of the ith bone's parent.
149  /// `bone_parents()[i]` < `bone_parents()[j]` for all i < j.
150  /// For bones at the root (i.e. no parent) value is kInvalidBoneIdx.
151  const BoneIndex* bone_parents() const { return bone_parents_.data(); }
152 
153  /// Animation is repeatable. That is, when the end of the animation is
154  /// reached, it can be started at the beginning again without glitching.
155  /// Generally, an animation is repeatable if it's curves have the same values
156  /// and derivatives at the start and end.
157  bool repeat() const { return repeat_; }
158 
159  /// Set the repeat flag.
160  bool set_repeat(bool repeat) { return repeat_ = repeat; }
161 
162  /// For debugging. The name of the animation currently being played.
163  /// Only valid if `record_names` is true in `Init()`.
164  const std::string& anim_name() const { return anim_name_; }
165 
166  private:
167  std::vector<MatrixAnim> anims_;
168  std::vector<BoneIndex> bone_parents_;
169  std::vector<std::string> bone_names_;
170  MotiveTime end_time_;
171  bool repeat_;
172  std::string anim_name_;
173 };
174 
175 } // namespace motive
176 
177 #endif // MOTIVE_ANIM_H
const BoneIndex * bone_parents() const
Definition: anim.h:151
const MatrixAnim & Anim(BoneIndex idx) const
Return the animation of the idxth bone. Each bone animates a matrix.
Definition: anim.h:89
Animation for a MatrixMotivator. Drives a single bone's transform.
Definition: anim.h:26
Animation for a RigMotivator. Drives a fully rigged model.
Definition: anim.h:72
void set_end_time(MotiveTime t)
Definition: anim.h:145
Initialize a MotivatorNf to follow a spline.
Definition: init.h:317
const char * BoneName(BoneIndex idx) const
Definition: anim.h:102
const std::string & anim_name() const
Definition: anim.h:164
bool set_repeat(bool repeat)
Set the repeat flag.
Definition: anim.h:160
bool repeat() const
Definition: anim.h:157
const MatrixOpArray & ops() const
Return the op array. Const version is to initialize a MatrixMotivator.
Definition: anim.h:58
static void Destroy(CompactSpline *spline)
Definition: compact_spline.h:404
Definition: anim.h:28
void Init(const char *anim_name, BoneIndex num_bones, bool record_names)
std::string CsvHeaderForDebugging(int line) const
MatrixAnim & InitMatrixAnim(BoneIndex idx, BoneIndex parent, const char *bone_name)
int NumOps() const
Total number of matrix operations across all MatrixAnims in this RigAnim.
MotiveTime end_time() const
Definition: anim.h:141
BoneIndex NumBones() const
Definition: anim.h:96
int NumCsvHeaderLines() const
Definition: anim.h:132
void GetSplinesAndConstants(BoneIndex bone, const MatrixOperationType *ops, int num_ops, const CompactSpline **splines, float *constants) const
Represent a smooth curve in a small amount of memory.
Definition: compact_spline.h:73
MatrixOpArray & ops()
Return the op array. Non-const version is for construction.
Definition: anim.h:55
Definition: init.h:424
Spline * Construct(int num_splines)
Definition: anim.h:43