mirror of
https://github.com/lubosz/overte.git
synced 2025-04-06 16:42:12 +02:00
Support for runtime plugins (DLLs)
This commit is contained in:
parent
7fdb8e28e7
commit
cfb2fd1523
47 changed files with 631 additions and 242 deletions
|
@ -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 ()
|
||||
|
||||
|
|
5
cmake/externals/glew/CMakeLists.txt
vendored
5
cmake/externals/glew/CMakeLists.txt
vendored
|
@ -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=<INSTALL_DIR>
|
||||
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")
|
||||
|
||||
|
|
33
cmake/macros/SetupHifiPlugin.cmake
Normal file
33
cmake/macros/SetupHifiPlugin.cmake
Normal file
|
@ -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/$<CONFIGURATION>/${PLUGIN_PATH}/"
|
||||
)
|
||||
|
||||
add_custom_command(TARGET ${DIR} POST_BUILD
|
||||
COMMAND "${CMAKE_COMMAND}" -E copy
|
||||
"$<TARGET_FILE:${TARGET_NAME}>"
|
||||
"${CMAKE_BINARY_DIR}/interface/$<CONFIGURATION>/${PLUGIN_PATH}/"
|
||||
)
|
||||
|
||||
endmacro()
|
|
@ -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
|
||||
|
|
|
@ -13,7 +13,6 @@
|
|||
#include "ui/DialogsManager.h"
|
||||
|
||||
PluginContainerProxy::PluginContainerProxy() {
|
||||
Plugin::setContainer(this);
|
||||
}
|
||||
|
||||
PluginContainerProxy::~PluginContainerProxy() {
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -12,7 +12,6 @@
|
|||
|
||||
#include "DisplayPlugin.h"
|
||||
#include <plugins/PluginContainer.h>
|
||||
#include <OVR_CAPI_Keys.h>
|
||||
|
||||
static Setting::Handle<float> 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 {
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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(),
|
||||
|
|
|
@ -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 <QSize>
|
||||
#include <QPoint>
|
||||
#include <functional>
|
||||
|
||||
#include <gl/Config.h>
|
||||
#include <GLMHelpers.h>
|
||||
|
||||
#include <glm/glm.hpp>
|
||||
#include <glm/gtc/quaternion.hpp>
|
||||
#include <RegisteredMetaTypes.h>
|
||||
|
||||
enum Eye {
|
||||
Left,
|
||||
Right,
|
||||
Mono
|
||||
};
|
||||
|
||||
/*
|
||||
* Helper method to iterate over each eye
|
||||
*/
|
||||
template <typename F>
|
||||
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 <typename F, typename FF>
|
||||
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 <plugins/DisplayPlugin.h>
|
||||
|
||||
|
|
|
@ -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() {}
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
#include <QOpenGLContext>
|
||||
#include <QCoreApplication>
|
||||
|
||||
#include <gl/Config.h>
|
||||
#include <gl/GlWindow.h>
|
||||
#include <GLMHelpers.h>
|
||||
|
||||
|
|
|
@ -42,7 +42,7 @@ bool WindowOpenGLDisplayPlugin::hasFocus() const {
|
|||
|
||||
void WindowOpenGLDisplayPlugin::activate() {
|
||||
OpenGLDisplayPlugin::activate();
|
||||
_window = CONTAINER->getPrimarySurface();
|
||||
_window = _container->getPrimarySurface();
|
||||
_window->makeCurrent();
|
||||
customizeContext();
|
||||
_window->doneCurrent();
|
||||
|
|
|
@ -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--;
|
||||
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
||||
|
|
|
@ -10,14 +10,4 @@
|
|||
//
|
||||
#pragma once
|
||||
|
||||
#include <plugins/Plugin.h>
|
||||
|
||||
class InputPlugin : public Plugin {
|
||||
public:
|
||||
virtual bool isJointController() const = 0;
|
||||
|
||||
virtual void pluginFocusOutEvent() = 0;
|
||||
|
||||
virtual void pluginUpdate(float deltaTime, bool jointsCaptured) = 0;
|
||||
};
|
||||
|
||||
#include <plugins/InputPlugin.h>
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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--;
|
||||
|
||||
|
|
140
libraries/plugins/src/plugins/DisplayPlugin.h
Normal file
140
libraries/plugins/src/plugins/DisplayPlugin.h
Normal file
|
@ -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 <functional>
|
||||
|
||||
#include <glm/glm.hpp>
|
||||
#include <glm/gtc/quaternion.hpp>
|
||||
|
||||
#include <QtCore/QSize>
|
||||
#include <QtCore/QPoint>
|
||||
|
||||
#include <GLMHelpers.h>
|
||||
#include <RegisteredMetaTypes.h>
|
||||
|
||||
#include "Plugin.h"
|
||||
|
||||
enum Eye {
|
||||
Left,
|
||||
Right,
|
||||
Mono
|
||||
};
|
||||
|
||||
/*
|
||||
* Helper method to iterate over each eye
|
||||
*/
|
||||
template <typename F>
|
||||
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 <typename F, typename FF>
|
||||
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();
|
||||
};
|
||||
|
|
@ -21,3 +21,4 @@ using DisplayPluginPointer = QSharedPointer<DisplayPlugin>;
|
|||
using DisplayPluginList = QVector<DisplayPluginPointer>;
|
||||
using InputPluginPointer = QSharedPointer<InputPlugin>;
|
||||
using InputPluginList = QVector<InputPluginPointer>;
|
||||
|
||||
|
|
23
libraries/plugins/src/plugins/InputPlugin.h
Normal file
23
libraries/plugins/src/plugins/InputPlugin.h
Normal file
|
@ -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;
|
||||
};
|
||||
|
|
@ -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; }
|
||||
|
|
|
@ -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;
|
||||
|
||||
};
|
||||
|
|
|
@ -6,15 +6,54 @@
|
|||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
#include "PluginManager.h"
|
||||
|
||||
#include <mutex>
|
||||
|
||||
#include "Forward.h"
|
||||
#include <QtCore/QCoreApplication>
|
||||
#include <QtCore/QDir>
|
||||
#include <QtCore/QDebug>
|
||||
#include <QtCore/QPluginLoader>
|
||||
|
||||
#include "RuntimePlugin.h"
|
||||
#include "DisplayPlugin.h"
|
||||
#include "InputPlugin.h"
|
||||
#include "PluginContainer.h"
|
||||
|
||||
|
||||
PluginManager* PluginManager::getInstance() {
|
||||
static PluginManager _manager;
|
||||
return &_manager;
|
||||
}
|
||||
|
||||
using Loader = QSharedPointer<QPluginLoader>;
|
||||
using LoaderList = QList<Loader>;
|
||||
|
||||
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<QPluginLoader> 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<DisplayProvider*>(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<InputProvider*>(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;
|
||||
}
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
class PluginManager : public QObject {
|
||||
public:
|
||||
static PluginManager* getInstance();
|
||||
PluginManager();
|
||||
|
||||
const DisplayPluginList& getDisplayPlugins();
|
||||
const InputPluginList& getInputPlugins();
|
||||
|
|
36
libraries/plugins/src/plugins/RuntimePlugin.h
Normal file
36
libraries/plugins/src/plugins/RuntimePlugin.h
Normal file
|
@ -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 <assert.h>
|
||||
|
||||
#include <QString>
|
||||
#include <QObject>
|
||||
|
||||
#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)
|
||||
|
18
plugins/CMakeLists.txt
Normal file
18
plugins/CMakeLists.txt
Normal file
|
@ -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()
|
||||
|
22
plugins/oculus/CMakeLists.txt
Normal file
22
plugins/oculus/CMakeLists.txt
Normal file
|
@ -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()
|
|
@ -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() {
|
||||
}
|
||||
|
|
@ -7,7 +7,7 @@
|
|||
//
|
||||
#pragma once
|
||||
|
||||
#include "../WindowOpenGLDisplayPlugin.h"
|
||||
#include <display-plugins/WindowOpenGLDisplayPlugin.h>
|
||||
|
||||
#include <QTimer>
|
||||
|
||||
|
@ -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;
|
||||
|
|
@ -7,11 +7,14 @@
|
|||
//
|
||||
#include "OculusDisplayPlugin.h"
|
||||
|
||||
#include <QGLWidget>
|
||||
#include <QtOpenGL/QGLWidget>
|
||||
|
||||
// FIXME get rid of this
|
||||
#include <gl/Config.h>
|
||||
#include <plugins/PluginContainer.h>
|
||||
|
||||
#include "OculusHelpers.h"
|
||||
|
||||
#include <plugins/PluginContainer.h>
|
||||
|
||||
#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());
|
54
plugins/oculus/src/OculusProvider.cpp
Normal file
54
plugins/oculus/src/OculusProvider.cpp
Normal file
|
@ -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 <mutex>
|
||||
|
||||
#include <QtCore/QObject>
|
||||
#include <QtCore/QtPlugin>
|
||||
#include <QtCore/QStringList>
|
||||
|
||||
#include <plugins/RuntimePlugin.h>
|
||||
#include <plugins/DisplayPlugin.h>
|
||||
|
||||
#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"
|
1
plugins/oculus/src/oculus.json
Normal file
1
plugins/oculus/src/oculus.json
Normal file
|
@ -0,0 +1 @@
|
|||
{}
|
22
plugins/oculusLegacy/CMakeLists.txt
Normal file
22
plugins/oculusLegacy/CMakeLists.txt
Normal file
|
@ -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()
|
9
plugins/oculusLegacy/src/OculusHelpers.cpp
Normal file
9
plugins/oculusLegacy/src/OculusHelpers.cpp
Normal file
|
@ -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"
|
85
plugins/oculusLegacy/src/OculusHelpers.h
Normal file
85
plugins/oculusLegacy/src/OculusHelpers.h
Normal file
|
@ -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 <OVR_CAPI_GL.h>
|
||||
#include <GLMHelpers.h>
|
||||
#include <glm/gtc/type_ptr.hpp>
|
||||
#include <glm/gtc/matrix_transform.hpp>
|
||||
|
||||
// Convenience method for looping over each eye with a lambda
|
||||
template <typename Function>
|
||||
inline void ovr_for_each_eye(Function function) {
|
||||
for (ovrEyeType eye = ovrEyeType::ovrEye_Left;
|
||||
eye < ovrEyeType::ovrEye_Count;
|
||||
eye = static_cast<ovrEyeType>(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;
|
||||
}
|
|
@ -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<ovrGLTexture&>(_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);
|
||||
}
|
||||
|
|
@ -7,7 +7,7 @@
|
|||
//
|
||||
#pragma once
|
||||
|
||||
#include "../WindowOpenGLDisplayPlugin.h"
|
||||
#include <display-plugins/WindowOpenGLDisplayPlugin.h>
|
||||
|
||||
#include <QTimer>
|
||||
|
45
plugins/oculusLegacy/src/OculusProvider.cpp
Normal file
45
plugins/oculusLegacy/src/OculusProvider.cpp
Normal file
|
@ -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 <mutex>
|
||||
|
||||
#include <QtCore/QObject>
|
||||
#include <QtCore/QtPlugin>
|
||||
#include <QtCore/QStringList>
|
||||
|
||||
#include <plugins/RuntimePlugin.h>
|
||||
#include <plugins/DisplayPlugin.h>
|
||||
|
||||
#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"
|
1
plugins/oculusLegacy/src/oculus.json
Normal file
1
plugins/oculusLegacy/src/oculus.json
Normal file
|
@ -0,0 +1 @@
|
|||
{}
|
|
@ -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 {}
|
||||
|
|
Loading…
Reference in a new issue