hand-tracking and exhibits part one
[laserbrain_demo] / src / app.cc
index 620ec52..63e7cd7 100644 (file)
@@ -21,6 +21,7 @@
 #include "blob_exhibit.h"
 #include "dbg_gui.h"
 #include "geomdraw.h"
+#include "ui_exhibit.h"
 
 #define NEAR_CLIP      5.0
 #define FAR_CLIP       10000.0
@@ -146,8 +147,6 @@ bool app_init(int argc, char **argv)
        float ambient[] = {0.0, 0.0, 0.0, 0.0};
        glLightModelfv(GL_LIGHT_MODEL_AMBIENT, ambient);
 
-       glClearColor(1, 1, 1, 1);
-
        init_audio();
 
        if(!init_vrhands()) {
@@ -170,6 +169,11 @@ bool app_init(int argc, char **argv)
                //return false;
        }
        */
+       if(!exui_init()) {
+               error_log("failed to initialize exhibit ui system\n");
+               return false;
+       }
+       exui_setnode(&exslot_left.node);
 
        if(!(sdr_ltmap_notex = create_program_load("sdr/lightmap.v.glsl", "sdr/lightmap-notex.p.glsl"))) {
                return false;
@@ -217,6 +221,8 @@ void app_cleanup()
 
        delete rend;
 
+       exui_shutdown();
+
        /* this must be destroyed before the scene graph to detach exhibit nodes
         * before the scene tries to delete them recursively
         */
@@ -253,6 +259,7 @@ static void update(float dt)
 
        mscn->update(dt);
        exman->update(dt);
+       exui_update(dt);
 
        float speed = walk_speed * dt;
        Vec3 dir;
@@ -342,22 +349,45 @@ 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 (only if we don't have one grabbed)
-       if(!exsel_grab_mouse) {
-               // 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);
-       }
-
-       if(!exslot_left.empty()) exslot_left.node.update(dt);
-       if(!exslot_right.empty()) exslot_right.node.update(dt);
 
        // update hand-tracking
        if(have_handtracking) {
                update_vrhands(&avatar);
+
+               if(vrhand[0].valid) {
+                       exslot_left.node.set_position(vrhand[0].pos);
+                       exslot_left.node.set_rotation(vrhand[0].rot);
+
+                       // right hand takes precedence for hover
+                       if(!exsel_grab_left && !exsel_hover) {
+                               exsel_hover = exman->select(Sphere(vrhand[0].pos, 5));
+                       }
+               }
+               if(vrhand[1].valid) {
+                       exslot_right.node.set_position(vrhand[1].pos);
+                       exslot_right.node.set_rotation(vrhand[1].rot);
+
+                       if(!exsel_grab_right) {
+                               exsel_hover = exman->select(Sphere(vrhand[1].pos, 5));
+                       }
+               }
+
+       } else {
+               // check if an exhibit is hovered-over by mouse (only if we don't have one grabbed)
+               if(!exsel_grab_mouse) {
+                       Ray ray = calc_pick_ray(prev_mx, prev_my);
+                       exsel_hover = exman->select(ray);
+               }
+
+               // TODO do this properly
+               // set the position of the left hand at a suitable position for the exhibit UI
+               dir = rotate(Vec3(-0.46, -0.1, -1), Vec3(0, 1, 0), deg_to_rad(-avatar.body_rot));
+               exslot_left.node.set_position(avatar.pos + dir * 30); // magic: distance in front
        }
+
+       if(!exslot_right.empty()) exslot_right.node.update(dt);
+       // always update the left slot, because it's the anchor point of the exhibit ui
+       exslot_left.node.update(dt);
 }
 
 void app_display()
@@ -372,6 +402,8 @@ void app_display()
                ImGui::ShowTestWindow();
        }
 
+       glClearColor(1, 1, 1, 1);
+
        if(opt.vr) {
                // VR mode
                goatvr_draw_start();
@@ -442,7 +474,6 @@ static void draw_scene()
        rend->draw();
        exman->draw();
 
-       /*
        if(have_handtracking) {
                Mat4 head_xform = inverse(mouse_view_matrix);//goatvr_head_matrix();
                Mat4 head_dir_xform = head_xform.upper3x3();
@@ -452,15 +483,15 @@ static void draw_scene()
                glDisable(GL_LIGHTING);
                glBegin(GL_LINES);
                for(int i=0; i<2; i++) {
-                       if(hand[i].valid) {
+                       if(vrhand[i].valid) {
                                glColor3f(i, 1 - i, i);
                        } else {
                                glColor3f(0.5, 0.5, 0.5);
                        }
-                       Vec3 v = head_xform * hand[i].pos;
-                       Vec3 dir = head_dir_xform * rotate(Vec3(0, 0, -1), hand[i].rot) * 20.0f;
-                       Vec3 up = head_dir_xform * rotate(Vec3(0, 1, 0), hand[i].rot) * 10.0f;
-                       Vec3 right = head_dir_xform * rotate(Vec3(1, 0, 0), hand[i].rot) * 10.0f;
+                       Vec3 v = head_xform * vrhand[i].pos;
+                       Vec3 dir = head_dir_xform * rotate(Vec3(0, 0, -1), vrhand[i].rot) * 20.0f;
+                       Vec3 up = head_dir_xform * rotate(Vec3(0, 1, 0), vrhand[i].rot) * 10.0f;
+                       Vec3 right = head_dir_xform * rotate(Vec3(1, 0, 0), vrhand[i].rot) * 10.0f;
 
                        glVertex3f(v.x, v.y, v.z);
                        glVertex3f(v.x + dir.x, v.y + dir.y, v.z + dir.z);
@@ -472,7 +503,6 @@ static void draw_scene()
                glEnd();
                glPopAttrib();
        }
-       */
 
        if(debug_gui && dbg_sel_node) {
                AABox bvol = dbg_sel_node->get_bounds();
@@ -498,6 +528,8 @@ static void draw_scene()
                glPopAttrib();
        }
 
+       exui_draw();
+
        print_text(Vec2(9 * win_width / 10, 20), Vec3(1, 1, 0), "fps: %.1f", framerate);
        draw_ui();
 }
@@ -600,6 +632,22 @@ void app_keyboard(int key, bool pressed)
                case 'x':
                        exman->load(mscn, "data/exhibits");
                        break;
+
+               case KEY_UP:
+                       exui_scroll(-1);
+                       break;
+
+               case KEY_DOWN:
+                       exui_scroll(1);
+                       break;
+
+               case KEY_LEFT:
+                       exui_change_tab(-1);
+                       break;
+
+               case KEY_RIGHT:
+                       exui_change_tab(1);
+                       break;
                }
        }