diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 86eae23882..0b41254f97 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -120,6 +120,7 @@ #include #include #include +#include #include #include #include @@ -5958,8 +5959,8 @@ void Application::update(float deltaTime) { } } - if (auto oculusPlugin = PluginManager::getInstance()->getOculusDisplayPlugin()) { - oculusPlugin->pluginUpdate(); + if (auto oculusPlugin = PluginManager::getInstance()->getOculusPlatformPlugin()) { + oculusPlugin->handleOVREvents(); } userInputMapper->setInputCalibrationData(calibrationData); diff --git a/interface/src/ui/LoginDialog.cpp b/interface/src/ui/LoginDialog.cpp index 943d9df465..0a8c276b90 100644 --- a/interface/src/ui/LoginDialog.cpp +++ b/interface/src/ui/LoginDialog.cpp @@ -18,6 +18,7 @@ #include #include +#include #include #include #include @@ -105,8 +106,8 @@ bool LoginDialog::isSteamRunning() const { } bool LoginDialog::isOculusRunning() const { - auto oculusDisplay = PluginManager::getInstance()->getOculusDisplayPlugin(); - return (oculusDisplay != nullptr); + auto oculusPlatform = PluginManager::getInstance()->getOculusPlatformPlugin(); + return (oculusPlatform != nullptr); } void LoginDialog::dismissLoginDialog() { @@ -124,8 +125,8 @@ void LoginDialog::login(const QString& username, const QString& password) const void LoginDialog::loginThroughOculus() { qDebug() << "Attempting to login through Oculus"; - if (auto oculusDisplay = PluginManager::getInstance()->getOculusDisplayPlugin()) { - oculusDisplay->requestTicket([this](QString nonce, QString userID) { + if (auto oculusPlatform = PluginManager::getInstance()->getOculusPlatformPlugin()) { + //oculusPlatform->requestTicket([this](QString nonce, QString userID) { // if (nonce.isEmpty() || userID.isEmpty()) { // emit handleLoginFailed(); // return; @@ -138,8 +139,8 @@ void LoginDialog::loginThroughOculus() { void LoginDialog::linkOculus() { qDebug() << "Attempting to link Oculus account"; - if (auto oculusDisplay = PluginManager::getInstance()->getOculusDisplayPlugin()) { - //oculusDisplay->requestTicket([this](QString nonce, QString userID) { + if (auto oculusPlatform = PluginManager::getInstance()->getOculusPlatformPlugin()) { + //oculusPlatform->requestTicket([this](QString nonce, QString userID) { // if (nonce.isEmpty() || userID.isEmpty()) { // emit handleLoginFailed(); // return; @@ -165,8 +166,8 @@ void LoginDialog::linkOculus() { void LoginDialog::createAccountFromOculus(QString username) { qDebug() << "Attempting to create account from Oculus info"; - if (auto oculusDisplay = PluginManager::getInstance()->getOculusDisplayPlugin()) { - //oculusDisplay->requestTicket([this, username](QString nonce, QString userID) { + if (auto oculusPlatform = PluginManager::getInstance()->getOculusPlatformPlugin()) { + //oculusPlatform->requestTicket([this, username](QString nonce, QString userID) { // if (nonce.isEmpty() || userID.isEmpty()) { // emit handleLoginFailed(); // return; diff --git a/libraries/plugins/src/plugins/Forward.h b/libraries/plugins/src/plugins/Forward.h index 9eefe983c2..fc1e12b639 100644 --- a/libraries/plugins/src/plugins/Forward.h +++ b/libraries/plugins/src/plugins/Forward.h @@ -21,7 +21,6 @@ class DisplayPlugin; class InputPlugin; class CodecPlugin; class SteamClientPlugin; -class OculusDisplayPlugin; class OculusPlatformPlugin; class Plugin; class PluginContainer; @@ -37,6 +36,5 @@ using CodecPluginPointer = std::shared_ptr; using CodecPluginList = std::vector; using CodecPluginProvider = std::function; using SteamClientPluginPointer = std::shared_ptr; -using OculusDisplayPluginPointer = std::shared_ptr; using OculusPlatformPluginPointer = std::shared_ptr; using InputPluginSettingsPersister = std::function; diff --git a/libraries/plugins/src/plugins/OculusPlatformPlugin.cpp b/libraries/plugins/src/plugins/OculusPlatformPlugin.cpp new file mode 100644 index 0000000000..f6343ebbec --- /dev/null +++ b/libraries/plugins/src/plugins/OculusPlatformPlugin.cpp @@ -0,0 +1,14 @@ +// +// Created by Wayne Chen on 2018/12/20 +// Copyright 2018 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 +// +#include "OculusPlatformPlugin.h" + +OculusPlatformPlugin::OculusPlatformPlugin() { +} + +OculusPlatformPlugin::~OculusPlatformPlugin() { +} diff --git a/libraries/plugins/src/plugins/OculusPlatformPlugin.h b/libraries/plugins/src/plugins/OculusPlatformPlugin.h index 3fe585eb75..1f2bf1cfbb 100644 --- a/libraries/plugins/src/plugins/OculusPlatformPlugin.h +++ b/libraries/plugins/src/plugins/OculusPlatformPlugin.h @@ -7,30 +7,21 @@ // #pragma once -#include +#include #include #include -using OculusTicketRequestCallback = std::function; - - -class OculusPlatformPlugin { +class OculusPlatformPlugin : public QObject { + Q_OBJECT public: - virtual ~OculusPlatformPlugin() = default; + OculusPlatformPlugin(); + virtual ~OculusPlatformPlugin(); - virtual bool init() = 0; - virtual void shutdown() = 0; + virtual const QString getName() const = 0; - virtual bool isRunning() = 0; + virtual void handleOVREvents() = 0; - virtual void runCallbacks() = 0; - - virtual void requestTicket(OculusTicketRequestCallback callback) = 0; - - virtual QString getUserProof() = 0; - - virtual QString getLoggedInUserID() = 0; - - virtual QString getOculusVRBuildID() = 0; +signals: + void nonceAndUserIDChanged(QString nonce, QString userID); }; diff --git a/libraries/plugins/src/plugins/PluginManager.cpp b/libraries/plugins/src/plugins/PluginManager.cpp index 7b7711663c..5473ab723d 100644 --- a/libraries/plugins/src/plugins/PluginManager.cpp +++ b/libraries/plugins/src/plugins/PluginManager.cpp @@ -179,19 +179,20 @@ const SteamClientPluginPointer PluginManager::getSteamClientPlugin() { return steamClientPlugin; } -const OculusDisplayPluginPointer PluginManager::getOculusDisplayPlugin() { - static OculusDisplayPluginPointer oculusDisplayPlugin; +const OculusPlatformPluginPointer PluginManager::getOculusPlatformPlugin() { + static OculusPlatformPluginPointer oculusPlatformPlugin; static std::once_flag once; std::call_once(once, [&] { - // Now grab the display plugins - might break in the main update loop if user unplugs the headset I think? - for (auto plugin : getDisplayPlugins()) { - if (plugin->getName() == "Oculus Rift") { - oculusDisplayPlugin = plugin; + // Now grab the dynamic plugins + for (auto loader : getLoadedPlugins()) { + OculusPlatformProvider* oculusPlatformProvider = qobject_cast(loader->instance()); + if (oculusPlatformProvider) { + oculusPlatformPlugin = oculusPlatformProvider->getOculusPlatformPlugin(); break; } } }); - return oculusDisplayPlugin; + return oculusPlatformPlugin; } const DisplayPluginList& PluginManager::getDisplayPlugins() { diff --git a/libraries/plugins/src/plugins/PluginManager.h b/libraries/plugins/src/plugins/PluginManager.h index 8387aab81a..dc3e3fd856 100644 --- a/libraries/plugins/src/plugins/PluginManager.h +++ b/libraries/plugins/src/plugins/PluginManager.h @@ -28,7 +28,7 @@ public: const InputPluginList& getInputPlugins(); const CodecPluginList& getCodecPlugins(); const SteamClientPluginPointer getSteamClientPlugin(); - const OculusDisplayPluginPointer getOculusDisplayPlugin(); + const OculusPlatformPluginPointer getOculusPlatformPlugin(); DisplayPluginList getPreferredDisplayPlugins(); void setPreferredDisplayPlugins(const QStringList& displays); diff --git a/plugins/CMakeLists.txt b/plugins/CMakeLists.txt index d52df1274e..4a0f52e272 100644 --- a/plugins/CMakeLists.txt +++ b/plugins/CMakeLists.txt @@ -34,8 +34,6 @@ if (NOT SERVER_ONLY AND NOT ANDROID) add_subdirectory(${DIR}) set(DIR "steamClient") add_subdirectory(${DIR}) - set(DIR "oculusPlatform") - add_subdirectory(${DIR}) set(DIR "hifiLeapMotion") add_subdirectory(${DIR}) endif() diff --git a/plugins/oculus/src/OculusBaseDisplayPlugin.cpp b/plugins/oculus/src/OculusBaseDisplayPlugin.cpp index 49c0148e74..9e77eb6478 100644 --- a/plugins/oculus/src/OculusBaseDisplayPlugin.cpp +++ b/plugins/oculus/src/OculusBaseDisplayPlugin.cpp @@ -227,73 +227,3 @@ QVector OculusBaseDisplayPlugin::getSensorPositions() { return result; } - -void OculusBaseDisplayPlugin::handleOVREvents() { -#ifdef OCULUS_APP_ID - if (qApp->property(hifi::properties::OCULUS_STORE).toBool()) { - // pop messages to see if we got a return for an entitlement check - ovrMessageHandle message = ovr_PopMessage(); - - while (message) { - switch (ovr_Message_GetType(message)) { - case ovrMessage_Entitlement_GetIsViewerEntitled: { - _isViewerEntitled = !ovr_Message_IsError(message); - if (_isViewerEntitled) { - // this viewer is entitled, no need to flag anything - qCDebug(oculusLog) << "Oculus Platform entitlement check succeeded, proceeding normally"; - } else { - // we failed the entitlement check, quit - qCDebug(oculusLog) << "Oculus Platform entitlement check failed, app will now quit" << OCULUS_APP_ID; - } - break; - } - case ovrMessage_User_Get: { - if (!ovr_Message_IsError(message)) { - qCDebug(oculusLog) << "Oculus Platform user retrieval succeeded"; - ovrUserHandle user = ovr_Message_GetUser(message); - ovr_FreeMessage(message); - _user = ovr_User_GetOculusID(user); - } else { - qCDebug(oculusLog) << "Oculus Platform user retrieval failed" << QString(ovr_Error_GetMessage(ovr_Message_GetError(message))); - _user = ""; - } - break; - } - case ovrMessage_User_GetLoggedInUser: { - if (!ovr_Message_IsError(message)) { - ovrUserHandle user = ovr_Message_GetUser(message); - ovr_FreeMessage(message); - _userID = ovr_User_GetID(user); - } else { - qCDebug(oculusLog) << "Oculus Platform user ID retrieval failed" << QString(ovr_Error_GetMessage(ovr_Message_GetError(message))); - } - break; - } - case ovrMessage_User_GetUserProof: { - _nonceChanged = true; - if (!ovr_Message_IsError(message)) { - ovrUserProofHandle userProof = ovr_Message_GetUserProof(message); - _nonce = ovr_UserProof_GetNonce(userProof); - } else { - qCDebug(oculusLog) << "Oculus Platform nonce retrieval failed" << QString(ovr_Error_GetMessage(ovr_Message_GetError(message))); - _nonce = ""; - } - break; - } - } - - if (_nonceChanged) { - emit nonceAndUserIDChanged(_nonce, _user); - _nonce = _user = ""; - _nonceChanged = false; - } - - // free the message handle to cleanup and not leak - ovr_FreeMessage(message); - - // pop the next message to check, if there is one - message = ovr_PopMessage(); - } - } -#endif -} diff --git a/plugins/oculus/src/OculusBaseDisplayPlugin.h b/plugins/oculus/src/OculusBaseDisplayPlugin.h index 45baf54174..9a76e1e553 100644 --- a/plugins/oculus/src/OculusBaseDisplayPlugin.h +++ b/plugins/oculus/src/OculusBaseDisplayPlugin.h @@ -43,7 +43,6 @@ protected: bool internalActivate() override; void internalDeactivate() override; void updatePresentPose() override; - void handleOVREvents(); protected: bool _isViewerEntitled; diff --git a/plugins/oculus/src/OculusDisplayPlugin.cpp b/plugins/oculus/src/OculusDisplayPlugin.cpp index 8f4d5c21a4..a34e647a5e 100644 --- a/plugins/oculus/src/OculusDisplayPlugin.cpp +++ b/plugins/oculus/src/OculusDisplayPlugin.cpp @@ -56,10 +56,6 @@ void OculusDisplayPlugin::init() { emit deviceConnected(getName()); } -void OculusDisplayPlugin::pluginUpdate() { - handleOVREvents(); -} - void OculusDisplayPlugin::cycleDebugOutput() { if (_session) { currentDebugMode = static_cast((currentDebugMode + 1) % ovrPerfHud_Count); diff --git a/plugins/oculus/src/OculusDisplayPlugin.h b/plugins/oculus/src/OculusDisplayPlugin.h index b290348eb8..9209fd373e 100644 --- a/plugins/oculus/src/OculusDisplayPlugin.h +++ b/plugins/oculus/src/OculusDisplayPlugin.h @@ -23,7 +23,6 @@ public: float getTargetFrameRate() const override; virtual QJsonObject getHardwareStats() const; - void pluginUpdate() override final; protected: QThread::Priority getPresentPriority() override { return QThread::TimeCriticalPriority; } diff --git a/plugins/oculus/src/OculusPlatformPlugin.cpp b/plugins/oculus/src/OculusPlatformPlugin.cpp new file mode 100644 index 0000000000..0d0d7c447c --- /dev/null +++ b/plugins/oculus/src/OculusPlatformPlugin.cpp @@ -0,0 +1,95 @@ +// +// Created by Wayne Chen on 2019/01/08 +// Copyright 2019 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 +// + +#include "OculusPlatformPlugin.h" + +#include + +#include + +#include "OculusHelpers.h" + +const char* OculusAPIPlugin::NAME { "Oculus Rift" }; + +OculusAPIPlugin::OculusAPIPlugin() { + _session = hifi::ovr::acquireRenderSession(); +} + +OculusAPIPlugin::~OculusAPIPlugin() { + hifi::ovr::releaseRenderSession(_session); +} + +void OculusAPIPlugin::handleOVREvents() { +#ifdef OCULUS_APP_ID + if (qApp->property(hifi::properties::OCULUS_STORE).toBool()) { + // pop messages to see if we got a return for an entitlement check + ovrMessageHandle message = ovr_PopMessage(); + + while (message) { + switch (ovr_Message_GetType(message)) { + case ovrMessage_Entitlement_GetIsViewerEntitled: { + if (!ovr_Message_IsError(message)) { + // this viewer is entitled, no need to flag anything + qCDebug(oculusLog) << "Oculus Platform entitlement check succeeded, proceeding normally"; + } else { + // we failed the entitlement check, quit + qCDebug(oculusLog) << "Oculus Platform entitlement check failed, app will now quit" << OCULUS_APP_ID; + QMetaObject::invokeMethod(qApp, "quit"); + } + break; + } + case ovrMessage_User_Get: { + if (!ovr_Message_IsError(message)) { + qCDebug(oculusLog) << "Oculus Platform user retrieval succeeded"; + ovrUserHandle user = ovr_Message_GetUser(message); + ovr_FreeMessage(message); + _user = ovr_User_GetOculusID(user); + } else { + qCDebug(oculusLog) << "Oculus Platform user retrieval failed" << QString(ovr_Error_GetMessage(ovr_Message_GetError(message))); + _user = ""; + } + break; + } + case ovrMessage_User_GetLoggedInUser: { + if (!ovr_Message_IsError(message)) { + ovrUserHandle user = ovr_Message_GetUser(message); + ovr_FreeMessage(message); + _userID = ovr_User_GetID(user); + } else { + qCDebug(oculusLog) << "Oculus Platform user ID retrieval failed" << QString(ovr_Error_GetMessage(ovr_Message_GetError(message))); + } + break; + } + case ovrMessage_User_GetUserProof: { + _nonceChanged = true; + if (!ovr_Message_IsError(message)) { + ovrUserProofHandle userProof = ovr_Message_GetUserProof(message); + _nonce = ovr_UserProof_GetNonce(userProof); + } else { + qCDebug(oculusLog) << "Oculus Platform nonce retrieval failed" << QString(ovr_Error_GetMessage(ovr_Message_GetError(message))); + _nonce = ""; + } + break; + } + } + + if (_nonceChanged) { + emit nonceAndUserIDChanged(_nonce, _user); + _nonce = _user = ""; + _nonceChanged = false; + } + + // free the message handle to cleanup and not leak + ovr_FreeMessage(message); + + // pop the next message to check, if there is one + message = ovr_PopMessage(); + } + } +#endif +} diff --git a/plugins/oculus/src/OculusPlatformPlugin.h b/plugins/oculus/src/OculusPlatformPlugin.h new file mode 100644 index 0000000000..a59c4f0b84 --- /dev/null +++ b/plugins/oculus/src/OculusPlatformPlugin.h @@ -0,0 +1,32 @@ +// +// Created by Wayne Chen on 2019/01/08 +// Copyright 2019 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 +// +#pragma once + +#include + +#include + +#define OVRPL_DISABLED +#include + +class OculusAPIPlugin : public OculusPlatformPlugin { +public: + OculusAPIPlugin(); + virtual ~OculusAPIPlugin(); + const QString getName() const { return NAME; } + + virtual void handleOVREvents(); + +private: + static const char* NAME; + QString _nonce; + bool _nonceChanged; + QString _user; + ovrID _userID; + ovrSession _session{ nullptr }; +}; diff --git a/plugins/oculus/src/OculusProvider.cpp b/plugins/oculus/src/OculusProvider.cpp index 47ccc5304e..67871b8610 100644 --- a/plugins/oculus/src/OculusProvider.cpp +++ b/plugins/oculus/src/OculusProvider.cpp @@ -18,15 +18,18 @@ #include "OculusDisplayPlugin.h" #include "OculusDebugDisplayPlugin.h" +#include "OculusPlatformPlugin.h" #include "OculusControllerManager.h" -class OculusProvider : public QObject, public DisplayProvider, InputProvider +class OculusProvider : public QObject, public DisplayProvider, InputProvider, OculusPlatformProvider { Q_OBJECT Q_PLUGIN_METADATA(IID DisplayProvider_iid FILE "oculus.json") Q_INTERFACES(DisplayProvider) Q_PLUGIN_METADATA(IID InputProvider_iid FILE "oculus.json") Q_INTERFACES(InputProvider) + Q_PLUGIN_METADATA(IID OculusPlatformProvider_iid FILE "oculus.json") + Q_INTERFACES(OculusPlatformProvider) public: OculusProvider(QObject* parent = nullptr) : QObject(parent) {} @@ -62,6 +65,15 @@ public: return _inputPlugins; } + virtual OculusPlatformPluginPointer getOculusPlatformPlugin() override { + static std::once_flag once; + std::call_once(once, [&] { + _oculusPlatformPlugin = std::make_shared(); + + }); + return _oculusPlatformPlugin; + } + virtual void destroyInputPlugins() override { _inputPlugins.clear(); } @@ -73,6 +85,7 @@ public: private: DisplayPluginList _displayPlugins; InputPluginList _inputPlugins; + OculusPlatformPluginPointer _oculusPlatformPlugin; }; #include "OculusProvider.moc" diff --git a/plugins/oculusPlatform/CMakeLists.txt b/plugins/oculusPlatform/CMakeLists.txt deleted file mode 100644 index 89608794ae..0000000000 --- a/plugins/oculusPlatform/CMakeLists.txt +++ /dev/null @@ -1,36 +0,0 @@ -# -# Created by Bradley Austin Davis on 2015/10/25 -# Copyright 2015 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 -# - -if (WIN32 AND (NOT USE_GLES)) - - # if we were passed an Oculus App ID for entitlement checks, send that along - if (DEFINED ENV{OCULUS_APP_ID}) - add_definitions(-DOCULUS_APP_ID="$ENV{OCULUS_APP_ID}") - endif () - - set(TARGET_NAME oculusPlatform) - setup_hifi_plugin(Multimedia) - link_hifi_libraries( - shared task gl shaders gpu ${PLATFORM_GL_BACKEND} controllers ui qml - plugins ui-plugins display-plugins input-plugins - audio-client networking render-utils - ${PLATFORM_GL_BACKEND} - ) - include_hifi_library_headers(octree) - - add_dependency_external_projects(LibOVR) - find_package(LibOVR REQUIRED) - target_include_directories(${TARGET_NAME} PRIVATE ${LIBOVR_INCLUDE_DIRS}) - target_link_libraries(${TARGET_NAME} ${LIBOVR_LIBRARIES}) - target_link_libraries(${TARGET_NAME} Winmm.lib) - - add_dependency_external_projects(LibOVRPlatform) - find_package(LibOVRPlatform REQUIRED) - target_include_directories(${TARGET_NAME} PRIVATE ${LIBOVRPLATFORM_INCLUDE_DIRS}) - target_link_libraries(${TARGET_NAME} ${LIBOVRPLATFORM_LIBRARIES}) -endif() diff --git a/plugins/oculusPlatform/src/OculusAPIPlugin.cpp b/plugins/oculusPlatform/src/OculusAPIPlugin.cpp deleted file mode 100644 index 2400670b0e..0000000000 --- a/plugins/oculusPlatform/src/OculusAPIPlugin.cpp +++ /dev/null @@ -1,226 +0,0 @@ -// -// Created by Wayne Chen on 2018/12/20 -// Copyright 2018 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 -// - -#include "OculusAPIPlugin.h" - -#include -#include -#include - -#include - -#define OVRPL_DISABLED -#include - -#include -#include "OculusHelpers.h" - -static std::atomic_bool initialized { false }; -static ovrSession session { nullptr }; - -bool OculusAPIPlugin::init() { - if (session) { - return initialized; - } - - ovrInitParams initParams{ ovrInit_RequestVersion | ovrInit_FocusAware, OVR_MINOR_VERSION, nullptr, 0, 0 }; - initParams.Flags |= ovrInit_Invisible; - - if (!OVR_SUCCESS(ovr_Initialize(&initParams))) { - qCWarning(oculusLog) << "Failed to initialze Oculus SDK" << hifi::ovr::getError(); - return initialized; - } - -#ifdef OCULUS_APP_ID - if (qApp->property(hifi::properties::OCULUS_STORE).toBool()) { - auto result = ovr_PlatformInitializeWindows(OCULUS_APP_ID); - if (result != ovrPlatformInitialize_Success && result != ovrPlatformInitialize_PreLoaded) { - qCWarning(oculusLog) << "Unable to initialize the platform for entitlement check - fail the check" << hifi::ovr::getError(); - } else { - qCDebug(oculusLog) << "Performing Oculus Platform entitlement check"; - ovr_Entitlement_GetIsViewerEntitled(); - QTimer timer; - timer.start(1000); - using namespace std::chrono_literals; - std::this_thread::sleep_for(50ms); - while (auto message = ovr_PopMessage()) { - if (timer.remainingTime() == 0) { - qCDebug(oculusLog) << "login user id timeout after 1 second"; - break; - } - switch (ovr_Message_GetType(message)) { - case ovrMessage_Entitlement_GetIsViewerEntitled: - if (ovr_Message_IsError(message)) { - qDebug() << QString(ovr_Error_GetMessage(ovr_Message_GetError(message))); - } - initialized = true; - default: - ovr_FreeMessage(message); - break; - } - } - } - } -#endif - - return initialized; -} - -void OculusAPIPlugin::shutdown() { -} - -void OculusAPIPlugin::runCallbacks() { -} - -void OculusAPIPlugin::requestTicket(OculusTicketRequestCallback callback) { - if (!initialized) { - if (!ovr_IsPlatformInitialized()) { - init(); - } - else { - qWarning() << "Oculus is not running"; - callback("", ""); - return; - } - } - - if (!initialized) { - qDebug() << "Oculus not initialized"; - return; - } - - auto nonce = getUserProof(); - auto userID = getLoggedInUserID(); - qDebug() << "Nonce: " << nonce << ", " << userID; - - callback(nonce, userID); - return; -} - -bool OculusAPIPlugin::isRunning() { - return initialized; -} - -QString OculusAPIPlugin::getUserProof() { - if (initialized) { - QTimer timer; - timer.start(5000); - auto request = ovr_User_GetUserProof(); - ovrMessageHandle message { nullptr }; - bool messageNotReceived = true; - while (messageNotReceived) { - message = ovr_PopMessage(); - if (timer.remainingTime() == 0) { - qCDebug(oculusLog) << "user proof timeout after 5 seconds"; - return ""; - } - if (message != nullptr) { - switch (ovr_Message_GetType(message)) { - case ovrMessage_User_GetUserProof: - messageNotReceived = false; - if (!ovr_Message_IsError(message)) { - ovrUserProofHandle userProof = ovr_Message_GetUserProof(message); - QString nonce = ovr_UserProof_GetNonce(userProof); - ovr_FreeMessage(message); - return nonce; - } else { - qDebug() << "Error getting user proof: " << QString(ovr_Error_GetMessage(ovr_Message_GetError(message))); - ovr_FreeMessage(message); - return ""; - } - break; - default: - ovr_FreeMessage(message); - break; - } - } - } - } - return ""; -} - -QString getOculusUserID(ovrID userID) { - QTimer timer; - timer.start(5000); - timer.setSingleShot(true); - auto request = ovr_User_Get(userID); - bool messageNotReceived = true; - while (messageNotReceived) { - auto message = ovr_PopMessage(); - if (timer.remainingTime() == 0) { - qCDebug(oculusLog) << "login user id timeout after 5 seconds"; - return ""; - } - if (message != nullptr) { - switch (ovr_Message_GetType(message)) { - case ovrMessage_User_Get: - if (!ovr_Message_IsError(message)) { - messageNotReceived = false; - ovrUserHandle user = ovr_Message_GetUser(message); - ovr_FreeMessage(message); - qCDebug(oculusLog) << "UserID: " << userID << "\nOculus ID: " << QString(ovr_User_GetOculusID(user)); - return QString(ovr_User_GetOculusID(user)); - } else { - qDebug() << "Error getting user id: " << QString(ovr_Error_GetMessage(ovr_Message_GetError(message))); - ovr_FreeMessage(message); - return ""; - } - break; - default: - ovr_FreeMessage(message); - break; - } - } - } -} - -QString OculusAPIPlugin::getLoggedInUserID() { - if (initialized) { - QTimer timer; - timer.start(5000); - timer.setSingleShot(true); - auto request = ovr_User_GetLoggedInUser(); - ovrMessageHandle message { nullptr }; - ovrID userID = 0; - bool messageNotReceived = true; - while (messageNotReceived) { - message = ovr_PopMessage(); - if (timer.remainingTime() == 0) { - qCDebug(oculusLog) << "login user id timeout after 5 seconds"; - return ""; - } - if (message != nullptr) { - switch (ovr_Message_GetType(message)) { - case ovrMessage_User_GetLoggedInUser: - if (!ovr_Message_IsError(message)) { - messageNotReceived = false; - ovrUserHandle user = ovr_Message_GetUser(message); - ovr_FreeMessage(message); - userID = ovr_User_GetID(user); - break; - } else { - qDebug() << "Error getting user id: " << QString(ovr_Error_GetMessage(ovr_Message_GetError(message))); - ovr_FreeMessage(message); - return ""; - } - break; - default: - ovr_FreeMessage(message); - break; - } - } - } - timer.stop(); - return getOculusUserID(userID); - } - return ""; -} - -QString OculusAPIPlugin::getOculusVRBuildID() { - return QString(OVR_MAJOR_VERSION + "." + OVR_MINOR_VERSION); -} diff --git a/plugins/oculusPlatform/src/OculusAPIPlugin.h b/plugins/oculusPlatform/src/OculusAPIPlugin.h deleted file mode 100644 index 86343d361c..0000000000 --- a/plugins/oculusPlatform/src/OculusAPIPlugin.h +++ /dev/null @@ -1,27 +0,0 @@ -// -// Created by Wayne Chen on 2018/12/20 -// Copyright 2018 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 -// -#pragma once - -#include - -class OculusAPIPlugin : public OculusPlatformPlugin { -public: - bool init() override; - void shutdown() override; - - bool isRunning() override; - - void runCallbacks() override; - - void requestTicket(OculusTicketRequestCallback callback) override; - - QString getUserProof() override; - QString getLoggedInUserID() override; - - QString getOculusVRBuildID() override; -}; diff --git a/plugins/oculusPlatform/src/OculusHelpers.cpp b/plugins/oculusPlatform/src/OculusHelpers.cpp deleted file mode 100644 index 29691e73a5..0000000000 --- a/plugins/oculusPlatform/src/OculusHelpers.cpp +++ /dev/null @@ -1,326 +0,0 @@ -// -// Created by Bradley Austin Davis on 2015/08/08 -// Copyright 2015 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 -// - -#include "OculusHelpers.h" - -#include - -#include -#include -#include -#include - -#define OVRPL_DISABLED -#include - -#include -#include -#include -#include - -Q_LOGGING_CATEGORY(displayplugins, "hifi.plugins.display") -Q_LOGGING_CATEGORY(oculusLog, "hifi.plugins.display.oculus") - -using namespace hifi; - -static wchar_t* REQUIRED_OCULUS_DLL = L"LibOVRRT64_1.dll"; -static wchar_t FOUND_PATH[MAX_PATH]; - -bool ovr::available() { - static std::once_flag once; - static bool result{ false }; - std::call_once(once, [&] { - static const QString DEBUG_FLAG("HIFI_DEBUG_OPENVR"); - static bool enableDebugOpenVR = QProcessEnvironment::systemEnvironment().contains(DEBUG_FLAG); - if (enableDebugOpenVR) { - return; - } - - ovrDetectResult detect = ovr_Detect(0); - if (!detect.IsOculusServiceRunning || !detect.IsOculusHMDConnected) { - return; - } - - DWORD searchResult = SearchPathW(NULL, REQUIRED_OCULUS_DLL, NULL, MAX_PATH, FOUND_PATH, NULL); - if (searchResult <= 0) { - return; - } - - result = true; - }); - - return result; -} - -class ovrImpl { - using Mutex = std::mutex; - using Lock = std::unique_lock; - std::mutex mutex; - ovrSession session{ nullptr }; - size_t renderCount{ 0 }; - -private: - void setupSession(bool render) { - if (session) { - return; - } - ovrInitParams initParams{ ovrInit_RequestVersion | ovrInit_FocusAware, OVR_MINOR_VERSION, nullptr, 0, 0 }; - if (render) { - initParams.Flags |= ovrInit_MixedRendering; - } else { - initParams.Flags |= ovrInit_Invisible; - } - - if (!OVR_SUCCESS(ovr_Initialize(&initParams))) { - qCWarning(oculusLog) << "Failed to initialze Oculus SDK" << ovr::getError(); - return; - } - -#ifdef OCULUS_APP_ID - if (qApp->property(hifi::properties::OCULUS_STORE).toBool()) { - if (ovr_PlatformInitializeWindows(OCULUS_APP_ID) != ovrPlatformInitialize_Success) { - qCWarning(oculusLog) << "Unable to initialize the platform for entitlement check - fail the check" << ovr::getError(); - return; - } else { - qCDebug(oculusLog) << "Performing Oculus Platform entitlement check"; - ovr_Entitlement_GetIsViewerEntitled(); - } - } -#endif - - ovrGraphicsLuid luid; - if (!OVR_SUCCESS(ovr_Create(&session, &luid))) { - qCWarning(oculusLog) << "Failed to acquire Oculus session" << ovr::getError(); - return; - } else { - ovrResult setFloorLevelOrigin = ovr_SetTrackingOriginType(session, ovrTrackingOrigin::ovrTrackingOrigin_FloorLevel); - if (!OVR_SUCCESS(setFloorLevelOrigin)) { - qCWarning(oculusLog) << "Failed to set the Oculus tracking origin to floor level" << ovr::getError(); - } - } - } - - void releaseSession() { - if (!session) { - return; - } - ovr_Destroy(session); - session = nullptr; - ovr_Shutdown(); - } - -public: - void withSession(const std::function& f) { - Lock lock(mutex); - if (!session) { - setupSession(false); - } - f(session); - } - - ovrSession acquireRenderSession() { - Lock lock(mutex); - if (renderCount++ == 0) { - releaseSession(); - setupSession(true); - } - return session; - } - - void releaseRenderSession(ovrSession session) { - Lock lock(mutex); - if (--renderCount == 0) { - releaseSession(); - } - } -} _ovr; - -ovrSession ovr::acquireRenderSession() { - return _ovr.acquireRenderSession(); -} - -void ovr::releaseRenderSession(ovrSession session) { - _ovr.releaseRenderSession(session); -} - -void ovr::withSession(const std::function& f) { - _ovr.withSession(f); -} - -ovrSessionStatus ovr::getStatus() { - ovrResult result; - return ovr::getStatus(result); -} - -ovrSessionStatus ovr::getStatus(ovrResult& result) { - ovrSessionStatus status{}; - withSession([&](ovrSession session) { - result = ovr_GetSessionStatus(session, &status); - if (!OVR_SUCCESS(result)) { - qCWarning(oculusLog) << "Failed to get session status" << ovr::getError(); - } - }); - return status; -} - -ovrTrackingState ovr::getTrackingState(double absTime, ovrBool latencyMarker) { - ovrTrackingState result{}; - withSession([&](ovrSession session) { result = ovr_GetTrackingState(session, absTime, latencyMarker); }); - return result; -} - -QString ovr::getError() { - static ovrErrorInfo error; - ovr_GetLastErrorInfo(&error); - return QString(error.ErrorString); -} - -controller::Pose hifi::ovr::toControllerPose(ovrHandType hand, const ovrPoseStatef& handPose) { - // When the sensor-to-world rotation is identity the coordinate axes look like this: - // - // user - // forward - // -z - // | - // y| user - // y o----x right - // o-----x user - // | up - // | - // z - // - // Rift - - // From ABOVE the hand canonical axes looks like this: - // - // | | | | y | | | | - // | | | | | | | | | - // | | | | | - // |left | / x---- + \ |right| - // | _/ z \_ | - // | | | | - // | | | | - // - - // So when the user is in Rift space facing the -zAxis with hands outstretched and palms down - // the rotation to align the Touch axes with those of the hands is: - // - // touchToHand = halfTurnAboutY * quaterTurnAboutX - - // Due to how the Touch controllers fit into the palm there is an offset that is different for each hand. - // You can think of this offset as the inverse of the measured rotation when the hands are posed, such that - // the combination (measurement * offset) is identity at this orientation. - // - // Qoffset = glm::inverse(deltaRotation when hand is posed fingers forward, palm down) - // - // An approximate offset for the Touch can be obtained by inspection: - // - // Qoffset = glm::inverse(glm::angleAxis(sign * PI/2.0f, zAxis) * glm::angleAxis(PI/4.0f, xAxis)) - // - // So the full equation is: - // - // Q = combinedMeasurement * touchToHand - // - // Q = (deltaQ * QOffset) * (yFlip * quarterTurnAboutX) - // - // Q = (deltaQ * inverse(deltaQForAlignedHand)) * (yFlip * quarterTurnAboutX) - static const glm::quat yFlip = glm::angleAxis(PI, Vectors::UNIT_Y); - static const glm::quat quarterX = glm::angleAxis(PI_OVER_TWO, Vectors::UNIT_X); - static const glm::quat touchToHand = yFlip * quarterX; - - static const glm::quat leftQuarterZ = glm::angleAxis(-PI_OVER_TWO, Vectors::UNIT_Z); - static const glm::quat rightQuarterZ = glm::angleAxis(PI_OVER_TWO, Vectors::UNIT_Z); - - static const glm::quat leftRotationOffset = glm::inverse(leftQuarterZ) * touchToHand; - static const glm::quat rightRotationOffset = glm::inverse(rightQuarterZ) * touchToHand; - - static const float CONTROLLER_LENGTH_OFFSET = 0.0762f; // three inches - static const glm::vec3 CONTROLLER_OFFSET = - glm::vec3(CONTROLLER_LENGTH_OFFSET / 2.0f, -CONTROLLER_LENGTH_OFFSET / 2.0f, CONTROLLER_LENGTH_OFFSET * 1.5f); - static const glm::vec3 leftTranslationOffset = glm::vec3(-1.0f, 1.0f, 1.0f) * CONTROLLER_OFFSET; - static const glm::vec3 rightTranslationOffset = CONTROLLER_OFFSET; - - auto translationOffset = (hand == ovrHand_Left ? leftTranslationOffset : rightTranslationOffset); - auto rotationOffset = (hand == ovrHand_Left ? leftRotationOffset : rightRotationOffset); - - glm::quat rotation = toGlm(handPose.ThePose.Orientation); - - controller::Pose pose; - pose.translation = toGlm(handPose.ThePose.Position); - pose.translation += rotation * translationOffset; - pose.rotation = rotation * rotationOffset; - pose.angularVelocity = rotation * toGlm(handPose.AngularVelocity); - pose.velocity = toGlm(handPose.LinearVelocity); - pose.valid = true; - return pose; -} - -controller::Pose hifi::ovr::toControllerPose(ovrHandType hand, - const ovrPoseStatef& handPose, - const ovrPoseStatef& lastHandPose) { - static const glm::quat yFlip = glm::angleAxis(PI, Vectors::UNIT_Y); - static const glm::quat quarterX = glm::angleAxis(PI_OVER_TWO, Vectors::UNIT_X); - static const glm::quat touchToHand = yFlip * quarterX; - - static const glm::quat leftQuarterZ = glm::angleAxis(-PI_OVER_TWO, Vectors::UNIT_Z); - static const glm::quat rightQuarterZ = glm::angleAxis(PI_OVER_TWO, Vectors::UNIT_Z); - - static const glm::quat leftRotationOffset = glm::inverse(leftQuarterZ) * touchToHand; - static const glm::quat rightRotationOffset = glm::inverse(rightQuarterZ) * touchToHand; - - static const float CONTROLLER_LENGTH_OFFSET = 0.0762f; // three inches - static const glm::vec3 CONTROLLER_OFFSET = - glm::vec3(CONTROLLER_LENGTH_OFFSET / 2.0f, -CONTROLLER_LENGTH_OFFSET / 2.0f, CONTROLLER_LENGTH_OFFSET * 1.5f); - static const glm::vec3 leftTranslationOffset = glm::vec3(-1.0f, 1.0f, 1.0f) * CONTROLLER_OFFSET; - static const glm::vec3 rightTranslationOffset = CONTROLLER_OFFSET; - - auto translationOffset = (hand == ovrHand_Left ? leftTranslationOffset : rightTranslationOffset); - auto rotationOffset = (hand == ovrHand_Left ? leftRotationOffset : rightRotationOffset); - - glm::quat rotation = toGlm(handPose.ThePose.Orientation); - - controller::Pose pose; - pose.translation = toGlm(lastHandPose.ThePose.Position); - pose.translation += rotation * translationOffset; - pose.rotation = rotation * rotationOffset; - pose.angularVelocity = toGlm(lastHandPose.AngularVelocity); - pose.velocity = toGlm(lastHandPose.LinearVelocity); - pose.valid = true; - return pose; -} - -bool hifi::ovr::handleOVREvents() { -#ifdef OCULUS_APP_ID - if (qApp->property(hifi::properties::OCULUS_STORE).toBool()) { - // pop messages to see if we got a return for an entitlement check - ovrMessageHandle message = ovr_PopMessage(); - - while (message) { - switch (ovr_Message_GetType(message)) { - case ovrMessage_Entitlement_GetIsViewerEntitled: { - if (!ovr_Message_IsError(message)) { - // this viewer is entitled, no need to flag anything - qCDebug(oculusLog) << "Oculus Platform entitlement check succeeded, proceeding normally"; - } else { - // we failed the entitlement check, quit - qCDebug(oculusLog) << "Oculus Platform entitlement check failed, app will now quit" << OCULUS_APP_ID; - return false; - } - } - } - - // free the message handle to cleanup and not leak - ovr_FreeMessage(message); - - // pop the next message to check, if there is one - message = ovr_PopMessage(); - } - } -#endif - return true; -} diff --git a/plugins/oculusPlatform/src/OculusHelpers.h b/plugins/oculusPlatform/src/OculusHelpers.h deleted file mode 100644 index bdfc4434bb..0000000000 --- a/plugins/oculusPlatform/src/OculusHelpers.h +++ /dev/null @@ -1,127 +0,0 @@ -// -// Created by Bradley Austin Davis on 2015/05/26 -// Copyright 2015 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 -// -#pragma once - -#include - -#include -#include -#include -#include - -#include - -Q_DECLARE_LOGGING_CATEGORY(displayplugins) -Q_DECLARE_LOGGING_CATEGORY(oculusLog) - -namespace hifi { - -struct ovr { - static bool available(); - static ovrSession acquireRenderSession(); - static void releaseRenderSession(ovrSession session); - static void withSession(const std::function& f); - static ovrSessionStatus getStatus(); - static ovrSessionStatus getStatus(ovrResult& result); - static ovrTrackingState getTrackingState(double absTime = 0.0, ovrBool latencyMarker = ovrFalse); - static QString getError(); - static bool handleOVREvents(); - - static inline bool quitRequested() { return quitRequested(getStatus()); } - static inline bool reorientRequested() { return reorientRequested(getStatus()); } - static inline bool hmdMounted() { return hmdMounted(getStatus()); } - static inline bool hasInputFocus() { return hasInputFocus(getStatus()); } - - static inline bool quitRequested(const ovrSessionStatus& status) { return status.ShouldQuit != ovrFalse; } - static inline bool displayLost(const ovrSessionStatus& status) { return status.DisplayLost != ovrFalse; } - static inline bool isVisible(const ovrSessionStatus& status) { return status.IsVisible != ovrFalse; } - static inline bool reorientRequested(const ovrSessionStatus& status) { return status.ShouldRecenter != ovrFalse; } - static inline bool hmdMounted(const ovrSessionStatus& status) { return status.HmdMounted != ovrFalse; } - static inline bool hasInputFocus(const ovrSessionStatus& status) { return status.HasInputFocus != ovrFalse; } - - // Convenience method for looping over each eye with a lambda - static inline void for_each_eye(const std::function& f) { - for (ovrEyeType eye = ovrEye_Left; eye < ovrEye_Count; eye = static_cast(eye + 1)) { - f(eye); - } - } - - static inline void for_each_hand(const std::function& f) { - for (ovrHandType hand = ovrHand_Left; hand < ovrHand_Count; hand = static_cast(hand + 1)) { - f(hand); - } - } - - static inline glm::mat4 toGlm(const ovrMatrix4f& om) { - return glm::transpose(glm::make_mat4(&om.M[0][0])); - } - - static inline glm::mat4 toGlm(const ovrFovPort& fovport, float nearPlane = 0.01f, float farPlane = 10000.0f) { - return toGlm(ovrMatrix4f_Projection(fovport, nearPlane, farPlane, true)); - } - - static inline glm::vec3 toGlm(const ovrVector3f& ov) { - return glm::make_vec3(&ov.x); - } - - static inline glm::vec2 toGlm(const ovrVector2f& ov) { - return glm::make_vec2(&ov.x); - } - - static inline glm::uvec2 toGlm(const ovrSizei& ov) { - return glm::uvec2(ov.w, ov.h); - } - - static inline glm::quat toGlm(const ovrQuatf& oq) { - return glm::make_quat(&oq.x); - } - - static inline glm::mat4 toGlm(const ovrPosef& op) { - glm::mat4 orientation = glm::mat4_cast(toGlm(op.Orientation)); - glm::mat4 translation = glm::translate(glm::mat4(), toGlm(op.Position)); - return translation * orientation; - } - - static inline ovrMatrix4f fromGlm(const glm::mat4& m) { - ovrMatrix4f result; - glm::mat4 transposed(glm::transpose(m)); - memcpy(result.M, &(transposed[0][0]), sizeof(float) * 16); - return result; - } - - static inline ovrVector3f fromGlm(const glm::vec3& v) { - return { v.x, v.y, v.z }; - } - - static inline ovrVector2f fromGlm(const glm::vec2& v) { - return { v.x, v.y }; - } - - static inline ovrSizei fromGlm(const glm::uvec2& v) { - return { (int)v.x, (int)v.y }; - } - - static inline ovrQuatf fromGlm(const glm::quat& q) { - return { q.x, q.y, q.z, q.w }; - } - - static inline ovrPosef poseFromGlm(const glm::mat4& m) { - glm::vec3 translation = glm::vec3(m[3]) / m[3].w; - glm::quat orientation = glm::quat_cast(m); - ovrPosef result; - result.Orientation = fromGlm(orientation); - result.Position = fromGlm(translation); - return result; - } - - static controller::Pose toControllerPose(ovrHandType hand, const ovrPoseStatef& handPose); - static controller::Pose toControllerPose(ovrHandType hand, const ovrPoseStatef& handPose, const ovrPoseStatef& lastHandPose); - -}; - -} // namespace hifi diff --git a/plugins/oculusPlatform/src/OculusPlatformProvider.cpp b/plugins/oculusPlatform/src/OculusPlatformProvider.cpp deleted file mode 100644 index 097ddceb29..0000000000 --- a/plugins/oculusPlatform/src/OculusPlatformProvider.cpp +++ /dev/null @@ -1,40 +0,0 @@ -// -// Created by Clément Brisset on 12/14/16 -// Copyright 2016 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 -// - -#include - -#include -#include -#include - -#include - -#include "OculusAPIPlugin.h" - -class OculusAPIProvider : public QObject, public OculusPlatformProvider { - Q_OBJECT - Q_PLUGIN_METADATA(IID OculusPlatformProvider_iid FILE "plugin.json") - Q_INTERFACES(OculusPlatformProvider) - -public: - OculusAPIProvider(QObject* parent = nullptr) : QObject(parent) {} - virtual ~OculusAPIProvider() {} - - virtual OculusPlatformPluginPointer getOculusPlatformPlugin() override { - static std::once_flag once; - std::call_once(once, [&] { - _oculusPlatformPlugin = std::make_shared(); - }); - return _oculusPlatformPlugin; - } - -private: - OculusPlatformPluginPointer _oculusPlatformPlugin; -}; - -#include "OculusPlatformProvider.moc" diff --git a/plugins/oculusPlatform/src/plugin.json b/plugins/oculusPlatform/src/plugin.json deleted file mode 100644 index 8799a7245a..0000000000 --- a/plugins/oculusPlatform/src/plugin.json +++ /dev/null @@ -1 +0,0 @@ -{"name":"Oculus Platform"}