improve vr controllers handling
This commit is contained in:
71
src/hmd.cpp
71
src/hmd.cpp
@@ -3,8 +3,11 @@
|
|||||||
#include "log.h"
|
#include "log.h"
|
||||||
#include <array>
|
#include <array>
|
||||||
|
|
||||||
std::map<ViveController::kButton, ViveController::kButtonMask> ViveController::m_mask{
|
std::map<ViveController::kButton, ViveController::kButtonMask> ViveController::m_mask {
|
||||||
{ ViveController::kButton::Trigger, ViveController::kButtonMask::TriggerBit },
|
{ 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()
|
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);
|
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);
|
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;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -90,7 +100,8 @@ void Vive::Update()
|
|||||||
m_pose = mat_pose;
|
m_pose = mat_pose;
|
||||||
|
|
||||||
// invalidate controller state
|
// 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;
|
int controller_index = 0;
|
||||||
auto pose_inv = glm::inverse(m_pose);
|
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_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);
|
m_controllers[controller_index].m_mat = glm::translate(-head_position) * Pose2Mat(poses[id].mDeviceToAbsoluteTracking);
|
||||||
|
|
||||||
std::array<ViveController::kButton, 4> button_ids{
|
auto pressed_mask = m_controllers[controller_index].m_state.ulButtonPressed;
|
||||||
ViveController::kButton::Trigger,
|
for (uint8_t bi = 0; bi < (uint8_t)ViveController::kButton::COUNT; bi++)
|
||||||
//ViveController::kButton::Pad, // unused
|
|
||||||
//ViveController::kButton::Menu, // unused
|
|
||||||
//ViveController::kButton::Grip, // unused
|
|
||||||
};
|
|
||||||
|
|
||||||
for (auto b : button_ids)
|
|
||||||
{
|
{
|
||||||
|
auto b = (ViveController::kButton)bi;
|
||||||
glm::vec2 force = { m_controllers[controller_index].m_state.rAxis[(int)b].x,
|
glm::vec2 force = { m_controllers[controller_index].m_state.rAxis[(int)b].x,
|
||||||
m_controllers[controller_index].m_state.rAxis[(int)b].y };
|
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;
|
if (glm::compMax(glm::abs(force)) > 0.f && !m_controllers[controller_index].m_analog_buttons[bi])
|
||||||
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])
|
|
||||||
{
|
{
|
||||||
m_controllers[controller_index].m_buttons[(uint64_t)b] = true;
|
m_controllers[controller_index].m_analog_buttons[bi] = true;
|
||||||
if (on_button)
|
if (on_analog_button)
|
||||||
on_button(m_controllers[controller_index], b, ViveController::kAction::Press);
|
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)
|
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++;
|
controller_index++;
|
||||||
|
|||||||
@@ -42,14 +42,14 @@ struct Vive
|
|||||||
vr::IVRSystem* m_hmd = nullptr;
|
vr::IVRSystem* m_hmd = nullptr;
|
||||||
vr::IVRCompositor* m_comp = nullptr;
|
vr::IVRCompositor* m_comp = nullptr;
|
||||||
vr::IVRSettings* m_settings = nullptr;
|
vr::IVRSettings* m_settings = nullptr;
|
||||||
ViveController m_controllers[2];
|
std::array<ViveController, 2> m_controllers;
|
||||||
glm::mat4 m_view[2];
|
glm::mat4 m_view[2];
|
||||||
glm::mat4 m_proj[2];
|
glm::mat4 m_proj[2];
|
||||||
glm::mat4 m_pose;
|
glm::mat4 m_pose;
|
||||||
bool m_active = false;
|
bool m_active = false;
|
||||||
std::function<void(const glm::mat4& m_proj, const glm::mat4& m_view, const glm::mat4& m_pose)> on_draw = nullptr;
|
std::function<void(const glm::mat4& m_proj, const glm::mat4& m_view, const glm::mat4& m_pose)> on_draw = nullptr;
|
||||||
std::function<void(const ViveController&, ViveController::kButton, ViveController::kAction)> on_button = nullptr;
|
std::function<void(const ViveController&, ViveController::kButton, ViveController::kAction, glm::vec2 axis)> on_button = nullptr;
|
||||||
std::function<void(const ViveController&, ViveController::kButton, ViveController::kAction)> on_analog_button = nullptr;
|
std::function<void(const ViveController&, ViveController::kButton, ViveController::kAction, glm::vec2 force)> on_analog_button = nullptr;
|
||||||
|
|
||||||
bool Initialize();
|
bool Initialize();
|
||||||
void Terminate();
|
void Terminate();
|
||||||
|
|||||||
10
src/main.cpp
10
src/main.cpp
@@ -482,15 +482,14 @@ bool win32_vr_start()
|
|||||||
bool trigger_down = false;
|
bool trigger_down = false;
|
||||||
cbuffer<glm::vec3> controller_points(10);
|
cbuffer<glm::vec3> controller_points(10);
|
||||||
glm::vec3 controller_last_point;
|
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 (b == ViveController::kButton::Trigger)
|
||||||
{
|
{
|
||||||
if (a == ViveController::kAction::Press)
|
if (a == ViveController::kAction::Press)
|
||||||
{
|
{
|
||||||
glm::vec3 pos = glm::normalize(xyz(vive->m_controllers[0].m_mat[3])) * 800.f;
|
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();
|
async_lock();
|
||||||
Canvas::I->stroke_start(pos, force);
|
Canvas::I->stroke_start(pos, force.x);
|
||||||
async_unlock();
|
async_unlock();
|
||||||
controller_last_point = pos;
|
controller_last_point = pos;
|
||||||
controller_points.clear();
|
controller_points.clear();
|
||||||
@@ -504,9 +503,12 @@ bool win32_vr_start()
|
|||||||
async_unlock();
|
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)
|
if (b == ViveController::kButton::Pad && a == ViveController::kAction::Press)
|
||||||
{
|
{
|
||||||
App::I.toggle_ui();
|
if (glm::length(axis) < 0.5f)
|
||||||
|
App::I.toggle_ui();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user