metascene initial implementation
authorJohn Tsiombikas <nuclear@mutantstargoat.com>
Sun, 13 Nov 2016 19:20:13 +0000 (21:20 +0200)
committerJohn Tsiombikas <nuclear@mutantstargoat.com>
Sun, 13 Nov 2016 19:20:13 +0000 (21:20 +0200)
Makefile
src/app.cc
src/datamap.cc
src/metascene.cc [new file with mode: 0644]
src/metascene.h [new file with mode: 0644]

index 82b42ca..71b98f1 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -14,7 +14,7 @@ warn = -pedantic -Wall
 
 CFLAGS = $(warn) $(opt) $(dbg) $(incpath)
 CXXFLAGS = -std=c++11 $(warn) $(opt) $(dbg) $(incpath)
-LDFLAGS = $(libpath) $(libgl_$(sys)) -lm -lgmath -lvmath -limago -lresman -lpthread -lassimp
+LDFLAGS = $(libpath) $(libgl_$(sys)) -lm -lgmath -lvmath -limago -lresman -lpthread -lassimp -ltreestore
 
 sys = $(shell uname -s)
 libgl_Linux = -lGL -lGLU -lglut -lGLEW
index 6cb808c..2501415 100644 (file)
@@ -7,6 +7,7 @@
 #include "mesh.h"
 #include "meshgen.h"
 #include "scene.h"
+#include "metascene.h"
 #include "datamap.h"
 
 static void draw_scene();
@@ -44,41 +45,23 @@ bool app_init()
        float ambient[] = {0.0, 0.0, 0.0, 0.0};
        glLightModelfv(GL_LIGHT_MODEL_AMBIENT, ambient);
 
+       scn = new Scene(&texman);
+       if(!load_scene(scn, "data/museum.scene")) {
+               return false;
+       }
+
+       /*
        datamap_set_path("data");
        if(!datamap_load_map("data.map")) {
                fprintf(stderr, "failed to load datafile mappings\n");
        }
 
        unsigned int sflags = SCNLOAD_FLIPTEX;
-       scn = new Scene(&texman);
        if(!(scn->load("data/testscene/patoma.fbx", sflags)) ||
                        !(scn->load("data/testscene/kolones.fbx", sflags))) {
                fprintf(stderr, "failed to load test scene\n");
                return false;
        }
-
-       // hardcoded texture assignment hack
-       Texture *tex_kolones_lightmap = texman.get_texture("data/testscene/kolones_lighmap.jpg", TEX_2D);
-       Texture *tex_patoma_lightmap = texman.get_texture("data/testscene/patomacorona_lightmap.jpg", TEX_2D);
-
-       /*
-       for(int i=0; i<(int)scn->objects.size(); i++) {
-               Object *obj = scn->objects[i];
-               if(obj->mtl.name == "WiteMarble") {
-                       obj->mtl.add_texture(tex_patoma_lightmap, MTL_TEX_LIGHTMAP);
-               } else if(obj->mtl.name == "BrownMarble") {
-                       obj->mtl.add_texture(tex_patoma_lightmap, MTL_TEX_LIGHTMAP);
-               } else if(obj->mtl.name == "GiroGiroMarmaro") {
-                       obj->mtl.add_texture(tex_patoma_lightmap, MTL_TEX_LIGHTMAP);
-               } else if(obj->mtl.name == "KentrikoKafeMarmaro") {
-                       obj->mtl.add_texture(tex_patoma_lightmap, MTL_TEX_LIGHTMAP);
-
-               } else if(obj->mtl.name == "SkouroGrizoMarmaro") {
-                       obj->mtl.add_texture(tex_kolones_lightmap, MTL_TEX_LIGHTMAP);
-               } else if(obj->mtl.name == "PalioMarmaro") {
-                       obj->mtl.add_texture(tex_kolones_lightmap, MTL_TEX_LIGHTMAP);
-               }
-       }
        */
 
        if(!(sdr = create_program_load("sdr/test.v.glsl", "sdr/test.p.glsl"))) {
index 19aaf44..ee7de51 100644 (file)
@@ -112,7 +112,7 @@ int datamap_lookup(const char *in, char *buf, int bsz)
                res = it->second;
        } else {
                // try matching with the available mappings
-               res = std::string(in);
+               res = root.empty() ? std::string(in) : root + "/" + std::string(in);
 
                int num = dmap.size();
                for(int i=0; i<num; i++) {
@@ -130,7 +130,7 @@ int datamap_lookup(const char *in, char *buf, int bsz)
        if(buf) {
                int n = std::min(bsz - 1, (int)res.length());
                memcpy(buf, res.c_str(), n);
-               buf[bsz - 1] = 0; // make sure it's null-terminated even if it got truncated
+               buf[n] = 0; // make sure it's null-terminated even if it got truncated
        }
        return res.length() + 1;
 }
diff --git a/src/metascene.cc b/src/metascene.cc
new file mode 100644 (file)
index 0000000..99a9daf
--- /dev/null
@@ -0,0 +1,80 @@
+#include "metascene.h"
+#include "scene.h"
+#include "datamap.h"
+#include "treestore.h"
+
+#ifdef WIN32
+#include <malloc.h>
+#else
+#include <alloca.h>
+#endif
+
+static bool proc_node(Scene *scn, struct ts_node *node);
+static struct ts_attr *attr_inscope(struct ts_node *node, const char *name);
+
+bool load_scene(Scene *scn, const char *fname)
+{
+       struct ts_node *root = ts_load(fname);
+       if(!root || strcmp(root->name, "scene") != 0) {
+               ts_free_tree(root);
+               fprintf(stderr, "failed to load scene metadata: %s\n", fname);
+               return false;
+       }
+
+       bool res = proc_node(scn, root);
+       ts_free_tree(root);
+       return res;
+}
+
+static bool proc_node(Scene *scn, struct ts_node *node)
+{
+       struct ts_node *c = node->child_list;
+       while(c) {
+               if(!proc_node(scn, c)) {
+                       return false;
+               }
+               c = c->next;
+       }
+
+       // 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();
+
+       } 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 struct ts_attr *attr_inscope(struct ts_node *node, const char *name)
+{
+       struct ts_attr *attr = 0;
+
+       while(node && !(attr = ts_get_attr(node, name))) {
+               node = node->parent;
+       }
+       return attr;
+}
diff --git a/src/metascene.h b/src/metascene.h
new file mode 100644 (file)
index 0000000..8d512eb
--- /dev/null
@@ -0,0 +1,8 @@
+#ifndef METASCENE_H_
+#define METASCENE_H_
+
+class Scene;
+
+bool load_scene(Scene *scn, const char *fname);
+
+#endif // METASCENE_H_