From: Mikko Rasa Date: Mon, 13 Aug 2012 12:25:54 +0000 (+0300) Subject: Fix several bugs in the animation system X-Git-Url: http://git.tdb.fi/?a=commitdiff_plain;h=164d77011ab4ebe76c9bf2b7ed8d8dd8ebc20e61;p=libs%2Fgl.git Fix several bugs in the animation system Make the identity fallback matrix static so the pointers in interpolations stay valid. Don't crash when getting pose matrices from the first keyframe. Matrix multiplication order for base point shift compensation was wrong. Re-compensate for base point shift after interpolation. Use correct comparison operator for max_index in AnimationPlayer. Pass collection to keyframe loader to make loading poses possible. Use Pose::set_armature rather than loading the pointer directly to get the matrix array resized. --- diff --git a/source/animation.cpp b/source/animation.cpp index e7174adc..efb67c97 100644 --- a/source/animation.cpp +++ b/source/animation.cpp @@ -46,7 +46,6 @@ void Animation::prepare_keyframe(TimedKeyFrame &tkf) return; tkf.prepare(); - } @@ -153,7 +152,7 @@ void Animation::TimedKeyFrame::prepare() pose_matrices.resize(max_index+1); const Pose *pose1 = prev->keyframe->get_pose(); const Pose *pose2 = keyframe->get_pose(); - Matrix identity; + static Matrix identity; for(unsigned i=0; i<=max_index; ++i) { const Matrix &matrix1 = (pose1 ? pose1->get_link_matrix(i) : identity); @@ -211,7 +210,20 @@ Matrix Animation::Iterator::get_pose_matrix(unsigned link) const if(link>animation.armature->get_max_link_index()) throw out_of_range("Animation::Iterator::get_pose_matrix"); - return iter->pose_matrices[link].get(time_since_keyframe/iter->delta_t); + if(!iter->prev) + { + if(const Pose *pose = iter->keyframe->get_pose()) + return pose->get_link_matrix(link); + else + return Matrix(); + } + + // We must redo the base point correction since interpolation throws if off + Matrix result = iter->pose_matrices[link].get(time_since_keyframe/iter->delta_t); + const Vector3 &base = animation.armature->get_link(link).get_base(); + Vector3 new_base = result*base; + result = Matrix::translation(base.x-new_base.x, base.y-new_base.y, base.z-new_base.z)*result; + return result; } @@ -244,7 +256,10 @@ void Animation::Loader::keyframe(const string &n) void Animation::Loader::keyframe_inline() { RefPtr kf = new KeyFrame; - load_sub(*kf); + if(coll) + load_sub(*kf, get_collection()); + else + load_sub(*kf); TimedKeyFrame tkf(obj); tkf.time = current_time; diff --git a/source/animationplayer.cpp b/source/animationplayer.cpp index a929f3c2..9bcb5e57 100644 --- a/source/animationplayer.cpp +++ b/source/animationplayer.cpp @@ -21,7 +21,7 @@ void AnimationPlayer::tick(const Time::TimeDelta &dt) if(const Armature *armature = i->animation.get_armature()) { unsigned max_index = armature->get_max_link_index(); - for(unsigned j=0; jobject.set_pose_matrix(j, i->iterator.get_pose_matrix(j)); } diff --git a/source/pose.cpp b/source/pose.cpp index b5c5781b..4d589397 100644 --- a/source/pose.cpp +++ b/source/pose.cpp @@ -37,7 +37,7 @@ void Pose::rotate_link(unsigned i, float angle, const Vector3 &axis) // Keep the base point stationary Vector3 base = arm_link.get_base(); Vector3 new_base = links[i].local_matrix*base; - links[i].local_matrix.translate(base.x-new_base.x, base.y-new_base.y, base.z-new_base.z); + links[i].local_matrix = GL::Matrix::translation(base.x-new_base.x, base.y-new_base.y, base.z-new_base.z)*links[i].local_matrix; if(const Armature::Link *parent = arm_link.get_parent()) links[i].matrix = links[parent->get_index()].matrix*links[i].local_matrix; @@ -56,10 +56,15 @@ const Matrix &Pose::get_link_matrix(unsigned i) const Pose::Loader::Loader(Pose &p, Collection &c): DataFile::CollectionObjectLoader(p, &c) { - add("armature", &Pose::armature); + add("armature", &Loader::armature); add("link", &Loader::link); } +void Pose::Loader::armature(const string &n) +{ + obj.set_armature(get_collection().get(n)); +} + void Pose::Loader::link(const string &n) { if(!obj.armature) diff --git a/source/pose.h b/source/pose.h index 5f37c414..41fc3de5 100644 --- a/source/pose.h +++ b/source/pose.h @@ -18,6 +18,7 @@ public: public: Loader(Pose &, Collection &); private: + void armature(const std::string &); void link(const std::string &); };