mirror of
https://thingvellir.net/git/overte
synced 2025-03-27 23:52:03 +01:00
First pass at requesting ID for unknown data
Keep list of AvatarData that was created from a data packet without a matching ID. If items get old enough send an ID request and remove them.
This commit is contained in:
parent
c8c135a985
commit
d638bdd986
7 changed files with 52 additions and 5 deletions
|
@ -639,6 +639,7 @@ void AvatarMixer::handleAvatarIdentityRequestPacket(QSharedPointer<ReceivedMessa
|
||||||
auto identityPackets = NLPacketList::create(PacketType::AvatarIdentity, QByteArray(), true, true);
|
auto identityPackets = NLPacketList::create(PacketType::AvatarIdentity, QByteArray(), true, true);
|
||||||
identityPackets->write(serializedAvatar);
|
identityPackets->write(serializedAvatar);
|
||||||
nodeList->sendPacketList(std::move(identityPackets), *senderNode);
|
nodeList->sendPacketList(std::move(identityPackets), *senderNode);
|
||||||
|
++_sumIdentityPackets;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -54,6 +54,9 @@ static const quint64 MIN_TIME_BETWEEN_MY_AVATAR_DATA_SENDS = USECS_PER_SECOND /
|
||||||
// We add _myAvatar into the hash with all the other AvatarData, and we use the default NULL QUid as the key.
|
// We add _myAvatar into the hash with all the other AvatarData, and we use the default NULL QUid as the key.
|
||||||
const QUuid MY_AVATAR_KEY; // NULL key
|
const QUuid MY_AVATAR_KEY; // NULL key
|
||||||
|
|
||||||
|
// For an unknown avatar-data packet, wait this long before requesting the identity (in µs).
|
||||||
|
const quint64 AvatarManager::REQUEST_UNKNOWN_IDENTITY_DELAY = 500 * 1000;
|
||||||
|
|
||||||
AvatarManager::AvatarManager(QObject* parent) :
|
AvatarManager::AvatarManager(QObject* parent) :
|
||||||
_avatarsToFade(),
|
_avatarsToFade(),
|
||||||
_myAvatar(new MyAvatar(qApp->thread()), [](MyAvatar* ptr) { ptr->deleteLater(); })
|
_myAvatar(new MyAvatar(qApp->thread()), [](MyAvatar* ptr) { ptr->deleteLater(); })
|
||||||
|
@ -118,6 +121,7 @@ void AvatarManager::updateMyAvatar(float deltaTime) {
|
||||||
_lastSendAvatarDataTime = now;
|
_lastSendAvatarDataTime = now;
|
||||||
_myAvatarSendRate.increment();
|
_myAvatarSendRate.increment();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -276,6 +280,19 @@ void AvatarManager::updateOtherAvatars(float deltaTime) {
|
||||||
|
|
||||||
simulateAvatarFades(deltaTime);
|
simulateAvatarFades(deltaTime);
|
||||||
|
|
||||||
|
const quint64 now = usecTimestampNow();
|
||||||
|
QWriteLocker writeLock(&_hashLock);
|
||||||
|
for (auto avatarData = _pendingAvatars.begin(); avatarData != _pendingAvatars.end(); ++avatarData) {
|
||||||
|
Avatar* pendingAvatar = dynamic_cast<Avatar*>(avatarData->get());
|
||||||
|
if (now - pendingAvatar->getLastRenderUpdateTime() >= REQUEST_UNKNOWN_IDENTITY_DELAY) {
|
||||||
|
pendingAvatar->sendIdentityRequest();
|
||||||
|
avatarData = _pendingAvatars.erase(avatarData);
|
||||||
|
if (avatarData == _pendingAvatars.end()) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
_avatarSimulationTime = (float)(usecTimestampNow() - startTime) / (float)USECS_PER_MSEC;
|
_avatarSimulationTime = (float)(usecTimestampNow() - startTime) / (float)USECS_PER_MSEC;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -194,6 +194,8 @@ private:
|
||||||
int _numAvatarsNotUpdated { 0 };
|
int _numAvatarsNotUpdated { 0 };
|
||||||
float _avatarSimulationTime { 0.0f };
|
float _avatarSimulationTime { 0.0f };
|
||||||
bool _shouldRender { true };
|
bool _shouldRender { true };
|
||||||
|
|
||||||
|
static const quint64 REQUEST_UNKNOWN_IDENTITY_DELAY;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // hifi_AvatarManager_h
|
#endif // hifi_AvatarManager_h
|
||||||
|
|
|
@ -1919,6 +1919,19 @@ void AvatarData::sendIdentityPacket() {
|
||||||
_identityDataChanged = false;
|
_identityDataChanged = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void AvatarData::sendIdentityRequest() const {
|
||||||
|
auto nodeList = DependencyManager::get<NodeList>();
|
||||||
|
auto packet = NLPacket::create(PacketType::AvatarIdentityRequest, NUM_BYTES_RFC4122_UUID, true);
|
||||||
|
packet->write(getID().toRfc4122());
|
||||||
|
nodeList->eachMatchingNode(
|
||||||
|
[&](const SharedNodePointer& node)->bool {
|
||||||
|
return node->getType() == NodeType::AvatarMixer && node->getActiveSocket();
|
||||||
|
},
|
||||||
|
[&](const SharedNodePointer& node) {
|
||||||
|
nodeList->sendPacket(std::move(packet), *node);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
void AvatarData::updateJointMappings() {
|
void AvatarData::updateJointMappings() {
|
||||||
{
|
{
|
||||||
QWriteLocker writeLock(&_jointDataLock);
|
QWriteLocker writeLock(&_jointDataLock);
|
||||||
|
|
|
@ -401,7 +401,7 @@ class AvatarData : public QObject, public SpatiallyNestable {
|
||||||
Q_PROPERTY(float sensorToWorldScale READ getSensorToWorldScale)
|
Q_PROPERTY(float sensorToWorldScale READ getSensorToWorldScale)
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
void sendIdentityRequest() const;
|
||||||
virtual QString getName() const override { return QString("Avatar:") + _displayName; }
|
virtual QString getName() const override { return QString("Avatar:") + _displayName; }
|
||||||
|
|
||||||
static const QString FRAME_NAME;
|
static const QString FRAME_NAME;
|
||||||
|
|
|
@ -89,11 +89,15 @@ AvatarSharedPointer AvatarHashMap::addAvatar(const QUuid& sessionUUID, const QWe
|
||||||
return avatar;
|
return avatar;
|
||||||
}
|
}
|
||||||
|
|
||||||
AvatarSharedPointer AvatarHashMap::newOrExistingAvatar(const QUuid& sessionUUID, const QWeakPointer<Node>& mixerWeakPointer) {
|
AvatarSharedPointer AvatarHashMap::newOrExistingAvatar(const QUuid& sessionUUID, const QWeakPointer<Node>& mixerWeakPointer,
|
||||||
|
bool& isNew) {
|
||||||
QWriteLocker locker(&_hashLock);
|
QWriteLocker locker(&_hashLock);
|
||||||
auto avatar = _avatarHash.value(sessionUUID);
|
auto avatar = _avatarHash.value(sessionUUID);
|
||||||
if (!avatar) {
|
if (!avatar) {
|
||||||
avatar = addAvatar(sessionUUID, mixerWeakPointer);
|
avatar = addAvatar(sessionUUID, mixerWeakPointer);
|
||||||
|
isNew = true;
|
||||||
|
} else {
|
||||||
|
isNew = false;
|
||||||
}
|
}
|
||||||
return avatar;
|
return avatar;
|
||||||
}
|
}
|
||||||
|
@ -125,8 +129,13 @@ AvatarSharedPointer AvatarHashMap::parseAvatarData(QSharedPointer<ReceivedMessag
|
||||||
// make sure this isn't our own avatar data or for a previously ignored node
|
// make sure this isn't our own avatar data or for a previously ignored node
|
||||||
auto nodeList = DependencyManager::get<NodeList>();
|
auto nodeList = DependencyManager::get<NodeList>();
|
||||||
|
|
||||||
|
bool isNewAvatar;
|
||||||
if (sessionUUID != _lastOwnerSessionUUID && (!nodeList->isIgnoringNode(sessionUUID) || nodeList->getRequestsDomainListData())) {
|
if (sessionUUID != _lastOwnerSessionUUID && (!nodeList->isIgnoringNode(sessionUUID) || nodeList->getRequestsDomainListData())) {
|
||||||
auto avatar = newOrExistingAvatar(sessionUUID, sendingNode);
|
auto avatar = newOrExistingAvatar(sessionUUID, sendingNode, isNewAvatar);
|
||||||
|
if (isNewAvatar) {
|
||||||
|
QWriteLocker locker(&_hashLock);
|
||||||
|
_pendingAvatars.insert(sessionUUID, avatar);
|
||||||
|
}
|
||||||
|
|
||||||
// have the matching (or new) avatar parse the data from the packet
|
// have the matching (or new) avatar parse the data from the packet
|
||||||
int bytesRead = avatar->parseDataFromBuffer(byteArray);
|
int bytesRead = avatar->parseDataFromBuffer(byteArray);
|
||||||
|
@ -157,6 +166,7 @@ void AvatarHashMap::processAvatarIdentityPacket(QSharedPointer<ReceivedMessage>
|
||||||
|
|
||||||
{
|
{
|
||||||
QReadLocker locker(&_hashLock);
|
QReadLocker locker(&_hashLock);
|
||||||
|
_pendingAvatars.remove(identityUUID);
|
||||||
auto me = _avatarHash.find(EMPTY);
|
auto me = _avatarHash.find(EMPTY);
|
||||||
if ((me != _avatarHash.end()) && (identityUUID == me.value()->getSessionUUID())) {
|
if ((me != _avatarHash.end()) && (identityUUID == me.value()->getSessionUUID())) {
|
||||||
// We add MyAvatar to _avatarHash with an empty UUID. Code relies on this. In order to correctly handle an
|
// We add MyAvatar to _avatarHash with an empty UUID. Code relies on this. In order to correctly handle an
|
||||||
|
@ -168,7 +178,8 @@ void AvatarHashMap::processAvatarIdentityPacket(QSharedPointer<ReceivedMessage>
|
||||||
|
|
||||||
if (!nodeList->isIgnoringNode(identityUUID) || nodeList->getRequestsDomainListData()) {
|
if (!nodeList->isIgnoringNode(identityUUID) || nodeList->getRequestsDomainListData()) {
|
||||||
// mesh URL for a UUID, find avatar in our list
|
// mesh URL for a UUID, find avatar in our list
|
||||||
auto avatar = newOrExistingAvatar(identityUUID, sendingNode);
|
bool isNewAvatar;
|
||||||
|
auto avatar = newOrExistingAvatar(identityUUID, sendingNode, isNewAvatar);
|
||||||
bool identityChanged = false;
|
bool identityChanged = false;
|
||||||
bool displayNameChanged = false;
|
bool displayNameChanged = false;
|
||||||
bool skeletonModelUrlChanged = false;
|
bool skeletonModelUrlChanged = false;
|
||||||
|
@ -189,6 +200,7 @@ void AvatarHashMap::processKillAvatar(QSharedPointer<ReceivedMessage> message, S
|
||||||
void AvatarHashMap::removeAvatar(const QUuid& sessionUUID, KillAvatarReason removalReason) {
|
void AvatarHashMap::removeAvatar(const QUuid& sessionUUID, KillAvatarReason removalReason) {
|
||||||
QWriteLocker locker(&_hashLock);
|
QWriteLocker locker(&_hashLock);
|
||||||
|
|
||||||
|
_pendingAvatars.remove(sessionUUID);
|
||||||
auto removedAvatar = _avatarHash.take(sessionUUID);
|
auto removedAvatar = _avatarHash.take(sessionUUID);
|
||||||
|
|
||||||
if (removedAvatar) {
|
if (removedAvatar) {
|
||||||
|
|
|
@ -145,13 +145,15 @@ protected:
|
||||||
virtual AvatarSharedPointer parseAvatarData(QSharedPointer<ReceivedMessage> message, SharedNodePointer sendingNode);
|
virtual AvatarSharedPointer parseAvatarData(QSharedPointer<ReceivedMessage> message, SharedNodePointer sendingNode);
|
||||||
virtual AvatarSharedPointer newSharedAvatar();
|
virtual AvatarSharedPointer newSharedAvatar();
|
||||||
virtual AvatarSharedPointer addAvatar(const QUuid& sessionUUID, const QWeakPointer<Node>& mixerWeakPointer);
|
virtual AvatarSharedPointer addAvatar(const QUuid& sessionUUID, const QWeakPointer<Node>& mixerWeakPointer);
|
||||||
AvatarSharedPointer newOrExistingAvatar(const QUuid& sessionUUID, const QWeakPointer<Node>& mixerWeakPointer);
|
AvatarSharedPointer newOrExistingAvatar(const QUuid& sessionUUID, const QWeakPointer<Node>& mixerWeakPointer,
|
||||||
|
bool& isNew);
|
||||||
virtual AvatarSharedPointer findAvatar(const QUuid& sessionUUID) const; // uses a QReadLocker on the hashLock
|
virtual AvatarSharedPointer findAvatar(const QUuid& sessionUUID) const; // uses a QReadLocker on the hashLock
|
||||||
virtual void removeAvatar(const QUuid& sessionUUID, KillAvatarReason removalReason = KillAvatarReason::NoReason);
|
virtual void removeAvatar(const QUuid& sessionUUID, KillAvatarReason removalReason = KillAvatarReason::NoReason);
|
||||||
|
|
||||||
virtual void handleRemovedAvatar(const AvatarSharedPointer& removedAvatar, KillAvatarReason removalReason = KillAvatarReason::NoReason);
|
virtual void handleRemovedAvatar(const AvatarSharedPointer& removedAvatar, KillAvatarReason removalReason = KillAvatarReason::NoReason);
|
||||||
|
|
||||||
AvatarHash _avatarHash;
|
AvatarHash _avatarHash;
|
||||||
|
AvatarHash _pendingAvatars;
|
||||||
mutable QReadWriteLock _hashLock;
|
mutable QReadWriteLock _hashLock;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
Loading…
Reference in a new issue