Add new packet processing to AvatarManager

This commit is contained in:
Ryan Huffman 2015-07-08 15:06:50 -07:00
parent c365ea60ad
commit 1b5d526444
4 changed files with 44 additions and 58 deletions

View file

@ -66,12 +66,6 @@ AvatarManager::AvatarManager(QObject* parent) :
// register a meta type for the weak pointer we'll use for the owning avatar mixer for each avatar
qRegisterMetaType<QWeakPointer<Node> >("NodeWeakPointer");
_myAvatar = std::make_shared<MyAvatar>();
auto& packetReceiver = DependencyManager::get<NodeList>()->getPacketReceiver();
packetReceiver.registerPacketListener(PacketType::BulkAvatarData, this, ...);
packetReceiver.registerPacketListener(PacketType::KillAvatar, this, ...);
packetReceiver.registerPacketListener(PacketType::AvatarIdentity, this, ...);
packetReceiver.registerPacketListener(PacketType::AvatarBillboard, this, ...);
}
void AvatarManager::init() {

View file

@ -18,25 +18,13 @@
AvatarHashMap::AvatarHashMap() {
connect(DependencyManager::get<NodeList>().data(), &NodeList::uuidChanged, this, &AvatarHashMap::sessionUUIDChanged);
}
void AvatarHashMap::processAvatarMixerDatagram(const QByteArray& datagram, const QWeakPointer<Node>& mixerWeakPointer) {
switch (packetTypeForPacket(datagram)) {
case PacketType::BulkAvatarData:
processAvatarDataPacket(datagram, mixerWeakPointer);
break;
case PacketType::AvatarIdentity:
processAvatarIdentityPacket(datagram, mixerWeakPointer);
break;
case PacketType::AvatarBillboard:
processAvatarBillboardPacket(datagram, mixerWeakPointer);
break;
case PacketType::KillAvatar:
processKillAvatar(datagram);
break;
default:
break;
}
auto& packetReceiver = DependencyManager::get<NodeList>()->getPacketReceiver();
packetReceiver.registerPacketListener(PacketType::BulkAvatarData, this, "processAvatarDataPacket");
packetReceiver.registerPacketListener(PacketType::KillAvatar, this, "processKillAvatar");
packetReceiver.registerPacketListener(PacketType::AvatarIdentity, this, "processAvatarIdentityPacket");
packetReceiver.registerPacketListener(PacketType::AvatarBillboard, this, "processAvatarBillboardPacket");
}
bool AvatarHashMap::isAvatarInRange(const glm::vec3& position, const float range) {
@ -65,86 +53,89 @@ AvatarSharedPointer AvatarHashMap::addAvatar(const QUuid& sessionUUID, const QWe
return avatar;
}
void AvatarHashMap::processAvatarDataPacket(const QByteArray &datagram, const QWeakPointer<Node> &mixerWeakPointer) {
int bytesRead = numBytesForPacketHeader(datagram);
void AvatarHashMap::processAvatarDataPacket(std::unique_ptr<NLPacket> packet, HifiSockAddr senderSockAddr) {
const auto data = QByteArray::fromRawData(packet->getPayload(), packet->size);
int bytesRead = 0;
SharedNodePointer avatarMixer = DependencyManager::get<NodeList>()->nodeWithUUID(packet->getSourceID());
// 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));
while (bytesRead < data.size() && avatarMixer.data()) {
QUuid sessionUUID = QUuid::fromRfc4122(data.mid(bytesRead, NUM_BYTES_RFC4122_UUID));
bytesRead += NUM_BYTES_RFC4122_UUID;
if (sessionUUID != _lastOwnerSessionUUID) {
AvatarSharedPointer avatar = _avatarHash.value(sessionUUID);
if (!avatar) {
avatar = addAvatar(sessionUUID, mixerWeakPointer);
avatar = addAvatar(sessionUUID, avatarMixer);
}
// have the matching (or new) avatar parse the data from the packet
bytesRead += avatar->parseDataAtOffset(datagram, bytesRead);
bytesRead += avatar->parseDataAtOffset(data, bytesRead);
} else {
// create a dummy AvatarData class to throw this data on the ground
AvatarData dummyData;
bytesRead += dummyData.parseDataAtOffset(datagram, bytesRead);
bytesRead += dummyData.parseDataAtOffset(data, bytesRead);
}
}
}
void AvatarHashMap::processAvatarIdentityPacket(const QByteArray &packet, const QWeakPointer<Node>& mixerWeakPointer) {
void AvatarHashMap::processAvatarIdentityPacket(std::unique_ptr<NLPacket> packet, HifiSockAddr senderSockAddr) {
// setup a data stream to parse the packet
QDataStream identityStream(packet);
identityStream.skipRawData(numBytesForPacketHeader(packet));
QDataStream identityStream { packet.get() };
QUuid sessionUUID;
while (!identityStream.atEnd()) {
QUrl faceMeshURL, skeletonURL;
QVector<AttachmentData> attachmentData;
QString displayName;
identityStream >> sessionUUID >> faceMeshURL >> skeletonURL >> attachmentData >> displayName;
// mesh URL for a UUID, find avatar in our list
AvatarSharedPointer avatar = _avatarHash.value(sessionUUID);
if (!avatar) {
avatar = addAvatar(sessionUUID, mixerWeakPointer);
SharedNodePointer avatarMixer = DependencyManager::get<NodeList>()->nodeWithUUID(packet->getSourceID());
avatar = addAvatar(sessionUUID, avatarMixer);
}
if (avatar->getFaceModelURL() != faceMeshURL) {
avatar->setFaceModelURL(faceMeshURL);
}
if (avatar->getSkeletonModelURL() != skeletonURL) {
avatar->setSkeletonModelURL(skeletonURL);
}
if (avatar->getAttachmentData() != attachmentData) {
avatar->setAttachmentData(attachmentData);
}
if (avatar->getDisplayName() != displayName) {
avatar->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));
void AvatarHashMap::processAvatarBillboardPacket(std::unique_ptr<NLPacket> packet, HifiSockAddr senderSockAddr) {
const auto data = QByteArray::fromRawData(packet->getPayload(), packet->size);
QUuid sessionUUID = QUuid::fromRfc4122(QByteArray::fromRawData(data, NUM_BYTES_RFC4122_UUID));
AvatarSharedPointer avatar = _avatarHash.value(sessionUUID);
if (!avatar) {
avatar = addAvatar(sessionUUID, mixerWeakPointer);
SharedNodePointer avatarMixer = DependencyManager::get<NodeList>()->nodeWithUUID(packet->getSourceID());
avatar = addAvatar(sessionUUID, avatarMixer);
}
QByteArray billboard = packet.mid(headerSize + NUM_BYTES_RFC4122_UUID);
QByteArray billboard = data.mid(NUM_BYTES_RFC4122_UUID);
if (avatar->getBillboard() != billboard) {
avatar->setBillboard(billboard);
}
}
void AvatarHashMap::processKillAvatar(const QByteArray& datagram) {
void AvatarHashMap::processKillAvatar(std::unique_ptr<NLPacket> packet, HifiSockAddr senderSockAddr) {
// read the node id
QUuid sessionUUID = QUuid::fromRfc4122(datagram.mid(numBytesForPacketHeader(datagram), NUM_BYTES_RFC4122_UUID));
QUuid sessionUUID = QUuid::fromRfc4122(QByteArray(packet->getPayload(), NUM_BYTES_RFC4122_UUID));
removeAvatar(sessionUUID);
}

View file

@ -38,6 +38,10 @@ public slots:
private slots:
void sessionUUIDChanged(const QUuid& sessionUUID, const QUuid& oldUUID);
void processAvatarDataPacket(std::unique_ptr<NLPacket> packet, HifiSockAddr senderSockAddr);
void processAvatarIdentityPacket(std::unique_ptr<NLPacket> packet, HifiSockAddr senderSockAddr);
void processAvatarBillboardPacket(std::unique_ptr<NLPacket> packet, HifiSockAddr senderSockAddr);
void processKillAvatar(std::unique_ptr<NLPacket> packet, HifiSockAddr senderSockAddr);
protected:
AvatarHashMap();
@ -49,11 +53,6 @@ protected:
AvatarHash _avatarHash;
private:
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);
QUuid _lastOwnerSessionUUID;
};

View file

@ -25,6 +25,8 @@ public:
virtual qint64 totalHeadersSize() const; // Cumulated size of all the headers
virtual qint64 localHeaderSize() const; // Current level's header size
QUuid getSourceID() const { return QUuid(); }
protected:
NLPacket(PacketType::Value type, int64_t size);