]> git.tdb.fi Git - libs/gl.git/blob - source/animation.h
Merge branch 'animation-rework'
[libs/gl.git] / source / 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
73                 Curve(CurveTarget);
74         public:
75                 virtual ~Curve() { }
76
77                 virtual void apply(float, Matrix &) const = 0;
78                 virtual void apply(float, KeyFrame::AnimatedUniform &) const = 0;
79         };
80
81         template<unsigned N>
82         class ValueCurve: public Curve
83         {
84         public:
85                 typedef typename Interpolate::SplineKnot<float, N> Knot;
86
87         private:
88                 Interpolate::Spline<float, 3, N> spline;
89
90         public:
91                 ValueCurve(CurveTarget, const std::vector<Knot> &);
92
93                 virtual void apply(float, Matrix &) const;
94                 virtual void apply(float, KeyFrame::AnimatedUniform &) const;
95         };
96
97         template<unsigned N>
98         struct ExtractUniform
99         {
100                 const std::string &name;
101
102                 ExtractUniform(const std::string &n): name(n) { }
103
104                 bool operator()(const KeyFrame &, typename Interpolate::SplineValue<float, N>::Type &) const;
105         };
106
107         struct TimedKeyFrame
108         {
109                 Time::TimeDelta time;
110                 RefPtr<const KeyFrame> keyframe;
111                 bool control;
112         };
113
114         struct Event
115         {
116                 Time::TimeDelta time;
117                 std::string name;
118                 Variant value;
119         };
120
121         struct UniformInfo
122         {
123                 std::string name;
124                 unsigned size;
125
126                 UniformInfo(const std::string &, unsigned);
127         };
128
129 public:
130         class Iterator
131         {
132         private:
133                 const Animation *animation;
134                 Time::TimeDelta elapsed;
135                 std::vector<Event>::const_iterator event_iter;
136                 bool end;
137
138         public:
139                 Iterator(const Animation &);
140
141                 Iterator &operator+=(const Time::TimeDelta &);
142                 void dispatch_events(AnimationEventObserver &);
143
144                 bool is_end() const { return end; }
145                 Matrix get_matrix() const;
146                 KeyFrame::AnimatedUniform get_uniform(unsigned) const;
147                 Matrix get_pose_matrix(unsigned) const;
148         };
149
150 private:
151         const Armature *armature;
152         std::vector<TimedKeyFrame> keyframes;
153         std::vector<Event> events;
154         bool looping;
155         std::vector<UniformInfo> uniforms;
156         std::vector<Curve *> curves;
157
158 public:
159         Animation();
160         ~Animation();
161
162         void set_armature(const Armature &);
163         const Armature *get_armature() const { return armature; }
164
165         unsigned get_n_uniforms() const { return uniforms.size(); }
166         unsigned get_slot_for_uniform(const std::string &) const;
167         const std::string &get_uniform_name(unsigned) const;
168
169         void add_keyframe(const Time::TimeDelta &, const KeyFrame &);
170         DEPRECATED void add_keyframe(const Time::TimeDelta &, const KeyFrame &, float);
171         DEPRECATED void add_keyframe(const Time::TimeDelta &, const KeyFrame &, float, float);
172         void add_control_keyframe(const KeyFrame &);
173 private:
174         void add_keyframe(const Time::TimeDelta &, const KeyFrame *, float, float, bool);
175         void add_keyframe(const Time::TimeDelta &, const KeyFrame *, bool, bool);
176         void prepare_keyframe(TimedKeyFrame &);
177         void create_curves();
178         template<unsigned N, typename T>
179         void create_curve(CurveTarget target, const T &);
180         static bool extract_position(const KeyFrame &, Vector3 &);
181         static bool extract_euler(const KeyFrame &, Vector3 &);
182         static bool extract_scale(const KeyFrame &, Vector3 &);
183 public:
184         void add_event(const Time::TimeDelta &, const std::string &, const Variant & = Variant());
185
186         const Msp::Time::TimeDelta &get_duration() const;
187
188         void set_looping(bool);
189 };
190
191 } // namespace GL
192 } // namespace Msp
193
194 #endif