--- /dev/null
+#include <msp/datafile/collection.h>
+#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 = Matrix::translation(base-new_base)*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;
+
+ // 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<Pose>(p, &c)
+{
+ add("armature", &Loader::armature);
+ 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)
+ throw logic_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<Pose>(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