simple ubershader system, reflection debugging
[laserbrain_demo] / src / scene.cc
index 651e9c6..10304f6 100644 (file)
@@ -1,23 +1,20 @@
 #include <regex>
 #include "scene.h"
 #include "objmesh.h"
+#include "app.h"
+#include "dbg_gui.h"
 
 static void destroy_node_tree(SceneNode *n);
 
-Scene::Scene(TextureSet *tset)
+Scene::Scene()
 {
        metascn = 0;
        nodes = 0;
 
        walk_mesh = 0;
 
-       if(tset) {
-               texset = tset;
-               own_texset = false;
-       } else {
-               texset = new TextureSet;
-               own_texset = true;
-       }
+       texset = 0;
+       loader_data = 0;
 }
 
 Scene::~Scene()
@@ -27,6 +24,17 @@ Scene::~Scene()
 
 void Scene::destroy()
 {
+       clear();
+
+       metascn = 0;
+       texset = 0;
+       loader_data = 0;
+
+       datamap.clear();
+}
+
+void Scene::clear()
+{
        destroy_node_tree(nodes);
        nodes = 0;
 
@@ -42,11 +50,6 @@ void Scene::destroy()
                delete objects[i];
        }
        objects.clear();
-
-       if(own_texset) {
-               delete texset;
-       }
-       texset = 0;
 }
 
 static void destroy_node_tree(SceneNode *n)
@@ -64,12 +67,6 @@ static void destroy_node_tree(SceneNode *n)
 
 bool Scene::merge(Scene *scn)
 {
-       if(texset != scn->texset) {
-               // TODO handle this properly
-               error_log("for now only able to merge scenes using the same texture set\n");
-               return false;
-       }
-
        if(walk_mesh) {
                if(scn->walk_mesh) {
                        walk_mesh->append(*scn->walk_mesh);
@@ -186,6 +183,35 @@ bool Scene::have_node(SceneNode *n) const
        return n->scene == this;
 }
 
+/* traverse scene graph and find node by name */
+static SceneNode *find_node_rec(SceneNode *tree, const char *name)
+{
+       if(strcmp(tree->get_name(), name) == 0) {
+               return tree;
+       }
+
+       int num = tree->get_num_children();
+       for(int i=0; i<num; i++) {
+               SceneNode *n = find_node_rec(tree->get_child(i), name);
+               if(n) return n;
+       }
+       return 0;
+}
+
+static SceneNode *find_node_rec(SceneNode *tree, const std::regex &re)
+{
+       if(std::regex_match(tree->get_name(), re)) {
+               return tree;
+       }
+
+       int num = tree->get_num_children();
+       for(int i=0; i<num; i++) {
+               SceneNode *n = find_node_rec(tree->get_child(i), re);
+               if(n) return n;
+       }
+       return 0;
+}
+
 static void find_nodes_rec(std::list<SceneNode*> *res, SceneNode *tree, const std::regex &re)
 {
        if(std::regex_match(tree->get_name(), re)) {
@@ -198,8 +224,34 @@ static void find_nodes_rec(std::list<SceneNode*> *res, SceneNode *tree, const st
        }
 }
 
+SceneNode *Scene::find_node(const char *name) const
+{
+       if(!nodes) return 0;
+       return find_node_rec(nodes, name);
+}
+
+SceneNode *Scene::match_node(const char *qstr) const
+{
+       if(!nodes) return 0;
+
+       std::regex re{qstr};
+       return find_node_rec(nodes, re);
+}
+
+std::list<SceneNode*> Scene::match_nodes(const char *qstr) const
+{
+       std::list<SceneNode*> res;
+       if(nodes) {
+               std::regex re{qstr};
+               find_nodes_rec(&res, nodes, re);
+       }
+       return res;
+}
+
 Scene *Scene::extract_nodes(const char *qstr)
 {
+       if(!nodes) return 0;
+
        std::regex re{qstr};
 
        std::list<SceneNode*> nodelist;
@@ -208,7 +260,7 @@ Scene *Scene::extract_nodes(const char *qstr)
                return 0;
        }
 
-       Scene *res = new Scene(texset);
+       Scene *res = new Scene;
 
        for(SceneNode *n : nodelist) {