]> git.tdb.fi Git - libs/gl.git/blob - source/animation.h
Make animation curve creation more generic
[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
32         public:
33                 Loader(Animation &);
34                 Loader(Animation &, Collection &);
35         private:
36                 void init();
37                 virtual void finish();
38
39                 void event(const std::string &);
40                 void event1i(const std::string &, int);
41                 void event1f(const std::string &, float);
42                 void event2f(const std::string &, float, float);
43                 void event3f(const std::string &, float, float, float);
44                 void event4f(const std::string &, float, float, float, float);
45                 void interval(float);
46                 void keyframe(const std::string &);
47                 void keyframe_inline();
48                 void slopes(float, float);
49         };
50
51 private:
52         enum CurveTarget
53         {
54                 POSITION,
55                 EULER,
56                 SCALE,
57                 UNIFORM
58         };
59
60         class Curve
61         {
62         protected:
63                 CurveTarget target;
64
65                 Curve(CurveTarget);
66         public:
67                 virtual ~Curve() { }
68
69                 virtual void apply(float, Matrix &) const = 0;
70                 virtual void apply(float, KeyFrame::AnimatedUniform &) const = 0;
71         };
72
73         template<unsigned N>
74         class ValueCurve: public Curve
75         {
76         public:
77                 typedef typename Interpolate::SplineKnot<float, N> Knot;
78
79         private:
80                 Interpolate::Spline<float, 1, N> spline;
81
82         public:
83                 ValueCurve(CurveTarget, const std::vector<Knot> &);
84
85                 virtual void apply(float, Matrix &) const;
86                 virtual void apply(float, KeyFrame::AnimatedUniform &) const;
87         };
88
89         template<unsigned N>
90         struct ExtractUniform
91         {
92                 const std::string &name;
93
94                 ExtractUniform(const std::string &n): name(n) { }
95
96                 bool operator()(const KeyFrame &, typename Interpolate::SplineValue<float, N>::Type &) const;
97         };
98
99         struct TimedKeyFrame
100         {
101                 Time::TimeDelta time;
102                 float start_slope;
103                 float end_slope;
104                 RefPtr<const KeyFrame> keyframe;
105         };
106
107         struct Event
108         {
109                 Time::TimeDelta time;
110                 std::string name;
111                 Variant value;
112         };
113
114         struct UniformInfo
115         {
116                 std::string name;
117                 unsigned size;
118
119                 UniformInfo(const std::string &, unsigned);
120         };
121
122 public:
123         class Iterator
124         {
125         private:
126                 const Animation *animation;
127                 Time::TimeDelta elapsed;
128                 std::vector<Event>::const_iterator event_iter;
129                 bool end;
130
131         public:
132                 Iterator(const Animation &);
133
134                 Iterator &operator+=(const Time::TimeDelta &);
135                 void dispatch_events(AnimationEventObserver &);
136
137                 bool is_end() const { return end; }
138                 Matrix get_matrix() const;
139                 KeyFrame::AnimatedUniform get_uniform(unsigned) const;
140                 Matrix get_pose_matrix(unsigned) const;
141         };
142
143 private:
144         const Armature *armature;
145         std::vector<TimedKeyFrame> keyframes;
146         std::vector<Event> events;
147         bool looping;
148         std::vector<UniformInfo> uniforms;
149         std::vector<Curve *> curves;
150
151 public:
152         Animation();
153         ~Animation();
154
155         void set_armature(const Armature &);
156         const Armature *get_armature() const { return armature; }
157
158         unsigned get_n_uniforms() const { return uniforms.size(); }
159         unsigned get_slot_for_uniform(const std::string &) const;
160         const std::string &get_uniform_name(unsigned) const;
161
162         void add_keyframe(const Time::TimeDelta &, const KeyFrame &);
163         void add_keyframe(const Time::TimeDelta &, const KeyFrame &, float);
164         void add_keyframe(const Time::TimeDelta &, const KeyFrame &, float, float);
165 private:
166         void add_keyframe(const Time::TimeDelta &, const RefPtr<const KeyFrame> &, float, float);
167         void prepare_keyframe(TimedKeyFrame &);
168         void create_curves();
169         template<unsigned N, typename T>
170         void create_curve(CurveTarget target, const T &);
171         static bool extract_position(const KeyFrame &, Vector3 &);
172         static bool extract_euler(const KeyFrame &, Vector3 &);
173         static bool extract_scale(const KeyFrame &, Vector3 &);
174 public:
175         void add_event(const Time::TimeDelta &, const std::string &, const Variant & = Variant());
176
177         const Msp::Time::TimeDelta &get_duration() const;
178
179         void set_looping(bool);
180 };
181
182 } // namespace GL
183 } // namespace Msp
184
185 #endif