X-Git-Url: http://git.tdb.fi/?p=libs%2Fgl.git;a=blobdiff_plain;f=source%2Fanimation.cpp;h=1e2dda900fafc0d580bf84cb648772ccf7747ac3;hp=b1d639e7c957dbffb3ce73f43256be5e0ba52c8a;hb=72a13418cc19e750abf3f8d8a52aea5e1abe4983;hpb=fa5b232a16e11d7950e80764497f0167ec9e3b41 diff --git a/source/animation.cpp b/source/animation.cpp index b1d639e7..1e2dda90 100644 --- a/source/animation.cpp +++ b/source/animation.cpp @@ -1,10 +1,10 @@ #include +#include #include #include #include "animation.h" #include "armature.h" #include "error.h" -#include "keyframe.h" #include "pose.h" using namespace std; @@ -26,6 +26,21 @@ void Animation::set_armature(const Armature &a) armature = &a; } +unsigned Animation::get_slot_for_uniform(const string &n) const +{ + for(unsigned i=0; i=uniforms.size()) + throw out_of_range("Animation::get_uniform_name"); + return uniforms[i].name; +} + void Animation::add_keyframe(const Time::TimeDelta &t, const KeyFrame &kf) { if(!keyframes.empty() && tget_uniforms(); + for(KeyFrame::UniformMap::const_iterator i=kf_uniforms.begin(); i!=kf_uniforms.end(); ++i) + { + bool found = false; + for(unsigned j=0; (!found && jfirst) + { + if(uniforms[j].size!=i->second.size) + throw invalid_operation("Animation::prepare_keyframe"); + found = true; + } + + if(!found) + uniforms.push_back(UniformInfo(i->first, i->second.size)); + } tkf.prepare(); } @@ -116,7 +145,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. */ @@ -148,8 +177,23 @@ Animation::TimedKeyFrame::TimedKeyFrame(const Animation &a): void Animation::TimedKeyFrame::prepare() { + const KeyFrame::UniformMap &kf_uniforms = keyframe->get_uniforms(); + for(KeyFrame::UniformMap::const_iterator i=kf_uniforms.begin(); i!=kf_uniforms.end(); ++i) + { + unsigned j = animation.get_slot_for_uniform(i->first); + uniforms.reserve(j+1); + for(unsigned k=uniforms.size(); k<=j; ++k) + uniforms.push_back(KeyFrame::AnimatedUniform(animation.uniforms[k].size, 0.0f)); + + uniforms[j] = i->second; + } + + if(!prev) + return; + delta_t = time-prev->time; matrix = MatrixInterpolation(prev->keyframe->get_matrix(), keyframe->get_matrix()); + if(animation.armature) { unsigned max_index = animation.armature->get_max_link_index(); @@ -167,6 +211,12 @@ void Animation::TimedKeyFrame::prepare() } +Animation::UniformInfo::UniformInfo(const string &n, unsigned s): + name(n), + size(s) +{ } + + Animation::Iterator::Iterator(const Animation &a): animation(a), iter(animation.keyframes.begin()), @@ -207,6 +257,24 @@ Matrix Animation::Iterator::get_matrix() const return iter->matrix.get(time_since_keyframe/iter->delta_t); } +KeyFrame::AnimatedUniform Animation::Iterator::get_uniform(unsigned i) const +{ + if(!iter->prev) + { + if(iter->uniforms.size()>i) + return iter->uniforms[i]; + else + return KeyFrame::AnimatedUniform(animation.uniforms[i].size, 0.0f); + } + + unsigned size = animation.uniforms[i].size; + float t = time_since_keyframe/iter->delta_t; + KeyFrame::AnimatedUniform result(size, 0.0f); + for(unsigned j=0; jprev->uniforms[i].values[j]*(1-t)+iter->uniforms[i].values[j]*t; + return result; +} + Matrix Animation::Iterator::get_pose_matrix(unsigned link) const { if(!animation.armature)