From 41f01e29a6a1669dc6cfe56238bbda8b75b54c1d Mon Sep 17 00:00:00 2001 From: CrispyPin Date: Tue, 11 Apr 2023 18:03:03 +0200 Subject: [PATCH] convert to steamvr input system & add binding to toggle all overlays --- Makefile | 2 +- bindings/action_manifest.json | 40 +++++++++++++++ bindings/index_controller.json | 33 ++++++++++++ src/app.cpp | 93 ++++++++++++++++++++++++---------- src/app.h | 23 ++++++++- src/panel.cpp | 35 ++++++++----- src/panel.h | 2 + 7 files changed, 186 insertions(+), 42 deletions(-) create mode 100644 bindings/action_manifest.json create mode 100644 bindings/index_controller.json diff --git a/Makefile b/Makefile index e42894c..c88c265 100644 --- a/Makefile +++ b/Makefile @@ -1,7 +1,7 @@ build: - CPATH=. g++ -Wall -lX11 -lXrandr -lglfw -lGL openvr/libopenvr_api.so src/*.cpp -o overlay + g++ -Wall -lX11 -lXrandr -lglfw -lGL openvr/libopenvr_api.so src/*.cpp -o overlay run: build ./overlay diff --git a/bindings/action_manifest.json b/bindings/action_manifest.json new file mode 100644 index 0000000..ddd3886 --- /dev/null +++ b/bindings/action_manifest.json @@ -0,0 +1,40 @@ +{ + "default_bindings": [ + { + "controller_type": "knuckles", + "binding_url": "index_controller.json" + } + ], + "actions": [ + { + "name": "/actions/main/in/ToggleAll", + "requirement": "mandatory", + "type": "boolean" + }, + { + "name": "/actions/main/in/Grab", + "requirement": "mandatory", + "type": "boolean" + }, + { + "name": "/actions/main/in/Distance", + "requirement": "suggested", + "type": "vector2" + } + ], + "action_sets": [ + { + "name": "/actions/main", + "usage": "leftright" + } + ], + "localization": [ + { + "language_tag": "en_us", + "/actions/main": "Overlay actions", + "/actions/main/in/ToggleAll": "Toggle all", + "/actions/main/in/Grab": "Grab panel", + "/actions/main/in/Distance": "Move away" + } + ] +} \ No newline at end of file diff --git a/bindings/index_controller.json b/bindings/index_controller.json new file mode 100644 index 0000000..ebfb3c8 --- /dev/null +++ b/bindings/index_controller.json @@ -0,0 +1,33 @@ +{ + "/actions/main": { + "sources": [ + { + "path": "/user/hand/right/input/b", + "mode": "button", + "inputs": { + "long": { + "output": "/actions/main/in/toggleall" + } + } + }, + { + "path": "/user/hand/right/input/thumbstick", + "mode": "joystick", + "inputs": { + "position": { + "output": "/actions/main/in/distance" + } + } + }, + { + "path": "/user/hand/right/input/trigger", + "mode": "button", + "inputs": { + "click": { + "output": "/actions/main/in/grab" + } + } + } + ] + } +} \ No newline at end of file diff --git a/src/app.cpp b/src/app.cpp index 2381e78..93cc016 100644 --- a/src/app.cpp +++ b/src/app.cpp @@ -7,6 +7,7 @@ App::App() { _tracking_origin = vr::TrackingUniverseStanding; + // _hidden = false; InitOVR(); InitX11(); @@ -34,6 +35,22 @@ App::App() vr::HmdMatrix34_t start_pose = {{{1, 0, 0, pos_x}, {0, 1, 0, pos_y}, {0, 0, 1, 0}}}; _panels.push_back(Panel(this, start_pose, i, mon.x, mon.y, mon.width, mon.height)); } + + { // initialize SteamVR input + auto exe_path = std::filesystem::read_symlink("/proc/self/exe"); + _actions_path = exe_path.parent_path().string() + "/bindings/action_manifest.json"; + printf("actions path: %s\n", _actions_path.c_str()); + vr_input->SetActionManifestPath(_actions_path.c_str()); + + auto action_err = vr_input->GetActionHandle("/actions/main/in/Grab", &_input_handles.grab); + assert(action_err == 0); + action_err = vr_input->GetActionHandle("/actions/main/in/ToggleAll", &_input_handles.toggle); + assert(action_err == 0); + action_err = vr_input->GetActionHandle("/actions/main/in/Distance", &_input_handles.distance); + assert(action_err == 0); + action_err = vr_input->GetActionSetHandle("/actions/main", &_input_handles.set); + assert(action_err == 0); + } } App::~App() @@ -72,6 +89,7 @@ void App::InitOVR() } printf("Initialized OpenVR\n"); vr_overlay = vr::VROverlay(); + vr_input = vr::VRInput(); } void App::InitGLFW() @@ -86,6 +104,42 @@ void App::InitGLFW() } void App::Update() +{ + UpdateInput(); + if (!_hidden) + { + UpdateFramebuffer(); + for (auto &panel : _panels) + { + panel.Update(); + } + } +} + +void App::UpdateInput() +{ + vr::VRActiveActionSet_t main; + main.ulActionSet = _input_handles.set; + main.ulRestrictedToDevice = 0; + vr_input->UpdateActionState(&main, sizeof(vr::VRActiveActionSet_t), 1); + + vr_sys->GetDeviceToAbsoluteTrackingPose(_tracking_origin, 0, _tracker_poses, vr::k_unMaxTrackedDeviceCount); + + for (unsigned int i = 0; i < vr::k_unMaxTrackedDeviceCount; i++) + { + if (IsInputJustPressed(i, _input_handles.toggle)) + { + _hidden = !_hidden; + for (auto &panel : _panels) + { + panel.SetHidden(_hidden); + } + break; + } + } +} + +void App::UpdateFramebuffer() { auto frame = XGetImage( _xdisplay, @@ -97,11 +151,6 @@ void App::Update() glBindTexture(GL_TEXTURE_2D, _gl_frame); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, _root_width, _root_height, 0, GL_BGRA, GL_UNSIGNED_BYTE, frame->data); XDestroyImage(frame); - - for (auto &panel : _panels) - { - panel.Update(); - } } std::vector App::GetControllers() @@ -114,35 +163,27 @@ std::vector App::GetControllers() glm::mat4 App::GetTrackerPose(TrackerID tracker) { - vr::VRControllerState_t state; - vr::TrackedDevicePose_t tracked_pose; - vr_sys->GetControllerStateWithPose( - _tracking_origin, - tracker, - &state, - sizeof(vr::VRControllerState_t), - &tracked_pose); - return ConvertMat(tracked_pose.mDeviceToAbsoluteTracking); + return ConvertMat(_tracker_poses[tracker].mDeviceToAbsoluteTracking); } -vr::VRControllerState_t App::GetControllerState(TrackerID controller) +vr::InputDigitalActionData_t App::GetControllerInputDigital(TrackerID controller, vr::VRActionHandle_t action) { - vr::VRControllerState_t state; - auto get_state_err = vr_sys->GetControllerState(controller, &state, sizeof(vr::VRControllerState_t)); - if (get_state_err == false) - printf("failed to get state of controller %d\n", controller); + vr::InputDigitalActionData_t state; + vr_input->GetDigitalActionData(action, &state, sizeof(vr::InputDigitalActionData_t), 0); return state; } -bool App::IsGrabActive(TrackerID controller) +vr::InputAnalogActionData_t App::GetControllerInputAnalog(TrackerID controller, vr::VRActionHandle_t action) { - vr::VRControllerState_t state; - auto get_state_err = vr_sys->GetControllerState(controller, &state, sizeof(vr::VRControllerState_t)); - if (get_state_err == false) - return false; + vr::InputAnalogActionData_t state; + vr_input->GetAnalogActionData(action, &state, sizeof(vr::InputAnalogActionData_t), 0); + return state; +} - auto trigger_mask = vr::ButtonMaskFromId(vr::k_EButton_SteamVR_Trigger); - return state.ulButtonPressed & trigger_mask; +bool App::IsInputJustPressed(TrackerID controller, vr::VRActionHandle_t action) +{ + auto data = GetControllerInputDigital(controller, action); + return data.bState && data.bChanged; } CursorPos App::GetCursorPosition() diff --git a/src/app.h b/src/app.h index d881b2e..09ac9e2 100644 --- a/src/app.h +++ b/src/app.h @@ -2,6 +2,7 @@ #include "util.h" #include #include +#include #include class Panel; @@ -11,6 +12,14 @@ struct CursorPos int x, y; }; +struct InputHandles +{ + vr::VRActionSetHandle_t set; + vr::VRActionHandle_t toggle; + vr::VRActionHandle_t distance; + vr::VRActionHandle_t grab; +}; + class App { public: @@ -20,8 +29,9 @@ class App std::vector GetControllers(); glm::mat4 GetTrackerPose(TrackerID tracker); - vr::VRControllerState_t GetControllerState(TrackerID controller); - bool IsGrabActive(TrackerID controller); + vr::InputDigitalActionData_t GetControllerInputDigital(TrackerID controller, vr::VRActionHandle_t action); + vr::InputAnalogActionData_t GetControllerInputAnalog(TrackerID controller, vr::VRActionHandle_t action); + bool IsInputJustPressed(TrackerID controller, vr::VRActionHandle_t action); CursorPos GetCursorPosition(); Display *_xdisplay; @@ -33,14 +43,23 @@ class App int _root_height; vr::ETrackingUniverseOrigin _tracking_origin; + std::filesystem::path _actions_path; vr::IVRSystem *vr_sys; vr::IVROverlay *vr_overlay; + vr::IVRInput *vr_input; + + InputHandles _input_handles; + vr::TrackedDevicePose_t _tracker_poses[vr::k_unMaxTrackedDeviceCount]; std::vector _panels; + bool _hidden = false; private: void InitX11(); void InitOVR(); void InitGLFW(); + + void UpdateFramebuffer(); + void UpdateInput(); }; \ No newline at end of file diff --git a/src/panel.cpp b/src/panel.cpp index ce2a910..1835e34 100644 --- a/src/panel.cpp +++ b/src/panel.cpp @@ -55,7 +55,7 @@ void Panel::Update() { for (auto controller : _app->GetControllers()) { - if (_app->IsGrabActive(controller)) + if (_app->IsInputJustPressed(controller, _app->_input_handles.grab)) { vr::HmdMatrix34_t overlay_pose; vr::ETrackingUniverseOrigin tracking_universe; @@ -79,19 +79,19 @@ void Panel::Update() } else { - if (!_app->IsGrabActive(_active_hand)) + if (!_app->GetControllerInputDigital(_active_hand, _app->_input_handles.grab).bState) { ControllerRelease(); } - auto state = _app->GetControllerState(_active_hand); - auto touchpad = state.rAxis[0]; - if (touchpad.x != 0.0f) - { - // TODO take into account the current framerate - _alpha += touchpad.x * 0.05; - _alpha = glm::clamp(_alpha, 0.1f, 1.0f); - _app->vr_overlay->SetOverlayAlpha(_id, _alpha); - } + // auto state = _app->GetControllerState(_active_hand); + // auto touchpad = state.rAxis[0]; + // if (touchpad.x != 0.0f) + // { + // // TODO take into account the current framerate + // _alpha += touchpad.x * 0.05; + // _alpha = glm::clamp(_alpha, 0.1f, 1.0f); + // _app->vr_overlay->SetOverlayAlpha(_id, _alpha); + // } } } @@ -108,6 +108,15 @@ void Panel::Render() assert(set_texture_err == 0); } +void Panel::SetHidden(bool state) +{ + _hidden = state; + if (state) + _app->vr_overlay->HideOverlay(_id); + else + _app->vr_overlay->ShowOverlay(_id); +} + void Panel::UpdateCursor() { auto global_pos = _app->GetCursorPosition(); @@ -130,7 +139,7 @@ void Panel::UpdateCursor() void Panel::ControllerGrab(TrackerID controller) { - printf("Grabbed panel %d\n", _index); + // printf("Grabbed panel %d\n", _index); _is_held = true; _active_hand = controller; @@ -151,7 +160,7 @@ void Panel::ControllerGrab(TrackerID controller) void Panel::ControllerRelease() { - printf("Released panel %d\n", _index); + // printf("Released panel %d\n", _index); _is_held = false; _app->vr_overlay->SetOverlayColor(_id, 1.0f, 1.0f, 1.0f); diff --git a/src/panel.h b/src/panel.h index 4b3a3e2..9e2fad9 100644 --- a/src/panel.h +++ b/src/panel.h @@ -13,6 +13,7 @@ class Panel Panel(App *app, vr::HmdMatrix34_t start_pose, int index, int xmin, int xmax, int ymin, int ymax); void Update(); + void SetHidden(bool state); private: void Render(); @@ -32,6 +33,7 @@ class Panel int _width, _height; float _meters; float _alpha; + bool _hidden; vr::Texture_t _texture; GLuint _gl_texture;