]> git.tdb.fi Git - libs/gl.git/blob - source/animatedobject.cpp
Add a class to unify loading coordinate transforms
[libs/gl.git] / source / animatedobject.cpp
1 #include <algorithm>
2 #include <msp/strings/format.h>
3 #include "animatedobject.h"
4 #include "error.h"
5 #include "object.h"
6 #include "programdata.h"
7 #include "renderer.h"
8 #include "technique.h"
9 #include "transform.h"
10
11 using namespace std;
12
13 namespace Msp {
14 namespace GL {
15
16 AnimatedObject::AnimatedObject(const Object &o):
17         ObjectInstance(o),
18         shdata(0)
19 {
20         if(const Technique *tech = object.get_technique())
21                 if(tech->has_shaders())
22                         shdata = new ProgramData;
23 }
24
25 AnimatedObject::~AnimatedObject()
26 {
27         delete shdata;
28 }
29
30 void AnimatedObject::set_pose_matrix(unsigned link, const Matrix &m)
31 {
32         if(shdata)
33         {
34                 if(link*16>=pose_data.size())
35                         pose_data.resize((link+1)*16);
36                 copy(m.data(), m.data()+16, &pose_data[link*16]);
37                 shdata->uniform_matrix4_array("pose", pose_data.size()/16, &pose_data[0]);
38         }
39 }
40
41 ProgramData &AnimatedObject::get_shader_data()
42 {
43         if(!shdata)
44                 throw invalid_operation("AnimatedObject::get_shader_data");
45         return *shdata;
46 }
47
48 const ProgramData &AnimatedObject::get_shader_data() const
49 {
50         if(!shdata)
51                 throw invalid_operation("AnimatedObject::get_shader_data");
52         return *shdata;
53 }
54
55 void AnimatedObject::set_uniform(const string &name, const KeyFrame::AnimatedUniform &uni)
56 {
57         if(!shdata)
58                 throw invalid_operation("AnimatedObject::set_uniform");
59
60         if(uni.size==1)
61                 shdata->uniform(name, uni.values[0]);
62         else if(uni.size==2)
63                 shdata->uniform2(name, uni.values);
64         else if(uni.size==3)
65                 shdata->uniform3(name, uni.values);
66         else if(uni.size==4)
67                 shdata->uniform4(name, uni.values);
68         else
69                 throw invalid_argument("AnimatedObject::set_uniform");
70 }
71
72 void AnimatedObject::setup_render(Renderer &renderer, const Tag &) const
73 {
74         renderer.transform(matrix);
75         if(shdata)
76                 renderer.add_shader_data(*shdata);
77 }
78
79
80 AnimatedObject::Loader::Loader(AnimatedObject &o):
81         DataFile::ObjectLoader<AnimatedObject>(o)
82 {
83         add("transform", &Loader::transform);
84
85         // Deprecated; Use the transform statement instead
86         add("position", &Loader::position);
87         add("rotation", &Loader::rotation);
88         add("scale", &Loader::scale);
89         add("scale", &Loader::scale_uniform);
90 }
91
92 void AnimatedObject::Loader::position(float x, float y, float z)
93 {
94         obj.matrix.translate(x, y, z);
95 }
96
97 void AnimatedObject::Loader::rotation(float a, float x, float y, float z)
98 {
99         obj.matrix.rotate_deg(a, x, y, z);
100 }
101
102 void AnimatedObject::Loader::scale(float x, float y, float z)
103 {
104         obj.matrix.scale(x, y, z);
105 }
106
107 void AnimatedObject::Loader::scale_uniform(float s)
108 {
109         obj.matrix.scale(s);
110 }
111
112 void AnimatedObject::Loader::transform()
113 {
114         Transform trn;
115         load_sub(trn);
116         obj.matrix = trn.to_matrix();
117 }
118
119 } // namespace GL
120 } // namespace Msp