tavli

annotate src/snode.cc @ 14:283eb6e9f0a3

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