1 #include <msp/core/algorithm.h>
2 #include "animatedobject.h"
3 #include "animationplayer.h"
5 #include "programdata.h"
12 AnimationPlayer::Target &AnimationPlayer::get_slot(Placeable &obj)
14 auto i = objects.find(&obj);
18 return objects.insert(make_pair(&obj, Target(obj))).first->second;
21 AnimationPlayer::Target &AnimationPlayer::play_(Placeable &obj, const Animation &anim, bool stacked, float speed)
23 Target &target = get_slot(obj);
26 target.animations.clear();
27 target.base_matrix = Matrix();
29 else if(target.animations.empty())
30 target.base_matrix = *obj.get_matrix();
31 target.stacked = stacked;
32 // TODO check for incompatible armature
33 target.armature = anim.get_armature();
34 target.animations.push_back(PlayingAnimation(anim, speed));
38 void AnimationPlayer::play(AnimatedObject &obj, const Animation &anim, float speed)
40 Target &target = play_(obj, anim, false, speed);
44 void AnimationPlayer::play(Placeable &obj, const Animation &anim, float speed)
46 play_(obj, anim, false, speed);
49 void AnimationPlayer::play_stacked(AnimatedObject &obj, const Animation &anim, float speed)
51 Target &target = play_(obj, anim, true, speed);
55 void AnimationPlayer::play_stacked(Placeable &obj, const Animation &anim, float speed)
57 play_(obj, anim, true, speed);
60 unsigned AnimationPlayer::get_n_active_animations(const AnimatedObject &obj) const
62 auto i = objects.find(&obj);
63 return (i!=objects.end() ? i->second.animations.size() : 0);
66 void AnimationPlayer::observe_events(AnimatedObject &obj, AnimationEventObserver &observer)
68 Target &target = get_slot(obj);
69 if(find(target.event_observers, &observer)==target.event_observers.end())
70 target.event_observers.push_back(&observer);
73 void AnimationPlayer::unobserve_events(AnimatedObject &obj, AnimationEventObserver &observer)
75 auto i = objects.find(&obj);
79 auto j = find(i->second.event_observers, &observer);
80 if(j!=i->second.event_observers.end())
81 i->second.event_observers.erase(j);
84 void AnimationPlayer::unobserve_events(AnimationEventObserver &observer)
86 for(auto &kvp: objects)
88 auto j = find(kvp.second.event_observers, &observer);
89 if(j!=kvp.second.event_observers.end())
90 kvp.second.event_observers.erase(j);
94 void AnimationPlayer::stop(Placeable &obj)
99 void AnimationPlayer::stop(Placeable &obj, const Animation &anim)
101 auto i = objects.find(&obj);
105 auto j = find_member(i->second.animations, &anim, &PlayingAnimation::animation);
106 if(j!=i->second.animations.end())
107 i->second.animations.erase(j);
109 if(i->second.animations.empty())
113 void AnimationPlayer::tick(const Time::TimeDelta &dt)
115 for(auto i=objects.begin(); i!=objects.end(); )
117 if(i->second.stacked)
118 tick_stacked(i->second, dt);
119 else if(!i->second.animations.empty())
120 tick_single(i->second, dt);
122 if(i->second.animations.empty() && i->second.event_observers.empty())
129 void AnimationPlayer::tick_single(Target &target, const Time::TimeDelta &dt)
131 PlayingAnimation &anim = target.animations.front();
132 anim.iterator += dt*anim.speed;
133 target.placeable.set_matrix(anim.iterator.get_matrix());
137 unsigned n_uniforms = anim.animation->get_n_uniforms();
138 for(unsigned i=0; i<n_uniforms; ++i)
139 set_object_uniform(*target.object, anim.animation->get_uniform_name(i), anim.iterator.get_uniform(i));
143 unsigned max_index = target.armature->get_max_link_index();
144 for(unsigned i=0; i<=max_index; ++i)
145 target.object->set_pose_matrix(i, anim.iterator.get_pose_matrix(i));
149 anim.iterator.dispatch_events(target);
151 if(anim.iterator.is_end())
152 target.animations.clear();
155 void AnimationPlayer::tick_stacked(Target &target, const Time::TimeDelta &dt)
157 Matrix matrix = target.base_matrix;
158 for(PlayingAnimation &a: target.animations)
160 a.iterator += dt*a.speed;
161 matrix *= a.iterator.get_matrix();
165 unsigned n_uniforms = a.animation->get_n_uniforms();
166 for(unsigned j=0; j<n_uniforms; ++j)
167 set_object_uniform(*target.object, a.animation->get_uniform_name(j), a.iterator.get_uniform(j));
170 target.placeable.set_matrix(matrix);
172 if(target.object && target.armature)
174 unsigned max_index = target.armature->get_max_link_index();
175 for(unsigned i=0; i<=max_index; ++i)
178 /* XXX This is in all likelihood incorrect. The stacking should be
179 performed on local matrices. */
180 for(const PlayingAnimation &a: target.animations)
181 if(a.animation->get_armature())
182 matrix *= a.iterator.get_pose_matrix(i);
183 target.object->set_pose_matrix(i, matrix);
187 for(auto i=target.animations.begin(); i!=target.animations.end(); )
189 i->iterator.dispatch_events(target);
191 if(i->iterator.is_end())
192 i = target.animations.erase(i);
197 if(target.animations.empty())
198 target.stacked = false;
201 void AnimationPlayer::set_object_uniform(AnimatedObject &obj, const string &name, const KeyFrame::AnimatedUniform &uni)
203 ProgramData &shdata = obj.get_shader_data();
206 shdata.uniform(name, uni.values[0]);
208 shdata.uniform2(name, uni.values);
210 shdata.uniform3(name, uni.values);
212 shdata.uniform4(name, uni.values);
216 AnimationPlayer::PlayingAnimation::PlayingAnimation(const Animation &a, float s):
223 AnimationPlayer::Target::Target(Placeable &p):
230 void AnimationPlayer::Target::animation_event(Placeable *, const string &name, const Variant &value)
232 for(AnimationEventObserver *o: event_observers)
233 o->animation_event(&placeable, name, value);