]> git.tdb.fi Git - libs/gl.git/blob - source/animation/pose.cpp
Use default member initializers for simple types
[libs/gl.git] / source / animation / pose.cpp
1 #include <msp/datafile/collection.h>
2 #include "armature.h"
3 #include "error.h"
4 #include "pose.h"
5
6 using namespace std;
7
8 namespace Msp {
9 namespace GL {
10
11 Pose::Pose(const Armature &a)
12 {
13         set_armature(a);
14 }
15
16 void Pose::set_armature(const Armature &a)
17 {
18         if(armature)
19                 throw invalid_operation("Pose::set_armature");
20         armature = &a;
21         links.resize(armature->get_max_link_index()+1);
22 }
23
24 void Pose::rotate_link(unsigned i, float angle, const Vector3 &axis)
25 {
26         if(i>=links.size())
27                 throw out_of_range("Pose::rotate_link");
28
29         const Armature::Link &arm_link = armature->get_link(i);
30         links[i].local_matrix.rotate(angle, axis);
31
32         // Keep the base point stationary
33         Vector3 base = arm_link.get_base();
34         Vector3 new_base = links[i].local_matrix*base;
35         links[i].local_matrix = Matrix::translation(base-new_base)*links[i].local_matrix;
36
37         if(const Armature::Link *parent = arm_link.get_parent())
38                 links[i].matrix = links[parent->get_index()].matrix*links[i].local_matrix;
39
40         // XXX apply matrix to descendants of the link
41 }
42
43 const Matrix &Pose::get_link_matrix(unsigned i) const
44 {
45         if(i>=links.size())
46                 throw out_of_range("Pose::get_link_matrix");
47         return links[i].matrix;
48 }
49
50
51 Pose::Loader::Loader(Pose &p, Collection &c):
52         DataFile::CollectionObjectLoader<Pose>(p, &c)
53 {
54         add("armature", &Loader::armature);
55         add("link",     &Loader::link);
56 }
57
58 void Pose::Loader::armature(const string &n)
59 {
60         obj.set_armature(get_collection().get<Armature>(n));
61 }
62
63 void Pose::Loader::link(const string &n)
64 {
65         if(!obj.armature)
66                 throw logic_error("Armature must be specified first");
67         LinkLoader ldr(obj, obj.armature->get_link(n).get_index());
68         load_sub_with(ldr);
69 }
70
71
72 Pose::LinkLoader::LinkLoader(Pose &p, unsigned l):
73         DataFile::ObjectLoader<Pose>(p),
74         link_index(l)
75 {
76         add("rotation", &LinkLoader::rotation);
77 }
78
79 void Pose::LinkLoader::rotation(float a, float x, float y, float z)
80 {
81         obj.rotate_link(link_index, a, Vector3(x, y, z));
82 }
83
84 } // namespace GL
85 } // namespace Msp