mirror of
https://github.com/overte-org/overte.git
synced 2025-06-03 22:51:02 +02:00
191 lines
6.1 KiB
C++
191 lines
6.1 KiB
C++
//
|
|
// GVRInterface.cpp
|
|
// gvr-interface/src
|
|
//
|
|
// Created by Stephen Birarda on 11/18/14.
|
|
// Copyright 2013 High Fidelity, Inc.
|
|
//
|
|
// Distributed under the Apache License, Version 2.0.
|
|
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
|
//
|
|
|
|
#ifdef ANDROID
|
|
|
|
#include <jni.h>
|
|
|
|
#include <qpa/qplatformnativeinterface.h>
|
|
#include <QtAndroidExtras/QAndroidJniEnvironment>
|
|
#include <QtAndroidExtras/QAndroidJniObject>
|
|
|
|
#ifdef HAVE_LIBOVR
|
|
|
|
#include <KeyState.h>
|
|
#include <VrApi/VrApi.h>
|
|
|
|
#endif
|
|
#endif
|
|
|
|
#include <QtCore/QTimer>
|
|
#include <QtGui/QKeyEvent>
|
|
#include <QtWidgets/QMenuBar>
|
|
|
|
#include "GVRMainWindow.h"
|
|
#include "RenderingClient.h"
|
|
|
|
#include "GVRInterface.h"
|
|
|
|
static QString launchURLString = QString();
|
|
|
|
#ifdef ANDROID
|
|
|
|
extern "C" {
|
|
|
|
JNIEXPORT void Java_io_highfidelity_gvrinterface_InterfaceActivity_handleHifiURL(JNIEnv *jni, jclass clazz, jstring hifiURLString) {
|
|
launchURLString = QAndroidJniObject(hifiURLString).toString();
|
|
}
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
GVRInterface::GVRInterface(int argc, char* argv[]) :
|
|
QApplication(argc, argv),
|
|
_mainWindow(NULL),
|
|
_inVRMode(false)
|
|
{
|
|
setApplicationName("gvr-interface");
|
|
setOrganizationName("highfidelity");
|
|
setOrganizationDomain("io");
|
|
|
|
if (!launchURLString.isEmpty()) {
|
|
// did we get launched with a lookup URL? If so it is time to give that to the AddressManager
|
|
qDebug() << "We were opened via a hifi URL -" << launchURLString;
|
|
}
|
|
|
|
_client = new RenderingClient(this, launchURLString);
|
|
|
|
launchURLString = QString();
|
|
|
|
connect(this, &QGuiApplication::applicationStateChanged, this, &GVRInterface::handleApplicationStateChange);
|
|
|
|
#if defined(ANDROID) && defined(HAVE_LIBOVR)
|
|
QAndroidJniEnvironment jniEnv;
|
|
|
|
QPlatformNativeInterface* interface = QApplication::platformNativeInterface();
|
|
jobject activity = (jobject) interface->nativeResourceForIntegration("QtActivity");
|
|
|
|
ovr_RegisterHmtReceivers(&*jniEnv, activity);
|
|
|
|
// PLATFORMACTIVITY_REMOVAL: Temp workaround for PlatformActivity being
|
|
// stripped from UnityPlugin. Alternate is to use LOCAL_WHOLE_STATIC_LIBRARIES
|
|
// but that increases the size of the plugin by ~1MiB
|
|
OVR::linkerPlatformActivity++;
|
|
#endif
|
|
|
|
// call our idle function whenever we can
|
|
QTimer* idleTimer = new QTimer(this);
|
|
connect(idleTimer, &QTimer::timeout, this, &GVRInterface::idle);
|
|
idleTimer->start(0);
|
|
|
|
// call our quit handler before we go down
|
|
connect(this, &QCoreApplication::aboutToQuit, this, &GVRInterface::handleApplicationQuit);
|
|
}
|
|
|
|
void GVRInterface::handleApplicationQuit() {
|
|
_client->cleanupBeforeQuit();
|
|
}
|
|
|
|
void GVRInterface::idle() {
|
|
#if defined(ANDROID) && defined(HAVE_LIBOVR)
|
|
if (!_inVRMode && ovr_IsHeadsetDocked()) {
|
|
qDebug() << "The headset just got docked - enter VR mode.";
|
|
enterVRMode();
|
|
} else if (_inVRMode) {
|
|
|
|
if (ovr_IsHeadsetDocked()) {
|
|
static int counter = 0;
|
|
|
|
// Get the latest head tracking state, predicted ahead to the midpoint of the time
|
|
// it will be displayed. It will always be corrected to the real values by
|
|
// time warp, but the closer we get, the less black will be pulled in at the edges.
|
|
const double now = ovr_GetTimeInSeconds();
|
|
static double prev;
|
|
const double rawDelta = now - prev;
|
|
prev = now;
|
|
const double clampedPrediction = std::min( 0.1, rawDelta * 2);
|
|
ovrSensorState sensor = ovrHmd_GetSensorState(OvrHmd, now + clampedPrediction, true );
|
|
|
|
auto ovrOrientation = sensor.Predicted.Pose.Orientation;
|
|
glm::quat newOrientation(ovrOrientation.w, ovrOrientation.x, ovrOrientation.y, ovrOrientation.z);
|
|
_client->setOrientation(newOrientation);
|
|
|
|
if (counter++ % 100000 == 0) {
|
|
qDebug() << "GetSensorState in frame" << counter << "-"
|
|
<< ovrOrientation.x << ovrOrientation.y << ovrOrientation.z << ovrOrientation.w;
|
|
}
|
|
} else {
|
|
qDebug() << "The headset was undocked - leaving VR mode.";
|
|
|
|
leaveVRMode();
|
|
}
|
|
}
|
|
|
|
OVR::KeyState& backKeyState = _mainWindow->getBackKeyState();
|
|
auto backEvent = backKeyState.Update(ovr_GetTimeInSeconds());
|
|
|
|
if (backEvent == OVR::KeyState::KEY_EVENT_LONG_PRESS) {
|
|
qDebug() << "Attemping to start the Platform UI Activity.";
|
|
ovr_StartPackageActivity(_ovr, PUI_CLASS_NAME, PUI_GLOBAL_MENU);
|
|
} else if (backEvent == OVR::KeyState::KEY_EVENT_DOUBLE_TAP || backEvent == OVR::KeyState::KEY_EVENT_SHORT_PRESS) {
|
|
qDebug() << "Got an event we should cancel for!";
|
|
} else if (backEvent == OVR::KeyState::KEY_EVENT_DOUBLE_TAP) {
|
|
qDebug() << "The button is down!";
|
|
}
|
|
#endif
|
|
}
|
|
|
|
void GVRInterface::handleApplicationStateChange(Qt::ApplicationState state) {
|
|
switch(state) {
|
|
case Qt::ApplicationActive:
|
|
qDebug() << "The application is active.";
|
|
break;
|
|
case Qt::ApplicationSuspended:
|
|
qDebug() << "The application is being suspended.";
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
|
|
void GVRInterface::enterVRMode() {
|
|
#if defined(ANDROID) && defined(HAVE_LIBOVR)
|
|
// Default vrModeParms
|
|
ovrModeParms vrModeParms;
|
|
vrModeParms.AsynchronousTimeWarp = true;
|
|
vrModeParms.AllowPowerSave = true;
|
|
vrModeParms.DistortionFileName = NULL;
|
|
vrModeParms.EnableImageServer = false;
|
|
vrModeParms.CpuLevel = 2;
|
|
vrModeParms.GpuLevel = 2;
|
|
vrModeParms.GameThreadTid = 0;
|
|
|
|
QAndroidJniEnvironment jniEnv;
|
|
|
|
QPlatformNativeInterface* interface = QApplication::platformNativeInterface();
|
|
jobject activity = (jobject) interface->nativeResourceForIntegration("QtActivity");
|
|
|
|
vrModeParms.ActivityObject = activity;
|
|
|
|
ovrHmdInfo hmdInfo;
|
|
_ovr = ovr_EnterVrMode(vrModeParms, &hmdInfo);
|
|
|
|
_inVRMode = true;
|
|
#endif
|
|
}
|
|
|
|
void GVRInterface::leaveVRMode() {
|
|
#if defined(ANDROID) && defined(HAVE_LIBOVR)
|
|
ovr_LeaveVrMode(_ovr);
|
|
_inVRMode = false;
|
|
#endif
|
|
}
|