erebus

view liberebus/src/snode.cc @ 8:e2d9bf168a41

semi-works ...
author John Tsiombikas <nuclear@member.fsf.org>
date Sat, 24 May 2014 06:12:57 +0300
parents 93894c232d65
children e9da2916bc79
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 auto it = std::find(children.begin(), children.end(), node);
35 if(it != children.end()) {
36 assert(node->parent == this);
37 node->parent = 0;
38 return true;
39 }
40 return false;
41 }
43 int SceneNode::get_num_children() const
44 {
45 return (int)children.size();
46 }
48 SceneNode *SceneNode::get_child(int idx) const
49 {
50 return children[idx];
51 }
53 SceneNode *SceneNode::get_parent() const
54 {
55 return parent;
56 }
58 void SceneNode::add_object(Object *obj)
59 {
60 if(std::find(this->obj.begin(), this->obj.end(), obj) == this->obj.end()) {
61 this->obj.push_back(obj);
62 }
63 }
65 int SceneNode::get_num_objects() const
66 {
67 return (int)obj.size();
68 }
70 Object *SceneNode::get_object(int idx) const
71 {
72 return obj[idx];
73 }
75 void SceneNode::set_position(const Vector3 &pos)
76 {
77 this->pos = pos;
78 }
80 void SceneNode::set_rotation(const Quaternion &rot)
81 {
82 this->rot = rot;
83 }
85 void SceneNode::set_scaling(const Vector3 &scale)
86 {
87 this->scale = scale;
88 }
91 const Vector3 &SceneNode::get_node_position() const
92 {
93 return pos;
94 }
96 const Quaternion &SceneNode::get_node_rotation() const
97 {
98 return rot;
99 }
101 const Vector3 &SceneNode::get_node_scaling() const
102 {
103 return scale;
104 }
107 Vector3 SceneNode::get_position() const
108 {
109 return Vector3{0, 0, 0}.transformed(xform);
110 }
112 Quaternion SceneNode::get_rotation() const
113 {
114 return rot; // TODO
115 }
117 Vector3 SceneNode::get_scaling() const
118 {
119 return scale; // TODO
120 }
123 void SceneNode::update_node(long msec)
124 {
125 xform.reset_identity();
126 xform.translate(pos);
127 xform.rotate(rot);
128 xform.scale(scale);
130 if(parent) {
131 xform = parent->xform * xform;
132 }
133 inv_xform = xform.inverse();
134 }
136 void SceneNode::update(long msec)
137 {
138 update_node(msec);
140 for(size_t i=0; i<children.size(); i++) {
141 children[i]->update(msec);
142 }
143 }
146 bool SceneNode::intersect(const Ray &ray, RayHit *hit) const
147 {
148 Ray local_ray = ray.transformed(inv_xform);
150 RayHit nearest;
151 nearest.dist = FLT_MAX;
152 for(size_t i=0; i<obj.size(); i++) {
153 if(obj[i]->intersect(local_ray, hit)) {
154 if(!hit) return true;
155 if(hit->dist < nearest.dist) {
156 nearest = *hit;
157 }
158 }
159 }
161 for(size_t i=0; i<children.size(); i++) {
162 if(children[i]->intersect(ray, hit)) {
163 if(!hit) return true;
164 if(hit->dist < nearest.dist) {
165 nearest = *hit;
166 }
167 }
168 }
170 if(nearest.dist < FLT_MAX) {
171 *hit = nearest;
172 hit->local_ray = local_ray;
173 hit->world_ray = ray;
174 return true;
175 }
176 return false;
177 }