Merge branch 'master' of goat:git/laserbrain_demo
authorJohn Tsiombikas <nuclear@mutantstargoat.com>
Fri, 1 Sep 2017 00:10:17 +0000 (03:10 +0300)
committerJohn Tsiombikas <nuclear@mutantstargoat.com>
Fri, 1 Sep 2017 00:10:17 +0000 (03:10 +0300)
17 files changed:
.gitignore
Makefile
laserbrain_demo.vcxproj
laserbrain_demo.vcxproj.filters
src/app.cc
src/blob_exhibit.cc
src/datamap.cc
src/exhibit.cc
src/exhibit.h
src/exman.cc
src/exman.h
src/image.cc
src/metascene.cc
src/metascene.h
src/optcfg.c
src/scene.cc
src/scene.h

index e377c0e..0d79523 100644 (file)
@@ -5,6 +5,9 @@ demo
 data/
 .clang_complete
 *.suo
+*.user
 *sdf
+*.dll
+*.exe
 Debug/
 Release/
index 959c10f..4b65ac3 100644 (file)
--- 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)
index 32abf23..a52a9fd 100644 (file)
     <ProjectGuid>{71A6DAF0-CBF6-4135-BE23-B3999E432EF6}</ProjectGuid>\r
     <Keyword>Win32Proj</Keyword>\r
     <RootNamespace>laserbrain_demo</RootNamespace>\r
+    <WindowsTargetPlatformVersion>8.1</WindowsTargetPlatformVersion>\r
   </PropertyGroup>\r
   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />\r
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">\r
     <ConfigurationType>Application</ConfigurationType>\r
     <UseDebugLibraries>true</UseDebugLibraries>\r
     <PlatformToolset>v141</PlatformToolset>\r
-    <CharacterSet>MultiByte</CharacterSet>\r
+    <CharacterSet>NotSet</CharacterSet>\r
   </PropertyGroup>\r
   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">\r
     <ConfigurationType>Application</ConfigurationType>\r
     <UseDebugLibraries>false</UseDebugLibraries>\r
     <PlatformToolset>v141</PlatformToolset>\r
-    <WholeProgramOptimization>true</WholeProgramOptimization>\r
-    <CharacterSet>MultiByte</CharacterSet>\r
+    <WholeProgramOptimization>false</WholeProgramOptimization>\r
+    <CharacterSet>NotSet</CharacterSet>\r
   </PropertyGroup>\r
   <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />\r
   <ImportGroup Label="ExtensionSettings">\r
@@ -89,6 +90,7 @@
     <ClCompile Include="src\blob_exhibit.cc" />\r
     <ClCompile Include="src\datamap.cc" />\r
     <ClCompile Include="src\exhibit.cc" />\r
+    <ClCompile Include="src\exman.cc" />\r
     <ClCompile Include="src\geom.cc" />\r
     <ClCompile Include="src\image.cc" />\r
     <ClCompile Include="src\logger.cc" />\r
     <ClCompile Include="src\opt.cc" />\r
     <ClCompile Include="src\optcfg.c" />\r
     <ClCompile Include="src\post.cc" />\r
+    <ClCompile Include="src\renderer.cc" />\r
+    <ClCompile Include="src\rend_cubemap.cc" />\r
     <ClCompile Include="src\scene.cc" />\r
     <ClCompile Include="src\sceneload.cc" />\r
     <ClCompile Include="src\sdr.c" />\r
+    <ClCompile Include="src\sdrman.cc" />\r
     <ClCompile Include="src\shader.cc" />\r
     <ClCompile Include="src\shadow.cc" />\r
     <ClCompile Include="src\snode.cc" />\r
     <ClInclude Include="src\datamap.h" />\r
     <ClInclude Include="src\dataset.h" />\r
     <ClInclude Include="src\exhibit.h" />\r
+    <ClInclude Include="src\exman.h" />\r
     <ClInclude Include="src\geom.h" />\r
     <ClInclude Include="src\image.h" />\r
     <ClInclude Include="src\logger.h" />\r
     <ClInclude Include="src\opt.h" />\r
     <ClInclude Include="src\optcfg.h" />\r
     <ClInclude Include="src\post.h" />\r
+    <ClInclude Include="src\renderer.h" />\r
+    <ClInclude Include="src\rend_cubemap.h" />\r
     <ClInclude Include="src\scene.h" />\r
     <ClInclude Include="src\sceneload.h" />\r
     <ClInclude Include="src\sdr.h" />\r
+    <ClInclude Include="src\sdrman.h" />\r
     <ClInclude Include="src\shader.h" />\r
     <ClInclude Include="src\shadow.h" />\r
     <ClInclude Include="src\snode.h" />\r
index b7d0998..c486d22 100644 (file)
     <ClCompile Include="src\optcfg.c">\r
       <Filter>src</Filter>\r
     </ClCompile>\r
+    <ClCompile Include="src\exman.cc">\r
+      <Filter>src</Filter>\r
+    </ClCompile>\r
+    <ClCompile Include="src\rend_cubemap.cc">\r
+      <Filter>src</Filter>\r
+    </ClCompile>\r
+    <ClCompile Include="src\renderer.cc">\r
+      <Filter>src</Filter>\r
+    </ClCompile>\r
+    <ClCompile Include="src\sdrman.cc">\r
+      <Filter>src</Filter>\r
+    </ClCompile>\r
   </ItemGroup>\r
   <ItemGroup>\r
     <ClInclude Include="src\app.h">\r
     <ClInclude Include="src\optcfg.h">\r
       <Filter>src</Filter>\r
     </ClInclude>\r
+    <ClInclude Include="src\exman.h">\r
+      <Filter>src</Filter>\r
+    </ClInclude>\r
+    <ClInclude Include="src\rend_cubemap.h">\r
+      <Filter>src</Filter>\r
+    </ClInclude>\r
+    <ClInclude Include="src\renderer.h">\r
+      <Filter>src</Filter>\r
+    </ClInclude>\r
+    <ClInclude Include="src\sdrman.h">\r
+      <Filter>src</Filter>\r
+    </ClInclude>\r
   </ItemGroup>\r
   <ItemGroup>\r
     <None Include="src\dataset.inl">\r
index 1cf21bd..6eb019a 100644 (file)
@@ -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;
index 0378359..5e9f213 100644 (file)
@@ -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)
index d39de6a..dcbae78 100644 (file)
@@ -4,7 +4,7 @@
 #include <algorithm>
 #include "datamap.h"
 
-#ifdef WIN32
+#if defined(WIN32) || defined(__WIN32__)
 #include <malloc.h>
 #else
 #include <alloca.h>
index 444fc40..d76b291 100644 (file)
@@ -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);
index 004626c..63b2898 100644 (file)
@@ -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;
 
index e0ededc..d93c2ff 100644 (file)
@@ -1,6 +1,8 @@
+#include <algorithm>
 #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<Exhibit*>::iterator it = std::find(items.begin(), items.end(), ex);
+       if(it == items.end()) {
+               items.push_back(ex);
+       }
+}
+
+bool ExhibitManager::remove(Exhibit *ex)
+{
+       std::vector<Exhibit*>::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; i<num; i++) {
+               items[i]->update(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;
 }
index 5c627e6..d91e374 100644 (file)
@@ -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_
index e79073d..57817ca 100644 (file)
@@ -1,9 +1,9 @@
 #include <string.h>
 
-#ifndef _MSC_VER
-#include <alloca.h>
-#else
+#if defined(WIN32) || defined(__WIN32__)
 #include <malloc.h>
+#else
+#include <alloca.h>
 #endif
 
 #include "imago2.h"
index 6059664..2328f33 100644 (file)
@@ -7,7 +7,7 @@
 #include "logger.h"
 #include "app.h"
 
-#ifdef WIN32
+#if defined(WIN32) || defined(__WIN32__)
 #include <malloc.h>
 #else
 #include <alloca.h>
@@ -75,6 +75,57 @@ void MetaScene::draw() const
        }
 }
 
+SceneNode *MetaScene::find_node(const char *name) const
+{
+       int num = scenes.size();
+       for(int i=0; i<num; i++) {
+               SceneNode *n = scenes[i]->find_node(name);
+               if(n) return n;
+       }
+       return 0;
+}
+
+SceneNode *MetaScene::match_node(const char *qstr) const
+{
+       int num = scenes.size();
+       for(int i=0; i<num; i++) {
+               SceneNode *n = scenes[i]->match_node(qstr);
+               if(n) return n;
+       }
+       return 0;
+}
+
+std::list<SceneNode*> MetaScene::match_nodes(const char *qstr) const
+{
+       std::list<SceneNode*> res;
+       int num = scenes.size();
+       for(int i=0; i<num; i++) {
+               std::list<SceneNode*> 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; i<nscn; i++) {
+               Scene *tmp = scenes[i]->extract_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;
index 8d0f5c2..9ac9092 100644 (file)
@@ -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<SceneNode*> match_nodes(const char *qstr) const;
+
+       Scene *extract_nodes(const char *qstr);
 };
 
 #endif // METASCENE_H_
index ab84474..c67c299 100644 (file)
@@ -2,7 +2,7 @@
 #include <stdlib.h>
 #include <string.h>
 #include <ctype.h>
-#ifdef _MSC_VER
+#if defined(WIN32) || defined(__WIN32__)
 #include <malloc.h>
 #else
 #include <alloca.h>
index 35b562d..adc90fb 100644 (file)
@@ -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; i<num; i++) {
+               SceneNode *n = find_node_rec(tree->get_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<num; i++) {
+               SceneNode *n = find_node_rec(tree, re);
+               if(n) return n;
+       }
+       return 0;
+}
+
 static void find_nodes_rec(std::list<SceneNode*> *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<SceneNode*> *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<SceneNode*> Scene::match_nodes(const char *qstr) const
+{
+       std::list<SceneNode*> 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;
index f295bbc..bd01dec 100644 (file)
@@ -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<SceneNode*> 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