From 8b7a3e0067ea82b452b2112e2fda41ecc9760dd9 Mon Sep 17 00:00:00 2001 From: CrispyPin Date: Mon, 1 May 2023 18:21:28 +0200 Subject: [PATCH 1/7] prevent accidental dragging by locking cursor in place while mouse movement is small --- src/app.cpp | 1 + src/controller.cpp | 17 ++++++++++++----- src/controller.h | 6 ++++-- 3 files changed, 17 insertions(+), 7 deletions(-) diff --git a/src/app.cpp b/src/app.cpp index a2cdeb1..caa4500 100644 --- a/src/app.cpp +++ b/src/app.cpp @@ -142,6 +142,7 @@ void App::InitRootOverlay() _root_overlay.SetWidth(0.25f); _root_overlay.SetTransformWorld(&root_start_pose); _root_overlay.SetTextureToColor(110, 30, 190); + _root_overlay.SetHidden(true); } void App::Update(float dtime) diff --git a/src/controller.cpp b/src/controller.cpp index 6f7891e..9597303 100644 --- a/src/controller.cpp +++ b/src/controller.cpp @@ -7,7 +7,8 @@ const float LASER_WIDTH = 0.004f; const Color EDIT_COLOR{1, 0.6f, 1}; const Color CURSOR_COLOR{0.3f, 1, 1}; -const float SCROLL_SPEED = 48.0f; +const float SCROLL_SPEED = 48; +const float MOUSE_DRAG_THRESHOLD = 48; Controller::Controller(App *app, ControllerSide side) { @@ -16,8 +17,6 @@ Controller::Controller(App *app, ControllerSide side) _input_handle = 0; _is_connected = false; _side = side; - _cursor_active = false; - _last_sent_scroll = 0; std::string laser_name = "controller_laser_"; if (side == ControllerSide::Left) @@ -126,7 +125,6 @@ void Controller::Update(float dtime) } if (_cursor_active) { - // printf("update cursor on hand %d\n", _side); if (_last_ray.overlay != nullptr && _last_ray.hit_panel != nullptr) { auto pos = glm::vec2(_last_ray.local_pos.x, _last_ray.local_pos.y); @@ -139,7 +137,15 @@ void Controller::Update(float dtime) pos.y += 0.5f * _last_ray.overlay->Ratio(); pos *= _last_ray.hit_panel->Width(); - _last_ray.hit_panel->SetCursor(pos.x, pos.y); + if (glm::length(pos - _last_set_mouse_pos) > MOUSE_DRAG_THRESHOLD) + { + _mouse_drag_lock = false; + } + if (!_mouse_drag_lock) + { + _last_ray.hit_panel->SetCursor(pos.x, pos.y); + _last_set_mouse_pos = pos; + } } UpdateMouseButton(_app->_input_handles.cursor.mouse_left, 1); UpdateMouseButton(_app->_input_handles.cursor.mouse_middle, 2); @@ -173,6 +179,7 @@ void Controller::UpdateMouseButton(vr::VRActionHandle_t binding, unsigned int bu if (state.bChanged) { _app->SendMouseInput(button, state.bState); + _mouse_drag_lock = state.bState; } } diff --git a/src/controller.h b/src/controller.h index 56531f5..e055a80 100644 --- a/src/controller.h +++ b/src/controller.h @@ -28,7 +28,7 @@ class Controller void Update(float dtime); - bool _cursor_active; + bool _cursor_active = false; private: void UpdateStatus(); @@ -50,5 +50,7 @@ class Controller glm::vec3 _last_rotation; glm::vec3 _last_pos; - float _last_sent_scroll; + float _last_sent_scroll = 0; + bool _mouse_drag_lock = false; + glm::vec2 _last_set_mouse_pos; }; From 47ebf9d64cf8f879ebfa721cf91949849faf15bb Mon Sep 17 00:00:00 2001 From: CrispyPin Date: Wed, 3 May 2023 20:37:03 +0200 Subject: [PATCH 2/7] fix raycasts going backwards when a controller is behind an overlay --- src/overlay.cpp | 29 +++++++++++++++-------------- 1 file changed, 15 insertions(+), 14 deletions(-) diff --git a/src/overlay.cpp b/src/overlay.cpp index a35f61a..a5ab795 100644 --- a/src/overlay.cpp +++ b/src/overlay.cpp @@ -159,28 +159,29 @@ void Overlay::SetTargetWorld() SetTransformWorld(&abs_pose); } -Ray Overlay::IntersectRay(glm::vec3 origin, glm::vec3 direction, float max_len) +Ray Overlay::IntersectRay(glm::vec3 ray_start_g, glm::vec3 direction, float max_len) { float dist = max_len; - auto end = origin + direction * max_len; + auto ray_end_g = ray_start_g + direction * max_len; auto panel_transform = GetTransformAbsolute(); auto panel_pos = GetPos(panel_transform); - auto a = glm::inverse(panel_transform) * glm::vec4(origin - panel_pos, 0); - auto b = glm::inverse(panel_transform) * glm::vec4(end - panel_pos, 0); - float r = a.z / (a.z - b.z); - auto p = a + (b - a) * r; - // printf("panel pos: (%.2f,%.2f,%.2f)\n", panel_pos.x, panel_pos.y, panel_pos.z); - // printf("a: (%.2f,%.2f,%.2f)\n", a.x, a.y, a.z); - // printf("b: (%.2f,%.2f,%.2f)\n", b.x, b.y, b.z); - // printf("r: %.2f\n", r); - // printf("p: (%.2f,%.2f,%.2f)\n", p.x, p.y, p.z); + auto ray_start = glm::inverse(panel_transform) * glm::vec4(ray_start_g - panel_pos, 0); + auto ray_end = glm::inverse(panel_transform) * glm::vec4(ray_end_g - panel_pos, 0); + float length_frac = ray_start.z / (ray_start.z - ray_end.z); + auto hit_pos = ray_start + (ray_end - ray_start) * length_frac; - if (b.z < a.z && b.z < 0 && glm::abs(p.x) < (_width_m * 0.5f) && glm::abs(p.y) < (_width_m * 0.5f * _ratio)) + // clang-format off + if (ray_end.z < ray_start.z + && ray_end.z < 0 + && glm::abs(hit_pos.x) < (_width_m * 0.5f) + && glm::abs(hit_pos.y) < (_width_m * 0.5f * _ratio) + && length_frac > 0) { - dist = glm::min(r * max_len, max_len); + // clang-format on + dist = glm::min(length_frac * max_len, max_len); } - return Ray{.overlay = this, .distance = dist, .local_pos = p, .hit_panel = nullptr}; + return Ray{.overlay = this, .distance = dist, .local_pos = hit_pos, .hit_panel = nullptr}; } glm::mat4x4 Overlay::GetTransformAbsolute() From 6f44ea6b5ac9449bd2ee912ce0a9fc727a4e5f07 Mon Sep 17 00:00:00 2001 From: CrispyPin Date: Wed, 3 May 2023 20:56:58 +0200 Subject: [PATCH 3/7] add haptic feedback on scroll --- bindings/action_manifest.json | 8 +++++++- bindings/index_controller.json | 10 ++++++++++ src/app.cpp | 2 ++ src/app.h | 1 + src/controller.cpp | 4 ++++ 5 files changed, 24 insertions(+), 1 deletion(-) diff --git a/bindings/action_manifest.json b/bindings/action_manifest.json index d4621c1..0c9128e 100644 --- a/bindings/action_manifest.json +++ b/bindings/action_manifest.json @@ -55,6 +55,11 @@ "name": "/actions/cursor/in/scroll", "requirement": "suggested", "type": "vector2" + }, + { + "name": "/actions/cursor/out/scroll_haptic", + "requirement": "suggested", + "type": "vibration" } ], "action_sets": [ @@ -83,7 +88,8 @@ "/actions/cursor/in/mouse_left": "left mouse button", "/actions/cursor/in/mouse_right": "right mouse button", "/actions/cursor/in/mouse_middle": "middle mouse button", - "/actions/cursor/in/scroll": "scroll" + "/actions/cursor/in/scroll": "scroll", + "/actions/cursor/out/scroll_haptic": "scrolling haptic feedback" } ] } \ No newline at end of file diff --git a/bindings/index_controller.json b/bindings/index_controller.json index de796c5..f42c299 100644 --- a/bindings/index_controller.json +++ b/bindings/index_controller.json @@ -141,6 +141,16 @@ "app_key" : "system.generated.sinpin_vr", "bindings" : { "/actions/cursor" : { + "haptics" : [ + { + "output" : "/actions/cursor/out/scroll_haptic", + "path" : "/user/hand/left/output/haptic" + }, + { + "output" : "/actions/cursor/out/scroll_haptic", + "path" : "/user/hand/right/output/haptic" + } + ], "sources" : [ { "inputs" : { diff --git a/src/app.cpp b/src/app.cpp index caa4500..72ff00a 100644 --- a/src/app.cpp +++ b/src/app.cpp @@ -75,6 +75,8 @@ App::App() assert(action_err == 0); action_err = vr_input->GetActionHandle("/actions/cursor/in/scroll", &_input_handles.cursor.scroll); assert(action_err == 0); + action_err = vr_input->GetActionHandle("/actions/cursor/out/scroll_haptic", &_input_handles.cursor.scroll_haptic); + assert(action_err == 0); action_err = vr_input->GetActionSetHandle("/actions/main", &_input_handles.main_set); assert(action_err == 0); action_err = vr_input->GetActionSetHandle("/actions/edit", &_input_handles.edit_set); diff --git a/src/app.h b/src/app.h index 232f74a..fa721ce 100644 --- a/src/app.h +++ b/src/app.h @@ -32,6 +32,7 @@ struct InputHandles vr::VRActionHandle_t mouse_right; vr::VRActionHandle_t mouse_middle; vr::VRActionHandle_t scroll; + vr::VRActionHandle_t scroll_haptic; } cursor; vr::VRActionSetHandle_t cursor_set; struct diff --git a/src/controller.cpp b/src/controller.cpp index 9597303..a9931de 100644 --- a/src/controller.cpp +++ b/src/controller.cpp @@ -8,6 +8,8 @@ const float LASER_WIDTH = 0.004f; const Color EDIT_COLOR{1, 0.6f, 1}; const Color CURSOR_COLOR{0.3f, 1, 1}; const float SCROLL_SPEED = 48; +const float SCROLL_HAPTIC_STRENGTH = 0.15f; +const float SCROLL_HAPTIC_TIME = 0.1f; const float MOUSE_DRAG_THRESHOLD = 48; Controller::Controller(App *app, ControllerSide side) @@ -161,11 +163,13 @@ void Controller::Update(float dtime) { _app->SendMouseInput(4, true); _app->SendMouseInput(4, false); + _app->vr_input->TriggerHapticVibrationAction(_app->_input_handles.cursor.scroll_haptic, 0, SCROLL_HAPTIC_TIME, 1 / SCROLL_HAPTIC_TIME, SCROLL_HAPTIC_STRENGTH, _input_handle); } else if (scroll_state.y < 0) { _app->SendMouseInput(5, true); _app->SendMouseInput(5, false); + _app->vr_input->TriggerHapticVibrationAction(_app->_input_handles.cursor.scroll_haptic, 0, SCROLL_HAPTIC_TIME, 1 / SCROLL_HAPTIC_TIME, SCROLL_HAPTIC_STRENGTH, _input_handle); } } } From ebb52a404d83739356f99f476ddd4c464786df2a Mon Sep 17 00:00:00 2001 From: CrispyPin Date: Wed, 3 May 2023 20:57:32 +0200 Subject: [PATCH 4/7] bump version --- Makefile | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Makefile b/Makefile index 3264bb6..dcb1dd9 100644 --- a/Makefile +++ b/Makefile @@ -1,6 +1,6 @@ -VERSION=v0.2.1 -# CC := g++ -CC := clang++ +VERSION=v0.2.2 +CC := g++ +# CC := clang++ LFLAGS := -lX11 -lXrandr -lXtst -lglfw -lGL LIBS := openvr/libopenvr_api.so SRC := src/*.cpp From 22496fcc35642073886bbd85677d8478c5e401ff Mon Sep 17 00:00:00 2001 From: CrispyPin Date: Wed, 3 May 2023 22:09:59 +0200 Subject: [PATCH 5/7] link executable properly so it can be started from other directories --- Makefile | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/Makefile b/Makefile index dcb1dd9..256e98a 100644 --- a/Makefile +++ b/Makefile @@ -1,18 +1,18 @@ VERSION=v0.2.2 -CC := g++ -# CC := clang++ + +CXX := g++ +# CXX := clang++ +CPPFLAGS := -g -Wall -std=c++17 LFLAGS := -lX11 -lXrandr -lXtst -lglfw -lGL -LIBS := openvr/libopenvr_api.so -SRC := src/*.cpp -OUT := ./sinpin_vr -CPPFLAGS := -Wall -std=c++17 $(LFLAGS) $(LIBS) $(SRC) -o $(OUT) +OVR := -Lopenvr -lopenvr_api +TARGET := ./sinpin_vr build: - $(CC) -g $(CPPFLAGS) + $(CXX) src/*.cpp $(CPPFLAGS) $(LFLAGS) -Wl,-rpath,'$$ORIGIN/openvr' $(OVR) -o $(TARGET) release: build zip -r sinpin_vr-$(VERSION).zip sinpin_vr bindings openvr/libopenvr_api.so run: build - $(OUT) + $(TARGET) From 2c0386b1418a5c5b3889b1721b554ecc6ce1e417 Mon Sep 17 00:00:00 2001 From: CrispyPin Date: Thu, 4 May 2023 22:27:47 +0200 Subject: [PATCH 6/7] refactor packaging --- .gitignore | 1 + Makefile | 13 +++++++++---- {openvr => lib}/libopenvr_api.so | Bin {openvr => lib}/openvr.h | 0 src/util.h | 2 +- 5 files changed, 11 insertions(+), 5 deletions(-) rename {openvr => lib}/libopenvr_api.so (100%) rename {openvr => lib}/openvr.h (100%) diff --git a/.gitignore b/.gitignore index 0aeec18..60b3c90 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ sinpin_vr .vscode/ *.zip +*.tar.xz diff --git a/Makefile b/Makefile index 256e98a..ce81dcc 100644 --- a/Makefile +++ b/Makefile @@ -1,17 +1,22 @@ -VERSION=v0.2.2 +VERSION=v0.2.3 CXX := g++ # CXX := clang++ CPPFLAGS := -g -Wall -std=c++17 LFLAGS := -lX11 -lXrandr -lXtst -lglfw -lGL -OVR := -Lopenvr -lopenvr_api +OVR := -Llib -lopenvr_api TARGET := ./sinpin_vr build: - $(CXX) src/*.cpp $(CPPFLAGS) $(LFLAGS) -Wl,-rpath,'$$ORIGIN/openvr' $(OVR) -o $(TARGET) + $(CXX) src/*.cpp $(CPPFLAGS) $(LFLAGS) -Wl,-rpath,'$$ORIGIN/lib' $(OVR) -o $(TARGET) release: build - zip -r sinpin_vr-$(VERSION).zip sinpin_vr bindings openvr/libopenvr_api.so + mkdir -p sinpin-vr/lib + cp lib/libopenvr_api.so sinpin-vr/lib + cp -r bindings sinpin-vr + cp sinpin_vr sinpin-vr + tar -caf sinpin-vr-$(VERSION).tar.xz sinpin-vr + rm -rf sinpin-vr run: build $(TARGET) diff --git a/openvr/libopenvr_api.so b/lib/libopenvr_api.so similarity index 100% rename from openvr/libopenvr_api.so rename to lib/libopenvr_api.so diff --git a/openvr/openvr.h b/lib/openvr.h similarity index 100% rename from openvr/openvr.h rename to lib/openvr.h diff --git a/src/util.h b/src/util.h index ecb7484..cfd8922 100644 --- a/src/util.h +++ b/src/util.h @@ -1,6 +1,6 @@ #pragma once -#include "../openvr/openvr.h" +#include "../lib/openvr.h" #include typedef vr::TrackedDeviceIndex_t TrackerID; From 66227ae7448cb6b9a2b11ffab0c9de00e0f372ff Mon Sep 17 00:00:00 2001 From: CrispyPin Date: Tue, 6 Jun 2023 14:05:43 +0200 Subject: [PATCH 7/7] add transparency toggle --- bindings/action_manifest.json | 6 ++++++ src/app.cpp | 17 +++++++++++++++++ src/app.h | 2 ++ 3 files changed, 25 insertions(+) diff --git a/bindings/action_manifest.json b/bindings/action_manifest.json index 0c9128e..e9f2b6d 100644 --- a/bindings/action_manifest.json +++ b/bindings/action_manifest.json @@ -56,6 +56,11 @@ "requirement": "suggested", "type": "vector2" }, + { + "name": "/actions/cursor/in/toggle_transparent", + "requirement": "suggested", + "type": "boolean" + }, { "name": "/actions/cursor/out/scroll_haptic", "requirement": "suggested", @@ -89,6 +94,7 @@ "/actions/cursor/in/mouse_right": "right mouse button", "/actions/cursor/in/mouse_middle": "middle mouse button", "/actions/cursor/in/scroll": "scroll", + "/actions/cursor/in/toggle_transparent": "toggle transparency", "/actions/cursor/out/scroll_haptic": "scrolling haptic feedback" } ] diff --git a/src/app.cpp b/src/app.cpp index 72ff00a..7bbc85d 100644 --- a/src/app.cpp +++ b/src/app.cpp @@ -10,6 +10,7 @@ const VRMat root_start_pose = {{{1, 0, 0, 0}, {0, 1, 0, 0.8f}, {0, 0, 1, 0}}}; // 0.8m above origin const int FRAME_INTERVAL = 4; // number of update loops until the frame buffer is updated +const float TRANSPARENCY = 0.6f; App::App() { @@ -75,6 +76,8 @@ App::App() assert(action_err == 0); action_err = vr_input->GetActionHandle("/actions/cursor/in/scroll", &_input_handles.cursor.scroll); assert(action_err == 0); + action_err = vr_input->GetActionHandle("/actions/cursor/in/toggle_transparent", &_input_handles.cursor.toggle_transparent); + assert(action_err == 0); action_err = vr_input->GetActionHandle("/actions/cursor/out/scroll_haptic", &_input_handles.cursor.scroll_haptic); assert(action_err == 0); action_err = vr_input->GetActionSetHandle("/actions/main", &_input_handles.main_set); @@ -193,6 +196,20 @@ void App::UpdateInput(float dtime) } UpdateUIVisibility(); } + if (IsInputJustPressed(_input_handles.cursor.toggle_transparent)) + { + _transparent = !_transparent; + if (_transparent) + { + for (auto &panel : _panels) + panel.GetOverlay()->SetAlpha(TRANSPARENCY); + } + else + { + for (auto &panel : _panels) + panel.GetOverlay()->SetAlpha(1); + } + } if (!_hidden) { if (IsInputJustPressed(_input_handles.main.reset)) diff --git a/src/app.h b/src/app.h index fa721ce..ecbbd79 100644 --- a/src/app.h +++ b/src/app.h @@ -33,6 +33,7 @@ struct InputHandles vr::VRActionHandle_t mouse_middle; vr::VRActionHandle_t scroll; vr::VRActionHandle_t scroll_haptic; + vr::VRActionHandle_t toggle_transparent; } cursor; vr::VRActionSetHandle_t cursor_set; struct @@ -87,6 +88,7 @@ class App Overlay _root_overlay; std::vector _panels; bool _hidden = false; + bool _transparent = false; bool _edit_mode = false; std::optional _active_cursor;