mirror of
https://github.com/overte-org/overte.git
synced 2025-08-10 20:03:06 +02:00
Merge pull request #6393 from hyperlogic/tony/avatar-mixer-identity-fixes
Fix for missing avatars on entry
This commit is contained in:
commit
8e6c860a24
3 changed files with 76 additions and 64 deletions
|
@ -63,7 +63,9 @@ AvatarMixer::~AvatarMixer() {
|
||||||
_broadcastThread.wait();
|
_broadcastThread.wait();
|
||||||
}
|
}
|
||||||
|
|
||||||
const float BILLBOARD_AND_IDENTITY_SEND_PROBABILITY = 1.0f / 300.0f;
|
// An 80% chance of sending a identity packet within a 5 second interval.
|
||||||
|
// assuming 60 htz update rate.
|
||||||
|
const float BILLBOARD_AND_IDENTITY_SEND_PROBABILITY = 1.0f / 187.0f;
|
||||||
|
|
||||||
// NOTE: some additional optimizations to consider.
|
// NOTE: some additional optimizations to consider.
|
||||||
// 1) use the view frustum to cull those avatars that are out of view. Since avatar data doesn't need to be present
|
// 1) use the view frustum to cull those avatars that are out of view. Since avatar data doesn't need to be present
|
||||||
|
@ -243,6 +245,47 @@ void AvatarMixer::broadcastAvatarData() {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// if an avatar has just connected make sure we send out the mesh and billboard
|
||||||
|
bool forceSend = !nodeData->checkAndSetHasReceivedFirstPackets()
|
||||||
|
|| !otherNodeData->checkAndSetHasReceivedFirstPacketsFrom(node->getUUID());
|
||||||
|
|
||||||
|
// we will also force a send of billboard or identity packet
|
||||||
|
// if either has changed in the last frame
|
||||||
|
if (otherNodeData->getBillboardChangeTimestamp() > 0
|
||||||
|
&& (forceSend
|
||||||
|
|| otherNodeData->getBillboardChangeTimestamp() > _lastFrameTimestamp
|
||||||
|
|| distribution(generator) < BILLBOARD_AND_IDENTITY_SEND_PROBABILITY)) {
|
||||||
|
|
||||||
|
QByteArray rfcUUID = otherNode->getUUID().toRfc4122();
|
||||||
|
QByteArray billboard = otherNodeData->getAvatar().getBillboard();
|
||||||
|
|
||||||
|
auto billboardPacket = NLPacket::create(PacketType::AvatarBillboard, rfcUUID.size() + billboard.size());
|
||||||
|
billboardPacket->write(rfcUUID);
|
||||||
|
billboardPacket->write(billboard);
|
||||||
|
|
||||||
|
nodeList->sendPacket(std::move(billboardPacket), *node);
|
||||||
|
|
||||||
|
++_sumBillboardPackets;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (otherNodeData->getIdentityChangeTimestamp() > 0
|
||||||
|
&& (forceSend
|
||||||
|
|| otherNodeData->getIdentityChangeTimestamp() > _lastFrameTimestamp
|
||||||
|
|| distribution(generator) < BILLBOARD_AND_IDENTITY_SEND_PROBABILITY)) {
|
||||||
|
|
||||||
|
QByteArray individualData = otherNodeData->getAvatar().identityByteArray();
|
||||||
|
|
||||||
|
auto identityPacket = NLPacket::create(PacketType::AvatarIdentity, individualData.size());
|
||||||
|
|
||||||
|
individualData.replace(0, NUM_BYTES_RFC4122_UUID, otherNode->getUUID().toRfc4122());
|
||||||
|
|
||||||
|
identityPacket->write(individualData);
|
||||||
|
|
||||||
|
nodeList->sendPacket(std::move(identityPacket), *node);
|
||||||
|
|
||||||
|
++_sumIdentityPackets;
|
||||||
|
}
|
||||||
|
|
||||||
AvatarData& otherAvatar = otherNodeData->getAvatar();
|
AvatarData& otherAvatar = otherNodeData->getAvatar();
|
||||||
// Decide whether to send this avatar's data based on it's distance from us
|
// Decide whether to send this avatar's data based on it's distance from us
|
||||||
|
|
||||||
|
@ -291,51 +334,9 @@ void AvatarMixer::broadcastAvatarData() {
|
||||||
|
|
||||||
numAvatarDataBytes += avatarPacketList->write(otherNode->getUUID().toRfc4122());
|
numAvatarDataBytes += avatarPacketList->write(otherNode->getUUID().toRfc4122());
|
||||||
numAvatarDataBytes +=
|
numAvatarDataBytes +=
|
||||||
avatarPacketList->write(otherAvatar.toByteArray(false, randFloat() < AVATAR_SEND_FULL_UPDATE_RATIO));
|
avatarPacketList->write(otherAvatar.toByteArray(false, distribution(generator) < AVATAR_SEND_FULL_UPDATE_RATIO));
|
||||||
|
|
||||||
avatarPacketList->endSegment();
|
avatarPacketList->endSegment();
|
||||||
|
|
||||||
// if the receiving avatar has just connected make sure we send out the mesh and billboard
|
|
||||||
// for this avatar (assuming they exist)
|
|
||||||
bool forceSend = !nodeData->checkAndSetHasReceivedFirstPackets();
|
|
||||||
|
|
||||||
// we will also force a send of billboard or identity packet
|
|
||||||
// if either has changed in the last frame
|
|
||||||
|
|
||||||
if (otherNodeData->getBillboardChangeTimestamp() > 0
|
|
||||||
&& (forceSend
|
|
||||||
|| otherNodeData->getBillboardChangeTimestamp() > _lastFrameTimestamp
|
|
||||||
|| randFloat() < BILLBOARD_AND_IDENTITY_SEND_PROBABILITY)) {
|
|
||||||
|
|
||||||
QByteArray rfcUUID = otherNode->getUUID().toRfc4122();
|
|
||||||
QByteArray billboard = otherNodeData->getAvatar().getBillboard();
|
|
||||||
|
|
||||||
auto billboardPacket = NLPacket::create(PacketType::AvatarBillboard, rfcUUID.size() + billboard.size());
|
|
||||||
billboardPacket->write(rfcUUID);
|
|
||||||
billboardPacket->write(billboard);
|
|
||||||
|
|
||||||
nodeList->sendPacket(std::move(billboardPacket), *node);
|
|
||||||
|
|
||||||
++_sumBillboardPackets;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (otherNodeData->getIdentityChangeTimestamp() > 0
|
|
||||||
&& (forceSend
|
|
||||||
|| otherNodeData->getIdentityChangeTimestamp() > _lastFrameTimestamp
|
|
||||||
|| randFloat() < BILLBOARD_AND_IDENTITY_SEND_PROBABILITY)) {
|
|
||||||
|
|
||||||
QByteArray individualData = otherNodeData->getAvatar().identityByteArray();
|
|
||||||
|
|
||||||
auto identityPacket = NLPacket::create(PacketType::AvatarIdentity, individualData.size());
|
|
||||||
|
|
||||||
individualData.replace(0, NUM_BYTES_RFC4122_UUID, otherNode->getUUID().toRfc4122());
|
|
||||||
|
|
||||||
identityPacket->write(individualData);
|
|
||||||
|
|
||||||
nodeList->sendPacket(std::move(identityPacket), *node);
|
|
||||||
|
|
||||||
++_sumIdentityPackets;
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
// close the current packet so that we're always sending something
|
// close the current packet so that we're always sending something
|
||||||
|
|
|
@ -27,6 +27,14 @@ bool AvatarMixerClientData::checkAndSetHasReceivedFirstPackets() {
|
||||||
return oldValue;
|
return oldValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool AvatarMixerClientData::checkAndSetHasReceivedFirstPacketsFrom(const QUuid& uuid) {
|
||||||
|
if (_hasReceivedFirstPacketsFrom.find(uuid) == _hasReceivedFirstPacketsFrom.end()) {
|
||||||
|
_hasReceivedFirstPacketsFrom.insert(uuid);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
uint16_t AvatarMixerClientData::getLastBroadcastSequenceNumber(const QUuid& nodeUUID) const {
|
uint16_t AvatarMixerClientData::getLastBroadcastSequenceNumber(const QUuid& nodeUUID) const {
|
||||||
// return the matching PacketSequenceNumber, or the default if we don't have it
|
// return the matching PacketSequenceNumber, or the default if we don't have it
|
||||||
auto nodeMatch = _lastBroadcastSequenceNumbers.find(nodeUUID);
|
auto nodeMatch = _lastBroadcastSequenceNumbers.find(nodeUUID);
|
||||||
|
|
|
@ -15,6 +15,7 @@
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <cfloat>
|
#include <cfloat>
|
||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
|
#include <unordered_set>
|
||||||
|
|
||||||
#include <QtCore/QJsonObject>
|
#include <QtCore/QJsonObject>
|
||||||
#include <QtCore/QUrl>
|
#include <QtCore/QUrl>
|
||||||
|
@ -36,6 +37,7 @@ public:
|
||||||
AvatarData& getAvatar() { return _avatar; }
|
AvatarData& getAvatar() { return _avatar; }
|
||||||
|
|
||||||
bool checkAndSetHasReceivedFirstPackets();
|
bool checkAndSetHasReceivedFirstPackets();
|
||||||
|
bool checkAndSetHasReceivedFirstPacketsFrom(const QUuid& uuid);
|
||||||
|
|
||||||
uint16_t getLastBroadcastSequenceNumber(const QUuid& nodeUUID) const;
|
uint16_t getLastBroadcastSequenceNumber(const QUuid& nodeUUID) const;
|
||||||
void setLastBroadcastSequenceNumber(const QUuid& nodeUUID, uint16_t sequenceNumber)
|
void setLastBroadcastSequenceNumber(const QUuid& nodeUUID, uint16_t sequenceNumber)
|
||||||
|
@ -83,6 +85,7 @@ private:
|
||||||
|
|
||||||
uint16_t _lastReceivedSequenceNumber { 0 };
|
uint16_t _lastReceivedSequenceNumber { 0 };
|
||||||
std::unordered_map<QUuid, uint16_t> _lastBroadcastSequenceNumbers;
|
std::unordered_map<QUuid, uint16_t> _lastBroadcastSequenceNumbers;
|
||||||
|
std::unordered_set<QUuid> _hasReceivedFirstPacketsFrom;
|
||||||
|
|
||||||
bool _hasReceivedFirstPackets = false;
|
bool _hasReceivedFirstPackets = false;
|
||||||
quint64 _billboardChangeTimestamp = 0;
|
quint64 _billboardChangeTimestamp = 0;
|
||||||
|
|
Loading…
Reference in a new issue