From e303ce1a12ca7a6c51010c809101baacaf0085dd Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Thu, 17 Apr 2014 16:37:40 -0700 Subject: [PATCH] move some Avatar management to AvatarHashMap --- interface/src/avatar/Avatar.cpp | 5 ++ interface/src/avatar/AvatarManager.cpp | 100 +----------------------- interface/src/avatar/AvatarManager.h | 7 +- libraries/avatars/src/AvatarHashMap.cpp | 94 ++++++++++++++++++++++ libraries/avatars/src/AvatarHashMap.h | 12 +++ 5 files changed, 115 insertions(+), 103 deletions(-) diff --git a/interface/src/avatar/Avatar.cpp b/interface/src/avatar/Avatar.cpp index e9d804d227..78d5131b77 100644 --- a/interface/src/avatar/Avatar.cpp +++ b/interface/src/avatar/Avatar.cpp @@ -685,6 +685,11 @@ void Avatar::setBillboard(const QByteArray& billboard) { } int Avatar::parseDataAtOffset(const QByteArray& packet, int offset) { + if (!_initialized) { + // now that we have data for this Avatar we are go for init + init(); + } + // change in position implies movement glm::vec3 oldPosition = _position; diff --git a/interface/src/avatar/AvatarManager.cpp b/interface/src/avatar/AvatarManager.cpp index 5798f33d0f..a8d8c8f6e3 100644 --- a/interface/src/avatar/AvatarManager.cpp +++ b/interface/src/avatar/AvatarManager.cpp @@ -127,22 +127,9 @@ void AvatarManager::renderAvatarFades(const glm::vec3& cameraPosition, Avatar::R } } -AvatarSharedPointer AvatarManager::matchingOrNewAvatar(const QUuid& sessionUUID, const QWeakPointer& mixerWeakPointer) { - AvatarSharedPointer matchingAvatar = _avatarHash.value(sessionUUID); - - if (!matchingAvatar) { - // construct a new Avatar for this node - Avatar* avatar = new Avatar(); - avatar->setOwningAvatarMixer(mixerWeakPointer); - - // insert the new avatar into our hash - matchingAvatar = AvatarSharedPointer(avatar); - _avatarHash.insert(sessionUUID, matchingAvatar); - - qDebug() << "Adding avatar with sessionUUID " << sessionUUID << "to AvatarManager hash."; - } - - return matchingAvatar; +void AvatarManager::sharedAvatarAddedToHash(const AvatarSharedPointer& sharedAvatar, + const QWeakPointer& mixerWeakPointer) { + reinterpret_cast(sharedAvatar.data())->setOwningAvatarMixer(mixerWeakPointer); } void AvatarManager::processAvatarMixerDatagram(const QByteArray& datagram, const QWeakPointer& mixerWeakPointer) { @@ -164,87 +151,6 @@ void AvatarManager::processAvatarMixerDatagram(const QByteArray& datagram, const } } -void AvatarManager::processAvatarDataPacket(const QByteArray &datagram, const QWeakPointer &mixerWeakPointer) { - int bytesRead = numBytesForPacketHeader(datagram); - - // enumerate over all of the avatars in this packet - // only add them if mixerWeakPointer points to something (meaning that mixer is still around) - while (bytesRead < datagram.size() && mixerWeakPointer.data()) { - QUuid sessionUUID = QUuid::fromRfc4122(datagram.mid(bytesRead, NUM_BYTES_RFC4122_UUID)); - bytesRead += NUM_BYTES_RFC4122_UUID; - - AvatarSharedPointer matchingAvatarData = matchingOrNewAvatar(sessionUUID, mixerWeakPointer); - - // have the matching (or new) avatar parse the data from the packet - bytesRead += matchingAvatarData->parseDataAtOffset(datagram, bytesRead); - - Avatar* matchingAvatar = reinterpret_cast(matchingAvatarData.data()); - - if (!matchingAvatar->isInitialized()) { - // now that we have AvatarData for this Avatar we are go for init - matchingAvatar->init(); - } - } -} - -void AvatarManager::processAvatarIdentityPacket(const QByteArray &packet, const QWeakPointer& mixerWeakPointer) { - // setup a data stream to parse the packet - QDataStream identityStream(packet); - identityStream.skipRawData(numBytesForPacketHeader(packet)); - - QUuid sessionUUID; - - while (!identityStream.atEnd()) { - - QUrl faceMeshURL, skeletonURL; - QString displayName; - identityStream >> sessionUUID >> faceMeshURL >> skeletonURL >> displayName; - - // mesh URL for a UUID, find avatar in our list - AvatarSharedPointer matchingAvatar = matchingOrNewAvatar(sessionUUID, mixerWeakPointer); - if (matchingAvatar) { - Avatar* avatar = static_cast(matchingAvatar.data()); - - if (avatar->getFaceModelURL() != faceMeshURL) { - avatar->setFaceModelURL(faceMeshURL); - } - - if (avatar->getSkeletonModelURL() != skeletonURL) { - avatar->setSkeletonModelURL(skeletonURL); - } - - if (avatar->getDisplayName() != displayName) { - avatar->setDisplayName(displayName); - } - } - } -} - -void AvatarManager::processAvatarBillboardPacket(const QByteArray& packet, const QWeakPointer& mixerWeakPointer) { - int headerSize = numBytesForPacketHeader(packet); - QUuid sessionUUID = QUuid::fromRfc4122(QByteArray::fromRawData(packet.constData() + headerSize, NUM_BYTES_RFC4122_UUID)); - - AvatarSharedPointer matchingAvatar = matchingOrNewAvatar(sessionUUID, mixerWeakPointer); - if (matchingAvatar) { - Avatar* avatar = static_cast(matchingAvatar.data()); - QByteArray billboard = packet.mid(headerSize + NUM_BYTES_RFC4122_UUID); - if (avatar->getBillboard() != billboard) { - avatar->setBillboard(billboard); - } - } -} - -void AvatarManager::processKillAvatar(const QByteArray& datagram) { - // read the node id - QUuid sessionUUID = QUuid::fromRfc4122(datagram.mid(numBytesForPacketHeader(datagram), NUM_BYTES_RFC4122_UUID)); - - // remove the avatar with that UUID from our hash, if it exists - AvatarHash::iterator matchedAvatar = _avatarHash.find(sessionUUID); - if (matchedAvatar != _avatarHash.end()) { - erase(matchedAvatar); - } -} - AvatarHash::iterator AvatarManager::erase(const AvatarHash::iterator& iterator) { if (iterator.key() != MY_AVATAR_KEY) { qDebug() << "Removing Avatar with UUID" << iterator.key() << "from AvatarManager hash."; diff --git a/interface/src/avatar/AvatarManager.h b/interface/src/avatar/AvatarManager.h index 78491b3a5d..db2bb0b5ac 100644 --- a/interface/src/avatar/AvatarManager.h +++ b/interface/src/avatar/AvatarManager.h @@ -42,12 +42,7 @@ public slots: private: AvatarManager(const AvatarManager& other); - AvatarSharedPointer matchingOrNewAvatar(const QUuid& nodeUUID, const QWeakPointer& mixerWeakPointer); - - void processAvatarDataPacket(const QByteArray& packet, const QWeakPointer& mixerWeakPointer); - void processAvatarIdentityPacket(const QByteArray& packet, const QWeakPointer& mixerWeakPointer); - void processAvatarBillboardPacket(const QByteArray& packet, const QWeakPointer& mixerWeakPointer); - void processKillAvatar(const QByteArray& datagram); + void sharedAvatarAddedToHash(const AvatarSharedPointer& sharedAvatar, const QWeakPointer& mixerWeakPointer); void simulateAvatarFades(float deltaTime); void renderAvatarFades(const glm::vec3& cameraPosition, Avatar::RenderMode renderMode); diff --git a/libraries/avatars/src/AvatarHashMap.cpp b/libraries/avatars/src/AvatarHashMap.cpp index 1c2cd4bf92..e3446637ef 100644 --- a/libraries/avatars/src/AvatarHashMap.cpp +++ b/libraries/avatars/src/AvatarHashMap.cpp @@ -9,6 +9,8 @@ // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // +#include + #include "AvatarHashMap.h" AvatarHashMap::AvatarHashMap() : @@ -25,3 +27,95 @@ AvatarHash::iterator AvatarHashMap::erase(const AvatarHash::iterator& iterator) return _avatarHash.erase(iterator); } +AvatarSharedPointer AvatarHashMap::newSharedAvatar() { + AvatarData* avatarData = new AvatarData(); + return AvatarSharedPointer(avatarData); +} + +AvatarSharedPointer AvatarHashMap::matchingOrNewAvatar(const QUuid& sessionUUID, const QWeakPointer& mixerWeakPointer) { + AvatarSharedPointer matchingAvatar = _avatarHash.value(sessionUUID); + + if (!matchingAvatar) { + // insert the new avatar into our hash + matchingAvatar = newSharedAvatar(); + + qDebug() << "Adding avatar with sessionUUID " << sessionUUID << "to AvatarManager hash."; + _avatarHash.insert(sessionUUID, matchingAvatar); + + sharedAvatarAddedToHash(matchingAvatar, mixerWeakPointer); + } + + return matchingAvatar; +} + +void AvatarHashMap::processAvatarDataPacket(const QByteArray &datagram, const QWeakPointer &mixerWeakPointer) { + int bytesRead = numBytesForPacketHeader(datagram); + + // enumerate over all of the avatars in this packet + // only add them if mixerWeakPointer points to something (meaning that mixer is still around) + while (bytesRead < datagram.size() && mixerWeakPointer.data()) { + QUuid sessionUUID = QUuid::fromRfc4122(datagram.mid(bytesRead, NUM_BYTES_RFC4122_UUID)); + bytesRead += NUM_BYTES_RFC4122_UUID; + + AvatarSharedPointer matchingAvatarData = matchingOrNewAvatar(sessionUUID, mixerWeakPointer); + + // have the matching (or new) avatar parse the data from the packet + bytesRead += matchingAvatarData->parseDataAtOffset(datagram, bytesRead); + } +} + +void AvatarHashMap::processAvatarIdentityPacket(const QByteArray &packet, const QWeakPointer& mixerWeakPointer) { + // setup a data stream to parse the packet + QDataStream identityStream(packet); + identityStream.skipRawData(numBytesForPacketHeader(packet)); + + QUuid sessionUUID; + + while (!identityStream.atEnd()) { + + QUrl faceMeshURL, skeletonURL; + QString displayName; + identityStream >> sessionUUID >> faceMeshURL >> skeletonURL >> displayName; + + // mesh URL for a UUID, find avatar in our list + AvatarSharedPointer matchingAvatar = matchingOrNewAvatar(sessionUUID, mixerWeakPointer); + if (matchingAvatar) { + + if (matchingAvatar->getFaceModelURL() != faceMeshURL) { + matchingAvatar->setFaceModelURL(faceMeshURL); + } + + if (matchingAvatar->getSkeletonModelURL() != skeletonURL) { + matchingAvatar->setSkeletonModelURL(skeletonURL); + } + + if (matchingAvatar->getDisplayName() != displayName) { + matchingAvatar->setDisplayName(displayName); + } + } + } +} + +void AvatarHashMap::processAvatarBillboardPacket(const QByteArray& packet, const QWeakPointer& mixerWeakPointer) { + int headerSize = numBytesForPacketHeader(packet); + QUuid sessionUUID = QUuid::fromRfc4122(QByteArray::fromRawData(packet.constData() + headerSize, NUM_BYTES_RFC4122_UUID)); + + AvatarSharedPointer matchingAvatar = matchingOrNewAvatar(sessionUUID, mixerWeakPointer); + if (matchingAvatar) { + QByteArray billboard = packet.mid(headerSize + NUM_BYTES_RFC4122_UUID); + if (matchingAvatar->getBillboard() != billboard) { + matchingAvatar->setBillboard(billboard); + } + } +} + +void AvatarHashMap::processKillAvatar(const QByteArray& datagram) { + // read the node id + QUuid sessionUUID = QUuid::fromRfc4122(datagram.mid(numBytesForPacketHeader(datagram), NUM_BYTES_RFC4122_UUID)); + + // remove the avatar with that UUID from our hash, if it exists + AvatarHash::iterator matchedAvatar = _avatarHash.find(sessionUUID); + if (matchedAvatar != _avatarHash.end()) { + erase(matchedAvatar); + } +} \ No newline at end of file diff --git a/libraries/avatars/src/AvatarHashMap.h b/libraries/avatars/src/AvatarHashMap.h index aee9cd09f1..c9b318dee8 100644 --- a/libraries/avatars/src/AvatarHashMap.h +++ b/libraries/avatars/src/AvatarHashMap.h @@ -16,6 +16,8 @@ #include #include +#include + #include "AvatarData.h" typedef QSharedPointer AvatarSharedPointer; @@ -32,6 +34,16 @@ public: protected: virtual AvatarHash::iterator erase(const AvatarHash::iterator& iterator); + + virtual AvatarSharedPointer newSharedAvatar(); + virtual void sharedAvatarAddedToHash(const AvatarSharedPointer& sharedAvatar, + const QWeakPointer& mixerWeakPointer) = 0; + AvatarSharedPointer matchingOrNewAvatar(const QUuid& nodeUUID, const QWeakPointer& mixerWeakPointer); + + void processAvatarDataPacket(const QByteArray& packet, const QWeakPointer& mixerWeakPointer); + void processAvatarIdentityPacket(const QByteArray& packet, const QWeakPointer& mixerWeakPointer); + void processAvatarBillboardPacket(const QByteArray& packet, const QWeakPointer& mixerWeakPointer); + void processKillAvatar(const QByteArray& datagram); AvatarHash _avatarHash; };