From 64a2025bcdf2c427484edf6d27788092011f0418 Mon Sep 17 00:00:00 2001 From: Simon Walton Date: Thu, 28 Feb 2019 18:40:53 -0800 Subject: [PATCH] Renaming in main loop to make source/destination clear Also comment clean-up, etc --- .../src/avatars/AvatarMixerSlave.cpp | 123 +++++++++--------- 1 file changed, 62 insertions(+), 61 deletions(-) diff --git a/assignment-client/src/avatars/AvatarMixerSlave.cpp b/assignment-client/src/avatars/AvatarMixerSlave.cpp index a38553ddeb..ac18268860 100644 --- a/assignment-client/src/avatars/AvatarMixerSlave.cpp +++ b/assignment-client/src/avatars/AvatarMixerSlave.cpp @@ -320,21 +320,21 @@ void AvatarMixerSlave::broadcastAvatarDataToAgent(const SharedNodePointer& node) _stats.nodesBroadcastedTo++; - AvatarMixerClientData* nodeData = reinterpret_cast(destinationNode->getLinkedData()); + AvatarMixerClientData* destinationNodeData = reinterpret_cast(destinationNode->getLinkedData()); - nodeData->resetInViewStats(); + destinationNodeData->resetInViewStats(); - const AvatarData& avatar = nodeData->getAvatar(); + const AvatarData& avatar = destinationNodeData->getAvatar(); glm::vec3 myPosition = avatar.getClientGlobalPosition(); // reset the internal state for correct random number distribution distribution.reset(); // Estimate number to sort on number sent last frame (with min. of 20). - const int numToSendEst = std::max(int(nodeData->getNumAvatarsSentLastFrame() * 2.5f), 20); + const int numToSendEst = std::max(int(destinationNodeData->getNumAvatarsSentLastFrame() * 2.5f), 20); // reset the number of sent avatars - nodeData->resetNumAvatarsSentLastFrame(); + destinationNodeData->resetNumAvatarsSentLastFrame(); // keep track of outbound data rate specifically for avatar data int numAvatarDataBytes = 0; @@ -353,8 +353,8 @@ void AvatarMixerSlave::broadcastAvatarDataToAgent(const SharedNodePointer& node) // When this is true, the AvatarMixer will send Avatar data to a client // about avatars they've ignored or that are out of view - bool PALIsOpen = nodeData->getRequestsDomainListData(); - bool PALWasOpen = nodeData->getPrevRequestsDomainListData(); + bool PALIsOpen = destinationNodeData->getRequestsDomainListData(); + bool PALWasOpen = destinationNodeData->getPrevRequestsDomainListData(); // When this is true, the AvatarMixer will send Avatar data to a client about avatars that have ignored them bool getsAnyIgnored = PALIsOpen && destinationNode->getCanKick(); @@ -368,7 +368,7 @@ void AvatarMixerSlave::broadcastAvatarDataToAgent(const SharedNodePointer& node) AABox nodeBox = computeBubbleBox(avatar, MY_AVATAR_BUBBLE_EXPANSION_FACTOR); // prepare to sort - const auto& cameraViews = nodeData->getViewFrustums(); + const auto& cameraViews = destinationNodeData->getViewFrustums(); using AvatarPriorityQueue = PrioritySortUtil::PriorityQueue; // Keep two independent queues, one for heroes and one for the riff-raff. @@ -391,47 +391,47 @@ void AvatarMixerSlave::broadcastAvatarDataToAgent(const SharedNodePointer& node) continue; } - auto avatarNode = otherNodeRaw; + auto sourceAvatarNode = otherNodeRaw; - bool shouldIgnore = false; + bool sendAvatar = true; // We will consider this source avatar for sending. // We ignore other nodes for a couple of reasons: // 1) ignore bubbles and ignore specific node // 2) the node hasn't really updated it's frame data recently, this can // happen if for example the avatar is connected on a desktop and sending // updates at ~30hz. So every 3 frames we skip a frame. - assert(avatarNode); // we can't have gotten here without the avatarData being a valid key in the map + assert(sourceAvatarNode); // we can't have gotten here without the avatarData being a valid key in the map - const AvatarMixerClientData* avatarClientNodeData = reinterpret_cast(avatarNode->getLinkedData()); - assert(avatarClientNodeData); // we can't have gotten here without avatarNode having valid data + const AvatarMixerClientData* sourceAvatarNodeData = reinterpret_cast(sourceAvatarNode->getLinkedData()); + assert(sourceAvatarNodeData); // we can't have gotten here without sourceAvatarNode having valid data quint64 startIgnoreCalculation = usecTimestampNow(); // make sure we have data for this avatar, that it isn't the same node, // and isn't an avatar that the viewing node has ignored // or that has ignored the viewing node - if ((destinationNode->isIgnoringNodeWithID(avatarNode->getUUID()) && !PALIsOpen) - || (avatarNode->isIgnoringNodeWithID(destinationNode->getUUID()) && !getsAnyIgnored)) { - shouldIgnore = true; + if ((destinationNode->isIgnoringNodeWithID(sourceAvatarNode->getUUID()) && !PALIsOpen) + || (sourceAvatarNode->isIgnoringNodeWithID(destinationNode->getUUID()) && !getsAnyIgnored)) { + sendAvatar = false; } else { // Check to see if the space bubble is enabled // Don't bother with these checks if the other avatar has their bubble enabled and we're gettingAnyIgnored - if (nodeData->isIgnoreRadiusEnabled() || (avatarClientNodeData->isIgnoreRadiusEnabled() && !getsAnyIgnored)) { + if (destinationNodeData->isIgnoreRadiusEnabled() || (sourceAvatarNodeData->isIgnoreRadiusEnabled() && !getsAnyIgnored)) { // Perform the collision check between the two bounding boxes - AABox otherNodeBox = avatarClientNodeData->getAvatar().getDefaultBubbleBox(); + AABox otherNodeBox = sourceAvatarNodeData->getAvatar().getDefaultBubbleBox(); if (nodeBox.touches(otherNodeBox)) { - nodeData->ignoreOther(destinationNode, avatarNode); - shouldIgnore = !getsAnyIgnored; + destinationNodeData->ignoreOther(destinationNode, sourceAvatarNode); + sendAvatar = getsAnyIgnored; } } // Not close enough to ignore - if (!shouldIgnore) { - nodeData->removeFromRadiusIgnoringSet(avatarNode->getUUID()); + if (sendAvatar) { + destinationNodeData->removeFromRadiusIgnoringSet(sourceAvatarNode->getUUID()); } } - if (!shouldIgnore) { - AvatarDataSequenceNumber lastSeqToReceiver = nodeData->getLastBroadcastSequenceNumber(avatarNode->getLocalID()); - AvatarDataSequenceNumber lastSeqFromSender = avatarClientNodeData->getLastReceivedSequenceNumber(); + if (sendAvatar) { + AvatarDataSequenceNumber lastSeqToReceiver = destinationNodeData->getLastBroadcastSequenceNumber(sourceAvatarNode->getLocalID()); + AvatarDataSequenceNumber lastSeqFromSender = sourceAvatarNodeData->getLastReceivedSequenceNumber(); // FIXME - This code does appear to be working. But it seems brittle. // It supports determining if the frame of data for this "other" @@ -445,12 +445,12 @@ void AvatarMixerSlave::broadcastAvatarDataToAgent(const SharedNodePointer& node) // or that somehow we haven't sent if (lastSeqToReceiver == lastSeqFromSender && lastSeqToReceiver != 0) { ++numAvatarsHeldBack; - shouldIgnore = true; + sendAvatar = false; } else if (lastSeqFromSender == 0) { - // We have have not yet recieved any data about this avatar. Ignore it for now + // We have have not yet received any data about this avatar. Ignore it for now // This is important for Agent scripts that are not avatar // so that they don't appear to be an avatar at the origin - shouldIgnore = true; + sendAvatar = false; } else if (lastSeqFromSender - lastSeqToReceiver > 1) { // this is a skip - we still send the packet but capture the presence of the skip so we see it happening ++numAvatarsWithSkippedFrames; @@ -459,13 +459,13 @@ void AvatarMixerSlave::broadcastAvatarDataToAgent(const SharedNodePointer& node) quint64 endIgnoreCalculation = usecTimestampNow(); _stats.ignoreCalculationElapsedTime += (endIgnoreCalculation - startIgnoreCalculation); - if (!shouldIgnore) { + if (sendAvatar) { // sort this one for later - const MixerAvatar* avatarNodeData = avatarClientNodeData->getConstAvatarData(); - auto lastEncodeTime = nodeData->getLastOtherAvatarEncodeTime(avatarNode->getLocalID()); + const MixerAvatar* avatarNodeData = sourceAvatarNodeData->getConstAvatarData(); + auto lastEncodeTime = destinationNodeData->getLastOtherAvatarEncodeTime(sourceAvatarNode->getLocalID()); avatarPriorityQueues[avatarNodeData->getPriorityAvatar() ? kHero : kNonhero].push( - SortableAvatar(avatarNodeData, avatarNode, lastEncodeTime)); + SortableAvatar(avatarNodeData, sourceAvatarNode, lastEncodeTime)); } // If Avatar A's PAL WAS open but is no longer open, AND @@ -475,18 +475,18 @@ void AvatarMixerSlave::broadcastAvatarDataToAgent(const SharedNodePointer& node) // will be sent when it doesn't need to be (but where it _should_ be OK to send). // However, it's less heavy-handed than using `shouldIgnore`. if (PALWasOpen && !PALIsOpen && - (destinationNode->isIgnoringNodeWithID(avatarNode->getUUID()) || - avatarNode->isIgnoringNodeWithID(destinationNode->getUUID()))) { + (destinationNode->isIgnoringNodeWithID(sourceAvatarNode->getUUID()) || + sourceAvatarNode->isIgnoringNodeWithID(destinationNode->getUUID()))) { // ...send a Kill Packet to Node A, instructing Node A to kill Avatar B, // then have Node A cleanup the killed Node B. auto packet = NLPacket::create(PacketType::KillAvatar, NUM_BYTES_RFC4122_UUID + sizeof(KillAvatarReason), true); - packet->write(avatarNode->getUUID().toRfc4122()); + packet->write(sourceAvatarNode->getUUID().toRfc4122()); packet->writePrimitive(KillAvatarReason::AvatarIgnored); nodeList->sendPacket(std::move(packet), *destinationNode); - nodeData->cleanupKilledNode(avatarNode->getUUID(), avatarNode->getLocalID()); + destinationNodeData->cleanupKilledNode(sourceAvatarNode->getUUID(), sourceAvatarNode->getLocalID()); } - nodeData->setPrevRequestsDomainListData(PALIsOpen); + destinationNodeData->setPrevRequestsDomainListData(PALIsOpen); } // loop through our sorted avatars and allocate our bandwidth to them accordingly @@ -501,13 +501,14 @@ void AvatarMixerSlave::broadcastAvatarDataToAgent(const SharedNodePointer& node) int numAvatarsSent = 0; auto identityPacketList = NLPacketList::create(PacketType::AvatarIdentity, QByteArray(), true, true); + // Loop over two priorities - hero avatars then everyone else: for (PriorityVariants currentVariant = kHero; currentVariant <= kNonhero; ++((int&)currentVariant)) { const auto& sortedAvatarVector = avatarPriorityQueues[currentVariant].getSortedVector(numToSendEst); for (const auto& sortedAvatar : sortedAvatarVector) { - const Node* otherNode = sortedAvatar.getNode(); + const Node* sourceNode = sortedAvatar.getNode(); auto lastEncodeForOther = sortedAvatar.getTimestamp(); - assert(otherNode); // we can't have gotten here without the avatarData being a valid key in the map + assert(sourceNode); // we can't have gotten here without the avatarData being a valid key in the map AvatarData::AvatarDataDetail detail = AvatarData::NoData; @@ -533,31 +534,31 @@ void AvatarMixerSlave::broadcastAvatarDataToAgent(const SharedNodePointer& node) auto startAvatarDataPacking = chrono::high_resolution_clock::now(); - const AvatarMixerClientData* otherNodeData = reinterpret_cast(otherNode->getLinkedData()); - const MixerAvatar* otherAvatar = otherNodeData->getConstAvatarData(); + const AvatarMixerClientData* sourceNodeData = reinterpret_cast(sourceNode->getLinkedData()); + const MixerAvatar* sourceAvatar = sourceNodeData->getConstAvatarData(); // Typically all out-of-view avatars but such avatars' priorities will rise with time: - bool isLowerPriority = sortedAvatar.getPriority() <= OUT_OF_VIEW_THRESHOLD; + bool isLowerPriority = sortedAvatar.getPriority() <= OUT_OF_VIEW_THRESHOLD; // XXX: hero handling? if (isLowerPriority) { detail = PALIsOpen ? AvatarData::PALMinimum : AvatarData::MinimumData; - nodeData->incrementAvatarOutOfView(); + destinationNodeData->incrementAvatarOutOfView(); } else if (!overBudget) { detail = distribution(generator) < AVATAR_SEND_FULL_UPDATE_RATIO ? AvatarData::SendAllData : AvatarData::CullSmallData; - nodeData->incrementAvatarInView(); + destinationNodeData->incrementAvatarInView(); // If the time that the mixer sent AVATAR DATA about Avatar B to Avatar A is BEFORE OR EQUAL TO // the time that Avatar B flagged an IDENTITY DATA change, send IDENTITY DATA about Avatar B to Avatar A. - if (otherAvatar->hasProcessedFirstIdentity() - && nodeData->getLastBroadcastTime(otherNode->getLocalID()) <= otherNodeData->getIdentityChangeTimestamp()) { - identityBytesSent += sendIdentityPacket(*identityPacketList, otherNodeData, *destinationNode); + if (sourceAvatar->hasProcessedFirstIdentity() + && destinationNodeData->getLastBroadcastTime(sourceNode->getLocalID()) <= sourceNodeData->getIdentityChangeTimestamp()) { + identityBytesSent += sendIdentityPacket(*identityPacketList, sourceNodeData, *destinationNode); // remember the last time we sent identity details about this other node to the receiver - nodeData->setLastBroadcastTime(otherNode->getLocalID(), usecTimestampNow()); + destinationNodeData->setLastBroadcastTime(sourceNode->getLocalID(), usecTimestampNow()); } } - QVector& lastSentJointsForOther = nodeData->getLastOtherAvatarSentJoints(otherNode->getLocalID()); + QVector& lastSentJointsForOther = destinationNodeData->getLastOtherAvatarSentJoints(sourceNode->getLocalID()); const bool distanceAdjust = true; const bool dropFaceTracking = false; @@ -566,7 +567,7 @@ void AvatarMixerSlave::broadcastAvatarDataToAgent(const SharedNodePointer& node) do { auto startSerialize = chrono::high_resolution_clock::now(); - QByteArray bytes = otherAvatar->toByteArray(detail, lastEncodeForOther, lastSentJointsForOther, + QByteArray bytes = sourceAvatar->toByteArray(detail, lastEncodeForOther, lastSentJointsForOther, sendStatus, dropFaceTracking, distanceAdjust, myPosition, &lastSentJointsForOther, avatarSpaceAvailable); auto endSerialize = chrono::high_resolution_clock::now(); @@ -587,17 +588,17 @@ void AvatarMixerSlave::broadcastAvatarDataToAgent(const SharedNodePointer& node) if (detail != AvatarData::NoData) { _stats.numOthersIncluded++; - if (otherAvatar->getPriorityAvatar()) { + if (sourceAvatar->getPriorityAvatar()) { _stats.numHeroesIncluded++; } // increment the number of avatars sent to this receiver - nodeData->incrementNumAvatarsSentLastFrame(); + destinationNodeData->incrementNumAvatarsSentLastFrame(); // set the last sent sequence number for this sender on the receiver - nodeData->setLastBroadcastSequenceNumber(otherNode->getLocalID(), - otherNodeData->getLastReceivedSequenceNumber()); - nodeData->setLastOtherAvatarEncodeTime(otherNode->getLocalID(), usecTimestampNow()); + destinationNodeData->setLastBroadcastSequenceNumber(sourceNode->getLocalID(), + sourceNodeData->getLastReceivedSequenceNumber()); + destinationNodeData->setLastOtherAvatarEncodeTime(sourceNode->getLocalID(), usecTimestampNow()); } auto endAvatarDataPacking = chrono::high_resolution_clock::now(); @@ -606,7 +607,7 @@ void AvatarMixerSlave::broadcastAvatarDataToAgent(const SharedNodePointer& node) if (!overBudget) { // use helper to add any changed traits to our packet list - traitBytesSent += addChangedTraitsToBulkPacket(nodeData, otherNodeData, *traitsPacketList); + traitBytesSent += addChangedTraitsToBulkPacket(destinationNodeData, sourceNodeData, *traitsPacketList); } numAvatarsSent++; remainingAvatars--; @@ -619,8 +620,8 @@ void AvatarMixerSlave::broadcastAvatarDataToAgent(const SharedNodePointer& node) } } - if (nodeData->getNumAvatarsSentLastFrame() > numToSendEst) { - qCWarning(avatars) << "More avatars sent than upper estimate" << nodeData->getNumAvatarsSentLastFrame() + if (destinationNodeData->getNumAvatarsSentLastFrame() > numToSendEst) { + qCWarning(avatars) << "More avatars sent than upper estimate" << destinationNodeData->getNumAvatarsSentLastFrame() << " / " << numToSendEst; } @@ -651,12 +652,12 @@ void AvatarMixerSlave::broadcastAvatarDataToAgent(const SharedNodePointer& node) } // record the bytes sent for other avatar data in the AvatarMixerClientData - nodeData->recordSentAvatarData(numAvatarDataBytes, traitBytesSent); + destinationNodeData->recordSentAvatarData(numAvatarDataBytes, traitBytesSent); // record the number of avatars held back this frame - nodeData->recordNumOtherAvatarStarves(numAvatarsHeldBack); - nodeData->recordNumOtherAvatarSkips(numAvatarsWithSkippedFrames); + destinationNodeData->recordNumOtherAvatarStarves(numAvatarsHeldBack); + destinationNodeData->recordNumOtherAvatarSkips(numAvatarsWithSkippedFrames); quint64 endPacketSending = usecTimestampNow(); _stats.packetSendingElapsedTime += (endPacketSending - startPacketSending);