From f2e69d5c818363e58566ceeca5a3aa75be209bfd Mon Sep 17 00:00:00 2001 From: Simon Walton Date: Thu, 20 Sep 2018 17:37:39 -0700 Subject: [PATCH] Make default bubble-box AvatarData property for efficiency Also a use of getClientGlobalPosition(), etc --- .../src/avatars/AvatarMixerClientData.h | 2 +- .../src/avatars/AvatarMixerSlave.cpp | 6 ++--- libraries/avatars/src/AvatarData.cpp | 24 +++++++++++++++++-- libraries/avatars/src/AvatarData.h | 6 +++++ 4 files changed, 31 insertions(+), 7 deletions(-) diff --git a/assignment-client/src/avatars/AvatarMixerClientData.h b/assignment-client/src/avatars/AvatarMixerClientData.h index ccb0f4001d..492d21a807 100644 --- a/assignment-client/src/avatars/AvatarMixerClientData.h +++ b/assignment-client/src/avatars/AvatarMixerClientData.h @@ -90,7 +90,7 @@ public: void loadJSONStats(QJsonObject& jsonObject) const; - glm::vec3 getPosition() const { return _avatar ? _avatar->getWorldPosition() : glm::vec3(0); } + glm::vec3 getPosition() const { return _avatar ? _avatar->getClientGlobalPosition() : glm::vec3(0); } bool isRadiusIgnoring(const QUuid& other) const; void addToRadiusIgnoringSet(const QUuid& other); void removeFromRadiusIgnoringSet(const QUuid& other); diff --git a/assignment-client/src/avatars/AvatarMixerSlave.cpp b/assignment-client/src/avatars/AvatarMixerSlave.cpp index c8cc4d0c8a..f83bb2d3cb 100644 --- a/assignment-client/src/avatars/AvatarMixerSlave.cpp +++ b/assignment-client/src/avatars/AvatarMixerSlave.cpp @@ -244,7 +244,7 @@ void AvatarMixerSlave::broadcastAvatarDataToAgent(const SharedNodePointer& node) // reset the internal state for correct random number distribution distribution.reset(); - // Base number to sort on number previously sent. + // Estimate number to sort on number sent last frame. const int numToSendEst = std::max(nodeData->getNumAvatarsSentLastFrame() * 2, 20); // reset the number of sent avatars @@ -342,8 +342,7 @@ void AvatarMixerSlave::broadcastAvatarDataToAgent(const SharedNodePointer& node) // Don't bother with these checks if the other avatar has their bubble enabled and we're gettingAnyIgnored if (destinationNode->isIgnoreRadiusEnabled() || (avatarNode->isIgnoreRadiusEnabled() && !getsAnyIgnored)) { // Perform the collision check between the two bounding boxes - const float OTHER_AVATAR_BUBBLE_EXPANSION_FACTOR = 2.4f; // magic number determined empirically - AABox otherNodeBox = computeBubbleBox(avatarClientNodeData->getAvatar(), OTHER_AVATAR_BUBBLE_EXPANSION_FACTOR); + AABox otherNodeBox = avatarClientNodeData->getAvatar().getDefaultBubbleBox(); if (nodeBox.touches(otherNodeBox)) { nodeData->ignoreOther(destinationNode, avatarNode); shouldIgnore = !getsAnyIgnored; @@ -396,7 +395,6 @@ void AvatarMixerSlave::broadcastAvatarDataToAgent(const SharedNodePointer& node) auto avatarPacket = NLPacket::create(PacketType::BulkAvatarData); const int avatarPacketCapacity = avatarPacket->getPayloadCapacity(); int avatarSpaceAvailable = avatarPacketCapacity; - //avatarSpaceAvailable = 100; int numPacketsSent = 0; const auto& sortedAvatarVector = sortedAvatars.getSortedVector(numToSendEst); diff --git a/libraries/avatars/src/AvatarData.cpp b/libraries/avatars/src/AvatarData.cpp index 73525f69a7..782483a6c1 100644 --- a/libraries/avatars/src/AvatarData.cpp +++ b/libraries/avatars/src/AvatarData.cpp @@ -384,8 +384,8 @@ QByteArray AvatarData::toByteArray(AvatarDataDetail dataDetail, quint64 lastSent QByteArray avatarDataByteArray((int)byteArraySize, 0); unsigned char* destinationBuffer = reinterpret_cast(avatarDataByteArray.data()); - unsigned char* startPosition = destinationBuffer; - const unsigned char * packetEnd = destinationBuffer + maxDataSize; + const unsigned char* const startPosition = destinationBuffer; + const unsigned char* const packetEnd = destinationBuffer + maxDataSize; AvatarDataPacket::HasFlags includedFlags = 0; @@ -971,6 +971,8 @@ int AvatarData::parseDataFromBuffer(const QByteArray& buffer) { _avatarBoundingBoxChanged = now; } + _defaultBubbleBox = computeBubbleBox(); + sourceBuffer += sizeof(AvatarDataPacket::AvatarBoundingBox); int numBytesRead = sourceBuffer - startSection; _avatarBoundingBoxRate.increment(numBytesRead); @@ -2916,3 +2918,21 @@ void AvatarEntityMapFromScriptValue(const QScriptValue& object, AvatarEntityMap& value[EntityID] = binaryEntityProperties; } } + +const float AvatarData::DEFAULT_BUBBLE_SCALE = 2.4f; // magic number determined empirically + +AABox AvatarData::computeBubbleBox(float bubbleScale) const { + AABox box = AABox(_globalBoundingBoxOffset - _globalBoundingBoxDimensions, _globalBoundingBoxDimensions); + glm::vec3 size = box.getScale(); + size *= bubbleScale; + const glm::vec3 MIN_BUBBLE_SCALE(0.3f, 1.3f, 0.3); + size= glm::max(size, MIN_BUBBLE_SCALE); + box.setScaleStayCentered(size); + return box; +} + +AABox AvatarData::getDefaultBubbleBox() const { + AABox bubbleBox(_defaultBubbleBox); + bubbleBox.translate(_globalPosition); + return bubbleBox; +} diff --git a/libraries/avatars/src/AvatarData.h b/libraries/avatars/src/AvatarData.h index df7129b7a5..3ea7631e0c 100644 --- a/libraries/avatars/src/AvatarData.h +++ b/libraries/avatars/src/AvatarData.h @@ -1100,6 +1100,7 @@ public: glm::vec3 getClientGlobalPosition() const { return _globalPosition; } AABox getGlobalBoundingBox() const { return AABox(_globalPosition + _globalBoundingBoxOffset - _globalBoundingBoxDimensions, _globalBoundingBoxDimensions); } + AABox getDefaultBubbleBox() const; /**jsdoc * @function MyAvatar.getAvatarEntityData @@ -1192,6 +1193,9 @@ public: void setReplicaIndex(int replicaIndex) { _replicaIndex = replicaIndex; } int getReplicaIndex() { return _replicaIndex; } + static const float DEFAULT_BUBBLE_SCALE; /* = 2.4 */ + AABox computeBubbleBox(float bubbleScale = DEFAULT_BUBBLE_SCALE) const; + signals: /**jsdoc @@ -1425,6 +1429,8 @@ protected: glm::vec3 _globalBoundingBoxDimensions; glm::vec3 _globalBoundingBoxOffset; + AABox _defaultBubbleBox; + mutable ReadWriteLockable _avatarEntitiesLock; AvatarEntityIDs _avatarEntityDetached; // recently detached from this avatar AvatarEntityIDs _avatarEntityForRecording; // create new entities id for avatar recording