rayzor

view src/snode.cc @ 17:79609d482762

the renderer renders, also fixed an unnoticed matrix conversion problem between scenegraph and min3d
author John Tsiombikas <nuclear@member.fsf.org>
date Mon, 14 Apr 2014 07:34:45 +0300
parents a9a948809c6f
children
line source
1 #include <string.h>
2 #include <assert.h>
3 #include "snode.h"
4 #include "min3d.h"
7 SceneNode::SceneNode()
8 {
9 parent = 0;
10 name = 0;
11 type = NODE_NULL;
12 scale = Vector3(1, 1, 1);
13 invalidate();
14 }
16 SceneNode::~SceneNode()
17 {
18 delete [] name;
19 }
21 void SceneNode::set_name(const char *name)
22 {
23 this->name = new char[strlen(name) + 1];
24 strcpy(this->name, name);
25 }
27 const char *SceneNode::get_name() const
28 {
29 return name ? name : "<unnamed>";
30 }
32 NodeType SceneNode::get_type() const
33 {
34 return type;
35 }
37 SceneNode *SceneNode::get_parent()
38 {
39 return parent;
40 }
42 const SceneNode *SceneNode::get_parent() const
43 {
44 return parent;
45 }
47 void SceneNode::add_child(SceneNode *child)
48 {
49 children.push_back(child);
50 child->parent = this;
51 invalidate();
52 }
54 void SceneNode::remove_child(SceneNode *child)
55 {
56 // TODO
57 invalidate();
58 }
60 int SceneNode::get_children_count() const
61 {
62 return (int)children.size();
63 }
65 SceneNode *SceneNode::get_child(int idx)
66 {
67 if(idx >= 0 && idx < get_children_count()) {
68 return children[idx];
69 }
70 return 0;
71 }
73 const SceneNode *SceneNode::get_child(int idx) const
74 {
75 if(idx >= 0 && idx < get_children_count()) {
76 return children[idx];
77 }
78 return 0;
79 }
83 void SceneNode::set_position(const Vector3 &pos)
84 {
85 this->pos = pos;
86 invalidate();
87 }
89 Vector3 SceneNode::get_node_position() const
90 {
91 return pos;
92 }
94 void SceneNode::set_rotation(const Quat &quat)
95 {
96 rot = quat;
97 invalidate();
98 }
100 Quat SceneNode::get_node_rotation() const
101 {
102 return rot;
103 }
105 void SceneNode::set_scaling(const Vector3 &scale)
106 {
107 this->scale = scale;
108 invalidate();
109 }
111 Vector3 SceneNode::get_node_scaling() const
112 {
113 return scale;
114 }
116 // these take hierarchy into account
117 Vector3 SceneNode::get_position() const
118 {
119 return transform(get_matrix(), Vector3(0, 0, 0));
120 }
122 Quat SceneNode::get_rotation() const
123 {
124 if(parent) {
125 return parent->get_rotation() * rot;
126 }
127 return rot;
128 }
130 Vector3 SceneNode::get_scaling() const
131 {
132 if(parent) {
133 return parent->get_scaling() * scale;
134 }
135 return scale;
136 }
138 void SceneNode::set_pivot(const Vector3 &pivot)
139 {
140 this->pivot = pivot;
141 invalidate();
142 }
144 Vector3 SceneNode::get_pivot() const
145 {
146 return pivot;
147 }
149 const Matrix4x4 &SceneNode::get_matrix() const
150 {
151 calc_matrix();
152 return xform;
153 }
155 const Matrix4x4 &SceneNode::get_inv_matrix() const
156 {
157 calc_inv_matrix();
158 return inv_xform;
159 }
161 void SceneNode::invalidate() const
162 {
163 xform_valid = inv_xform_valid = false;
164 }
166 // TODO: hierarchy
167 void SceneNode::calc_matrix() const
168 {
169 if(xform_valid) return;
171 xform.set_identity();
172 xform.translate(pivot.x, pivot.y, pivot.z);
173 xform = xform * rot.get_matrix();
174 xform.translate(pos.x, pos.y, pos.z);
175 xform.scale(scale.x, scale.y, scale.z);
176 xform.translate(-pivot.x, -pivot.y, -pivot.z);
178 xform_valid = true;
179 }
181 void SceneNode::calc_inv_matrix() const
182 {
183 if(inv_xform_valid) return;
185 calc_matrix();
187 inv_xform = xform.inverse();
188 inv_xform_valid = true;
189 }
191 void SceneNode::pre_draw() const
192 {
193 m3d_matrix_mode(M3D_MODELVIEW);
194 m3d_push_matrix();
195 m3d_mult_transpose_matrix(get_matrix()[0]);
196 }
198 void SceneNode::post_draw() const
199 {
200 m3d_matrix_mode(M3D_MODELVIEW);
201 m3d_pop_matrix();
202 }
204 void SceneNode::draw(bool emph) const
205 {
206 if(emph) {
207 float avg_scale = (scale.x + scale.y + scale.z) / 3.0;
208 m3d_push_matrix();
209 m3d_scale(avg_scale / scale.x, avg_scale / scale.y, avg_scale / scale.z);
211 m3d_begin(M3D_LINES);
212 m3d_color(1, 0, 0);
213 m3d_vertex(0, 0, 0);
214 m3d_vertex(0.5, 0, 0);
215 m3d_color(0, 1, 0);
216 m3d_vertex(0, 0, 0);
217 m3d_vertex(0, 0.5, 0);
218 m3d_color(0, 0, 1);
219 m3d_vertex(0, 0, 0);
220 m3d_vertex(0, 0, 0.5);
221 m3d_end();
223 m3d_pop_matrix();
225 m3d_color(1, 0.8, 0.1);
226 } else {
227 m3d_color(0.9, 0.9, 0.9);
228 }
229 }
231 bool SceneNode::intersect(const Ray &ray, RayHit *hit) const
232 {
233 return false;
234 }