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.
pose_matrices.resize(max_index+1);
const Pose *pose1 = prev->keyframe->get_pose();
const Pose *pose2 = keyframe->get_pose();
pose_matrices.resize(max_index+1);
const Pose *pose1 = prev->keyframe->get_pose();
const Pose *pose2 = keyframe->get_pose();
+ static Matrix identity;
for(unsigned i=0; i<=max_index; ++i)
{
const Matrix &matrix1 = (pose1 ? pose1->get_link_matrix(i) : identity);
for(unsigned i=0; i<=max_index; ++i)
{
const Matrix &matrix1 = (pose1 ? pose1->get_link_matrix(i) : identity);
if(link>animation.armature->get_max_link_index())
throw out_of_range("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
+ 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;
void Animation::Loader::keyframe_inline()
{
RefPtr<KeyFrame> kf = new KeyFrame;
void Animation::Loader::keyframe_inline()
{
RefPtr<KeyFrame> kf = new KeyFrame;
+ if(coll)
+ load_sub(*kf, get_collection());
+ else
+ load_sub(*kf);
TimedKeyFrame tkf(obj);
tkf.time = current_time;
TimedKeyFrame tkf(obj);
tkf.time = current_time;
if(const Armature *armature = i->animation.get_armature())
{
unsigned max_index = armature->get_max_link_index();
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));
}
i->object.set_pose_matrix(j, i->iterator.get_pose_matrix(j));
}
// Keep the base point stationary
Vector3 base = arm_link.get_base();
Vector3 new_base = links[i].local_matrix*base;
// 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;
if(const Armature::Link *parent = arm_link.get_parent())
links[i].matrix = links[parent->get_index()].matrix*links[i].local_matrix;
Pose::Loader::Loader(Pose &p, Collection &c):
DataFile::CollectionObjectLoader<Pose>(p, &c)
{
Pose::Loader::Loader(Pose &p, Collection &c):
DataFile::CollectionObjectLoader<Pose>(p, &c)
{
- add("armature", &Pose::armature);
+ add("armature", &Loader::armature);
add("link", &Loader::link);
}
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)
void Pose::Loader::link(const string &n)
{
if(!obj.armature)
public:
Loader(Pose &, Collection &);
private:
public:
Loader(Pose &, Collection &);
private:
+ void armature(const std::string &);
void link(const std::string &);
};
void link(const std::string &);
};