]> git.tdb.fi Git - libs/gl.git/commitdiff
Fix several bugs in the animation system
authorMikko Rasa <tdb@tdb.fi>
Mon, 13 Aug 2012 12:25:54 +0000 (15:25 +0300)
committerMikko Rasa <tdb@tdb.fi>
Mon, 13 Aug 2012 12:25:54 +0000 (15:25 +0300)
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.

source/animation.cpp
source/animationplayer.cpp
source/pose.cpp
source/pose.h

index e7174adc1bdab351a9799edb9af197d1b840c25f..efb67c972ded72ad916c286def76bd34bf5de28c 100644 (file)
@@ -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<KeyFrame> kf = new KeyFrame;
-       load_sub(*kf);
+       if(coll)
+               load_sub(*kf, get_collection());
+       else
+               load_sub(*kf);
 
        TimedKeyFrame tkf(obj);
        tkf.time = current_time;
index a929f3c233e846bcc39eedae496bbd7a860e0988..9bcb5e5720872d006b28ac6f8a9c1dec7421c26b 100644 (file)
@@ -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; j<max_index; ++j)
+                       for(unsigned j=0; j<=max_index; ++j)
                                i->object.set_pose_matrix(j, i->iterator.get_pose_matrix(j));
                }
 
index b5c5781b630be2365c5dcb06841acd3060291180..4d58939775b592ffa37366ce7aa75996116795e8 100644 (file)
@@ -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<Pose>(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<Armature>(n));
+}
+
 void Pose::Loader::link(const string &n)
 {
        if(!obj.armature)
index 5f37c414d4e60d127626a68db3f53dfa352a19cd..41fc3de596986940f7f60528d4af510615894557 100644 (file)
@@ -18,6 +18,7 @@ public:
        public:
                Loader(Pose &, Collection &);
        private:
+               void armature(const std::string &);
                void link(const std::string &);
        };