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