From 82b81c907670a0eb26053648bc551045219c6841 Mon Sep 17 00:00:00 2001 From: Simon Walton Date: Mon, 24 Sep 2018 11:48:48 -0700 Subject: [PATCH] Limit no. of joints sent per avatar to prevent lock-up With this the avatar mixer will sent the full bit-vector but only the first 111 actual joints. --- libraries/avatars/src/AvatarData.cpp | 10 +++++++--- libraries/avatars/src/AvatarData.h | 3 ++- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/libraries/avatars/src/AvatarData.cpp b/libraries/avatars/src/AvatarData.cpp index 782483a6c1..31687a7f27 100644 --- a/libraries/avatars/src/AvatarData.cpp +++ b/libraries/avatars/src/AvatarData.cpp @@ -592,10 +592,12 @@ QByteArray AvatarData::toByteArray(AvatarDataDetail dataDetail, quint64 lastSent jointData = _jointData; } const int numJoints = jointData.size(); + assert(numJoints <= 255); const int jointBitVectorSize = calcBitVectorSize(numJoints); + const int cappedNumJoints = std::min(numJoints, AvatarDataPacket::MAX_NUM_JOINTS); // Check against full size or minimum size: count + two bit-vectors + two controllers - const size_t approxJointSpace = sendAll ? AvatarDataPacket::maxJointDataSize(numJoints, true) : + const size_t approxJointSpace = sendAll ? AvatarDataPacket::maxJointDataSize(cappedNumJoints, false) : 1 + 2 * jointBitVectorSize + 2 * (sizeof(AvatarDataPacket::SixByteQuat) + sizeof(AvatarDataPacket::SixByteTrans)); IF_AVATAR_SPACE(PACKET_HAS_JOINT_DATA, approxJointSpace) { @@ -605,6 +607,7 @@ QByteArray AvatarData::toByteArray(AvatarDataDetail dataDetail, quint64 lastSent *destinationBuffer++ = (uint8_t)numJoints; unsigned char* validityPosition = destinationBuffer; + memset(validityPosition, 0, jointBitVectorSize); unsigned char validity = 0; int validityBit = 0; @@ -622,7 +625,7 @@ QByteArray AvatarData::toByteArray(AvatarDataDetail dataDetail, quint64 lastSent float minRotationDOT = (distanceAdjust && cullSmallChanges) ? getDistanceBasedMinRotationDOT(viewerPosition) : AVATAR_MIN_ROTATION_DOT; - for (int i = 0; i < jointData.size(); i++) { + for (int i = 0; i < cappedNumJoints; i++) { const JointData& data = jointData[i]; const JointData& last = lastSentJointData[i]; @@ -666,12 +669,13 @@ QByteArray AvatarData::toByteArray(AvatarDataDetail dataDetail, quint64 lastSent unsigned char* beforeTranslations = destinationBuffer; #endif + memset(destinationBuffer, 0, jointBitVectorSize); destinationBuffer += jointBitVectorSize; // Move pointer past the validity bytes float minTranslation = (distanceAdjust && cullSmallChanges) ? getDistanceBasedMinTranslationDistance(viewerPosition) : AVATAR_MIN_TRANSLATION; float maxTranslationDimension = 0.0; - for (int i = 0; i < jointData.size(); i++) { + for (int i = 0; i < cappedNumJoints; i++) { const JointData& data = jointData[i]; const JointData& last = lastSentJointData[i]; diff --git a/libraries/avatars/src/AvatarData.h b/libraries/avatars/src/AvatarData.h index 3ea7631e0c..5b5d49feea 100644 --- a/libraries/avatars/src/AvatarData.h +++ b/libraries/avatars/src/AvatarData.h @@ -297,7 +297,8 @@ namespace AvatarDataPacket { const size_t FAR_GRAB_JOINTS_SIZE = 84; static_assert(sizeof(FarGrabJoints) == FAR_GRAB_JOINTS_SIZE, "AvatarDataPacket::FarGrabJoints size doesn't match."); - const size_t MIN_BULK_PACKET_SIZE = NUM_BYTES_RFC4122_UUID + HEADER_SIZE; + static const size_t MIN_BULK_PACKET_SIZE = NUM_BYTES_RFC4122_UUID + HEADER_SIZE; + static const int MAX_NUM_JOINTS = 111; } const float MAX_AUDIO_LOUDNESS = 1000.0f; // close enough for mouth animation