From: John Tsiombikas Date: Sun, 14 Jan 2018 03:44:05 +0000 (+0200) Subject: select and move exhibits X-Git-Url: http://git.mutantstargoat.com/user/nuclear/?p=laserbrain_demo;a=commitdiff_plain;h=b5ed5107e21ff834d5a4510b9047f976abb03dff;hp=ebbb52cd0de8e27817a0770bd7bdb48a58348a02 select and move exhibits --- diff --git a/src/app.cc b/src/app.cc index 25c59b3..59d713c 100644 --- a/src/app.cc +++ b/src/app.cc @@ -72,7 +72,7 @@ static ExhibitManager *exman; static BlobExhibit *blobs; static bool show_blobs; -static ExSelection ex_sel; +ExSelection exsel_grab, exsel_hover; static Renderer *rend; @@ -343,6 +343,13 @@ static void update(float dt) mouse_view_matrix.pre_rotate_y(deg_to_rad(avatar.body_rot)); mouse_view_matrix.pre_translate(-avatar.pos.x, -avatar.pos.y, -avatar.pos.z); + // check if an exhibit is hovered-over by mouse or 6dof + // XXX note: using previous view/proj matrix lattency shouldn't be an issue but + // make sure state-creep doesn't get us + // XXX also this mouse-picking probably should only be active in non-VR mode + Ray ray = calc_pick_ray(prev_mx, prev_my); + exsel_hover = exman->select(ray); + // update hand-tracking if(have_handtracking) { update_vrhands(&avatar); @@ -605,11 +612,11 @@ void app_mouse_button(int bn, bool pressed, int x, int y) if(bn == 0) { if(!pressed) { - if(ex_sel.ex) { - ex_sel.ex = 0; + if(exsel_grab.ex) { + exsel_grab.ex = 0; } else { Ray ray = calc_pick_ray(x, y); - ex_sel = exman->select(ray); + exsel_grab = exman->select(ray); } } } @@ -645,11 +652,11 @@ void app_mouse_motion(int x, int y) if(!dx && !dy) return; - if(ex_sel.ex) { - Vec3 pos = ex_sel.ex->node->get_node_position(); + if(exsel_grab.ex) { + Vec3 pos = exsel_grab.ex->node->get_node_position(); Vec3 dir = transpose(view_matrix.upper3x3()) * Vec3(dx * 1.0, dy * -1.0, 0); - ex_sel.ex->node->set_position(pos + dir); + exsel_grab.ex->node->set_position(pos + dir); } if(bnstate[2]) { diff --git a/src/app.h b/src/app.h index fe06daf..1eed2fe 100644 --- a/src/app.h +++ b/src/app.h @@ -3,6 +3,7 @@ #include "texture.h" #include "scene.h" +#include "exhibit.h" extern long time_msec; extern int win_width, win_height; @@ -15,6 +16,8 @@ extern SceneSet sceneman; extern unsigned int sdr_ltmap, sdr_ltmap_notex; +extern ExSelection exsel_grab, exsel_hover; + extern int fpexcept_enabled; // int so that C modules may fwd-delcare and use it enum { diff --git a/src/exhibit.cc b/src/exhibit.cc index b8d44cc..266a583 100644 --- a/src/exhibit.cc +++ b/src/exhibit.cc @@ -2,6 +2,7 @@ #include "snode.h" #include "scene.h" #include "geomdraw.h" +#include "app.h" class ExhibitPriv { public: @@ -63,12 +64,20 @@ void Exhibit::set_node(SceneNode *node) ExSelection Exhibit::select(const Ray &ray) const { - return ExSelection(0); + ExSelection sel; + HitPoint hit; + if(get_aabox().intersect(ray, &hit)) { + sel.ex = (Exhibit*)this; + sel.selray = ray; + sel.dist = hit.dist; + sel.validmask = EXSEL_RAY; + } + return sel; } ExSelection Exhibit::select(const Sphere &sph) const { - return ExSelection(0); + return ExSelection(0); // TODO } void Exhibit::update(float dt) @@ -94,8 +103,10 @@ void Exhibit::post_draw() const glMatrixMode(GL_MODELVIEW); glPopMatrix(); - const AABox &bvol = get_aabox(); - draw_geom_object(&bvol); + if(exsel_hover.ex == this) { + const AABox &bvol = get_aabox(); + draw_geom_object(&bvol); + } } } diff --git a/src/exhibit.h b/src/exhibit.h index f2c521b..f331d99 100644 --- a/src/exhibit.h +++ b/src/exhibit.h @@ -23,6 +23,7 @@ public: void *data; Ray selray; Sphere selsphere; + float dist; unsigned int validmask; ExSelection(Exhibit *ex = 0); diff --git a/src/exman.cc b/src/exman.cc index 6517b65..21e0074 100644 --- a/src/exman.cc +++ b/src/exman.cc @@ -1,3 +1,4 @@ +#include #include #include "exman.h" #include "exhibit.h" @@ -103,13 +104,18 @@ bool ExhibitManager::load(MetaScene *mscn, const char *fname) ExSelection ExhibitManager::select(const Ray &ray) const { - ExSelection sel; - if(!items.empty()) { - sel.ex = items[0]; - sel.selray = ray; - sel.validmask = EXSEL_RAY; + ExSelection nearest; + nearest.dist = FLT_MAX; + + int nitems = items.size(); + for(int i=0; iselect(ray); + if(sel && sel.dist < nearest.dist) { + nearest = sel; + } } - return sel; // TODO + + return nearest; } ExSelection ExhibitManager::select(const Sphere &sph) const