tavli

view src/snode.cc @ 14:283eb6e9f0a3

scenery
author John Tsiombikas <nuclear@member.fsf.org>
date Sun, 28 Jun 2015 07:44:23 +0300
parents
children
line source
1 #include <float.h>
2 #include <assert.h>
3 #include <algorithm>
4 #include "snode.h"
6 SceneNode::SceneNode()
7 : scale(1, 1, 1)
8 {
9 parent = 0;
10 }
12 SceneNode::SceneNode(Object *obj)
13 : scale(1, 1, 1)
14 {
15 parent = 0;
16 add_object(obj);
17 }
19 void SceneNode::add_child(SceneNode *node)
20 {
21 if(node->parent) {
22 if(node->parent == this) {
23 return;
24 }
25 node->parent->remove_child(node);
26 }
28 children.push_back(node);
29 node->parent = this;
30 }
32 bool SceneNode::remove_child(SceneNode *node)
33 {
34 for(size_t i=0; i<children.size(); i++) {
35 if(children[i] == node) {
36 assert(node->parent == this);
37 node->parent = 0;
38 return true;
39 }
40 }
41 return false;
42 }
44 int SceneNode::get_num_children() const
45 {
46 return (int)children.size();
47 }
49 SceneNode *SceneNode::get_child(int idx) const
50 {
51 return children[idx];
52 }
54 SceneNode *SceneNode::get_parent() const
55 {
56 return parent;
57 }
59 void SceneNode::add_object(Object *obj)
60 {
61 if(std::find(this->obj.begin(), this->obj.end(), obj) == this->obj.end()) {
62 this->obj.push_back(obj);
63 }
64 }
66 int SceneNode::get_num_objects() const
67 {
68 return (int)obj.size();
69 }
71 Object *SceneNode::get_object(int idx) const
72 {
73 return obj[idx];
74 }
76 void SceneNode::set_position(const Vector3 &pos)
77 {
78 this->pos = pos;
79 }
81 void SceneNode::set_rotation(const Quaternion &rot)
82 {
83 this->rot = rot;
84 }
86 void SceneNode::set_scaling(const Vector3 &scale)
87 {
88 this->scale = scale;
89 }
92 const Vector3 &SceneNode::get_node_position() const
93 {
94 return pos;
95 }
97 const Quaternion &SceneNode::get_node_rotation() const
98 {
99 return rot;
100 }
102 const Vector3 &SceneNode::get_node_scaling() const
103 {
104 return scale;
105 }
108 Vector3 SceneNode::get_position() const
109 {
110 return Vector3(0, 0, 0).transformed(xform);
111 }
113 Quaternion SceneNode::get_rotation() const
114 {
115 return rot; // TODO
116 }
118 Vector3 SceneNode::get_scaling() const
119 {
120 return scale; // TODO
121 }
123 const Matrix4x4 &SceneNode::get_matrix() const
124 {
125 return xform;
126 }
128 const Matrix4x4 &SceneNode::get_inv_matrix() const
129 {
130 return inv_xform;
131 }
134 void SceneNode::update_node(long msec)
135 {
136 xform.reset_identity();
137 xform.translate(pos);
138 xform.rotate(rot);
139 xform.scale(scale);
141 if(parent) {
142 xform = parent->xform * xform;
143 }
144 inv_xform = xform.inverse();
145 }
147 void SceneNode::update(long msec)
148 {
149 update_node(msec);
151 for(size_t i=0; i<children.size(); i++) {
152 children[i]->update(msec);
153 }
154 }
157 bool SceneNode::intersect(const Ray &ray, HitPoint *hit) const
158 {
159 Ray local_ray = ray.transformed(inv_xform);
161 HitPoint nearest;
162 nearest.dist = FLT_MAX;
163 for(size_t i=0; i<obj.size(); i++) {
164 if(obj[i]->intersect(local_ray, hit)) {
165 if(!hit) return true;
166 if(hit->dist < nearest.dist) {
167 nearest = *hit;
168 nearest.node = this;
169 }
170 }
171 }
173 for(size_t i=0; i<children.size(); i++) {
174 if(children[i]->intersect(ray, hit)) {
175 if(!hit) return true;
176 if(hit->dist < nearest.dist) {
177 nearest = *hit;
178 }
179 }
180 }
182 if(nearest.dist < FLT_MAX) {
183 *hit = nearest;
184 hit->ray = ray;
185 return true;
186 }
187 return false;
188 }