From e48c456d246e2f5b0e015ac3e4c098a22292be74 Mon Sep 17 00:00:00 2001 From: samcake Date: Wed, 6 Sep 2017 17:57:18 -0700 Subject: [PATCH 01/59] Trying to sync the render transform for overlay web at the right time... --- interface/src/ui/overlays/Base3DOverlay.cpp | 4 ++ interface/src/ui/overlays/Base3DOverlay.h | 4 ++ interface/src/ui/overlays/Overlay.h | 1 + interface/src/ui/overlays/Web3DOverlay.cpp | 42 +++++++++++++++++++-- interface/src/ui/overlays/Web3DOverlay.h | 5 +++ 5 files changed, 53 insertions(+), 3 deletions(-) diff --git a/interface/src/ui/overlays/Base3DOverlay.cpp b/interface/src/ui/overlays/Base3DOverlay.cpp index c0278a6496..010be802a9 100644 --- a/interface/src/ui/overlays/Base3DOverlay.cpp +++ b/interface/src/ui/overlays/Base3DOverlay.cpp @@ -256,6 +256,10 @@ bool Base3DOverlay::findRayIntersection(const glm::vec3& origin, const glm::vec3 void Base3DOverlay::locationChanged(bool tellPhysics) { SpatiallyNestable::locationChanged(tellPhysics); + // Force the actual update of the render transform now that we notify for the change + // so it s captured for the time of rendering + notifyRenderTransformChange(); + auto itemID = getRenderItemID(); if (render::Item::isValidID(itemID)) { render::ScenePointer scene = qApp->getMain3DScene(); diff --git a/interface/src/ui/overlays/Base3DOverlay.h b/interface/src/ui/overlays/Base3DOverlay.h index 6377b46d7d..3f57f2e577 100644 --- a/interface/src/ui/overlays/Base3DOverlay.h +++ b/interface/src/ui/overlays/Base3DOverlay.h @@ -52,6 +52,9 @@ public: virtual AABox getBounds() const override = 0; + void notifyRenderTransformChange() const { _renderTransformDirty = true; } + virtual Transform evalRenderTransform() const { return Transform(); } + void setProperties(const QVariantMap& properties) override; QVariant getProperty(const QString& property) override; @@ -73,6 +76,7 @@ protected: bool _ignoreRayIntersection; bool _drawInFront; bool _isGrabbable { false }; + mutable bool _renderTransformDirty{ true }; QString _name; }; diff --git a/interface/src/ui/overlays/Overlay.h b/interface/src/ui/overlays/Overlay.h index db2979b4d5..31846501ec 100644 --- a/interface/src/ui/overlays/Overlay.h +++ b/interface/src/ui/overlays/Overlay.h @@ -102,6 +102,7 @@ protected: render::ItemID _renderItemID{ render::Item::INVALID_ITEM_ID }; + bool _isLoaded; float _alpha; diff --git a/interface/src/ui/overlays/Web3DOverlay.cpp b/interface/src/ui/overlays/Web3DOverlay.cpp index 104082dee4..a1fd0414ee 100644 --- a/interface/src/ui/overlays/Web3DOverlay.cpp +++ b/interface/src/ui/overlays/Web3DOverlay.cpp @@ -180,12 +180,46 @@ void Web3DOverlay::buildWebSurface() { void Web3DOverlay::update(float deltatime) { + if (_renderTransformDirty) { + auto itemID = getRenderItemID(); + if (render::Item::isValidID(itemID)) { + render::ScenePointer scene = qApp->getMain3DScene(); + render::Transaction transaction; + transaction.updateItem(itemID, [](Overlay& data) { + auto web3D = dynamic_cast(&data); + if (web3D) { + web3D->evalRenderTransform(); + } + }); + scene->enqueueTransaction(transaction); + } + } + if (_webSurface) { // update globalPosition _webSurface->getSurfaceContext()->setContextProperty("globalPosition", vec3toVariant(getPosition())); } } +Transform Web3DOverlay::evalRenderTransform() const { + if (_renderTransformDirty) { + _renderTransform = getTransform(); + + // FIXME: applyTransformTo causes tablet overlay to detach from tablet entity. + // Perhaps rather than deleting the following code it should be run only if isFacingAvatar() is true? + /* + applyTransformTo(transform, true); + setTransform(transform); + */ + + if (glm::length2(getDimensions()) != 1.0f) { + _renderTransform.postScale(vec3(getDimensions(), 1.0f)); + } + _renderTransformDirty = false; + } + return _renderTransform; +} + QString Web3DOverlay::pickURL() { QUrl sourceUrl(_url); if (sourceUrl.scheme() == "http" || sourceUrl.scheme() == "https" || @@ -305,7 +339,7 @@ void Web3DOverlay::render(RenderArgs* args) { vec2 halfSize = getSize() / 2.0f; vec4 color(toGlm(getColor()), getAlpha()); - + /* Transform transform = getTransform(); // FIXME: applyTransformTo causes tablet overlay to detach from tablet entity. @@ -314,10 +348,11 @@ void Web3DOverlay::render(RenderArgs* args) { applyTransformTo(transform, true); setTransform(transform); */ - + /* if (glm::length2(getDimensions()) != 1.0f) { transform.postScale(vec3(getDimensions(), 1.0f)); } + */ if (!_texture) { _texture = gpu::Texture::createExternal(OffscreenQmlSurface::getDiscardLambda()); @@ -332,7 +367,8 @@ void Web3DOverlay::render(RenderArgs* args) { Q_ASSERT(args->_batch); gpu::Batch& batch = *args->_batch; batch.setResourceTexture(0, _texture); - batch.setModelTransform(transform); + // batch.setModelTransform(transform); + batch.setModelTransform(_renderTransform); auto geometryCache = DependencyManager::get(); if (color.a < OPAQUE_ALPHA_THRESHOLD) { geometryCache->bindWebBrowserProgram(batch, true); diff --git a/interface/src/ui/overlays/Web3DOverlay.h b/interface/src/ui/overlays/Web3DOverlay.h index 2eae7f33da..721f86019c 100644 --- a/interface/src/ui/overlays/Web3DOverlay.h +++ b/interface/src/ui/overlays/Web3DOverlay.h @@ -37,6 +37,9 @@ public: virtual void update(float deltatime) override; + Transform evalRenderTransform() const override; + + QObject* getEventHandler(); void setProxyWindow(QWindow* proxyWindow); void handlePointerEvent(const PointerEvent& event); @@ -92,6 +95,8 @@ private: std::map _activeTouchPoints; QTouchDevice _touchDevice; + mutable Transform _renderTransform; + uint8_t _desiredMaxFPS { 10 }; uint8_t _currentMaxFPS { 0 }; From 73ec095235dd6a5c9daea8a326e9f5751ba61765 Mon Sep 17 00:00:00 2001 From: samcake Date: Thu, 7 Sep 2017 17:58:16 -0700 Subject: [PATCH 02/59] fooling around with communicating the update transform to render thread through a trasnaction, not the solution yet --- interface/src/ui/overlays/Web3DOverlay.cpp | 15 ++++++++++----- interface/src/ui/overlays/Web3DOverlay.h | 3 ++- 2 files changed, 12 insertions(+), 6 deletions(-) diff --git a/interface/src/ui/overlays/Web3DOverlay.cpp b/interface/src/ui/overlays/Web3DOverlay.cpp index a1fd0414ee..9ad2cef443 100644 --- a/interface/src/ui/overlays/Web3DOverlay.cpp +++ b/interface/src/ui/overlays/Web3DOverlay.cpp @@ -181,14 +181,15 @@ void Web3DOverlay::buildWebSurface() { void Web3DOverlay::update(float deltatime) { if (_renderTransformDirty) { + auto updateTransform = evalRenderTransform(); auto itemID = getRenderItemID(); if (render::Item::isValidID(itemID)) { render::ScenePointer scene = qApp->getMain3DScene(); render::Transaction transaction; - transaction.updateItem(itemID, [](Overlay& data) { + transaction.updateItem(itemID, [updateTransform](Overlay& data) { auto web3D = dynamic_cast(&data); if (web3D) { - web3D->evalRenderTransform(); + web3D->setRenderTransform(updateTransform);// evalRenderTransform(); } }); scene->enqueueTransaction(transaction); @@ -203,7 +204,7 @@ void Web3DOverlay::update(float deltatime) { Transform Web3DOverlay::evalRenderTransform() const { if (_renderTransformDirty) { - _renderTransform = getTransform(); + _updateTransform = getTransform(); // FIXME: applyTransformTo causes tablet overlay to detach from tablet entity. // Perhaps rather than deleting the following code it should be run only if isFacingAvatar() is true? @@ -213,11 +214,15 @@ Transform Web3DOverlay::evalRenderTransform() const { */ if (glm::length2(getDimensions()) != 1.0f) { - _renderTransform.postScale(vec3(getDimensions(), 1.0f)); + _updateTransform.postScale(vec3(getDimensions(), 1.0f)); } _renderTransformDirty = false; } - return _renderTransform; + return _updateTransform; +} + +void Web3DOverlay::setRenderTransform(const Transform& transform) { + _renderTransform = transform; } QString Web3DOverlay::pickURL() { diff --git a/interface/src/ui/overlays/Web3DOverlay.h b/interface/src/ui/overlays/Web3DOverlay.h index 721f86019c..ef40d88333 100644 --- a/interface/src/ui/overlays/Web3DOverlay.h +++ b/interface/src/ui/overlays/Web3DOverlay.h @@ -38,7 +38,7 @@ public: virtual void update(float deltatime) override; Transform evalRenderTransform() const override; - + void setRenderTransform(const Transform& transform); QObject* getEventHandler(); void setProxyWindow(QWindow* proxyWindow); @@ -95,6 +95,7 @@ private: std::map _activeTouchPoints; QTouchDevice _touchDevice; + mutable Transform _updateTransform; mutable Transform _renderTransform; uint8_t _desiredMaxFPS { 10 }; From b953c49461dc26176336770f5cd1f6afdfb26eec Mon Sep 17 00:00:00 2001 From: Cain Kilgore Date: Fri, 8 Sep 2017 03:20:55 +0100 Subject: [PATCH 03/59] Commit for Better Logger - WL 21537 --- interface/src/Application.cpp | 13 +++++++++++-- libraries/shared/src/shared/FileLogger.cpp | 11 ++++++++++- libraries/shared/src/shared/FileLogger.h | 1 + 3 files changed, 22 insertions(+), 3 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 3650c495f2..f0ad0fe85b 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -510,6 +510,13 @@ void messageHandler(QtMsgType type, const QMessageLogContext& context, const QSt OutputDebugStringA(logMessage.toLocal8Bit().constData()); OutputDebugStringA("\n"); #endif + auto avatarManager = DependencyManager::get(); + auto myAvatar = avatarManager ? avatarManager->getMyAvatar() : nullptr; + + QUuid fileLoggerSessionID = myAvatar->getSessionUUID(); + if (!fileLoggerSessionID.isNull()) { + qApp->getLogger()->setSessionID(fileLoggerSessionID); + } qApp->getLogger()->addMessage(qPrintable(logMessage + "\n")); } } @@ -804,6 +811,10 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo _deadlockWatchdogThread = new DeadlockWatchdogThread(); _deadlockWatchdogThread->start(); + // Set File Logger Session UUID + auto avatarManager = DependencyManager::get(); + auto myAvatar = avatarManager ? avatarManager->getMyAvatar() : nullptr; + if (steamClient) { qCDebug(interfaceapp) << "[VERSION] SteamVR buildID:" << steamClient->getSteamVRBuildID(); } @@ -920,8 +931,6 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo // send a location update immediately discoverabilityManager->updateLocation(); - auto myAvatar = getMyAvatar(); - connect(nodeList.data(), &NodeList::nodeAdded, this, &Application::nodeAdded); connect(nodeList.data(), &NodeList::nodeKilled, this, &Application::nodeKilled); connect(nodeList.data(), &NodeList::nodeActivated, this, &Application::nodeActivated); diff --git a/libraries/shared/src/shared/FileLogger.cpp b/libraries/shared/src/shared/FileLogger.cpp index bea28b2b6f..1ac87907bf 100644 --- a/libraries/shared/src/shared/FileLogger.cpp +++ b/libraries/shared/src/shared/FileLogger.cpp @@ -48,6 +48,8 @@ static const QString LOGS_DIRECTORY = "Logs"; static const QString IPADDR_WILDCARD = "[0-9]*.[0-9]*.[0-9]*.[0-9]*"; static const QString DATETIME_WILDCARD = "20[0-9][0-9]-[0,1][0-9]-[0-3][0-9]_[0-2][0-9].[0-6][0-9].[0-6][0-9]"; static const QString FILENAME_WILDCARD = "hifi-log_" + IPADDR_WILDCARD + "_" + DATETIME_WILDCARD + ".txt"; +static QUuid& SESSION_ID = QUuid::QUuid("{00000000-0000-0000-0000-000000000000}"); + // Max log size is 512 KB. We send log files to our crash reporter, so we want to keep this relatively // small so it doesn't go over the 2MB zipped limit for all of the files we send. static const qint64 MAX_LOG_SIZE = 512 * 1024; @@ -62,7 +64,10 @@ QString getLogRollerFilename() { QString result = FileUtils::standardPath(LOGS_DIRECTORY); QHostAddress clientAddress = getGuessedLocalAddress(); QDateTime now = QDateTime::currentDateTime(); - result.append(QString(FILENAME_FORMAT).arg(clientAddress.toString(), now.toString(DATETIME_FORMAT))); + + auto FILE_SESSION_ID = SESSION_ID.toString().replace("{", "").replace("}", ""); + + result.append(QString(FILENAME_FORMAT).arg(FILE_SESSION_ID, now.toString(DATETIME_FORMAT))); return result; } @@ -142,6 +147,10 @@ FileLogger::~FileLogger() { _persistThreadInstance->terminate(); } +void FileLogger::setSessionID(const QUuid& message) { + SESSION_ID = message; // This is for the output of log files. It will change if the Avatar enters a different domain. +} + void FileLogger::addMessage(const QString& message) { _persistThreadInstance->queueItem(message); emit logReceived(message); diff --git a/libraries/shared/src/shared/FileLogger.h b/libraries/shared/src/shared/FileLogger.h index 15d211afe8..d9d7651147 100644 --- a/libraries/shared/src/shared/FileLogger.h +++ b/libraries/shared/src/shared/FileLogger.h @@ -26,6 +26,7 @@ public: QString getFilename() const { return _fileName; } virtual void addMessage(const QString&) override; + virtual void setSessionID(const QUuid&); virtual QString getLogData() override; virtual void locateLog() override; virtual void sync() override; From 7f4cc0ed2a6382e289eaf7907ac51537e5531fc0 Mon Sep 17 00:00:00 2001 From: Cain Kilgore Date: Fri, 8 Sep 2017 20:21:17 +0100 Subject: [PATCH 04/59] Should fix the Mac Build --- libraries/shared/src/shared/FileLogger.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/shared/src/shared/FileLogger.cpp b/libraries/shared/src/shared/FileLogger.cpp index 1ac87907bf..56393f4f32 100644 --- a/libraries/shared/src/shared/FileLogger.cpp +++ b/libraries/shared/src/shared/FileLogger.cpp @@ -48,7 +48,7 @@ static const QString LOGS_DIRECTORY = "Logs"; static const QString IPADDR_WILDCARD = "[0-9]*.[0-9]*.[0-9]*.[0-9]*"; static const QString DATETIME_WILDCARD = "20[0-9][0-9]-[0,1][0-9]-[0-3][0-9]_[0-2][0-9].[0-6][0-9].[0-6][0-9]"; static const QString FILENAME_WILDCARD = "hifi-log_" + IPADDR_WILDCARD + "_" + DATETIME_WILDCARD + ".txt"; -static QUuid& SESSION_ID = QUuid::QUuid("{00000000-0000-0000-0000-000000000000}"); +static QUuid& SESSION_ID = QUuid("{00000000-0000-0000-0000-000000000000}"); // Max log size is 512 KB. We send log files to our crash reporter, so we want to keep this relatively // small so it doesn't go over the 2MB zipped limit for all of the files we send. From dfbd25fd77ffe1e6b9b6ec5938dc250126ade69b Mon Sep 17 00:00:00 2001 From: Cain Kilgore Date: Fri, 8 Sep 2017 20:51:41 +0100 Subject: [PATCH 05/59] Now pls --- libraries/shared/src/shared/FileLogger.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/shared/src/shared/FileLogger.cpp b/libraries/shared/src/shared/FileLogger.cpp index 56393f4f32..652cca79a3 100644 --- a/libraries/shared/src/shared/FileLogger.cpp +++ b/libraries/shared/src/shared/FileLogger.cpp @@ -48,7 +48,7 @@ static const QString LOGS_DIRECTORY = "Logs"; static const QString IPADDR_WILDCARD = "[0-9]*.[0-9]*.[0-9]*.[0-9]*"; static const QString DATETIME_WILDCARD = "20[0-9][0-9]-[0,1][0-9]-[0-3][0-9]_[0-2][0-9].[0-6][0-9].[0-6][0-9]"; static const QString FILENAME_WILDCARD = "hifi-log_" + IPADDR_WILDCARD + "_" + DATETIME_WILDCARD + ".txt"; -static QUuid& SESSION_ID = QUuid("{00000000-0000-0000-0000-000000000000}"); +QUuid& SESSION_ID = QUuid("{00000000-0000-0000-0000-000000000000}"); // Max log size is 512 KB. We send log files to our crash reporter, so we want to keep this relatively // small so it doesn't go over the 2MB zipped limit for all of the files we send. From 7b39cb77916e032aa7dcb954c64b165e8f197d75 Mon Sep 17 00:00:00 2001 From: Cain Kilgore Date: Fri, 8 Sep 2017 21:44:38 +0100 Subject: [PATCH 06/59] Should work now --- libraries/shared/src/shared/FileLogger.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/shared/src/shared/FileLogger.cpp b/libraries/shared/src/shared/FileLogger.cpp index 652cca79a3..46ba45e238 100644 --- a/libraries/shared/src/shared/FileLogger.cpp +++ b/libraries/shared/src/shared/FileLogger.cpp @@ -48,7 +48,7 @@ static const QString LOGS_DIRECTORY = "Logs"; static const QString IPADDR_WILDCARD = "[0-9]*.[0-9]*.[0-9]*.[0-9]*"; static const QString DATETIME_WILDCARD = "20[0-9][0-9]-[0,1][0-9]-[0-3][0-9]_[0-2][0-9].[0-6][0-9].[0-6][0-9]"; static const QString FILENAME_WILDCARD = "hifi-log_" + IPADDR_WILDCARD + "_" + DATETIME_WILDCARD + ".txt"; -QUuid& SESSION_ID = QUuid("{00000000-0000-0000-0000-000000000000}"); +QUuid SESSION_ID = QUuid("{00000000-0000-0000-0000-000000000000}"); // Max log size is 512 KB. We send log files to our crash reporter, so we want to keep this relatively // small so it doesn't go over the 2MB zipped limit for all of the files we send. From f109a86b23fb0476e8d9b40e1dac7229a7b9c042 Mon Sep 17 00:00:00 2001 From: Cain Kilgore Date: Fri, 8 Sep 2017 23:05:22 +0100 Subject: [PATCH 07/59] Fixed small crash bug on exit --- interface/src/Application.cpp | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index f0ad0fe85b..3ee5406ad0 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -513,10 +513,13 @@ void messageHandler(QtMsgType type, const QMessageLogContext& context, const QSt auto avatarManager = DependencyManager::get(); auto myAvatar = avatarManager ? avatarManager->getMyAvatar() : nullptr; - QUuid fileLoggerSessionID = myAvatar->getSessionUUID(); - if (!fileLoggerSessionID.isNull()) { - qApp->getLogger()->setSessionID(fileLoggerSessionID); + if (myAvatar) { + QUuid fileLoggerSessionID = myAvatar->getSessionUUID(); + if (!fileLoggerSessionID.isNull()) { + qApp->getLogger()->setSessionID(fileLoggerSessionID); + } } + qApp->getLogger()->addMessage(qPrintable(logMessage + "\n")); } } From 387e474889fd7961d63b198a6718a7ccc2ad285f Mon Sep 17 00:00:00 2001 From: Cain Kilgore Date: Fri, 8 Sep 2017 23:48:09 +0100 Subject: [PATCH 08/59] WIP --- interface/src/Application.cpp | 24 ++++++++++++------------ libraries/avatars/src/AvatarData.h | 10 ++++++++-- 2 files changed, 20 insertions(+), 14 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 3ee5406ad0..e373e321f2 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -510,16 +510,6 @@ void messageHandler(QtMsgType type, const QMessageLogContext& context, const QSt OutputDebugStringA(logMessage.toLocal8Bit().constData()); OutputDebugStringA("\n"); #endif - auto avatarManager = DependencyManager::get(); - auto myAvatar = avatarManager ? avatarManager->getMyAvatar() : nullptr; - - if (myAvatar) { - QUuid fileLoggerSessionID = myAvatar->getSessionUUID(); - if (!fileLoggerSessionID.isNull()) { - qApp->getLogger()->setSessionID(fileLoggerSessionID); - } - } - qApp->getLogger()->addMessage(qPrintable(logMessage + "\n")); } } @@ -798,10 +788,19 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo installNativeEventFilter(&MyNativeEventFilter::getInstance()); #endif - _logger = new FileLogger(this); // After setting organization name in order to get correct directory - + qInstallMessageHandler(messageHandler); + _logger = new FileLogger(this); + + connect(getMyAvatar().get(), &AvatarData::sessionUUIDChanged, _logger, [this] { + auto myAvatar = getMyAvatar(); + if (myAvatar) { + _logger->setSessionID(myAvatar->getSessionUUID()); + } + }); + + QFontDatabase::addApplicationFont(PathUtils::resourcesPath() + "styles/Inconsolata.otf"); _window->setWindowTitle("High Fidelity Interface"); @@ -2102,6 +2101,7 @@ Application::~Application() { _octreeProcessor.terminate(); _entityEditSender.terminate(); + disconnect(getMyAvatar().get(), &AvatarData::sessionUUIDChanged, _logger, nullptr); DependencyManager::destroy(); DependencyManager::destroy(); diff --git a/libraries/avatars/src/AvatarData.h b/libraries/avatars/src/AvatarData.h index b4c36dba70..b5bce50e68 100644 --- a/libraries/avatars/src/AvatarData.h +++ b/libraries/avatars/src/AvatarData.h @@ -381,7 +381,7 @@ class AvatarData : public QObject, public SpatiallyNestable { Q_PROPERTY(QStringList jointNames READ getJointNames) - Q_PROPERTY(QUuid sessionUUID READ getSessionUUID) + Q_PROPERTY(QUuid sessionUUID READ getSessionUUID NOTIFY sessionUUIDChanged) Q_PROPERTY(glm::mat4 sensorToWorldMatrix READ getSensorToWorldMatrix) Q_PROPERTY(glm::mat4 controllerLeftHandMatrix READ getControllerLeftHandMatrix) @@ -667,13 +667,19 @@ public: signals: void displayNameChanged(); void lookAtSnappingChanged(bool enabled); + void sessionUUIDChanged(); public slots: void sendAvatarDataPacket(); void sendIdentityPacket(); void setJointMappingsFromNetworkReply(); - void setSessionUUID(const QUuid& sessionUUID) { setID(sessionUUID); } + void setSessionUUID(const QUuid& sessionUUID) { + if (sessionUUID != getID()) { + setID(sessionUUID); + emit sessionUUIDChanged(); + } + } virtual glm::quat getAbsoluteJointRotationInObjectFrame(int index) const override; virtual glm::vec3 getAbsoluteJointTranslationInObjectFrame(int index) const override; From 0820eadc5b154949466311ce190aad83c8b5c00e Mon Sep 17 00:00:00 2001 From: Cain Kilgore Date: Fri, 8 Sep 2017 23:52:04 +0100 Subject: [PATCH 09/59] Fixed a thing --- interface/src/Application.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index e373e321f2..874cf34726 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -789,9 +789,8 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo #endif - qInstallMessageHandler(messageHandler); - _logger = new FileLogger(this); + qInstallMessageHandler(messageHandler); connect(getMyAvatar().get(), &AvatarData::sessionUUIDChanged, _logger, [this] { auto myAvatar = getMyAvatar(); From f6e22b0733569d27a55aac233224cb7fc33abc2c Mon Sep 17 00:00:00 2001 From: Cain Kilgore Date: Sat, 9 Sep 2017 17:21:42 +0100 Subject: [PATCH 10/59] Changes The ID no longer relies on the Avatar Session ID as this changed per domain switch. The intention of this PR is to be able to group the log files easier, hence why it now relies on Interface ID instead. Additionally, when no ID is found when the interface is first launched, the ID doesn't appear in the rolled over log file. It will just appear blank. --- interface/src/Application.cpp | 13 ++++--------- libraries/shared/src/shared/FileLogger.cpp | 9 ++++++--- 2 files changed, 10 insertions(+), 12 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 874cf34726..a063dfd0a1 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -792,14 +792,6 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo _logger = new FileLogger(this); qInstallMessageHandler(messageHandler); - connect(getMyAvatar().get(), &AvatarData::sessionUUIDChanged, _logger, [this] { - auto myAvatar = getMyAvatar(); - if (myAvatar) { - _logger->setSessionID(myAvatar->getSessionUUID()); - } - }); - - QFontDatabase::addApplicationFont(PathUtils::resourcesPath() + "styles/Inconsolata.otf"); _window->setWindowTitle("High Fidelity Interface"); @@ -815,6 +807,9 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo // Set File Logger Session UUID auto avatarManager = DependencyManager::get(); auto myAvatar = avatarManager ? avatarManager->getMyAvatar() : nullptr; + auto accountManager = DependencyManager::get(); + + _logger->setSessionID(accountManager->getSessionID()); if (steamClient) { qCDebug(interfaceapp) << "[VERSION] SteamVR buildID:" << steamClient->getSteamVRBuildID(); @@ -943,7 +938,7 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo connect(nodeList.data(), &NodeList::limitOfSilentDomainCheckInsReached, nodeList.data(), &NodeList::reset); // connect to appropriate slots on AccountManager - auto accountManager = DependencyManager::get(); + // auto accountManager = DependencyManager::get(); auto dialogsManager = DependencyManager::get(); connect(accountManager.data(), &AccountManager::authRequired, dialogsManager.data(), &DialogsManager::showLoginDialog); diff --git a/libraries/shared/src/shared/FileLogger.cpp b/libraries/shared/src/shared/FileLogger.cpp index 46ba45e238..f712a341fe 100644 --- a/libraries/shared/src/shared/FileLogger.cpp +++ b/libraries/shared/src/shared/FileLogger.cpp @@ -42,13 +42,13 @@ private: -static const QString FILENAME_FORMAT = "hifi-log_%1_%2.txt"; +static const QString FILENAME_FORMAT = "hifi-log%1_%2.txt"; static const QString DATETIME_FORMAT = "yyyy-MM-dd_hh.mm.ss"; static const QString LOGS_DIRECTORY = "Logs"; static const QString IPADDR_WILDCARD = "[0-9]*.[0-9]*.[0-9]*.[0-9]*"; static const QString DATETIME_WILDCARD = "20[0-9][0-9]-[0,1][0-9]-[0-3][0-9]_[0-2][0-9].[0-6][0-9].[0-6][0-9]"; static const QString FILENAME_WILDCARD = "hifi-log_" + IPADDR_WILDCARD + "_" + DATETIME_WILDCARD + ".txt"; -QUuid SESSION_ID = QUuid("{00000000-0000-0000-0000-000000000000}"); +QUuid SESSION_ID; // Max log size is 512 KB. We send log files to our crash reporter, so we want to keep this relatively // small so it doesn't go over the 2MB zipped limit for all of the files we send. @@ -64,8 +64,11 @@ QString getLogRollerFilename() { QString result = FileUtils::standardPath(LOGS_DIRECTORY); QHostAddress clientAddress = getGuessedLocalAddress(); QDateTime now = QDateTime::currentDateTime(); + QString FILE_SESSION_ID; - auto FILE_SESSION_ID = SESSION_ID.toString().replace("{", "").replace("}", ""); + if (!SESSION_ID.isNull()) { + FILE_SESSION_ID = "_" + SESSION_ID.toString().replace("{", "").replace("}", ""); + } result.append(QString(FILENAME_FORMAT).arg(FILE_SESSION_ID, now.toString(DATETIME_FORMAT))); return result; From b69bd0ef49f2c04862ca31c56a8f101082309a06 Mon Sep 17 00:00:00 2001 From: Cain Kilgore Date: Sat, 9 Sep 2017 17:23:18 +0100 Subject: [PATCH 11/59] Removed old Disconnect --- interface/src/Application.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index a063dfd0a1..2fa141a44f 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -2095,8 +2095,6 @@ Application::~Application() { _octreeProcessor.terminate(); _entityEditSender.terminate(); - disconnect(getMyAvatar().get(), &AvatarData::sessionUUIDChanged, _logger, nullptr); - DependencyManager::destroy(); DependencyManager::destroy(); DependencyManager::destroy(); From 01e4bfc53e6c7f7054cb707e3c78be116c2ff233 Mon Sep 17 00:00:00 2001 From: samcake Date: Mon, 11 Sep 2017 17:36:10 -0700 Subject: [PATCH 12/59] Trying to avoid calling getTransform on nestables from render thread --- interface/src/Application.cpp | 2 +- interface/src/ui/overlays/Base3DOverlay.cpp | 32 ++++++++++++++++++--- interface/src/ui/overlays/Base3DOverlay.h | 7 ++++- interface/src/ui/overlays/Web3DOverlay.cpp | 21 ++++++-------- interface/src/ui/overlays/Web3DOverlay.h | 4 --- libraries/render-utils/src/Model.cpp | 11 ++++--- 6 files changed, 51 insertions(+), 26 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 3650c495f2..63e4069c01 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -427,7 +427,7 @@ public: // Don't actually crash in debug builds, in case this apparent deadlock is simply from // the developer actively debugging code #ifdef NDEBUG - deadlockDetectionCrash(); + // deadlockDetectionCrash(); #endif } } diff --git a/interface/src/ui/overlays/Base3DOverlay.cpp b/interface/src/ui/overlays/Base3DOverlay.cpp index 010be802a9..56fbc8d873 100644 --- a/interface/src/ui/overlays/Base3DOverlay.cpp +++ b/interface/src/ui/overlays/Base3DOverlay.cpp @@ -191,13 +191,14 @@ void Base3DOverlay::setProperties(const QVariantMap& originalProperties) { // Communicate changes to the renderItem if needed if (needRenderItemUpdate) { - auto itemID = getRenderItemID(); + + /* auto itemID = getRenderItemID(); if (render::Item::isValidID(itemID)) { render::ScenePointer scene = qApp->getMain3DScene(); render::Transaction transaction; transaction.updateItem(itemID); scene->enqueueTransaction(transaction); - } + }*/ } } @@ -259,16 +260,39 @@ void Base3DOverlay::locationChanged(bool tellPhysics) { // Force the actual update of the render transform now that we notify for the change // so it s captured for the time of rendering notifyRenderTransformChange(); - +/* auto itemID = getRenderItemID(); if (render::Item::isValidID(itemID)) { render::ScenePointer scene = qApp->getMain3DScene(); render::Transaction transaction; transaction.updateItem(itemID); scene->enqueueTransaction(transaction); - } + }*/ } void Base3DOverlay::parentDeleted() { qApp->getOverlays().deleteOverlay(getOverlayID()); } + +void Base3DOverlay::update(float duration) { + if (_renderTransformDirty) { + setRenderTransform(evalRenderTransform()); + auto itemID = getRenderItemID(); + if (render::Item::isValidID(itemID)) { + render::ScenePointer scene = qApp->getMain3DScene(); + render::Transaction transaction; + + transaction.updateItem(itemID); + scene->enqueueTransaction(transaction); + } + _renderTransformDirty = false; + } +} + +Transform Base3DOverlay::evalRenderTransform() const { + return getTransform(); +} + +void Base3DOverlay::setRenderTransform(const Transform& transform) { + _renderTransform = transform; +} diff --git a/interface/src/ui/overlays/Base3DOverlay.h b/interface/src/ui/overlays/Base3DOverlay.h index 3f57f2e577..fa26993724 100644 --- a/interface/src/ui/overlays/Base3DOverlay.h +++ b/interface/src/ui/overlays/Base3DOverlay.h @@ -52,8 +52,11 @@ public: virtual AABox getBounds() const override = 0; + void update(float deltatime) override; + void notifyRenderTransformChange() const { _renderTransformDirty = true; } - virtual Transform evalRenderTransform() const { return Transform(); } + virtual Transform evalRenderTransform() const; + void setRenderTransform(const Transform& transform); void setProperties(const QVariantMap& properties) override; QVariant getProperty(const QString& property) override; @@ -70,6 +73,8 @@ protected: virtual void locationChanged(bool tellPhysics = true) override; virtual void parentDeleted() override; + mutable Transform _renderTransform; + float _lineWidth; bool _isSolid; bool _isDashedLine; diff --git a/interface/src/ui/overlays/Web3DOverlay.cpp b/interface/src/ui/overlays/Web3DOverlay.cpp index 9ad2cef443..490460fdb3 100644 --- a/interface/src/ui/overlays/Web3DOverlay.cpp +++ b/interface/src/ui/overlays/Web3DOverlay.cpp @@ -180,7 +180,7 @@ void Web3DOverlay::buildWebSurface() { void Web3DOverlay::update(float deltatime) { - if (_renderTransformDirty) { + /* if (_renderTransformDirty) { auto updateTransform = evalRenderTransform(); auto itemID = getRenderItemID(); if (render::Item::isValidID(itemID)) { @@ -194,17 +194,19 @@ void Web3DOverlay::update(float deltatime) { }); scene->enqueueTransaction(transaction); } - } + }*/ if (_webSurface) { // update globalPosition _webSurface->getSurfaceContext()->setContextProperty("globalPosition", vec3toVariant(getPosition())); } + + Billboard3DOverlay::update(deltatime); + } Transform Web3DOverlay::evalRenderTransform() const { - if (_renderTransformDirty) { - _updateTransform = getTransform(); + auto transform = getTransform(); // FIXME: applyTransformTo causes tablet overlay to detach from tablet entity. // Perhaps rather than deleting the following code it should be run only if isFacingAvatar() is true? @@ -214,15 +216,10 @@ Transform Web3DOverlay::evalRenderTransform() const { */ if (glm::length2(getDimensions()) != 1.0f) { - _updateTransform.postScale(vec3(getDimensions(), 1.0f)); + transform.postScale(vec3(getDimensions(), 1.0f)); } - _renderTransformDirty = false; - } - return _updateTransform; -} - -void Web3DOverlay::setRenderTransform(const Transform& transform) { - _renderTransform = transform; + + return transform; } QString Web3DOverlay::pickURL() { diff --git a/interface/src/ui/overlays/Web3DOverlay.h b/interface/src/ui/overlays/Web3DOverlay.h index ef40d88333..7acaf5a430 100644 --- a/interface/src/ui/overlays/Web3DOverlay.h +++ b/interface/src/ui/overlays/Web3DOverlay.h @@ -38,7 +38,6 @@ public: virtual void update(float deltatime) override; Transform evalRenderTransform() const override; - void setRenderTransform(const Transform& transform); QObject* getEventHandler(); void setProxyWindow(QWindow* proxyWindow); @@ -95,9 +94,6 @@ private: std::map _activeTouchPoints; QTouchDevice _touchDevice; - mutable Transform _updateTransform; - mutable Transform _renderTransform; - uint8_t _desiredMaxFPS { 10 }; uint8_t _currentMaxFPS { 0 }; diff --git a/libraries/render-utils/src/Model.cpp b/libraries/render-utils/src/Model.cpp index 42bb91ce94..5fc7c7a1b1 100644 --- a/libraries/render-utils/src/Model.cpp +++ b/libraries/render-utils/src/Model.cpp @@ -235,15 +235,18 @@ void Model::updateRenderItems() { uint32_t deleteGeometryCounter = self->_deleteGeometryCounter; + Transform modelTransform = self->getTransform(); + // Transform modelTransform = model->getTransform(); + modelTransform.setScale(glm::vec3(1.0f)); + render::Transaction transaction; foreach (auto itemID, self->_modelMeshRenderItemsMap.keys()) { - transaction.updateItem(itemID, [deleteGeometryCounter](ModelMeshPartPayload& data) { + transaction.updateItem(itemID, [deleteGeometryCounter, modelTransform](ModelMeshPartPayload& data) { ModelPointer model = data._model.lock(); if (model && model->isLoaded()) { // Ensure the model geometry was not reset between frames if (deleteGeometryCounter == model->_deleteGeometryCounter) { - Transform modelTransform = model->getTransform(); - modelTransform.setScale(glm::vec3(1.0f)); + const Model::MeshState& state = model->getMeshState(data._meshIndex); Transform renderTransform = modelTransform; @@ -259,7 +262,7 @@ void Model::updateRenderItems() { // collision mesh does not share the same unit scale as the FBX file's mesh: only apply offset Transform collisionMeshOffset; collisionMeshOffset.setIdentity(); - Transform modelTransform = self->getTransform(); + // Transform modelTransform = self->getTransform(); foreach(auto itemID, self->_collisionRenderItemsMap.keys()) { transaction.updateItem(itemID, [modelTransform, collisionMeshOffset](MeshPartPayload& data) { // update the model transform for this render item. From 3669e66619f7b8034dc748c15730b231a27c75df Mon Sep 17 00:00:00 2001 From: Sam Gateau Date: Tue, 12 Sep 2017 00:02:54 -0700 Subject: [PATCH 13/59] trying to update the transform at the right time in overlays --- interface/src/ui/overlays/Base3DOverlay.cpp | 3 +- .../src/ui/overlays/Billboard3DOverlay.cpp | 1 + interface/src/ui/overlays/ModelOverlay.cpp | 48 ++++++++++++------- interface/src/ui/overlays/Planar3DOverlay.cpp | 10 ++++ interface/src/ui/overlays/Planar3DOverlay.h | 4 +- interface/src/ui/overlays/Web3DOverlay.cpp | 48 ------------------- interface/src/ui/overlays/Web3DOverlay.h | 2 - 7 files changed, 48 insertions(+), 68 deletions(-) diff --git a/interface/src/ui/overlays/Base3DOverlay.cpp b/interface/src/ui/overlays/Base3DOverlay.cpp index 56fbc8d873..af6206e819 100644 --- a/interface/src/ui/overlays/Base3DOverlay.cpp +++ b/interface/src/ui/overlays/Base3DOverlay.cpp @@ -191,8 +191,9 @@ void Base3DOverlay::setProperties(const QVariantMap& originalProperties) { // Communicate changes to the renderItem if needed if (needRenderItemUpdate) { + notifyRenderTransformChange(); - /* auto itemID = getRenderItemID(); + /*auto itemID = getRenderItemID(); if (render::Item::isValidID(itemID)) { render::ScenePointer scene = qApp->getMain3DScene(); render::Transaction transaction; diff --git a/interface/src/ui/overlays/Billboard3DOverlay.cpp b/interface/src/ui/overlays/Billboard3DOverlay.cpp index f5668caa71..a333df0821 100644 --- a/interface/src/ui/overlays/Billboard3DOverlay.cpp +++ b/interface/src/ui/overlays/Billboard3DOverlay.cpp @@ -45,3 +45,4 @@ bool Billboard3DOverlay::applyTransformTo(Transform& transform, bool force) { } return transformChanged; } + diff --git a/interface/src/ui/overlays/ModelOverlay.cpp b/interface/src/ui/overlays/ModelOverlay.cpp index 0bed07891e..f65faaca12 100644 --- a/interface/src/ui/overlays/ModelOverlay.cpp +++ b/interface/src/ui/overlays/ModelOverlay.cpp @@ -59,20 +59,6 @@ void ModelOverlay::update(float deltatime) { _model->simulate(deltatime); } _isLoaded = _model->isActive(); -} - -bool ModelOverlay::addToScene(Overlay::Pointer overlay, const render::ScenePointer& scene, render::Transaction& transaction) { - Volume3DOverlay::addToScene(overlay, scene, transaction); - _model->addToScene(scene, transaction); - return true; -} - -void ModelOverlay::removeFromScene(Overlay::Pointer overlay, const render::ScenePointer& scene, render::Transaction& transaction) { - Volume3DOverlay::removeFromScene(overlay, scene, transaction); - _model->removeFromScene(scene, transaction); -} - -void ModelOverlay::render(RenderArgs* args) { // check to see if when we added our model to the scene they were ready, if they were not ready, then // fix them up in the scene @@ -89,6 +75,35 @@ void ModelOverlay::render(RenderArgs* args) { scene->enqueueTransaction(transaction); } +bool ModelOverlay::addToScene(Overlay::Pointer overlay, const render::ScenePointer& scene, render::Transaction& transaction) { + Volume3DOverlay::addToScene(overlay, scene, transaction); + _model->addToScene(scene, transaction); + return true; +} + +void ModelOverlay::removeFromScene(Overlay::Pointer overlay, const render::ScenePointer& scene, render::Transaction& transaction) { + Volume3DOverlay::removeFromScene(overlay, scene, transaction); + _model->removeFromScene(scene, transaction); +} + +void ModelOverlay::render(RenderArgs* args) { +/* + // check to see if when we added our model to the scene they were ready, if they were not ready, then + // fix them up in the scene + render::ScenePointer scene = qApp->getMain3DScene(); + render::Transaction transaction; + if (_model->needsFixupInScene()) { + _model->removeFromScene(scene, transaction); + _model->addToScene(scene, transaction); + } + + _model->setVisibleInScene(_visible, scene); + _model->setLayeredInFront(getDrawInFront(), scene); + + scene->enqueueTransaction(transaction); + */ +} + void ModelOverlay::setProperties(const QVariantMap& properties) { auto origPosition = getPosition(); auto origRotation = getRotation(); @@ -280,11 +295,12 @@ ModelOverlay* ModelOverlay::createClone() const { void ModelOverlay::locationChanged(bool tellPhysics) { Base3DOverlay::locationChanged(tellPhysics); - +/* if (_model && _model->isActive()) { _model->setRotation(getRotation()); _model->setTranslation(getPosition()); - } + }*/ + _updateModel = true; } QString ModelOverlay::getName() const { diff --git a/interface/src/ui/overlays/Planar3DOverlay.cpp b/interface/src/ui/overlays/Planar3DOverlay.cpp index 58d72b100b..a979120dc6 100644 --- a/interface/src/ui/overlays/Planar3DOverlay.cpp +++ b/interface/src/ui/overlays/Planar3DOverlay.cpp @@ -66,3 +66,13 @@ bool Planar3DOverlay::findRayIntersection(const glm::vec3& origin, const glm::ve // FIXME - face and surfaceNormal not being returned return findRayRectangleIntersection(origin, direction, getRotation(), getPosition(), getDimensions(), distance); } + +Transform Planar3DOverlay::evalRenderTransform() const { + auto transform = getTransform(); + + if (glm::length2(getDimensions()) != 1.0f) { + transform.postScale(vec3(getDimensions(), 1.0f)); + } + + return transform; +} \ No newline at end of file diff --git a/interface/src/ui/overlays/Planar3DOverlay.h b/interface/src/ui/overlays/Planar3DOverlay.h index 8127d4ebb9..9e4babae8d 100644 --- a/interface/src/ui/overlays/Planar3DOverlay.h +++ b/interface/src/ui/overlays/Planar3DOverlay.h @@ -32,7 +32,9 @@ public: virtual bool findRayIntersection(const glm::vec3& origin, const glm::vec3& direction, float& distance, BoxFace& face, glm::vec3& surfaceNormal) override; - + + Transform evalRenderTransform() const override; + protected: glm::vec2 _dimensions; }; diff --git a/interface/src/ui/overlays/Web3DOverlay.cpp b/interface/src/ui/overlays/Web3DOverlay.cpp index 490460fdb3..a1f68add4a 100644 --- a/interface/src/ui/overlays/Web3DOverlay.cpp +++ b/interface/src/ui/overlays/Web3DOverlay.cpp @@ -180,22 +180,6 @@ void Web3DOverlay::buildWebSurface() { void Web3DOverlay::update(float deltatime) { - /* if (_renderTransformDirty) { - auto updateTransform = evalRenderTransform(); - auto itemID = getRenderItemID(); - if (render::Item::isValidID(itemID)) { - render::ScenePointer scene = qApp->getMain3DScene(); - render::Transaction transaction; - transaction.updateItem(itemID, [updateTransform](Overlay& data) { - auto web3D = dynamic_cast(&data); - if (web3D) { - web3D->setRenderTransform(updateTransform);// evalRenderTransform(); - } - }); - scene->enqueueTransaction(transaction); - } - }*/ - if (_webSurface) { // update globalPosition _webSurface->getSurfaceContext()->setContextProperty("globalPosition", vec3toVariant(getPosition())); @@ -205,23 +189,6 @@ void Web3DOverlay::update(float deltatime) { } -Transform Web3DOverlay::evalRenderTransform() const { - auto transform = getTransform(); - - // FIXME: applyTransformTo causes tablet overlay to detach from tablet entity. - // Perhaps rather than deleting the following code it should be run only if isFacingAvatar() is true? - /* - applyTransformTo(transform, true); - setTransform(transform); - */ - - if (glm::length2(getDimensions()) != 1.0f) { - transform.postScale(vec3(getDimensions(), 1.0f)); - } - - return transform; -} - QString Web3DOverlay::pickURL() { QUrl sourceUrl(_url); if (sourceUrl.scheme() == "http" || sourceUrl.scheme() == "https" || @@ -341,20 +308,6 @@ void Web3DOverlay::render(RenderArgs* args) { vec2 halfSize = getSize() / 2.0f; vec4 color(toGlm(getColor()), getAlpha()); - /* - Transform transform = getTransform(); - - // FIXME: applyTransformTo causes tablet overlay to detach from tablet entity. - // Perhaps rather than deleting the following code it should be run only if isFacingAvatar() is true? - /* - applyTransformTo(transform, true); - setTransform(transform); - */ - /* - if (glm::length2(getDimensions()) != 1.0f) { - transform.postScale(vec3(getDimensions(), 1.0f)); - } - */ if (!_texture) { _texture = gpu::Texture::createExternal(OffscreenQmlSurface::getDiscardLambda()); @@ -369,7 +322,6 @@ void Web3DOverlay::render(RenderArgs* args) { Q_ASSERT(args->_batch); gpu::Batch& batch = *args->_batch; batch.setResourceTexture(0, _texture); - // batch.setModelTransform(transform); batch.setModelTransform(_renderTransform); auto geometryCache = DependencyManager::get(); if (color.a < OPAQUE_ALPHA_THRESHOLD) { diff --git a/interface/src/ui/overlays/Web3DOverlay.h b/interface/src/ui/overlays/Web3DOverlay.h index 7acaf5a430..2eae7f33da 100644 --- a/interface/src/ui/overlays/Web3DOverlay.h +++ b/interface/src/ui/overlays/Web3DOverlay.h @@ -37,8 +37,6 @@ public: virtual void update(float deltatime) override; - Transform evalRenderTransform() const override; - QObject* getEventHandler(); void setProxyWindow(QWindow* proxyWindow); void handlePointerEvent(const PointerEvent& event); From 10b1e3f561d5994071c51accdf7ee50dabfdf47d Mon Sep 17 00:00:00 2001 From: samcake Date: Tue, 12 Sep 2017 14:35:25 -0700 Subject: [PATCH 14/59] Trying to implement differnet solution to the transform updates problem and debug --- interface/src/ui/overlays/Base3DOverlay.cpp | 54 ++++++++++++++++----- interface/src/ui/overlays/Base3DOverlay.h | 2 +- libraries/render-utils/src/Model.cpp | 10 ++-- 3 files changed, 50 insertions(+), 16 deletions(-) diff --git a/interface/src/ui/overlays/Base3DOverlay.cpp b/interface/src/ui/overlays/Base3DOverlay.cpp index af6206e819..22448cc719 100644 --- a/interface/src/ui/overlays/Base3DOverlay.cpp +++ b/interface/src/ui/overlays/Base3DOverlay.cpp @@ -191,15 +191,15 @@ void Base3DOverlay::setProperties(const QVariantMap& originalProperties) { // Communicate changes to the renderItem if needed if (needRenderItemUpdate) { - notifyRenderTransformChange(); + // notifyRenderTransformChange(); - /*auto itemID = getRenderItemID(); + auto itemID = getRenderItemID(); if (render::Item::isValidID(itemID)) { render::ScenePointer scene = qApp->getMain3DScene(); render::Transaction transaction; transaction.updateItem(itemID); scene->enqueueTransaction(transaction); - }*/ + } } } @@ -277,19 +277,51 @@ void Base3DOverlay::parentDeleted() { void Base3DOverlay::update(float duration) { if (_renderTransformDirty) { - setRenderTransform(evalRenderTransform()); - auto itemID = getRenderItemID(); - if (render::Item::isValidID(itemID)) { - render::ScenePointer scene = qApp->getMain3DScene(); - render::Transaction transaction; + auto self = this; + // queue up this work for later processing, at the end of update and just before rendering. + // the application will ensure only the last lambda is actually invoked. + /* void* key = (void*)this; + std::weak_ptr weakSelf = shared_from_this(); + AbstractViewStateInterface::instance()->pushPostUpdateLambda(key, [weakSelf]() { + // do nothing, if the model has already been destroyed. + auto spatiallyNestableSelf = weakSelf.lock(); + if (!spatiallyNestableSelf) { + return; + } + auto self = std::dynamic_pointer_cast(spatiallyNestableSelf); + */ +#ifdef UpdateInMain + self->setRenderTransform(self->evalRenderTransform()); +#else + auto renderTransform = self->evalRenderTransform(); +#endif + auto itemID = self->getRenderItemID(); - transaction.updateItem(itemID); - scene->enqueueTransaction(transaction); - } + if (render::Item::isValidID(itemID)) { + render::ScenePointer scene = qApp->getMain3DScene(); + render::Transaction transaction; + +#ifdef UpdateInMain + transaction.updateItem(itemID); +#else + transaction.updateItem(itemID, [renderTransform](Overlay& data) { + auto overlay3D = dynamic_cast(&data); + if (overlay3D) { + overlay3D->setRenderTransform(renderTransform);// evalRenderTransform(); + } + }); +#endif + scene->enqueueTransaction(transaction); + } + // }); _renderTransformDirty = false; } } +void Base3DOverlay::notifyRenderTransformChange() const { + _renderTransformDirty = true; +} + Transform Base3DOverlay::evalRenderTransform() const { return getTransform(); } diff --git a/interface/src/ui/overlays/Base3DOverlay.h b/interface/src/ui/overlays/Base3DOverlay.h index fa26993724..b40727a807 100644 --- a/interface/src/ui/overlays/Base3DOverlay.h +++ b/interface/src/ui/overlays/Base3DOverlay.h @@ -54,7 +54,7 @@ public: void update(float deltatime) override; - void notifyRenderTransformChange() const { _renderTransformDirty = true; } + void notifyRenderTransformChange() const; virtual Transform evalRenderTransform() const; void setRenderTransform(const Transform& transform); diff --git a/libraries/render-utils/src/Model.cpp b/libraries/render-utils/src/Model.cpp index 5fc7c7a1b1..9e552859e3 100644 --- a/libraries/render-utils/src/Model.cpp +++ b/libraries/render-utils/src/Model.cpp @@ -235,18 +235,20 @@ void Model::updateRenderItems() { uint32_t deleteGeometryCounter = self->_deleteGeometryCounter; - Transform modelTransform = self->getTransform(); + // Transform modelTransform = self->getTransform(); // Transform modelTransform = model->getTransform(); - modelTransform.setScale(glm::vec3(1.0f)); + // modelTransform.setScale(glm::vec3(1.0f)); render::Transaction transaction; foreach (auto itemID, self->_modelMeshRenderItemsMap.keys()) { - transaction.updateItem(itemID, [deleteGeometryCounter, modelTransform](ModelMeshPartPayload& data) { + transaction.updateItem(itemID, [deleteGeometryCounter /*, modelTransform*/](ModelMeshPartPayload& data) { ModelPointer model = data._model.lock(); if (model && model->isLoaded()) { // Ensure the model geometry was not reset between frames if (deleteGeometryCounter == model->_deleteGeometryCounter) { + Transform modelTransform = model->getTransform(); + modelTransform.setScale(glm::vec3(1.0f)); const Model::MeshState& state = model->getMeshState(data._meshIndex); Transform renderTransform = modelTransform; @@ -262,7 +264,7 @@ void Model::updateRenderItems() { // collision mesh does not share the same unit scale as the FBX file's mesh: only apply offset Transform collisionMeshOffset; collisionMeshOffset.setIdentity(); - // Transform modelTransform = self->getTransform(); + Transform modelTransform = self->getTransform(); foreach(auto itemID, self->_collisionRenderItemsMap.keys()) { transaction.updateItem(itemID, [modelTransform, collisionMeshOffset](MeshPartPayload& data) { // update the model transform for this render item. From 1c05311056cb64385ff93f69de0d66310174e0f4 Mon Sep 17 00:00:00 2001 From: Cain Kilgore Date: Wed, 13 Sep 2017 16:48:18 +0100 Subject: [PATCH 15/59] Some code cleanup --- interface/src/Application.cpp | 3 --- libraries/shared/src/shared/FileLogger.cpp | 16 +++++++++------- 2 files changed, 9 insertions(+), 10 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 2fa141a44f..8de6d93dd6 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -937,9 +937,6 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo // you might think we could just do this in NodeList but we only want this connection for Interface connect(nodeList.data(), &NodeList::limitOfSilentDomainCheckInsReached, nodeList.data(), &NodeList::reset); - // connect to appropriate slots on AccountManager - // auto accountManager = DependencyManager::get(); - auto dialogsManager = DependencyManager::get(); connect(accountManager.data(), &AccountManager::authRequired, dialogsManager.data(), &DialogsManager::showLoginDialog); connect(accountManager.data(), &AccountManager::usernameChanged, this, &Application::updateWindowTitle); diff --git a/libraries/shared/src/shared/FileLogger.cpp b/libraries/shared/src/shared/FileLogger.cpp index f712a341fe..50b0ccb43c 100644 --- a/libraries/shared/src/shared/FileLogger.cpp +++ b/libraries/shared/src/shared/FileLogger.cpp @@ -48,7 +48,7 @@ static const QString LOGS_DIRECTORY = "Logs"; static const QString IPADDR_WILDCARD = "[0-9]*.[0-9]*.[0-9]*.[0-9]*"; static const QString DATETIME_WILDCARD = "20[0-9][0-9]-[0,1][0-9]-[0-3][0-9]_[0-2][0-9].[0-6][0-9].[0-6][0-9]"; static const QString FILENAME_WILDCARD = "hifi-log_" + IPADDR_WILDCARD + "_" + DATETIME_WILDCARD + ".txt"; -QUuid SESSION_ID; +QUuid _sessionId; // Max log size is 512 KB. We send log files to our crash reporter, so we want to keep this relatively // small so it doesn't go over the 2MB zipped limit for all of the files we send. @@ -64,13 +64,13 @@ QString getLogRollerFilename() { QString result = FileUtils::standardPath(LOGS_DIRECTORY); QHostAddress clientAddress = getGuessedLocalAddress(); QDateTime now = QDateTime::currentDateTime(); - QString FILE_SESSION_ID; + QString fileSessionID; - if (!SESSION_ID.isNull()) { - FILE_SESSION_ID = "_" + SESSION_ID.toString().replace("{", "").replace("}", ""); + if (!_sessionId.isNull()) { + fileSessionID = "_" + _sessionId.toString().replace("{", "").replace("}", ""); } - result.append(QString(FILENAME_FORMAT).arg(FILE_SESSION_ID, now.toString(DATETIME_FORMAT))); + result.append(QString(FILENAME_FORMAT).arg(fileSessionID, now.toString(DATETIME_FORMAT))); return result; } @@ -151,8 +151,10 @@ FileLogger::~FileLogger() { } void FileLogger::setSessionID(const QUuid& message) { - SESSION_ID = message; // This is for the output of log files. It will change if the Avatar enters a different domain. -} + // This is for the output of log files. Once the application is first started, + // this function runs and grabs the AccountManager Session ID and saves it here. + _sessionId = message; + } void FileLogger::addMessage(const QString& message) { _persistThreadInstance->queueItem(message); From 2427008ff333ad534c2c0e3c14c7e3de0a4b90a5 Mon Sep 17 00:00:00 2001 From: Cain Kilgore Date: Wed, 13 Sep 2017 17:40:04 +0100 Subject: [PATCH 16/59] Static --- libraries/shared/src/shared/FileLogger.cpp | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/libraries/shared/src/shared/FileLogger.cpp b/libraries/shared/src/shared/FileLogger.cpp index 50b0ccb43c..b019b69fb8 100644 --- a/libraries/shared/src/shared/FileLogger.cpp +++ b/libraries/shared/src/shared/FileLogger.cpp @@ -26,7 +26,6 @@ class FilePersistThread : public GenericQueueThread < QString > { Q_OBJECT public: FilePersistThread(const FileLogger& logger); - signals: void rollingLogFile(QString newFilename); @@ -48,7 +47,7 @@ static const QString LOGS_DIRECTORY = "Logs"; static const QString IPADDR_WILDCARD = "[0-9]*.[0-9]*.[0-9]*.[0-9]*"; static const QString DATETIME_WILDCARD = "20[0-9][0-9]-[0,1][0-9]-[0-3][0-9]_[0-2][0-9].[0-6][0-9].[0-6][0-9]"; static const QString FILENAME_WILDCARD = "hifi-log_" + IPADDR_WILDCARD + "_" + DATETIME_WILDCARD + ".txt"; -QUuid _sessionId; +static QUuid SESSION_ID; // Max log size is 512 KB. We send log files to our crash reporter, so we want to keep this relatively // small so it doesn't go over the 2MB zipped limit for all of the files we send. @@ -66,8 +65,8 @@ QString getLogRollerFilename() { QDateTime now = QDateTime::currentDateTime(); QString fileSessionID; - if (!_sessionId.isNull()) { - fileSessionID = "_" + _sessionId.toString().replace("{", "").replace("}", ""); + if (!SESSION_ID.isNull()) { + fileSessionID = "_" + SESSION_ID.toString().replace("{", "").replace("}", ""); } result.append(QString(FILENAME_FORMAT).arg(fileSessionID, now.toString(DATETIME_FORMAT))); @@ -153,7 +152,7 @@ FileLogger::~FileLogger() { void FileLogger::setSessionID(const QUuid& message) { // This is for the output of log files. Once the application is first started, // this function runs and grabs the AccountManager Session ID and saves it here. - _sessionId = message; + SESSION_ID = message; } void FileLogger::addMessage(const QString& message) { From a70f7dfc878de238c92ade1b452d30f493f631cb Mon Sep 17 00:00:00 2001 From: Sam Gateau Date: Wed, 13 Sep 2017 22:05:20 -0700 Subject: [PATCH 17/59] put updateCamera in its function --- interface/src/Application.cpp | 112 +++++++++++++++++++++++++++++++++- interface/src/Application.h | 2 + 2 files changed, 111 insertions(+), 3 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 63e4069c01..4efad9000b 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -2371,6 +2371,111 @@ void Application::initializeUi() { offscreenSurfaceCache->reserve(Web3DOverlay::QML, 2); } +void Application::updateCamera(RenderArgs& renderArgs) { + + glm::vec3 boomOffset; + { + PROFILE_RANGE(render, "/updateCamera"); + { + PerformanceTimer perfTimer("CameraUpdates"); + + auto myAvatar = getMyAvatar(); + boomOffset = myAvatar->getScale() * myAvatar->getBoomLength() * -IDENTITY_FORWARD; + + // The render mode is default or mirror if the camera is in mirror mode, assigned further below + renderArgs._renderMode = RenderArgs::DEFAULT_RENDER_MODE; + renderArgs._boomOffset = boomOffset; + + // Always use the default eye position, not the actual head eye position. + // Using the latter will cause the camera to wobble with idle animations, + // or with changes from the face tracker + if (_myCamera.getMode() == CAMERA_MODE_FIRST_PERSON) { + if (isHMDMode()) { + mat4 camMat = myAvatar->getSensorToWorldMatrix() * myAvatar->getHMDSensorMatrix(); + _myCamera.setPosition(extractTranslation(camMat)); + _myCamera.setOrientation(glm::quat_cast(camMat)); + } + else { + _myCamera.setPosition(myAvatar->getDefaultEyePosition()); + _myCamera.setOrientation(myAvatar->getMyHead()->getHeadOrientation()); + } + } + else if (_myCamera.getMode() == CAMERA_MODE_THIRD_PERSON) { + if (isHMDMode()) { + auto hmdWorldMat = myAvatar->getSensorToWorldMatrix() * myAvatar->getHMDSensorMatrix(); + _myCamera.setOrientation(glm::normalize(glm::quat_cast(hmdWorldMat))); + _myCamera.setPosition(extractTranslation(hmdWorldMat) + + myAvatar->getOrientation() * boomOffset); + } + else { + _myCamera.setOrientation(myAvatar->getHead()->getOrientation()); + if (Menu::getInstance()->isOptionChecked(MenuOption::CenterPlayerInView)) { + _myCamera.setPosition(myAvatar->getDefaultEyePosition() + + _myCamera.getOrientation() * boomOffset); + } + else { + _myCamera.setPosition(myAvatar->getDefaultEyePosition() + + myAvatar->getOrientation() * boomOffset); + } + } + } + else if (_myCamera.getMode() == CAMERA_MODE_MIRROR) { + if (isHMDMode()) { + auto mirrorBodyOrientation = myAvatar->getOrientation() * glm::quat(glm::vec3(0.0f, PI + _rotateMirror, 0.0f)); + + glm::quat hmdRotation = extractRotation(myAvatar->getHMDSensorMatrix()); + // Mirror HMD yaw and roll + glm::vec3 mirrorHmdEulers = glm::eulerAngles(hmdRotation); + mirrorHmdEulers.y = -mirrorHmdEulers.y; + mirrorHmdEulers.z = -mirrorHmdEulers.z; + glm::quat mirrorHmdRotation = glm::quat(mirrorHmdEulers); + + glm::quat worldMirrorRotation = mirrorBodyOrientation * mirrorHmdRotation; + + _myCamera.setOrientation(worldMirrorRotation); + + glm::vec3 hmdOffset = extractTranslation(myAvatar->getHMDSensorMatrix()); + // Mirror HMD lateral offsets + hmdOffset.x = -hmdOffset.x; + + _myCamera.setPosition(myAvatar->getDefaultEyePosition() + + glm::vec3(0, _raiseMirror * myAvatar->getUniformScale(), 0) + + mirrorBodyOrientation * glm::vec3(0.0f, 0.0f, 1.0f) * MIRROR_FULLSCREEN_DISTANCE * _scaleMirror + + mirrorBodyOrientation * hmdOffset); + } + else { + _myCamera.setOrientation(myAvatar->getOrientation() + * glm::quat(glm::vec3(0.0f, PI + _rotateMirror, 0.0f))); + _myCamera.setPosition(myAvatar->getDefaultEyePosition() + + glm::vec3(0, _raiseMirror * myAvatar->getUniformScale(), 0) + + (myAvatar->getOrientation() * glm::quat(glm::vec3(0.0f, _rotateMirror, 0.0f))) * + glm::vec3(0.0f, 0.0f, -1.0f) * MIRROR_FULLSCREEN_DISTANCE * _scaleMirror); + } + renderArgs._renderMode = RenderArgs::MIRROR_RENDER_MODE; + } + else if (_myCamera.getMode() == CAMERA_MODE_ENTITY) { + EntityItemPointer cameraEntity = _myCamera.getCameraEntityPointer(); + if (cameraEntity != nullptr) { + if (isHMDMode()) { + glm::quat hmdRotation = extractRotation(myAvatar->getHMDSensorMatrix()); + _myCamera.setOrientation(cameraEntity->getRotation() * hmdRotation); + glm::vec3 hmdOffset = extractTranslation(myAvatar->getHMDSensorMatrix()); + _myCamera.setPosition(cameraEntity->getPosition() + (hmdRotation * hmdOffset)); + } + else { + _myCamera.setOrientation(cameraEntity->getRotation()); + _myCamera.setPosition(cameraEntity->getPosition()); + } + } + } + // Update camera position + if (!isHMDMode()) { + _myCamera.update(1.0f / _frameCounter.rate()); + } + } + } +} + void Application::paintGL() { // Some plugins process message events, allowing paintGL to be called reentrantly. if (_aboutToQuit || _window->isMinimized()) { @@ -2457,7 +2562,9 @@ void Application::paintGL() { _applicationOverlay.renderOverlay(&renderArgs); } - glm::vec3 boomOffset; + updateCamera(renderArgs); + + /* glm::vec3 boomOffset; { PROFILE_RANGE(render, "/updateCamera"); { @@ -2549,7 +2656,7 @@ void Application::paintGL() { } } } - + */ { PROFILE_RANGE(render, "/updateCompositor"); getApplicationCompositor().setFrameInfo(_frameCount, _myCamera.getTransform()); @@ -2570,7 +2677,6 @@ void Application::paintGL() { { PROFILE_RANGE(render, "/mainRender"); PerformanceTimer perfTimer("mainRender"); - renderArgs._boomOffset = boomOffset; // FIXME is this ever going to be different from the size previously set in the render args // in the overlay render? // Viewport is assigned to the size of the framebuffer diff --git a/interface/src/Application.h b/interface/src/Application.h index c7f83ad28f..3a6a183512 100644 --- a/interface/src/Application.h +++ b/interface/src/Application.h @@ -147,6 +147,8 @@ public: void initializeGL(); void initializeUi(); + + void updateCamera(RenderArgs& renderArgs); void paintGL(); void resizeGL(); From bff578b283d17d5d2c21050db34015e2cb4c6adc Mon Sep 17 00:00:00 2001 From: samcake Date: Thu, 14 Sep 2017 17:07:50 -0700 Subject: [PATCH 18/59] Working version that fixes the web overlay / tablet --- interface/src/ui/overlays/Base3DOverlay.cpp | 3 ++- libraries/render-utils/src/Model.cpp | 17 ++++++++++++----- 2 files changed, 14 insertions(+), 6 deletions(-) diff --git a/interface/src/ui/overlays/Base3DOverlay.cpp b/interface/src/ui/overlays/Base3DOverlay.cpp index 22448cc719..7d6fa40989 100644 --- a/interface/src/ui/overlays/Base3DOverlay.cpp +++ b/interface/src/ui/overlays/Base3DOverlay.cpp @@ -307,7 +307,8 @@ void Base3DOverlay::update(float duration) { transaction.updateItem(itemID, [renderTransform](Overlay& data) { auto overlay3D = dynamic_cast(&data); if (overlay3D) { - overlay3D->setRenderTransform(renderTransform);// evalRenderTransform(); + auto latestTransform = overlay3D->evalRenderTransform(); + overlay3D->setRenderTransform(latestTransform);// evalRenderTransform(); } }); #endif diff --git a/libraries/render-utils/src/Model.cpp b/libraries/render-utils/src/Model.cpp index 9e552859e3..5041f953a1 100644 --- a/libraries/render-utils/src/Model.cpp +++ b/libraries/render-utils/src/Model.cpp @@ -234,21 +234,28 @@ void Model::updateRenderItems() { self->updateClusterMatrices(); uint32_t deleteGeometryCounter = self->_deleteGeometryCounter; - - // Transform modelTransform = self->getTransform(); +#ifdef CAPTURE_TRANSFORM_IN_GAMEPLAY + Transform modelTransform = self->getTransform(); // Transform modelTransform = model->getTransform(); - // modelTransform.setScale(glm::vec3(1.0f)); - + modelTransform.setScale(glm::vec3(1.0f)); +#endif render::Transaction transaction; foreach (auto itemID, self->_modelMeshRenderItemsMap.keys()) { - transaction.updateItem(itemID, [deleteGeometryCounter /*, modelTransform*/](ModelMeshPartPayload& data) { + transaction.updateItem(itemID, [deleteGeometryCounter +#ifdef CAPTURE_TRANSFORM_IN_GAMEPLAY + , modelTransform +#endif + ](ModelMeshPartPayload& data) { ModelPointer model = data._model.lock(); if (model && model->isLoaded()) { // Ensure the model geometry was not reset between frames if (deleteGeometryCounter == model->_deleteGeometryCounter) { +#ifdef CAPTURE_TRANSFORM_IN_GAMEPLAY +#else Transform modelTransform = model->getTransform(); modelTransform.setScale(glm::vec3(1.0f)); +#endif const Model::MeshState& state = model->getMeshState(data._meshIndex); Transform renderTransform = modelTransform; From eed099502aa469bb6536ac222624115192be6f60 Mon Sep 17 00:00:00 2001 From: samcake Date: Thu, 21 Sep 2017 17:20:32 -0700 Subject: [PATCH 19/59] minimise the changes compared to upstream --- interface/src/ui/overlays/Base3DOverlay.cpp | 5 +++-- interface/src/ui/overlays/Base3DOverlay.h | 1 - .../src/ui/overlays/Billboard3DOverlay.cpp | 1 - interface/src/ui/overlays/ModelOverlay.cpp | 18 +----------------- interface/src/ui/overlays/Overlay.h | 1 - libraries/render-utils/src/Model.cpp | 1 + 6 files changed, 5 insertions(+), 22 deletions(-) diff --git a/interface/src/ui/overlays/Base3DOverlay.cpp b/interface/src/ui/overlays/Base3DOverlay.cpp index 6fb2bac6ed..f5e43db6b5 100644 --- a/interface/src/ui/overlays/Base3DOverlay.cpp +++ b/interface/src/ui/overlays/Base3DOverlay.cpp @@ -191,7 +191,7 @@ void Base3DOverlay::setProperties(const QVariantMap& originalProperties) { // Communicate changes to the renderItem if needed if (needRenderItemUpdate) { - // notifyRenderTransformChange(); + notifyRenderTransformChange(); auto itemID = getRenderItemID(); if (render::Item::isValidID(itemID)) { @@ -266,7 +266,8 @@ void Base3DOverlay::parentDeleted() { qApp->getOverlays().deleteOverlay(getOverlayID()); } -void Base3DOverlay::update(float duration) { +void Base3DOverlay::update(float duration) { + // In Base3DOverlay, if its location or bound changed, the renderTrasnformDirty flag is true. // then the correct transform used for rendering is computed in the update transaction and assigned. // TODO: Fix the value to be computed in main thread now and passed by value to the render item. diff --git a/interface/src/ui/overlays/Base3DOverlay.h b/interface/src/ui/overlays/Base3DOverlay.h index df1d3d2875..55b55ed16f 100644 --- a/interface/src/ui/overlays/Base3DOverlay.h +++ b/interface/src/ui/overlays/Base3DOverlay.h @@ -72,7 +72,6 @@ protected: virtual void parentDeleted() override; mutable Transform _renderTransform; - virtual Transform evalRenderTransform() const; virtual void setRenderTransform(const Transform& transform); const Transform& getRenderTransform() const { return _renderTransform; } diff --git a/interface/src/ui/overlays/Billboard3DOverlay.cpp b/interface/src/ui/overlays/Billboard3DOverlay.cpp index a333df0821..f5668caa71 100644 --- a/interface/src/ui/overlays/Billboard3DOverlay.cpp +++ b/interface/src/ui/overlays/Billboard3DOverlay.cpp @@ -45,4 +45,3 @@ bool Billboard3DOverlay::applyTransformTo(Transform& transform, bool force) { } return transformChanged; } - diff --git a/interface/src/ui/overlays/ModelOverlay.cpp b/interface/src/ui/overlays/ModelOverlay.cpp index 34bb50994f..74819689e9 100644 --- a/interface/src/ui/overlays/ModelOverlay.cpp +++ b/interface/src/ui/overlays/ModelOverlay.cpp @@ -63,20 +63,6 @@ void ModelOverlay::update(float deltatime) { _model->simulate(deltatime); } _isLoaded = _model->isActive(); - - // check to see if when we added our model to the scene they were ready, if they were not ready, then - // fix them up in the scene - render::ScenePointer scene = qApp->getMain3DScene(); - render::Transaction transaction; - if (_model->needsFixupInScene()) { - _model->removeFromScene(scene, transaction); - _model->addToScene(scene, transaction); - } - - _model->setVisibleInScene(_visible, scene); - _model->setLayeredInFront(getDrawInFront(), scene); - - scene->enqueueTransaction(transaction); } bool ModelOverlay::addToScene(Overlay::Pointer overlay, const render::ScenePointer& scene, render::Transaction& transaction) { @@ -91,7 +77,6 @@ void ModelOverlay::removeFromScene(Overlay::Pointer overlay, const render::Scene } void ModelOverlay::render(RenderArgs* args) { -/* // check to see if when we added our model to the scene they were ready, if they were not ready, then // fix them up in the scene render::ScenePointer scene = qApp->getMain3DScene(); @@ -105,7 +90,6 @@ void ModelOverlay::render(RenderArgs* args) { _model->setLayeredInFront(getDrawInFront(), scene); scene->enqueueTransaction(transaction); - */ } void ModelOverlay::setProperties(const QVariantMap& properties) { @@ -300,11 +284,11 @@ ModelOverlay* ModelOverlay::createClone() const { void ModelOverlay::locationChanged(bool tellPhysics) { Base3DOverlay::locationChanged(tellPhysics); + // FIXME Start using the _renderTransform instead of calling for Transform and Dimensions from here, do the custom things needed in evalRenderTransform() if (_model && _model->isActive()) { _model->setRotation(getRotation()); _model->setTranslation(getPosition()); } - _updateModel = true; } QString ModelOverlay::getName() const { diff --git a/interface/src/ui/overlays/Overlay.h b/interface/src/ui/overlays/Overlay.h index 31846501ec..db2979b4d5 100644 --- a/interface/src/ui/overlays/Overlay.h +++ b/interface/src/ui/overlays/Overlay.h @@ -102,7 +102,6 @@ protected: render::ItemID _renderItemID{ render::Item::INVALID_ITEM_ID }; - bool _isLoaded; float _alpha; diff --git a/libraries/render-utils/src/Model.cpp b/libraries/render-utils/src/Model.cpp index 051858afca..eec3a7b8fe 100644 --- a/libraries/render-utils/src/Model.cpp +++ b/libraries/render-utils/src/Model.cpp @@ -246,6 +246,7 @@ void Model::updateRenderItems() { if (model && model->isLoaded()) { // Ensure the model geometry was not reset between frames if (deleteGeometryCounter == model->_deleteGeometryCounter) { + const Model::MeshState& state = model->getMeshState(data._meshIndex); Transform renderTransform = modelTransform; if (state.clusterMatrices.size() == 1) { From 4a67e0421f4de185f3dec0151ee17c57d1798302 Mon Sep 17 00:00:00 2001 From: samcake Date: Thu, 21 Sep 2017 17:33:50 -0700 Subject: [PATCH 20/59] minimise the changes compared to upstream --- interface/src/ui/overlays/ModelOverlay.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/interface/src/ui/overlays/ModelOverlay.cpp b/interface/src/ui/overlays/ModelOverlay.cpp index 74819689e9..e2a7df7ae6 100644 --- a/interface/src/ui/overlays/ModelOverlay.cpp +++ b/interface/src/ui/overlays/ModelOverlay.cpp @@ -77,6 +77,7 @@ void ModelOverlay::removeFromScene(Overlay::Pointer overlay, const render::Scene } void ModelOverlay::render(RenderArgs* args) { + // check to see if when we added our model to the scene they were ready, if they were not ready, then // fix them up in the scene render::ScenePointer scene = qApp->getMain3DScene(); From 11c55755d5010c8bcac2678927fe2fc165de518c Mon Sep 17 00:00:00 2001 From: samcake Date: Mon, 25 Sep 2017 15:10:40 -0700 Subject: [PATCH 21/59] Removing unused call --- interface/src/Application.cpp | 5 ----- interface/src/Application.h | 2 -- libraries/render-utils/src/AbstractViewStateInterface.h | 3 --- tests/render-perf/src/main.cpp | 5 ----- 4 files changed, 15 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 9402cba7bc..6552141665 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -5648,11 +5648,6 @@ void Application::copyDisplayViewFrustum(ViewFrustum& viewOut) const { viewOut = _displayViewFrustum; } -void Application::copyShadowViewFrustum(ViewFrustum& viewOut) const { - QMutexLocker viewLocker(&_viewMutex); - viewOut = _shadowViewFrustum; -} - // WorldBox Render Data & rendering functions class WorldBoxRenderData { diff --git a/interface/src/Application.h b/interface/src/Application.h index dc5c6a47d5..3a1f756893 100644 --- a/interface/src/Application.h +++ b/interface/src/Application.h @@ -175,7 +175,6 @@ public: // which might be different from the viewFrustum, i.e. shadowmap // passes, mirror window passes, etc void copyDisplayViewFrustum(ViewFrustum& viewOut) const; - void copyShadowViewFrustum(ViewFrustum& viewOut) const override; const OctreePacketProcessor& getOctreePacketProcessor() const { return _octreeProcessor; } QSharedPointer getEntities() const { return DependencyManager::get(); } QUndoStack* getUndoStack() { return &_undoStack; } @@ -556,7 +555,6 @@ private: ViewFrustum _viewFrustum; // current state of view frustum, perspective, orientation, etc. ViewFrustum _lastQueriedViewFrustum; /// last view frustum used to query octree servers (voxels) ViewFrustum _displayViewFrustum; - ViewFrustum _shadowViewFrustum; quint64 _lastQueriedTime; OctreeQuery _octreeQuery; // NodeData derived class for querying octee cells from octree servers diff --git a/libraries/render-utils/src/AbstractViewStateInterface.h b/libraries/render-utils/src/AbstractViewStateInterface.h index 4570ead9e1..96e9f4d222 100644 --- a/libraries/render-utils/src/AbstractViewStateInterface.h +++ b/libraries/render-utils/src/AbstractViewStateInterface.h @@ -31,9 +31,6 @@ public: /// copies the current view frustum for rendering the view state virtual void copyCurrentViewFrustum(ViewFrustum& viewOut) const = 0; - /// copies the shadow view frustum for rendering the view state - virtual void copyShadowViewFrustum(ViewFrustum& viewOut) const = 0; - virtual QThread* getMainThread() = 0; virtual PickRay computePickRay(float x, float y) const = 0; diff --git a/tests/render-perf/src/main.cpp b/tests/render-perf/src/main.cpp index 58eb4d16f9..c70a74cd7f 100644 --- a/tests/render-perf/src/main.cpp +++ b/tests/render-perf/src/main.cpp @@ -443,10 +443,6 @@ protected: viewOut = _viewFrustum; } - void copyShadowViewFrustum(ViewFrustum& viewOut) const override { - viewOut = _shadowViewFrustum; - } - QThread* getMainThread() override { return QThread::currentThread(); } @@ -1118,7 +1114,6 @@ private: RenderThread _renderThread; QWindowCamera _camera; ViewFrustum _viewFrustum; // current state of view frustum, perspective, orientation, etc. - ViewFrustum _shadowViewFrustum; // current state of view frustum, perspective, orientation, etc. model::SunSkyStage _sunSkyStage; model::LightPointer _globalLight { std::make_shared() }; bool _ready { false }; From 157b4f2e133d39173d053354aa39c113846955f4 Mon Sep 17 00:00:00 2001 From: samcake Date: Mon, 25 Sep 2017 18:28:33 -0700 Subject: [PATCH 22/59] Moving some of the updates on the camera and the avatar out from render to game loop --- interface/src/Application.cpp | 55 +++++++++++++++++++++++++++-------- interface/src/Application.h | 7 +++++ 2 files changed, 50 insertions(+), 12 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 6552141665..cf4a103ad4 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -2373,6 +2373,11 @@ void Application::initializeUi() { } void Application::updateCamera(RenderArgs& renderArgs) { + // load the view frustum + { + QMutexLocker viewLocker(&_viewMutex); + _myCamera.loadViewFrustum(_displayViewFrustum); + } glm::vec3 boomOffset; { @@ -2474,6 +2479,25 @@ void Application::updateCamera(RenderArgs& renderArgs) { } } } + + renderArgs._cameraMode = (int8_t)_myCamera.getMode(); // HACK + + + // FIXME: This preDisplayRender call is temporary until we create a separate render::scene for the mirror rendering. + // Then we can move this logic into the Avatar::simulate call. + auto myAvatar = getMyAvatar(); + myAvatar->preDisplaySide(&renderArgs); + + { + QMutexLocker viewLocker(&_viewMutex); + renderArgs.setViewFrustum(_displayViewFrustum); + } +} + +void Application::editRenderArgs(RenderArgsEditor editor) { + QMutexLocker viewLocker(&_renderArgsMutex); + editor(_renderArgs); + } void Application::paintGL() { @@ -2518,6 +2542,10 @@ void Application::paintGL() { auto lodManager = DependencyManager::get(); RenderArgs renderArgs; + { + QMutexLocker viewLocker(&_renderArgsMutex); + renderArgs = _renderArgs; + } float sensorToWorldScale = getMyAvatar()->getSensorToWorldScale(); { @@ -2570,7 +2598,7 @@ void Application::paintGL() { _applicationOverlay.renderOverlay(&renderArgs); } - updateCamera(renderArgs); + // updateCamera(renderArgs); /* glm::vec3 boomOffset; { @@ -5336,6 +5364,7 @@ void Application::update(float deltaTime) { avatarManager->postUpdate(deltaTime, getMain3DScene()); + { PROFILE_RANGE_EX(app, "PreRenderLambdas", 0xffff0000, (uint64_t)0); @@ -5346,6 +5375,10 @@ void Application::update(float deltaTime) { _postUpdateLambdas.clear(); } + editRenderArgs([this](RenderArgs& renderArgs) { + this->updateCamera(renderArgs); + }); + AnimDebugDraw::getInstance().update(); DependencyManager::get()->update(); @@ -5679,20 +5712,18 @@ void Application::displaySide(RenderArgs* renderArgs, Camera& theCamera, bool se // FIXME: This preDisplayRender call is temporary until we create a separate render::scene for the mirror rendering. // Then we can move this logic into the Avatar::simulate call. - auto myAvatar = getMyAvatar(); - myAvatar->preDisplaySide(renderArgs); + // auto myAvatar = getMyAvatar(); + // myAvatar->preDisplaySide(renderArgs); PROFILE_RANGE(render, __FUNCTION__); PerformanceTimer perfTimer("display"); PerformanceWarning warn(Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings), "Application::displaySide()"); // load the view frustum - { - QMutexLocker viewLocker(&_viewMutex); - theCamera.loadViewFrustum(_displayViewFrustum); - } - - // TODO fix shadows and make them use the GPU library + // { + // QMutexLocker viewLocker(&_viewMutex); + // theCamera.loadViewFrustum(_displayViewFrustum); + // } // The pending changes collecting the changes here render::Transaction transaction; @@ -5740,11 +5771,11 @@ void Application::displaySide(RenderArgs* renderArgs, Camera& theCamera, bool se { PerformanceTimer perfTimer("EngineRun"); - { + /* { QMutexLocker viewLocker(&_viewMutex); renderArgs->setViewFrustum(_displayViewFrustum); - } - renderArgs->_cameraMode = (int8_t)theCamera.getMode(); // HACK + }*/ + // renderArgs->_cameraMode = (int8_t)theCamera.getMode(); // HACK renderArgs->_scene = getMain3DScene(); _renderEngine->getRenderContext()->args = renderArgs; diff --git a/interface/src/Application.h b/interface/src/Application.h index 3a1f756893..edb356fcef 100644 --- a/interface/src/Application.h +++ b/interface/src/Application.h @@ -625,6 +625,13 @@ private: render::EnginePointer _renderEngine{ new render::Engine() }; gpu::ContextPointer _gpuContext; // initialized during window creation + mutable QMutex _renderArgsMutex{ QMutex::Recursive }; + render::Args _renderArgs; + + using RenderArgsEditor = std::function ; + void editRenderArgs(RenderArgsEditor editor); + + Overlays _overlays; ApplicationOverlay _applicationOverlay; OverlayConductor _overlayConductor; From 953614fe65579f1cb8c0652dde9bc6adae0c210a Mon Sep 17 00:00:00 2001 From: Sam Gateau Date: Mon, 25 Sep 2017 23:43:32 -0700 Subject: [PATCH 23/59] More stuff out of render to the gameloop --- interface/src/Application.cpp | 72 ++++++++++++++++++++++++++--------- interface/src/Application.h | 10 ++++- 2 files changed, 62 insertions(+), 20 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index cf4a103ad4..10e6356a83 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -2482,12 +2482,6 @@ void Application::updateCamera(RenderArgs& renderArgs) { renderArgs._cameraMode = (int8_t)_myCamera.getMode(); // HACK - - // FIXME: This preDisplayRender call is temporary until we create a separate render::scene for the mirror rendering. - // Then we can move this logic into the Avatar::simulate call. - auto myAvatar = getMyAvatar(); - myAvatar->preDisplaySide(&renderArgs); - { QMutexLocker viewLocker(&_viewMutex); renderArgs.setViewFrustum(_displayViewFrustum); @@ -2495,8 +2489,8 @@ void Application::updateCamera(RenderArgs& renderArgs) { } void Application::editRenderArgs(RenderArgsEditor editor) { - QMutexLocker viewLocker(&_renderArgsMutex); - editor(_renderArgs); + QMutexLocker renderLocker(&_renderArgsMutex); + editor(_appRenderArgs); } @@ -2534,19 +2528,19 @@ void Application::paintGL() { } // update the avatar with a fresh HMD pose - { - PROFILE_RANGE(render, "/updateAvatar"); - getMyAvatar()->updateFromHMDSensorMatrix(getHMDSensorPose()); - } + // { + // PROFILE_RANGE(render, "/updateAvatar"); + // getMyAvatar()->updateFromHMDSensorMatrix(getHMDSensorPose()); + // } - auto lodManager = DependencyManager::get(); + // auto lodManager = DependencyManager::get(); RenderArgs renderArgs; { QMutexLocker viewLocker(&_renderArgsMutex); - renderArgs = _renderArgs; + renderArgs = _appRenderArgs._renderArgs; } - +/* float sensorToWorldScale = getMyAvatar()->getSensorToWorldScale(); { PROFILE_RANGE(render, "/buildFrustrumAndArgs"); @@ -2568,7 +2562,7 @@ void Application::paintGL() { renderArgs.setViewFrustum(_viewFrustum); } } - +*/ { PROFILE_RANGE(render, "/resizeGL"); PerformanceWarning::setSuppressShortTimings(Menu::getInstance()->isOptionChecked(MenuOption::SuppressShortTimings)); @@ -2579,6 +2573,7 @@ void Application::paintGL() { { PROFILE_RANGE(render, "/gpuContextReset"); + // _gpuContext->beginFrame(getHMDSensorPose()); _gpuContext->beginFrame(getHMDSensorPose()); // Reset the gpu::Context Stages // Back to the default framebuffer; @@ -5375,8 +5370,49 @@ void Application::update(float deltaTime) { _postUpdateLambdas.clear(); } - editRenderArgs([this](RenderArgs& renderArgs) { - this->updateCamera(renderArgs); + editRenderArgs([this](AppRenderArgs& appRenderArgs) { + + appRenderArgs._eyeToWorld = getHMDSensorPose(); + + auto myAvatar = getMyAvatar(); + + + // update the avatar with a fresh HMD pose + { + PROFILE_RANGE(render, "/updateAvatar"); + myAvatar->updateFromHMDSensorMatrix(appRenderArgs._eyeToWorld); + } + + auto lodManager = DependencyManager::get(); + + float sensorToWorldScale = getMyAvatar()->getSensorToWorldScale(); + { + PROFILE_RANGE(render, "/buildFrustrumAndArgs"); + { + QMutexLocker viewLocker(&_viewMutex); + // adjust near clip plane to account for sensor scaling. + auto adjustedProjection = glm::perspective(_viewFrustum.getFieldOfView(), + _viewFrustum.getAspectRatio(), + DEFAULT_NEAR_CLIP * sensorToWorldScale, + _viewFrustum.getFarClip()); + _viewFrustum.setProjection(adjustedProjection); + _viewFrustum.calculate(); + } + appRenderArgs._renderArgs = RenderArgs(_gpuContext, lodManager->getOctreeSizeScale(), + lodManager->getBoundaryLevelAdjust(), RenderArgs::DEFAULT_RENDER_MODE, + RenderArgs::MONO, RenderArgs::RENDER_DEBUG_NONE); + { + QMutexLocker viewLocker(&_viewMutex); + appRenderArgs._renderArgs.setViewFrustum(_viewFrustum); + } + } + + this->updateCamera(appRenderArgs._renderArgs); + + // FIXME: This preDisplayRender call is temporary until we create a separate render::scene for the mirror rendering. + // Then we can move this logic into the Avatar::simulate call. + myAvatar->preDisplaySide(&appRenderArgs._renderArgs); + }); AnimDebugDraw::getInstance().update(); diff --git a/interface/src/Application.h b/interface/src/Application.h index edb356fcef..45393cfbea 100644 --- a/interface/src/Application.h +++ b/interface/src/Application.h @@ -626,9 +626,15 @@ private: gpu::ContextPointer _gpuContext; // initialized during window creation mutable QMutex _renderArgsMutex{ QMutex::Recursive }; - render::Args _renderArgs; + struct AppRenderArgs { + render::Args _renderArgs; + glm::mat4 _eyeToWorld; + glm::mat4 _sensorToWorld; + }; + AppRenderArgs _appRenderArgs; - using RenderArgsEditor = std::function ; + + using RenderArgsEditor = std::function ; void editRenderArgs(RenderArgsEditor editor); From 669af73a961c67b66ba86b64a36a6cbc1a9340e3 Mon Sep 17 00:00:00 2001 From: samcake Date: Tue, 26 Sep 2017 10:47:24 -0700 Subject: [PATCH 24/59] Bringing as much as possible out from render to game --- interface/src/Application.cpp | 7 ++++++- interface/src/Application.h | 1 + 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 10e6356a83..d4c0837989 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -2536,9 +2536,13 @@ void Application::paintGL() { // auto lodManager = DependencyManager::get(); RenderArgs renderArgs; + float sensorToWorldScale; + glm::mat4 HMDSensorPose; { QMutexLocker viewLocker(&_renderArgsMutex); renderArgs = _appRenderArgs._renderArgs; + HMDSensorPose = _appRenderArgs._eyeToWorld; + sensorToWorldScale = _appRenderArgs._sensorToWorldScale; } /* float sensorToWorldScale = getMyAvatar()->getSensorToWorldScale(); @@ -2574,7 +2578,7 @@ void Application::paintGL() { { PROFILE_RANGE(render, "/gpuContextReset"); // _gpuContext->beginFrame(getHMDSensorPose()); - _gpuContext->beginFrame(getHMDSensorPose()); + _gpuContext->beginFrame(HMDSensorPose); // Reset the gpu::Context Stages // Back to the default framebuffer; gpu::doInBatch(_gpuContext, [&](gpu::Batch& batch) { @@ -5386,6 +5390,7 @@ void Application::update(float deltaTime) { auto lodManager = DependencyManager::get(); float sensorToWorldScale = getMyAvatar()->getSensorToWorldScale(); + appRenderArgs._sensorToWorldScale = sensorToWorldScale; { PROFILE_RANGE(render, "/buildFrustrumAndArgs"); { diff --git a/interface/src/Application.h b/interface/src/Application.h index 45393cfbea..be3fa19400 100644 --- a/interface/src/Application.h +++ b/interface/src/Application.h @@ -630,6 +630,7 @@ private: render::Args _renderArgs; glm::mat4 _eyeToWorld; glm::mat4 _sensorToWorld; + float _sensorToWorldScale { 1.0f }; }; AppRenderArgs _appRenderArgs; From 40ca98214bb9a4908a346b765f373d4d065a0740 Mon Sep 17 00:00:00 2001 From: samcake Date: Wed, 27 Sep 2017 17:58:43 -0700 Subject: [PATCH 25/59] Moving all of the camera and avatar eval to game loop --- interface/src/Application.cpp | 221 ++++++++----------------- interface/src/Application.h | 5 +- interface/src/ui/overlays/Overlays.cpp | 2 +- 3 files changed, 70 insertions(+), 158 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 2dba980fb1..465c066bec 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -2374,11 +2374,7 @@ void Application::initializeUi() { } void Application::updateCamera(RenderArgs& renderArgs) { - // load the view frustum - { - QMutexLocker viewLocker(&_viewMutex); - _myCamera.loadViewFrustum(_displayViewFrustum); - } + glm::vec3 boomOffset; { @@ -2481,12 +2477,7 @@ void Application::updateCamera(RenderArgs& renderArgs) { } } - renderArgs._cameraMode = (int8_t)_myCamera.getMode(); // HACK - - { - QMutexLocker viewLocker(&_viewMutex); - renderArgs.setViewFrustum(_displayViewFrustum); - } + renderArgs._cameraMode = (int8_t)_myCamera.getMode(); } void Application::editRenderArgs(RenderArgsEditor editor) { @@ -2539,42 +2530,46 @@ void Application::paintGL() { RenderArgs renderArgs; float sensorToWorldScale; glm::mat4 HMDSensorPose; + glm::mat4 eyeToWorld; + glm::mat4 sensorToWorld; { QMutexLocker viewLocker(&_renderArgsMutex); renderArgs = _appRenderArgs._renderArgs; - HMDSensorPose = _appRenderArgs._eyeToWorld; + HMDSensorPose = _appRenderArgs._headPose; + eyeToWorld = _appRenderArgs._eyeToWorld; + sensorToWorld = _appRenderArgs._sensorToWorld; sensorToWorldScale = _appRenderArgs._sensorToWorldScale; } -/* - float sensorToWorldScale = getMyAvatar()->getSensorToWorldScale(); - { - PROFILE_RANGE(render, "/buildFrustrumAndArgs"); - { - QMutexLocker viewLocker(&_viewMutex); - // adjust near clip plane to account for sensor scaling. - auto adjustedProjection = glm::perspective(_viewFrustum.getFieldOfView(), - _viewFrustum.getAspectRatio(), - DEFAULT_NEAR_CLIP * sensorToWorldScale, - _viewFrustum.getFarClip()); - _viewFrustum.setProjection(adjustedProjection); - _viewFrustum.calculate(); - } - renderArgs = RenderArgs(_gpuContext, lodManager->getOctreeSizeScale(), - lodManager->getBoundaryLevelAdjust(), RenderArgs::DEFAULT_RENDER_MODE, - RenderArgs::MONO, RenderArgs::RENDER_DEBUG_NONE); - { - QMutexLocker viewLocker(&_viewMutex); - renderArgs.setViewFrustum(_viewFrustum); - } - } -*/ - { - PROFILE_RANGE(render, "/resizeGL"); - PerformanceWarning::setSuppressShortTimings(Menu::getInstance()->isOptionChecked(MenuOption::SuppressShortTimings)); - bool showWarnings = Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings); - PerformanceWarning warn(showWarnings, "Application::paintGL()"); - resizeGL(); - } + + //float sensorToWorldScale = getMyAvatar()->getSensorToWorldScale(); + //{ + // PROFILE_RANGE(render, "/buildFrustrumAndArgs"); + // { + // QMutexLocker viewLocker(&_viewMutex); + // // adjust near clip plane to account for sensor scaling. + // auto adjustedProjection = glm::perspective(_viewFrustum.getFieldOfView(), + // _viewFrustum.getAspectRatio(), + // DEFAULT_NEAR_CLIP * sensorToWorldScale, + // _viewFrustum.getFarClip()); + // _viewFrustum.setProjection(adjustedProjection); + // _viewFrustum.calculate(); + // } + // renderArgs = RenderArgs(_gpuContext, lodManager->getOctreeSizeScale(), + // lodManager->getBoundaryLevelAdjust(), RenderArgs::DEFAULT_RENDER_MODE, + // RenderArgs::MONO, RenderArgs::RENDER_DEBUG_NONE); + // { + // QMutexLocker viewLocker(&_viewMutex); + // renderArgs.setViewFrustum(_viewFrustum); + // } + //} + + //{ + // PROFILE_RANGE(render, "/resizeGL"); + // PerformanceWarning::setSuppressShortTimings(Menu::getInstance()->isOptionChecked(MenuOption::SuppressShortTimings)); + // bool showWarnings = Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings); + // PerformanceWarning warn(showWarnings, "Application::paintGL()"); + // resizeGL(); + //} { PROFILE_RANGE(render, "/gpuContextReset"); @@ -2599,103 +2594,10 @@ void Application::paintGL() { } // updateCamera(renderArgs); - - /* glm::vec3 boomOffset; - { - PROFILE_RANGE(render, "/updateCamera"); - { - PerformanceTimer perfTimer("CameraUpdates"); - - auto myAvatar = getMyAvatar(); - boomOffset = myAvatar->getModelScale() * myAvatar->getBoomLength() * -IDENTITY_FORWARD; - - // The render mode is default or mirror if the camera is in mirror mode, assigned further below - renderArgs._renderMode = RenderArgs::DEFAULT_RENDER_MODE; - - // Always use the default eye position, not the actual head eye position. - // Using the latter will cause the camera to wobble with idle animations, - // or with changes from the face tracker - if (_myCamera.getMode() == CAMERA_MODE_FIRST_PERSON) { - if (isHMDMode()) { - mat4 camMat = myAvatar->getSensorToWorldMatrix() * myAvatar->getHMDSensorMatrix(); - _myCamera.setPosition(extractTranslation(camMat)); - _myCamera.setOrientation(glmExtractRotation(camMat)); - } else { - _myCamera.setPosition(myAvatar->getDefaultEyePosition()); - _myCamera.setOrientation(myAvatar->getMyHead()->getHeadOrientation()); - } - } else if (_myCamera.getMode() == CAMERA_MODE_THIRD_PERSON) { - if (isHMDMode()) { - auto hmdWorldMat = myAvatar->getSensorToWorldMatrix() * myAvatar->getHMDSensorMatrix(); - _myCamera.setOrientation(glm::normalize(glmExtractRotation(hmdWorldMat))); - _myCamera.setPosition(extractTranslation(hmdWorldMat) + - myAvatar->getOrientation() * boomOffset); - } else { - _myCamera.setOrientation(myAvatar->getHead()->getOrientation()); - if (Menu::getInstance()->isOptionChecked(MenuOption::CenterPlayerInView)) { - _myCamera.setPosition(myAvatar->getDefaultEyePosition() - + _myCamera.getOrientation() * boomOffset); - } else { - _myCamera.setPosition(myAvatar->getDefaultEyePosition() - + myAvatar->getOrientation() * boomOffset); - } - } - } else if (_myCamera.getMode() == CAMERA_MODE_MIRROR) { - if (isHMDMode()) { - auto mirrorBodyOrientation = myAvatar->getOrientation() * glm::quat(glm::vec3(0.0f, PI + _rotateMirror, 0.0f)); - - glm::quat hmdRotation = extractRotation(myAvatar->getHMDSensorMatrix()); - // Mirror HMD yaw and roll - glm::vec3 mirrorHmdEulers = glm::eulerAngles(hmdRotation); - mirrorHmdEulers.y = -mirrorHmdEulers.y; - mirrorHmdEulers.z = -mirrorHmdEulers.z; - glm::quat mirrorHmdRotation = glm::quat(mirrorHmdEulers); - - glm::quat worldMirrorRotation = mirrorBodyOrientation * mirrorHmdRotation; - - _myCamera.setOrientation(worldMirrorRotation); - - glm::vec3 hmdOffset = extractTranslation(myAvatar->getHMDSensorMatrix()); - // Mirror HMD lateral offsets - hmdOffset.x = -hmdOffset.x; - - _myCamera.setPosition(myAvatar->getDefaultEyePosition() - + glm::vec3(0, _raiseMirror * myAvatar->getModelScale(), 0) - + mirrorBodyOrientation * glm::vec3(0.0f, 0.0f, 1.0f) * MIRROR_FULLSCREEN_DISTANCE * _scaleMirror - + mirrorBodyOrientation * hmdOffset); - } else { - _myCamera.setOrientation(myAvatar->getOrientation() - * glm::quat(glm::vec3(0.0f, PI + _rotateMirror, 0.0f))); - _myCamera.setPosition(myAvatar->getDefaultEyePosition() - + glm::vec3(0, _raiseMirror * myAvatar->getModelScale(), 0) - + (myAvatar->getOrientation() * glm::quat(glm::vec3(0.0f, _rotateMirror, 0.0f))) * - glm::vec3(0.0f, 0.0f, -1.0f) * MIRROR_FULLSCREEN_DISTANCE * _scaleMirror); - } - renderArgs._renderMode = RenderArgs::MIRROR_RENDER_MODE; - } else if (_myCamera.getMode() == CAMERA_MODE_ENTITY) { - EntityItemPointer cameraEntity = _myCamera.getCameraEntityPointer(); - if (cameraEntity != nullptr) { - if (isHMDMode()) { - glm::quat hmdRotation = extractRotation(myAvatar->getHMDSensorMatrix()); - _myCamera.setOrientation(cameraEntity->getRotation() * hmdRotation); - glm::vec3 hmdOffset = extractTranslation(myAvatar->getHMDSensorMatrix()); - _myCamera.setPosition(cameraEntity->getPosition() + (hmdRotation * hmdOffset)); - } else { - _myCamera.setOrientation(cameraEntity->getRotation()); - _myCamera.setPosition(cameraEntity->getPosition()); - } - } - } - // Update camera position - if (!isHMDMode()) { - _myCamera.update(1.0f / _frameCounter.rate()); - } - } - } - */ { PROFILE_RANGE(render, "/updateCompositor"); - getApplicationCompositor().setFrameInfo(_frameCount, _myCamera.getTransform(), getMyAvatar()->getSensorToWorldMatrix()); + // getApplicationCompositor().setFrameInfo(_frameCount, _myCamera.getTransform(), getMyAvatar()->getSensorToWorldMatrix()); + getApplicationCompositor().setFrameInfo(_frameCount, eyeToWorld, sensorToWorld); } gpu::FramebufferPointer finalFramebuffer; @@ -2761,7 +2663,8 @@ void Application::paintGL() { renderArgs._displayMode = (isHMDMode() ? RenderArgs::STEREO_HMD : RenderArgs::STEREO_MONITOR); } renderArgs._blitFramebuffer = finalFramebuffer; - displaySide(&renderArgs, _myCamera); + // displaySide(&renderArgs, _myCamera); + runRenderFrame(&renderArgs); } gpu::Batch postCompositeBatch; @@ -5367,7 +5270,7 @@ void Application::update(float deltaTime) { editRenderArgs([this](AppRenderArgs& appRenderArgs) { - appRenderArgs._eyeToWorld = getHMDSensorPose(); + appRenderArgs._headPose= getHMDSensorPose(); auto myAvatar = getMyAvatar(); @@ -5375,7 +5278,7 @@ void Application::update(float deltaTime) { // update the avatar with a fresh HMD pose { PROFILE_RANGE(render, "/updateAvatar"); - myAvatar->updateFromHMDSensorMatrix(appRenderArgs._eyeToWorld); + myAvatar->updateFromHMDSensorMatrix(appRenderArgs._headPose); } auto lodManager = DependencyManager::get(); @@ -5402,13 +5305,31 @@ void Application::update(float deltaTime) { appRenderArgs._renderArgs.setViewFrustum(_viewFrustum); } } + { + PROFILE_RANGE(render, "/resizeGL"); + PerformanceWarning::setSuppressShortTimings(Menu::getInstance()->isOptionChecked(MenuOption::SuppressShortTimings)); + bool showWarnings = Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings); + PerformanceWarning warn(showWarnings, "Application::paintGL()"); + resizeGL(); + } this->updateCamera(appRenderArgs._renderArgs); + + // HACK + // load the view frustum // FIXME: This preDisplayRender call is temporary until we create a separate render::scene for the mirror rendering. // Then we can move this logic into the Avatar::simulate call. myAvatar->preDisplaySide(&appRenderArgs._renderArgs); + { + QMutexLocker viewLocker(&_viewMutex); + _myCamera.loadViewFrustum(_displayViewFrustum); + } + { + QMutexLocker viewLocker(&_viewMutex); + appRenderArgs._renderArgs.setViewFrustum(_displayViewFrustum); + } }); AnimDebugDraw::getInstance().update(); @@ -5740,7 +5661,7 @@ namespace render { } } -void Application::displaySide(RenderArgs* renderArgs, Camera& theCamera, bool selfAvatarOnly) { +void Application::runRenderFrame(RenderArgs* renderArgs) { // FIXME: This preDisplayRender call is temporary until we create a separate render::scene for the mirror rendering. // Then we can move this logic into the Avatar::simulate call. @@ -5749,7 +5670,7 @@ void Application::displaySide(RenderArgs* renderArgs, Camera& theCamera, bool se PROFILE_RANGE(render, __FUNCTION__); PerformanceTimer perfTimer("display"); - PerformanceWarning warn(Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings), "Application::displaySide()"); + PerformanceWarning warn(Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings), "Application::runRenderFrame()"); // load the view frustum // { @@ -5761,12 +5682,13 @@ void Application::displaySide(RenderArgs* renderArgs, Camera& theCamera, bool se render::Transaction transaction; // Assuming nothing gets rendered through that - if (!selfAvatarOnly) { + //if (!selfAvatarOnly) { + { if (DependencyManager::get()->shouldRenderEntities()) { // render models... PerformanceTimer perfTimer("entities"); PerformanceWarning warn(Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings), - "Application::displaySide() ... entities..."); + "Application::runRenderFrame() ... entities..."); RenderArgs::DebugFlags renderDebugFlags = RenderArgs::RENDER_DEBUG_NONE; @@ -5775,7 +5697,6 @@ void Application::displaySide(RenderArgs* renderArgs, Camera& theCamera, bool se static_cast(RenderArgs::RENDER_DEBUG_HULLS)); } renderArgs->_debugFlags = renderDebugFlags; - //ViveControllerManager::getInstance().updateRendering(renderArgs, _main3DScene, transaction); } } @@ -5788,17 +5709,10 @@ void Application::displaySide(RenderArgs* renderArgs, Camera& theCamera, bool se WorldBoxRenderData::_item = _main3DScene->allocateID(); transaction.resetItem(WorldBoxRenderData::_item, worldBoxRenderPayload); - } else { - transaction.updateItem(WorldBoxRenderData::_item, - [](WorldBoxRenderData& payload) { - payload._val++; - }); - } - - { _main3DScene->enqueueTransaction(transaction); } + // For now every frame pass the renderContext { PerformanceTimer perfTimer("EngineRun"); @@ -7861,5 +7775,4 @@ void Application::setAvatarOverrideUrl(const QUrl& url, bool save) { _avatarOverrideUrl = url; _saveAvatarOverrideUrl = save; } - #include "Application.moc" diff --git a/interface/src/Application.h b/interface/src/Application.h index 3cd0ea07bc..edb615794c 100644 --- a/interface/src/Application.h +++ b/interface/src/Application.h @@ -470,8 +470,6 @@ private: void queryOctree(NodeType_t serverType, PacketType packetType, NodeToJurisdictionMap& jurisdictions, bool forceResend = false); - void renderRearViewMirror(RenderArgs* renderArgs, const QRect& region, bool isZoomed); - int sendNackPackets(); void sendAvatarViewFrustum(); @@ -481,7 +479,7 @@ private: void initializeAcceptedFiles(); - void displaySide(RenderArgs* renderArgs, Camera& whichCamera, bool selfAvatarOnly = false); + void runRenderFrame(RenderArgs* renderArgs/*, Camera& whichCamera, bool selfAvatarOnly = false*/); bool importJSONFromURL(const QString& urlString); bool importSVOFromURL(const QString& urlString); @@ -628,6 +626,7 @@ private: struct AppRenderArgs { render::Args _renderArgs; glm::mat4 _eyeToWorld; + glm::mat4 _headPose; glm::mat4 _sensorToWorld; float _sensorToWorldScale { 1.0f }; }; diff --git a/interface/src/ui/overlays/Overlays.cpp b/interface/src/ui/overlays/Overlays.cpp index c93d225718..e9cb1f2973 100644 --- a/interface/src/ui/overlays/Overlays.cpp +++ b/interface/src/ui/overlays/Overlays.cpp @@ -152,7 +152,7 @@ void Overlays::render3DHUDOverlays(RenderArgs* renderArgs) { foreach(Overlay::Pointer thisOverlay, _overlays3DHUD) { // Reset necessary batch pipeline settings between overlays batch.setResourceTexture(0, textureCache->getWhiteTexture()); // FIXME - do we really need to do this?? - batch.setModelTransform(Transform()); + // batch.setModelTransform(Transform()); renderArgs->_shapePipeline = _shapePlumber->pickPipeline(renderArgs, thisOverlay->getShapeKey()); thisOverlay->render(renderArgs); From c112a3baf16f3be42fd940798ed29eaa4a762d6b Mon Sep 17 00:00:00 2001 From: samcake Date: Thu, 28 Sep 2017 15:09:49 -0700 Subject: [PATCH 26/59] Seting up of camera and avatar correctly in game loop, not in render loop --- interface/src/Application.cpp | 159 ++++++++++++++++++++++++---------- interface/src/Application.h | 3 + 2 files changed, 116 insertions(+), 46 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 596917da28..284cc5056a 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -2536,6 +2536,11 @@ void Application::paintGL() { glm::mat4 HMDSensorPose; glm::mat4 eyeToWorld; glm::mat4 sensorToWorld; + + bool isStereo; + glm::mat4 stereoEyeOffsets[2]; + glm::mat4 stereoEyeProjections[2]; + { QMutexLocker viewLocker(&_renderArgsMutex); renderArgs = _appRenderArgs._renderArgs; @@ -2543,6 +2548,11 @@ void Application::paintGL() { eyeToWorld = _appRenderArgs._eyeToWorld; sensorToWorld = _appRenderArgs._sensorToWorld; sensorToWorldScale = _appRenderArgs._sensorToWorldScale; + isStereo = _appRenderArgs._isStereo; + for_each_eye([&](Eye eye) { + stereoEyeOffsets[eye] = _appRenderArgs._eyeOffsets[eye]; + stereoEyeProjections[eye] = _appRenderArgs._eyeProjections[eye]; + }); } //float sensorToWorldScale = getMyAvatar()->getSensorToWorldScale(); @@ -2615,57 +2625,65 @@ void Application::paintGL() { finalFramebuffer = framebufferCache->getFramebuffer(); } - auto hmdInterface = DependencyManager::get(); - float ipdScale = hmdInterface->getIPDScale(); + //auto hmdInterface = DependencyManager::get(); + //float ipdScale = hmdInterface->getIPDScale(); - // scale IPD by sensorToWorldScale, to make the world seem larger or smaller accordingly. - ipdScale *= sensorToWorldScale; + //// scale IPD by sensorToWorldScale, to make the world seem larger or smaller accordingly. + //ipdScale *= sensorToWorldScale; { - PROFILE_RANGE(render, "/mainRender"); - PerformanceTimer perfTimer("mainRender"); - // FIXME is this ever going to be different from the size previously set in the render args - // in the overlay render? - // Viewport is assigned to the size of the framebuffer - renderArgs._viewport = ivec4(0, 0, finalFramebufferSize.width(), finalFramebufferSize.height()); - auto baseProjection = renderArgs.getViewFrustum().getProjection(); - if (displayPlugin->isStereo()) { - // Stereo modes will typically have a larger projection matrix overall, - // so we ask for the 'mono' projection matrix, which for stereo and HMD - // plugins will imply the combined projection for both eyes. - // - // This is properly implemented for the Oculus plugins, but for OpenVR - // and Stereo displays I'm not sure how to get / calculate it, so we're - // just relying on the left FOV in each case and hoping that the - // overall culling margin of error doesn't cause popping in the - // right eye. There are FIXMEs in the relevant plugins - _myCamera.setProjection(displayPlugin->getCullingProjection(baseProjection)); + //PROFILE_RANGE(render, "/mainRender"); + //PerformanceTimer perfTimer("mainRender"); + //// FIXME is this ever going to be different from the size previously set in the render args + //// in the overlay render? + //// Viewport is assigned to the size of the framebuffer + //renderArgs._viewport = ivec4(0, 0, finalFramebufferSize.width(), finalFramebufferSize.height()); + //auto baseProjection = renderArgs.getViewFrustum().getProjection(); + //if (displayPlugin->isStereo()) { + // // Stereo modes will typically have a larger projection matrix overall, + // // so we ask for the 'mono' projection matrix, which for stereo and HMD + // // plugins will imply the combined projection for both eyes. + // // + // // This is properly implemented for the Oculus plugins, but for OpenVR + // // and Stereo displays I'm not sure how to get / calculate it, so we're + // // just relying on the left FOV in each case and hoping that the + // // overall culling margin of error doesn't cause popping in the + // // right eye. There are FIXMEs in the relevant plugins + // _myCamera.setProjection(displayPlugin->getCullingProjection(baseProjection)); + // renderArgs._context->enableStereo(true); + // mat4 eyeOffsets[2]; + // mat4 eyeProjections[2]; + + // // FIXME we probably don't need to set the projection matrix every frame, + // // only when the display plugin changes (or in non-HMD modes when the user + // // changes the FOV manually, which right now I don't think they can. + // for_each_eye([&](Eye eye) { + // // For providing the stereo eye views, the HMD head pose has already been + // // applied to the avatar, so we need to get the difference between the head + // // pose applied to the avatar and the per eye pose, and use THAT as + // // the per-eye stereo matrix adjustment. + // mat4 eyeToHead = displayPlugin->getEyeToHeadTransform(eye); + // // Grab the translation + // vec3 eyeOffset = glm::vec3(eyeToHead[3]); + // // Apply IPD scaling + // mat4 eyeOffsetTransform = glm::translate(mat4(), eyeOffset * -1.0f * ipdScale); + // eyeOffsets[eye] = eyeOffsetTransform; + // eyeProjections[eye] = displayPlugin->getEyeProjection(eye, baseProjection); + // }); + // renderArgs._context->setStereoProjections(eyeProjections); + // renderArgs._context->setStereoViews(eyeOffsets); + + // // Configure the type of display / stereo + // renderArgs._displayMode = (isHMDMode() ? RenderArgs::STEREO_HMD : RenderArgs::STEREO_MONITOR); + //} + + if (isStereo) { renderArgs._context->enableStereo(true); - mat4 eyeOffsets[2]; - mat4 eyeProjections[2]; - - // FIXME we probably don't need to set the projection matrix every frame, - // only when the display plugin changes (or in non-HMD modes when the user - // changes the FOV manually, which right now I don't think they can. - for_each_eye([&](Eye eye) { - // For providing the stereo eye views, the HMD head pose has already been - // applied to the avatar, so we need to get the difference between the head - // pose applied to the avatar and the per eye pose, and use THAT as - // the per-eye stereo matrix adjustment. - mat4 eyeToHead = displayPlugin->getEyeToHeadTransform(eye); - // Grab the translation - vec3 eyeOffset = glm::vec3(eyeToHead[3]); - // Apply IPD scaling - mat4 eyeOffsetTransform = glm::translate(mat4(), eyeOffset * -1.0f * ipdScale); - eyeOffsets[eye] = eyeOffsetTransform; - eyeProjections[eye] = displayPlugin->getEyeProjection(eye, baseProjection); - }); - renderArgs._context->setStereoProjections(eyeProjections); - renderArgs._context->setStereoViews(eyeOffsets); - - // Configure the type of display / stereo - renderArgs._displayMode = (isHMDMode() ? RenderArgs::STEREO_HMD : RenderArgs::STEREO_MONITOR); + renderArgs._context->setStereoProjections(stereoEyeProjections); + renderArgs._context->setStereoViews(stereoEyeOffsets); + // renderArgs._displayMode } + renderArgs._blitFramebuffer = finalFramebuffer; // displaySide(&renderArgs, _myCamera); runRenderFrame(&renderArgs); @@ -5320,7 +5338,55 @@ void Application::update(float deltaTime) { } this->updateCamera(appRenderArgs._renderArgs); + appRenderArgs._isStereo = false; + { + auto hmdInterface = DependencyManager::get(); + float ipdScale = hmdInterface->getIPDScale(); + + // scale IPD by sensorToWorldScale, to make the world seem larger or smaller accordingly. + ipdScale *= sensorToWorldScale; + + auto baseProjection = appRenderArgs._renderArgs.getViewFrustum().getProjection(); + if (getActiveDisplayPlugin()->isStereo()) { + // Stereo modes will typically have a larger projection matrix overall, + // so we ask for the 'mono' projection matrix, which for stereo and HMD + // plugins will imply the combined projection for both eyes. + // + // This is properly implemented for the Oculus plugins, but for OpenVR + // and Stereo displays I'm not sure how to get / calculate it, so we're + // just relying on the left FOV in each case and hoping that the + // overall culling margin of error doesn't cause popping in the + // right eye. There are FIXMEs in the relevant plugins + _myCamera.setProjection(getActiveDisplayPlugin()->getCullingProjection(baseProjection)); + appRenderArgs._isStereo = true; + + auto& eyeOffsets = appRenderArgs._eyeOffsets; + auto& eyeProjections = appRenderArgs._eyeProjections; + + // FIXME we probably don't need to set the projection matrix every frame, + // only when the display plugin changes (or in non-HMD modes when the user + // changes the FOV manually, which right now I don't think they can. + for_each_eye([&](Eye eye) { + // For providing the stereo eye views, the HMD head pose has already been + // applied to the avatar, so we need to get the difference between the head + // pose applied to the avatar and the per eye pose, and use THAT as + // the per-eye stereo matrix adjustment. + mat4 eyeToHead = getActiveDisplayPlugin()->getEyeToHeadTransform(eye); + // Grab the translation + vec3 eyeOffset = glm::vec3(eyeToHead[3]); + // Apply IPD scaling + mat4 eyeOffsetTransform = glm::translate(mat4(), eyeOffset * -1.0f * ipdScale); + eyeOffsets[eye] = eyeOffsetTransform; + eyeProjections[eye] = getActiveDisplayPlugin()->getEyeProjection(eye, baseProjection); + }); + //renderArgs._context->setStereoProjections(eyeProjections); + //renderArgs._context->setStereoViews(eyeOffsets); + + // Configure the type of display / stereo + appRenderArgs._renderArgs._displayMode = (isHMDMode() ? RenderArgs::STEREO_HMD : RenderArgs::STEREO_MONITOR); + } + } // HACK // load the view frustum @@ -5332,6 +5398,7 @@ void Application::update(float deltaTime) { QMutexLocker viewLocker(&_viewMutex); _myCamera.loadViewFrustum(_displayViewFrustum); } + { QMutexLocker viewLocker(&_viewMutex); appRenderArgs._renderArgs.setViewFrustum(_displayViewFrustum); diff --git a/interface/src/Application.h b/interface/src/Application.h index 377a31fb2c..3f4c55999e 100644 --- a/interface/src/Application.h +++ b/interface/src/Application.h @@ -626,9 +626,12 @@ private: struct AppRenderArgs { render::Args _renderArgs; glm::mat4 _eyeToWorld; + glm::mat4 _eyeOffsets[2]; + glm::mat4 _eyeProjections[2]; glm::mat4 _headPose; glm::mat4 _sensorToWorld; float _sensorToWorldScale { 1.0f }; + bool _isStereo{ false }; }; AppRenderArgs _appRenderArgs; From e637842f8afbf126c6fb1113d1c1976551e2210c Mon Sep 17 00:00:00 2001 From: samcake Date: Thu, 28 Sep 2017 17:45:50 -0700 Subject: [PATCH 27/59] Separating some of the code sepecific to render in its own cpp --- interface/src/Application_render.cpp | 320 +++++++++++++++++++++++++++ 1 file changed, 320 insertions(+) create mode 100644 interface/src/Application_render.cpp diff --git a/interface/src/Application_render.cpp b/interface/src/Application_render.cpp new file mode 100644 index 0000000000..ee3267284a --- /dev/null +++ b/interface/src/Application_render.cpp @@ -0,0 +1,320 @@ +// +// Application_render.cpp +// interface/src +// +// Copyright 2013 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 +// + +#ifdef tryingSOmething + +void Application::paintGL() { + // Some plugins process message events, allowing paintGL to be called reentrantly. + if (_aboutToQuit || _window->isMinimized()) { + return; + } + + _frameCount++; + _lastTimeRendered.start(); + + auto lastPaintBegin = usecTimestampNow(); + PROFILE_RANGE_EX(render, __FUNCTION__, 0xff0000ff, (uint64_t)_frameCount); + PerformanceTimer perfTimer("paintGL"); + + if (nullptr == _displayPlugin) { + return; + } + + DisplayPluginPointer displayPlugin; + { + PROFILE_RANGE(render, "/getActiveDisplayPlugin"); + displayPlugin = getActiveDisplayPlugin(); + } + + { + PROFILE_RANGE(render, "/pluginBeginFrameRender"); + // If a display plugin loses it's underlying support, it + // needs to be able to signal us to not use it + if (!displayPlugin->beginFrameRender(_frameCount)) { + updateDisplayMode(); + return; + } + } + + // update the avatar with a fresh HMD pose + // { + // PROFILE_RANGE(render, "/updateAvatar"); + // getMyAvatar()->updateFromHMDSensorMatrix(getHMDSensorPose()); + // } + + // auto lodManager = DependencyManager::get(); + + RenderArgs renderArgs; + float sensorToWorldScale; + glm::mat4 HMDSensorPose; + { + QMutexLocker viewLocker(&_renderArgsMutex); + renderArgs = _appRenderArgs._renderArgs; + HMDSensorPose = _appRenderArgs._eyeToWorld; + sensorToWorldScale = _appRenderArgs._sensorToWorldScale; + } + /* + float sensorToWorldScale = getMyAvatar()->getSensorToWorldScale(); + { + PROFILE_RANGE(render, "/buildFrustrumAndArgs"); + { + QMutexLocker viewLocker(&_viewMutex); + // adjust near clip plane to account for sensor scaling. + auto adjustedProjection = glm::perspective(_viewFrustum.getFieldOfView(), + _viewFrustum.getAspectRatio(), + DEFAULT_NEAR_CLIP * sensorToWorldScale, + _viewFrustum.getFarClip()); + _viewFrustum.setProjection(adjustedProjection); + _viewFrustum.calculate(); + } + renderArgs = RenderArgs(_gpuContext, lodManager->getOctreeSizeScale(), + lodManager->getBoundaryLevelAdjust(), RenderArgs::DEFAULT_RENDER_MODE, + RenderArgs::MONO, RenderArgs::RENDER_DEBUG_NONE); + { + QMutexLocker viewLocker(&_viewMutex); + renderArgs.setViewFrustum(_viewFrustum); + } + } + */ + { + PROFILE_RANGE(render, "/resizeGL"); + PerformanceWarning::setSuppressShortTimings(Menu::getInstance()->isOptionChecked(MenuOption::SuppressShortTimings)); + bool showWarnings = Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings); + PerformanceWarning warn(showWarnings, "Application::paintGL()"); + resizeGL(); + } + + { + PROFILE_RANGE(render, "/gpuContextReset"); + // _gpuContext->beginFrame(getHMDSensorPose()); + _gpuContext->beginFrame(HMDSensorPose); + // Reset the gpu::Context Stages + // Back to the default framebuffer; + gpu::doInBatch(_gpuContext, [&](gpu::Batch& batch) { + batch.resetStages(); + }); + } + + + { + PROFILE_RANGE(render, "/renderOverlay"); + PerformanceTimer perfTimer("renderOverlay"); + // NOTE: There is no batch associated with this renderArgs + // the ApplicationOverlay class assumes it's viewport is setup to be the device size + QSize size = getDeviceSize(); + renderArgs._viewport = glm::ivec4(0, 0, size.width(), size.height()); + _applicationOverlay.renderOverlay(&renderArgs); + } + + // updateCamera(renderArgs); + + /* glm::vec3 boomOffset; + { + PROFILE_RANGE(render, "/updateCamera"); + { + PerformanceTimer perfTimer("CameraUpdates"); + + auto myAvatar = getMyAvatar(); + boomOffset = myAvatar->getModelScale() * myAvatar->getBoomLength() * -IDENTITY_FORWARD; + + // The render mode is default or mirror if the camera is in mirror mode, assigned further below + renderArgs._renderMode = RenderArgs::DEFAULT_RENDER_MODE; + + // Always use the default eye position, not the actual head eye position. + // Using the latter will cause the camera to wobble with idle animations, + // or with changes from the face tracker + if (_myCamera.getMode() == CAMERA_MODE_FIRST_PERSON) { + if (isHMDMode()) { + mat4 camMat = myAvatar->getSensorToWorldMatrix() * myAvatar->getHMDSensorMatrix(); + _myCamera.setPosition(extractTranslation(camMat)); + _myCamera.setOrientation(glmExtractRotation(camMat)); + } else { + _myCamera.setPosition(myAvatar->getDefaultEyePosition()); + _myCamera.setOrientation(myAvatar->getMyHead()->getHeadOrientation()); + } + } else if (_myCamera.getMode() == CAMERA_MODE_THIRD_PERSON) { + if (isHMDMode()) { + auto hmdWorldMat = myAvatar->getSensorToWorldMatrix() * myAvatar->getHMDSensorMatrix(); + _myCamera.setOrientation(glm::normalize(glmExtractRotation(hmdWorldMat))); + _myCamera.setPosition(extractTranslation(hmdWorldMat) + + myAvatar->getOrientation() * boomOffset); + } else { + _myCamera.setOrientation(myAvatar->getHead()->getOrientation()); + if (Menu::getInstance()->isOptionChecked(MenuOption::CenterPlayerInView)) { + _myCamera.setPosition(myAvatar->getDefaultEyePosition() + + _myCamera.getOrientation() * boomOffset); + } else { + _myCamera.setPosition(myAvatar->getDefaultEyePosition() + + myAvatar->getOrientation() * boomOffset); + } + } + } else if (_myCamera.getMode() == CAMERA_MODE_MIRROR) { + if (isHMDMode()) { + auto mirrorBodyOrientation = myAvatar->getOrientation() * glm::quat(glm::vec3(0.0f, PI + _rotateMirror, 0.0f)); + + glm::quat hmdRotation = extractRotation(myAvatar->getHMDSensorMatrix()); + // Mirror HMD yaw and roll + glm::vec3 mirrorHmdEulers = glm::eulerAngles(hmdRotation); + mirrorHmdEulers.y = -mirrorHmdEulers.y; + mirrorHmdEulers.z = -mirrorHmdEulers.z; + glm::quat mirrorHmdRotation = glm::quat(mirrorHmdEulers); + + glm::quat worldMirrorRotation = mirrorBodyOrientation * mirrorHmdRotation; + + _myCamera.setOrientation(worldMirrorRotation); + + glm::vec3 hmdOffset = extractTranslation(myAvatar->getHMDSensorMatrix()); + // Mirror HMD lateral offsets + hmdOffset.x = -hmdOffset.x; + + _myCamera.setPosition(myAvatar->getDefaultEyePosition() + + glm::vec3(0, _raiseMirror * myAvatar->getModelScale(), 0) + + mirrorBodyOrientation * glm::vec3(0.0f, 0.0f, 1.0f) * MIRROR_FULLSCREEN_DISTANCE * _scaleMirror + + mirrorBodyOrientation * hmdOffset); + } else { + _myCamera.setOrientation(myAvatar->getOrientation() + * glm::quat(glm::vec3(0.0f, PI + _rotateMirror, 0.0f))); + _myCamera.setPosition(myAvatar->getDefaultEyePosition() + + glm::vec3(0, _raiseMirror * myAvatar->getModelScale(), 0) + + (myAvatar->getOrientation() * glm::quat(glm::vec3(0.0f, _rotateMirror, 0.0f))) * + glm::vec3(0.0f, 0.0f, -1.0f) * MIRROR_FULLSCREEN_DISTANCE * _scaleMirror); + } + renderArgs._renderMode = RenderArgs::MIRROR_RENDER_MODE; + } else if (_myCamera.getMode() == CAMERA_MODE_ENTITY) { + EntityItemPointer cameraEntity = _myCamera.getCameraEntityPointer(); + if (cameraEntity != nullptr) { + if (isHMDMode()) { + glm::quat hmdRotation = extractRotation(myAvatar->getHMDSensorMatrix()); + _myCamera.setOrientation(cameraEntity->getRotation() * hmdRotation); + glm::vec3 hmdOffset = extractTranslation(myAvatar->getHMDSensorMatrix()); + _myCamera.setPosition(cameraEntity->getPosition() + (hmdRotation * hmdOffset)); + } else { + _myCamera.setOrientation(cameraEntity->getRotation()); + _myCamera.setPosition(cameraEntity->getPosition()); + } + } + } + // Update camera position + if (!isHMDMode()) { + _myCamera.update(1.0f / _frameCounter.rate()); + } + } + } + */ + { + PROFILE_RANGE(render, "/updateCompositor"); + getApplicationCompositor().setFrameInfo(_frameCount, _myCamera.getTransform(), getMyAvatar()->getSensorToWorldMatrix()); + } + + gpu::FramebufferPointer finalFramebuffer; + QSize finalFramebufferSize; + { + PROFILE_RANGE(render, "/getOutputFramebuffer"); + // Primary rendering pass + auto framebufferCache = DependencyManager::get(); + finalFramebufferSize = framebufferCache->getFrameBufferSize(); + // Final framebuffer that will be handled to the display-plugin + finalFramebuffer = framebufferCache->getFramebuffer(); + } + + auto hmdInterface = DependencyManager::get(); + float ipdScale = hmdInterface->getIPDScale(); + + // scale IPD by sensorToWorldScale, to make the world seem larger or smaller accordingly. + ipdScale *= sensorToWorldScale; + + { + PROFILE_RANGE(render, "/mainRender"); + PerformanceTimer perfTimer("mainRender"); + // FIXME is this ever going to be different from the size previously set in the render args + // in the overlay render? + // Viewport is assigned to the size of the framebuffer + renderArgs._viewport = ivec4(0, 0, finalFramebufferSize.width(), finalFramebufferSize.height()); + auto baseProjection = renderArgs.getViewFrustum().getProjection(); + if (displayPlugin->isStereo()) { + // Stereo modes will typically have a larger projection matrix overall, + // so we ask for the 'mono' projection matrix, which for stereo and HMD + // plugins will imply the combined projection for both eyes. + // + // This is properly implemented for the Oculus plugins, but for OpenVR + // and Stereo displays I'm not sure how to get / calculate it, so we're + // just relying on the left FOV in each case and hoping that the + // overall culling margin of error doesn't cause popping in the + // right eye. There are FIXMEs in the relevant plugins + _myCamera.setProjection(displayPlugin->getCullingProjection(baseProjection)); + renderArgs._context->enableStereo(true); + mat4 eyeOffsets[2]; + mat4 eyeProjections[2]; + + // FIXME we probably don't need to set the projection matrix every frame, + // only when the display plugin changes (or in non-HMD modes when the user + // changes the FOV manually, which right now I don't think they can. + for_each_eye([&](Eye eye) { + // For providing the stereo eye views, the HMD head pose has already been + // applied to the avatar, so we need to get the difference between the head + // pose applied to the avatar and the per eye pose, and use THAT as + // the per-eye stereo matrix adjustment. + mat4 eyeToHead = displayPlugin->getEyeToHeadTransform(eye); + // Grab the translation + vec3 eyeOffset = glm::vec3(eyeToHead[3]); + // Apply IPD scaling + mat4 eyeOffsetTransform = glm::translate(mat4(), eyeOffset * -1.0f * ipdScale); + eyeOffsets[eye] = eyeOffsetTransform; + eyeProjections[eye] = displayPlugin->getEyeProjection(eye, baseProjection); + }); + renderArgs._context->setStereoProjections(eyeProjections); + renderArgs._context->setStereoViews(eyeOffsets); + + // Configure the type of display / stereo + renderArgs._displayMode = (isHMDMode() ? RenderArgs::STEREO_HMD : RenderArgs::STEREO_MONITOR); + } + renderArgs._blitFramebuffer = finalFramebuffer; + // displaySide(&renderArgs, _myCamera); + runRenderFrame(&renderArgs); + } + + gpu::Batch postCompositeBatch; + { + PROFILE_RANGE(render, "/postComposite"); + PerformanceTimer perfTimer("postComposite"); + renderArgs._batch = &postCompositeBatch; + renderArgs._batch->setViewportTransform(ivec4(0, 0, finalFramebufferSize.width(), finalFramebufferSize.height())); + renderArgs._batch->setViewTransform(renderArgs.getViewFrustum().getView()); + _overlays.render3DHUDOverlays(&renderArgs); + } + + auto frame = _gpuContext->endFrame(); + frame->frameIndex = _frameCount; + frame->framebuffer = finalFramebuffer; + frame->framebufferRecycler = [](const gpu::FramebufferPointer& framebuffer) { + DependencyManager::get()->releaseFramebuffer(framebuffer); + }; + frame->overlay = _applicationOverlay.getOverlayTexture(); + frame->postCompositeBatch = postCompositeBatch; + // deliver final scene rendering commands to the display plugin + { + PROFILE_RANGE(render, "/pluginOutput"); + PerformanceTimer perfTimer("pluginOutput"); + _frameCounter.increment(); + displayPlugin->submitFrame(frame); + } + + // Reset the framebuffer and stereo state + renderArgs._blitFramebuffer.reset(); + renderArgs._context->enableStereo(false); + + { + Stats::getInstance()->setRenderDetails(renderArgs._details); + } + + uint64_t lastPaintDuration = usecTimestampNow() - lastPaintBegin; + _frameTimingsScriptingInterface.addValue(lastPaintDuration); +} +#endif \ No newline at end of file From 577378f5392ee1e37f9da71abf3755e4157711cd Mon Sep 17 00:00:00 2001 From: samcake Date: Fri, 29 Sep 2017 17:45:10 -0700 Subject: [PATCH 28/59] Adding stuff that seems to break? --- interface/src/Application.cpp | 3 ++ libraries/render/src/render/Scene.cpp | 60 +++++++++++++++++++-------- libraries/render/src/render/Scene.h | 12 ++++++ 3 files changed, 58 insertions(+), 17 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 218c1eb5eb..5bf5f52a53 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -5400,6 +5400,9 @@ void Application::update(float deltaTime) { AnimDebugDraw::getInstance().update(); DependencyManager::get()->update(); + + // Game loopis done, mark the end of the frame for the scene transactions + getMain3DScene()->enqueueFrame(); } void Application::sendAvatarViewFrustum() { diff --git a/libraries/render/src/render/Scene.cpp b/libraries/render/src/render/Scene.cpp index d2d3ad6de6..714be2a8c6 100644 --- a/libraries/render/src/render/Scene.cpp +++ b/libraries/render/src/render/Scene.cpp @@ -15,9 +15,6 @@ #include "Logging.h" #include "TransitionStage.h" -// Comment this to disable transitions (fades) -#define SCENE_ENABLE_TRANSITIONS - using namespace render; void Transaction::resetItem(ItemID id, const PayloadPointer& payload) { @@ -101,16 +98,46 @@ void consolidateTransaction(TransactionQueue& queue, Transaction& singleBatch) { queue.pop(); }; } - -void Scene::processTransactionQueue() { + +uint32_t Scene::enqueueFrame() { PROFILE_RANGE(render, __FUNCTION__); Transaction consolidatedTransaction; - { std::unique_lock lock(_transactionQueueMutex); consolidateTransaction(_transactionQueue, consolidatedTransaction); } - + + uint32_t frameNumber = 0; + { + std::unique_lock lock(_transactionFramesMutex); + _transactionFrames.push_back(consolidatedTransaction); + _transactionFrameNumber++; + frameNumber = _transactionFrameNumber; + } + + return frameNumber; +} + + +void Scene::processTransactionQueue() { + PROFILE_RANGE(render, __FUNCTION__); + + TransactionFrames queuedFrames; + { + // capture the queued frames and clear the queue + std::unique_lock lock(_transactionFramesMutex); + queuedFrames = _transactionFrames; + _transactionFrames.clear(); + } + + // go through the queue of frames and process them + for (auto& frame : queuedFrames) { + processTransactionFrame(frame); + } +} + +void Scene::processTransactionFrame(const Transaction& transaction) { + PROFILE_RANGE(render, __FUNCTION__); { std::unique_lock lock(_itemsMutex); // Here we should be able to check the value of last ItemID allocated @@ -123,32 +150,31 @@ void Scene::processTransactionQueue() { // capture anything coming from the transaction // resets and potential NEW items - resetItems(consolidatedTransaction._resetItems); + resetItems(transaction._resetItems); // Update the numItemsAtomic counter AFTER the reset changes went through _numAllocatedItems.exchange(maxID); // updates - updateItems(consolidatedTransaction._updatedItems); + updateItems(transaction._updatedItems); // removes - removeItems(consolidatedTransaction._removedItems); + removeItems(transaction._removedItems); -#ifdef SCENE_ENABLE_TRANSITIONS // add transitions - transitionItems(consolidatedTransaction._addedTransitions); - reApplyTransitions(consolidatedTransaction._reAppliedTransitions); - queryTransitionItems(consolidatedTransaction._queriedTransitions); -#endif + transitionItems(transaction._addedTransitions); + reApplyTransitions(transaction._reAppliedTransitions); + queryTransitionItems(transaction._queriedTransitions); + // Update the numItemsAtomic counter AFTER the pending changes went through _numAllocatedItems.exchange(maxID); } - if (consolidatedTransaction.touchTransactions()) { + if (transaction.touchTransactions()) { std::unique_lock lock(_selectionsMutex); // resets and potential NEW items - resetSelections(consolidatedTransaction._resetSelections); + resetSelections(transaction._resetSelections); } } diff --git a/libraries/render/src/render/Scene.h b/libraries/render/src/render/Scene.h index 3b61a20f24..fef2077897 100644 --- a/libraries/render/src/render/Scene.h +++ b/libraries/render/src/render/Scene.h @@ -117,6 +117,9 @@ public: // Enqueue transaction to the scene void enqueueTransaction(const Transaction& transaction); + // Enqueue end of frame transactions boundary + uint32_t enqueueFrame(); + // Process the pending transactions queued void processTransactionQueue(); @@ -162,6 +165,15 @@ protected: std::mutex _transactionQueueMutex; TransactionQueue _transactionQueue; + + std::mutex _transactionFramesMutex; + using TransactionFrames = std::list; + TransactionFrames _transactionFrames; + uint32_t _transactionFrameNumber{ 0 }; + + // Process one transaction frame + void processTransactionFrame(const Transaction& transaction); + // The actual database // database of items is protected for editing by a mutex std::mutex _itemsMutex; From 44cc6deac227b738fa91ae56418004723421b8f6 Mon Sep 17 00:00:00 2001 From: Sam Gateau Date: Sun, 1 Oct 2017 12:55:44 -0700 Subject: [PATCH 29/59] moving render specific code from Application.cpp to Application_render.cpp --- interface/src/Application.cpp | 678 +++++++++++++-------------- interface/src/Application_render.cpp | 388 ++++++++------- 2 files changed, 553 insertions(+), 513 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 5bf5f52a53..5ce63441aa 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -2483,249 +2483,249 @@ void Application::updateCamera(RenderArgs& renderArgs) { renderArgs._cameraMode = (int8_t)_myCamera.getMode(); } - -void Application::editRenderArgs(RenderArgsEditor editor) { - QMutexLocker renderLocker(&_renderArgsMutex); - editor(_appRenderArgs); - -} - -void Application::paintGL() { - // Some plugins process message events, allowing paintGL to be called reentrantly. - if (_aboutToQuit || _window->isMinimized()) { - return; - } - - _frameCount++; - _lastTimeRendered.start(); - - auto lastPaintBegin = usecTimestampNow(); - PROFILE_RANGE_EX(render, __FUNCTION__, 0xff0000ff, (uint64_t)_frameCount); - PerformanceTimer perfTimer("paintGL"); - - if (nullptr == _displayPlugin) { - return; - } - - DisplayPluginPointer displayPlugin; - { - PROFILE_RANGE(render, "/getActiveDisplayPlugin"); - displayPlugin = getActiveDisplayPlugin(); - } - - { - PROFILE_RANGE(render, "/pluginBeginFrameRender"); - // If a display plugin loses it's underlying support, it - // needs to be able to signal us to not use it - if (!displayPlugin->beginFrameRender(_frameCount)) { - updateDisplayMode(); - return; - } - } - - // update the avatar with a fresh HMD pose - // { - // PROFILE_RANGE(render, "/updateAvatar"); - // getMyAvatar()->updateFromHMDSensorMatrix(getHMDSensorPose()); - // } - - // auto lodManager = DependencyManager::get(); - - RenderArgs renderArgs; - float sensorToWorldScale; - glm::mat4 HMDSensorPose; - glm::mat4 eyeToWorld; - glm::mat4 sensorToWorld; - - bool isStereo; - glm::mat4 stereoEyeOffsets[2]; - glm::mat4 stereoEyeProjections[2]; - - { - QMutexLocker viewLocker(&_renderArgsMutex); - renderArgs = _appRenderArgs._renderArgs; - HMDSensorPose = _appRenderArgs._headPose; - eyeToWorld = _appRenderArgs._eyeToWorld; - sensorToWorld = _appRenderArgs._sensorToWorld; - sensorToWorldScale = _appRenderArgs._sensorToWorldScale; - isStereo = _appRenderArgs._isStereo; - for_each_eye([&](Eye eye) { - stereoEyeOffsets[eye] = _appRenderArgs._eyeOffsets[eye]; - stereoEyeProjections[eye] = _appRenderArgs._eyeProjections[eye]; - }); - } - - //float sensorToWorldScale = getMyAvatar()->getSensorToWorldScale(); - //{ - // PROFILE_RANGE(render, "/buildFrustrumAndArgs"); - // { - // QMutexLocker viewLocker(&_viewMutex); - // // adjust near clip plane to account for sensor scaling. - // auto adjustedProjection = glm::perspective(_viewFrustum.getFieldOfView(), - // _viewFrustum.getAspectRatio(), - // DEFAULT_NEAR_CLIP * sensorToWorldScale, - // _viewFrustum.getFarClip()); - // _viewFrustum.setProjection(adjustedProjection); - // _viewFrustum.calculate(); - // } - // renderArgs = RenderArgs(_gpuContext, lodManager->getOctreeSizeScale(), - // lodManager->getBoundaryLevelAdjust(), RenderArgs::DEFAULT_RENDER_MODE, - // RenderArgs::MONO, RenderArgs::RENDER_DEBUG_NONE); - // { - // QMutexLocker viewLocker(&_viewMutex); - // renderArgs.setViewFrustum(_viewFrustum); - // } - //} - - //{ - // PROFILE_RANGE(render, "/resizeGL"); - // PerformanceWarning::setSuppressShortTimings(Menu::getInstance()->isOptionChecked(MenuOption::SuppressShortTimings)); - // bool showWarnings = Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings); - // PerformanceWarning warn(showWarnings, "Application::paintGL()"); - // resizeGL(); - //} - - { - PROFILE_RANGE(render, "/gpuContextReset"); - // _gpuContext->beginFrame(getHMDSensorPose()); - _gpuContext->beginFrame(HMDSensorPose); - // Reset the gpu::Context Stages - // Back to the default framebuffer; - gpu::doInBatch(_gpuContext, [&](gpu::Batch& batch) { - batch.resetStages(); - }); - } - - - { - PROFILE_RANGE(render, "/renderOverlay"); - PerformanceTimer perfTimer("renderOverlay"); - // NOTE: There is no batch associated with this renderArgs - // the ApplicationOverlay class assumes it's viewport is setup to be the device size - QSize size = getDeviceSize(); - renderArgs._viewport = glm::ivec4(0, 0, size.width(), size.height()); - _applicationOverlay.renderOverlay(&renderArgs); - } - - // updateCamera(renderArgs); - { - PROFILE_RANGE(render, "/updateCompositor"); - // getApplicationCompositor().setFrameInfo(_frameCount, _myCamera.getTransform(), getMyAvatar()->getSensorToWorldMatrix()); - getApplicationCompositor().setFrameInfo(_frameCount, eyeToWorld, sensorToWorld); - } - - gpu::FramebufferPointer finalFramebuffer; - QSize finalFramebufferSize; - { - PROFILE_RANGE(render, "/getOutputFramebuffer"); - // Primary rendering pass - auto framebufferCache = DependencyManager::get(); - finalFramebufferSize = framebufferCache->getFrameBufferSize(); - // Final framebuffer that will be handled to the display-plugin - finalFramebuffer = framebufferCache->getFramebuffer(); - } - - //auto hmdInterface = DependencyManager::get(); - //float ipdScale = hmdInterface->getIPDScale(); - - //// scale IPD by sensorToWorldScale, to make the world seem larger or smaller accordingly. - //ipdScale *= sensorToWorldScale; - - { - //PROFILE_RANGE(render, "/mainRender"); - //PerformanceTimer perfTimer("mainRender"); - //// FIXME is this ever going to be different from the size previously set in the render args - //// in the overlay render? - //// Viewport is assigned to the size of the framebuffer - //renderArgs._viewport = ivec4(0, 0, finalFramebufferSize.width(), finalFramebufferSize.height()); - //auto baseProjection = renderArgs.getViewFrustum().getProjection(); - //if (displayPlugin->isStereo()) { - // // Stereo modes will typically have a larger projection matrix overall, - // // so we ask for the 'mono' projection matrix, which for stereo and HMD - // // plugins will imply the combined projection for both eyes. - // // - // // This is properly implemented for the Oculus plugins, but for OpenVR - // // and Stereo displays I'm not sure how to get / calculate it, so we're - // // just relying on the left FOV in each case and hoping that the - // // overall culling margin of error doesn't cause popping in the - // // right eye. There are FIXMEs in the relevant plugins - // _myCamera.setProjection(displayPlugin->getCullingProjection(baseProjection)); - // renderArgs._context->enableStereo(true); - // mat4 eyeOffsets[2]; - // mat4 eyeProjections[2]; - - // // FIXME we probably don't need to set the projection matrix every frame, - // // only when the display plugin changes (or in non-HMD modes when the user - // // changes the FOV manually, which right now I don't think they can. - // for_each_eye([&](Eye eye) { - // // For providing the stereo eye views, the HMD head pose has already been - // // applied to the avatar, so we need to get the difference between the head - // // pose applied to the avatar and the per eye pose, and use THAT as - // // the per-eye stereo matrix adjustment. - // mat4 eyeToHead = displayPlugin->getEyeToHeadTransform(eye); - // // Grab the translation - // vec3 eyeOffset = glm::vec3(eyeToHead[3]); - // // Apply IPD scaling - // mat4 eyeOffsetTransform = glm::translate(mat4(), eyeOffset * -1.0f * ipdScale); - // eyeOffsets[eye] = eyeOffsetTransform; - // eyeProjections[eye] = displayPlugin->getEyeProjection(eye, baseProjection); - // }); - // renderArgs._context->setStereoProjections(eyeProjections); - // renderArgs._context->setStereoViews(eyeOffsets); - - // // Configure the type of display / stereo - // renderArgs._displayMode = (isHMDMode() ? RenderArgs::STEREO_HMD : RenderArgs::STEREO_MONITOR); - //} - - if (isStereo) { - renderArgs._context->enableStereo(true); - renderArgs._context->setStereoProjections(stereoEyeProjections); - renderArgs._context->setStereoViews(stereoEyeOffsets); - // renderArgs._displayMode - } - - renderArgs._blitFramebuffer = finalFramebuffer; - // displaySide(&renderArgs, _myCamera); - runRenderFrame(&renderArgs); - } - - gpu::Batch postCompositeBatch; - { - PROFILE_RANGE(render, "/postComposite"); - PerformanceTimer perfTimer("postComposite"); - renderArgs._batch = &postCompositeBatch; - renderArgs._batch->setViewportTransform(ivec4(0, 0, finalFramebufferSize.width(), finalFramebufferSize.height())); - renderArgs._batch->setViewTransform(renderArgs.getViewFrustum().getView()); - _overlays.render3DHUDOverlays(&renderArgs); - } - - auto frame = _gpuContext->endFrame(); - frame->frameIndex = _frameCount; - frame->framebuffer = finalFramebuffer; - frame->framebufferRecycler = [](const gpu::FramebufferPointer& framebuffer){ - DependencyManager::get()->releaseFramebuffer(framebuffer); - }; - frame->overlay = _applicationOverlay.getOverlayTexture(); - frame->postCompositeBatch = postCompositeBatch; - // deliver final scene rendering commands to the display plugin - { - PROFILE_RANGE(render, "/pluginOutput"); - PerformanceTimer perfTimer("pluginOutput"); - _frameCounter.increment(); - displayPlugin->submitFrame(frame); - } - - // Reset the framebuffer and stereo state - renderArgs._blitFramebuffer.reset(); - renderArgs._context->enableStereo(false); - - { - Stats::getInstance()->setRenderDetails(renderArgs._details); - } - - uint64_t lastPaintDuration = usecTimestampNow() - lastPaintBegin; - _frameTimingsScriptingInterface.addValue(lastPaintDuration); -} +// +//void Application::editRenderArgs(RenderArgsEditor editor) { +// QMutexLocker renderLocker(&_renderArgsMutex); +// editor(_appRenderArgs); +// +//} +// +//void Application::paintGL() { +// // Some plugins process message events, allowing paintGL to be called reentrantly. +// if (_aboutToQuit || _window->isMinimized()) { +// return; +// } +// +// _frameCount++; +// _lastTimeRendered.start(); +// +// auto lastPaintBegin = usecTimestampNow(); +// PROFILE_RANGE_EX(render, __FUNCTION__, 0xff0000ff, (uint64_t)_frameCount); +// PerformanceTimer perfTimer("paintGL"); +// +// if (nullptr == _displayPlugin) { +// return; +// } +// +// DisplayPluginPointer displayPlugin; +// { +// PROFILE_RANGE(render, "/getActiveDisplayPlugin"); +// displayPlugin = getActiveDisplayPlugin(); +// } +// +// { +// PROFILE_RANGE(render, "/pluginBeginFrameRender"); +// // If a display plugin loses it's underlying support, it +// // needs to be able to signal us to not use it +// if (!displayPlugin->beginFrameRender(_frameCount)) { +// updateDisplayMode(); +// return; +// } +// } +// +// // update the avatar with a fresh HMD pose +// // { +// // PROFILE_RANGE(render, "/updateAvatar"); +// // getMyAvatar()->updateFromHMDSensorMatrix(getHMDSensorPose()); +// // } +// +// // auto lodManager = DependencyManager::get(); +// +// RenderArgs renderArgs; +// float sensorToWorldScale; +// glm::mat4 HMDSensorPose; +// glm::mat4 eyeToWorld; +// glm::mat4 sensorToWorld; +// +// bool isStereo; +// glm::mat4 stereoEyeOffsets[2]; +// glm::mat4 stereoEyeProjections[2]; +// +// { +// QMutexLocker viewLocker(&_renderArgsMutex); +// renderArgs = _appRenderArgs._renderArgs; +// HMDSensorPose = _appRenderArgs._headPose; +// eyeToWorld = _appRenderArgs._eyeToWorld; +// sensorToWorld = _appRenderArgs._sensorToWorld; +// sensorToWorldScale = _appRenderArgs._sensorToWorldScale; +// isStereo = _appRenderArgs._isStereo; +// for_each_eye([&](Eye eye) { +// stereoEyeOffsets[eye] = _appRenderArgs._eyeOffsets[eye]; +// stereoEyeProjections[eye] = _appRenderArgs._eyeProjections[eye]; +// }); +// } +// +// //float sensorToWorldScale = getMyAvatar()->getSensorToWorldScale(); +// //{ +// // PROFILE_RANGE(render, "/buildFrustrumAndArgs"); +// // { +// // QMutexLocker viewLocker(&_viewMutex); +// // // adjust near clip plane to account for sensor scaling. +// // auto adjustedProjection = glm::perspective(_viewFrustum.getFieldOfView(), +// // _viewFrustum.getAspectRatio(), +// // DEFAULT_NEAR_CLIP * sensorToWorldScale, +// // _viewFrustum.getFarClip()); +// // _viewFrustum.setProjection(adjustedProjection); +// // _viewFrustum.calculate(); +// // } +// // renderArgs = RenderArgs(_gpuContext, lodManager->getOctreeSizeScale(), +// // lodManager->getBoundaryLevelAdjust(), RenderArgs::DEFAULT_RENDER_MODE, +// // RenderArgs::MONO, RenderArgs::RENDER_DEBUG_NONE); +// // { +// // QMutexLocker viewLocker(&_viewMutex); +// // renderArgs.setViewFrustum(_viewFrustum); +// // } +// //} +// +// //{ +// // PROFILE_RANGE(render, "/resizeGL"); +// // PerformanceWarning::setSuppressShortTimings(Menu::getInstance()->isOptionChecked(MenuOption::SuppressShortTimings)); +// // bool showWarnings = Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings); +// // PerformanceWarning warn(showWarnings, "Application::paintGL()"); +// // resizeGL(); +// //} +// +// { +// PROFILE_RANGE(render, "/gpuContextReset"); +// // _gpuContext->beginFrame(getHMDSensorPose()); +// _gpuContext->beginFrame(HMDSensorPose); +// // Reset the gpu::Context Stages +// // Back to the default framebuffer; +// gpu::doInBatch(_gpuContext, [&](gpu::Batch& batch) { +// batch.resetStages(); +// }); +// } +// +// +// { +// PROFILE_RANGE(render, "/renderOverlay"); +// PerformanceTimer perfTimer("renderOverlay"); +// // NOTE: There is no batch associated with this renderArgs +// // the ApplicationOverlay class assumes it's viewport is setup to be the device size +// QSize size = getDeviceSize(); +// renderArgs._viewport = glm::ivec4(0, 0, size.width(), size.height()); +// _applicationOverlay.renderOverlay(&renderArgs); +// } +// +// // updateCamera(renderArgs); +// { +// PROFILE_RANGE(render, "/updateCompositor"); +// // getApplicationCompositor().setFrameInfo(_frameCount, _myCamera.getTransform(), getMyAvatar()->getSensorToWorldMatrix()); +// getApplicationCompositor().setFrameInfo(_frameCount, eyeToWorld, sensorToWorld); +// } +// +// gpu::FramebufferPointer finalFramebuffer; +// QSize finalFramebufferSize; +// { +// PROFILE_RANGE(render, "/getOutputFramebuffer"); +// // Primary rendering pass +// auto framebufferCache = DependencyManager::get(); +// finalFramebufferSize = framebufferCache->getFrameBufferSize(); +// // Final framebuffer that will be handled to the display-plugin +// finalFramebuffer = framebufferCache->getFramebuffer(); +// } +// +// //auto hmdInterface = DependencyManager::get(); +// //float ipdScale = hmdInterface->getIPDScale(); +// +// //// scale IPD by sensorToWorldScale, to make the world seem larger or smaller accordingly. +// //ipdScale *= sensorToWorldScale; +// +// { +// //PROFILE_RANGE(render, "/mainRender"); +// //PerformanceTimer perfTimer("mainRender"); +// //// FIXME is this ever going to be different from the size previously set in the render args +// //// in the overlay render? +// //// Viewport is assigned to the size of the framebuffer +// //renderArgs._viewport = ivec4(0, 0, finalFramebufferSize.width(), finalFramebufferSize.height()); +// //auto baseProjection = renderArgs.getViewFrustum().getProjection(); +// //if (displayPlugin->isStereo()) { +// // // Stereo modes will typically have a larger projection matrix overall, +// // // so we ask for the 'mono' projection matrix, which for stereo and HMD +// // // plugins will imply the combined projection for both eyes. +// // // +// // // This is properly implemented for the Oculus plugins, but for OpenVR +// // // and Stereo displays I'm not sure how to get / calculate it, so we're +// // // just relying on the left FOV in each case and hoping that the +// // // overall culling margin of error doesn't cause popping in the +// // // right eye. There are FIXMEs in the relevant plugins +// // _myCamera.setProjection(displayPlugin->getCullingProjection(baseProjection)); +// // renderArgs._context->enableStereo(true); +// // mat4 eyeOffsets[2]; +// // mat4 eyeProjections[2]; +// +// // // FIXME we probably don't need to set the projection matrix every frame, +// // // only when the display plugin changes (or in non-HMD modes when the user +// // // changes the FOV manually, which right now I don't think they can. +// // for_each_eye([&](Eye eye) { +// // // For providing the stereo eye views, the HMD head pose has already been +// // // applied to the avatar, so we need to get the difference between the head +// // // pose applied to the avatar and the per eye pose, and use THAT as +// // // the per-eye stereo matrix adjustment. +// // mat4 eyeToHead = displayPlugin->getEyeToHeadTransform(eye); +// // // Grab the translation +// // vec3 eyeOffset = glm::vec3(eyeToHead[3]); +// // // Apply IPD scaling +// // mat4 eyeOffsetTransform = glm::translate(mat4(), eyeOffset * -1.0f * ipdScale); +// // eyeOffsets[eye] = eyeOffsetTransform; +// // eyeProjections[eye] = displayPlugin->getEyeProjection(eye, baseProjection); +// // }); +// // renderArgs._context->setStereoProjections(eyeProjections); +// // renderArgs._context->setStereoViews(eyeOffsets); +// +// // // Configure the type of display / stereo +// // renderArgs._displayMode = (isHMDMode() ? RenderArgs::STEREO_HMD : RenderArgs::STEREO_MONITOR); +// //} +// +// if (isStereo) { +// renderArgs._context->enableStereo(true); +// renderArgs._context->setStereoProjections(stereoEyeProjections); +// renderArgs._context->setStereoViews(stereoEyeOffsets); +// // renderArgs._displayMode +// } +// +// renderArgs._blitFramebuffer = finalFramebuffer; +// // displaySide(&renderArgs, _myCamera); +// runRenderFrame(&renderArgs); +// } +// +// gpu::Batch postCompositeBatch; +// { +// PROFILE_RANGE(render, "/postComposite"); +// PerformanceTimer perfTimer("postComposite"); +// renderArgs._batch = &postCompositeBatch; +// renderArgs._batch->setViewportTransform(ivec4(0, 0, finalFramebufferSize.width(), finalFramebufferSize.height())); +// renderArgs._batch->setViewTransform(renderArgs.getViewFrustum().getView()); +// _overlays.render3DHUDOverlays(&renderArgs); +// } +// +// auto frame = _gpuContext->endFrame(); +// frame->frameIndex = _frameCount; +// frame->framebuffer = finalFramebuffer; +// frame->framebufferRecycler = [](const gpu::FramebufferPointer& framebuffer){ +// DependencyManager::get()->releaseFramebuffer(framebuffer); +// }; +// frame->overlay = _applicationOverlay.getOverlayTexture(); +// frame->postCompositeBatch = postCompositeBatch; +// // deliver final scene rendering commands to the display plugin +// { +// PROFILE_RANGE(render, "/pluginOutput"); +// PerformanceTimer perfTimer("pluginOutput"); +// _frameCounter.increment(); +// displayPlugin->submitFrame(frame); +// } +// +// // Reset the framebuffer and stereo state +// renderArgs._blitFramebuffer.reset(); +// renderArgs._context->enableStereo(false); +// +// { +// Stats::getInstance()->setRenderDetails(renderArgs._details); +// } +// +// uint64_t lastPaintDuration = usecTimestampNow() - lastPaintBegin; +// _frameTimingsScriptingInterface.addValue(lastPaintDuration); +//} void Application::runTests() { runTimingTests(); @@ -5401,7 +5401,7 @@ void Application::update(float deltaTime) { DependencyManager::get()->update(); - // Game loopis done, mark the end of the frame for the scene transactions + // Game loop is done, mark the end of the frame for the scene transactions and the render loop to take over getMain3DScene()->enqueueFrame(); } @@ -5692,101 +5692,101 @@ void Application::copyDisplayViewFrustum(ViewFrustum& viewOut) const { viewOut = _displayViewFrustum; } -// WorldBox Render Data & rendering functions - -class WorldBoxRenderData { -public: - typedef render::Payload Payload; - typedef Payload::DataPointer Pointer; - - int _val = 0; - static render::ItemID _item; // unique WorldBoxRenderData -}; - -render::ItemID WorldBoxRenderData::_item { render::Item::INVALID_ITEM_ID }; - -namespace render { - template <> const ItemKey payloadGetKey(const WorldBoxRenderData::Pointer& stuff) { return ItemKey::Builder::opaqueShape(); } - template <> const Item::Bound payloadGetBound(const WorldBoxRenderData::Pointer& stuff) { return Item::Bound(); } - template <> void payloadRender(const WorldBoxRenderData::Pointer& stuff, RenderArgs* args) { - if (Menu::getInstance()->isOptionChecked(MenuOption::WorldAxes)) { - PerformanceTimer perfTimer("worldBox"); - - auto& batch = *args->_batch; - DependencyManager::get()->bindSimpleProgram(batch); - renderWorldBox(args, batch); - } - } -} - -void Application::runRenderFrame(RenderArgs* renderArgs) { - - // FIXME: This preDisplayRender call is temporary until we create a separate render::scene for the mirror rendering. - // Then we can move this logic into the Avatar::simulate call. - // auto myAvatar = getMyAvatar(); - // myAvatar->preDisplaySide(renderArgs); - - PROFILE_RANGE(render, __FUNCTION__); - PerformanceTimer perfTimer("display"); - PerformanceWarning warn(Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings), "Application::runRenderFrame()"); - - // load the view frustum - // { - // QMutexLocker viewLocker(&_viewMutex); - // theCamera.loadViewFrustum(_displayViewFrustum); - // } - - // The pending changes collecting the changes here - render::Transaction transaction; - - // Assuming nothing gets rendered through that - //if (!selfAvatarOnly) { - { - if (DependencyManager::get()->shouldRenderEntities()) { - // render models... - PerformanceTimer perfTimer("entities"); - PerformanceWarning warn(Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings), - "Application::runRenderFrame() ... entities..."); - - RenderArgs::DebugFlags renderDebugFlags = RenderArgs::RENDER_DEBUG_NONE; - - if (Menu::getInstance()->isOptionChecked(MenuOption::PhysicsShowHulls)) { - renderDebugFlags = static_cast(renderDebugFlags | - static_cast(RenderArgs::RENDER_DEBUG_HULLS)); - } - renderArgs->_debugFlags = renderDebugFlags; - } - } - - // FIXME: Move this out of here!, WorldBox should be driven by the entity content just like the other entities - // Make sure the WorldBox is in the scene - if (!render::Item::isValidID(WorldBoxRenderData::_item)) { - auto worldBoxRenderData = make_shared(); - auto worldBoxRenderPayload = make_shared(worldBoxRenderData); - - WorldBoxRenderData::_item = _main3DScene->allocateID(); - - transaction.resetItem(WorldBoxRenderData::_item, worldBoxRenderPayload); - _main3DScene->enqueueTransaction(transaction); - } - - - // For now every frame pass the renderContext - { - PerformanceTimer perfTimer("EngineRun"); - - /* { - QMutexLocker viewLocker(&_viewMutex); - renderArgs->setViewFrustum(_displayViewFrustum); - }*/ - // renderArgs->_cameraMode = (int8_t)theCamera.getMode(); // HACK - renderArgs->_scene = getMain3DScene(); - _renderEngine->getRenderContext()->args = renderArgs; - - // Before the deferred pass, let's try to use the render engine - _renderEngine->run(); - } -} +//// WorldBox Render Data & rendering functions +// +//class WorldBoxRenderData { +//public: +// typedef render::Payload Payload; +// typedef Payload::DataPointer Pointer; +// +// int _val = 0; +// static render::ItemID _item; // unique WorldBoxRenderData +//}; +// +//render::ItemID WorldBoxRenderData::_item { render::Item::INVALID_ITEM_ID }; +// +//namespace render { +// template <> const ItemKey payloadGetKey(const WorldBoxRenderData::Pointer& stuff) { return ItemKey::Builder::opaqueShape(); } +// template <> const Item::Bound payloadGetBound(const WorldBoxRenderData::Pointer& stuff) { return Item::Bound(); } +// template <> void payloadRender(const WorldBoxRenderData::Pointer& stuff, RenderArgs* args) { +// if (Menu::getInstance()->isOptionChecked(MenuOption::WorldAxes)) { +// PerformanceTimer perfTimer("worldBox"); +// +// auto& batch = *args->_batch; +// DependencyManager::get()->bindSimpleProgram(batch); +// renderWorldBox(args, batch); +// } +// } +//} +// +//void Application::runRenderFrame(RenderArgs* renderArgs) { +// +// // FIXME: This preDisplayRender call is temporary until we create a separate render::scene for the mirror rendering. +// // Then we can move this logic into the Avatar::simulate call. +// // auto myAvatar = getMyAvatar(); +// // myAvatar->preDisplaySide(renderArgs); +// +// PROFILE_RANGE(render, __FUNCTION__); +// PerformanceTimer perfTimer("display"); +// PerformanceWarning warn(Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings), "Application::runRenderFrame()"); +// +// // load the view frustum +// // { +// // QMutexLocker viewLocker(&_viewMutex); +// // theCamera.loadViewFrustum(_displayViewFrustum); +// // } +// +// // The pending changes collecting the changes here +// render::Transaction transaction; +// +// // Assuming nothing gets rendered through that +// //if (!selfAvatarOnly) { +// { +// if (DependencyManager::get()->shouldRenderEntities()) { +// // render models... +// PerformanceTimer perfTimer("entities"); +// PerformanceWarning warn(Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings), +// "Application::runRenderFrame() ... entities..."); +// +// RenderArgs::DebugFlags renderDebugFlags = RenderArgs::RENDER_DEBUG_NONE; +// +// if (Menu::getInstance()->isOptionChecked(MenuOption::PhysicsShowHulls)) { +// renderDebugFlags = static_cast(renderDebugFlags | +// static_cast(RenderArgs::RENDER_DEBUG_HULLS)); +// } +// renderArgs->_debugFlags = renderDebugFlags; +// } +// } +// +// // FIXME: Move this out of here!, WorldBox should be driven by the entity content just like the other entities +// // Make sure the WorldBox is in the scene +// if (!render::Item::isValidID(WorldBoxRenderData::_item)) { +// auto worldBoxRenderData = make_shared(); +// auto worldBoxRenderPayload = make_shared(worldBoxRenderData); +// +// WorldBoxRenderData::_item = _main3DScene->allocateID(); +// +// transaction.resetItem(WorldBoxRenderData::_item, worldBoxRenderPayload); +// _main3DScene->enqueueTransaction(transaction); +// } +// +// +// // For now every frame pass the renderContext +// { +// PerformanceTimer perfTimer("EngineRun"); +// +// /* { +// QMutexLocker viewLocker(&_viewMutex); +// renderArgs->setViewFrustum(_displayViewFrustum); +// }*/ +// // renderArgs->_cameraMode = (int8_t)theCamera.getMode(); // HACK +// renderArgs->_scene = getMain3DScene(); +// _renderEngine->getRenderContext()->args = renderArgs; +// +// // Before the deferred pass, let's try to use the render engine +// _renderEngine->run(); +// } +//} void Application::resetSensors(bool andReload) { DependencyManager::get()->reset(); diff --git a/interface/src/Application_render.cpp b/interface/src/Application_render.cpp index ee3267284a..51d55a2bd8 100644 --- a/interface/src/Application_render.cpp +++ b/interface/src/Application_render.cpp @@ -8,7 +8,22 @@ // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // -#ifdef tryingSOmething +#include "Application.h" +#include + +#include +#include +#include "ui/Stats.h" +#include "FrameTimingsScriptingInterface.h" + +// Statically provided display and input plugins +extern DisplayPluginList getDisplayPlugins(); + +void Application::editRenderArgs(RenderArgsEditor editor) { + QMutexLocker renderLocker(&_renderArgsMutex); + editor(_appRenderArgs); + +} void Application::paintGL() { // Some plugins process message events, allowing paintGL to be called reentrantly. @@ -54,42 +69,56 @@ void Application::paintGL() { RenderArgs renderArgs; float sensorToWorldScale; glm::mat4 HMDSensorPose; + glm::mat4 eyeToWorld; + glm::mat4 sensorToWorld; + + bool isStereo; + glm::mat4 stereoEyeOffsets[2]; + glm::mat4 stereoEyeProjections[2]; + { QMutexLocker viewLocker(&_renderArgsMutex); renderArgs = _appRenderArgs._renderArgs; - HMDSensorPose = _appRenderArgs._eyeToWorld; + HMDSensorPose = _appRenderArgs._headPose; + eyeToWorld = _appRenderArgs._eyeToWorld; + sensorToWorld = _appRenderArgs._sensorToWorld; sensorToWorldScale = _appRenderArgs._sensorToWorldScale; + isStereo = _appRenderArgs._isStereo; + for_each_eye([&](Eye eye) { + stereoEyeOffsets[eye] = _appRenderArgs._eyeOffsets[eye]; + stereoEyeProjections[eye] = _appRenderArgs._eyeProjections[eye]; + }); } - /* - float sensorToWorldScale = getMyAvatar()->getSensorToWorldScale(); - { - PROFILE_RANGE(render, "/buildFrustrumAndArgs"); - { - QMutexLocker viewLocker(&_viewMutex); - // adjust near clip plane to account for sensor scaling. - auto adjustedProjection = glm::perspective(_viewFrustum.getFieldOfView(), - _viewFrustum.getAspectRatio(), - DEFAULT_NEAR_CLIP * sensorToWorldScale, - _viewFrustum.getFarClip()); - _viewFrustum.setProjection(adjustedProjection); - _viewFrustum.calculate(); - } - renderArgs = RenderArgs(_gpuContext, lodManager->getOctreeSizeScale(), - lodManager->getBoundaryLevelAdjust(), RenderArgs::DEFAULT_RENDER_MODE, - RenderArgs::MONO, RenderArgs::RENDER_DEBUG_NONE); - { - QMutexLocker viewLocker(&_viewMutex); - renderArgs.setViewFrustum(_viewFrustum); - } - } - */ - { - PROFILE_RANGE(render, "/resizeGL"); - PerformanceWarning::setSuppressShortTimings(Menu::getInstance()->isOptionChecked(MenuOption::SuppressShortTimings)); - bool showWarnings = Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings); - PerformanceWarning warn(showWarnings, "Application::paintGL()"); - resizeGL(); - } + + //float sensorToWorldScale = getMyAvatar()->getSensorToWorldScale(); + //{ + // PROFILE_RANGE(render, "/buildFrustrumAndArgs"); + // { + // QMutexLocker viewLocker(&_viewMutex); + // // adjust near clip plane to account for sensor scaling. + // auto adjustedProjection = glm::perspective(_viewFrustum.getFieldOfView(), + // _viewFrustum.getAspectRatio(), + // DEFAULT_NEAR_CLIP * sensorToWorldScale, + // _viewFrustum.getFarClip()); + // _viewFrustum.setProjection(adjustedProjection); + // _viewFrustum.calculate(); + // } + // renderArgs = RenderArgs(_gpuContext, lodManager->getOctreeSizeScale(), + // lodManager->getBoundaryLevelAdjust(), RenderArgs::DEFAULT_RENDER_MODE, + // RenderArgs::MONO, RenderArgs::RENDER_DEBUG_NONE); + // { + // QMutexLocker viewLocker(&_viewMutex); + // renderArgs.setViewFrustum(_viewFrustum); + // } + //} + + //{ + // PROFILE_RANGE(render, "/resizeGL"); + // PerformanceWarning::setSuppressShortTimings(Menu::getInstance()->isOptionChecked(MenuOption::SuppressShortTimings)); + // bool showWarnings = Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings); + // PerformanceWarning warn(showWarnings, "Application::paintGL()"); + // resizeGL(); + //} { PROFILE_RANGE(render, "/gpuContextReset"); @@ -114,103 +143,10 @@ void Application::paintGL() { } // updateCamera(renderArgs); - - /* glm::vec3 boomOffset; - { - PROFILE_RANGE(render, "/updateCamera"); - { - PerformanceTimer perfTimer("CameraUpdates"); - - auto myAvatar = getMyAvatar(); - boomOffset = myAvatar->getModelScale() * myAvatar->getBoomLength() * -IDENTITY_FORWARD; - - // The render mode is default or mirror if the camera is in mirror mode, assigned further below - renderArgs._renderMode = RenderArgs::DEFAULT_RENDER_MODE; - - // Always use the default eye position, not the actual head eye position. - // Using the latter will cause the camera to wobble with idle animations, - // or with changes from the face tracker - if (_myCamera.getMode() == CAMERA_MODE_FIRST_PERSON) { - if (isHMDMode()) { - mat4 camMat = myAvatar->getSensorToWorldMatrix() * myAvatar->getHMDSensorMatrix(); - _myCamera.setPosition(extractTranslation(camMat)); - _myCamera.setOrientation(glmExtractRotation(camMat)); - } else { - _myCamera.setPosition(myAvatar->getDefaultEyePosition()); - _myCamera.setOrientation(myAvatar->getMyHead()->getHeadOrientation()); - } - } else if (_myCamera.getMode() == CAMERA_MODE_THIRD_PERSON) { - if (isHMDMode()) { - auto hmdWorldMat = myAvatar->getSensorToWorldMatrix() * myAvatar->getHMDSensorMatrix(); - _myCamera.setOrientation(glm::normalize(glmExtractRotation(hmdWorldMat))); - _myCamera.setPosition(extractTranslation(hmdWorldMat) + - myAvatar->getOrientation() * boomOffset); - } else { - _myCamera.setOrientation(myAvatar->getHead()->getOrientation()); - if (Menu::getInstance()->isOptionChecked(MenuOption::CenterPlayerInView)) { - _myCamera.setPosition(myAvatar->getDefaultEyePosition() - + _myCamera.getOrientation() * boomOffset); - } else { - _myCamera.setPosition(myAvatar->getDefaultEyePosition() - + myAvatar->getOrientation() * boomOffset); - } - } - } else if (_myCamera.getMode() == CAMERA_MODE_MIRROR) { - if (isHMDMode()) { - auto mirrorBodyOrientation = myAvatar->getOrientation() * glm::quat(glm::vec3(0.0f, PI + _rotateMirror, 0.0f)); - - glm::quat hmdRotation = extractRotation(myAvatar->getHMDSensorMatrix()); - // Mirror HMD yaw and roll - glm::vec3 mirrorHmdEulers = glm::eulerAngles(hmdRotation); - mirrorHmdEulers.y = -mirrorHmdEulers.y; - mirrorHmdEulers.z = -mirrorHmdEulers.z; - glm::quat mirrorHmdRotation = glm::quat(mirrorHmdEulers); - - glm::quat worldMirrorRotation = mirrorBodyOrientation * mirrorHmdRotation; - - _myCamera.setOrientation(worldMirrorRotation); - - glm::vec3 hmdOffset = extractTranslation(myAvatar->getHMDSensorMatrix()); - // Mirror HMD lateral offsets - hmdOffset.x = -hmdOffset.x; - - _myCamera.setPosition(myAvatar->getDefaultEyePosition() - + glm::vec3(0, _raiseMirror * myAvatar->getModelScale(), 0) - + mirrorBodyOrientation * glm::vec3(0.0f, 0.0f, 1.0f) * MIRROR_FULLSCREEN_DISTANCE * _scaleMirror - + mirrorBodyOrientation * hmdOffset); - } else { - _myCamera.setOrientation(myAvatar->getOrientation() - * glm::quat(glm::vec3(0.0f, PI + _rotateMirror, 0.0f))); - _myCamera.setPosition(myAvatar->getDefaultEyePosition() - + glm::vec3(0, _raiseMirror * myAvatar->getModelScale(), 0) - + (myAvatar->getOrientation() * glm::quat(glm::vec3(0.0f, _rotateMirror, 0.0f))) * - glm::vec3(0.0f, 0.0f, -1.0f) * MIRROR_FULLSCREEN_DISTANCE * _scaleMirror); - } - renderArgs._renderMode = RenderArgs::MIRROR_RENDER_MODE; - } else if (_myCamera.getMode() == CAMERA_MODE_ENTITY) { - EntityItemPointer cameraEntity = _myCamera.getCameraEntityPointer(); - if (cameraEntity != nullptr) { - if (isHMDMode()) { - glm::quat hmdRotation = extractRotation(myAvatar->getHMDSensorMatrix()); - _myCamera.setOrientation(cameraEntity->getRotation() * hmdRotation); - glm::vec3 hmdOffset = extractTranslation(myAvatar->getHMDSensorMatrix()); - _myCamera.setPosition(cameraEntity->getPosition() + (hmdRotation * hmdOffset)); - } else { - _myCamera.setOrientation(cameraEntity->getRotation()); - _myCamera.setPosition(cameraEntity->getPosition()); - } - } - } - // Update camera position - if (!isHMDMode()) { - _myCamera.update(1.0f / _frameCounter.rate()); - } - } - } - */ { PROFILE_RANGE(render, "/updateCompositor"); - getApplicationCompositor().setFrameInfo(_frameCount, _myCamera.getTransform(), getMyAvatar()->getSensorToWorldMatrix()); + // getApplicationCompositor().setFrameInfo(_frameCount, _myCamera.getTransform(), getMyAvatar()->getSensorToWorldMatrix()); + getApplicationCompositor().setFrameInfo(_frameCount, eyeToWorld, sensorToWorld); } gpu::FramebufferPointer finalFramebuffer; @@ -224,57 +160,65 @@ void Application::paintGL() { finalFramebuffer = framebufferCache->getFramebuffer(); } - auto hmdInterface = DependencyManager::get(); - float ipdScale = hmdInterface->getIPDScale(); + //auto hmdInterface = DependencyManager::get(); + //float ipdScale = hmdInterface->getIPDScale(); - // scale IPD by sensorToWorldScale, to make the world seem larger or smaller accordingly. - ipdScale *= sensorToWorldScale; + //// scale IPD by sensorToWorldScale, to make the world seem larger or smaller accordingly. + //ipdScale *= sensorToWorldScale; { - PROFILE_RANGE(render, "/mainRender"); - PerformanceTimer perfTimer("mainRender"); - // FIXME is this ever going to be different from the size previously set in the render args - // in the overlay render? - // Viewport is assigned to the size of the framebuffer - renderArgs._viewport = ivec4(0, 0, finalFramebufferSize.width(), finalFramebufferSize.height()); - auto baseProjection = renderArgs.getViewFrustum().getProjection(); - if (displayPlugin->isStereo()) { - // Stereo modes will typically have a larger projection matrix overall, - // so we ask for the 'mono' projection matrix, which for stereo and HMD - // plugins will imply the combined projection for both eyes. - // - // This is properly implemented for the Oculus plugins, but for OpenVR - // and Stereo displays I'm not sure how to get / calculate it, so we're - // just relying on the left FOV in each case and hoping that the - // overall culling margin of error doesn't cause popping in the - // right eye. There are FIXMEs in the relevant plugins - _myCamera.setProjection(displayPlugin->getCullingProjection(baseProjection)); + //PROFILE_RANGE(render, "/mainRender"); + //PerformanceTimer perfTimer("mainRender"); + //// FIXME is this ever going to be different from the size previously set in the render args + //// in the overlay render? + //// Viewport is assigned to the size of the framebuffer + //renderArgs._viewport = ivec4(0, 0, finalFramebufferSize.width(), finalFramebufferSize.height()); + //auto baseProjection = renderArgs.getViewFrustum().getProjection(); + //if (displayPlugin->isStereo()) { + // // Stereo modes will typically have a larger projection matrix overall, + // // so we ask for the 'mono' projection matrix, which for stereo and HMD + // // plugins will imply the combined projection for both eyes. + // // + // // This is properly implemented for the Oculus plugins, but for OpenVR + // // and Stereo displays I'm not sure how to get / calculate it, so we're + // // just relying on the left FOV in each case and hoping that the + // // overall culling margin of error doesn't cause popping in the + // // right eye. There are FIXMEs in the relevant plugins + // _myCamera.setProjection(displayPlugin->getCullingProjection(baseProjection)); + // renderArgs._context->enableStereo(true); + // mat4 eyeOffsets[2]; + // mat4 eyeProjections[2]; + + // // FIXME we probably don't need to set the projection matrix every frame, + // // only when the display plugin changes (or in non-HMD modes when the user + // // changes the FOV manually, which right now I don't think they can. + // for_each_eye([&](Eye eye) { + // // For providing the stereo eye views, the HMD head pose has already been + // // applied to the avatar, so we need to get the difference between the head + // // pose applied to the avatar and the per eye pose, and use THAT as + // // the per-eye stereo matrix adjustment. + // mat4 eyeToHead = displayPlugin->getEyeToHeadTransform(eye); + // // Grab the translation + // vec3 eyeOffset = glm::vec3(eyeToHead[3]); + // // Apply IPD scaling + // mat4 eyeOffsetTransform = glm::translate(mat4(), eyeOffset * -1.0f * ipdScale); + // eyeOffsets[eye] = eyeOffsetTransform; + // eyeProjections[eye] = displayPlugin->getEyeProjection(eye, baseProjection); + // }); + // renderArgs._context->setStereoProjections(eyeProjections); + // renderArgs._context->setStereoViews(eyeOffsets); + + // // Configure the type of display / stereo + // renderArgs._displayMode = (isHMDMode() ? RenderArgs::STEREO_HMD : RenderArgs::STEREO_MONITOR); + //} + + if (isStereo) { renderArgs._context->enableStereo(true); - mat4 eyeOffsets[2]; - mat4 eyeProjections[2]; - - // FIXME we probably don't need to set the projection matrix every frame, - // only when the display plugin changes (or in non-HMD modes when the user - // changes the FOV manually, which right now I don't think they can. - for_each_eye([&](Eye eye) { - // For providing the stereo eye views, the HMD head pose has already been - // applied to the avatar, so we need to get the difference between the head - // pose applied to the avatar and the per eye pose, and use THAT as - // the per-eye stereo matrix adjustment. - mat4 eyeToHead = displayPlugin->getEyeToHeadTransform(eye); - // Grab the translation - vec3 eyeOffset = glm::vec3(eyeToHead[3]); - // Apply IPD scaling - mat4 eyeOffsetTransform = glm::translate(mat4(), eyeOffset * -1.0f * ipdScale); - eyeOffsets[eye] = eyeOffsetTransform; - eyeProjections[eye] = displayPlugin->getEyeProjection(eye, baseProjection); - }); - renderArgs._context->setStereoProjections(eyeProjections); - renderArgs._context->setStereoViews(eyeOffsets); - - // Configure the type of display / stereo - renderArgs._displayMode = (isHMDMode() ? RenderArgs::STEREO_HMD : RenderArgs::STEREO_MONITOR); + renderArgs._context->setStereoProjections(stereoEyeProjections); + renderArgs._context->setStereoViews(stereoEyeOffsets); + // renderArgs._displayMode } + renderArgs._blitFramebuffer = finalFramebuffer; // displaySide(&renderArgs, _myCamera); runRenderFrame(&renderArgs); @@ -317,4 +261,100 @@ void Application::paintGL() { uint64_t lastPaintDuration = usecTimestampNow() - lastPaintBegin; _frameTimingsScriptingInterface.addValue(lastPaintDuration); } -#endif \ No newline at end of file + + +// WorldBox Render Data & rendering functions + +class WorldBoxRenderData { +public: + typedef render::Payload Payload; + typedef Payload::DataPointer Pointer; + + int _val = 0; + static render::ItemID _item; // unique WorldBoxRenderData +}; + +render::ItemID WorldBoxRenderData::_item{ render::Item::INVALID_ITEM_ID }; + +namespace render { + template <> const ItemKey payloadGetKey(const WorldBoxRenderData::Pointer& stuff) { return ItemKey::Builder::opaqueShape(); } + template <> const Item::Bound payloadGetBound(const WorldBoxRenderData::Pointer& stuff) { return Item::Bound(); } + template <> void payloadRender(const WorldBoxRenderData::Pointer& stuff, RenderArgs* args) { + if (Menu::getInstance()->isOptionChecked(MenuOption::WorldAxes)) { + PerformanceTimer perfTimer("worldBox"); + + auto& batch = *args->_batch; + DependencyManager::get()->bindSimpleProgram(batch); + renderWorldBox(args, batch); + } + } +} + +void Application::runRenderFrame(RenderArgs* renderArgs) { + + // FIXME: This preDisplayRender call is temporary until we create a separate render::scene for the mirror rendering. + // Then we can move this logic into the Avatar::simulate call. + // auto myAvatar = getMyAvatar(); + // myAvatar->preDisplaySide(renderArgs); + + PROFILE_RANGE(render, __FUNCTION__); + PerformanceTimer perfTimer("display"); + PerformanceWarning warn(Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings), "Application::runRenderFrame()"); + + // load the view frustum + // { + // QMutexLocker viewLocker(&_viewMutex); + // theCamera.loadViewFrustum(_displayViewFrustum); + // } + + // The pending changes collecting the changes here + render::Transaction transaction; + + // Assuming nothing gets rendered through that + //if (!selfAvatarOnly) { + { + if (DependencyManager::get()->shouldRenderEntities()) { + // render models... + PerformanceTimer perfTimer("entities"); + PerformanceWarning warn(Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings), + "Application::runRenderFrame() ... entities..."); + + RenderArgs::DebugFlags renderDebugFlags = RenderArgs::RENDER_DEBUG_NONE; + + if (Menu::getInstance()->isOptionChecked(MenuOption::PhysicsShowHulls)) { + renderDebugFlags = static_cast(renderDebugFlags | + static_cast(RenderArgs::RENDER_DEBUG_HULLS)); + } + renderArgs->_debugFlags = renderDebugFlags; + } + } + + // FIXME: Move this out of here!, WorldBox should be driven by the entity content just like the other entities + // Make sure the WorldBox is in the scene + if (!render::Item::isValidID(WorldBoxRenderData::_item)) { + auto worldBoxRenderData = make_shared(); + auto worldBoxRenderPayload = make_shared(worldBoxRenderData); + + WorldBoxRenderData::_item = _main3DScene->allocateID(); + + transaction.resetItem(WorldBoxRenderData::_item, worldBoxRenderPayload); + _main3DScene->enqueueTransaction(transaction); + } + + + // For now every frame pass the renderContext + { + PerformanceTimer perfTimer("EngineRun"); + + /* { + QMutexLocker viewLocker(&_viewMutex); + renderArgs->setViewFrustum(_displayViewFrustum); + }*/ + // renderArgs->_cameraMode = (int8_t)theCamera.getMode(); // HACK + renderArgs->_scene = getMain3DScene(); + _renderEngine->getRenderContext()->args = renderArgs; + + // Before the deferred pass, let's try to use the render engine + _renderEngine->run(); + } +} From aa10c29609d90942915791e9bae1514d888fa7d1 Mon Sep 17 00:00:00 2001 From: samcake Date: Sun, 1 Oct 2017 17:16:10 -0700 Subject: [PATCH 30/59] Cleaning up the changed code --- interface/src/Application.cpp | 535 +++++---------------------- interface/src/Application_render.cpp | 150 +------- 2 files changed, 112 insertions(+), 573 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 5ce63441aa..3f87d72c88 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -188,7 +188,7 @@ #include "InterfaceParentFinder.h" #include "ui/OctreeStatsProvider.h" -#include "FrameTimingsScriptingInterface.h" +//#include "FrameTimingsScriptingInterface.h" #include #include #include @@ -2018,7 +2018,7 @@ void Application::cleanupBeforeQuit() { // The cleanup process enqueues the transactions but does not process them. Calling this here will force the actual // removal of the items. // See https://highfidelity.fogbugz.com/f/cases/5328 - _main3DScene->processTransactionQueue(); + // _main3DScene->processTransactionQueue(); // first stop all timers directly or by invokeMethod // depending on what thread they run in @@ -2216,7 +2216,7 @@ void Application::initializeGL() { update(0); } -FrameTimingsScriptingInterface _frameTimingsScriptingInterface; +//FrameTimingsScriptingInterface _frameTimingsScriptingInterface; extern void setupPreferences(); @@ -2272,7 +2272,7 @@ void Application::initializeUi() { surfaceContext->setContextProperty("Recording", DependencyManager::get().data()); surfaceContext->setContextProperty("Preferences", DependencyManager::get().data()); surfaceContext->setContextProperty("AddressManager", DependencyManager::get().data()); - surfaceContext->setContextProperty("FrameTimings", &_frameTimingsScriptingInterface); + //surfaceContext->setContextProperty("FrameTimings", &_frameTimingsScriptingInterface); // TODO: Remove this Context Property ? i don;t see anywhere surfaceContext->setContextProperty("Rates", new RatesScriptingInterface(this)); surfaceContext->setContextProperty("TREE_SCALE", TREE_SCALE); @@ -2378,354 +2378,105 @@ void Application::initializeUi() { } void Application::updateCamera(RenderArgs& renderArgs) { - + PROFILE_RANGE(render, "/updateCamera"); + PerformanceTimer perfTimer("CameraUpdates"); glm::vec3 boomOffset; - { - PROFILE_RANGE(render, "/updateCamera"); - { - PerformanceTimer perfTimer("CameraUpdates"); + auto myAvatar = getMyAvatar(); + boomOffset = myAvatar->getModelScale() * myAvatar->getBoomLength() * -IDENTITY_FORWARD; - auto myAvatar = getMyAvatar(); - boomOffset = myAvatar->getModelScale() * myAvatar->getBoomLength() * -IDENTITY_FORWARD; + // The render mode is default or mirror if the camera is in mirror mode, assigned further below + renderArgs._renderMode = RenderArgs::DEFAULT_RENDER_MODE; - // The render mode is default or mirror if the camera is in mirror mode, assigned further below - renderArgs._renderMode = RenderArgs::DEFAULT_RENDER_MODE; - - // Always use the default eye position, not the actual head eye position. - // Using the latter will cause the camera to wobble with idle animations, - // or with changes from the face tracker - if (_myCamera.getMode() == CAMERA_MODE_FIRST_PERSON) { - if (isHMDMode()) { - mat4 camMat = myAvatar->getSensorToWorldMatrix() * myAvatar->getHMDSensorMatrix(); - _myCamera.setPosition(extractTranslation(camMat)); - _myCamera.setOrientation(glmExtractRotation(camMat)); - } - else { - _myCamera.setPosition(myAvatar->getDefaultEyePosition()); - _myCamera.setOrientation(myAvatar->getMyHead()->getHeadOrientation()); - } + // Always use the default eye position, not the actual head eye position. + // Using the latter will cause the camera to wobble with idle animations, + // or with changes from the face tracker + if (_myCamera.getMode() == CAMERA_MODE_FIRST_PERSON) { + if (isHMDMode()) { + mat4 camMat = myAvatar->getSensorToWorldMatrix() * myAvatar->getHMDSensorMatrix(); + _myCamera.setPosition(extractTranslation(camMat)); + _myCamera.setOrientation(glmExtractRotation(camMat)); + } + else { + _myCamera.setPosition(myAvatar->getDefaultEyePosition()); + _myCamera.setOrientation(myAvatar->getMyHead()->getHeadOrientation()); + } + } + else if (_myCamera.getMode() == CAMERA_MODE_THIRD_PERSON) { + if (isHMDMode()) { + auto hmdWorldMat = myAvatar->getSensorToWorldMatrix() * myAvatar->getHMDSensorMatrix(); + _myCamera.setOrientation(glm::normalize(glmExtractRotation(hmdWorldMat))); + _myCamera.setPosition(extractTranslation(hmdWorldMat) + + myAvatar->getOrientation() * boomOffset); + } + else { + _myCamera.setOrientation(myAvatar->getHead()->getOrientation()); + if (Menu::getInstance()->isOptionChecked(MenuOption::CenterPlayerInView)) { + _myCamera.setPosition(myAvatar->getDefaultEyePosition() + + _myCamera.getOrientation() * boomOffset); } - else if (_myCamera.getMode() == CAMERA_MODE_THIRD_PERSON) { - if (isHMDMode()) { - auto hmdWorldMat = myAvatar->getSensorToWorldMatrix() * myAvatar->getHMDSensorMatrix(); - _myCamera.setOrientation(glm::normalize(glmExtractRotation(hmdWorldMat))); - _myCamera.setPosition(extractTranslation(hmdWorldMat) + - myAvatar->getOrientation() * boomOffset); - } - else { - _myCamera.setOrientation(myAvatar->getHead()->getOrientation()); - if (Menu::getInstance()->isOptionChecked(MenuOption::CenterPlayerInView)) { - _myCamera.setPosition(myAvatar->getDefaultEyePosition() - + _myCamera.getOrientation() * boomOffset); - } - else { - _myCamera.setPosition(myAvatar->getDefaultEyePosition() - + myAvatar->getOrientation() * boomOffset); - } - } - } - else if (_myCamera.getMode() == CAMERA_MODE_MIRROR) { - if (isHMDMode()) { - auto mirrorBodyOrientation = myAvatar->getOrientation() * glm::quat(glm::vec3(0.0f, PI + _rotateMirror, 0.0f)); - - glm::quat hmdRotation = extractRotation(myAvatar->getHMDSensorMatrix()); - // Mirror HMD yaw and roll - glm::vec3 mirrorHmdEulers = glm::eulerAngles(hmdRotation); - mirrorHmdEulers.y = -mirrorHmdEulers.y; - mirrorHmdEulers.z = -mirrorHmdEulers.z; - glm::quat mirrorHmdRotation = glm::quat(mirrorHmdEulers); - - glm::quat worldMirrorRotation = mirrorBodyOrientation * mirrorHmdRotation; - - _myCamera.setOrientation(worldMirrorRotation); - - glm::vec3 hmdOffset = extractTranslation(myAvatar->getHMDSensorMatrix()); - // Mirror HMD lateral offsets - hmdOffset.x = -hmdOffset.x; - - _myCamera.setPosition(myAvatar->getDefaultEyePosition() - + glm::vec3(0, _raiseMirror * myAvatar->getModelScale(), 0) - + mirrorBodyOrientation * glm::vec3(0.0f, 0.0f, 1.0f) * MIRROR_FULLSCREEN_DISTANCE * _scaleMirror - + mirrorBodyOrientation * hmdOffset); - } - else { - _myCamera.setOrientation(myAvatar->getOrientation() - * glm::quat(glm::vec3(0.0f, PI + _rotateMirror, 0.0f))); - _myCamera.setPosition(myAvatar->getDefaultEyePosition() - + glm::vec3(0, _raiseMirror * myAvatar->getModelScale(), 0) - + (myAvatar->getOrientation() * glm::quat(glm::vec3(0.0f, _rotateMirror, 0.0f))) * - glm::vec3(0.0f, 0.0f, -1.0f) * MIRROR_FULLSCREEN_DISTANCE * _scaleMirror); - } - renderArgs._renderMode = RenderArgs::MIRROR_RENDER_MODE; - } - else if (_myCamera.getMode() == CAMERA_MODE_ENTITY) { - EntityItemPointer cameraEntity = _myCamera.getCameraEntityPointer(); - if (cameraEntity != nullptr) { - if (isHMDMode()) { - glm::quat hmdRotation = extractRotation(myAvatar->getHMDSensorMatrix()); - _myCamera.setOrientation(cameraEntity->getRotation() * hmdRotation); - glm::vec3 hmdOffset = extractTranslation(myAvatar->getHMDSensorMatrix()); - _myCamera.setPosition(cameraEntity->getPosition() + (hmdRotation * hmdOffset)); - } - else { - _myCamera.setOrientation(cameraEntity->getRotation()); - _myCamera.setPosition(cameraEntity->getPosition()); - } - } - } - // Update camera position - if (!isHMDMode()) { - _myCamera.update(1.0f / _frameCounter.rate()); + else { + _myCamera.setPosition(myAvatar->getDefaultEyePosition() + + myAvatar->getOrientation() * boomOffset); } } } + else if (_myCamera.getMode() == CAMERA_MODE_MIRROR) { + if (isHMDMode()) { + auto mirrorBodyOrientation = myAvatar->getOrientation() * glm::quat(glm::vec3(0.0f, PI + _rotateMirror, 0.0f)); + + glm::quat hmdRotation = extractRotation(myAvatar->getHMDSensorMatrix()); + // Mirror HMD yaw and roll + glm::vec3 mirrorHmdEulers = glm::eulerAngles(hmdRotation); + mirrorHmdEulers.y = -mirrorHmdEulers.y; + mirrorHmdEulers.z = -mirrorHmdEulers.z; + glm::quat mirrorHmdRotation = glm::quat(mirrorHmdEulers); + + glm::quat worldMirrorRotation = mirrorBodyOrientation * mirrorHmdRotation; + + _myCamera.setOrientation(worldMirrorRotation); + + glm::vec3 hmdOffset = extractTranslation(myAvatar->getHMDSensorMatrix()); + // Mirror HMD lateral offsets + hmdOffset.x = -hmdOffset.x; + + _myCamera.setPosition(myAvatar->getDefaultEyePosition() + + glm::vec3(0, _raiseMirror * myAvatar->getModelScale(), 0) + + mirrorBodyOrientation * glm::vec3(0.0f, 0.0f, 1.0f) * MIRROR_FULLSCREEN_DISTANCE * _scaleMirror + + mirrorBodyOrientation * hmdOffset); + } + else { + _myCamera.setOrientation(myAvatar->getOrientation() + * glm::quat(glm::vec3(0.0f, PI + _rotateMirror, 0.0f))); + _myCamera.setPosition(myAvatar->getDefaultEyePosition() + + glm::vec3(0, _raiseMirror * myAvatar->getModelScale(), 0) + + (myAvatar->getOrientation() * glm::quat(glm::vec3(0.0f, _rotateMirror, 0.0f))) * + glm::vec3(0.0f, 0.0f, -1.0f) * MIRROR_FULLSCREEN_DISTANCE * _scaleMirror); + } + renderArgs._renderMode = RenderArgs::MIRROR_RENDER_MODE; + } + else if (_myCamera.getMode() == CAMERA_MODE_ENTITY) { + EntityItemPointer cameraEntity = _myCamera.getCameraEntityPointer(); + if (cameraEntity != nullptr) { + if (isHMDMode()) { + glm::quat hmdRotation = extractRotation(myAvatar->getHMDSensorMatrix()); + _myCamera.setOrientation(cameraEntity->getRotation() * hmdRotation); + glm::vec3 hmdOffset = extractTranslation(myAvatar->getHMDSensorMatrix()); + _myCamera.setPosition(cameraEntity->getPosition() + (hmdRotation * hmdOffset)); + } + else { + _myCamera.setOrientation(cameraEntity->getRotation()); + _myCamera.setPosition(cameraEntity->getPosition()); + } + } + } + // Update camera position + if (!isHMDMode()) { + _myCamera.update(1.0f / _frameCounter.rate()); + } renderArgs._cameraMode = (int8_t)_myCamera.getMode(); } -// -//void Application::editRenderArgs(RenderArgsEditor editor) { -// QMutexLocker renderLocker(&_renderArgsMutex); -// editor(_appRenderArgs); -// -//} -// -//void Application::paintGL() { -// // Some plugins process message events, allowing paintGL to be called reentrantly. -// if (_aboutToQuit || _window->isMinimized()) { -// return; -// } -// -// _frameCount++; -// _lastTimeRendered.start(); -// -// auto lastPaintBegin = usecTimestampNow(); -// PROFILE_RANGE_EX(render, __FUNCTION__, 0xff0000ff, (uint64_t)_frameCount); -// PerformanceTimer perfTimer("paintGL"); -// -// if (nullptr == _displayPlugin) { -// return; -// } -// -// DisplayPluginPointer displayPlugin; -// { -// PROFILE_RANGE(render, "/getActiveDisplayPlugin"); -// displayPlugin = getActiveDisplayPlugin(); -// } -// -// { -// PROFILE_RANGE(render, "/pluginBeginFrameRender"); -// // If a display plugin loses it's underlying support, it -// // needs to be able to signal us to not use it -// if (!displayPlugin->beginFrameRender(_frameCount)) { -// updateDisplayMode(); -// return; -// } -// } -// -// // update the avatar with a fresh HMD pose -// // { -// // PROFILE_RANGE(render, "/updateAvatar"); -// // getMyAvatar()->updateFromHMDSensorMatrix(getHMDSensorPose()); -// // } -// -// // auto lodManager = DependencyManager::get(); -// -// RenderArgs renderArgs; -// float sensorToWorldScale; -// glm::mat4 HMDSensorPose; -// glm::mat4 eyeToWorld; -// glm::mat4 sensorToWorld; -// -// bool isStereo; -// glm::mat4 stereoEyeOffsets[2]; -// glm::mat4 stereoEyeProjections[2]; -// -// { -// QMutexLocker viewLocker(&_renderArgsMutex); -// renderArgs = _appRenderArgs._renderArgs; -// HMDSensorPose = _appRenderArgs._headPose; -// eyeToWorld = _appRenderArgs._eyeToWorld; -// sensorToWorld = _appRenderArgs._sensorToWorld; -// sensorToWorldScale = _appRenderArgs._sensorToWorldScale; -// isStereo = _appRenderArgs._isStereo; -// for_each_eye([&](Eye eye) { -// stereoEyeOffsets[eye] = _appRenderArgs._eyeOffsets[eye]; -// stereoEyeProjections[eye] = _appRenderArgs._eyeProjections[eye]; -// }); -// } -// -// //float sensorToWorldScale = getMyAvatar()->getSensorToWorldScale(); -// //{ -// // PROFILE_RANGE(render, "/buildFrustrumAndArgs"); -// // { -// // QMutexLocker viewLocker(&_viewMutex); -// // // adjust near clip plane to account for sensor scaling. -// // auto adjustedProjection = glm::perspective(_viewFrustum.getFieldOfView(), -// // _viewFrustum.getAspectRatio(), -// // DEFAULT_NEAR_CLIP * sensorToWorldScale, -// // _viewFrustum.getFarClip()); -// // _viewFrustum.setProjection(adjustedProjection); -// // _viewFrustum.calculate(); -// // } -// // renderArgs = RenderArgs(_gpuContext, lodManager->getOctreeSizeScale(), -// // lodManager->getBoundaryLevelAdjust(), RenderArgs::DEFAULT_RENDER_MODE, -// // RenderArgs::MONO, RenderArgs::RENDER_DEBUG_NONE); -// // { -// // QMutexLocker viewLocker(&_viewMutex); -// // renderArgs.setViewFrustum(_viewFrustum); -// // } -// //} -// -// //{ -// // PROFILE_RANGE(render, "/resizeGL"); -// // PerformanceWarning::setSuppressShortTimings(Menu::getInstance()->isOptionChecked(MenuOption::SuppressShortTimings)); -// // bool showWarnings = Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings); -// // PerformanceWarning warn(showWarnings, "Application::paintGL()"); -// // resizeGL(); -// //} -// -// { -// PROFILE_RANGE(render, "/gpuContextReset"); -// // _gpuContext->beginFrame(getHMDSensorPose()); -// _gpuContext->beginFrame(HMDSensorPose); -// // Reset the gpu::Context Stages -// // Back to the default framebuffer; -// gpu::doInBatch(_gpuContext, [&](gpu::Batch& batch) { -// batch.resetStages(); -// }); -// } -// -// -// { -// PROFILE_RANGE(render, "/renderOverlay"); -// PerformanceTimer perfTimer("renderOverlay"); -// // NOTE: There is no batch associated with this renderArgs -// // the ApplicationOverlay class assumes it's viewport is setup to be the device size -// QSize size = getDeviceSize(); -// renderArgs._viewport = glm::ivec4(0, 0, size.width(), size.height()); -// _applicationOverlay.renderOverlay(&renderArgs); -// } -// -// // updateCamera(renderArgs); -// { -// PROFILE_RANGE(render, "/updateCompositor"); -// // getApplicationCompositor().setFrameInfo(_frameCount, _myCamera.getTransform(), getMyAvatar()->getSensorToWorldMatrix()); -// getApplicationCompositor().setFrameInfo(_frameCount, eyeToWorld, sensorToWorld); -// } -// -// gpu::FramebufferPointer finalFramebuffer; -// QSize finalFramebufferSize; -// { -// PROFILE_RANGE(render, "/getOutputFramebuffer"); -// // Primary rendering pass -// auto framebufferCache = DependencyManager::get(); -// finalFramebufferSize = framebufferCache->getFrameBufferSize(); -// // Final framebuffer that will be handled to the display-plugin -// finalFramebuffer = framebufferCache->getFramebuffer(); -// } -// -// //auto hmdInterface = DependencyManager::get(); -// //float ipdScale = hmdInterface->getIPDScale(); -// -// //// scale IPD by sensorToWorldScale, to make the world seem larger or smaller accordingly. -// //ipdScale *= sensorToWorldScale; -// -// { -// //PROFILE_RANGE(render, "/mainRender"); -// //PerformanceTimer perfTimer("mainRender"); -// //// FIXME is this ever going to be different from the size previously set in the render args -// //// in the overlay render? -// //// Viewport is assigned to the size of the framebuffer -// //renderArgs._viewport = ivec4(0, 0, finalFramebufferSize.width(), finalFramebufferSize.height()); -// //auto baseProjection = renderArgs.getViewFrustum().getProjection(); -// //if (displayPlugin->isStereo()) { -// // // Stereo modes will typically have a larger projection matrix overall, -// // // so we ask for the 'mono' projection matrix, which for stereo and HMD -// // // plugins will imply the combined projection for both eyes. -// // // -// // // This is properly implemented for the Oculus plugins, but for OpenVR -// // // and Stereo displays I'm not sure how to get / calculate it, so we're -// // // just relying on the left FOV in each case and hoping that the -// // // overall culling margin of error doesn't cause popping in the -// // // right eye. There are FIXMEs in the relevant plugins -// // _myCamera.setProjection(displayPlugin->getCullingProjection(baseProjection)); -// // renderArgs._context->enableStereo(true); -// // mat4 eyeOffsets[2]; -// // mat4 eyeProjections[2]; -// -// // // FIXME we probably don't need to set the projection matrix every frame, -// // // only when the display plugin changes (or in non-HMD modes when the user -// // // changes the FOV manually, which right now I don't think they can. -// // for_each_eye([&](Eye eye) { -// // // For providing the stereo eye views, the HMD head pose has already been -// // // applied to the avatar, so we need to get the difference between the head -// // // pose applied to the avatar and the per eye pose, and use THAT as -// // // the per-eye stereo matrix adjustment. -// // mat4 eyeToHead = displayPlugin->getEyeToHeadTransform(eye); -// // // Grab the translation -// // vec3 eyeOffset = glm::vec3(eyeToHead[3]); -// // // Apply IPD scaling -// // mat4 eyeOffsetTransform = glm::translate(mat4(), eyeOffset * -1.0f * ipdScale); -// // eyeOffsets[eye] = eyeOffsetTransform; -// // eyeProjections[eye] = displayPlugin->getEyeProjection(eye, baseProjection); -// // }); -// // renderArgs._context->setStereoProjections(eyeProjections); -// // renderArgs._context->setStereoViews(eyeOffsets); -// -// // // Configure the type of display / stereo -// // renderArgs._displayMode = (isHMDMode() ? RenderArgs::STEREO_HMD : RenderArgs::STEREO_MONITOR); -// //} -// -// if (isStereo) { -// renderArgs._context->enableStereo(true); -// renderArgs._context->setStereoProjections(stereoEyeProjections); -// renderArgs._context->setStereoViews(stereoEyeOffsets); -// // renderArgs._displayMode -// } -// -// renderArgs._blitFramebuffer = finalFramebuffer; -// // displaySide(&renderArgs, _myCamera); -// runRenderFrame(&renderArgs); -// } -// -// gpu::Batch postCompositeBatch; -// { -// PROFILE_RANGE(render, "/postComposite"); -// PerformanceTimer perfTimer("postComposite"); -// renderArgs._batch = &postCompositeBatch; -// renderArgs._batch->setViewportTransform(ivec4(0, 0, finalFramebufferSize.width(), finalFramebufferSize.height())); -// renderArgs._batch->setViewTransform(renderArgs.getViewFrustum().getView()); -// _overlays.render3DHUDOverlays(&renderArgs); -// } -// -// auto frame = _gpuContext->endFrame(); -// frame->frameIndex = _frameCount; -// frame->framebuffer = finalFramebuffer; -// frame->framebufferRecycler = [](const gpu::FramebufferPointer& framebuffer){ -// DependencyManager::get()->releaseFramebuffer(framebuffer); -// }; -// frame->overlay = _applicationOverlay.getOverlayTexture(); -// frame->postCompositeBatch = postCompositeBatch; -// // deliver final scene rendering commands to the display plugin -// { -// PROFILE_RANGE(render, "/pluginOutput"); -// PerformanceTimer perfTimer("pluginOutput"); -// _frameCounter.increment(); -// displayPlugin->submitFrame(frame); -// } -// -// // Reset the framebuffer and stereo state -// renderArgs._blitFramebuffer.reset(); -// renderArgs._context->enableStereo(false); -// -// { -// Stats::getInstance()->setRenderDetails(renderArgs._details); -// } -// -// uint64_t lastPaintDuration = usecTimestampNow() - lastPaintBegin; -// _frameTimingsScriptingInterface.addValue(lastPaintDuration); -//} void Application::runTests() { runTimingTests(); @@ -5286,11 +5037,12 @@ void Application::update(float deltaTime) { editRenderArgs([this](AppRenderArgs& appRenderArgs) { + appRenderArgs._renderArgs._scene = getMain3DScene(); + appRenderArgs._headPose= getHMDSensorPose(); auto myAvatar = getMyAvatar(); - // update the avatar with a fresh HMD pose { PROFILE_RANGE(render, "/updateAvatar"); @@ -5372,8 +5124,6 @@ void Application::update(float deltaTime) { eyeOffsets[eye] = eyeOffsetTransform; eyeProjections[eye] = getActiveDisplayPlugin()->getEyeProjection(eye, baseProjection); }); - //renderArgs._context->setStereoProjections(eyeProjections); - //renderArgs._context->setStereoViews(eyeOffsets); // Configure the type of display / stereo appRenderArgs._renderArgs._displayMode = (isHMDMode() ? RenderArgs::STEREO_HMD : RenderArgs::STEREO_MONITOR); @@ -5461,7 +5211,6 @@ int Application::sendNackPackets() { } }); - return packetsSent; } @@ -5692,102 +5441,6 @@ void Application::copyDisplayViewFrustum(ViewFrustum& viewOut) const { viewOut = _displayViewFrustum; } -//// WorldBox Render Data & rendering functions -// -//class WorldBoxRenderData { -//public: -// typedef render::Payload Payload; -// typedef Payload::DataPointer Pointer; -// -// int _val = 0; -// static render::ItemID _item; // unique WorldBoxRenderData -//}; -// -//render::ItemID WorldBoxRenderData::_item { render::Item::INVALID_ITEM_ID }; -// -//namespace render { -// template <> const ItemKey payloadGetKey(const WorldBoxRenderData::Pointer& stuff) { return ItemKey::Builder::opaqueShape(); } -// template <> const Item::Bound payloadGetBound(const WorldBoxRenderData::Pointer& stuff) { return Item::Bound(); } -// template <> void payloadRender(const WorldBoxRenderData::Pointer& stuff, RenderArgs* args) { -// if (Menu::getInstance()->isOptionChecked(MenuOption::WorldAxes)) { -// PerformanceTimer perfTimer("worldBox"); -// -// auto& batch = *args->_batch; -// DependencyManager::get()->bindSimpleProgram(batch); -// renderWorldBox(args, batch); -// } -// } -//} -// -//void Application::runRenderFrame(RenderArgs* renderArgs) { -// -// // FIXME: This preDisplayRender call is temporary until we create a separate render::scene for the mirror rendering. -// // Then we can move this logic into the Avatar::simulate call. -// // auto myAvatar = getMyAvatar(); -// // myAvatar->preDisplaySide(renderArgs); -// -// PROFILE_RANGE(render, __FUNCTION__); -// PerformanceTimer perfTimer("display"); -// PerformanceWarning warn(Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings), "Application::runRenderFrame()"); -// -// // load the view frustum -// // { -// // QMutexLocker viewLocker(&_viewMutex); -// // theCamera.loadViewFrustum(_displayViewFrustum); -// // } -// -// // The pending changes collecting the changes here -// render::Transaction transaction; -// -// // Assuming nothing gets rendered through that -// //if (!selfAvatarOnly) { -// { -// if (DependencyManager::get()->shouldRenderEntities()) { -// // render models... -// PerformanceTimer perfTimer("entities"); -// PerformanceWarning warn(Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings), -// "Application::runRenderFrame() ... entities..."); -// -// RenderArgs::DebugFlags renderDebugFlags = RenderArgs::RENDER_DEBUG_NONE; -// -// if (Menu::getInstance()->isOptionChecked(MenuOption::PhysicsShowHulls)) { -// renderDebugFlags = static_cast(renderDebugFlags | -// static_cast(RenderArgs::RENDER_DEBUG_HULLS)); -// } -// renderArgs->_debugFlags = renderDebugFlags; -// } -// } -// -// // FIXME: Move this out of here!, WorldBox should be driven by the entity content just like the other entities -// // Make sure the WorldBox is in the scene -// if (!render::Item::isValidID(WorldBoxRenderData::_item)) { -// auto worldBoxRenderData = make_shared(); -// auto worldBoxRenderPayload = make_shared(worldBoxRenderData); -// -// WorldBoxRenderData::_item = _main3DScene->allocateID(); -// -// transaction.resetItem(WorldBoxRenderData::_item, worldBoxRenderPayload); -// _main3DScene->enqueueTransaction(transaction); -// } -// -// -// // For now every frame pass the renderContext -// { -// PerformanceTimer perfTimer("EngineRun"); -// -// /* { -// QMutexLocker viewLocker(&_viewMutex); -// renderArgs->setViewFrustum(_displayViewFrustum); -// }*/ -// // renderArgs->_cameraMode = (int8_t)theCamera.getMode(); // HACK -// renderArgs->_scene = getMain3DScene(); -// _renderEngine->getRenderContext()->args = renderArgs; -// -// // Before the deferred pass, let's try to use the render engine -// _renderEngine->run(); -// } -//} - void Application::resetSensors(bool andReload) { DependencyManager::get()->reset(); DependencyManager::get()->reset(); diff --git a/interface/src/Application_render.cpp b/interface/src/Application_render.cpp index 51d55a2bd8..43e1d7a9e1 100644 --- a/interface/src/Application_render.cpp +++ b/interface/src/Application_render.cpp @@ -15,6 +15,10 @@ #include #include "ui/Stats.h" #include "FrameTimingsScriptingInterface.h" +#include +#include "Util.h" + +FrameTimingsScriptingInterface _frameTimingsScriptingInterface; // Statically provided display and input plugins extern DisplayPluginList getDisplayPlugins(); @@ -58,14 +62,6 @@ void Application::paintGL() { } } - // update the avatar with a fresh HMD pose - // { - // PROFILE_RANGE(render, "/updateAvatar"); - // getMyAvatar()->updateFromHMDSensorMatrix(getHMDSensorPose()); - // } - - // auto lodManager = DependencyManager::get(); - RenderArgs renderArgs; float sensorToWorldScale; glm::mat4 HMDSensorPose; @@ -90,39 +86,8 @@ void Application::paintGL() { }); } - //float sensorToWorldScale = getMyAvatar()->getSensorToWorldScale(); - //{ - // PROFILE_RANGE(render, "/buildFrustrumAndArgs"); - // { - // QMutexLocker viewLocker(&_viewMutex); - // // adjust near clip plane to account for sensor scaling. - // auto adjustedProjection = glm::perspective(_viewFrustum.getFieldOfView(), - // _viewFrustum.getAspectRatio(), - // DEFAULT_NEAR_CLIP * sensorToWorldScale, - // _viewFrustum.getFarClip()); - // _viewFrustum.setProjection(adjustedProjection); - // _viewFrustum.calculate(); - // } - // renderArgs = RenderArgs(_gpuContext, lodManager->getOctreeSizeScale(), - // lodManager->getBoundaryLevelAdjust(), RenderArgs::DEFAULT_RENDER_MODE, - // RenderArgs::MONO, RenderArgs::RENDER_DEBUG_NONE); - // { - // QMutexLocker viewLocker(&_viewMutex); - // renderArgs.setViewFrustum(_viewFrustum); - // } - //} - - //{ - // PROFILE_RANGE(render, "/resizeGL"); - // PerformanceWarning::setSuppressShortTimings(Menu::getInstance()->isOptionChecked(MenuOption::SuppressShortTimings)); - // bool showWarnings = Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings); - // PerformanceWarning warn(showWarnings, "Application::paintGL()"); - // resizeGL(); - //} - { PROFILE_RANGE(render, "/gpuContextReset"); - // _gpuContext->beginFrame(getHMDSensorPose()); _gpuContext->beginFrame(HMDSensorPose); // Reset the gpu::Context Stages // Back to the default framebuffer; @@ -160,67 +125,14 @@ void Application::paintGL() { finalFramebuffer = framebufferCache->getFramebuffer(); } - //auto hmdInterface = DependencyManager::get(); - //float ipdScale = hmdInterface->getIPDScale(); - - //// scale IPD by sensorToWorldScale, to make the world seem larger or smaller accordingly. - //ipdScale *= sensorToWorldScale; - { - //PROFILE_RANGE(render, "/mainRender"); - //PerformanceTimer perfTimer("mainRender"); - //// FIXME is this ever going to be different from the size previously set in the render args - //// in the overlay render? - //// Viewport is assigned to the size of the framebuffer - //renderArgs._viewport = ivec4(0, 0, finalFramebufferSize.width(), finalFramebufferSize.height()); - //auto baseProjection = renderArgs.getViewFrustum().getProjection(); - //if (displayPlugin->isStereo()) { - // // Stereo modes will typically have a larger projection matrix overall, - // // so we ask for the 'mono' projection matrix, which for stereo and HMD - // // plugins will imply the combined projection for both eyes. - // // - // // This is properly implemented for the Oculus plugins, but for OpenVR - // // and Stereo displays I'm not sure how to get / calculate it, so we're - // // just relying on the left FOV in each case and hoping that the - // // overall culling margin of error doesn't cause popping in the - // // right eye. There are FIXMEs in the relevant plugins - // _myCamera.setProjection(displayPlugin->getCullingProjection(baseProjection)); - // renderArgs._context->enableStereo(true); - // mat4 eyeOffsets[2]; - // mat4 eyeProjections[2]; - - // // FIXME we probably don't need to set the projection matrix every frame, - // // only when the display plugin changes (or in non-HMD modes when the user - // // changes the FOV manually, which right now I don't think they can. - // for_each_eye([&](Eye eye) { - // // For providing the stereo eye views, the HMD head pose has already been - // // applied to the avatar, so we need to get the difference between the head - // // pose applied to the avatar and the per eye pose, and use THAT as - // // the per-eye stereo matrix adjustment. - // mat4 eyeToHead = displayPlugin->getEyeToHeadTransform(eye); - // // Grab the translation - // vec3 eyeOffset = glm::vec3(eyeToHead[3]); - // // Apply IPD scaling - // mat4 eyeOffsetTransform = glm::translate(mat4(), eyeOffset * -1.0f * ipdScale); - // eyeOffsets[eye] = eyeOffsetTransform; - // eyeProjections[eye] = displayPlugin->getEyeProjection(eye, baseProjection); - // }); - // renderArgs._context->setStereoProjections(eyeProjections); - // renderArgs._context->setStereoViews(eyeOffsets); - - // // Configure the type of display / stereo - // renderArgs._displayMode = (isHMDMode() ? RenderArgs::STEREO_HMD : RenderArgs::STEREO_MONITOR); - //} - if (isStereo) { renderArgs._context->enableStereo(true); renderArgs._context->setStereoProjections(stereoEyeProjections); renderArgs._context->setStereoViews(stereoEyeOffsets); - // renderArgs._displayMode } renderArgs._blitFramebuffer = finalFramebuffer; - // displaySide(&renderArgs, _myCamera); runRenderFrame(&renderArgs); } @@ -291,49 +203,34 @@ namespace render { } void Application::runRenderFrame(RenderArgs* renderArgs) { - - // FIXME: This preDisplayRender call is temporary until we create a separate render::scene for the mirror rendering. - // Then we can move this logic into the Avatar::simulate call. - // auto myAvatar = getMyAvatar(); - // myAvatar->preDisplaySide(renderArgs); - PROFILE_RANGE(render, __FUNCTION__); PerformanceTimer perfTimer("display"); PerformanceWarning warn(Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings), "Application::runRenderFrame()"); - // load the view frustum - // { - // QMutexLocker viewLocker(&_viewMutex); - // theCamera.loadViewFrustum(_displayViewFrustum); - // } - // The pending changes collecting the changes here render::Transaction transaction; - // Assuming nothing gets rendered through that - //if (!selfAvatarOnly) { - { - if (DependencyManager::get()->shouldRenderEntities()) { - // render models... - PerformanceTimer perfTimer("entities"); - PerformanceWarning warn(Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings), - "Application::runRenderFrame() ... entities..."); + if (DependencyManager::get()->shouldRenderEntities()) { + // render models... + PerformanceTimer perfTimer("entities"); + PerformanceWarning warn(Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings), + "Application::runRenderFrame() ... entities..."); - RenderArgs::DebugFlags renderDebugFlags = RenderArgs::RENDER_DEBUG_NONE; + RenderArgs::DebugFlags renderDebugFlags = RenderArgs::RENDER_DEBUG_NONE; - if (Menu::getInstance()->isOptionChecked(MenuOption::PhysicsShowHulls)) { - renderDebugFlags = static_cast(renderDebugFlags | - static_cast(RenderArgs::RENDER_DEBUG_HULLS)); - } - renderArgs->_debugFlags = renderDebugFlags; + if (Menu::getInstance()->isOptionChecked(MenuOption::PhysicsShowHulls)) { + renderDebugFlags = static_cast(renderDebugFlags | + static_cast(RenderArgs::RENDER_DEBUG_HULLS)); } + renderArgs->_debugFlags = renderDebugFlags; } - // FIXME: Move this out of here!, WorldBox should be driven by the entity content just like the other entities // Make sure the WorldBox is in the scene + // For the record, this one RenderItem is the first one we created and added to the scene. + // We could meoee that code elsewhere but you know... if (!render::Item::isValidID(WorldBoxRenderData::_item)) { - auto worldBoxRenderData = make_shared(); - auto worldBoxRenderPayload = make_shared(worldBoxRenderData); + auto worldBoxRenderData = std::make_shared(); + auto worldBoxRenderPayload = std::make_shared(worldBoxRenderData); WorldBoxRenderData::_item = _main3DScene->allocateID(); @@ -341,20 +238,9 @@ void Application::runRenderFrame(RenderArgs* renderArgs) { _main3DScene->enqueueTransaction(transaction); } - - // For now every frame pass the renderContext { PerformanceTimer perfTimer("EngineRun"); - - /* { - QMutexLocker viewLocker(&_viewMutex); - renderArgs->setViewFrustum(_displayViewFrustum); - }*/ - // renderArgs->_cameraMode = (int8_t)theCamera.getMode(); // HACK - renderArgs->_scene = getMain3DScene(); _renderEngine->getRenderContext()->args = renderArgs; - - // Before the deferred pass, let's try to use the render engine _renderEngine->run(); } } From 0cbf19bcf141765c153befda56705359272b7c58 Mon Sep 17 00:00:00 2001 From: samcake Date: Sun, 1 Oct 2017 17:47:35 -0700 Subject: [PATCH 31/59] Removing comments --- interface/src/Application.cpp | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 3f87d72c88..efa18f36df 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -429,7 +429,7 @@ public: // Don't actually crash in debug builds, in case this apparent deadlock is simply from // the developer actively debugging code #ifdef NDEBUG - // deadlockDetectionCrash(); + deadlockDetectionCrash(); #endif } } @@ -5036,9 +5036,6 @@ void Application::update(float deltaTime) { } editRenderArgs([this](AppRenderArgs& appRenderArgs) { - - appRenderArgs._renderArgs._scene = getMain3DScene(); - appRenderArgs._headPose= getHMDSensorPose(); auto myAvatar = getMyAvatar(); @@ -5068,6 +5065,8 @@ void Application::update(float deltaTime) { appRenderArgs._renderArgs = RenderArgs(_gpuContext, lodManager->getOctreeSizeScale(), lodManager->getBoundaryLevelAdjust(), RenderArgs::DEFAULT_RENDER_MODE, RenderArgs::MONO, RenderArgs::RENDER_DEBUG_NONE); + appRenderArgs._renderArgs._scene = getMain3DScene(); + { QMutexLocker viewLocker(&_viewMutex); appRenderArgs._renderArgs.setViewFrustum(_viewFrustum); From 6c510bc18f297842fac4c4c3e77dc20041a3b65c Mon Sep 17 00:00:00 2001 From: Sam Gateau Date: Sun, 1 Oct 2017 20:05:48 -0700 Subject: [PATCH 32/59] fine tuning the changes to respect clean up --- interface/src/Application.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index efa18f36df..35fc0049a8 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -2018,7 +2018,8 @@ void Application::cleanupBeforeQuit() { // The cleanup process enqueues the transactions but does not process them. Calling this here will force the actual // removal of the items. // See https://highfidelity.fogbugz.com/f/cases/5328 - // _main3DScene->processTransactionQueue(); + _main3DScene->enqueueFrame(); // flush all the transactions + _main3DScene->processTransactionQueue(); // process and apply deletions // first stop all timers directly or by invokeMethod // depending on what thread they run in From ec10d38983f813e37ff123486602f0ea14fa2add Mon Sep 17 00:00:00 2001 From: Sam Gateau Date: Sun, 1 Oct 2017 22:28:04 -0700 Subject: [PATCH 33/59] more cleaning --- interface/src/Application_render.cpp | 3 --- 1 file changed, 3 deletions(-) diff --git a/interface/src/Application_render.cpp b/interface/src/Application_render.cpp index 43e1d7a9e1..1c82c95a8a 100644 --- a/interface/src/Application_render.cpp +++ b/interface/src/Application_render.cpp @@ -63,7 +63,6 @@ void Application::paintGL() { } RenderArgs renderArgs; - float sensorToWorldScale; glm::mat4 HMDSensorPose; glm::mat4 eyeToWorld; glm::mat4 sensorToWorld; @@ -78,7 +77,6 @@ void Application::paintGL() { HMDSensorPose = _appRenderArgs._headPose; eyeToWorld = _appRenderArgs._eyeToWorld; sensorToWorld = _appRenderArgs._sensorToWorld; - sensorToWorldScale = _appRenderArgs._sensorToWorldScale; isStereo = _appRenderArgs._isStereo; for_each_eye([&](Eye eye) { stereoEyeOffsets[eye] = _appRenderArgs._eyeOffsets[eye]; @@ -110,7 +108,6 @@ void Application::paintGL() { // updateCamera(renderArgs); { PROFILE_RANGE(render, "/updateCompositor"); - // getApplicationCompositor().setFrameInfo(_frameCount, _myCamera.getTransform(), getMyAvatar()->getSensorToWorldMatrix()); getApplicationCompositor().setFrameInfo(_frameCount, eyeToWorld, sensorToWorld); } From f150d77d318517975fa32996cb162eca8f9158e5 Mon Sep 17 00:00:00 2001 From: Liv Date: Mon, 2 Oct 2017 11:08:07 -0700 Subject: [PATCH 34/59] Updating placeholder.js to use a url that points to example scripts --- domain-server/resources/web/assignment/placeholder.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/domain-server/resources/web/assignment/placeholder.js b/domain-server/resources/web/assignment/placeholder.js index 2c1d8253aa..bf64539bea 100644 --- a/domain-server/resources/web/assignment/placeholder.js +++ b/domain-server/resources/web/assignment/placeholder.js @@ -1,3 +1,3 @@ // Here you can put a script that will be run by an assignment-client (AC) -// For examples, please go to http://public.highfidelity.io/scripts +// For examples, please go to https://github.com/highfidelity/hifi/tree/master/script-archive/acScripts // The directory named acScripts contains assignment-client specific scripts you can try. From 97b09d680ca7bbff215a7765d082f909deed5d73 Mon Sep 17 00:00:00 2001 From: SamGondelman Date: Mon, 2 Oct 2017 13:17:53 -0700 Subject: [PATCH 35/59] fix and improve laser pointer locking --- interface/src/raypick/LaserPointer.h | 3 + interface/src/raypick/LaserPointerManager.cpp | 105 ++++++++++-------- interface/src/raypick/LaserPointerManager.h | 2 - interface/src/raypick/RayPick.h | 5 + interface/src/raypick/RayPickManager.cpp | 76 +++++++------ interface/src/raypick/RayPickManager.h | 2 - 6 files changed, 108 insertions(+), 85 deletions(-) diff --git a/interface/src/raypick/LaserPointer.h b/interface/src/raypick/LaserPointer.h index 5467a8233e..fa7d396ae8 100644 --- a/interface/src/raypick/LaserPointer.h +++ b/interface/src/raypick/LaserPointer.h @@ -75,6 +75,8 @@ public: void setLockEndUUID(QUuid objectID, const bool isOverlay) { _objectLockEnd = std::pair(objectID, isOverlay); } + QReadWriteLock* getLock() { return &_lock; } + void update(); private: @@ -89,6 +91,7 @@ private: std::pair _objectLockEnd { std::pair(QUuid(), false)}; QUuid _rayPickUID; + QReadWriteLock _lock; void updateRenderStateOverlay(const OverlayID& id, const QVariant& props); void updateRenderState(const RenderState& renderState, const IntersectionType type, const float distance, const QUuid& objectID, const PickRay& pickRay, const bool defaultState); diff --git a/interface/src/raypick/LaserPointerManager.cpp b/interface/src/raypick/LaserPointerManager.cpp index b19ecc14f0..387f88724e 100644 --- a/interface/src/raypick/LaserPointerManager.cpp +++ b/interface/src/raypick/LaserPointerManager.cpp @@ -17,7 +17,6 @@ QUuid LaserPointerManager::createLaserPointer(const QVariant& rayProps, const La QWriteLocker containsLock(&_containsLock); QUuid id = QUuid::createUuid(); _laserPointers[id] = laserPointer; - _laserPointerLocks[id] = std::make_shared(); return id; } return QUuid(); @@ -26,46 +25,50 @@ QUuid LaserPointerManager::createLaserPointer(const QVariant& rayProps, const La void LaserPointerManager::removeLaserPointer(const QUuid uid) { QWriteLocker lock(&_containsLock); _laserPointers.remove(uid); - _laserPointerLocks.remove(uid); } void LaserPointerManager::enableLaserPointer(const QUuid uid) { QReadLocker lock(&_containsLock); - if (_laserPointers.contains(uid)) { - QWriteLocker laserLock(_laserPointerLocks[uid].get()); - _laserPointers[uid]->enable(); + auto laserPointer = _laserPointers.find(uid); + if (laserPointer != _laserPointers.end()) { + QWriteLocker laserLock(laserPointer.value()->getLock()); + laserPointer.value()->enable(); } } void LaserPointerManager::disableLaserPointer(const QUuid uid) { QReadLocker lock(&_containsLock); - if (_laserPointers.contains(uid)) { - QWriteLocker laserLock(_laserPointerLocks[uid].get()); - _laserPointers[uid]->disable(); + auto laserPointer = _laserPointers.find(uid); + if (laserPointer != _laserPointers.end()) { + QWriteLocker laserLock(laserPointer.value()->getLock()); + laserPointer.value()->disable(); } } void LaserPointerManager::setRenderState(QUuid uid, const std::string& renderState) { QReadLocker lock(&_containsLock); - if (_laserPointers.contains(uid)) { - QWriteLocker laserLock(_laserPointerLocks[uid].get()); - _laserPointers[uid]->setRenderState(renderState); + auto laserPointer = _laserPointers.find(uid); + if (laserPointer != _laserPointers.end()) { + QWriteLocker laserLock(laserPointer.value()->getLock()); + laserPointer.value()->setRenderState(renderState); } } void LaserPointerManager::editRenderState(QUuid uid, const std::string& state, const QVariant& startProps, const QVariant& pathProps, const QVariant& endProps) { QReadLocker lock(&_containsLock); - if (_laserPointers.contains(uid)) { - QWriteLocker laserLock(_laserPointerLocks[uid].get()); - _laserPointers[uid]->editRenderState(state, startProps, pathProps, endProps); + auto laserPointer = _laserPointers.find(uid); + if (laserPointer != _laserPointers.end()) { + QWriteLocker laserLock(laserPointer.value()->getLock()); + laserPointer.value()->editRenderState(state, startProps, pathProps, endProps); } } const RayPickResult LaserPointerManager::getPrevRayPickResult(const QUuid uid) { QReadLocker lock(&_containsLock); - if (_laserPointers.contains(uid)) { - QReadLocker laserLock(_laserPointerLocks[uid].get()); - return _laserPointers[uid]->getPrevRayPickResult(); + auto laserPointer = _laserPointers.find(uid); + if (laserPointer != _laserPointers.end()) { + QReadLocker laserLock(laserPointer.value()->getLock()); + return laserPointer.value()->getPrevRayPickResult(); } return RayPickResult(); } @@ -74,79 +77,89 @@ void LaserPointerManager::update() { QReadLocker lock(&_containsLock); for (QUuid& uid : _laserPointers.keys()) { // This only needs to be a read lock because update won't change any of the properties that can be modified from scripts - QReadLocker laserLock(_laserPointerLocks[uid].get()); - _laserPointers[uid]->update(); + auto laserPointer = _laserPointers.find(uid); + QReadLocker laserLock(laserPointer.value()->getLock()); + laserPointer.value()->update(); } } void LaserPointerManager::setPrecisionPicking(QUuid uid, const bool precisionPicking) { QReadLocker lock(&_containsLock); - if (_laserPointers.contains(uid)) { - QWriteLocker laserLock(_laserPointerLocks[uid].get()); - _laserPointers[uid]->setPrecisionPicking(precisionPicking); + auto laserPointer = _laserPointers.find(uid); + if (laserPointer != _laserPointers.end()) { + QWriteLocker laserLock(laserPointer.value()->getLock()); + laserPointer.value()->setPrecisionPicking(precisionPicking); } } void LaserPointerManager::setLaserLength(QUuid uid, const float laserLength) { QReadLocker lock(&_containsLock); - if (_laserPointers.contains(uid)) { - QWriteLocker laserLock(_laserPointerLocks[uid].get()); - _laserPointers[uid]->setLaserLength(laserLength); + auto laserPointer = _laserPointers.find(uid); + if (laserPointer != _laserPointers.end()) { + QWriteLocker laserLock(laserPointer.value()->getLock()); + laserPointer.value()->setLaserLength(laserLength); } } void LaserPointerManager::setIgnoreEntities(QUuid uid, const QScriptValue& ignoreEntities) { QReadLocker lock(&_containsLock); - if (_laserPointers.contains(uid)) { - QWriteLocker laserLock(_laserPointerLocks[uid].get()); - _laserPointers[uid]->setIgnoreEntities(ignoreEntities); + auto laserPointer = _laserPointers.find(uid); + if (laserPointer != _laserPointers.end()) { + QWriteLocker laserLock(laserPointer.value()->getLock()); + laserPointer.value()->setIgnoreEntities(ignoreEntities); } } void LaserPointerManager::setIncludeEntities(QUuid uid, const QScriptValue& includeEntities) { QReadLocker lock(&_containsLock); - if (_laserPointers.contains(uid)) { - QWriteLocker laserLock(_laserPointerLocks[uid].get()); - _laserPointers[uid]->setIncludeEntities(includeEntities); + auto laserPointer = _laserPointers.find(uid); + if (laserPointer != _laserPointers.end()) { + QWriteLocker laserLock(laserPointer.value()->getLock()); + laserPointer.value()->setIncludeEntities(includeEntities); } } void LaserPointerManager::setIgnoreOverlays(QUuid uid, const QScriptValue& ignoreOverlays) { QReadLocker lock(&_containsLock); - if (_laserPointers.contains(uid)) { - QWriteLocker laserLock(_laserPointerLocks[uid].get()); - _laserPointers[uid]->setIgnoreOverlays(ignoreOverlays); + auto laserPointer = _laserPointers.find(uid); + if (laserPointer != _laserPointers.end()) { + QWriteLocker laserLock(laserPointer.value()->getLock()); + laserPointer.value()->setIgnoreOverlays(ignoreOverlays); } } void LaserPointerManager::setIncludeOverlays(QUuid uid, const QScriptValue& includeOverlays) { QReadLocker lock(&_containsLock); - if (_laserPointers.contains(uid)) { - QWriteLocker laserLock(_laserPointerLocks[uid].get()); - _laserPointers[uid]->setIncludeOverlays(includeOverlays); + auto laserPointer = _laserPointers.find(uid); + if (laserPointer != _laserPointers.end()) { + QWriteLocker laserLock(laserPointer.value()->getLock()); + laserPointer.value()->setIncludeOverlays(includeOverlays); } } void LaserPointerManager::setIgnoreAvatars(QUuid uid, const QScriptValue& ignoreAvatars) { QReadLocker lock(&_containsLock); - if (_laserPointers.contains(uid)) { - QWriteLocker laserLock(_laserPointerLocks[uid].get()); - _laserPointers[uid]->setIgnoreAvatars(ignoreAvatars); + auto laserPointer = _laserPointers.find(uid); + if (laserPointer != _laserPointers.end()) { + QWriteLocker laserLock(laserPointer.value()->getLock()); + laserPointer.value()->setIgnoreAvatars(ignoreAvatars); } } void LaserPointerManager::setIncludeAvatars(QUuid uid, const QScriptValue& includeAvatars) { QReadLocker lock(&_containsLock); - if (_laserPointers.contains(uid)) { - QWriteLocker laserLock(_laserPointerLocks[uid].get()); - _laserPointers[uid]->setIncludeAvatars(includeAvatars); + auto laserPointer = _laserPointers.find(uid); + if (laserPointer != _laserPointers.end()) { + QWriteLocker laserLock(laserPointer.value()->getLock()); + laserPointer.value()->setIncludeAvatars(includeAvatars); } } void LaserPointerManager::setLockEndUUID(QUuid uid, QUuid objectID, const bool isOverlay) { QReadLocker lock(&_containsLock); - if (_laserPointers.contains(uid)) { - QWriteLocker laserLock(_laserPointerLocks[uid].get()); - _laserPointers[uid]->setLockEndUUID(objectID, isOverlay); + auto laserPointer = _laserPointers.find(uid); + if (laserPointer != _laserPointers.end()) { + QWriteLocker laserLock(laserPointer.value()->getLock()); + laserPointer.value()->setLockEndUUID(objectID, isOverlay); } } diff --git a/interface/src/raypick/LaserPointerManager.h b/interface/src/raypick/LaserPointerManager.h index 6494bb7056..b841877578 100644 --- a/interface/src/raypick/LaserPointerManager.h +++ b/interface/src/raypick/LaserPointerManager.h @@ -13,7 +13,6 @@ #include #include -#include #include "LaserPointer.h" @@ -46,7 +45,6 @@ public: private: QHash> _laserPointers; - QHash> _laserPointerLocks; QReadWriteLock _containsLock; }; diff --git a/interface/src/raypick/RayPick.h b/interface/src/raypick/RayPick.h index 0686a05718..428e44d670 100644 --- a/interface/src/raypick/RayPick.h +++ b/interface/src/raypick/RayPick.h @@ -16,6 +16,7 @@ #include "EntityItemID.h" #include "ui/overlays/Overlay.h" +#include class RayPickFilter { public: @@ -127,6 +128,8 @@ public: void setIgnoreAvatars(const QScriptValue& ignoreAvatars) { _ignoreAvatars = qVectorEntityItemIDFromScriptValue(ignoreAvatars); } void setIncludeAvatars(const QScriptValue& includeAvatars) { _includeAvatars = qVectorEntityItemIDFromScriptValue(includeAvatars); } + QReadWriteLock* getLock() { return &_lock; } + private: RayPickFilter _filter; float _maxDistance; @@ -139,6 +142,8 @@ private: QVector _includeOverlays; QVector _ignoreAvatars; QVector _includeAvatars; + + QReadWriteLock _lock; }; #endif // hifi_RayPick_h diff --git a/interface/src/raypick/RayPickManager.cpp b/interface/src/raypick/RayPickManager.cpp index bfc6e3fcb2..65f82dcd5f 100644 --- a/interface/src/raypick/RayPickManager.cpp +++ b/interface/src/raypick/RayPickManager.cpp @@ -47,6 +47,7 @@ void RayPickManager::update() { RayPickCache results; for (auto& uid : _rayPicks.keys()) { std::shared_ptr rayPick = _rayPicks[uid]; + QWriteLocker lock(rayPick->getLock()); if (!rayPick->isEnabled() || rayPick->getFilter().doesPickNothing() || rayPick->getMaxDistance() < 0.0f) { continue; } @@ -114,7 +115,6 @@ void RayPickManager::update() { } } - QWriteLocker lock(_rayPickLocks[uid].get()); if (rayPick->getMaxDistance() == 0.0f || (rayPick->getMaxDistance() > 0.0f && res.distance < rayPick->getMaxDistance())) { rayPick->setRayPickResult(res); } else { @@ -127,7 +127,6 @@ QUuid RayPickManager::createRayPick(const std::string& jointName, const glm::vec QWriteLocker lock(&_containsLock); QUuid id = QUuid::createUuid(); _rayPicks[id] = std::make_shared(jointName, posOffset, dirOffset, filter, maxDistance, enabled); - _rayPickLocks[id] = std::make_shared(); return id; } @@ -135,7 +134,6 @@ QUuid RayPickManager::createRayPick(const RayPickFilter& filter, const float max QWriteLocker lock(&_containsLock); QUuid id = QUuid::createUuid(); _rayPicks[id] = std::make_shared(filter, maxDistance, enabled); - _rayPickLocks[id] = std::make_shared(); return id; } @@ -143,93 +141,101 @@ QUuid RayPickManager::createRayPick(const glm::vec3& position, const glm::vec3& QWriteLocker lock(&_containsLock); QUuid id = QUuid::createUuid(); _rayPicks[id] = std::make_shared(position, direction, filter, maxDistance, enabled); - _rayPickLocks[id] = std::make_shared(); return id; } void RayPickManager::removeRayPick(const QUuid uid) { QWriteLocker lock(&_containsLock); _rayPicks.remove(uid); - _rayPickLocks.remove(uid); } void RayPickManager::enableRayPick(const QUuid uid) { QReadLocker containsLock(&_containsLock); - if (_rayPicks.contains(uid)) { - QWriteLocker rayPickLock(_rayPickLocks[uid].get()); - _rayPicks[uid]->enable(); + auto rayPick = _rayPicks.find(uid); + if (rayPick != _rayPicks.end()) { + QWriteLocker rayPickLock(rayPick.value()->getLock()); + rayPick.value()->enable(); } } void RayPickManager::disableRayPick(const QUuid uid) { QReadLocker containsLock(&_containsLock); - if (_rayPicks.contains(uid)) { - QWriteLocker rayPickLock(_rayPickLocks[uid].get()); - _rayPicks[uid]->disable(); + auto rayPick = _rayPicks.find(uid); + if (rayPick != _rayPicks.end()) { + QWriteLocker rayPickLock(rayPick.value()->getLock()); + rayPick.value()->disable(); } } const RayPickResult RayPickManager::getPrevRayPickResult(const QUuid uid) { QReadLocker containsLock(&_containsLock); - if (_rayPicks.contains(uid)) { - QReadLocker lock(_rayPickLocks[uid].get()); - return _rayPicks[uid]->getPrevRayPickResult(); + auto rayPick = _rayPicks.find(uid); + if (rayPick != _rayPicks.end()) { + QReadLocker lock(rayPick.value()->getLock()); + return rayPick.value()->getPrevRayPickResult(); } return RayPickResult(); } void RayPickManager::setPrecisionPicking(QUuid uid, const bool precisionPicking) { QReadLocker containsLock(&_containsLock); - if (_rayPicks.contains(uid)) { - QWriteLocker lock(_rayPickLocks[uid].get()); - _rayPicks[uid]->setPrecisionPicking(precisionPicking); + auto rayPick = _rayPicks.find(uid); + if (rayPick != _rayPicks.end()) { + QWriteLocker lock(rayPick.value()->getLock()); + rayPick.value()->setPrecisionPicking(precisionPicking); } } void RayPickManager::setIgnoreEntities(QUuid uid, const QScriptValue& ignoreEntities) { QReadLocker containsLock(&_containsLock); - if (_rayPicks.contains(uid)) { - QWriteLocker lock(_rayPickLocks[uid].get()); - _rayPicks[uid]->setIgnoreEntities(ignoreEntities); + auto rayPick = _rayPicks.find(uid); + if (rayPick != _rayPicks.end()) { + QWriteLocker lock(rayPick.value()->getLock()); + rayPick.value()->setIgnoreEntities(ignoreEntities); } } void RayPickManager::setIncludeEntities(QUuid uid, const QScriptValue& includeEntities) { QReadLocker containsLock(&_containsLock); - if (_rayPicks.contains(uid)) { - QWriteLocker lock(_rayPickLocks[uid].get()); - _rayPicks[uid]->setIncludeEntities(includeEntities); + auto rayPick = _rayPicks.find(uid); + if (rayPick != _rayPicks.end()) { + QWriteLocker lock(rayPick.value()->getLock()); + rayPick.value()->setIncludeEntities(includeEntities); } } void RayPickManager::setIgnoreOverlays(QUuid uid, const QScriptValue& ignoreOverlays) { QReadLocker containsLock(&_containsLock); - if (_rayPicks.contains(uid)) { - QWriteLocker lock(_rayPickLocks[uid].get()); - _rayPicks[uid]->setIgnoreOverlays(ignoreOverlays); + auto rayPick = _rayPicks.find(uid); + if (rayPick != _rayPicks.end()) { + QWriteLocker lock(rayPick.value()->getLock()); + rayPick.value()->setIgnoreOverlays(ignoreOverlays); } } void RayPickManager::setIncludeOverlays(QUuid uid, const QScriptValue& includeOverlays) { QReadLocker containsLock(&_containsLock); - if (_rayPicks.contains(uid)) { - QWriteLocker lock(_rayPickLocks[uid].get()); - _rayPicks[uid]->setIncludeOverlays(includeOverlays); + auto rayPick = _rayPicks.find(uid); + if (rayPick != _rayPicks.end()) { + QWriteLocker lock(rayPick.value()->getLock()); + rayPick.value()->setIncludeOverlays(includeOverlays); } } void RayPickManager::setIgnoreAvatars(QUuid uid, const QScriptValue& ignoreAvatars) { QReadLocker containsLock(&_containsLock); - if (_rayPicks.contains(uid)) { - QWriteLocker lock(_rayPickLocks[uid].get()); - _rayPicks[uid]->setIgnoreAvatars(ignoreAvatars); + auto rayPick = _rayPicks.find(uid); + if (rayPick != _rayPicks.end()) { + QWriteLocker lock(rayPick.value()->getLock()); + rayPick.value()->setIgnoreAvatars(ignoreAvatars); } } void RayPickManager::setIncludeAvatars(QUuid uid, const QScriptValue& includeAvatars) { QReadLocker containsLock(&_containsLock); - if (_rayPicks.contains(uid)) { - QWriteLocker lock(_rayPickLocks[uid].get()); - _rayPicks[uid]->setIncludeAvatars(includeAvatars); + auto rayPick = _rayPicks.find(uid); + if (rayPick != _rayPicks.end()) { + QWriteLocker lock(rayPick.value()->getLock()); + rayPick.value()->setIncludeAvatars(includeAvatars); } } \ No newline at end of file diff --git a/interface/src/raypick/RayPickManager.h b/interface/src/raypick/RayPickManager.h index 9717767f19..974022eb4d 100644 --- a/interface/src/raypick/RayPickManager.h +++ b/interface/src/raypick/RayPickManager.h @@ -15,7 +15,6 @@ #include #include -#include #include "RegisteredMetaTypes.h" @@ -47,7 +46,6 @@ public: private: QHash> _rayPicks; - QHash> _rayPickLocks; QReadWriteLock _containsLock; typedef QHash, std::unordered_map> RayPickCache; From bb99f68d40ec7e0a67bb366067380d2638377a59 Mon Sep 17 00:00:00 2001 From: samcake Date: Mon, 2 Oct 2017 17:04:00 -0700 Subject: [PATCH 36/59] Avoiding the need for the GLobal frameTiing Scriptiong interface and just a regular member of APplication instead --- interface/src/Application.cpp | 5 +---- interface/src/Application.h | 3 +++ interface/src/Application_render.cpp | 2 -- 3 files changed, 4 insertions(+), 6 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 35fc0049a8..97d621478d 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -188,7 +188,6 @@ #include "InterfaceParentFinder.h" #include "ui/OctreeStatsProvider.h" -//#include "FrameTimingsScriptingInterface.h" #include #include #include @@ -2217,8 +2216,6 @@ void Application::initializeGL() { update(0); } -//FrameTimingsScriptingInterface _frameTimingsScriptingInterface; - extern void setupPreferences(); void Application::initializeUi() { @@ -2273,7 +2270,7 @@ void Application::initializeUi() { surfaceContext->setContextProperty("Recording", DependencyManager::get().data()); surfaceContext->setContextProperty("Preferences", DependencyManager::get().data()); surfaceContext->setContextProperty("AddressManager", DependencyManager::get().data()); - //surfaceContext->setContextProperty("FrameTimings", &_frameTimingsScriptingInterface); // TODO: Remove this Context Property ? i don;t see anywhere + surfaceContext->setContextProperty("FrameTimings", &_frameTimingsScriptingInterface); surfaceContext->setContextProperty("Rates", new RatesScriptingInterface(this)); surfaceContext->setContextProperty("TREE_SCALE", TREE_SCALE); diff --git a/interface/src/Application.h b/interface/src/Application.h index 77ae840274..3966d1c50d 100644 --- a/interface/src/Application.h +++ b/interface/src/Application.h @@ -76,6 +76,7 @@ #include #include #include +#include "FrameTimingsScriptingInterface.h" #include "Sound.h" @@ -537,6 +538,8 @@ private: RateCounter<> _avatarSimCounter; RateCounter<> _simCounter; + FrameTimingsScriptingInterface _frameTimingsScriptingInterface; + QTimer _minimizedWindowTimer; QElapsedTimer _timerStart; QElapsedTimer _lastTimeUpdated; diff --git a/interface/src/Application_render.cpp b/interface/src/Application_render.cpp index 1c82c95a8a..b09705c300 100644 --- a/interface/src/Application_render.cpp +++ b/interface/src/Application_render.cpp @@ -14,11 +14,9 @@ #include #include #include "ui/Stats.h" -#include "FrameTimingsScriptingInterface.h" #include #include "Util.h" -FrameTimingsScriptingInterface _frameTimingsScriptingInterface; // Statically provided display and input plugins extern DisplayPluginList getDisplayPlugins(); From acb99592eeb266688c373a3395119d221c4fabe0 Mon Sep 17 00:00:00 2001 From: Sam Gateau Date: Mon, 2 Oct 2017 21:31:30 -0700 Subject: [PATCH 37/59] fixing th e bug on exit due to the debug anim draw of the avatars --- libraries/render-utils/src/AnimDebugDraw.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/libraries/render-utils/src/AnimDebugDraw.cpp b/libraries/render-utils/src/AnimDebugDraw.cpp index 4f7f9ef5c4..c22e99cbbc 100644 --- a/libraries/render-utils/src/AnimDebugDraw.cpp +++ b/libraries/render-utils/src/AnimDebugDraw.cpp @@ -144,6 +144,7 @@ void AnimDebugDraw::shutdown() { if (scene && _itemID) { render::Transaction transaction; transaction.removeItem(_itemID); + render::Item::clearID(_itemID); scene->enqueueTransaction(transaction); } } @@ -316,7 +317,9 @@ void AnimDebugDraw::update() { if (!scene) { return; } - + if (!render::Item::isValidID(_itemID)) { + return; + } render::Transaction transaction; transaction.updateItem(_itemID, [&](AnimDebugDrawData& data) { From 895e3d0430017be666ddd4a6f81fd1b6c37b5e6c Mon Sep 17 00:00:00 2001 From: Sam Gateau Date: Mon, 2 Oct 2017 21:46:52 -0700 Subject: [PATCH 38/59] more cleanups --- interface/src/Application_render.cpp | 1 - interface/src/ui/overlays/Overlays.cpp | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/interface/src/Application_render.cpp b/interface/src/Application_render.cpp index b09705c300..ac9aecf66c 100644 --- a/interface/src/Application_render.cpp +++ b/interface/src/Application_render.cpp @@ -103,7 +103,6 @@ void Application::paintGL() { _applicationOverlay.renderOverlay(&renderArgs); } - // updateCamera(renderArgs); { PROFILE_RANGE(render, "/updateCompositor"); getApplicationCompositor().setFrameInfo(_frameCount, eyeToWorld, sensorToWorld); diff --git a/interface/src/ui/overlays/Overlays.cpp b/interface/src/ui/overlays/Overlays.cpp index e9cb1f2973..c93d225718 100644 --- a/interface/src/ui/overlays/Overlays.cpp +++ b/interface/src/ui/overlays/Overlays.cpp @@ -152,7 +152,7 @@ void Overlays::render3DHUDOverlays(RenderArgs* renderArgs) { foreach(Overlay::Pointer thisOverlay, _overlays3DHUD) { // Reset necessary batch pipeline settings between overlays batch.setResourceTexture(0, textureCache->getWhiteTexture()); // FIXME - do we really need to do this?? - // batch.setModelTransform(Transform()); + batch.setModelTransform(Transform()); renderArgs->_shapePipeline = _shapePlumber->pickPipeline(renderArgs, thisOverlay->getShapeKey()); thisOverlay->render(renderArgs); From 64f70f1ebbd3dcf69b772f5b2076466738ba2484 Mon Sep 17 00:00:00 2001 From: Sam Gateau Date: Mon, 2 Oct 2017 22:00:41 -0700 Subject: [PATCH 39/59] more cleanups --- interface/src/ui/overlays/Base3DOverlay.cpp | 3 --- 1 file changed, 3 deletions(-) diff --git a/interface/src/ui/overlays/Base3DOverlay.cpp b/interface/src/ui/overlays/Base3DOverlay.cpp index 4d4f2c3a1c..4210e76097 100644 --- a/interface/src/ui/overlays/Base3DOverlay.cpp +++ b/interface/src/ui/overlays/Base3DOverlay.cpp @@ -191,8 +191,6 @@ void Base3DOverlay::setProperties(const QVariantMap& originalProperties) { // Communicate changes to the renderItem if needed if (needRenderItemUpdate) { - notifyRenderTransformChange(); - auto itemID = getRenderItemID(); if (render::Item::isValidID(itemID)) { render::ScenePointer scene = qApp->getMain3DScene(); @@ -267,7 +265,6 @@ void Base3DOverlay::parentDeleted() { } void Base3DOverlay::update(float duration) { - // In Base3DOverlay, if its location or bound changed, the renderTrasnformDirty flag is true. // then the correct transform used for rendering is computed in the update transaction and assigned. if (_renderTransformDirty) { From ef326a38518969dff000d550717b40027394cfc1 Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Tue, 3 Oct 2017 11:59:25 -0700 Subject: [PATCH 40/59] expose performance hot spot in stats details --- .../src/EntityTreeRenderer.cpp | 26 ++++++++++++++----- 1 file changed, 19 insertions(+), 7 deletions(-) diff --git a/libraries/entities-renderer/src/EntityTreeRenderer.cpp b/libraries/entities-renderer/src/EntityTreeRenderer.cpp index 0cb25a2e2f..e42a307d96 100644 --- a/libraries/entities-renderer/src/EntityTreeRenderer.cpp +++ b/libraries/entities-renderer/src/EntityTreeRenderer.cpp @@ -260,12 +260,24 @@ void EntityTreeRenderer::update(bool simulate) { } } - auto scene = _viewState->getMain3DScene(); - if (scene) { - render::Transaction transaction; - addPendingEntities(scene, transaction); - updateChangedEntities(scene, transaction); - scene->enqueueTransaction(transaction); + { + PerformanceTimer sceneTimer("scene"); + auto scene = _viewState->getMain3DScene(); + if (scene) { + render::Transaction transaction; + { + PerformanceTimer foo("add"); + addPendingEntities(scene, transaction); + } + { + PerformanceTimer foo("change"); + updateChangedEntities(scene, transaction); + } + { + PerformanceTimer foo("enqueue"); + scene->enqueueTransaction(transaction); + } + } } } } @@ -1078,4 +1090,4 @@ void EntityTreeRenderer::onEntityChanged(const EntityItemID& id) { _changedEntitiesGuard.withWriteLock([&] { _changedEntities.insert(id); }); -} \ No newline at end of file +} From 46e809bbb25e64e912daf64ecd89b478c2645fec Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Tue, 3 Oct 2017 12:19:19 -0700 Subject: [PATCH 41/59] use a better variable name --- libraries/entities-renderer/src/EntityTreeRenderer.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/libraries/entities-renderer/src/EntityTreeRenderer.cpp b/libraries/entities-renderer/src/EntityTreeRenderer.cpp index e42a307d96..67fcc5cc69 100644 --- a/libraries/entities-renderer/src/EntityTreeRenderer.cpp +++ b/libraries/entities-renderer/src/EntityTreeRenderer.cpp @@ -266,15 +266,15 @@ void EntityTreeRenderer::update(bool simulate) { if (scene) { render::Transaction transaction; { - PerformanceTimer foo("add"); + PerformanceTimer pt("add"); addPendingEntities(scene, transaction); } { - PerformanceTimer foo("change"); + PerformanceTimer pt("change"); updateChangedEntities(scene, transaction); } { - PerformanceTimer foo("enqueue"); + PerformanceTimer pt("enqueue"); scene->enqueueTransaction(transaction); } } From f8aa3d72de9a5020b67e8ca039259fe3deef978e Mon Sep 17 00:00:00 2001 From: Atlante45 Date: Wed, 4 Oct 2017 15:20:47 -0700 Subject: [PATCH 42/59] Update macOS build guide --- BUILD_OSX.md | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/BUILD_OSX.md b/BUILD_OSX.md index 586f81def3..6b66863534 100644 --- a/BUILD_OSX.md +++ b/BUILD_OSX.md @@ -1,28 +1,28 @@ -Please read the [general build guide](BUILD.md) for information on dependencies required for all platforms. Only OS X specific instructions are found in this file. +Please read the [general build guide](BUILD.md) for information on dependencies required for all platforms. Only macOS specific instructions are found in this file. ### Homebrew -[Homebrew](https://brew.sh/) is an excellent package manager for OS X. It makes install of some High Fidelity dependencies very simple. +[Homebrew](https://brew.sh/) is an excellent package manager for macOS. It makes install of some High Fidelity dependencies very simple. - brew install cmake openssl + brew install cmake openssl qt ### OpenSSL Assuming you've installed OpenSSL using the homebrew instructions above, you'll need to set OPENSSL_ROOT_DIR so CMake can find your installations. For OpenSSL installed via homebrew, set OPENSSL_ROOT_DIR: - export OPENSSL_ROOT_DIR=/usr/local/Cellar/openssl/1.0.2h_1/ + export OPENSSL_ROOT_DIR=/usr/local/Cellar/openssl/1.0.2l Note that this uses the version from the homebrew formula at the time of this writing, and the version in the path will likely change. ### Qt -Download and install the [Qt 5.6.2 for macOS](http://download.qt.io/official_releases/qt/5.6/5.6.2/qt-opensource-mac-x64-clang-5.6.2.dmg). +Assuming you've installed Qt using the homebrew instructions above, you'll need to set QT_CMAKE_PREFIX_PATH so CMake can find your installations. +For Qt installed via homebrew, set QT_CMAKE_PREFIX_PATH: -Keep the default components checked when going through the installer. + export QT_CMAKE_PREFIX_PATH=/usr/local/Cellar/qt/5.9.1/lib/cmake -Once Qt is installed, you need to manually configure the following: -* Set the QT_CMAKE_PREFIX_PATH environment variable to your `Qt5.6.2/5.6/clang_64/lib/cmake/` directory. +Note that this uses the version from the homebrew formula at the time of this writing, and the version in the path will likely change. ### Xcode From 193dc83b99878a9aeea73b5688c78b0db13080bf Mon Sep 17 00:00:00 2001 From: vladest Date: Thu, 5 Oct 2017 13:59:42 +0200 Subject: [PATCH 43/59] Fix alignment of audio devices input header --- interface/resources/qml/hifi/audio/Audio.qml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/interface/resources/qml/hifi/audio/Audio.qml b/interface/resources/qml/hifi/audio/Audio.qml index b1f80ac5e8..12c2ec1835 100644 --- a/interface/resources/qml/hifi/audio/Audio.qml +++ b/interface/resources/qml/hifi/audio/Audio.qml @@ -167,6 +167,9 @@ Rectangle { } RalewayRegular { anchors.verticalCenter: parent.verticalCenter; + width: margins.sizeText + margins.sizeLevel + anchors.left: parent.left + anchors.leftMargin: margins.sizeCheckBox size: 16; color: hifi.colors.lightGrayText; text: qsTr("CHOOSE INPUT DEVICE"); From 218de29356eb515774efb7e31cc7e9bf5467308d Mon Sep 17 00:00:00 2001 From: Ken Cooke Date: Thu, 5 Oct 2017 07:39:21 -0700 Subject: [PATCH 44/59] disable compiler optimization as temporary fix --- libraries/audio/src/AudioGate.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/libraries/audio/src/AudioGate.cpp b/libraries/audio/src/AudioGate.cpp index 5b2561da07..18884d008a 100644 --- a/libraries/audio/src/AudioGate.cpp +++ b/libraries/audio/src/AudioGate.cpp @@ -13,6 +13,10 @@ #include #include "AudioDynamics.h" +#ifdef __clang__ +#pragma clang optimize off +#endif + // log2 domain headroom bits above 0dB (int32_t) static const int LOG2_HEADROOM_Q30 = 1; From de2c1aabac887a96f303e2aa918c6e506f82fa7b Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Tue, 26 Sep 2017 15:37:14 -0700 Subject: [PATCH 45/59] Add removal of temporary files in FBXBaker --- libraries/baking/src/Baker.h | 2 ++ libraries/baking/src/FBXBaker.cpp | 11 +++++++++++ libraries/baking/src/FBXBaker.h | 1 + 3 files changed, 14 insertions(+) diff --git a/libraries/baking/src/Baker.h b/libraries/baking/src/Baker.h index 2da315c9fc..c1b2ddf959 100644 --- a/libraries/baking/src/Baker.h +++ b/libraries/baking/src/Baker.h @@ -18,6 +18,8 @@ class Baker : public QObject { Q_OBJECT public: + virtual ~Baker() = default; + bool shouldStop(); bool hasErrors() const { return !_errorList.isEmpty(); } diff --git a/libraries/baking/src/FBXBaker.cpp b/libraries/baking/src/FBXBaker.cpp index 3ef291af22..017f11c680 100644 --- a/libraries/baking/src/FBXBaker.cpp +++ b/libraries/baking/src/FBXBaker.cpp @@ -56,6 +56,17 @@ FBXBaker::FBXBaker(const QUrl& fbxURL, TextureBakerThreadGetter textureThreadGet } +FBXBaker::~FBXBaker() { + if (_tempDir.exists()) { + if (!_tempDir.remove(_originalFBXFilePath)) { + qCWarning(model_baking) << "Failed to remove temporary copy of fbx file:" << _originalFBXFilePath; + } + if (!_tempDir.rmdir(".")) { + qCWarning(model_baking) << "Failed to remove temporary directory:" << _tempDir; + } + } +} + void FBXBaker::abort() { Baker::abort(); diff --git a/libraries/baking/src/FBXBaker.h b/libraries/baking/src/FBXBaker.h index ad8284bfa8..a6034ee2b7 100644 --- a/libraries/baking/src/FBXBaker.h +++ b/libraries/baking/src/FBXBaker.h @@ -35,6 +35,7 @@ class FBXBaker : public Baker { public: FBXBaker(const QUrl& fbxURL, TextureBakerThreadGetter textureThreadGetter, const QString& bakedOutputDir, const QString& originalOutputDir = ""); + ~FBXBaker() override; QUrl getFBXUrl() const { return _fbxURL; } QString getBakedFBXFilePath() const { return _bakedFBXFilePath; } From a6d148475bea71e881ccc785c7146ac831f905eb Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Wed, 27 Sep 2017 14:52:21 -0700 Subject: [PATCH 46/59] Add removal of temporary baked files in AssetServer --- assignment-client/src/assets/AssetServer.cpp | 13 ++++++++- assignment-client/src/assets/AssetServer.h | 3 +- .../src/assets/BakeAssetTask.cpp | 29 +++++++++++++++++-- assignment-client/src/assets/BakeAssetTask.h | 2 +- 4 files changed, 41 insertions(+), 6 deletions(-) diff --git a/assignment-client/src/assets/AssetServer.cpp b/assignment-client/src/assets/AssetServer.cpp index 9df606c227..c03721d097 100644 --- a/assignment-client/src/assets/AssetServer.cpp +++ b/assignment-client/src/assets/AssetServer.cpp @@ -1162,7 +1162,8 @@ void AssetServer::handleFailedBake(QString originalAssetHash, QString assetPath, _pendingBakes.remove(originalAssetHash); } -void AssetServer::handleCompletedBake(QString originalAssetHash, QString originalAssetPath, QVector bakedFilePaths) { +void AssetServer::handleCompletedBake(QString originalAssetHash, QString originalAssetPath, + QString bakedTempOutputDir, QVector bakedFilePaths) { bool errorCompletingBake { false }; QString errorReason; @@ -1234,6 +1235,16 @@ void AssetServer::handleCompletedBake(QString originalAssetHash, QString origina } } + for (auto& filePath : bakedFilePaths) { + QFile file(filePath); + if (!file.remove()) { + qWarning() << "Failed to remove temporary file:" << filePath; + } + } + if (!QDir(bakedTempOutputDir).rmdir(".")) { + qWarning() << "Failed to remove temporary directory:" << bakedTempOutputDir; + } + if (!errorCompletingBake) { // create the meta file to store which version of the baking process we just completed writeMetaFile(originalAssetHash); diff --git a/assignment-client/src/assets/AssetServer.h b/assignment-client/src/assets/AssetServer.h index 94be560c9b..aeb40a416f 100644 --- a/assignment-client/src/assets/AssetServer.h +++ b/assignment-client/src/assets/AssetServer.h @@ -100,7 +100,8 @@ private: void bakeAsset(const AssetHash& assetHash, const AssetPath& assetPath, const QString& filePath); /// Move baked content for asset to baked directory and update baked status - void handleCompletedBake(QString originalAssetHash, QString assetPath, QVector bakedFilePaths); + void handleCompletedBake(QString originalAssetHash, QString assetPath, QString bakedTempOutputDir, + QVector bakedFilePaths); void handleFailedBake(QString originalAssetHash, QString assetPath, QString errors); void handleAbortedBake(QString originalAssetHash, QString assetPath); diff --git a/assignment-client/src/assets/BakeAssetTask.cpp b/assignment-client/src/assets/BakeAssetTask.cpp index 9073510f79..94a0739612 100644 --- a/assignment-client/src/assets/BakeAssetTask.cpp +++ b/assignment-client/src/assets/BakeAssetTask.cpp @@ -24,20 +24,39 @@ BakeAssetTask::BakeAssetTask(const AssetHash& assetHash, const AssetPath& assetP } +void cleanupTempFiles(QString tempOutputDir, std::vector files) { + for (const auto& filename : files) { + QFile f { filename }; + if (!f.remove()) { + qDebug() << "Failed to remove:" << filename; + } + } + if (!tempOutputDir.isEmpty()) { + QDir dir { tempOutputDir }; + if (!dir.rmdir(".")) { + qDebug() << "Failed to remove temporary directory:" << tempOutputDir; + } + } +}; + void BakeAssetTask::run() { _isBaking.store(true); qRegisterMetaType >("QVector"); TextureBakerThreadGetter fn = []() -> QThread* { return QThread::currentThread(); }; + QString tempOutputDir; + if (_assetPath.endsWith(".fbx")) { + tempOutputDir = PathUtils::generateTemporaryDir(); _baker = std::unique_ptr { - new FBXBaker(QUrl("file:///" + _filePath), fn, PathUtils::generateTemporaryDir()) + new FBXBaker(QUrl("file:///" + _filePath), fn, tempOutputDir) }; } else { + tempOutputDir = PathUtils::generateTemporaryDir(); _baker = std::unique_ptr { new TextureBaker(QUrl("file:///" + _filePath), image::TextureUsage::CUBE_TEXTURE, - PathUtils::generateTemporaryDir()) + tempOutputDir) }; } @@ -52,6 +71,8 @@ void BakeAssetTask::run() { _wasAborted.store(true); + cleanupTempFiles(tempOutputDir, _baker->getOutputFiles()); + emit bakeAborted(_assetHash, _assetPath); } else if (_baker->hasErrors()) { qDebug() << "Failed to bake: " << _assetHash << _assetPath << _baker->getErrors(); @@ -60,6 +81,8 @@ void BakeAssetTask::run() { _didFinish.store(true); + cleanupTempFiles(tempOutputDir, _baker->getOutputFiles()); + emit bakeFailed(_assetHash, _assetPath, errors); } else { auto vectorOutputFiles = QVector::fromStdVector(_baker->getOutputFiles()); @@ -68,7 +91,7 @@ void BakeAssetTask::run() { _didFinish.store(true); - emit bakeComplete(_assetHash, _assetPath, vectorOutputFiles); + emit bakeComplete(_assetHash, _assetPath, tempOutputDir, vectorOutputFiles); } } diff --git a/assignment-client/src/assets/BakeAssetTask.h b/assignment-client/src/assets/BakeAssetTask.h index 45e7ec8702..90458ac223 100644 --- a/assignment-client/src/assets/BakeAssetTask.h +++ b/assignment-client/src/assets/BakeAssetTask.h @@ -35,7 +35,7 @@ public: bool didFinish() const { return _didFinish.load(); } signals: - void bakeComplete(QString assetHash, QString assetPath, QVector outputFiles); + void bakeComplete(QString assetHash, QString assetPath, QString tempOutputDir, QVector outputFiles); void bakeFailed(QString assetHash, QString assetPath, QString errors); void bakeAborted(QString assetHash, QString assetPath); From f0c9badbd6a4912a1a4340db8945b5d39349b7d6 Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Wed, 27 Sep 2017 15:56:04 -0700 Subject: [PATCH 47/59] Fix misspelling in lost-connection-to-atp error --- interface/resources/qml/hifi/AssetServer.qml | 2 +- interface/resources/qml/hifi/dialogs/TabletAssetServer.qml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/interface/resources/qml/hifi/AssetServer.qml b/interface/resources/qml/hifi/AssetServer.qml index 6b60cbff7b..5358ad1adc 100644 --- a/interface/resources/qml/hifi/AssetServer.qml +++ b/interface/resources/qml/hifi/AssetServer.qml @@ -171,7 +171,7 @@ ScrollingWindow { } function handleGetMappingsError(errorString) { - errorMessageBox("There was a problem retreiving the list of assets from your Asset Server.\n" + errorString); + errorMessageBox("There was a problem retrieving the list of assets from your Asset Server.\n" + errorString); } function addToWorld() { diff --git a/interface/resources/qml/hifi/dialogs/TabletAssetServer.qml b/interface/resources/qml/hifi/dialogs/TabletAssetServer.qml index 44cd700eac..a02496a252 100644 --- a/interface/resources/qml/hifi/dialogs/TabletAssetServer.qml +++ b/interface/resources/qml/hifi/dialogs/TabletAssetServer.qml @@ -172,7 +172,7 @@ Rectangle { } function handleGetMappingsError(errorString) { - errorMessageBox("There was a problem retreiving the list of assets from your Asset Server.\n" + errorString); + errorMessageBox("There was a problem retrieving the list of assets from your Asset Server.\n" + errorString); } function addToWorld() { From d8341a0929e6992bbdb670f9b684773a854e9a4c Mon Sep 17 00:00:00 2001 From: Ken Cooke Date: Thu, 5 Oct 2017 09:27:07 -0700 Subject: [PATCH 48/59] Work around compiler optimization bug --- libraries/audio/src/AudioDynamics.h | 19 +++++++++++-------- libraries/audio/src/AudioGate.cpp | 4 ---- 2 files changed, 11 insertions(+), 12 deletions(-) diff --git a/libraries/audio/src/AudioDynamics.h b/libraries/audio/src/AudioDynamics.h index 08daa21348..a759e1c63c 100644 --- a/libraries/audio/src/AudioDynamics.h +++ b/libraries/audio/src/AudioDynamics.h @@ -31,6 +31,9 @@ #define MULQ31(a,b) ((int32_t)(MUL64(a, b) >> 31)) #define MULDIV64(a,b,c) (int32_t)(MUL64(a, b) / (c)) +#define ADDMOD32(a,b) (int32_t)((uint32_t)(a) + (uint32_t)(b)) +#define SUBMOD32(a,b) (int32_t)((uint32_t)(a) - (uint32_t)(b)) + // // on x86 architecture, assume that SSE2 is present // @@ -399,14 +402,14 @@ public: x = MULHI(x, CICGAIN); _buffer[i] = _acc1; - _acc1 += x; // integrator + _acc1 = ADDMOD32(_acc1, x); // integrator i = (i + CIC1 - 1) & MASK; - x = _acc1 - _buffer[i]; // comb + x = SUBMOD32(_acc1, _buffer[i]); // comb _buffer[i] = _acc2; - _acc2 += x; // integrator + _acc2 = ADDMOD32(_acc2, x); // integrator i = (i + CIC2 - 1) & MASK; - x = _acc2 - _buffer[i]; // comb + x = SUBMOD32(_acc2, _buffer[i]); // comb _index = (i + 1) & MASK; // skip unused tap return x; @@ -464,14 +467,14 @@ public: x = MULHI(x, CICGAIN); _buffer[i] = _acc1; - _acc1 += x; // integrator + _acc1 = ADDMOD32(_acc1, x); // integrator i = (i + CIC1 - 1) & MASK; - x = _acc1 - _buffer[i]; // comb + x = SUBMOD32(_acc1, _buffer[i]); // comb _buffer[i] = _acc2; - _acc2 += x; // integrator + _acc2 = ADDMOD32(_acc2, x); // integrator i = (i + CIC2 - 1) & MASK; - x = _acc2 - _buffer[i]; // comb + x = SUBMOD32(_acc2, _buffer[i]); // comb _index = (i + 1) & MASK; // skip unused tap return x; diff --git a/libraries/audio/src/AudioGate.cpp b/libraries/audio/src/AudioGate.cpp index 18884d008a..5b2561da07 100644 --- a/libraries/audio/src/AudioGate.cpp +++ b/libraries/audio/src/AudioGate.cpp @@ -13,10 +13,6 @@ #include #include "AudioDynamics.h" -#ifdef __clang__ -#pragma clang optimize off -#endif - // log2 domain headroom bits above 0dB (int32_t) static const int LOG2_HEADROOM_Q30 = 1; From 82d13090f9a40e6a30372581658663942e6eea8c Mon Sep 17 00:00:00 2001 From: Ken Cooke Date: Thu, 5 Oct 2017 09:28:30 -0700 Subject: [PATCH 49/59] Better comments --- libraries/audio/src/AudioDynamics.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/libraries/audio/src/AudioDynamics.h b/libraries/audio/src/AudioDynamics.h index a759e1c63c..b7c168bfab 100644 --- a/libraries/audio/src/AudioDynamics.h +++ b/libraries/audio/src/AudioDynamics.h @@ -397,6 +397,8 @@ public: // Fast FIR attack/lowpass filter using a 2-stage CIC filter. // The step response reaches final value after N-1 samples. + // NOTE: CIC integrators intentionally overflow, using modulo arithmetic. + // See E. B. Hogenauer, "An economical class of digital filters for decimation and interpolation" const int32_t CICGAIN = 0xffffffff / (CIC1 * CIC2); // Q32 x = MULHI(x, CICGAIN); @@ -462,6 +464,8 @@ public: // Fast FIR attack/lowpass filter using a 2-stage CIC filter. // The step response reaches final value after N-1 samples. + // NOTE: CIC integrators intentionally overflow, using modulo arithmetic. + // See E. B. Hogenauer, "An economical class of digital filters for decimation and interpolation" const int32_t CICGAIN = 0xffffffff / (CIC1 * CIC2); // Q32 x = MULHI(x, CICGAIN); From 8822b1bfa425dc1434d363df542d094543589dc8 Mon Sep 17 00:00:00 2001 From: Ken Cooke Date: Thu, 5 Oct 2017 09:49:38 -0700 Subject: [PATCH 50/59] Minor cleanup --- libraries/audio/src/AudioGate.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/libraries/audio/src/AudioGate.cpp b/libraries/audio/src/AudioGate.cpp index 5b2561da07..13c794b923 100644 --- a/libraries/audio/src/AudioGate.cpp +++ b/libraries/audio/src/AudioGate.cpp @@ -6,12 +6,12 @@ // Copyright 2017 High Fidelity, Inc. // -#include "AudioGate.h" - #include +#include #include -#include + #include "AudioDynamics.h" +#include "AudioGate.h" // log2 domain headroom bits above 0dB (int32_t) static const int LOG2_HEADROOM_Q30 = 1; @@ -418,7 +418,7 @@ void GateMono::process(int16_t* input, int16_t* output, int numFrames) { _dc.process(x); // peak detect - int32_t peak = std::abs(x); + int32_t peak = abs(x); // convert to log2 domain peak = fixlog2(peak); From d605bd9ef4f1da448ccc1561df1cb12d5ce5b480 Mon Sep 17 00:00:00 2001 From: Zach Fox Date: Thu, 5 Oct 2017 11:01:15 -0700 Subject: [PATCH 51/59] Preprocess inventory endpoint result --- .../qml/hifi/commerce/purchases/Purchases.qml | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/interface/resources/qml/hifi/commerce/purchases/Purchases.qml b/interface/resources/qml/hifi/commerce/purchases/Purchases.qml index 0bb1515b69..1f7f2e6e53 100644 --- a/interface/resources/qml/hifi/commerce/purchases/Purchases.qml +++ b/interface/resources/qml/hifi/commerce/purchases/Purchases.qml @@ -81,8 +81,10 @@ Rectangle { if (result.status !== 'success') { console.log("Failed to get purchases", result.message); } else { + var inventoryResult = processInventoryResult(result.data.assets); + purchasesModel.clear(); - purchasesModel.append(result.data.assets); + purchasesModel.append(inventoryResult); if (previousPurchasesModel.count !== 0) { checkIfAnyItemStatusChanged(); @@ -93,7 +95,7 @@ Rectangle { purchasesModel.setProperty(i, "statusChanged", false); } } - previousPurchasesModel.append(result.data.assets); + previousPurchasesModel.append(inventoryResult); buildFilteredPurchasesModel(); @@ -590,6 +592,17 @@ Rectangle { // FUNCTION DEFINITIONS START // + function processInventoryResult(inventory) { + for (var i = 0; i < inventory.length; i++) { + if (inventory[i].status.length > 1) { + console.log("WARNING: Inventory result index " + i + " has a status of length >1!") + } + inventory[i].status = inventory[i].status[0]; + inventory[i].categories = inventory[i].categories.join(';'); + } + return inventory; + } + function populateDisplayedItemCounts() { var itemCountDictionary = {}; var currentItemId; From b3c3b2d34fbab47b720c8a6b1876568433ed8097 Mon Sep 17 00:00:00 2001 From: Cain Kilgore Date: Thu, 5 Oct 2017 19:42:31 +0100 Subject: [PATCH 52/59] Switched Time & Session ID Over --- libraries/shared/src/shared/FileLogger.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libraries/shared/src/shared/FileLogger.cpp b/libraries/shared/src/shared/FileLogger.cpp index b019b69fb8..8ceb378574 100644 --- a/libraries/shared/src/shared/FileLogger.cpp +++ b/libraries/shared/src/shared/FileLogger.cpp @@ -41,7 +41,7 @@ private: -static const QString FILENAME_FORMAT = "hifi-log%1_%2.txt"; +static const QString FILENAME_FORMAT = "hifi-log_%1%2.txt"; static const QString DATETIME_FORMAT = "yyyy-MM-dd_hh.mm.ss"; static const QString LOGS_DIRECTORY = "Logs"; static const QString IPADDR_WILDCARD = "[0-9]*.[0-9]*.[0-9]*.[0-9]*"; @@ -69,7 +69,7 @@ QString getLogRollerFilename() { fileSessionID = "_" + SESSION_ID.toString().replace("{", "").replace("}", ""); } - result.append(QString(FILENAME_FORMAT).arg(fileSessionID, now.toString(DATETIME_FORMAT))); + result.append(QString(FILENAME_FORMAT).arg(now.toString(DATETIME_FORMAT), fileSessionID)); return result; } From 8e8209513502e97c83e8716c0c156300c00ad23b Mon Sep 17 00:00:00 2001 From: Zach Fox Date: Thu, 5 Oct 2017 12:11:31 -0700 Subject: [PATCH 53/59] Number sold and limited run --- .../resources/qml/hifi/commerce/purchases/PurchasedItem.qml | 4 ++++ interface/resources/qml/hifi/commerce/purchases/Purchases.qml | 2 ++ 2 files changed, 6 insertions(+) diff --git a/interface/resources/qml/hifi/commerce/purchases/PurchasedItem.qml b/interface/resources/qml/hifi/commerce/purchases/PurchasedItem.qml index a026a818c0..1e26806b30 100644 --- a/interface/resources/qml/hifi/commerce/purchases/PurchasedItem.qml +++ b/interface/resources/qml/hifi/commerce/purchases/PurchasedItem.qml @@ -36,6 +36,8 @@ Item { property string itemHref; property int displayedItemCount; property int itemEdition; + property int numberSold; + property int limitedRun; property string originalStatusText; property string originalStatusColor; @@ -222,6 +224,8 @@ Item { "PENDING..." } else if (root.purchaseStatus === "invalidated") { "INVALIDATED" + } else if (root.numberSold !== -1) { + ("Sales: " + root.numberSold + "/" + (root.limitedRun === -1 ? "INFTY" : root.limitedRun)) } else { "" } diff --git a/interface/resources/qml/hifi/commerce/purchases/Purchases.qml b/interface/resources/qml/hifi/commerce/purchases/Purchases.qml index 1f7f2e6e53..990fd348c6 100644 --- a/interface/resources/qml/hifi/commerce/purchases/Purchases.qml +++ b/interface/resources/qml/hifi/commerce/purchases/Purchases.qml @@ -430,6 +430,8 @@ Rectangle { purchaseStatus: status; purchaseStatusChanged: statusChanged; itemEdition: model.edition_number; + numberSold: model.number_sold; + limitedRun: model.limited_run; displayedItemCount: model.displayedItemCount; anchors.topMargin: 12; anchors.bottomMargin: 12; From 6b02cbb9112923e90fd92baa91304f1bbd3ebe93 Mon Sep 17 00:00:00 2001 From: SamGondelman Date: Thu, 5 Oct 2017 13:17:57 -0700 Subject: [PATCH 54/59] move locking inside laserpointer and raypick --- interface/src/raypick/LaserPointer.cpp | 56 +++++++++++++++++++ interface/src/raypick/LaserPointer.h | 20 +++---- interface/src/raypick/LaserPointerManager.cpp | 16 ------ interface/src/raypick/RayPick.cpp | 44 +++++++++++++++ interface/src/raypick/RayPick.h | 18 +++--- interface/src/raypick/RayPickManager.cpp | 10 ---- 6 files changed, 119 insertions(+), 45 deletions(-) diff --git a/interface/src/raypick/LaserPointer.cpp b/interface/src/raypick/LaserPointer.cpp index 55ddd01123..0e0f13cd6c 100644 --- a/interface/src/raypick/LaserPointer.cpp +++ b/interface/src/raypick/LaserPointer.cpp @@ -49,11 +49,13 @@ LaserPointer::~LaserPointer() { } void LaserPointer::enable() { + QWriteLocker lock(getLock()); DependencyManager::get()->enableRayPick(_rayPickUID); _renderingEnabled = true; } void LaserPointer::disable() { + QWriteLocker lock(getLock()); DependencyManager::get()->disableRayPick(_rayPickUID); _renderingEnabled = false; if (!_currentRenderState.empty()) { @@ -67,6 +69,7 @@ void LaserPointer::disable() { } void LaserPointer::setRenderState(const std::string& state) { + QWriteLocker lock(getLock()); if (!_currentRenderState.empty() && state != _currentRenderState) { if (_renderStates.find(_currentRenderState) != _renderStates.end()) { disableRenderState(_renderStates[_currentRenderState]); @@ -79,6 +82,7 @@ void LaserPointer::setRenderState(const std::string& state) { } void LaserPointer::editRenderState(const std::string& state, const QVariant& startProps, const QVariant& pathProps, const QVariant& endProps) { + QWriteLocker lock(getLock()); updateRenderStateOverlay(_renderStates[state].getStartID(), startProps); updateRenderStateOverlay(_renderStates[state].getPathID(), pathProps); updateRenderStateOverlay(_renderStates[state].getEndID(), endProps); @@ -92,6 +96,11 @@ void LaserPointer::updateRenderStateOverlay(const OverlayID& id, const QVariant& } } +const RayPickResult LaserPointer::getPrevRayPickResult() { + QReadLocker lock(getLock()); + return DependencyManager::get()->getPrevRayPickResult(_rayPickUID); +} + void LaserPointer::updateRenderState(const RenderState& renderState, const IntersectionType type, const float distance, const QUuid& objectID, const PickRay& pickRay, const bool defaultState) { if (!renderState.getStartID().isNull()) { QVariantMap startProps; @@ -183,6 +192,8 @@ void LaserPointer::disableRenderState(const RenderState& renderState) { } void LaserPointer::update() { + // This only needs to be a read lock because update won't change any of the properties that can be modified from scripts + QReadLocker lock(getLock()); RayPickResult prevRayPickResult = DependencyManager::get()->getPrevRayPickResult(_rayPickUID); if (_renderingEnabled && !_currentRenderState.empty() && _renderStates.find(_currentRenderState) != _renderStates.end() && (prevRayPickResult.type != IntersectionType::NONE || _laserLength > 0.0f || !_objectLockEnd.first.isNull())) { @@ -198,6 +209,51 @@ void LaserPointer::update() { } } +void LaserPointer::setPrecisionPicking(const bool precisionPicking) { + QWriteLocker lock(getLock()); + DependencyManager::get()->setPrecisionPicking(_rayPickUID, precisionPicking); +} + +void LaserPointer::setLaserLength(const float laserLength) { + QWriteLocker lock(getLock()); + _laserLength = laserLength; +} + +void LaserPointer::setLockEndUUID(QUuid objectID, const bool isOverlay) { + QWriteLocker lock(getLock()); + _objectLockEnd = std::pair(objectID, isOverlay); +} + +void LaserPointer::setIgnoreEntities(const QScriptValue& ignoreEntities) { + QWriteLocker lock(getLock()); + DependencyManager::get()->setIgnoreEntities(_rayPickUID, ignoreEntities); +} + +void LaserPointer::setIncludeEntities(const QScriptValue& includeEntities) { + QWriteLocker lock(getLock()); + DependencyManager::get()->setIncludeEntities(_rayPickUID, includeEntities); +} + +void LaserPointer::setIgnoreOverlays(const QScriptValue& ignoreOverlays) { + QWriteLocker lock(getLock()); + DependencyManager::get()->setIgnoreOverlays(_rayPickUID, ignoreOverlays); +} + +void LaserPointer::setIncludeOverlays(const QScriptValue& includeOverlays) { + QWriteLocker lock(getLock()); + DependencyManager::get()->setIncludeOverlays(_rayPickUID, includeOverlays); +} + +void LaserPointer::setIgnoreAvatars(const QScriptValue& ignoreAvatars) { + QWriteLocker lock(getLock()); + DependencyManager::get()->setIgnoreAvatars(_rayPickUID, ignoreAvatars); +} + +void LaserPointer::setIncludeAvatars(const QScriptValue& includeAvatars) { + QWriteLocker lock(getLock()); + DependencyManager::get()->setIncludeAvatars(_rayPickUID, includeAvatars); +} + RenderState::RenderState(const OverlayID& startID, const OverlayID& pathID, const OverlayID& endID) : _startID(startID), _pathID(pathID), _endID(endID) { diff --git a/interface/src/raypick/LaserPointer.h b/interface/src/raypick/LaserPointer.h index fa7d396ae8..01dfe01cfd 100644 --- a/interface/src/raypick/LaserPointer.h +++ b/interface/src/raypick/LaserPointer.h @@ -58,22 +58,22 @@ public: QUuid getRayUID() { return _rayPickUID; } void enable(); void disable(); - const RayPickResult getPrevRayPickResult() { return DependencyManager::get()->getPrevRayPickResult(_rayPickUID); } + const RayPickResult getPrevRayPickResult(); void setRenderState(const std::string& state); // You cannot use editRenderState to change the overlay type of any part of the laser pointer. You can only edit the properties of the existing overlays. void editRenderState(const std::string& state, const QVariant& startProps, const QVariant& pathProps, const QVariant& endProps); - void setPrecisionPicking(const bool precisionPicking) { DependencyManager::get()->setPrecisionPicking(_rayPickUID, precisionPicking); } - void setLaserLength(const float laserLength) { _laserLength = laserLength; } - void setIgnoreEntities(const QScriptValue& ignoreEntities) { DependencyManager::get()->setIgnoreEntities(_rayPickUID, ignoreEntities); } - void setIncludeEntities(const QScriptValue& includeEntities) { DependencyManager::get()->setIncludeEntities(_rayPickUID, includeEntities); } - void setIgnoreOverlays(const QScriptValue& ignoreOverlays) { DependencyManager::get()->setIgnoreOverlays(_rayPickUID, ignoreOverlays); } - void setIncludeOverlays(const QScriptValue& includeOverlays) { DependencyManager::get()->setIncludeOverlays(_rayPickUID, includeOverlays); } - void setIgnoreAvatars(const QScriptValue& ignoreAvatars) { DependencyManager::get()->setIgnoreAvatars(_rayPickUID, ignoreAvatars); } - void setIncludeAvatars(const QScriptValue& includeAvatars) { DependencyManager::get()->setIncludeAvatars(_rayPickUID, includeAvatars); } + void setPrecisionPicking(const bool precisionPicking); + void setLaserLength(const float laserLength); + void setLockEndUUID(QUuid objectID, const bool isOverlay); - void setLockEndUUID(QUuid objectID, const bool isOverlay) { _objectLockEnd = std::pair(objectID, isOverlay); } + void setIgnoreEntities(const QScriptValue& ignoreEntities); + void setIncludeEntities(const QScriptValue& includeEntities); + void setIgnoreOverlays(const QScriptValue& ignoreOverlays); + void setIncludeOverlays(const QScriptValue& includeOverlays); + void setIgnoreAvatars(const QScriptValue& ignoreAvatars); + void setIncludeAvatars(const QScriptValue& includeAvatars); QReadWriteLock* getLock() { return &_lock; } diff --git a/interface/src/raypick/LaserPointerManager.cpp b/interface/src/raypick/LaserPointerManager.cpp index 387f88724e..8615a96c3f 100644 --- a/interface/src/raypick/LaserPointerManager.cpp +++ b/interface/src/raypick/LaserPointerManager.cpp @@ -31,7 +31,6 @@ void LaserPointerManager::enableLaserPointer(const QUuid uid) { QReadLocker lock(&_containsLock); auto laserPointer = _laserPointers.find(uid); if (laserPointer != _laserPointers.end()) { - QWriteLocker laserLock(laserPointer.value()->getLock()); laserPointer.value()->enable(); } } @@ -40,7 +39,6 @@ void LaserPointerManager::disableLaserPointer(const QUuid uid) { QReadLocker lock(&_containsLock); auto laserPointer = _laserPointers.find(uid); if (laserPointer != _laserPointers.end()) { - QWriteLocker laserLock(laserPointer.value()->getLock()); laserPointer.value()->disable(); } } @@ -49,7 +47,6 @@ void LaserPointerManager::setRenderState(QUuid uid, const std::string& renderSta QReadLocker lock(&_containsLock); auto laserPointer = _laserPointers.find(uid); if (laserPointer != _laserPointers.end()) { - QWriteLocker laserLock(laserPointer.value()->getLock()); laserPointer.value()->setRenderState(renderState); } } @@ -58,7 +55,6 @@ void LaserPointerManager::editRenderState(QUuid uid, const std::string& state, c QReadLocker lock(&_containsLock); auto laserPointer = _laserPointers.find(uid); if (laserPointer != _laserPointers.end()) { - QWriteLocker laserLock(laserPointer.value()->getLock()); laserPointer.value()->editRenderState(state, startProps, pathProps, endProps); } } @@ -67,7 +63,6 @@ const RayPickResult LaserPointerManager::getPrevRayPickResult(const QUuid uid) { QReadLocker lock(&_containsLock); auto laserPointer = _laserPointers.find(uid); if (laserPointer != _laserPointers.end()) { - QReadLocker laserLock(laserPointer.value()->getLock()); return laserPointer.value()->getPrevRayPickResult(); } return RayPickResult(); @@ -76,9 +71,7 @@ const RayPickResult LaserPointerManager::getPrevRayPickResult(const QUuid uid) { void LaserPointerManager::update() { QReadLocker lock(&_containsLock); for (QUuid& uid : _laserPointers.keys()) { - // This only needs to be a read lock because update won't change any of the properties that can be modified from scripts auto laserPointer = _laserPointers.find(uid); - QReadLocker laserLock(laserPointer.value()->getLock()); laserPointer.value()->update(); } } @@ -87,7 +80,6 @@ void LaserPointerManager::setPrecisionPicking(QUuid uid, const bool precisionPic QReadLocker lock(&_containsLock); auto laserPointer = _laserPointers.find(uid); if (laserPointer != _laserPointers.end()) { - QWriteLocker laserLock(laserPointer.value()->getLock()); laserPointer.value()->setPrecisionPicking(precisionPicking); } } @@ -96,7 +88,6 @@ void LaserPointerManager::setLaserLength(QUuid uid, const float laserLength) { QReadLocker lock(&_containsLock); auto laserPointer = _laserPointers.find(uid); if (laserPointer != _laserPointers.end()) { - QWriteLocker laserLock(laserPointer.value()->getLock()); laserPointer.value()->setLaserLength(laserLength); } } @@ -105,7 +96,6 @@ void LaserPointerManager::setIgnoreEntities(QUuid uid, const QScriptValue& ignor QReadLocker lock(&_containsLock); auto laserPointer = _laserPointers.find(uid); if (laserPointer != _laserPointers.end()) { - QWriteLocker laserLock(laserPointer.value()->getLock()); laserPointer.value()->setIgnoreEntities(ignoreEntities); } } @@ -114,7 +104,6 @@ void LaserPointerManager::setIncludeEntities(QUuid uid, const QScriptValue& incl QReadLocker lock(&_containsLock); auto laserPointer = _laserPointers.find(uid); if (laserPointer != _laserPointers.end()) { - QWriteLocker laserLock(laserPointer.value()->getLock()); laserPointer.value()->setIncludeEntities(includeEntities); } } @@ -123,7 +112,6 @@ void LaserPointerManager::setIgnoreOverlays(QUuid uid, const QScriptValue& ignor QReadLocker lock(&_containsLock); auto laserPointer = _laserPointers.find(uid); if (laserPointer != _laserPointers.end()) { - QWriteLocker laserLock(laserPointer.value()->getLock()); laserPointer.value()->setIgnoreOverlays(ignoreOverlays); } } @@ -132,7 +120,6 @@ void LaserPointerManager::setIncludeOverlays(QUuid uid, const QScriptValue& incl QReadLocker lock(&_containsLock); auto laserPointer = _laserPointers.find(uid); if (laserPointer != _laserPointers.end()) { - QWriteLocker laserLock(laserPointer.value()->getLock()); laserPointer.value()->setIncludeOverlays(includeOverlays); } } @@ -141,7 +128,6 @@ void LaserPointerManager::setIgnoreAvatars(QUuid uid, const QScriptValue& ignore QReadLocker lock(&_containsLock); auto laserPointer = _laserPointers.find(uid); if (laserPointer != _laserPointers.end()) { - QWriteLocker laserLock(laserPointer.value()->getLock()); laserPointer.value()->setIgnoreAvatars(ignoreAvatars); } } @@ -150,7 +136,6 @@ void LaserPointerManager::setIncludeAvatars(QUuid uid, const QScriptValue& inclu QReadLocker lock(&_containsLock); auto laserPointer = _laserPointers.find(uid); if (laserPointer != _laserPointers.end()) { - QWriteLocker laserLock(laserPointer.value()->getLock()); laserPointer.value()->setIncludeAvatars(includeAvatars); } } @@ -159,7 +144,6 @@ void LaserPointerManager::setLockEndUUID(QUuid uid, QUuid objectID, const bool i QReadLocker lock(&_containsLock); auto laserPointer = _laserPointers.find(uid); if (laserPointer != _laserPointers.end()) { - QWriteLocker laserLock(laserPointer.value()->getLock()); laserPointer.value()->setLockEndUUID(objectID, isOverlay); } } diff --git a/interface/src/raypick/RayPick.cpp b/interface/src/raypick/RayPick.cpp index 70170a8f85..a5b1299210 100644 --- a/interface/src/raypick/RayPick.cpp +++ b/interface/src/raypick/RayPick.cpp @@ -16,3 +16,47 @@ RayPick::RayPick(const RayPickFilter& filter, const float maxDistance, const boo _enabled(enabled) { } +void RayPick::enable() { + QWriteLocker lock(getLock()); + _enabled = true; +} + +void RayPick::disable() { + QWriteLocker lock(getLock()); + _enabled = false; +} + +const RayPickResult& RayPick::getPrevRayPickResult() { + QReadLocker lock(getLock()); + return _prevResult; +} + +void RayPick::setIgnoreEntities(const QScriptValue& ignoreEntities) { + QWriteLocker lock(getLock()); + _ignoreEntities = qVectorEntityItemIDFromScriptValue(ignoreEntities); +} + +void RayPick::setIncludeEntities(const QScriptValue& includeEntities) { + QWriteLocker lock(getLock()); + _includeEntities = qVectorEntityItemIDFromScriptValue(includeEntities); +} + +void RayPick::setIgnoreOverlays(const QScriptValue& ignoreOverlays) { + QWriteLocker lock(getLock()); + _ignoreOverlays = qVectorOverlayIDFromScriptValue(ignoreOverlays); +} + +void RayPick::setIncludeOverlays(const QScriptValue& includeOverlays) { + QWriteLocker lock(getLock()); + _includeOverlays = qVectorOverlayIDFromScriptValue(includeOverlays); +} + +void RayPick::setIgnoreAvatars(const QScriptValue& ignoreAvatars) { + QWriteLocker lock(getLock()); + _ignoreAvatars = qVectorEntityItemIDFromScriptValue(ignoreAvatars); +} + +void RayPick::setIncludeAvatars(const QScriptValue& includeAvatars) { + QWriteLocker lock(getLock()); + _includeAvatars = qVectorEntityItemIDFromScriptValue(includeAvatars); +} \ No newline at end of file diff --git a/interface/src/raypick/RayPick.h b/interface/src/raypick/RayPick.h index 428e44d670..6dacc084b4 100644 --- a/interface/src/raypick/RayPick.h +++ b/interface/src/raypick/RayPick.h @@ -103,13 +103,13 @@ public: virtual const PickRay getPickRay(bool& valid) const = 0; - void enable() { _enabled = true; } - void disable() { _enabled = false; } + void enable(); + void disable(); const RayPickFilter& getFilter() { return _filter; } float getMaxDistance() { return _maxDistance; } bool isEnabled() { return _enabled; } - const RayPickResult& getPrevRayPickResult() { return _prevResult; } + const RayPickResult& getPrevRayPickResult(); void setPrecisionPicking(bool precisionPicking) { _filter.setFlag(RayPickFilter::PICK_COURSE, !precisionPicking); } @@ -121,12 +121,12 @@ public: const QVector& getIncludeOverlays() { return _includeOverlays; } const QVector& getIgnoreAvatars() { return _ignoreAvatars; } const QVector& getIncludeAvatars() { return _includeAvatars; } - void setIgnoreEntities(const QScriptValue& ignoreEntities) { _ignoreEntities = qVectorEntityItemIDFromScriptValue(ignoreEntities); } - void setIncludeEntities(const QScriptValue& includeEntities) { _includeEntities = qVectorEntityItemIDFromScriptValue(includeEntities); } - void setIgnoreOverlays(const QScriptValue& ignoreOverlays) { _ignoreOverlays = qVectorOverlayIDFromScriptValue(ignoreOverlays); } - void setIncludeOverlays(const QScriptValue& includeOverlays) { _includeOverlays = qVectorOverlayIDFromScriptValue(includeOverlays); } - void setIgnoreAvatars(const QScriptValue& ignoreAvatars) { _ignoreAvatars = qVectorEntityItemIDFromScriptValue(ignoreAvatars); } - void setIncludeAvatars(const QScriptValue& includeAvatars) { _includeAvatars = qVectorEntityItemIDFromScriptValue(includeAvatars); } + void setIgnoreEntities(const QScriptValue& ignoreEntities); + void setIncludeEntities(const QScriptValue& includeEntities); + void setIgnoreOverlays(const QScriptValue& ignoreOverlays); + void setIncludeOverlays(const QScriptValue& includeOverlays); + void setIgnoreAvatars(const QScriptValue& ignoreAvatars); + void setIncludeAvatars(const QScriptValue& includeAvatars); QReadWriteLock* getLock() { return &_lock; } diff --git a/interface/src/raypick/RayPickManager.cpp b/interface/src/raypick/RayPickManager.cpp index 65f82dcd5f..1728ecd01a 100644 --- a/interface/src/raypick/RayPickManager.cpp +++ b/interface/src/raypick/RayPickManager.cpp @@ -153,7 +153,6 @@ void RayPickManager::enableRayPick(const QUuid uid) { QReadLocker containsLock(&_containsLock); auto rayPick = _rayPicks.find(uid); if (rayPick != _rayPicks.end()) { - QWriteLocker rayPickLock(rayPick.value()->getLock()); rayPick.value()->enable(); } } @@ -162,7 +161,6 @@ void RayPickManager::disableRayPick(const QUuid uid) { QReadLocker containsLock(&_containsLock); auto rayPick = _rayPicks.find(uid); if (rayPick != _rayPicks.end()) { - QWriteLocker rayPickLock(rayPick.value()->getLock()); rayPick.value()->disable(); } } @@ -171,7 +169,6 @@ const RayPickResult RayPickManager::getPrevRayPickResult(const QUuid uid) { QReadLocker containsLock(&_containsLock); auto rayPick = _rayPicks.find(uid); if (rayPick != _rayPicks.end()) { - QReadLocker lock(rayPick.value()->getLock()); return rayPick.value()->getPrevRayPickResult(); } return RayPickResult(); @@ -181,7 +178,6 @@ void RayPickManager::setPrecisionPicking(QUuid uid, const bool precisionPicking) QReadLocker containsLock(&_containsLock); auto rayPick = _rayPicks.find(uid); if (rayPick != _rayPicks.end()) { - QWriteLocker lock(rayPick.value()->getLock()); rayPick.value()->setPrecisionPicking(precisionPicking); } } @@ -190,7 +186,6 @@ void RayPickManager::setIgnoreEntities(QUuid uid, const QScriptValue& ignoreEnti QReadLocker containsLock(&_containsLock); auto rayPick = _rayPicks.find(uid); if (rayPick != _rayPicks.end()) { - QWriteLocker lock(rayPick.value()->getLock()); rayPick.value()->setIgnoreEntities(ignoreEntities); } } @@ -199,7 +194,6 @@ void RayPickManager::setIncludeEntities(QUuid uid, const QScriptValue& includeEn QReadLocker containsLock(&_containsLock); auto rayPick = _rayPicks.find(uid); if (rayPick != _rayPicks.end()) { - QWriteLocker lock(rayPick.value()->getLock()); rayPick.value()->setIncludeEntities(includeEntities); } } @@ -208,7 +202,6 @@ void RayPickManager::setIgnoreOverlays(QUuid uid, const QScriptValue& ignoreOver QReadLocker containsLock(&_containsLock); auto rayPick = _rayPicks.find(uid); if (rayPick != _rayPicks.end()) { - QWriteLocker lock(rayPick.value()->getLock()); rayPick.value()->setIgnoreOverlays(ignoreOverlays); } } @@ -217,7 +210,6 @@ void RayPickManager::setIncludeOverlays(QUuid uid, const QScriptValue& includeOv QReadLocker containsLock(&_containsLock); auto rayPick = _rayPicks.find(uid); if (rayPick != _rayPicks.end()) { - QWriteLocker lock(rayPick.value()->getLock()); rayPick.value()->setIncludeOverlays(includeOverlays); } } @@ -226,7 +218,6 @@ void RayPickManager::setIgnoreAvatars(QUuid uid, const QScriptValue& ignoreAvata QReadLocker containsLock(&_containsLock); auto rayPick = _rayPicks.find(uid); if (rayPick != _rayPicks.end()) { - QWriteLocker lock(rayPick.value()->getLock()); rayPick.value()->setIgnoreAvatars(ignoreAvatars); } } @@ -235,7 +226,6 @@ void RayPickManager::setIncludeAvatars(QUuid uid, const QScriptValue& includeAva QReadLocker containsLock(&_containsLock); auto rayPick = _rayPicks.find(uid); if (rayPick != _rayPicks.end()) { - QWriteLocker lock(rayPick.value()->getLock()); rayPick.value()->setIncludeAvatars(includeAvatars); } } \ No newline at end of file From 9290a516851f7e70a437468cc313752baa65e504 Mon Sep 17 00:00:00 2001 From: Zach Fox Date: Thu, 5 Oct 2017 14:03:56 -0700 Subject: [PATCH 55/59] Fix confirmed text --- .../resources/qml/hifi/commerce/purchases/PurchasedItem.qml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/interface/resources/qml/hifi/commerce/purchases/PurchasedItem.qml b/interface/resources/qml/hifi/commerce/purchases/PurchasedItem.qml index 1e26806b30..5eb5516519 100644 --- a/interface/resources/qml/hifi/commerce/purchases/PurchasedItem.qml +++ b/interface/resources/qml/hifi/commerce/purchases/PurchasedItem.qml @@ -52,7 +52,6 @@ Item { statusText.text = "CONFIRMED!"; statusText.color = hifi.colors.blueAccent; confirmedTimer.start(); - root.purchaseStatusChanged = false; } } @@ -62,6 +61,7 @@ Item { onTriggered: { statusText.text = root.originalStatusText; statusText.color = root.originalStatusColor; + root.purchaseStatusChanged = false; } } @@ -205,7 +205,7 @@ Item { Item { id: statusContainer; - visible: root.purchaseStatus === "pending" || root.purchaseStatus === "invalidated"; + visible: root.purchaseStatus === "pending" || root.purchaseStatus === "invalidated" || root.purchaseStatusChanged; anchors.left: itemName.left; anchors.top: certificateContainer.bottom; anchors.topMargin: 8; From 0b600a74c3b6990e4caf90bb9c9adbfccc582163 Mon Sep 17 00:00:00 2001 From: Zach Fox Date: Thu, 5 Oct 2017 14:34:53 -0700 Subject: [PATCH 56/59] Fix passphrase input focus problem; fix getting inventory and balance after logging in on Checkout --- interface/resources/qml/hifi/commerce/checkout/Checkout.qml | 4 ++++ .../qml/hifi/commerce/common/EmulatedMarketplaceHeader.qml | 2 +- .../resources/qml/hifi/commerce/wallet/PassphraseModal.qml | 4 +++- 3 files changed, 8 insertions(+), 2 deletions(-) diff --git a/interface/resources/qml/hifi/commerce/checkout/Checkout.qml b/interface/resources/qml/hifi/commerce/checkout/Checkout.qml index 32f324aea9..09c2f6fa76 100644 --- a/interface/resources/qml/hifi/commerce/checkout/Checkout.qml +++ b/interface/resources/qml/hifi/commerce/checkout/Checkout.qml @@ -892,6 +892,10 @@ Rectangle { } else { root.activeView = "checkoutSuccess"; } + root.balanceReceived = false; + root.purchasesReceived = false; + commerce.inventory(); + commerce.balance(); } // diff --git a/interface/resources/qml/hifi/commerce/common/EmulatedMarketplaceHeader.qml b/interface/resources/qml/hifi/commerce/common/EmulatedMarketplaceHeader.qml index 420b51ba15..cc316a70e9 100644 --- a/interface/resources/qml/hifi/commerce/common/EmulatedMarketplaceHeader.qml +++ b/interface/resources/qml/hifi/commerce/common/EmulatedMarketplaceHeader.qml @@ -39,7 +39,7 @@ Item { sendToParent({method: "needsLogIn"}); } else if (walletStatus === 3) { commerce.getSecurityImage(); - } else { + } else if (walletStatus > 3) { console.log("ERROR in EmulatedMarketplaceHeader.qml: Unknown wallet status: " + walletStatus); } } diff --git a/interface/resources/qml/hifi/commerce/wallet/PassphraseModal.qml b/interface/resources/qml/hifi/commerce/wallet/PassphraseModal.qml index 5bd88ba790..8d5d9f97de 100644 --- a/interface/resources/qml/hifi/commerce/wallet/PassphraseModal.qml +++ b/interface/resources/qml/hifi/commerce/wallet/PassphraseModal.qml @@ -197,6 +197,8 @@ Item { height: 50; echoMode: TextInput.Password; placeholderText: "passphrase"; + activeFocusOnPress: true; + activeFocusOnTab: true; onFocusChanged: { root.keyboardRaised = focus; @@ -206,8 +208,8 @@ Item { anchors.fill: parent; onClicked: { - parent.focus = true; root.keyboardRaised = true; + mouse.accepted = false; } } From ba50fcc5097835c443f9e753e9888d1ab3aa6069 Mon Sep 17 00:00:00 2001 From: druiz17 Date: Thu, 5 Oct 2017 15:07:49 -0700 Subject: [PATCH 57/59] fix mouse dissapearing in desktop mode --- scripts/system/controllers/controllerModules/mouseHMD.js | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/scripts/system/controllers/controllerModules/mouseHMD.js b/scripts/system/controllers/controllerModules/mouseHMD.js index 9ccf4912a1..ed0bc03223 100644 --- a/scripts/system/controllers/controllerModules/mouseHMD.js +++ b/scripts/system/controllers/controllerModules/mouseHMD.js @@ -115,7 +115,12 @@ this.run = function(controllerData, deltaTime) { var now = Date.now(); if (this.mouseActivity.expired(now) || this.triggersPressed(controllerData, now)) { - Reticle.visible = false; + if (!HMD.active) { + Reticle.visible = true; + } else { + Reticle.visible = false; + } + return ControllerDispatcherUtils.makeRunningValues(false, [], []); } this.adjustReticleDepth(controllerData); From 3139f5ef2a2b29c4b6e4328b59bf7679256bec54 Mon Sep 17 00:00:00 2001 From: druiz17 Date: Thu, 5 Oct 2017 15:12:58 -0700 Subject: [PATCH 58/59] improve mouseHMD exit logic --- scripts/system/controllers/controllerModules/mouseHMD.js | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/scripts/system/controllers/controllerModules/mouseHMD.js b/scripts/system/controllers/controllerModules/mouseHMD.js index ed0bc03223..1d8aeee1f9 100644 --- a/scripts/system/controllers/controllerModules/mouseHMD.js +++ b/scripts/system/controllers/controllerModules/mouseHMD.js @@ -114,8 +114,9 @@ this.run = function(controllerData, deltaTime) { var now = Date.now(); - if (this.mouseActivity.expired(now) || this.triggersPressed(controllerData, now)) { - if (!HMD.active) { + var hmdActive = HMD.active; + if (this.mouseActivity.expired(now) || this.triggersPressed(controllerData, now) || !hmdActive) { + if (!hmdActive) { Reticle.visible = true; } else { Reticle.visible = false; From 525e0d8f61418a567e6f15d0f602f67e8be78279 Mon Sep 17 00:00:00 2001 From: Zach Fox Date: Thu, 5 Oct 2017 16:51:13 -0700 Subject: [PATCH 59/59] Make SettingsScriptingInterface accessible to tablet --- interface/src/ui/overlays/Web3DOverlay.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/interface/src/ui/overlays/Web3DOverlay.cpp b/interface/src/ui/overlays/Web3DOverlay.cpp index 811e169faf..526890b9c1 100644 --- a/interface/src/ui/overlays/Web3DOverlay.cpp +++ b/interface/src/ui/overlays/Web3DOverlay.cpp @@ -40,6 +40,7 @@ #include "scripting/HMDScriptingInterface.h" #include "scripting/AssetMappingsScriptingInterface.h" #include "scripting/MenuScriptingInterface.h" +#include "scripting/SettingsScriptingInterface.h" #include #include #include "FileDialogHelper.h" @@ -243,6 +244,7 @@ void Web3DOverlay::setupQmlSurface() { _webSurface->getSurfaceContext()->setContextProperty("InputConfiguration", DependencyManager::get().data()); _webSurface->getSurfaceContext()->setContextProperty("SoundCache", DependencyManager::get().data()); _webSurface->getSurfaceContext()->setContextProperty("MenuInterface", MenuScriptingInterface::getInstance()); + _webSurface->getSurfaceContext()->setContextProperty("Settings", SettingsScriptingInterface::getInstance()); _webSurface->getSurfaceContext()->setContextProperty("pathToFonts", "../../");