X-Git-Url: http://git.tdb.fi/?p=libs%2Fgl.git;a=blobdiff_plain;f=source%2Fpose.cpp;fp=source%2Fpose.cpp;h=b5c5781b630be2365c5dcb06841acd3060291180;hp=0000000000000000000000000000000000000000;hb=9abfb801dbceb59272f6561731d066ed516340e5;hpb=e8bdd7946874a6622bda3376232290a35422fdea diff --git a/source/pose.cpp b/source/pose.cpp new file mode 100644 index 00000000..b5c5781b --- /dev/null +++ b/source/pose.cpp @@ -0,0 +1,85 @@ +#include +#include "armature.h" +#include "error.h" +#include "pose.h" + +using namespace std; + +namespace Msp { +namespace GL { + +Pose::Pose(): + armature(0) +{ } + +Pose::Pose(const Armature &a): + armature(0) +{ + set_armature(a); +} + +void Pose::set_armature(const Armature &a) +{ + if(armature) + throw invalid_operation("Pose::set_armature"); + armature = &a; + links.resize(armature->get_max_link_index()+1); +} + +void Pose::rotate_link(unsigned i, float angle, const Vector3 &axis) +{ + if(i>=links.size()) + throw out_of_range("Pose::rotate_link"); + + const Armature::Link &arm_link = armature->get_link(i); + links[i].local_matrix.rotate(angle, 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); + + if(const Armature::Link *parent = arm_link.get_parent()) + links[i].matrix = links[parent->get_index()].matrix*links[i].local_matrix; + + // XXX apply matrix to descendants of the link +} + +const Matrix &Pose::get_link_matrix(unsigned i) const +{ + if(i>=links.size()) + throw out_of_range("Pose::get_link_matrix"); + return links[i].matrix; +} + + +Pose::Loader::Loader(Pose &p, Collection &c): + DataFile::CollectionObjectLoader(p, &c) +{ + add("armature", &Pose::armature); + add("link", &Loader::link); +} + +void Pose::Loader::link(const string &n) +{ + if(!obj.armature) + error("Armature must be specified first"); + LinkLoader ldr(obj, obj.armature->get_link(n).get_index()); + load_sub_with(ldr); +} + + +Pose::LinkLoader::LinkLoader(Pose &p, unsigned l): + DataFile::ObjectLoader(p), + link_index(l) +{ + add("rotation", &LinkLoader::rotation); +} + +void Pose::LinkLoader::rotation(float a, float x, float y, float z) +{ + obj.rotate_link(link_index, a, Vector3(x, y, z)); +} + +} // namespace GL +} // namespace Msp