From 5c9a88868d65aff271ebc0d65521e7e1f16df934 Mon Sep 17 00:00:00 2001 From: Dante Ruiz Date: Tue, 11 Sep 2018 12:01:55 -0700 Subject: [PATCH 1/3] first round of requested changes --- interface/src/Application.cpp | 7 +- .../src/octree/OctreePacketProcessor.cpp | 4 - interface/src/octree/OctreePacketProcessor.h | 1 - interface/src/octree/SafeLanding.cpp | 89 +++++++++---------- interface/src/octree/SafeLanding.h | 6 +- libraries/audio-client/src/AudioClient.cpp | 2 +- libraries/audio-client/src/AudioClient.h | 4 +- 7 files changed, 49 insertions(+), 64 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index de0aea3bc2..d2079c4b4d 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -1387,7 +1387,6 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo }); connect(this, &Application::activeDisplayPluginChanged, reinterpret_cast(audioScriptingInterface.data()), &scripting::Audio::onContextChanged); - connect(this, &Application::interstitialModeChanged, audioIO, &AudioClient::setInterstitialStatus); } // Create the rendering engine. This can be slow on some machines due to lots of @@ -3500,6 +3499,9 @@ bool Application::isInterstitialMode() const { void Application::setIsInterstitialMode(bool interstitialMode) { if (_interstitialMode != interstitialMode) { _interstitialMode = interstitialMode; + + auto audioClient = DependencyManager::get(); + audioClient->setAudioPaused(_interstitialMode); emit interstitialModeChanged(_interstitialMode); } } @@ -5581,8 +5583,7 @@ 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(); - bool renderReady = _octreeProcessor.isEntitiesRenderReady(); - if (isServerlessMode() || (_octreeProcessor.isLoadSequenceComplete() && renderReady)) { + if (isServerlessMode() || _octreeProcessor.isLoadSequenceComplete()) { // we've received a new full-scene octree stats packet, or it's been long enough to try again anyway _lastPhysicsCheckTime = now; _fullSceneCounterAtLastPhysicsCheck = _fullSceneReceivedCounter; diff --git a/interface/src/octree/OctreePacketProcessor.cpp b/interface/src/octree/OctreePacketProcessor.cpp index e670153a77..1abc755057 100644 --- a/interface/src/octree/OctreePacketProcessor.cpp +++ b/interface/src/octree/OctreePacketProcessor.cpp @@ -138,10 +138,6 @@ bool OctreePacketProcessor::isLoadSequenceComplete() const { return _safeLanding->isLoadSequenceComplete(); } -bool OctreePacketProcessor::isEntitiesRenderReady() const { - return _safeLanding->entitiesRenderReady(); -} - float OctreePacketProcessor::domainLoadingProgress() { return _safeLanding->loadingProgressPercentage(); } diff --git a/interface/src/octree/OctreePacketProcessor.h b/interface/src/octree/OctreePacketProcessor.h index 71e22bf240..0460fc7da0 100644 --- a/interface/src/octree/OctreePacketProcessor.h +++ b/interface/src/octree/OctreePacketProcessor.h @@ -27,7 +27,6 @@ public: void startEntitySequence(); bool isLoadSequenceComplete() const; - bool isEntitiesRenderReady() const; float domainLoadingProgress(); signals: diff --git a/interface/src/octree/SafeLanding.cpp b/interface/src/octree/SafeLanding.cpp index 6b7a0f582c..27674920d7 100644 --- a/interface/src/octree/SafeLanding.cpp +++ b/interface/src/octree/SafeLanding.cpp @@ -37,7 +37,6 @@ void SafeLanding::startEntitySequence(QSharedPointer entityT if (entityTree) { Locker lock(_lock); _entityTree = entityTree; - _trackedEntitiesRenderStatus.clear(); _trackedEntities.clear(); _trackingEntities = true; connect(std::const_pointer_cast(_entityTree).get(), @@ -67,35 +66,19 @@ void SafeLanding::addTrackedEntity(const EntityItemID& entityID) { Locker lock(_lock); EntityItemPointer entity = _entityTree->findEntityByID(entityID); - if (entity && !entity->getCollisionless()) { - const auto& entityType = entity->getType(); - if (entityType == EntityTypes::Model) { - ModelEntityItem * modelEntity = std::dynamic_pointer_cast(entity).get(); - static const std::set downloadedCollisionTypes - { SHAPE_TYPE_COMPOUND, SHAPE_TYPE_SIMPLE_COMPOUND, SHAPE_TYPE_STATIC_MESH, SHAPE_TYPE_SIMPLE_HULL }; - bool hasAABox; - entity->getAABox(hasAABox); - if (hasAABox && downloadedCollisionTypes.count(modelEntity->getShapeType()) != 0) { - // Only track entities with downloaded collision bodies. - _trackedEntities.emplace(entityID, entity); - qCDebug(interfaceapp) << "Safe Landing: Tracking entity " << entity->getItemName(); - } - } - } - - _trackedEntitiesRenderStatus.emplace(entityID, entity); - float trackedEntityCount = (float)_trackedEntitiesRenderStatus.size(); + _trackedEntities.emplace(entityID, entity); + int trackedEntityCount = _trackedEntities.size(); if (trackedEntityCount > _maxTrackedEntityCount) { _maxTrackedEntityCount = trackedEntityCount; } + qCDebug(interfaceapp) << "Safe Landing: Tracking entity " << entity->getItemName(); } } void SafeLanding::deleteTrackedEntity(const EntityItemID& entityID) { Locker lock(_lock); _trackedEntities.erase(entityID); - _trackedEntitiesRenderStatus.erase(entityID); } void SafeLanding::setCompletionSequenceNumbers(int first, int last) { @@ -114,7 +97,7 @@ void SafeLanding::noteReceivedsequenceNumber(int sequenceNumber) { } bool SafeLanding::isLoadSequenceComplete() { - if (isEntityPhysicsComplete() && isSequenceNumbersComplete()) { + if (isEntityLoadingComplete() && isSequenceNumbersComplete()) { Locker lock(_lock); _trackedEntities.clear(); _initialStart = INVALID_SEQUENCE; @@ -130,8 +113,8 @@ bool SafeLanding::isLoadSequenceComplete() { float SafeLanding::loadingProgressPercentage() { Locker lock(_lock); if (_maxTrackedEntityCount > 0) { - float trackedEntityCount = (float)_trackedEntitiesRenderStatus.size(); - return ((_maxTrackedEntityCount - trackedEntityCount) / _maxTrackedEntityCount); + int trackedEntityCount = _trackedEntities.size(); + return ((_maxTrackedEntityCount - trackedEntityCount) / (float)_maxTrackedEntityCount); } return 0.0f; @@ -155,38 +138,46 @@ bool SafeLanding::isSequenceNumbersComplete() { return false; } -bool SafeLanding::isEntityPhysicsComplete() { - Locker lock(_lock); - for (auto entityMapIter = _trackedEntities.begin(); entityMapIter != _trackedEntities.end(); ++entityMapIter) { - auto entity = entityMapIter->second; - if (!entity->shouldBePhysical() || entity->isReadyToComputeShape()) { - entityMapIter = _trackedEntities.erase(entityMapIter); - if (entityMapIter == _trackedEntities.end()) { - break; +bool isEntityPhysicsReady(const EntityItemPointer& entity) { + if (entity && !entity->getCollisionless()) { + const auto& entityType = entity->getType(); + if (entityType == EntityTypes::Model) { + ModelEntityItem * modelEntity = std::dynamic_pointer_cast(entity).get(); + static const std::set downloadedCollisionTypes + { SHAPE_TYPE_COMPOUND, SHAPE_TYPE_SIMPLE_COMPOUND, SHAPE_TYPE_STATIC_MESH, SHAPE_TYPE_SIMPLE_HULL }; + bool hasAABox; + entity->getAABox(hasAABox); + if (hasAABox && downloadedCollisionTypes.count(modelEntity->getShapeType()) != 0) { + return entity->isReadyToComputeShape(); + qCDebug(interfaceapp) << "Safe Landing: Tracking entity " << entity->getItemName(); } } } + + return true; +} + +bool SafeLanding::isEntityLoadingComplete() { + Locker lock(_lock); + auto entityTree = qApp->getEntities(); + auto entityMapIter = _trackedEntities.begin(); + + while (entityMapIter != _trackedEntities.end()) { + auto entity = entityMapIter->second; + bool isVisuallyReady = (entity->isVisuallyReady() || !entityTree->renderableForEntityId(entityMapIter->first)); + if (isEntityPhysicsReady(entity) && isVisuallyReady) { + entityMapIter = _trackedEntities.erase(entityMapIter); + } else { + if (!isVisuallyReady) { + entity->requestRenderUpdate(); + } + + entityMapIter++; + } + } return _trackedEntities.empty(); } -bool SafeLanding::entitiesRenderReady() { - Locker lock(_lock); - auto entityTree = qApp->getEntities(); - for (auto entityMapIter = _trackedEntitiesRenderStatus.begin(); entityMapIter != _trackedEntitiesRenderStatus.end(); ++entityMapIter) { - auto entity = entityMapIter->second; - bool visuallyReady = entity->isVisuallyReady(); - if (visuallyReady || !entityTree->renderableForEntityId(entityMapIter->first)) { - entityMapIter = _trackedEntitiesRenderStatus.erase(entityMapIter); - if (entityMapIter == _trackedEntitiesRenderStatus.end()) { - break; - } - } else { - entity->requestRenderUpdate(); - } - } - return _trackedEntitiesRenderStatus.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 611b75ab79..317e4587c7 100644 --- a/interface/src/octree/SafeLanding.h +++ b/interface/src/octree/SafeLanding.h @@ -30,7 +30,6 @@ public: void setCompletionSequenceNumbers(int first, int last); // 'last' exclusive. void noteReceivedsequenceNumber(int sequenceNumber); bool isLoadSequenceComplete(); - bool entitiesRenderReady(); float loadingProgressPercentage(); private slots: @@ -40,7 +39,7 @@ private slots: private: bool isSequenceNumbersComplete(); void debugDumpSequenceIDs() const; - bool isEntityPhysicsComplete(); + bool isEntityLoadingComplete(); std::mutex _lock; using Locker = std::lock_guard; @@ -48,12 +47,11 @@ private: EntityTreePointer _entityTree; using EntityMap = std::map; EntityMap _trackedEntities; - EntityMap _trackedEntitiesRenderStatus; static constexpr int INVALID_SEQUENCE = -1; int _initialStart { INVALID_SEQUENCE }; int _initialEnd { INVALID_SEQUENCE }; - float _maxTrackedEntityCount { 0.0f }; + int _maxTrackedEntityCount { 0 }; struct SequenceLessThan { bool operator()(const int& a, const int& b) const; diff --git a/libraries/audio-client/src/AudioClient.cpp b/libraries/audio-client/src/AudioClient.cpp index 7af8a05f25..caf57cbc6e 100644 --- a/libraries/audio-client/src/AudioClient.cpp +++ b/libraries/audio-client/src/AudioClient.cpp @@ -1024,7 +1024,7 @@ void AudioClient::handleLocalEchoAndReverb(QByteArray& inputByteArray) { } void AudioClient::handleAudioInput(QByteArray& audioBuffer) { - if (!_interstitialMode) { + if (!_audioPaused) { if (_muted) { _lastInputLoudness = 0.0f; _timeSinceLastClip = 0.0f; diff --git a/libraries/audio-client/src/AudioClient.h b/libraries/audio-client/src/AudioClient.h index 90860798b3..099a692e26 100644 --- a/libraries/audio-client/src/AudioClient.h +++ b/libraries/audio-client/src/AudioClient.h @@ -162,6 +162,7 @@ public: bool startRecording(const QString& filename); void stopRecording(); + void setAudioPaused(bool pause) { _audioPaused = pause; } #ifdef Q_OS_WIN @@ -187,7 +188,6 @@ public slots: void handleRecordedAudioInput(const QByteArray& audio); void reset(); void audioMixerKilled(); - void setInterstitialStatus(bool interstitialMode) { _interstitialMode = interstitialMode; } void setMuted(bool muted, bool emitSignal = true); bool isMuted() { return _muted; } @@ -417,7 +417,7 @@ private: QVector _activeLocalAudioInjectors; bool _isPlayingBackRecording { false }; - bool _interstitialMode { true }; + bool _audioPaused { false }; CodecPluginPointer _codec; QString _selectedCodecName; From cc2c208b12f25c7d8ccd22cc91ced86d9f1f953e Mon Sep 17 00:00:00 2001 From: Dante Ruiz Date: Tue, 11 Sep 2018 12:12:31 -0700 Subject: [PATCH 2/3] fix small issue --- interface/src/octree/SafeLanding.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/interface/src/octree/SafeLanding.cpp b/interface/src/octree/SafeLanding.cpp index 2bbda7f5d5..f73a13f346 100644 --- a/interface/src/octree/SafeLanding.cpp +++ b/interface/src/octree/SafeLanding.cpp @@ -148,7 +148,6 @@ bool isEntityPhysicsReady(const EntityItemPointer& entity) { entity->getAABox(hasAABox); if (hasAABox && downloadedCollisionTypes.count(modelEntity->getShapeType()) != 0) { return entity->isReadyToComputeShape(); - qCDebug(interfaceapp) << "Safe Landing: Tracking entity " << entity->getItemName(); } } } From b665dbe13e00793de11a1b87153027b0bdccc706 Mon Sep 17 00:00:00 2001 From: Dante Ruiz Date: Tue, 11 Sep 2018 14:18:12 -0700 Subject: [PATCH 3/3] finished requested changes --- interface/src/Application.cpp | 32 ++++++---------------- interface/src/avatar/AvatarManager.cpp | 12 +++++++- interface/src/avatar/AvatarManager.h | 3 ++ libraries/audio-client/src/AudioClient.cpp | 10 +++++++ libraries/audio-client/src/AudioClient.h | 2 +- scripts/system/interstitialPage.js | 2 +- 6 files changed, 34 insertions(+), 27 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 8a68a606fc..ca27b29b92 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -2294,25 +2294,6 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo // Preload Tablet sounds DependencyManager::get()->preloadSounds(); - connect(this, &Application::interstitialModeChanged, this, [this] (bool interstitialMode) { - if (!interstitialMode) { - DependencyManager::get()->negotiateAudioFormat(); - _queryExpiry = SteadyClock::now(); - if (_avatarOverrideUrl.isValid()) { - getMyAvatar()->useFullAvatarURL(_avatarOverrideUrl); - } - - if (getMyAvatar()->getFullAvatarURLFromPreferences() != getMyAvatar()->getSkeletonModelURL()) { - getMyAvatar()->resetFullAvatarURL(); - } - getMyAvatar()->markIdentityDataChanged(); - getMyAvatar()->resetLastSent(); - - // transmit a "sendAll" packet to the AvatarMixer we just connected to. - getMyAvatar()->sendAvatarDataPacket(true); - } - }); - _pendingIdleEvent = false; _pendingRenderEvent = false; @@ -3496,8 +3477,9 @@ void Application::setIsInterstitialMode(bool interstitialMode) { if (_interstitialMode != interstitialMode) { _interstitialMode = interstitialMode; - auto audioClient = DependencyManager::get(); - audioClient->setAudioPaused(_interstitialMode); + DependencyManager::get()->setAudioPaused(_interstitialMode); + DependencyManager::get()->setMyAvatarDataPacketsPaused(_interstitialMode); + emit interstitialModeChanged(_interstitialMode); } } @@ -6477,7 +6459,7 @@ void Application::nodeActivated(SharedNodePointer node) { DependencyManager::get()->negotiateAudioFormat(); } - if (node->getType() == NodeType::AvatarMixer && !isInterstitialMode()) { + if (node->getType() == NodeType::AvatarMixer) { _queryExpiry = SteadyClock::now(); // new avatar mixer, send off our identity packet on next update loop @@ -6493,8 +6475,10 @@ void Application::nodeActivated(SharedNodePointer node) { getMyAvatar()->markIdentityDataChanged(); getMyAvatar()->resetLastSent(); - // transmit a "sendAll" packet to the AvatarMixer we just connected to. - getMyAvatar()->sendAvatarDataPacket(true); + if (!isInterstitialMode()) { + // transmit a "sendAll" packet to the AvatarMixer we just connected to. + getMyAvatar()->sendAvatarDataPacket(true); + } } } diff --git a/interface/src/avatar/AvatarManager.cpp b/interface/src/avatar/AvatarManager.cpp index 2c758dfc69..b9e30a38eb 100644 --- a/interface/src/avatar/AvatarManager.cpp +++ b/interface/src/avatar/AvatarManager.cpp @@ -137,7 +137,7 @@ void AvatarManager::updateMyAvatar(float deltaTime) { quint64 now = usecTimestampNow(); quint64 dt = now - _lastSendAvatarDataTime; - if (dt > MIN_TIME_BETWEEN_MY_AVATAR_DATA_SENDS && !qApp->isInterstitialMode()) { + if (dt > MIN_TIME_BETWEEN_MY_AVATAR_DATA_SENDS && !_myAvatarDataPacketsPaused) { // send head/hand data to the avatar mixer and voxel server PerformanceTimer perfTimer("send"); _myAvatar->sendAvatarDataPacket(); @@ -155,6 +155,16 @@ float AvatarManager::getAvatarDataRate(const QUuid& sessionID, const QString& ra return avatar ? avatar->getDataRate(rateName) : 0.0f; } +void AvatarManager::setMyAvatarDataPacketsPaused(bool pause) { + if (_myAvatarDataPacketsPaused != pause) { + _myAvatarDataPacketsPaused = pause; + + if (!_myAvatarDataPacketsPaused) { + _myAvatar->sendAvatarDataPacket(true); + } + } +} + float AvatarManager::getAvatarUpdateRate(const QUuid& sessionID, const QString& rateName) const { auto avatar = getAvatarBySessionID(sessionID); return avatar ? avatar->getUpdateRate(rateName) : 0.0f; diff --git a/interface/src/avatar/AvatarManager.h b/interface/src/avatar/AvatarManager.h index bcdfc064bd..ea92389adc 100644 --- a/interface/src/avatar/AvatarManager.h +++ b/interface/src/avatar/AvatarManager.h @@ -91,6 +91,8 @@ public: void updateOtherAvatars(float deltaTime); void sendIdentityRequest(const QUuid& avatarID) const; + void setMyAvatarDataPacketsPaused(bool puase); + void postUpdate(float deltaTime, const render::ScenePointer& scene); void clearOtherAvatars(); @@ -219,6 +221,7 @@ private: int _numAvatarsNotUpdated { 0 }; float _avatarSimulationTime { 0.0f }; bool _shouldRender { true }; + bool _myAvatarDataPacketsPaused { false }; mutable int _identityRequestsSent { 0 }; mutable std::mutex _spaceLock; diff --git a/libraries/audio-client/src/AudioClient.cpp b/libraries/audio-client/src/AudioClient.cpp index caf57cbc6e..3a33eccc8a 100644 --- a/libraries/audio-client/src/AudioClient.cpp +++ b/libraries/audio-client/src/AudioClient.cpp @@ -305,6 +305,16 @@ void AudioClient::audioMixerKilled() { emit disconnected(); } +void AudioClient::setAudioPaused(bool pause) { + if (_audioPaused != pause) { + _audioPaused = pause; + + if (!_audioPaused) { + negotiateAudioFormat(); + } + } +} + QAudioDeviceInfo getNamedAudioDeviceForMode(QAudio::Mode mode, const QString& deviceName) { QAudioDeviceInfo result; foreach(QAudioDeviceInfo audioDevice, getAvailableDevices(mode)) { diff --git a/libraries/audio-client/src/AudioClient.h b/libraries/audio-client/src/AudioClient.h index 099a692e26..4640d7c045 100644 --- a/libraries/audio-client/src/AudioClient.h +++ b/libraries/audio-client/src/AudioClient.h @@ -162,7 +162,7 @@ public: bool startRecording(const QString& filename); void stopRecording(); - void setAudioPaused(bool pause) { _audioPaused = pause; } + void setAudioPaused(bool pause); #ifdef Q_OS_WIN diff --git a/scripts/system/interstitialPage.js b/scripts/system/interstitialPage.js index 1cc048ca99..dcce721cd9 100644 --- a/scripts/system/interstitialPage.js +++ b/scripts/system/interstitialPage.js @@ -305,7 +305,7 @@ } } - var THE_PLACE = "hifi://TheSpot-dev"; + var THE_PLACE = (HifiAbout.buildVersion === "dev") ? "hifi://TheSpot-dev": "hifi://TheSpot"; function clickedOnOverlay(overlayID, event) { if (loadingToTheSpotID === overlayID) { location.handleLookupString(THE_PLACE);