diff --git a/android/src/cpp/main.cpp b/android/src/cpp/main.cpp index d331329..ae87a5a 100644 --- a/android/src/cpp/main.cpp +++ b/android/src/cpp/main.cpp @@ -601,10 +601,6 @@ static int engine_init_display(struct engine* engine) { //LOG("PROP: %s", os_props[""].c_str()); //LOG("PROP: %s", os_props[""].c_str()); -#ifdef __QUEST__ - oculus_init_vr(display, context, engine->app->window); -#endif - // Initialize GL state. android_async_lock(engine); @@ -628,7 +624,14 @@ static int engine_init_display(struct engine* engine) { App::I.height = h; App::I.redraw = true; App::I.init(); + +#ifdef __QUEST__ App::I.resize(w, h); + oculus_init_vr(display, context, engine->app->window); + App::I.vr_active = true; + App::I.has_vr = true; + App::I.vr_only = true; +#endif LOG("All ready"); engine->animating = 1; @@ -669,35 +672,20 @@ static void engine_draw_frame(struct engine* engine) { return; rendered_frames++; - elapsed = 0; #ifdef __QUEST__ - App::I.vr_draw_ui(); + App::I.update(elapsed); oculus_draw(); #else - /* - int w, h; - eglQuerySurface(engine->display, engine->surface, EGL_WIDTH, &w); - eglQuerySurface(engine->display, engine->surface, EGL_HEIGHT, &h); - - if (w != engine->width || h != engine->height) { - engine->width = w; - engine->height = h; - App::I.resize(w, h); - App::I.redraw = true; - LOG("resize window to %d %d", w, h); - } - */ - if (!(App::I.redraw || App::I.animate)) return; App::I.clear(); App::I.update(elapsed); - elapsed = 0; eglSwapBuffers(engine->display, engine->surface); #endif + elapsed = 0; } /** diff --git a/src/app.cpp b/src/app.cpp index 5b9ea79..1f50845 100644 --- a/src/app.cpp +++ b/src/app.cpp @@ -110,7 +110,6 @@ bool App::request_close() void App::clear() { glClearColor(.1f, .1f, .1f, 1.f); - glViewport(off_x, off_y, (GLsizei)width, (GLsizei)height); glClear(GL_COLOR_BUFFER_BIT); } @@ -588,11 +587,6 @@ void App::update(float dt) if (!(redraw || animate)) return; - //glClearColor(.1f, .1f, .1f, 1.f); - //glViewport(0, 0, (GLsizei)width, (GLsizei)height); - //glClear(GL_COLOR_BUFFER_BIT); - - //if (!canvas->m_mouse_captured) #if /*_DEBUG &&*/ (_WIN32 || __OSX__) reload_timer += dt; if (reload_timer > 1.0) @@ -634,6 +628,7 @@ void App::update(float dt) { uirtt.bindFramebuffer(); uirtt.clear(); + glViewport(0, 0, uirtt.getWidth(), uirtt.getHeight()); glEnable(GL_SCISSOR_TEST); for (int i = 1; i < layout[main_id]->m_children.size(); i++) layout[main_id]->m_children[i]->watch(observer); @@ -641,29 +636,21 @@ void App::update(float dt) glDisable(GL_SCISSOR_TEST); uirtt.unbindFramebuffer(); } - -#if __IOS__ - [ios_view->glview bindDrawable]; -#else - glBindFramebuffer(GL_FRAMEBUFFER, 0); -#endif - glEnable(GL_SCISSOR_TEST); - for (int i = 0; i < layout[main_id]->m_children.size(); i++) - layout[main_id]->m_children[i]->watch(observer); - //msgbox->watch(observer); - glDisable(GL_SCISSOR_TEST); - //canvas->watch(observer); - //glEnable(GL_BLEND); - //sampler.bind(0); - //ShaderManager::use(kShader::Texture); - //ShaderManager::u_int(kShaderUniform::Tex, 0); - //ShaderManager::u_mat4(kShaderUniform::MVP, glm::ortho(-1.f, 1.f, -1.f, 1.f)); - //glActiveTexture(GL_TEXTURE0); - //uirtt.bindTexture(); - //m_face_plane.draw_fill(); - //uirtt.unbindTexture(); - //glDisable(GL_BLEND); + if (!vr_only) + { +#if __IOS__ + [ios_view->glview bindDrawable]; +#else + glBindFramebuffer(GL_FRAMEBUFFER, 0); +#endif + glViewport(off_x, off_y, (GLsizei)width, (GLsizei)height); + glEnable(GL_SCISSOR_TEST); + for (int i = 0; i < layout[main_id]->m_children.size(); i++) + layout[main_id]->m_children[i]->watch(observer); + //msgbox->watch(observer); + glDisable(GL_SCISSOR_TEST); + } if (rec_running) { diff --git a/src/app.h b/src/app.h index 045e8cf..fdd40d6 100644 --- a/src/app.h +++ b/src/app.h @@ -34,6 +34,29 @@ #include "node_panel_grid.h" #include "node_panel_quick.h" +struct VRController +{ + enum class kButton : uint8_t + { + Pad, + Trigger, + Menu, + Grip, + COUNT, + }; + enum class kAction + { + Press, + Release, + }; + std::array m_buttons; + std::array m_analog_buttons; + glm::mat4 m_mat; + bool m_valid = false; + virtual float get_trigger_value() { return 1.f; } +}; + + class App { public: @@ -90,6 +113,7 @@ public: bool ui_visible = true; bool ui_rtl = false; bool vr_active = false; + bool vr_only = false; glm::mat4 vr_controller; glm::vec3 vr_controller_pos; float vr_pressure = 1.f; @@ -140,7 +164,10 @@ public: bool update_ui_observer(Node* n); bool vr_start(); void vr_stop(); + void vr_update(float dt); void vr_draw(const glm::mat4& proj, const glm::mat4& view, const glm::mat4& pose); + void vr_analog(const VRController& c, VRController::kButton b, VRController::kAction a, glm::vec2 force); + void vr_digital(const VRController& c, VRController::kButton b, VRController::kAction a, glm::vec2 axis); void vr_draw_ui(); void async_start(); void async_update(); diff --git a/src/app_vr.cpp b/src/app_vr.cpp index 6d493f3..ee62682 100644 --- a/src/app_vr.cpp +++ b/src/app_vr.cpp @@ -1,5 +1,6 @@ #include "pch.h" #include "app.h" +#include "util.h" #ifdef _WIN32 bool win32_vr_start(); @@ -40,6 +41,72 @@ void App::vr_draw_ui() uirtt.unbindFramebuffer(); } +bool trigger_down = false; +cbuffer controller_points(10); +glm::vec3 controller_last_point; +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)) + { + 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); + } + if (trigger_down) + { + controller_points.add(App::I.vr_controller_pos * 800.f); + auto p = controller_points.average(); + if (glm::distance(p, controller_last_point) > 10) + { + async_start(); + Canvas::I->stroke_update(p, 1.f); + async_end(); + controller_last_point = p; + App::I.redraw = true; + } + } + +} + +void App::vr_analog(const VRController& c, VRController::kButton b, VRController::kAction a, glm::vec2 force) +{ + if (b == VRController::kButton::Trigger) + { + if (a == VRController::kAction::Press) + { + glm::vec3 pos = vr_controller_pos * 800.f; + async_start(); + Canvas::I->stroke_start(pos, force.x); + async_end(); + controller_last_point = pos; + controller_points.clear(); + trigger_down = true; + } + if (a == VRController::kAction::Release) + { + trigger_down = false; + async_start(); + Canvas::I->stroke_end(); + async_end(); + } + } +} + +void App::vr_digital(const VRController& c, VRController::kButton b, VRController::kAction a, glm::vec2 axis) +{ + if (b == VRController::kButton::Pad && a == VRController::kAction::Press) + { + if (glm::length(axis) < 0.5f) + App::I.toggle_ui(); + } +} + void App::vr_draw(const glm::mat4& proj, const glm::mat4& camera, const glm::mat4& pose) { //glm::mat4 ortho_proj = glm::ortho(0.f, box.z, 0.f, box.w, -1000.f, 1000.f); @@ -220,7 +287,7 @@ void App::vr_draw(const glm::mat4& proj, const glm::mat4& camera, const glm::mat if (ui_visible && mode) { auto pos = mode->m_resizing ? mode->m_size_pos_start : mode->m_cur_pos; - if (App::I.keys[(int)kKey::KeyAlt] && !mode->m_resizing) + if (keys[(int)kKey::KeyAlt] && !mode->m_resizing) pos.x = pos.x - canvas->m_canvas->m_current_brush->m_tip_size * 500; auto cur = (glm::vec2(pos.x / width, 1.f - pos.y / height) - 0.5f) * 2.f; @@ -235,7 +302,7 @@ void App::vr_draw(const glm::mat4& proj, const glm::mat4& camera, const glm::mat glm::scale(glm::vec3(100)) * glm::transpose(canvas->m_canvas->m_cam_rot) * glm::translate(glm::vec3(cur * glm::vec2(aspect * tan_fov), -1)) * - glm::scale(glm::vec3(canvas->m_canvas->m_current_brush->m_tip_size / App::I.height)) * + glm::scale(glm::vec3(canvas->m_canvas->m_current_brush->m_tip_size / height)) * glm::eulerAngleZ(canvas->m_canvas->m_current_brush->m_tip_angle * (float)(M_PI * 2.0)) ); glEnable(GL_BLEND); @@ -305,7 +372,7 @@ void App::vr_draw(const glm::mat4& proj, const glm::mat4& camera, const glm::mat ShaderManager::u_mat4(kShaderUniform::MVP, proj * camera * pos * glm::inverse(glm::lookAt({ 0, 0, 0 }, vr_controller_pos, { 0, 1, 0 })) * - glm::scale(glm::vec3(canvas->m_canvas->m_current_brush->m_tip_size * 100.f / App::I.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)) ); glEnable(GL_BLEND); diff --git a/src/hmd.h b/src/hmd.h index 2f5fac4..b4244ec 100644 --- a/src/hmd.h +++ b/src/hmd.h @@ -1,16 +1,9 @@ #pragma once #include "rtt.h" +#include "app.h" -struct ViveController +struct ViveController : public VRController { - enum class kButton : uint8_t - { - Pad, - Trigger, - Menu, - Grip, - COUNT, - }; enum class kButtonMask : uint64_t { TriggerBit = 0x200000000, @@ -18,20 +11,20 @@ struct ViveController MenuBit = 0x000000002, GripBit = 0x000000004, }; - enum class kAction - { - Press, - Release, - }; + static std::map m_mask; - std::array m_buttons; - std::array m_analog_buttons; - glm::mat4 m_mat; + vr::VRControllerState_t m_state{ 0 }; - bool m_valid = false; - glm::vec2 axis(kButton button) const { + + glm::vec2 axis(kButton button) const + { return { m_state.rAxis[(int)button].x, m_state.rAxis[(int)button].y }; } + + virtual float get_trigger_value() override + { + return axis(VRController::kButton::Trigger).x; + } }; struct Vive diff --git a/src/main.cpp b/src/main.cpp index 0c2f8d7..a594f6e 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -513,38 +513,10 @@ bool win32_vr_start() App::I.has_vr = true; vr_running = true; - 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, 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; - async_lock(); - Canvas::I->stroke_start(pos, force.x); - async_unlock(); - controller_last_point = pos; - controller_points.clear(); - trigger_down = true; - } - if (a == ViveController::kAction::Release) - { - trigger_down = false; - async_lock(); - Canvas::I->stroke_end(); - 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 (glm::length(axis) < 0.5f) - App::I.toggle_ui(); - } - }; + vive->on_analog_button = std::bind(&App::vr_analog, &App::I, std::placeholders::_1, + std::placeholders::_2, std::placeholders::_3, std::placeholders::_4); + vive->on_button = std::bind(&App::vr_digital, &App::I, std::placeholders::_1, + std::placeholders::_2, std::placeholders::_3, std::placeholders::_4); const float target_tick_rate = 90; auto t0 = GetTickCount64(); @@ -569,21 +541,8 @@ bool win32_vr_start() 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_update(dt); - if (trigger_down) - { - controller_points.add(App::I.vr_controller_pos * 800.f); - auto p = controller_points.average(); - if (glm::distance(p, controller_last_point) > 10) - { - async_lock(); - Canvas::I->stroke_update(p, vive->m_controllers[0].axis(ViveController::kButton::Trigger).x); - async_unlock(); - controller_last_point = p; - App::I.redraw = true; - } - } - if (vr_running && vive->m_active) { async_lock();