erebus

annotate liberebus/src/snode.cc @ 48:9971a08f4104

merged
author John Tsiombikas <nuclear@member.fsf.org>
date Wed, 24 Feb 2016 00:29:31 +0200
parents e9da2916bc79
children
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@46 75 void SceneNode::set_position(const Vec3 &pos)
nuclear@4 76 {
nuclear@4 77 this->pos = pos;
nuclear@4 78 }
nuclear@4 79
nuclear@46 80 void SceneNode::set_rotation(const Quat &rot)
nuclear@4 81 {
nuclear@4 82 this->rot = rot;
nuclear@4 83 }
nuclear@4 84
nuclear@46 85 void SceneNode::set_scaling(const Vec3 &scale)
nuclear@4 86 {
nuclear@4 87 this->scale = scale;
nuclear@4 88 }
nuclear@4 89
nuclear@4 90
nuclear@46 91 const Vec3 &SceneNode::get_node_position() const
nuclear@4 92 {
nuclear@4 93 return pos;
nuclear@4 94 }
nuclear@4 95
nuclear@46 96 const Quat &SceneNode::get_node_rotation() const
nuclear@4 97 {
nuclear@4 98 return rot;
nuclear@4 99 }
nuclear@4 100
nuclear@46 101 const Vec3 &SceneNode::get_node_scaling() const
nuclear@4 102 {
nuclear@4 103 return scale;
nuclear@4 104 }
nuclear@4 105
nuclear@4 106
nuclear@46 107 Vec3 SceneNode::get_position() const
nuclear@4 108 {
nuclear@46 109 return Vec3{0, 0, 0}.transformed(xform);
nuclear@4 110 }
nuclear@4 111
nuclear@46 112 Quat SceneNode::get_rotation() const
nuclear@4 113 {
nuclear@4 114 return rot; // TODO
nuclear@4 115 }
nuclear@4 116
nuclear@46 117 Vec3 SceneNode::get_scaling() const
nuclear@4 118 {
nuclear@4 119 return scale; // TODO
nuclear@4 120 }
nuclear@4 121
nuclear@46 122 const Mat4x4 &SceneNode::get_matrix() const
nuclear@17 123 {
nuclear@17 124 return xform;
nuclear@17 125 }
nuclear@17 126
nuclear@46 127 const Mat4x4 &SceneNode::get_inv_matrix() const
nuclear@17 128 {
nuclear@17 129 return inv_xform;
nuclear@17 130 }
nuclear@17 131
nuclear@4 132
nuclear@4 133 void SceneNode::update_node(long msec)
nuclear@4 134 {
nuclear@4 135 xform.reset_identity();
nuclear@4 136 xform.translate(pos);
nuclear@4 137 xform.rotate(rot);
nuclear@4 138 xform.scale(scale);
nuclear@4 139
nuclear@4 140 if(parent) {
nuclear@4 141 xform = parent->xform * xform;
nuclear@4 142 }
nuclear@4 143 inv_xform = xform.inverse();
nuclear@4 144 }
nuclear@4 145
nuclear@4 146 void SceneNode::update(long msec)
nuclear@4 147 {
nuclear@4 148 update_node(msec);
nuclear@4 149
nuclear@4 150 for(size_t i=0; i<children.size(); i++) {
nuclear@4 151 children[i]->update(msec);
nuclear@4 152 }
nuclear@4 153 }
nuclear@4 154
nuclear@4 155
nuclear@4 156 bool SceneNode::intersect(const Ray &ray, RayHit *hit) const
nuclear@4 157 {
nuclear@4 158 Ray local_ray = ray.transformed(inv_xform);
nuclear@4 159
nuclear@4 160 RayHit nearest;
nuclear@4 161 nearest.dist = FLT_MAX;
nuclear@4 162 for(size_t i=0; i<obj.size(); i++) {
nuclear@4 163 if(obj[i]->intersect(local_ray, hit)) {
nuclear@4 164 if(!hit) return true;
nuclear@4 165 if(hit->dist < nearest.dist) {
nuclear@4 166 nearest = *hit;
nuclear@17 167 nearest.node = this;
nuclear@17 168 nearest.local_ray = local_ray;
nuclear@4 169 }
nuclear@4 170 }
nuclear@4 171 }
nuclear@4 172
nuclear@8 173 for(size_t i=0; i<children.size(); i++) {
nuclear@8 174 if(children[i]->intersect(ray, hit)) {
nuclear@8 175 if(!hit) return true;
nuclear@8 176 if(hit->dist < nearest.dist) {
nuclear@8 177 nearest = *hit;
nuclear@8 178 }
nuclear@8 179 }
nuclear@8 180 }
nuclear@8 181
nuclear@4 182 if(nearest.dist < FLT_MAX) {
nuclear@4 183 *hit = nearest;
nuclear@4 184 hit->world_ray = ray;
nuclear@4 185 return true;
nuclear@4 186 }
nuclear@4 187 return false;
nuclear@4 188 }