diff --git a/assignment-client/src/avatars/AvatarMixerClientData.cpp b/assignment-client/src/avatars/AvatarMixerClientData.cpp index 0ab9d3be25..b7d2f5cdf8 100644 --- a/assignment-client/src/avatars/AvatarMixerClientData.cpp +++ b/assignment-client/src/avatars/AvatarMixerClientData.cpp @@ -207,8 +207,10 @@ void AvatarMixerClientData::processBulkAvatarTraitsAckMessage(ReceivedMessage& m // process simple traits auto simpleReceivedIt = traitVersions.simpleCBegin(); while (simpleReceivedIt != traitVersions.simpleCEnd()) { - auto traitType = static_cast(std::distance(traitVersions.simpleCBegin(), simpleReceivedIt)); - _perNodeAckedTraitVersions[nodeId][traitType] = *simpleReceivedIt; + if (*simpleReceivedIt != AvatarTraits::DEFAULT_TRAIT_VERSION) { + auto traitType = static_cast(std::distance(traitVersions.simpleCBegin(), simpleReceivedIt)); + _perNodeAckedTraitVersions[nodeId][traitType] = *simpleReceivedIt; + } simpleReceivedIt++; } diff --git a/assignment-client/src/avatars/AvatarMixerSlave.cpp b/assignment-client/src/avatars/AvatarMixerSlave.cpp index 5e84df0d7f..6b039e2c03 100644 --- a/assignment-client/src/avatars/AvatarMixerSlave.cpp +++ b/assignment-client/src/avatars/AvatarMixerSlave.cpp @@ -106,12 +106,13 @@ qint64 AvatarMixerSlave::addChangedTraitsToBulkPacket(AvatarMixerClientData* lis // in that packet_ are ignored. Updates to traits not in that packet will // be sent. - auto otherNodeLocalID = sendingNodeData->getNodeLocalID(); + auto sendingNodeLocalID = sendingNodeData->getNodeLocalID(); // Perform a simple check with two server clock time points // to see if there is any new traits data for this avatar that we need to send - auto timeOfLastTraitsSent = listeningNodeData->getLastOtherAvatarTraitsSendPoint(otherNodeLocalID); + auto timeOfLastTraitsSent = listeningNodeData->getLastOtherAvatarTraitsSendPoint(sendingNodeLocalID); auto timeOfLastTraitsChange = sendingNodeData->getLastReceivedTraitsChange(); + bool allTraitsUpdated = true; qint64 bytesWritten = 0; @@ -121,8 +122,8 @@ qint64 AvatarMixerSlave::addChangedTraitsToBulkPacket(AvatarMixerClientData* lis auto sendingAvatar = sendingNodeData->getAvatarSharedPointer(); // compare trait versions so we can see what exactly needs to go out - auto& lastSentVersions = listeningNodeData->getLastSentTraitVersions(otherNodeLocalID); - auto& lastAckedVersions = listeningNodeData->getLastAckedTraitVersions(otherNodeLocalID); + auto& lastSentVersions = listeningNodeData->getLastSentTraitVersions(sendingNodeLocalID); + auto& lastAckedVersions = listeningNodeData->getLastAckedTraitVersions(sendingNodeLocalID); const auto& lastReceivedVersions = sendingNodeData->getLastReceivedTraitVersions(); auto simpleReceivedIt = lastReceivedVersions.simpleCBegin(); @@ -134,16 +135,20 @@ qint64 AvatarMixerSlave::addChangedTraitsToBulkPacket(AvatarMixerClientData* lis auto& lastAckedVersionRef = lastAckedVersions[traitType]; // hold sending more traits until we've been acked that the last one we sent was received - if (lastSentVersionRef == lastAckedVersionRef && lastReceivedVersions[traitType] > lastSentVersionRef) { - bytesWritten += addTraitsNodeHeader(listeningNodeData, sendingNodeData, traitsPacketList, bytesWritten); - // there is an update to this trait, add it to the traits packet - bytesWritten += sendingAvatar->packTrait(traitType, traitsPacketList, lastReceivedVersion); - // update the last sent version - lastSentVersionRef = lastReceivedVersion; - // Remember which versions we sent in this particular packet - // so we can verify when it's acked. - auto& pendingTraitVersions = listeningNodeData->getPendingTraitVersions(listeningNodeData->getTraitsMessageSequence(), otherNodeLocalID); - pendingTraitVersions[traitType] = lastReceivedVersion; + if (lastSentVersionRef == lastAckedVersionRef) { + if (lastReceivedVersion > lastSentVersionRef) { + bytesWritten += addTraitsNodeHeader(listeningNodeData, sendingNodeData, traitsPacketList, bytesWritten); + // there is an update to this trait, add it to the traits packet + bytesWritten += sendingAvatar->packTrait(traitType, traitsPacketList, lastReceivedVersion); + // update the last sent version + lastSentVersionRef = lastReceivedVersion; + // Remember which versions we sent in this particular packet + // so we can verify when it's acked. + auto& pendingTraitVersions = listeningNodeData->getPendingTraitVersions(listeningNodeData->getTraitsMessageSequence(), sendingNodeLocalID); + pendingTraitVersions[traitType] = lastReceivedVersion; + } + } else { + allTraitsUpdated = false; } ++simpleReceivedIt; @@ -182,6 +187,7 @@ qint64 AvatarMixerSlave::addChangedTraitsToBulkPacket(AvatarMixerClientData* lis // version to go on, otherwise we drop the received trait if (sentInstanceIt != sentIDValuePairs.end() && (ackedInstanceIt == ackIDValuePairs.end() || sentInstanceIt->value != ackedInstanceIt->value)) { + allTraitsUpdated = false; continue; } if (!isDeleted && (sentInstanceIt == sentIDValuePairs.end() || receivedVersion > sentInstanceIt->value)) { @@ -198,7 +204,7 @@ qint64 AvatarMixerSlave::addChangedTraitsToBulkPacket(AvatarMixerClientData* lis auto& pendingTraitVersions = listeningNodeData->getPendingTraitVersions(listeningNodeData->getTraitsMessageSequence(), - otherNodeLocalID); + sendingNodeLocalID); pendingTraitVersions.instanceInsert(traitType, instanceID, receivedVersion); } else if (isDeleted && sentInstanceIt != sentIDValuePairs.end() && absoluteReceivedVersion > sentInstanceIt->value) { @@ -212,7 +218,7 @@ qint64 AvatarMixerSlave::addChangedTraitsToBulkPacket(AvatarMixerClientData* lis auto& pendingTraitVersions = listeningNodeData->getPendingTraitVersions(listeningNodeData->getTraitsMessageSequence(), - otherNodeLocalID); + sendingNodeLocalID); pendingTraitVersions.instanceInsert(traitType, instanceID, absoluteReceivedVersion); } @@ -223,10 +229,12 @@ qint64 AvatarMixerSlave::addChangedTraitsToBulkPacket(AvatarMixerClientData* lis if (bytesWritten) { // write a null trait type to mark the end of trait data for this avatar bytesWritten += traitsPacketList.writePrimitive(AvatarTraits::NullTrait); + // since we send all traits for this other avatar, update the time of last traits sent + // to match the time of last traits change + if (allTraitsUpdated) { + listeningNodeData->setLastOtherAvatarTraitsSendPoint(sendingNodeLocalID, timeOfLastTraitsChange); + } } - // since we send all traits for this other avatar, update the time of last traits sent - // to match the time of last traits change - listeningNodeData->setLastOtherAvatarTraitsSendPoint(otherNodeLocalID, timeOfLastTraitsChange); }