X-Git-Url: http://git.mutantstargoat.com/user/nuclear/?p=laserbrain_demo;a=blobdiff_plain;f=src%2Fapp.cc;h=30222f9ce50d57444519b7aef8e6d427dc4df427;hp=7f173f35a1fafea2fafa93ee75334371ded9a4dc;hb=844f36f03073c5db86a8acd2cf7cd1a89e1a16b9;hpb=a65c61e066fecc441ebf651987dc56deb78a4247 diff --git a/src/app.cc b/src/app.cc index 7f173f3..30222f9 100644 --- a/src/app.cc +++ b/src/app.cc @@ -33,6 +33,7 @@ static Ray calc_pick_ray(int x, int y); long time_msec; int win_width, win_height; +int vp_width, vp_height; float win_aspect; bool fb_srgb; bool opt_gear_wireframe; @@ -84,6 +85,8 @@ static Renderer *rend; static Ray last_pick_ray; +static bool post_scene_init_pending = true; + bool app_init(int argc, char **argv) { @@ -164,11 +167,8 @@ bool app_init(int argc, char **argv) avatar.body_rot = rad_to_deg(acos(dot(dir, Vec3(0, 0, 1)))); exman = new ExhibitManager; - /* - if(!exman->load(mscn, "data/exhibits")) { - //return false; - } - */ + // exhibits are loaded in post_scene_init, because they need access to the scene graph + if(!exui_init()) { error_log("failed to initialize exhibit ui system\n"); return false; @@ -192,6 +192,9 @@ bool app_init(int argc, char **argv) } rend = new Renderer; + if(!rend->init()) { + return false; + } rend->set_scene(mscn); glUseProgram(0); @@ -206,6 +209,17 @@ bool app_init(int argc, char **argv) return true; } +// post_scene_init is called after the scene has completed loading +static void post_scene_init() +{ + mscn->update(0); // update once to calculate node matrices + + int num_mir = mscn->calc_mirror_planes(); + info_log("found %d mirror planes\n", num_mir); + + exman->load(mscn, "data/exhibits"); +} + void app_cleanup() { if(mscn->music) { @@ -257,6 +271,11 @@ static void update(float dt) texman.update(); sceneman.update(); + if(post_scene_init_pending && !sceneman.pending()) { + post_scene_init_pending = false; + post_scene_init(); + } + mscn->update(dt); exman->update(dt); exui_update(dt); @@ -349,22 +368,39 @@ 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); - } // 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 = transpose(mouse_view_matrix.upper3x3()) * Vec3(-0.47, 0, -1); + 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 } @@ -397,6 +433,8 @@ void app_display() for(int i=0; i<2; i++) { // for each eye goatvr_draw_eye(i); + vp_width = goatvr_get_fb_eye_width(i); + vp_height = goatvr_get_fb_eye_height(i); proj_matrix = goatvr_projection_matrix(i, NEAR_CLIP, FAR_CLIP); glMatrixMode(GL_PROJECTION); @@ -417,6 +455,9 @@ void app_display() } goatvr_draw_done(); + vp_width = win_width; + vp_height = win_height; + if(should_swap) { app_swap_buffers(); } @@ -457,7 +498,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(); @@ -467,15 +507,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); @@ -487,7 +527,6 @@ static void draw_scene() glEnd(); glPopAttrib(); } - */ if(debug_gui && dbg_sel_node) { AABox bvol = dbg_sel_node->get_bounds(); @@ -525,6 +564,9 @@ void app_reshape(int x, int y) glViewport(0, 0, x, y); goatvr_set_fb_size(x, y, 1.0f); debug_gui_reshape(x, y); + + vp_width = x; + vp_height = y; } void app_keyboard(int key, bool pressed) @@ -614,8 +656,20 @@ void app_keyboard(int key, bool pressed) show_message("VR recenter\n"); break; - case 'x': - exman->load(mscn, "data/exhibits"); + 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; } }