erebus

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