From 37491d9fe142ce4e3f190db78372d544313d5201 Mon Sep 17 00:00:00 2001 From: omigamedev Date: Wed, 22 May 2019 14:14:34 +0200 Subject: [PATCH] improve vr controllers handling --- src/hmd.cpp | 71 +++++++++++++++++++++++++++------------------------- src/hmd.h | 6 ++--- src/main.cpp | 10 +++++--- 3 files changed, 46 insertions(+), 41 deletions(-) diff --git a/src/hmd.cpp b/src/hmd.cpp index ee18993..6d8e265 100644 --- a/src/hmd.cpp +++ b/src/hmd.cpp @@ -3,8 +3,11 @@ #include "log.h" #include -std::map ViveController::m_mask{ +std::map ViveController::m_mask { { ViveController::kButton::Trigger, ViveController::kButtonMask::TriggerBit }, + { ViveController::kButton::Pad, ViveController::kButtonMask::PadBit }, + { ViveController::kButton::Menu, ViveController::kButtonMask::MenuBit }, + { ViveController::kButton::Grip, ViveController::kButtonMask::GripBit }, }; bool Vive::Initialize() @@ -32,6 +35,13 @@ bool Vive::Initialize() float timeout = s.GetFloat(vr::k_pch_Power_Section, vr::k_pch_Power_TurnOffScreensTimeout_Float); s.SetFloat(vr::k_pch_Power_Section, vr::k_pch_Power_TurnOffScreensTimeout_Float, 0.5); + // init buttons state + for (auto& c : m_controllers) + { + c.m_buttons.fill(false); + c.m_analog_buttons.fill(false); + } + return true; } @@ -90,7 +100,8 @@ void Vive::Update() m_pose = mat_pose; // invalidate controller state - std::for_each(m_controllers, m_controllers + 1, [&](ViveController& c) { c.m_valid = false; }); + for (auto& c : m_controllers) + c.m_valid = false; int controller_index = 0; auto pose_inv = glm::inverse(m_pose); @@ -111,46 +122,38 @@ void Vive::Update() m_hmd->GetControllerState(id, &m_controllers[controller_index].m_state, sizeof(vr::VRControllerState_t)); m_controllers[controller_index].m_mat = glm::translate(-head_position) * Pose2Mat(poses[id].mDeviceToAbsoluteTracking); - std::array button_ids{ - ViveController::kButton::Trigger, - //ViveController::kButton::Pad, // unused - //ViveController::kButton::Menu, // unused - //ViveController::kButton::Grip, // unused - }; - - for (auto b : button_ids) + auto pressed_mask = m_controllers[controller_index].m_state.ulButtonPressed; + for (uint8_t bi = 0; bi < (uint8_t)ViveController::kButton::COUNT; bi++) { + auto b = (ViveController::kButton)bi; glm::vec2 force = { m_controllers[controller_index].m_state.rAxis[(int)b].x, m_controllers[controller_index].m_state.rAxis[(int)b].y }; - if (glm::compMax(glm::abs(force)) > 0.f && !m_controllers[controller_index].m_analog_buttons[(uint8_t)b]) - { - m_controllers[controller_index].m_analog_buttons[(uint8_t)b] = true; - if (on_analog_button) - on_analog_button(m_controllers[controller_index], b, ViveController::kAction::Press); - } - if (glm::compMax(glm::abs(force)) == 0.f && m_controllers[controller_index].m_analog_buttons[(uint64_t)b]) - { - m_controllers[controller_index].m_analog_buttons[(uint8_t)b] = false; - if (on_analog_button) - on_analog_button(m_controllers[controller_index], b, ViveController::kAction::Release); - } - } - auto pressed_mask = m_controllers[controller_index].m_state.ulButtonPressed; - for (auto b : button_ids) - { - bool b_pressed = pressed_mask & (uint64_t)m_controllers[controller_index].m_mask[b]; - if (b_pressed == true && !m_controllers[controller_index].m_buttons[(uint64_t)b]) + if (glm::compMax(glm::abs(force)) > 0.f && !m_controllers[controller_index].m_analog_buttons[bi]) { - m_controllers[controller_index].m_buttons[(uint64_t)b] = true; - if (on_button) - on_button(m_controllers[controller_index], b, ViveController::kAction::Press); + m_controllers[controller_index].m_analog_buttons[bi] = true; + if (on_analog_button) + on_analog_button(m_controllers[controller_index], b, ViveController::kAction::Press, force); } - if (b_pressed == false && m_controllers[controller_index].m_buttons[(uint64_t)b]) + if (glm::compMax(glm::abs(force)) == 0.f && m_controllers[controller_index].m_analog_buttons[bi]) { - m_controllers[controller_index].m_buttons[(uint64_t)b] = false; + m_controllers[controller_index].m_analog_buttons[bi] = false; + if (on_analog_button) + on_analog_button(m_controllers[controller_index], b, ViveController::kAction::Release, force); + } + + bool b_pressed = pressed_mask & (uint64_t)m_controllers[controller_index].m_mask[b]; + if (b_pressed == true && !m_controllers[controller_index].m_buttons[bi]) + { + m_controllers[controller_index].m_buttons[bi] = true; if (on_button) - on_button(m_controllers[controller_index], b, ViveController::kAction::Release); + on_button(m_controllers[controller_index], b, ViveController::kAction::Press, force); + } + if (b_pressed == false && m_controllers[controller_index].m_buttons[bi]) + { + m_controllers[controller_index].m_buttons[bi] = false; + if (on_button) + on_button(m_controllers[controller_index], b, ViveController::kAction::Release, force); } } controller_index++; diff --git a/src/hmd.h b/src/hmd.h index 837110d..2f5fac4 100644 --- a/src/hmd.h +++ b/src/hmd.h @@ -42,14 +42,14 @@ struct Vive vr::IVRSystem* m_hmd = nullptr; vr::IVRCompositor* m_comp = nullptr; vr::IVRSettings* m_settings = nullptr; - ViveController m_controllers[2]; + std::array m_controllers; glm::mat4 m_view[2]; glm::mat4 m_proj[2]; glm::mat4 m_pose; bool m_active = false; std::function on_draw = nullptr; - std::function on_button = nullptr; - std::function on_analog_button = nullptr; + std::function on_button = nullptr; + std::function on_analog_button = nullptr; bool Initialize(); void Terminate(); diff --git a/src/main.cpp b/src/main.cpp index cb5fe79..9792c51 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -482,15 +482,14 @@ bool win32_vr_start() bool trigger_down = false; cbuffer controller_points(10); glm::vec3 controller_last_point; - vive->on_analog_button = [&](const ViveController& c, ViveController::kButton b, ViveController::kAction a) { + vive->on_analog_button = [&](const ViveController& c, ViveController::kButton b, ViveController::kAction a, glm::vec2 force) { if (b == ViveController::kButton::Trigger) { if (a == ViveController::kAction::Press) { glm::vec3 pos = glm::normalize(xyz(vive->m_controllers[0].m_mat[3])) * 800.f; - float force = vive->m_controllers[0].axis(b).x; async_lock(); - Canvas::I->stroke_start(pos, force); + Canvas::I->stroke_start(pos, force.x); async_unlock(); controller_last_point = pos; controller_points.clear(); @@ -504,9 +503,12 @@ bool win32_vr_start() async_unlock(); } } + }; + vive->on_button = [&](const ViveController& c, ViveController::kButton b, ViveController::kAction a, glm::vec2 axis) { if (b == ViveController::kButton::Pad && a == ViveController::kAction::Press) { - App::I.toggle_ui(); + if (glm::length(axis) < 0.5f) + App::I.toggle_ui(); } };