From: John Tsiombikas Date: Fri, 1 Sep 2017 00:10:17 +0000 (+0300) Subject: Merge branch 'master' of goat:git/laserbrain_demo X-Git-Url: http://git.mutantstargoat.com/user/nuclear/?p=laserbrain_demo;a=commitdiff_plain;h=c77ee2a7256ffdb3aac158955178c372de349a1e;hp=a16a1a6cb3d831842f75e13653934360db617097 Merge branch 'master' of goat:git/laserbrain_demo --- diff --git a/.gitignore b/.gitignore index e377c0e..0d79523 100644 --- a/.gitignore +++ b/.gitignore @@ -5,6 +5,9 @@ demo data/ .clang_complete *.suo +*.user *sdf +*.dll +*.exe Debug/ Release/ diff --git a/Makefile b/Makefile index 959c10f..4b65ac3 100644 --- a/Makefile +++ b/Makefile @@ -4,7 +4,7 @@ obj = $(src:.cc=.o) $(csrc:.c=.o) dep = $(obj:.o=.d) bin = demo -opt = -O3 -ffast-math +#opt = -O3 -ffast-math dbg = -g incpath = -Isrc -Isrc/machine -I/usr/local/include `pkg-config --cflags sdl2` @@ -14,16 +14,20 @@ 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 -ltreestore -ldrawtext -loptcfg -lgoatvr `pkg-config --libs sdl2` +LDFLAGS = $(libpath) -ldrawtext $(libgl_$(sys)) -lm -lgmath -lvmath -limago \ + -lresman -lpthread -lassimp -ltreestore -lgoatvr \ + -lz -lpng -ljpeg `pkg-config --libs sdl2 freetype2` sys = $(shell uname -s | sed 's/MINGW.*/mingw/') libgl_Linux = -lGL -lGLU -lGLEW libgl_Darwin = -framework OpenGL -lGLEW libgl_mingw = -lopengl32 -lglu32 -lglew32 +#libgl_mingw = -lglu32 -Wl,-Bstatic -lglew32 -Wl,-Bdynamic -lopengl32 ifeq ($(sys), mingw) bin = demo.exe + #CFLAGS += -DGLEW_STATIC + #CXXFLAGS += -DGLEW_STATIC endif $(bin): .clang_complete $(obj) diff --git a/laserbrain_demo.vcxproj b/laserbrain_demo.vcxproj index 32abf23..a52a9fd 100644 --- a/laserbrain_demo.vcxproj +++ b/laserbrain_demo.vcxproj @@ -14,20 +14,21 @@ {71A6DAF0-CBF6-4135-BE23-B3999E432EF6} Win32Proj laserbrain_demo + 8.1 Application true v141 - MultiByte + NotSet Application false v141 - true - MultiByte + false + NotSet @@ -89,6 +90,7 @@ + @@ -105,9 +107,12 @@ + + + @@ -123,6 +128,7 @@ + @@ -140,9 +146,12 @@ + + + diff --git a/laserbrain_demo.vcxproj.filters b/laserbrain_demo.vcxproj.filters index b7d0998..c486d22 100644 --- a/laserbrain_demo.vcxproj.filters +++ b/laserbrain_demo.vcxproj.filters @@ -106,6 +106,18 @@ src + + src + + + src + + + src + + + src + @@ -207,6 +219,18 @@ src + + src + + + src + + + src + + + src + diff --git a/src/app.cc b/src/app.cc index 1cf21bd..6eb019a 100644 --- a/src/app.cc +++ b/src/app.cc @@ -14,6 +14,7 @@ #include "opt.h" #include "post.h" #include "renderer.h" +#include "exman.h" #include "blob_exhibit.h" #define NEAR_CLIP 5.0 @@ -61,6 +62,7 @@ static unsigned int sdr_post_gamma; static long prev_msec; +static ExhibitManager *exman; static BlobExhibit *blobs; static bool show_blobs; @@ -119,6 +121,11 @@ bool app_init(int argc, char **argv) dir.y = 0; cam_theta = rad_to_deg(acos(dot(dir, Vec3(0, 0, 1)))); + exman = new ExhibitManager; + if(!exman->load(mscn, "data/exhibits")) { + //return false; + } + blobs = new BlobExhibit; blobs->node = new SceneNode; blobs->init(); @@ -126,6 +133,8 @@ bool app_init(int argc, char **argv) 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; } @@ -162,9 +171,7 @@ void app_cleanup() delete rend; - blobs->destroy(); - delete blobs->node; - delete blobs; + delete exman; texman.clear(); sceneman.clear(); @@ -194,9 +201,7 @@ static void update(float dt) sceneman.update(); mscn->update(dt); - if(show_blobs) { - blobs->update(dt); - } + exman->update(dt); float speed = walk_speed * dt; Vec3 dir; diff --git a/src/blob_exhibit.cc b/src/blob_exhibit.cc index 0378359..5e9f213 100644 --- a/src/blob_exhibit.cc +++ b/src/blob_exhibit.cc @@ -41,6 +41,7 @@ BlobExhibit::BlobExhibit() BlobExhibit::~BlobExhibit() { + destroy(); delete priv; } @@ -62,8 +63,10 @@ bool BlobExhibit::init() void BlobExhibit::destroy() { - msurf_free(priv->msurf); - priv->msurf = 0; + if(priv->msurf) { + msurf_free(priv->msurf); + priv->msurf = 0; + } } void BlobExhibit::update(float dt) diff --git a/src/datamap.cc b/src/datamap.cc index d39de6a..dcbae78 100644 --- a/src/datamap.cc +++ b/src/datamap.cc @@ -4,7 +4,7 @@ #include #include "datamap.h" -#ifdef WIN32 +#if defined(WIN32) || defined(__WIN32__) #include #else #include diff --git a/src/exhibit.cc b/src/exhibit.cc index 444fc40..d76b291 100644 --- a/src/exhibit.cc +++ b/src/exhibit.cc @@ -1,10 +1,14 @@ #include "exhibit.h" #include "snode.h" +#include "scene.h" class ExhibitPriv { +public: Vec3 orig_pos; Quat orig_rot; SceneNode *orig_node; + + ExhibitPriv(); }; ExSelection::ExSelection(Exhibit *ex) @@ -19,10 +23,14 @@ ExSelection::operator bool() const return ex != 0; } +ExhibitPriv::ExhibitPriv() +{ + orig_node = 0; +} + Exhibit::Exhibit() { priv = new ExhibitPriv; - priv->orig_node = 0; } Exhibit::~Exhibit() @@ -30,6 +38,13 @@ Exhibit::~Exhibit() delete priv; } +void Exhibit::set_node(SceneNode *node) +{ + this->node = priv->orig_node = node; + priv->orig_pos = node->get_position(); + priv->orig_rot = node->get_rotation(); +} + ExSelection Exhibit::select(const Ray &ray) const { return ExSelection(0); diff --git a/src/exhibit.h b/src/exhibit.h index 004626c..63b2898 100644 --- a/src/exhibit.h +++ b/src/exhibit.h @@ -7,6 +7,7 @@ class Exhibit; class ExhibitPriv; +class Scene; enum { EXSEL_RAY = 1, @@ -43,6 +44,8 @@ public: Exhibit(const Exhibit&) = delete; Exhibit &operator =(const Exhibit &) = delete; + virtual void set_node(SceneNode *node); + virtual ExSelection select(const Ray &ray) const; virtual ExSelection select(const Sphere &sph) const; diff --git a/src/exman.cc b/src/exman.cc index e0ededc..d93c2ff 100644 --- a/src/exman.cc +++ b/src/exman.cc @@ -1,6 +1,8 @@ +#include #include "exman.h" #include "exhibit.h" #include "blob_exhibit.h" +#include "treestore.h" static Exhibit *create_exhibit(const char *type); @@ -17,7 +19,25 @@ ExhibitManager::~ExhibitManager() items.clear(); } -bool ExhibitManager::load(const MetaScene *mscn, const char *fname) +void ExhibitManager::add(Exhibit *ex) +{ + std::vector::iterator it = std::find(items.begin(), items.end(), ex); + if(it == items.end()) { + items.push_back(ex); + } +} + +bool ExhibitManager::remove(Exhibit *ex) +{ + std::vector::iterator it = std::find(items.begin(), items.end(), ex); + if(it != items.end()) { + items.erase(it); + return true; + } + return false; +} + +bool ExhibitManager::load(MetaScene *mscn, const char *fname) { struct ts_node *root = ts_load(fname); if(!root || strcmp(root->name, "exhibits") != 0) { @@ -26,10 +46,43 @@ bool ExhibitManager::load(const MetaScene *mscn, const char *fname) return false; } + 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("regexp \"%s\" didn't match any nodes\n", amatch ? amatch : ""); + continue; + } + + 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); + } + } + ts_free_tree(root); return true; } +void ExhibitManager::update(float dt) +{ + int num = items.size(); + for(int i=0; iupdate(dt); + } +} static Exhibit *create_exhibit(const char *type) { @@ -38,5 +91,6 @@ static Exhibit *create_exhibit(const char *type) } else if(strcmp(type, "blobs") == 0) { return new BlobExhibit; } + error_log("unknown exhibit type: %s\n", type); return 0; } diff --git a/src/exman.h b/src/exman.h index 5c627e6..d91e374 100644 --- a/src/exman.h +++ b/src/exman.h @@ -13,10 +13,15 @@ public: ExhibitManager(); ~ExhibitManager(); - bool load(const MetaScene *mscn, const char *fname); + void add(Exhibit *ex); + bool remove(Exhibit *ex); + + bool load(MetaScene *mscn, const char *fname); ExSelection select(const Ray &ray) const; ExSelection select(const Sphere &sph) const; + + void update(float dt = 0.0f); }; #endif // EXMAN_H_ diff --git a/src/image.cc b/src/image.cc index e79073d..57817ca 100644 --- a/src/image.cc +++ b/src/image.cc @@ -1,9 +1,9 @@ #include -#ifndef _MSC_VER -#include -#else +#if defined(WIN32) || defined(__WIN32__) #include +#else +#include #endif #include "imago2.h" diff --git a/src/metascene.cc b/src/metascene.cc index 6059664..2328f33 100644 --- a/src/metascene.cc +++ b/src/metascene.cc @@ -7,7 +7,7 @@ #include "logger.h" #include "app.h" -#ifdef WIN32 +#if defined(WIN32) || defined(__WIN32__) #include #else #include @@ -75,6 +75,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; diff --git a/src/metascene.h b/src/metascene.h index 8d0f5c2..9ac9092 100644 --- a/src/metascene.h +++ b/src/metascene.h @@ -27,6 +27,15 @@ public: void update(float dt); void draw() const; + + /* helper functions which end up calling the corresponding Scene functions + * for every scene + */ + SceneNode *find_node(const char *name) const; + SceneNode *match_node(const char *qstr) const; + std::list match_nodes(const char *qstr) const; + + Scene *extract_nodes(const char *qstr); }; #endif // METASCENE_H_ diff --git a/src/optcfg.c b/src/optcfg.c index ab84474..c67c299 100644 --- a/src/optcfg.c +++ b/src/optcfg.c @@ -2,7 +2,7 @@ #include #include #include -#ifdef _MSC_VER +#if defined(WIN32) || defined(__WIN32__) #include #else #include diff --git a/src/scene.cc b/src/scene.cc index 35b562d..adc90fb 100644 --- a/src/scene.cc +++ b/src/scene.cc @@ -182,6 +182,36 @@ bool Scene::have_node(SceneNode *n) const return n->scene == this; } +/* traverse scene graph and find node by name */ +static SceneNode *find_node_rec(SceneNode *tree, const char *name) +{ + if(strcmp(tree->get_name(), name) == 0) { + return tree; + } + + int num = tree->get_num_children(); + for(int i=0; iget_child(i), name); + if(n) return n; + } + return 0; +} + +static SceneNode *find_node_rec(SceneNode *tree, const std::regex &re) +{ + if(std::regex_match(tree->get_name(), re)) { + return tree; + } + debug_log("no match: \"%s\"\n", tree->get_name()); + + int num = tree->get_num_children(); + for(int i=0; i *res, SceneNode *tree, const std::regex &re) { if(std::regex_match(tree->get_name(), re)) { @@ -194,6 +224,30 @@ static void find_nodes_rec(std::list *res, SceneNode *tree, const st } } +SceneNode *Scene::find_node(const char *name) const +{ + if(!nodes) return 0; + return find_node_rec(nodes, name); +} + +SceneNode *Scene::match_node(const char *qstr) const +{ + if(!nodes) return 0; + + std::regex re{qstr}; + return find_node_rec(nodes, re); +} + +std::list Scene::match_nodes(const char *qstr) const +{ + std::list res; + if(nodes) { + std::regex re{qstr}; + find_nodes_rec(&res, nodes, re); + } + return std::move(res); +} + Scene *Scene::extract_nodes(const char *qstr) { if(!nodes) return 0; diff --git a/src/scene.h b/src/scene.h index f295bbc..bd01dec 100644 --- a/src/scene.h +++ b/src/scene.h @@ -60,6 +60,13 @@ public: bool remove_node(SceneNode *n); bool have_node(SceneNode *n) const; + // find node by name + SceneNode *find_node(const char *name) const; + // match nodes with regexp and return the first that matches + SceneNode *match_node(const char *qstr) const; + // match nodes with regexp and return a list of matches + std::list match_nodes(const char *qstr) const; + /* find and remove all nodes whose names match the regexp * XXX at the moment this has the effect of flattening the hierarchy in the * result scene. If we ever need verbatim extraction of whole subtrees we'll