From 1b976d364b0edf9414b13fdffa9bba3192fb3cf7 Mon Sep 17 00:00:00 2001 From: Zeno Rogue Date: Wed, 30 Dec 2020 18:34:13 +0100 Subject: [PATCH] uniform VR control --- control.cpp | 10 +++- dialogs.cpp | 44 -------------- drawing.cpp | 2 +- graph.cpp | 3 +- vr.cpp | 164 +++++++++++++++++++++++++++++----------------------- 5 files changed, 103 insertions(+), 120 deletions(-) diff --git a/control.cpp b/control.cpp index 5b8480d9..51f7a185 100644 --- a/control.cpp +++ b/control.cpp @@ -178,7 +178,15 @@ EX void calcMousedest() { } EX void mousemovement() { - if(GDIM == 3) { + + #if CAP_VR + if(WDIM == 3 && vrhr::active() && which_pointer) { + movevrdir(vrhr::vr_direction); + return; + } + #endif + + if(GDIM == 3 && !which_pointer) { if(WDIM == 2) { if(View[2][2] < -0.75) movepcto(MD_DROP, 1); diff --git a/dialogs.cpp b/dialogs.cpp index 2bc69a00..2d1fad73 100644 --- a/dialogs.cpp +++ b/dialogs.cpp @@ -385,11 +385,6 @@ EX namespace dialog { EX void display() { - #if CAP_VR - for(auto h: vrhr::get_hits()) - displaystr(h.x, h.y, 2, vid.fsize * 2, "X", 0xFFD500, 8); - #endif - callhooks(hooks_display_dialog); int N = items.size(); dfsize = vid.fsize; @@ -442,16 +437,6 @@ EX namespace dialog { xthis = xthis && (mousex >= dcenter - dialogwidth/2 && mousex <= dcenter + dialogwidth/2); displayfr(dcenter, mid, 2, dfsize * I.scale/100, I.body, I.color, 8); if(xthis) getcstat = I.key; - - #if CAP_VR - for(auto h: vrhr::get_hits()) { - bool vrthis = (h.y >= top && h.y < tothei); - if(cmode & sm::DIALOG_STRICT_X) - vrthis = vrthis && (mousex >= dcenter - dialogwidth/2 && mousex <= dcenter + dialogwidth/2); - if(vrthis) I.color = I.colors; - if(vrthis && h.clicked) queue_key(I.key); - } - #endif } else if(I.type == diItem || I.type == diBigItem) { bool xthis = (mousey >= top && mousey < tothei); @@ -470,18 +455,6 @@ EX namespace dialog { } #endif - #if CAP_VR - for(auto h: vrhr::get_hits()) { - bool vrthis = (h.y >= top && h.y < tothei); - if(cmode & sm::DIALOG_STRICT_X) - vrthis = vrthis && (mousex >= dcenter - dialogwidth/2 && mousex <= dcenter + dialogwidth/2); - if(vrthis) I.color = I.colors; - if(vrthis && h.clicked) { - queue_key(I.key); - } - } - #endif - if(I.type == diBigItem) { displayfr(dcenter, mid, 2, dfsize * I.scale/100, I.body, I.color, 8); } @@ -516,16 +489,6 @@ EX namespace dialog { displayfr(sr, mid, 2, dfsize * I.scale/100, "}", I.color, 0); } if(xthis) getcstat = I.key, inslider = true, slider_x = mousex; - - #if CAP_VR - for(auto h: vrhr::get_hits()) { - bool vrthis = (h.y >= top && h.y < tothei); - if(cmode & sm::DIALOG_STRICT_X) - vrthis = vrthis && (mousex >= dcenter - dialogwidth/2 && mousex <= dcenter + dialogwidth/2); - if(vrthis) I.color = I.colors; - if(vrthis && h.clicked) queue_key(I.key), inslider = true, slider_x = h.x; - } - #endif } else if(I.type == diKeyboard) { int len = 0; @@ -749,13 +712,6 @@ EX namespace dialog { if(mousey >= y - vid.fsize && mousey < y + vid.fsize) getcstat = 'A' + i, inslider = true, slider_x = mousex; - - #if CAP_VR - for(auto h: vrhr::get_hits()) { - bool vrthis = (h.y >= y - vid.fsize && h.y < y + vid.fsize); - if(vrthis && h.clicked) queue_key('A' + i), inslider = true, slider_x = h.x; - } - #endif } displayColorButton(dcenter, vid.yres/2+vid.fsize * 6, XLAT("select this color") + " : " + format(colorAlpha ? "%08X" : "%06X", color), ' ', 8, 0, color >> (colorAlpha ? ash : 0)); diff --git a/drawing.cpp b/drawing.cpp index 1cd4fc26..0c631e9e 100644 --- a/drawing.cpp +++ b/drawing.cpp @@ -227,7 +227,7 @@ EX void glflush() { }; #if CAP_VR - if(vrhr::should_render() && !(cmode & sm::NORMAL)) + if(vrhr::should_render() && vrhr::in_menu()) vrhr::in_vr_ui(drawer); else diff --git a/graph.cpp b/graph.cpp index 6d7c0cb2..2357b89c 100644 --- a/graph.cpp +++ b/graph.cpp @@ -5102,7 +5102,8 @@ EX void gamescreen(int _darken) { #endif #if CAP_VR - if(vrhr::active() && _darken) { + + if(vrhr::active() && vrhr::in_menu()) { int xsi = current_display->xsize; int ysi = current_display->ysize; color_t col = 0x000000C0; diff --git a/vr.cpp b/vr.cpp index ec9c51c9..7bf261e8 100644 --- a/vr.cpp +++ b/vr.cpp @@ -293,20 +293,6 @@ vr_rendermodel *get_render_model(string name) { return md; } -#if HDR -struct click { - int x, y, clicked; - }; -#endif - -EX vector get_hits() { - vector res; - for(auto h: vrhr::vrdata.cdata) - if(h.x || h.y) - res.emplace_back(click{h.x, h.y, h.clicked}); - return res; - } - void track_all() { track_actions(); @@ -348,17 +334,19 @@ void track_all() { println(hlog, "axis ", i, " = ", tie(cd.cur.rAxis[i].x, cd.cur.rAxis[i].y)); } */ - - hyperpoint h1 = sm * hmd_at * vrdata.pose_matrix[i] * sm * C0; - hyperpoint h2 = sm * hmd_at * vrdata.pose_matrix[i] * sm * point31(0, 0, -0.01); - ld p = ilerp(h1[2], h2[2], -ui_depth); - hyperpoint px = lerp(h1, h2, p); - px[0] /= ui_size; - px[1] /= -ui_size; - px[0] += current_display->xsize/2; - px[1] += current_display->ysize/2; - cd.x = px[0]; - cd.y = px[1]; + + if(in_menu() && which_pointer == i) { + hyperpoint h1 = sm * hmd_at * vrdata.pose_matrix[i] * sm * C0; + hyperpoint h2 = sm * hmd_at * vrdata.pose_matrix[i] * sm * point31(0, 0, -0.01); + ld p = ilerp(h1[2], h2[2], -ui_depth); + hyperpoint px = lerp(h1, h2, p); + px[0] /= ui_size; + px[1] /= -ui_size; + px[0] += current_display->xsize/2; + px[1] += current_display->ysize/2; + mousex = px[0]; + mousey = px[1]; + } if(hdist(vrdata.pose_matrix[i] * C0, vrdata.last_pose_matrix[i] * C0) > .05) { vrdata.last_pose_matrix[i] = vrdata.pose_matrix[i]; @@ -372,6 +360,23 @@ void track_all() { } +EX void send_click() { + holdmouse = false; + fix_mouseh(); + println(hlog, "sending a click, getcstat = ", getcstat, " in menu = ", in_menu()); + if(in_menu()) + handlekey(getcstat, getcstat); + else + handlekey('-', '-'); + } + +EX void send_release() { + holdmouse = false; + fix_mouseh(); + println(hlog, "sending a release"); + handlekey(PSEUDOKEY_RELEASE, PSEUDOKEY_RELEASE); + } + EX void vr_control() { if(!enabled || !vid.usingGL) { if(state) shutdown_vr(); @@ -383,6 +388,37 @@ EX void vr_control() { if(state == 1) { track_all(); } + static bool last_vr_clicked = false; + + shiftmul = getcshift; + + if(which_pointer) mousemoved = true; + + println(hlog, tie(which_pointer, vr_clicked)); + + if(vr_clicked && last_vr_clicked && holdmouse) send_click(); + + mousepressed = vr_clicked; + + if(vr_clicked && !last_vr_clicked && vid.quickmouse) send_click(); + + if(vr_clicked && !last_vr_clicked && !vid.quickmouse) + actonrelease = true; + + if(!vr_clicked && last_vr_clicked && !vid.quickmouse && actonrelease) { + send_click(); + actonrelease = false; + } + + else if(!vr_clicked && last_vr_clicked) { + send_release(); + } + + if(mousepressed && inslider) { + send_click(); + } + + last_vr_clicked = vr_clicked; } EX void be_33(transmatrix& T) { @@ -435,7 +471,21 @@ ld vr_distance(shiftpoint h, int id) { return sqhypot_d(2, hc); } +EX hyperpoint vr_direction; + EX void compute_point(int id, shiftpoint& res, cell*& c) { + + if(WDIM == 3) { + E4; + transmatrix T = (hsm == eHeadset::none ? hmd_at : hmd_ref_at) * vrdata.pose_matrix[id] * sm; + vrhr::be_33(T); + vr_direction = T * point31(0, 0, -0.01); + movedir md = vectodir(vr_direction); + cellwalker xc = cwt + md.d + wstep; + forward_cell = xc.at; + return; + } + gen_mv(); c = nullptr; ld best = 1e9; @@ -460,34 +510,14 @@ EX void compute_point(int id, shiftpoint& res, cell*& c) { res = T * rel; } +EX bool vr_clicked; + void move_according_to(vr::ETrackedControllerRole role, bool last, bool cur) { - if(!last && !cur) return; + if(cur) vr_clicked = true; int id = vr::VRSystem()->GetTrackedDeviceIndexForControllerRole(role); - if(id >= 0 && id < int(vr::k_unMaxTrackedDeviceCount)) { - hyperpoint h; - if(in_perspective_v()) { - if(1) { - E4; - transmatrix T = (hsm == eHeadset::none ? hmd_at : hmd_ref_at) * vrdata.pose_matrix[id] * sm; - vrhr::be_33(T); - h = T * point31(0, 0, -0.01); - } - if(last && !cur) - movevrdir(h); - else { - movedir md = vectodir(h); - cellwalker xc = cwt + md.d + wstep; - forward_cell = xc.at; - } - } - else { - compute_point(id, mouseh, forward_cell); - if(forward_cell && last && !cur) { - calcMousedest(); - if(!canmove) movepcto(mousedest), remission(); else movepcto(mousedest); - forward_cell = nullptr; - } - } + if((last || cur) && id >= 0 && id < int(vr::k_unMaxTrackedDeviceCount)) { + println(hlog, "click setting which_pointer to ", id); + which_pointer = id; } } @@ -517,27 +547,10 @@ struct set_data { }; vector dads = { - digital_action_data("/actions/menu/in/SelectLeft", [] { return !(cmode && sm::NORMAL); }, [] (bool last, bool curr) { - if(curr && !last) { - int id = vr::VRSystem()->GetTrackedDeviceIndexForControllerRole( vr::TrackedControllerRole_LeftHand); - if(id >= 0 && id < int(vr::k_unMaxTrackedDeviceCount)) - vrdata.cdata[id].clicked = true; - } - }), - digital_action_data("/actions/menu/in/SelectRight", [] { return !(cmode && sm::NORMAL); }, [] (bool last, bool curr) { - if(curr && !last) { - int id = vr::VRSystem()->GetTrackedDeviceIndexForControllerRole( vr::TrackedControllerRole_RightHand); - if(id >= 0 && id < int(vr::k_unMaxTrackedDeviceCount)) - vrdata.cdata[id].clicked = true; - } - }), - digital_action_data("/actions/menu/in/Exit", [] { return !(cmode && sm::NORMAL); }, [] (bool last, bool curr) { - if(curr && !last) dialog::queue_key(PSEUDOKEY_EXIT); - }), - digital_action_data("/actions/game/in/MoveLeft", [] { return (cmode && sm::NORMAL); }, [] (bool last, bool curr) { + digital_action_data("/actions/general/in/ClickLeft", [] { return true; }, [] (bool last, bool curr) { move_according_to(vr::TrackedControllerRole_LeftHand, last, curr); }), - digital_action_data("/actions/game/in/MoveRight", [] { return (cmode && sm::NORMAL); }, [] (bool last, bool curr) { + digital_action_data("/actions/general/in/ClickRight", [] { return true; }, [] (bool last, bool curr) { move_according_to(vr::TrackedControllerRole_RightHand, last, curr); }), digital_action_data("/actions/game/in/Drop", [] { return (cmode && sm::NORMAL); }, [] (bool last, bool curr) { @@ -546,8 +559,8 @@ vector dads = { digital_action_data("/actions/game/in/Skip turn", [] { return (cmode && sm::NORMAL); }, [] (bool last, bool curr) { if(curr && !last) dialog::queue_key('s'); }), - digital_action_data("/actions/game/in/EnterMenu", [] { return (cmode && sm::NORMAL); }, [] (bool last, bool curr) { - if(curr && !last) dialog::queue_key(PSEUDOKEY_MENU); + digital_action_data("/actions/general/in/Menu", [] { return true; }, [] (bool last, bool curr) { + if(curr && !last) always_show_hud = !always_show_hud; }), digital_action_data("/actions/general/in/SetReference", [] { return true; }, [] (bool last, bool curr) { if(curr && !last) hmd_ref_at = hmd_at; @@ -565,8 +578,11 @@ vector aads = { }), }; +EX bool always_show_hud = false; +EX bool in_actual_menu() { return !(cmode & (sm::NORMAL | sm::DRAW)); } +EX bool in_menu() { return always_show_hud || in_actual_menu(); } + vector sads = { - set_data("/actions/menu", 20, [] { return !(cmode & sm::NORMAL); }), set_data("/actions/game", 20, [] { return cmode & sm::NORMAL; }), set_data("/actions/general", 10, [] { return true; }) }; @@ -602,6 +618,8 @@ EX void track_actions() { for(auto& cd: vrdata.cdata) cd.clicked = false; + vr_clicked = false; + forward_cell = nullptr; vector sets;