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/')
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;
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:
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()) {
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;
#include <stdio.h>
#include <assert.h>
+#include "assman.h"
#include "logger.h"
#include "ovstream.h"
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;
}
#include "avatar.h"
+#include "logger.h"
Avatar::Avatar()
{
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
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)
}
}
+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();
class ExhibitManager {
private:
std::vector<Exhibit*> items, stashed;
+ int cur_stashed;
std::vector<ExhibitSlot*> exslots;
// TODO kdtree of slots for quick nearest queries
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;
#endif
#include "imago2.h"
+#include "assman.h"
#include "image.h"
static int pixel_elements(Image::Format fmt);
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;
}
{
if (default_filter)
{
- ImStrncpy(InputBuf, default_filter, IM_ARRAYSIZE(InputBuf));
+ ImStrncpy(InputBuf, default_filter, IM_ARRAYSIZE(InputBuf) - 1);
Build();
}
else
#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>
#include <assimp/vector3.h>
#include <assimp/matrix4x4.h>
#include <assimp/quaternion.h>
+#include "assman.h"
#include "app.h"
#include "scene.h"
#include "objmesh.h"
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;
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;
{
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;
+}
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)
}
}
- scn->update(0);
+ //scn->update(0);
}
void draw_vrhands()
{
- bind_shader(0);
- scn->draw();
+ //bind_shader(0);
+ //scn->draw();
}