From 78f453f89c67f71ed7cd9cd99d1036fe213d2710 Mon Sep 17 00:00:00 2001 From: omigamedev Date: Sat, 1 Jun 2019 17:06:33 +0200 Subject: [PATCH] Quest controller events --- android/quest/src/main/cpp/oculus_vr.cpp | 125 +++++++++++++---------- android/quest/src/main/cpp/oculus_vr.h | 2 +- android/src/cpp/main.cpp | 34 +++--- 3 files changed, 89 insertions(+), 72 deletions(-) diff --git a/android/quest/src/main/cpp/oculus_vr.cpp b/android/quest/src/main/cpp/oculus_vr.cpp index 0620c35..de91ea4 100644 --- a/android/quest/src/main/cpp/oculus_vr.cpp +++ b/android/quest/src/main/cpp/oculus_vr.cpp @@ -13,7 +13,68 @@ int swap_chain_count = 0; int swap_chain_index = 0; ovrMobile* ovr_context = nullptr; uint64_t ovr_frame = 0; -ovrDeviceID controller = -1; + +struct QuestController : public VRController +{ + ovrDeviceID id = -1; + ovrTracking tracking; + ovrInputStateTrackedRemote state; + void update_state(double predictedDisplayTime, glm::vec3 head_pos) + { + vrapi_GetInputTrackingState(ovr_context, id, predictedDisplayTime, &tracking); + glm::vec3 c_pos = glm::make_vec3((float*)&tracking.HeadPose.Pose.Position) - head_pos; + auto c_rot_ovr = ovrMatrix4f_CreateFromQuaternion(&tracking.HeadPose.Pose.Orientation); + glm::mat4 c_rot = glm::make_mat4((float*)&c_rot_ovr); + m_mat = glm::translate(c_pos) * c_rot; + + // update controllers + state.Header.ControllerType = ovrControllerType_TrackedRemote; + vrapi_GetCurrentInputState(ovr_context, id, &state.Header); + + update_analog(kButton::Trigger, {state.IndexTrigger, 0}); + update_analog(kButton::Grip, {state.GripTrigger, 0}); + update_analog(kButton::Pad, glm::make_vec2((float*)&state.Joystick)); + update_digital(kButton::Trigger, state.Buttons & ovrButton_Trigger, {state.IndexTrigger, 0}); + update_digital(kButton::Pad, state.Buttons & ovrButton_Joystick, glm::make_vec2((float*)&state.Joystick)); + update_digital(kButton::A, state.Buttons & ovrButton_A); + } + void update_digital(kButton b, bool pressed, glm::vec2 axis = {0, 0}) + { + if (pressed && !m_buttons[(int)b]) + { + m_buttons[(int)b] = true; + App::I.vr_digital(*this, b, kAction::Press, axis); + } + if (!pressed && m_buttons[(int)b]) + { + m_buttons[(int)b] = false; + App::I.vr_digital(*this, b, kAction::Release, axis); + } + } + void update_analog(kButton b, glm::vec2 force) + { + float l = glm::compMax(glm::abs(force)); + const float zero = 0.01f; + if (l > zero && !m_analog_buttons[(int)b]) + { + m_analog_buttons[(int)b] = true; + App::I.vr_analog(*this, b, kAction::Press, force); + } + if (l <= zero && m_analog_buttons[(int)b]) + { + m_analog_buttons[(int)b] = false; + App::I.vr_analog(*this, b, kAction::Release, force); + } + } + + float get_trigger_value() const override { + if (id == -1) + return 0.f; + return state.IndexTrigger; + } +}; + +QuestController controllers[2]; void oculus_init(JavaVM* vm, JNIEnv* jni, jobject activity_class) { @@ -80,7 +141,7 @@ void oculus_init_vr(EGLDisplay display, EGLContext context, ANativeWindow* surfa vrapi_SetPerfThread(ovr_context, VRAPI_PERF_THREAD_TYPE_RENDERER, 0); } -void oculus_draw() +void oculus_draw(float dt) { const double predictedDisplayTime = vrapi_GetPredictedDisplayTime(ovr_context, ovr_frame); const ovrTracking2 tracking = vrapi_GetPredictedTracking2(ovr_context, predictedDisplayTime); @@ -89,13 +150,12 @@ void oculus_draw() glm::mat4 pose = glm::make_mat4(reinterpret_cast(&pose_ovr_tp)); glm::vec3 head_pos = glm::make_vec3((float*)&tracking.HeadPose.Pose.Position); - if (controller == -1) + if (controllers[0].id == -1) { // init controller ovrInputCapabilityHeader capsHeader; for (int i = 0; ; i++) { - LOG("") if ( vrapi_EnumerateInputDevices( ovr_context, i, &capsHeader ) >= 0 ) { if ( capsHeader.Type == ovrControllerType_TrackedRemote ) @@ -108,8 +168,8 @@ void oculus_draw() if (remoteCaps.ControllerCapabilities & ovrControllerCaps_RightHand) { // right controller found - controller = capsHeader.DeviceID; - LOG("found controller id %d", (int)controller); + controllers[0].id = capsHeader.DeviceID; + LOG("found controller id %d", (int)controllers[0].id); break; } } @@ -122,57 +182,14 @@ void oculus_draw() } } - if (controller != -1) + if (controllers[0].id != -1) { - ovrTracking trackingState; - vrapi_GetInputTrackingState(ovr_context, controller, predictedDisplayTime, &trackingState); - glm::vec3 c_pos = glm::make_vec3((float*)&trackingState.HeadPose.Pose.Position) - head_pos; - auto c_rot_ovr = ovrMatrix4f_CreateFromQuaternion(&trackingState.HeadPose.Pose.Orientation); - glm::mat4 c_rot = glm::make_mat4((float*)&c_rot_ovr); - glm::mat4 c_mat = glm::translate(c_pos); - - App::I.vr_controller = c_mat; - App::I.vr_controller_pos = c_pos; - - // update controllers - ovrInputStateTrackedRemote remote_state; - remote_state.Header.ControllerType = ovrControllerType_TrackedRemote; - vrapi_GetCurrentInputState(ovr_context, controller, &remote_state.Header); - - static cbuffer controller_points(10); - static bool down = false; - static glm::vec3 last_point; - - auto cur = glm::normalize(c_pos) * 800.f; - - if (remote_state.IndexTrigger > 0.f) - { - if (!down) - { - controller_points.clear(); - last_point = cur; - Canvas::I->stroke_start(cur, remote_state.IndexTrigger); - down = true; - } - else - { - controller_points.add(cur); - auto p = controller_points.average(); - if (glm::distance(last_point, p) > 0.1f) - { - Canvas::I->stroke_update(p, remote_state.IndexTrigger); - App::I.update(0); - last_point = p; - } - } - } - else if (down) - { - down = false; - Canvas::I->stroke_end(); - } + controllers[0].update_state(predictedDisplayTime, head_pos); + App::I.vr_controllers[0] = controllers[0]; } + App::I.vr_update(dt); + // update hmd auto layer = vrapi_DefaultLayerProjection2(); //ovrVector4f red = {1, 1, 0, 1}; diff --git a/android/quest/src/main/cpp/oculus_vr.h b/android/quest/src/main/cpp/oculus_vr.h index 2146fcc..88eaaf4 100644 --- a/android/quest/src/main/cpp/oculus_vr.h +++ b/android/quest/src/main/cpp/oculus_vr.h @@ -12,4 +12,4 @@ void oculus_init(JavaVM* vm, JNIEnv* jni, jobject activity_class); void oculus_init_vr(EGLDisplay display, EGLContext context, ANativeWindow* surface); -void oculus_draw(); +void oculus_draw(float dt); diff --git a/android/src/cpp/main.cpp b/android/src/cpp/main.cpp index ae87a5a..82bf9b4 100644 --- a/android/src/cpp/main.cpp +++ b/android/src/cpp/main.cpp @@ -262,18 +262,13 @@ JNIEXPORT void JNICALL Java_com_omixlab_panopainter_MainActivity_pickExternalCal JNIEXPORT void JNICALL Java_com_omixlab_panopainter_MainActivity_contentRectChanged(JNIEnv *end, jobject, jint wnd_w, jint wnd_h, jint rect_left, jint rect_top, jint rect_right, jint rect_bottom) { - //if (!android_async_trylock(&g_engine)) - // return; +#ifndef __QUEST__ LOG("resize wnd [%d %d] rect [%d %d %d %d]", wnd_w, wnd_h, rect_left, rect_top, rect_right, rect_bottom); App::I.width = wnd_w; App::I.height = (rect_bottom - rect_top); App::I.off_x = 0; App::I.off_y = wnd_h - (rect_bottom - rect_top); - //App::I.redraw = true; - //App::I.resize(App::I.width, App::I.height); - //g_engine.width = wnd_w; - //g_engine.height = wnd_h; - //android_async_unlock(&g_engine); +#endif } } @@ -494,10 +489,6 @@ static int engine_init_display(struct engine* engine) { engine->height = h; engine->state.angle = 0; - float density = get_display_density(engine->app); - LOG("density %f", density); - App::I.zoom = density;// / 1.5; - g_display = display; g_context = context; @@ -620,17 +611,26 @@ static int engine_init_display(struct engine* engine) { App::I.data_path = get_data_path(engine->app); LOG("data_path %s", App::I.data_path.c_str()); - App::I.width = w; - App::I.height = h; - App::I.redraw = true; - App::I.init(); #ifdef __QUEST__ - App::I.resize(w, h); + App::I.zoom = 1.f; + App::I.width = 1024; + App::I.height = 1024; + 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; +#else + float density = get_display_density(engine->app); + LOG("density %f", density); + App::I.zoom = density;// / 1.5; + App::I.width = w; + App::I.height = h; + App::I.redraw = true; + App::I.init(); #endif LOG("All ready"); @@ -675,7 +675,7 @@ static void engine_draw_frame(struct engine* engine) { #ifdef __QUEST__ App::I.update(elapsed); - oculus_draw(); + oculus_draw(dt.count()); #else if (!(App::I.redraw || App::I.animate)) return;