Merge branch 'master' of github.com:highfidelity/hifi into near-grab-via-parenting

This commit is contained in:
Seth Alves 2015-12-22 11:23:09 -08:00
commit 5e4a165b4d
30 changed files with 698 additions and 537 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

@ -1,77 +0,0 @@
set(EXTERNAL_NAME qxmpp)
# we need to find qmake inside QT_DIR
find_program(QMAKE_COMMAND NAME qmake PATHS ${QT_DIR}/bin $ENV{QTTOOLDIR} NO_DEFAULT_PATH)
if (NOT QMAKE_COMMAND)
message(FATAL_ERROR "Could not find qmake. Qxmpp cannot be compiled without qmake.")
endif ()
if (ANDROID)
set(ANDROID_CMAKE_ARGS "-DCMAKE_TOOLCHAIN_FILE=${CMAKE_TOOLCHAIN_FILE}" "-DANDROID_NATIVE_API_LEVEL=19")
endif ()
if (WIN32)
find_program(PLATFORM_BUILD_COMMAND nmake PATHS "C:/Program Files (x86)/Microsoft Visual Studio 12.0/VC/bin")
if (NOT PLATFORM_BUILD_COMMAND)
message(FATAL_ERROR "You asked CMake to grap QXmpp and build it, but nmake was not found. Please make sure the folder containing nmake.exe is in your PATH.")
endif ()
else ()
find_program(PLATFORM_BUILD_COMMAND make)
endif ()
include(ExternalProject)
ExternalProject_Add(
${EXTERNAL_NAME}
URL http://qxmpp.googlecode.com/files/qxmpp-0.7.6.tar.gz
URL_MD5 ee45a97313306ded2ff0f6618a3ed1e1
BUILD_IN_SOURCE 1
PATCH_COMMAND patch -p2 -t -N --verbose < ${CMAKE_CURRENT_SOURCE_DIR}/qxmpp.patch
CONFIGURE_COMMAND ${QMAKE_COMMAND} PREFIX=<INSTALL_DIR>
BUILD_COMMAND ${PLATFORM_BUILD_COMMAND}
INSTALL_COMMAND ${PLATFORM_BUILD_COMMAND} install
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")
ExternalProject_Get_Property(${EXTERNAL_NAME} INSTALL_DIR)
if (CMAKE_GENERATOR STREQUAL Xcode)
find_program(DITTO_COMMAND ditto)
ExternalProject_Add_Step(
${EXTERNAL_NAME}
copy-from-xcode-install
COMMENT "Copying from /tmp/hifi.dst${INSTALL_DIR} to move install to proper location"
COMMAND ${DITTO_COMMAND} /tmp/hifi.dst${INSTALL_DIR} ${INSTALL_DIR}
DEPENDEES install
LOG 1
)
endif ()
string(TOUPPER ${EXTERNAL_NAME} EXTERNAL_NAME_UPPER)
set(${EXTERNAL_NAME_UPPER}_INCLUDE_DIRS ${INSTALL_DIR}/include CACHE FILEPATH "Path to Qxmpp include directory")
set(_LIB_DIR ${INSTALL_DIR}/lib)
if (WIN32)
set(_LIB_EXT "0.lib")
set(${EXTERNAL_NAME_UPPER}_DLL_PATH ${_LIB_DIR} CACHE PATH "Location of QXmpp DLL")
else ()
if (APPLE)
set(_LIB_EXT ".dylib")
else ()
set(_LIB_EXT ".so")
endif ()
set(_LIB_PREFIX "lib")
endif ()
set(${EXTERNAL_NAME_UPPER}_LIBRARY_RELEASE ${_LIB_DIR}/${_LIB_PREFIX}qxmpp${_LIB_EXT} CACHE FILEPATH "Path to QXmpp release library")
set(${EXTERNAL_NAME_UPPER}_LIBRARY_DEBUG "" CACHE FILEPATH "Path to QXmpp debug library")

View file

@ -9,13 +9,14 @@
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
//
var whichHand = Controller.Standard.RightHand;
var whichTrigger = Controller.Standard.RT;
var DEBUGGING = false;
Math.clamp=function(a,b,c) {
return Math.max(b,Math.min(c,a));
}
var whichHand = Controller.Standard.RightHand;
var whichTrigger = Controller.Standard.RT;
function length(posA, posB) {
var dx = posA.x - posB.x;
var dy = posA.y - posB.y;
@ -61,35 +62,37 @@ mapping.from(whichHand).peek().to(function(pose) {
var rotated = Vec3.multiplyQbyV(pose.rotation, Vec3.UNIT_NEG_Y); //
var absolutePitch = rotated.y; // from 1 down to -1 up ... but note: if you rotate down "too far" it starts to go up again...
var absoluteYaw = rotated.z; // from -1 left to 1 right
//print("absolutePitch:" + absolutePitch);
//print("absoluteYaw:" + absoluteYaw);
//Vec3.print("rotated:", rotated);
var absoluteYaw = -rotated.x; // from -1 left to 1 right
if (DEBUGGING) {
print("absolutePitch:" + absolutePitch);
print("absoluteYaw:" + absoluteYaw);
Vec3.print("rotated:", rotated);
}
var ROTATION_BOUND = 0.6;
var clampYaw = Math.clamp(absoluteYaw, -ROTATION_BOUND, ROTATION_BOUND);
var clampPitch = Math.clamp(absolutePitch, -ROTATION_BOUND, ROTATION_BOUND);
//var clampYaw = absoluteYaw;
//print("clampYaw:" + clampYaw);
//print("clampPitch:" + clampPitch);
if (DEBUGGING) {
print("clampYaw:" + clampYaw);
print("clampPitch:" + clampPitch);
}
// if using entire span...
//var xRatio = (absoluteYaw + 1) / 2;
//var yRatio = (absolutePitch + 1) / 2;
// if using only from -0.5 to 0.5
// using only from -ROTATION_BOUND to ROTATION_BOUND
var xRatio = (clampYaw + ROTATION_BOUND) / (2 * ROTATION_BOUND);
var yRatio = (clampPitch + ROTATION_BOUND) / (2 * ROTATION_BOUND);
//print("xRatio:" + xRatio);
//print("yRatio:" + yRatio);
//print("ratio x:" + xRatio + " y:" + yRatio);
if (DEBUGGING) {
print("xRatio:" + xRatio);
print("yRatio:" + yRatio);
}
var x = screenSizeX * xRatio;
var y = screenSizeY * yRatio;
//print("position x:" + x + " y:" + y);
if (DEBUGGING) {
print("position x:" + x + " y:" + y);
}
if (!(xRatio == 0.5 && yRatio == 0)) {
moveReticleAbsolute(x, y);
}

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

@ -22,7 +22,7 @@ Number.prototype.clamp = function(min, max) {
var panel = new Panel(10, 100);
function CounterWidget(parentPanel, name, feedGetter, drawGetter, capSetter, capGetter) {
this.subPanel = panel.newSubPanel(name);
this.subPanel = parentPanel.newSubPanel(name);
this.subPanel.newSlider("Num Feed", 0, 1,
function(value) { },
@ -37,12 +37,14 @@ function CounterWidget(parentPanel, name, feedGetter, drawGetter, capSetter, cap
capGetter,
function(value) { return (value); });
this.update = function () {
this.update = function () {
var numFeed = this.subPanel.get("Num Feed");
this.subPanel.set("Num Feed", numFeed);
this.subPanel.set("Num Drawn", this.subPanel.get("Num Drawn"));
var numDrawn = this.subPanel.get("Num Drawn");
var numMax = Math.max(numFeed, 1);
this.subPanel.set("Num Feed", numFeed);
this.subPanel.set("Num Drawn", numDrawn);
this.subPanel.getWidget("Num Feed").setMaxValue(numMax);
this.subPanel.getWidget("Num Drawn").setMaxValue(numMax);
this.subPanel.getWidget("Max Drawn").setMaxValue(numMax);
@ -50,46 +52,46 @@ function CounterWidget(parentPanel, name, feedGetter, drawGetter, capSetter, cap
};
var opaquesCounter = new CounterWidget(panel, "Opaques",
function () { return Render.getEngineNumFeedOpaqueItems(); },
function () { return Render.getEngineNumDrawnOpaqueItems(); },
function(value) { Render.setEngineMaxDrawnOpaqueItems(value); },
function () { return Render.getEngineMaxDrawnOpaqueItems(); }
function () { return Render.opaque.numFeed; },
function () { return Render.opaque.numDrawn; },
function(value) { Render.opaque.maxDrawn = value; },
function () { return Render.opaque.maxDrawn; }
);
var transparentsCounter = new CounterWidget(panel, "Transparents",
function () { return Render.getEngineNumFeedTransparentItems(); },
function () { return Render.getEngineNumDrawnTransparentItems(); },
function(value) { Render.setEngineMaxDrawnTransparentItems(value); },
function () { return Render.getEngineMaxDrawnTransparentItems(); }
function () { return Render.transparent.numFeed; },
function () { return Render.transparent.numDrawn; },
function(value) { Render.transparent.maxDrawn = value; },
function () { return Render.transparent.maxDrawn; }
);
var overlaysCounter = new CounterWidget(panel, "Overlays",
function () { return Render.getEngineNumFeedOverlay3DItems(); },
function () { return Render.getEngineNumDrawnOverlay3DItems(); },
function(value) { Render.setEngineMaxDrawnOverlay3DItems(value); },
function () { return Render.getEngineMaxDrawnOverlay3DItems(); }
function () { return Render.overlay3D.numFeed; },
function () { return Render.overlay3D.numDrawn; },
function(value) { Render.overlay3D.maxDrawn = value; },
function () { return Render.overlay3D.maxDrawn; }
);
var resizing = false;
var previousMode = Settings.getValue(SETTINGS_KEY, -1);
Menu.addActionGroup(MENU, ACTIONS, ACTIONS[previousMode + 1]);
Render.setEngineDeferredDebugMode(previousMode);
Render.setEngineDeferredDebugSize({ x: 0.0, y: -1.0, z: 1.0, w: 1.0 }); // Reset to default size
Render.deferredDebugMode = previousMode;
Render.deferredDebugSize = { x: 0.0, y: -1.0, z: 1.0, w: 1.0 }; // Reset to default size
function setEngineDeferredDebugSize(eventX) {
var scaledX = (2.0 * (eventX / Window.innerWidth) - 1.0).clamp(-1.0, 1.0);
Render.setEngineDeferredDebugSize({ x: scaledX, y: -1.0, z: 1.0, w: 1.0 });
Render.deferredDebugSize = { x: scaledX, y: -1.0, z: 1.0, w: 1.0 };
}
function shouldStartResizing(eventX) {
var x = Math.abs(eventX - Window.innerWidth * (1.0 + Render.getEngineDeferredDebugSize().x) / 2.0);
var mode = Render.getEngineDeferredDebugMode();
var x = Math.abs(eventX - Window.innerWidth * (1.0 + Render.deferredDebugSize.x) / 2.0);
var mode = Render.deferredDebugMode;
return mode !== -1 && x < 20;
}
function menuItemEvent(menuItem) {
var index = ACTIONS.indexOf(menuItem);
if (index >= 0) {
Render.setEngineDeferredDebugMode(index - 1);
Render.deferredDebugMode = (index - 1);
}
}
@ -98,24 +100,24 @@ var showDisplayStatusFlag = 1;
var showNetworkStatusFlag = 2;
panel.newCheckbox("Display status",
function(value) { Render.setEngineDisplayItemStatus(value ?
Render.doEngineDisplayItemStatus() | showDisplayStatusFlag :
Render.doEngineDisplayItemStatus() & ~showDisplayStatusFlag); },
function() { return (Render.doEngineDisplayItemStatus() & showDisplayStatusFlag) > 0; },
function(value) { Render.displayItemStatus = (value ?
Render.displayItemStatus | showDisplayStatusFlag :
Render.displayItemStatus & ~showDisplayStatusFlag); },
function() { return (Render.displayItemStatus & showDisplayStatusFlag) > 0; },
function(value) { return (value & showDisplayStatusFlag) > 0; }
);
panel.newCheckbox("Network/Physics status",
function(value) { Render.setEngineDisplayItemStatus(value ?
Render.doEngineDisplayItemStatus() | showNetworkStatusFlag :
Render.doEngineDisplayItemStatus() & ~showNetworkStatusFlag); },
function() { return (Render.doEngineDisplayItemStatus() & showNetworkStatusFlag) > 0; },
function(value) { Render.displayItemStatus = (value ?
Render.displayItemStatus | showNetworkStatusFlag :
Render.displayItemStatus & ~showNetworkStatusFlag); },
function() { return (Render.displayItemStatus & showNetworkStatusFlag) > 0; },
function(value) { return (value & showNetworkStatusFlag) > 0; }
);
panel.newSlider("Tone Mapping Exposure", -10, 10,
function (value) { Render.setEngineToneMappingExposure(value); },
function() { return Render.getEngineToneMappingExposure(); },
function (value) { Render.tone.exposure = value; },
function() { return Render.tone.exposure; },
function (value) { return (value); });
var tickTackPeriod = 500;
@ -160,9 +162,9 @@ Menu.menuItemEvent.connect(menuItemEvent);
function scriptEnding() {
panel.destroy();
Menu.removeActionGroup(MENU);
Settings.setValue(SETTINGS_KEY, Render.getEngineDeferredDebugMode());
Render.setEngineDeferredDebugMode(-1);
Render.setEngineDeferredDebugSize({ x: 0.0, y: -1.0, z: 1.0, w: 1.0 }); // Reset to default size
Settings.setValue(SETTINGS_KEY, Render.deferredDebugMode);
Render.deferredDebugMode = -1;
Render.deferredDebugSize = { x: 0.0, y: -1.0, z: 1.0, w: 1.0 }; // Reset to default size
}
Script.scriptEnding.connect(scriptEnding);

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

@ -3721,21 +3721,18 @@ void Application::displaySide(RenderArgs* renderArgs, Camera& theCamera, bool se
{
PerformanceTimer perfTimer("EngineRun");
auto renderInterface = DependencyManager::get<RenderScriptingInterface>();
auto renderContext = renderInterface->getRenderContext();
renderArgs->_shouldRender = LODManager::shouldRender;
renderArgs->_viewFrustum = getDisplayViewFrustum();
auto renderInterface = DependencyManager::get<RenderScriptingInterface>();
auto renderItemsConfig = renderInterface->getItemsConfig();
auto renderTone = renderInterface->getTone();
int drawStatus = renderInterface->getDrawStatus();
bool drawHitEffect = renderInterface->getDrawHitEffect();
renderContext.setArgs(renderArgs);
bool occlusionStatus = Menu::getInstance()->isOptionChecked(MenuOption::DebugAmbientOcclusion);
bool antialiasingStatus = Menu::getInstance()->isOptionChecked(MenuOption::Antialiasing);
bool showOwnedStatus = Menu::getInstance()->isOptionChecked(MenuOption::PhysicsShowOwned);
renderContext.setOptions(occlusionStatus, antialiasingStatus, showOwnedStatus);
render::RenderContext renderContext{renderArgs, renderItemsConfig, renderTone};
renderContext.setOptions(drawStatus, drawHitEffect, occlusionStatus, antialiasingStatus, showOwnedStatus);
_renderEngine->setRenderContext(renderContext);
// Before the deferred pass, let's try to use the render engine
@ -4204,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

@ -289,7 +289,6 @@ uint64_t AudioInjector::injectNextFrame() {
_currentSendOffset = 0;
} else {
// we weren't to loop, say that we're done now
qDebug() << "AudioInjector::injectNextFrame has sent all data and was not asked to loop - calling finish().";
finish();
return NEXT_FRAME_DELTA_ERROR_OR_FINISHED;
}

View file

@ -256,33 +256,38 @@ void EntityTreeRenderer::forceRecheckEntities() {
void EntityTreeRenderer::applyZonePropertiesToScene(std::shared_ptr<ZoneEntityItem> zone) {
QSharedPointer<SceneScriptingInterface> scene = DependencyManager::get<SceneScriptingInterface>();
auto sceneStage = scene->getStage();
auto sceneKeyLight = sceneStage->getKeyLight();
auto sceneLocation = sceneStage->getLocation();
auto sceneTime = sceneStage->getTime();
if (zone) {
if (!_hasPreviousZone) {
_previousKeyLightColor = scene->getKeyLightColor();
_previousKeyLightIntensity = scene->getKeyLightIntensity();
_previousKeyLightAmbientIntensity = scene->getKeyLightAmbientIntensity();
_previousKeyLightDirection = scene->getKeyLightDirection();
_previousStageSunModelEnabled = scene->isStageSunModelEnabled();
_previousStageLongitude = scene->getStageLocationLongitude();
_previousStageLatitude = scene->getStageLocationLatitude();
_previousStageAltitude = scene->getStageLocationAltitude();
_previousStageHour = scene->getStageDayTime();
_previousStageDay = scene->getStageYearTime();
_previousKeyLightColor = sceneKeyLight->getColor();
_previousKeyLightIntensity = sceneKeyLight->getIntensity();
_previousKeyLightAmbientIntensity = sceneKeyLight->getAmbientIntensity();
_previousKeyLightDirection = sceneKeyLight->getDirection();
_previousStageSunModelEnabled = sceneStage->isSunModelEnabled();
_previousStageLongitude = sceneLocation->getLongitude();
_previousStageLatitude = sceneLocation->getLatitude();
_previousStageAltitude = sceneLocation->getAltitude();
_previousStageHour = sceneTime->getHour();
_previousStageDay = sceneTime->getDay();
_hasPreviousZone = true;
}
scene->setKeyLightColor(ColorUtils::toVec3(zone->getKeyLightProperties().getColor()));
scene->setKeyLightIntensity(zone->getKeyLightProperties().getIntensity());
scene->setKeyLightAmbientIntensity(zone->getKeyLightProperties().getAmbientIntensity());
scene->setKeyLightDirection(zone->getKeyLightProperties().getDirection());
scene->setStageSunModelEnable(zone->getStageProperties().getSunModelEnabled());
scene->setStageLocation(zone->getStageProperties().getLongitude(), zone->getStageProperties().getLatitude(),
sceneKeyLight->setColor(ColorUtils::toVec3(zone->getKeyLightProperties().getColor()));
sceneKeyLight->setIntensity(zone->getKeyLightProperties().getIntensity());
sceneKeyLight->setAmbientIntensity(zone->getKeyLightProperties().getAmbientIntensity());
sceneKeyLight->setDirection(zone->getKeyLightProperties().getDirection());
sceneStage->setSunModelEnable(zone->getStageProperties().getSunModelEnabled());
sceneStage->setLocation(zone->getStageProperties().getLongitude(), zone->getStageProperties().getLatitude(),
zone->getStageProperties().getAltitude());
scene->setStageDayTime(zone->getStageProperties().calculateHour());
scene->setStageYearTime(zone->getStageProperties().calculateDay());
sceneTime->setHour(zone->getStageProperties().calculateHour());
sceneTime->setDay(zone->getStageProperties().calculateDay());
if (zone->getBackgroundMode() == BACKGROUND_MODE_ATMOSPHERE) {
EnvironmentData data = zone->getEnvironmentData();
glm::vec3 keyLightDirection = scene->getKeyLightDirection();
glm::vec3 keyLightDirection = sceneKeyLight->getDirection();
glm::vec3 inverseKeyLightDirection = keyLightDirection * -1.0f;
// NOTE: is this right? It seems like the "sun" should be based on the center of the
@ -293,7 +298,7 @@ void EntityTreeRenderer::applyZonePropertiesToScene(std::shared_ptr<ZoneEntityIt
data.setSunLocation(keyLightLocation);
const float KEY_LIGHT_INTENSITY_TO_SUN_BRIGHTNESS_RATIO = 20.0f;
float sunBrightness = scene->getKeyLightIntensity() * KEY_LIGHT_INTENSITY_TO_SUN_BRIGHTNESS_RATIO;
float sunBrightness = sceneKeyLight->getIntensity() * KEY_LIGHT_INTENSITY_TO_SUN_BRIGHTNESS_RATIO;
data.setSunBrightness(sunBrightness);
_viewState->overrideEnvironmentData(data);
@ -339,15 +344,15 @@ void EntityTreeRenderer::applyZonePropertiesToScene(std::shared_ptr<ZoneEntityIt
} else {
_pendingSkyboxTextureDownload = false;
if (_hasPreviousZone) {
scene->setKeyLightColor(_previousKeyLightColor);
scene->setKeyLightIntensity(_previousKeyLightIntensity);
scene->setKeyLightAmbientIntensity(_previousKeyLightAmbientIntensity);
scene->setKeyLightDirection(_previousKeyLightDirection);
scene->setStageSunModelEnable(_previousStageSunModelEnabled);
scene->setStageLocation(_previousStageLongitude, _previousStageLatitude,
sceneKeyLight->setColor(_previousKeyLightColor);
sceneKeyLight->setIntensity(_previousKeyLightIntensity);
sceneKeyLight->setAmbientIntensity(_previousKeyLightAmbientIntensity);
sceneKeyLight->setDirection(_previousKeyLightDirection);
sceneStage->setSunModelEnable(_previousStageSunModelEnabled);
sceneStage->setLocation(_previousStageLongitude, _previousStageLatitude,
_previousStageAltitude);
scene->setStageDayTime(_previousStageHour);
scene->setStageYearTime(_previousStageDay);
sceneTime->setHour(_previousStageHour);
sceneTime->setDay(_previousStageDay);
_hasPreviousZone = false;
}
_viewState->endOverrideEnvironmentData();

View file

@ -225,6 +225,21 @@ void SunSkyStage::setOriginOrientation(const Quat& orientation) {
invalidate();
}
void SunSkyStage::setOriginLongitude(float longitude) {
_earthSunModel.setLongitude(longitude);
invalidate();
}
void SunSkyStage::setOriginLatitude(float latitude) {
_earthSunModel.setLatitude(latitude);
invalidate();
}
void SunSkyStage::setOriginSurfaceAltitude(float altitude) {
_earthSunModel.setAltitude(altitude);
invalidate();
}
void SunSkyStage::setOriginLocation(float longitude, float latitude, float altitude) {
_earthSunModel.setLongitude(longitude);
_earthSunModel.setLatitude(latitude);

View file

@ -184,6 +184,9 @@ public:
const Quat& getOriginOrientation() const { return _earthSunModel.getSurfaceOrientation(); }
// Location used to define the sun & sky is a longitude and latitude [rad] and a earth surface altitude [km]
void setOriginLatitude(float latitude);
void setOriginLongitude(float longitude);
void setOriginSurfaceAltitude(float surfaceAltitude);
void setOriginLocation(float longitude, float latitude, float surfaceAltitude);
float getOriginLatitude() const { return _earthSunModel.getLatitude(); }
float getOriginLongitude() const { return _earthSunModel.getLongitude(); }

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

@ -94,7 +94,7 @@ NodeList::NodeList(char newOwnerType, unsigned short socketListenPort, unsigned
_keepAlivePingTimer.setInterval(KEEPALIVE_PING_INTERVAL_MS);
connect(&_keepAlivePingTimer, &QTimer::timeout, this, &NodeList::sendKeepAlivePings);
connect(&_domainHandler, SIGNAL(connectedToDomain(QString)), &_keepAlivePingTimer, SLOT(start()));
connect(&_domainHandler, &DomainHandler::disconnectedFromDomain, this, &NodeList::stopKeepalivePingTimer);
connect(&_domainHandler, &DomainHandler::disconnectedFromDomain, &_keepAlivePingTimer, &QTimer::stop);
// we definitely want STUN to update our public socket, so call the LNL to kick that off
startSTUNPublicSocketUpdate();

View file

@ -122,8 +122,10 @@ void ThreadedAssignment::startSendingStats() {
}
void ThreadedAssignment::stopSendingStats() {
// stop sending stats, we just disconnected from domain
_statsTimer->stop();
if (_statsTimer) {
// stop sending stats, we just disconnected from domain
_statsTimer->stop();
}
}
void ThreadedAssignment::checkInWithDomainServerOrExit() {

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

@ -13,20 +13,20 @@
RenderScriptingInterface::RenderScriptingInterface() {};
void RenderScriptingInterface::setEngineToneMappingToneCurve(const QString& toneCurve) {
if (toneCurve == QString("None")) {
_tone.toneCurve = 0;
} else if (toneCurve == QString("Gamma22")) {
_tone.toneCurve = 1;
} else if (toneCurve == QString("Reinhard")) {
_tone.toneCurve = 2;
} else if (toneCurve == QString("Filmic")) {
_tone.toneCurve = 3;
void RenderScripting::Tone::setCurve(const QString& curve) {
if (curve == QString("None")) {
toneCurve = 0;
} else if (curve == QString("Gamma22")) {
toneCurve = 1;
} else if (curve == QString("Reinhard")) {
toneCurve = 2;
} else if (curve == QString("Filmic")) {
toneCurve = 3;
}
}
QString RenderScriptingInterface::getEngineToneMappingToneCurve() const {
switch (_tone.toneCurve) {
QString RenderScripting::Tone::getCurve() const {
switch (toneCurve) {
case 0:
return QString("None");
case 1:
@ -38,4 +38,15 @@ QString RenderScriptingInterface::getEngineToneMappingToneCurve() const {
default:
return QString("Filmic");
};
}
render::RenderContext RenderScriptingInterface::getRenderContext() {
render::RenderContext::ItemsConfig items{ *_opaque, *_transparent, *_overlay3D };
return render::RenderContext{ items, *_tone, _drawStatus, _drawHitEffect, _deferredDebugSize, _deferredDebugMode };
}
void RenderScriptingInterface::setItemCounts(const render::RenderContext::ItemsConfig& items) {
_opaque->setCounts(items.opaque);
_transparent->setCounts(items.transparent);
_overlay3D->setCounts(items.overlay3D);
}

View file

@ -17,71 +17,91 @@
#include "render/Engine.h"
namespace RenderScripting {
using State = render::RenderContext::ItemsConfig::State;
using Counter = render::RenderContext::ItemsConfig::Counter;
class ItemCounter : public QObject, public Counter {
Q_OBJECT
public:
Q_PROPERTY(int numFeed READ getNumFeed)
Q_PROPERTY(int numDrawn READ getNumDrawn)
Q_PROPERTY(int maxDrawn MEMBER maxDrawn)
protected:
int getNumFeed() const { return numFeed; }
int getNumDrawn() const { return numDrawn; }
};
using ItemCounterPointer = std::unique_ptr<ItemCounter>;
class ItemState : public QObject, public State {
Q_OBJECT
public:
Q_PROPERTY(bool render MEMBER render)
Q_PROPERTY(bool cull MEMBER cull)
Q_PROPERTY(bool sort MEMBER sort)
Q_PROPERTY(int numFeed READ getNumFeed)
Q_PROPERTY(int numDrawn READ getNumDrawn)
Q_PROPERTY(int maxDrawn MEMBER maxDrawn)
protected:
int getNumFeed() const { return numFeed; }
int getNumDrawn() const { return numDrawn; }
};
using ItemStatePointer = std::unique_ptr<ItemState>;
class Tone : public QObject, public render::RenderContext::Tone {
Q_OBJECT
public:
Q_PROPERTY(float exposure MEMBER exposure)
Q_PROPERTY(QString curve READ getCurve WRITE setCurve)
QString getCurve() const;
int getCurveValue() const { return toneCurve; }
void setCurve(const QString& curve);
};
using TonePointer = std::unique_ptr<Tone>;
};
class RenderScriptingInterface : public QObject, public Dependency {
Q_OBJECT
SINGLETON_DEPENDENCY
public:
Q_INVOKABLE void setEngineRenderOpaque(bool renderOpaque) { _items.opaque.render = renderOpaque; };
Q_INVOKABLE bool doEngineRenderOpaque() const { return _items.opaque.render; }
Q_INVOKABLE void setEngineRenderTransparent(bool renderTransparent) { _items.transparent.render = renderTransparent; };
Q_INVOKABLE bool doEngineRenderTransparent() const { return _items.transparent.render; }
Q_INVOKABLE void setEngineCullOpaque(bool cullOpaque) { _items.opaque.cull = cullOpaque; };
Q_INVOKABLE bool doEngineCullOpaque() const { return _items.opaque.cull; }
Q_INVOKABLE void setEngineCullTransparent(bool cullTransparent) { _items.transparent.cull = cullTransparent; };
Q_INVOKABLE bool doEngineCullTransparent() const { return _items.transparent.cull; }
Q_PROPERTY(RenderScripting::ItemState* opaque READ getOpaque)
Q_PROPERTY(RenderScripting::ItemState* transparent READ getTransparent)
Q_PROPERTY(RenderScripting::ItemCounter* overlay3D READ getOverlay3D)
Q_INVOKABLE void setEngineSortOpaque(bool sortOpaque) { _items.opaque.sort = sortOpaque; };
Q_INVOKABLE bool doEngineSortOpaque() const { return _items.opaque.sort; }
Q_INVOKABLE void setEngineSortTransparent(bool sortTransparent) { _items.transparent.sort = sortTransparent; };
Q_INVOKABLE bool doEngineSortTransparent() const { return _items.transparent.sort; }
Q_PROPERTY(RenderScripting::Tone* tone READ getTone)
Q_INVOKABLE int getEngineNumDrawnOpaqueItems() { return _items.opaque.numDrawn; }
Q_INVOKABLE int getEngineNumDrawnTransparentItems() { return _items.transparent.numDrawn; }
Q_INVOKABLE int getEngineNumDrawnOverlay3DItems() { return _items.overlay3D.numDrawn; }
Q_PROPERTY(int displayItemStatus MEMBER _drawStatus)
Q_PROPERTY(bool displayHitEffect MEMBER _drawHitEffect)
Q_INVOKABLE int getEngineNumFeedOpaqueItems() { return _items.opaque.numFeed; }
Q_INVOKABLE int getEngineNumFeedTransparentItems() { return _items.transparent.numFeed; }
Q_INVOKABLE int getEngineNumFeedOverlay3DItems() { return _items.overlay3D.numFeed; }
Q_PROPERTY(int deferredDebugMode MEMBER _deferredDebugMode)
Q_PROPERTY(glm::vec4 deferredDebugSize MEMBER _deferredDebugSize)
Q_INVOKABLE void setEngineMaxDrawnOpaqueItems(int count) { _items.opaque.maxDrawn = count; }
Q_INVOKABLE int getEngineMaxDrawnOpaqueItems() { return _items.opaque.maxDrawn; }
Q_INVOKABLE void setEngineMaxDrawnTransparentItems(int count) { _items.transparent.maxDrawn = count; }
Q_INVOKABLE int getEngineMaxDrawnTransparentItems() { return _items.transparent.maxDrawn; }
Q_INVOKABLE void setEngineMaxDrawnOverlay3DItems(int count) { _items.overlay3D.maxDrawn = count; }
Q_INVOKABLE int getEngineMaxDrawnOverlay3DItems() { return _items.overlay3D.maxDrawn; }
Q_INVOKABLE void setEngineDeferredDebugMode(int mode) { _deferredDebugMode = mode; }
Q_INVOKABLE int getEngineDeferredDebugMode() { return _deferredDebugMode; }
Q_INVOKABLE void setEngineDeferredDebugSize(glm::vec4 size) { _deferredDebugSize = size; }
Q_INVOKABLE glm::vec4 getEngineDeferredDebugSize() { return _deferredDebugSize; }
Q_INVOKABLE void setEngineDisplayItemStatus(int display) { _drawStatus = display; }
Q_INVOKABLE int doEngineDisplayItemStatus() { return _drawStatus; }
Q_INVOKABLE void setEngineDisplayHitEffect(bool display) { _drawHitEffect = display; }
Q_INVOKABLE bool doEngineDisplayHitEffect() { return _drawHitEffect; }
Q_INVOKABLE void setEngineToneMappingExposure(float exposure) { _tone.exposure = exposure; }
Q_INVOKABLE float getEngineToneMappingExposure() const { return _tone.exposure; }
Q_INVOKABLE void setEngineToneMappingToneCurve(const QString& curve);
Q_INVOKABLE QString getEngineToneMappingToneCurve() const;
int getEngineToneMappingToneCurveValue() const { return _tone.toneCurve; }
inline int getDrawStatus() { return _drawStatus; }
inline bool getDrawHitEffect() { return _drawHitEffect; }
inline const render::RenderContext::ItemsConfig& getItemsConfig() { return _items; }
inline const render::RenderContext::Tone& getTone() { return _tone; }
void setItemCounts(const render::RenderContext::ItemsConfig& items) { _items.setCounts(items); };
render::RenderContext getRenderContext();
void setItemCounts(const render::RenderContext::ItemsConfig& items);
protected:
RenderScriptingInterface();
~RenderScriptingInterface() {};
render::RenderContext::ItemsConfig _items;
render::RenderContext::Tone _tone;
RenderScripting::ItemState* getOpaque() const { return _opaque.get(); }
RenderScripting::ItemState* getTransparent() const { return _transparent.get(); }
RenderScripting::ItemCounter* getOverlay3D() const { return _overlay3D.get(); }
RenderScripting::Tone* getTone() const { return _tone.get(); }
RenderScripting::ItemStatePointer _opaque = RenderScripting::ItemStatePointer{new RenderScripting::ItemState{}};
RenderScripting::ItemStatePointer _transparent = RenderScripting::ItemStatePointer{new RenderScripting::ItemState{}};
RenderScripting::ItemCounterPointer _overlay3D = RenderScripting::ItemCounterPointer{new RenderScripting::ItemCounter{}};
RenderScripting::TonePointer _tone = RenderScripting::TonePointer{ new RenderScripting::Tone{} };
// Options
int _drawStatus = 0;

View file

@ -13,11 +13,14 @@
#include "DrawTask.h"
using namespace render;
void RenderContext::setOptions(int drawStatus, bool drawHitEffect, bool occlusion, bool fxaa, bool showOwned) {
_drawStatus = drawStatus;
RenderContext::RenderContext(ItemsConfig items, Tone tone, int drawStatus, bool drawHitEffect, glm::vec4 deferredDebugSize, int deferredDebugMode)
: _args{ nullptr }, _items{ items }, _tone{ tone },
_drawStatus{ drawStatus }, _drawHitEffect{ drawHitEffect },
_deferredDebugSize{ deferredDebugSize }, _deferredDebugMode{ deferredDebugMode } {};
void RenderContext::setOptions(bool occlusion, bool fxaa, bool showOwned) {
_occlusionStatus = occlusion;
_fxaaStatus = fxaa;
_drawHitEffect = drawHitEffect;
if (showOwned) {
_drawStatus |= render::showNetworkStatusFlag;

View file

@ -34,12 +34,6 @@ class RenderContext {
public:
class ItemsConfig {
public:
inline void setCounts(const ItemsConfig& items) {
opaque.setCounts(items.opaque);
transparent.setCounts(items.transparent);
overlay3D.setCounts(items.overlay3D);
};
class Counter {
public:
Counter() {};
@ -48,7 +42,7 @@ public:
maxDrawn = counter.maxDrawn;
};
inline void setCounts(const Counter& counter) {
void setCounts(const Counter& counter) {
numFeed = counter.numFeed;
numDrawn = counter.numDrawn;
};
@ -67,6 +61,10 @@ public:
Counter counter{};
};
ItemsConfig(State opaqueState, State transparentState, Counter overlay3DCounter)
: opaque{ opaqueState }, transparent{ transparentState }, overlay3D{ overlay3DCounter } {}
ItemsConfig() : ItemsConfig{ {}, {}, {} } {}
// TODO: If member count increases, store counters in a map instead of multiple members
State opaque{};
State transparent{};
@ -79,9 +77,10 @@ public:
float exposure = 0.0;
};
RenderContext(RenderArgs* args, ItemsConfig items, Tone tone) : _args{args}, _items{items}, _tone{tone} {};
RenderContext() : RenderContext(nullptr, {}, {}) {};
RenderContext(ItemsConfig items, Tone tone, int drawStatus, bool drawHitEffect, glm::vec4 deferredDebugSize, int deferredDebugMode);
RenderContext() : RenderContext({}, {}, {}, {}, {}, {}) {};
void setArgs(RenderArgs* args) { _args = args; }
inline RenderArgs* getArgs() { return _args; }
inline ItemsConfig& getItemsConfig() { return _items; }
inline Tone& getTone() { return _tone; }
@ -89,7 +88,7 @@ public:
inline bool getDrawHitEffect() { return _drawHitEffect; }
inline bool getOcclusionStatus() { return _occlusionStatus; }
inline bool getFxaaStatus() { return _fxaaStatus; }
void setOptions(int drawStatus, bool drawHitEffect, bool occlusion, bool fxaa, bool showOwned);
void setOptions(bool occlusion, bool fxaa, bool showOwned);
// Debugging
int _deferredDebugMode = -1;

View file

@ -13,7 +13,118 @@
#include <procedural/ProceduralSkybox.h>
SceneScriptingInterface::SceneScriptingInterface() {
float SceneScripting::Location::getLongitude() const {
return _skyStage->getOriginLongitude();
}
float SceneScripting::Location::getLatitude() const {
return _skyStage->getOriginLatitude();
}
float SceneScripting::Location::getAltitude() const {
return _skyStage->getOriginSurfaceAltitude();
}
void SceneScripting::Location::setLongitude(float longitude) {
_skyStage->setOriginLongitude(longitude);
}
void SceneScripting::Location::setLatitude(float latitude) {
_skyStage->setOriginLatitude(latitude);
}
void SceneScripting::Location::setAltitude(float altitude) {
_skyStage->setOriginSurfaceAltitude(altitude);
}
void SceneScripting::Time::setHour(float hour) {
_skyStage->setDayTime(hour);
}
float SceneScripting::Time::getHour() const {
return _skyStage->getDayTime();
}
void SceneScripting::Time::setDay(int day) {
_skyStage->setYearTime(day);
}
int SceneScripting::Time::getDay() const {
return _skyStage->getYearTime();
}
glm::vec3 SceneScripting::KeyLight::getColor() const {
return _skyStage->getSunColor();
}
void SceneScripting::KeyLight::setColor(const glm::vec3& color) {
_skyStage->setSunColor(color);
}
float SceneScripting::KeyLight::getIntensity() const {
return _skyStage->getSunIntensity();
}
void SceneScripting::KeyLight::setIntensity(float intensity) {
_skyStage->setSunIntensity(intensity);
}
float SceneScripting::KeyLight::getAmbientIntensity() const {
return _skyStage->getSunAmbientIntensity();
}
void SceneScripting::KeyLight::setAmbientIntensity(float intensity) {
_skyStage->setSunAmbientIntensity(intensity);
}
glm::vec3 SceneScripting::KeyLight::getDirection() const {
return _skyStage->getSunDirection();
}
void SceneScripting::KeyLight::setDirection(const glm::vec3& direction) {
_skyStage->setSunDirection(direction);
}
void SceneScripting::Stage::setOrientation(const glm::quat& orientation) const {
_skyStage->setOriginOrientation(orientation);
}
void SceneScripting::Stage::setLocation(float longitude, float latitude, float altitude) {
_skyStage->setOriginLocation(longitude, latitude, altitude);
}
void SceneScripting::Stage::setSunModelEnable(bool isEnabled) {
_skyStage->setSunModelEnable(isEnabled);
}
bool SceneScripting::Stage::isSunModelEnabled() const {
return _skyStage->isSunModelEnabled();
}
void SceneScripting::Stage::setBackgroundMode(const QString& mode) {
if (mode == QString("inherit")) {
_skyStage->setBackgroundMode(model::SunSkyStage::NO_BACKGROUND);
} else if (mode == QString("atmosphere")) {
_skyStage->setBackgroundMode(model::SunSkyStage::SKY_DOME);
} else if (mode == QString("skybox")) {
_skyStage->setBackgroundMode(model::SunSkyStage::SKY_BOX);
}
}
QString SceneScripting::Stage::getBackgroundMode() const {
switch (_skyStage->getBackgroundMode()) {
case model::SunSkyStage::NO_BACKGROUND:
return QString("inherit");
case model::SunSkyStage::SKY_DOME:
return QString("atmosphere");
case model::SunSkyStage::SKY_BOX:
return QString("skybox");
default:
return QString("inherit");
};
}
SceneScriptingInterface::SceneScriptingInterface() : _stage{ new SceneScripting::Stage{ _skyStage } } {
// Let's make sure the sunSkyStage is using a proceduralSkybox
_skyStage->setSkybox(model::SkyboxPointer(new ProceduralSkybox()));
}
@ -32,102 +143,6 @@ void SceneScriptingInterface::setShouldRenderEntities(bool shouldRenderEntities)
}
}
void SceneScriptingInterface::setStageOrientation(const glm::quat& orientation) {
_skyStage->setOriginOrientation(orientation);
}
void SceneScriptingInterface::setStageLocation(float longitude, float latitude, float altitude) {
_skyStage->setOriginLocation(longitude, latitude, altitude);
}
float SceneScriptingInterface::getStageLocationLongitude() const {
return _skyStage->getOriginLongitude();
}
float SceneScriptingInterface::getStageLocationLatitude() const {
return _skyStage->getOriginLatitude();
}
float SceneScriptingInterface::getStageLocationAltitude() const {
return _skyStage->getOriginSurfaceAltitude();
}
void SceneScriptingInterface::setStageDayTime(float hour) {
_skyStage->setDayTime(hour);
}
float SceneScriptingInterface::getStageDayTime() const {
return _skyStage->getDayTime();
}
void SceneScriptingInterface::setStageYearTime(int day) {
_skyStage->setYearTime(day);
}
int SceneScriptingInterface::getStageYearTime() const {
return _skyStage->getYearTime();
}
void SceneScriptingInterface::setKeyLightColor(const glm::vec3& color) {
_skyStage->setSunColor(color);
}
glm::vec3 SceneScriptingInterface::getKeyLightColor() const {
return _skyStage->getSunColor();
}
void SceneScriptingInterface::setKeyLightIntensity(float intensity) {
_skyStage->setSunIntensity(intensity);
}
float SceneScriptingInterface::getKeyLightIntensity() const {
return _skyStage->getSunIntensity();
}
void SceneScriptingInterface::setKeyLightAmbientIntensity(float intensity) {
_skyStage->setSunAmbientIntensity(intensity);
}
float SceneScriptingInterface::getKeyLightAmbientIntensity() const {
return _skyStage->getSunAmbientIntensity();
}
void SceneScriptingInterface::setKeyLightDirection(const glm::vec3& direction) {
_skyStage->setSunDirection(direction);
}
glm::vec3 SceneScriptingInterface::getKeyLightDirection() const {
return _skyStage->getSunDirection();
}
void SceneScriptingInterface::setStageSunModelEnable(bool isEnabled) {
_skyStage->setSunModelEnable(isEnabled);
}
bool SceneScriptingInterface::isStageSunModelEnabled() const {
return _skyStage->isSunModelEnabled();
}
void SceneScriptingInterface::setBackgroundMode(const QString& mode) {
if (mode == QString("inherit")) {
_skyStage->setBackgroundMode(model::SunSkyStage::NO_BACKGROUND);
} else if (mode == QString("atmosphere")) {
_skyStage->setBackgroundMode(model::SunSkyStage::SKY_DOME);
} else if (mode == QString("skybox")) {
_skyStage->setBackgroundMode(model::SunSkyStage::SKY_BOX);
}
}
QString SceneScriptingInterface::getBackgroundMode() const {
switch (_skyStage->getBackgroundMode()) {
case model::SunSkyStage::NO_BACKGROUND:
return QString("inherit");
case model::SunSkyStage::SKY_DOME:
return QString("atmosphere");
case model::SunSkyStage::SKY_BOX:
return QString("skybox");
default:
return QString("inherit");
};
}
model::SunSkyStagePointer SceneScriptingInterface::getSkyStage() const {
return _skyStage;
}

View file

@ -17,6 +17,114 @@
#include "model/Stage.h"
// TODO: if QT moc ever supports nested classes, subclass these to the interface instead of namespacing
namespace SceneScripting {
class Location : public QObject {
Q_OBJECT
public:
Location(model::SunSkyStagePointer skyStage) : _skyStage{ skyStage } {}
Q_PROPERTY(float longitude READ getLongitude WRITE setLongitude)
Q_PROPERTY(float latitude READ getLatitude WRITE setLatitude)
Q_PROPERTY(float altitude READ getAltitude WRITE setAltitude)
float getLongitude() const;
float getLatitude() const;
float getAltitude() const;
void setLongitude(float longitude);
void setLatitude(float latitude);
void setAltitude(float altitude);
protected:
model::SunSkyStagePointer _skyStage;
};
using LocationPointer = std::unique_ptr<Location>;
class Time : public QObject {
Q_OBJECT
public:
Time(model::SunSkyStagePointer skyStage) : _skyStage{ skyStage } {}
Q_PROPERTY(float hour READ getHour WRITE setHour)
Q_PROPERTY(int day READ getDay WRITE setDay)
float getHour() const;
void setHour(float hour);
int getDay() const;
void setDay(int day);
protected:
model::SunSkyStagePointer _skyStage;
};
using TimePointer = std::unique_ptr<Time>;
class KeyLight : public QObject {
Q_OBJECT
public:
KeyLight(model::SunSkyStagePointer skyStage) : _skyStage{ skyStage } {}
Q_PROPERTY(glm::vec3 color READ getColor WRITE setColor)
Q_PROPERTY(float intensity READ getIntensity WRITE setIntensity)
Q_PROPERTY(float ambientIntensity READ getAmbientIntensity WRITE setAmbientIntensity)
Q_PROPERTY(glm::vec3 direction READ getDirection WRITE setDirection)
glm::vec3 getColor() const;
void setColor(const glm::vec3& color);
float getIntensity() const;
void setIntensity(float intensity);
float getAmbientIntensity() const;
void setAmbientIntensity(float intensity);
glm::vec3 getDirection() const;
// setDirection is only effective if stage Sun model is disabled
void setDirection(const glm::vec3& direction);
protected:
model::SunSkyStagePointer _skyStage;
};
using KeyLightPointer = std::unique_ptr<KeyLight>;
class Stage : public QObject {
Q_OBJECT
public:
Stage(model::SunSkyStagePointer skyStage)
: _skyStage{ skyStage },
_location{ new Location{ skyStage } }, _time{ new Time{ skyStage } }, _keyLight{ new KeyLight{ skyStage } }{}
Q_INVOKABLE void setOrientation(const glm::quat& orientation) const;
Q_PROPERTY(Location* location READ getLocation)
Location* getLocation() const { return _location.get(); }
Q_INVOKABLE void setLocation(float longitude, float latitude, float altitude);
Q_PROPERTY(Time* time READ getTime)
Time* getTime() const { return _time.get(); }
Q_PROPERTY(KeyLight* keyLight READ getKeyLight)
KeyLight* getKeyLight() const { return _keyLight.get(); }
// Enable/disable the stage sun model which uses the key light to simulate
// the sun light based on the location of the stage relative to earth and the current time
Q_PROPERTY(bool sunModel READ isSunModelEnabled WRITE setSunModelEnable)
void setSunModelEnable(bool isEnabled);
bool isSunModelEnabled() const;
Q_PROPERTY(QString backgroundMode READ getBackgroundMode WRITE setBackgroundMode)
void setBackgroundMode(const QString& mode);
QString getBackgroundMode() const;
protected:
model::SunSkyStagePointer _skyStage;
LocationPointer _location;
TimePointer _time;
KeyLightPointer _keyLight;
};
using StagePointer = std::unique_ptr<Stage>;
};
class SceneScriptingInterface : public QObject, public Dependency {
Q_OBJECT
SINGLETON_DEPENDENCY
@ -24,46 +132,14 @@ class SceneScriptingInterface : public QObject, public Dependency {
public:
Q_PROPERTY(bool shouldRenderAvatars READ shouldRenderAvatars WRITE setShouldRenderAvatars)
Q_PROPERTY(bool shouldRenderEntities READ shouldRenderEntities WRITE setShouldRenderEntities)
bool shouldRenderAvatars() const { return _shouldRenderAvatars; }
bool shouldRenderEntities() const { return _shouldRenderEntities; }
void setShouldRenderAvatars(bool shouldRenderAvatars);
void setShouldRenderEntities(bool shouldRenderEntities);
Q_INVOKABLE void setShouldRenderAvatars(bool shouldRenderAvatars);
Q_INVOKABLE bool shouldRenderAvatars() const { return _shouldRenderAvatars; }
Q_INVOKABLE void setShouldRenderEntities(bool shouldRenderEntities);
Q_INVOKABLE bool shouldRenderEntities() const { return _shouldRenderEntities; }
Q_INVOKABLE void setStageOrientation(const glm::quat& orientation);
Q_INVOKABLE void setStageLocation(float longitude, float latitude, float altitude);
Q_INVOKABLE float getStageLocationLongitude() const;
Q_INVOKABLE float getStageLocationLatitude() const;
Q_INVOKABLE float getStageLocationAltitude() const;
Q_INVOKABLE void setStageDayTime(float hour);
Q_INVOKABLE float getStageDayTime() const;
Q_INVOKABLE void setStageYearTime(int day);
Q_INVOKABLE int getStageYearTime() const;
// Enable/disable the stage sun model which uses the key light to simulate
// the sun light based on the location of the stage trelative to earth and the current time
Q_INVOKABLE void setStageSunModelEnable(bool isEnabled);
Q_INVOKABLE bool isStageSunModelEnabled() const;
Q_INVOKABLE void setKeyLightColor(const glm::vec3& color);
Q_INVOKABLE glm::vec3 getKeyLightColor() const;
Q_INVOKABLE void setKeyLightIntensity(float intensity);
Q_INVOKABLE float getKeyLightIntensity() const;
Q_INVOKABLE void setKeyLightAmbientIntensity(float intensity);
Q_INVOKABLE float getKeyLightAmbientIntensity() const;
// setKeyLightDIrection is only effective if stage Sun model is disabled
Q_INVOKABLE void setKeyLightDirection(const glm::vec3& direction);
Q_INVOKABLE glm::vec3 getKeyLightDirection() const;
Q_INVOKABLE void setBackgroundMode(const QString& mode);
Q_INVOKABLE QString getBackgroundMode() const;
Q_PROPERTY(SceneScripting::Stage* stage READ getStage)
SceneScripting::Stage* getStage() const { return _stage.get(); }
model::SunSkyStagePointer getSkyStage() const;
signals:
@ -75,9 +151,10 @@ protected:
~SceneScriptingInterface() {};
model::SunSkyStagePointer _skyStage = std::make_shared<model::SunSkyStage>();
SceneScripting::StagePointer _stage;
bool _shouldRenderAvatars = true;
bool _shouldRenderEntities = true;
};
#endif // hifi_SceneScriptingInterface_h
#endif // hifi_SceneScriptingInterface_h

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];