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