From c96b704a28e64ea92e6e1b12d04fcbf256289a66 Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Wed, 26 Jun 2019 15:38:59 -0700 Subject: [PATCH 01/26] avoid dupe connections and teardown old connections --- interface/src/octree/SafeLanding.cpp | 55 +++++++++++++++------------- 1 file changed, 29 insertions(+), 26 deletions(-) diff --git a/interface/src/octree/SafeLanding.cpp b/interface/src/octree/SafeLanding.cpp index 2e11de508b..573933a408 100644 --- a/interface/src/octree/SafeLanding.cpp +++ b/interface/src/octree/SafeLanding.cpp @@ -34,15 +34,15 @@ bool SafeLanding::SequenceLessThan::operator()(const int& a, const int& b) const } void SafeLanding::startEntitySequence(QSharedPointer entityTreeRenderer) { - if (!entityTreeRenderer.isNull()) { auto entityTree = entityTreeRenderer->getTree(); - if (entityTree) { + if (entityTree && !_trackingEntities) { Locker lock(_lock); _entityTreeRenderer = entityTreeRenderer; _trackedEntities.clear(); _trackingEntities = true; _maxTrackedEntityCount = 0; + connect(std::const_pointer_cast(entityTree).get(), &EntityTree::addingEntity, this, &SafeLanding::addTrackedEntity, Qt::DirectConnection); connect(std::const_pointer_cast(entityTree).get(), @@ -69,25 +69,20 @@ void SafeLanding::stopEntitySequence() { } void SafeLanding::addTrackedEntity(const EntityItemID& entityID) { - if (_trackingEntities) { + if (_trackingEntities && _entityTreeRenderer) { Locker lock(_lock); + auto entityTree = _entityTreeRenderer->getTree(); + if (entityTree) { + EntityItemPointer entity = entityTree->findEntityByID(entityID); + if (entity && !entity->isLocalEntity() && entity->getCreated() < _startTime) { + _trackedEntities.emplace(entityID, entity); - if (_entityTreeRenderer.isNull() || _entityTreeRenderer->getTree() == nullptr) { - return; - } - - EntityItemPointer entity = _entityTreeRenderer->getTree()->findEntityByID(entityID); - - if (entity && !entity->isLocalEntity() && entity->getCreated() < _startTime) { - - _trackedEntities.emplace(entityID, entity); - int trackedEntityCount = (int)_trackedEntities.size(); - - if (trackedEntityCount > _maxTrackedEntityCount) { - _maxTrackedEntityCount = trackedEntityCount; - _trackedEntityStabilityCount = 0; + int trackedEntityCount = (int)_trackedEntities.size(); + if (trackedEntityCount > _maxTrackedEntityCount) { + _maxTrackedEntityCount = trackedEntityCount; + _trackedEntityStabilityCount = 0; + } } - //qCDebug(interfaceapp) << "Safe Landing: Tracking entity " << entity->getItemName(); } } } @@ -114,11 +109,20 @@ void SafeLanding::noteReceivedsequenceNumber(int sequenceNumber) { bool SafeLanding::isLoadSequenceComplete() { if ((isEntityLoadingComplete() && isSequenceNumbersComplete()) || qApp->failedToConnectToEntityServer()) { + _trackingEntities = false; + Locker lock(_lock); + if (_entityTreeRenderer) { + auto entityTree = _entityTreeRenderer->getTree(); + disconnect(std::const_pointer_cast(entityTree).get(), + &EntityTree::addingEntity, this, &SafeLanding::addTrackedEntity); + disconnect(std::const_pointer_cast(entityTree).get(), + &EntityTree::deletingEntity, this, &SafeLanding::deleteTrackedEntity); + _entityTreeRenderer.reset(); + } + _initialStart = INVALID_SEQUENCE; _initialEnd = INVALID_SEQUENCE; - _entityTreeRenderer.clear(); - _trackingEntities = false; // Don't track anything else that comes in. EntityTreeRenderer::setEntityLoadingPriorityFunction(StandardPriority); } @@ -187,9 +191,9 @@ bool SafeLanding::isEntityPhysicsReady(const EntityItemPointer& entity) { bool SafeLanding::isEntityLoadingComplete() { Locker lock(_lock); - - - auto entityTree = qApp->getEntities(); + if (!_entityTreeRenderer) { + return true; + } auto entityMapIter = _trackedEntities.begin(); bool enableInterstitial = DependencyManager::get()->getDomainHandler().getInterstitialModeEnabled(); @@ -200,9 +204,9 @@ bool SafeLanding::isEntityLoadingComplete() { bool isVisuallyReady = true; if (enableInterstitial) { - auto entityRenderable = entityTree->renderableForEntityId(entityMapIter->first); + auto entityRenderable = _entityTreeRenderer->renderableForEntityId(entityMapIter->first); if (!entityRenderable) { - entityTree->addingEntity(entityMapIter->first); + _entityTreeRenderer->addingEntity(entityMapIter->first); } isVisuallyReady = entity->isVisuallyReady() || (!entityRenderable && !entity->isParentPathComplete()); @@ -223,7 +227,6 @@ bool SafeLanding::isEntityLoadingComplete() { _trackedEntityStabilityCount++; } - return _trackedEntities.empty(); } From 355de0e6d5712c8caa54da4a1311219ef129c2e2 Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Wed, 26 Jun 2019 15:41:01 -0700 Subject: [PATCH 02/26] move Application::setFailedToConnect() to cpp for easier debugging --- interface/src/Application.cpp | 4 ++++ interface/src/Application.h | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index eba8664f72..f2ffbcc3ac 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -2498,6 +2498,10 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo pauseUntilLoginDetermined(); } +void Application::setFailedToConnectToEntityServer() { + _failedToConnectToEntityServer = true; +} + void Application::updateVerboseLogging() { auto menu = Menu::getInstance(); if (!menu) { diff --git a/interface/src/Application.h b/interface/src/Application.h index 2cea492d56..641f62461f 100644 --- a/interface/src/Application.h +++ b/interface/src/Application.h @@ -512,7 +512,7 @@ private slots: void loadSettings(); void saveSettings() const; - void setFailedToConnectToEntityServer() { _failedToConnectToEntityServer = true; } + void setFailedToConnectToEntityServer(); bool acceptSnapshot(const QString& urlString); bool askToSetAvatarUrl(const QString& url); From 46b3d84be583946babe9b0185c285d9e1131aa7f Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Wed, 26 Jun 2019 15:41:50 -0700 Subject: [PATCH 03/26] remove unused cruft --- interface/src/Application.cpp | 2 -- interface/src/Application.h | 2 -- 2 files changed, 4 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index f2ffbcc3ac..234e3d597a 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -6186,8 +6186,6 @@ void Application::update(float deltaTime) { bool enableInterstitial = DependencyManager::get()->getDomainHandler().getInterstitialModeEnabled(); if (gpuTextureMemSizeStable() || !enableInterstitial) { - // we've received a new full-scene octree stats packet, or it's been long enough to try again anyway - _lastPhysicsCheckTime = now; _fullSceneCounterAtLastPhysicsCheck = _fullSceneReceivedCounter; _lastQueriedViews.clear(); // Force new view. diff --git a/interface/src/Application.h b/interface/src/Application.h index 641f62461f..bd7c9d758e 100644 --- a/interface/src/Application.h +++ b/interface/src/Application.h @@ -786,8 +786,6 @@ private: qint64 _gpuTextureMemSizeStabilityCount { 0 }; qint64 _gpuTextureMemSizeAtLastCheck { 0 }; - quint64 _lastPhysicsCheckTime { usecTimestampNow() }; // when did we last check to see if physics was ready - bool _keyboardDeviceHasFocus { true }; ConnectionMonitor _connectionMonitor; From 496a7f36087c48a5198b11bc4589eacf44f4ccc7 Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Wed, 26 Jun 2019 16:02:00 -0700 Subject: [PATCH 04/26] less cruft, more readable --- interface/src/Application.cpp | 2 +- .../src/octree/OctreePacketProcessor.cpp | 2 +- interface/src/octree/OctreePacketProcessor.h | 2 +- interface/src/octree/SafeLanding.cpp | 43 ++++++++----------- interface/src/octree/SafeLanding.h | 2 +- 5 files changed, 21 insertions(+), 30 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 234e3d597a..e23e3172ac 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -5915,7 +5915,7 @@ void Application::resetPhysicsReadyInformation() { _gpuTextureMemSizeStabilityCount = 0; _gpuTextureMemSizeAtLastCheck = 0; _physicsEnabled = false; - _octreeProcessor.startEntitySequence(); + _octreeProcessor.startSafeLanding(); } diff --git a/interface/src/octree/OctreePacketProcessor.cpp b/interface/src/octree/OctreePacketProcessor.cpp index 6b07e6717c..544c56c802 100644 --- a/interface/src/octree/OctreePacketProcessor.cpp +++ b/interface/src/octree/OctreePacketProcessor.cpp @@ -133,6 +133,6 @@ void OctreePacketProcessor::processPacket(QSharedPointer messag } } -void OctreePacketProcessor::startEntitySequence() { +void OctreePacketProcessor::startSafeLanding() { _safeLanding->startEntitySequence(qApp->getEntities()); } diff --git a/interface/src/octree/OctreePacketProcessor.h b/interface/src/octree/OctreePacketProcessor.h index d6ffb942e6..7f906eab99 100644 --- a/interface/src/octree/OctreePacketProcessor.h +++ b/interface/src/octree/OctreePacketProcessor.h @@ -25,7 +25,7 @@ public: OctreePacketProcessor(); ~OctreePacketProcessor(); - void startEntitySequence(); + void startSafeLanding(); bool isLoadSequenceComplete() const { return _safeLanding->isLoadSequenceComplete(); } float domainLoadingProgress() const { return _safeLanding->loadingProgressPercentage(); } diff --git a/interface/src/octree/SafeLanding.cpp b/interface/src/octree/SafeLanding.cpp index 573933a408..e4a2156aff 100644 --- a/interface/src/octree/SafeLanding.cpp +++ b/interface/src/octree/SafeLanding.cpp @@ -57,17 +57,6 @@ void SafeLanding::startEntitySequence(QSharedPointer entityT } } -void SafeLanding::stopEntitySequence() { - Locker lock(_lock); - _trackingEntities = false; - _maxTrackedEntityCount = 0; - _trackedEntityStabilityCount = 0; - _initialStart = INVALID_SEQUENCE; - _initialEnd = INVALID_SEQUENCE; - _trackedEntities.clear(); - _sequenceNumbers.clear(); -} - void SafeLanding::addTrackedEntity(const EntityItemID& entityID) { if (_trackingEntities && _entityTreeRenderer) { Locker lock(_lock); @@ -109,24 +98,26 @@ void SafeLanding::noteReceivedsequenceNumber(int sequenceNumber) { bool SafeLanding::isLoadSequenceComplete() { if ((isEntityLoadingComplete() && isSequenceNumbersComplete()) || qApp->failedToConnectToEntityServer()) { - _trackingEntities = false; + stopTracking(); + } + return !_trackingEntities; +} - Locker lock(_lock); - if (_entityTreeRenderer) { - auto entityTree = _entityTreeRenderer->getTree(); - disconnect(std::const_pointer_cast(entityTree).get(), - &EntityTree::addingEntity, this, &SafeLanding::addTrackedEntity); - disconnect(std::const_pointer_cast(entityTree).get(), - &EntityTree::deletingEntity, this, &SafeLanding::deleteTrackedEntity); - _entityTreeRenderer.reset(); - } - - _initialStart = INVALID_SEQUENCE; - _initialEnd = INVALID_SEQUENCE; - EntityTreeRenderer::setEntityLoadingPriorityFunction(StandardPriority); +void SafeLanding::stopTracking() { + Locker lock(_lock); + _trackingEntities = false; + if (_entityTreeRenderer) { + auto entityTree = _entityTreeRenderer->getTree(); + disconnect(std::const_pointer_cast(entityTree).get(), + &EntityTree::addingEntity, this, &SafeLanding::addTrackedEntity); + disconnect(std::const_pointer_cast(entityTree).get(), + &EntityTree::deletingEntity, this, &SafeLanding::deleteTrackedEntity); + _entityTreeRenderer.reset(); } - return !_trackingEntities; + _initialStart = INVALID_SEQUENCE; + _initialEnd = INVALID_SEQUENCE; + EntityTreeRenderer::setEntityLoadingPriorityFunction(StandardPriority); } float SafeLanding::loadingProgressPercentage() { diff --git a/interface/src/octree/SafeLanding.h b/interface/src/octree/SafeLanding.h index 428ca15bdc..f88282ba5e 100644 --- a/interface/src/octree/SafeLanding.h +++ b/interface/src/octree/SafeLanding.h @@ -26,7 +26,6 @@ class EntityItemID; class SafeLanding : public QObject { public: void startEntitySequence(QSharedPointer entityTreeRenderer); - void stopEntitySequence(); void setCompletionSequenceNumbers(int first, int last); // 'last' exclusive. void noteReceivedsequenceNumber(int sequenceNumber); bool isLoadSequenceComplete(); @@ -41,6 +40,7 @@ private: bool isEntityPhysicsReady(const EntityItemPointer& entity); void debugDumpSequenceIDs() const; bool isEntityLoadingComplete(); + void stopTracking(); std::mutex _lock; using Locker = std::lock_guard; From 00185ee82e0afcf953b4713cad0dd17e4b6b0d77 Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Wed, 26 Jun 2019 17:05:44 -0700 Subject: [PATCH 05/26] cleaup to help unravel one spaghetti strand --- interface/src/Application.cpp | 41 +++++++++++-------- interface/src/Application.h | 1 + .../src/octree/OctreePacketProcessor.cpp | 10 +++-- interface/src/octree/OctreePacketProcessor.h | 1 + interface/src/octree/SafeLanding.cpp | 8 ++-- interface/src/octree/SafeLanding.h | 8 ++-- 6 files changed, 42 insertions(+), 27 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index e23e3172ac..58b042e084 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -6165,6 +6165,24 @@ void Application::updateSecondaryCameraViewFrustum() { static bool domainLoadingInProgress = false; +void Application::tryToEnablePhysics() { + bool enableInterstitial = DependencyManager::get()->getDomainHandler().getInterstitialModeEnabled(); + + if (gpuTextureMemSizeStable() || !enableInterstitial) { + _fullSceneCounterAtLastPhysicsCheck = _fullSceneReceivedCounter; + _lastQueriedViews.clear(); // Force new view. + + // process octree stats packets are sent in between full sends of a scene (this isn't currently true). + // We keep physics disabled until we've received a full scene and everything near the avatar in that + // scene is ready to compute its collision shape. + if (getMyAvatar()->isReadyForPhysics()) { + _physicsEnabled = true; + setIsInterstitialMode(false); + getMyAvatar()->updateMotionBehaviorFromMenu(); + } + } +} + void Application::update(float deltaTime) { PROFILE_RANGE_EX(app, __FUNCTION__, 0xffff0000, (uint64_t)_graphicsEngine._renderFrameCount + 1); @@ -6172,7 +6190,6 @@ void Application::update(float deltaTime) { return; } - if (!_physicsEnabled) { if (!domainLoadingInProgress) { PROFILE_ASYNC_BEGIN(app, "Scene Loading", ""); @@ -6182,21 +6199,13 @@ void Application::update(float deltaTime) { // we haven't yet enabled physics. we wait until we think we have all the collision information // for nearby entities before starting bullet up. quint64 now = usecTimestampNow(); - if (isServerlessMode() || _octreeProcessor.isLoadSequenceComplete()) { - bool enableInterstitial = DependencyManager::get()->getDomainHandler().getInterstitialModeEnabled(); - - if (gpuTextureMemSizeStable() || !enableInterstitial) { - _fullSceneCounterAtLastPhysicsCheck = _fullSceneReceivedCounter; - _lastQueriedViews.clear(); // Force new view. - - // process octree stats packets are sent in between full sends of a scene (this isn't currently true). - // We keep physics disabled until we've received a full scene and everything near the avatar in that - // scene is ready to compute its collision shape. - if (getMyAvatar()->isReadyForPhysics()) { - _physicsEnabled = true; - setIsInterstitialMode(false); - getMyAvatar()->updateMotionBehaviorFromMenu(); - } + if (isServerlessMode()) { + tryToEnablePhysics(); + } else if (_failedToConnectToEntityServer) { + _octreeProcessor.stopSafeLanding(); + } else { + if (_octreeProcessor.isLoadSequenceComplete()) { + tryToEnablePhysics(); } } } else if (domainLoadingInProgress) { diff --git a/interface/src/Application.h b/interface/src/Application.h index bd7c9d758e..8b25417abe 100644 --- a/interface/src/Application.h +++ b/interface/src/Application.h @@ -564,6 +564,7 @@ private: void cleanupBeforeQuit(); void idle(); + void tryToEnablePhysics(); void update(float deltaTime); // Various helper functions called during update() diff --git a/interface/src/octree/OctreePacketProcessor.cpp b/interface/src/octree/OctreePacketProcessor.cpp index 544c56c802..68e68ee0af 100644 --- a/interface/src/octree/OctreePacketProcessor.cpp +++ b/interface/src/octree/OctreePacketProcessor.cpp @@ -115,7 +115,7 @@ void OctreePacketProcessor::processPacket(QSharedPointer messag auto renderer = qApp->getEntities(); if (renderer) { renderer->processDatagram(*message, sendingNode); - _safeLanding->noteReceivedsequenceNumber(renderer->getLastOctreeMessageSequence()); + _safeLanding->updateSequence(renderer->getLastOctreeMessageSequence()); } } } break; @@ -124,7 +124,7 @@ void OctreePacketProcessor::processPacket(QSharedPointer messag // Read sequence # OCTREE_PACKET_SEQUENCE completionNumber; message->readPrimitive(&completionNumber); - _safeLanding->setCompletionSequenceNumbers(0, completionNumber); + _safeLanding->finishSequence(0, completionNumber); } break; default: { @@ -134,5 +134,9 @@ void OctreePacketProcessor::processPacket(QSharedPointer messag } void OctreePacketProcessor::startSafeLanding() { - _safeLanding->startEntitySequence(qApp->getEntities()); + _safeLanding->startTracking(qApp->getEntities()); +} + +void OctreePacketProcessor::stopSafeLanding() { + _safeLanding->stopTracking(); } diff --git a/interface/src/octree/OctreePacketProcessor.h b/interface/src/octree/OctreePacketProcessor.h index 7f906eab99..5c5bc7ed9a 100644 --- a/interface/src/octree/OctreePacketProcessor.h +++ b/interface/src/octree/OctreePacketProcessor.h @@ -26,6 +26,7 @@ public: ~OctreePacketProcessor(); void startSafeLanding(); + void stopSafeLanding(); bool isLoadSequenceComplete() const { return _safeLanding->isLoadSequenceComplete(); } float domainLoadingProgress() const { return _safeLanding->loadingProgressPercentage(); } diff --git a/interface/src/octree/SafeLanding.cpp b/interface/src/octree/SafeLanding.cpp index e4a2156aff..3ae31a4b1a 100644 --- a/interface/src/octree/SafeLanding.cpp +++ b/interface/src/octree/SafeLanding.cpp @@ -33,7 +33,7 @@ bool SafeLanding::SequenceLessThan::operator()(const int& a, const int& b) const return lessThanWraparound(a, b); } -void SafeLanding::startEntitySequence(QSharedPointer entityTreeRenderer) { +void SafeLanding::startTracking(QSharedPointer entityTreeRenderer) { if (!entityTreeRenderer.isNull()) { auto entityTree = entityTreeRenderer->getTree(); if (entityTree && !_trackingEntities) { @@ -81,7 +81,7 @@ void SafeLanding::deleteTrackedEntity(const EntityItemID& entityID) { _trackedEntities.erase(entityID); } -void SafeLanding::setCompletionSequenceNumbers(int first, int last) { +void SafeLanding::finishSequence(int first, int last) { Locker lock(_lock); if (_initialStart == INVALID_SEQUENCE) { _initialStart = first; @@ -89,7 +89,7 @@ void SafeLanding::setCompletionSequenceNumbers(int first, int last) { } } -void SafeLanding::noteReceivedsequenceNumber(int sequenceNumber) { +void SafeLanding::updateSequence(int sequenceNumber) { if (_trackingEntities) { Locker lock(_lock); _sequenceNumbers.insert(sequenceNumber); @@ -97,7 +97,7 @@ void SafeLanding::noteReceivedsequenceNumber(int sequenceNumber) { } bool SafeLanding::isLoadSequenceComplete() { - if ((isEntityLoadingComplete() && isSequenceNumbersComplete()) || qApp->failedToConnectToEntityServer()) { + if (isEntityLoadingComplete() && isSequenceNumbersComplete()) { stopTracking(); } return !_trackingEntities; diff --git a/interface/src/octree/SafeLanding.h b/interface/src/octree/SafeLanding.h index f88282ba5e..ec9fb98989 100644 --- a/interface/src/octree/SafeLanding.h +++ b/interface/src/octree/SafeLanding.h @@ -25,9 +25,10 @@ class EntityItemID; class SafeLanding : public QObject { public: - void startEntitySequence(QSharedPointer entityTreeRenderer); - void setCompletionSequenceNumbers(int first, int last); // 'last' exclusive. - void noteReceivedsequenceNumber(int sequenceNumber); + void startTracking(QSharedPointer entityTreeRenderer); + void stopTracking(); + void finishSequence(int first, int last); // 'last' exclusive. + void updateSequence(int sequenceNumber); bool isLoadSequenceComplete(); float loadingProgressPercentage(); @@ -40,7 +41,6 @@ private: bool isEntityPhysicsReady(const EntityItemPointer& entity); void debugDumpSequenceIDs() const; bool isEntityLoadingComplete(); - void stopTracking(); std::mutex _lock; using Locker = std::lock_guard; From 50965f1916619ee1aca1694d04318503f4bad05d Mon Sep 17 00:00:00 2001 From: Simon Walton Date: Wed, 26 Jun 2019 18:04:41 -0700 Subject: [PATCH 06/26] Handle remote public-address changes --- libraries/networking/src/NetworkPeer.cpp | 24 ++++++++++++------------ libraries/networking/src/NetworkPeer.h | 2 +- libraries/networking/src/udt/Socket.cpp | 5 +++++ libraries/networking/src/udt/Socket.h | 2 +- 4 files changed, 19 insertions(+), 14 deletions(-) diff --git a/libraries/networking/src/NetworkPeer.cpp b/libraries/networking/src/NetworkPeer.cpp index 4e0a82ba0e..a48922726e 100644 --- a/libraries/networking/src/NetworkPeer.cpp +++ b/libraries/networking/src/NetworkPeer.cpp @@ -59,13 +59,13 @@ void NetworkPeer::setPublicSocket(const HifiSockAddr& publicSocket) { bool wasOldSocketNull = _publicSocket.isNull(); - auto temp = _publicSocket.objectName(); + auto previousSocket = _publicSocket; _publicSocket = publicSocket; - _publicSocket.setObjectName(temp); + _publicSocket.setObjectName(previousSocket.objectName()); if (!wasOldSocketNull) { - qCDebug(networking) << "Public socket change for node" << *this; - emit socketUpdated(); + qCDebug(networking) << "Public socket change for node" << *this << "; previously" << previousSocket; + emit socketUpdated(previousSocket, _publicSocket); } } } @@ -79,13 +79,13 @@ void NetworkPeer::setLocalSocket(const HifiSockAddr& localSocket) { bool wasOldSocketNull = _localSocket.isNull(); - auto temp = _localSocket.objectName(); + auto previousSocket = _localSocket; _localSocket = localSocket; - _localSocket.setObjectName(temp); + _localSocket.setObjectName(previousSocket.objectName()); if (!wasOldSocketNull) { - qCDebug(networking) << "Local socket change for node" << *this; - emit socketUpdated(); + qCDebug(networking) << "Local socket change for node" << *this << "; previously" << previousSocket; + emit socketUpdated(previousSocket, _localSocket); } } } @@ -99,13 +99,13 @@ void NetworkPeer::setSymmetricSocket(const HifiSockAddr& symmetricSocket) { bool wasOldSocketNull = _symmetricSocket.isNull(); - auto temp = _symmetricSocket.objectName(); + auto previousSocket = _symmetricSocket; _symmetricSocket = symmetricSocket; - _symmetricSocket.setObjectName(temp); + _symmetricSocket.setObjectName(previousSocket.objectName()); if (!wasOldSocketNull) { - qCDebug(networking) << "Symmetric socket change for node" << *this; - emit socketUpdated(); + qCDebug(networking) << "Symmetric socket change for node" << *this << "; previously" << previousSocket; + emit socketUpdated(previousSocket, _symmetricSocket); } } } diff --git a/libraries/networking/src/NetworkPeer.h b/libraries/networking/src/NetworkPeer.h index e2149d64af..4c08c97d3c 100644 --- a/libraries/networking/src/NetworkPeer.h +++ b/libraries/networking/src/NetworkPeer.h @@ -94,7 +94,7 @@ public slots: signals: void pingTimerTimeout(); void socketActivated(const HifiSockAddr& sockAddr); - void socketUpdated(); + void socketUpdated(HifiSockAddr previousAddress, HifiSockAddr currentAddress); protected: void setActiveSocket(HifiSockAddr* discoveredSocket); diff --git a/libraries/networking/src/udt/Socket.cpp b/libraries/networking/src/udt/Socket.cpp index c56f276560..7cc6680efd 100644 --- a/libraries/networking/src/udt/Socket.cpp +++ b/libraries/networking/src/udt/Socket.cpp @@ -538,6 +538,11 @@ void Socket::handleStateChanged(QAbstractSocket::SocketState socketState) { } } +void Socket::handleRemoteAddressChange(HifiSockAddr previousAddress, HifiSockAddr currentAddress) { + Lock connectionsLock(_connectionsHashMutex); + +} + #if (PR_BUILD || DEV_BUILD) void Socket::sendFakedHandshakeRequest(const HifiSockAddr& sockAddr) { diff --git a/libraries/networking/src/udt/Socket.h b/libraries/networking/src/udt/Socket.h index ad9d6de8b8..74eb413bc2 100644 --- a/libraries/networking/src/udt/Socket.h +++ b/libraries/networking/src/udt/Socket.h @@ -106,11 +106,11 @@ private slots: void handleSocketError(QAbstractSocket::SocketError socketError); void handleStateChanged(QAbstractSocket::SocketState socketState); + void handleRemoteAddressChange(HifiSockAddr previousAddress, HifiSockAddr currentAddress); private: void setSystemBufferSizes(); Connection* findOrCreateConnection(const HifiSockAddr& sockAddr, bool filterCreation = false); - bool socketMatchesNodeOrDomain(const HifiSockAddr& sockAddr); // privatized methods used by UDTTest - they are private since they must be called on the Socket thread ConnectionStats::Stats sampleStatsForConnection(const HifiSockAddr& destination); From dfb7ac7044e3e9ad1d3d02e49d8dec4f55e29d1b Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Thu, 27 Jun 2019 08:14:34 -0700 Subject: [PATCH 07/26] name changes and improved flow for SafeLanding logic --- interface/src/Application.cpp | 4 +- .../src/octree/OctreePacketProcessor.cpp | 10 +- interface/src/octree/OctreePacketProcessor.h | 4 +- interface/src/octree/SafeLanding.cpp | 143 ++++++++---------- interface/src/octree/SafeLanding.h | 8 +- 5 files changed, 81 insertions(+), 88 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 58b042e084..7ffa32c40c 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -6198,13 +6198,13 @@ void Application::update(float deltaTime) { // we haven't yet enabled physics. we wait until we think we have all the collision information // for nearby entities before starting bullet up. - quint64 now = usecTimestampNow(); if (isServerlessMode()) { tryToEnablePhysics(); } else if (_failedToConnectToEntityServer) { _octreeProcessor.stopSafeLanding(); } else { - if (_octreeProcessor.isLoadSequenceComplete()) { + _octreeProcessor.updateSafeLanding(); + if (_octreeProcessor.safeLandingIsComplete()) { tryToEnablePhysics(); } } diff --git a/interface/src/octree/OctreePacketProcessor.cpp b/interface/src/octree/OctreePacketProcessor.cpp index 68e68ee0af..1cfbcd0890 100644 --- a/interface/src/octree/OctreePacketProcessor.cpp +++ b/interface/src/octree/OctreePacketProcessor.cpp @@ -115,7 +115,7 @@ void OctreePacketProcessor::processPacket(QSharedPointer messag auto renderer = qApp->getEntities(); if (renderer) { renderer->processDatagram(*message, sendingNode); - _safeLanding->updateSequence(renderer->getLastOctreeMessageSequence()); + _safeLanding->addToSequence(renderer->getLastOctreeMessageSequence()); } } } break; @@ -137,6 +137,14 @@ void OctreePacketProcessor::startSafeLanding() { _safeLanding->startTracking(qApp->getEntities()); } +void OctreePacketProcessor::updateSafeLanding() { + _safeLanding->updateTracking(); +} + void OctreePacketProcessor::stopSafeLanding() { _safeLanding->stopTracking(); } + +bool OctreePacketProcessor::safeLandingIsComplete() const { + return _safeLanding->trackingIsComplete(); +} diff --git a/interface/src/octree/OctreePacketProcessor.h b/interface/src/octree/OctreePacketProcessor.h index 5c5bc7ed9a..e59ae7cb5e 100644 --- a/interface/src/octree/OctreePacketProcessor.h +++ b/interface/src/octree/OctreePacketProcessor.h @@ -26,8 +26,10 @@ public: ~OctreePacketProcessor(); void startSafeLanding(); + void updateSafeLanding(); void stopSafeLanding(); - bool isLoadSequenceComplete() const { return _safeLanding->isLoadSequenceComplete(); } + bool safeLandingIsComplete() const; + float domainLoadingProgress() const { return _safeLanding->loadingProgressPercentage(); } signals: diff --git a/interface/src/octree/SafeLanding.cpp b/interface/src/octree/SafeLanding.cpp index 3ae31a4b1a..c9fd8c01ee 100644 --- a/interface/src/octree/SafeLanding.cpp +++ b/interface/src/octree/SafeLanding.cpp @@ -40,18 +40,18 @@ void SafeLanding::startTracking(QSharedPointer entityTreeRen Locker lock(_lock); _entityTreeRenderer = entityTreeRenderer; _trackedEntities.clear(); - _trackingEntities = true; _maxTrackedEntityCount = 0; + _initialStart = INVALID_SEQUENCE; + _initialEnd = INVALID_SEQUENCE; + _sequenceNumbers.clear(); + _trackingEntities = true; + _startTime = usecTimestampNow(); connect(std::const_pointer_cast(entityTree).get(), &EntityTree::addingEntity, this, &SafeLanding::addTrackedEntity, Qt::DirectConnection); connect(std::const_pointer_cast(entityTree).get(), &EntityTree::deletingEntity, this, &SafeLanding::deleteTrackedEntity); - _sequenceNumbers.clear(); - _initialStart = INVALID_SEQUENCE; - _initialEnd = INVALID_SEQUENCE; - _startTime = usecTimestampNow(); EntityTreeRenderer::setEntityLoadingPriorityFunction(&ElevatedPriority); } } @@ -83,24 +83,71 @@ void SafeLanding::deleteTrackedEntity(const EntityItemID& entityID) { void SafeLanding::finishSequence(int first, int last) { Locker lock(_lock); - if (_initialStart == INVALID_SEQUENCE) { + if (_trackingEntities) { _initialStart = first; _initialEnd = last; } } -void SafeLanding::updateSequence(int sequenceNumber) { +void SafeLanding::addToSequence(int sequenceNumber) { + Locker lock(_lock); if (_trackingEntities) { - Locker lock(_lock); _sequenceNumbers.insert(sequenceNumber); } } -bool SafeLanding::isLoadSequenceComplete() { - if (isEntityLoadingComplete() && isSequenceNumbersComplete()) { - stopTracking(); +void SafeLanding::updateTracking() { + if (!_trackingEntities || !_entityTreeRenderer) { + return; + } + Locker lock(_lock); + + bool enableInterstitial = DependencyManager::get()->getDomainHandler().getInterstitialModeEnabled(); + + auto entityMapIter = _trackedEntities.begin(); + while (entityMapIter != _trackedEntities.end()) { + auto entity = entityMapIter->second; + bool isVisuallyReady = true; + if (enableInterstitial) { + auto entityRenderable = _entityTreeRenderer->renderableForEntityId(entityMapIter->first); + if (!entityRenderable) { + _entityTreeRenderer->addingEntity(entityMapIter->first); + } + + isVisuallyReady = entity->isVisuallyReady() || (!entityRenderable && !entity->isParentPathComplete()); + } + if (isEntityPhysicsReady(entity) && isVisuallyReady) { + entityMapIter = _trackedEntities.erase(entityMapIter); + } else { + if (!isVisuallyReady) { + entity->requestRenderUpdate(); + } + entityMapIter++; + } + } + + if (enableInterstitial) { + _trackedEntityStabilityCount++; + } + + if (_trackedEntities.empty()) { + // no more tracked entities --> check sequenceNumbers + if (_initialStart != INVALID_SEQUENCE) { + Locker lock(_lock); + int sequenceSize = _initialStart <= _initialEnd ? _initialEnd - _initialStart: + _initialEnd + SEQUENCE_MODULO - _initialStart; + auto startIter = _sequenceNumbers.find(_initialStart); + auto endIter = _sequenceNumbers.find(_initialEnd - 1); + + bool missingSequenceNumbers = qApp->isMissingSequenceNumbers(); + if (sequenceSize == 0 || + (startIter != _sequenceNumbers.end() && + endIter != _sequenceNumbers.end() && + ((distance(startIter, endIter) == sequenceSize - 1) || !missingSequenceNumbers))) { + stopTracking(); + } + } } - return !_trackingEntities; } void SafeLanding::stopTracking() { @@ -114,12 +161,13 @@ void SafeLanding::stopTracking() { &EntityTree::deletingEntity, this, &SafeLanding::deleteTrackedEntity); _entityTreeRenderer.reset(); } - - _initialStart = INVALID_SEQUENCE; - _initialEnd = INVALID_SEQUENCE; EntityTreeRenderer::setEntityLoadingPriorityFunction(StandardPriority); } +bool SafeLanding::trackingIsComplete() const { + return !_trackingEntities && (_initialStart != INVALID_SEQUENCE); +} + float SafeLanding::loadingProgressPercentage() { Locker lock(_lock); static const int MINIMUM_TRACKED_ENTITY_STABILITY_COUNT = 15; @@ -136,29 +184,6 @@ float SafeLanding::loadingProgressPercentage() { return entityReadyPercentage; } -bool SafeLanding::isSequenceNumbersComplete() { - if (_initialStart != INVALID_SEQUENCE) { - Locker lock(_lock); - int sequenceSize = _initialStart <= _initialEnd ? _initialEnd - _initialStart: - _initialEnd + SEQUENCE_MODULO - _initialStart; - auto startIter = _sequenceNumbers.find(_initialStart); - auto endIter = _sequenceNumbers.find(_initialEnd - 1); - - bool missingSequenceNumbers = qApp->isMissingSequenceNumbers(); - if (sequenceSize == 0 || - (startIter != _sequenceNumbers.end() - && endIter != _sequenceNumbers.end() - && ((distance(startIter, endIter) == sequenceSize - 1) || !missingSequenceNumbers))) { - bool enableInterstitial = DependencyManager::get()->getDomainHandler().getInterstitialModeEnabled(); - if (!enableInterstitial) { - _trackingEntities = false; // Don't track anything else that comes in. - } - return true; - } - } - return false; -} - bool SafeLanding::isEntityPhysicsReady(const EntityItemPointer& entity) { if (entity && !entity->getCollisionless()) { const auto& entityType = entity->getType(); @@ -176,51 +201,9 @@ bool SafeLanding::isEntityPhysicsReady(const EntityItemPointer& entity) { } } } - return true; } -bool SafeLanding::isEntityLoadingComplete() { - Locker lock(_lock); - if (!_entityTreeRenderer) { - return true; - } - auto entityMapIter = _trackedEntities.begin(); - - bool enableInterstitial = DependencyManager::get()->getDomainHandler().getInterstitialModeEnabled(); - - while (entityMapIter != _trackedEntities.end()) { - auto entity = entityMapIter->second; - - bool isVisuallyReady = true; - - if (enableInterstitial) { - auto entityRenderable = _entityTreeRenderer->renderableForEntityId(entityMapIter->first); - if (!entityRenderable) { - _entityTreeRenderer->addingEntity(entityMapIter->first); - } - - isVisuallyReady = entity->isVisuallyReady() || (!entityRenderable && !entity->isParentPathComplete()); - } - - if (isEntityPhysicsReady(entity) && isVisuallyReady) { - entityMapIter = _trackedEntities.erase(entityMapIter); - } else { - if (!isVisuallyReady) { - entity->requestRenderUpdate(); - } - - entityMapIter++; - } - } - - if (enableInterstitial) { - _trackedEntityStabilityCount++; - } - - return _trackedEntities.empty(); -} - float SafeLanding::ElevatedPriority(const EntityItem& entityItem) { return entityItem.getCollisionless() ? 0.0f : 10.0f; } diff --git a/interface/src/octree/SafeLanding.h b/interface/src/octree/SafeLanding.h index ec9fb98989..32fba282fe 100644 --- a/interface/src/octree/SafeLanding.h +++ b/interface/src/octree/SafeLanding.h @@ -26,10 +26,12 @@ class EntityItemID; class SafeLanding : public QObject { public: void startTracking(QSharedPointer entityTreeRenderer); + void updateTracking(); void stopTracking(); + bool trackingIsComplete() const; + void finishSequence(int first, int last); // 'last' exclusive. - void updateSequence(int sequenceNumber); - bool isLoadSequenceComplete(); + void addToSequence(int sequenceNumber); float loadingProgressPercentage(); private slots: @@ -37,10 +39,8 @@ private slots: void deleteTrackedEntity(const EntityItemID& entityID); private: - bool isSequenceNumbersComplete(); bool isEntityPhysicsReady(const EntityItemPointer& entity); void debugDumpSequenceIDs() const; - bool isEntityLoadingComplete(); std::mutex _lock; using Locker = std::lock_guard; From bf068a32114036130a4901e2475999d5486f59d1 Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Thu, 27 Jun 2019 11:33:51 -0700 Subject: [PATCH 08/26] fix SafeLanding start/stop on entity-server connection flow --- interface/src/Application.cpp | 17 +++-- interface/src/Application.h | 2 +- .../src/octree/OctreePacketProcessor.cpp | 29 +++++--- interface/src/octree/OctreePacketProcessor.h | 1 + interface/src/octree/SafeLanding.cpp | 69 ++++++++++--------- interface/src/octree/SafeLanding.h | 1 + 6 files changed, 71 insertions(+), 48 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 7ffa32c40c..676577932a 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -6201,7 +6201,9 @@ void Application::update(float deltaTime) { if (isServerlessMode()) { tryToEnablePhysics(); } else if (_failedToConnectToEntityServer) { - _octreeProcessor.stopSafeLanding(); + if (_octreeProcessor.safeLandingIsActive()) { + _octreeProcessor.stopSafeLanding(); + } } else { _octreeProcessor.updateSafeLanding(); if (_octreeProcessor.safeLandingIsComplete()) { @@ -7154,13 +7156,17 @@ void Application::resettingDomain() { clearDomainOctreeDetails(false); } -void Application::nodeAdded(SharedNodePointer node) const { +void Application::nodeAdded(SharedNodePointer node) { if (node->getType() == NodeType::EntityServer) { - if (!_failedToConnectToEntityServer) { + if (_failedToConnectToEntityServer && !_entityServerConnectionTimer.isActive()) { + _failedToConnectToEntityServer = false; + _octreeProcessor.stopSafeLanding(); + _octreeProcessor.startSafeLanding(); + } else if (_entityServerConnectionTimer.isActive()) { _entityServerConnectionTimer.stop(); - _entityServerConnectionTimer.setInterval(ENTITY_SERVER_CONNECTION_TIMEOUT); - _entityServerConnectionTimer.start(); } + _entityServerConnectionTimer.setInterval(ENTITY_SERVER_CONNECTION_TIMEOUT); + _entityServerConnectionTimer.start(); } } @@ -7170,7 +7176,6 @@ void Application::nodeActivated(SharedNodePointer node) { #if !defined(DISABLE_QML) auto offscreenUi = getOffscreenUI(); - if (offscreenUi) { auto nodeList = DependencyManager::get(); diff --git a/interface/src/Application.h b/interface/src/Application.h index 8b25417abe..2d6821bbd9 100644 --- a/interface/src/Application.h +++ b/interface/src/Application.h @@ -527,7 +527,7 @@ private slots: void domainURLChanged(QUrl domainURL); void updateWindowTitle() const; - void nodeAdded(SharedNodePointer node) const; + void nodeAdded(SharedNodePointer node); void nodeActivated(SharedNodePointer node); void nodeKilled(SharedNodePointer node); static void packetSent(quint64 length); diff --git a/interface/src/octree/OctreePacketProcessor.cpp b/interface/src/octree/OctreePacketProcessor.cpp index 1cfbcd0890..7533ddbac5 100644 --- a/interface/src/octree/OctreePacketProcessor.cpp +++ b/interface/src/octree/OctreePacketProcessor.cpp @@ -63,7 +63,6 @@ void OctreePacketProcessor::processPacket(QSharedPointer messag // construct a new packet from the piggybacked one auto buffer = std::unique_ptr(new char[piggybackBytes]); memcpy(buffer.get(), message->getRawMessage() + statsMessageLength, piggybackBytes); - auto newPacket = NLPacket::fromReceivedPacket(std::move(buffer), piggybackBytes, message->getSenderSockAddr()); message = QSharedPointer::create(*newPacket); } else { @@ -80,7 +79,6 @@ void OctreePacketProcessor::processPacket(QSharedPointer messag const QUuid& senderUUID = sendingNode->getUUID(); if (!versionDebugSuppressMap.contains(senderUUID, packetType)) { - qDebug() << "Was stats packet? " << wasStatsPacket; qDebug() << "OctreePacketProcessor - piggyback packet version mismatch on" << packetType << "- Sender" << senderUUID << "sent" << (int) message->getVersion() << "but" @@ -113,7 +111,7 @@ void OctreePacketProcessor::processPacket(QSharedPointer messag case PacketType::EntityData: { if (DependencyManager::get()->shouldRenderEntities()) { auto renderer = qApp->getEntities(); - if (renderer) { + if (renderer && _safeLanding) { renderer->processDatagram(*message, sendingNode); _safeLanding->addToSequence(renderer->getLastOctreeMessageSequence()); } @@ -124,7 +122,9 @@ void OctreePacketProcessor::processPacket(QSharedPointer messag // Read sequence # OCTREE_PACKET_SEQUENCE completionNumber; message->readPrimitive(&completionNumber); - _safeLanding->finishSequence(0, completionNumber); + if (_safeLanding) { + _safeLanding->finishSequence(0, completionNumber); + } } break; default: { @@ -134,17 +134,30 @@ void OctreePacketProcessor::processPacket(QSharedPointer messag } void OctreePacketProcessor::startSafeLanding() { - _safeLanding->startTracking(qApp->getEntities()); + if (_safeLanding) { + _safeLanding->startTracking(qApp->getEntities()); + } } void OctreePacketProcessor::updateSafeLanding() { - _safeLanding->updateTracking(); + if (_safeLanding) { + _safeLanding->updateTracking(); + } } void OctreePacketProcessor::stopSafeLanding() { - _safeLanding->stopTracking(); + if (_safeLanding) { + _safeLanding->stopTracking(); + } +} + +bool OctreePacketProcessor::safeLandingIsActive() const { + return _safeLanding && _safeLanding->isTracking(); } bool OctreePacketProcessor::safeLandingIsComplete() const { - return _safeLanding->trackingIsComplete(); + if (_safeLanding) { + return _safeLanding->trackingIsComplete(); + } + return false; } diff --git a/interface/src/octree/OctreePacketProcessor.h b/interface/src/octree/OctreePacketProcessor.h index e59ae7cb5e..eacc15f62d 100644 --- a/interface/src/octree/OctreePacketProcessor.h +++ b/interface/src/octree/OctreePacketProcessor.h @@ -28,6 +28,7 @@ public: void startSafeLanding(); void updateSafeLanding(); void stopSafeLanding(); + bool safeLandingIsActive() const; bool safeLandingIsComplete() const; float domainLoadingProgress() const { return _safeLanding->loadingProgressPercentage(); } diff --git a/interface/src/octree/SafeLanding.cpp b/interface/src/octree/SafeLanding.cpp index c9fd8c01ee..bcce86f9f9 100644 --- a/interface/src/octree/SafeLanding.cpp +++ b/interface/src/octree/SafeLanding.cpp @@ -100,50 +100,53 @@ void SafeLanding::updateTracking() { if (!_trackingEntities || !_entityTreeRenderer) { return; } - Locker lock(_lock); - bool enableInterstitial = DependencyManager::get()->getDomainHandler().getInterstitialModeEnabled(); - - auto entityMapIter = _trackedEntities.begin(); - while (entityMapIter != _trackedEntities.end()) { - auto entity = entityMapIter->second; - bool isVisuallyReady = true; + { + Locker lock(_lock); + bool enableInterstitial = DependencyManager::get()->getDomainHandler().getInterstitialModeEnabled(); + auto entityMapIter = _trackedEntities.begin(); + while (entityMapIter != _trackedEntities.end()) { + auto entity = entityMapIter->second; + bool isVisuallyReady = true; + if (enableInterstitial) { + auto entityRenderable = _entityTreeRenderer->renderableForEntityId(entityMapIter->first); + if (!entityRenderable) { + _entityTreeRenderer->addingEntity(entityMapIter->first); + } + isVisuallyReady = entity->isVisuallyReady() || (!entityRenderable && !entity->isParentPathComplete()); + } + if (isEntityPhysicsReady(entity) && isVisuallyReady) { + entityMapIter = _trackedEntities.erase(entityMapIter); + } else { + if (!isVisuallyReady) { + entity->requestRenderUpdate(); + } + entityMapIter++; + } + } if (enableInterstitial) { - auto entityRenderable = _entityTreeRenderer->renderableForEntityId(entityMapIter->first); - if (!entityRenderable) { - _entityTreeRenderer->addingEntity(entityMapIter->first); - } - - isVisuallyReady = entity->isVisuallyReady() || (!entityRenderable && !entity->isParentPathComplete()); + _trackedEntityStabilityCount++; } - if (isEntityPhysicsReady(entity) && isVisuallyReady) { - entityMapIter = _trackedEntities.erase(entityMapIter); - } else { - if (!isVisuallyReady) { - entity->requestRenderUpdate(); - } - entityMapIter++; - } - } - - if (enableInterstitial) { - _trackedEntityStabilityCount++; } if (_trackedEntities.empty()) { // no more tracked entities --> check sequenceNumbers if (_initialStart != INVALID_SEQUENCE) { - Locker lock(_lock); - int sequenceSize = _initialStart <= _initialEnd ? _initialEnd - _initialStart: - _initialEnd + SEQUENCE_MODULO - _initialStart; - auto startIter = _sequenceNumbers.find(_initialStart); - auto endIter = _sequenceNumbers.find(_initialEnd - 1); + bool shouldStop = false; + { + Locker lock(_lock); + int sequenceSize = _initialStart <= _initialEnd ? _initialEnd - _initialStart: + _initialEnd + SEQUENCE_MODULO - _initialStart; + auto startIter = _sequenceNumbers.find(_initialStart); + auto endIter = _sequenceNumbers.find(_initialEnd - 1); - bool missingSequenceNumbers = qApp->isMissingSequenceNumbers(); - if (sequenceSize == 0 || + bool missingSequenceNumbers = qApp->isMissingSequenceNumbers(); + shouldStop = (sequenceSize == 0 || (startIter != _sequenceNumbers.end() && endIter != _sequenceNumbers.end() && - ((distance(startIter, endIter) == sequenceSize - 1) || !missingSequenceNumbers))) { + ((distance(startIter, endIter) == sequenceSize - 1) || !missingSequenceNumbers))); + } + if (shouldStop) { stopTracking(); } } diff --git a/interface/src/octree/SafeLanding.h b/interface/src/octree/SafeLanding.h index 32fba282fe..2f1db2366f 100644 --- a/interface/src/octree/SafeLanding.h +++ b/interface/src/octree/SafeLanding.h @@ -28,6 +28,7 @@ public: void startTracking(QSharedPointer entityTreeRenderer); void updateTracking(); void stopTracking(); + bool isTracking() const { return _trackingEntities; } bool trackingIsComplete() const; void finishSequence(int first, int last); // 'last' exclusive. From 0bec2bca838f69a2f040b3dca31bdbd1a22f93ab Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Thu, 27 Jun 2019 14:44:23 -0700 Subject: [PATCH 09/26] OctreePacketProcessor should process packet even when no SafeLanding --- interface/src/octree/OctreePacketProcessor.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/interface/src/octree/OctreePacketProcessor.cpp b/interface/src/octree/OctreePacketProcessor.cpp index 7533ddbac5..c6f908e039 100644 --- a/interface/src/octree/OctreePacketProcessor.cpp +++ b/interface/src/octree/OctreePacketProcessor.cpp @@ -111,9 +111,11 @@ void OctreePacketProcessor::processPacket(QSharedPointer messag case PacketType::EntityData: { if (DependencyManager::get()->shouldRenderEntities()) { auto renderer = qApp->getEntities(); - if (renderer && _safeLanding) { + if (renderer) { renderer->processDatagram(*message, sendingNode); - _safeLanding->addToSequence(renderer->getLastOctreeMessageSequence()); + if (_safeLanding && _safeLanding->isTracking()) { + _safeLanding->addToSequence(renderer->getLastOctreeMessageSequence()); + } } } } break; From 1265531f797f535e95ba18cfd696482115050673 Mon Sep 17 00:00:00 2001 From: Simon Walton Date: Thu, 27 Jun 2019 15:52:39 -0700 Subject: [PATCH 10/26] Plumb down change of destination address --- libraries/networking/src/udt/Connection.cpp | 8 ++++++++ libraries/networking/src/udt/Connection.h | 2 ++ libraries/networking/src/udt/SendQueue.cpp | 4 ++++ libraries/networking/src/udt/SendQueue.h | 1 + libraries/networking/src/udt/Socket.cpp | 8 ++++++++ 5 files changed, 23 insertions(+) diff --git a/libraries/networking/src/udt/Connection.cpp b/libraries/networking/src/udt/Connection.cpp index 418dc8f417..872ee4dd4c 100644 --- a/libraries/networking/src/udt/Connection.cpp +++ b/libraries/networking/src/udt/Connection.cpp @@ -114,6 +114,7 @@ SendQueue& Connection::getSendQueue() { QObject::connect(_sendQueue.get(), &SendQueue::packetRetransmitted, this, &Connection::recordRetransmission); QObject::connect(_sendQueue.get(), &SendQueue::queueInactive, this, &Connection::queueInactive); QObject::connect(_sendQueue.get(), &SendQueue::timeout, this, &Connection::queueTimeout); + QObject::connect(this, &Connection::destinationAddressChange, _sendQueue.get(), &SendQueue::updateDestinationAddress); // set defaults on the send queue from our congestion control object and estimatedTimeout() @@ -485,3 +486,10 @@ std::unique_ptr PendingReceivedMessage::removeNextPacket() { } return std::unique_ptr(); } + +void Connection::setDestinationAddress(const HifiSockAddr& destination) { + if (_destination != destination) { + _destination = destination; + emit destinationAddressChange(destination); + } +} diff --git a/libraries/networking/src/udt/Connection.h b/libraries/networking/src/udt/Connection.h index 938ec36860..47edb021c8 100644 --- a/libraries/networking/src/udt/Connection.h +++ b/libraries/networking/src/udt/Connection.h @@ -76,10 +76,12 @@ public: void recordSentUnreliablePackets(int wireSize, int payloadSize); void recordReceivedUnreliablePackets(int wireSize, int payloadSize); + void setDestinationAddress(const HifiSockAddr& destination); signals: void packetSent(); void receiverHandshakeRequestComplete(const HifiSockAddr& sockAddr); + void destinationAddressChange(HifiSockAddr currentAddress); private slots: void recordSentPackets(int wireSize, int payloadSize, SequenceNumber seqNum, p_high_resolution_clock::time_point timePoint); diff --git a/libraries/networking/src/udt/SendQueue.cpp b/libraries/networking/src/udt/SendQueue.cpp index 15841b5c21..2997c272f9 100644 --- a/libraries/networking/src/udt/SendQueue.cpp +++ b/libraries/networking/src/udt/SendQueue.cpp @@ -557,3 +557,7 @@ void SendQueue::deactivate() { bool SendQueue::isFlowWindowFull() const { return seqlen(SequenceNumber { (uint32_t) _lastACKSequenceNumber }, _currentSequenceNumber) > _flowWindowSize; } + +void SendQueue::updateDestinationAddress(HifiSockAddr newAddress) { + _destination = newAddress; +} diff --git a/libraries/networking/src/udt/SendQueue.h b/libraries/networking/src/udt/SendQueue.h index c1a2b59075..2153745250 100644 --- a/libraries/networking/src/udt/SendQueue.h +++ b/libraries/networking/src/udt/SendQueue.h @@ -75,6 +75,7 @@ public slots: void ack(SequenceNumber ack); void fastRetransmit(SequenceNumber ack); void handshakeACK(); + void updateDestinationAddress(HifiSockAddr newAddress); signals: void packetSent(int wireSize, int payloadSize, SequenceNumber seqNum, p_high_resolution_clock::time_point timePoint); diff --git a/libraries/networking/src/udt/Socket.cpp b/libraries/networking/src/udt/Socket.cpp index 7cc6680efd..94628aa852 100644 --- a/libraries/networking/src/udt/Socket.cpp +++ b/libraries/networking/src/udt/Socket.cpp @@ -540,7 +540,15 @@ void Socket::handleStateChanged(QAbstractSocket::SocketState socketState) { void Socket::handleRemoteAddressChange(HifiSockAddr previousAddress, HifiSockAddr currentAddress) { Lock connectionsLock(_connectionsHashMutex); + _connectionsHash.erase(currentAddress); + const auto connectionIter = _connectionsHash.find(currentAddress); + if (connectionIter != _connectionsHash.end()) { + auto connection = std::move(connectionIter->second); + _connectionsHash.erase(connectionIter); + connection->setDestinationAddress(currentAddress); + _connectionsHash[currentAddress] = std::move(connection); + } } #if (PR_BUILD || DEV_BUILD) From 8af469992e85094279a5fde04d1acca90c7ed306 Mon Sep 17 00:00:00 2001 From: Zach Fox Date: Thu, 27 Jun 2019 15:40:18 -0700 Subject: [PATCH 11/26] BUGZ-858: Implement 'Reduce Other Volume While Pushing-to-Talk' option --- .../simplifiedUI/settingsApp/audio/Audio.qml | 44 +++++++++++++++++++ .../hifi/simplifiedUI/settingsApp/vr/VR.qml | 1 + .../SimplifiedConstants.qml | 6 ++- .../simplifiedControls/Slider.qml | 2 +- .../simplifiedControls/Switch.qml | 16 ++++--- interface/src/scripting/Audio.cpp | 35 ++++++++++++++- interface/src/scripting/Audio.h | 31 ++++++++++++- 7 files changed, 125 insertions(+), 10 deletions(-) diff --git a/interface/resources/qml/hifi/simplifiedUI/settingsApp/audio/Audio.qml b/interface/resources/qml/hifi/simplifiedUI/settingsApp/audio/Audio.qml index 68a8fa49da..ec211fd2f5 100644 --- a/interface/resources/qml/hifi/simplifiedUI/settingsApp/audio/Audio.qml +++ b/interface/resources/qml/hifi/simplifiedUI/settingsApp/audio/Audio.qml @@ -182,6 +182,7 @@ Flickable { ColumnLayout { id: micControlsSwitchGroup + Layout.preferredWidth: parent.width Layout.topMargin: simplifiedUI.margins.settings.settingsGroupTopMargin SimplifiedControls.Switch { @@ -205,6 +206,49 @@ Flickable { AudioScriptingInterface.pushToTalkDesktop = !AudioScriptingInterface.pushToTalkDesktop; } } + + SimplifiedControls.Switch { + id: attenuateOutputSwitch + enabled: AudioScriptingInterface.pushToTalkDesktop + Layout.preferredHeight: 18 + Layout.preferredWidth: parent.width + labelTextOn: "Reduce volume of other sounds while I'm pushing-to-talk" + checked: AudioScriptingInterface.pushingToTalkOutputGainDesktop !== 0.0 + onClicked: { + if (AudioScriptingInterface.pushingToTalkOutputGainDesktop === 0.0) { + AudioScriptingInterface.pushingToTalkOutputGainDesktop = -20.0; + } else { + AudioScriptingInterface.pushingToTalkOutputGainDesktop = 0.0; + } + } + } + + SimplifiedControls.Slider { + id: muteOutputSlider + enabled: AudioScriptingInterface.pushToTalkDesktop && attenuateOutputSwitch.checked + Layout.preferredWidth: parent.width + Layout.preferredHeight: 18 + labelText: "Amount to reduce" + from: 0.0 + to: 60.0 + defaultValue: 20.0 + stepSize: 5.0 + value: -1 * AudioScriptingInterface.pushingToTalkOutputGainDesktop + live: true + function updatePushingToTalkOutputGainDesktop(newValue) { + if (AudioScriptingInterface.pushingToTalkOutputGainDesktop !== newValue) { + AudioScriptingInterface.pushingToTalkOutputGainDesktop = newValue; + } + } + onValueChanged: { + updatePushingToTalkOutputGainDesktop(-1 * value); + } + onPressedChanged: { + if (!pressed) { + updatePushingToTalkOutputGainDesktop(-1 * value); + } + } + } } } diff --git a/interface/resources/qml/hifi/simplifiedUI/settingsApp/vr/VR.qml b/interface/resources/qml/hifi/simplifiedUI/settingsApp/vr/VR.qml index c1dc3888e2..d7e85c7f68 100644 --- a/interface/resources/qml/hifi/simplifiedUI/settingsApp/vr/VR.qml +++ b/interface/resources/qml/hifi/simplifiedUI/settingsApp/vr/VR.qml @@ -171,6 +171,7 @@ Flickable { ColumnLayout { id: micControlsSwitchGroup + Layout.preferredWidth: parent.width Layout.topMargin: simplifiedUI.margins.settings.settingsGroupTopMargin SimplifiedControls.Switch { diff --git a/interface/resources/qml/hifi/simplifiedUI/simplifiedConstants/SimplifiedConstants.qml b/interface/resources/qml/hifi/simplifiedUI/simplifiedConstants/SimplifiedConstants.qml index fb09a7ae1d..30b2c5a111 100644 --- a/interface/resources/qml/hifi/simplifiedUI/simplifiedConstants/SimplifiedConstants.qml +++ b/interface/resources/qml/hifi/simplifiedUI/simplifiedConstants/SimplifiedConstants.qml @@ -72,10 +72,14 @@ QtObject { readonly property color border: "#00B4EF" } } + readonly property QtObject text: QtObject { + readonly property color enabled: "#FFFFFF" + readonly property color disabled: "#8F8F8F" + } } readonly property QtObject simplifiedSwitch: QtObject { readonly property QtObject background: QtObject { - readonly property color disabled: "#616161" + readonly property color disabled: "#2B2B2B" readonly property color off: "#616161" readonly property color hover: "#616161" readonly property color pressed: "#616161" diff --git a/interface/resources/qml/hifi/simplifiedUI/simplifiedControls/Slider.qml b/interface/resources/qml/hifi/simplifiedUI/simplifiedControls/Slider.qml index 38b114e9d2..9397963fbf 100644 --- a/interface/resources/qml/hifi/simplifiedUI/simplifiedControls/Slider.qml +++ b/interface/resources/qml/hifi/simplifiedUI/simplifiedControls/Slider.qml @@ -44,7 +44,7 @@ Item { anchors.bottom: parent.bottom horizontalAlignment: Text.AlignRight visible: sliderText.text != "" - color: simplifiedUI.colors.text.white + color: root.enabled ? simplifiedUI.colors.controls.slider.text.enabled : simplifiedUI.colors.controls.slider.text.disabled size: simplifiedUI.sizes.controls.slider.labelTextSize } diff --git a/interface/resources/qml/hifi/simplifiedUI/simplifiedControls/Switch.qml b/interface/resources/qml/hifi/simplifiedUI/simplifiedControls/Switch.qml index 9377dba9e1..bbfaa1ef1a 100644 --- a/interface/resources/qml/hifi/simplifiedUI/simplifiedControls/Switch.qml +++ b/interface/resources/qml/hifi/simplifiedUI/simplifiedControls/Switch.qml @@ -54,6 +54,7 @@ Item { innerSwitchHandle.color = simplifiedUI.colors.controls.simplifiedSwitch.handle.disabled; return; } + if (originalSwitch.checked) { if (originalSwitch.hovered) { innerSwitchHandle.color = simplifiedUI.colors.controls.simplifiedSwitch.handle.hover; @@ -69,6 +70,10 @@ Item { } } + onEnabledChanged: { + originalSwitch.changeColor(); + } + onCheckedChanged: { originalSwitch.changeColor(); } @@ -88,7 +93,8 @@ Item { background: Rectangle { id: switchBackground anchors.verticalCenter: parent.verticalCenter - color: originalSwitch.checked ? simplifiedUI.colors.controls.simplifiedSwitch.background.on : simplifiedUI.colors.controls.simplifiedSwitch.background.off + color: originalSwitch.enabled ? (originalSwitch.checked ? simplifiedUI.colors.controls.simplifiedSwitch.background.on : + simplifiedUI.colors.controls.simplifiedSwitch.background.off) : simplifiedUI.colors.controls.simplifiedSwitch.background.disabled width: originalSwitch.width height: simplifiedUI.sizes.controls.simplifiedSwitch.switchBackgroundHeight radius: height/2 @@ -113,7 +119,7 @@ Item { height: width radius: width/2 color: "transparent" - border.width: simplifiedUI.sizes.controls.simplifiedSwitch.switchHandleBorderSize + border.width: originalSwitch.enabled ? simplifiedUI.sizes.controls.simplifiedSwitch.switchHandleBorderSize : 0 border.color: simplifiedUI.colors.controls.simplifiedSwitch.handle.activeBorder } @@ -124,7 +130,7 @@ Item { height: width radius: width/2 color: simplifiedUI.colors.controls.simplifiedSwitch.handle.off - border.width: originalSwitch.pressed || originalSwitch.checked ? simplifiedUI.sizes.controls.simplifiedSwitch.switchHandleBorderSize : 0 + border.width: (originalSwitch.pressed || originalSwitch.checked) && originalSwitch.enabled ? simplifiedUI.sizes.controls.simplifiedSwitch.switchHandleBorderSize : 0 border.color: originalSwitch.pressed ? simplifiedUI.colors.controls.simplifiedSwitch.handle.activeBorder : simplifiedUI.colors.controls.simplifiedSwitch.handle.checkedBorder Component.onCompleted: { @@ -145,7 +151,7 @@ Item { id: labelOff text: "" size: simplifiedUI.sizes.controls.simplifiedSwitch.labelTextSize - color: originalSwitch.checked ? simplifiedUI.colors.controls.simplifiedSwitch.text.off : simplifiedUI.colors.controls.simplifiedSwitch.text.on + color: originalSwitch.checked && !originalSwitch.enabled ? simplifiedUI.colors.controls.simplifiedSwitch.text.off : simplifiedUI.colors.controls.simplifiedSwitch.text.on anchors.top: parent.top anchors.topMargin: -2 // Necessary for text alignment anchors.bottom: parent.bottom @@ -193,7 +199,7 @@ Item { id: labelOn text: "" size: simplifiedUI.sizes.controls.simplifiedSwitch.labelTextSize - color: originalSwitch.checked ? simplifiedUI.colors.controls.simplifiedSwitch.text.on : simplifiedUI.colors.controls.simplifiedSwitch.text.off + color: originalSwitch.checked && originalSwitch.enabled ? simplifiedUI.colors.controls.simplifiedSwitch.text.on : simplifiedUI.colors.controls.simplifiedSwitch.text.off anchors.top: parent.top anchors.topMargin: -2 // Necessary for text alignment anchors.left: parent.left diff --git a/interface/src/scripting/Audio.cpp b/interface/src/scripting/Audio.cpp index 6df4729ee0..ddf9ccca10 100644 --- a/interface/src/scripting/Audio.cpp +++ b/interface/src/scripting/Audio.cpp @@ -366,7 +366,14 @@ void Audio::onContextChanged() { void Audio::handlePushedToTalk(bool enabled) { if (getPTT()) { if (enabled) { - DependencyManager::get()->setOutputGain(0.1f); // duck the output by 20dB + if (!qApp->isHMDMode()) { + float gain = resultWithReadLock([&] { return _pttOutputGainDesktop; }); + // convert dB to amplitude + gain = fastExp2f(gain / 6.02059991f); + // quantize and limit to match NodeList::setInjectorGain() + gain = unpackFloatGainFromByte(packFloatGainToByte(gain)); + DependencyManager::get()->setOutputGain(gain); // duck the output by N dB + } setMuted(false); } else { DependencyManager::get()->setOutputGain(1.0f); @@ -499,3 +506,29 @@ float Audio::getSystemInjectorGain() { return _systemInjectorGain; }); } + +void Audio::setPushingToTalkOutputGainDesktop(float gain) { + if (gain > 0.0f) { + qDebug() << "Denying attempt to set Pushing to Talk Output Gain above 0dB. Attempted value:" << gain; + return; + } + + bool changed = false; + if (getPushingToTalkOutputGainDesktop() != gain) { + changed = true; + } + + withWriteLock([&] { + if (_pttOutputGainDesktop != gain) { + _pttOutputGainDesktop = gain; + } + }); + + if (changed) { + emit pushingToTalkOutputGainDesktopChanged(gain); + } +} + +float Audio::getPushingToTalkOutputGainDesktop() { + return resultWithReadLock([&] { return _pttOutputGainDesktop; }); +} diff --git a/interface/src/scripting/Audio.h b/interface/src/scripting/Audio.h index c7ac98402c..0954d5f062 100644 --- a/interface/src/scripting/Audio.h +++ b/interface/src/scripting/Audio.h @@ -94,6 +94,8 @@ class Audio : public AudioScriptingInterface, protected ReadWriteLockable { Q_PROPERTY(bool pushToTalkDesktop READ getPTTDesktop WRITE setPTTDesktop NOTIFY pushToTalkDesktopChanged) Q_PROPERTY(bool pushToTalkHMD READ getPTTHMD WRITE setPTTHMD NOTIFY pushToTalkHMDChanged) Q_PROPERTY(bool pushingToTalk READ getPushingToTalk WRITE setPushingToTalk NOTIFY pushingToTalkChanged) + Q_PROPERTY(float pushingToTalkOutputGainDesktop READ getPushingToTalkOutputGainDesktop + WRITE setPushingToTalkOutputGainDesktop NOTIFY pushingToTalkOutputGainDesktopChanged) Q_PROPERTY(float avatarGain READ getAvatarGain WRITE setAvatarGain NOTIFY avatarGainChanged) Q_PROPERTY(float localInjectorGain READ getLocalInjectorGain WRITE setLocalInjectorGain NOTIFY localInjectorGainChanged) Q_PROPERTY(float serverInjectorGain READ getInjectorGain WRITE setInjectorGain NOTIFY serverInjectorGainChanged) @@ -290,6 +292,22 @@ public: */ Q_INVOKABLE bool getRecording(); + /**jsdoc + * Sets the output volume gain that will be used when the user is holding the Push to Talk key. + * Should be negative. + * @function Audio.setPushingToTalkOutputGainDesktop + * @param {number} gain - Output volume gain (dB) while using PTT. + */ + Q_INVOKABLE void setPushingToTalkOutputGainDesktop(float gain); + + /**jsdoc + * Gets the output volume gain that is used when the user is holding the Push to Talk key. + * Should be negative. + * @function Audio.getPushingToTalkOutputGainDesktop + * @returns {number} gain - Output volume gain (dB) while using PTT. + */ + Q_INVOKABLE float getPushingToTalkOutputGainDesktop(); + signals: /**jsdoc @@ -452,6 +470,14 @@ signals: */ void systemInjectorGainChanged(float gain); + /**jsdoc + * Triggered when the push to talk gain changes. + * @function Audio.pushingToTalkOutputGainDesktopChanged + * @param {float} gain - The new output gain value. + * @returns {Signal} + */ + void pushingToTalkOutputGainDesktopChanged(float gain); + public slots: /**jsdoc @@ -478,8 +504,9 @@ private: bool _settingsLoaded { false }; float _inputVolume { 1.0f }; float _inputLevel { 0.0f }; - float _localInjectorGain { 0.0f }; // in dB - float _systemInjectorGain { 0.0f }; // in dB + float _localInjectorGain { 0.0f }; // in dB + float _systemInjectorGain { 0.0f }; // in dB + float _pttOutputGainDesktop { -20.0f }; // in dB bool _isClipping { false }; bool _enableNoiseReduction { true }; // Match default value of AudioClient::_isNoiseGateEnabled. bool _enableWarnWhenMuted { true }; From 8bcde84d892399ceeff0b818baa8d24c28b125af Mon Sep 17 00:00:00 2001 From: Brad Davis Date: Thu, 27 Jun 2019 16:37:56 -0700 Subject: [PATCH 12/26] Disable remote QML unless whitelisted --- interface/src/Application.cpp | 15 +++++++++++++++ libraries/qml/src/qml/OffscreenSurface.cpp | 22 ++++++++++++++++++++++ libraries/qml/src/qml/OffscreenSurface.h | 6 +++++- 3 files changed, 42 insertions(+), 1 deletion(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 1a0030bc12..632a8c78ae 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -3081,7 +3081,22 @@ void Application::showLoginScreen() { #endif } +static const QUrl AUTHORIZED_EXTERNAL_QML_SOURCE { "https://content.highfidelity.com/Experiences/Releases" }; + void Application::initializeUi() { + + // Allow remote QML content from trusted sources ONLY + { + auto defaultUrlValidator = OffscreenQmlSurface::getUrlValidator(); + auto newValidator = [=](const QUrl& url)->bool { + if (AUTHORIZED_EXTERNAL_QML_SOURCE.isParentOf(url)) { + return true; + } + return defaultUrlValidator(url); + }; + OffscreenQmlSurface::setUrlValidator(newValidator); + } + AddressBarDialog::registerType(); ErrorDialog::registerType(); LoginDialog::registerType(); diff --git a/libraries/qml/src/qml/OffscreenSurface.cpp b/libraries/qml/src/qml/OffscreenSurface.cpp index 69e6c833ee..117ff61c6e 100644 --- a/libraries/qml/src/qml/OffscreenSurface.cpp +++ b/libraries/qml/src/qml/OffscreenSurface.cpp @@ -23,6 +23,7 @@ #include #include +#include #include "Logging.h" #include "impl/SharedObject.h" @@ -33,6 +34,23 @@ using namespace hifi::qml; using namespace hifi::qml::impl; +QmlUrlValidator OffscreenSurface::validator = [](const QUrl& url) -> bool { + if (url.isRelative()) { + return true; + } + + if (url.isLocalFile()) { + return true; + } + + if (url.scheme() == URL_SCHEME_QRC) { + return true; + } + + // By default, only allow local QML, either from the local filesystem or baked into the QRC + return false; +}; + static uvec2 clampSize(const uvec2& size, uint32_t maxDimension) { return glm::clamp(size, glm::uvec2(1), glm::uvec2(maxDimension)); } @@ -307,6 +325,10 @@ void OffscreenSurface::loadInternal(const QUrl& qmlSource, // For desktop toolbar mode window: stop script when window is closed. if (qmlSource.isEmpty()) { getSurfaceContext()->engine()->quit(); + } + + if (!validator(qmlSource)) { + qCWarning(qmlLogging) << "Unauthorized QML URL found" << qmlSource; return; } diff --git a/libraries/qml/src/qml/OffscreenSurface.h b/libraries/qml/src/qml/OffscreenSurface.h index 18d24c93f7..528baf76be 100644 --- a/libraries/qml/src/qml/OffscreenSurface.h +++ b/libraries/qml/src/qml/OffscreenSurface.h @@ -40,6 +40,7 @@ class SharedObject; using QmlContextCallback = ::std::function; using QmlContextObjectCallback = ::std::function; +using QmlUrlValidator = std::function; class OffscreenSurface : public QObject { Q_OBJECT @@ -47,10 +48,13 @@ class OffscreenSurface : public QObject { public: static const QmlContextObjectCallback DEFAULT_CONTEXT_OBJECT_CALLBACK; static const QmlContextCallback DEFAULT_CONTEXT_CALLBACK; - + static QmlUrlValidator validator; using TextureAndFence = std::pair; using MouseTranslator = std::function; + + static const QmlUrlValidator& getUrlValidator() { return validator; } + static void setUrlValidator(const QmlUrlValidator& newValidator) { validator = newValidator; } static void setSharedContext(QOpenGLContext* context); OffscreenSurface(); From 9b894456e9a6bdd76c7f6866eb16b791417747ad Mon Sep 17 00:00:00 2001 From: Simon Walton Date: Thu, 27 Jun 2019 17:29:17 -0700 Subject: [PATCH 13/26] Change address for sequence-number hash also --- libraries/networking/src/udt/Socket.cpp | 30 ++++++++++++++++++------- 1 file changed, 22 insertions(+), 8 deletions(-) diff --git a/libraries/networking/src/udt/Socket.cpp b/libraries/networking/src/udt/Socket.cpp index 94628aa852..e8fe3741aa 100644 --- a/libraries/networking/src/udt/Socket.cpp +++ b/libraries/networking/src/udt/Socket.cpp @@ -539,15 +539,29 @@ void Socket::handleStateChanged(QAbstractSocket::SocketState socketState) { } void Socket::handleRemoteAddressChange(HifiSockAddr previousAddress, HifiSockAddr currentAddress) { - Lock connectionsLock(_connectionsHashMutex); - _connectionsHash.erase(currentAddress); + { + Lock connectionsLock(_connectionsHashMutex); + _connectionsHash.erase(currentAddress); - const auto connectionIter = _connectionsHash.find(currentAddress); - if (connectionIter != _connectionsHash.end()) { - auto connection = std::move(connectionIter->second); - _connectionsHash.erase(connectionIter); - connection->setDestinationAddress(currentAddress); - _connectionsHash[currentAddress] = std::move(connection); + const auto connectionIter = _connectionsHash.find(previousAddress); + if (connectionIter != _connectionsHash.end()) { + auto connection = std::move(connectionIter->second); + _connectionsHash.erase(connectionIter); + connection->setDestinationAddress(currentAddress); + _connectionsHash[currentAddress] = std::move(connection); + } + } + + { + Lock sequenceNumbersLock(_unreliableSequenceNumbersMutex); + _unreliableSequenceNumbers.erase(currentAddress); + + const auto sequenceNumbersIter = _unreliableSequenceNumbers.find(previousAddress); + if (sequenceNumbersIter != _unreliableSequenceNumbers.end()) { + auto sequenceNumbers = sequenceNumbersIter->second; + _unreliableSequenceNumbers.erase(sequenceNumbersIter); + _unreliableSequenceNumbers[currentAddress] = sequenceNumbers; + } } } From 2d6d3eb4fef499d3182aa07176100fab27b4a97e Mon Sep 17 00:00:00 2001 From: David Rowe Date: Fri, 28 Jun 2019 17:05:36 +1200 Subject: [PATCH 14/26] Doc review --- interface/src/avatar/AvatarActionHold.cpp | 14 +- interface/src/ui/overlays/Overlays.h | 2 +- .../entities/src/AnimationPropertyGroup.cpp | 9 +- .../entities/src/EntityDynamicInterface.cpp | 2 +- .../entities/src/EntityItemProperties.cpp | 159 +++++++++--------- .../entities/src/EntityScriptingInterface.h | 58 ++++--- libraries/entities/src/GrabPropertyGroup.h | 25 +-- libraries/entities/src/HazePropertyGroup.h | 14 +- .../entities/src/KeyLightPropertyGroup.h | 5 +- .../src/material-networking/MaterialCache.cpp | 12 +- libraries/physics/src/ObjectActionOffset.cpp | 4 +- libraries/physics/src/ObjectDynamic.cpp | 19 ++- .../src/AudioScriptingInterface.h | 4 +- 13 files changed, 171 insertions(+), 156 deletions(-) diff --git a/interface/src/avatar/AvatarActionHold.cpp b/interface/src/avatar/AvatarActionHold.cpp index 3ac9f63649..b7019bd6f0 100644 --- a/interface/src/avatar/AvatarActionHold.cpp +++ b/interface/src/avatar/AvatarActionHold.cpp @@ -457,12 +457,14 @@ bool AvatarActionHold::updateArguments(QVariantMap arguments) { * @property {number} timeScale=3.4e+38 - Controls how long it takes for the entity's position and rotation to catch up with * the target. The value is the time for the action to catch up to 1/e = 0.368 of the target value, where the action is * applied using an exponential decay. - * @property {boolean} kinematic=false - If true, the entity is made kinematic during the action; the entity won't - * lag behind the hand but constraint actions such as "hinge" won't act properly. - * @property {boolean} kinematicSetVelocity=false - If true and kinematic is true, the - * entity's velocity property will be set during the action, e.g., so that other scripts may use the value. - * @property {boolean} ignoreIK=false - If true, the entity follows the HMD controller rather than the avatar's - * hand. + * @property {boolean} kinematic=false - true if the entity is made kinematic during the action; the entity won't + * lag behind the hand but constraint actions such as "hinge" won't act properly. false if the + * entity is not made kinematic during the action + * @property {boolean} kinematicSetVelocity=false - true if, when kinematic is true, the + * entity's velocity will be set during the action, e.g., so that other scripts may use the value. false if + * the entity's velocity will not be set during the action. + * @property {boolean} ignoreIK=false - true if the entity follows the HMD controller, false if it + * follows the avatar's hand. */ QVariantMap AvatarActionHold::getArguments() { QVariantMap arguments = ObjectDynamic::getArguments(); diff --git a/interface/src/ui/overlays/Overlays.h b/interface/src/ui/overlays/Overlays.h index 6eaf481efe..1a2382769c 100644 --- a/interface/src/ui/overlays/Overlays.h +++ b/interface/src/ui/overlays/Overlays.h @@ -77,7 +77,7 @@ public: * @hifi-avatar * * @property {Uuid} keyboardFocusOverlay - Get or set the {@link Entities.EntityTypes|Web} entity that has keyboard focus. - * If no entity has keyboard focus, get returns null; set to null or {@link Uuid(0)|Uuid.NULL} to + * If no entity has keyboard focus, returns null; set to null or {@link Uuid(0)|Uuid.NULL} to * clear keyboard focus. */ diff --git a/libraries/entities/src/AnimationPropertyGroup.cpp b/libraries/entities/src/AnimationPropertyGroup.cpp index 03cd3a0742..7f9225bd6c 100644 --- a/libraries/entities/src/AnimationPropertyGroup.cpp +++ b/libraries/entities/src/AnimationPropertyGroup.cpp @@ -57,10 +57,11 @@ bool operator!=(const AnimationPropertyGroup& a, const AnimationPropertyGroup& b * @property {number} firstFrame=0 - The first frame to play in the animation. * @property {number} lastFrame=100000 - The last frame to play in the animation. * @property {number} currentFrame=0 - The current frame being played in the animation. - * @property {boolean} running=false - If true then the animation should play. - * @property {boolean} loop=true - If true then the animation is continuously repeated in a loop. - * @property {boolean} hold=false - If true then the rotations and translations of the last frame played are - * maintained when the animation stops playing. + * @property {boolean} running=false - true if the animation should play, false if it shouldn't. + * @property {boolean} loop=true - true if the animation is continuously repeated in a loop, false if + * it isn't. + * @property {boolean} hold=false - true if the rotations and translations of the last frame played are + * maintained when the animation stops playing, false if they aren't. */ void AnimationPropertyGroup::copyToScriptValue(const EntityPropertyFlags& desiredProperties, QScriptValue& properties, QScriptEngine* engine, bool skipDefaults, EntityItemProperties& defaultEntityProperties) const { COPY_GROUP_PROPERTY_TO_QSCRIPTVALUE(PROP_ANIMATION_URL, Animation, animation, URL, url); diff --git a/libraries/entities/src/EntityDynamicInterface.cpp b/libraries/entities/src/EntityDynamicInterface.cpp index 4586b665ee..69d771db22 100644 --- a/libraries/entities/src/EntityDynamicInterface.cpp +++ b/libraries/entities/src/EntityDynamicInterface.cpp @@ -109,7 +109,7 @@ variables. These argument variables are used by the code which is run when bull * are disabled during the hold. * {@link Entities.ActionArguments-Hold} * "offset"Object action - * Moves an entity so that it is a set distance away from a target point. + * Moves an entity so that it is a defined distance away from a target point. * {@link Entities.ActionArguments-Offset} * "tractor"Object action * Moves and rotates an entity to a target position and orientation, optionally relative to another entity. diff --git a/libraries/entities/src/EntityItemProperties.cpp b/libraries/entities/src/EntityItemProperties.cpp index 5b3bbb88ee..064fe2e3b1 100644 --- a/libraries/entities/src/EntityItemProperties.cpp +++ b/libraries/entities/src/EntityItemProperties.cpp @@ -609,8 +609,7 @@ EntityPropertyFlags EntityItemProperties::getChangedProperties() const { /**jsdoc * Different entity types have different properties: some common to all entities (listed in the table) and some specific to - * each {@link Entities.EntityType|EntityType} (linked to below). The properties are accessed as an object of property names - * and values. + * each {@link Entities.EntityType|EntityType} (linked to below). * * @typedef {object} Entities.EntityProperties * @property {Uuid} id - The ID of the entity. Read-only. @@ -644,16 +643,17 @@ EntityPropertyFlags EntityItemProperties::getChangedProperties() const { * @property {Uuid} lastEditedBy - The session ID of the avatar or agent that most recently created or edited the entity. * Read-only. * - * @property {boolean} locked=false - Whether or not the entity can be edited or deleted. If true then the - * entity's properties other than locked cannot be changed, and the entity cannot be deleted. - * @property {boolean} visible=true - Whether or not the entity is rendered. If true then the entity is rendered. - * @property {boolean} canCastShadow=true - Whether or not the entity can cast a shadow. Currently applicable only to - * {@link Entities.EntityProperties-Model|Model} and {@link Entities.EntityProperties-Shape|Shape} entities. Shadows are - * cast if inside a {@link Entities.EntityProperties-Zone|Zone} entity with castShadows enabled in its - * keyLight property. + * @property {boolean} locked=false - true if properties other than locked cannot be changed and the + * entity cannot be deleted, false if all properties can be changed and the entity can be deleted. + * @property {boolean} visible=true - true if the entity is rendered, false if it isn't. + * @property {boolean} canCastShadow=true - true if the entity can cast a shadow, false if it can't. + * Currently applicable only to {@link Entities.EntityProperties-Model|Model} and + * {@link Entities.EntityProperties-Shape|Shape} entities. Shadows are cast if inside a + * {@link Entities.EntityProperties-Zone|Zone} entity with castShadows enabled in its keyLight + * property. * @property {boolean} isVisibleInSecondaryCamera=true - true if the entity is rendered in the secondary camera, * false if it isn't. - * @property {Entities.RenderLayer} renderLayer="world" - Which layer the entity renders in. + * @property {Entities.RenderLayer} renderLayer="world" - The layer that the entity renders in. * @property {Entities.PrimitiveMode} primitiveMode="solid" - How the entity's geometry is rendered. * @property {boolean} ignorePickIntersection=false - true if {@link Picks} and {@link RayPick} ignore the entity, * false if they don't. @@ -697,20 +697,20 @@ EntityPropertyFlags EntityItemProperties::getChangedProperties() const { * @property {number} friction=0.5 - How much an entity slows down when it's moving against another, range 0.0 * – 10.0. The higher the value, the more quickly it slows down. Examples: 0.1 for ice, * 0.9 for sandpaper. - * @property {number} density=1000 - The density of the entity in kg/m3, range 100 for balsa wood - * – 10000 for silver. The density is used in conjunction with the entity's bounding box volume to work - * out its mass in the application of physics. + * @property {number} density=1000 - The density of the entity in kg/m3, range 100 – + * 10000. Examples: 100 for balsa wood, 10000 for silver. The density is used in + * conjunction with the entity's bounding box volume to work out its mass in the application of physics. * - * @property {boolean} collisionless=false - Whether or not the entity should collide with items per its - * collisionMask property. If true then the entity does not collide. + * @property {boolean} collisionless=false - true if the entity shouldn't collide, false if it + * collides with items per its collisionMask property. * @property {boolean} ignoreForCollisions - Synonym for collisionless. * @property {CollisionMask} collisionMask=31 - What types of items the entity should collide with. * @property {string} collidesWith="static,dynamic,kinematic,myAvatar,otherAvatar," - Synonym for collisionMask, * in text format. * @property {string} collisionSoundURL="" - The sound that's played when the entity experiences a collision. Valid file * formats are per {@link SoundObject}. - * @property {boolean} dynamic=false - Whether or not the entity should be affected by collisions. If true then - * the entity's movement is affected by collisions. + * @property {boolean} dynamic=false - true if the entity's movement is affected by collisions, false + * if it isn't. * @property {boolean} collisionsWillMove - A synonym for dynamic. * * @property {string} href="" - A "hifi://" metaverse address that a user is teleported to when they click on the entity. @@ -732,8 +732,8 @@ EntityPropertyFlags EntityItemProperties::getChangedProperties() const { * button beside the "script URL" field in properties tab of the Create app works. * @property {string} serverScripts="" - The URL of the server entity script, if any, that is attached to the entity. * - * @property {Uuid} parentID=Uuid.NULL - The ID of the entity or avatar that the entity is parented to. - * {@link Uuid(0)|Uuid.NULL} if the entity is not parented. + * @property {Uuid} parentID=Uuid.NULL - The ID of the entity or avatar that the entity is parented to. A value of + * {@link Uuid(0)|Uuid.NULL} is used if the entity is not parented. * @property {number} parentJointIndex=65535 - The joint of the entity or avatar that the entity is parented to. Use * 65535 or -1 to parent to the entity or avatar's position and orientation rather than a joint. * @property {Vec3} localPosition=0,0,0 - The position of the entity relative to its parent if the entity is parented, @@ -759,19 +759,19 @@ EntityPropertyFlags EntityItemProperties::getChangedProperties() const { * @property {string} actionData="" - Base-64 encoded compressed dump of the actions associated with the entity. This property * is typically not used in scripts directly; rather, functions that manipulate an entity's actions update it, e.g., * {@link Entities.addAction}. The size of this property increases with the number of actions. Because this property value - * has to fit within a High Fidelity datagram packet there is a limit to the number of actions that an entity can have, and + * has to fit within a High Fidelity datagram packet, there is a limit to the number of actions that an entity can have; * edits which would result in overflow are rejected. Read-only. * @property {Entities.RenderInfo} renderInfo - Information on the cost of rendering the entity. Currently information is only * provided for Model entities. Read-only. * - * @property {boolean} cloneable=false - If true then the domain or avatar entity can be cloned via - * {@link Entities.cloneEntity}. + * @property {boolean} cloneable=false - true if the domain or avatar entity can be cloned via + * {@link Entities.cloneEntity}, false if it can't be. * @property {number} cloneLifetime=300 - The entity lifetime for clones created from this entity. * @property {number} cloneLimit=0 - The total number of clones of this entity that can exist in the domain at any given time. - * @property {boolean} cloneDynamic=false - If true then clones created from this entity will have their - * dynamic property set to true. - * @property {boolean} cloneAvatarEntity=false - If true then clones created from this entity will be created as - * avatar entities. + * @property {boolean} cloneDynamic=false - true if clones created from this entity will have their + * dynamic property set to true, false if they won't. + * @property {boolean} cloneAvatarEntity=false - true if clones created from this entity will be created as + * avatar entities, false if they won't be. * @property {Uuid} cloneOriginID - The ID of the entity that this entity was cloned from. * * @property {Entities.Grab} grab - The entity's grab-related properties. @@ -833,8 +833,8 @@ EntityPropertyFlags EntityItemProperties::getChangedProperties() const { * @property {Color} color=255,255,255 - The color of the light emitted. * @property {number} intensity=1 - The brightness of the light. * @property {number} falloffRadius=0.1 - The distance from the light's center at which intensity is reduced by 25%. - * @property {boolean} isSpotlight=false - If true then the light is directional, emitting along the entity's - * local negative z-axis; otherwise, the light is a point light which emanates in all directions. + * @property {boolean} isSpotlight=false - true if the light is directional, emitting along the entity's + * local negative z-axis; false if the light is a point light which emanates in all directions. * @property {number} exponent=0 - Affects the softness of the spotlight beam: the higher the value the softer the beam. * @property {number} cutoff=1.57 - Affects the size of the spotlight beam: the higher the value the larger the beam. * @example Create a spotlight pointing at the ground. @@ -855,7 +855,7 @@ EntityPropertyFlags EntityItemProperties::getChangedProperties() const { /**jsdoc * The "Line" {@link Entities.EntityType|EntityType} draws thin, straight lines between a sequence of two or more * points. It has properties in addition to the common {@link Entities.EntityProperties|EntityProperties}. - *

Deprecated: Use PolyLines instead.

+ *

Deprecated: Use {@link Entities.EntityProperties-PolyLine|PolyLine} entities instead.

* * @typedef {object} Entities.EntityProperties-Line * @property {Vec3} dimensions=0.1,0.1,0.1 - The dimensions of the entity. Must be sufficient to contain all the @@ -904,7 +904,7 @@ EntityPropertyFlags EntityItemProperties::getChangedProperties() const { * 0. * @property {string} parentMaterialName="0" - Selects the mesh part or parts within the parent to which to apply the material. * If in the format "mat::string", all mesh parts with material name "string" are replaced. - * If "all" then all mesh parts are replaced. + * If "all", then all mesh parts are replaced. * Otherwise the property value is parsed as an unsigned integer, specifying the mesh part index to modify. *

If the string represents an array (starts with "[" and ends with "]"), the string is split * at each "," and each element parsed as either a number or a string if it starts with "mat::". @@ -919,8 +919,9 @@ EntityPropertyFlags EntityItemProperties::getChangedProperties() const { * { x: 0, y: 0 }{ x: 1, y: 1 }. * @property {Vec2} materialMappingScale=1,1 - How much to scale the material within the parent's UV-space. * @property {number} materialMappingRot=0 - How much to rotate the material within the parent's UV-space, in degrees. - * @property {boolean} materialRepeat=true - If true, the material repeats. If false, fragments - * outside of texCoord 0 – 1 will be discarded. Works in both "uv" and "projected" modes. + * @property {boolean} materialRepeat=true - true if the material repeats, false if it doesn't. If + * false, fragments outside of texCoord 0 – 1 will be discarded. Works in both "uv" and + * "projected" modes. * @example Color a sphere using a Material entity. * var entityID = Entities.addEntity({ * type: "Sphere", @@ -980,7 +981,7 @@ EntityPropertyFlags EntityItemProperties::getChangedProperties() const { * model hasn't loaded. The array indexes are per {@link Entities.getJointIndex|getJointIndex}. Rotations are relative to * each joint's parent. *

Joint rotations can be set by {@link Entities.setLocalJointRotation|setLocalJointRotation} and similar functions, or - * by setting the value of this property. If you set a joint rotation using this property you also need to set the + * by setting the value of this property. If you set a joint rotation using this property, you also need to set the * corresponding jointRotationsSet value to true.

* @property {boolean[]} jointRotationsSet=[]] - true values for joints that have had rotations applied, * false otherwise; [] if none are applied or the model hasn't loaded. The array indexes are per @@ -994,10 +995,11 @@ EntityPropertyFlags EntityItemProperties::getChangedProperties() const { * @property {boolean[]} jointTranslationsSet=[]] - true values for joints that have had translations applied, * false otherwise; [] if none are applied or the model hasn't loaded. The array indexes are per * {@link Entities.getJointIndex|getJointIndex}. - * @property {boolean} relayParentJoints=false - If true and the entity is parented to an avatar, then the - * avatar's joint rotations are applied to the entity's joints. - * @property {boolean} groupCulled=false - If true, the mesh parts of the model are LOD culled as a group. - * If false, separate mesh parts will be LOD culled individually. + * @property {boolean} relayParentJoints=false - true if when the entity is parented to an avatar, the avatar's + * joint rotations are applied to the entity's joints; false if a parent avatar's joint rotations are not + * applied to the entity's joints. + * @property {boolean} groupCulled=false - true if the mesh parts of the model are LOD culled as a group, + * false if separate mesh parts are LOD culled individually. * * @example Rez a Vive tracker puck. * var entity = Entities.addEntity({ @@ -1033,8 +1035,8 @@ EntityPropertyFlags EntityItemProperties::getChangedProperties() const { * – {x: 0, y: -8.8, z: 0}. * @property {Vec3} dimensions - The dimensions of the particle effect, i.e., a bounding box containing all the particles * during their lifetimes, assuming that emitterShouldTrail == false. Read-only. - * @property {boolean} emitterShouldTrail=false - If true then particles are "left behind" as the emitter moves, - * otherwise they stay within the entity's dimensions. + * @property {boolean} emitterShouldTrail=false - true if particles are "left behind" as the emitter moves, + * false if they stay within the entity's dimensions. * * @property {Quat} emitOrientation=-0.707,0,0,0.707 - The orientation of particle emission relative to the entity's axes. By * default, particles emit along the entity's local z-axis, and azimuthStart and azimuthFinish @@ -1105,8 +1107,8 @@ EntityPropertyFlags EntityItemProperties::getChangedProperties() const { * 2 * Math.PI radians. For example, if particleSpin == Math.PI and * spinSpread == Math.PI / 2, each particle will have a rotation in the range Math.PI / 2 – * 3 * Math.PI / 2. - * @property {boolean} rotateWithEntity=false - true to make the particles' rotations relative to the entity's - * instantaneous rotation, false to make them relative to world coordinates. If true with + * @property {boolean} rotateWithEntity=false - true if the particles' rotations are relative to the entity's + * instantaneous rotation, false if they're relative to world coordinates. If true with * particleSpin == 0, the particles keep oriented per the entity's orientation. * * @example Create a ball of green smoke. @@ -1141,17 +1143,19 @@ EntityPropertyFlags EntityItemProperties::getChangedProperties() const { * @property {number[]} strokeWidths=[]] - The widths, in m, of the line at the linePoints. Must be specified in * order for the entity to render. * @property {Vec3[]} strokeColors=[]] - The base colors of each point, with values in the range 0.0,0.0,0.0 - * — 1.0,1.0,1.0. These colors are multiplied with the color of the texture. If there are more line + * – 1.0,1.0,1.0. These colors are multiplied with the color of the texture. If there are more line * points than stroke colors, the color property value is used for the remaining points. - *

Warning: The ordinate values are in the range 0.01.0.

+ *

Warning: The ordinate values are in the range 0.01.0.

* @property {Color} color=255,255,255 - Used as the color for each point if strokeColors doesn't have a value for * the point. * @property {string} textures="" - The URL of a JPG or PNG texture to use for the lines. If you want transparency, use PNG * format. - * @property {boolean} isUVModeStretch=true - If true, the texture is stretched to fill the whole line, otherwise - * the texture repeats along the line. - * @property {boolean} glow=false - If true, the opacity of the strokes drops off away from the line center. - * @property {boolean} faceCamera=false - If true, each line segment rotates to face the camera. + * @property {boolean} isUVModeStretch=true - true if the texture is stretched to fill the whole line, + * false if the texture repeats along the line. + * @property {boolean} glow=false - true if the opacity of the strokes drops off away from the line center, + * false if it doesn't. + * @property {boolean} faceCamera=false - true if each line segment rotates to face the camera, false + * if they don't. * @example Draw a textured "V". * var entity = Entities.addEntity({ * type: "PolyLine", @@ -1192,9 +1196,8 @@ EntityPropertyFlags EntityItemProperties::getChangedProperties() const { * the PolyVox data. This property is typically not used in scripts directly; rather, functions that manipulate a PolyVox * entity update it.
* The size of this property increases with the size and complexity of the PolyVox entity, with the size depending on how - * the particular entity's voxels compress. Because this property value has to fit within a High Fidelity datagram packet - * there is a limit to the size and complexity of a PolyVox entity, and edits which would result in an overflow are - * rejected. + * the particular entity's voxels compress. Because this property value has to fit within a High Fidelity datagram packet, + * there is a limit to the size and complexity of a PolyVox entity; edits which would result in an overflow are rejected. * @property {Entities.PolyVoxSurfaceStyle} voxelSurfaceStyle=2 - The style of rendering the voxels' surface and how * neighboring PolyVox entities are joined. * @property {string} xTextureURL="" - The URL of the texture to map to surfaces perpendicular to the entity's local x-axis. @@ -1282,12 +1285,11 @@ EntityPropertyFlags EntityItemProperties::getChangedProperties() const { * @property {number} topMargin=0.0 - The top margin, in meters. * @property {number} bottomMargin=0.0 - The bottom margin, in meters. * @property {BillboardMode} billboardMode="none" - Whether the entity is billboarded to face the camera. - * @property {boolean} faceCamera - true if billboardMode is "yaw", otherwise - * false. Setting this property to false sets the billboardMode to - * "none". + * @property {boolean} faceCamera - true if billboardMode is "yaw", false + * if it isn't. Setting this property to false sets the billboardMode to "none". *

Deprecated: This property is deprecated and will be removed.

- * @property {boolean} isFacingAvatar - true if billboardMode is "full", otherwise - * false. Setting this property to false sets the billboardMode to + * @property {boolean} isFacingAvatar - true if billboardMode is "full", + * false if it isn't. Setting this property to false sets the billboardMode to * "none". *

Deprecated: This property is deprecated and will be removed.

* @example Create a text entity. @@ -1312,17 +1314,18 @@ EntityPropertyFlags EntityItemProperties::getChangedProperties() const { * @property {Vec3} dimensions=0.1,0.1,0.01 - The dimensions of the entity. * @property {string} sourceUrl="" - The URL of the web page to display. This value does not change as you or others navigate * on the Web entity. - * @property {Color} color=255,255,255 - The color of the web surface. + * @property {Color} color=255,255,255 - The color of the web surface. This color tints the web page displayed: the pixel + * colors on the web page are multiplied by the property color. For example, a value of + * { red: 255, green: 0, blue: 0 } lets only the red channel of pixels' colors through. * @property {number} alpha=1 - The opacity of the web surface. * @property {Entities.Pulse} pulse - Color and alpha pulse. *

Deprecated: This property is deprecated and will be removed.

* @property {BillboardMode} billboardMode="none" - Whether the entity is billboarded to face the camera. - * @property {boolean} faceCamera - true if billboardMode is "yaw", otherwise - * false. Setting this property to false sets the billboardMode to - * "none". + * @property {boolean} faceCamera - true if billboardMode is "yaw", false + * if it isn't. Setting this property to false sets the billboardMode to "none". *

Deprecated: This property is deprecated and will be removed.

- * @property {boolean} isFacingAvatar - true if billboardMode is "full", otherwise - * false. Setting this property to false sets the billboardMode to + * @property {boolean} isFacingAvatar - true if billboardMode is "full", + * false if it isn't. Setting this property to false sets the billboardMode to * "none". *

Deprecated: This property is deprecated and will be removed.

* @property {number} dpi=30 - The resolution to display the page at, in dots per inch. If you convert this to dots per meter @@ -1331,8 +1334,8 @@ EntityPropertyFlags EntityItemProperties::getChangedProperties() const { * @property {string} scriptURL="" - The URL of a JavaScript file to inject into the web page. * @property {number} maxFPS=10 - The maximum update rate for the web content, in frames/second. * @property {WebInputMode} inputMode="touch" - The user input mode to use. - * @property {boolean} showKeyboardFocusHighlight=true - true to highlight the entity when it has keyboard focus, - * false to not display the highlight. + * @property {boolean} showKeyboardFocusHighlight=true - true if the entity is highlighted when it has keyboard + * focus, false if it isn't. * @example Create a Web entity displaying at 1920 x 1080 resolution. * var METERS_TO_INCHES = 39.3701; * var entity = Entities.addEntity({ @@ -1380,12 +1383,12 @@ EntityPropertyFlags EntityItemProperties::getChangedProperties() const { * @property {Entities.ComponentMode} bloomMode="inherit" - Configures the bloom in the zone. * @property {Entities.Bloom} bloom - The bloom properties of the zone. * - * @property {boolean} flyingAllowed=true - If true then visitors can fly in the zone; otherwise, they cannot. - * Only works for domain entities. - * @property {boolean} ghostingAllowed=true - If true then visitors with avatar collisions turned off will not - * collide with content in the zone; otherwise, visitors will always collide with content in the zone. Only works for domain - * entities. - + * @property {boolean} flyingAllowed=true - true if visitors can fly in the zone; false if they + * cannot. Only works for domain entities. + * @property {boolean} ghostingAllowed=true - true if visitors with avatar collisions turned off will not + * collide with content in the zone; false if visitors will always collide with content in the zone. Only + * works for domain entities. + * * @property {string} filterURL="" - The URL of a JavaScript file that filters changes to properties of entities within the * zone. It is periodically executed for each entity in the zone. It can, for example, be used to not allow changes to * certain properties: @@ -1421,7 +1424,7 @@ EntityPropertyFlags EntityItemProperties::getChangedProperties() const { * @typedef {object} Entities.EntityProperties-Image * @property {Vec3} dimensions=0.1,0.1,0.01 - The dimensions of the entity. * @property {string} imageURL="" - The URL of the image to use. - * @property {boolean} emissive=false - true fi the the image should be emissive (unlit), false if it + * @property {boolean} emissive=false - true if the image should be emissive (unlit), false if it * shouldn't. * @property {boolean} keepAspectRatio=true - true if the image should maintain its aspect ratio, * false if it shouldn't. @@ -1432,12 +1435,11 @@ EntityPropertyFlags EntityItemProperties::getChangedProperties() const { * @property {Entities.Pulse} pulse - Color and alpha pulse. *

Deprecated: This property is deprecated and will be removed.

* @property {BillboardMode} billboardMode="none" - Whether the entity is billboarded to face the camera. - * @property {boolean} faceCamera - true if billboardMode is "yaw", otherwise - * false. Setting this property to false sets the billboardMode to - * "none". + * @property {boolean} faceCamera - true if billboardMode is "yaw", false + * if it isn't. Setting this property to false sets the billboardMode to "none". *

Deprecated: This property is deprecated and will be removed.

- * @property {boolean} isFacingAvatar - true if billboardMode is "full", otherwise - * false. Setting this property to false sets the billboardMode to + * @property {boolean} isFacingAvatar - true if billboardMode is "full", + * false if it isn't. Setting this property to false sets the billboardMode to * "none". *

Deprecated: This property is deprecated and will be removed.

* @example Create an image entity. @@ -1461,8 +1463,8 @@ EntityPropertyFlags EntityItemProperties::getChangedProperties() const { * @property {number} alpha=1 - The opacity of the grid. * @property {Entities.Pulse} pulse - Color and alpha pulse. *

Deprecated: This property is deprecated and will be removed.

- * @property {boolean} followCamera=true - If true, the grid is always visible even as the camera moves to another - * position. + * @property {boolean} followCamera=true - true if the grid is always visible even as the camera moves to another + * position, false if it doesn't follow the camrmea. * @property {number} majorGridEvery=5 - Integer number of minorGridEvery intervals at which to draw a thick grid * line. Minimum value = 1. * @property {number} minorGridEvery=1 - Real number of meters at which to draw thin grid lines. Minimum value = @@ -1895,7 +1897,8 @@ QScriptValue EntityItemProperties::copyToScriptValue(QScriptEngine* engine, bool * @property {number} verticesCount - The number of vertices in the entity. * @property {number} texturesCount - The number of textures in the entity. * @property {number} texturesSize - The total size of the textures in the entity, in bytes. - * @property {boolean} hasTransparent - Is true if any of the textures has transparency. + * @property {boolean} hasTransparent - true if any of the textures has transparency, false + * if none of them do. * @property {number} drawCalls - The number of draw calls required to render the entity. */ // currently only supported by models diff --git a/libraries/entities/src/EntityScriptingInterface.h b/libraries/entities/src/EntityScriptingInterface.h index 0666bb98df..ad2aaf2160 100644 --- a/libraries/entities/src/EntityScriptingInterface.h +++ b/libraries/entities/src/EntityScriptingInterface.h @@ -59,8 +59,8 @@ private: /**jsdoc * The result of a {@link Entities.findRayIntersection|findRayIntersection} search using a {@link PickRay}. * @typedef {object} Entities.RayToEntityIntersectionResult - * @property {boolean} intersects - true if the {@link PickRay} intersected an entity, otherwise - * false. + * @property {boolean} intersects - true if the {@link PickRay} intersected an entity, false if it + * didn't. * @property {boolean} accurate - Is always true. * @property {Uuid} entityID - The ID if the entity intersected, if any, otherwise null. * @property {number} distance - The distance from the {@link PickRay} origin to the intersection point. @@ -131,8 +131,8 @@ public: * leaveEntity{@link Entities.leaveEntity} * mouseDoublePressOnEntity{@link Entities.mouseDoublePressOnEntity} * mouseMoveOnEntity{@link Entities.mouseMoveOnEntity} - * mouseMoveEventDeprecated: This is a synonym for - * mouseMoveOnEntity. + * mouseMoveEventDeprecated: Use mouseMoveOnEntity + * instead. * mousePressOnEntity{@link Entities.mousePressOnEntity} * mouseReleaseOnEntity{@link Entities.mouseReleaseOnEntity} * @@ -148,8 +148,8 @@ public: * @hifi-assignment-client * * @property {Uuid} keyboardFocusEntity - The {@link Entities.EntityProperties-Web|Web} entity that has keyboard focus. If no - * Web entity has keyboard focus, get returns null; set to null or {@link Uuid(0)|Uuid.NULL} to - * clear keyboard focus. + * Web entity has keyboard focus, returns null; set to null or {@link Uuid(0)|Uuid.NULL} to clear + * keyboard focus. */ /// handles scripting of Entity commands from JS passed to assigned clients class EntityScriptingInterface : public OctreeScriptingInterface, public Dependency { @@ -191,8 +191,8 @@ public: * objects (e.g., the "keyLight" property), use the property and subproperty names in dot notation (e.g., * "keyLight.color"). * @returns {Entities.EntityProperties[]} The specified properties of each entity for each entity that can be found. If - * none of the entities can be found then an empty array. If no properties are specified, then all properties are - * returned. + * none of the entities can be found, then an empty array is returned. If no properties are specified, then all + * properties are returned. * @example Retrieve the names of the nearby entities * var SEARCH_RADIUS = 50; // meters * var entityIDs = Entities.findEntities(MyAvatar.position, SEARCH_RADIUS); @@ -353,9 +353,10 @@ public slots: bool collisionless, bool grabbable, const glm::vec3& position, const glm::vec3& gravity); /**jsdoc - * Creates a clone of an entity. The clone has a modified name property, other properties set per the original - * entity's clone-related {@link Entities.EntityProperties|properties} (e.g., cloneLifetime), and - * clone-related properties set to defaults. + * Creates a clone of an entity. The clone has the same properties as the original except that: it has a modified + * name property, clone-related properties are set per the original entity's clone-related + * {@link Entities.EntityProperties|properties} (e.g., cloneLifetime), and its clone-related properties are + * set to their defaults. *

Domain entities must have their cloneable property value be true in order to be cloned. A * domain entity can be cloned by a client that doesn't have rez permissions in the domain.

*

Avatar entities must have their cloneable and cloneAvatarEntity property values be @@ -507,7 +508,7 @@ public slots: Q_INVOKABLE QObject* getEntityObject(const QUuid& id); /**jsdoc - * Checks whether an entities's assets have been loaded. For example, for an Model entity the result indicates + * Checks whether an entity's assets have been loaded. For example, for an Model entity the result indicates * whether its textures have been loaded. * @function Entities.isLoaded * @param {Uuid} id - The ID of the entity to check. @@ -747,7 +748,8 @@ public slots: * @param {string} entityName - The name of the entity to search for. * @param {Vec3} center - The point about which to search. * @param {number} radius - The radius within which to search. - * @param {boolean} [caseSensitive=false] - If true then the search is case-sensitive. + * @param {boolean} [caseSensitive=false] - true if the search is case-sensitive, false if it is + * case-insensitive. * @returns {Uuid[]} An array of entity IDs that have the specified name and intersect the search sphere. The array is * empty if no entities could be found. * @example Report the number of entities with the name, "Light-Target". @@ -767,12 +769,14 @@ public slots: * @param {boolean} [precisionPicking=false] - true to pick against precise meshes, false to pick * against coarse meshes. If true and the intersected entity is a Model entity, the result's * extraInfo property includes more information than it otherwise would. - * @param {Uuid[]} [entitiesToInclude=[]] - If not empty then the search is restricted to these entities. + * @param {Uuid[]} [entitiesToInclude=[]] - If not empty, then the search is restricted to these entities. * @param {Uuid[]} [entitiesToDiscard=[]] - Entities to ignore during the search. - * @param {boolean} [visibleOnly=false] - If true then only entities that are - * {@link Entities.EntityProperties|visible} are searched. - * @param {boolean} [collideableOnly=false] - If true then only entities that are not - * {@link Entities.EntityProperties|collisionless} are searched. + * @param {boolean} [visibleOnly=false] - true if only entities that are + * {@link Entities.EntityProperties|visible} are searched for, false if their visibility + * doesn't matter. + * @param {boolean} [collideableOnly=false] - true if only entities that are not + * {@link Entities.EntityProperties|collisionless} are searched, false if their + * collideability doesn't matter. * @returns {Entities.RayToEntityIntersectionResult} The result of the search for the first intersected entity. * @example Find the entity directly in front of your avatar. * var pickRay = { @@ -856,7 +860,7 @@ public slots: /**jsdoc * Sets whether or not ray picks intersect the bounding box of {@link Entities.EntityProperties-Light|Light} entities. By - * default, Light entities are not intersected. The setting lasts for the Interface session. Ray picks are done using + * default, Light entities are not intersected. The setting lasts for the Interface session. Ray picks are performed using * {@link Entities.findRayIntersection|findRayIntersection}, or the {@link Picks} API. * @function Entities.setLightsArePickable * @param {boolean} value - true to make ray picks intersect the bounding box of @@ -867,7 +871,7 @@ public slots: /**jsdoc * Gets whether or not ray picks intersect the bounding box of {@link Entities.EntityProperties-Light|Light} entities. Ray - * picks are done using {@link Entities.findRayIntersection|findRayIntersection}, or the {@link Picks} API. + * picks are performed using {@link Entities.findRayIntersection|findRayIntersection}, or the {@link Picks} API. * @function Entities.getLightsArePickable * @returns {boolean} true if ray picks intersect the bounding box of * {@link Entities.EntityProperties-Light|Light} entities, otherwise false. @@ -877,7 +881,7 @@ public slots: /**jsdoc * Sets whether or not ray picks intersect the bounding box of {@link Entities.EntityProperties-Zone|Zone} entities. By - * default, Zone entities are not intersected. The setting lasts for the Interface session. Ray picks are done using + * default, Zone entities are not intersected. The setting lasts for the Interface session. Ray picks are performed using * {@link Entities.findRayIntersection|findRayIntersection}, or the {@link Picks} API. * @function Entities.setZonesArePickable * @param {boolean} value - true to make ray picks intersect the bounding box of @@ -888,7 +892,7 @@ public slots: /**jsdoc * Gets whether or not ray picks intersect the bounding box of {@link Entities.EntityProperties-Zone|Zone} entities. Ray - * picks are done using {@link Entities.findRayIntersection|findRayIntersection}, or the {@link Picks} API. + * picks are performed using {@link Entities.findRayIntersection|findRayIntersection}, or the {@link Picks} API. * @function Entities.getZonesArePickable * @returns {boolean} true if ray picks intersect the bounding box of * {@link Entities.EntityProperties-Zone|Zone} entities, otherwise false. @@ -1068,7 +1072,7 @@ public slots: * the dimensions of each voxel. * @function Entities.worldCoordsToVoxelCoords * @param {Uuid} entityID - The ID of the {@link Entities.EntityProperties-PolyVox|PolyVox} entity. - * @param {Vec3} worldCoords - The world coordinates. May be outside the entity's bounding box. + * @param {Vec3} worldCoords - The world coordinates. The value may be outside the entity's bounding box. * @returns {Vec3} The voxel coordinates of the worldCoords if the entityID is a * {@link Entities.EntityProperties-PolyVox|PolyVox} entity, otherwise {@link Vec3(0)|Vec3.ZERO}. The value may be * fractional and outside the entity's bounding box. @@ -1083,7 +1087,7 @@ public slots: * Vec3.ONE being the dimensions of each voxel. * @function Entities.voxelCoordsToLocalCoords * @param {Uuid} entityID - The ID of the {@link Entities.EntityProperties-PolyVox|PolyVox} entity. - * @param {Vec3} voxelCoords - The voxel coordinates. May be fractional and outside the entity's bounding box. + * @param {Vec3} voxelCoords - The voxel coordinates. The value may be fractional and outside the entity's bounding box. * @returns {Vec3} The local coordinates of the voxelCoords if the entityID is a * {@link Entities.EntityProperties-PolyVox|PolyVox} entity, otherwise {@link Vec3(0)|Vec3.ZERO}. * @example Get the world dimensions of a voxel in a PolyVox entity. @@ -1107,7 +1111,7 @@ public slots: * Vec3.ONE being the dimensions of each voxel. * @function Entities.localCoordsToVoxelCoords * @param {Uuid} entityID - The ID of the {@link Entities.EntityProperties-PolyVox|PolyVox} entity. - * @param {Vec3} localCoords - The local coordinates. May be outside the entity's bounding box. + * @param {Vec3} localCoords - The local coordinates. The value may be outside the entity's bounding box. * @returns {Vec3} The voxel coordinates of the worldCoords if the entityID is a * {@link Entities.EntityProperties-PolyVox|PolyVox} entity, otherwise {@link Vec3(0)|Vec3.ZERO}. The value may be * fractional and outside the entity's bounding box. @@ -2105,7 +2109,7 @@ public slots: * @function Entities.getPropertyInfo * @param {string} propertyName - The name of the property to get the information for. * @returns {Entities.EntityPropertyInfo} The information about the property if it can be found, otherwise an empty object. - * @example Report property info. for some properties. + * @example Report property information for some properties. * print("alpha: " + JSON.stringify(Entities.getPropertyInfo("alpha"))); * print("script: " + JSON.stringify(Entities.getPropertyInfo("script"))); */ @@ -2209,7 +2213,7 @@ signals: /**jsdoc * Triggered when your ability to make changes to the asset server's assets changes. * @function Entities.canWriteAssetsChanged - * @param {boolean} canWriteAssets - true if the script can change the ? property of an entity, + * @param {boolean} canWriteAssets - true if the script can change the asset server's assets, * false if it can't. * @returns {Signal} */ diff --git a/libraries/entities/src/GrabPropertyGroup.h b/libraries/entities/src/GrabPropertyGroup.h index 75804378aa..9fa58273be 100644 --- a/libraries/entities/src/GrabPropertyGroup.h +++ b/libraries/entities/src/GrabPropertyGroup.h @@ -44,19 +44,20 @@ static const glm::vec3 INITIAL_EQUIPPABLE_INDICATOR_OFFSET { glm::vec3(0.0f) }; * Grabbing behavior is defined by the following properties: * * @typedef {object} Entities.Grab - * @property {boolean} grabbable=true - If true then the entity can be grabbed. - * @property {boolean} grabKinematic=true - If true then the entity will be updated in a kinematic manner when - * grabbed; if false it will be grabbed using a tractor action. A kinematic grab will make the item appear + * @property {boolean} grabbable=true - true if the entity can be grabbed, false if it can't be. + * @property {boolean} grabKinematic=true - true if the entity will be updated in a kinematic manner when + * grabbed; false if it will be grabbed using a tractor action. A kinematic grab will make the item appear * more tightly held but will cause it to behave poorly when interacting with dynamic entities. - * @property {boolean} grabFollowsController=true - If true then the entity will follow the motions of the hand - * controller even if the avatar's hand can't get to the implied position. This should be set true for tools, - * pens, etc. and false for things meant to decorate the hand. - * @property {boolean} triggerable=false - If true then the entity will receive calls to trigger - * {@link Controller|Controller entity methods}. - * @property {boolean} grabDelegateToParent=true - If true and the entity is grabbed, the grab will be transferred - * to its parent entity if there is one; if false, a child entity can be grabbed and moved relative to its - * parent. - * @property {boolean} equippable=true - If true then the entity can be equipped. + * @property {boolean} grabFollowsController=true - true if the entity will follow the motions of the hand + * controller even if the avatar's hand can't get to the implied position, false if it will follow the motions + * of the avatar's hand. This should be set true for tools, pens, etc. and false for things meant +* to decorate the hand. + * @property {boolean} triggerable=false - true if the entity will receive calls to trigger + * {@link Controller|Controller entity methods}, false if it won't. + * @property {boolean} grabDelegateToParent=true - true if when the entity is grabbed, the grab will be + * transferred to its parent entity if there is one; false if the grab won't be transferred, so a child entity + * can be grabbed and moved relative to its parent. + * @property {boolean} equippable=true - true if the entity can be equipped, false if it cannot. * @property {Vec3} equippableLeftPosition=0,0,0 - Positional offset from the left hand, when equipped. * @property {Quat} equippableLeftRotation=0,0,0,1 - Rotational offset from the left hand, when equipped. * @property {Vec3} equippableRightPosition=0,0,0 - Positional offset from the right hand, when equipped. diff --git a/libraries/entities/src/HazePropertyGroup.h b/libraries/entities/src/HazePropertyGroup.h index 116bfd9687..59a36b6f7f 100644 --- a/libraries/entities/src/HazePropertyGroup.h +++ b/libraries/entities/src/HazePropertyGroup.h @@ -49,14 +49,16 @@ static const float INITIAL_KEY_LIGHT_ALTITUDE{ 200.0f }; * @property {number} hazeRange=1000 - The horizontal distance at which visibility is reduced to 95%; i.e., 95% of each pixel's * color is haze. * @property {Color} hazeColor=128,154,179 - The color of the haze when looking away from the key light. - * @property {boolean} hazeEnableGlare=false - If true then the haze is colored with glare from the key light; - * hazeGlareColor and hazeGlareAngle are used. + * @property {boolean} hazeEnableGlare=false - true if the haze is colored with glare from the key light, + * false if it isn't. If true, then hazeGlareColor and hazeGlareAngle + * are used. * @property {Color} hazeGlareColor=255,299,179 - The color of the haze when looking towards the key light. * @property {number} hazeGlareAngle=20 - The angle in degrees across the circle around the key light that the glare color and * haze color are blended 50/50. * - * @property {boolean} hazeAltitudeEffect=false - If true then haze decreases with altitude as defined by the - * entity's local coordinate system; hazeBaseRef and hazeCeiling are used. + * @property {boolean} hazeAltitudeEffect=false - true if haze decreases with altitude as defined by the + * entity's local coordinate system, false if it doesn't. If true, then hazeBaseRef + * and hazeCeiling are used. * @property {number} hazeBaseRef=0 - The y-axis value in the entity's local coordinate system at which the haze density starts * reducing with altitude. * @property {number} hazeCeiling=200 - The y-axis value in the entity's local coordinate system at which the haze density has @@ -65,8 +67,8 @@ static const float INITIAL_KEY_LIGHT_ALTITUDE{ 200.0f }; * @property {number} hazeBackgroundBlend=0 - The proportion of the skybox image to show through the haze: 0.0 * displays no skybox image; 1.0 displays no haze. * - * @property {boolean} hazeAttenuateKeyLight=false - If true then the haze attenuates the key light; - * hazeKeyLightRange and hazeKeyLightAltitude are used. + * @property {boolean} hazeAttenuateKeyLight=false - true if the haze attenuates the key light, false + * if it doesn't. If true, then hazeKeyLightRange and hazeKeyLightAltitude are used. * @property {number} hazeKeyLightRange=1000 - The distance at which the haze attenuates the key light by 95%. * @property {number} hazeKeyLightAltitude=200 - The altitude at which the haze starts attenuating the key light (i.e., the * altitude at which the distance starts being calculated). diff --git a/libraries/entities/src/KeyLightPropertyGroup.h b/libraries/entities/src/KeyLightPropertyGroup.h index 31e0cba1c6..d46f5ce9b5 100644 --- a/libraries/entities/src/KeyLightPropertyGroup.h +++ b/libraries/entities/src/KeyLightPropertyGroup.h @@ -33,8 +33,9 @@ class ReadBitstreamToTreeParams; * @property {Color} color=255,255,255 - The color of the light. * @property {number} intensity=1 - The intensity of the light. * @property {Vec3} direction=0,-1,0 - The direction the light is shining. - * @property {boolean} castShadows=false - If true then shadows are cast. Shadows are cast by avatars, plus - * {@link Entities.EntityProperties-Model|Model} and {@link Entities.EntityProperties-Shape|Shape} entities that have their + * @property {boolean} castShadows=false - true if shadows are cast, false if they aren't. Shadows + * are cast by avatars, plus {@link Entities.EntityProperties-Model|Model} and + * {@link Entities.EntityProperties-Shape|Shape} entities that have their * {@link Entities.EntityProperties|canCastShadow} property set to true. */ class KeyLightPropertyGroup : public PropertyGroup { diff --git a/libraries/material-networking/src/material-networking/MaterialCache.cpp b/libraries/material-networking/src/material-networking/MaterialCache.cpp index 4f6d149fbe..cfe3b73e49 100644 --- a/libraries/material-networking/src/material-networking/MaterialCache.cpp +++ b/libraries/material-networking/src/material-networking/MaterialCache.cpp @@ -115,15 +115,15 @@ NetworkMaterialResource::ParsedMaterials NetworkMaterialResource::parseJSONMater * Supported models are: "hifi_pbr". * @property {string} name="" - A name for the material. Supported by all material models. * @property {ColorFloat|RGBS|string} emissive - The emissive color, i.e., the color that the material emits. A - * {@link ColorFloat} value is treated as sRGB and must have component values in the range 0.0 — + * {@link ColorFloat} value is treated as sRGB and must have component values in the range 0.0 – * 1.0. A {@link RGBS} value can be either RGB or sRGB. * Set to "fallthrough" to fall through to the material below. "hifi_pbr" model only. * @property {number|string} opacity=1.0 - The opacity, range 0.01.0. * Set to "fallthrough" to fall through to the material below. "hifi_pbr" model only. - * @property {boolean|string} unlit=false - If true, the material is not lit, otherwise it is. + * @property {boolean|string} unlit=false - true if the material is not lit, false if it is. * Set to "fallthrough" to fall through to the material below. "hifi_pbr" model only. * @property {ColorFloat|RGBS|string} albedo - The albedo color. A {@link ColorFloat} value is treated as sRGB and must have - * component values in the range 0.01.0. A {@link RGBS} value can be either RGB or sRGB. + * component values in the range 0.01.0. A {@link RGBS} value can be either RGB or sRGB. * Set to "fallthrough" to fall through to the material below. "hifi_pbr" model only. * @property {number|string} roughness - The roughness, range 0.01.0. * Set to "fallthrough" to fall through to the material below. "hifi_pbr" model only. @@ -172,9 +172,9 @@ NetworkMaterialResource::ParsedMaterials NetworkMaterialResource::parseJSONMater * @property {string} materialParams - Parameters for controlling the material projection and repetition. * Set to "fallthrough" to fall through to the material below. "hifi_pbr" model only. *

Currently not used.

- * @property {boolean} defaultFallthrough=false - If true, all properties fall through to the material below - * unless they are set. If false, they respect their individual fall-through setting. "hifi_pbr" - * model only. + * @property {boolean} defaultFallthrough=false - true if all properties fall through to the material below + * unless they are set, false if properties respect their individual fall-through settings. + * "hifi_pbr" model only. */ // Note: See MaterialEntityItem.h for default values used in practice. std::pair> NetworkMaterialResource::parseJSONMaterial(const QJsonObject& materialJSON, const QUrl& baseUrl) { diff --git a/libraries/physics/src/ObjectActionOffset.cpp b/libraries/physics/src/ObjectActionOffset.cpp index a99c875106..526eb9f000 100644 --- a/libraries/physics/src/ObjectActionOffset.cpp +++ b/libraries/physics/src/ObjectActionOffset.cpp @@ -143,8 +143,8 @@ bool ObjectActionOffset::updateArguments(QVariantMap arguments) { } /**jsdoc - * The "offset" {@link Entities.ActionType|ActionType} moves an entity so that it is a set distance away from a - * target point. + * The "offset" {@link Entities.ActionType|ActionType} moves an entity so that it is a defined distance away from + * a target point. * It has arguments in addition to the common {@link Entities.ActionArguments|ActionArguments}: * * @typedef {object} Entities.ActionArguments-Offset diff --git a/libraries/physics/src/ObjectDynamic.cpp b/libraries/physics/src/ObjectDynamic.cpp index f02b7b1c4c..4f7feacbab 100644 --- a/libraries/physics/src/ObjectDynamic.cpp +++ b/libraries/physics/src/ObjectDynamic.cpp @@ -95,23 +95,24 @@ bool ObjectDynamic::updateArguments(QVariantMap arguments) { /**jsdoc * Different entity action types have different arguments: some common to all actions (listed in the table) and some specific - * to each {@link Entities.ActionType|ActionType} (linked to below). The arguments are accessed as an object of property names - * and values. + * to each {@link Entities.ActionType|ActionType} (linked to below). * * @typedef {object} Entities.ActionArguments * @property {Entities.ActionType} type - The type of action. * @property {string} tag="" - A string that a script can use for its own purposes. * @property {number} ttl=0 - How long the action should exist, in seconds, before it is automatically deleted. A value of * 0 means that the action should not be deleted. - * @property {boolean} isMine=true - Is true if the action was created during the current client session, - * false otherwise. Read-only. - * @property {boolean} ::no-motion-state - Is present when the entity hasn't been registered with the physics engine yet (e.g., - * if the action hasn't been properly configured), otherwise undefined. Read-only. - * @property {boolean} ::active - Is true when the action is modifying the entity's motion, false - * otherwise. Is present once the entity has been registered with the physics engine, otherwise undefined. + * @property {boolean} isMine=true - true if the action was created during the current client session, + * false if it wasn't. Read-only. + * @property {boolean} ::no-motion-state - Is present with a value of true when the entity hasn't been registered + * with the physics engine yet (e.g., if the action hasn't been properly configured), otherwise the property is + * undefined. Read-only. + * @property {boolean} ::active - true when the action is modifying the entity's motion, false + * otherwise. Is present once the entity has been registered with the physics engine, otherwise the property is + * undefined. * Read-only. * @property {Entities.PhysicsMotionType} ::motion-type - How the entity moves with the action. Is present once the entity has - * been registered with the physics engine, otherwise undefined. Read-only. + * been registered with the physics engine, otherwise the property is undefined. Read-only. * * @comment The different action types have additional arguments as follows: * @see {@link Entities.ActionArguments-FarGrab|ActionArguments-FarGrab} diff --git a/libraries/script-engine/src/AudioScriptingInterface.h b/libraries/script-engine/src/AudioScriptingInterface.h index dea44d6a1d..10af9214c1 100644 --- a/libraries/script-engine/src/AudioScriptingInterface.h +++ b/libraries/script-engine/src/AudioScriptingInterface.h @@ -108,8 +108,8 @@ public: * Sets whether your microphone audio is echoed back to you from the server. When enabled, microphone audio is echoed * only if you're unmuted or are using push-to-talk. * @function Audio.setServerEcho - * @parm {boolean} serverEcho - true to enable echoing microphone back to you from the server, - * false to disable. + * @param {boolean} serverEcho - true to enable echoing microphone back to you from the server, + * false to disable. */ Q_INVOKABLE void setServerEcho(bool serverEcho); From 5cc6efc831d0fd1748388b3cfc2b8233f84583fe Mon Sep 17 00:00:00 2001 From: Zach Fox Date: Fri, 28 Jun 2019 09:07:58 -0700 Subject: [PATCH 15/26] CR feedback --- interface/src/scripting/Audio.cpp | 2 -- interface/src/scripting/Audio.h | 38 ++++++++++++++++--------------- 2 files changed, 20 insertions(+), 20 deletions(-) diff --git a/interface/src/scripting/Audio.cpp b/interface/src/scripting/Audio.cpp index ddf9ccca10..a0bea256ad 100644 --- a/interface/src/scripting/Audio.cpp +++ b/interface/src/scripting/Audio.cpp @@ -370,8 +370,6 @@ void Audio::handlePushedToTalk(bool enabled) { float gain = resultWithReadLock([&] { return _pttOutputGainDesktop; }); // convert dB to amplitude gain = fastExp2f(gain / 6.02059991f); - // quantize and limit to match NodeList::setInjectorGain() - gain = unpackFloatGainFromByte(packFloatGainToByte(gain)); DependencyManager::get()->setOutputGain(gain); // duck the output by N dB } setMuted(false); diff --git a/interface/src/scripting/Audio.h b/interface/src/scripting/Audio.h index 0954d5f062..9173a4b4eb 100644 --- a/interface/src/scripting/Audio.h +++ b/interface/src/scripting/Audio.h @@ -66,10 +66,12 @@ class Audio : public AudioScriptingInterface, protected ReadWriteLockable { * @property {boolean} pushToTalkHMD - true if HMD push-to-talk is enabled, otherwise false. * @property {boolean} pushingToTalk - true if the user is currently pushing-to-talk, otherwise * false. - * @property {float} avatarGain - The gain (relative volume) that avatars' voices are played at. This gain is used at the server. - * @property {float} localInjectorGain - The gain (relative volume) that local injectors (local environment sounds) are played at. - * @property {float} serverInjectorGain - The gain (relative volume) that server injectors (server environment sounds) are played at. This gain is used at the server. - * @property {float} systemInjectorGain - The gain (relative volume) that system sounds are played at. + * @property {number} avatarGain - The gain (relative volume) that avatars' voices are played at. This gain is used at the server. + * @property {number} localInjectorGain - The gain (relative volume) that local injectors (local environment sounds) are played at. + * @property {number} serverInjectorGain - The gain (relative volume) that server injectors (server environment sounds) are played at. This gain is used at the server. + * @property {number} systemInjectorGain - The gain (relative volume) that system sounds are played at. + * @property {number} pushingToTalkOutputGainDesktop - The gain (relative volume) that all sounds are played at when the user is holding + * the push-to-talk key in Desktop mode. * * @comment The following properties are from AudioScriptingInterface.h. * @property {boolean} isStereoInput - true if the input audio is being used in stereo, otherwise @@ -199,14 +201,14 @@ public: /**jsdoc * Sets the gain (relative volume) that avatars' voices are played at. This gain is used at the server. * @function Audio.setAvatarGain - * @param {number} gain - Avatar gain (dB) at the server. + * @param {number} gain - The avatar gain (dB) at the server. */ Q_INVOKABLE void setAvatarGain(float gain); /**jsdoc * Gets the gain (relative volume) that avatars' voices are played at. This gain is used at the server. * @function Audio.getAvatarGain - * @returns {number} Avatar gain (dB) at the server. + * @returns {number} The avatar gain (dB) at the server. * @example Report current audio gain settings. * // 0 value = normal volume; -ve value = quieter; +ve value = louder. * print("Avatar gain: " + Audio.getAvatarGain()); @@ -219,42 +221,42 @@ public: /**jsdoc * Sets the gain (relative volume) that environment sounds from the server are played at. * @function Audio.setInjectorGain - * @param {number} gain - Injector gain (dB) at the server. + * @param {number} gain - The injector gain (dB) at the server. */ Q_INVOKABLE void setInjectorGain(float gain); /**jsdoc * Gets the gain (relative volume) that environment sounds from the server are played at. * @function Audio.getInjectorGain - * @returns {number} Injector gain (dB) at the server. + * @returns {number} The injector gain (dB) at the server. */ Q_INVOKABLE float getInjectorGain(); /**jsdoc * Sets the gain (relative volume) that environment sounds from the client are played at. * @function Audio.setLocalInjectorGain - * @param {number} gain - Injector gain (dB) in the client. + * @param {number} gain - The injector gain (dB) in the client. */ Q_INVOKABLE void setLocalInjectorGain(float gain); /**jsdoc * Gets the gain (relative volume) that environment sounds from the client are played at. * @function Audio.getLocalInjectorGain - * @returns {number} Injector gain (dB) in the client. + * @returns {number} The injector gain (dB) in the client. */ Q_INVOKABLE float getLocalInjectorGain(); /**jsdoc * Sets the gain (relative volume) that system sounds are played at. * @function Audio.setSystemInjectorGain - * @param {number} gain - Injector gain (dB) in the client. + * @param {number} gain - The injector gain (dB) in the client. */ Q_INVOKABLE void setSystemInjectorGain(float gain); /**jsdoc * Gets the gain (relative volume) that system sounds are played at. * @function Audio.getSystemInjectorGain - * @returns {number} Injector gain (dB) in the client. + * @returns {number} The injector gain (dB) in the client. */ Q_INVOKABLE float getSystemInjectorGain(); @@ -296,7 +298,7 @@ public: * Sets the output volume gain that will be used when the user is holding the Push to Talk key. * Should be negative. * @function Audio.setPushingToTalkOutputGainDesktop - * @param {number} gain - Output volume gain (dB) while using PTT. + * @param {number} gain - The output volume gain (dB) while using PTT. */ Q_INVOKABLE void setPushingToTalkOutputGainDesktop(float gain); @@ -304,7 +306,7 @@ public: * Gets the output volume gain that is used when the user is holding the Push to Talk key. * Should be negative. * @function Audio.getPushingToTalkOutputGainDesktop - * @returns {number} gain - Output volume gain (dB) while using PTT. + * @returns {number} gain - The output volume gain (dB) while using PTT. */ Q_INVOKABLE float getPushingToTalkOutputGainDesktop(); @@ -441,7 +443,7 @@ signals: /**jsdoc * Triggered when the avatar gain changes. * @function Audio.avatarGainChanged - * @param {float} gain - The new avatar gain value. + * @param {number} gain - The new avatar gain value. * @returns {Signal} */ void avatarGainChanged(float gain); @@ -449,7 +451,7 @@ signals: /**jsdoc * Triggered when the local injector gain changes. * @function Audio.localInjectorGainChanged - * @param {float} gain - The new local injector gain value. + * @param {number} gain - The new local injector gain value. * @returns {Signal} */ void localInjectorGainChanged(float gain); @@ -465,7 +467,7 @@ signals: /**jsdoc * Triggered when the system injector gain changes. * @function Audio.systemInjectorGainChanged - * @param {float} gain - The new system injector gain value. + * @param {number} gain - The new system injector gain value. * @returns {Signal} */ void systemInjectorGainChanged(float gain); @@ -473,7 +475,7 @@ signals: /**jsdoc * Triggered when the push to talk gain changes. * @function Audio.pushingToTalkOutputGainDesktopChanged - * @param {float} gain - The new output gain value. + * @param {number} gain - The new output gain value. * @returns {Signal} */ void pushingToTalkOutputGainDesktopChanged(float gain); From 17d127ecf3ca0a373841be82ad4af7120da561e4 Mon Sep 17 00:00:00 2001 From: raveenajain Date: Fri, 28 Jun 2019 10:07:49 -0700 Subject: [PATCH 16/26] modify shadow debugger for new bias input --- scripts/developer/utilities/render/shadow.qml | 22 ++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) mode change 100644 => 100755 scripts/developer/utilities/render/shadow.qml diff --git a/scripts/developer/utilities/render/shadow.qml b/scripts/developer/utilities/render/shadow.qml old mode 100644 new mode 100755 index a1d6777a68..427b52c659 --- a/scripts/developer/utilities/render/shadow.qml +++ b/scripts/developer/utilities/render/shadow.qml @@ -67,7 +67,7 @@ Rectangle { } ColumnLayout { - spacing: 20 + spacing: 10 anchors.left: parent.left anchors.right: parent.right anchors.margins: hifi.dimensions.contentMargin.x @@ -109,6 +109,26 @@ Rectangle { font.italic: true } } + ConfigSlider { + label: qsTr("Bias Input") + integral: false + config: shadowConfig + property: "biasInput" + max: 1.0 + min: 0.0 + height: 38 + width:250 + } + ConfigSlider { + label: qsTr("Shadow Max Distance") + integral: false + config: shadowConfig + property: "globalMaxDistance" + max: 100.0 + min: 1.0 + height: 38 + width:250 + } Repeater { model: [ "0", "1", "2", "3" From e3393a8ee5e825e0e9155b049bb2dbd17c3cd182 Mon Sep 17 00:00:00 2001 From: Brad Davis Date: Fri, 28 Jun 2019 10:43:03 -0700 Subject: [PATCH 17/26] Apply URL validation to top level window QML --- .../src/scripting/DesktopScriptingInterface.cpp | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/interface/src/scripting/DesktopScriptingInterface.cpp b/interface/src/scripting/DesktopScriptingInterface.cpp index 8a34c8f2ba..ef5bd7abb9 100644 --- a/interface/src/scripting/DesktopScriptingInterface.cpp +++ b/interface/src/scripting/DesktopScriptingInterface.cpp @@ -117,5 +117,15 @@ InteractiveWindowPointer DesktopScriptingInterface::createWindow(const QString& Q_ARG(QVariantMap, properties)); return interactiveWindow; } - return new InteractiveWindow(sourceUrl, properties);; + + + // The offscreen surface already validates against non-local QML sources, but we also need to ensure that + // if we create top level QML, like dock widgets or other types of QQuickView containing desktop windows + // that the source URL is permitted + const auto& urlValidator = OffscreenQmlSurface::getUrlValidator(); + if (!urlValidator(sourceUrl)) { + return nullptr; + } + + return new InteractiveWindow(sourceUrl, properties); } From 225f65f4fb02df71ce4315973bea8359f8109a9a Mon Sep 17 00:00:00 2001 From: Simon Walton Date: Fri, 28 Jun 2019 11:30:09 -0700 Subject: [PATCH 18/26] Log message tweaks Also don't need std in std::move, somehow. --- libraries/networking/src/LimitedNodeList.cpp | 8 +++++--- libraries/networking/src/udt/Socket.cpp | 4 ++-- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/libraries/networking/src/LimitedNodeList.cpp b/libraries/networking/src/LimitedNodeList.cpp index ac0f9e0b07..b5872a46fd 100644 --- a/libraries/networking/src/LimitedNodeList.cpp +++ b/libraries/networking/src/LimitedNodeList.cpp @@ -1088,12 +1088,14 @@ void LimitedNodeList::processSTUNResponse(std::unique_ptr packe if (parseSTUNResponse(packet.get(), newPublicAddress, newPublicPort)) { if (newPublicAddress != _publicSockAddr.getAddress() || newPublicPort != _publicSockAddr.getPort()) { - _publicSockAddr = HifiSockAddr(newPublicAddress, newPublicPort); - - qCDebug(networking, "New public socket received from STUN server is %s:%hu", + qCDebug(networking, "New public socket received from STUN server is %s:%hu (was %s:%hu)", + newPublicAddress.toString().toStdString().c_str(), + newPublicPort, _publicSockAddr.getAddress().toString().toLocal8Bit().constData(), _publicSockAddr.getPort()); + _publicSockAddr = HifiSockAddr(newPublicAddress, newPublicPort); + if (!_hasCompletedInitialSTUN) { // if we're here we have definitely completed our initial STUN sequence stopInitialSTUNUpdate(true); diff --git a/libraries/networking/src/udt/Socket.cpp b/libraries/networking/src/udt/Socket.cpp index e8fe3741aa..4714160ace 100644 --- a/libraries/networking/src/udt/Socket.cpp +++ b/libraries/networking/src/udt/Socket.cpp @@ -545,10 +545,10 @@ void Socket::handleRemoteAddressChange(HifiSockAddr previousAddress, HifiSockAdd const auto connectionIter = _connectionsHash.find(previousAddress); if (connectionIter != _connectionsHash.end()) { - auto connection = std::move(connectionIter->second); + auto connection = move(connectionIter->second); _connectionsHash.erase(connectionIter); connection->setDestinationAddress(currentAddress); - _connectionsHash[currentAddress] = std::move(connection); + _connectionsHash[currentAddress] = move(connection); } } From c76d267c2abeace5f4d6fed9a13e19a7b10512c0 Mon Sep 17 00:00:00 2001 From: SamGondelman Date: Fri, 28 Jun 2019 13:53:44 -0700 Subject: [PATCH 19/26] separate text into two render items --- .../src/RenderableTextEntityItem.cpp | 275 ++++++++++++++---- .../src/RenderableTextEntityItem.h | 42 ++- 2 files changed, 253 insertions(+), 64 deletions(-) diff --git a/libraries/entities-renderer/src/RenderableTextEntityItem.cpp b/libraries/entities-renderer/src/RenderableTextEntityItem.cpp index a281c1d097..381edd8731 100644 --- a/libraries/entities-renderer/src/RenderableTextEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableTextEntityItem.cpp @@ -25,28 +25,22 @@ using namespace render; using namespace render::entities; static const int FIXED_FONT_POINT_SIZE = 40; -const int FIXED_FONT_SCALING_RATIO = FIXED_FONT_POINT_SIZE * 92.0f; // Determined through experimentation to fit font to line - // height. +const int FIXED_FONT_SCALING_RATIO = FIXED_FONT_POINT_SIZE * 92.0f; // Determined through experimentation to fit font to line height. const float LINE_SCALE_RATIO = 1.2f; TextEntityRenderer::TextEntityRenderer(const EntityItemPointer& entity) : Parent(entity), _textRenderer(TextRenderer3D::getInstance(SANS_FONT_FAMILY, FIXED_FONT_POINT_SIZE / 2.0f)) { - auto geometryCache = DependencyManager::get(); - if (geometryCache) { - _geometryID = geometryCache->allocateID(); - } -} - -TextEntityRenderer::~TextEntityRenderer() { - auto geometryCache = DependencyManager::get(); - if (_geometryID && geometryCache) { - geometryCache->releaseID(_geometryID); - } } bool TextEntityRenderer::isTransparent() const { - return Parent::isTransparent() || _textAlpha < 1.0f || _backgroundAlpha < 1.0f || _pulseProperties.getAlphaMode() != PulseMode::NONE; + return Parent::isTransparent() || _backgroundAlpha < 1.0f || _pulseProperties.getAlphaMode() != PulseMode::NONE; +} + +bool TextEntityRenderer::isTextTransparent() const { + return resultWithReadLock([&] { + return Parent::isTransparent() || _textAlpha < 1.0f || _pulseProperties.getAlphaMode() != PulseMode::NONE; + }); } Item::Bound TextEntityRenderer::getBound() { @@ -61,7 +55,7 @@ Item::Bound TextEntityRenderer::getBound() { } ShapeKey TextEntityRenderer::getShapeKey() { - auto builder = render::ShapeKey::Builder().withOwnPipeline(); + auto builder = render::ShapeKey::Builder(); if (isTransparent()) { builder.withTranslucent(); } @@ -134,6 +128,7 @@ void TextEntityRenderer::doRenderUpdateSynchronousTyped(const ScenePointer& scen _dimensions = entity->getScaledDimensions(); updateModelTransformAndBound(); _renderTransform = getModelTransform(); + _renderTransform.postScale(_dimensions); }); }); } @@ -152,65 +147,49 @@ void TextEntityRenderer::doRenderUpdateAsynchronousTyped(const TypedEntityPointe _rightMargin = entity->getRightMargin(); _topMargin = entity->getTopMargin(); _bottomMargin = entity->getBottomMargin(); + updateTextRenderItem(); }); } void TextEntityRenderer::doRender(RenderArgs* args) { PerformanceTimer perfTimer("RenderableTextEntityItem::render"); - - glm::vec4 textColor; - glm::vec4 backgroundColor; - Transform modelTransform; - glm::vec3 dimensions; - BillboardMode billboardMode; - bool forward; - withReadLock([&] { - modelTransform = _renderTransform; - dimensions = _dimensions; - billboardMode = _billboardMode; - - float fadeRatio = _isFading ? Interpolate::calculateFadeRatio(_fadeStartTime) : 1.0f; - textColor = glm::vec4(_textColor, fadeRatio * _textAlpha); - textColor = EntityRenderer::calculatePulseColor(textColor, _pulseProperties, _created); - backgroundColor = glm::vec4(_backgroundColor, fadeRatio * _backgroundAlpha); - backgroundColor = EntityRenderer::calculatePulseColor(backgroundColor, _pulseProperties, _created); - forward = _renderLayer != RenderLayer::WORLD || args->_renderMethod == render::Args::FORWARD; - }); - - // Render background - static const float SLIGHTLY_BEHIND = -0.005f; - glm::vec3 minCorner = glm::vec3(0.0f, -dimensions.y, SLIGHTLY_BEHIND); - glm::vec3 maxCorner = glm::vec3(dimensions.x, 0.0f, SLIGHTLY_BEHIND); - - // Batch render calls Q_ASSERT(args->_batch); gpu::Batch& batch = *args->_batch; - // FIXME: we need to find a better way of rendering text so we don't have to do this - if (forward) { - DependencyManager::get()->setupKeyLightBatch(args, batch); + glm::vec4 backgroundColor; + Transform modelTransform; + BillboardMode billboardMode; + PrimitiveMode primitiveMode; + RenderLayer renderLayer; + withReadLock([&] { + modelTransform = _renderTransform; + billboardMode = _billboardMode; + primitiveMode = _primitiveMode; + renderLayer = _renderLayer; + + float fadeRatio = _isFading ? Interpolate::calculateFadeRatio(_fadeStartTime) : 1.0f; + backgroundColor = glm::vec4(_backgroundColor, fadeRatio * _backgroundAlpha); + backgroundColor = EntityRenderer::calculatePulseColor(backgroundColor, _pulseProperties, _created); + }); + + if (backgroundColor.a <= 0.0f) { + return; } - auto transformToTopLeft = modelTransform; - transformToTopLeft.setRotation(EntityItem::getBillboardRotation(transformToTopLeft.getTranslation(), transformToTopLeft.getRotation(), billboardMode, args->getViewFrustum().getPosition())); - transformToTopLeft.postTranslate(dimensions * glm::vec3(-0.5f, 0.5f, 0.0f)); // Go to the top left - transformToTopLeft.setScale(1.0f); // Use a scale of one so that the text is not deformed + modelTransform.setRotation(EntityItem::getBillboardRotation(modelTransform.getTranslation(), modelTransform.getRotation(), billboardMode, args->getViewFrustum().getPosition())); + batch.setModelTransform(modelTransform); - if (backgroundColor.a > 0.0f) { - batch.setModelTransform(transformToTopLeft); - auto geometryCache = DependencyManager::get(); - geometryCache->bindSimpleProgram(batch, false, backgroundColor.a < 1.0f, false, false, false, true, forward); - geometryCache->renderQuad(batch, minCorner, maxCorner, backgroundColor, _geometryID); + auto geometryCache = DependencyManager::get(); + render::ShapePipelinePointer pipeline; + if (renderLayer == RenderLayer::WORLD && args->_renderMethod != Args::RenderMethod::FORWARD) { + pipeline = backgroundColor.a < 1.0f ? geometryCache->getTransparentShapePipeline() : geometryCache->getOpaqueShapePipeline(); + } else { + pipeline = backgroundColor.a < 1.0f ? geometryCache->getForwardTransparentShapePipeline() : geometryCache->getForwardOpaqueShapePipeline(); } - - if (textColor.a > 0.0f) { - // FIXME: Factor out textRenderer so that text parts can be grouped by pipeline for a gpu performance increase. - float scale = _lineHeight / _textRenderer->getFontSize(); - transformToTopLeft.setScale(scale); // Scale to have the correct line height - batch.setModelTransform(transformToTopLeft); - - glm::vec2 bounds = glm::vec2(dimensions.x - (_leftMargin + _rightMargin), dimensions.y - (_topMargin + _bottomMargin)); - _textRenderer->draw(batch, _leftMargin / scale, -_topMargin / scale, _text, textColor, bounds / scale, forward); + if (render::ShapeKey(args->_globalShapeKey).isWireframe() || primitiveMode == PrimitiveMode::LINES) { + geometryCache->renderWireShapeInstance(args, batch, GeometryCache::Quad, backgroundColor, pipeline); + } else { + geometryCache->renderSolidShapeInstance(args, batch, GeometryCache::Quad, backgroundColor, pipeline); } } @@ -222,4 +201,176 @@ QSizeF TextEntityRenderer::textSize(const QString& text) const { float pointToWorldScale = (maxHeight / FIXED_FONT_SCALING_RATIO) * _lineHeight; return QSizeF(extents.x, extents.y) * pointToWorldScale; +} + +void TextEntityRenderer::onAddToSceneTyped(const TypedEntityPointer& entity) { + Parent::onAddToSceneTyped(entity); + _textPayload = std::make_shared(entity->getID(), _textRenderer); + _textRenderID = AbstractViewStateInterface::instance()->getMain3DScene()->allocateID(); + auto renderPayload = std::make_shared(_textPayload); + render::Transaction transaction; + transaction.resetItem(_textRenderID, renderPayload); + AbstractViewStateInterface::instance()->getMain3DScene()->enqueueTransaction(transaction); + updateTextRenderItem(); +} + +void TextEntityRenderer::onRemoveFromSceneTyped(const TypedEntityPointer& entity) { + Parent::onRemoveFromSceneTyped(entity); + render::Transaction transaction; + transaction.removeItem(_textRenderID); + AbstractViewStateInterface::instance()->getMain3DScene()->enqueueTransaction(transaction); + _textPayload.reset(); +} + +void TextEntityRenderer::updateTextRenderItem() const { + render::Transaction transaction; + transaction.updateItem(_textRenderID); + AbstractViewStateInterface::instance()->getMain3DScene()->enqueueTransaction(transaction); +} + +entities::TextPayload::TextPayload(const QUuid& entityID, const std::weak_ptr& textRenderer) : + _entityID(entityID), _textRenderer(textRenderer) { + auto geometryCache = DependencyManager::get(); + if (geometryCache) { + _geometryID = geometryCache->allocateID(); + } +} + +entities::TextPayload::~TextPayload() { + auto geometryCache = DependencyManager::get(); + if (_geometryID && geometryCache) { + geometryCache->releaseID(_geometryID); + } +} + +ItemKey entities::TextPayload::getKey() const { + auto renderable = DependencyManager::get()->renderableForEntityId(_entityID); + if (renderable) { + auto textRenderable = std::static_pointer_cast(renderable); + ItemKey::Builder key; + // Similar to EntityRenderer::getKey() + // FIXME: should be withSubMetaCulled and not meta, but there's a bug in the layer rendering that won't render it in that case + // (the TextEntityRenderer should also be withMetaCullGroup) + if (textRenderable->isTextTransparent()) { + key = ItemKey::Builder::transparentShape().withTypeMeta().withTagBits(textRenderable->getTagMask()).withLayer(textRenderable->getHifiRenderLayer()); + } else if (textRenderable->_canCastShadow) { + key = ItemKey::Builder::opaqueShape().withTypeMeta().withTagBits(textRenderable->getTagMask()).withShadowCaster().withLayer(textRenderable->getHifiRenderLayer()); + } else { + key = ItemKey::Builder::opaqueShape().withTypeMeta().withTagBits(textRenderable->getTagMask()).withLayer(textRenderable->getHifiRenderLayer()); + } + + if (!textRenderable->_visible) { + key.withInvisible(); + } + return key; + } + return ItemKey::Builder::opaqueShape(); +} + +Item::Bound entities::TextPayload::getBound() const { + auto renderable = DependencyManager::get()->renderableForEntityId(_entityID); + if (renderable) { + return std::static_pointer_cast(renderable)->getBound(); + } + return Item::Bound(); +} + +ShapeKey entities::TextPayload::getShapeKey() const { + auto renderable = DependencyManager::get()->renderableForEntityId(_entityID); + if (renderable) { + auto textRenderable = std::static_pointer_cast(renderable); + + auto builder = render::ShapeKey::Builder().withOwnPipeline(); + if (textRenderable->isTextTransparent()) { + builder.withTranslucent(); + } + if (textRenderable->_primitiveMode == PrimitiveMode::LINES) { + builder.withWireframe(); + } + return builder.build(); + } + return ShapeKey::Builder::invalid(); +} + +void entities::TextPayload::render(RenderArgs* args) { + PerformanceTimer perfTimer("TextPayload::render"); + Q_ASSERT(args->_batch); + gpu::Batch& batch = *args->_batch; + + auto textRenderer = _textRenderer.lock(); + if (!textRenderer) { + return; + } + + auto renderable = DependencyManager::get()->renderableForEntityId(_entityID); + if (!renderable) { + return; + } + auto textRenderable = std::static_pointer_cast(renderable); + + glm::vec4 textColor; + Transform modelTransform; + BillboardMode billboardMode; + float lineHeight, leftMargin, rightMargin, topMargin, bottomMargin; + QString text; + glm::vec3 dimensions; + bool forward; + textRenderable->withReadLock([&] { + modelTransform = textRenderable->_renderTransform; + billboardMode = textRenderable->_billboardMode; + lineHeight = textRenderable->_lineHeight; + leftMargin = textRenderable->_leftMargin; + rightMargin = textRenderable->_rightMargin; + topMargin = textRenderable->_topMargin; + bottomMargin = textRenderable->_bottomMargin; + text = textRenderable->_text; + dimensions = textRenderable->_dimensions; + + float fadeRatio = textRenderable->_isFading ? Interpolate::calculateFadeRatio(textRenderable->_fadeStartTime) : 1.0f; + textColor = glm::vec4(textRenderable->_textColor, fadeRatio * textRenderable->_textAlpha); + textColor = EntityRenderer::calculatePulseColor(textColor, textRenderable->_pulseProperties, textRenderable->_created); + forward = textRenderable->_renderLayer != RenderLayer::WORLD || args->_renderMethod == render::Args::FORWARD; + }); + + if (textColor.a <= 0.0f) { + return; + } + + modelTransform.setRotation(EntityItem::getBillboardRotation(modelTransform.getTranslation(), modelTransform.getRotation(), billboardMode, args->getViewFrustum().getPosition())); + + float scale = lineHeight / textRenderer->getFontSize(); + const float TEXT_ENTITY_ITEM_FIXED_DEPTH = 0.01f; + modelTransform.postTranslate(glm::vec3(-0.5, 0.5, 1.0f + EPSILON / dimensions.z)); + modelTransform.setScale(scale); + batch.setModelTransform(modelTransform); + + glm::vec2 bounds = glm::vec2(dimensions.x - (leftMargin + rightMargin), dimensions.y - (topMargin + bottomMargin)); + textRenderer->draw(batch, leftMargin / scale, -topMargin / scale, text, textColor, bounds / scale, forward); +} + +namespace render { +template <> const ItemKey payloadGetKey(const TextPayload::Pointer& payload) { + if (payload) { + return payload->getKey(); + } + return ItemKey::Builder::opaqueShape(); +} + +template <> const Item::Bound payloadGetBound(const TextPayload::Pointer& payload) { + if (payload) { + return payload->getBound(); + } + return Item::Bound(); +} + +template <> const ShapeKey shapeGetShapeKey(const TextPayload::Pointer& payload) { + if (payload) { + return payload->getShapeKey(); + } + return ShapeKey::Builder::invalid(); +} + +template <> void payloadRender(const TextPayload::Pointer& payload, RenderArgs* args) { + return payload->render(args); +} } \ No newline at end of file diff --git a/libraries/entities-renderer/src/RenderableTextEntityItem.h b/libraries/entities-renderer/src/RenderableTextEntityItem.h index e0306375a0..04b1c7a851 100644 --- a/libraries/entities-renderer/src/RenderableTextEntityItem.h +++ b/libraries/entities-renderer/src/RenderableTextEntityItem.h @@ -19,27 +19,31 @@ class TextRenderer3D; namespace render { namespace entities { +class TextPayload; + class TextEntityRenderer : public TypedEntityRenderer { using Parent = TypedEntityRenderer; using Pointer = std::shared_ptr; public: TextEntityRenderer(const EntityItemPointer& entity); - ~TextEntityRenderer(); QSizeF textSize(const QString& text) const; protected: bool isTransparent() const override; + bool isTextTransparent() const; Item::Bound getBound() override; ShapeKey getShapeKey() override; + void onAddToSceneTyped(const TypedEntityPointer& entity) override; + void onRemoveFromSceneTyped(const TypedEntityPointer& entity) override; + private: virtual bool needsRenderUpdateFromTypedEntity(const TypedEntityPointer& entity) const override; virtual void doRenderUpdateSynchronousTyped(const ScenePointer& scene, Transaction& transaction, const TypedEntityPointer& entity) override; virtual void doRenderUpdateAsynchronousTyped(const TypedEntityPointer& entity) override; virtual void doRender(RenderArgs* args) override; - int _geometryID{ 0 }; std::shared_ptr _textRenderer; PulsePropertyGroup _pulseProperties; @@ -58,8 +62,42 @@ private: BillboardMode _billboardMode; glm::vec3 _dimensions; + + std::shared_ptr _textPayload; + render::ItemID _textRenderID; + void updateTextRenderItem() const; + + friend class render::entities::TextPayload; +}; + +class TextPayload { +public: + TextPayload() = default; + TextPayload(const QUuid& entityID, const std::weak_ptr& textRenderer); + ~TextPayload(); + + typedef render::Payload Payload; + typedef Payload::DataPointer Pointer; + + ItemKey getKey() const; + Item::Bound getBound() const; + ShapeKey getShapeKey() const; + void render(RenderArgs* args); + +protected: + QUuid _entityID; + std::weak_ptr _textRenderer; + + int _geometryID { 0 }; }; } } +namespace render { + template <> const ItemKey payloadGetKey(const entities::TextPayload::Pointer& payload); + template <> const Item::Bound payloadGetBound(const entities::TextPayload::Pointer& payload); + template <> const ShapeKey shapeGetShapeKey(const entities::TextPayload::Pointer& payload); + template <> void payloadRender(const entities::TextPayload::Pointer& payload, RenderArgs* args); +} + #endif // hifi_RenderableTextEntityItem_h From a5b92a6c7b67fee641b25ebd0453a8f3f415328a Mon Sep 17 00:00:00 2001 From: SamGondelman Date: Fri, 28 Jun 2019 14:24:33 -0700 Subject: [PATCH 20/26] fix layered rendering of group culled sub items --- .../src/RenderableTextEntityItem.cpp | 21 ++++++++++++++----- .../src/RenderableTextEntityItem.h | 2 ++ .../src/render/RenderFetchCullSortTask.cpp | 2 +- 3 files changed, 19 insertions(+), 6 deletions(-) diff --git a/libraries/entities-renderer/src/RenderableTextEntityItem.cpp b/libraries/entities-renderer/src/RenderableTextEntityItem.cpp index 381edd8731..c9d6df8c8f 100644 --- a/libraries/entities-renderer/src/RenderableTextEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableTextEntityItem.cpp @@ -54,6 +54,10 @@ Item::Bound TextEntityRenderer::getBound() { return bound; } +ItemKey TextEntityRenderer::getKey() { + return ItemKey::Builder(Parent::getKey()).withMetaCullGroup(); +} + ShapeKey TextEntityRenderer::getShapeKey() { auto builder = render::ShapeKey::Builder(); if (isTransparent()) { @@ -65,6 +69,15 @@ ShapeKey TextEntityRenderer::getShapeKey() { return builder.build(); } +uint32_t TextEntityRenderer::metaFetchMetaSubItems(ItemIDs& subItems) { + auto parentSubs = Parent::metaFetchMetaSubItems(subItems); + if (Item::isValidID(_textRenderID)) { + subItems.emplace_back(_textRenderID); + return parentSubs + 1; + } + return parentSubs; +} + bool TextEntityRenderer::needsRenderUpdateFromTypedEntity(const TypedEntityPointer& entity) const { if (_text != entity->getText()) { return true; @@ -249,14 +262,12 @@ ItemKey entities::TextPayload::getKey() const { auto textRenderable = std::static_pointer_cast(renderable); ItemKey::Builder key; // Similar to EntityRenderer::getKey() - // FIXME: should be withSubMetaCulled and not meta, but there's a bug in the layer rendering that won't render it in that case - // (the TextEntityRenderer should also be withMetaCullGroup) if (textRenderable->isTextTransparent()) { - key = ItemKey::Builder::transparentShape().withTypeMeta().withTagBits(textRenderable->getTagMask()).withLayer(textRenderable->getHifiRenderLayer()); + key = ItemKey::Builder::transparentShape().withSubMetaCulled().withTagBits(textRenderable->getTagMask()).withLayer(textRenderable->getHifiRenderLayer()); } else if (textRenderable->_canCastShadow) { - key = ItemKey::Builder::opaqueShape().withTypeMeta().withTagBits(textRenderable->getTagMask()).withShadowCaster().withLayer(textRenderable->getHifiRenderLayer()); + key = ItemKey::Builder::opaqueShape().withSubMetaCulled().withTagBits(textRenderable->getTagMask()).withShadowCaster().withLayer(textRenderable->getHifiRenderLayer()); } else { - key = ItemKey::Builder::opaqueShape().withTypeMeta().withTagBits(textRenderable->getTagMask()).withLayer(textRenderable->getHifiRenderLayer()); + key = ItemKey::Builder::opaqueShape().withSubMetaCulled().withTagBits(textRenderable->getTagMask()).withLayer(textRenderable->getHifiRenderLayer()); } if (!textRenderable->_visible) { diff --git a/libraries/entities-renderer/src/RenderableTextEntityItem.h b/libraries/entities-renderer/src/RenderableTextEntityItem.h index 04b1c7a851..d5e36a4622 100644 --- a/libraries/entities-renderer/src/RenderableTextEntityItem.h +++ b/libraries/entities-renderer/src/RenderableTextEntityItem.h @@ -34,6 +34,8 @@ protected: bool isTextTransparent() const; Item::Bound getBound() override; ShapeKey getShapeKey() override; + ItemKey getKey() override; + virtual uint32_t metaFetchMetaSubItems(ItemIDs& subItems) override; void onAddToSceneTyped(const TypedEntityPointer& entity) override; void onRemoveFromSceneTyped(const TypedEntityPointer& entity) override; diff --git a/libraries/render/src/render/RenderFetchCullSortTask.cpp b/libraries/render/src/render/RenderFetchCullSortTask.cpp index d82fdef258..6b1a57ed88 100644 --- a/libraries/render/src/render/RenderFetchCullSortTask.cpp +++ b/libraries/render/src/render/RenderFetchCullSortTask.cpp @@ -30,7 +30,7 @@ void RenderFetchCullSortTask::build(JobModel& task, const Varying& input, Varyin const auto culledSpatialSelection = task.addJob("CullSceneSelection", cullInputs, cullFunctor, RenderDetails::ITEM); // Layered objects are not culled - const ItemFilter layeredFilter = ItemFilter::Builder().withVisible().withoutSubMetaCulled().withTagBits(tagBits, tagMask); + const ItemFilter layeredFilter = ItemFilter::Builder::visibleWorldItems().withTagBits(tagBits, tagMask); const auto nonspatialFilter = render::Varying(layeredFilter); const auto nonspatialSelection = task.addJob("FetchLayeredSelection", nonspatialFilter); From d1470d3323f0b4cca78b61aaeb3291bdec37cea1 Mon Sep 17 00:00:00 2001 From: Preston Bezos Date: Fri, 28 Jun 2019 14:33:03 -0700 Subject: [PATCH 21/26] readded ctrl+n and ctrl+b as shortcuts with a default script --- .../scripting/WindowScriptingInterface.cpp | 10 ++++++ .../src/scripting/WindowScriptingInterface.h | 6 ++++ scripts/defaultScripts.js | 3 +- .../keyboardShortcuts/keyboardShortcuts.js | 32 +++++++++++++++++++ 4 files changed, 50 insertions(+), 1 deletion(-) create mode 100644 scripts/system/keyboardShortcuts/keyboardShortcuts.js diff --git a/interface/src/scripting/WindowScriptingInterface.cpp b/interface/src/scripting/WindowScriptingInterface.cpp index eb967dde89..80c0479bd7 100644 --- a/interface/src/scripting/WindowScriptingInterface.cpp +++ b/interface/src/scripting/WindowScriptingInterface.cpp @@ -638,3 +638,13 @@ void WindowScriptingInterface::setActiveDisplayPlugin(int index) { auto name = PluginManager::getInstance()->getDisplayPlugins().at(index)->getName(); qApp->setActiveDisplayPlugin(name); } + +void WindowScriptingInterface::openWebBrowser() { + if (QThread::currentThread() != thread()) { + QMetaObject::invokeMethod(this, "openWebBrowser", Qt::QueuedConnection); + return; + } + + auto offscreenUi = DependencyManager::get(); + offscreenUi->load("Browser.qml"); +} diff --git a/interface/src/scripting/WindowScriptingInterface.h b/interface/src/scripting/WindowScriptingInterface.h index 0c2b494b0b..d05145acb2 100644 --- a/interface/src/scripting/WindowScriptingInterface.h +++ b/interface/src/scripting/WindowScriptingInterface.h @@ -608,6 +608,12 @@ public slots: */ void setActiveDisplayPlugin(int index); + /**jsdoc + * Opens `Browser.qml` in a pop-up window. + * @function Window.openWebBrowser + */ + void openWebBrowser(); + private slots: void onWindowGeometryChanged(const QRect& geometry); diff --git a/scripts/defaultScripts.js b/scripts/defaultScripts.js index e392680df9..24b62b6653 100644 --- a/scripts/defaultScripts.js +++ b/scripts/defaultScripts.js @@ -33,7 +33,8 @@ var DEFAULT_SCRIPTS_COMBINED = [ "system/tablet-ui/tabletUI.js", "system/emote.js", "system/miniTablet.js", - "system/audioMuteOverlay.js" + "system/audioMuteOverlay.js", + "system/keyboardShortcuts/keyboardShortcuts.js" ]; var DEFAULT_SCRIPTS_SEPARATE = [ "system/controllers/controllerScripts.js", diff --git a/scripts/system/keyboardShortcuts/keyboardShortcuts.js b/scripts/system/keyboardShortcuts/keyboardShortcuts.js new file mode 100644 index 0000000000..9cab11ef42 --- /dev/null +++ b/scripts/system/keyboardShortcuts/keyboardShortcuts.js @@ -0,0 +1,32 @@ +"use strict"; + +// +// keyboardShortcuts.js +// scripts/system/keyboardShortcuts +// +// Created by Preston Bezos on 06/28/2019 +// Copyright 2019 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 +// + +(function () { // BEGIN LOCAL_SCOPE + function keyPressEvent(event) { + if (event.text.toUpperCase() === "B" && event.isControl) { + console.log("TEST B"); + Window.openWebBrowser(); + } + + else if (event.text.toUpperCase() === "N" && event.isControl) { + Users.toggleIgnoreRadius(); + } + } + + function scriptEnding() { + Controller.keyPressEvent.disconnect(keyPressEvent); + } + + Controller.keyPressEvent.connect(keyPressEvent); + Script.scriptEnding.connect(scriptEnding); +}()); // END LOCAL_SCOPE From 09830dd40c7ba97560474c8a5e24939d8005a06d Mon Sep 17 00:00:00 2001 From: Preston Bezos Date: Fri, 28 Jun 2019 14:41:07 -0700 Subject: [PATCH 22/26] removed white space --- scripts/system/keyboardShortcuts/keyboardShortcuts.js | 1 - 1 file changed, 1 deletion(-) diff --git a/scripts/system/keyboardShortcuts/keyboardShortcuts.js b/scripts/system/keyboardShortcuts/keyboardShortcuts.js index 9cab11ef42..cbc5202d39 100644 --- a/scripts/system/keyboardShortcuts/keyboardShortcuts.js +++ b/scripts/system/keyboardShortcuts/keyboardShortcuts.js @@ -17,7 +17,6 @@ console.log("TEST B"); Window.openWebBrowser(); } - else if (event.text.toUpperCase() === "N" && event.isControl) { Users.toggleIgnoreRadius(); } From b9deb7bb580172055f838be4cf91718523659b5c Mon Sep 17 00:00:00 2001 From: Preston Bezos Date: Fri, 28 Jun 2019 14:42:48 -0700 Subject: [PATCH 23/26] formatting --- scripts/system/keyboardShortcuts/keyboardShortcuts.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/scripts/system/keyboardShortcuts/keyboardShortcuts.js b/scripts/system/keyboardShortcuts/keyboardShortcuts.js index cbc5202d39..1021f54662 100644 --- a/scripts/system/keyboardShortcuts/keyboardShortcuts.js +++ b/scripts/system/keyboardShortcuts/keyboardShortcuts.js @@ -16,8 +16,7 @@ if (event.text.toUpperCase() === "B" && event.isControl) { console.log("TEST B"); Window.openWebBrowser(); - } - else if (event.text.toUpperCase() === "N" && event.isControl) { + } else if (event.text.toUpperCase() === "N" && event.isControl) { Users.toggleIgnoreRadius(); } } From 1315677aec11887da409b19c783db17d9378cc7b Mon Sep 17 00:00:00 2001 From: Preston Bezos Date: Fri, 28 Jun 2019 15:02:33 -0700 Subject: [PATCH 24/26] fixed doc and removed log spam --- interface/src/scripting/WindowScriptingInterface.h | 2 +- scripts/system/keyboardShortcuts/keyboardShortcuts.js | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/interface/src/scripting/WindowScriptingInterface.h b/interface/src/scripting/WindowScriptingInterface.h index d05145acb2..eab1c65ebb 100644 --- a/interface/src/scripting/WindowScriptingInterface.h +++ b/interface/src/scripting/WindowScriptingInterface.h @@ -609,7 +609,7 @@ public slots: void setActiveDisplayPlugin(int index); /**jsdoc - * Opens `Browser.qml` in a pop-up window. + * Opens a web browser in a pop-up window. * @function Window.openWebBrowser */ void openWebBrowser(); diff --git a/scripts/system/keyboardShortcuts/keyboardShortcuts.js b/scripts/system/keyboardShortcuts/keyboardShortcuts.js index 1021f54662..cf3927ac2d 100644 --- a/scripts/system/keyboardShortcuts/keyboardShortcuts.js +++ b/scripts/system/keyboardShortcuts/keyboardShortcuts.js @@ -14,7 +14,6 @@ (function () { // BEGIN LOCAL_SCOPE function keyPressEvent(event) { if (event.text.toUpperCase() === "B" && event.isControl) { - console.log("TEST B"); Window.openWebBrowser(); } else if (event.text.toUpperCase() === "N" && event.isControl) { Users.toggleIgnoreRadius(); From e2bf3d7138d0aa4b698e34ac36efa94f1e7f6fde Mon Sep 17 00:00:00 2001 From: Sam Gondelman Date: Fri, 28 Jun 2019 15:11:22 -0700 Subject: [PATCH 25/26] remove unused constant --- libraries/entities-renderer/src/RenderableTextEntityItem.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/libraries/entities-renderer/src/RenderableTextEntityItem.cpp b/libraries/entities-renderer/src/RenderableTextEntityItem.cpp index c9d6df8c8f..d871df78d5 100644 --- a/libraries/entities-renderer/src/RenderableTextEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableTextEntityItem.cpp @@ -350,7 +350,6 @@ void entities::TextPayload::render(RenderArgs* args) { modelTransform.setRotation(EntityItem::getBillboardRotation(modelTransform.getTranslation(), modelTransform.getRotation(), billboardMode, args->getViewFrustum().getPosition())); float scale = lineHeight / textRenderer->getFontSize(); - const float TEXT_ENTITY_ITEM_FIXED_DEPTH = 0.01f; modelTransform.postTranslate(glm::vec3(-0.5, 0.5, 1.0f + EPSILON / dimensions.z)); modelTransform.setScale(scale); batch.setModelTransform(modelTransform); @@ -384,4 +383,4 @@ template <> const ShapeKey shapeGetShapeKey(const TextPayload::Pointer& payload) template <> void payloadRender(const TextPayload::Pointer& payload, RenderArgs* args) { return payload->render(args); } -} \ No newline at end of file +} From ef674a5934ab6c36bca7e366b7832113f94fcd49 Mon Sep 17 00:00:00 2001 From: Preston Bezos Date: Fri, 28 Jun 2019 15:23:50 -0700 Subject: [PATCH 26/26] removed permission for qml to access webcam and mic --- interface/resources/qml/+webengine/BrowserWebView.qml | 10 ---------- interface/resources/qml/+webengine/TabletBrowser.qml | 2 +- .../qml/controls/+webengine/FlickableWebViewCore.qml | 2 +- .../qml/controlsUit/+webengine/BaseWebView.qml | 4 ++++ 4 files changed, 6 insertions(+), 12 deletions(-) diff --git a/interface/resources/qml/+webengine/BrowserWebView.qml b/interface/resources/qml/+webengine/BrowserWebView.qml index 5c5cf2cfb9..137531f517 100644 --- a/interface/resources/qml/+webengine/BrowserWebView.qml +++ b/interface/resources/qml/+webengine/BrowserWebView.qml @@ -29,16 +29,6 @@ WebView { userScripts: [ createGlobalEventBridge, raiseAndLowerKeyboard ] - onFeaturePermissionRequested: { - if (feature == 2) { // QWebEnginePage::MediaAudioCapture - grantFeaturePermission(securityOrigin, feature, true); - } else { - permissionsBar.securityOrigin = securityOrigin; - permissionsBar.feature = feature; - parentRoot.showPermissionsBar(); - } - } - onLoadingChanged: { if (loadRequest.status === WebEngineView.LoadSucceededStatus) { addressBar.text = loadRequest.url diff --git a/interface/resources/qml/+webengine/TabletBrowser.qml b/interface/resources/qml/+webengine/TabletBrowser.qml index 720a904231..3bb2c17ba6 100644 --- a/interface/resources/qml/+webengine/TabletBrowser.qml +++ b/interface/resources/qml/+webengine/TabletBrowser.qml @@ -84,7 +84,7 @@ Item { } onFeaturePermissionRequested: { - grantFeaturePermission(securityOrigin, feature, true); + grantFeaturePermission(securityOrigin, feature, false); } onLoadingChanged: { diff --git a/interface/resources/qml/controls/+webengine/FlickableWebViewCore.qml b/interface/resources/qml/controls/+webengine/FlickableWebViewCore.qml index 823d0107a2..56eecf3f46 100644 --- a/interface/resources/qml/controls/+webengine/FlickableWebViewCore.qml +++ b/interface/resources/qml/controls/+webengine/FlickableWebViewCore.qml @@ -141,7 +141,7 @@ Item { } onFeaturePermissionRequested: { - grantFeaturePermission(securityOrigin, feature, true); + grantFeaturePermission(securityOrigin, feature, false); } //disable popup diff --git a/interface/resources/qml/controlsUit/+webengine/BaseWebView.qml b/interface/resources/qml/controlsUit/+webengine/BaseWebView.qml index fdd9c12220..faf80b2b11 100644 --- a/interface/resources/qml/controlsUit/+webengine/BaseWebView.qml +++ b/interface/resources/qml/controlsUit/+webengine/BaseWebView.qml @@ -35,4 +35,8 @@ WebEngineView { } WebSpinner { } + + onFeaturePermissionRequested: { + grantFeaturePermission(securityOrigin, feature, false); + } }