X-Git-Url: http://git.mutantstargoat.com/user/nuclear/?p=laserbrain_demo;a=blobdiff_plain;f=src%2Fsnode.cc;h=8305302ce0a6ae8389d08ab15d74b9e781f67a56;hp=bce8c0a4c42cbd995c91f8ee578d5702354fbf8e;hb=2fd19c29d765f973a757807d4e051e09495b47b4;hpb=82a1d96d9a18e94ccdc13b4bda0c470e81e70768 diff --git a/src/snode.cc b/src/snode.cc index bce8c0a..8305302 100644 --- a/src/snode.cc +++ b/src/snode.cc @@ -11,7 +11,8 @@ SceneNode::SceneNode() scene = 0; parent = 0; name = 0; - bvol_valid = false; + visible = true; + local_bvol_valid = false; } SceneNode::SceneNode(Object *obj) @@ -20,7 +21,8 @@ SceneNode::SceneNode(Object *obj) scene = 0; parent = 0; name = 0; - bvol_valid = false; + visible = true; + local_bvol_valid = false; add_object(obj); } @@ -55,8 +57,6 @@ void SceneNode::add_child(SceneNode *node) children.push_back(node); node->parent = this; node->scene = scene; - - bvol_valid = false; } bool SceneNode::remove_child(SceneNode *node) @@ -69,8 +69,6 @@ bool SceneNode::remove_child(SceneNode *node) node->parent = 0; node->scene = 0; children.erase(it); - - bvol_valid = false; return true; } return false; @@ -91,6 +89,18 @@ SceneNode *SceneNode::get_parent() const return parent; } +SceneNode *SceneNode::find_object_node() const +{ + if(!obj.empty()) return (SceneNode*)this; + + int numc = get_num_children(); + for(int i=0; ifind_object_node(); + if(n) return n; + } + return 0; +} + void SceneNode::add_object(Object *obj) { if(obj->node == this) return; @@ -102,7 +112,7 @@ void SceneNode::add_object(Object *obj) this->obj.push_back(obj); obj->node = this; - bvol_valid = false; + local_bvol_valid = false; } bool SceneNode::remove_object(Object *o) @@ -118,7 +128,7 @@ bool SceneNode::remove_object(Object *o) } obj.erase(it); - bvol_valid = false; + local_bvol_valid = false; return true; } @@ -166,17 +176,17 @@ const Vec3 &SceneNode::get_node_scaling() const Vec3 SceneNode::get_position() const { - return xform * Vec3(0, 0, 0); + return xform.get_translation(); } Quat SceneNode::get_rotation() const { - return rot; // TODO + return xform.get_rotation(); } Vec3 SceneNode::get_scaling() const { - return scale; // TODO + return xform.get_scaling(); } const Mat4 &SceneNode::get_matrix() const @@ -209,8 +219,77 @@ void SceneNode::update(float dt) if(debug_gui) { if(parent_expanded) { - int flags = children.empty() ? ImGuiTreeNodeFlags_Leaf : 0; + ImGui::PushID(this); + ImGui::AlignTextToFramePadding(); + + int flags = ImGuiTreeNodeFlags_OpenOnArrow | ImGuiTreeNodeFlags_OpenOnDoubleClick; + if(children.empty()) flags |= ImGuiTreeNodeFlags_Leaf; + if(dbg_sel_node == this) flags |= ImGuiTreeNodeFlags_Selected; expanded = ImGui::TreeNodeEx(name ? name : "", flags); + if(ImGui::IsItemClicked()) { + dbg_sel_node = this; + } + + ImGui::NextColumn(); + ImGui::Checkbox("##vis", &visible); + ImGui::SameLine(); + if(ImGui::Button("xform")) { + ImGui::OpenPopup("xform_popup"); + } + ImGui::SameLine(); + if(ImGui::Button("bbox")) { + ImGui::OpenPopup("bbox_popup"); + } + if(ImGui::BeginPopup("xform_popup")) { + ImGui::Text("Local transform"); + Vec3 p = get_node_position(); + ImGui::BulletText("P: %g %g %g", p.x, p.y, p.z); + Quat q = get_node_rotation(); + ImGui::BulletText("R: %g %g %g %g", q.x, q.y, q.z, q.w); + Vec3 s = get_node_scaling(); + ImGui::BulletText("S: %g %g %g", s.x, s.y, s.z); + + ImGui::Separator(); + ImGui::Text("Global transform"); + p = get_position(); + ImGui::BulletText("P: %g %g %g", p.x, p.y, p.z); + q = get_rotation(); + ImGui::BulletText("R: %g %g %g %g", q.x, q.y, q.z, q.w); + s = get_scaling(); + ImGui::BulletText("S: %g %g %g", s.x, s.y, s.z); + + const Mat4 &mat = get_matrix(); + ImGui::BulletText("| %3.3f %3.3f %3.3f %3.3f |", mat[0][0], mat[0][1], mat[0][2], mat[0][3]); + ImGui::BulletText("| %3.3f %3.3f %3.3f %3.3f |", mat[1][0], mat[1][1], mat[1][2], mat[1][3]); + ImGui::BulletText("| %3.3f %3.3f %3.3f %3.3f |", mat[2][0], mat[2][1], mat[2][2], mat[2][3]); + ImGui::BulletText("| %3.3f %3.3f %3.3f %3.3f |", mat[3][0], mat[3][1], mat[3][2], mat[3][3]); + + ImGui::EndPopup(); + } + if(ImGui::BeginPopup("bbox_popup")) { + AABox bloc = get_local_bounds(); + ImGui::Text("Local bounds:"); + if(bloc.max.x < bloc.min.x || bloc.max.y < bloc.min.y || bloc.max.z < bloc.min.z) { + ImGui::BulletText("invalid"); + } else { + ImGui::BulletText("X: %f - %f", bloc.min.x, bloc.max.x); + ImGui::BulletText("Y: %f - %f", bloc.min.y, bloc.max.y); + ImGui::BulletText("Z: %f - %f", bloc.min.z, bloc.max.z); + } + ImGui::Separator(); + AABox bbox = get_bounds(); + ImGui::Text("Global bounds:"); + if(bbox.max.x < bbox.min.x || bbox.max.y < bbox.min.y || bbox.max.z < bbox.min.z) { + ImGui::BulletText("invalid"); + } else { + ImGui::BulletText("X: %f - %f", bbox.min.x, bbox.max.x); + ImGui::BulletText("Y: %f - %f", bbox.min.y, bbox.max.y); + ImGui::BulletText("Z: %f - %f", bbox.min.z, bbox.max.z); + } + ImGui::EndPopup(); + } + ImGui::NextColumn(); + ImGui::PopID(); } } @@ -287,15 +366,54 @@ bool SceneNode::intersect(const Ray &ray, HitPoint *hit) const return false; } -const Box &SceneNode::calc_bounds() +const AABox &SceneNode::calc_local_bounds() +{ + local_bvol = AABox(Vec3(FLT_MAX, FLT_MAX, FLT_MAX), Vec3(-FLT_MAX, -FLT_MAX, -FLT_MAX)); + + // calculate the axis-aligned bounding box of all objects in this node + int nobj = obj.size(); + for(int i=0; iget_aabox(); + calc_bounding_aabox(&local_bvol, &local_bvol, &tmp); + } + + local_bvol_valid = true; + return local_bvol; +} + +const AABox &SceneNode::get_local_bounds() const +{ + if(!local_bvol_valid) { + ((SceneNode*)this)->calc_local_bounds(); + } + return local_bvol; +} + +AABox SceneNode::get_node_bounds() const { - // TODO + get_local_bounds(); // validate local_bvol + + // calculate the transformed local_bvol + Box node_bbox = Box(local_bvol, xform); + + // then calculate the axis-aligned bounding box + AABox aabox; + calc_bounding_aabox(&aabox, &node_bbox); + return aabox; } -const Box &SceneNode::get_bounds() const +AABox SceneNode::get_bounds() const { - if(!bvol_valid) { - return ((SceneNode*)this)->calc_bounds(); + AABox sub_aabb = AABox(Vec3(FLT_MAX, FLT_MAX, FLT_MAX), Vec3(-FLT_MAX, -FLT_MAX, -FLT_MAX)); + + // calculate the bounding box of all children + int nchild = children.size(); + for(int i=0; iget_bounds(); + calc_bounding_aabox(&sub_aabb, &sub_aabb, &tmp); } - return bvol; + + AABox aabb = get_node_bounds(); + calc_bounding_aabox(&aabb, &aabb, &sub_aabb); + return aabb; }