+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;
+}
+