X-Git-Url: http://git.mutantstargoat.com/user/nuclear/?p=laserbrain_demo;a=blobdiff_plain;f=src%2Fmetascene.cc;h=fd4569b17beaa9b888a2277660952d3951ebb324;hp=53474f76c16ef73f8183254cd5a8a5670aef5132;hb=d29eba477666f0753170d9ad549a4715ce071d04;hpb=68e71418a70dab4174981d5a579e96a9089f8682 diff --git a/src/metascene.cc b/src/metascene.cc index 53474f7..fd4569b 100644 --- a/src/metascene.cc +++ b/src/metascene.cc @@ -1,3 +1,13 @@ +/*! \file + * \brief Metascene implementation + * + * Loading starts at `MetaScene::load`, which calls `ts_load` (libtreestore) + * to load the metascene description tree into memory. Then `proc_node` is + * called at the root to recursively process the tree. `scenefile` nodes are + * handed over to `proc_scenefile`, which will trigger scene loading for any + * nodes with a `file` attribute. Scene loading is handled by requesting the + * filename from the scene resource manager, which is of type [SceneSet](\ref SceneSet). + */ #include #include #include @@ -7,7 +17,7 @@ #include "logger.h" #include "app.h" -#ifdef WIN32 +#if defined(WIN32) || defined(__WIN32__) #include #else #include @@ -22,6 +32,7 @@ struct MaterialEdit { static bool proc_node(MetaScene *mscn, struct ts_node *node); static bool proc_scenefile(MetaScene *mscn, struct ts_node *node); static bool proc_mtledit(MetaScene *mscn, MaterialEdit *med, struct ts_node *node); +static bool proc_music(MetaScene *mscn, struct ts_node *node); static void apply_mtledit(Scene *scn, const MaterialEdit &med); static void apply_mtledit(Material *mtl, const MaterialEdit &med); static struct ts_attr *attr_inscope(struct ts_node *node, const char *name); @@ -32,14 +43,15 @@ static void print_scene_graph(SceneNode *n, int level); MetaScene::MetaScene() { walk_mesh = 0; + music = 0; } MetaScene::~MetaScene() { delete walk_mesh; + delete music; } - bool MetaScene::load(const char *fname) { struct ts_node *root = ts_load(fname); @@ -75,6 +87,57 @@ void MetaScene::draw() const } } +SceneNode *MetaScene::find_node(const char *name) const +{ + int num = scenes.size(); + for(int i=0; ifind_node(name); + if(n) return n; + } + return 0; +} + +SceneNode *MetaScene::match_node(const char *qstr) const +{ + int num = scenes.size(); + for(int i=0; imatch_node(qstr); + if(n) return n; + } + return 0; +} + +std::list MetaScene::match_nodes(const char *qstr) const +{ + std::list res; + int num = scenes.size(); + for(int i=0; i tmp = scenes[i]->match_nodes(qstr); + if(!tmp.empty()) { + res.splice(res.end(), tmp); + } + } + return std::move(res); +} + +Scene *MetaScene::extract_nodes(const char *qstr) +{ + Scene *scn = 0; + int nscn = scenes.size(); + for(int i=0; iextract_nodes(qstr); + if(tmp) { + if(!scn) { + scn = tmp; + } else { + scn->merge(tmp); + delete tmp; + } + } + } + return scn; +} + static bool proc_node(MetaScene *mscn, struct ts_node *node) { struct ts_node *c = node->child_list; @@ -95,6 +158,9 @@ static bool proc_node(MetaScene *mscn, struct ts_node *node) if(match && replace) { mscn->datamap.map(match, replace); } + + } else if(strcmp(node->name, "music") == 0) { + return proc_music(mscn, node); } return true; @@ -108,6 +174,9 @@ struct SceneData { std::vector mtledit; }; +/*! Processes a `scenefile` node. And kicks off scene loading (if necessary) by + * calling `SceneSet::get`. + */ static bool proc_scenefile(MetaScene *mscn, struct ts_node *node) { const char *fname = ts_get_attr_str(node, "file"); @@ -118,10 +187,15 @@ static bool proc_scenefile(MetaScene *mscn, struct ts_node *node) // 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); mscn->datamap.set_path(adpath->val.str); } + // strip path + struct ts_attr *aspath = attr_inscope(node, "strip_path"); + if(aspath && aspath->val.type == TS_NUMBER) { + mscn->datamap.set_strip(aspath->val.inum); + } + // walkmesh struct ts_attr *awmesh = attr_inscope(node, "walkmesh"); if(awmesh && awmesh->val.type == TS_STRING) { @@ -156,7 +230,7 @@ static bool proc_scenefile(MetaScene *mscn, struct ts_node *node) fname = namebuf; } - // material edits + // material edits are kept in a list to be applied when the scene has been loaded struct ts_node *child = node->child_list; while(child) { MaterialEdit medit; @@ -310,6 +384,37 @@ static void apply_mtledit(Scene *scn, const MaterialEdit &med) } } +static bool proc_music(MetaScene *mscn, struct ts_node *node) +{ + const char *fname = ts_get_attr_str(node, "file"); + if(fname) { + SceneData *sdat = new SceneData; + sdat->meta = mscn; + + // datapath + struct ts_attr *adpath = attr_inscope(node, "datapath"); + if(adpath && adpath->val.type == TS_STRING) { + mscn->datamap.set_path(adpath->val.str); + } + + int namesz = mscn->datamap.lookup(fname, 0, 0); + char *namebuf = (char*)alloca(namesz + 1); + if(mscn->datamap.lookup(fname, namebuf, namesz + 1)) { + fname = namebuf; + } + + OggVorbisStream *ovstream = new OggVorbisStream; + if(!ovstream->open(fname)) { + delete ovstream; + return false; + } + + delete mscn->music; + mscn->music = ovstream; + } + return true; +} + static void apply_mtledit(Material *mtl, const MaterialEdit &med) { // TODO more edit modes...