diff --git a/android/quest/src/main/cpp/oculus_vr.cpp b/android/quest/src/main/cpp/oculus_vr.cpp index de91ea4..f1dc7a3 100644 --- a/android/quest/src/main/cpp/oculus_vr.cpp +++ b/android/quest/src/main/cpp/oculus_vr.cpp @@ -141,6 +141,22 @@ void oculus_init_vr(EGLDisplay display, EGLContext context, ANativeWindow* surfa vrapi_SetPerfThread(ovr_context, VRAPI_PERF_THREAD_TYPE_RENDERER, 0); } +void oculus_release_vr() +{ + vrapi_LeaveVrMode(ovr_context); + ovr_context = nullptr; + for (int eye = 0; eye < 2; eye++) + { + vrapi_DestroyTextureSwapChain(swap_chain[eye]); + swap_chain[eye] = nullptr; + for (int i = 0; i < swap_chain_count; i++) + ovr_eyes[eye][i].destroy(); + } + swap_chain_index = 0; + swap_chain_count = 0; + LOG("leave vr mode"); +} + void oculus_draw(float dt) { const double predictedDisplayTime = vrapi_GetPredictedDisplayTime(ovr_context, ovr_frame); diff --git a/android/quest/src/main/cpp/oculus_vr.h b/android/quest/src/main/cpp/oculus_vr.h index 88eaaf4..a22f979 100644 --- a/android/quest/src/main/cpp/oculus_vr.h +++ b/android/quest/src/main/cpp/oculus_vr.h @@ -12,4 +12,5 @@ void oculus_init(JavaVM* vm, JNIEnv* jni, jobject activity_class); void oculus_init_vr(EGLDisplay display, EGLContext context, ANativeWindow* surface); +void oculus_release_vr(); void oculus_draw(float dt); diff --git a/android/src/cpp/main.cpp b/android/src/cpp/main.cpp index 82bf9b4..c0af210 100644 --- a/android/src/cpp/main.cpp +++ b/android/src/cpp/main.cpp @@ -492,6 +492,10 @@ static int engine_init_display(struct engine* engine) { g_display = display; g_context = context; +#ifdef __QUEST__ + oculus_init_vr(display, context, engine->app->window); +#endif + if (resuming_context) { LOG("RESUME APP"); @@ -588,9 +592,6 @@ static int engine_init_display(struct engine* engine) { LOG("PROP Brand: %s", os_props["ro.product.brand"].c_str()); LOG("PROP Maker: %s", os_props["ro.product.manufacturer"].c_str()); LOG("PROP Mode: %s", os_props["ro.product.model"].c_str()); - //LOG("PROP: %s", os_props[""].c_str()); - //LOG("PROP: %s", os_props[""].c_str()); - //LOG("PROP: %s", os_props[""].c_str()); // Initialize GL state. @@ -619,7 +620,6 @@ static int engine_init_display(struct engine* engine) { App::I.redraw = true; App::I.init(); App::I.resize(1024, 1024); - oculus_init_vr(display, context, engine->app->window); App::I.vr_active = true; App::I.has_vr = true; App::I.vr_only = true; @@ -706,6 +706,9 @@ static void engine_term_display(struct engine* engine) { engine->display = EGL_NO_DISPLAY; engine->context = EGL_NO_CONTEXT; engine->surface = EGL_NO_SURFACE; +#ifdef __QUEST__ + oculus_release_vr(); +#endif } /** diff --git a/src/app_vr.cpp b/src/app_vr.cpp index f13a7b4..d6ef9de 100644 --- a/src/app_vr.cpp +++ b/src/app_vr.cpp @@ -51,16 +51,28 @@ void App::vr_update(float dt) { glm::vec3 hit; float 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::mat3 m = glm::transpose(Canvas::I->m_cam_rot); + auto o = m * glm::vec3(0, 0, -1); + auto r = m * glm::vec3(1, 0, 0); + auto n = m * glm::vec3(0, 0, 1); + auto u = m * glm::vec3(0, 1, 0); + if (ray_intersect({ 0, 0, 0 }, vr_controllers[0].get_pos_n(), o, n, r, 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(o, n, u); glm::vec4 plane_local = plane_camera * glm::vec4(hit, 1); - 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 (glm::all(glm::lessThanEqual(glm::abs(xy(plane_local)), glm::vec2(1.5f)))) + { + 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; + } + else + { + ui_inside = false; + } } else { @@ -111,7 +123,11 @@ 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) - I.toggle_ui(); + { + if (!ui_visible) + Canvas::I->m_cam_rot = vr_rot; + toggle_ui(); + } } if (b == VRController::kButton::A) { @@ -135,7 +151,8 @@ void App::vr_draw(const glm::mat4& proj, const glm::mat4& camera, const glm::mat // glm::scale(glm::vec3(sz, 1)); //glm::extractEulerAngleXYZ(camera, vr_rot.y, vr_rot.x, vr_rot.z); - vr_rot = pose; + glm::vec3 origin = glm::vec3(0, 0, -1) * glm::transpose(glm::mat3(pose)); + vr_rot = glm::lookAt({ 0, 0, 0 }, origin, { 0, 1, 0 }); sampler.bind(0); sampler.bind(1); diff --git a/src/hmd.cpp b/src/hmd.cpp index 4a7e130..0faa19e 100644 --- a/src/hmd.cpp +++ b/src/hmd.cpp @@ -98,13 +98,12 @@ void Vive::Update() m_proj[eye] = mat_proj; m_view[eye] = mat_eye * mat_pose; - m_pose = mat_pose; + m_pose = glm::make_mat4(data_hmd_pose); // invalidate controller state for (auto& c : m_controllers) c.m_valid = false; int controller_index = 0; - auto pose_inv = glm::inverse(m_pose); for (int id = 0; id < vr::k_unMaxTrackedDeviceCount; id++) {