#include <msp/time/units.h>
#include "animation.h"
#include "armature.h"
+#include "error.h"
#include "keyframe.h"
#include "pose.h"
looping(false)
{ }
+// Avoid synthesizing ~RefPtr in files including animation.h
+Animation::~Animation()
+{ }
+
void Animation::set_armature(const Armature &a)
{
armature = &a;
scale(0)
{ }
-Animation::AxisInterpolation::AxisInterpolation(const double *axis1, const double *axis2)
+Animation::AxisInterpolation::AxisInterpolation(const float *axis1, const float *axis2)
{
// Compute a normalized vector halfway between the two endpoints
- double half[3];
- double len = 0;
+ float half[3];
+ float a1_len = 0;
+ float 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 angle = acos(cos_half);
+ float cos_half = (axis1[0]*half[0]+axis1[1]*half[1]+axis1[2]*half[2])/sqrt(a1_len*h_len);
+ float angle = acos(cos_half);
slope = (angle ? angle/tan(angle) : 1);
scale = cos_half;
}
matrix1(&m1),
matrix2(&m2)
{
- const double *m1_data = matrix1->data();
- const double *m2_data = matrix2->data();
+ const float *m1_data = matrix1->data();
+ const float *m2_data = matrix2->data();
for(unsigned i=0; i<3; ++i)
axes[i] = AxisInterpolation(m1_data+i*4, m2_data+i*4);
}
{
float u = t*2.0f-1.0f;
- double matrix[16];
+ float matrix[16];
for(unsigned i=0; i<4; ++i)
{
- const double *m1_col = matrix1->data()+i*4;
- const double *m2_col = matrix2->data()+i*4;
- double *out_col = matrix+i*4;
+ const float *m1_col = matrix1->data()+i*4;
+ const float *m2_col = matrix2->data()+i*4;
+ float *out_col = matrix+i*4;
if(i<3)
{
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");
}
// 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.x-new_base.x, base.y-new_base.y, base.z-new_base.z)*result;
+ result = Matrix::translation(base-new_base)*result;
return result;
}