X-Git-Url: http://git.tdb.fi/?a=blobdiff_plain;ds=sidebyside;f=source%2Fanimation%2Fanimation.h;fp=source%2Fanimation%2Fanimation.h;h=6845d23ee3e1652c9f7e49a86e5145f3faa6aa52;hb=7aaec9a70b8d7733429bec043f8e33e02956f266;hp=0000000000000000000000000000000000000000;hpb=bec07999d95b76f4b47cffcc564d0cd0afc0435e;p=libs%2Fgl.git diff --git a/source/animation/animation.h b/source/animation/animation.h new file mode 100644 index 00000000..6845d23e --- /dev/null +++ b/source/animation/animation.h @@ -0,0 +1,213 @@ +#ifndef MSP_GL_ANIMATION_H_ +#define MSP_GL_ANIMATION_H_ + +#include +#include +#include +#include +#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 + { + 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 + class ValueCurve: public Curve + { + public: + typedef typename Interpolate::SplineKnot Knot; + + private: + Interpolate::Spline spline; + + public: + ValueCurve(CurveTarget, int, const std::vector &); + + 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 + struct ExtractUniform + { + const std::string &name; + + ExtractUniform(const std::string &n): name(n) { } + + bool operator()(const KeyFrame &, typename Interpolate::SplineValue::Type &) const; + }; + + struct TimedKeyFrame + { + Time::TimeDelta time; + RefPtr 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::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 keyframes; + std::vector events; + bool looping; + std::vector uniforms; + std::vector 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 + 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