minor changes (bounds lazy eval state)
[laserbrain_demo] / src / snode.cc
index 101fe62..bce8c0a 100644 (file)
@@ -2,19 +2,25 @@
 #include <assert.h>
 #include <algorithm>
 #include "snode.h"
+#include "objmesh.h"
+#include "dbg_gui.h"
 
 SceneNode::SceneNode()
        : scale(1, 1, 1)
 {
+       scene = 0;
        parent = 0;
        name = 0;
+       bvol_valid = false;
 }
 
 SceneNode::SceneNode(Object *obj)
        : scale(1, 1, 1)
 {
+       scene = 0;
        parent = 0;
        name = 0;
+       bvol_valid = false;
        add_object(obj);
 }
 
@@ -48,6 +54,9 @@ 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)
@@ -58,6 +67,10 @@ bool SceneNode::remove_child(SceneNode *node)
        if(it != children.end()) {
                assert(node->parent == this);
                node->parent = 0;
+               node->scene = 0;
+               children.erase(it);
+
+               bvol_valid = false;
                return true;
        }
        return false;
@@ -88,6 +101,8 @@ void SceneNode::add_object(Object *obj)
 
        this->obj.push_back(obj);
        obj->node = this;
+
+       bvol_valid = false;
 }
 
 bool SceneNode::remove_object(Object *o)
@@ -102,6 +117,8 @@ bool SceneNode::remove_object(Object *o)
                return false;
        }
        obj.erase(it);
+
+       bvol_valid = false;
        return true;
 }
 
@@ -188,13 +205,53 @@ void SceneNode::update_node(float dt)
 
 void SceneNode::update(float dt)
 {
+       bool expanded = false;
+
+       if(debug_gui) {
+               if(parent_expanded) {
+                       int flags = children.empty() ? ImGuiTreeNodeFlags_Leaf : 0;
+                       expanded = ImGui::TreeNodeEx(name ? name : "<nameless node>", flags);
+               }
+       }
+
        update_node(dt);
 
-       for(size_t i=0; i<children.size(); i++) {
+       int num = children.size();
+       for(int i=0; i<num; i++) {
+               parent_expanded = expanded;
                children[i]->update(dt);
        }
+
+       if(debug_gui && expanded) {
+               ImGui::TreePop();
+       }
 }
 
+void SceneNode::apply_xform()
+{
+       update_node();
+
+       // apply post-order to make sure we don't affect the children xform by our reset
+
+       int nchild = children.size();
+       for(int i=0; i<nchild; i++) {
+               children[i]->apply_xform();
+       }
+
+       int nobj = obj.size();
+       for(int i=0; i<nobj; i++) {
+               if(obj[i]->get_type() == OBJ_MESH) {
+                       ObjMesh *om = (ObjMesh*)obj[i];
+                       if(om->mesh) {
+                               om->mesh->apply_xform(xform);
+                       }
+               }
+       }
+
+       pos = Vec3(0, 0, 0);
+       rot = Quat::identity;
+       scale = Vec3(1, 1, 1);
+}
 
 bool SceneNode::intersect(const Ray &ray, HitPoint *hit) const
 {
@@ -229,3 +286,16 @@ bool SceneNode::intersect(const Ray &ray, HitPoint *hit) const
        }
        return false;
 }
+
+const Box &SceneNode::calc_bounds()
+{
+       // TODO
+}
+
+const Box &SceneNode::get_bounds() const
+{
+       if(!bvol_valid) {
+               return ((SceneNode*)this)->calc_bounds();
+       }
+       return bvol;
+}