mirror of
https://github.com/overte-org/overte.git
synced 2025-04-19 12:23:24 +02:00
fix differential avatar-joint sending to work if more than 2 avatars are in the domain
This commit is contained in:
parent
cd1dac50ad
commit
36ca789d92
6 changed files with 51 additions and 13 deletions
|
@ -295,7 +295,8 @@ void AvatarMixer::broadcastAvatarData() {
|
|||
avatarPacketList.startSegment();
|
||||
|
||||
numAvatarDataBytes += avatarPacketList.write(otherNode->getUUID().toRfc4122());
|
||||
numAvatarDataBytes += avatarPacketList.write(otherAvatar.toByteArray(false));
|
||||
numAvatarDataBytes +=
|
||||
avatarPacketList.write(otherAvatar.toByteArray(false, randFloat() < AVATAR_SEND_FULL_UPDATE_RATIO));
|
||||
|
||||
avatarPacketList.endSegment();
|
||||
|
||||
|
@ -361,6 +362,29 @@ void AvatarMixer::broadcastAvatarData() {
|
|||
} else {
|
||||
nodeData->setMaxAvatarDistance(maxAvatarDistanceThisFrame);
|
||||
}
|
||||
|
||||
// We're done encoding this version of the otherAvatars. Update their "lastSent" joint-states so
|
||||
// that we can notice differences, next time around.
|
||||
nodeList->eachMatchingNode(
|
||||
[&](const SharedNodePointer& otherNode)->bool {
|
||||
if (!otherNode->getLinkedData()) {
|
||||
return false;
|
||||
}
|
||||
if (otherNode->getUUID() == node->getUUID()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
},
|
||||
[&](const SharedNodePointer& otherNode) {
|
||||
AvatarMixerClientData* otherNodeData = reinterpret_cast<AvatarMixerClientData*>(otherNode->getLinkedData());
|
||||
MutexTryLocker lock(otherNodeData->getMutex());
|
||||
if (!lock.isLocked()) {
|
||||
return;
|
||||
}
|
||||
AvatarData& otherAvatar = otherNodeData->getAvatar();
|
||||
otherAvatar.doneEncoding();
|
||||
});
|
||||
}
|
||||
);
|
||||
|
||||
|
|
|
@ -123,18 +123,18 @@ MyAvatar::~MyAvatar() {
|
|||
_lookAtTargetAvatar.reset();
|
||||
}
|
||||
|
||||
QByteArray MyAvatar::toByteArray(bool cullSmallChanges) {
|
||||
QByteArray MyAvatar::toByteArray(bool cullSmallChanges, bool sendAll) {
|
||||
CameraMode mode = Application::getInstance()->getCamera()->getMode();
|
||||
if (mode == CAMERA_MODE_THIRD_PERSON || mode == CAMERA_MODE_INDEPENDENT) {
|
||||
// fake the avatar position that is sent up to the AvatarMixer
|
||||
glm::vec3 oldPosition = _position;
|
||||
_position = getSkeletonPosition();
|
||||
QByteArray array = AvatarData::toByteArray(cullSmallChanges);
|
||||
QByteArray array = AvatarData::toByteArray(cullSmallChanges, sendAll);
|
||||
// copy the correct position back
|
||||
_position = oldPosition;
|
||||
return array;
|
||||
}
|
||||
return AvatarData::toByteArray(cullSmallChanges);
|
||||
return AvatarData::toByteArray(cullSmallChanges, sendAll);
|
||||
}
|
||||
|
||||
void MyAvatar::reset() {
|
||||
|
|
|
@ -200,7 +200,7 @@ private:
|
|||
|
||||
glm::vec3 getWorldBodyPosition() const;
|
||||
glm::quat getWorldBodyOrientation() const;
|
||||
QByteArray toByteArray(bool cullSmallChanges);
|
||||
QByteArray toByteArray(bool cullSmallChanges, bool sendAll);
|
||||
void simulate(float deltaTime);
|
||||
void updateFromTrackers(float deltaTime);
|
||||
virtual void render(RenderArgs* renderArgs, const glm::vec3& cameraPositio) override;
|
||||
|
|
|
@ -145,7 +145,7 @@ void AvatarData::setHandPosition(const glm::vec3& handPosition) {
|
|||
_handPosition = glm::inverse(getOrientation()) * (handPosition - _position);
|
||||
}
|
||||
|
||||
QByteArray AvatarData::toByteArray(bool cullSmallChanges) {
|
||||
QByteArray AvatarData::toByteArray(bool cullSmallChanges, bool sendAll) {
|
||||
// TODO: DRY this up to a shared method
|
||||
// that can pack any type given the number of bytes
|
||||
// and return the number of bytes to push the pointer
|
||||
|
@ -244,11 +244,12 @@ QByteArray AvatarData::toByteArray(bool cullSmallChanges) {
|
|||
|
||||
_lastSentJointData.resize(_jointData.size());
|
||||
|
||||
// foreach (const JointData& data, _jointData) {
|
||||
for (int i=0; i < _jointData.size(); i++) {
|
||||
const JointData& data = _jointData.at(i);
|
||||
if (_lastSentJointData[i].rotation != data.rotation) {
|
||||
if (!cullSmallChanges || fabsf(glm::dot(data.rotation, _lastSentJointData[i].rotation)) <= MIN_ROTATION_DOT) {
|
||||
if (sendAll || _lastSentJointData[i].rotation != data.rotation) {
|
||||
if (sendAll ||
|
||||
!cullSmallChanges ||
|
||||
fabsf(glm::dot(data.rotation, _lastSentJointData[i].rotation)) <= MIN_ROTATION_DOT) {
|
||||
validity |= (1 << validityBit);
|
||||
}
|
||||
}
|
||||
|
@ -267,7 +268,6 @@ QByteArray AvatarData::toByteArray(bool cullSmallChanges) {
|
|||
const JointData& data = _jointData[ i ];
|
||||
if (validity & (1 << validityBit)) {
|
||||
destinationBuffer += packOrientationQuatToBytes(destinationBuffer, data.rotation);
|
||||
_lastSentJointData[i].rotation = data.rotation;
|
||||
}
|
||||
if (++validityBit == BITS_IN_BYTE) {
|
||||
validityBit = 0;
|
||||
|
@ -278,6 +278,16 @@ QByteArray AvatarData::toByteArray(bool cullSmallChanges) {
|
|||
return avatarDataByteArray.left(destinationBuffer - startPosition);
|
||||
}
|
||||
|
||||
void AvatarData::doneEncoding() {
|
||||
// The server has finished sending this version of the joint-data to other nodes. Update _lastSentJointData.
|
||||
_lastSentJointData.resize(_jointData.size());
|
||||
for (int i = 0; i < _jointData.size(); i ++) {
|
||||
const JointData& data = _jointData[ i ];
|
||||
_lastSentJointData[i].rotation = data.rotation;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool AvatarData::shouldLogError(const quint64& now) {
|
||||
if (now > _errorLogExpiry) {
|
||||
_errorLogExpiry = now + DEFAULT_FILTERED_LOG_EXPIRY;
|
||||
|
@ -1083,7 +1093,8 @@ void AvatarData::setJointMappingsFromNetworkReply() {
|
|||
void AvatarData::sendAvatarDataPacket() {
|
||||
auto nodeList = DependencyManager::get<NodeList>();
|
||||
|
||||
QByteArray avatarByteArray = toByteArray(true);
|
||||
QByteArray avatarByteArray = toByteArray(true, randFloat() < AVATAR_SEND_FULL_UPDATE_RATIO);
|
||||
doneEncoding();
|
||||
|
||||
auto avatarPacket = NLPacket::create(PacketType::AvatarData, avatarByteArray.size());
|
||||
avatarPacket->write(avatarByteArray);
|
||||
|
|
|
@ -111,6 +111,7 @@ const int AVATAR_BILLBOARD_PACKET_SEND_INTERVAL_MSECS = 5000;
|
|||
// See also static AvatarData::defaultFullAvatarModelUrl().
|
||||
const QString DEFAULT_FULL_AVATAR_MODEL_NAME = QString("Default");
|
||||
|
||||
const float AVATAR_SEND_FULL_UPDATE_RATIO = 0.02;
|
||||
|
||||
// Where one's own Avatar begins in the world (will be overwritten if avatar data file is found).
|
||||
// This is the start location in the Sandbox (xyz: 6270, 211, 6000).
|
||||
|
@ -171,7 +172,8 @@ public:
|
|||
glm::vec3 getHandPosition() const;
|
||||
void setHandPosition(const glm::vec3& handPosition);
|
||||
|
||||
virtual QByteArray toByteArray(bool cullSmallChanges);
|
||||
virtual QByteArray toByteArray(bool cullSmallChanges, bool sendAll);
|
||||
virtual void doneEncoding();
|
||||
|
||||
/// \return true if an error should be logged
|
||||
bool shouldLogError(const quint64& now);
|
||||
|
|
|
@ -599,7 +599,8 @@ void ScriptEngine::run() {
|
|||
/ (1000 * 1000)) + 0.5);
|
||||
const int SCRIPT_AUDIO_BUFFER_BYTES = SCRIPT_AUDIO_BUFFER_SAMPLES * sizeof(int16_t);
|
||||
|
||||
QByteArray avatarByteArray = _avatarData->toByteArray(true);
|
||||
QByteArray avatarByteArray = _avatarData->toByteArray(true, randFloat() < AVATAR_SEND_FULL_UPDATE_RATIO);
|
||||
_avatarData->doneEncoding();
|
||||
auto avatarPacket = NLPacket::create(PacketType::AvatarData, avatarByteArray.size());
|
||||
|
||||
avatarPacket->write(avatarByteArray);
|
||||
|
|
Loading…
Reference in a new issue