metadata, walk polygons, stuff...
[laserbrain_demo] / src / metascene.cc
index 99a9daf..aae7482 100644 (file)
 #endif
 
 static bool proc_node(Scene *scn, struct ts_node *node);
+static bool proc_scenefile(Scene *scn, struct ts_node *node);
 static struct ts_attr *attr_inscope(struct ts_node *node, const char *name);
 
+static void print_scene_graph(SceneNode *n, int level);
+
 bool load_scene(Scene *scn, const char *fname)
 {
        struct ts_node *root = ts_load(fname);
@@ -23,6 +26,10 @@ bool load_scene(Scene *scn, const char *fname)
 
        bool res = proc_node(scn, root);
        ts_free_tree(root);
+
+       printf("loaded scene: %s\n", fname);
+       printf("scene graph:\n");
+       print_scene_graph(scn->nodes, 0);
        return res;
 }
 
@@ -38,25 +45,7 @@ static bool proc_node(Scene *scn, struct ts_node *node)
 
        // do this last to allow other contents of the node to do their thing
        if(strcmp(node->name, "scenefile") == 0) {
-               const char *fname = ts_get_attr_str(node, "file");
-               if(fname) {
-                       struct ts_attr *adpath = attr_inscope(node, "datapath");
-                       if(adpath && adpath->val.type == TS_STRING) {
-                               printf("adding data path: %s\n", adpath->val.str);
-                               datamap_set_path(adpath->val.str);
-                       }
-
-                       int namesz = datamap_lookup(fname, 0, 0);
-                       char *namebuf = (char*)alloca(namesz + 1);
-                       if(datamap_lookup(fname, namebuf, namesz + 1)) {
-                               fname = namebuf;
-                       }
-
-                       if(!(scn->load(fname, SCNLOAD_FLIPTEX))) {
-                               return false;
-                       }
-               }
-               datamap_reset();
+               return proc_scenefile(scn, node);
 
        } else if(strcmp(node->name, "remap") == 0) {
                const char *match = ts_get_attr_str(node, "match");
@@ -69,6 +58,61 @@ static bool proc_node(Scene *scn, struct ts_node *node)
        return true;
 }
 
+static bool proc_scenefile(Scene *scn, struct ts_node *node)
+{
+       const char *fname = ts_get_attr_str(node, "file");
+       if(fname) {
+               // datapath
+               struct ts_attr *adpath = attr_inscope(node, "datapath");
+               if(adpath && adpath->val.type == TS_STRING) {
+                       printf("adding data path: %s\n", adpath->val.str);
+                       datamap_set_path(adpath->val.str);
+               }
+
+               // walkmesh
+               char *walkmesh_regexp = 0;
+               struct ts_attr *awmesh = attr_inscope(node, "walkmesh");
+               if(awmesh && awmesh->val.type == TS_STRING) {
+                       walkmesh_regexp = awmesh->val.str;
+               }
+
+               int namesz = datamap_lookup(fname, 0, 0);
+               char *namebuf = (char*)alloca(namesz + 1);
+               if(datamap_lookup(fname, namebuf, namesz + 1)) {
+                       fname = namebuf;
+               }
+
+               if(!(scn->load(fname, SCNLOAD_FLIPTEX))) {
+                       return false;
+               }
+
+               // extract the walk mesh if necessary
+               // XXX as written, this will match even objects loaded by previous scenefile blocks
+               Scene *wscn;
+               if(walkmesh_regexp && (wscn = scn->extract_nodes(walkmesh_regexp))) {
+                       // apply all transformations to the meshes
+                       wscn->apply_xform();
+
+                       int nmeshes = wscn->meshes.size();
+                       for(int i=0; i<nmeshes; i++) {
+                               Mesh *m = wscn->meshes[i];
+
+                               if(scn->walk_mesh) {
+                                       scn->walk_mesh->append(*m);
+                               } else {
+                                       scn->walk_mesh = m;
+                                       wscn->remove_mesh(m);   // to save it from destruction
+                               }
+                       }
+
+                       delete wscn;
+               }
+       }
+       datamap_reset();
+
+       return true;
+}
+
 static struct ts_attr *attr_inscope(struct ts_node *node, const char *name)
 {
        struct ts_attr *attr = 0;
@@ -78,3 +122,23 @@ static struct ts_attr *attr_inscope(struct ts_node *node, const char *name)
        }
        return attr;
 }
+
+static void print_scene_graph(SceneNode *n, int level)
+{
+       if(!n) return;
+
+       for(int i=0; i<level; i++) {
+               fputs("  ", stdout);
+       }
+
+       int nobj = n->get_num_objects();
+       if(nobj) {
+               printf("%s - %d obj\n", n->get_name(), n->get_num_objects());
+       } else {
+               printf("%s\n", n->get_name());
+       }
+
+       for(int i=0; i<n->get_num_children(); i++) {
+               print_scene_graph(n->get_child(i), level + 1);
+       }
+}