1 #include "animatedobject.h"
2 #include "animationplayer.h"
4 #include "programdata.h"
11 AnimationPlayer::Target &AnimationPlayer::get_slot(AnimatedObject &obj)
13 ObjectMap::iterator i = objects.find(&obj);
17 return objects.insert(ObjectMap::value_type(&obj, Target(obj))).first->second;
20 void AnimationPlayer::play(AnimatedObject &obj, const Animation &anim)
22 Target &target = get_slot(obj);
23 target.animations.clear();
24 target.base_matrix = Matrix();
25 target.stacked = false;
26 target.armature = anim.get_armature();
27 target.animations.push_back(PlayingAnimation(anim));
30 void AnimationPlayer::play_stacked(AnimatedObject &obj, const Animation &anim)
32 Target &target = get_slot(obj);
33 if(target.animations.empty())
34 target.base_matrix = *obj.get_matrix();
35 // TODO check for incompatible armature
36 target.stacked = true;
37 target.armature = anim.get_armature();
38 target.animations.push_back(PlayingAnimation(anim));
41 unsigned AnimationPlayer::get_n_active_animations(const AnimatedObject &obj) const
43 ObjectMap::const_iterator i = objects.find(&obj);
44 return (i!=objects.end() ? i->second.animations.size() : 0);
47 void AnimationPlayer::stop(AnimatedObject &obj)
52 void AnimationPlayer::stop(AnimatedObject &obj, const Animation &anim)
54 ObjectMap::iterator i = objects.find(&obj);
58 for(vector<PlayingAnimation>::iterator j=i->second.animations.begin(); j!=i->second.animations.end(); ++j)
59 if(j->animation==&anim)
61 i->second.animations.erase(j);
65 if(i->second.animations.empty())
69 void AnimationPlayer::tick(const Time::TimeDelta &dt)
71 for(ObjectMap::iterator i=objects.begin(); i!=objects.end(); )
74 tick_stacked(i->second, dt);
76 tick_single(i->second, dt);
78 if(i->second.animations.empty())
85 void AnimationPlayer::tick_single(Target &target, const Time::TimeDelta &dt)
87 PlayingAnimation &anim = target.animations.front();
89 target.object.set_matrix(anim.iterator.get_matrix());
91 unsigned n_uniforms = anim.animation->get_n_uniforms();
92 for(unsigned i=0; i<n_uniforms; ++i)
93 set_object_uniform(target.object, anim.animation->get_uniform_name(i), anim.iterator.get_uniform(i));
97 unsigned max_index = target.armature->get_max_link_index();
98 for(unsigned i=0; i<=max_index; ++i)
99 target.object.set_pose_matrix(i, anim.iterator.get_pose_matrix(i));
102 if(!anim.iterator.is_end())
103 target.animations.clear();
106 void AnimationPlayer::tick_stacked(Target &target, const Time::TimeDelta &dt)
108 Matrix matrix = target.base_matrix;
109 for(vector<PlayingAnimation>::iterator i=target.animations.begin(); i!=target.animations.end(); ++i)
112 matrix *= i->iterator.get_matrix();
114 unsigned n_uniforms = i->animation->get_n_uniforms();
115 for(unsigned j=0; j<n_uniforms; ++j)
116 set_object_uniform(target.object, i->animation->get_uniform_name(j), i->iterator.get_uniform(j));
118 target.object.set_matrix(matrix);
122 unsigned max_index = target.armature->get_max_link_index();
123 for(unsigned i=0; i<=max_index; ++i)
126 /* XXX This is in all likelihood incorrect. The stacking should be
127 performed on local matrices. */
128 for(vector<PlayingAnimation>::iterator j=target.animations.begin(); j!=target.animations.end(); ++j)
129 if(j->animation->get_armature())
130 matrix *= j->iterator.get_pose_matrix(i);
131 target.object.set_pose_matrix(i, matrix);
135 for(vector<PlayingAnimation>::iterator i=target.animations.begin(); i!=target.animations.end(); )
137 if(i->iterator.is_end())
138 i = target.animations.erase(i);
143 if(target.animations.empty())
144 target.stacked = false;
147 void AnimationPlayer::set_object_uniform(AnimatedObject &obj, const string &name, const KeyFrame::AnimatedUniform &uni)
149 ProgramData &shdata = obj.get_shader_data();
152 shdata.uniform(name, uni.values[0]);
154 shdata.uniform2(name, uni.values);
156 shdata.uniform3(name, uni.values);
158 shdata.uniform4(name, uni.values);
162 AnimationPlayer::Target::Target(AnimatedObject &o):
169 AnimationPlayer::PlayingAnimation::PlayingAnimation(const Animation &a):