From b495e6251d94ec6549476fef829ef1e43f8c0b69 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Thu, 23 Jan 2014 17:39:14 -0800 Subject: [PATCH] add a weak pointer to the avatar mixer that owns the avatar --- interface/src/DatagramProcessor.cpp | 7 +++++-- interface/src/avatar/Avatar.cpp | 1 + interface/src/avatar/Avatar.h | 5 ++++- interface/src/avatar/AvatarManager.cpp | 26 +++++++++++++++++++------- interface/src/avatar/AvatarManager.h | 2 +- 5 files changed, 30 insertions(+), 11 deletions(-) diff --git a/interface/src/DatagramProcessor.cpp b/interface/src/DatagramProcessor.cpp index 04dd7618e1..eba001a0f5 100644 --- a/interface/src/DatagramProcessor.cpp +++ b/interface/src/DatagramProcessor.cpp @@ -6,6 +6,8 @@ // Copyright (c) 2014 HighFidelity, Inc. All rights reserved. // +#include + #include #include "Application.h" @@ -100,9 +102,10 @@ void DatagramProcessor::processDatagrams() { QByteArray datagram(reinterpret_cast(incomingPacket), bytesReceived); - if (incomingPacket[0] == PACKET_TYPE_BULK_AVATAR_DATA) { + if (incomingPacket[0] == PACKET_TYPE_BULK_AVATAR_DATA) { QMetaObject::invokeMethod(&application->getAvatarManager(), "processAvatarMixerDatagram", - Q_ARG(const QByteArray&, datagram)); + Q_ARG(const QByteArray&, datagram), + Q_ARG(const QWeakPointer&, avatarMixer)); } else { // this is an avatar kill, pass it to the application AvatarManager QMetaObject::invokeMethod(&application->getAvatarManager(), "processKillAvatar", diff --git a/interface/src/avatar/Avatar.cpp b/interface/src/avatar/Avatar.cpp index 5bf06cd8ea..5e41619997 100644 --- a/interface/src/avatar/Avatar.cpp +++ b/interface/src/avatar/Avatar.cpp @@ -75,6 +75,7 @@ Avatar::Avatar() : _mouseRayDirection(0.0f, 0.0f, 0.0f), _isCollisionsOn(true), _moving(false), + _owningAvatarMixer(), _initialized(false) { // we may have been created in the network thread, but we live in the main thread diff --git a/interface/src/avatar/Avatar.h b/interface/src/avatar/Avatar.h index 242e5d7963..10a3760f6e 100755 --- a/interface/src/avatar/Avatar.h +++ b/interface/src/avatar/Avatar.h @@ -90,6 +90,9 @@ public: Head& getHead() { return _head; } Hand& getHand() { return _hand; } glm::quat getWorldAlignedOrientation() const; + + Node* getOwningAvatarMixer() { return _owningAvatarMixer.data(); } + void setOwningAvatarMixer(const QWeakPointer& owningAvatarMixer) { _owningAvatarMixer = owningAvatarMixer; } bool findRayIntersection(const glm::vec3& origin, const glm::vec3& direction, float& distance) const; @@ -141,8 +144,8 @@ protected: glm::vec3 _mouseRayDirection; bool _isCollisionsOn; float _stringLength; - bool _moving; ///< set when position is changing + QWeakPointer _owningAvatarMixer; // protected methods... glm::vec3 getBodyRightDirection() const { return getOrientation() * IDENTITY_RIGHT; } diff --git a/interface/src/avatar/AvatarManager.cpp b/interface/src/avatar/AvatarManager.cpp index b381efd24d..bf373c8027 100644 --- a/interface/src/avatar/AvatarManager.cpp +++ b/interface/src/avatar/AvatarManager.cpp @@ -23,7 +23,8 @@ AvatarManager::AvatarManager(QObject* parent) : _avatarHash(), _avatarFades() { - + // register a meta type for the weak pointer we'll use for the owning avatar mixer for each avatar + qRegisterMetaType >("NodeWeakPointer"); } void AvatarManager::updateLookAtTargetAvatar(const glm::vec3& mouseRayOrigin, const glm::vec3& mouseRayDirection, @@ -59,9 +60,17 @@ void AvatarManager::updateAvatars(float deltaTime, const glm::vec3& mouseRayOrig PerformanceWarning warn(showWarnings, "Application::updateAvatars()"); // simulate avatars - foreach (const AvatarSharedPointer& avatar, _avatarHash) { - avatar->simulate(deltaTime, NULL); - avatar->setMouseRay(mouseRayOrigin, mouseRayDirection); + AvatarHash::iterator avatar = _avatarHash.begin(); + if (avatar != _avatarHash.end()) { + if (avatar->data()->getOwningAvatarMixer()) { + // this avatar's mixer is still around, go ahead and simulate it + avatar->data()->simulate(deltaTime, NULL); + avatar->data()->setMouseRay(mouseRayOrigin, mouseRayDirection); + } else { + // the mixer that owned this avatar is gone, give it to the vector of fades and kill it + _avatarFades.push_back(*avatar); + avatar = _avatarHash.erase(avatar); + } } // simulate avatar fades @@ -106,6 +115,7 @@ void AvatarManager::simulateAvatarFades(float deltaTime) { const float MIN_FADE_SCALE = 0.001f; if (fadingAvatar->data()->getTargetScale() < MIN_FADE_SCALE) { + fadingAvatar = _avatarFades.erase(fadingAvatar); } else { fadingAvatar->data()->simulate(deltaTime, NULL); @@ -149,7 +159,7 @@ void AvatarManager::processDataServerResponse(const QString& userString, const Q } } -void AvatarManager::processAvatarMixerDatagram(const QByteArray& datagram) { +void AvatarManager::processAvatarMixerDatagram(const QByteArray& datagram, const QWeakPointer& mixerWeakPointer) { unsigned char packetData[MAX_PACKET_SIZE]; memcpy(packetData, datagram.data(), datagram.size()); @@ -160,7 +170,9 @@ void AvatarManager::processAvatarMixerDatagram(const QByteArray& datagram) { unsigned char avatarData[MAX_PACKET_SIZE]; int numBytesDummyPacketHeader = populateTypeAndVersion(avatarData, PACKET_TYPE_HEAD_DATA); - while (bytesRead < datagram.size()) { + // 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 nodeUUID = QUuid::fromRfc4122(datagram.mid(bytesRead, NUM_BYTES_RFC4122_UUID)); AvatarSharedPointer matchingAvatar = _avatarHash.value(nodeUUID); @@ -168,6 +180,7 @@ void AvatarManager::processAvatarMixerDatagram(const QByteArray& datagram) { if (!matchingAvatar) { // construct a new Avatar for this node matchingAvatar = AvatarSharedPointer(new Avatar()); + matchingAvatar->setOwningAvatarMixer(mixerWeakPointer); // insert the new avatar into our hash _avatarHash.insert(nodeUUID, matchingAvatar); @@ -203,7 +216,6 @@ void AvatarManager::processKillAvatar(const QByteArray& datagram) { } void AvatarManager::clearHash() { - qDebug() << "clear the hash!"; // clear the AvatarManager hash - typically happens on the removal of the avatar-mixer _avatarHash.clear(); } \ No newline at end of file diff --git a/interface/src/avatar/AvatarManager.h b/interface/src/avatar/AvatarManager.h index 4775a39ba8..264b98547a 100644 --- a/interface/src/avatar/AvatarManager.h +++ b/interface/src/avatar/AvatarManager.h @@ -41,7 +41,7 @@ public: public slots: void processDataServerResponse(const QString& userString, const QStringList& keyList, const QStringList& valueList); - void processAvatarMixerDatagram(const QByteArray& datagram); + void processAvatarMixerDatagram(const QByteArray& datagram, const QWeakPointer& mixerWeakPointer); void processKillAvatar(const QByteArray& datagram); private: