diff --git a/.clang-format b/.clang-format new file mode 100644 index 0000000..0c43460 --- /dev/null +++ b/.clang-format @@ -0,0 +1,4 @@ +BasedOnStyle: Microsoft +UseTab: Always +ReflowComments: false +ColumnLimit: 0 diff --git a/src/main.cpp b/src/main.cpp index efbe2e4..c4b2c96 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,12 +1,15 @@ -#include #include +#include -#include #include +#include +#include -#include "openvr/openvr.h" +#include "../openvr/openvr.h" +#include "util.h" auto TRACKING_UNIVERSE = vr::ETrackingUniverseOrigin::TrackingUniverseStanding; +const vr::HmdMatrix34_t DEFAULT_POSE = {{{1, 0, 0, 0}, {0, -1, 0, 1}, {0, 0, 1, 0}}}; #define FRAMERATE 30 @@ -59,8 +62,8 @@ void init_vr() vr::EVRInitError init_err; ovr_sys = vr::VR_Init(&init_err, vr::EVRApplicationType::VRApplication_Overlay); assert(init_err == 0); + printf("Initialized openvr\n"); ovr_overlay = vr::VROverlay(); - printf("Initialized openvr overlay\n"); } void init_overlay() @@ -73,12 +76,7 @@ void init_overlay() ovr_overlay->SetOverlayRaw(main_overlay, &col, 1, 1, 4); printf("Created overlay instance\n"); - vr::HmdMatrix34_t transform; - auto err = ovr_overlay->GetOverlayTransformAbsolute(main_overlay, &TRACKING_UNIVERSE, &transform); - assert(err == 0); - transform.m[1][1] = -1; // flip Y axis - err = ovr_overlay->SetOverlayTransformAbsolute(main_overlay, TRACKING_UNIVERSE, &transform); - assert(err == 0); + ovr_overlay->SetOverlayTransformAbsolute(main_overlay, TRACKING_UNIVERSE, &DEFAULT_POSE); } void render_desktop() @@ -111,6 +109,89 @@ void update_cursor() ovr_overlay->SetOverlayCursorPositionOverride(main_overlay, &pos); } +bool is_grab_active(vr::TrackedDeviceIndex_t controller) +{ + vr::VRControllerState_t state; + ovr_sys->GetControllerState(controller, &state, sizeof(state)); + + auto trigger_mask = vr::ButtonMaskFromId(vr::EVRButtonId::k_EButton_SteamVR_Trigger); + auto b_mask = vr::ButtonMaskFromId(vr::EVRButtonId::k_EButton_IndexController_B); + auto mask = trigger_mask | b_mask; + return (state.ulButtonPressed & mask) == mask; +} + +vr::HmdMatrix34_t get_controller_pose(vr::TrackedDeviceIndex_t controller) +{ + vr::VRControllerState_t state; + vr::TrackedDevicePose_t tracked_pose; + ovr_sys->GetControllerStateWithPose(TRACKING_UNIVERSE, controller, &state, sizeof(state), &tracked_pose); + return tracked_pose.mDeviceToAbsoluteTracking; +} + +void update_pos() +{ + static bool is_held = false; + static vr::TrackedDeviceIndex_t active_controller; + + if (!is_held) + { + vr::TrackedDeviceIndex_t controllers[8]; + auto controller_count = ovr_sys->GetSortedTrackedDeviceIndicesOfClass(vr::ETrackedDeviceClass::TrackedDeviceClass_Controller, controllers, 8); + + for (int i = 0; i < controller_count; i++) + { + auto controller = controllers[i]; + + auto controller_pose = get_controller_pose(controller); + + vr::HmdMatrix34_t overlay_pose; + ovr_overlay->GetOverlayTransformAbsolute(main_overlay, &TRACKING_UNIVERSE, &overlay_pose); + + auto controller_pos = glm::vec3(controller_pose.m[0][3], controller_pose.m[1][3], controller_pose.m[2][3]); + auto overlay_pos = glm::vec3(overlay_pose.m[0][3], overlay_pose.m[1][3], overlay_pose.m[2][3]); + + bool close_enough = glm::length(overlay_pos - controller_pos) < 1.0f; + // close_enough = true; + + if (close_enough && is_grab_active(controller)) + { + // printf("Grabbed screen\n"); + is_held = true; + active_controller = controller; + + vr::HmdMatrix34_t abs_pose; + + ovr_overlay->GetOverlayTransformAbsolute(main_overlay, &TRACKING_UNIVERSE, &abs_pose); + auto abs_mat = convert_mat(abs_pose); + + auto controller_mat = convert_mat(get_controller_pose(controller)); + + vr::HmdMatrix34_t relative_pose = convert_mat(glm::inverse(controller_mat) * (abs_mat)); + + ovr_overlay->SetOverlayTransformTrackedDeviceRelative(main_overlay, controller, &relative_pose); + } + } + } + else + { + if (!is_grab_active(active_controller)) + { + // printf("Released screen\n"); + is_held = false; + + vr::HmdMatrix34_t relative_pose; + ovr_overlay->GetOverlayTransformTrackedDeviceRelative(main_overlay, &active_controller, &relative_pose); + auto relative_mat = convert_mat(relative_pose); + + auto controller_mat = convert_mat(get_controller_pose(active_controller)); + + vr::HmdMatrix34_t new_pose = convert_mat(controller_mat * relative_mat); + + ovr_overlay->SetOverlayTransformAbsolute(main_overlay, TRACKING_UNIVERSE, &new_pose); + } + } +} + void interrupted(int _sig) { should_exit = true; @@ -130,6 +211,8 @@ int main() render_desktop(); update_cursor(); + update_pos(); + glfwSwapBuffers(gl_window); usleep(1000000 / FRAMERATE); } diff --git a/src/util.h b/src/util.h new file mode 100644 index 0000000..a8f6ebd --- /dev/null +++ b/src/util.h @@ -0,0 +1,38 @@ +#include "../openvr/openvr.h" +#include + +inline void print_matrix(vr::HmdMatrix34_t m) +{ + printf("[%.2f, %.2f, %.2f, %.2f]\n", m.m[0][0], m.m[0][1], m.m[0][2], m.m[0][3]); + printf("[%.2f, %.2f, %.2f, %.2f]\n", m.m[1][0], m.m[1][1], m.m[1][2], m.m[1][3]); + printf("[%.2f, %.2f, %.2f, %.2f]\n", m.m[2][0], m.m[2][1], m.m[2][2], m.m[2][3]); +} + +inline void print_matrix(glm::mat4x4 m) +{ + printf("[%.2f, %.2f, %.2f, %.2f]\n", m[0][0], m[0][1], m[0][2], m[0][3]); + printf("[%.2f, %.2f, %.2f, %.2f]\n", m[1][0], m[1][1], m[1][2], m[1][3]); + printf("[%.2f, %.2f, %.2f, %.2f]\n", m[2][0], m[2][1], m[2][2], m[2][3]); + printf("[%.2f, %.2f, %.2f, %.2f]\n", m[3][0], m[3][1], m[3][2], m[3][3]); +} + +inline glm::mat4x4 convert_mat(vr::HmdMatrix34_t mat) +{ + auto m = mat.m; + return glm::mat4x4( + m[0][0], m[1][0], m[2][0], 0, + m[0][1], m[1][1], m[2][1], 0, + m[0][2], m[1][2], m[2][2], 0, + m[0][3], m[1][3], m[2][3], 1); +} + +inline vr::HmdMatrix34_t convert_mat(glm::mat4x4 m) +{ + // clang-format off + return vr::HmdMatrix34_t{{ + {m[0][0], m[1][0], m[2][0], m[3][0]}, + {m[0][1], m[1][1], m[2][1], m[3][1]}, + {m[0][2], m[1][2], m[2][2], m[3][2]} + }}; + // clang-format on +} \ No newline at end of file