From 332f9dce52862e39afabd50bdce9691de7986921 Mon Sep 17 00:00:00 2001 From: John Tsiombikas Date: Thu, 18 Jan 2018 08:25:19 +0200 Subject: [PATCH] ad-hoc exhibits created by the manager and described with the same file --- src/app.cc | 10 ------- src/blob_exhibit.cc | 2 +- src/exman.cc | 80 +++++++++++++++++++++++++++++++++++++++++---------- src/exman.h | 2 ++ 4 files changed, 68 insertions(+), 26 deletions(-) diff --git a/src/app.cc b/src/app.cc index 8aaaee3..620ec52 100644 --- a/src/app.cc +++ b/src/app.cc @@ -71,7 +71,6 @@ static unsigned int sdr_post_gamma; static long prev_msec; static ExhibitManager *exman; -static BlobExhibit *blobs; static bool show_blobs; ExSelection exsel_active, exsel_hover; @@ -172,15 +171,6 @@ bool app_init(int argc, char **argv) } */ - blobs = new BlobExhibit; - blobs->node = new SceneNode; - blobs->init(); - blobs->node->set_position(Vec3(-680, 160, -100)); - blobs->node->set_scaling(Vec3(28, 28, 28)); - blobs->node->update(0); - - exman->add(blobs); - if(!(sdr_ltmap_notex = create_program_load("sdr/lightmap.v.glsl", "sdr/lightmap-notex.p.glsl"))) { return false; } diff --git a/src/blob_exhibit.cc b/src/blob_exhibit.cc index c92ac7a..35552e4 100644 --- a/src/blob_exhibit.cc +++ b/src/blob_exhibit.cc @@ -189,7 +189,7 @@ void BlobExhibit::draw() const const AABox &BlobExhibit::get_aabox() const { - Box box = Box(priv->vol, node->get_matrix()); + Box box = Box(priv->vol, node ? node->get_matrix() : Mat4::identity); calc_bounding_aabox(&aabb, &box); return aabb; } diff --git a/src/exman.cc b/src/exman.cc index 02f4bc5..d6cac9c 100644 --- a/src/exman.cc +++ b/src/exman.cc @@ -104,6 +104,7 @@ bool ExhibitSlot::detach_exhibit() ExhibitManager::ExhibitManager() { + own_scn = 0; } ExhibitManager::~ExhibitManager() @@ -124,6 +125,8 @@ void ExhibitManager::clear() delete exslots[i]; } exslots.clear(); + + delete own_scn; // this must be the last thing to destroy } void ExhibitManager::add(Exhibit *ex) @@ -153,35 +156,76 @@ bool ExhibitManager::load(MetaScene *mscn, const char *fname) return false; } + // create our own scene to manage all exhibits not already in an existing scene + // and add it to the metascene + if(!own_scn) { + own_scn = new Scene; + own_scn->name = "ad-hoc exhibits"; + mscn->scenes.push_back(own_scn); + } + struct ts_node *iter = root->child_list; while(iter) { struct ts_node *node = iter; iter = iter->next; - if(strcmp(node->name, "item") == 0) { - SceneNode *snode; - - const char *amatch = ts_get_attr_str(node, "match_node"); - if(!amatch || !(snode = mscn->match_node(amatch))) { - error_log("ExhibitManager::load: regexp \"%s\" didn't match any nodes\n", - amatch ? amatch : ""); - continue; - } + SceneNode *snode = 0; + if(strcmp(node->name, "item") == 0) { Exhibit *ex; const char *atype = ts_get_attr_str(node, "type"); if(!atype || !(ex = create_exhibit(atype))) { error_log("failed to create exhibit of type: %s\n", atype); continue; } - ex->set_node(snode); - items.push_back(ex); - const char *alabel = ts_get_attr_str(node, "label"); if(alabel) { ex->set_name(alabel); } + const char *amatch = ts_get_attr_str(node, "match_node"); + if(amatch) { + if(!(snode = mscn->match_node(amatch))) { + error_log("ExhibitManager::load: regexp \"%s\" didn't match any nodes\n", + amatch ? amatch : ""); + continue; + } + } + + if(!snode) { + snode = new SceneNode; + snode->set_name(ex->get_name()); + own_scn->add_node(snode); + } + ex->set_node(snode); + + items.push_back(ex); + + float *apos = ts_get_attr_vec(node, "pos"); + if(apos) { + snode->set_position(Vec3(apos[0], apos[1], apos[2])); + } + float *arot_axis = ts_get_attr_vec(node, "rotaxis"); + if(arot_axis) { + float arot_angle = ts_get_attr_num(node, "rotangle", 0.0f); + Vec3 axis = Vec3(arot_axis[0], arot_axis[1], arot_axis[2]); + Quat q; + q.set_rotation(axis, deg_to_rad(arot_angle)); + snode->set_rotation(q); + } + struct ts_attr *ascale = ts_get_attr(node, "scale"); + if(ascale) { + switch(ascale->val.type) { + case TS_NUMBER: + snode->set_scaling(Vec3(ascale->val.fnum, ascale->val.fnum, ascale->val.fnum)); + break; + case TS_VECTOR: + snode->set_scaling(Vec3(ascale->val.vec[0], ascale->val.vec[1], ascale->val.vec[2])); + default: + break; + } + } + // create a new slot and attach the exhibit to it ExhibitSlot *slot = new ExhibitSlot(ex); exslots.push_back(slot); @@ -280,8 +324,8 @@ void ExhibitManager::update(float dt) int num = items.size(); for(int i=0; inode->get_parent()) { + // node's update function (otherwise it would have been called recursively earlier) + if(items[i]->node && !items[i]->node->get_parent()) { items[i]->node->update(dt); } items[i]->update(dt); @@ -305,7 +349,13 @@ static Exhibit *create_exhibit(const char *type) return new Exhibit; } else if(strcmp(type, "blobs") == 0) { debug_log("creating blobs exhibit\n"); - return new BlobExhibit; + BlobExhibit *b = new BlobExhibit; + if(!b->init()) { + delete b; + error_log("failed to initialize blobs exhibit\n"); + return 0; + } + return b; } error_log("unknown exhibit type: %s\n", type); return 0; diff --git a/src/exman.h b/src/exman.h index bbd72fd..df3d8bd 100644 --- a/src/exman.h +++ b/src/exman.h @@ -38,6 +38,8 @@ private: std::vector exslots; // TODO kdtree of slots for quick nearest queries + Scene *own_scn; // scene to manage all exhibits not taken from an existing scene + public: ExhibitManager(); ~ExhibitManager(); -- 1.7.10.4