Merge branch 'master' of goat:git/laserbrain_demo
authorJohn Tsiombikas <nuclear@member.fsf.org>
Sat, 29 Sep 2018 03:05:06 +0000 (06:05 +0300)
committerJohn Tsiombikas <nuclear@member.fsf.org>
Sat, 29 Sep 2018 03:05:06 +0000 (06:05 +0300)
Makefile
src/app.cc
src/audio/ovstream.cc
src/avatar.cc
src/exman.cc
src/exman.h
src/image.cc
src/imgui/imgui.cc
src/sceneload.cc
src/vrinput.cc

index 370828e..a7334ee 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -21,7 +21,7 @@ warn = -pedantic -Wall
 CFLAGS = $(warn) $(opt) $(dbg) $(incpath) -fopenmp
 CXXFLAGS = -std=c++11 $(warn) $(opt) $(dbg) $(incpath) -fopenmp
 LDFLAGS = $(libpath) -ldrawtext $(libgl_$(sys)) $(libal_$(sys)) -lm -lgmath -lvmath \
-                 -limago -lresman -lpthread -lassimp -ltreestore -lgoatvr \
+                 -limago -lresman -lpthread -lassimp -ltreestore -lgoatvr -lassman \
                  `pkg-config --libs sdl2 freetype2` -lpng -ljpeg -lz -lvorbisfile -lgomp
 
 sys ?= $(shell uname -s | sed 's/MINGW.*/mingw/')
index 3a77eef..9f58b5f 100644 (file)
@@ -345,11 +345,8 @@ static void update(float dt)
                avatar.pos.y -= speed;
        }
 
-       float theta = M_PI * avatar.body_rot / 180.0f;
-       Vec3 newpos;
-       newpos.x = avatar.pos.x + cos(theta) * dir.x - sin(theta) * dir.z;
-       newpos.y = avatar.pos.y;
-       newpos.z = avatar.pos.z + sin(theta) * dir.x + cos(theta) * dir.z;
+       Vec3 walk_dir = avatar.calc_walk_dir(dir.z, dir.x);
+       Vec3 newpos = avatar.pos + walk_dir;
 
        if(noclip) {
                avatar.pos = newpos;
@@ -786,6 +783,24 @@ void app_keyboard(int key, bool pressed)
                        exui_change_tab(1);
                        break;
 
+               case '\t':
+                       if(exsel_grab_mouse) {
+                               Exhibit *ex = exsel_grab_mouse.ex;
+                               exslot_mouse.detach_exhibit();
+                               exman->stash_exhibit(ex);
+                               exsel_grab_mouse = ExSelection::null;
+                       } else {
+                               Exhibit *ex = exman->unstash_exhibit();
+                               if(ex) {
+                                       exslot_mouse.attach_exhibit(ex, EXSLOT_ATTACH_TRANSIENT);
+                                       exsel_grab_mouse = ex;
+
+                                       Vec3 fwd = avatar.get_body_fwd();
+                                       exslot_mouse.node.set_position(avatar.pos + fwd * 100);
+                               }
+                       }
+                       break;
+
                case KEY_F5:
                case KEY_F6:
                case KEY_F7:
@@ -843,7 +858,7 @@ void app_mouse_button(int bn, bool pressed, int x, int y)
 
                                exslot_mouse.detach_exhibit();
 
-                               ExhibitSlot *slot = exman->nearest_empty_slot(pos, 100);
+                               ExhibitSlot *slot = exman->nearest_empty_slot(pos, 300);
                                if(!slot) {
                                        debug_log("no empty slot nearby\n");
                                        if(ex->prev_slot && ex->prev_slot->empty()) {
@@ -881,7 +896,7 @@ void app_mouse_button(int bn, bool pressed, int x, int y)
 static inline void mouse_look(float dx, float dy)
 {
        float scrsz = (float)win_height;
-       avatar.body_rot += dx * 512.0 / scrsz;
+       avatar.set_body_rotation(avatar.body_rot + dx * 512.0 / scrsz);
        avatar.head_alt += dy * 512.0 / scrsz;
 
        if(avatar.head_alt < -90) avatar.head_alt = -90;
index 56f3033..0c347f8 100644 (file)
@@ -1,5 +1,6 @@
 #include <stdio.h>
 #include <assert.h>
+#include "assman.h"
 #include "logger.h"
 #include "ovstream.h"
 
@@ -15,14 +16,38 @@ OggVorbisStream::~OggVorbisStream()
        close();
 }
 
+static int io_fseek(void *fp, ogg_int64_t offs, int whence)
+{
+       if(ass_fseek(fp, offs, whence) != -1) {
+               return 0;
+       }
+       return -1;
+}
+
+static int io_close(void *fp)
+{
+       ass_fclose(fp);
+       return 0;
+}
+
+
 bool OggVorbisStream::open(const char *fname)
 {
        close();
 
        pthread_mutex_lock(&vflock);
 
-       if(ov_fopen(fname, &vf) != 0) {
-               error_log("failed to open ogg/vorbis stream: %s\n", fname ? fname : "<not found>");
+       ass_file *fp;
+       if(!(fp = ass_fopen(fname, "rb"))) {
+               error_log("failed to open ogg/vorbis stream: %s: %s\n", fname, strerror(ass_errno));
+               pthread_mutex_unlock(&vflock);
+               return false;
+       }
+
+       ov_callbacks iofuncs = { ass_fread, io_fseek, io_close, ass_ftell };
+       if(ov_open_callbacks(fp, &vf, 0, 0, iofuncs) != 0) {
+               error_log("failed to open ogg/vorbis stream: %s: %s\n", fname, strerror(ass_errno));
+               ass_fclose(fp);
                pthread_mutex_unlock(&vflock);
                return false;
        }
index 737d3a6..456f269 100644 (file)
@@ -1,4 +1,5 @@
 #include "avatar.h"
+#include "logger.h"
 
 Avatar::Avatar()
 {
@@ -30,6 +31,12 @@ const Vec3 &Avatar::get_position() const
 void Avatar::set_body_rotation(float rot)
 {
        body_rot = rot;
+
+       float theta = deg_to_rad(body_rot);
+       fwd.x = sin(theta);
+       fwd.y = 0;
+       fwd.z = -cos(theta);
+       right = Vec3(-fwd.z, 0, fwd.x);
 }
 
 float Avatar::get_body_rotation() const
@@ -79,8 +86,10 @@ void Avatar::mouselook(float horiz, float vert)
 
 Vec3 Avatar::calc_walk_dir(float fwd, float right) const
 {
-       // TODO
-       return Vec3(0, 0, 0);
+       float theta = M_PI * body_rot / 180.0f;
+       float dx = cos(theta) * right - sin(theta) * fwd;
+       float dz = sin(theta) * right + cos(theta) * fwd;
+       return Vec3(dx, 0, dz);
 }
 
 void Avatar::walk(float fwd, float right)
index 00f7e39..4fff917 100644 (file)
@@ -334,6 +334,17 @@ void ExhibitManager::stash_exhibit(Exhibit *ex)
        }
 }
 
+Exhibit *ExhibitManager::unstash_exhibit()
+{
+       if(stashed.empty()) {
+               return 0;
+       }
+
+       Exhibit *ex = stashed[0];
+       stashed.erase(stashed.begin());
+       return ex;
+}
+
 void ExhibitManager::update(float dt)
 {
        int num = items.size();
index 8b9b65a..13d9bcc 100644 (file)
@@ -36,6 +36,7 @@ public:
 class ExhibitManager {
 private:
        std::vector<Exhibit*> items, stashed;
+       int cur_stashed;
        std::vector<ExhibitSlot*> exslots;
        // TODO kdtree of slots for quick nearest queries
 
@@ -58,6 +59,7 @@ public:
        ExhibitSlot *nearest_empty_slot(const Vec3 &pos, float max_dist = 10) const;
 
        void stash_exhibit(Exhibit *ex);
+       Exhibit *unstash_exhibit();
 
        void update(float dt = 0.0f);
        void draw() const;
index 57817ca..ce930f3 100644 (file)
@@ -7,6 +7,7 @@
 #endif
 
 #include "imago2.h"
+#include "assman.h"
 #include "image.h"
 
 static int pixel_elements(Image::Format fmt);
@@ -171,12 +172,30 @@ void Image::resize_half()
        height = newysz;
 }
 
+static size_t io_read(void *buf, size_t bytes, void *fp)
+{
+       return ass_fread(buf, 1, bytes, fp);
+}
+
+static long io_seek(long offs, int whence, void *fp)
+{
+       ass_fseek(fp, offs, whence);
+       return ass_ftell(fp);
+}
+
 bool Image::load(const char *fname)
 {
        struct img_pixmap pixmap;
+       struct img_io io = {0, io_read, 0, io_seek};
+       ass_file *fp;
+
+       if(!(fp = ass_fopen(fname, "rb"))) {
+               return false;
+       }
+       io.uptr = fp;
 
        img_init(&pixmap);
-       if(img_load(&pixmap, fname) == -1) {
+       if(img_read(&pixmap, &io) == -1) {
                return false;
        }
 
index 211bd29..303b780 100644 (file)
@@ -1541,7 +1541,7 @@ ImGuiTextFilter::ImGuiTextFilter(const char* default_filter)
 {
     if (default_filter)
     {
-        ImStrncpy(InputBuf, default_filter, IM_ARRAYSIZE(InputBuf));
+        ImStrncpy(InputBuf, default_filter, IM_ARRAYSIZE(InputBuf) - 1);
         Build();
     }
     else
index 28f5877..7459c1d 100644 (file)
@@ -5,6 +5,7 @@
 #include <map>
 #include <gmath/gmath.h>
 #include <assimp/cimport.h>
+#include <assimp/cfileio.h>
 #include <assimp/postprocess.h>
 #include <assimp/scene.h>
 #include <assimp/mesh.h>
@@ -13,6 +14,7 @@
 #include <assimp/vector3.h>
 #include <assimp/matrix4x4.h>
 #include <assimp/quaternion.h>
+#include "assman.h"
 #include "app.h"
 #include "scene.h"
 #include "objmesh.h"
@@ -36,6 +38,13 @@ static long assimp_time(const aiAnimation *anim, double aitime);
 static void print_hierarchy(const aiNode *node);
 */
 
+static aiFile *io_open(aiFileIO *io, const char *fname, const char *mode);
+static void io_close(aiFileIO *io, aiFile *aifp);
+static size_t io_read(aiFile *aifp, char *buf, size_t size, size_t count);
+static size_t io_tell(aiFile *aifp);
+static size_t io_filesize(aiFile *aifp);
+static aiReturn io_seek(aiFile *aifp, size_t offs, aiOrigin whence);
+
 struct LoaderData {
        const aiScene *aiscn;
        std::string fname;
@@ -72,7 +81,11 @@ bool Scene::load(const char *fname, unsigned int flags)
                        this->name = std::string(fname);
                }
 
-               const aiScene *aiscn = aiImportFile(fname, ppflags);
+               aiFileIO io;
+               io.OpenProc = io_open;
+               io.CloseProc = io_close;
+
+               const aiScene *aiscn = aiImportFileEx(fname, ppflags, &io);
                if(!aiscn) {
                        error_log("failed to load scene file: %s\n", fname);
                        return false;
@@ -400,3 +413,59 @@ void SceneSet::free_scene(Scene *scn)
 {
        delete scn;
 }
+
+
+// ------ custom file I/O for assimp -------
+
+static aiFile *io_open(aiFileIO *io, const char *fname, const char *mode)
+{
+       ass_file *fp;
+       if(!(fp = ass_fopen(fname, mode))) {
+               error_log("failed to open scene file: %s: %s\n", fname, strerror(ass_errno));
+               return 0;
+       }
+
+       aiFile *aifp = new aiFile;
+       aifp->ReadProc = io_read;
+       aifp->WriteProc = 0;
+       aifp->TellProc = io_tell;
+       aifp->FileSizeProc = io_filesize;
+       aifp->SeekProc = io_seek;
+       aifp->FlushProc = 0;
+       aifp->UserData = (aiUserData)fp;
+       return aifp;
+}
+
+static void io_close(aiFileIO *io, aiFile *aifp)
+{
+       ass_fclose(aifp->UserData);
+       delete aifp;
+}
+
+static size_t io_read(aiFile *aifp, char *buf, size_t size, size_t count)
+{
+       return ass_fread(buf, size, count, aifp->UserData);
+}
+
+static size_t io_tell(aiFile *aifp)
+{
+       return ass_ftell(aifp->UserData);
+}
+
+static size_t io_filesize(aiFile *aifp)
+{
+       ass_file *fp = aifp->UserData;
+       long cur = ass_ftell(fp);
+       ass_fseek(fp, 0, SEEK_END);
+       long off = ass_ftell(fp);
+       ass_fseek(fp, cur, SEEK_SET);
+       return off;
+}
+
+static aiReturn io_seek(aiFile *aifp, size_t offs, aiOrigin whence)
+{
+       if(ass_fseek(aifp->UserData, offs, (int)whence) == -1) {
+               return aiReturn_FAILURE;
+       }
+       return aiReturn_SUCCESS;
+}
index 6bb2aaa..2d0646a 100644 (file)
@@ -6,24 +6,25 @@
 
 VRHand vrhand[2];
 
-static Scene *scn;
+//static Scene *scn;
 
 bool init_vrhands()
 {
-       scn = new Scene;
+       /*scn = new Scene;
        if(!(scn->load("data/vrhands.obj"))) {
                return false;
        }
        scn->objects[0]->node->set_position(Vec3(0, 150, 0));
        scn->objects[1]->node->set_position(Vec3(0, 250, 0));
        scn->update(0);
+       */
        return true;
 }
 
 void destroy_vrhands()
 {
-       delete scn;
-       scn = 0;
+       //delete scn;
+       //scn = 0;
 }
 
 void update_vrhands(const Avatar *avatar)
@@ -46,11 +47,11 @@ void update_vrhands(const Avatar *avatar)
                }
        }
 
-       scn->update(0);
+       //scn->update(0);
 }
 
 void draw_vrhands()
 {
-       bind_shader(0);
-       scn->draw();
+       //bind_shader(0);
+       //scn->draw();
 }