diff --git a/CMakeLists.txt b/CMakeLists.txt index efe99b550b..d1c69e4f6b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -203,6 +203,7 @@ if (NOT ANDROID) add_subdirectory(interface) set_target_properties(interface PROPERTIES FOLDER "Apps") add_subdirectory(tests) + add_subdirectory(plugins) add_subdirectory(tools) endif () diff --git a/cmake/externals/glew/CMakeLists.txt b/cmake/externals/glew/CMakeLists.txt index 5f59cc2377..0a4a0abe71 100644 --- a/cmake/externals/glew/CMakeLists.txt +++ b/cmake/externals/glew/CMakeLists.txt @@ -7,14 +7,15 @@ endif () include(ExternalProject) ExternalProject_Add( ${EXTERNAL_NAME} - URL http://hifi-public.s3.amazonaws.com/dependencies/glew_simple.zip - URL_MD5 0507dc08337a82a5e7ecbc5417f92cc1 + URL http://hifi-public.s3.amazonaws.com/dependencies/glew_simple2.zip + URL_MD5 f05d858e8203c32b689da208ad8b39db CONFIGURE_COMMAND CMAKE_ARGS ${ANDROID_CMAKE_ARGS} -DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE} -DCMAKE_INSTALL_PREFIX:PATH= LOG_DOWNLOAD 1 LOG_CONFIGURE 1 LOG_BUILD 1 ) + # Hide this external target (for ide users) set_target_properties(${EXTERNAL_NAME} PROPERTIES FOLDER "hidden/externals") diff --git a/cmake/macros/SetupHifiPlugin.cmake b/cmake/macros/SetupHifiPlugin.cmake new file mode 100644 index 0000000000..0ee94c7816 --- /dev/null +++ b/cmake/macros/SetupHifiPlugin.cmake @@ -0,0 +1,33 @@ +# +# 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 +# +macro(SETUP_HIFI_PLUGIN) + set(${TARGET_NAME}_SHARED 1) + setup_hifi_library(${ARGV}) + add_dependencies(interface ${TARGET_NAME}) + set_target_properties(${TARGET_NAME} PROPERTIES FOLDER "Plugins") + + if (APPLE) + set(PLUGIN_PATH "interface.app/Contents/MacOS/plugins") + else() + set(PLUGIN_PATH "plugins") + endif() + + # create the destination for the plugin binaries + add_custom_command( + TARGET ${TARGET_NAME} POST_BUILD + COMMAND "${CMAKE_COMMAND}" -E make_directory + "${CMAKE_BINARY_DIR}/interface/$/${PLUGIN_PATH}/" + ) + + add_custom_command(TARGET ${DIR} POST_BUILD + COMMAND "${CMAKE_COMMAND}" -E copy + "$" + "${CMAKE_BINARY_DIR}/interface/$/${PLUGIN_PATH}/" + ) + +endmacro() \ No newline at end of file diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index dc2eee000d..653f9cf906 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -392,7 +392,6 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer) : _entityClipboard->createRootElement(); _pluginContainer = new PluginContainerProxy(); - Plugin::setContainer(_pluginContainer); #ifdef Q_OS_WIN installNativeEventFilter(&MyNativeEventFilter::getInstance()); #endif diff --git a/interface/src/PluginContainerProxy.cpp b/interface/src/PluginContainerProxy.cpp index 079d6d0bea..2e5c883897 100644 --- a/interface/src/PluginContainerProxy.cpp +++ b/interface/src/PluginContainerProxy.cpp @@ -13,7 +13,6 @@ #include "ui/DialogsManager.h" PluginContainerProxy::PluginContainerProxy() { - Plugin::setContainer(this); } PluginContainerProxy::~PluginContainerProxy() { diff --git a/libraries/display-plugins/CMakeLists.txt b/libraries/display-plugins/CMakeLists.txt index 14aa03de44..fad244fa5f 100644 --- a/libraries/display-plugins/CMakeLists.txt +++ b/libraries/display-plugins/CMakeLists.txt @@ -1,6 +1,6 @@ set(TARGET_NAME display-plugins) setup_hifi_library(OpenGL) -link_hifi_libraries(shared plugins gpu gl) +link_hifi_libraries(shared plugins gl) target_opengl() @@ -8,11 +8,6 @@ GroupSources("src/display-plugins") target_oglplus() -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}) - if (WIN32) add_dependency_external_projects(OpenVR) find_package(OpenVR REQUIRED) diff --git a/libraries/display-plugins/src/display-plugins/AbstractHMDScriptingInterface.cpp b/libraries/display-plugins/src/display-plugins/AbstractHMDScriptingInterface.cpp index 9987ae345c..4b8d957e5f 100644 --- a/libraries/display-plugins/src/display-plugins/AbstractHMDScriptingInterface.cpp +++ b/libraries/display-plugins/src/display-plugins/AbstractHMDScriptingInterface.cpp @@ -12,7 +12,6 @@ #include "DisplayPlugin.h" #include -#include static Setting::Handle IPD_SCALE_HANDLE("hmd.ipdScale", 1.0f); @@ -26,12 +25,12 @@ float AbstractHMDScriptingInterface::getIPD() const { float AbstractHMDScriptingInterface::getEyeHeight() const { // FIXME update the display plugin interface to expose per-plugin settings - return OVR_DEFAULT_EYE_HEIGHT; + return getPlayerHeight() - 0.10f; } float AbstractHMDScriptingInterface::getPlayerHeight() const { // FIXME update the display plugin interface to expose per-plugin settings - return OVR_DEFAULT_PLAYER_HEIGHT; + return 1.755f; } float AbstractHMDScriptingInterface::getIPDScale() const { diff --git a/libraries/display-plugins/src/display-plugins/Basic2DWindowOpenGLDisplayPlugin.cpp b/libraries/display-plugins/src/display-plugins/Basic2DWindowOpenGLDisplayPlugin.cpp index 914d30d58a..9366ec4403 100644 --- a/libraries/display-plugins/src/display-plugins/Basic2DWindowOpenGLDisplayPlugin.cpp +++ b/libraries/display-plugins/src/display-plugins/Basic2DWindowOpenGLDisplayPlugin.cpp @@ -35,36 +35,36 @@ QAction* _vsyncAction{ nullptr }; void Basic2DWindowOpenGLDisplayPlugin::activate() { _framerateActions.clear(); - CONTAINER->addMenuItem(MENU_PATH(), FULLSCREEN, + _container->addMenuItem(MENU_PATH(), FULLSCREEN, [this](bool clicked) { if (clicked) { - CONTAINER->setFullscreen(getFullscreenTarget()); + _container->setFullscreen(getFullscreenTarget()); } else { - CONTAINER->unsetFullscreen(); + _container->unsetFullscreen(); } }, true, false); - CONTAINER->addMenu(FRAMERATE); + _container->addMenu(FRAMERATE); _framerateActions.push_back( - CONTAINER->addMenuItem(FRAMERATE, FRAMERATE_UNLIMITED, + _container->addMenuItem(FRAMERATE, FRAMERATE_UNLIMITED, [this](bool) { updateFramerate(); }, true, true, FRAMERATE)); _framerateActions.push_back( - CONTAINER->addMenuItem(FRAMERATE, FRAMERATE_60, + _container->addMenuItem(FRAMERATE, FRAMERATE_60, [this](bool) { updateFramerate(); }, true, false, FRAMERATE)); _framerateActions.push_back( - CONTAINER->addMenuItem(FRAMERATE, FRAMERATE_50, + _container->addMenuItem(FRAMERATE, FRAMERATE_50, [this](bool) { updateFramerate(); }, true, false, FRAMERATE)); _framerateActions.push_back( - CONTAINER->addMenuItem(FRAMERATE, FRAMERATE_40, + _container->addMenuItem(FRAMERATE, FRAMERATE_40, [this](bool) { updateFramerate(); }, true, false, FRAMERATE)); _framerateActions.push_back( - CONTAINER->addMenuItem(FRAMERATE, FRAMERATE_30, + _container->addMenuItem(FRAMERATE, FRAMERATE_30, [this](bool) { updateFramerate(); }, true, false, FRAMERATE)); WindowOpenGLDisplayPlugin::activate(); // Vsync detection happens in the parent class activate, so we need to check after that if (_vsyncSupported) { - _vsyncAction = CONTAINER->addMenuItem(MENU_PATH(), VSYNC_ON, [this](bool) {}, true, true); + _vsyncAction = _container->addMenuItem(MENU_PATH(), VSYNC_ON, [this](bool) {}, true, true); } else { _vsyncAction = nullptr; } @@ -107,7 +107,7 @@ int Basic2DWindowOpenGLDisplayPlugin::getDesiredInterval() const { bool Basic2DWindowOpenGLDisplayPlugin::isThrottled() const { static const QString ThrottleFPSIfNotFocus = "Throttle FPS If Not Focus"; // FIXME - this value duplicated in Menu.h - bool shouldThrottle = (!CONTAINER->isForeground() && CONTAINER->isOptionChecked(ThrottleFPSIfNotFocus)); + bool shouldThrottle = (!_container->isForeground() && _container->isOptionChecked(ThrottleFPSIfNotFocus)); if (_isThrottled != shouldThrottle) { _isThrottled = shouldThrottle; diff --git a/libraries/display-plugins/src/display-plugins/DisplayPlugin.cpp b/libraries/display-plugins/src/display-plugins/DisplayPlugin.cpp index 4af45d299b..8155d69826 100644 --- a/libraries/display-plugins/src/display-plugins/DisplayPlugin.cpp +++ b/libraries/display-plugins/src/display-plugins/DisplayPlugin.cpp @@ -15,9 +15,6 @@ #include "Basic2DWindowOpenGLDisplayPlugin.h" #include "openvr/OpenVrDisplayPlugin.h" -#include "oculus/OculusDisplayPlugin.h" -#include "oculus/OculusDebugDisplayPlugin.h" -#include "oculus/OculusLegacyDisplayPlugin.h" const QString& DisplayPlugin::MENU_PATH() { static const QString value = "Display"; @@ -40,15 +37,6 @@ DisplayPluginList getDisplayPlugins() { new InterleavedStereoDisplayPlugin(), // HMDs - - // Windows Oculus SDK - new OculusDisplayPlugin(), - // Windows Oculus Simulator... uses head tracking and the same rendering - // as the connected hardware, but without using the SDK to display to the - // Rift. Useful for debugging Rift performance with nSight. - new OculusDebugDisplayPlugin(), - // Mac/Linux Oculus SDK (0.5) - new OculusLegacyDisplayPlugin(), #ifdef Q_OS_WIN // SteamVR SDK new OpenVrDisplayPlugin(), diff --git a/libraries/display-plugins/src/display-plugins/DisplayPlugin.h b/libraries/display-plugins/src/display-plugins/DisplayPlugin.h index b2176e0bd1..84c6592c53 100644 --- a/libraries/display-plugins/src/display-plugins/DisplayPlugin.h +++ b/libraries/display-plugins/src/display-plugins/DisplayPlugin.h @@ -5,135 +5,6 @@ // 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 "plugins/Plugin.h" -#include -#include -#include - -#include -#include - -#include -#include -#include - -enum Eye { - Left, - Right, - Mono -}; - -/* - * Helper method to iterate over each eye - */ -template -void for_each_eye(F f) { - f(Left); - f(Right); -} - -/* - * Helper method to iterate over each eye, with an additional lambda to take action between the eyes - */ -template -void for_each_eye(F f, FF ff) { - f(Eye::Left); - ff(); - f(Eye::Right); -} - -class QWindow; - -#define AVERAGE_HUMAN_IPD 0.064f - -class DisplayPlugin : public Plugin { - Q_OBJECT -public: - virtual bool isHmd() const { return false; } - virtual int getHmdScreen() const { return -1; } - /// By default, all HMDs are stereo - virtual bool isStereo() const { return isHmd(); } - virtual bool isThrottled() const { return false; } - - // Rendering support - - // Stop requesting renders, but don't do full deactivation - // needed to work around the issues caused by Oculus - // processing messages in the middle of submitFrame - virtual void stop() = 0; - - /** - * Called by the application before the frame rendering. Can be used for - * render timing related calls (for instance, the Oculus begin frame timing - * call) - */ - virtual void preRender() = 0; - /** - * Called by the application immediately before calling the display function. - * For OpenGL based plugins, this is the best place to put activate the output - * OpenGL context - */ - virtual void preDisplay() = 0; - - /** - * Sends the scene texture to the display plugin. - */ - virtual void display(GLuint sceneTexture, const glm::uvec2& sceneSize) = 0; - - /** - * Called by the application immeidately after display. For OpenGL based - * displays, this is the best place to put the buffer swap - */ - virtual void finishFrame() = 0; - - // Does the rendering surface have current focus? - virtual bool hasFocus() const = 0; - - // The size of the rendering target (may be larger than the device size due to distortion) - virtual glm::uvec2 getRecommendedRenderSize() const = 0; - - // The size of the UI - virtual glm::uvec2 getRecommendedUiSize() const { - return getRecommendedRenderSize(); - } - - // By default the aspect ratio is just the render size - virtual float getRecommendedAspectRatio() const { - return aspect(getRecommendedRenderSize()); - } - - // Stereo specific methods - virtual glm::mat4 getProjection(Eye eye, const glm::mat4& baseProjection) const { - return baseProjection; - } - - // HMD specific methods - // TODO move these into another class? - virtual glm::mat4 getEyeToHeadTransform(Eye eye) const { - static const glm::mat4 transform; return transform; - } - - virtual glm::mat4 getHeadPose() const { - static const glm::mat4 pose; return pose; - } - - // Needed for timewarp style features - virtual void setEyeRenderPose(Eye eye, const glm::mat4& pose) { - // NOOP - } - - virtual float getIPD() const { return AVERAGE_HUMAN_IPD; } - - virtual void abandonCalibration() {} - virtual void resetSensors() {} - virtual float devicePixelRatio() { return 1.0; } - - - static const QString& MENU_PATH(); -signals: - void recommendedFramebufferSizeChanged(const QSize & size); - void requestRender(); -}; +#include diff --git a/libraries/display-plugins/src/display-plugins/NullDisplayPlugin.cpp b/libraries/display-plugins/src/display-plugins/NullDisplayPlugin.cpp index 914f80d983..ce512962ff 100644 --- a/libraries/display-plugins/src/display-plugins/NullDisplayPlugin.cpp +++ b/libraries/display-plugins/src/display-plugins/NullDisplayPlugin.cpp @@ -25,6 +25,6 @@ bool NullDisplayPlugin::hasFocus() const { void NullDisplayPlugin::preRender() {} void NullDisplayPlugin::preDisplay() {} -void NullDisplayPlugin::display(GLuint sceneTexture, const glm::uvec2& sceneSize) {} +void NullDisplayPlugin::display(uint32_t sceneTexture, const glm::uvec2& sceneSize) {} void NullDisplayPlugin::finishFrame() {} void NullDisplayPlugin::stop() {} diff --git a/libraries/display-plugins/src/display-plugins/NullDisplayPlugin.h b/libraries/display-plugins/src/display-plugins/NullDisplayPlugin.h index 4f2cc77b8f..8cd5c2bc37 100644 --- a/libraries/display-plugins/src/display-plugins/NullDisplayPlugin.h +++ b/libraries/display-plugins/src/display-plugins/NullDisplayPlugin.h @@ -21,7 +21,7 @@ public: virtual bool hasFocus() const override; virtual void preRender() override; virtual void preDisplay() override; - virtual void display(GLuint sceneTexture, const glm::uvec2& sceneSize) override; + virtual void display(uint32_t sceneTexture, const glm::uvec2& sceneSize) override; virtual void finishFrame() override; private: diff --git a/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.cpp b/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.cpp index 3791375c9e..3ef882fe76 100644 --- a/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.cpp +++ b/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.cpp @@ -9,6 +9,7 @@ #include #include +#include #include #include diff --git a/libraries/display-plugins/src/display-plugins/WindowOpenGLDisplayPlugin.cpp b/libraries/display-plugins/src/display-plugins/WindowOpenGLDisplayPlugin.cpp index ffea6605af..6ddc791503 100644 --- a/libraries/display-plugins/src/display-plugins/WindowOpenGLDisplayPlugin.cpp +++ b/libraries/display-plugins/src/display-plugins/WindowOpenGLDisplayPlugin.cpp @@ -42,7 +42,7 @@ bool WindowOpenGLDisplayPlugin::hasFocus() const { void WindowOpenGLDisplayPlugin::activate() { OpenGLDisplayPlugin::activate(); - _window = CONTAINER->getPrimarySurface(); + _window = _container->getPrimarySurface(); _window->makeCurrent(); customizeContext(); _window->doneCurrent(); diff --git a/libraries/display-plugins/src/display-plugins/openvr/OpenVrDisplayPlugin.cpp b/libraries/display-plugins/src/display-plugins/openvr/OpenVrDisplayPlugin.cpp index 245fd11ef7..174bf1bf36 100644 --- a/libraries/display-plugins/src/display-plugins/openvr/OpenVrDisplayPlugin.cpp +++ b/libraries/display-plugins/src/display-plugins/openvr/OpenVrDisplayPlugin.cpp @@ -89,7 +89,7 @@ bool OpenVrDisplayPlugin::isSupported() const { } void OpenVrDisplayPlugin::activate() { - CONTAINER->setIsOptionChecked(StandingHMDSensorMode, true); + _container->setIsOptionChecked(StandingHMDSensorMode, true); hmdRefCount++; vr::HmdError eError = vr::HmdError_None; @@ -132,7 +132,7 @@ void OpenVrDisplayPlugin::activate() { } void OpenVrDisplayPlugin::deactivate() { - CONTAINER->setIsOptionChecked(StandingHMDSensorMode, false); + _container->setIsOptionChecked(StandingHMDSensorMode, false); hmdRefCount--; diff --git a/libraries/display-plugins/src/display-plugins/stereo/StereoDisplayPlugin.cpp b/libraries/display-plugins/src/display-plugins/stereo/StereoDisplayPlugin.cpp index 4f7b0a1a78..f7e71313df 100644 --- a/libraries/display-plugins/src/display-plugins/stereo/StereoDisplayPlugin.cpp +++ b/libraries/display-plugins/src/display-plugins/stereo/StereoDisplayPlugin.cpp @@ -74,21 +74,21 @@ void StereoDisplayPlugin::activate() { if (screen == qApp->primaryScreen()) { checked = true; } - auto action = CONTAINER->addMenuItem(MENU_PATH(), name, + auto action = _container->addMenuItem(MENU_PATH(), name, [this](bool clicked) { updateScreen(); }, true, checked, "Screens"); _screenActions[i] = action; } - CONTAINER->removeMenu(FRAMERATE); + _container->removeMenu(FRAMERATE); - CONTAINER->setFullscreen(qApp->primaryScreen()); + _container->setFullscreen(qApp->primaryScreen()); WindowOpenGLDisplayPlugin::activate(); } void StereoDisplayPlugin::updateScreen() { for (uint32_t i = 0; i < _screenActions.size(); ++i) { if (_screenActions[i]->isChecked()) { - CONTAINER->setFullscreen(qApp->screens().at(i)); + _container->setFullscreen(qApp->screens().at(i)); break; } } @@ -96,7 +96,7 @@ void StereoDisplayPlugin::updateScreen() { void StereoDisplayPlugin::deactivate() { _screenActions.clear(); - CONTAINER->unsetFullscreen(); + _container->unsetFullscreen(); WindowOpenGLDisplayPlugin::deactivate(); } diff --git a/libraries/input-plugins/src/input-plugins/InputPlugin.h b/libraries/input-plugins/src/input-plugins/InputPlugin.h index 787922e04c..d03f884ec7 100644 --- a/libraries/input-plugins/src/input-plugins/InputPlugin.h +++ b/libraries/input-plugins/src/input-plugins/InputPlugin.h @@ -10,14 +10,4 @@ // #pragma once -#include - -class InputPlugin : public Plugin { -public: - virtual bool isJointController() const = 0; - - virtual void pluginFocusOutEvent() = 0; - - virtual void pluginUpdate(float deltaTime, bool jointsCaptured) = 0; -}; - +#include diff --git a/libraries/input-plugins/src/input-plugins/SixenseManager.cpp b/libraries/input-plugins/src/input-plugins/SixenseManager.cpp index 5e0f3277b1..024eb86182 100644 --- a/libraries/input-plugins/src/input-plugins/SixenseManager.cpp +++ b/libraries/input-plugins/src/input-plugins/SixenseManager.cpp @@ -94,8 +94,8 @@ void SixenseManager::activate() { _calibrationState = CALIBRATION_STATE_IDLE; _avatarPosition = DEFAULT_AVATAR_POSITION; - CONTAINER->addMenu(MENU_PATH); - CONTAINER->addMenuItem(MENU_PATH, TOGGLE_SMOOTH, + _container->addMenu(MENU_PATH); + _container->addMenuItem(MENU_PATH, TOGGLE_SMOOTH, [this] (bool clicked) { this->setSixenseFilter(clicked); }, true, true); @@ -136,8 +136,8 @@ void SixenseManager::deactivate() { InputPlugin::deactivate(); #ifdef HAVE_SIXENSE - CONTAINER->removeMenuItem(MENU_NAME, TOGGLE_SMOOTH); - CONTAINER->removeMenu(MENU_PATH); + _container->removeMenuItem(MENU_NAME, TOGGLE_SMOOTH); + _container->removeMenu(MENU_PATH); _poseStateMap.clear(); _collectedSamples.clear(); @@ -319,7 +319,7 @@ void SixenseManager::updateCalibration(void* controllersX) { _avatarRotation = glm::inverse(glm::quat_cast(glm::mat3(xAxis, Vectors::UNIT_Y, zAxis))); const float Y_OFFSET_CALIBRATED_HANDS_TO_AVATAR = -0.3f; _avatarPosition.y += Y_OFFSET_CALIBRATED_HANDS_TO_AVATAR; - CONTAINER->requestReset(); + _container->requestReset(); qCDebug(inputplugins, "succeess: sixense calibration"); } break; diff --git a/libraries/input-plugins/src/input-plugins/ViveControllerManager.cpp b/libraries/input-plugins/src/input-plugins/ViveControllerManager.cpp index e90006e014..69b2b5b2c6 100644 --- a/libraries/input-plugins/src/input-plugins/ViveControllerManager.cpp +++ b/libraries/input-plugins/src/input-plugins/ViveControllerManager.cpp @@ -75,8 +75,8 @@ bool ViveControllerManager::isSupported() const { void ViveControllerManager::activate() { InputPlugin::activate(); #ifdef Q_OS_WIN - CONTAINER->addMenu(MENU_PATH); - CONTAINER->addMenuItem(MENU_PATH, RENDER_CONTROLLERS, + _container->addMenu(MENU_PATH); + _container->addMenuItem(MENU_PATH, RENDER_CONTROLLERS, [this] (bool clicked) { this->setRenderControllers(clicked); }, true, true); @@ -146,8 +146,8 @@ void ViveControllerManager::deactivate() { InputPlugin::deactivate(); #ifdef Q_OS_WIN - CONTAINER->removeMenuItem(MENU_NAME, RENDER_CONTROLLERS); - CONTAINER->removeMenu(MENU_PATH); + _container->removeMenuItem(MENU_NAME, RENDER_CONTROLLERS); + _container->removeMenu(MENU_PATH); hmdRefCount--; diff --git a/libraries/plugins/src/plugins/DisplayPlugin.h b/libraries/plugins/src/plugins/DisplayPlugin.h new file mode 100644 index 0000000000..5b00391f09 --- /dev/null +++ b/libraries/plugins/src/plugins/DisplayPlugin.h @@ -0,0 +1,140 @@ +// +// Created by Bradley Austin Davis on 2015/05/29 +// 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 +#include + +#include "Plugin.h" + +enum Eye { + Left, + Right, + Mono +}; + +/* + * Helper method to iterate over each eye + */ +template +void for_each_eye(F f) { + f(Left); + f(Right); +} + +/* + * Helper method to iterate over each eye, with an additional lambda to take action between the eyes + */ +template +void for_each_eye(F f, FF ff) { + f(Eye::Left); + ff(); + f(Eye::Right); +} + +class QWindow; + +#define AVERAGE_HUMAN_IPD 0.064f + +class DisplayPlugin : public Plugin { + Q_OBJECT +public: + virtual bool isHmd() const { return false; } + virtual int getHmdScreen() const { return -1; } + /// By default, all HMDs are stereo + virtual bool isStereo() const { return isHmd(); } + virtual bool isThrottled() const { return false; } + + // Rendering support + + // Stop requesting renders, but don't do full deactivation + // needed to work around the issues caused by Oculus + // processing messages in the middle of submitFrame + virtual void stop() = 0; + + /** + * Called by the application before the frame rendering. Can be used for + * render timing related calls (for instance, the Oculus begin frame timing + * call) + */ + virtual void preRender() = 0; + /** + * Called by the application immediately before calling the display function. + * For OpenGL based plugins, this is the best place to put activate the output + * OpenGL context + */ + virtual void preDisplay() = 0; + + /** + * Sends the scene texture to the display plugin. + */ + virtual void display(uint32_t sceneTexture, const glm::uvec2& sceneSize) = 0; + + /** + * Called by the application immeidately after display. For OpenGL based + * displays, this is the best place to put the buffer swap + */ + virtual void finishFrame() = 0; + + // Does the rendering surface have current focus? + virtual bool hasFocus() const = 0; + + // The size of the rendering target (may be larger than the device size due to distortion) + virtual glm::uvec2 getRecommendedRenderSize() const = 0; + + // The size of the UI + virtual glm::uvec2 getRecommendedUiSize() const { + return getRecommendedRenderSize(); + } + + // By default the aspect ratio is just the render size + virtual float getRecommendedAspectRatio() const { + return aspect(getRecommendedRenderSize()); + } + + // Stereo specific methods + virtual glm::mat4 getProjection(Eye eye, const glm::mat4& baseProjection) const { + return baseProjection; + } + + // HMD specific methods + // TODO move these into another class? + virtual glm::mat4 getEyeToHeadTransform(Eye eye) const { + static const glm::mat4 transform; return transform; + } + + virtual glm::mat4 getHeadPose() const { + static const glm::mat4 pose; return pose; + } + + // Needed for timewarp style features + virtual void setEyeRenderPose(Eye eye, const glm::mat4& pose) { + // NOOP + } + + virtual float getIPD() const { return AVERAGE_HUMAN_IPD; } + + virtual void abandonCalibration() {} + virtual void resetSensors() {} + virtual float devicePixelRatio() { return 1.0; } + + + static const QString& MENU_PATH(); +signals: + void recommendedFramebufferSizeChanged(const QSize & size); + void requestRender(); +}; + diff --git a/libraries/plugins/src/plugins/Forward.h b/libraries/plugins/src/plugins/Forward.h index 1a9298d13c..78ec8fdcb3 100644 --- a/libraries/plugins/src/plugins/Forward.h +++ b/libraries/plugins/src/plugins/Forward.h @@ -21,3 +21,4 @@ using DisplayPluginPointer = QSharedPointer; using DisplayPluginList = QVector; using InputPluginPointer = QSharedPointer; using InputPluginList = QVector; + diff --git a/libraries/plugins/src/plugins/InputPlugin.h b/libraries/plugins/src/plugins/InputPlugin.h new file mode 100644 index 0000000000..e9d8ac8d86 --- /dev/null +++ b/libraries/plugins/src/plugins/InputPlugin.h @@ -0,0 +1,23 @@ +// +// InputPlugin.h +// input-plugins/src/input-plugins +// +// Created by Sam Gondelman on 7/13/2015 +// 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 "Plugin.h" + +class InputPlugin : public Plugin { +public: + virtual bool isJointController() const = 0; + + virtual void pluginFocusOutEvent() = 0; + + virtual void pluginUpdate(float deltaTime, bool jointsCaptured) = 0; +}; + diff --git a/libraries/plugins/src/plugins/Plugin.cpp b/libraries/plugins/src/plugins/Plugin.cpp index 2c0b9fa5cf..7c30f252c9 100644 --- a/libraries/plugins/src/plugins/Plugin.cpp +++ b/libraries/plugins/src/plugins/Plugin.cpp @@ -7,12 +7,10 @@ // #include "Plugin.h" -PluginContainer* Plugin::CONTAINER{ nullptr }; - QString Plugin::UNKNOWN_PLUGIN_ID("unknown"); void Plugin::setContainer(PluginContainer* container) { - CONTAINER = container; + _container = container; } bool Plugin::isSupported() const { return true; } diff --git a/libraries/plugins/src/plugins/Plugin.h b/libraries/plugins/src/plugins/Plugin.h index f53d309e97..c030b1073f 100644 --- a/libraries/plugins/src/plugins/Plugin.h +++ b/libraries/plugins/src/plugins/Plugin.h @@ -24,7 +24,7 @@ public: virtual bool isSupported() const; - static void setContainer(PluginContainer* container); + void setContainer(PluginContainer* container); /// Called when plugin is initially loaded, typically at application start virtual void init(); @@ -57,8 +57,8 @@ public: virtual void loadSettings() {} protected: - bool _active{ false }; - static PluginContainer* CONTAINER; + bool _active { false }; + PluginContainer* _container { nullptr }; static QString UNKNOWN_PLUGIN_ID; }; diff --git a/libraries/plugins/src/plugins/PluginManager.cpp b/libraries/plugins/src/plugins/PluginManager.cpp index 2deb41fb13..27e326fcba 100644 --- a/libraries/plugins/src/plugins/PluginManager.cpp +++ b/libraries/plugins/src/plugins/PluginManager.cpp @@ -6,15 +6,54 @@ // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // #include "PluginManager.h" + #include -#include "Forward.h" +#include +#include +#include +#include + +#include "RuntimePlugin.h" +#include "DisplayPlugin.h" +#include "InputPlugin.h" +#include "PluginContainer.h" + PluginManager* PluginManager::getInstance() { static PluginManager _manager; return &_manager; } +using Loader = QSharedPointer; +using LoaderList = QList; + +const LoaderList& getLoadedPlugins() { + static std::once_flag once; + static LoaderList loadedPlugins; + std::call_once(once, [&] { + QString pluginPath = QCoreApplication::applicationDirPath() + "/plugins/"; + QDir pluginDir(pluginPath); + pluginDir.setFilter(QDir::Files); + if (pluginDir.exists()) { + qDebug() << "Loading runtime plugins from " << pluginPath; + auto candidates = pluginDir.entryList(); + for (auto plugin : candidates) { + qDebug() << "Attempting plugins " << plugin; + QSharedPointer loader(new QPluginLoader(pluginPath + plugin)); + if (loader->load()) { + qDebug() << "Plugins " << plugin << " success"; + loadedPlugins.push_back(loader); + } + } + } + }); + return loadedPlugins; +} + +PluginManager::PluginManager() { +} + // TODO migrate to a DLL model where plugins are discovered and loaded at runtime by the PluginManager class extern DisplayPluginList getDisplayPlugins(); extern InputPluginList getInputPlugins(); @@ -23,8 +62,25 @@ extern void saveInputPluginSettings(const InputPluginList& plugins); const DisplayPluginList& PluginManager::getDisplayPlugins() { static DisplayPluginList displayPlugins; static std::once_flag once; + std::call_once(once, [&] { + // Grab the built in plugins displayPlugins = ::getDisplayPlugins(); + + // Now grab the dynamic plugins + for (auto loader : getLoadedPlugins()) { + DisplayProvider* displayProvider = qobject_cast(loader->instance()); + if (displayProvider) { + for (auto displayPlugin : displayProvider->getDisplayPlugins()) { + displayPlugins.push_back(displayPlugin); + } + } + } + auto& container = PluginContainer::getInstance(); + for (auto plugin : displayPlugins) { + plugin->setContainer(&container); + } + }); return displayPlugins; } @@ -34,6 +90,21 @@ const InputPluginList& PluginManager::getInputPlugins() { static std::once_flag once; std::call_once(once, [&] { inputPlugins = ::getInputPlugins(); + + // Now grab the dynamic plugins + for (auto loader : getLoadedPlugins()) { + InputProvider* inputProvider = qobject_cast(loader->instance()); + if (inputProvider) { + for (auto inputPlugin : inputProvider->getInputPlugins()) { + inputPlugins.push_back(inputPlugin); + } + } + } + + auto& container = PluginContainer::getInstance(); + for (auto plugin : inputPlugins) { + plugin->setContainer(&container); + } }); return inputPlugins; } diff --git a/libraries/plugins/src/plugins/PluginManager.h b/libraries/plugins/src/plugins/PluginManager.h index 09dcc9d107..17619a93c0 100644 --- a/libraries/plugins/src/plugins/PluginManager.h +++ b/libraries/plugins/src/plugins/PluginManager.h @@ -12,6 +12,7 @@ class PluginManager : public QObject { public: static PluginManager* getInstance(); + PluginManager(); const DisplayPluginList& getDisplayPlugins(); const InputPluginList& getInputPlugins(); diff --git a/libraries/plugins/src/plugins/RuntimePlugin.h b/libraries/plugins/src/plugins/RuntimePlugin.h new file mode 100644 index 0000000000..d7bf31ea28 --- /dev/null +++ b/libraries/plugins/src/plugins/RuntimePlugin.h @@ -0,0 +1,36 @@ +// +// Created by Bradley Austin Davis on 2015/10/24 +// 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 "Forward.h" + +class DisplayProvider { +public: + virtual ~DisplayProvider() {} + + virtual DisplayPluginList getDisplayPlugins() = 0; +}; + +#define DisplayProvider_iid "com.highfidelity.plugins.display" +Q_DECLARE_INTERFACE(DisplayProvider, DisplayProvider_iid) + + +class InputProvider { +public: + virtual ~InputProvider() {} + virtual InputPluginList getInputPlugins() = 0; +}; + +#define InputProvider_iid "com.highfidelity.plugins.input" +Q_DECLARE_INTERFACE(InputProvider, InputProvider_iid) + diff --git a/plugins/CMakeLists.txt b/plugins/CMakeLists.txt new file mode 100644 index 0000000000..55b18b122c --- /dev/null +++ b/plugins/CMakeLists.txt @@ -0,0 +1,18 @@ +# +# 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 +# + +# add the plugin directories +file(GLOB PLUGIN_SUBDIRS RELATIVE "${CMAKE_CURRENT_SOURCE_DIR}" "${CMAKE_CURRENT_SOURCE_DIR}/*") +list(REMOVE_ITEM PLUGIN_SUBDIRS "CMakeFiles") + +foreach(DIR ${PLUGIN_SUBDIRS}) + if(IS_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/${DIR}") + add_subdirectory(${DIR}) + endif() +endforeach() + diff --git a/plugins/oculus/CMakeLists.txt b/plugins/oculus/CMakeLists.txt new file mode 100644 index 0000000000..62999cbb7e --- /dev/null +++ b/plugins/oculus/CMakeLists.txt @@ -0,0 +1,22 @@ +# +# 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) + + set(TARGET_NAME oculus) + setup_hifi_plugin() + link_hifi_libraries(shared gl plugins display-plugins) + + 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}) + +endif() \ No newline at end of file diff --git a/libraries/display-plugins/src/display-plugins/oculus/OculusBaseDisplayPlugin.cpp b/plugins/oculus/src/OculusBaseDisplayPlugin.cpp similarity index 95% rename from libraries/display-plugins/src/display-plugins/oculus/OculusBaseDisplayPlugin.cpp rename to plugins/oculus/src/OculusBaseDisplayPlugin.cpp index 859a4a810a..4c80b9a51d 100644 --- a/libraries/display-plugins/src/display-plugins/oculus/OculusBaseDisplayPlugin.cpp +++ b/plugins/oculus/src/OculusBaseDisplayPlugin.cpp @@ -61,6 +61,14 @@ bool OculusBaseDisplayPlugin::isSupported() const { #endif } +// DLL based display plugins MUST initialize GLEW inside the DLL code. +void OculusBaseDisplayPlugin::customizeContext() { + glewExperimental = true; + GLenum err = glewInit(); + glGetError(); + WindowOpenGLDisplayPlugin::customizeContext(); +} + void OculusBaseDisplayPlugin::init() { } diff --git a/libraries/display-plugins/src/display-plugins/oculus/OculusBaseDisplayPlugin.h b/plugins/oculus/src/OculusBaseDisplayPlugin.h similarity index 96% rename from libraries/display-plugins/src/display-plugins/oculus/OculusBaseDisplayPlugin.h rename to plugins/oculus/src/OculusBaseDisplayPlugin.h index 6307f6bbf9..ba1924bfff 100644 --- a/libraries/display-plugins/src/display-plugins/oculus/OculusBaseDisplayPlugin.h +++ b/plugins/oculus/src/OculusBaseDisplayPlugin.h @@ -7,7 +7,7 @@ // #pragma once -#include "../WindowOpenGLDisplayPlugin.h" +#include #include @@ -35,6 +35,7 @@ public: virtual float getIPD() const override final; protected: + virtual void customizeContext() override; virtual void preRender() override final; virtual void display(GLuint finalTexture, const glm::uvec2& sceneSize) override; diff --git a/libraries/display-plugins/src/display-plugins/oculus/OculusDebugDisplayPlugin.cpp b/plugins/oculus/src/OculusDebugDisplayPlugin.cpp similarity index 100% rename from libraries/display-plugins/src/display-plugins/oculus/OculusDebugDisplayPlugin.cpp rename to plugins/oculus/src/OculusDebugDisplayPlugin.cpp diff --git a/libraries/display-plugins/src/display-plugins/oculus/OculusDebugDisplayPlugin.h b/plugins/oculus/src/OculusDebugDisplayPlugin.h similarity index 100% rename from libraries/display-plugins/src/display-plugins/oculus/OculusDebugDisplayPlugin.h rename to plugins/oculus/src/OculusDebugDisplayPlugin.h diff --git a/libraries/display-plugins/src/display-plugins/oculus/OculusDisplayPlugin.cpp b/plugins/oculus/src/OculusDisplayPlugin.cpp similarity index 97% rename from libraries/display-plugins/src/display-plugins/oculus/OculusDisplayPlugin.cpp rename to plugins/oculus/src/OculusDisplayPlugin.cpp index 3e2290f104..923b8bde6e 100644 --- a/libraries/display-plugins/src/display-plugins/oculus/OculusDisplayPlugin.cpp +++ b/plugins/oculus/src/OculusDisplayPlugin.cpp @@ -7,11 +7,14 @@ // #include "OculusDisplayPlugin.h" -#include +#include + +// FIXME get rid of this +#include +#include #include "OculusHelpers.h" -#include #if (OVR_MAJOR_VERSION >= 6) @@ -142,16 +145,16 @@ static const QString FRAMERATE = DisplayPlugin::MENU_PATH() + ">Framerate"; void OculusDisplayPlugin::activate() { - CONTAINER->addMenuItem(MENU_PATH(), MONO_PREVIEW, + _container->addMenuItem(MENU_PATH(), MONO_PREVIEW, [this](bool clicked) { _monoPreview = clicked; }, true, true); - CONTAINER->removeMenu(FRAMERATE); + _container->removeMenu(FRAMERATE); OculusBaseDisplayPlugin::activate(); } void OculusDisplayPlugin::customizeContext() { - WindowOpenGLDisplayPlugin::customizeContext(); + OculusBaseDisplayPlugin::customizeContext(); #if (OVR_MAJOR_VERSION >= 6) _sceneFbo = SwapFboPtr(new SwapFramebufferWrapper(_hmd)); _sceneFbo->Init(getRecommendedRenderSize()); diff --git a/libraries/display-plugins/src/display-plugins/oculus/OculusDisplayPlugin.h b/plugins/oculus/src/OculusDisplayPlugin.h similarity index 100% rename from libraries/display-plugins/src/display-plugins/oculus/OculusDisplayPlugin.h rename to plugins/oculus/src/OculusDisplayPlugin.h diff --git a/libraries/display-plugins/src/display-plugins/oculus/OculusHelpers.cpp b/plugins/oculus/src/OculusHelpers.cpp similarity index 100% rename from libraries/display-plugins/src/display-plugins/oculus/OculusHelpers.cpp rename to plugins/oculus/src/OculusHelpers.cpp diff --git a/libraries/display-plugins/src/display-plugins/oculus/OculusHelpers.h b/plugins/oculus/src/OculusHelpers.h similarity index 100% rename from libraries/display-plugins/src/display-plugins/oculus/OculusHelpers.h rename to plugins/oculus/src/OculusHelpers.h diff --git a/plugins/oculus/src/OculusProvider.cpp b/plugins/oculus/src/OculusProvider.cpp new file mode 100644 index 0000000000..40dfb9df9a --- /dev/null +++ b/plugins/oculus/src/OculusProvider.cpp @@ -0,0 +1,54 @@ +// +// 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 +// + +#include + +#include +#include +#include + +#include +#include + +#include "OculusDisplayPlugin.h" +#include "OculusDebugDisplayPlugin.h" + +class OculusProvider : public QObject, public DisplayProvider +{ + Q_OBJECT + Q_PLUGIN_METADATA(IID DisplayProvider_iid FILE "oculus.json") + Q_INTERFACES(DisplayProvider) + +public: + OculusProvider(QObject* parent = nullptr) : QObject(parent) {} + virtual ~OculusProvider() {} + + virtual DisplayPluginList getDisplayPlugins() override { + static std::once_flag once; + std::call_once(once, [&] { + DisplayPluginPointer plugin(new OculusDisplayPlugin()); + if (plugin->isSupported()) { + _displayPlugins.push_back(plugin); + } + + // Windows Oculus Simulator... uses head tracking and the same rendering + // as the connected hardware, but without using the SDK to display to the + // Rift. Useful for debugging Rift performance with nSight. + plugin = DisplayPluginPointer(new OculusDebugDisplayPlugin()); + if (plugin->isSupported()) { + _displayPlugins.push_back(plugin); + } + }); + return _displayPlugins; + } + +private: + DisplayPluginList _displayPlugins; +}; + +#include "OculusProvider.moc" diff --git a/plugins/oculus/src/oculus.json b/plugins/oculus/src/oculus.json new file mode 100644 index 0000000000..0967ef424b --- /dev/null +++ b/plugins/oculus/src/oculus.json @@ -0,0 +1 @@ +{} diff --git a/plugins/oculusLegacy/CMakeLists.txt b/plugins/oculusLegacy/CMakeLists.txt new file mode 100644 index 0000000000..bf9d22410d --- /dev/null +++ b/plugins/oculusLegacy/CMakeLists.txt @@ -0,0 +1,22 @@ +# +# 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 (NOT WIN32) + + set(TARGET_NAME oculusLegacy) + setup_hifi_plugin() + link_hifi_libraries(shared gl plugins display-plugins) + + 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}) + +endif() \ No newline at end of file diff --git a/plugins/oculusLegacy/src/OculusHelpers.cpp b/plugins/oculusLegacy/src/OculusHelpers.cpp new file mode 100644 index 0000000000..fff2a38344 --- /dev/null +++ b/plugins/oculusLegacy/src/OculusHelpers.cpp @@ -0,0 +1,9 @@ +// +// 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" diff --git a/plugins/oculusLegacy/src/OculusHelpers.h b/plugins/oculusLegacy/src/OculusHelpers.h new file mode 100644 index 0000000000..b4bcdc1511 --- /dev/null +++ b/plugins/oculusLegacy/src/OculusHelpers.h @@ -0,0 +1,85 @@ +// +// 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 + +// Convenience method for looping over each eye with a lambda +template +inline void ovr_for_each_eye(Function function) { + for (ovrEyeType eye = ovrEyeType::ovrEye_Left; + eye < ovrEyeType::ovrEye_Count; + eye = static_cast(eye + 1)) { + function(eye); + } +} + +inline glm::mat4 toGlm(const ovrMatrix4f & om) { + return glm::transpose(glm::make_mat4(&om.M[0][0])); +} + +inline glm::mat4 toGlm(const ovrFovPort & fovport, float nearPlane = 0.01f, float farPlane = 10000.0f) { + return toGlm(ovrMatrix4f_Projection(fovport, nearPlane, farPlane, true)); +} + +inline glm::vec3 toGlm(const ovrVector3f & ov) { + return glm::make_vec3(&ov.x); +} + +inline glm::vec2 toGlm(const ovrVector2f & ov) { + return glm::make_vec2(&ov.x); +} + +inline glm::uvec2 toGlm(const ovrSizei & ov) { + return glm::uvec2(ov.w, ov.h); +} + +inline glm::quat toGlm(const ovrQuatf & oq) { + return glm::make_quat(&oq.x); +} + +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; +} + +inline ovrMatrix4f ovrFromGlm(const glm::mat4 & m) { + ovrMatrix4f result; + glm::mat4 transposed(glm::transpose(m)); + memcpy(result.M, &(transposed[0][0]), sizeof(float) * 16); + return result; +} + +inline ovrVector3f ovrFromGlm(const glm::vec3 & v) { + return{ v.x, v.y, v.z }; +} + +inline ovrVector2f ovrFromGlm(const glm::vec2 & v) { + return{ v.x, v.y }; +} + +inline ovrSizei ovrFromGlm(const glm::uvec2 & v) { + return{ (int)v.x, (int)v.y }; +} + +inline ovrQuatf ovrFromGlm(const glm::quat & q) { + return{ q.x, q.y, q.z, q.w }; +} + +inline ovrPosef ovrPoseFromGlm(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 = ovrFromGlm(orientation); + result.Position = ovrFromGlm(translation); + return result; +} diff --git a/libraries/display-plugins/src/display-plugins/oculus/OculusLegacyDisplayPlugin.cpp b/plugins/oculusLegacy/src/OculusLegacyDisplayPlugin.cpp similarity index 90% rename from libraries/display-plugins/src/display-plugins/oculus/OculusLegacyDisplayPlugin.cpp rename to plugins/oculusLegacy/src/OculusLegacyDisplayPlugin.cpp index 205444397f..5a253cdbbf 100644 --- a/libraries/display-plugins/src/display-plugins/oculus/OculusLegacyDisplayPlugin.cpp +++ b/plugins/oculusLegacy/src/OculusLegacyDisplayPlugin.cpp @@ -42,10 +42,8 @@ uvec2 OculusLegacyDisplayPlugin::getRecommendedRenderSize() const { } void OculusLegacyDisplayPlugin::preRender() { -#if (OVR_MAJOR_VERSION == 5) ovrHmd_GetEyePoses(_hmd, _frameIndex, _eyeOffsets, _eyePoses, &_trackingState); ovrHmd_BeginFrame(_hmd, _frameIndex); -#endif WindowOpenGLDisplayPlugin::preRender(); } @@ -54,32 +52,21 @@ glm::mat4 OculusLegacyDisplayPlugin::getProjection(Eye eye, const glm::mat4& bas } void OculusLegacyDisplayPlugin::resetSensors() { -#if (OVR_MAJOR_VERSION == 5) ovrHmd_RecenterPose(_hmd); -#endif } glm::mat4 OculusLegacyDisplayPlugin::getEyeToHeadTransform(Eye eye) const { -#if (OVR_MAJOR_VERSION == 5) return toGlm(_eyePoses[eye]); -#else - return WindowOpenGLDisplayPlugin::getEyeToHeadTransform(eye); -#endif } // Should NOT be used for rendering as this will mess up timewarp. Use the getModelview() method above for // any use of head poses for rendering, ensuring you use the correct eye glm::mat4 OculusLegacyDisplayPlugin::getHeadPose() const { -#if (OVR_MAJOR_VERSION == 5) return toGlm(_trackingState.HeadPose.ThePose); -#else - return WindowOpenGLDisplayPlugin::getHeadPose(); -#endif } bool OculusLegacyDisplayPlugin::isSupported() const { -#if (OVR_MAJOR_VERSION == 5) if (!ovr_Initialize(nullptr)) { return false; } @@ -104,14 +91,10 @@ bool OculusLegacyDisplayPlugin::isSupported() const { ovr_Shutdown(); return result; -#else - return false; -#endif } void OculusLegacyDisplayPlugin::activate() { -#if (OVR_MAJOR_VERSION == 5) - if (!OVR_SUCCESS(ovr_Initialize(nullptr))) { + if (!(ovr_Initialize(nullptr))) { Q_ASSERT(false); qFatal("Failed to Initialize SDK"); } @@ -149,8 +132,8 @@ void OculusLegacyDisplayPlugin::activate() { _frameIndex = 0; - if (!OVR_SUCCESS(ovrHmd_ConfigureTracking(_hmd, - ovrTrackingCap_Orientation | ovrTrackingCap_Position | ovrTrackingCap_MagYawCorrection, 0))) { + if (!ovrHmd_ConfigureTracking(_hmd, + ovrTrackingCap_Orientation | ovrTrackingCap_Position | ovrTrackingCap_MagYawCorrection, 0)) { qFatal("Could not attach to sensor device"); } @@ -158,7 +141,7 @@ void OculusLegacyDisplayPlugin::activate() { int screen = getHmdScreen(); if (screen != -1) { - CONTAINER->setFullscreen(qApp->screens()[screen]); + _container->setFullscreen(qApp->screens()[screen]); } _window->installEventFilter(this); @@ -189,11 +172,9 @@ void OculusLegacyDisplayPlugin::activate() { #endif ovrHmd_ConfigureRendering(_hmd, &config.Config, distortionCaps, _eyeFovs, _eyeRenderDescs); Q_ASSERT(result); -#endif } void OculusLegacyDisplayPlugin::deactivate() { -#if (OVR_MAJOR_VERSION == 5) _window->removeEventFilter(this); WindowOpenGLDisplayPlugin::deactivate(); @@ -202,12 +183,11 @@ void OculusLegacyDisplayPlugin::deactivate() { if (_hmdScreen >= 0) { riftScreen = qApp->screens()[_hmdScreen]; } - CONTAINER->unsetFullscreen(riftScreen); + _container->unsetFullscreen(riftScreen); ovrHmd_Destroy(_hmd); _hmd = nullptr; ovr_Shutdown(); -#endif } void OculusLegacyDisplayPlugin::preDisplay() { @@ -216,17 +196,14 @@ void OculusLegacyDisplayPlugin::preDisplay() { void OculusLegacyDisplayPlugin::display(GLuint finalTexture, const glm::uvec2& sceneSize) { ++_frameIndex; -#if (OVR_MAJOR_VERSION == 5) ovr_for_each_eye([&](ovrEyeType eye) { reinterpret_cast(_eyeTextures[eye]).OGL.TexId = finalTexture; }); ovrHmd_EndFrame(_hmd, _eyePoses, _eyeTextures); -#endif } // Pass input events on to the application bool OculusLegacyDisplayPlugin::eventFilter(QObject* receiver, QEvent* event) { -#if (OVR_MAJOR_VERSION == 5) if (!_hswDismissed && (event->type() == QEvent::KeyPress)) { static ovrHSWDisplayState hswState; ovrHmd_GetHSWDisplayState(_hmd, &hswState); @@ -236,7 +213,6 @@ bool OculusLegacyDisplayPlugin::eventFilter(QObject* receiver, QEvent* event) { _hswDismissed = true; } } -#endif return WindowOpenGLDisplayPlugin::eventFilter(receiver, event); } diff --git a/libraries/display-plugins/src/display-plugins/oculus/OculusLegacyDisplayPlugin.h b/plugins/oculusLegacy/src/OculusLegacyDisplayPlugin.h similarity index 97% rename from libraries/display-plugins/src/display-plugins/oculus/OculusLegacyDisplayPlugin.h rename to plugins/oculusLegacy/src/OculusLegacyDisplayPlugin.h index 9e2e47f434..2e95cee9bb 100644 --- a/libraries/display-plugins/src/display-plugins/oculus/OculusLegacyDisplayPlugin.h +++ b/plugins/oculusLegacy/src/OculusLegacyDisplayPlugin.h @@ -7,7 +7,7 @@ // #pragma once -#include "../WindowOpenGLDisplayPlugin.h" +#include #include diff --git a/plugins/oculusLegacy/src/OculusProvider.cpp b/plugins/oculusLegacy/src/OculusProvider.cpp new file mode 100644 index 0000000000..606563e0ad --- /dev/null +++ b/plugins/oculusLegacy/src/OculusProvider.cpp @@ -0,0 +1,45 @@ +// +// 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 +// + +#include + +#include +#include +#include + +#include +#include + +#include "OculusLegacyDisplayPlugin.h" + +class OculusProvider : public QObject, public DisplayProvider +{ + Q_OBJECT + Q_PLUGIN_METADATA(IID DisplayProvider_iid FILE "oculus.json") + Q_INTERFACES(DisplayProvider) + +public: + OculusProvider(QObject* parent = nullptr) : QObject(parent) {} + virtual ~OculusProvider() {} + + virtual DisplayPluginList getDisplayPlugins() override { + static std::once_flag once; + std::call_once(once, [&] { + DisplayPluginPointer plugin(new OculusLegacyDisplayPlugin()); + if (plugin->isSupported()) { + _displayPlugins.push_back(plugin); + } + }); + return _displayPlugins; + } + +private: + DisplayPluginList _displayPlugins; +}; + +#include "OculusProvider.moc" diff --git a/plugins/oculusLegacy/src/oculus.json b/plugins/oculusLegacy/src/oculus.json new file mode 100644 index 0000000000..0967ef424b --- /dev/null +++ b/plugins/oculusLegacy/src/oculus.json @@ -0,0 +1 @@ +{} diff --git a/tests/controllers/src/main.cpp b/tests/controllers/src/main.cpp index a7b1be15ca..139d9b282c 100644 --- a/tests/controllers/src/main.cpp +++ b/tests/controllers/src/main.cpp @@ -80,9 +80,6 @@ using namespace controller; class PluginContainerProxy : public QObject, PluginContainer { Q_OBJECT public: - PluginContainerProxy() { - Plugin::setContainer(this); - } virtual ~PluginContainerProxy() {} virtual void addMenu(const QString& menuName) override {} virtual void removeMenu(const QString& menuName) override {}