From 166a419e900f0a07afccae6a325b1b3f290b068f Mon Sep 17 00:00:00 2001 From: Brad Davis Date: Mon, 7 Mar 2016 21:13:15 -0800 Subject: [PATCH] Oculus update --- plugins/oculus/CMakeLists.txt | 2 +- .../oculus/src/OculusBaseDisplayPlugin.cpp | 37 +----------- plugins/oculus/src/OculusHelpers.cpp | 56 +++++++++++++++++++ plugins/oculus/src/OculusHelpers.h | 18 ++++++ plugins/oculus/src/OculusProvider.cpp | 20 ++++++- 5 files changed, 97 insertions(+), 36 deletions(-) diff --git a/plugins/oculus/CMakeLists.txt b/plugins/oculus/CMakeLists.txt index 5928224bad..4b2927e0fa 100644 --- a/plugins/oculus/CMakeLists.txt +++ b/plugins/oculus/CMakeLists.txt @@ -13,7 +13,7 @@ if (WIN32) set(TARGET_NAME oculus) setup_hifi_plugin() - link_hifi_libraries(shared gl plugins gpu display-plugins input-plugins) + link_hifi_libraries(shared gl gpu controllers plugins display-plugins input-plugins) include_hifi_library_headers(octree) diff --git a/plugins/oculus/src/OculusBaseDisplayPlugin.cpp b/plugins/oculus/src/OculusBaseDisplayPlugin.cpp index 11db3d5149..6e3d38f1aa 100644 --- a/plugins/oculus/src/OculusBaseDisplayPlugin.cpp +++ b/plugins/oculus/src/OculusBaseDisplayPlugin.cpp @@ -26,31 +26,7 @@ glm::mat4 OculusBaseDisplayPlugin::getHeadPose(uint32_t frameIndex) const { } bool OculusBaseDisplayPlugin::isSupported() const { - if (!OVR_SUCCESS(ovr_Initialize(nullptr))) { - qDebug() << "OculusBaseDisplayPlugin : ovr_Initialize() failed"; - return false; - } - - ovrSession session { nullptr }; - ovrGraphicsLuid luid; - auto result = ovr_Create(&session, &luid); - if (!OVR_SUCCESS(result)) { - ovrErrorInfo error; - ovr_GetLastErrorInfo(&error); - qDebug() << "OculusBaseDisplayPlugin : ovr_Create() failed" << result << error.Result << error.ErrorString; - ovr_Shutdown(); - return false; - } - - auto hmdDesc = ovr_GetHmdDesc(session); - if (hmdDesc.Type == ovrHmd_None) { - ovr_Destroy(session); - ovr_Shutdown(); - return false; - } - - ovr_Shutdown(); - return true; + return oculusAvailable(); } // DLL based display plugins MUST initialize GLEW inside the DLL code. @@ -68,13 +44,7 @@ void OculusBaseDisplayPlugin::deinit() { } void OculusBaseDisplayPlugin::activate() { - if (!OVR_SUCCESS(ovr_Initialize(nullptr))) { - qFatal("Could not init OVR"); - } - - if (!OVR_SUCCESS(ovr_Create(&_session, &_luid))) { - qFatal("Failed to acquire HMD"); - } + _session = acquireOculusSession(); _hmdDesc = ovr_GetHmdDesc(_session); @@ -130,7 +100,6 @@ void OculusBaseDisplayPlugin::activate() { void OculusBaseDisplayPlugin::deactivate() { HmdDisplayPlugin::deactivate(); - ovr_Destroy(_session); + releaseOculusSession(); _session = nullptr; - ovr_Shutdown(); } diff --git a/plugins/oculus/src/OculusHelpers.cpp b/plugins/oculus/src/OculusHelpers.cpp index c901c65f4f..db65c72aac 100644 --- a/plugins/oculus/src/OculusHelpers.cpp +++ b/plugins/oculus/src/OculusHelpers.cpp @@ -8,6 +8,62 @@ #include "OculusHelpers.h" +#include +#include +using Mutex = std::mutex; +using Lock = std::unique_lock; + + +Q_DECLARE_LOGGING_CATEGORY(oculus) +Q_LOGGING_CATEGORY(oculus, "hifi.plugins.oculus") + +static std::atomic refCount { 0 }; +static ovrSession session { nullptr }; + +bool oculusAvailable() { + ovrDetectResult detect = ovr_Detect(0); + return (detect.IsOculusServiceRunning && detect.IsOculusHMDConnected); +} + +ovrSession acquireOculusSession() { + if (!session && !oculusAvailable()) { + qCDebug(oculus) << "oculus: no runtime or HMD present"; + return session; + } + + if (!session) { + ovrInitParams init = {}; + init.Flags = 0; + init.ConnectionTimeoutMS = 0; + init.LogCallback = nullptr; + if (!OVR_SUCCESS(ovr_Initialize(nullptr))) { + qCWarning(oculus) << "Failed to initialize Oculus SDK"; + return session; + } + + Q_ASSERT(0 == refCount); + ovrGraphicsLuid luid; + if (!OVR_SUCCESS(ovr_Create(&session, &luid))) { + qCWarning(oculus) << "Failed to acquire Oculus session"; + return session; + } + } + + ++refCount; + return session; +} + +void releaseOculusSession() { + Q_ASSERT(refCount > 0 && session); + if (!--refCount) { + qCDebug(oculus) << "oculus: zero refcount, shutdown SDK and session"; + ovr_Destroy(session); + ovr_Shutdown(); + session = nullptr; + } +} + + // A wrapper for constructing and using a swap texture set, // where each frame you draw to a texture via the FBO, // then submit it and increment to the next texture. diff --git a/plugins/oculus/src/OculusHelpers.h b/plugins/oculus/src/OculusHelpers.h index 7189de5324..cd527b184b 100644 --- a/plugins/oculus/src/OculusHelpers.h +++ b/plugins/oculus/src/OculusHelpers.h @@ -14,6 +14,10 @@ #include +bool oculusAvailable(); +ovrSession acquireOculusSession(); +void releaseOculusSession(); + // Convenience method for looping over each eye with a lambda template inline void ovr_for_each_eye(Function function) { @@ -24,6 +28,19 @@ inline void ovr_for_each_eye(Function function) { } } +template +inline void ovr_for_each_hand(Function function) { + for (ovrHandType hand = ovrHandType::ovrHand_Left; + hand <= ovrHandType::ovrHand_Right; + hand = static_cast(hand + 1)) { + function(hand); + } +} + + + + + inline glm::mat4 toGlm(const ovrMatrix4f & om) { return glm::transpose(glm::make_mat4(&om.M[0][0])); } @@ -86,6 +103,7 @@ inline ovrPosef ovrPoseFromGlm(const glm::mat4 & m) { return result; } + // A wrapper for constructing and using a swap texture set, // where each frame you draw to a texture via the FBO, // then submit it and increment to the next texture. diff --git a/plugins/oculus/src/OculusProvider.cpp b/plugins/oculus/src/OculusProvider.cpp index 40dfb9df9a..be708db932 100644 --- a/plugins/oculus/src/OculusProvider.cpp +++ b/plugins/oculus/src/OculusProvider.cpp @@ -14,15 +14,18 @@ #include #include +#include #include "OculusDisplayPlugin.h" #include "OculusDebugDisplayPlugin.h" -class OculusProvider : public QObject, public DisplayProvider +class OculusProvider : public QObject, public DisplayProvider, InputProvider { 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) public: OculusProvider(QObject* parent = nullptr) : QObject(parent) {} @@ -47,8 +50,23 @@ public: return _displayPlugins; } + virtual InputPluginList getInputPlugins() override { + // FIXME pending full oculus input API and hardware +#if 0 + static std::once_flag once; + std::call_once(once, [&] { + InputPluginPointer plugin(new OculusControllerManager()); + if (plugin->isSupported()) { + _inputPlugins.push_back(plugin); + } + }); +#endif + return _inputPlugins; + } + private: DisplayPluginList _displayPlugins; + InputPluginList _inputPlugins; }; #include "OculusProvider.moc"