nuclear@13: #include nuclear@13: #include nuclear@13: #include "snode.h" nuclear@14: #include "min3d.h" nuclear@13: nuclear@13: nuclear@13: SceneNode::SceneNode() nuclear@13: { nuclear@13: parent = 0; nuclear@13: name = 0; nuclear@13: type = NODE_NULL; nuclear@13: scale = Vector3(1, 1, 1); nuclear@13: invalidate(); nuclear@13: } nuclear@13: nuclear@13: SceneNode::~SceneNode() nuclear@13: { nuclear@13: delete [] name; nuclear@13: } nuclear@13: nuclear@13: void SceneNode::set_name(const char *name) nuclear@13: { nuclear@13: this->name = new char[strlen(name) + 1]; nuclear@13: strcpy(this->name, name); nuclear@13: } nuclear@13: nuclear@13: const char *SceneNode::get_name() const nuclear@13: { nuclear@13: return name ? name : ""; nuclear@13: } nuclear@13: nuclear@13: NodeType SceneNode::get_type() const nuclear@13: { nuclear@13: return type; nuclear@13: } nuclear@13: nuclear@13: SceneNode *SceneNode::get_parent() nuclear@13: { nuclear@13: return parent; nuclear@13: } nuclear@13: nuclear@13: const SceneNode *SceneNode::get_parent() const nuclear@13: { nuclear@13: return parent; nuclear@13: } nuclear@13: nuclear@13: void SceneNode::add_child(SceneNode *child) nuclear@13: { nuclear@13: children.push_back(child); nuclear@13: child->parent = this; nuclear@13: invalidate(); nuclear@13: } nuclear@13: nuclear@13: void SceneNode::remove_child(SceneNode *child) nuclear@13: { nuclear@13: // TODO nuclear@13: invalidate(); nuclear@13: } nuclear@13: nuclear@13: int SceneNode::get_children_count() const nuclear@13: { nuclear@13: return (int)children.size(); nuclear@13: } nuclear@13: nuclear@13: SceneNode *SceneNode::get_child(int idx) nuclear@13: { nuclear@13: if(idx >= 0 && idx < get_children_count()) { nuclear@13: return children[idx]; nuclear@13: } nuclear@13: return 0; nuclear@13: } nuclear@13: nuclear@13: const SceneNode *SceneNode::get_child(int idx) const nuclear@13: { nuclear@13: if(idx >= 0 && idx < get_children_count()) { nuclear@13: return children[idx]; nuclear@13: } nuclear@13: return 0; nuclear@13: } nuclear@13: nuclear@13: nuclear@13: nuclear@13: void SceneNode::set_position(const Vector3 &pos) nuclear@13: { nuclear@13: this->pos = pos; nuclear@13: invalidate(); nuclear@13: } nuclear@13: nuclear@13: Vector3 SceneNode::get_node_position() const nuclear@13: { nuclear@13: return pos; nuclear@13: } nuclear@13: nuclear@13: void SceneNode::set_rotation(const Quat &quat) nuclear@13: { nuclear@13: rot = quat; nuclear@13: invalidate(); nuclear@13: } nuclear@13: nuclear@13: Quat SceneNode::get_node_rotation() const nuclear@13: { nuclear@13: return rot; nuclear@13: } nuclear@13: nuclear@13: void SceneNode::set_scaling(const Vector3 &scale) nuclear@13: { nuclear@13: this->scale = scale; nuclear@13: invalidate(); nuclear@13: } nuclear@13: nuclear@13: Vector3 SceneNode::get_node_scaling() const nuclear@13: { nuclear@13: return scale; nuclear@13: } nuclear@13: nuclear@13: // these take hierarchy into account nuclear@13: Vector3 SceneNode::get_position() const nuclear@13: { nuclear@13: return transform(get_matrix(), Vector3(0, 0, 0)); nuclear@13: } nuclear@13: nuclear@13: Quat SceneNode::get_rotation() const nuclear@13: { nuclear@13: if(parent) { nuclear@13: return parent->get_rotation() * rot; nuclear@13: } nuclear@13: return rot; nuclear@13: } nuclear@13: nuclear@13: Vector3 SceneNode::get_scaling() const nuclear@13: { nuclear@13: if(parent) { nuclear@13: return parent->get_scaling() * scale; nuclear@13: } nuclear@13: return scale; nuclear@13: } nuclear@13: nuclear@13: void SceneNode::set_pivot(const Vector3 &pivot) nuclear@13: { nuclear@13: this->pivot = pivot; nuclear@13: invalidate(); nuclear@13: } nuclear@13: nuclear@13: Vector3 SceneNode::get_pivot() const nuclear@13: { nuclear@13: return pivot; nuclear@13: } nuclear@13: nuclear@13: const Matrix4x4 &SceneNode::get_matrix() const nuclear@13: { nuclear@13: calc_matrix(); nuclear@13: return xform; nuclear@13: } nuclear@13: nuclear@13: const Matrix4x4 &SceneNode::get_inv_matrix() const nuclear@13: { nuclear@13: calc_inv_matrix(); nuclear@13: return inv_xform; nuclear@13: } nuclear@13: nuclear@13: void SceneNode::invalidate() const nuclear@13: { nuclear@13: xform_valid = inv_xform_valid = false; nuclear@13: } nuclear@13: nuclear@13: // TODO: hierarchy nuclear@13: void SceneNode::calc_matrix() const nuclear@13: { nuclear@14: if(xform_valid) return; nuclear@14: nuclear@13: xform.set_identity(); nuclear@13: xform.translate(pivot.x, pivot.y, pivot.z); nuclear@13: xform = xform * rot.get_matrix(); nuclear@13: xform.translate(pos.x, pos.y, pos.z); nuclear@13: xform.scale(scale.x, scale.y, scale.z); nuclear@13: xform.translate(-pivot.x, -pivot.y, -pivot.z); nuclear@13: nuclear@13: xform_valid = true; nuclear@13: } nuclear@13: nuclear@13: void SceneNode::calc_inv_matrix() const nuclear@13: { nuclear@14: if(inv_xform_valid) return; nuclear@14: nuclear@13: calc_matrix(); nuclear@13: nuclear@13: inv_xform = xform.inverse(); nuclear@13: inv_xform_valid = true; nuclear@13: } nuclear@13: nuclear@14: void SceneNode::pre_draw() const nuclear@13: { nuclear@14: m3d_matrix_mode(M3D_MODELVIEW); nuclear@14: m3d_push_matrix(); nuclear@17: m3d_mult_transpose_matrix(get_matrix()[0]); nuclear@14: } nuclear@14: nuclear@14: void SceneNode::post_draw() const nuclear@14: { nuclear@14: m3d_matrix_mode(M3D_MODELVIEW); nuclear@14: m3d_pop_matrix(); nuclear@14: } nuclear@14: nuclear@14: void SceneNode::draw(bool emph) const nuclear@14: { nuclear@14: if(emph) { nuclear@14: float avg_scale = (scale.x + scale.y + scale.z) / 3.0; nuclear@14: m3d_push_matrix(); nuclear@14: m3d_scale(avg_scale / scale.x, avg_scale / scale.y, avg_scale / scale.z); nuclear@14: nuclear@14: m3d_begin(M3D_LINES); nuclear@14: m3d_color(1, 0, 0); nuclear@14: m3d_vertex(0, 0, 0); nuclear@14: m3d_vertex(0.5, 0, 0); nuclear@14: m3d_color(0, 1, 0); nuclear@14: m3d_vertex(0, 0, 0); nuclear@14: m3d_vertex(0, 0.5, 0); nuclear@14: m3d_color(0, 0, 1); nuclear@14: m3d_vertex(0, 0, 0); nuclear@14: m3d_vertex(0, 0, 0.5); nuclear@14: m3d_end(); nuclear@14: nuclear@14: m3d_pop_matrix(); nuclear@14: nuclear@14: m3d_color(1, 0.8, 0.1); nuclear@14: } else { nuclear@14: m3d_color(0.9, 0.9, 0.9); nuclear@14: } nuclear@13: } nuclear@13: nuclear@17: bool SceneNode::intersect(const Ray &ray, RayHit *hit) const nuclear@13: { nuclear@13: return false; nuclear@13: }