vr controlled ui
This commit is contained in:
@@ -42,6 +42,7 @@ struct VRController
|
||||
Trigger,
|
||||
Menu,
|
||||
Grip,
|
||||
A,
|
||||
COUNT,
|
||||
};
|
||||
enum class kAction
|
||||
@@ -53,7 +54,9 @@ struct VRController
|
||||
std::array<bool, (int)kButton::COUNT> 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 };
|
||||
|
||||
@@ -44,34 +44,42 @@ void App::vr_draw_ui()
|
||||
bool trigger_down = false;
|
||||
cbuffer<glm::vec3> 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<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;
|
||||
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))
|
||||
);
|
||||
|
||||
@@ -8,6 +8,7 @@ std::map<ViveController::kButton, ViveController::kButtonMask> 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()
|
||||
|
||||
11
src/hmd.h
11
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<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 };
|
||||
}
|
||||
|
||||
virtual float get_trigger_value() override
|
||||
virtual float get_trigger_value() const override
|
||||
{
|
||||
return axis(VRController::kButton::Trigger).x;
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user