diff --git a/src/app.h b/src/app.h index fdd40d6..3f484dd 100644 --- a/src/app.h +++ b/src/app.h @@ -42,6 +42,7 @@ struct VRController Trigger, Menu, Grip, + A, COUNT, }; enum class kAction @@ -53,7 +54,9 @@ struct VRController std::array m_analog_buttons; glm::mat4 m_mat; bool m_valid = false; - virtual float get_trigger_value() { return 1.f; } + glm::vec3 get_pos() const { return m_mat[3]; } + glm::vec3 get_pos_n() const { return glm::normalize(xyz(m_mat[3])); } + virtual float get_trigger_value() const { return 1.f; } }; @@ -114,8 +117,7 @@ public: bool ui_rtl = false; bool vr_active = false; bool vr_only = false; - glm::mat4 vr_controller; - glm::vec3 vr_controller_pos; + VRController vr_controllers[2]; float vr_pressure = 1.f; glm::mat4 vr_rot{ 0 }; glm::mat4 vr_uirot{ 0 }; diff --git a/src/app_vr.cpp b/src/app_vr.cpp index ee62682..f13a7b4 100644 --- a/src/app_vr.cpp +++ b/src/app_vr.cpp @@ -44,34 +44,42 @@ void App::vr_draw_ui() bool trigger_down = false; cbuffer controller_points(10); glm::vec3 controller_last_point; +const VRController* down_controller = nullptr; +glm::vec2 controller_cursor; +bool ui_inside = false; void App::vr_update(float dt) { glm::vec3 hit; - glm::vec2 hit_fb_pos; float t; - if (ray_intersect({ 0, 0, 0 }, glm::normalize(vr_controller_pos), { 0, 0, -1 }, { 0, 0, 1 }, { 1, 0, 0 }, hit, t)) + if (ray_intersect({ 0, 0, 0 }, vr_controllers[0].get_pos_n(), { 0, 0, -1 }, { 0, 0, 1 }, { 1, 0, 0 }, hit, t)) { glm::mat4 plane_camera = glm::lookAt(glm::vec3(0, 0, -1), { 0, 0, 1 }, { 0, 1, 0 }); glm::vec4 plane_local = plane_camera * glm::vec4(hit, 1); - hit_fb_pos.x = -(plane_local.x * 0.5f - 0.5f) * width; - hit_fb_pos.y = (plane_local.y * 0.5f + 0.5f) * height; - LOG("cursor %f %f", hit_fb_pos.x, hit_fb_pos.y); - mouse_move(hit_fb_pos.x, height - hit_fb_pos.y - 1, 1.f, kEventSource::Mouse, false); + controller_cursor.x = -(plane_local.x * 0.5f - 0.5f) * width; + controller_cursor.y = height - (plane_local.y * 0.5f + 0.5f) * height - 1; + async_start(); + mouse_move(controller_cursor.x, controller_cursor.y, 1.f, kEventSource::Mouse, false); + async_end(); + ui_inside = true; } - if (trigger_down) + else { - controller_points.add(App::I.vr_controller_pos * 800.f); + ui_inside = false; + } + + if (down_controller) + { + controller_points.add(down_controller->get_pos_n() * 800.f); auto p = controller_points.average(); if (glm::distance(p, controller_last_point) > 10) { async_start(); - Canvas::I->stroke_update(p, 1.f); + Canvas::I->stroke_update(p, down_controller->get_trigger_value()); async_end(); controller_last_point = p; - App::I.redraw = true; + redraw = true; } } - } void App::vr_analog(const VRController& c, VRController::kButton b, VRController::kAction a, glm::vec2 force) @@ -80,17 +88,17 @@ void App::vr_analog(const VRController& c, VRController::kButton b, VRController { if (a == VRController::kAction::Press) { - glm::vec3 pos = vr_controller_pos * 800.f; + glm::vec3 pos = c.get_pos_n() * 800.f; async_start(); Canvas::I->stroke_start(pos, force.x); async_end(); controller_last_point = pos; controller_points.clear(); - trigger_down = true; + down_controller = &c; } if (a == VRController::kAction::Release) { - trigger_down = false; + down_controller = nullptr; async_start(); Canvas::I->stroke_end(); async_end(); @@ -103,7 +111,16 @@ void App::vr_digital(const VRController& c, VRController::kButton b, VRControlle if (b == VRController::kButton::Pad && a == VRController::kAction::Press) { if (glm::length(axis) < 0.5f) - App::I.toggle_ui(); + I.toggle_ui(); + } + if (b == VRController::kButton::A) + { + async_start(); + if (a == VRController::kAction::Press) + mouse_down(0, controller_cursor.x, controller_cursor.y, 1.f, kEventSource::Mouse, false); + else + mouse_up(0, controller_cursor.x, controller_cursor.y, kEventSource::Mouse, false); + async_end(); } } @@ -284,7 +301,7 @@ void App::vr_draw(const glm::mat4& proj, const glm::mat4& camera, const glm::mat // draw the brush auto mode = dynamic_cast(canvas->m_canvas->modes[(int)canvas->m_canvas->m_current_mode][0]); - if (ui_visible && mode) + if (ui_visible && ui_inside && mode) { auto pos = mode->m_resizing ? mode->m_size_pos_start : mode->m_cur_pos; if (keys[(int)kKey::KeyAlt] && !mode->m_resizing) @@ -333,7 +350,7 @@ void App::vr_draw(const glm::mat4& proj, const glm::mat4& camera, const glm::mat } // draw the cursor - if (ui_visible) + if (ui_visible && ui_inside) { auto cur = (glm::vec2(cursor.x / width * zoom, 1.f - cursor.y / height * zoom) - 0.5f) * 2.f; auto mvp = proj * camera * @@ -361,8 +378,9 @@ void App::vr_draw(const glm::mat4& proj, const glm::mat4& camera, const glm::mat */ // draw the motion controller brush + if (!ui_visible || !ui_inside) { - auto pos = glm::translate(glm::normalize(vr_controller_pos) * 100.f); + auto pos = glm::translate(vr_controllers[0].get_pos_n() * 100.f); ShaderManager::use(kShader::StrokePreview); ShaderManager::u_int(kShaderUniform::Tex, 0); ShaderManager::u_float(kShaderUniform::Alpha, canvas->m_canvas->m_current_brush->m_tip_flow); @@ -371,7 +389,7 @@ void App::vr_draw(const glm::mat4& proj, const glm::mat4& camera, const glm::mat ShaderManager::u_vec4(kShaderUniform::Col, tip_color); ShaderManager::u_mat4(kShaderUniform::MVP, proj * camera * pos * - glm::inverse(glm::lookAt({ 0, 0, 0 }, vr_controller_pos, { 0, 1, 0 })) * + glm::inverse(glm::lookAt({ 0, 0, 0 }, vr_controllers[0].get_pos(), { 0, 1, 0 })) * glm::scale(glm::vec3(canvas->m_canvas->m_current_brush->m_tip_size * 100.f / height)) * glm::eulerAngleZ(canvas->m_canvas->m_current_brush->m_tip_angle * (float)(M_PI * 2.0)) ); diff --git a/src/hmd.cpp b/src/hmd.cpp index ece3741..4a7e130 100644 --- a/src/hmd.cpp +++ b/src/hmd.cpp @@ -8,6 +8,7 @@ std::map ViveController::m { ViveController::kButton::Pad, ViveController::kButtonMask::PadBit }, { ViveController::kButton::Menu, ViveController::kButtonMask::MenuBit }, { ViveController::kButton::Grip, ViveController::kButtonMask::GripBit }, + { ViveController::kButton::A, ViveController::kButtonMask::ButtonA }, }; bool Vive::Initialize() diff --git a/src/hmd.h b/src/hmd.h index b4244ec..2c91f0d 100644 --- a/src/hmd.h +++ b/src/hmd.h @@ -6,10 +6,11 @@ struct ViveController : public VRController { enum class kButtonMask : uint64_t { - TriggerBit = 0x200000000, - PadBit = 0x100000000, - MenuBit = 0x000000002, - GripBit = 0x000000004, + TriggerBit = 1ull << vr::k_EButton_SteamVR_Trigger, + PadBit = 1ull << vr::k_EButton_SteamVR_Touchpad, + MenuBit = 1ull << vr::k_EButton_ApplicationMenu, + GripBit = 1ull << vr::k_EButton_Grip, + ButtonA = 1ull << vr::k_EButton_A, }; static std::map m_mask; @@ -21,7 +22,7 @@ struct ViveController : public VRController return { m_state.rAxis[(int)button].x, m_state.rAxis[(int)button].y }; } - virtual float get_trigger_value() override + virtual float get_trigger_value() const override { return axis(VRController::kButton::Trigger).x; } diff --git a/src/main.cpp b/src/main.cpp index a594f6e..9767581 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -539,8 +539,7 @@ bool win32_vr_start() vive->Update(); App::I.vr_active = vive->m_active; - App::I.vr_controller = vive->m_controllers[0].m_mat; - App::I.vr_controller_pos = glm::normalize(xyz(vive->m_controllers[0].m_mat[3])); + App::I.vr_controllers[0] = vive->m_controllers[0]; App::I.vr_update(dt); if (vr_running && vive->m_active)