Quest controller events

This commit is contained in:
2019-06-01 17:06:33 +02:00
parent c7a2a92b52
commit 78f453f89c
3 changed files with 89 additions and 72 deletions

View File

@@ -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<float*>(&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<glm::vec3> 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};

View File

@@ -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);

View File

@@ -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;