nuclear@4: #include nuclear@4: #include nuclear@4: #include nuclear@4: #include "snode.h" nuclear@4: nuclear@4: SceneNode::SceneNode() nuclear@4: : scale(1, 1, 1) nuclear@4: { nuclear@4: parent = 0; nuclear@4: } nuclear@4: nuclear@4: SceneNode::SceneNode(Object *obj) nuclear@4: : scale(1, 1, 1) nuclear@4: { nuclear@4: parent = 0; nuclear@4: add_object(obj); nuclear@4: } nuclear@4: nuclear@4: void SceneNode::add_child(SceneNode *node) nuclear@4: { nuclear@4: if(node->parent) { nuclear@4: if(node->parent == this) { nuclear@4: return; nuclear@4: } nuclear@4: node->parent->remove_child(node); nuclear@4: } nuclear@4: nuclear@4: children.push_back(node); nuclear@4: node->parent = this; nuclear@4: } nuclear@4: nuclear@4: bool SceneNode::remove_child(SceneNode *node) nuclear@4: { nuclear@4: auto it = std::find(children.begin(), children.end(), node); nuclear@4: if(it != children.end()) { nuclear@4: assert(node->parent == this); nuclear@4: node->parent = 0; nuclear@4: return true; nuclear@4: } nuclear@4: return false; nuclear@4: } nuclear@4: nuclear@4: int SceneNode::get_num_children() const nuclear@4: { nuclear@4: return (int)children.size(); nuclear@4: } nuclear@4: nuclear@4: SceneNode *SceneNode::get_child(int idx) const nuclear@4: { nuclear@4: return children[idx]; nuclear@4: } nuclear@4: nuclear@4: SceneNode *SceneNode::get_parent() const nuclear@4: { nuclear@4: return parent; nuclear@4: } nuclear@4: nuclear@4: void SceneNode::add_object(Object *obj) nuclear@4: { nuclear@4: if(std::find(this->obj.begin(), this->obj.end(), obj) == this->obj.end()) { nuclear@4: this->obj.push_back(obj); nuclear@4: } nuclear@4: } nuclear@4: nuclear@4: int SceneNode::get_num_objects() const nuclear@4: { nuclear@4: return (int)obj.size(); nuclear@4: } nuclear@4: nuclear@4: Object *SceneNode::get_object(int idx) const nuclear@4: { nuclear@4: return obj[idx]; nuclear@4: } nuclear@4: nuclear@4: void SceneNode::set_position(const Vector3 &pos) nuclear@4: { nuclear@4: this->pos = pos; nuclear@4: } nuclear@4: nuclear@4: void SceneNode::set_rotation(const Quaternion &rot) nuclear@4: { nuclear@4: this->rot = rot; nuclear@4: } nuclear@4: nuclear@4: void SceneNode::set_scaling(const Vector3 &scale) nuclear@4: { nuclear@4: this->scale = scale; nuclear@4: } nuclear@4: nuclear@4: nuclear@4: const Vector3 &SceneNode::get_node_position() const nuclear@4: { nuclear@4: return pos; nuclear@4: } nuclear@4: nuclear@4: const Quaternion &SceneNode::get_node_rotation() const nuclear@4: { nuclear@4: return rot; nuclear@4: } nuclear@4: nuclear@4: const Vector3 &SceneNode::get_node_scaling() const nuclear@4: { nuclear@4: return scale; nuclear@4: } nuclear@4: nuclear@4: nuclear@4: Vector3 SceneNode::get_position() const nuclear@4: { nuclear@4: return Vector3{0, 0, 0}.transformed(xform); nuclear@4: } nuclear@4: nuclear@4: Quaternion SceneNode::get_rotation() const nuclear@4: { nuclear@4: return rot; // TODO nuclear@4: } nuclear@4: nuclear@4: Vector3 SceneNode::get_scaling() const nuclear@4: { nuclear@4: return scale; // TODO nuclear@4: } nuclear@4: nuclear@4: nuclear@4: void SceneNode::update_node(long msec) nuclear@4: { nuclear@4: xform.reset_identity(); nuclear@4: xform.translate(pos); nuclear@4: xform.rotate(rot); nuclear@4: xform.scale(scale); nuclear@4: nuclear@4: if(parent) { nuclear@4: xform = parent->xform * xform; nuclear@4: } nuclear@4: inv_xform = xform.inverse(); nuclear@4: } nuclear@4: nuclear@4: void SceneNode::update(long msec) nuclear@4: { nuclear@4: update_node(msec); nuclear@4: nuclear@4: for(size_t i=0; iupdate(msec); nuclear@4: } nuclear@4: } nuclear@4: nuclear@4: nuclear@4: bool SceneNode::intersect(const Ray &ray, RayHit *hit) const nuclear@4: { nuclear@4: Ray local_ray = ray.transformed(inv_xform); nuclear@4: nuclear@4: RayHit nearest; nuclear@4: nearest.dist = FLT_MAX; nuclear@4: for(size_t i=0; iintersect(local_ray, hit)) { nuclear@4: if(!hit) return true; nuclear@4: if(hit->dist < nearest.dist) { nuclear@4: nearest = *hit; nuclear@4: } nuclear@4: } nuclear@4: } nuclear@4: nuclear@4: if(nearest.dist < FLT_MAX) { nuclear@4: *hit = nearest; nuclear@4: hit->local_ray = local_ray; nuclear@4: hit->world_ray = ray; nuclear@4: return true; nuclear@4: } nuclear@4: return false; nuclear@4: }