move some Avatar management to AvatarHashMap

This commit is contained in:
Stephen Birarda 2014-04-17 16:37:40 -07:00
parent 7c048b7512
commit e303ce1a12
5 changed files with 115 additions and 103 deletions

View file

@ -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;

View file

@ -127,22 +127,9 @@ void AvatarManager::renderAvatarFades(const glm::vec3& cameraPosition, Avatar::R
}
}
AvatarSharedPointer AvatarManager::matchingOrNewAvatar(const QUuid& sessionUUID, const QWeakPointer<Node>& 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<Node>& mixerWeakPointer) {
reinterpret_cast<Avatar*>(sharedAvatar.data())->setOwningAvatarMixer(mixerWeakPointer);
}
void AvatarManager::processAvatarMixerDatagram(const QByteArray& datagram, const QWeakPointer<Node>& mixerWeakPointer) {
@ -164,87 +151,6 @@ void AvatarManager::processAvatarMixerDatagram(const QByteArray& datagram, const
}
}
void AvatarManager::processAvatarDataPacket(const QByteArray &datagram, const QWeakPointer<Node> &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<Avatar*>(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<Node>& 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<Avatar*>(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<Node>& 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<Avatar*>(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.";

View file

@ -42,12 +42,7 @@ public slots:
private:
AvatarManager(const AvatarManager& other);
AvatarSharedPointer matchingOrNewAvatar(const QUuid& nodeUUID, const QWeakPointer<Node>& mixerWeakPointer);
void processAvatarDataPacket(const QByteArray& packet, const QWeakPointer<Node>& mixerWeakPointer);
void processAvatarIdentityPacket(const QByteArray& packet, const QWeakPointer<Node>& mixerWeakPointer);
void processAvatarBillboardPacket(const QByteArray& packet, const QWeakPointer<Node>& mixerWeakPointer);
void processKillAvatar(const QByteArray& datagram);
void sharedAvatarAddedToHash(const AvatarSharedPointer& sharedAvatar, const QWeakPointer<Node>& mixerWeakPointer);
void simulateAvatarFades(float deltaTime);
void renderAvatarFades(const glm::vec3& cameraPosition, Avatar::RenderMode renderMode);

View file

@ -9,6 +9,8 @@
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
//
#include <PacketHeaders.h>
#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<Node>& 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<Node> &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<Node>& 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<Node>& 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);
}
}

View file

@ -16,6 +16,8 @@
#include <QtCore/QSharedPointer>
#include <QtCore/QUuid>
#include <Node.h>
#include "AvatarData.h"
typedef QSharedPointer<AvatarData> 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<Node>& mixerWeakPointer) = 0;
AvatarSharedPointer matchingOrNewAvatar(const QUuid& nodeUUID, const QWeakPointer<Node>& mixerWeakPointer);
void processAvatarDataPacket(const QByteArray& packet, const QWeakPointer<Node>& mixerWeakPointer);
void processAvatarIdentityPacket(const QByteArray& packet, const QWeakPointer<Node>& mixerWeakPointer);
void processAvatarBillboardPacket(const QByteArray& packet, const QWeakPointer<Node>& mixerWeakPointer);
void processKillAvatar(const QByteArray& datagram);
AvatarHash _avatarHash;
};