vr controlled ui

This commit is contained in:
2019-06-01 00:54:56 +02:00
parent 20582dafa8
commit c7a2a92b52
5 changed files with 50 additions and 29 deletions

View File

@@ -42,6 +42,7 @@ struct VRController
Trigger, Trigger,
Menu, Menu,
Grip, Grip,
A,
COUNT, COUNT,
}; };
enum class kAction enum class kAction
@@ -53,7 +54,9 @@ struct VRController
std::array<bool, (int)kButton::COUNT> m_analog_buttons; std::array<bool, (int)kButton::COUNT> m_analog_buttons;
glm::mat4 m_mat; glm::mat4 m_mat;
bool m_valid = false; 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 ui_rtl = false;
bool vr_active = false; bool vr_active = false;
bool vr_only = false; bool vr_only = false;
glm::mat4 vr_controller; VRController vr_controllers[2];
glm::vec3 vr_controller_pos;
float vr_pressure = 1.f; float vr_pressure = 1.f;
glm::mat4 vr_rot{ 0 }; glm::mat4 vr_rot{ 0 };
glm::mat4 vr_uirot{ 0 }; glm::mat4 vr_uirot{ 0 };

View File

@@ -44,34 +44,42 @@ void App::vr_draw_ui()
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;
const VRController* down_controller = nullptr;
glm::vec2 controller_cursor;
bool ui_inside = false;
void App::vr_update(float dt) void App::vr_update(float dt)
{ {
glm::vec3 hit; glm::vec3 hit;
glm::vec2 hit_fb_pos;
float t; 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::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); glm::vec4 plane_local = plane_camera * glm::vec4(hit, 1);
hit_fb_pos.x = -(plane_local.x * 0.5f - 0.5f) * width; controller_cursor.x = -(plane_local.x * 0.5f - 0.5f) * width;
hit_fb_pos.y = (plane_local.y * 0.5f + 0.5f) * height; controller_cursor.y = height - (plane_local.y * 0.5f + 0.5f) * height - 1;
LOG("cursor %f %f", hit_fb_pos.x, hit_fb_pos.y); async_start();
mouse_move(hit_fb_pos.x, height - hit_fb_pos.y - 1, 1.f, kEventSource::Mouse, false); 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(); auto p = controller_points.average();
if (glm::distance(p, controller_last_point) > 10) if (glm::distance(p, controller_last_point) > 10)
{ {
async_start(); async_start();
Canvas::I->stroke_update(p, 1.f); Canvas::I->stroke_update(p, down_controller->get_trigger_value());
async_end(); async_end();
controller_last_point = p; 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) 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) if (a == VRController::kAction::Press)
{ {
glm::vec3 pos = vr_controller_pos * 800.f; glm::vec3 pos = c.get_pos_n() * 800.f;
async_start(); async_start();
Canvas::I->stroke_start(pos, force.x); Canvas::I->stroke_start(pos, force.x);
async_end(); async_end();
controller_last_point = pos; controller_last_point = pos;
controller_points.clear(); controller_points.clear();
trigger_down = true; down_controller = &c;
} }
if (a == VRController::kAction::Release) if (a == VRController::kAction::Release)
{ {
trigger_down = false; down_controller = nullptr;
async_start(); async_start();
Canvas::I->stroke_end(); Canvas::I->stroke_end();
async_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 (b == VRController::kButton::Pad && a == VRController::kAction::Press)
{ {
if (glm::length(axis) < 0.5f) 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 // draw the brush
auto mode = dynamic_cast<CanvasModePen*>(canvas->m_canvas->modes[(int)canvas->m_canvas->m_current_mode][0]); auto mode = dynamic_cast<CanvasModePen*>(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; auto pos = mode->m_resizing ? mode->m_size_pos_start : mode->m_cur_pos;
if (keys[(int)kKey::KeyAlt] && !mode->m_resizing) 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 // 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 cur = (glm::vec2(cursor.x / width * zoom, 1.f - cursor.y / height * zoom) - 0.5f) * 2.f;
auto mvp = proj * camera * 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 // 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::use(kShader::StrokePreview);
ShaderManager::u_int(kShaderUniform::Tex, 0); ShaderManager::u_int(kShaderUniform::Tex, 0);
ShaderManager::u_float(kShaderUniform::Alpha, canvas->m_canvas->m_current_brush->m_tip_flow); 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_vec4(kShaderUniform::Col, tip_color);
ShaderManager::u_mat4(kShaderUniform::MVP, ShaderManager::u_mat4(kShaderUniform::MVP,
proj * camera * pos * 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::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)) glm::eulerAngleZ(canvas->m_canvas->m_current_brush->m_tip_angle * (float)(M_PI * 2.0))
); );

View File

@@ -8,6 +8,7 @@ std::map<ViveController::kButton, ViveController::kButtonMask> ViveController::m
{ ViveController::kButton::Pad, ViveController::kButtonMask::PadBit }, { ViveController::kButton::Pad, ViveController::kButtonMask::PadBit },
{ ViveController::kButton::Menu, ViveController::kButtonMask::MenuBit }, { ViveController::kButton::Menu, ViveController::kButtonMask::MenuBit },
{ ViveController::kButton::Grip, ViveController::kButtonMask::GripBit }, { ViveController::kButton::Grip, ViveController::kButtonMask::GripBit },
{ ViveController::kButton::A, ViveController::kButtonMask::ButtonA },
}; };
bool Vive::Initialize() bool Vive::Initialize()

View File

@@ -6,10 +6,11 @@ struct ViveController : public VRController
{ {
enum class kButtonMask : uint64_t enum class kButtonMask : uint64_t
{ {
TriggerBit = 0x200000000, TriggerBit = 1ull << vr::k_EButton_SteamVR_Trigger,
PadBit = 0x100000000, PadBit = 1ull << vr::k_EButton_SteamVR_Touchpad,
MenuBit = 0x000000002, MenuBit = 1ull << vr::k_EButton_ApplicationMenu,
GripBit = 0x000000004, GripBit = 1ull << vr::k_EButton_Grip,
ButtonA = 1ull << vr::k_EButton_A,
}; };
static std::map<kButton, kButtonMask> m_mask; static std::map<kButton, kButtonMask> m_mask;
@@ -21,7 +22,7 @@ struct ViveController : public VRController
return { m_state.rAxis[(int)button].x, m_state.rAxis[(int)button].y }; 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; return axis(VRController::kButton::Trigger).x;
} }

View File

@@ -539,8 +539,7 @@ bool win32_vr_start()
vive->Update(); vive->Update();
App::I.vr_active = vive->m_active; App::I.vr_active = vive->m_active;
App::I.vr_controller = vive->m_controllers[0].m_mat; App::I.vr_controllers[0] = vive->m_controllers[0];
App::I.vr_controller_pos = glm::normalize(xyz(vive->m_controllers[0].m_mat[3]));
App::I.vr_update(dt); App::I.vr_update(dt);
if (vr_running && vive->m_active) if (vr_running && vive->m_active)