rayzor

annotate 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
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 }