diff --git a/control.cpp b/control.cpp index 21a13918..d5f85fb6 100644 --- a/control.cpp +++ b/control.cpp @@ -608,14 +608,15 @@ EX bool need_mouseh = false; EX void fix_mouseh() { if(0) ; +#if CAP_RUG + else if(rug::rugged) { + if(need_mouseh || (vrhr::active() && which_pointer)) + mouseh = rug::gethyper(mousex, mousey); + } +#endif #if CAP_VR else if(vrhr::active() && which_pointer && !vrhr::targeting_menu) vrhr::compute_point(which_pointer, mouseh, mouseover, vrhr::pointer_distance); -#endif - else if(!need_mouseh) ; -#if CAP_RUG - else if(rug::rugged) - mouseh = rug::gethyper(mousex, mousey); #endif else { if(dual::state) { diff --git a/rug.cpp b/rug.cpp index 2916e126..c97cee63 100644 --- a/rug.cpp +++ b/rug.cpp @@ -1331,6 +1331,21 @@ EX shiftpoint gethyper(ld x, ld y) { double mx = (x - current_display->xcenter)/current_display->radius; double my = (y - current_display->ycenter)/current_display->radius/pconf.stretch; + + bool vr = vrhr::active() && which_pointer; + transmatrix T = Id, U; + + if(1) { + USING_NATIVE_GEOMETRY; + U = ortho_inverse(NLP) * rugView; + } + + if(vr) { + mx = my = 0; + E4; + vrhr::gen_mv(); + T = vrhr::screen_to_controller(which_pointer); + } calcparam(); @@ -1339,6 +1354,9 @@ EX shiftpoint gethyper(ld x, ld y) { double rx1=0, ry1=0; bool found = false; + + auto md = pmodel; + if(vrhr::active()) md = vrhr::pmodel_3d_version(); for(int i=0; inative), p0); - applymodel(shiftless(ortho_inverse(NLP) * rugView * r1->native), p1); - applymodel(shiftless(ortho_inverse(NLP) * rugView * r2->native), p2); + apply_other_model(shiftless(U * r0->native), p0, md); + apply_other_model(shiftless(U * r1->native), p1, md); + apply_other_model(shiftless(U * r2->native), p2, md); } if(error || spherepoints == 1 || spherepoints == 2) continue; + + if(vr) { + E4; + p0[3] = 1; p0 = T * p0; + p1[3] = 1; p1 = T * p1; + p2[3] = 1; p2 = T * p2; + } + double dx1 = p1[0] - p0[0]; double dy1 = p1[1] - p0[1]; double dx2 = p2[0] - p0[0]; @@ -1381,10 +1407,12 @@ EX shiftpoint gethyper(ld x, ld y) { if(tx >= 0 && ty >= 0 && tx+ty <= 1) { double rz1 = p0[2] * (1-tx-ty) + p1[2] * tx + p2[2] * ty; rz1 = -rz1; - if(rz1 < radar_distance) { + if(vr && rz1 < 0) { /* behind the controller, ignore */ } + else if(rz1 < radar_distance) { radar_distance = rz1; rx1 = r0->x1 + (r1->x1 - r0->x1) * tx + (r2->x1 - r0->x1) * ty; ry1 = r0->y1 + (r1->y1 - r0->y1) * tx + (r2->y1 - r0->y1) * ty; + if(vr) vrhr::pointer_distance = radar_distance; } found = true; } diff --git a/vr.cpp b/vr.cpp index badfab00..887ffc27 100644 --- a/vr.cpp +++ b/vr.cpp @@ -468,12 +468,17 @@ EX ld absolute_unit_in_meters = 3; /** what point and cell is the controller number id pointing to */ -eModel pmodel_3d_version() { +EX eModel pmodel_3d_version() { if(pmodel == mdGeodesic) return mdEquidistant; if(pmodel == mdPerspective) return nonisotropic ? mdHorocyclic : mdEquidistant; return pmodel; } +/** convert model coordinates to controller-relative coordinates */ +EX transmatrix screen_to_controller(int id) { + return inverse(sm * hmd_at * vrdata.pose_matrix[id] * sm) * hmd_mv; + } + ld vr_distance(shiftpoint h, int id, ld& dist) { hyperpoint hscr; h.h = hmd_pre_for[2] * h.h; @@ -482,7 +487,7 @@ ld vr_distance(shiftpoint h, int id, ld& dist) { if(in_vr_sphere && get_side(hscr) == (sphereflipped() ? -1 : 1)) return 1e5; E4; hscr[3] = 1; - hyperpoint hc = inverse(sm * hmd_at * vrdata.pose_matrix[id] * sm) * hmd_mv * hscr; + hyperpoint hc = screen_to_controller(id) * hscr; if(WDIM == 2) { if(hc[2] > 0.1) return 1e6; /* behind */ dist = -hc[2];