X-Git-Url: http://git.tdb.fi/?a=blobdiff_plain;f=source%2Fanimation.cpp;h=c0b508180b0da9f8676cd12e6f5c74a4a77cede1;hb=619aae12e01f25e79626a94c973927e5599e99a5;hp=e7174adc1bdab351a9799edb9af197d1b840c25f;hpb=57fc4142e0b19a21f61c60b00f8310d5d2c27871;p=libs%2Fgl.git diff --git a/source/animation.cpp b/source/animation.cpp index e7174adc..c0b50818 100644 --- a/source/animation.cpp +++ b/source/animation.cpp @@ -3,6 +3,7 @@ #include #include "animation.h" #include "armature.h" +#include "error.h" #include "keyframe.h" #include "pose.h" @@ -16,6 +17,10 @@ Animation::Animation(): looping(false) { } +// Avoid synthesizing ~RefPtr in files including animation.h +Animation::~Animation() +{ } + void Animation::set_armature(const Armature &a) { armature = &a; @@ -46,7 +51,6 @@ void Animation::prepare_keyframe(TimedKeyFrame &tkf) return; tkf.prepare(); - } @@ -59,18 +63,17 @@ Animation::AxisInterpolation::AxisInterpolation(const double *axis1, const doubl { // Compute a normalized vector halfway between the two endpoints double half[3]; - double len = 0; + double a1_len = 0; + double h_len = 0; for(unsigned i=0; i<3; ++i) { half[i] = (axis1[i]+axis2[i])/2; - len += half[i]*half[i]; + a1_len += axis1[i]*axis1[i]; + h_len += half[i]*half[i]; } - len = sqrt(len); - for(unsigned i=0; i<3; ++i) - half[i] /= len; // Compute correction factors for smooth interpolation - double cos_half = axis1[0]*half[0]+axis1[1]*half[1]+axis1[2]*half[2]; + double cos_half = (axis1[0]*half[0]+axis1[1]*half[1]+axis1[2]*half[2])/sqrt(a1_len*h_len); double angle = acos(cos_half); slope = (angle ? angle/tan(angle) : 1); scale = cos_half; @@ -153,7 +156,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); @@ -207,11 +210,25 @@ Matrix Animation::Iterator::get_matrix() const Matrix Animation::Iterator::get_pose_matrix(unsigned link) const { if(!animation.armature) - throw logic_error("Animation::Iterator::get_pose_matrix"); + throw invalid_operation("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); + 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 + // 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(); + Vector3 new_base = result*base; + result = Matrix::translation(base-new_base)*result; + return result; } @@ -244,7 +261,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;