From 495925a017b0191c6723c8ff6329bf2270909fb0 Mon Sep 17 00:00:00 2001 From: Zach Fox Date: Thu, 5 Jan 2017 16:58:32 -0800 Subject: [PATCH] This behavior was harder to change than expected... --- assignment-client/src/avatars/AvatarMixer.cpp | 6 +++--- .../src/avatars/AvatarMixerClientData.cpp | 9 +++++++++ .../src/avatars/AvatarMixerClientData.h | 2 +- interface/src/avatar/Avatar.cpp | 4 +++- interface/src/avatar/AvatarManager.cpp | 2 ++ libraries/avatars/src/AvatarHashMap.cpp | 7 +++++++ libraries/avatars/src/AvatarHashMap.h | 1 + libraries/networking/src/NodeList.cpp | 20 +++++++++++++++++++ libraries/networking/src/NodeList.h | 4 ++++ libraries/networking/src/udt/PacketHeaders.h | 3 ++- 10 files changed, 52 insertions(+), 6 deletions(-) diff --git a/assignment-client/src/avatars/AvatarMixer.cpp b/assignment-client/src/avatars/AvatarMixer.cpp index 3cacfdedf1..ddecd1b50f 100644 --- a/assignment-client/src/avatars/AvatarMixer.cpp +++ b/assignment-client/src/avatars/AvatarMixer.cpp @@ -299,7 +299,7 @@ void AvatarMixer::broadcastAvatarData() { AvatarMixerClientData* otherData = reinterpret_cast(otherNode->getLinkedData()); AvatarMixerClientData* nodeData = reinterpret_cast(node->getLinkedData()); // Check to see if the space bubble is enabled - if ((node->isIgnoreRadiusEnabled() && !getsIgnoredByMe) || (otherNode->isIgnoreRadiusEnabled() && !getsAnyIgnored)) { + if (node->isIgnoreRadiusEnabled() || otherNode->isIgnoreRadiusEnabled()) { // Define the minimum bubble size static const glm::vec3 minBubbleSize = glm::vec3(0.3f, 1.3f, 0.3f); // Define the scale of the box for the current node @@ -326,11 +326,11 @@ void AvatarMixer::broadcastAvatarData() { // Perform the collision check between the two bounding boxes if (nodeBox.touches(otherNodeBox)) { nodeData->ignoreOther(node, otherNode); - return false; + return getsIgnoredByMe || getsAnyIgnored; } } // Not close enough to ignore - nodeData->removeFromRadiusIgnoringSet(otherNode->getUUID()); + nodeData->removeFromRadiusIgnoringSet(node, otherNode->getUUID()); return true; } }, diff --git a/assignment-client/src/avatars/AvatarMixerClientData.cpp b/assignment-client/src/avatars/AvatarMixerClientData.cpp index c65703b8e6..a7a506e1d8 100644 --- a/assignment-client/src/avatars/AvatarMixerClientData.cpp +++ b/assignment-client/src/avatars/AvatarMixerClientData.cpp @@ -57,6 +57,15 @@ void AvatarMixerClientData::ignoreOther(SharedNodePointer self, SharedNodePointe } } +void AvatarMixerClientData::removeFromRadiusIgnoringSet(SharedNodePointer self, const QUuid& other) { + if (isRadiusIgnoring(other)) { + _radiusIgnoredOthers.erase(other); + auto exitingSpaceBubblePacket = NLPacket::create(PacketType::ExitingSpaceBubble, NUM_BYTES_RFC4122_UUID); + exitingSpaceBubblePacket->write(other.toRfc4122()); + DependencyManager::get()->sendUnreliablePacket(*exitingSpaceBubblePacket, *self); + } +} + void AvatarMixerClientData::readViewFrustumPacket(const QByteArray& message) { _currentViewFrustum.fromByteArray(message); } diff --git a/assignment-client/src/avatars/AvatarMixerClientData.h b/assignment-client/src/avatars/AvatarMixerClientData.h index 861086893a..f18cfdde1b 100644 --- a/assignment-client/src/avatars/AvatarMixerClientData.h +++ b/assignment-client/src/avatars/AvatarMixerClientData.h @@ -89,7 +89,7 @@ public: glm::vec3 getGlobalBoundingBoxCorner() { return _avatar ? _avatar->getGlobalBoundingBoxCorner() : glm::vec3(0); } bool isRadiusIgnoring(const QUuid& other) { return _radiusIgnoredOthers.find(other) != _radiusIgnoredOthers.end(); } void addToRadiusIgnoringSet(const QUuid& other) { _radiusIgnoredOthers.insert(other); } - void removeFromRadiusIgnoringSet(const QUuid& other) { _radiusIgnoredOthers.erase(other); } + void removeFromRadiusIgnoringSet(SharedNodePointer self, const QUuid& other); void ignoreOther(SharedNodePointer self, SharedNodePointer other); void readViewFrustumPacket(const QByteArray& message); diff --git a/interface/src/avatar/Avatar.cpp b/interface/src/avatar/Avatar.cpp index 1ade21930d..659a96afa0 100644 --- a/interface/src/avatar/Avatar.cpp +++ b/interface/src/avatar/Avatar.cpp @@ -1339,7 +1339,9 @@ void Avatar::addToScene(AvatarSharedPointer myHandle) { render::ScenePointer scene = qApp->getMain3DScene(); if (scene) { render::PendingChanges pendingChanges; - if (DependencyManager::get()->shouldRenderAvatars() && !DependencyManager::get()->isIgnoringNode(getSessionUUID())) { + if (DependencyManager::get()->shouldRenderAvatars() + && !DependencyManager::get()->isIgnoringNode(getSessionUUID()) + && !DependencyManager::get()->isRadiusIgnoringNode(getSessionUUID())) { addToScene(myHandle, scene, pendingChanges); } scene->enqueuePendingChanges(pendingChanges); diff --git a/interface/src/avatar/AvatarManager.cpp b/interface/src/avatar/AvatarManager.cpp index e3ccc10a65..e955f94597 100644 --- a/interface/src/avatar/AvatarManager.cpp +++ b/interface/src/avatar/AvatarManager.cpp @@ -79,6 +79,7 @@ AvatarManager::AvatarManager(QObject* parent) : packetReceiver.registerListener(PacketType::BulkAvatarData, this, "processAvatarDataPacket"); packetReceiver.registerListener(PacketType::KillAvatar, this, "processKillAvatar"); packetReceiver.registerListener(PacketType::AvatarIdentity, this, "processAvatarIdentityPacket"); + packetReceiver.registerListener(PacketType::ExitingSpaceBubble, this, "processExitingSpaceBubble"); // when we hear that the user has ignored an avatar by session UUID // immediately remove that avatar instead of waiting for the absence of packets from avatar mixer @@ -256,6 +257,7 @@ void AvatarManager::handleRemovedAvatar(const AvatarSharedPointer& removedAvatar if (removalReason == KillAvatarReason::TheirAvatarEnteredYourBubble) { emit DependencyManager::get()->enteredIgnoreRadius(); + DependencyManager::get()->radiusIgnoreNodeBySessionID(avatar->getSessionUUID(), true); } _avatarFades.push_back(removedAvatar); } diff --git a/libraries/avatars/src/AvatarHashMap.cpp b/libraries/avatars/src/AvatarHashMap.cpp index c708176da7..f4e94b9a35 100644 --- a/libraries/avatars/src/AvatarHashMap.cpp +++ b/libraries/avatars/src/AvatarHashMap.cpp @@ -161,6 +161,13 @@ void AvatarHashMap::processKillAvatar(QSharedPointer message, S removeAvatar(sessionUUID, reason); } +void AvatarHashMap::processExitingSpaceBubble(QSharedPointer message, SharedNodePointer sendingNode) { + // read the node id + QUuid sessionUUID = QUuid::fromRfc4122(message->readWithoutCopy(NUM_BYTES_RFC4122_UUID)); + auto nodeList = DependencyManager::get(); + nodeList->radiusIgnoreNodeBySessionID(sessionUUID, false); +} + void AvatarHashMap::removeAvatar(const QUuid& sessionUUID, KillAvatarReason removalReason) { QWriteLocker locker(&_hashLock); diff --git a/libraries/avatars/src/AvatarHashMap.h b/libraries/avatars/src/AvatarHashMap.h index 02aef6ac8a..eae4026bfc 100644 --- a/libraries/avatars/src/AvatarHashMap.h +++ b/libraries/avatars/src/AvatarHashMap.h @@ -57,6 +57,7 @@ private slots: void processAvatarDataPacket(QSharedPointer message, SharedNodePointer sendingNode); void processAvatarIdentityPacket(QSharedPointer message, SharedNodePointer sendingNode); void processKillAvatar(QSharedPointer message, SharedNodePointer sendingNode); + void processExitingSpaceBubble(QSharedPointer message, SharedNodePointer sendingNode); protected: AvatarHashMap(); diff --git a/libraries/networking/src/NodeList.cpp b/libraries/networking/src/NodeList.cpp index bd3203150e..c587037911 100644 --- a/libraries/networking/src/NodeList.cpp +++ b/libraries/networking/src/NodeList.cpp @@ -238,6 +238,10 @@ void NodeList::reset() { _numNoReplyDomainCheckIns = 0; + // lock and clear our set of radius ignored IDs + _radiusIgnoredSetLock.lockForWrite(); + _radiusIgnoredNodeIDs.clear(); + _radiusIgnoredSetLock.unlock(); // lock and clear our set of ignored IDs _ignoredSetLock.lockForWrite(); _ignoredNodeIDs.clear(); @@ -781,6 +785,22 @@ void NodeList::sendIgnoreRadiusStateToNode(const SharedNodePointer& destinationN sendPacket(std::move(ignorePacket), *destinationNode); } +void NodeList::radiusIgnoreNodeBySessionID(const QUuid& nodeID, bool radiusIgnoreEnabled) { + if (radiusIgnoreEnabled) { + QReadLocker radiusIgnoredSetLocker{ &_radiusIgnoredSetLock }; // read lock for insert + // add this nodeID to our set of ignored IDs + _radiusIgnoredNodeIDs.insert(nodeID); + } else { + QWriteLocker radiusIgnoredSetLocker{ &_radiusIgnoredSetLock }; // write lock for unsafe_erase + _radiusIgnoredNodeIDs.unsafe_erase(nodeID); + } +} + +bool NodeList::isRadiusIgnoringNode(const QUuid& nodeID) const { + QReadLocker radiusIgnoredSetLocker{ &_radiusIgnoredSetLock }; // read lock for reading + return _radiusIgnoredNodeIDs.find(nodeID) != _radiusIgnoredNodeIDs.cend(); +} + void NodeList::ignoreNodeBySessionID(const QUuid& nodeID, bool ignoreEnabled) { // enumerate the nodes to send a reliable ignore packet to each that can leverage it if (!nodeID.isNull() && _sessionUUID != nodeID) { diff --git a/libraries/networking/src/NodeList.h b/libraries/networking/src/NodeList.h index 75958f1847..8e285629dc 100644 --- a/libraries/networking/src/NodeList.h +++ b/libraries/networking/src/NodeList.h @@ -76,6 +76,8 @@ public: void toggleIgnoreRadius() { ignoreNodesInRadius(!getIgnoreRadiusEnabled()); } void enableIgnoreRadius() { ignoreNodesInRadius(true); } void disableIgnoreRadius() { ignoreNodesInRadius(false); } + void radiusIgnoreNodeBySessionID(const QUuid& nodeID, bool radiusIgnoreEnabled); + bool isRadiusIgnoringNode(const QUuid& other) const; void ignoreNodeBySessionID(const QUuid& nodeID, bool ignoreEnabled); bool isIgnoringNode(const QUuid& nodeID) const; void personalMuteNodeBySessionID(const QUuid& nodeID, bool muteEnabled); @@ -159,6 +161,8 @@ private: QTimer _keepAlivePingTimer; bool _requestsDomainListData; + mutable QReadWriteLock _radiusIgnoredSetLock; + tbb::concurrent_unordered_set _radiusIgnoredNodeIDs; mutable QReadWriteLock _ignoredSetLock; tbb::concurrent_unordered_set _ignoredNodeIDs; mutable QReadWriteLock _personalMutedSetLock; diff --git a/libraries/networking/src/udt/PacketHeaders.h b/libraries/networking/src/udt/PacketHeaders.h index 3561624f63..37a0e4e804 100644 --- a/libraries/networking/src/udt/PacketHeaders.h +++ b/libraries/networking/src/udt/PacketHeaders.h @@ -105,7 +105,8 @@ public: UsernameFromIDReply, ViewFrustum, RequestsDomainListData, - LAST_PACKET_TYPE = RequestsDomainListData + ExitingSpaceBubble, + LAST_PACKET_TYPE = ExitingSpaceBubble //FIXME }; };