- 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);
+ return proc_scenefile(scn, node);
+
+ } else if(strcmp(node->name, "remap") == 0) {
+ const char *match = ts_get_attr_str(node, "match");
+ const char *replace = ts_get_attr_str(node, "replace");
+ if(match && replace) {
+ datamap_map(match, replace);
+ }
+ }
+
+ 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) {
+ info_log("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;
+ }
+
+ Scene *newscn = new Scene(scn->texset);
+ if(!(newscn->load(fname, SCNLOAD_FLIPTEX))) { // TODO unhardcode FLIPTEX
+ return false;
+ }
+
+ // extract the walk mesh if necessary
+ Scene *wscn;
+ if(walkmesh_regexp && (wscn = newscn->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(newscn->walk_mesh) {
+ newscn->walk_mesh->append(*m);
+ } else {
+ newscn->walk_mesh = m;
+ wscn->remove_mesh(m); // to save it from destruction
+ }