ld33_umonster

annotate src/snode.cc @ 0:4a6683050e29

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