tavli
diff src/snode.cc @ 3:94aff2ff1934
too much?
author | John Tsiombikas <nuclear@member.fsf.org> |
---|---|
date | Mon, 22 Jun 2015 21:46:57 +0300 |
parents | |
children |
line diff
1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/src/snode.cc Mon Jun 22 21:46:57 2015 +0300 1.3 @@ -0,0 +1,188 @@ 1.4 +#include <float.h> 1.5 +#include <assert.h> 1.6 +#include <algorithm> 1.7 +#include "snode.h" 1.8 + 1.9 +SceneNode::SceneNode() 1.10 + : scale(1, 1, 1) 1.11 +{ 1.12 + parent = 0; 1.13 +} 1.14 + 1.15 +SceneNode::SceneNode(Object *obj) 1.16 + : scale(1, 1, 1) 1.17 +{ 1.18 + parent = 0; 1.19 + add_object(obj); 1.20 +} 1.21 + 1.22 +void SceneNode::add_child(SceneNode *node) 1.23 +{ 1.24 + if(node->parent) { 1.25 + if(node->parent == this) { 1.26 + return; 1.27 + } 1.28 + node->parent->remove_child(node); 1.29 + } 1.30 + 1.31 + children.push_back(node); 1.32 + node->parent = this; 1.33 +} 1.34 + 1.35 +bool SceneNode::remove_child(SceneNode *node) 1.36 +{ 1.37 + for(size_t i=0; i<children.size(); i++) { 1.38 + if(children[i] == node) { 1.39 + assert(node->parent == this); 1.40 + node->parent = 0; 1.41 + return true; 1.42 + } 1.43 + } 1.44 + return false; 1.45 +} 1.46 + 1.47 +int SceneNode::get_num_children() const 1.48 +{ 1.49 + return (int)children.size(); 1.50 +} 1.51 + 1.52 +SceneNode *SceneNode::get_child(int idx) const 1.53 +{ 1.54 + return children[idx]; 1.55 +} 1.56 + 1.57 +SceneNode *SceneNode::get_parent() const 1.58 +{ 1.59 + return parent; 1.60 +} 1.61 + 1.62 +void SceneNode::add_object(Object *obj) 1.63 +{ 1.64 + if(std::find(this->obj.begin(), this->obj.end(), obj) == this->obj.end()) { 1.65 + this->obj.push_back(obj); 1.66 + } 1.67 +} 1.68 + 1.69 +int SceneNode::get_num_objects() const 1.70 +{ 1.71 + return (int)obj.size(); 1.72 +} 1.73 + 1.74 +Object *SceneNode::get_object(int idx) const 1.75 +{ 1.76 + return obj[idx]; 1.77 +} 1.78 + 1.79 +void SceneNode::set_position(const Vector3 &pos) 1.80 +{ 1.81 + this->pos = pos; 1.82 +} 1.83 + 1.84 +void SceneNode::set_rotation(const Quaternion &rot) 1.85 +{ 1.86 + this->rot = rot; 1.87 +} 1.88 + 1.89 +void SceneNode::set_scaling(const Vector3 &scale) 1.90 +{ 1.91 + this->scale = scale; 1.92 +} 1.93 + 1.94 + 1.95 +const Vector3 &SceneNode::get_node_position() const 1.96 +{ 1.97 + return pos; 1.98 +} 1.99 + 1.100 +const Quaternion &SceneNode::get_node_rotation() const 1.101 +{ 1.102 + return rot; 1.103 +} 1.104 + 1.105 +const Vector3 &SceneNode::get_node_scaling() const 1.106 +{ 1.107 + return scale; 1.108 +} 1.109 + 1.110 + 1.111 +Vector3 SceneNode::get_position() const 1.112 +{ 1.113 + return Vector3(0, 0, 0).transformed(xform); 1.114 +} 1.115 + 1.116 +Quaternion SceneNode::get_rotation() const 1.117 +{ 1.118 + return rot; // TODO 1.119 +} 1.120 + 1.121 +Vector3 SceneNode::get_scaling() const 1.122 +{ 1.123 + return scale; // TODO 1.124 +} 1.125 + 1.126 +const Matrix4x4 &SceneNode::get_matrix() const 1.127 +{ 1.128 + return xform; 1.129 +} 1.130 + 1.131 +const Matrix4x4 &SceneNode::get_inv_matrix() const 1.132 +{ 1.133 + return inv_xform; 1.134 +} 1.135 + 1.136 + 1.137 +void SceneNode::update_node(long msec) 1.138 +{ 1.139 + xform.reset_identity(); 1.140 + xform.translate(pos); 1.141 + xform.rotate(rot); 1.142 + xform.scale(scale); 1.143 + 1.144 + if(parent) { 1.145 + xform = parent->xform * xform; 1.146 + } 1.147 + inv_xform = xform.inverse(); 1.148 +} 1.149 + 1.150 +void SceneNode::update(long msec) 1.151 +{ 1.152 + update_node(msec); 1.153 + 1.154 + for(size_t i=0; i<children.size(); i++) { 1.155 + children[i]->update(msec); 1.156 + } 1.157 +} 1.158 + 1.159 + 1.160 +bool SceneNode::intersect(const Ray &ray, HitPoint *hit) const 1.161 +{ 1.162 + Ray local_ray = ray.transformed(inv_xform); 1.163 + 1.164 + HitPoint nearest; 1.165 + nearest.dist = FLT_MAX; 1.166 + for(size_t i=0; i<obj.size(); i++) { 1.167 + if(obj[i]->intersect(local_ray, hit)) { 1.168 + if(!hit) return true; 1.169 + if(hit->dist < nearest.dist) { 1.170 + nearest = *hit; 1.171 + nearest.node = this; 1.172 + } 1.173 + } 1.174 + } 1.175 + 1.176 + for(size_t i=0; i<children.size(); i++) { 1.177 + if(children[i]->intersect(ray, hit)) { 1.178 + if(!hit) return true; 1.179 + if(hit->dist < nearest.dist) { 1.180 + nearest = *hit; 1.181 + } 1.182 + } 1.183 + } 1.184 + 1.185 + if(nearest.dist < FLT_MAX) { 1.186 + *hit = nearest; 1.187 + hit->ray = ray; 1.188 + return true; 1.189 + } 1.190 + return false; 1.191 +}