diff --git a/Makefile b/Makefile index 3264bb6..256e98a 100644 --- a/Makefile +++ b/Makefile @@ -1,18 +1,18 @@ -VERSION=v0.2.1 -# CC := g++ -CC := clang++ +VERSION=v0.2.2 + +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) 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); } } } 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()