]> git.tdb.fi Git - libs/gl.git/blobdiff - source/animation.cpp
Support for armature-based animation
[libs/gl.git] / source / animation.cpp
index 9f93a8d494222424dcc276e9547b29d488f9cd81..e7174adc1bdab351a9799edb9af197d1b840c25f 100644 (file)
@@ -2,19 +2,25 @@
 #include <msp/datafile/collection.h>
 #include <msp/time/units.h>
 #include "animation.h"
+#include "armature.h"
 #include "keyframe.h"
+#include "pose.h"
 
 using namespace std;
 
-#include <msp/io/print.h>
-
 namespace Msp {
 namespace GL {
 
 Animation::Animation():
+       armature(0),
        looping(false)
 { }
 
+void Animation::set_armature(const Armature &a)
+{
+       armature = &a;
+}
+
 void Animation::add_keyframe(const Time::TimeDelta &t, const KeyFrame &kf)
 {
        if(!keyframes.empty() && t<keyframes.back().time)
@@ -141,6 +147,20 @@ void Animation::TimedKeyFrame::prepare()
 {
        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();
+               pose_matrices.resize(max_index+1);
+               const Pose *pose1 = prev->keyframe->get_pose();
+               const Pose *pose2 = keyframe->get_pose();
+               Matrix identity;
+               for(unsigned i=0; i<=max_index; ++i)
+               {
+                       const Matrix &matrix1 = (pose1 ? pose1->get_link_matrix(i) : identity);
+                       const Matrix &matrix2 = (pose2 ? pose2->get_link_matrix(i) : identity);
+                       pose_matrices[i] = MatrixInterpolation(matrix1, matrix2);
+               }
+       }
 }
 
 
@@ -184,6 +204,16 @@ Matrix Animation::Iterator::get_matrix() const
        return iter->matrix.get(time_since_keyframe/iter->delta_t);
 }
 
+Matrix Animation::Iterator::get_pose_matrix(unsigned link) const
+{
+       if(!animation.armature)
+               throw logic_error("Animation::Iterator::get_pose_matrix");
+       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);
+}
+
 
 Animation::Loader::Loader(Animation &a):
        DataFile::CollectionObjectLoader<Animation>(a, 0)
@@ -199,6 +229,7 @@ Animation::Loader::Loader(Animation &a, Collection &c):
 
 void Animation::Loader::init()
 {
+       add("armature", &Animation::armature);
        add("interval", &Loader::interval);
        add("keyframe", &Loader::keyframe);
        add("keyframe", &Loader::keyframe_inline);