tavli

diff src/snode.cc @ 3:94aff2ff1934

too much?
author John Tsiombikas <nuclear@member.fsf.org>
date Mon, 22 Jun 2015 21:46:57 +0300
parents
children
line diff
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/src/snode.cc	Mon Jun 22 21:46:57 2015 +0300
     1.3 @@ -0,0 +1,188 @@
     1.4 +#include <float.h>
     1.5 +#include <assert.h>
     1.6 +#include <algorithm>
     1.7 +#include "snode.h"
     1.8 +
     1.9 +SceneNode::SceneNode()
    1.10 +	: scale(1, 1, 1)
    1.11 +{
    1.12 +	parent = 0;
    1.13 +}
    1.14 +
    1.15 +SceneNode::SceneNode(Object *obj)
    1.16 +	: scale(1, 1, 1)
    1.17 +{
    1.18 +	parent = 0;
    1.19 +	add_object(obj);
    1.20 +}
    1.21 +
    1.22 +void SceneNode::add_child(SceneNode *node)
    1.23 +{
    1.24 +	if(node->parent) {
    1.25 +		if(node->parent == this) {
    1.26 +			return;
    1.27 +		}
    1.28 +		node->parent->remove_child(node);
    1.29 +	}
    1.30 +
    1.31 +	children.push_back(node);
    1.32 +	node->parent = this;
    1.33 +}
    1.34 +
    1.35 +bool SceneNode::remove_child(SceneNode *node)
    1.36 +{
    1.37 +	for(size_t i=0; i<children.size(); i++) {
    1.38 +		if(children[i] == node) {
    1.39 +			assert(node->parent == this);
    1.40 +			node->parent = 0;
    1.41 +			return true;
    1.42 +		}
    1.43 +	}
    1.44 +	return false;
    1.45 +}
    1.46 +
    1.47 +int SceneNode::get_num_children() const
    1.48 +{
    1.49 +	return (int)children.size();
    1.50 +}
    1.51 +
    1.52 +SceneNode *SceneNode::get_child(int idx) const
    1.53 +{
    1.54 +	return children[idx];
    1.55 +}
    1.56 +
    1.57 +SceneNode *SceneNode::get_parent() const
    1.58 +{
    1.59 +	return parent;
    1.60 +}
    1.61 +
    1.62 +void SceneNode::add_object(Object *obj)
    1.63 +{
    1.64 +	if(std::find(this->obj.begin(), this->obj.end(), obj) == this->obj.end()) {
    1.65 +		this->obj.push_back(obj);
    1.66 +	}
    1.67 +}
    1.68 +
    1.69 +int SceneNode::get_num_objects() const
    1.70 +{
    1.71 +	return (int)obj.size();
    1.72 +}
    1.73 +
    1.74 +Object *SceneNode::get_object(int idx) const
    1.75 +{
    1.76 +	return obj[idx];
    1.77 +}
    1.78 +
    1.79 +void SceneNode::set_position(const Vector3 &pos)
    1.80 +{
    1.81 +	this->pos = pos;
    1.82 +}
    1.83 +
    1.84 +void SceneNode::set_rotation(const Quaternion &rot)
    1.85 +{
    1.86 +	this->rot = rot;
    1.87 +}
    1.88 +
    1.89 +void SceneNode::set_scaling(const Vector3 &scale)
    1.90 +{
    1.91 +	this->scale = scale;
    1.92 +}
    1.93 +
    1.94 +
    1.95 +const Vector3 &SceneNode::get_node_position() const
    1.96 +{
    1.97 +	return pos;
    1.98 +}
    1.99 +
   1.100 +const Quaternion &SceneNode::get_node_rotation() const
   1.101 +{
   1.102 +	return rot;
   1.103 +}
   1.104 +
   1.105 +const Vector3 &SceneNode::get_node_scaling() const
   1.106 +{
   1.107 +	return scale;
   1.108 +}
   1.109 +
   1.110 +
   1.111 +Vector3 SceneNode::get_position() const
   1.112 +{
   1.113 +	return Vector3(0, 0, 0).transformed(xform);
   1.114 +}
   1.115 +
   1.116 +Quaternion SceneNode::get_rotation() const
   1.117 +{
   1.118 +	return rot;	// TODO
   1.119 +}
   1.120 +
   1.121 +Vector3 SceneNode::get_scaling() const
   1.122 +{
   1.123 +	return scale;	// TODO
   1.124 +}
   1.125 +
   1.126 +const Matrix4x4 &SceneNode::get_matrix() const
   1.127 +{
   1.128 +	return xform;
   1.129 +}
   1.130 +
   1.131 +const Matrix4x4 &SceneNode::get_inv_matrix() const
   1.132 +{
   1.133 +	return inv_xform;
   1.134 +}
   1.135 +
   1.136 +
   1.137 +void SceneNode::update_node(long msec)
   1.138 +{
   1.139 +	xform.reset_identity();
   1.140 +	xform.translate(pos);
   1.141 +	xform.rotate(rot);
   1.142 +	xform.scale(scale);
   1.143 +
   1.144 +	if(parent) {
   1.145 +		xform = parent->xform * xform;
   1.146 +	}
   1.147 +	inv_xform = xform.inverse();
   1.148 +}
   1.149 +
   1.150 +void SceneNode::update(long msec)
   1.151 +{
   1.152 +	update_node(msec);
   1.153 +
   1.154 +	for(size_t i=0; i<children.size(); i++) {
   1.155 +		children[i]->update(msec);
   1.156 +	}
   1.157 +}
   1.158 +
   1.159 +
   1.160 +bool SceneNode::intersect(const Ray &ray, HitPoint *hit) const
   1.161 +{
   1.162 +	Ray local_ray = ray.transformed(inv_xform);
   1.163 +
   1.164 +	HitPoint nearest;
   1.165 +	nearest.dist = FLT_MAX;
   1.166 +	for(size_t i=0; i<obj.size(); i++) {
   1.167 +		if(obj[i]->intersect(local_ray, hit)) {
   1.168 +			if(!hit) return true;
   1.169 +			if(hit->dist < nearest.dist) {
   1.170 +				nearest = *hit;
   1.171 +				nearest.node = this;
   1.172 +			}
   1.173 +		}
   1.174 +	}
   1.175 +
   1.176 +	for(size_t i=0; i<children.size(); i++) {
   1.177 +		if(children[i]->intersect(ray, hit)) {
   1.178 +			if(!hit) return true;
   1.179 +			if(hit->dist < nearest.dist) {
   1.180 +				nearest = *hit;
   1.181 +			}
   1.182 +		}
   1.183 +	}
   1.184 +
   1.185 +	if(nearest.dist < FLT_MAX) {
   1.186 +		*hit = nearest;
   1.187 +		hit->ray = ray;
   1.188 +		return true;
   1.189 +	}
   1.190 +	return false;
   1.191 +}