Merge branch 'master' of https://github.com/highfidelity/hifi into rightClickMenu

This commit is contained in:
Brad Hefta-Gaub 2015-12-22 11:54:34 -08:00
commit cc00aa01fb
15 changed files with 239 additions and 152 deletions

View file

@ -197,6 +197,10 @@ if (WIN32)
add_paths_to_fixup_libs("${QT_DIR}/bin")
endif ()
if (NOT DEFINED SERVER_ONLY)
set(SERVER_ONLY 0)
endif()
# add subdirectories for all targets
if (NOT ANDROID)
add_subdirectory(assignment-client)
@ -205,14 +209,16 @@ if (NOT ANDROID)
set_target_properties(domain-server PROPERTIES FOLDER "Apps")
add_subdirectory(ice-server)
set_target_properties(ice-server PROPERTIES FOLDER "Apps")
add_subdirectory(interface)
set_target_properties(interface PROPERTIES FOLDER "Apps")
add_subdirectory(stack-manager)
set_target_properties(stack-manager PROPERTIES FOLDER "Apps")
add_subdirectory(tests)
add_subdirectory(plugins)
if (NOT SERVER_ONLY)
add_subdirectory(interface)
set_target_properties(interface PROPERTIES FOLDER "Apps")
add_subdirectory(tests)
add_subdirectory(plugins)
endif()
add_subdirectory(tools)
endif ()
endif()
if (ANDROID OR DESKTOP_GVR)
add_subdirectory(gvr-interface)

View file

@ -140,9 +140,33 @@ var importingSVOTextOverlay = Overlays.addOverlay("text", {
});
var MARKETPLACE_URL = "https://metaverse.highfidelity.com/marketplace";
var marketplaceWindow = new WebWindow('Marketplace', MARKETPLACE_URL, 900, 700, false);
var marketplaceWindow = new OverlayWebWindow('Marketplace', "about:blank", 900, 700, false);
marketplaceWindow.setVisible(false);
function showMarketplace(marketplaceID) {
var url = MARKETPLACE_URL;
if (marketplaceID) {
url = url + "/items/" + marketplaceID;
}
print("setting marketplace URL to " + url);
marketplaceWindow.setURL(url);
marketplaceWindow.setVisible(true);
marketplaceWindow.raise();
}
function hideMarketplace() {
marketplaceWindow.setVisible(false);
marketplaceWindow.setURL("about:blank");
}
function toggleMarketplace() {
if (marketplaceWindow.visible) {
hideMarketplace();
} else {
showMarketplace();
}
}
var toolBar = (function() {
var that = {},
toolBar,
@ -413,12 +437,9 @@ var toolBar = (function() {
newModelButtonDown = true;
return true;
}
if (browseMarketplaceButton === toolBar.clicked(clickedOverlay)) {
if (marketplaceWindow.url != MARKETPLACE_URL) {
marketplaceWindow.setURL(MARKETPLACE_URL);
}
marketplaceWindow.setVisible(true);
marketplaceWindow.raise();
toggleMarketplace();
return true;
}
@ -1336,6 +1357,7 @@ function getPositionToCreateEntity() {
}
function importSVO(importURL) {
print("Import URL requested: " + importURL)
if (!Entities.canAdjustLocks()) {
Window.alert(INSUFFICIENT_PERMISSIONS_IMPORT_ERROR_MSG);
return;
@ -1574,11 +1596,7 @@ PropertiesTool = function(opts) {
pushCommandForSelections();
selectionManager._update();
} else if (data.type == "showMarketplace") {
if (marketplaceWindow.url != data.url) {
marketplaceWindow.setURL(data.url);
}
marketplaceWindow.setVisible(true);
marketplaceWindow.raise();
showMarketplace();
} else if (data.type == "action") {
if (data.action == "moveSelectionToGrid") {
if (selectionManager.hasSelection()) {
@ -1859,12 +1877,7 @@ var propertyMenu = PopupMenu();
propertyMenu.onSelectMenuItem = function(name) {
if (propertyMenu.marketplaceID) {
var url = MARKETPLACE_URL + "/items/" + propertyMenu.marketplaceID;
if (marketplaceWindow.url != url) {
marketplaceWindow.setURL(url);
}
marketplaceWindow.setVisible(true);
marketplaceWindow.raise();
showMarketplace(propertyMenu.marketplaceID);
}
};

View file

@ -13,12 +13,18 @@ VrDialog {
HifiConstants { id: hifi }
title: "WebWindow"
resizable: true
// Don't destroy on close... otherwise the JS/C++ will have a dangling pointer
destroyOnCloseButton: false
contentImplicitWidth: clientArea.implicitWidth
contentImplicitHeight: clientArea.implicitHeight
backgroundColor: "#7f000000"
property url source: "about:blank"
signal navigating(string url)
function stop() {
webview.stop();
}
Component.onCompleted: {
enabled = true
@ -26,18 +32,14 @@ VrDialog {
webview.javaScriptConsoleMessage.connect(function(level, message, lineNumber, sourceID) {
console.log("Web Window JS message: " + sourceID + " " + lineNumber + " " + message);
});
webview.loadingChanged.connect(handleWebviewLoading)
}
function handleWebviewLoading(loadRequest) {
var HIFI_URL_PATTERN = /^hifi:\/\//;
if (WebEngineView.LoadStartedStatus == loadRequest.status) {
var newUrl = loadRequest.url.toString();
if (newUrl.match(HIFI_URL_PATTERN)) {
root.navigating(newUrl);
}
root.navigating(newUrl)
}
}
@ -54,9 +56,18 @@ VrDialog {
id: webview
url: root.source
anchors.fill: parent
profile: WebEngineProfile {
httpUserAgent: "Mozilla/5.0 (HighFidelityInterface)"
onUrlChanged: {
var currentUrl = url.toString();
var newUrl = urlFixer.fixupUrl(currentUrl);
if (newUrl != currentUrl) {
url = newUrl;
}
}
profile: WebEngineProfile {
id: webviewProfile
httpUserAgent: "Mozilla/5.0 (HighFidelityInterface)"
storageName: "qmlWebEngine"
}
}
} // item
} // dialog

View file

@ -4201,7 +4201,7 @@ void Application::registerScriptEngineWithApplicationServices(ScriptEngine* scri
scriptEngine->registerGlobalObject("ScriptDiscoveryService", this->getRunningScriptsWidget());
}
bool Application::canAcceptURL(const QString& urlString) {
bool Application::canAcceptURL(const QString& urlString) const {
QUrl url(urlString);
if (urlString.startsWith(HIFI_URL_SCHEME)) {
return true;

View file

@ -38,6 +38,7 @@
#include <SimpleMovingAverage.h>
#include <StDev.h>
#include <ViewFrustum.h>
#include <AbstractUriHandler.h>
#include "avatar/AvatarUpdate.h"
#include "avatar/MyAvatar.h"
@ -88,7 +89,7 @@ class Application;
#endif
#define qApp (static_cast<Application*>(QCoreApplication::instance()))
class Application : public QApplication, public AbstractViewStateInterface, public AbstractScriptingServicesInterface {
class Application : public QApplication, public AbstractViewStateInterface, public AbstractScriptingServicesInterface, public AbstractUriHandler {
Q_OBJECT
// TODO? Get rid of those
@ -219,8 +220,8 @@ public:
QString getScriptsLocation();
void setScriptsLocation(const QString& scriptsLocation);
bool canAcceptURL(const QString& url);
bool acceptURL(const QString& url, bool defaultUpload = false);
virtual bool canAcceptURL(const QString& url) const override;
virtual bool acceptURL(const QString& url, bool defaultUpload = false) override;
void setMaxOctreePacketsPerSecond(int maxOctreePPS);
int getMaxOctreePacketsPerSecond();

View file

@ -0,0 +1,19 @@
//
// Created by Bradley Austin Davis on 2015/12/17
// Copyright 2013-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
#ifndef hifi_network_AbstractUriHandler_h
#define hifi_network_AbstractUriHandler_h
class AbstractUriHandler {
public:
virtual bool canAcceptURL(const QString& url) const = 0;
virtual bool acceptURL(const QString& url, bool defaultUpload = false) = 0;
};
#endif

View file

@ -1867,7 +1867,7 @@ bool Octree::readJSONFromStream(unsigned long streamLength, QDataStream& inputSt
QByteArray jsonBuffer;
char* rawData = new char[READ_JSON_BUFFER_SIZE];
while (true) {
while (!inputStream.atEnd()) {
int got = inputStream.readRawData(rawData, READ_JSON_BUFFER_SIZE - 1);
if (got < 0) {
qCritical() << "error while reading from json stream";

View file

@ -10,18 +10,20 @@
#include <mutex>
#include <QtCore/QThread>
#include <QtScript/QScriptContext>
#include <QtScript/QScriptEngine>
#include <QtQuick/QQuickItem>
#include <QtWebSockets/QWebSocketServer>
#include <QtWebSockets/QWebSocket>
#include <QtWebChannel/QWebChannel>
#include <QtCore/QCoreApplication>
#include <QtCore/QJsonDocument>
#include <QtCore/QJsonObject>
#include <QtCore/QUrl>
#include <QtCore/QUrlQuery>
#include <QtCore/QThread>
#include <QtQml/QQmlContext>
#include <QtScript/QScriptContext>
#include <QtScript/QScriptEngine>
#include <QtWebChannel/QWebChannel>
#include <QtWebSockets/QWebSocketServer>
#include <QtWebSockets/QWebSocket>
#include <AbstractUriHandler.h>
#include <AddressManager.h>
#include <DependencyManager.h>
@ -83,17 +85,41 @@ void QmlWebWindowClass::setupServer() {
}
}
class UrlFixer : public QObject {
Q_OBJECT
public:
Q_INVOKABLE QString fixupUrl(const QString& originalUrl) {
static const QString ACCESS_TOKEN_PARAMETER = "access_token";
static const QString ALLOWED_HOST = "metaverse.highfidelity.com";
QString result = originalUrl;
QUrl url(originalUrl);
QUrlQuery query(url);
if (url.host() == ALLOWED_HOST && query.allQueryItemValues(ACCESS_TOKEN_PARAMETER).empty()) {
qDebug() << "Updating URL with auth token";
AccountManager& accountManager = AccountManager::getInstance();
query.addQueryItem(ACCESS_TOKEN_PARAMETER, accountManager.getAccountInfo().getAccessToken().token);
url.setQuery(query.query());
result = url.toString();
}
return result;
}
};
static UrlFixer URL_FIXER;
// Method called by Qt scripts to create a new web window in the overlay
QScriptValue QmlWebWindowClass::constructor(QScriptContext* context, QScriptEngine* engine) {
QmlWebWindowClass* retVal { nullptr };
const QString title = context->argument(0).toString();
QString url = context->argument(1).toString();
if (!url.startsWith("http") && !url.startsWith("file://")) {
if (!url.startsWith("http") && !url.startsWith("file://") && !url.startsWith("about:")) {
url = QUrl::fromLocalFile(url).toString();
}
const int width = std::max(100, std::min(1280, context->argument(2).toInt32()));;
const int height = std::max(100, std::min(720, context->argument(3).toInt32()));;
// Build the event bridge and wrapper on the main thread
QMetaObject::invokeMethod(DependencyManager::get<OffscreenUi>().data(), "load", Qt::BlockingQueuedConnection,
Q_ARG(const QString&, "QmlWebWindow.qml"),
@ -101,6 +127,7 @@ QScriptValue QmlWebWindowClass::constructor(QScriptContext* context, QScriptEngi
setupServer();
retVal = new QmlWebWindowClass(object);
webChannel.registerObject(url.toLower(), retVal);
context->setContextProperty("urlFixer", &URL_FIXER);
retVal->setTitle(title);
retVal->setURL(url);
retVal->setSize(width, height);
@ -119,7 +146,23 @@ QmlWebWindowClass::QmlWebWindowClass(QObject* qmlWindow)
}
void QmlWebWindowClass::handleNavigation(const QString& url) {
DependencyManager::get<AddressManager>()->handleLookupString(url);
bool handled = false;
if (url.contains(HIFI_URL_PATTERN)) {
DependencyManager::get<AddressManager>()->handleLookupString(url);
handled = true;
} else {
static auto handler = dynamic_cast<AbstractUriHandler*>(qApp);
if (handler) {
if (handler->canAcceptURL(url)) {
handled = handler->acceptURL(url);
}
}
}
if (handled) {
QMetaObject::invokeMethod(_qmlWindow, "stop", Qt::AutoConnection);
}
}
void QmlWebWindowClass::setVisible(bool visible) {
@ -202,6 +245,7 @@ QString QmlWebWindowClass::getURL() const {
QMetaObject::invokeMethod(const_cast<QmlWebWindowClass*>(this), "getURL", Qt::BlockingQueuedConnection, Q_RETURN_ARG(QString, result));
return result;
}
return _qmlWindow->property(URL_PROPERTY).toString();
}

View file

@ -10,11 +10,12 @@
#define hifi_ui_QmlWebWindowClass_h
#include <QtCore/QObject>
#include <GLMHelpers.h>
#include <QtScript/QScriptValue>
#include <QtQuick/QQuickItem>
#include <QtWebChannel/QWebChannelAbstractTransport>
#include <GLMHelpers.h>
class QScriptEngine;
class QScriptContext;
class QmlWebWindowClass;

View file

@ -13,6 +13,9 @@
#ifdef HAVE_SIXENSE
#include <sixense.h>
#else
#define SIXENSE_FAILURE -1
#define SIXENSE_SUCCESS 0
#endif
#include <QCoreApplication>
@ -43,6 +46,14 @@ static const unsigned int BUTTON_TRIGGER = 1U << 8;
const glm::vec3 SixenseManager::DEFAULT_AVATAR_POSITION { -0.25f, -0.35f, -0.3f }; // in hydra frame
const float SixenseManager::CONTROLLER_THRESHOLD { 0.35f };
bool SixenseManager::_sixenseLoaded = false;
#define BAIL_IF_NOT_LOADED \
if (!_sixenseLoaded) { \
return; \
}
const QString SixenseManager::NAME = "Sixense";
const QString SixenseManager::HYDRA_ID_STRING = "Razer Hydra";
@ -89,11 +100,12 @@ void SixenseManager::activate() {
userInputMapper->registerDevice(_inputDevice);
loadSettings();
sixenseInit();
_sixenseLoaded = (sixenseInit() == SIXENSE_SUCCESS);
#endif
}
void SixenseManager::deactivate() {
BAIL_IF_NOT_LOADED
InputPlugin::deactivate();
#ifdef HAVE_SIXENSE
@ -114,12 +126,14 @@ void SixenseManager::deactivate() {
}
void SixenseManager::setSixenseFilter(bool filter) {
BAIL_IF_NOT_LOADED
#ifdef HAVE_SIXENSE
sixenseSetFilterEnabled(filter ? 1 : 0);
#endif
}
void SixenseManager::pluginUpdate(float deltaTime, bool jointsCaptured) {
BAIL_IF_NOT_LOADED
_inputDevice->update(deltaTime, jointsCaptured);
if (_inputDevice->_requestReset) {
_container->requestReset();
@ -128,6 +142,7 @@ void SixenseManager::pluginUpdate(float deltaTime, bool jointsCaptured) {
}
void SixenseManager::InputDevice::update(float deltaTime, bool jointsCaptured) {
BAIL_IF_NOT_LOADED
#ifdef HAVE_SIXENSE
_buttonPressedMap.clear();
@ -246,6 +261,7 @@ void SixenseManager::InputDevice::update(float deltaTime, bool jointsCaptured) {
}
void SixenseManager::InputDevice::setDebugDrawRaw(bool flag) {
BAIL_IF_NOT_LOADED
_debugDrawRaw = flag;
if (!flag) {
DebugDraw::getInstance().removeMyAvatarMarker("SIXENSE_RAW_LEFT");
@ -254,6 +270,7 @@ void SixenseManager::InputDevice::setDebugDrawRaw(bool flag) {
}
void SixenseManager::InputDevice::setDebugDrawCalibrated(bool flag) {
BAIL_IF_NOT_LOADED
_debugDrawCalibrated = flag;
if (!flag) {
DebugDraw::getInstance().removeMyAvatarMarker("SIXENSE_CALIBRATED_LEFT");
@ -281,6 +298,7 @@ static bool calibrationRequested(SixenseControllerData* controllers) {
}
void SixenseManager::InputDevice::updateCalibration(SixenseControllerData* controllers) {
BAIL_IF_NOT_LOADED
const SixenseControllerData* dataLeft = controllers;
const SixenseControllerData* dataRight = controllers + 1;
@ -365,11 +383,13 @@ void SixenseManager::InputDevice::updateCalibration(SixenseControllerData* contr
#endif // HAVE_SIXENSE
void SixenseManager::InputDevice::focusOutEvent() {
BAIL_IF_NOT_LOADED
_axisStateMap.clear();
_buttonPressedMap.clear();
};
void SixenseManager::InputDevice::handleButtonEvent(unsigned int buttons, bool left) {
BAIL_IF_NOT_LOADED
using namespace controller;
if (buttons & BUTTON_0) {
_buttonPressedMap.insert(left ? BACK : START);
@ -395,6 +415,7 @@ void SixenseManager::InputDevice::handleButtonEvent(unsigned int buttons, bool l
}
void SixenseManager::InputDevice::handlePoseEvent(float deltaTime, glm::vec3 position, glm::quat rotation, bool left) {
BAIL_IF_NOT_LOADED
#ifdef HAVE_SIXENSE
auto hand = left ? controller::StandardPoseChannel::LEFT_HAND : controller::StandardPoseChannel::RIGHT_HAND;

View file

@ -98,6 +98,8 @@ private:
static const QString NAME;
static const QString HYDRA_ID_STRING;
static bool _sixenseLoaded;
};
#endif // hifi_SixenseManager_h

View file

@ -63,6 +63,9 @@ void unloadSixense() {
// sixense.h wrapper for OSX dynamic linking
int sixenseInit() {
loadSixense();
if (!SIXENSE || !SIXENSE->isLoaded()) {
return SIXENSE_FAILURE;
}
return FORWARD();
}
int sixenseExit() {

View file

@ -6,8 +6,7 @@
# See the accompanying file LICENSE or http:#www.apache.org/licenses/LICENSE-2.0.html
#
#if (NOT WIN32)
if (FALSE)
if (NOT WIN32)
set(TARGET_NAME oculusLegacy)
setup_hifi_plugin()

View file

@ -26,7 +26,7 @@
using namespace oglplus;
const QString OculusLegacyDisplayPlugin::NAME("Oculus Rift (0.5)");
const QString OculusLegacyDisplayPlugin::NAME("Oculus Rift (0.5) (Simulated)");
const QString & OculusLegacyDisplayPlugin::getName() const {
return NAME;
@ -39,12 +39,6 @@ uvec2 OculusLegacyDisplayPlugin::getRecommendedRenderSize() const {
return _desiredFramebufferSize;
}
void OculusLegacyDisplayPlugin::preRender() {
ovrHmd_GetEyePoses(_hmd, _frameIndex, _eyeOffsets, _eyePoses, &_trackingState);
ovrHmd_BeginFrame(_hmd, _frameIndex);
WindowOpenGLDisplayPlugin::preRender();
}
glm::mat4 OculusLegacyDisplayPlugin::getProjection(Eye eye, const glm::mat4& baseProjection) const {
return _eyeProjections[eye];
}
@ -57,13 +51,18 @@ glm::mat4 OculusLegacyDisplayPlugin::getEyeToHeadTransform(Eye eye) const {
return toGlm(_eyePoses[eye]);
}
// 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 {
glm::mat4 OculusLegacyDisplayPlugin::getHeadPose(uint32_t frameIndex) const {
static uint32_t lastFrameSeen = 0;
if (frameIndex > lastFrameSeen) {
Lock lock(_mutex);
_trackingState = ovrHmd_GetTrackingState(_hmd, ovr_GetTimeInSeconds());
ovrHmd_GetEyePoses(_hmd, frameIndex, _eyeOffsets, _eyePoses, &_trackingState);
lastFrameSeen = frameIndex;
}
return toGlm(_trackingState.HeadPose.ThePose);
}
bool OculusLegacyDisplayPlugin::isSupported() const {
if (!ovr_Initialize(nullptr)) {
return false;
@ -92,10 +91,13 @@ bool OculusLegacyDisplayPlugin::isSupported() const {
}
void OculusLegacyDisplayPlugin::activate() {
WindowOpenGLDisplayPlugin::activate();
if (!(ovr_Initialize(nullptr))) {
Q_ASSERT(false);
qFatal("Failed to Initialize SDK");
}
_hswDismissed = false;
_hmd = ovrHmd_Create(0);
if (!_hmd) {
@ -107,13 +109,13 @@ void OculusLegacyDisplayPlugin::activate() {
_eyeFovs[eye] = _hmd->MaxEyeFov[eye];
ovrEyeRenderDesc erd = _eyeRenderDescs[eye] = ovrHmd_GetRenderDesc(_hmd, eye, _eyeFovs[eye]);
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);
ovrPerspectiveProjection =
ovrMatrix4f_Projection(erd.Fov, 0.001f, 10.0f, ovrProjection_RightHanded);
ovrMatrix4f_Projection(erd.Fov, 0.001f, 10.0f, ovrProjection_RightHanded);
_compositeEyeProjections[eye] = toGlm(ovrPerspectiveProjection);
_eyeOffsets[eye] = erd.HmdToEyeViewOffset;
eyeSizes[eye] = toGlm(ovrHmd_GetFovTextureSize(_hmd, eye, erd.Fov, 1.0f));
});
@ -121,38 +123,43 @@ void OculusLegacyDisplayPlugin::activate() {
combined.LeftTan = std::max(_eyeFovs[Left].LeftTan, _eyeFovs[Right].LeftTan);
combined.RightTan = std::max(_eyeFovs[Left].RightTan, _eyeFovs[Right].RightTan);
ovrMatrix4f ovrPerspectiveProjection =
ovrMatrix4f_Projection(combined, DEFAULT_NEAR_CLIP, DEFAULT_FAR_CLIP, ovrProjection_RightHanded);
ovrMatrix4f_Projection(combined, DEFAULT_NEAR_CLIP, DEFAULT_FAR_CLIP, ovrProjection_RightHanded);
_eyeProjections[Mono] = toGlm(ovrPerspectiveProjection);
_desiredFramebufferSize = uvec2(
eyeSizes[0].x + eyeSizes[1].x,
std::max(eyeSizes[0].y, eyeSizes[1].y));
_frameIndex = 0;
_desiredFramebufferSize = uvec2(eyeSizes[0].x + eyeSizes[1].x,
std::max(eyeSizes[0].y, eyeSizes[1].y));
if (!ovrHmd_ConfigureTracking(_hmd,
ovrTrackingCap_Orientation | ovrTrackingCap_Position | ovrTrackingCap_MagYawCorrection, 0)) {
ovrTrackingCap_Orientation | ovrTrackingCap_Position | ovrTrackingCap_MagYawCorrection, 0)) {
qFatal("Could not attach to sensor device");
}
}
WindowOpenGLDisplayPlugin::activate();
void OculusLegacyDisplayPlugin::deactivate() {
WindowOpenGLDisplayPlugin::deactivate();
ovrHmd_Destroy(_hmd);
_hmd = nullptr;
ovr_Shutdown();
}
int screen = getHmdScreen();
if (screen != -1) {
_container->setFullscreen(qApp->screens()[screen]);
}
_window->installEventFilter(this);
_window->makeCurrent();
// DLL based display plugins MUST initialize GLEW inside the DLL code.
void OculusLegacyDisplayPlugin::customizeContext() {
static std::once_flag once;
std::call_once(once, []{
glewExperimental = true;
glewInit();
glGetError();
});
WindowOpenGLDisplayPlugin::customizeContext();
#if 0
ovrGLConfig config; memset(&config, 0, sizeof(ovrRenderAPIConfig));
auto& header = config.Config.Header;
header.API = ovrRenderAPI_OpenGL;
header.BackBufferSize = _hmd->Resolution;
header.Multisample = 1;
int distortionCaps = 0
| ovrDistortionCap_TimeWarp
;
int distortionCaps = ovrDistortionCap_TimeWarp;
memset(_eyeTextures, 0, sizeof(ovrTexture) * 2);
ovr_for_each_eye([&](ovrEyeType eye) {
auto& header = _eyeTextures[eye].Header;
@ -164,74 +171,36 @@ void OculusLegacyDisplayPlugin::activate() {
header.RenderViewport.Pos.x = header.RenderViewport.Size.w;
}
});
#ifndef NDEBUG
#ifndef NDEBUG
ovrBool result =
#endif
ovrHmd_ConfigureRendering(_hmd, &config.Config, distortionCaps, _eyeFovs, _eyeRenderDescs);
#endif
ovrHmd_ConfigureRendering(_hmd, &config.Config, distortionCaps, _eyeFovs, _eyeRenderDescs);
assert(result);
}
void OculusLegacyDisplayPlugin::deactivate() {
_window->removeEventFilter(this);
WindowOpenGLDisplayPlugin::deactivate();
#endif
QScreen* riftScreen = nullptr;
if (_hmdScreen >= 0) {
riftScreen = qApp->screens()[_hmdScreen];
}
_container->unsetFullscreen(riftScreen);
ovrHmd_Destroy(_hmd);
_hmd = nullptr;
ovr_Shutdown();
}
// DLL based display plugins MUST initialize GLEW inside the DLL code.
void OculusLegacyDisplayPlugin::customizeContext() {
glewExperimental = true;
glewInit();
glGetError();
WindowOpenGLDisplayPlugin::customizeContext();
#if 0
void OculusLegacyDisplayPlugin::uncustomizeContext() {
WindowOpenGLDisplayPlugin::uncustomizeContext();
}
void OculusLegacyDisplayPlugin::preDisplay() {
_window->makeCurrent();
}
void OculusLegacyDisplayPlugin::display(GLuint finalTexture, const glm::uvec2& sceneSize) {
++_frameIndex;
void OculusLegacyDisplayPlugin::internalPresent() {
ovrHmd_BeginFrame(_hmd, 0);
ovr_for_each_eye([&](ovrEyeType eye) {
reinterpret_cast<ovrGLTexture&>(_eyeTextures[eye]).OGL.TexId = finalTexture;
reinterpret_cast<ovrGLTexture&>(_eyeTextures[eye]).OGL.TexId = _currentSceneTexture;
});
ovrHmd_EndFrame(_hmd, _eyePoses, _eyeTextures);
}
// Pass input events on to the application
bool OculusLegacyDisplayPlugin::eventFilter(QObject* receiver, QEvent* event) {
if (!_hswDismissed && (event->type() == QEvent::KeyPress)) {
static ovrHSWDisplayState hswState;
ovrHmd_GetHSWDisplayState(_hmd, &hswState);
if (hswState.Displayed) {
ovrHmd_DismissHSWDisplay(_hmd);
} else {
_hswDismissed = true;
}
}
return WindowOpenGLDisplayPlugin::eventFilter(receiver, event);
}
// FIXME mirroring tot he main window is diffucult on OSX because it requires that we
// trigger a swap, which causes the client to wait for the v-sync of the main screen running
// at 60 Hz. This would introduce judder. Perhaps we can push mirroring to a separate
// thread
// FIXME If we move to the 'batch rendering on a different thread' we can possibly do this.
// however, we need to make sure it doesn't block the event handling.
void OculusLegacyDisplayPlugin::finishFrame() {
_window->doneCurrent();
};
#endif
int OculusLegacyDisplayPlugin::getHmdScreen() const {
return _hmdScreen;
}
float OculusLegacyDisplayPlugin::getTargetFrameRate() {
return TARGET_RATE_OculusLegacy;
}

View file

@ -24,11 +24,8 @@ public:
virtual void activate() override;
virtual void deactivate() override;
virtual bool eventFilter(QObject* receiver, QEvent* event) override;
virtual int getHmdScreen() const override;
virtual float getTargetFrameRate() override { return TARGET_RATE_OculusLegacy; }
// Stereo specific methods
virtual bool isHmd() const override { return true; }
virtual glm::mat4 getProjection(Eye eye, const glm::mat4& baseProjection) const override;
@ -36,23 +33,24 @@ public:
virtual glm::uvec2 getRecommendedUiSize() const override { return uvec2(1920, 1080); }
virtual void resetSensors() override;
virtual glm::mat4 getEyeToHeadTransform(Eye eye) const override;
virtual glm::mat4 getHeadPose() const override;
virtual glm::mat4 getHeadPose(uint32_t frameIndex) const override;
virtual float getTargetFrameRate() override;
protected:
virtual void customizeContext() override;
virtual void preRender() override;
virtual void preDisplay() override;
virtual void display(GLuint finalTexture, const glm::uvec2& sceneSize) override;
// Do not perform swap in finish
virtual void finishFrame() override;
#if 0
virtual void uncustomizeContext() override;
virtual void internalPresent() override;
#endif
private:
static const QString NAME;
ovrHmd _hmd;
ovrTrackingState _trackingState;
mutable ovrTrackingState _trackingState;
ovrEyeRenderDesc _eyeRenderDescs[2];
ovrPosef _eyePoses[2];
mutable ovrPosef _eyePoses[2];
ovrVector3f _eyeOffsets[2];
ovrFovPort _eyeFovs[2];
mat4 _eyeProjections[3];