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())
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
{
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; i<n_uniforms; ++i)
- set_object_uniform(target.object, anim.animation->get_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; i<n_uniforms; ++i)
+ set_object_uniform(*target.object, anim.animation->get_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);
i->iterator += dt;
matrix *= i->iterator.get_matrix();
- unsigned n_uniforms = i->animation->get_n_uniforms();
- for(unsigned j=0; j<n_uniforms; ++j)
- set_object_uniform(target.object, i->animation->get_uniform_name(j), i->iterator.get_uniform(j));
+ if(target.object)
+ {
+ unsigned n_uniforms = i->animation->get_n_uniforms();
+ for(unsigned j=0; j<n_uniforms; ++j)
+ set_object_uniform(*target.object, i->animation->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)
for(vector<PlayingAnimation>::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);
}
}
{ }
-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<AnimationEventObserver *>::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
struct Target: AnimationEventObserver
{
- AnimatedObject &object;
+ Placeable &placeable;
+ AnimatedObject *object;
Matrix base_matrix;
const Armature *armature;
std::vector<PlayingAnimation> animations;
bool stacked;
std::vector<AnimationEventObserver *> 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<const AnimatedObject *, Target> ObjectMap;
+ typedef std::map<const Placeable *, Target> 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;