1 #include <msp/core/algorithm.h>
2 #include "animatedobject.h"
3 #include "animationplayer.h"
5 #include "programdata.h"
12 AnimationPlayer::Target &AnimationPlayer::get_slot(AnimatedObject &obj)
14 ObjectMap::iterator i = objects.find(&obj);
18 return objects.insert(ObjectMap::value_type(&obj, Target(obj))).first->second;
21 void AnimationPlayer::play(AnimatedObject &obj, const Animation &anim)
23 Target &target = get_slot(obj);
24 target.animations.clear();
25 target.base_matrix = Matrix();
26 target.stacked = false;
27 target.armature = anim.get_armature();
28 target.animations.push_back(PlayingAnimation(anim));
31 void AnimationPlayer::play_stacked(AnimatedObject &obj, const Animation &anim)
33 Target &target = get_slot(obj);
34 if(target.animations.empty())
35 target.base_matrix = *obj.get_matrix();
36 // TODO check for incompatible armature
37 target.stacked = true;
38 target.armature = anim.get_armature();
39 target.animations.push_back(PlayingAnimation(anim));
42 unsigned AnimationPlayer::get_n_active_animations(const AnimatedObject &obj) const
44 ObjectMap::const_iterator i = objects.find(&obj);
45 return (i!=objects.end() ? i->second.animations.size() : 0);
48 void AnimationPlayer::observe_events(AnimatedObject &obj, AnimationEventObserver &observer)
50 Target &target = get_slot(obj);
51 if(find(target.event_observers, &observer)==target.event_observers.end())
52 target.event_observers.push_back(&observer);
55 void AnimationPlayer::unobserve_events(AnimatedObject &obj, AnimationEventObserver &observer)
57 ObjectMap::iterator i = objects.find(&obj);
61 vector<AnimationEventObserver *>::iterator j = find(i->second.event_observers, &observer);
62 if(j!=i->second.event_observers.end())
63 i->second.event_observers.erase(j);
66 void AnimationPlayer::unobserve_events(AnimationEventObserver &observer)
68 for(ObjectMap::iterator i=objects.begin(); i!=objects.end(); ++i)
70 vector<AnimationEventObserver *>::iterator j = find(i->second.event_observers, &observer);
71 if(j!=i->second.event_observers.end())
72 i->second.event_observers.erase(j);
76 void AnimationPlayer::stop(AnimatedObject &obj)
81 void AnimationPlayer::stop(AnimatedObject &obj, const Animation &anim)
83 ObjectMap::iterator i = objects.find(&obj);
87 for(vector<PlayingAnimation>::iterator j=i->second.animations.begin(); j!=i->second.animations.end(); ++j)
88 if(j->animation==&anim)
90 i->second.animations.erase(j);
94 if(i->second.animations.empty())
98 void AnimationPlayer::tick(const Time::TimeDelta &dt)
100 for(ObjectMap::iterator i=objects.begin(); i!=objects.end(); )
102 if(i->second.stacked)
103 tick_stacked(i->second, dt);
104 else if(!i->second.animations.empty())
105 tick_single(i->second, dt);
107 if(i->second.animations.empty() && i->second.event_observers.empty())
114 void AnimationPlayer::tick_single(Target &target, const Time::TimeDelta &dt)
116 PlayingAnimation &anim = target.animations.front();
118 target.object.set_matrix(anim.iterator.get_matrix());
120 unsigned n_uniforms = anim.animation->get_n_uniforms();
121 for(unsigned i=0; i<n_uniforms; ++i)
122 set_object_uniform(target.object, anim.animation->get_uniform_name(i), anim.iterator.get_uniform(i));
126 unsigned max_index = target.armature->get_max_link_index();
127 for(unsigned i=0; i<=max_index; ++i)
128 target.object.set_pose_matrix(i, anim.iterator.get_pose_matrix(i));
131 anim.iterator.dispatch_events(target);
133 if(anim.iterator.is_end())
134 target.animations.clear();
137 void AnimationPlayer::tick_stacked(Target &target, const Time::TimeDelta &dt)
139 Matrix matrix = target.base_matrix;
140 for(vector<PlayingAnimation>::iterator i=target.animations.begin(); i!=target.animations.end(); ++i)
143 matrix *= i->iterator.get_matrix();
145 unsigned n_uniforms = i->animation->get_n_uniforms();
146 for(unsigned j=0; j<n_uniforms; ++j)
147 set_object_uniform(target.object, i->animation->get_uniform_name(j), i->iterator.get_uniform(j));
149 target.object.set_matrix(matrix);
153 unsigned max_index = target.armature->get_max_link_index();
154 for(unsigned i=0; i<=max_index; ++i)
157 /* XXX This is in all likelihood incorrect. The stacking should be
158 performed on local matrices. */
159 for(vector<PlayingAnimation>::iterator j=target.animations.begin(); j!=target.animations.end(); ++j)
160 if(j->animation->get_armature())
161 matrix *= j->iterator.get_pose_matrix(i);
162 target.object.set_pose_matrix(i, matrix);
166 for(vector<PlayingAnimation>::iterator i=target.animations.begin(); i!=target.animations.end(); )
168 i->iterator.dispatch_events(target);
170 if(i->iterator.is_end())
171 i = target.animations.erase(i);
176 if(target.animations.empty())
177 target.stacked = false;
180 void AnimationPlayer::set_object_uniform(AnimatedObject &obj, const string &name, const KeyFrame::AnimatedUniform &uni)
182 ProgramData &shdata = obj.get_shader_data();
185 shdata.uniform(name, uni.values[0]);
187 shdata.uniform2(name, uni.values);
189 shdata.uniform3(name, uni.values);
191 shdata.uniform4(name, uni.values);
195 AnimationPlayer::PlayingAnimation::PlayingAnimation(const Animation &a):
201 AnimationPlayer::Target::Target(AnimatedObject &o):
207 void AnimationPlayer::Target::animation_event(AnimatedObject *, const string &name, const Variant &value)
209 for(vector<AnimationEventObserver *>::const_iterator i=event_observers.begin(); i!=event_observers.end(); ++i)
210 (*i)->animation_event(&object, name, value);