mirror of
https://github.com/HifiExperiments/overte.git
synced 2025-04-10 02:44:34 +02:00
remove skeleton from identity, handle in clients
This commit is contained in:
parent
26a1f03314
commit
a80d19a44a
11 changed files with 104 additions and 47 deletions
|
@ -447,11 +447,6 @@ void Agent::executeScript() {
|
|||
auto avatarHashMap = DependencyManager::set<AvatarHashMap>();
|
||||
_scriptEngine->registerGlobalObject("AvatarList", avatarHashMap.data());
|
||||
|
||||
auto& packetReceiver = DependencyManager::get<NodeList>()->getPacketReceiver();
|
||||
packetReceiver.registerListener(PacketType::BulkAvatarData, avatarHashMap.data(), "processAvatarDataPacket");
|
||||
packetReceiver.registerListener(PacketType::KillAvatar, avatarHashMap.data(), "processKillAvatar");
|
||||
packetReceiver.registerListener(PacketType::AvatarIdentity, avatarHashMap.data(), "processAvatarIdentityPacket");
|
||||
|
||||
// register ourselves to the script engine
|
||||
_scriptEngine->registerGlobalObject("Agent", new AgentScriptingInterface(this));
|
||||
|
||||
|
|
|
@ -109,17 +109,10 @@ void AvatarMixerClientData::processSetTraitsMessage(ReceivedMessage& message) {
|
|||
message.readPrimitive(&traitSize);
|
||||
|
||||
if (packetTraitVersion > _receivedSimpleTraitVersions[traitType]) {
|
||||
if (traitType == AvatarTraits::SkeletonModelURL) {
|
||||
// get the URL from the binary data
|
||||
auto skeletonModelURL = QUrl::fromEncoded(message.read(traitSize));
|
||||
_avatar->setSkeletonModelURL(skeletonModelURL);
|
||||
|
||||
qDebug() << "Set skeleton URL to" << skeletonModelURL << "for trait packet version" << packetTraitVersion;
|
||||
|
||||
_receivedSimpleTraitVersions[traitType] = packetTraitVersion;
|
||||
|
||||
anyTraitsChanged = true;
|
||||
}
|
||||
_avatar->processTrait(traitType, message.readWithoutCopy(traitSize));
|
||||
_receivedSimpleTraitVersions[traitType] = packetTraitVersion;
|
||||
|
||||
anyTraitsChanged = true;
|
||||
} else {
|
||||
message.seek(message.getPosition() + traitSize);
|
||||
}
|
||||
|
|
|
@ -81,9 +81,6 @@ EntityScriptServer::EntityScriptServer(ReceivedMessage& message) : ThreadedAssig
|
|||
packetReceiver.registerListener(PacketType::SelectedAudioFormat, this, "handleSelectedAudioFormat");
|
||||
|
||||
auto avatarHashMap = DependencyManager::set<AvatarHashMap>();
|
||||
packetReceiver.registerListener(PacketType::BulkAvatarData, avatarHashMap.data(), "processAvatarDataPacket");
|
||||
packetReceiver.registerListener(PacketType::KillAvatar, avatarHashMap.data(), "processKillAvatar");
|
||||
packetReceiver.registerListener(PacketType::AvatarIdentity, avatarHashMap.data(), "processAvatarIdentityPacket");
|
||||
|
||||
packetReceiver.registerListener(PacketType::ReloadEntityServerScript, this, "handleReloadEntityServerScriptPacket");
|
||||
packetReceiver.registerListener(PacketType::EntityScriptGetStatus, this, "handleEntityScriptGetStatusPacket");
|
||||
|
|
|
@ -72,10 +72,6 @@ AvatarManager::AvatarManager(QObject* parent) :
|
|||
qRegisterMetaType<QWeakPointer<Node> >("NodeWeakPointer");
|
||||
|
||||
auto nodeList = DependencyManager::get<NodeList>();
|
||||
auto& packetReceiver = nodeList->getPacketReceiver();
|
||||
packetReceiver.registerListener(PacketType::BulkAvatarData, this, "processAvatarDataPacket");
|
||||
packetReceiver.registerListener(PacketType::KillAvatar, this, "processKillAvatar");
|
||||
packetReceiver.registerListener(PacketType::AvatarIdentity, this, "processAvatarIdentityPacket");
|
||||
|
||||
// when we hear that the user has ignored an avatar by session UUID
|
||||
// immediately remove that avatar instead of waiting for the absence of packets from avatar mixer
|
||||
|
|
|
@ -1705,8 +1705,6 @@ void MyAvatar::setSkeletonModelURL(const QUrl& skeletonModelURL) {
|
|||
|
||||
if (previousSkeletonModelURL != _skeletonModelURL) {
|
||||
_clientTraitsHandler.markTraitChanged(AvatarTraits::SkeletonModelURL);
|
||||
} else {
|
||||
qDebug() << "Not marking skeleton model URL trait changed since the new value matches the previous";
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -42,6 +42,7 @@
|
|||
#include <BitVectorHelpers.h>
|
||||
|
||||
#include "AvatarLogging.h"
|
||||
#include "AvatarTraits.h"
|
||||
|
||||
//#define WANT_DEBUG
|
||||
|
||||
|
@ -1756,7 +1757,7 @@ QUrl AvatarData::cannonicalSkeletonModelURL(const QUrl& emptyURL) const {
|
|||
}
|
||||
|
||||
void AvatarData::processAvatarIdentity(const QByteArray& identityData, bool& identityChanged,
|
||||
bool& displayNameChanged, bool& skeletonModelUrlChanged) {
|
||||
bool& displayNameChanged) {
|
||||
|
||||
QDataStream packetStream(identityData);
|
||||
|
||||
|
@ -1777,7 +1778,7 @@ void AvatarData::processAvatarIdentity(const QByteArray& identityData, bool& ide
|
|||
if (incomingSequenceNumber > _identitySequenceNumber) {
|
||||
Identity identity;
|
||||
|
||||
packetStream >> identity.skeletonModelURL
|
||||
packetStream
|
||||
>> identity.attachmentData
|
||||
>> identity.displayName
|
||||
>> identity.sessionDisplayName
|
||||
|
@ -1789,16 +1790,6 @@ void AvatarData::processAvatarIdentity(const QByteArray& identityData, bool& ide
|
|||
// set the store identity sequence number to match the incoming identity
|
||||
_identitySequenceNumber = incomingSequenceNumber;
|
||||
|
||||
if (_firstSkeletonCheck || (identity.skeletonModelURL != cannonicalSkeletonModelURL(emptyURL))) {
|
||||
setSkeletonModelURL(identity.skeletonModelURL);
|
||||
identityChanged = true;
|
||||
skeletonModelUrlChanged = true;
|
||||
if (_firstSkeletonCheck) {
|
||||
displayNameChanged = true;
|
||||
}
|
||||
_firstSkeletonCheck = false;
|
||||
}
|
||||
|
||||
if (identity.displayName != _displayName) {
|
||||
_displayName = identity.displayName;
|
||||
identityChanged = true;
|
||||
|
@ -1834,7 +1825,6 @@ void AvatarData::processAvatarIdentity(const QByteArray& identityData, bool& ide
|
|||
#ifdef WANT_DEBUG
|
||||
qCDebug(avatars) << __FUNCTION__
|
||||
<< "identity.uuid:" << identity.uuid
|
||||
<< "identity.skeletonModelURL:" << identity.skeletonModelURL
|
||||
<< "identity.displayName:" << identity.displayName
|
||||
<< "identity.sessionDisplayName:" << identity.sessionDisplayName;
|
||||
} else {
|
||||
|
@ -1846,10 +1836,18 @@ void AvatarData::processAvatarIdentity(const QByteArray& identityData, bool& ide
|
|||
}
|
||||
}
|
||||
|
||||
void AvatarData::processTrait(AvatarTraits::TraitType traitType, QByteArray traitBinaryData) {
|
||||
if (traitType == AvatarTraits::SkeletonModelURL) {
|
||||
// get the URL from the binary data
|
||||
auto skeletonModelURL = QUrl::fromEncoded(traitBinaryData);
|
||||
qDebug() << "Setting skeleton model URL from trait packet to" << skeletonModelURL;
|
||||
setSkeletonModelURL(skeletonModelURL);
|
||||
}
|
||||
}
|
||||
|
||||
QByteArray AvatarData::identityByteArray(bool setIsReplicated) const {
|
||||
QByteArray identityData;
|
||||
QDataStream identityStream(&identityData, QIODevice::Append);
|
||||
const QUrl& urlToSend = cannonicalSkeletonModelURL(emptyURL); // depends on _skeletonModelURL
|
||||
|
||||
// when mixers send identity packets to agents, they simply forward along the last incoming sequence number they received
|
||||
// whereas agents send a fresh outgoing sequence number when identity data has changed
|
||||
|
@ -1857,7 +1855,6 @@ QByteArray AvatarData::identityByteArray(bool setIsReplicated) const {
|
|||
_avatarEntitiesLock.withReadLock([&] {
|
||||
identityStream << getSessionUUID()
|
||||
<< (udt::SequenceNumber::Type) _identitySequenceNumber
|
||||
<< urlToSend
|
||||
<< _attachmentData
|
||||
<< _displayName
|
||||
<< getSessionDisplayNameForTransport() // depends on _sessionDisplayName
|
||||
|
|
|
@ -51,6 +51,7 @@
|
|||
#include <udt/SequenceNumber.h>
|
||||
|
||||
#include "AABox.h"
|
||||
#include "AvatarTraits.h"
|
||||
#include "HeadData.h"
|
||||
#include "PathUtils.h"
|
||||
|
||||
|
@ -955,8 +956,9 @@ public:
|
|||
|
||||
// identityChanged returns true if identity has changed, false otherwise.
|
||||
// identityChanged returns true if identity has changed, false otherwise. Similarly for displayNameChanged and skeletonModelUrlChange.
|
||||
void processAvatarIdentity(const QByteArray& identityData, bool& identityChanged,
|
||||
bool& displayNameChanged, bool& skeletonModelUrlChanged);
|
||||
void processAvatarIdentity(const QByteArray& identityData, bool& identityChanged, bool& displayNameChanged);
|
||||
|
||||
void processTrait(AvatarTraits::TraitType traitType, QByteArray traitBinaryData);
|
||||
|
||||
QByteArray identityByteArray(bool setIsReplicated = false) const;
|
||||
|
||||
|
@ -1327,7 +1329,6 @@ protected:
|
|||
mutable HeadData* _headData { nullptr };
|
||||
|
||||
QUrl _skeletonModelURL;
|
||||
bool _firstSkeletonCheck { true };
|
||||
QUrl _skeletonFBXURL;
|
||||
QVector<AttachmentData> _attachmentData;
|
||||
QVector<AttachmentData> _oldAttachmentData;
|
||||
|
|
|
@ -19,10 +19,17 @@
|
|||
#include <SharedUtil.h>
|
||||
|
||||
#include "AvatarLogging.h"
|
||||
#include "AvatarTraits.h"
|
||||
|
||||
AvatarHashMap::AvatarHashMap() {
|
||||
auto nodeList = DependencyManager::get<NodeList>();
|
||||
|
||||
auto& packetReceiver = nodeList->getPacketReceiver();
|
||||
packetReceiver.registerListener(PacketType::BulkAvatarData, this, "processAvatarDataPacket");
|
||||
packetReceiver.registerListener(PacketType::KillAvatar, this, "processKillAvatar");
|
||||
packetReceiver.registerListener(PacketType::AvatarIdentity, this, "processAvatarIdentityPacket");
|
||||
packetReceiver.registerListener(PacketType::BulkAvatarTraits, this, "processBulkAvatarTraits");
|
||||
|
||||
connect(nodeList.data(), &NodeList::uuidChanged, this, &AvatarHashMap::sessionUUIDChanged);
|
||||
}
|
||||
|
||||
|
@ -182,9 +189,74 @@ void AvatarHashMap::processAvatarIdentityPacket(QSharedPointer<ReceivedMessage>
|
|||
auto avatar = newOrExistingAvatar(identityUUID, sendingNode, isNewAvatar);
|
||||
bool identityChanged = false;
|
||||
bool displayNameChanged = false;
|
||||
bool skeletonModelUrlChanged = false;
|
||||
// In this case, the "sendingNode" is the Avatar Mixer.
|
||||
avatar->processAvatarIdentity(message->getMessage(), identityChanged, displayNameChanged, skeletonModelUrlChanged);
|
||||
avatar->processAvatarIdentity(message->getMessage(), identityChanged, displayNameChanged);
|
||||
}
|
||||
}
|
||||
|
||||
bool AvatarHashMap::checkLastProcessedTraitVersion(QUuid avatarID,
|
||||
AvatarTraits::TraitType traitType, AvatarTraits::TraitVersion newVersion) {
|
||||
auto it = _processedSimpleTraitVersions.find(avatarID);
|
||||
if (it == _processedSimpleTraitVersions.end()) {
|
||||
auto pair = _processedSimpleTraitVersions.insert({
|
||||
avatarID,
|
||||
{ AvatarTraits::TotalTraitTypes, AvatarTraits::DEFAULT_TRAIT_VERSION }
|
||||
});
|
||||
|
||||
it = pair.first;
|
||||
};
|
||||
|
||||
if (it->second[traitType] < newVersion) {
|
||||
it->second[traitType] = newVersion;
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
void AvatarHashMap::processBulkAvatarTraits(QSharedPointer<ReceivedMessage> 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));
|
||||
|
||||
// grab the avatar so we can ask it to process trait data
|
||||
AvatarSharedPointer avatar;
|
||||
|
||||
QReadLocker locker(&_hashLock);
|
||||
auto it = _avatarHash.find(avatarID);
|
||||
if (it != _avatarHash.end()) {
|
||||
avatar = *it;
|
||||
}
|
||||
locker.unlock();
|
||||
|
||||
// read the first trait type for this avatar
|
||||
AvatarTraits::TraitType traitType;
|
||||
message->readPrimitive(&traitType);
|
||||
|
||||
while (traitType != AvatarTraits::NullTrait) {
|
||||
AvatarTraits::TraitVersion traitVersion;
|
||||
message->readPrimitive(&traitVersion);
|
||||
|
||||
AvatarTraits::TraitWireSize traitBinarySize;
|
||||
message->readPrimitive(&traitBinarySize);
|
||||
|
||||
if (avatar) {
|
||||
// check if this trait version is newer than what we already have for this avatar
|
||||
bool traitIsNewer = checkLastProcessedTraitVersion(avatarID, traitType, traitVersion);
|
||||
if (traitIsNewer) {
|
||||
avatar->processTrait(traitType, message->readWithoutCopy(traitBinarySize));
|
||||
} else {
|
||||
message->seek(message->getPosition() + traitBinarySize);
|
||||
}
|
||||
} else {
|
||||
// though we have no avatar pointer, we still hop through the packet in case there are
|
||||
// traits for avatars we do have later in the packet
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -30,6 +30,7 @@
|
|||
#include "ScriptAvatarData.h"
|
||||
|
||||
#include "AvatarData.h"
|
||||
#include "AvatarTraits.h"
|
||||
|
||||
/**jsdoc
|
||||
* <strong>Note:</strong> An <code>AvatarList</code> API is also provided for Interface and client entity scripts: it is a
|
||||
|
@ -133,6 +134,8 @@ protected slots:
|
|||
*/
|
||||
void processAvatarIdentityPacket(QSharedPointer<ReceivedMessage> message, SharedNodePointer sendingNode);
|
||||
|
||||
void processBulkAvatarTraits(QSharedPointer<ReceivedMessage> message, SharedNodePointer sendingNode);
|
||||
|
||||
/**jsdoc
|
||||
* @function AvatarList.processKillAvatar
|
||||
* @param {} message
|
||||
|
@ -153,6 +156,9 @@ protected:
|
|||
|
||||
virtual void handleRemovedAvatar(const AvatarSharedPointer& removedAvatar, KillAvatarReason removalReason = KillAvatarReason::NoReason);
|
||||
|
||||
bool checkLastProcessedTraitVersion(QUuid avatarID,
|
||||
AvatarTraits::TraitType traitType, AvatarTraits::TraitVersion newVersion);
|
||||
|
||||
AvatarHash _avatarHash;
|
||||
struct PendingAvatar {
|
||||
std::chrono::steady_clock::time_point creationTime;
|
||||
|
@ -163,6 +169,7 @@ protected:
|
|||
AvatarPendingHash _pendingAvatars;
|
||||
mutable QReadWriteLock _hashLock;
|
||||
|
||||
std::unordered_map<QUuid, AvatarTraits::SimpleTraitVersions> _processedSimpleTraitVersions;
|
||||
private:
|
||||
QUuid _lastOwnerSessionUUID;
|
||||
};
|
||||
|
|
|
@ -40,7 +40,7 @@ PacketVersion versionForPacketType(PacketType packetType) {
|
|||
case PacketType::AvatarData:
|
||||
case PacketType::BulkAvatarData:
|
||||
case PacketType::KillAvatar:
|
||||
return static_cast<PacketVersion>(AvatarMixerPacketVersion::FarGrabJoints);
|
||||
return static_cast<PacketVersion>(AvatarMixerPacketVersion::MigrateSkeletonURLToTraits);
|
||||
case PacketType::MessagesData:
|
||||
return static_cast<PacketVersion>(MessageDataVersion::TextOrBinaryData);
|
||||
// ICE packets
|
||||
|
|
|
@ -134,7 +134,7 @@ public:
|
|||
EntityClone,
|
||||
EntityQueryInitialResultsComplete,
|
||||
BulkAvatarTraits,
|
||||
|
||||
|
||||
NUM_PACKET_TYPE
|
||||
};
|
||||
|
||||
|
@ -291,6 +291,7 @@ enum class AvatarMixerPacketVersion : PacketVersion {
|
|||
FixMannequinDefaultAvatarFeet,
|
||||
ProceduralFaceMovementFlagsAndBlendshapes,
|
||||
FarGrabJoints
|
||||
MigrateSkeletonURLToTraits
|
||||
};
|
||||
|
||||
enum class DomainConnectRequestVersion : PacketVersion {
|
||||
|
|
Loading…
Reference in a new issue