]> git.tdb.fi Git - libs/gl.git/blob - source/animation.h
83b369bfca1f1e975df889de113d9655ca77db80
[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         struct TimedKeyFrame
90         {
91                 Time::TimeDelta time;
92                 float start_slope;
93                 float end_slope;
94                 RefPtr<const KeyFrame> keyframe;
95         };
96
97         struct Event
98         {
99                 Time::TimeDelta time;
100                 std::string name;
101                 Variant value;
102         };
103
104         struct UniformInfo
105         {
106                 std::string name;
107                 unsigned size;
108
109                 UniformInfo(const std::string &, unsigned);
110         };
111
112 public:
113         class Iterator
114         {
115         private:
116                 const Animation *animation;
117                 Time::TimeDelta elapsed;
118                 std::vector<Event>::const_iterator event_iter;
119                 bool end;
120
121         public:
122                 Iterator(const Animation &);
123
124                 Iterator &operator+=(const Time::TimeDelta &);
125                 void dispatch_events(AnimationEventObserver &);
126
127                 bool is_end() const { return end; }
128                 Matrix get_matrix() const;
129                 KeyFrame::AnimatedUniform get_uniform(unsigned) const;
130                 Matrix get_pose_matrix(unsigned) const;
131         };
132
133 private:
134         const Armature *armature;
135         std::vector<TimedKeyFrame> keyframes;
136         std::vector<Event> events;
137         bool looping;
138         std::vector<UniformInfo> uniforms;
139         std::vector<Curve *> curves;
140
141 public:
142         Animation();
143         ~Animation();
144
145         void set_armature(const Armature &);
146         const Armature *get_armature() const { return armature; }
147
148         unsigned get_n_uniforms() const { return uniforms.size(); }
149         unsigned get_slot_for_uniform(const std::string &) const;
150         const std::string &get_uniform_name(unsigned) const;
151
152         void add_keyframe(const Time::TimeDelta &, const KeyFrame &);
153         void add_keyframe(const Time::TimeDelta &, const KeyFrame &, float);
154         void add_keyframe(const Time::TimeDelta &, const KeyFrame &, float, float);
155 private:
156         void add_keyframe(const Time::TimeDelta &, const RefPtr<const KeyFrame> &, float, float);
157         void prepare_keyframe(TimedKeyFrame &);
158         void create_curves();
159         template<unsigned N>
160         void create_uniform_curve(const std::string &);
161 public:
162         void add_event(const Time::TimeDelta &, const std::string &, const Variant & = Variant());
163
164         const Msp::Time::TimeDelta &get_duration() const;
165
166         void set_looping(bool);
167 };
168
169 } // namespace GL
170 } // namespace Msp
171
172 #endif