]> git.tdb.fi Git - libs/gl.git/blobdiff - source/animation/animation.h
Rearrange soucre files into subdirectories
[libs/gl.git] / source / animation / animation.h
diff --git a/source/animation/animation.h b/source/animation/animation.h
new file mode 100644 (file)
index 0000000..6845d23
--- /dev/null
@@ -0,0 +1,213 @@
+#ifndef MSP_GL_ANIMATION_H_
+#define MSP_GL_ANIMATION_H_
+
+#include <msp/core/refptr.h>
+#include <msp/datafile/objectloader.h>
+#include <msp/interpolate/spline.h>
+#include <msp/time/timedelta.h>
+#include "keyframe.h"
+
+namespace Msp {
+namespace GL {
+
+class AnimationEventObserver;
+class Armature;
+class Matrix;
+class Pose;
+
+/**
+An Animation is a sequence of KeyFrames combined with timing information.  The
+state at any point in the animation can be interpolated from the keyframes.
+*/
+class Animation
+{
+public:
+       class Loader: public DataFile::CollectionObjectLoader<Animation>
+       {
+       private:
+               Time::TimeDelta current_time;
+               float start_slope;
+               float end_slope;
+               int slopes_set;
+
+       public:
+               Loader(Animation &);
+               Loader(Animation &, Collection &);
+       private:
+               void init();
+               virtual void finish();
+
+               void check_slopes_and_control(bool, bool);
+               void add_kf(const KeyFrame *, bool, bool);
+               void load_kf(const std::string &, bool);
+               void load_kf_inline(bool);
+
+               void control_keyframe(const std::string &);
+               void control_keyframe_inline();
+               void event(const std::string &);
+               void event1i(const std::string &, int);
+               void event1f(const std::string &, float);
+               void event2f(const std::string &, float, float);
+               void event3f(const std::string &, float, float, float);
+               void event4f(const std::string &, float, float, float, float);
+               void interval(float);
+               void keyframe(const std::string &);
+               void keyframe_inline();
+               void slopes(float, float);
+       };
+
+private:
+       enum CurveTarget
+       {
+               POSITION,
+               EULER,
+               SCALE,
+               UNIFORM
+       };
+
+       class Curve
+       {
+       protected:
+               CurveTarget target;
+               int component;
+
+               Curve(CurveTarget, int);
+       public:
+               virtual ~Curve() { }
+
+               virtual void apply(float, Matrix &) const = 0;
+               virtual void apply(float, KeyFrame::AnimatedUniform &) const = 0;
+       };
+
+       template<unsigned N>
+       class ValueCurve: public Curve
+       {
+       public:
+               typedef typename Interpolate::SplineKnot<double, N> Knot;
+
+       private:
+               Interpolate::Spline<double, 3, N> spline;
+
+       public:
+               ValueCurve(CurveTarget, int, const std::vector<Knot> &);
+
+               virtual void apply(float, Matrix &) const;
+               virtual void apply(float, KeyFrame::AnimatedUniform &) const;
+       };
+
+       struct ExtractComponent
+       {
+               typedef bool (*Extract)(const KeyFrame &, Vector3 &);
+
+               Extract extract;
+               unsigned index;
+               Transform::ComponentMask mask;
+
+               ExtractComponent(Extract e, unsigned i, Transform::ComponentMask m): extract(e), index(i), mask(m) { }
+
+               bool operator()(const KeyFrame &, float &) const;
+       };
+
+       template<unsigned N>
+       struct ExtractUniform
+       {
+               const std::string &name;
+
+               ExtractUniform(const std::string &n): name(n) { }
+
+               bool operator()(const KeyFrame &, typename Interpolate::SplineValue<float, N>::Type &) const;
+       };
+
+       struct TimedKeyFrame
+       {
+               Time::TimeDelta time;
+               RefPtr<const KeyFrame> keyframe;
+               bool control;
+       };
+
+       struct Event
+       {
+               Time::TimeDelta time;
+               std::string name;
+               Variant value;
+       };
+
+       struct UniformInfo
+       {
+               std::string name;
+               unsigned size;
+
+               UniformInfo(const std::string &, unsigned);
+       };
+
+public:
+       class Iterator
+       {
+       private:
+               const Animation *animation;
+               Time::TimeDelta elapsed;
+               std::vector<Event>::const_iterator event_iter;
+               bool end;
+
+       public:
+               Iterator(const Animation &);
+
+               Iterator &operator+=(const Time::TimeDelta &);
+               void dispatch_events(AnimationEventObserver &);
+
+               bool is_end() const { return end; }
+               Matrix get_matrix() const;
+               KeyFrame::AnimatedUniform get_uniform(unsigned) const;
+               Matrix get_pose_matrix(unsigned) const;
+       };
+
+private:
+       const Armature *armature;
+       std::vector<TimedKeyFrame> keyframes;
+       std::vector<Event> events;
+       bool looping;
+       std::vector<UniformInfo> uniforms;
+       std::vector<Curve *> curves;
+       unsigned uniform_curve_offset;
+
+public:
+       Animation();
+       ~Animation();
+
+       void set_armature(const Armature &);
+       const Armature *get_armature() const { return armature; }
+
+       unsigned get_n_uniforms() const { return uniforms.size(); }
+       unsigned get_slot_for_uniform(const std::string &) const;
+       const std::string &get_uniform_name(unsigned) const;
+
+       void add_keyframe(const Time::TimeDelta &, const KeyFrame &);
+       void add_keyframe_owned(const Time::TimeDelta &, const KeyFrame *);
+       DEPRECATED void add_keyframe(const Time::TimeDelta &, const KeyFrame &, float);
+       DEPRECATED void add_keyframe(const Time::TimeDelta &, const KeyFrame &, float, float);
+       void add_control_keyframe(const KeyFrame &);
+       void add_control_keyframe_owned(const KeyFrame *);
+private:
+       void add_keyframe(const Time::TimeDelta &, const KeyFrame *, float, float, bool);
+       void add_keyframe(const Time::TimeDelta &, const KeyFrame *, bool, bool);
+       void prepare_keyframe(TimedKeyFrame &);
+       void create_curves();
+       void create_curve(CurveTarget, Transform::ComponentMask, ExtractComponent::Extract);
+       template<unsigned N, typename T>
+       void create_curve(CurveTarget target, int, const T &);
+       static bool extract_position(const KeyFrame &, Vector3 &);
+       static bool extract_euler(const KeyFrame &, Vector3 &);
+       static bool extract_scale(const KeyFrame &, Vector3 &);
+public:
+       void add_event(const Time::TimeDelta &, const std::string &, const Variant & = Variant());
+
+       const Msp::Time::TimeDelta &get_duration() const;
+
+       void set_looping(bool);
+       bool is_looping() const { return looping; }
+};
+
+} // namespace GL
+} // namespace Msp
+
+#endif