From b1caf9df027b3cfca3909947b6041fbf80e9c277 Mon Sep 17 00:00:00 2001 From: Mikko Rasa Date: Sun, 1 Jul 2018 23:58:02 +0300 Subject: [PATCH] Support animations on Placeables Only matrix animations work for obvious reasons. --- source/animationeventobserver.h | 4 +- source/animationplayer.cpp | 87 +++++++++++++++++++++------------ source/animationplayer.h | 16 ++++-- 3 files changed, 69 insertions(+), 38 deletions(-) diff --git a/source/animationeventobserver.h b/source/animationeventobserver.h index 167b966c..1eafc4d2 100644 --- a/source/animationeventobserver.h +++ b/source/animationeventobserver.h @@ -7,7 +7,7 @@ namespace Msp { namespace GL { -class AnimatedObject; +class Placeable; class AnimationEventObserver { @@ -16,7 +16,7 @@ protected: public: virtual ~AnimationEventObserver() { } - virtual void animation_event(AnimatedObject *, const std::string &, const Variant &) { } + virtual void animation_event(Placeable *, const std::string &, const Variant &) { } }; } // namespace GL diff --git a/source/animationplayer.cpp b/source/animationplayer.cpp index 7c693ad2..13bd7af0 100644 --- a/source/animationplayer.cpp +++ b/source/animationplayer.cpp @@ -9,7 +9,7 @@ using namespace std; namespace Msp { namespace GL { -AnimationPlayer::Target &AnimationPlayer::get_slot(AnimatedObject &obj) +AnimationPlayer::Target &AnimationPlayer::get_slot(Placeable &obj) { ObjectMap::iterator i = objects.find(&obj); if(i!=objects.end()) @@ -18,25 +18,43 @@ AnimationPlayer::Target &AnimationPlayer::get_slot(AnimatedObject &obj) return objects.insert(ObjectMap::value_type(&obj, Target(obj))).first->second; } -void AnimationPlayer::play(AnimatedObject &obj, const Animation &anim) +AnimationPlayer::Target &AnimationPlayer::play_(Placeable &obj, const Animation &anim, bool stacked) { Target &target = get_slot(obj); - target.animations.clear(); - target.base_matrix = Matrix(); - target.stacked = false; + if(!stacked) + { + target.animations.clear(); + target.base_matrix = Matrix(); + } + else if(target.animations.empty()) + target.base_matrix = *obj.get_matrix(); + target.stacked = stacked; + // TODO check for incompatible armature target.armature = anim.get_armature(); target.animations.push_back(PlayingAnimation(anim)); + return target; +} + +void AnimationPlayer::play(AnimatedObject &obj, const Animation &anim) +{ + Target &target = play_(obj, anim, false); + target.object = &obj; +} + +void AnimationPlayer::play(Placeable &obj, const Animation &anim) +{ + play_(obj, anim, false); } void AnimationPlayer::play_stacked(AnimatedObject &obj, const Animation &anim) { - Target &target = get_slot(obj); - if(target.animations.empty()) - target.base_matrix = *obj.get_matrix(); - // TODO check for incompatible armature - target.stacked = true; - target.armature = anim.get_armature(); - target.animations.push_back(PlayingAnimation(anim)); + Target &target = play_(obj, anim, true); + target.object = &obj; +} + +void AnimationPlayer::play_stacked(Placeable &obj, const Animation &anim) +{ + play_(obj, anim, true); } unsigned AnimationPlayer::get_n_active_animations(const AnimatedObject &obj) const @@ -115,17 +133,20 @@ void AnimationPlayer::tick_single(Target &target, const Time::TimeDelta &dt) { PlayingAnimation &anim = target.animations.front(); anim.iterator += dt; - target.object.set_matrix(anim.iterator.get_matrix()); - - unsigned n_uniforms = anim.animation->get_n_uniforms(); - for(unsigned i=0; iget_uniform_name(i), anim.iterator.get_uniform(i)); + target.placeable.set_matrix(anim.iterator.get_matrix()); - if(target.armature) + if(target.object) { - unsigned max_index = target.armature->get_max_link_index(); - for(unsigned i=0; i<=max_index; ++i) - target.object.set_pose_matrix(i, anim.iterator.get_pose_matrix(i)); + unsigned n_uniforms = anim.animation->get_n_uniforms(); + for(unsigned i=0; iget_uniform_name(i), anim.iterator.get_uniform(i)); + + if(target.armature) + { + unsigned max_index = target.armature->get_max_link_index(); + for(unsigned i=0; i<=max_index; ++i) + target.object->set_pose_matrix(i, anim.iterator.get_pose_matrix(i)); + } } anim.iterator.dispatch_events(target); @@ -142,13 +163,16 @@ void AnimationPlayer::tick_stacked(Target &target, const Time::TimeDelta &dt) i->iterator += dt; matrix *= i->iterator.get_matrix(); - unsigned n_uniforms = i->animation->get_n_uniforms(); - for(unsigned j=0; janimation->get_uniform_name(j), i->iterator.get_uniform(j)); + if(target.object) + { + unsigned n_uniforms = i->animation->get_n_uniforms(); + for(unsigned j=0; janimation->get_uniform_name(j), i->iterator.get_uniform(j)); + } } - target.object.set_matrix(matrix); + target.placeable.set_matrix(matrix); - if(target.armature) + if(target.object && target.armature) { unsigned max_index = target.armature->get_max_link_index(); for(unsigned i=0; i<=max_index; ++i) @@ -159,7 +183,7 @@ void AnimationPlayer::tick_stacked(Target &target, const Time::TimeDelta &dt) for(vector::iterator j=target.animations.begin(); j!=target.animations.end(); ++j) if(j->animation->get_armature()) matrix *= j->iterator.get_pose_matrix(i); - target.object.set_pose_matrix(i, matrix); + target.object->set_pose_matrix(i, matrix); } } @@ -198,16 +222,17 @@ AnimationPlayer::PlayingAnimation::PlayingAnimation(const Animation &a): { } -AnimationPlayer::Target::Target(AnimatedObject &o): - object(o), +AnimationPlayer::Target::Target(Placeable &p): + placeable(p), + object(0), armature(0), stacked(false) { } -void AnimationPlayer::Target::animation_event(AnimatedObject *, const string &name, const Variant &value) +void AnimationPlayer::Target::animation_event(Placeable *, const string &name, const Variant &value) { for(vector::const_iterator i=event_observers.begin(); i!=event_observers.end(); ++i) - (*i)->animation_event(&object, name, value); + (*i)->animation_event(&placeable, name, value); } } // namespace GL diff --git a/source/animationplayer.h b/source/animationplayer.h index 4c6e9cec..4158627d 100644 --- a/source/animationplayer.h +++ b/source/animationplayer.h @@ -28,33 +28,39 @@ private: struct Target: AnimationEventObserver { - AnimatedObject &object; + Placeable &placeable; + AnimatedObject *object; Matrix base_matrix; const Armature *armature; std::vector animations; bool stacked; std::vector event_observers; - Target(AnimatedObject &); + Target(Placeable &); - virtual void animation_event(AnimatedObject *, const std::string &, const Variant &); + virtual void animation_event(Placeable *, const std::string &, const Variant &); }; - typedef std::map ObjectMap; + typedef std::map ObjectMap; ObjectMap objects; private: - Target &get_slot(AnimatedObject &); + Target &get_slot(Placeable &); + Target &play_(Placeable &, const Animation &, bool); public: /// Plays an animation on an object. Any previous animations are replaced. void play(AnimatedObject &, const Animation &); + void play(Placeable &, const Animation &); + /** Plays an animation, stacked with other animations. If no animations are playing yet, the object's current matrix is used as the base. */ void play_stacked(AnimatedObject &, const Animation &); + void play_stacked(Placeable &, const Animation &); + /// Returns the number of animations currently affecting an object. unsigned get_n_active_animations(const AnimatedObject &) const; -- 2.43.0