diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index c2a4088dcc..e3f2812c1f 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -3019,8 +3019,19 @@ void Application::init() { _entityClipboardRenderer.setTree(_entityClipboard); // Make sure any new sounds are loaded as soon as know about them. - connect(tree.get(), &EntityTree::newCollisionSoundURL, DependencyManager::get().data(), &SoundCache::getSound); - connect(getMyAvatar(), &MyAvatar::newCollisionSoundURL, DependencyManager::get().data(), &SoundCache::getSound); + connect(tree.get(), &EntityTree::newCollisionSoundURL, this, [this](QUrl newURL, EntityItemID id) { + EntityTreePointer tree = getEntities()->getTree(); + if (auto entity = tree->findEntityByEntityItemID(id)) { + auto sound = DependencyManager::get()->getSound(newURL); + entity->setCollisionSound(sound); + } + }, Qt::QueuedConnection); + connect(getMyAvatar(), &MyAvatar::newCollisionSoundURL, this, [this](QUrl newURL) { + if (auto avatar = getMyAvatar()) { + auto sound = DependencyManager::get()->getSound(newURL); + avatar->setCollisionSound(sound); + } + }, Qt::QueuedConnection); } void Application::updateLOD() const { diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp index f0e5f2f19e..f6caedb014 100644 --- a/interface/src/avatar/MyAvatar.cpp +++ b/interface/src/avatar/MyAvatar.cpp @@ -97,7 +97,6 @@ MyAvatar::MyAvatar(RigPointer rig) : _scriptedMotorTimescale(DEFAULT_SCRIPTED_MOTOR_TIMESCALE), _scriptedMotorFrame(SCRIPTED_MOTOR_CAMERA_FRAME), _motionBehaviors(AVATAR_MOTION_DEFAULTS), - _collisionSoundURL(""), _characterController(this), _lookAtTargetAvatar(), _shouldRender(true), @@ -1234,7 +1233,6 @@ void MyAvatar::clearScriptableSettings() { void MyAvatar::setCollisionSoundURL(const QString& url) { if (url != _collisionSoundURL) { _collisionSoundURL = url; - _collisionSound = DependencyManager::get()->getSound(_collisionSoundURL); emit newCollisionSoundURL(QUrl(_collisionSoundURL)); } diff --git a/interface/src/avatar/MyAvatar.h b/interface/src/avatar/MyAvatar.h index e72d12ef26..d25318c9fb 100644 --- a/interface/src/avatar/MyAvatar.h +++ b/interface/src/avatar/MyAvatar.h @@ -224,6 +224,7 @@ public: void setCollisionSoundURL(const QString& url); SharedSoundPointer getCollisionSound(); + void setCollisionSound(SharedSoundPointer sound) { _collisionSound = sound; } void clearScriptableSettings(); diff --git a/libraries/audio/src/AudioInjector.cpp b/libraries/audio/src/AudioInjector.cpp index 073753c525..878a4c627c 100644 --- a/libraries/audio/src/AudioInjector.cpp +++ b/libraries/audio/src/AudioInjector.cpp @@ -395,7 +395,7 @@ AudioInjector* AudioInjector::playSound(SharedSoundPointer sound, const float vo nInputFrames); Q_UNUSED(nOutputFrames); - return playSoundAndDelete(resampled, options, NULL); + return playSoundAndDelete(resampled, options, nullptr); } AudioInjector* AudioInjector::playSoundAndDelete(const QByteArray& buffer, const AudioInjectorOptions options, AbstractAudioInterface* localInterface) { diff --git a/libraries/entities-renderer/src/EntityTreeRenderer.cpp b/libraries/entities-renderer/src/EntityTreeRenderer.cpp index 013385a169..814faa8874 100644 --- a/libraries/entities-renderer/src/EntityTreeRenderer.cpp +++ b/libraries/entities-renderer/src/EntityTreeRenderer.cpp @@ -820,14 +820,14 @@ void EntityTreeRenderer::playEntityCollisionSound(const QUuid& myNodeID, EntityT return; } - QString collisionSoundURL; + SharedSoundPointer collisionSound; float mass = 1.0; // value doesn't get used, but set it so compiler is quiet AACube minAACube; bool success = false; _tree->withReadLock([&] { EntityItemPointer entity = entityTree->findEntityByEntityItemID(id); if (entity) { - collisionSoundURL = entity->getCollisionSoundURL(); + collisionSound = entity->getCollisionSound(); mass = entity->computeMass(); minAACube = entity->getMinimumAACube(success); } @@ -835,9 +835,10 @@ void EntityTreeRenderer::playEntityCollisionSound(const QUuid& myNodeID, EntityT if (!success) { return; } - if (collisionSoundURL.isEmpty()) { + if (!collisionSound) { return; } + const float COLLISION_PENETRATION_TO_VELOCITY = 50; // as a subsitute for RELATIVE entity->getVelocity() // The collision.penetration is a pretty good indicator of changed velocity AFTER the initial contact, // but that first contact depends on exactly where we hit in the physics step. @@ -859,11 +860,10 @@ void EntityTreeRenderer::playEntityCollisionSound(const QUuid& myNodeID, EntityT const float COLLISION_SOUND_COMPRESSION_RANGE = 1.0f; // This section could be removed when the value is 1, but let's see how it goes. const float volume = (energyFactorOfFull * COLLISION_SOUND_COMPRESSION_RANGE) + (1.0f - COLLISION_SOUND_COMPRESSION_RANGE); - // Shift the pitch down by ln(1 + (size / COLLISION_SIZE_FOR_STANDARD_PITCH)) / ln(2) const float COLLISION_SIZE_FOR_STANDARD_PITCH = 0.2f; const float stretchFactor = log(1.0f + (minAACube.getLargestDimension() / COLLISION_SIZE_FOR_STANDARD_PITCH)) / log(2); - AudioInjector::playSound(collisionSoundURL, volume, stretchFactor, position); + AudioInjector::playSound(collisionSound, volume, stretchFactor, position); } void EntityTreeRenderer::entityCollisionWithEntity(const EntityItemID& idA, const EntityItemID& idB, diff --git a/libraries/entities/src/EntityItem.cpp b/libraries/entities/src/EntityItem.cpp index bdedbbce77..a36c69b880 100644 --- a/libraries/entities/src/EntityItem.cpp +++ b/libraries/entities/src/EntityItem.cpp @@ -852,6 +852,23 @@ void EntityItem::setHref(QString value) { _href = value; } +void EntityItem::setCollisionSoundURL(const QString& value) { + if (_collisionSoundURL != value) { + _collisionSoundURL = value; + + if (auto myTree = getTree()) { + myTree->notifyNewCollisionSoundURL(_collisionSoundURL, getEntityItemID()); + } + } +} + +SharedSoundPointer EntityItem::getCollisionSound() { + if (!_collisionSound) { + _collisionSound = DependencyManager::get()->getSound(_collisionSoundURL); + } + return _collisionSound; +} + void EntityItem::simulate(const quint64& now) { if (_lastSimulated == 0) { _lastSimulated = now; diff --git a/libraries/entities/src/EntityItem.h b/libraries/entities/src/EntityItem.h index ecb9800e70..210dbba284 100644 --- a/libraries/entities/src/EntityItem.h +++ b/libraries/entities/src/EntityItem.h @@ -24,6 +24,7 @@ #include #include #include +#include #include #include "EntityItemID.h" @@ -250,7 +251,10 @@ public: void setScriptTimestamp(const quint64 value) { _scriptTimestamp = value; } const QString& getCollisionSoundURL() const { return _collisionSoundURL; } - void setCollisionSoundURL(const QString& value) { _collisionSoundURL = value; } + void setCollisionSoundURL(const QString& value); + + SharedSoundPointer getCollisionSound(); + void setCollisionSound(SharedSoundPointer sound) { _collisionSound = sound; } const glm::vec3& getRegistrationPoint() const { return _registrationPoint; } /// registration point as ratio of entity @@ -478,6 +482,7 @@ protected: quint64 _loadedScriptTimestamp{ ENTITY_ITEM_DEFAULT_SCRIPT_TIMESTAMP + 1 }; QString _collisionSoundURL; + SharedSoundPointer _collisionSound; glm::vec3 _registrationPoint; float _angularDamping; bool _visible; diff --git a/libraries/entities/src/EntityTree.cpp b/libraries/entities/src/EntityTree.cpp index b4f0c484d5..7b6756f3c1 100644 --- a/libraries/entities/src/EntityTree.cpp +++ b/libraries/entities/src/EntityTree.cpp @@ -95,7 +95,6 @@ void EntityTree::postAddEntity(EntityItemPointer entity) { } _isDirty = true; - maybeNotifyNewCollisionSoundURL("", entity->getCollisionSoundURL()); emit addingEntity(entity->getEntityItemID()); // find and hook up any entities with this entity as a (previously) missing parent @@ -223,7 +222,6 @@ bool EntityTree::updateEntityWithElement(EntityItemPointer entity, const EntityI QString entityScriptBefore = entity->getScript(); quint64 entityScriptTimestampBefore = entity->getScriptTimestamp(); - QString collisionSoundURLBefore = entity->getCollisionSoundURL(); uint32_t preFlags = entity->getDirtyFlags(); AACube newQueryAACube; @@ -295,7 +293,6 @@ bool EntityTree::updateEntityWithElement(EntityItemPointer entity, const EntityI if (entityScriptBefore != entityScriptAfter || reload) { emitEntityScriptChanging(entity->getEntityItemID(), reload); // the entity script has changed } - maybeNotifyNewCollisionSoundURL(collisionSoundURLBefore, entity->getCollisionSoundURL()); } // TODO: this final containingElement check should eventually be removed (or wrapped in an #ifdef DEBUG). @@ -362,10 +359,8 @@ void EntityTree::emitEntityScriptChanging(const EntityItemID& entityItemID, cons emit entityScriptChanging(entityItemID, reload); } -void EntityTree::maybeNotifyNewCollisionSoundURL(const QString& previousCollisionSoundURL, const QString& nextCollisionSoundURL) { - if (!nextCollisionSoundURL.isEmpty() && (nextCollisionSoundURL != previousCollisionSoundURL)) { - emit newCollisionSoundURL(QUrl(nextCollisionSoundURL)); - } +void EntityTree::notifyNewCollisionSoundURL(const QString& newURL, const EntityItemID& entityID) { + emit newCollisionSoundURL(QUrl(newURL), entityID); } void EntityTree::setSimulation(EntitySimulation* simulation) { diff --git a/libraries/entities/src/EntityTree.h b/libraries/entities/src/EntityTree.h index 54e516d01d..83bc31aa92 100644 --- a/libraries/entities/src/EntityTree.h +++ b/libraries/entities/src/EntityTree.h @@ -249,6 +249,8 @@ public: void forgetAvatarID(QUuid avatarID) { _avatarIDs -= avatarID; } void deleteDescendantsOfAvatar(QUuid avatarID); + void notifyNewCollisionSoundURL(const QString& newCollisionSoundURL, const EntityItemID& entityID); + public slots: void callLoader(EntityItemID entityID); @@ -256,7 +258,7 @@ signals: void deletingEntity(const EntityItemID& entityID); void addingEntity(const EntityItemID& entityID); void entityScriptChanging(const EntityItemID& entityItemID, const bool reload); - void newCollisionSoundURL(const QUrl& url); + void newCollisionSoundURL(const QUrl& url, const EntityItemID& entityID); void clearingEntities(); protected: @@ -301,7 +303,6 @@ protected: bool _wantEditLogging = false; bool _wantTerseEditLogging = false; - void maybeNotifyNewCollisionSoundURL(const QString& oldCollisionSoundURL, const QString& newCollisionSoundURL); // some performance tracking properties - only used in server trees diff --git a/libraries/entities/src/EntityTreeElement.cpp b/libraries/entities/src/EntityTreeElement.cpp index 8270dc7e69..a919dc4251 100644 --- a/libraries/entities/src/EntityTreeElement.cpp +++ b/libraries/entities/src/EntityTreeElement.cpp @@ -34,8 +34,6 @@ OctreeElementPointer EntityTreeElement::createNewElement(unsigned char* octalCod return newChild; } - - void EntityTreeElement::init(unsigned char* octalCode) { OctreeElement::init(octalCode); _octreeMemoryUsage += sizeof(EntityTreeElement);