mirror of
https://github.com/overte-org/overte.git
synced 2025-08-08 11:37:58 +02:00
Merge pull request #6595 from jherico/zaan
Migrate to latest Oculus SDK (0.8)
This commit is contained in:
commit
5933a055a9
20 changed files with 247 additions and 199 deletions
11
cmake/externals/LibOVR/CMakeLists.txt
vendored
11
cmake/externals/LibOVR/CMakeLists.txt
vendored
|
@ -15,17 +15,16 @@ string(TOUPPER ${EXTERNAL_NAME} EXTERNAL_NAME_UPPER)
|
||||||
# 0.6 public
|
# 0.6 public
|
||||||
# URL http://static.oculus.com/sdk-downloads/0.6.0.1/Public/1435190862/ovr_sdk_win_0.6.0.1.zip
|
# URL http://static.oculus.com/sdk-downloads/0.6.0.1/Public/1435190862/ovr_sdk_win_0.6.0.1.zip
|
||||||
# URL_MD5 4b3ef825f9a1d6d3035c9f6820687da9
|
# URL_MD5 4b3ef825f9a1d6d3035c9f6820687da9
|
||||||
# 0.7 alpha
|
# 0.8 public
|
||||||
# URL https://s3.amazonaws.com/static.oculus.com/sdk-downloads/0.7.0.0/Public/Alpha/ovr_sdk_win_0.7.0.0_RC1.zip
|
# URL http://static.oculus.com/sdk-downloads/0.8.0.0/Public/1445451746/ovr_sdk_win_0.8.0.0.zip
|
||||||
# URL_MD5 a562bb9d117087b2cf9d86653ea70fd8
|
# URL_MD5 54944b03b95149d6010f84eb701b9647
|
||||||
|
|
||||||
|
|
||||||
if (WIN32)
|
if (WIN32)
|
||||||
|
|
||||||
ExternalProject_Add(
|
ExternalProject_Add(
|
||||||
${EXTERNAL_NAME}
|
${EXTERNAL_NAME}
|
||||||
URL http://static.oculus.com/sdk-downloads/0.6.0.1/Public/1435190862/ovr_sdk_win_0.6.0.1.zip
|
URL http://static.oculus.com/sdk-downloads/0.8.0.0/Public/1445451746/ovr_sdk_win_0.8.0.0.zip
|
||||||
URL_MD5 4b3ef825f9a1d6d3035c9f6820687da9
|
URL_MD5 54944b03b95149d6010f84eb701b9647
|
||||||
CONFIGURE_COMMAND ""
|
CONFIGURE_COMMAND ""
|
||||||
BUILD_COMMAND ""
|
BUILD_COMMAND ""
|
||||||
INSTALL_COMMAND ""
|
INSTALL_COMMAND ""
|
||||||
|
|
5
cmake/externals/openvr/CMakeLists.txt
vendored
5
cmake/externals/openvr/CMakeLists.txt
vendored
|
@ -7,9 +7,8 @@ string(TOUPPER ${EXTERNAL_NAME} EXTERNAL_NAME_UPPER)
|
||||||
|
|
||||||
ExternalProject_Add(
|
ExternalProject_Add(
|
||||||
${EXTERNAL_NAME}
|
${EXTERNAL_NAME}
|
||||||
#URL https://github.com/ValveSoftware/openvr/archive/0.9.1.zip
|
URL https://github.com/ValveSoftware/openvr/archive/v0.9.12.zip
|
||||||
URL http://hifi-public.s3.amazonaws.com/dependencies/openvr-0.9.1.zip
|
URL_MD5 c08dced68ce4e341e1467e6814ae419d
|
||||||
URL_MD5 f986f5a6815e9454c53c5bf58ce02fdc
|
|
||||||
CONFIGURE_COMMAND ""
|
CONFIGURE_COMMAND ""
|
||||||
BUILD_COMMAND ""
|
BUILD_COMMAND ""
|
||||||
INSTALL_COMMAND ""
|
INSTALL_COMMAND ""
|
||||||
|
|
|
@ -14,8 +14,6 @@
|
||||||
#include "stereo/InterleavedStereoDisplayPlugin.h"
|
#include "stereo/InterleavedStereoDisplayPlugin.h"
|
||||||
#include "Basic2DWindowOpenGLDisplayPlugin.h"
|
#include "Basic2DWindowOpenGLDisplayPlugin.h"
|
||||||
|
|
||||||
#include "openvr/OpenVrDisplayPlugin.h"
|
|
||||||
|
|
||||||
const QString& DisplayPlugin::MENU_PATH() {
|
const QString& DisplayPlugin::MENU_PATH() {
|
||||||
static const QString value = "Display";
|
static const QString value = "Display";
|
||||||
return value;
|
return value;
|
||||||
|
@ -25,22 +23,14 @@ const QString& DisplayPlugin::MENU_PATH() {
|
||||||
DisplayPluginList getDisplayPlugins() {
|
DisplayPluginList getDisplayPlugins() {
|
||||||
DisplayPlugin* PLUGIN_POOL[] = {
|
DisplayPlugin* PLUGIN_POOL[] = {
|
||||||
new Basic2DWindowOpenGLDisplayPlugin(),
|
new Basic2DWindowOpenGLDisplayPlugin(),
|
||||||
new NullDisplayPlugin(),
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
|
new NullDisplayPlugin(),
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Stereo modes
|
// Stereo modes
|
||||||
|
|
||||||
// SBS left/right
|
// SBS left/right
|
||||||
new SideBySideStereoDisplayPlugin(),
|
new SideBySideStereoDisplayPlugin(),
|
||||||
// Interleaved left/right
|
// Interleaved left/right
|
||||||
new InterleavedStereoDisplayPlugin(),
|
new InterleavedStereoDisplayPlugin(),
|
||||||
|
|
||||||
// HMDs
|
|
||||||
//#ifdef Q_OS_WIN
|
|
||||||
// // SteamVR SDK
|
|
||||||
// new OpenVrDisplayPlugin(),
|
|
||||||
//#endif
|
|
||||||
nullptr
|
nullptr
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -15,6 +15,7 @@
|
||||||
|
|
||||||
#include <QtOpenGL/QGLWidget>
|
#include <QtOpenGL/QGLWidget>
|
||||||
#include <QtGui/QImage>
|
#include <QtGui/QImage>
|
||||||
|
#include <QtGui/QOpenGLContext>
|
||||||
|
|
||||||
#include <gl/GLWidget.h>
|
#include <gl/GLWidget.h>
|
||||||
#include <NumericalConstants.h>
|
#include <NumericalConstants.h>
|
||||||
|
@ -103,8 +104,12 @@ public:
|
||||||
|
|
||||||
// take the latest texture and present it
|
// take the latest texture and present it
|
||||||
_context->makeCurrent();
|
_context->makeCurrent();
|
||||||
currentPlugin->present();
|
if (QOpenGLContext::currentContext() == _context->contextHandle()) {
|
||||||
_context->doneCurrent();
|
currentPlugin->present();
|
||||||
|
_context->doneCurrent();
|
||||||
|
} else {
|
||||||
|
qWarning() << "Makecurrent failed";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_context->makeCurrent();
|
_context->makeCurrent();
|
||||||
|
|
|
@ -74,7 +74,7 @@ protected:
|
||||||
ProgramPtr _program;
|
ProgramPtr _program;
|
||||||
ShapeWrapperPtr _plane;
|
ShapeWrapperPtr _plane;
|
||||||
|
|
||||||
Mutex _mutex;
|
mutable Mutex _mutex;
|
||||||
SimpleMovingAverage _usecsPerFrame { 10 };
|
SimpleMovingAverage _usecsPerFrame { 10 };
|
||||||
QMap<uint32_t, uint32_t> _sceneTextureToFrameIndexMap;
|
QMap<uint32_t, uint32_t> _sceneTextureToFrameIndexMap;
|
||||||
|
|
||||||
|
|
|
@ -1,15 +1,5 @@
|
||||||
set(TARGET_NAME input-plugins)
|
set(TARGET_NAME input-plugins)
|
||||||
setup_hifi_library()
|
setup_hifi_library()
|
||||||
link_hifi_libraries(shared plugins controllers script-engine render-utils)
|
link_hifi_libraries(shared plugins controllers)
|
||||||
|
|
||||||
GroupSources("src/input-plugins")
|
GroupSources("src/input-plugins")
|
||||||
|
|
||||||
if (WIN32)
|
|
||||||
add_dependency_external_projects(OpenVR)
|
|
||||||
find_package(OpenVR REQUIRED)
|
|
||||||
target_include_directories(${TARGET_NAME} PRIVATE ${OPENVR_INCLUDE_DIRS})
|
|
||||||
target_link_libraries(${TARGET_NAME} ${OPENVR_LIBRARIES})
|
|
||||||
endif()
|
|
||||||
|
|
||||||
target_sdl2()
|
|
||||||
target_sixense()
|
|
||||||
|
|
|
@ -15,7 +15,6 @@
|
||||||
#include "KeyboardMouseDevice.h"
|
#include "KeyboardMouseDevice.h"
|
||||||
#include "SDL2Manager.h"
|
#include "SDL2Manager.h"
|
||||||
#include "SixenseManager.h"
|
#include "SixenseManager.h"
|
||||||
#include "ViveControllerManager.h"
|
|
||||||
|
|
||||||
// TODO migrate to a DLL model where plugins are discovered and loaded at runtime by the PluginManager class
|
// TODO migrate to a DLL model where plugins are discovered and loaded at runtime by the PluginManager class
|
||||||
InputPluginList getInputPlugins() {
|
InputPluginList getInputPlugins() {
|
||||||
|
@ -23,7 +22,6 @@ InputPluginList getInputPlugins() {
|
||||||
new KeyboardMouseDevice(),
|
new KeyboardMouseDevice(),
|
||||||
new SDL2Manager(),
|
new SDL2Manager(),
|
||||||
new SixenseManager(),
|
new SixenseManager(),
|
||||||
new ViveControllerManager(),
|
|
||||||
nullptr
|
nullptr
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -82,7 +82,7 @@ void avatarDataFromScriptValue(const QScriptValue &object, AvatarData* &out) {
|
||||||
}
|
}
|
||||||
|
|
||||||
Q_DECLARE_METATYPE(controller::InputController*)
|
Q_DECLARE_METATYPE(controller::InputController*)
|
||||||
static int inputControllerPointerId = qRegisterMetaType<controller::InputController*>();
|
//static int inputControllerPointerId = qRegisterMetaType<controller::InputController*>();
|
||||||
|
|
||||||
QScriptValue inputControllerToScriptValue(QScriptEngine *engine, controller::InputController* const &in) {
|
QScriptValue inputControllerToScriptValue(QScriptEngine *engine, controller::InputController* const &in) {
|
||||||
return engine->newQObject(in);
|
return engine->newQObject(in);
|
||||||
|
|
|
@ -20,9 +20,7 @@ glm::mat4 OculusBaseDisplayPlugin::getProjection(Eye eye, const glm::mat4& baseP
|
||||||
}
|
}
|
||||||
|
|
||||||
void OculusBaseDisplayPlugin::resetSensors() {
|
void OculusBaseDisplayPlugin::resetSensors() {
|
||||||
#if (OVR_MAJOR_VERSION >= 6)
|
ovr_RecenterPose(_session);
|
||||||
ovr_RecenterPose(_hmd);
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
glm::mat4 OculusBaseDisplayPlugin::getEyeToHeadTransform(Eye eye) const {
|
glm::mat4 OculusBaseDisplayPlugin::getEyeToHeadTransform(Eye eye) const {
|
||||||
|
@ -30,27 +28,39 @@ glm::mat4 OculusBaseDisplayPlugin::getEyeToHeadTransform(Eye eye) const {
|
||||||
}
|
}
|
||||||
|
|
||||||
glm::mat4 OculusBaseDisplayPlugin::getHeadPose(uint32_t frameIndex) const {
|
glm::mat4 OculusBaseDisplayPlugin::getHeadPose(uint32_t frameIndex) const {
|
||||||
#if (OVR_MAJOR_VERSION >= 6)
|
static uint32_t lastFrameSeen = 0;
|
||||||
auto frameTiming = ovr_GetFrameTiming(_hmd, frameIndex);
|
auto displayTime = ovr_GetPredictedDisplayTime(_session, frameIndex);
|
||||||
auto trackingState = ovr_GetTrackingState(_hmd, frameTiming.DisplayMidpointSeconds);
|
auto trackingState = ovr_GetTrackingState(_session, displayTime, frameIndex > lastFrameSeen);
|
||||||
|
if (frameIndex > lastFrameSeen) {
|
||||||
|
lastFrameSeen = frameIndex;
|
||||||
|
}
|
||||||
return toGlm(trackingState.HeadPose.ThePose);
|
return toGlm(trackingState.HeadPose.ThePose);
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool OculusBaseDisplayPlugin::isSupported() const {
|
bool OculusBaseDisplayPlugin::isSupported() const {
|
||||||
#if (OVR_MAJOR_VERSION >= 6)
|
|
||||||
if (!OVR_SUCCESS(ovr_Initialize(nullptr))) {
|
if (!OVR_SUCCESS(ovr_Initialize(nullptr))) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
bool result = false;
|
|
||||||
if (ovrHmd_Detect() > 0) {
|
ovrSession session { nullptr };
|
||||||
result = true;
|
ovrGraphicsLuid luid;
|
||||||
|
auto result = ovr_Create(&session, &luid);
|
||||||
|
if (!OVR_SUCCESS(result)) {
|
||||||
|
ovrErrorInfo error;
|
||||||
|
ovr_GetLastErrorInfo(&error);
|
||||||
|
ovr_Shutdown();
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
auto hmdDesc = ovr_GetHmdDesc(session);
|
||||||
|
if (hmdDesc.Type == ovrHmd_None) {
|
||||||
|
ovr_Destroy(session);
|
||||||
|
ovr_Shutdown();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
ovr_Shutdown();
|
ovr_Shutdown();
|
||||||
return result;
|
return true;
|
||||||
#else
|
|
||||||
return false;
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// DLL based display plugins MUST initialize GLEW inside the DLL code.
|
// DLL based display plugins MUST initialize GLEW inside the DLL code.
|
||||||
|
@ -69,28 +79,22 @@ void OculusBaseDisplayPlugin::deinit() {
|
||||||
|
|
||||||
void OculusBaseDisplayPlugin::activate() {
|
void OculusBaseDisplayPlugin::activate() {
|
||||||
WindowOpenGLDisplayPlugin::activate();
|
WindowOpenGLDisplayPlugin::activate();
|
||||||
#if (OVR_MAJOR_VERSION >= 6)
|
|
||||||
if (!OVR_SUCCESS(ovr_Initialize(nullptr))) {
|
if (!OVR_SUCCESS(ovr_Initialize(nullptr))) {
|
||||||
qFatal("Could not init OVR");
|
qFatal("Could not init OVR");
|
||||||
}
|
}
|
||||||
|
|
||||||
#if (OVR_MAJOR_VERSION == 6)
|
if (!OVR_SUCCESS(ovr_Create(&_session, &_luid))) {
|
||||||
if (!OVR_SUCCESS(ovr_Create(0, &_hmd))) {
|
|
||||||
#elif (OVR_MAJOR_VERSION == 7)
|
|
||||||
if (!OVR_SUCCESS(ovr_Create(&_hmd, &_luid))) {
|
|
||||||
#endif
|
|
||||||
Q_ASSERT(false);
|
|
||||||
qFatal("Failed to acquire HMD");
|
qFatal("Failed to acquire HMD");
|
||||||
}
|
}
|
||||||
|
|
||||||
_hmdDesc = ovr_GetHmdDesc(_hmd);
|
_hmdDesc = ovr_GetHmdDesc(_session);
|
||||||
|
|
||||||
_ipd = ovr_GetFloat(_hmd, OVR_KEY_IPD, _ipd);
|
_ipd = ovr_GetFloat(_session, OVR_KEY_IPD, _ipd);
|
||||||
|
|
||||||
glm::uvec2 eyeSizes[2];
|
glm::uvec2 eyeSizes[2];
|
||||||
ovr_for_each_eye([&](ovrEyeType eye) {
|
ovr_for_each_eye([&](ovrEyeType eye) {
|
||||||
_eyeFovs[eye] = _hmdDesc.DefaultEyeFov[eye];
|
_eyeFovs[eye] = _hmdDesc.DefaultEyeFov[eye];
|
||||||
ovrEyeRenderDesc& erd = _eyeRenderDescs[eye] = ovr_GetRenderDesc(_hmd, eye, _eyeFovs[eye]);
|
ovrEyeRenderDesc& erd = _eyeRenderDescs[eye] = ovr_GetRenderDesc(_session, eye, _eyeFovs[eye]);
|
||||||
ovrMatrix4f ovrPerspectiveProjection =
|
ovrMatrix4f ovrPerspectiveProjection =
|
||||||
ovrMatrix4f_Projection(erd.Fov, DEFAULT_NEAR_CLIP, DEFAULT_FAR_CLIP, ovrProjection_RightHanded);
|
ovrMatrix4f_Projection(erd.Fov, DEFAULT_NEAR_CLIP, DEFAULT_FAR_CLIP, ovrProjection_RightHanded);
|
||||||
_eyeProjections[eye] = toGlm(ovrPerspectiveProjection);
|
_eyeProjections[eye] = toGlm(ovrPerspectiveProjection);
|
||||||
|
@ -100,7 +104,7 @@ void OculusBaseDisplayPlugin::activate() {
|
||||||
_compositeEyeProjections[eye] = toGlm(ovrPerspectiveProjection);
|
_compositeEyeProjections[eye] = toGlm(ovrPerspectiveProjection);
|
||||||
|
|
||||||
_eyeOffsets[eye] = erd.HmdToEyeViewOffset;
|
_eyeOffsets[eye] = erd.HmdToEyeViewOffset;
|
||||||
eyeSizes[eye] = toGlm(ovr_GetFovTextureSize(_hmd, eye, erd.Fov, 1.0f));
|
eyeSizes[eye] = toGlm(ovr_GetFovTextureSize(_session, eye, erd.Fov, 1.0f));
|
||||||
});
|
});
|
||||||
ovrFovPort combined = _eyeFovs[Left];
|
ovrFovPort combined = _eyeFovs[Left];
|
||||||
combined.LeftTan = std::max(_eyeFovs[Left].LeftTan, _eyeFovs[Right].LeftTan);
|
combined.LeftTan = std::max(_eyeFovs[Left].LeftTan, _eyeFovs[Right].LeftTan);
|
||||||
|
@ -115,34 +119,33 @@ void OculusBaseDisplayPlugin::activate() {
|
||||||
eyeSizes[0].x + eyeSizes[1].x,
|
eyeSizes[0].x + eyeSizes[1].x,
|
||||||
std::max(eyeSizes[0].y, eyeSizes[1].y));
|
std::max(eyeSizes[0].y, eyeSizes[1].y));
|
||||||
|
|
||||||
if (!OVR_SUCCESS(ovr_ConfigureTracking(_hmd,
|
if (!OVR_SUCCESS(ovr_ConfigureTracking(_session,
|
||||||
ovrTrackingCap_Orientation | ovrTrackingCap_Position | ovrTrackingCap_MagYawCorrection, 0))) {
|
ovrTrackingCap_Orientation | ovrTrackingCap_Position | ovrTrackingCap_MagYawCorrection, 0))) {
|
||||||
qFatal("Could not attach to sensor device");
|
qFatal("Could not attach to sensor device");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Parent class relies on our _hmd intialization, so it must come after that.
|
// Parent class relies on our _session intialization, so it must come after that.
|
||||||
memset(&_sceneLayer, 0, sizeof(ovrLayerEyeFov));
|
memset(&_sceneLayer, 0, sizeof(ovrLayerEyeFov));
|
||||||
_sceneLayer.Header.Type = ovrLayerType_EyeFov;
|
_sceneLayer.Header.Type = ovrLayerType_EyeFov;
|
||||||
_sceneLayer.Header.Flags = ovrLayerFlag_TextureOriginAtBottomLeft;
|
_sceneLayer.Header.Flags = ovrLayerFlag_TextureOriginAtBottomLeft;
|
||||||
ovr_for_each_eye([&](ovrEyeType eye) {
|
ovr_for_each_eye([&](ovrEyeType eye) {
|
||||||
ovrFovPort & fov = _sceneLayer.Fov[eye] = _eyeRenderDescs[eye].Fov;
|
ovrFovPort & fov = _sceneLayer.Fov[eye] = _eyeRenderDescs[eye].Fov;
|
||||||
ovrSizei & size = _sceneLayer.Viewport[eye].Size = ovr_GetFovTextureSize(_hmd, eye, fov, 1.0f);
|
ovrSizei & size = _sceneLayer.Viewport[eye].Size = ovr_GetFovTextureSize(_session, eye, fov, 1.0f);
|
||||||
_sceneLayer.Viewport[eye].Pos = { eye == ovrEye_Left ? 0 : size.w, 0 };
|
_sceneLayer.Viewport[eye].Pos = { eye == ovrEye_Left ? 0 : size.w, 0 };
|
||||||
});
|
});
|
||||||
|
|
||||||
if (!OVR_SUCCESS(ovr_ConfigureTracking(_hmd,
|
if (!OVR_SUCCESS(ovr_ConfigureTracking(_session,
|
||||||
ovrTrackingCap_Orientation | ovrTrackingCap_Position | ovrTrackingCap_MagYawCorrection, 0))) {
|
ovrTrackingCap_Orientation | ovrTrackingCap_Position | ovrTrackingCap_MagYawCorrection, 0))) {
|
||||||
qFatal("Could not attach to sensor device");
|
qFatal("Could not attach to sensor device");
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void OculusBaseDisplayPlugin::deactivate() {
|
void OculusBaseDisplayPlugin::deactivate() {
|
||||||
WindowOpenGLDisplayPlugin::deactivate();
|
WindowOpenGLDisplayPlugin::deactivate();
|
||||||
|
|
||||||
#if (OVR_MAJOR_VERSION >= 6)
|
#if (OVR_MAJOR_VERSION >= 6)
|
||||||
ovr_Destroy(_hmd);
|
ovr_Destroy(_session);
|
||||||
_hmd = nullptr;
|
_session = nullptr;
|
||||||
ovr_Shutdown();
|
ovr_Shutdown();
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
@ -151,7 +154,7 @@ void OculusBaseDisplayPlugin::deactivate() {
|
||||||
float OculusBaseDisplayPlugin::getIPD() const {
|
float OculusBaseDisplayPlugin::getIPD() const {
|
||||||
float result = OVR_DEFAULT_IPD;
|
float result = OVR_DEFAULT_IPD;
|
||||||
#if (OVR_MAJOR_VERSION >= 6)
|
#if (OVR_MAJOR_VERSION >= 6)
|
||||||
result = ovr_GetFloat(_hmd, OVR_KEY_IPD, result);
|
result = ovr_GetFloat(_session, OVR_KEY_IPD, result);
|
||||||
#endif
|
#endif
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
|
@ -43,17 +43,13 @@ protected:
|
||||||
mat4 _compositeEyeProjections[2];
|
mat4 _compositeEyeProjections[2];
|
||||||
uvec2 _desiredFramebufferSize;
|
uvec2 _desiredFramebufferSize;
|
||||||
|
|
||||||
#if (OVR_MAJOR_VERSION >= 6)
|
ovrSession _session;
|
||||||
ovrHmd _hmd;
|
ovrGraphicsLuid _luid;
|
||||||
float _ipd{ OVR_DEFAULT_IPD };
|
float _ipd{ OVR_DEFAULT_IPD };
|
||||||
ovrEyeRenderDesc _eyeRenderDescs[2];
|
ovrEyeRenderDesc _eyeRenderDescs[2];
|
||||||
ovrFovPort _eyeFovs[2];
|
ovrFovPort _eyeFovs[2];
|
||||||
ovrHmdDesc _hmdDesc;
|
ovrHmdDesc _hmdDesc;
|
||||||
ovrLayerEyeFov _sceneLayer;
|
ovrLayerEyeFov _sceneLayer;
|
||||||
#endif
|
|
||||||
#if (OVR_MAJOR_VERSION == 7)
|
|
||||||
ovrGraphicsLuid _luid;
|
|
||||||
#endif
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#if (OVR_MAJOR_VERSION == 6)
|
#if (OVR_MAJOR_VERSION == 6)
|
||||||
|
|
|
@ -23,12 +23,16 @@
|
||||||
// ovr_CreateMirrorTextureGL, etc
|
// ovr_CreateMirrorTextureGL, etc
|
||||||
template <typename C>
|
template <typename C>
|
||||||
struct RiftFramebufferWrapper : public FramebufferWrapper<C, char> {
|
struct RiftFramebufferWrapper : public FramebufferWrapper<C, char> {
|
||||||
ovrHmd hmd;
|
ovrSession session;
|
||||||
RiftFramebufferWrapper(const ovrHmd & hmd) : hmd(hmd) {
|
RiftFramebufferWrapper(const ovrSession& session) : session(session) {
|
||||||
color = 0;
|
color = 0;
|
||||||
depth = 0;
|
depth = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
~RiftFramebufferWrapper() {
|
||||||
|
destroyColor();
|
||||||
|
}
|
||||||
|
|
||||||
void Resize(const uvec2 & size) {
|
void Resize(const uvec2 & size) {
|
||||||
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, oglplus::GetName(fbo));
|
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, oglplus::GetName(fbo));
|
||||||
glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, 0, 0);
|
glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, 0, 0);
|
||||||
|
@ -39,6 +43,9 @@ struct RiftFramebufferWrapper : public FramebufferWrapper<C, char> {
|
||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
virtual void destroyColor() {
|
||||||
|
}
|
||||||
|
|
||||||
virtual void initDepth() override final {
|
virtual void initDepth() override final {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -53,12 +60,6 @@ struct SwapFramebufferWrapper : public RiftFramebufferWrapper<ovrSwapTextureSet*
|
||||||
: RiftFramebufferWrapper(hmd) {
|
: RiftFramebufferWrapper(hmd) {
|
||||||
}
|
}
|
||||||
|
|
||||||
~SwapFramebufferWrapper() {
|
|
||||||
if (color) {
|
|
||||||
ovr_DestroySwapTextureSet(hmd, color);
|
|
||||||
color = nullptr;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void Increment() {
|
void Increment() {
|
||||||
++color->CurrentIndex;
|
++color->CurrentIndex;
|
||||||
|
@ -66,13 +67,17 @@ struct SwapFramebufferWrapper : public RiftFramebufferWrapper<ovrSwapTextureSet*
|
||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual void initColor() override {
|
virtual void destroyColor() override {
|
||||||
if (color) {
|
if (color) {
|
||||||
ovr_DestroySwapTextureSet(hmd, color);
|
ovr_DestroySwapTextureSet(session, color);
|
||||||
color = nullptr;
|
color = nullptr;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (!OVR_SUCCESS(ovr_CreateSwapTextureSetGL(hmd, GL_RGBA, size.x, size.y, &color))) {
|
virtual void initColor() override {
|
||||||
|
destroyColor();
|
||||||
|
|
||||||
|
if (!OVR_SUCCESS(ovr_CreateSwapTextureSetGL(session, GL_SRGB8_ALPHA8, size.x, size.y, &color))) {
|
||||||
qFatal("Unable to create swap textures");
|
qFatal("Unable to create swap textures");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -107,20 +112,17 @@ struct MirrorFramebufferWrapper : public RiftFramebufferWrapper<ovrGLTexture*> {
|
||||||
MirrorFramebufferWrapper(const ovrHmd & hmd)
|
MirrorFramebufferWrapper(const ovrHmd & hmd)
|
||||||
: RiftFramebufferWrapper(hmd) { }
|
: RiftFramebufferWrapper(hmd) { }
|
||||||
|
|
||||||
virtual ~MirrorFramebufferWrapper() {
|
private:
|
||||||
|
virtual void destroyColor() override {
|
||||||
if (color) {
|
if (color) {
|
||||||
ovr_DestroyMirrorTexture(hmd, (ovrTexture*)color);
|
ovr_DestroyMirrorTexture(session, (ovrTexture*)color);
|
||||||
color = nullptr;
|
color = nullptr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
|
||||||
void initColor() override {
|
void initColor() override {
|
||||||
if (color) {
|
destroyColor();
|
||||||
ovr_DestroyMirrorTexture(hmd, (ovrTexture*)color);
|
ovrResult result = ovr_CreateMirrorTextureGL(session, GL_SRGB8_ALPHA8, size.x, size.y, (ovrTexture**)&color);
|
||||||
color = nullptr;
|
|
||||||
}
|
|
||||||
ovrResult result = ovr_CreateMirrorTextureGL(hmd, GL_RGBA, size.x, size.y, (ovrTexture**)&color);
|
|
||||||
Q_ASSERT(OVR_SUCCESS(result));
|
Q_ASSERT(OVR_SUCCESS(result));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -154,8 +156,7 @@ void OculusDisplayPlugin::activate() {
|
||||||
|
|
||||||
void OculusDisplayPlugin::customizeContext() {
|
void OculusDisplayPlugin::customizeContext() {
|
||||||
OculusBaseDisplayPlugin::customizeContext();
|
OculusBaseDisplayPlugin::customizeContext();
|
||||||
#if (OVR_MAJOR_VERSION >= 6)
|
_sceneFbo = SwapFboPtr(new SwapFramebufferWrapper(_session));
|
||||||
_sceneFbo = SwapFboPtr(new SwapFramebufferWrapper(_hmd));
|
|
||||||
_sceneFbo->Init(getRecommendedRenderSize());
|
_sceneFbo->Init(getRecommendedRenderSize());
|
||||||
|
|
||||||
// We're rendering both eyes to the same texture, so only one of the
|
// We're rendering both eyes to the same texture, so only one of the
|
||||||
|
@ -163,7 +164,7 @@ void OculusDisplayPlugin::customizeContext() {
|
||||||
_sceneLayer.ColorTexture[0] = _sceneFbo->color;
|
_sceneLayer.ColorTexture[0] = _sceneFbo->color;
|
||||||
// not needed since the structure was zeroed on init, but explicit
|
// not needed since the structure was zeroed on init, but explicit
|
||||||
_sceneLayer.ColorTexture[1] = nullptr;
|
_sceneLayer.ColorTexture[1] = nullptr;
|
||||||
#endif
|
|
||||||
enableVsync(false);
|
enableVsync(false);
|
||||||
// Only enable mirroring if we know vsync is disabled
|
// Only enable mirroring if we know vsync is disabled
|
||||||
_enablePreview = !isVsyncEnabled();
|
_enablePreview = !isVsyncEnabled();
|
||||||
|
@ -177,7 +178,6 @@ void OculusDisplayPlugin::uncustomizeContext() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void OculusDisplayPlugin::internalPresent() {
|
void OculusDisplayPlugin::internalPresent() {
|
||||||
#if (OVR_MAJOR_VERSION >= 6)
|
|
||||||
if (!_currentSceneTexture) {
|
if (!_currentSceneTexture) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -206,8 +206,10 @@ void OculusDisplayPlugin::internalPresent() {
|
||||||
auto size = _sceneFbo->size;
|
auto size = _sceneFbo->size;
|
||||||
Context::Viewport(size.x, size.y);
|
Context::Viewport(size.x, size.y);
|
||||||
glBindTexture(GL_TEXTURE_2D, _currentSceneTexture);
|
glBindTexture(GL_TEXTURE_2D, _currentSceneTexture);
|
||||||
|
//glEnable(GL_FRAMEBUFFER_SRGB);
|
||||||
GLenum err = glGetError();
|
GLenum err = glGetError();
|
||||||
drawUnitQuad();
|
drawUnitQuad();
|
||||||
|
//glDisable(GL_FRAMEBUFFER_SRGB);
|
||||||
});
|
});
|
||||||
|
|
||||||
uint32_t frameIndex { 0 };
|
uint32_t frameIndex { 0 };
|
||||||
|
@ -230,13 +232,12 @@ void OculusDisplayPlugin::internalPresent() {
|
||||||
viewScaleDesc.HmdToEyeViewOffset[1] = _eyeOffsets[1];
|
viewScaleDesc.HmdToEyeViewOffset[1] = _eyeOffsets[1];
|
||||||
|
|
||||||
ovrLayerHeader* layers = &_sceneLayer.Header;
|
ovrLayerHeader* layers = &_sceneLayer.Header;
|
||||||
ovrResult result = ovr_SubmitFrame(_hmd, frameIndex, &viewScaleDesc, &layers, 1);
|
ovrResult result = ovr_SubmitFrame(_session, frameIndex, &viewScaleDesc, &layers, 1);
|
||||||
if (!OVR_SUCCESS(result)) {
|
if (!OVR_SUCCESS(result)) {
|
||||||
qDebug() << result;
|
qDebug() << result;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_sceneFbo->Increment();
|
_sceneFbo->Increment();
|
||||||
#endif
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
The swapbuffer call here is only required if we want to mirror the content to the screen.
|
The swapbuffer call here is only required if we want to mirror the content to the screen.
|
||||||
|
|
27
plugins/openvr/CMakeLists.txt
Normal file
27
plugins/openvr/CMakeLists.txt
Normal file
|
@ -0,0 +1,27 @@
|
||||||
|
#
|
||||||
|
# Created by Bradley Austin Davis on 2015/11/18
|
||||||
|
# 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
|
||||||
|
#
|
||||||
|
|
||||||
|
# OpenVR is disabled until a) it works with threaded present and
|
||||||
|
# b) it doesn't interfere with Oculus SDK 0.8
|
||||||
|
if (FALSE)
|
||||||
|
#if (WIN32)
|
||||||
|
# we're using static GLEW, so define GLEW_STATIC
|
||||||
|
add_definitions(-DGLEW_STATIC)
|
||||||
|
set(TARGET_NAME openvr)
|
||||||
|
setup_hifi_plugin(OpenGL Script Qml Widgets)
|
||||||
|
link_hifi_libraries(shared gl networking controllers
|
||||||
|
plugins display-plugins input-plugins script-engine
|
||||||
|
render-utils model gpu render model-networking fbx)
|
||||||
|
|
||||||
|
include_hifi_library_headers(octree)
|
||||||
|
|
||||||
|
add_dependency_external_projects(OpenVR)
|
||||||
|
find_package(OpenVR REQUIRED)
|
||||||
|
target_include_directories(${TARGET_NAME} PRIVATE ${OPENVR_INCLUDE_DIRS})
|
||||||
|
target_link_libraries(${TARGET_NAME} ${OPENVR_LIBRARIES})
|
||||||
|
endif()
|
|
@ -7,24 +7,23 @@
|
||||||
//
|
//
|
||||||
#include "OpenVrDisplayPlugin.h"
|
#include "OpenVrDisplayPlugin.h"
|
||||||
|
|
||||||
#if defined(Q_OS_WIN)
|
|
||||||
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
|
||||||
#include <QMainWindow>
|
#include <QMainWindow>
|
||||||
|
#include <QLoggingCategory>
|
||||||
#include <QGLWidget>
|
#include <QGLWidget>
|
||||||
#include <GLMHelpers.h>
|
|
||||||
#include <QEvent>
|
#include <QEvent>
|
||||||
#include <QResizeEvent>
|
#include <QResizeEvent>
|
||||||
|
|
||||||
|
#include <GLMHelpers.h>
|
||||||
|
#include <gl/GlWindow.h>
|
||||||
|
|
||||||
#include <PerfStat.h>
|
#include <PerfStat.h>
|
||||||
#include <plugins/PluginContainer.h>
|
#include <plugins/PluginContainer.h>
|
||||||
#include <ViewFrustum.h>
|
#include <ViewFrustum.h>
|
||||||
|
|
||||||
#include "OpenVrHelpers.h"
|
#include "OpenVrHelpers.h"
|
||||||
#include "GLMHelpers.h"
|
|
||||||
|
|
||||||
#include <QLoggingCategory>
|
|
||||||
Q_DECLARE_LOGGING_CATEGORY(displayplugins)
|
Q_DECLARE_LOGGING_CATEGORY(displayplugins)
|
||||||
Q_LOGGING_CATEGORY(displayplugins, "hifi.displayplugins")
|
Q_LOGGING_CATEGORY(displayplugins, "hifi.displayplugins")
|
||||||
|
|
||||||
|
@ -41,12 +40,11 @@ vr::TrackedDevicePose_t _trackedDevicePose[vr::k_unMaxTrackedDeviceCount];
|
||||||
mat4 _trackedDevicePoseMat4[vr::k_unMaxTrackedDeviceCount];
|
mat4 _trackedDevicePoseMat4[vr::k_unMaxTrackedDeviceCount];
|
||||||
static mat4 _sensorResetMat;
|
static mat4 _sensorResetMat;
|
||||||
static uvec2 _windowSize;
|
static uvec2 _windowSize;
|
||||||
static ivec2 _windowPosition;
|
|
||||||
static uvec2 _renderTargetSize;
|
static uvec2 _renderTargetSize;
|
||||||
|
|
||||||
struct PerEyeData {
|
struct PerEyeData {
|
||||||
uvec2 _viewportOrigin;
|
//uvec2 _viewportOrigin;
|
||||||
uvec2 _viewportSize;
|
//uvec2 _viewportSize;
|
||||||
mat4 _projectionMatrix;
|
mat4 _projectionMatrix;
|
||||||
mat4 _eyeOffset;
|
mat4 _eyeOffset;
|
||||||
mat4 _pose;
|
mat4 _pose;
|
||||||
|
@ -89,36 +87,17 @@ void OpenVrDisplayPlugin::activate() {
|
||||||
}
|
}
|
||||||
Q_ASSERT(_hmd);
|
Q_ASSERT(_hmd);
|
||||||
|
|
||||||
_hmd->GetWindowBounds(&_windowPosition.x, &_windowPosition.y, &_windowSize.x, &_windowSize.y);
|
|
||||||
_hmd->GetRecommendedRenderTargetSize(&_renderTargetSize.x, &_renderTargetSize.y);
|
_hmd->GetRecommendedRenderTargetSize(&_renderTargetSize.x, &_renderTargetSize.y);
|
||||||
// Recommended render target size is per-eye, so double the X size for
|
// Recommended render target size is per-eye, so double the X size for
|
||||||
// left + right eyes
|
// left + right eyes
|
||||||
_renderTargetSize.x *= 2;
|
_renderTargetSize.x *= 2;
|
||||||
openvr_for_each_eye([&](vr::Hmd_Eye eye) {
|
openvr_for_each_eye([&](vr::Hmd_Eye eye) {
|
||||||
PerEyeData& eyeData = _eyesData[eye];
|
PerEyeData& eyeData = _eyesData[eye];
|
||||||
_hmd->GetEyeOutputViewport(eye,
|
|
||||||
&eyeData._viewportOrigin.x, &eyeData._viewportOrigin.y,
|
|
||||||
&eyeData._viewportSize.x, &eyeData._viewportSize.y);
|
|
||||||
eyeData._projectionMatrix = toGlm(_hmd->GetProjectionMatrix(eye, DEFAULT_NEAR_CLIP, DEFAULT_FAR_CLIP, vr::API_OpenGL));
|
eyeData._projectionMatrix = toGlm(_hmd->GetProjectionMatrix(eye, DEFAULT_NEAR_CLIP, DEFAULT_FAR_CLIP, vr::API_OpenGL));
|
||||||
eyeData._eyeOffset = toGlm(_hmd->GetEyeToHeadTransform(eye));
|
eyeData._eyeOffset = toGlm(_hmd->GetEyeToHeadTransform(eye));
|
||||||
});
|
});
|
||||||
|
_compositor = vr::VRCompositor();
|
||||||
|
|
||||||
vr::HmdError eError = vr::HmdError_None;
|
|
||||||
_compositor = (vr::IVRCompositor*)vr::VR_GetGenericInterface(vr::IVRCompositor_Version, &eError);
|
|
||||||
Q_ASSERT(eError == vr::HmdError_None);
|
|
||||||
Q_ASSERT(_compositor);
|
Q_ASSERT(_compositor);
|
||||||
|
|
||||||
_compositor->SetGraphicsDevice(vr::Compositor_DeviceType_OpenGL, NULL);
|
|
||||||
|
|
||||||
uint32_t unSize = _compositor->GetLastError(NULL, 0);
|
|
||||||
if (unSize > 1) {
|
|
||||||
char* buffer = new char[unSize];
|
|
||||||
_compositor->GetLastError(buffer, unSize);
|
|
||||||
printf("Compositor - %s\n", buffer);
|
|
||||||
delete[] buffer;
|
|
||||||
}
|
|
||||||
Q_ASSERT(unSize <= 1);
|
|
||||||
WindowOpenGLDisplayPlugin::activate();
|
WindowOpenGLDisplayPlugin::activate();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -132,6 +111,16 @@ void OpenVrDisplayPlugin::deactivate() {
|
||||||
WindowOpenGLDisplayPlugin::deactivate();
|
WindowOpenGLDisplayPlugin::deactivate();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void OpenVrDisplayPlugin::customizeContext() {
|
||||||
|
static std::once_flag once;
|
||||||
|
std::call_once(once, []{
|
||||||
|
glewExperimental = true;
|
||||||
|
GLenum err = glewInit();
|
||||||
|
glGetError();
|
||||||
|
});
|
||||||
|
WindowOpenGLDisplayPlugin::customizeContext();
|
||||||
|
}
|
||||||
|
|
||||||
uvec2 OpenVrDisplayPlugin::getRecommendedRenderSize() const {
|
uvec2 OpenVrDisplayPlugin::getRecommendedRenderSize() const {
|
||||||
return _renderTargetSize;
|
return _renderTargetSize;
|
||||||
}
|
}
|
||||||
|
@ -153,33 +142,41 @@ glm::mat4 OpenVrDisplayPlugin::getEyeToHeadTransform(Eye eye) const {
|
||||||
}
|
}
|
||||||
|
|
||||||
glm::mat4 OpenVrDisplayPlugin::getHeadPose(uint32_t frameIndex) const {
|
glm::mat4 OpenVrDisplayPlugin::getHeadPose(uint32_t frameIndex) const {
|
||||||
return _trackedDevicePoseMat4[0];
|
glm::mat4 result;
|
||||||
|
{
|
||||||
|
Lock lock(_mutex);
|
||||||
|
result = _trackedDevicePoseMat4[0];
|
||||||
|
|
||||||
|
}
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
void OpenVrDisplayPlugin::customizeContext() {
|
|
||||||
WindowOpenGLDisplayPlugin::customizeContext();
|
void OpenVrDisplayPlugin::submitSceneTexture(uint32_t frameIndex, uint32_t sceneTexture, const glm::uvec2& sceneSize) {
|
||||||
|
WindowOpenGLDisplayPlugin::submitSceneTexture(frameIndex, sceneTexture, sceneSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
//void OpenVrDisplayPlugin::display(uint32_t frameIndex, uint32_t finalTexture, const glm::uvec2& sceneSize) {
|
void OpenVrDisplayPlugin::internalPresent() {
|
||||||
// // Flip y-axis since GL UV coords are backwards.
|
// Flip y-axis since GL UV coords are backwards.
|
||||||
// static vr::Compositor_TextureBounds leftBounds{ 0, 1, 0.5f, 0 };
|
static vr::VRTextureBounds_t leftBounds{ 0, 0, 0.5f, 1 };
|
||||||
// static vr::Compositor_TextureBounds rightBounds{ 0.5f, 1, 1, 0 };
|
static vr::VRTextureBounds_t rightBounds{ 0.5f, 0, 1, 1 };
|
||||||
// _compositor->Submit(vr::Eye_Left, (void*)finalTexture, &leftBounds);
|
vr::Texture_t texture{ (void*)_currentSceneTexture, vr::API_OpenGL, vr::ColorSpace_Auto };
|
||||||
// _compositor->Submit(vr::Eye_Right, (void*)finalTexture, &rightBounds);
|
{
|
||||||
// glFinish();
|
Lock lock(_mutex);
|
||||||
//}
|
_compositor->Submit(vr::Eye_Left, &texture, &leftBounds);
|
||||||
|
_compositor->Submit(vr::Eye_Right, &texture, &rightBounds);
|
||||||
//void OpenVrDisplayPlugin::finishFrame() {
|
}
|
||||||
//// swapBuffers();
|
glFinish();
|
||||||
// doneCurrent();
|
{
|
||||||
// _compositor->WaitGetPoses(_trackedDevicePose, vr::k_unMaxTrackedDeviceCount);
|
Lock lock(_mutex);
|
||||||
// for (int i = 0; i < vr::k_unMaxTrackedDeviceCount; i++) {
|
_compositor->WaitGetPoses(_trackedDevicePose, vr::k_unMaxTrackedDeviceCount, nullptr, 0);
|
||||||
// _trackedDevicePoseMat4[i] = _sensorResetMat * toGlm(_trackedDevicePose[i].mDeviceToAbsoluteTracking);
|
for (int i = 0; i < vr::k_unMaxTrackedDeviceCount; i++) {
|
||||||
// }
|
_trackedDevicePoseMat4[i] = _sensorResetMat * toGlm(_trackedDevicePose[i].mDeviceToAbsoluteTracking);
|
||||||
// openvr_for_each_eye([&](vr::Hmd_Eye eye) {
|
}
|
||||||
// _eyesData[eye]._pose = _trackedDevicePoseMat4[0];
|
openvr_for_each_eye([&](vr::Hmd_Eye eye) {
|
||||||
// });
|
_eyesData[eye]._pose = _trackedDevicePoseMat4[0];
|
||||||
//};
|
});
|
||||||
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
|
//WindowOpenGLDisplayPlugin::internalPresent();
|
||||||
|
}
|
|
@ -9,10 +9,9 @@
|
||||||
|
|
||||||
#include <QtGlobal>
|
#include <QtGlobal>
|
||||||
|
|
||||||
#if defined(Q_OS_WIN)
|
|
||||||
#include <openvr.h>
|
#include <openvr.h>
|
||||||
|
|
||||||
#include "../WindowOpenGLDisplayPlugin.h"
|
#include <display-plugins/WindowOpenGLDisplayPlugin.h>
|
||||||
|
|
||||||
class OpenVrDisplayPlugin : public WindowOpenGLDisplayPlugin {
|
class OpenVrDisplayPlugin : public WindowOpenGLDisplayPlugin {
|
||||||
public:
|
public:
|
||||||
|
@ -23,6 +22,8 @@ public:
|
||||||
virtual void activate() override;
|
virtual void activate() override;
|
||||||
virtual void deactivate() override;
|
virtual void deactivate() override;
|
||||||
|
|
||||||
|
virtual void customizeContext() override;
|
||||||
|
|
||||||
virtual glm::uvec2 getRecommendedRenderSize() const override;
|
virtual glm::uvec2 getRecommendedRenderSize() const override;
|
||||||
virtual glm::uvec2 getRecommendedUiSize() const override { return uvec2(1920, 1080); }
|
virtual glm::uvec2 getRecommendedUiSize() const override { return uvec2(1920, 1080); }
|
||||||
|
|
||||||
|
@ -32,15 +33,13 @@ public:
|
||||||
|
|
||||||
virtual glm::mat4 getEyeToHeadTransform(Eye eye) const override;
|
virtual glm::mat4 getEyeToHeadTransform(Eye eye) const override;
|
||||||
virtual glm::mat4 getHeadPose(uint32_t frameIndex) const override;
|
virtual glm::mat4 getHeadPose(uint32_t frameIndex) const override;
|
||||||
|
virtual void submitSceneTexture(uint32_t frameIndex, uint32_t sceneTexture, const glm::uvec2& sceneSize) override;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
// virtual void display(uint32_t frameIndex, uint32_t finalTexture, const glm::uvec2& sceneSize) override;
|
virtual void internalPresent() override;
|
||||||
virtual void customizeContext() override;
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
vr::IVRSystem* _hmd { nullptr };
|
vr::IVRSystem* _hmd { nullptr };
|
||||||
static const QString NAME;
|
static const QString NAME;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
|
@ -7,14 +7,15 @@
|
||||||
//
|
//
|
||||||
#include "OpenVrHelpers.h"
|
#include "OpenVrHelpers.h"
|
||||||
|
|
||||||
#if defined(Q_OS_WIN)
|
|
||||||
|
|
||||||
#include <QtCore/QTimer>
|
|
||||||
|
|
||||||
#include <atomic>
|
#include <atomic>
|
||||||
#include <mutex>
|
#include <mutex>
|
||||||
|
|
||||||
#include "../Logging.h"
|
#include <QtCore/QDebug>
|
||||||
|
#include <QtCore/QTimer>
|
||||||
|
#include <QtCore/QLoggingCategory>
|
||||||
|
|
||||||
|
|
||||||
|
Q_DECLARE_LOGGING_CATEGORY(displayplugins)
|
||||||
|
|
||||||
using Mutex = std::mutex;
|
using Mutex = std::mutex;
|
||||||
using Lock = std::unique_lock<Mutex>;
|
using Lock = std::unique_lock<Mutex>;
|
||||||
|
@ -30,13 +31,13 @@ vr::IVRSystem* acquireOpenVrSystem() {
|
||||||
if (hmdPresent) {
|
if (hmdPresent) {
|
||||||
Lock lock(mutex);
|
Lock lock(mutex);
|
||||||
if (!activeHmd) {
|
if (!activeHmd) {
|
||||||
qCDebug(displayPlugins) << "openvr: No vr::IVRSystem instance active, building";
|
qCDebug(displayplugins) << "openvr: No vr::IVRSystem instance active, building";
|
||||||
vr::HmdError eError = vr::HmdError_None;
|
vr::EVRInitError eError = vr::VRInitError_None;
|
||||||
activeHmd = vr::VR_Init(&eError);
|
activeHmd = vr::VR_Init(&eError);
|
||||||
qCDebug(displayPlugins) << "openvr display: HMD is " << activeHmd << " error is " << eError;
|
qCDebug(displayplugins) << "openvr display: HMD is " << activeHmd << " error is " << eError;
|
||||||
}
|
}
|
||||||
if (activeHmd) {
|
if (activeHmd) {
|
||||||
qCDebug(displayPlugins) << "openvr: incrementing refcount";
|
qCDebug(displayplugins) << "openvr: incrementing refcount";
|
||||||
++refCount;
|
++refCount;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -46,10 +47,10 @@ vr::IVRSystem* acquireOpenVrSystem() {
|
||||||
void releaseOpenVrSystem() {
|
void releaseOpenVrSystem() {
|
||||||
if (activeHmd) {
|
if (activeHmd) {
|
||||||
Lock lock(mutex);
|
Lock lock(mutex);
|
||||||
qDebug() << "openvr: decrementing refcount";
|
qCDebug(displayplugins) << "openvr: decrementing refcount";
|
||||||
--refCount;
|
--refCount;
|
||||||
if (0 == refCount) {
|
if (0 == refCount) {
|
||||||
qDebug() << "openvr: zero refcount, deallocate VR system";
|
qCDebug(displayplugins) << "openvr: zero refcount, deallocate VR system";
|
||||||
// Avoid spamming the VR system with activate/deactivate calls at system startup by
|
// Avoid spamming the VR system with activate/deactivate calls at system startup by
|
||||||
// putting in a delay before we destory the shutdown the VR subsystem
|
// putting in a delay before we destory the shutdown the VR subsystem
|
||||||
|
|
||||||
|
@ -71,5 +72,3 @@ void releaseOpenVrSystem() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
|
|
@ -7,9 +7,6 @@
|
||||||
//
|
//
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <QtGlobal>
|
|
||||||
|
|
||||||
#if defined(Q_OS_WIN)
|
|
||||||
#include <openvr.h>
|
#include <openvr.h>
|
||||||
#include <GLMHelpers.h>
|
#include <GLMHelpers.h>
|
||||||
#include <glm/gtc/type_ptr.hpp>
|
#include <glm/gtc/type_ptr.hpp>
|
||||||
|
@ -18,5 +15,3 @@
|
||||||
vr::IVRSystem* acquireOpenVrSystem();
|
vr::IVRSystem* acquireOpenVrSystem();
|
||||||
void releaseOpenVrSystem();
|
void releaseOpenVrSystem();
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
60
plugins/openvr/src/OpenVrProvider.cpp
Normal file
60
plugins/openvr/src/OpenVrProvider.cpp
Normal file
|
@ -0,0 +1,60 @@
|
||||||
|
//
|
||||||
|
// 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 "OpenVrDisplayPlugin.h"
|
||||||
|
#include "ViveControllerManager.h"
|
||||||
|
|
||||||
|
class OpenVrProvider : public QObject, public DisplayProvider, InputProvider
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
Q_PLUGIN_METADATA(IID DisplayProvider_iid FILE "plugin.json")
|
||||||
|
Q_INTERFACES(DisplayProvider)
|
||||||
|
Q_PLUGIN_METADATA(IID InputProvider_iid FILE "plugin.json")
|
||||||
|
Q_INTERFACES(InputProvider)
|
||||||
|
|
||||||
|
public:
|
||||||
|
OpenVrProvider(QObject* parent = nullptr) : QObject(parent) {}
|
||||||
|
virtual ~OpenVrProvider() {}
|
||||||
|
|
||||||
|
virtual DisplayPluginList getDisplayPlugins() override {
|
||||||
|
static std::once_flag once;
|
||||||
|
std::call_once(once, [&] {
|
||||||
|
DisplayPluginPointer plugin(new OpenVrDisplayPlugin());
|
||||||
|
if (plugin->isSupported()) {
|
||||||
|
_displayPlugins.push_back(plugin);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return _displayPlugins;
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual InputPluginList getInputPlugins() override {
|
||||||
|
static std::once_flag once;
|
||||||
|
std::call_once(once, [&] {
|
||||||
|
InputPluginPointer plugin(new ViveControllerManager());
|
||||||
|
if (plugin->isSupported()) {
|
||||||
|
_inputPlugins.push_back(plugin);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return _inputPlugins;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private:
|
||||||
|
DisplayPluginList _displayPlugins;
|
||||||
|
InputPluginList _inputPlugins;
|
||||||
|
};
|
||||||
|
|
||||||
|
#include "OpenVrProvider.moc"
|
|
@ -17,7 +17,6 @@
|
||||||
#include <gpu/Batch.h>
|
#include <gpu/Batch.h>
|
||||||
#include <gpu/Context.h>
|
#include <gpu/Context.h>
|
||||||
#include <DeferredLightingEffect.h>
|
#include <DeferredLightingEffect.h>
|
||||||
#include <display-plugins/openvr/OpenVrHelpers.h>
|
|
||||||
#include <NumericalConstants.h>
|
#include <NumericalConstants.h>
|
||||||
#include <plugins/PluginContainer.h>
|
#include <plugins/PluginContainer.h>
|
||||||
#include <UserActivityLogger.h>
|
#include <UserActivityLogger.h>
|
||||||
|
@ -26,10 +25,10 @@
|
||||||
|
|
||||||
#include <controllers/StandardControls.h>
|
#include <controllers/StandardControls.h>
|
||||||
|
|
||||||
#ifdef Q_OS_WIN
|
#include "OpenVrHelpers.h"
|
||||||
|
|
||||||
extern vr::TrackedDevicePose_t _trackedDevicePose[vr::k_unMaxTrackedDeviceCount];
|
extern vr::TrackedDevicePose_t _trackedDevicePose[vr::k_unMaxTrackedDeviceCount];
|
||||||
extern mat4 _trackedDevicePoseMat4[vr::k_unMaxTrackedDeviceCount];
|
extern mat4 _trackedDevicePoseMat4[vr::k_unMaxTrackedDeviceCount];
|
||||||
#endif
|
|
||||||
|
|
||||||
vr::IVRSystem* acquireOpenVrSystem();
|
vr::IVRSystem* acquireOpenVrSystem();
|
||||||
void releaseOpenVrSystem();
|
void releaseOpenVrSystem();
|
||||||
|
@ -39,7 +38,7 @@ static const float CONTROLLER_LENGTH_OFFSET = 0.0762f; // three inches
|
||||||
static const glm::vec3 CONTROLLER_OFFSET = glm::vec3(CONTROLLER_LENGTH_OFFSET / 2.0f,
|
static const glm::vec3 CONTROLLER_OFFSET = glm::vec3(CONTROLLER_LENGTH_OFFSET / 2.0f,
|
||||||
CONTROLLER_LENGTH_OFFSET / 2.0f,
|
CONTROLLER_LENGTH_OFFSET / 2.0f,
|
||||||
CONTROLLER_LENGTH_OFFSET * 2.0f);
|
CONTROLLER_LENGTH_OFFSET * 2.0f);
|
||||||
static const QString CONTROLLER_MODEL_STRING = "vr_controller_05_wireless_b";
|
static const char* CONTROLLER_MODEL_STRING = "vr_controller_05_wireless_b";
|
||||||
|
|
||||||
static const QString MENU_PARENT = "Avatar";
|
static const QString MENU_PARENT = "Avatar";
|
||||||
static const QString MENU_NAME = "Vive Controllers";
|
static const QString MENU_NAME = "Vive Controllers";
|
||||||
|
@ -49,19 +48,14 @@ static const QString RENDER_CONTROLLERS = "Render Hand Controllers";
|
||||||
const QString ViveControllerManager::NAME = "OpenVR";
|
const QString ViveControllerManager::NAME = "OpenVR";
|
||||||
|
|
||||||
bool ViveControllerManager::isSupported() const {
|
bool ViveControllerManager::isSupported() const {
|
||||||
#ifdef Q_OS_WIN
|
|
||||||
auto hmd = acquireOpenVrSystem();
|
auto hmd = acquireOpenVrSystem();
|
||||||
bool success = hmd != nullptr;
|
bool success = hmd != nullptr;
|
||||||
releaseOpenVrSystem();
|
releaseOpenVrSystem();
|
||||||
return success;
|
return success;
|
||||||
#else
|
|
||||||
return false;
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ViveControllerManager::activate() {
|
void ViveControllerManager::activate() {
|
||||||
InputPlugin::activate();
|
InputPlugin::activate();
|
||||||
#ifdef Q_OS_WIN
|
|
||||||
_container->addMenu(MENU_PATH);
|
_container->addMenu(MENU_PATH);
|
||||||
_container->addMenuItem(PluginType::INPUT_PLUGIN, MENU_PATH, RENDER_CONTROLLERS,
|
_container->addMenuItem(PluginType::INPUT_PLUGIN, MENU_PATH, RENDER_CONTROLLERS,
|
||||||
[this] (bool clicked) { this->setRenderControllers(clicked); },
|
[this] (bool clicked) { this->setRenderControllers(clicked); },
|
||||||
|
@ -72,8 +66,11 @@ void ViveControllerManager::activate() {
|
||||||
}
|
}
|
||||||
Q_ASSERT(_hmd);
|
Q_ASSERT(_hmd);
|
||||||
|
|
||||||
|
auto renderModels = vr::VRRenderModels();
|
||||||
|
|
||||||
vr::RenderModel_t model;
|
vr::RenderModel_t model;
|
||||||
if (!_hmd->LoadRenderModel(CONTROLLER_MODEL_STRING.toStdString().c_str(), &model)) {
|
/*
|
||||||
|
if (!_hmd->LoadRenderModel(CONTROLLER_MODEL_STRING, &model)) {
|
||||||
qDebug() << QString("Unable to load render model %1\n").arg(CONTROLLER_MODEL_STRING);
|
qDebug() << QString("Unable to load render model %1\n").arg(CONTROLLER_MODEL_STRING);
|
||||||
} else {
|
} else {
|
||||||
model::Mesh* mesh = new model::Mesh();
|
model::Mesh* mesh = new model::Mesh();
|
||||||
|
@ -118,7 +115,7 @@ void ViveControllerManager::activate() {
|
||||||
_modelLoaded = true;
|
_modelLoaded = true;
|
||||||
_renderControllers = true;
|
_renderControllers = true;
|
||||||
}
|
}
|
||||||
#endif
|
*/
|
||||||
|
|
||||||
// unregister with UserInputMapper
|
// unregister with UserInputMapper
|
||||||
auto userInputMapper = DependencyManager::get<controller::UserInputMapper>();
|
auto userInputMapper = DependencyManager::get<controller::UserInputMapper>();
|
||||||
|
@ -129,7 +126,6 @@ void ViveControllerManager::activate() {
|
||||||
void ViveControllerManager::deactivate() {
|
void ViveControllerManager::deactivate() {
|
||||||
InputPlugin::deactivate();
|
InputPlugin::deactivate();
|
||||||
|
|
||||||
#ifdef Q_OS_WIN
|
|
||||||
_container->removeMenuItem(MENU_NAME, RENDER_CONTROLLERS);
|
_container->removeMenuItem(MENU_NAME, RENDER_CONTROLLERS);
|
||||||
_container->removeMenu(MENU_PATH);
|
_container->removeMenu(MENU_PATH);
|
||||||
|
|
||||||
|
@ -139,7 +135,6 @@ void ViveControllerManager::deactivate() {
|
||||||
}
|
}
|
||||||
|
|
||||||
_inputDevice->_poseStateMap.clear();
|
_inputDevice->_poseStateMap.clear();
|
||||||
#endif
|
|
||||||
|
|
||||||
// unregister with UserInputMapper
|
// unregister with UserInputMapper
|
||||||
auto userInputMapper = DependencyManager::get<controller::UserInputMapper>();
|
auto userInputMapper = DependencyManager::get<controller::UserInputMapper>();
|
||||||
|
@ -225,7 +220,6 @@ void ViveControllerManager::pluginUpdate(float deltaTime, bool jointsCaptured) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void ViveControllerManager::InputDevice::update(float deltaTime, bool jointsCaptured) {
|
void ViveControllerManager::InputDevice::update(float deltaTime, bool jointsCaptured) {
|
||||||
#ifdef Q_OS_WIN
|
|
||||||
_poseStateMap.clear();
|
_poseStateMap.clear();
|
||||||
|
|
||||||
_buttonPressedMap.clear();
|
_buttonPressedMap.clear();
|
||||||
|
@ -276,7 +270,6 @@ void ViveControllerManager::InputDevice::update(float deltaTime, bool jointsCapt
|
||||||
}
|
}
|
||||||
|
|
||||||
_trackedControllers = numTrackedControllers;
|
_trackedControllers = numTrackedControllers;
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ViveControllerManager::InputDevice::focusOutEvent() {
|
void ViveControllerManager::InputDevice::focusOutEvent() {
|
||||||
|
@ -286,7 +279,6 @@ void ViveControllerManager::InputDevice::focusOutEvent() {
|
||||||
|
|
||||||
// These functions do translation from the Steam IDs to the standard controller IDs
|
// These functions do translation from the Steam IDs to the standard controller IDs
|
||||||
void ViveControllerManager::InputDevice::handleAxisEvent(uint32_t axis, float x, float y, bool left) {
|
void ViveControllerManager::InputDevice::handleAxisEvent(uint32_t axis, float x, float y, bool left) {
|
||||||
#ifdef Q_OS_WIN
|
|
||||||
//FIX ME? It enters here every frame: probably we want to enter only if an event occurs
|
//FIX ME? It enters here every frame: probably we want to enter only if an event occurs
|
||||||
axis += vr::k_EButton_Axis0;
|
axis += vr::k_EButton_Axis0;
|
||||||
using namespace controller;
|
using namespace controller;
|
||||||
|
@ -296,12 +288,10 @@ void ViveControllerManager::InputDevice::handleAxisEvent(uint32_t axis, float x,
|
||||||
} else if (axis == vr::k_EButton_SteamVR_Trigger) {
|
} else if (axis == vr::k_EButton_SteamVR_Trigger) {
|
||||||
_axisStateMap[left ? LT : RT] = x;
|
_axisStateMap[left ? LT : RT] = x;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// These functions do translation from the Steam IDs to the standard controller IDs
|
// These functions do translation from the Steam IDs to the standard controller IDs
|
||||||
void ViveControllerManager::InputDevice::handleButtonEvent(uint32_t button, bool pressed, bool left) {
|
void ViveControllerManager::InputDevice::handleButtonEvent(uint32_t button, bool pressed, bool left) {
|
||||||
#ifdef Q_OS_WIN
|
|
||||||
if (!pressed) {
|
if (!pressed) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -319,7 +309,6 @@ void ViveControllerManager::InputDevice::handleButtonEvent(uint32_t button, bool
|
||||||
//FIX ME: not able to ovrewrite the behaviour of this button
|
//FIX ME: not able to ovrewrite the behaviour of this button
|
||||||
_buttonPressedMap.insert(left ? controller::LEFT_SECONDARY_THUMB : controller::RIGHT_SECONDARY_THUMB);
|
_buttonPressedMap.insert(left ? controller::LEFT_SECONDARY_THUMB : controller::RIGHT_SECONDARY_THUMB);
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ViveControllerManager::InputDevice::handlePoseEvent(const mat4& mat, bool left) {
|
void ViveControllerManager::InputDevice::handlePoseEvent(const mat4& mat, bool left) {
|
|
@ -20,7 +20,7 @@
|
||||||
#include <model/Geometry.h>
|
#include <model/Geometry.h>
|
||||||
#include <gpu/Texture.h>
|
#include <gpu/Texture.h>
|
||||||
#include <controllers/InputDevice.h>
|
#include <controllers/InputDevice.h>
|
||||||
#include "InputPlugin.h"
|
#include <plugins/InputPlugin.h>
|
||||||
#include <RenderArgs.h>
|
#include <RenderArgs.h>
|
||||||
#include <render/Scene.h>
|
#include <render/Scene.h>
|
||||||
|
|
1
plugins/openvr/src/plugin.json
Normal file
1
plugins/openvr/src/plugin.json
Normal file
|
@ -0,0 +1 @@
|
||||||
|
{}
|
Loading…
Reference in a new issue