From f81836c8300ee89146f07b4757d392f3f79bcc3a Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Mon, 9 Apr 2018 18:28:59 -0700 Subject: [PATCH 01/14] support specification of named landing-points in serverless-domain json files --- interface/src/Application.cpp | 3 +++ libraries/entities/src/EntityTree.cpp | 12 ++++++++++++ libraries/entities/src/EntityTree.h | 4 ++++ libraries/networking/src/AddressManager.cpp | 12 ++++++++++-- libraries/networking/src/DomainHandler.cpp | 15 +++++++++++---- libraries/networking/src/DomainHandler.h | 6 +++++- libraries/networking/src/NodeList.cpp | 20 ++++++++++++++++---- 7 files changed, 61 insertions(+), 11 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 18ba881573..9a97e9a42f 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -3146,6 +3146,9 @@ void Application::loadServerlessDomain(QUrl domainURL) { tmpTree->sendEntities(&_entityEditSender, getEntities()->getTree(), 0, 0, 0); } + std::map namedPaths = tmpTree->getNamedPaths(); + nodeList->getDomainHandler().setIsConnected(true, namedPaths); + _fullSceneReceivedCounter++; } diff --git a/libraries/entities/src/EntityTree.cpp b/libraries/entities/src/EntityTree.cpp index 2cf66911a4..d5c7b9c2d6 100644 --- a/libraries/entities/src/EntityTree.cpp +++ b/libraries/entities/src/EntityTree.cpp @@ -2303,6 +2303,18 @@ bool EntityTree::readFromMap(QVariantMap& map) { _persistDataVersion = map["DataVersion"].toInt(); } + _namedPaths.clear(); + if (map.contains("Paths")) { + QVariantMap namedPathsMap = map["Paths"].toMap(); + for(QVariantMap::const_iterator iter = namedPathsMap.begin(); iter != namedPathsMap.end(); ++iter) { + QString namedPathName = iter.key(); + QString namedPathViewPoint = iter.value().toString(); + _namedPaths[namedPathName] = namedPathViewPoint; + } + } else { + _namedPaths["/"] = "/"; + } + // map will have a top-level list keyed as "Entities". This will be extracted // and iterated over. Each member of this list is converted to a QVariantMap, then // to a QScriptValue, and then to EntityItemProperties. These properties are used diff --git a/libraries/entities/src/EntityTree.h b/libraries/entities/src/EntityTree.h index 5f69714432..791c030fc8 100644 --- a/libraries/entities/src/EntityTree.h +++ b/libraries/entities/src/EntityTree.h @@ -301,6 +301,8 @@ public: static bool addMaterialToOverlay(const QUuid& overlayID, graphics::MaterialLayer material, const std::string& parentMaterialName); static bool removeMaterialFromOverlay(const QUuid& overlayID, graphics::MaterialPointer material, const std::string& parentMaterialName); + std::map getNamedPaths() const { return _namedPaths; } + signals: void deletingEntity(const EntityItemID& entityID); void deletingEntityPointer(EntityItem* entityID); @@ -417,6 +419,8 @@ private: static std::function _removeMaterialFromOverlayOperator; bool _serverlessDomain { false }; + + std::map _namedPaths; }; #endif // hifi_EntityTree_h diff --git a/libraries/networking/src/AddressManager.cpp b/libraries/networking/src/AddressManager.cpp index 3c24cc796c..56b148a43c 100644 --- a/libraries/networking/src/AddressManager.cpp +++ b/libraries/networking/src/AddressManager.cpp @@ -29,7 +29,7 @@ #include "UserActivityLogger.h" #include "udt/PacketHeaders.h" -const QString DEFAULT_HIFI_ADDRESS = "file:///~/serverless/tutorial.json"; +const QString DEFAULT_HIFI_ADDRESS = "file:///~/serverless/tutorial.json?location=/"; const QString ADDRESS_MANAGER_SETTINGS_GROUP = "AddressManager"; const QString SETTINGS_CURRENT_ADDRESS_KEY = "address"; @@ -312,7 +312,15 @@ bool AddressManager::handleUrl(const QUrl& lookupUrl, LookupTrigger trigger) { _shareablePlaceName.clear(); setDomainInfo(lookupUrl, trigger); emit lookupResultsFinished(); - handlePath(DOMAIN_SPAWNING_POINT, LookupTrigger::Internal, false); + + QString path = DOMAIN_SPAWNING_POINT; + QUrlQuery queryArgs(lookupUrl); + const QString LOCATION_QUERY_KEY = "location"; + if (queryArgs.hasQueryItem(LOCATION_QUERY_KEY)) { + path = queryArgs.queryItemValue(LOCATION_QUERY_KEY); + } + + handlePath(path, LookupTrigger::Internal, false); return true; } diff --git a/libraries/networking/src/DomainHandler.cpp b/libraries/networking/src/DomainHandler.cpp index c20d6d73be..fe3b0abcb7 100644 --- a/libraries/networking/src/DomainHandler.cpp +++ b/libraries/networking/src/DomainHandler.cpp @@ -173,9 +173,7 @@ void DomainHandler::setURLAndID(QUrl domainURL, QUuid domainID) { QString previousHost = _domainURL.host(); _domainURL = domainURL; - if (domainURL.scheme() != URL_SCHEME_HIFI) { - setIsConnected(true); - } else if (previousHost != domainURL.host()) { + if (previousHost != domainURL.host()) { qCDebug(networking) << "Updated domain hostname to" << domainURL.host(); if (!domainURL.host().isEmpty()) { @@ -250,6 +248,14 @@ void DomainHandler::activateICEPublicSocket() { emit completedSocketDiscovery(); } +QString DomainHandler::getViewPointFromNamedPath(QString namedPath) { + auto lookup = _namedPaths.find(namedPath); + if (lookup != _namedPaths.end()) { + return lookup->second; + } + return DOMAIN_SPAWNING_POINT; +} + void DomainHandler::completedHostnameLookup(const QHostInfo& hostInfo) { for (int i = 0; i < hostInfo.addresses().size(); i++) { if (hostInfo.addresses()[i].protocol() == QAbstractSocket::IPv4Protocol) { @@ -279,7 +285,8 @@ void DomainHandler::completedIceServerHostnameLookup() { emit iceSocketAndIDReceived(); } -void DomainHandler::setIsConnected(bool isConnected) { +void DomainHandler::setIsConnected(bool isConnected, std::map namedPaths) { + _namedPaths = namedPaths; if (_isConnected != isConnected) { _isConnected = isConnected; diff --git a/libraries/networking/src/DomainHandler.h b/libraries/networking/src/DomainHandler.h index fbc60e2492..760b2f8235 100644 --- a/libraries/networking/src/DomainHandler.h +++ b/libraries/networking/src/DomainHandler.h @@ -73,9 +73,11 @@ public: void activateICEPublicSocket(); bool isConnected() const { return _isConnected; } - void setIsConnected(bool isConnected); + void setIsConnected(bool isConnected, std::map namedPaths = std::map()); bool isServerless() const { return _domainURL.scheme() != URL_SCHEME_HIFI; } + QString getViewPointFromNamedPath(QString namedPath); + bool hasSettings() const { return !_settingsObject.isEmpty(); } void requestDomainSettings(); const QJsonObject& getSettingsObject() const { return _settingsObject; } @@ -200,6 +202,8 @@ private: int _checkInPacketsSinceLastReply { 0 }; QTimer _apiRefreshTimer; + + std::map _namedPaths; }; const QString DOMAIN_SPAWNING_POINT { "/0, -10, 0" }; diff --git a/libraries/networking/src/NodeList.cpp b/libraries/networking/src/NodeList.cpp index cb0d2e4cd5..3c2b4cd336 100644 --- a/libraries/networking/src/NodeList.cpp +++ b/libraries/networking/src/NodeList.cpp @@ -413,7 +413,14 @@ void NodeList::sendDomainServerCheckIn() { } void NodeList::handleDSPathQuery(const QString& newPath) { - if (_domainHandler.isSocketKnown()) { + if (_domainHandler.isServerless()) { + if (_domainHandler.isConnected()) { + auto viewpoint = _domainHandler.getViewPointFromNamedPath(newPath); + DependencyManager::get()->goToViewpointForPath(viewpoint, newPath); + } else { + _domainHandler.setPendingPath(newPath); + } + } else if (_domainHandler.isSocketKnown()) { // if we have a DS socket we assume it will get this packet and send if off right away sendDSPathQuery(newPath); } else { @@ -427,10 +434,15 @@ void NodeList::sendPendingDSPathQuery() { QString pendingPath = _domainHandler.getPendingPath(); if (!pendingPath.isEmpty()) { - qCDebug(networking) << "Attempting to send pending query to DS for path" << pendingPath; - // this is a slot triggered if we just established a network link with a DS and want to send a path query - sendDSPathQuery(_domainHandler.getPendingPath()); + if (_domainHandler.isServerless()) { + auto viewpoint = _domainHandler.getViewPointFromNamedPath(pendingPath); + DependencyManager::get()->goToViewpointForPath(viewpoint, pendingPath); + } else { + qCDebug(networking) << "Attempting to send pending query to DS for path" << pendingPath; + // this is a slot triggered if we just established a network link with a DS and want to send a path query + sendDSPathQuery(_domainHandler.getPendingPath()); + } // clear whatever the pending path was _domainHandler.clearPendingPath(); From ee3e8093e18bd06f1564e594bd6b882aeea228d4 Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Tue, 10 Apr 2018 10:19:35 -0700 Subject: [PATCH 02/14] update tutorial content to include default landing-point --- cmake/externals/serverless-content/CMakeLists.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cmake/externals/serverless-content/CMakeLists.txt b/cmake/externals/serverless-content/CMakeLists.txt index 4d0773f5f5..6235205aad 100644 --- a/cmake/externals/serverless-content/CMakeLists.txt +++ b/cmake/externals/serverless-content/CMakeLists.txt @@ -4,8 +4,8 @@ set(EXTERNAL_NAME serverless-content) ExternalProject_Add( ${EXTERNAL_NAME} - URL http://cdn.highfidelity.com/content-sets/serverless-tutorial-RC66-v2.zip - URL_MD5 d76bdb3e2bf7ae5d20115bd97b0c44a8 + URL http://cdn.highfidelity.com/content-sets/serverless-tutorial-RC67.zip + URL_MD5 3fc4b7332be771d71b43b6d688de9aa7 CONFIGURE_COMMAND "" BUILD_COMMAND "" INSTALL_COMMAND "" From a56f3f4a1029742fd668d9283f241ace9fc4138a Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Thu, 12 Apr 2018 19:06:12 -0700 Subject: [PATCH 03/14] code review --- interface/src/Application.cpp | 3 ++- libraries/networking/src/AddressManager.cpp | 4 +++- libraries/networking/src/DomainHandler.cpp | 21 +++++++++++++++------ libraries/networking/src/DomainHandler.h | 6 ++++-- 4 files changed, 24 insertions(+), 10 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 9a97e9a42f..37fd2da56f 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -3147,7 +3147,8 @@ void Application::loadServerlessDomain(QUrl domainURL) { } std::map namedPaths = tmpTree->getNamedPaths(); - nodeList->getDomainHandler().setIsConnected(true, namedPaths); + nodeList->getDomainHandler().connectedToServerless(namedPaths); + _fullSceneReceivedCounter++; } diff --git a/libraries/networking/src/AddressManager.cpp b/libraries/networking/src/AddressManager.cpp index 56b148a43c..431a2e8ad5 100644 --- a/libraries/networking/src/AddressManager.cpp +++ b/libraries/networking/src/AddressManager.cpp @@ -29,7 +29,7 @@ #include "UserActivityLogger.h" #include "udt/PacketHeaders.h" -const QString DEFAULT_HIFI_ADDRESS = "file:///~/serverless/tutorial.json?location=/"; +const QString DEFAULT_HIFI_ADDRESS = "file:///~/serverless/tutorial.json"; const QString ADDRESS_MANAGER_SETTINGS_GROUP = "AddressManager"; const QString SETTINGS_CURRENT_ADDRESS_KEY = "address"; @@ -318,6 +318,8 @@ bool AddressManager::handleUrl(const QUrl& lookupUrl, LookupTrigger trigger) { const QString LOCATION_QUERY_KEY = "location"; if (queryArgs.hasQueryItem(LOCATION_QUERY_KEY)) { path = queryArgs.queryItemValue(LOCATION_QUERY_KEY); + } else { + path = DEFAULT_NAMED_PATH; } handlePath(path, LookupTrigger::Internal, false); diff --git a/libraries/networking/src/DomainHandler.cpp b/libraries/networking/src/DomainHandler.cpp index fe3b0abcb7..cd8064c4c0 100644 --- a/libraries/networking/src/DomainHandler.cpp +++ b/libraries/networking/src/DomainHandler.cpp @@ -177,9 +177,11 @@ void DomainHandler::setURLAndID(QUrl domainURL, QUuid domainID) { qCDebug(networking) << "Updated domain hostname to" << domainURL.host(); if (!domainURL.host().isEmpty()) { - // re-set the sock addr to null and fire off a lookup of the IP address for this domain-server's hostname - qCDebug(networking, "Looking up DS hostname %s.", domainURL.host().toLocal8Bit().constData()); - QHostInfo::lookupHost(domainURL.host(), this, SLOT(completedHostnameLookup(const QHostInfo&))); + if (domainURL.scheme() == URL_SCHEME_HIFI) { + // re-set the sock addr to null and fire off a lookup of the IP address for this domain-server's hostname + qCDebug(networking, "Looking up DS hostname %s.", domainURL.host().toLocal8Bit().constData()); + QHostInfo::lookupHost(domainURL.host(), this, SLOT(completedHostnameLookup(const QHostInfo&))); + } DependencyManager::get()->flagTimeForConnectionStep( LimitedNodeList::ConnectionStep::SetDomainHostname); @@ -253,7 +255,10 @@ QString DomainHandler::getViewPointFromNamedPath(QString namedPath) { if (lookup != _namedPaths.end()) { return lookup->second; } - return DOMAIN_SPAWNING_POINT; + if (namedPath == DEFAULT_NAMED_PATH) { + return DOMAIN_SPAWNING_POINT; + } + return ""; } void DomainHandler::completedHostnameLookup(const QHostInfo& hostInfo) { @@ -285,8 +290,7 @@ void DomainHandler::completedIceServerHostnameLookup() { emit iceSocketAndIDReceived(); } -void DomainHandler::setIsConnected(bool isConnected, std::map namedPaths) { - _namedPaths = namedPaths; +void DomainHandler::setIsConnected(bool isConnected) { if (_isConnected != isConnected) { _isConnected = isConnected; @@ -304,6 +308,11 @@ void DomainHandler::setIsConnected(bool isConnected, std::map } } +void DomainHandler::connectedToServerless(std::map namedPaths) { + _namedPaths = namedPaths; + setIsConnected(true); +} + void DomainHandler::requestDomainSettings() { qCDebug(networking) << "Requesting settings from domain server"; diff --git a/libraries/networking/src/DomainHandler.h b/libraries/networking/src/DomainHandler.h index 760b2f8235..7137b8084d 100644 --- a/libraries/networking/src/DomainHandler.h +++ b/libraries/networking/src/DomainHandler.h @@ -73,9 +73,11 @@ public: void activateICEPublicSocket(); bool isConnected() const { return _isConnected; } - void setIsConnected(bool isConnected, std::map namedPaths = std::map()); + void setIsConnected(bool isConnected); bool isServerless() const { return _domainURL.scheme() != URL_SCHEME_HIFI; } + void connectedToServerless(std::map namedPaths); + QString getViewPointFromNamedPath(QString namedPath); bool hasSettings() const { return !_settingsObject.isEmpty(); } @@ -207,6 +209,6 @@ private: }; const QString DOMAIN_SPAWNING_POINT { "/0, -10, 0" }; - +const QString DEFAULT_NAMED_PATH { "/" }; #endif // hifi_DomainHandler_h From 0e081a394421a84b6ed161817289918e53814d07 Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Fri, 13 Apr 2018 10:42:22 -0700 Subject: [PATCH 04/14] code review --- libraries/entities/src/EntityTree.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/libraries/entities/src/EntityTree.cpp b/libraries/entities/src/EntityTree.cpp index d5c7b9c2d6..63d9a3ab16 100644 --- a/libraries/entities/src/EntityTree.cpp +++ b/libraries/entities/src/EntityTree.cpp @@ -2311,8 +2311,6 @@ bool EntityTree::readFromMap(QVariantMap& map) { QString namedPathViewPoint = iter.value().toString(); _namedPaths[namedPathName] = namedPathViewPoint; } - } else { - _namedPaths["/"] = "/"; } // map will have a top-level list keyed as "Entities". This will be extracted From e6085a90d66ae700d3f9351a16667ddbce745c45 Mon Sep 17 00:00:00 2001 From: samcake Date: Fri, 13 Apr 2018 12:17:50 -0700 Subject: [PATCH 05/14] Exposing more texture memory budget options --- interface/src/Menu.cpp | 9 +++++++++ interface/src/Menu.h | 4 ++++ 2 files changed, 13 insertions(+) diff --git a/interface/src/Menu.cpp b/interface/src/Menu.cpp index fa0e8087f0..7f71358eb5 100644 --- a/interface/src/Menu.cpp +++ b/interface/src/Menu.cpp @@ -447,6 +447,9 @@ Menu::Menu() { textureGroup->addAction(addCheckableActionToQMenuAndActionHash(textureMenu, MenuOption::RenderMaxTexture512MB, 0, false)); textureGroup->addAction(addCheckableActionToQMenuAndActionHash(textureMenu, MenuOption::RenderMaxTexture1024MB, 0, false)); textureGroup->addAction(addCheckableActionToQMenuAndActionHash(textureMenu, MenuOption::RenderMaxTexture2048MB, 0, false)); + textureGroup->addAction(addCheckableActionToQMenuAndActionHash(textureMenu, MenuOption::RenderMaxTexture4096MB, 0, false)); + textureGroup->addAction(addCheckableActionToQMenuAndActionHash(textureMenu, MenuOption::RenderMaxTexture6144MB, 0, false)); + textureGroup->addAction(addCheckableActionToQMenuAndActionHash(textureMenu, MenuOption::RenderMaxTexture8192MB, 0, false)); connect(textureGroup, &QActionGroup::triggered, [textureGroup] { auto checked = textureGroup->checkedAction(); auto text = checked->text(); @@ -463,6 +466,12 @@ Menu::Menu() { newMaxTextureMemory = MB_TO_BYTES(1024); } else if (MenuOption::RenderMaxTexture2048MB == text) { newMaxTextureMemory = MB_TO_BYTES(2048); + } else if (MenuOption::RenderMaxTexture4096MB == text) { + newMaxTextureMemory = MB_TO_BYTES(4096); + } else if (MenuOption::RenderMaxTexture6144MB == text) { + +newMaxTextureMemory = MB_TO_BYTES(6144); + } else if (MenuOption::RenderMaxTexture8192MB == text) { + newMaxTextureMemory = MB_TO_BYTES(8192); } gpu::Texture::setAllowedGPUMemoryUsage(newMaxTextureMemory); }); diff --git a/interface/src/Menu.h b/interface/src/Menu.h index cf9eed1a27..4d418a16d2 100644 --- a/interface/src/Menu.h +++ b/interface/src/Menu.h @@ -155,6 +155,10 @@ namespace MenuOption { const QString RenderMaxTexture512MB = "512 MB"; const QString RenderMaxTexture1024MB = "1024 MB"; const QString RenderMaxTexture2048MB = "2048 MB"; + const QString RenderMaxTexture3072MB = "3072 MB"; + const QString RenderMaxTexture4096MB = "4096 MB"; + const QString RenderMaxTexture6144MB = "6144 MB"; + const QString RenderMaxTexture8192MB = "8192 MB"; const QString RenderResolution = "Scale Resolution"; const QString RenderResolutionOne = "1"; const QString RenderResolutionTwoThird = "2/3"; From b88b668a065e05d47cc2d839baeb6eb206824168 Mon Sep 17 00:00:00 2001 From: samcake Date: Fri, 13 Apr 2018 12:19:53 -0700 Subject: [PATCH 06/14] Exposing more texture memory budget options --- interface/src/Menu.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/interface/src/Menu.cpp b/interface/src/Menu.cpp index 7f71358eb5..e74339a019 100644 --- a/interface/src/Menu.cpp +++ b/interface/src/Menu.cpp @@ -469,7 +469,7 @@ Menu::Menu() { } else if (MenuOption::RenderMaxTexture4096MB == text) { newMaxTextureMemory = MB_TO_BYTES(4096); } else if (MenuOption::RenderMaxTexture6144MB == text) { - +newMaxTextureMemory = MB_TO_BYTES(6144); + newMaxTextureMemory = MB_TO_BYTES(6144); } else if (MenuOption::RenderMaxTexture8192MB == text) { newMaxTextureMemory = MB_TO_BYTES(8192); } From 426d18ed2a7755b38556ac258d54bef951d5d4ec Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Fri, 13 Apr 2018 13:20:06 -0700 Subject: [PATCH 07/14] code review --- libraries/networking/src/NodeList.cpp | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/libraries/networking/src/NodeList.cpp b/libraries/networking/src/NodeList.cpp index 3c2b4cd336..13931be2ac 100644 --- a/libraries/networking/src/NodeList.cpp +++ b/libraries/networking/src/NodeList.cpp @@ -416,7 +416,9 @@ void NodeList::handleDSPathQuery(const QString& newPath) { if (_domainHandler.isServerless()) { if (_domainHandler.isConnected()) { auto viewpoint = _domainHandler.getViewPointFromNamedPath(newPath); - DependencyManager::get()->goToViewpointForPath(viewpoint, newPath); + if (!newPath.isEmpty()) { + DependencyManager::get()->goToViewpointForPath(viewpoint, newPath); + } } else { _domainHandler.setPendingPath(newPath); } @@ -437,7 +439,9 @@ void NodeList::sendPendingDSPathQuery() { if (_domainHandler.isServerless()) { auto viewpoint = _domainHandler.getViewPointFromNamedPath(pendingPath); - DependencyManager::get()->goToViewpointForPath(viewpoint, pendingPath); + if (!pendingPath.isEmpty()) { + DependencyManager::get()->goToViewpointForPath(viewpoint, pendingPath); + } } else { qCDebug(networking) << "Attempting to send pending query to DS for path" << pendingPath; // this is a slot triggered if we just established a network link with a DS and want to send a path query @@ -510,7 +514,7 @@ void NodeList::processDomainServerPathResponse(QSharedPointer m QString viewpoint = QString::fromUtf8(message->getRawMessage() + message->getPosition(), numViewpointBytes); // Hand it off to the AddressManager so it can handle it as a relative viewpoint - if (DependencyManager::get()->goToViewpointForPath(viewpoint, pathQuery)) { + if (!pathQuery.isEmpty() && DependencyManager::get()->goToViewpointForPath(viewpoint, pathQuery)) { qCDebug(networking) << "Going to viewpoint" << viewpoint << "which was the lookup result for path" << pathQuery; } else { qCDebug(networking) << "Could not go to viewpoint" << viewpoint From 8e7b9dfa2b16aca9235c017412cfe0aedf03aed1 Mon Sep 17 00:00:00 2001 From: samcake Date: Fri, 13 Apr 2018 17:30:30 -0700 Subject: [PATCH 08/14] Reverting TAA to FXAA in rc66 until we fix the aa on tablet --- libraries/render-utils/src/AntialiasingEffect.h | 11 +++++++++-- scripts/developer/utilities/render/antialiasing.qml | 2 +- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/libraries/render-utils/src/AntialiasingEffect.h b/libraries/render-utils/src/AntialiasingEffect.h index 03fdb9d9a4..19f204d930 100644 --- a/libraries/render-utils/src/AntialiasingEffect.h +++ b/libraries/render-utils/src/AntialiasingEffect.h @@ -26,7 +26,11 @@ class JitterSampleConfig : public render::Job::Config { Q_PROPERTY(bool stop MEMBER stop NOTIFY dirty) Q_PROPERTY(int index READ getIndex NOTIFY dirty) public: - JitterSampleConfig() : render::Job::Config(true) {} + JitterSampleConfig() : render::Job::Config(true) { + // FIXME: For RC66 disable Taa by default + // Disable jitter by default for now by default: + none(); + } float scale{ 0.5f }; bool stop{ false }; @@ -113,7 +117,10 @@ public: bool feedbackColor{ false }; float debugX{ 0.0f }; - float debugFXAAX{ 1.0f }; + // FIXME: For RC66 disable Taa by default + // Fall back to FXAA :( + // float debugFXAAX{ 1.0f }; + float debugFXAAX{ 0.0f }; float debugShowVelocityThreshold{ 1.0f }; glm::vec2 debugCursorTexcoord{ 0.5f, 0.5f }; float debugOrbZoom{ 2.0f }; diff --git a/scripts/developer/utilities/render/antialiasing.qml b/scripts/developer/utilities/render/antialiasing.qml index e8034c48bd..c46d753635 100644 --- a/scripts/developer/utilities/render/antialiasing.qml +++ b/scripts/developer/utilities/render/antialiasing.qml @@ -36,7 +36,7 @@ Rectangle { Row { spacing: 10 id: fxaaOnOff - property bool debugFXAA: false + property bool debugFXAA: true HifiControls.Button { text: { if (fxaaOnOff.debugFXAA) { From f4096c39319dc1019b22790d2d7e91c1b6902014 Mon Sep 17 00:00:00 2001 From: "Anthony J. Thibault" Date: Mon, 19 Mar 2018 18:53:00 -0700 Subject: [PATCH 09/14] Disable elbow pole vectors, solve from joint limit centers. (cherry picked from commit 69f462baeb79dc6d1c3dc36dfad84c68ff1adfdc) --- libraries/animation/src/Rig.cpp | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/libraries/animation/src/Rig.cpp b/libraries/animation/src/Rig.cpp index 848f384687..7996c3372c 100644 --- a/libraries/animation/src/Rig.cpp +++ b/libraries/animation/src/Rig.cpp @@ -1246,6 +1246,7 @@ void Rig::updateHands(bool leftHandEnabled, bool rightHandEnabled, bool hipsEnab const FBXJointShapeInfo& hipsShapeInfo, const FBXJointShapeInfo& spineShapeInfo, const FBXJointShapeInfo& spine1ShapeInfo, const FBXJointShapeInfo& spine2ShapeInfo) { + const bool ENABLE_POLE_VECTORS = false; const float ELBOW_POLE_VECTOR_BLEND_FACTOR = 0.95f; int hipsIndex = indexOfJoint("Hips"); @@ -1268,7 +1269,7 @@ void Rig::updateHands(bool leftHandEnabled, bool rightHandEnabled, bool hipsEnab int handJointIndex = _animSkeleton->nameToJointIndex("LeftHand"); int armJointIndex = _animSkeleton->nameToJointIndex("LeftArm"); int elbowJointIndex = _animSkeleton->nameToJointIndex("LeftForeArm"); - if (!leftArmEnabled && handJointIndex >= 0 && armJointIndex >= 0 && elbowJointIndex >= 0) { + if (ENABLE_POLE_VECTORS && !leftArmEnabled && handJointIndex >= 0 && armJointIndex >= 0 && elbowJointIndex >= 0) { glm::vec3 poleVector = calculateElbowPoleVector(handJointIndex, elbowJointIndex, armJointIndex, hipsIndex, true); // smooth toward desired pole vector from previous pole vector... to reduce jitter @@ -1315,7 +1316,7 @@ void Rig::updateHands(bool leftHandEnabled, bool rightHandEnabled, bool hipsEnab int handJointIndex = _animSkeleton->nameToJointIndex("RightHand"); int armJointIndex = _animSkeleton->nameToJointIndex("RightArm"); int elbowJointIndex = _animSkeleton->nameToJointIndex("RightForeArm"); - if (!rightArmEnabled && handJointIndex >= 0 && armJointIndex >= 0 && elbowJointIndex >= 0) { + if (ENABLE_POLE_VECTORS && !rightArmEnabled && handJointIndex >= 0 && armJointIndex >= 0 && elbowJointIndex >= 0) { glm::vec3 poleVector = calculateElbowPoleVector(handJointIndex, elbowJointIndex, armJointIndex, hipsIndex, false); // smooth toward desired pole vector from previous pole vector... to reduce jitter @@ -1555,18 +1556,16 @@ void Rig::updateFromControllerParameters(const ControllerParameters& params, flo updateFeet(leftFootEnabled, rightFootEnabled, params.primaryControllerPoses[PrimaryControllerType_LeftFoot], params.primaryControllerPoses[PrimaryControllerType_RightFoot]); + + // Always relax IK chains toward joint limit centers. + _animVars.set("solutionSource", (int)AnimInverseKinematics::SolutionSource::RelaxToLimitCenterPoses); + // if the hips or the feet are being controlled. if (hipsEnabled || rightFootEnabled || leftFootEnabled) { - // for more predictable IK solve from the center of the joint limits, not from the underpose - _animVars.set("solutionSource", (int)AnimInverseKinematics::SolutionSource::RelaxToLimitCenterPoses); - // replace the feet animation with the default pose, this is to prevent unexpected toe wiggling. _animVars.set("defaultPoseOverlayAlpha", 1.0f); _animVars.set("defaultPoseOverlayBoneSet", (int)AnimOverlay::BothFeetBoneSet); } else { - // augment the IK with the underPose. - _animVars.set("solutionSource", (int)AnimInverseKinematics::SolutionSource::RelaxToUnderPoses); - // feet should follow source animation _animVars.unset("defaultPoseOverlayAlpha"); _animVars.unset("defaultPoseOverlayBoneSet"); From 63ee8c0ccbf9826420cb1c9988bbf8598904e4f1 Mon Sep 17 00:00:00 2001 From: "Anthony J. Thibault" Date: Tue, 20 Mar 2018 18:12:55 -0700 Subject: [PATCH 10/14] Fix for character walk animations in desktop mode. (cherry picked from commit f19b1d9890fb360dd7949c05054439561e9bab19) --- libraries/animation/src/Rig.cpp | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/libraries/animation/src/Rig.cpp b/libraries/animation/src/Rig.cpp index 7996c3372c..0833b28142 100644 --- a/libraries/animation/src/Rig.cpp +++ b/libraries/animation/src/Rig.cpp @@ -1557,8 +1557,13 @@ void Rig::updateFromControllerParameters(const ControllerParameters& params, flo params.primaryControllerPoses[PrimaryControllerType_LeftFoot], params.primaryControllerPoses[PrimaryControllerType_RightFoot]); - // Always relax IK chains toward joint limit centers. - _animVars.set("solutionSource", (int)AnimInverseKinematics::SolutionSource::RelaxToLimitCenterPoses); + if (headEnabled) { + // Blend IK chains toward the joint limit centers, this should stablize head and hand ik. + _animVars.set("solutionSource", (int)AnimInverseKinematics::SolutionSource::RelaxToLimitCenterPoses); + } else { + // Blend IK chains toward the UnderPoses, so some of the animaton motion is present in the IK solution. + _animVars.set("solutionSource", (int)AnimInverseKinematics::SolutionSource::RelaxToUnderPoses); + } // if the hips or the feet are being controlled. if (hipsEnabled || rightFootEnabled || leftFootEnabled) { From c29bf5122698cf3fa2bcdd84fbc3981b32e988c1 Mon Sep 17 00:00:00 2001 From: "Anthony J. Thibault" Date: Sun, 15 Apr 2018 19:47:39 -0700 Subject: [PATCH 11/14] Fix for avatar glitches, head and legs folding into chest. As a form of compression, when encoding avatar data we only send joints that have changed significantly from the previous packet. Also, if a joint has the same value as the avatar's default pose, we don't send the full value, instead we mark it with a single bit. This particular issue is caused by an interaction between the default value flag and the joint changed culling. When connecting to a domain for the first time, it's possible that a I-frame or 'full' packet will not be sent for several seconds. In this case, the AvatarMixer has no previous history for values that have not changed recently. This causes the AvatarMixer to broadcast incorrect values to other clients. Keep in mind that the AvatarMixer does not have access to the avatar FBX file, so it cannot make an educated guess for this value and uses zero values instead. (0, 0, 0) for translation and (0, 0, 0, 1) for rotation. When a translation value of zero is received for the lower legs it will cause the legs to fold into the avatar's chest. Also, we've uncovered a bug where sometimes values were not sent to the AvatarMixer even when the value was previously default. This would also exhibit the same issue where zero translation values would be sent. I've done three things to help mitigate this issue. 1) On first connect to a new AvatarMixer, the Avatar now sends a 'full' packet. 2) When a joint rotation or translation changes from the default value, we transmit it. No questions asked. 3) Once a SkeletonModel has finished loading we initialize the avatar's _jointData with the proper translations from the default pose. This will help the case where a client receives a non default value, but has no previous history. (cherry picked from commit 94efdf76a6454f316985f95d6a221adb24788d66) --- interface/src/avatar/MyAvatar.cpp | 7 +++++ interface/src/avatar/MyAvatar.h | 1 + .../src/avatars-renderer/SkeletonModel.cpp | 7 +++++ libraries/avatars/src/AvatarData.cpp | 28 +++++++++++++++---- libraries/avatars/src/AvatarData.h | 9 ++++-- 5 files changed, 44 insertions(+), 8 deletions(-) diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp index 9620a2dcec..e98dfe7c06 100755 --- a/interface/src/avatar/MyAvatar.cpp +++ b/interface/src/avatar/MyAvatar.cpp @@ -3398,6 +3398,13 @@ void MyAvatar::setModelScale(float scale) { } } +void MyAvatar::setSessionUUID(const QUuid& sessionUUID) { + Avatar::setSessionUUID(sessionUUID); + + // transmit a "sendAll" packet to the AvatarMixer we just connected to. + sendAvatarDataPacket(true); +} + SpatialParentTree* MyAvatar::getParentTree() const { auto entityTreeRenderer = qApp->getEntities(); EntityTreePointer entityTree = entityTreeRenderer ? entityTreeRenderer->getTree() : nullptr; diff --git a/interface/src/avatar/MyAvatar.h b/interface/src/avatar/MyAvatar.h index 5ca010d128..c1e554cd1d 100644 --- a/interface/src/avatar/MyAvatar.h +++ b/interface/src/avatar/MyAvatar.h @@ -616,6 +616,7 @@ public slots: glm::quat getOrientationForAudio(); virtual void setModelScale(float scale) override; + virtual void setSessionUUID(const QUuid& sessionUUID) override; signals: void audioListenerModeChanged(); diff --git a/libraries/avatars-renderer/src/avatars-renderer/SkeletonModel.cpp b/libraries/avatars-renderer/src/avatars-renderer/SkeletonModel.cpp index b25df633c0..428f86f0ab 100644 --- a/libraries/avatars-renderer/src/avatars-renderer/SkeletonModel.cpp +++ b/libraries/avatars-renderer/src/avatars-renderer/SkeletonModel.cpp @@ -58,6 +58,13 @@ void SkeletonModel::initJointStates() { glm::mat4 modelOffset = glm::scale(_scale) * glm::translate(_offset); _rig.initJointStates(geometry, modelOffset); + { + // initialize _jointData with proper values for default joints + QVector defaultJointData; + _rig.copyJointsIntoJointData(defaultJointData); + _owningAvatar->setRawJointData(defaultJointData); + } + // Determine the default eye position for avatar scale = 1.0 int headJointIndex = geometry.headJointIndex; if (0 > headJointIndex || headJointIndex >= _rig.getJointStateCount()) { diff --git a/libraries/avatars/src/AvatarData.cpp b/libraries/avatars/src/AvatarData.cpp index 1bbc8cc1a5..77a3b39ec5 100644 --- a/libraries/avatars/src/AvatarData.cpp +++ b/libraries/avatars/src/AvatarData.cpp @@ -559,7 +559,8 @@ QByteArray AvatarData::toByteArray(AvatarDataDetail dataDetail, quint64 lastSent const JointData& last = lastSentJointData[i]; if (!data.rotationIsDefaultPose) { - if (sendAll || last.rotationIsDefaultPose || last.rotation != data.rotation) { + bool mustSend = sendAll || last.rotationIsDefaultPose; + if (mustSend || last.rotation != data.rotation) { bool largeEnoughRotation = true; if (cullSmallChanges) { @@ -568,7 +569,7 @@ QByteArray AvatarData::toByteArray(AvatarDataDetail dataDetail, quint64 lastSent largeEnoughRotation = fabsf(glm::dot(last.rotation, data.rotation)) < minRotationDOT; } - if (sendAll || !cullSmallChanges || largeEnoughRotation) { + if (mustSend || !cullSmallChanges || largeEnoughRotation) { validity |= (1 << validityBit); #ifdef WANT_DEBUG rotationSentCount++; @@ -608,10 +609,12 @@ QByteArray AvatarData::toByteArray(AvatarDataDetail dataDetail, quint64 lastSent float maxTranslationDimension = 0.0; for (int i = 0; i < _jointData.size(); i++) { const JointData& data = _jointData[i]; + const JointData& last = lastSentJointData[i]; if (!data.translationIsDefaultPose) { - if (sendAll || lastSentJointData[i].translation != data.translation) { - if (sendAll || !cullSmallChanges || glm::distance(data.translation, lastSentJointData[i].translation) > minTranslation) { + bool mustSend = sendAll || last.translationIsDefaultPose; + if (mustSend || last.translation != data.translation) { + if (mustSend || !cullSmallChanges || glm::distance(data.translation, lastSentJointData[i].translation) > minTranslation) { validity |= (1 << validityBit); #ifdef WANT_DEBUG translationSentCount++; @@ -669,6 +672,19 @@ QByteArray AvatarData::toByteArray(AvatarDataDetail dataDetail, quint64 lastSent } if (sentJointDataOut) { + + // Mark default poses in lastSentJointData, so when they become non-default we send them. + for (int i = 0; i < _jointData.size(); i++) { + const JointData& data = _jointData[i]; + JointData& local = localSentJointDataOut[i]; + if (data.rotationIsDefaultPose) { + local.rotationIsDefaultPose = true; + } + if (data.translationIsDefaultPose) { + local.translationIsDefaultPose = true; + } + } + // Push new sent joint data to sentJointDataOut sentJointDataOut->swap(localSentJointDataOut); } @@ -1816,13 +1832,13 @@ void AvatarData::setJointMappingsFromNetworkReply() { networkReply->deleteLater(); } -void AvatarData::sendAvatarDataPacket() { +void AvatarData::sendAvatarDataPacket(bool sendAll) { auto nodeList = DependencyManager::get(); // about 2% of the time, we send a full update (meaning, we transmit all the joint data), even if nothing has changed. // this is to guard against a joint moving once, the packet getting lost, and the joint never moving again. - bool cullSmallData = (randFloat() < AVATAR_SEND_FULL_UPDATE_RATIO); + bool cullSmallData = !sendAll && (randFloat() < AVATAR_SEND_FULL_UPDATE_RATIO); auto dataDetail = cullSmallData ? SendAllData : CullSmallData; QByteArray avatarByteArray = toByteArrayStateful(dataDetail); diff --git a/libraries/avatars/src/AvatarData.h b/libraries/avatars/src/AvatarData.h index e927120b07..7c188019db 100644 --- a/libraries/avatars/src/AvatarData.h +++ b/libraries/avatars/src/AvatarData.h @@ -256,6 +256,11 @@ namespace AvatarDataPacket { SixByteQuat rotation[numValidRotations]; // encodeded and compressed by packOrientationQuatToSixBytes() uint8_t translationValidityBits[ceil(numJoints / 8)]; // one bit per joint, if true then a compressed translation follows. SixByteTrans translation[numValidTranslations]; // encodeded and compressed by packFloatVec3ToSignedTwoByteFixed() + + SixByteQuat leftHandControllerRotation; + SixByteTrans leftHandControllerTranslation; + SixByteQuat rightHandControllerRotation; + SixByteTrans rightHandControllerTranslation; }; */ size_t maxJointDataSize(size_t numJoints); @@ -707,11 +712,11 @@ signals: void sessionUUIDChanged(); public slots: - void sendAvatarDataPacket(); + void sendAvatarDataPacket(bool sendAll = false); void sendIdentityPacket(); void setJointMappingsFromNetworkReply(); - void setSessionUUID(const QUuid& sessionUUID) { + virtual void setSessionUUID(const QUuid& sessionUUID) { if (sessionUUID != getID()) { if (sessionUUID == QUuid()) { setID(AVATAR_SELF_ID); From 0a162e62b01314d6e8613a467acc9bcf66250378 Mon Sep 17 00:00:00 2001 From: "Anthony J. Thibault" Date: Mon, 16 Apr 2018 16:15:35 -0700 Subject: [PATCH 12/14] transmit sendAll packet in nodeActivated signal callback (cherry picked from commit 9f1a8290148da12849935c916b2e0a59864cb49b) --- interface/src/Application.cpp | 3 +++ interface/src/avatar/MyAvatar.cpp | 7 ------- interface/src/avatar/MyAvatar.h | 1 - 3 files changed, 3 insertions(+), 8 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 37fd2da56f..f5aaa2fbe9 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -5940,6 +5940,9 @@ void Application::nodeActivated(SharedNodePointer node) { } getMyAvatar()->markIdentityDataChanged(); getMyAvatar()->resetLastSent(); + + // transmit a "sendAll" packet to the AvatarMixer we just connected to. + getMyAvatar()->sendAvatarDataPacket(true); } } diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp index e98dfe7c06..9620a2dcec 100755 --- a/interface/src/avatar/MyAvatar.cpp +++ b/interface/src/avatar/MyAvatar.cpp @@ -3398,13 +3398,6 @@ void MyAvatar::setModelScale(float scale) { } } -void MyAvatar::setSessionUUID(const QUuid& sessionUUID) { - Avatar::setSessionUUID(sessionUUID); - - // transmit a "sendAll" packet to the AvatarMixer we just connected to. - sendAvatarDataPacket(true); -} - SpatialParentTree* MyAvatar::getParentTree() const { auto entityTreeRenderer = qApp->getEntities(); EntityTreePointer entityTree = entityTreeRenderer ? entityTreeRenderer->getTree() : nullptr; diff --git a/interface/src/avatar/MyAvatar.h b/interface/src/avatar/MyAvatar.h index c1e554cd1d..5ca010d128 100644 --- a/interface/src/avatar/MyAvatar.h +++ b/interface/src/avatar/MyAvatar.h @@ -616,7 +616,6 @@ public slots: glm::quat getOrientationForAudio(); virtual void setModelScale(float scale) override; - virtual void setSessionUUID(const QUuid& sessionUUID) override; signals: void audioListenerModeChanged(); From 515c185887163294238ffa36be942a3a2090031e Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Mon, 16 Apr 2018 19:10:16 -0700 Subject: [PATCH 13/14] don't call setPort on hifi urls when port is 0 (unset) --- libraries/networking/src/AddressManager.cpp | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/libraries/networking/src/AddressManager.cpp b/libraries/networking/src/AddressManager.cpp index 431a2e8ad5..daebcfb40d 100644 --- a/libraries/networking/src/AddressManager.cpp +++ b/libraries/networking/src/AddressManager.cpp @@ -439,7 +439,9 @@ void AddressManager::goToAddressFromObject(const QVariantMap& dataObject, const QUrl domainURL; domainURL.setScheme(URL_SCHEME_HIFI); domainURL.setHost(domainHostname); - domainURL.setPort(domainPort); + if (domainPort > 0) { + domainURL.setPort(domainPort); + } emit possibleDomainChangeRequired(domainURL, domainID); } else { QString iceServerAddress = domainObject[DOMAIN_ICE_SERVER_ADDRESS_KEY].toString(); @@ -610,7 +612,9 @@ bool AddressManager::handleNetworkAddress(const QString& lookupString, LookupTri QUrl domainURL; domainURL.setScheme(URL_SCHEME_HIFI); domainURL.setHost(domainIPString); - domainURL.setPort(domainPort); + if (domainPort > 0) { + domainURL.setPort(domainPort); + } hostChanged = setDomainInfo(domainURL, trigger); return true; @@ -631,7 +635,9 @@ bool AddressManager::handleNetworkAddress(const QString& lookupString, LookupTri QUrl domainURL; domainURL.setScheme(URL_SCHEME_HIFI); domainURL.setHost(domainHostname); - domainURL.setPort(domainPort); + if (domainPort > 0) { + domainURL.setPort(domainPort); + } hostChanged = setDomainInfo(domainURL, trigger); return true; @@ -763,7 +769,9 @@ bool AddressManager::setHost(const QString& host, LookupTrigger trigger, quint16 _domainURL = QUrl(); _domainURL.setScheme(URL_SCHEME_HIFI); _domainURL.setHost(host); - _domainURL.setPort(port); + if (port > 0) { + _domainURL.setPort(port); + } // any host change should clear the shareable place name _shareablePlaceName.clear(); From 9fca98aa0f4a63620fc4f7efc80b5341e2173cb7 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Tue, 17 Apr 2018 15:35:16 -0700 Subject: [PATCH 14/14] Revert "Reverting TAA to FXAA in rc66 until we fix the aa on tablet" This reverts commit 8e7b9dfa2b16aca9235c017412cfe0aedf03aed1. --- libraries/render-utils/src/AntialiasingEffect.h | 11 ++--------- scripts/developer/utilities/render/antialiasing.qml | 2 +- 2 files changed, 3 insertions(+), 10 deletions(-) diff --git a/libraries/render-utils/src/AntialiasingEffect.h b/libraries/render-utils/src/AntialiasingEffect.h index 19f204d930..03fdb9d9a4 100644 --- a/libraries/render-utils/src/AntialiasingEffect.h +++ b/libraries/render-utils/src/AntialiasingEffect.h @@ -26,11 +26,7 @@ class JitterSampleConfig : public render::Job::Config { Q_PROPERTY(bool stop MEMBER stop NOTIFY dirty) Q_PROPERTY(int index READ getIndex NOTIFY dirty) public: - JitterSampleConfig() : render::Job::Config(true) { - // FIXME: For RC66 disable Taa by default - // Disable jitter by default for now by default: - none(); - } + JitterSampleConfig() : render::Job::Config(true) {} float scale{ 0.5f }; bool stop{ false }; @@ -117,10 +113,7 @@ public: bool feedbackColor{ false }; float debugX{ 0.0f }; - // FIXME: For RC66 disable Taa by default - // Fall back to FXAA :( - // float debugFXAAX{ 1.0f }; - float debugFXAAX{ 0.0f }; + float debugFXAAX{ 1.0f }; float debugShowVelocityThreshold{ 1.0f }; glm::vec2 debugCursorTexcoord{ 0.5f, 0.5f }; float debugOrbZoom{ 2.0f }; diff --git a/scripts/developer/utilities/render/antialiasing.qml b/scripts/developer/utilities/render/antialiasing.qml index c46d753635..e8034c48bd 100644 --- a/scripts/developer/utilities/render/antialiasing.qml +++ b/scripts/developer/utilities/render/antialiasing.qml @@ -36,7 +36,7 @@ Rectangle { Row { spacing: 10 id: fxaaOnOff - property bool debugFXAA: true + property bool debugFXAA: false HifiControls.Button { text: { if (fxaaOnOff.debugFXAA) {