]> git.tdb.fi Git - libs/gl.git/blob - source/animation/animation.h
6845d23ee3e1652c9f7e49a86e5145f3faa6aa52
[libs/gl.git] / source / animation / animation.h
1 #ifndef MSP_GL_ANIMATION_H_
2 #define MSP_GL_ANIMATION_H_
3
4 #include <msp/core/refptr.h>
5 #include <msp/datafile/objectloader.h>
6 #include <msp/interpolate/spline.h>
7 #include <msp/time/timedelta.h>
8 #include "keyframe.h"
9
10 namespace Msp {
11 namespace GL {
12
13 class AnimationEventObserver;
14 class Armature;
15 class Matrix;
16 class Pose;
17
18 /**
19 An Animation is a sequence of KeyFrames combined with timing information.  The
20 state at any point in the animation can be interpolated from the keyframes.
21 */
22 class Animation
23 {
24 public:
25         class Loader: public DataFile::CollectionObjectLoader<Animation>
26         {
27         private:
28                 Time::TimeDelta current_time;
29                 float start_slope;
30                 float end_slope;
31                 int slopes_set;
32
33         public:
34                 Loader(Animation &);
35                 Loader(Animation &, Collection &);
36         private:
37                 void init();
38                 virtual void finish();
39
40                 void check_slopes_and_control(bool, bool);
41                 void add_kf(const KeyFrame *, bool, bool);
42                 void load_kf(const std::string &, bool);
43                 void load_kf_inline(bool);
44
45                 void control_keyframe(const std::string &);
46                 void control_keyframe_inline();
47                 void event(const std::string &);
48                 void event1i(const std::string &, int);
49                 void event1f(const std::string &, float);
50                 void event2f(const std::string &, float, float);
51                 void event3f(const std::string &, float, float, float);
52                 void event4f(const std::string &, float, float, float, float);
53                 void interval(float);
54                 void keyframe(const std::string &);
55                 void keyframe_inline();
56                 void slopes(float, float);
57         };
58
59 private:
60         enum CurveTarget
61         {
62                 POSITION,
63                 EULER,
64                 SCALE,
65                 UNIFORM
66         };
67
68         class Curve
69         {
70         protected:
71                 CurveTarget target;
72                 int component;
73
74                 Curve(CurveTarget, int);
75         public:
76                 virtual ~Curve() { }
77
78                 virtual void apply(float, Matrix &) const = 0;
79                 virtual void apply(float, KeyFrame::AnimatedUniform &) const = 0;
80         };
81
82         template<unsigned N>
83         class ValueCurve: public Curve
84         {
85         public:
86                 typedef typename Interpolate::SplineKnot<double, N> Knot;
87
88         private:
89                 Interpolate::Spline<double, 3, N> spline;
90
91         public:
92                 ValueCurve(CurveTarget, int, const std::vector<Knot> &);
93
94                 virtual void apply(float, Matrix &) const;
95                 virtual void apply(float, KeyFrame::AnimatedUniform &) const;
96         };
97
98         struct ExtractComponent
99         {
100                 typedef bool (*Extract)(const KeyFrame &, Vector3 &);
101
102                 Extract extract;
103                 unsigned index;
104                 Transform::ComponentMask mask;
105
106                 ExtractComponent(Extract e, unsigned i, Transform::ComponentMask m): extract(e), index(i), mask(m) { }
107
108                 bool operator()(const KeyFrame &, float &) const;
109         };
110
111         template<unsigned N>
112         struct ExtractUniform
113         {
114                 const std::string &name;
115
116                 ExtractUniform(const std::string &n): name(n) { }
117
118                 bool operator()(const KeyFrame &, typename Interpolate::SplineValue<float, N>::Type &) const;
119         };
120
121         struct TimedKeyFrame
122         {
123                 Time::TimeDelta time;
124                 RefPtr<const KeyFrame> keyframe;
125                 bool control;
126         };
127
128         struct Event
129         {
130                 Time::TimeDelta time;
131                 std::string name;
132                 Variant value;
133         };
134
135         struct UniformInfo
136         {
137                 std::string name;
138                 unsigned size;
139
140                 UniformInfo(const std::string &, unsigned);
141         };
142
143 public:
144         class Iterator
145         {
146         private:
147                 const Animation *animation;
148                 Time::TimeDelta elapsed;
149                 std::vector<Event>::const_iterator event_iter;
150                 bool end;
151
152         public:
153                 Iterator(const Animation &);
154
155                 Iterator &operator+=(const Time::TimeDelta &);
156                 void dispatch_events(AnimationEventObserver &);
157
158                 bool is_end() const { return end; }
159                 Matrix get_matrix() const;
160                 KeyFrame::AnimatedUniform get_uniform(unsigned) const;
161                 Matrix get_pose_matrix(unsigned) const;
162         };
163
164 private:
165         const Armature *armature;
166         std::vector<TimedKeyFrame> keyframes;
167         std::vector<Event> events;
168         bool looping;
169         std::vector<UniformInfo> uniforms;
170         std::vector<Curve *> curves;
171         unsigned uniform_curve_offset;
172
173 public:
174         Animation();
175         ~Animation();
176
177         void set_armature(const Armature &);
178         const Armature *get_armature() const { return armature; }
179
180         unsigned get_n_uniforms() const { return uniforms.size(); }
181         unsigned get_slot_for_uniform(const std::string &) const;
182         const std::string &get_uniform_name(unsigned) const;
183
184         void add_keyframe(const Time::TimeDelta &, const KeyFrame &);
185         void add_keyframe_owned(const Time::TimeDelta &, const KeyFrame *);
186         DEPRECATED void add_keyframe(const Time::TimeDelta &, const KeyFrame &, float);
187         DEPRECATED void add_keyframe(const Time::TimeDelta &, const KeyFrame &, float, float);
188         void add_control_keyframe(const KeyFrame &);
189         void add_control_keyframe_owned(const KeyFrame *);
190 private:
191         void add_keyframe(const Time::TimeDelta &, const KeyFrame *, float, float, bool);
192         void add_keyframe(const Time::TimeDelta &, const KeyFrame *, bool, bool);
193         void prepare_keyframe(TimedKeyFrame &);
194         void create_curves();
195         void create_curve(CurveTarget, Transform::ComponentMask, ExtractComponent::Extract);
196         template<unsigned N, typename T>
197         void create_curve(CurveTarget target, int, const T &);
198         static bool extract_position(const KeyFrame &, Vector3 &);
199         static bool extract_euler(const KeyFrame &, Vector3 &);
200         static bool extract_scale(const KeyFrame &, Vector3 &);
201 public:
202         void add_event(const Time::TimeDelta &, const std::string &, const Variant & = Variant());
203
204         const Msp::Time::TimeDelta &get_duration() const;
205
206         void set_looping(bool);
207         bool is_looping() const { return looping; }
208 };
209
210 } // namespace GL
211 } // namespace Msp
212
213 #endif