From e3ad5adcaec07108360e340302cd643c61e4af31 Mon Sep 17 00:00:00 2001 From: luiscuenca Date: Thu, 23 Aug 2018 06:49:35 -0700 Subject: [PATCH 1/7] first approach vertical alignment --- libraries/avatars/src/AvatarData.cpp | 2 +- libraries/avatars/src/AvatarData.h | 4 ++ libraries/avatars/src/AvatarHashMap.cpp | 72 +++++++++++++++++++++++-- libraries/avatars/src/AvatarHashMap.h | 2 + 4 files changed, 74 insertions(+), 6 deletions(-) diff --git a/libraries/avatars/src/AvatarData.cpp b/libraries/avatars/src/AvatarData.cpp index c1ec19b307..63a905aa6e 100644 --- a/libraries/avatars/src/AvatarData.cpp +++ b/libraries/avatars/src/AvatarData.cpp @@ -918,7 +918,7 @@ int AvatarData::parseDataFromBuffer(const QByteArray& buffer) { PACKET_READ_CHECK(AvatarGlobalPosition, sizeof(AvatarDataPacket::AvatarGlobalPosition)); auto data = reinterpret_cast(sourceBuffer); - auto newValue = glm::vec3(data->globalPosition[0], data->globalPosition[1], data->globalPosition[2]); + auto newValue = glm::vec3(data->globalPosition[0], data->globalPosition[1], data->globalPosition[2]) + glm::vec3(0, 2 * _surrogateIndex, 0); if (_globalPosition != newValue) { _globalPosition = newValue; _globalPositionChanged = usecTimestampNow(); diff --git a/libraries/avatars/src/AvatarData.h b/libraries/avatars/src/AvatarData.h index 53a2a69119..b3443dbd8a 100644 --- a/libraries/avatars/src/AvatarData.h +++ b/libraries/avatars/src/AvatarData.h @@ -1186,6 +1186,9 @@ public: virtual void addMaterial(graphics::MaterialLayer material, const std::string& parentMaterialName) {} virtual void removeMaterial(graphics::MaterialPointer material, const std::string& parentMaterialName) {} + void setSurrogateIndex(int surrogateIndex) { _surrogateIndex = surrogateIndex; } + int getSurrogateIndex() { return _surrogateIndex; } + signals: /**jsdoc @@ -1443,6 +1446,7 @@ protected: udt::SequenceNumber _identitySequenceNumber { 0 }; bool _hasProcessedFirstIdentity { false }; float _density; + int _surrogateIndex{ 0 }; // null unless MyAvatar or ScriptableAvatar sending traits data to mixer std::unique_ptr _clientTraitsHandler; diff --git a/libraries/avatars/src/AvatarHashMap.cpp b/libraries/avatars/src/AvatarHashMap.cpp index 64b26131be..a84d83e663 100644 --- a/libraries/avatars/src/AvatarHashMap.cpp +++ b/libraries/avatars/src/AvatarHashMap.cpp @@ -21,6 +21,8 @@ #include "AvatarLogging.h" #include "AvatarTraits.h" +const int SURROGATE_COUNT = 2; + AvatarHashMap::AvatarHashMap() { auto nodeList = DependencyManager::get(); @@ -139,14 +141,37 @@ AvatarSharedPointer AvatarHashMap::parseAvatarData(QSharedPointerisIgnoringNode(sessionUUID) || nodeList->getRequestsDomainListData())) { auto avatar = newOrExistingAvatar(sessionUUID, sendingNode, isNewAvatar); + + if (isNewAvatar) { QWriteLocker locker(&_hashLock); _pendingAvatars.insert(sessionUUID, { std::chrono::steady_clock::now(), 0, avatar }); + std::vector surrogateIDs; + for (int i = 0; i < SURROGATE_COUNT; i++) { + QUuid surrogateID = QUuid::createUuid(); + surrogateIDs.push_back(surrogateID); + auto surrogateAvatar = addAvatar(surrogateID, sendingNode); + surrogateAvatar->setSurrogateIndex(i + 1); + surrogateAvatar->parseDataFromBuffer(byteArray); + _pendingAvatars.insert(surrogateID, { std::chrono::steady_clock::now(), 0, surrogateAvatar }); + } + _surrogates.insert(std::pair>(sessionUUID, surrogateIDs)); + } else { + auto surrogateIDs = _surrogates[sessionUUID]; + for (auto id : surrogateIDs) { + auto surrogateAvatar = newOrExistingAvatar(id, sendingNode, isNewAvatar); + if (!isNewAvatar) { + surrogateAvatar->parseDataFromBuffer(byteArray); + } + } + } // have the matching (or new) avatar parse the data from the packet int bytesRead = avatar->parseDataFromBuffer(byteArray); message->seek(positionBeforeRead + bytesRead); + + avatar->parseDataFromBuffer(byteArray); return avatar; } else { // create a dummy AvatarData class to throw this data on the ground @@ -191,13 +216,22 @@ void AvatarHashMap::processAvatarIdentityPacket(QSharedPointer bool displayNameChanged = false; // In this case, the "sendingNode" is the Avatar Mixer. avatar->processAvatarIdentity(message->getMessage(), identityChanged, displayNameChanged); + auto surrogateIDs = _surrogates[identityUUID]; + for (auto id : surrogateIDs) { + auto surrogateAvatar = newOrExistingAvatar(id, sendingNode, isNewAvatar); + if (!isNewAvatar) { + surrogateAvatar->processAvatarIdentity(message->getMessage(), identityChanged, displayNameChanged); + } + } } } -void AvatarHashMap::processBulkAvatarTraits(QSharedPointer message, SharedNodePointer sendingNode) { +void AvatarHashMap::processAvatarTraits(QUuid sessionUUID, QSharedPointer message, SharedNodePointer sendingNode) { + message->seek(0); while (message->getBytesLeftToRead()) { // read the avatar ID to figure out which avatar this is for auto avatarID = QUuid::fromRfc4122(message->readWithoutCopy(NUM_BYTES_RFC4122_UUID)); + avatarID = sessionUUID; // grab the avatar so we can ask it to process trait data bool isNewAvatar; @@ -225,10 +259,12 @@ void AvatarHashMap::processBulkAvatarTraits(QSharedPointer mess if (packetTraitVersion > lastProcessedVersions[traitType]) { avatar->processTrait(traitType, message->read(traitBinarySize)); lastProcessedVersions[traitType] = packetTraitVersion; - } else { + } + else { skipBinaryTrait = true; } - } else { + } + else { AvatarTraits::TraitInstanceID traitInstanceID = QUuid::fromRfc4122(message->readWithoutCopy(NUM_BYTES_RFC4122_UUID)); @@ -238,11 +274,13 @@ void AvatarHashMap::processBulkAvatarTraits(QSharedPointer mess if (packetTraitVersion > processedInstanceVersion) { if (traitBinarySize == AvatarTraits::DELETED_TRAIT_SIZE) { avatar->processDeletedTraitInstance(traitType, traitInstanceID); - } else { + } + else { avatar->processTraitInstance(traitType, traitInstanceID, message->read(traitBinarySize)); } processedInstanceVersion = packetTraitVersion; - } else { + } + else { skipBinaryTrait = true; } } @@ -258,6 +296,18 @@ void AvatarHashMap::processBulkAvatarTraits(QSharedPointer mess } } +void AvatarHashMap::processBulkAvatarTraits(QSharedPointer message, SharedNodePointer sendingNode) { + while (message->getBytesLeftToRead()) { + // read the avatar ID to figure out which avatar this is for + auto avatarID = QUuid::fromRfc4122(message->readWithoutCopy(NUM_BYTES_RFC4122_UUID)); + processAvatarTraits(avatarID, message, sendingNode); + auto surrogateIDs = _surrogates[avatarID]; + for (auto id : surrogateIDs) { + processAvatarTraits(id, message, sendingNode); + } + } +} + void AvatarHashMap::processKillAvatar(QSharedPointer message, SharedNodePointer sendingNode) { // read the node id QUuid sessionUUID = QUuid::fromRfc4122(message->readWithoutCopy(NUM_BYTES_RFC4122_UUID)); @@ -265,6 +315,10 @@ void AvatarHashMap::processKillAvatar(QSharedPointer message, S KillAvatarReason reason; message->readPrimitive(&reason); removeAvatar(sessionUUID, reason); + auto surrogateIDs = _surrogates[sessionUUID]; + for (auto id : surrogateIDs) { + removeAvatar(id, reason); + } } void AvatarHashMap::removeAvatar(const QUuid& sessionUUID, KillAvatarReason removalReason) { @@ -276,6 +330,14 @@ void AvatarHashMap::removeAvatar(const QUuid& sessionUUID, KillAvatarReason remo if (removedAvatar) { handleRemovedAvatar(removedAvatar, removalReason); } + auto surrogateIDs = _surrogates[sessionUUID]; + for (auto id : surrogateIDs) { + _pendingAvatars.remove(id); + auto removedSurrogate = _avatarHash.take(id); + if (removedSurrogate) { + handleRemovedAvatar(removedSurrogate, removalReason); + } + } } void AvatarHashMap::handleRemovedAvatar(const AvatarSharedPointer& removedAvatar, KillAvatarReason removalReason) { diff --git a/libraries/avatars/src/AvatarHashMap.h b/libraries/avatars/src/AvatarHashMap.h index ba16fa9568..41981df693 100644 --- a/libraries/avatars/src/AvatarHashMap.h +++ b/libraries/avatars/src/AvatarHashMap.h @@ -134,6 +134,7 @@ protected slots: */ void processAvatarIdentityPacket(QSharedPointer message, SharedNodePointer sendingNode); + void processAvatarTraits(QUuid sessionUUID, QSharedPointer message, SharedNodePointer sendingNode); void processBulkAvatarTraits(QSharedPointer message, SharedNodePointer sendingNode); /**jsdoc @@ -167,6 +168,7 @@ protected: mutable QReadWriteLock _hashLock; std::unordered_map _processedTraitVersions; + std::map> _surrogates; private: QUuid _lastOwnerSessionUUID; }; From 3d959ca7ee6c59496f30dc15f6da02f666376166 Mon Sep 17 00:00:00 2001 From: luiscuenca Date: Thu, 23 Aug 2018 15:52:42 -0700 Subject: [PATCH 2/7] Refactoring and cleaning --- .../src/avatars-renderer/Avatar.h | 1 - libraries/avatars/src/AvatarData.cpp | 21 +- libraries/avatars/src/AvatarData.h | 8 +- libraries/avatars/src/AvatarHashMap.cpp | 223 ++++++++++++++---- libraries/avatars/src/AvatarHashMap.h | 23 +- 5 files changed, 223 insertions(+), 53 deletions(-) diff --git a/libraries/avatars-renderer/src/avatars-renderer/Avatar.h b/libraries/avatars-renderer/src/avatars-renderer/Avatar.h index c6e8ac59f1..63aa6d9b6f 100644 --- a/libraries/avatars-renderer/src/avatars-renderer/Avatar.h +++ b/libraries/avatars-renderer/src/avatars-renderer/Avatar.h @@ -464,7 +464,6 @@ protected: glm::vec3 _lastAngularVelocity; glm::vec3 _angularAcceleration; glm::quat _lastOrientation; - glm::vec3 _worldUpDirection { Vectors::UP }; bool _moving { false }; ///< set when position is changing diff --git a/libraries/avatars/src/AvatarData.cpp b/libraries/avatars/src/AvatarData.cpp index 63a905aa6e..ddb53f8acb 100644 --- a/libraries/avatars/src/AvatarData.cpp +++ b/libraries/avatars/src/AvatarData.cpp @@ -918,7 +918,26 @@ int AvatarData::parseDataFromBuffer(const QByteArray& buffer) { PACKET_READ_CHECK(AvatarGlobalPosition, sizeof(AvatarDataPacket::AvatarGlobalPosition)); auto data = reinterpret_cast(sourceBuffer); - auto newValue = glm::vec3(data->globalPosition[0], data->globalPosition[1], data->globalPosition[2]) + glm::vec3(0, 2 * _surrogateIndex, 0); + + const float SPACE_BETWEEN_AVATARS = 2.0f; + const int RANDOM_RADIUS = 100; + const int AVATARS_PER_ROW = 3; + + glm::vec3 offset; + + if (false) { + qsrand(static_cast(getID().toByteArray().toInt())); + float xrand = float((qrand() % ((RANDOM_RADIUS + 1) - 10) + 10) / 10.0f); + float yrand = float((qrand() % ((RANDOM_RADIUS + 1) - 10) + 10) / 10.0f); + offset = glm::vec3(xrand, 0.0f, yrand); + } + else { + int row = _replicaIndex % AVATARS_PER_ROW; + int col = floor(_replicaIndex / AVATARS_PER_ROW); + offset = glm::vec3(row * SPACE_BETWEEN_AVATARS, 0.0f, col * SPACE_BETWEEN_AVATARS); + } + + auto newValue = glm::vec3(data->globalPosition[0], data->globalPosition[1], data->globalPosition[2]) + offset; if (_globalPosition != newValue) { _globalPosition = newValue; _globalPositionChanged = usecTimestampNow(); diff --git a/libraries/avatars/src/AvatarData.h b/libraries/avatars/src/AvatarData.h index b3443dbd8a..36cc0f936d 100644 --- a/libraries/avatars/src/AvatarData.h +++ b/libraries/avatars/src/AvatarData.h @@ -337,6 +337,7 @@ enum KillAvatarReason : uint8_t { TheirAvatarEnteredYourBubble, YourAvatarEnteredTheirBubble }; + Q_DECLARE_METATYPE(KillAvatarReason); class QDataStream; @@ -1185,9 +1186,8 @@ public: virtual void addMaterial(graphics::MaterialLayer material, const std::string& parentMaterialName) {} virtual void removeMaterial(graphics::MaterialPointer material, const std::string& parentMaterialName) {} - - void setSurrogateIndex(int surrogateIndex) { _surrogateIndex = surrogateIndex; } - int getSurrogateIndex() { return _surrogateIndex; } + void setReplicaIndex(int replicaIndex) { _replicaIndex = replicaIndex; } + int getReplicaIndex() { return _replicaIndex; } signals: @@ -1446,7 +1446,7 @@ protected: udt::SequenceNumber _identitySequenceNumber { 0 }; bool _hasProcessedFirstIdentity { false }; float _density; - int _surrogateIndex{ 0 }; + int _replicaIndex { 0 }; // null unless MyAvatar or ScriptableAvatar sending traits data to mixer std::unique_ptr _clientTraitsHandler; diff --git a/libraries/avatars/src/AvatarHashMap.cpp b/libraries/avatars/src/AvatarHashMap.cpp index a84d83e663..800825f574 100644 --- a/libraries/avatars/src/AvatarHashMap.cpp +++ b/libraries/avatars/src/AvatarHashMap.cpp @@ -21,7 +21,80 @@ #include "AvatarLogging.h" #include "AvatarTraits.h" -const int SURROGATE_COUNT = 2; + +void AvatarReplicas::addReplica(const QUuid& parentID, AvatarSharedPointer replica) { + if (_replicasMap.find(parentID) == _replicasMap.end()) { + std::vector emptyReplicas = std::vector(); + _replicasMap.insert(std::pair>(parentID, emptyReplicas)); + } + auto &replicas = _replicasMap[parentID]; + replica->setReplicaIndex((int)replicas.size() + 1); + replicas.push_back(replica); +} + +std::vector AvatarReplicas::getReplicaIDs(const QUuid& parentID, int count) { + std::vector ids; + if (_replicasMap.find(parentID) != _replicasMap.end()) { + auto &replicas = _replicasMap[parentID]; + for (int i = 0; i < replicas.size(); i++) { + ids.push_back(replicas[i]->getID()); + } + } else if (count > 0) { + for (int i = 0; i < count; i++) { + ids.push_back(QUuid::createUuid()); + } + } + return ids; +} + +void AvatarReplicas::parseDataFromBuffer(const QUuid& parentID, const QByteArray& buffer) { + if (_replicasMap.find(parentID) != _replicasMap.end()) { + auto &replicas = _replicasMap[parentID]; + for (auto avatar : replicas) { + avatar->parseDataFromBuffer(buffer); + } + } +} + +void AvatarReplicas::removeReplicas(const QUuid& parentID) { + if (_replicasMap.find(parentID) != _replicasMap.end()) { + _replicasMap.erase(parentID); + } +} + +void AvatarReplicas::processAvatarIdentity(const QUuid& parentID, const QByteArray& identityData, bool& identityChanged, bool& displayNameChanged) { + if (_replicasMap.find(parentID) != _replicasMap.end()) { + auto &replicas = _replicasMap[parentID]; + for (auto avatar : replicas) { + avatar->processAvatarIdentity(identityData, identityChanged, displayNameChanged); + } + } +} +void AvatarReplicas::processTrait(const QUuid& parentID, AvatarTraits::TraitType traitType, QByteArray traitBinaryData) { + if (_replicasMap.find(parentID) != _replicasMap.end()) { + auto &replicas = _replicasMap[parentID]; + for (auto avatar : replicas) { + avatar->processTrait(traitType, traitBinaryData); + } + } +} +void AvatarReplicas::processDeletedTraitInstance(const QUuid& parentID, AvatarTraits::TraitType traitType, AvatarTraits::TraitInstanceID instanceID) { + if (_replicasMap.find(parentID) != _replicasMap.end()) { + auto &replicas = _replicasMap[parentID]; + for (auto avatar : replicas) { + avatar->processDeletedTraitInstance(traitType, instanceID); + } + } +} +void AvatarReplicas::processTraitInstance(const QUuid& parentID, AvatarTraits::TraitType traitType, + AvatarTraits::TraitInstanceID instanceID, QByteArray traitBinaryData) { + if (_replicasMap.find(parentID) != _replicasMap.end()) { + auto &replicas = _replicasMap[parentID]; + for (auto avatar : replicas) { + avatar->processTraitInstance(traitType, instanceID, traitBinaryData); + } + } +} AvatarHashMap::AvatarHashMap() { auto nodeList = DependencyManager::get(); @@ -138,40 +211,28 @@ AvatarSharedPointer AvatarHashMap::parseAvatarData(QSharedPointer(); + const int REPLICAS_COUNT = 8; + bool isNewAvatar; if (sessionUUID != _lastOwnerSessionUUID && (!nodeList->isIgnoringNode(sessionUUID) || nodeList->getRequestsDomainListData())) { auto avatar = newOrExistingAvatar(sessionUUID, sendingNode, isNewAvatar); - - + if (isNewAvatar) { QWriteLocker locker(&_hashLock); _pendingAvatars.insert(sessionUUID, { std::chrono::steady_clock::now(), 0, avatar }); - std::vector surrogateIDs; - for (int i = 0; i < SURROGATE_COUNT; i++) { - QUuid surrogateID = QUuid::createUuid(); - surrogateIDs.push_back(surrogateID); - auto surrogateAvatar = addAvatar(surrogateID, sendingNode); - surrogateAvatar->setSurrogateIndex(i + 1); - surrogateAvatar->parseDataFromBuffer(byteArray); - _pendingAvatars.insert(surrogateID, { std::chrono::steady_clock::now(), 0, surrogateAvatar }); + auto replicaIDs = _replicas.getReplicaIDs(sessionUUID, REPLICAS_COUNT); + for (auto replicaID : replicaIDs) { + auto replicaAvatar = addAvatar(replicaID, sendingNode); + _replicas.addReplica(sessionUUID, replicaAvatar); + _pendingAvatars.insert(replicaID, { std::chrono::steady_clock::now(), 0, replicaAvatar }); } - _surrogates.insert(std::pair>(sessionUUID, surrogateIDs)); - } else { - auto surrogateIDs = _surrogates[sessionUUID]; - for (auto id : surrogateIDs) { - auto surrogateAvatar = newOrExistingAvatar(id, sendingNode, isNewAvatar); - if (!isNewAvatar) { - surrogateAvatar->parseDataFromBuffer(byteArray); - } - } - - } + } // have the matching (or new) avatar parse the data from the packet int bytesRead = avatar->parseDataFromBuffer(byteArray); message->seek(positionBeforeRead + bytesRead); + _replicas.parseDataFromBuffer(sessionUUID, byteArray); - avatar->parseDataFromBuffer(byteArray); return avatar; } else { // create a dummy AvatarData class to throw this data on the ground @@ -216,17 +277,11 @@ void AvatarHashMap::processAvatarIdentityPacket(QSharedPointer bool displayNameChanged = false; // In this case, the "sendingNode" is the Avatar Mixer. avatar->processAvatarIdentity(message->getMessage(), identityChanged, displayNameChanged); - auto surrogateIDs = _surrogates[identityUUID]; - for (auto id : surrogateIDs) { - auto surrogateAvatar = newOrExistingAvatar(id, sendingNode, isNewAvatar); - if (!isNewAvatar) { - surrogateAvatar->processAvatarIdentity(message->getMessage(), identityChanged, displayNameChanged); - } - } + _replicas.processAvatarIdentity(identityUUID, message->getMessage(), identityChanged, displayNameChanged); } } -void AvatarHashMap::processAvatarTraits(QUuid sessionUUID, QSharedPointer message, SharedNodePointer sendingNode) { +void AvatarHashMap::processBulkAvatarTraitsForID(QUuid sessionUUID, QSharedPointer message, SharedNodePointer sendingNode) { message->seek(0); while (message->getBytesLeftToRead()) { // read the avatar ID to figure out which avatar this is for @@ -297,13 +352,88 @@ void AvatarHashMap::processAvatarTraits(QUuid sessionUUID, QSharedPointer message, SharedNodePointer sendingNode) { + /* while (message->getBytesLeftToRead()) { // read the avatar ID to figure out which avatar this is for auto avatarID = QUuid::fromRfc4122(message->readWithoutCopy(NUM_BYTES_RFC4122_UUID)); - processAvatarTraits(avatarID, message, sendingNode); - auto surrogateIDs = _surrogates[avatarID]; - for (auto id : surrogateIDs) { - processAvatarTraits(id, message, sendingNode); + processBulkAvatarTraitsForID(avatarID, message, sendingNode); + auto replicaIDs = _replicas.getReplicaIDs(avatarID); + for (auto id : replicaIDs) { + processBulkAvatarTraitsForID(id, message, sendingNode); + } + } + */ + int position = 0; + while (message->getBytesLeftToRead()) { + // read the avatar ID to figure out which avatar this is for + auto avatarID = QUuid::fromRfc4122(message->readWithoutCopy(NUM_BYTES_RFC4122_UUID)); + + // grab the avatar so we can ask it to process trait data + bool isNewAvatar; + auto avatar = newOrExistingAvatar(avatarID, sendingNode, isNewAvatar); + + // read the first trait type for this avatar + AvatarTraits::TraitType traitType; + message->readPrimitive(&traitType); + + // grab the last trait versions for this avatar + auto& lastProcessedVersions = _processedTraitVersions[avatarID]; + + while (traitType != AvatarTraits::NullTrait) { + AvatarTraits::TraitVersion packetTraitVersion; + message->readPrimitive(&packetTraitVersion); + + AvatarTraits::TraitWireSize traitBinarySize; + bool skipBinaryTrait = false; + + + if (AvatarTraits::isSimpleTrait(traitType)) { + message->readPrimitive(&traitBinarySize); + + // check if this trait version is newer than what we already have for this avatar + if (packetTraitVersion > lastProcessedVersions[traitType]) { + position = message->getPosition(); + avatar->processTrait(traitType, message->read(traitBinarySize)); + message->seek(position); + _replicas.processTrait(avatarID, traitType, message->read(traitBinarySize)); + lastProcessedVersions[traitType] = packetTraitVersion; + } + else { + skipBinaryTrait = true; + } + } + else { + AvatarTraits::TraitInstanceID traitInstanceID = + QUuid::fromRfc4122(message->readWithoutCopy(NUM_BYTES_RFC4122_UUID)); + + message->readPrimitive(&traitBinarySize); + + auto& processedInstanceVersion = lastProcessedVersions.getInstanceValueRef(traitType, traitInstanceID); + if (packetTraitVersion > processedInstanceVersion) { + if (traitBinarySize == AvatarTraits::DELETED_TRAIT_SIZE) { + avatar->processDeletedTraitInstance(traitType, traitInstanceID); + _replicas.processDeletedTraitInstance(avatarID, traitType, traitInstanceID); + } + else { + position = message->getPosition(); + avatar->processTraitInstance(traitType, traitInstanceID, message->read(traitBinarySize)); + message->seek(position); + _replicas.processTraitInstance(avatarID, traitType, traitInstanceID, message->read(traitBinarySize)); + } + processedInstanceVersion = packetTraitVersion; + } + else { + skipBinaryTrait = true; + } + } + + if (skipBinaryTrait) { + // we didn't read this trait because it was older or because we didn't have an avatar to process it for + message->seek(message->getPosition() + traitBinarySize); + } + + // read the next trait type, which is null if there are no more traits for this avatar + message->readPrimitive(&traitType); } } } @@ -315,8 +445,8 @@ void AvatarHashMap::processKillAvatar(QSharedPointer message, S KillAvatarReason reason; message->readPrimitive(&reason); removeAvatar(sessionUUID, reason); - auto surrogateIDs = _surrogates[sessionUUID]; - for (auto id : surrogateIDs) { + auto replicaIDs = _replicas.getReplicaIDs(sessionUUID); + for (auto id : replicaIDs) { removeAvatar(id, reason); } } @@ -324,20 +454,23 @@ void AvatarHashMap::processKillAvatar(QSharedPointer message, S void AvatarHashMap::removeAvatar(const QUuid& sessionUUID, KillAvatarReason removalReason) { QWriteLocker locker(&_hashLock); + auto replicaIDs = _replicas.getReplicaIDs(sessionUUID); + _replicas.removeReplicas(sessionUUID); + for (auto id : replicaIDs) { + _pendingAvatars.remove(id); + auto removedReplica = _avatarHash.take(id); + if (removedReplica) { + handleRemovedAvatar(removedReplica, removalReason); + } + } + _pendingAvatars.remove(sessionUUID); auto removedAvatar = _avatarHash.take(sessionUUID); if (removedAvatar) { handleRemovedAvatar(removedAvatar, removalReason); } - auto surrogateIDs = _surrogates[sessionUUID]; - for (auto id : surrogateIDs) { - _pendingAvatars.remove(id); - auto removedSurrogate = _avatarHash.take(id); - if (removedSurrogate) { - handleRemovedAvatar(removedSurrogate, removalReason); - } - } + } void AvatarHashMap::handleRemovedAvatar(const AvatarSharedPointer& removedAvatar, KillAvatarReason removalReason) { diff --git a/libraries/avatars/src/AvatarHashMap.h b/libraries/avatars/src/AvatarHashMap.h index 41981df693..2d8d7f907f 100644 --- a/libraries/avatars/src/AvatarHashMap.h +++ b/libraries/avatars/src/AvatarHashMap.h @@ -41,6 +41,24 @@ * @hifi-assignment-client */ +class AvatarReplicas { +public: + AvatarReplicas() {}; + void addReplica(const QUuid& parentID, AvatarSharedPointer replica); + std::vector getReplicaIDs(const QUuid& parentID, int count = 0); + void parseDataFromBuffer(const QUuid& parentID, const QByteArray& buffer); + void processAvatarIdentity(const QUuid& parentID, const QByteArray& identityData, bool& identityChanged, bool& displayNameChanged); + void removeReplicas(const QUuid& parentID); + void processTrait(const QUuid& parentID, AvatarTraits::TraitType traitType, QByteArray traitBinaryData); + void processDeletedTraitInstance(const QUuid& parentID, AvatarTraits::TraitType traitType, AvatarTraits::TraitInstanceID instanceID); + void processTraitInstance(const QUuid& parentID, AvatarTraits::TraitType traitType, + AvatarTraits::TraitInstanceID instanceID, QByteArray traitBinaryData); + +private: + std::map> _replicasMap; +}; + + class AvatarHashMap : public QObject, public Dependency { Q_OBJECT SINGLETON_DEPENDENCY @@ -134,7 +152,7 @@ protected slots: */ void processAvatarIdentityPacket(QSharedPointer message, SharedNodePointer sendingNode); - void processAvatarTraits(QUuid sessionUUID, QSharedPointer message, SharedNodePointer sendingNode); + void processBulkAvatarTraitsForID(QUuid sessionUUID, QSharedPointer message, SharedNodePointer sendingNode); void processBulkAvatarTraits(QSharedPointer message, SharedNodePointer sendingNode); /**jsdoc @@ -168,7 +186,8 @@ protected: mutable QReadWriteLock _hashLock; std::unordered_map _processedTraitVersions; - std::map> _surrogates; + AvatarReplicas _replicas; + private: QUuid _lastOwnerSessionUUID; }; From 1fd0d7da94c3cca2f4dc367cc41f8e84eed1f072 Mon Sep 17 00:00:00 2001 From: luiscuenca Date: Thu, 23 Aug 2018 18:03:27 -0700 Subject: [PATCH 3/7] Create API call --- libraries/avatars/src/AvatarHashMap.cpp | 24 +++++++++++++++++------- libraries/avatars/src/AvatarHashMap.h | 12 ++++++++++-- 2 files changed, 27 insertions(+), 9 deletions(-) diff --git a/libraries/avatars/src/AvatarHashMap.cpp b/libraries/avatars/src/AvatarHashMap.cpp index 800825f574..6949efc19c 100644 --- a/libraries/avatars/src/AvatarHashMap.cpp +++ b/libraries/avatars/src/AvatarHashMap.cpp @@ -32,15 +32,15 @@ void AvatarReplicas::addReplica(const QUuid& parentID, AvatarSharedPointer repli replicas.push_back(replica); } -std::vector AvatarReplicas::getReplicaIDs(const QUuid& parentID, int count) { +std::vector AvatarReplicas::getReplicaIDs(const QUuid& parentID) { std::vector ids; if (_replicasMap.find(parentID) != _replicasMap.end()) { auto &replicas = _replicasMap[parentID]; for (int i = 0; i < replicas.size(); i++) { ids.push_back(replicas[i]->getID()); } - } else if (count > 0) { - for (int i = 0; i < count; i++) { + } else if (_replicaCount > 0) { + for (int i = 0; i < _replicaCount; i++) { ids.push_back(QUuid::createUuid()); } } @@ -139,6 +139,19 @@ bool AvatarHashMap::isAvatarInRange(const glm::vec3& position, const float range return false; } +void AvatarHashMap::setReplicaCount(int count) { + _replicas.setReplicaCount(count); + auto avatars = getAvatarIdentifiers(); + for (int i = 0; i < avatars.size(); i++) { + KillAvatarReason reason = KillAvatarReason::NoReason; + removeAvatar(avatars[i], reason); + auto replicaIDs = _replicas.getReplicaIDs(avatars[i]); + for (auto id : replicaIDs) { + removeAvatar(id, reason); + } + } +} + int AvatarHashMap::numberOfAvatarsInRange(const glm::vec3& position, float rangeMeters) { auto hashCopy = getHashCopy(); auto rangeMeters2 = rangeMeters * rangeMeters; @@ -210,9 +223,6 @@ AvatarSharedPointer AvatarHashMap::parseAvatarData(QSharedPointer(); - - const int REPLICAS_COUNT = 8; - bool isNewAvatar; if (sessionUUID != _lastOwnerSessionUUID && (!nodeList->isIgnoringNode(sessionUUID) || nodeList->getRequestsDomainListData())) { auto avatar = newOrExistingAvatar(sessionUUID, sendingNode, isNewAvatar); @@ -220,7 +230,7 @@ AvatarSharedPointer AvatarHashMap::parseAvatarData(QSharedPointer getReplicaIDs(const QUuid& parentID, int count = 0); + std::vector getReplicaIDs(const QUuid& parentID); void parseDataFromBuffer(const QUuid& parentID, const QByteArray& buffer); void processAvatarIdentity(const QUuid& parentID, const QByteArray& identityData, bool& identityChanged, bool& displayNameChanged); void removeReplicas(const QUuid& parentID); @@ -53,9 +53,11 @@ public: void processDeletedTraitInstance(const QUuid& parentID, AvatarTraits::TraitType traitType, AvatarTraits::TraitInstanceID instanceID); void processTraitInstance(const QUuid& parentID, AvatarTraits::TraitType traitType, AvatarTraits::TraitInstanceID instanceID, QByteArray traitBinaryData); + void setReplicaCount(int count) { _replicaCount = count; } private: std::map> _replicasMap; + int _replicaCount; }; @@ -92,6 +94,12 @@ public: // Null/Default-constructed QUuids will return MyAvatar Q_INVOKABLE virtual ScriptAvatarData* getAvatar(QUuid avatarID) { return new ScriptAvatarData(getAvatarBySessionID(avatarID)); } + /**jsdoc + * @function AvatarList.setReplicaCount + * @param {number} count // The times an avatar will get replicated + */ + Q_INVOKABLE void setReplicaCount(int count); + virtual AvatarSharedPointer getAvatarBySessionID(const QUuid& sessionID) const { return findAvatar(sessionID); } int numberOfAvatarsInRange(const glm::vec3& position, float rangeMeters); From 5654acf5bf28c9476402a1bc6a2cb4ef3545bf07 Mon Sep 17 00:00:00 2001 From: luiscuenca Date: Fri, 24 Aug 2018 09:24:58 -0700 Subject: [PATCH 4/7] Fix warnings --- libraries/avatars/src/AvatarHashMap.cpp | 99 ++----------------------- libraries/avatars/src/AvatarHashMap.h | 8 +- 2 files changed, 15 insertions(+), 92 deletions(-) diff --git a/libraries/avatars/src/AvatarHashMap.cpp b/libraries/avatars/src/AvatarHashMap.cpp index 6949efc19c..67cc9f0563 100644 --- a/libraries/avatars/src/AvatarHashMap.cpp +++ b/libraries/avatars/src/AvatarHashMap.cpp @@ -36,7 +36,7 @@ std::vector AvatarReplicas::getReplicaIDs(const QUuid& parentID) { std::vector ids; if (_replicasMap.find(parentID) != _replicasMap.end()) { auto &replicas = _replicasMap[parentID]; - for (int i = 0; i < replicas.size(); i++) { + for (int i = 0; i < (int)replicas.size(); i++) { ids.push_back(replicas[i]->getID()); } } else if (_replicaCount > 0) { @@ -288,92 +288,12 @@ void AvatarHashMap::processAvatarIdentityPacket(QSharedPointer // In this case, the "sendingNode" is the Avatar Mixer. avatar->processAvatarIdentity(message->getMessage(), identityChanged, displayNameChanged); _replicas.processAvatarIdentity(identityUUID, message->getMessage(), identityChanged, displayNameChanged); - } -} -void AvatarHashMap::processBulkAvatarTraitsForID(QUuid sessionUUID, QSharedPointer message, SharedNodePointer sendingNode) { - message->seek(0); - while (message->getBytesLeftToRead()) { - // read the avatar ID to figure out which avatar this is for - auto avatarID = QUuid::fromRfc4122(message->readWithoutCopy(NUM_BYTES_RFC4122_UUID)); - avatarID = sessionUUID; - - // grab the avatar so we can ask it to process trait data - bool isNewAvatar; - auto avatar = newOrExistingAvatar(avatarID, sendingNode, isNewAvatar); - - // read the first trait type for this avatar - AvatarTraits::TraitType traitType; - message->readPrimitive(&traitType); - - // grab the last trait versions for this avatar - auto& lastProcessedVersions = _processedTraitVersions[avatarID]; - - while (traitType != AvatarTraits::NullTrait) { - AvatarTraits::TraitVersion packetTraitVersion; - message->readPrimitive(&packetTraitVersion); - - AvatarTraits::TraitWireSize traitBinarySize; - bool skipBinaryTrait = false; - - - if (AvatarTraits::isSimpleTrait(traitType)) { - message->readPrimitive(&traitBinarySize); - - // check if this trait version is newer than what we already have for this avatar - if (packetTraitVersion > lastProcessedVersions[traitType]) { - avatar->processTrait(traitType, message->read(traitBinarySize)); - lastProcessedVersions[traitType] = packetTraitVersion; - } - else { - skipBinaryTrait = true; - } - } - else { - AvatarTraits::TraitInstanceID traitInstanceID = - QUuid::fromRfc4122(message->readWithoutCopy(NUM_BYTES_RFC4122_UUID)); - - message->readPrimitive(&traitBinarySize); - - auto& processedInstanceVersion = lastProcessedVersions.getInstanceValueRef(traitType, traitInstanceID); - if (packetTraitVersion > processedInstanceVersion) { - if (traitBinarySize == AvatarTraits::DELETED_TRAIT_SIZE) { - avatar->processDeletedTraitInstance(traitType, traitInstanceID); - } - else { - avatar->processTraitInstance(traitType, traitInstanceID, message->read(traitBinarySize)); - } - processedInstanceVersion = packetTraitVersion; - } - else { - skipBinaryTrait = true; - } - } - - if (skipBinaryTrait) { - // we didn't read this trait because it was older or because we didn't have an avatar to process it for - message->seek(message->getPosition() + traitBinarySize); - } - - // read the next trait type, which is null if there are no more traits for this avatar - message->readPrimitive(&traitType); - } } } void AvatarHashMap::processBulkAvatarTraits(QSharedPointer message, SharedNodePointer sendingNode) { - /* - while (message->getBytesLeftToRead()) { - // read the avatar ID to figure out which avatar this is for - auto avatarID = QUuid::fromRfc4122(message->readWithoutCopy(NUM_BYTES_RFC4122_UUID)); - processBulkAvatarTraitsForID(avatarID, message, sendingNode); - auto replicaIDs = _replicas.getReplicaIDs(avatarID); - for (auto id : replicaIDs) { - processBulkAvatarTraitsForID(id, message, sendingNode); - } - } - */ - int position = 0; + while (message->getBytesLeftToRead()) { // read the avatar ID to figure out which avatar this is for auto avatarID = QUuid::fromRfc4122(message->readWithoutCopy(NUM_BYTES_RFC4122_UUID)); @@ -381,7 +301,6 @@ void AvatarHashMap::processBulkAvatarTraits(QSharedPointer mess // grab the avatar so we can ask it to process trait data bool isNewAvatar; auto avatar = newOrExistingAvatar(avatarID, sendingNode, isNewAvatar); - // read the first trait type for this avatar AvatarTraits::TraitType traitType; message->readPrimitive(&traitType); @@ -402,10 +321,9 @@ void AvatarHashMap::processBulkAvatarTraits(QSharedPointer mess // check if this trait version is newer than what we already have for this avatar if (packetTraitVersion > lastProcessedVersions[traitType]) { - position = message->getPosition(); - avatar->processTrait(traitType, message->read(traitBinarySize)); - message->seek(position); - _replicas.processTrait(avatarID, traitType, message->read(traitBinarySize)); + auto traitData = message->read(traitBinarySize); + avatar->processTrait(traitType, traitData); + _replicas.processTrait(avatarID, traitType, traitData); lastProcessedVersions[traitType] = packetTraitVersion; } else { @@ -425,10 +343,9 @@ void AvatarHashMap::processBulkAvatarTraits(QSharedPointer mess _replicas.processDeletedTraitInstance(avatarID, traitType, traitInstanceID); } else { - position = message->getPosition(); - avatar->processTraitInstance(traitType, traitInstanceID, message->read(traitBinarySize)); - message->seek(position); - _replicas.processTraitInstance(avatarID, traitType, traitInstanceID, message->read(traitBinarySize)); + auto traitData = message->read(traitBinarySize); + avatar->processTraitInstance(traitType, traitInstanceID, traitData); + _replicas.processTraitInstance(avatarID, traitType, traitInstanceID, traitData); } processedInstanceVersion = packetTraitVersion; } diff --git a/libraries/avatars/src/AvatarHashMap.h b/libraries/avatars/src/AvatarHashMap.h index b7199d25ac..97c54e1787 100644 --- a/libraries/avatars/src/AvatarHashMap.h +++ b/libraries/avatars/src/AvatarHashMap.h @@ -54,6 +54,7 @@ public: void processTraitInstance(const QUuid& parentID, AvatarTraits::TraitType traitType, AvatarTraits::TraitInstanceID instanceID, QByteArray traitBinaryData); void setReplicaCount(int count) { _replicaCount = count; } + int getReplicaCount() { return _replicaCount; } private: std::map> _replicasMap; @@ -99,6 +100,12 @@ public: * @param {number} count // The times an avatar will get replicated */ Q_INVOKABLE void setReplicaCount(int count); + + /**jsdoc + * @function AvatarList.setReplicaCount + * @param {number} count // The times an avatar will get replicated + */ + Q_INVOKABLE int getReplicaCount() { return _replicas.getReplicaCount(); }; virtual AvatarSharedPointer getAvatarBySessionID(const QUuid& sessionID) const { return findAvatar(sessionID); } int numberOfAvatarsInRange(const glm::vec3& position, float rangeMeters); @@ -160,7 +167,6 @@ protected slots: */ void processAvatarIdentityPacket(QSharedPointer message, SharedNodePointer sendingNode); - void processBulkAvatarTraitsForID(QUuid sessionUUID, QSharedPointer message, SharedNodePointer sendingNode); void processBulkAvatarTraits(QSharedPointer message, SharedNodePointer sendingNode); /**jsdoc From ddbadf5a6936e29a426bd862ffca06129cfd1fac Mon Sep 17 00:00:00 2001 From: luiscuenca Date: Fri, 24 Aug 2018 11:59:46 -0700 Subject: [PATCH 5/7] change to Test API --- interface/src/Application.h | 3 +++ .../src/scripting/TestScriptingInterface.cpp | 8 ++++++++ interface/src/scripting/TestScriptingInterface.h | 14 ++++++++++++++ libraries/avatars/src/AvatarHashMap.h | 15 +++------------ 4 files changed, 28 insertions(+), 12 deletions(-) diff --git a/interface/src/Application.h b/interface/src/Application.h index 742cf075f6..0d4417cd91 100644 --- a/interface/src/Application.h +++ b/interface/src/Application.h @@ -311,6 +311,9 @@ public: Q_INVOKABLE void copyToClipboard(const QString& text); + int getOtherAvatarsReplicaCount() { return DependencyManager::get()->getReplicaCount(); } + void setOtherAvatarsReplicaCount(int count) { DependencyManager::get()->setReplicaCount(count); } + #if defined(Q_OS_ANDROID) void beforeEnterBackground(); void enterBackground(); diff --git a/interface/src/scripting/TestScriptingInterface.cpp b/interface/src/scripting/TestScriptingInterface.cpp index 430441226f..52f6a3ebc0 100644 --- a/interface/src/scripting/TestScriptingInterface.cpp +++ b/interface/src/scripting/TestScriptingInterface.cpp @@ -190,4 +190,12 @@ void TestScriptingInterface::saveObject(QVariant variant, const QString& filenam void TestScriptingInterface::showMaximized() { qApp->getWindow()->showMaximized(); +} + +void TestScriptingInterface::setOtherAvatarsReplicaCount(int count) { + qApp->setOtherAvatarsReplicaCount(count); +} + +int TestScriptingInterface::getOtherAvatarsReplicaCount() { + return qApp->getOtherAvatarsReplicaCount(); } \ No newline at end of file diff --git a/interface/src/scripting/TestScriptingInterface.h b/interface/src/scripting/TestScriptingInterface.h index c47e39d1f3..4a1d1a3eeb 100644 --- a/interface/src/scripting/TestScriptingInterface.h +++ b/interface/src/scripting/TestScriptingInterface.h @@ -149,6 +149,20 @@ public slots: */ void showMaximized(); + /**jsdoc + * Values higher than 0 will create replicas of other-avatars when entering a domain for testing purpouses + * @function Test.setOtherAvatarsReplicaCount + * @param {number} count - Number of replicas we want to create + */ + Q_INVOKABLE void setOtherAvatarsReplicaCount(int count); + + /**jsdoc + * Return the number of replicas that are being created of other-avatars when entering a domain + * @function Test.getOtherAvatarsReplicaCount + * @returns {number} Current number of replicas of other-avatars. + */ + Q_INVOKABLE int getOtherAvatarsReplicaCount(); + private: bool waitForCondition(qint64 maxWaitMs, std::function condition); QString _testResultsLocation; diff --git a/libraries/avatars/src/AvatarHashMap.h b/libraries/avatars/src/AvatarHashMap.h index 97c54e1787..e4e197a080 100644 --- a/libraries/avatars/src/AvatarHashMap.h +++ b/libraries/avatars/src/AvatarHashMap.h @@ -95,21 +95,12 @@ public: // Null/Default-constructed QUuids will return MyAvatar Q_INVOKABLE virtual ScriptAvatarData* getAvatar(QUuid avatarID) { return new ScriptAvatarData(getAvatarBySessionID(avatarID)); } - /**jsdoc - * @function AvatarList.setReplicaCount - * @param {number} count // The times an avatar will get replicated - */ - Q_INVOKABLE void setReplicaCount(int count); - - /**jsdoc - * @function AvatarList.setReplicaCount - * @param {number} count // The times an avatar will get replicated - */ - Q_INVOKABLE int getReplicaCount() { return _replicas.getReplicaCount(); }; - virtual AvatarSharedPointer getAvatarBySessionID(const QUuid& sessionID) const { return findAvatar(sessionID); } int numberOfAvatarsInRange(const glm::vec3& position, float rangeMeters); + void setReplicaCount(int count); + int getReplicaCount() { return _replicas.getReplicaCount(); }; + signals: /**jsdoc From 8ede6f1cd09cf2ed33a006fa9629dae134fe0d5f Mon Sep 17 00:00:00 2001 From: luiscuenca Date: Mon, 27 Aug 2018 06:55:52 -0700 Subject: [PATCH 6/7] Fix removing my avatar and code standards --- libraries/avatars/src/AvatarData.cpp | 16 ++++----------- libraries/avatars/src/AvatarHashMap.cpp | 26 ++++++++++++------------- libraries/avatars/src/AvatarHashMap.h | 4 ++-- 3 files changed, 19 insertions(+), 27 deletions(-) diff --git a/libraries/avatars/src/AvatarData.cpp b/libraries/avatars/src/AvatarData.cpp index ddb53f8acb..5e1094276c 100644 --- a/libraries/avatars/src/AvatarData.cpp +++ b/libraries/avatars/src/AvatarData.cpp @@ -919,19 +919,11 @@ int AvatarData::parseDataFromBuffer(const QByteArray& buffer) { PACKET_READ_CHECK(AvatarGlobalPosition, sizeof(AvatarDataPacket::AvatarGlobalPosition)); auto data = reinterpret_cast(sourceBuffer); - const float SPACE_BETWEEN_AVATARS = 2.0f; - const int RANDOM_RADIUS = 100; - const int AVATARS_PER_ROW = 3; + glm::vec3 offset = glm::vec3(0.0f, 0.0f, 0.0f); - glm::vec3 offset; - - if (false) { - qsrand(static_cast(getID().toByteArray().toInt())); - float xrand = float((qrand() % ((RANDOM_RADIUS + 1) - 10) + 10) / 10.0f); - float yrand = float((qrand() % ((RANDOM_RADIUS + 1) - 10) + 10) / 10.0f); - offset = glm::vec3(xrand, 0.0f, yrand); - } - else { + if (_replicaIndex > 0) { + const float SPACE_BETWEEN_AVATARS = 2.0f; + const int AVATARS_PER_ROW = 3; int row = _replicaIndex % AVATARS_PER_ROW; int col = floor(_replicaIndex / AVATARS_PER_ROW); offset = glm::vec3(row * SPACE_BETWEEN_AVATARS, 0.0f, col * SPACE_BETWEEN_AVATARS); diff --git a/libraries/avatars/src/AvatarHashMap.cpp b/libraries/avatars/src/AvatarHashMap.cpp index 67cc9f0563..8dfee3551e 100644 --- a/libraries/avatars/src/AvatarHashMap.cpp +++ b/libraries/avatars/src/AvatarHashMap.cpp @@ -23,6 +23,9 @@ void AvatarReplicas::addReplica(const QUuid& parentID, AvatarSharedPointer replica) { + if (parentID == QUuid()) { + return; + } if (_replicasMap.find(parentID) == _replicasMap.end()) { std::vector emptyReplicas = std::vector(); _replicasMap.insert(std::pair>(parentID, emptyReplicas)); @@ -144,10 +147,12 @@ void AvatarHashMap::setReplicaCount(int count) { auto avatars = getAvatarIdentifiers(); for (int i = 0; i < avatars.size(); i++) { KillAvatarReason reason = KillAvatarReason::NoReason; - removeAvatar(avatars[i], reason); - auto replicaIDs = _replicas.getReplicaIDs(avatars[i]); - for (auto id : replicaIDs) { - removeAvatar(id, reason); + if (avatars[i] != QUuid()) { + removeAvatar(avatars[i], reason); + auto replicaIDs = _replicas.getReplicaIDs(avatars[i]); + for (auto id : replicaIDs) { + removeAvatar(id, reason); + } } } } @@ -315,7 +320,6 @@ void AvatarHashMap::processBulkAvatarTraits(QSharedPointer mess AvatarTraits::TraitWireSize traitBinarySize; bool skipBinaryTrait = false; - if (AvatarTraits::isSimpleTrait(traitType)) { message->readPrimitive(&traitBinarySize); @@ -325,12 +329,10 @@ void AvatarHashMap::processBulkAvatarTraits(QSharedPointer mess avatar->processTrait(traitType, traitData); _replicas.processTrait(avatarID, traitType, traitData); lastProcessedVersions[traitType] = packetTraitVersion; - } - else { + } else { skipBinaryTrait = true; } - } - else { + } else { AvatarTraits::TraitInstanceID traitInstanceID = QUuid::fromRfc4122(message->readWithoutCopy(NUM_BYTES_RFC4122_UUID)); @@ -341,15 +343,13 @@ void AvatarHashMap::processBulkAvatarTraits(QSharedPointer mess if (traitBinarySize == AvatarTraits::DELETED_TRAIT_SIZE) { avatar->processDeletedTraitInstance(traitType, traitInstanceID); _replicas.processDeletedTraitInstance(avatarID, traitType, traitInstanceID); - } - else { + } else { auto traitData = message->read(traitBinarySize); avatar->processTraitInstance(traitType, traitInstanceID, traitData); _replicas.processTraitInstance(avatarID, traitType, traitInstanceID, traitData); } processedInstanceVersion = packetTraitVersion; - } - else { + } else { skipBinaryTrait = true; } } diff --git a/libraries/avatars/src/AvatarHashMap.h b/libraries/avatars/src/AvatarHashMap.h index e4e197a080..0f847b2a61 100644 --- a/libraries/avatars/src/AvatarHashMap.h +++ b/libraries/avatars/src/AvatarHashMap.h @@ -43,7 +43,7 @@ class AvatarReplicas { public: - AvatarReplicas() : _replicaCount(0) {} + AvatarReplicas() {} void addReplica(const QUuid& parentID, AvatarSharedPointer replica); std::vector getReplicaIDs(const QUuid& parentID); void parseDataFromBuffer(const QUuid& parentID, const QByteArray& buffer); @@ -58,7 +58,7 @@ public: private: std::map> _replicasMap; - int _replicaCount; + int _replicaCount { 0 }; }; From c19bd8968ad315df6abdfc336ba58fcafe47e041 Mon Sep 17 00:00:00 2001 From: luiscuenca Date: Mon, 27 Aug 2018 16:48:47 -0700 Subject: [PATCH 7/7] Fix mixer crash --- libraries/avatars/src/AvatarHashMap.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/libraries/avatars/src/AvatarHashMap.cpp b/libraries/avatars/src/AvatarHashMap.cpp index 8dfee3551e..c437b56f32 100644 --- a/libraries/avatars/src/AvatarHashMap.cpp +++ b/libraries/avatars/src/AvatarHashMap.cpp @@ -239,7 +239,6 @@ AvatarSharedPointer AvatarHashMap::parseAvatarData(QSharedPointer