# HG changeset patch # User John Tsiombikas # Date 1434998817 -10800 # Node ID 94aff2ff193476e18aea608a7422059ff5fec058 # Parent 893192aea0990bb8677b3cd637451db960e76acf too much? diff -r 893192aea099 -r 94aff2ff1934 src/geom.h --- a/src/geom.h Mon Jun 22 05:15:39 2015 +0300 +++ b/src/geom.h Mon Jun 22 21:46:57 2015 +0300 @@ -4,12 +4,15 @@ #include "vmath/vmath.h" class GeomObject; +class SceneNode; struct HitPoint { float dist; //< parametric distance along the ray Vector3 pos; //< position of intersection (orig + dir * dist) Vector3 normal; //< normal at the point of intersection const void *obj; //< pointer to the intersected object + const SceneNode *node; + Ray ray; }; class GeomObject { diff -r 893192aea099 -r 94aff2ff1934 src/object.cc --- a/src/object.cc Mon Jun 22 05:15:39 2015 +0300 +++ b/src/object.cc Mon Jun 22 21:46:57 2015 +0300 @@ -43,3 +43,8 @@ glPopMatrix(); } + +bool Object::intersect(const Ray &ray, HitPoint *hit) const +{ + return false; // TODO +} diff -r 893192aea099 -r 94aff2ff1934 src/object.h --- a/src/object.h Mon Jun 22 05:15:39 2015 +0300 +++ b/src/object.h Mon Jun 22 21:46:57 2015 +0300 @@ -2,6 +2,7 @@ #define OBJECT_H_ #include "mesh.h" +#include "geom.h" class Object { private: @@ -19,6 +20,8 @@ Mesh *get_mesh() const; void draw() const; + + bool intersect(const Ray &ray, HitPoint *hit) const; }; #endif // OBJECT_H_ diff -r 893192aea099 -r 94aff2ff1934 src/snode.cc --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/snode.cc Mon Jun 22 21:46:57 2015 +0300 @@ -0,0 +1,188 @@ +#include +#include +#include +#include "snode.h" + +SceneNode::SceneNode() + : scale(1, 1, 1) +{ + parent = 0; +} + +SceneNode::SceneNode(Object *obj) + : scale(1, 1, 1) +{ + parent = 0; + add_object(obj); +} + +void SceneNode::add_child(SceneNode *node) +{ + if(node->parent) { + if(node->parent == this) { + return; + } + node->parent->remove_child(node); + } + + children.push_back(node); + node->parent = this; +} + +bool SceneNode::remove_child(SceneNode *node) +{ + for(size_t i=0; iparent == this); + node->parent = 0; + return true; + } + } + return false; +} + +int SceneNode::get_num_children() const +{ + return (int)children.size(); +} + +SceneNode *SceneNode::get_child(int idx) const +{ + return children[idx]; +} + +SceneNode *SceneNode::get_parent() const +{ + return parent; +} + +void SceneNode::add_object(Object *obj) +{ + if(std::find(this->obj.begin(), this->obj.end(), obj) == this->obj.end()) { + this->obj.push_back(obj); + } +} + +int SceneNode::get_num_objects() const +{ + return (int)obj.size(); +} + +Object *SceneNode::get_object(int idx) const +{ + return obj[idx]; +} + +void SceneNode::set_position(const Vector3 &pos) +{ + this->pos = pos; +} + +void SceneNode::set_rotation(const Quaternion &rot) +{ + this->rot = rot; +} + +void SceneNode::set_scaling(const Vector3 &scale) +{ + this->scale = scale; +} + + +const Vector3 &SceneNode::get_node_position() const +{ + return pos; +} + +const Quaternion &SceneNode::get_node_rotation() const +{ + return rot; +} + +const Vector3 &SceneNode::get_node_scaling() const +{ + return scale; +} + + +Vector3 SceneNode::get_position() const +{ + return Vector3(0, 0, 0).transformed(xform); +} + +Quaternion SceneNode::get_rotation() const +{ + return rot; // TODO +} + +Vector3 SceneNode::get_scaling() const +{ + return scale; // TODO +} + +const Matrix4x4 &SceneNode::get_matrix() const +{ + return xform; +} + +const Matrix4x4 &SceneNode::get_inv_matrix() const +{ + return inv_xform; +} + + +void SceneNode::update_node(long msec) +{ + xform.reset_identity(); + xform.translate(pos); + xform.rotate(rot); + xform.scale(scale); + + if(parent) { + xform = parent->xform * xform; + } + inv_xform = xform.inverse(); +} + +void SceneNode::update(long msec) +{ + update_node(msec); + + for(size_t i=0; iupdate(msec); + } +} + + +bool SceneNode::intersect(const Ray &ray, HitPoint *hit) const +{ + Ray local_ray = ray.transformed(inv_xform); + + HitPoint nearest; + nearest.dist = FLT_MAX; + for(size_t i=0; iintersect(local_ray, hit)) { + if(!hit) return true; + if(hit->dist < nearest.dist) { + nearest = *hit; + nearest.node = this; + } + } + } + + for(size_t i=0; iintersect(ray, hit)) { + if(!hit) return true; + if(hit->dist < nearest.dist) { + nearest = *hit; + } + } + } + + if(nearest.dist < FLT_MAX) { + *hit = nearest; + hit->ray = ray; + return true; + } + return false; +} diff -r 893192aea099 -r 94aff2ff1934 src/snode.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/snode.h Mon Jun 22 21:46:57 2015 +0300 @@ -0,0 +1,60 @@ +#ifndef SNODE_H_ +#define SNODE_H_ + +#include +#include "object.h" +#include "vmath/vmath.h" +#include "geom.h" + +class SceneNode { +private: + Vector3 pos; + Quaternion rot; + Vector3 scale; + + std::vector obj; + + SceneNode *parent; + std::vector children; + + Matrix4x4 xform; + Matrix4x4 inv_xform; + +public: + SceneNode(); + explicit SceneNode(Object *obj); + + void add_child(SceneNode *node); + bool remove_child(SceneNode *node); + + int get_num_children() const; + SceneNode *get_child(int idx) const; + + SceneNode *get_parent() const; + + void add_object(Object *obj); + int get_num_objects() const; + Object *get_object(int idx) const; + + void set_position(const Vector3 &pos); + void set_rotation(const Quaternion &rot); + void set_scaling(const Vector3 &scale); + + const Vector3 &get_node_position() const; + const Quaternion &get_node_rotation() const; + const Vector3 &get_node_scaling() const; + + Vector3 get_position() const; + Quaternion get_rotation() const; + Vector3 get_scaling() const; + + const Matrix4x4 &get_matrix() const; + const Matrix4x4 &get_inv_matrix() const; + + void update_node(long msec = 0); + void update(long msec = 0); + + bool intersect(const Ray &ray, HitPoint *hit) const; +}; + +#endif // SNODE_H_