X-Git-Url: http://git.tdb.fi/?p=libs%2Fgl.git;a=blobdiff_plain;f=source%2Fanimation.cpp;h=2f78d1eafad574b4d1c060a8209d0527309cc393;hp=8f7dea03bd90e8c8513c5e2ac77379699072ed16;hb=89a1ada18430079896cfb28862e61bb32d66b8a0;hpb=3f7c493e13b7108098539078b729cffc095c304b diff --git a/source/animation.cpp b/source/animation.cpp index 8f7dea03..2f78d1ea 100644 --- a/source/animation.cpp +++ b/source/animation.cpp @@ -42,16 +42,33 @@ const string &Animation::get_uniform_name(unsigned i) const } void Animation::add_keyframe(const Time::TimeDelta &t, const KeyFrame &kf) +{ + RefPtr kfr(&kf); + kfr.keep(); + add_keyframe(t, kfr); +} + +void Animation::add_keyframe(const Time::TimeDelta &t, const RefPtr &kf) { if(!keyframes.empty() && t=keyframes.capacity()); + + keyframes.push_back(TimedKeyFrame()); + TimedKeyFrame &tkf = keyframes.back(); tkf.time = t; - tkf.keyframe = &kf; - tkf.keyframe.keep(); + tkf.keyframe = kf; + + if(realloc) + { + for(unsigned i=1; i1) + tkf.prev = &tkf-1; + prepare_keyframe(tkf); - keyframes.push_back(tkf); } void Animation::set_looping(bool l) @@ -61,8 +78,6 @@ void Animation::set_looping(bool l) void Animation::prepare_keyframe(TimedKeyFrame &tkf) { - tkf.prev = (keyframes.empty() ? 0 : &keyframes.back()); - const KeyFrame::UniformMap &kf_uniforms = tkf.keyframe->get_uniforms(); for(KeyFrame::UniformMap::const_iterator i=kf_uniforms.begin(); i!=kf_uniforms.end(); ++i) { @@ -79,7 +94,7 @@ void Animation::prepare_keyframe(TimedKeyFrame &tkf) uniforms.push_back(UniformInfo(i->first, i->second.size)); } - tkf.prepare(); + tkf.prepare(*this); } @@ -145,7 +160,7 @@ Matrix Animation::MatrixInterpolation::get(float t) const will be in the range [-1, 1]. */ float w = (axes[i].slope+(1-axes[i].slope)*u*u)*u*0.5f+0.5f; - /* The interpolate vectors will also be shorter than unit length. At + /* The interpolated vectors will also be shorter than unit length. At the halfway point the length will be equal to the cosine of half the angle, which was computed earlier. Use a second degree polynomial to approximate. */ @@ -170,12 +185,11 @@ Matrix Animation::MatrixInterpolation::get(float t) const } -Animation::TimedKeyFrame::TimedKeyFrame(const Animation &a): - animation(a), +Animation::TimedKeyFrame::TimedKeyFrame(): prev(0) { } -void Animation::TimedKeyFrame::prepare() +void Animation::TimedKeyFrame::prepare(const Animation &animation) { const KeyFrame::UniformMap &kf_uniforms = keyframe->get_uniforms(); for(KeyFrame::UniformMap::const_iterator i=kf_uniforms.begin(); i!=kf_uniforms.end(); ++i) @@ -218,8 +232,8 @@ Animation::UniformInfo::UniformInfo(const string &n, unsigned s): Animation::Iterator::Iterator(const Animation &a): - animation(a), - iter(animation.keyframes.begin()), + animation(&a), + iter(animation->keyframes.begin()), end(false) { } @@ -228,12 +242,12 @@ Animation::Iterator &Animation::Iterator::operator+=(const Time::TimeDelta &t) time_since_keyframe += t; while(time_since_keyframe>iter->delta_t) { - KeyFrameList::const_iterator next = iter; + vector::const_iterator next = iter; ++next; - if(next==animation.keyframes.end()) + if(next==animation->keyframes.end()) { - if(animation.looping) - next = animation.keyframes.begin(); + if(animation->looping) + next = animation->keyframes.begin(); else { end = true; @@ -264,10 +278,10 @@ KeyFrame::AnimatedUniform Animation::Iterator::get_uniform(unsigned i) const if(iter->uniforms.size()>i) return iter->uniforms[i]; else - return KeyFrame::AnimatedUniform(animation.uniforms[i].size, 0.0f); + return KeyFrame::AnimatedUniform(animation->uniforms[i].size, 0.0f); } - unsigned size = animation.uniforms[i].size; + unsigned size = animation->uniforms[i].size; float t = time_since_keyframe/iter->delta_t; KeyFrame::AnimatedUniform result(size, 0.0f); for(unsigned j=0; jarmature) throw invalid_operation("Animation::Iterator::get_pose_matrix"); - if(link>animation.armature->get_max_link_index()) + if(link>animation->armature->get_max_link_index()) throw out_of_range("Animation::Iterator::get_pose_matrix"); if(!iter->prev) @@ -293,7 +307,7 @@ Matrix Animation::Iterator::get_pose_matrix(unsigned link) const // We must redo the base point correction since interpolation throws if off // XXX This should probably be done on local matrices Matrix result = iter->pose_matrices[link].get(time_since_keyframe/iter->delta_t); - const Vector3 &base = animation.armature->get_link(link).get_base(); + const Vector3 &base = animation->armature->get_link(link).get_base(); Vector3 new_base = result*base; result = Matrix::translation(base-new_base)*result; return result; @@ -334,11 +348,7 @@ void Animation::Loader::keyframe_inline() else load_sub(*kf); - TimedKeyFrame tkf(obj); - tkf.time = current_time; - tkf.keyframe = kf; - obj.prepare_keyframe(tkf); - obj.keyframes.push_back(tkf); + obj.add_keyframe(current_time, kf); } void Animation::Loader::interval(float t)