mirror of
https://github.com/overte-org/overte.git
synced 2025-08-08 22:16:58 +02:00
Split avatar joint-data across multiple packets if necessary
This commit is contained in:
parent
82b81c9076
commit
07bdaeede7
3 changed files with 80 additions and 83 deletions
|
@ -450,12 +450,12 @@ void AvatarMixerSlave::broadcastAvatarDataToAgent(const SharedNodePointer& node)
|
||||||
|
|
||||||
const bool distanceAdjust = true;
|
const bool distanceAdjust = true;
|
||||||
const bool dropFaceTracking = false;
|
const bool dropFaceTracking = false;
|
||||||
AvatarDataPacket::HasFlags includeFlags = 0; // the result of the toByteArray
|
AvatarDataPacket::SendStatus sendStatus;
|
||||||
|
|
||||||
do {
|
do {
|
||||||
auto startSerialize = chrono::high_resolution_clock::now();
|
auto startSerialize = chrono::high_resolution_clock::now();
|
||||||
QByteArray bytes = otherAvatar->toByteArray(detail, lastEncodeForOther, lastSentJointsForOther,
|
QByteArray bytes = otherAvatar->toByteArray(detail, lastEncodeForOther, lastSentJointsForOther,
|
||||||
includeFlags, dropFaceTracking, distanceAdjust, myPosition,
|
sendStatus, dropFaceTracking, distanceAdjust, myPosition,
|
||||||
&lastSentJointsForOther, avatarSpaceAvailable);
|
&lastSentJointsForOther, avatarSpaceAvailable);
|
||||||
auto endSerialize = chrono::high_resolution_clock::now();
|
auto endSerialize = chrono::high_resolution_clock::now();
|
||||||
_stats.toByteArrayElapsedTime +=
|
_stats.toByteArrayElapsedTime +=
|
||||||
|
@ -464,14 +464,14 @@ void AvatarMixerSlave::broadcastAvatarDataToAgent(const SharedNodePointer& node)
|
||||||
avatarPacket->write(bytes);
|
avatarPacket->write(bytes);
|
||||||
avatarSpaceAvailable -= bytes.size();
|
avatarSpaceAvailable -= bytes.size();
|
||||||
numAvatarDataBytes += bytes.size();
|
numAvatarDataBytes += bytes.size();
|
||||||
if (includeFlags != 0 || avatarSpaceAvailable < (int)AvatarDataPacket::MIN_BULK_PACKET_SIZE) {
|
if (sendStatus.itemFlags != 0 || avatarSpaceAvailable < (int)AvatarDataPacket::MIN_BULK_PACKET_SIZE) {
|
||||||
// Weren't able to fit everything.
|
// Weren't able to fit everything.
|
||||||
nodeList->sendPacket(std::move(avatarPacket), *destinationNode);
|
nodeList->sendPacket(std::move(avatarPacket), *destinationNode);
|
||||||
++numPacketsSent;
|
++numPacketsSent;
|
||||||
avatarPacket = NLPacket::create(PacketType::BulkAvatarData);
|
avatarPacket = NLPacket::create(PacketType::BulkAvatarData);
|
||||||
avatarSpaceAvailable = avatarPacketCapacity;
|
avatarSpaceAvailable = avatarPacketCapacity;
|
||||||
}
|
}
|
||||||
} while (includeFlags != 0);
|
} while (!sendStatus);
|
||||||
|
|
||||||
if (detail != AvatarData::NoData) {
|
if (detail != AvatarData::NoData) {
|
||||||
_stats.numOthersIncluded++;
|
_stats.numOthersIncluded++;
|
||||||
|
@ -565,12 +565,12 @@ void AvatarMixerSlave::broadcastAvatarDataToDownstreamMixer(const SharedNodePoin
|
||||||
// so we always send a full update for this avatar
|
// so we always send a full update for this avatar
|
||||||
|
|
||||||
quint64 start = usecTimestampNow();
|
quint64 start = usecTimestampNow();
|
||||||
AvatarDataPacket::HasFlags flagsOut;
|
AvatarDataPacket::SendStatus sendStatus;
|
||||||
|
|
||||||
QVector<JointData> emptyLastJointSendData { otherAvatar->getJointCount() };
|
QVector<JointData> emptyLastJointSendData { otherAvatar->getJointCount() };
|
||||||
|
|
||||||
QByteArray avatarByteArray = otherAvatar->toByteArray(AvatarData::SendAllData, 0, emptyLastJointSendData,
|
QByteArray avatarByteArray = otherAvatar->toByteArray(AvatarData::SendAllData, 0, emptyLastJointSendData,
|
||||||
flagsOut, false, false, glm::vec3(0), nullptr, 0);
|
sendStatus, false, false, glm::vec3(0), nullptr, 0);
|
||||||
quint64 end = usecTimestampNow();
|
quint64 end = usecTimestampNow();
|
||||||
_stats.toByteArrayElapsedTime += (end - start);
|
_stats.toByteArrayElapsedTime += (end - start);
|
||||||
|
|
||||||
|
@ -596,14 +596,14 @@ void AvatarMixerSlave::broadcastAvatarDataToDownstreamMixer(const SharedNodePoin
|
||||||
<< "-" << avatarByteArray.size() << "bytes";
|
<< "-" << avatarByteArray.size() << "bytes";
|
||||||
|
|
||||||
avatarByteArray = otherAvatar->toByteArray(AvatarData::SendAllData, 0, emptyLastJointSendData,
|
avatarByteArray = otherAvatar->toByteArray(AvatarData::SendAllData, 0, emptyLastJointSendData,
|
||||||
flagsOut, true, false, glm::vec3(0), nullptr, 0);
|
sendStatus, true, false, glm::vec3(0), nullptr, 0);
|
||||||
|
|
||||||
if (avatarByteArray.size() > maxAvatarByteArraySize) {
|
if (avatarByteArray.size() > maxAvatarByteArraySize) {
|
||||||
qCWarning(avatars) << "Replicated avatar data without facial data still too large for"
|
qCWarning(avatars) << "Replicated avatar data without facial data still too large for"
|
||||||
<< otherAvatar->getSessionUUID() << "-" << avatarByteArray.size() << "bytes";
|
<< otherAvatar->getSessionUUID() << "-" << avatarByteArray.size() << "bytes";
|
||||||
|
|
||||||
avatarByteArray = otherAvatar->toByteArray(AvatarData::MinimumData, 0, emptyLastJointSendData,
|
avatarByteArray = otherAvatar->toByteArray(AvatarData::MinimumData, 0, emptyLastJointSendData,
|
||||||
flagsOut, true, false, glm::vec3(0), nullptr, 0);
|
sendStatus, true, false, glm::vec3(0), nullptr, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -225,16 +225,16 @@ QByteArray AvatarData::toByteArrayStateful(AvatarDataDetail dataDetail, bool dro
|
||||||
AvatarDataPacket::HasFlags hasFlagsOut = 0;
|
AvatarDataPacket::HasFlags hasFlagsOut = 0;
|
||||||
auto lastSentTime = _lastToByteArray;
|
auto lastSentTime = _lastToByteArray;
|
||||||
_lastToByteArray = usecTimestampNow();
|
_lastToByteArray = usecTimestampNow();
|
||||||
|
AvatarDataPacket::SendStatus sendStatus;
|
||||||
auto avatarByteArray = AvatarData::toByteArray(dataDetail, lastSentTime, getLastSentJointData(),
|
auto avatarByteArray = AvatarData::toByteArray(dataDetail, lastSentTime, getLastSentJointData(),
|
||||||
hasFlagsOut, dropFaceTracking, false, glm::vec3(0), nullptr,
|
sendStatus, dropFaceTracking, false, glm::vec3(0), nullptr, 0, &_outboundDataRate);
|
||||||
0, &_outboundDataRate);
|
|
||||||
// Strip UUID
|
// Strip UUID
|
||||||
return avatarByteArray.right(avatarByteArray.size() - NUM_BYTES_RFC4122_UUID);
|
return avatarByteArray.right(avatarByteArray.size() - NUM_BYTES_RFC4122_UUID);
|
||||||
}
|
}
|
||||||
|
|
||||||
QByteArray AvatarData::toByteArray(AvatarDataDetail dataDetail, quint64 lastSentTime,
|
QByteArray AvatarData::toByteArray(AvatarDataDetail dataDetail, quint64 lastSentTime,
|
||||||
const QVector<JointData>& lastSentJointData,
|
const QVector<JointData>& lastSentJointData,
|
||||||
AvatarDataPacket::HasFlags& itemFlags, bool dropFaceTracking, bool distanceAdjust,
|
AvatarDataPacket::SendStatus& sendStatus, bool dropFaceTracking, bool distanceAdjust,
|
||||||
glm::vec3 viewerPosition, QVector<JointData>* sentJointDataOut, int maxDataSize, AvatarDataRate* outboundDataRateOut) const {
|
glm::vec3 viewerPosition, QVector<JointData>* sentJointDataOut, int maxDataSize, AvatarDataRate* outboundDataRateOut) const {
|
||||||
|
|
||||||
bool cullSmallChanges = (dataDetail == CullSmallData);
|
bool cullSmallChanges = (dataDetail == CullSmallData);
|
||||||
|
@ -248,7 +248,7 @@ QByteArray AvatarData::toByteArray(AvatarDataDetail dataDetail, quint64 lastSent
|
||||||
// special case, if we were asked for no data, then just include the flags all set to nothing
|
// special case, if we were asked for no data, then just include the flags all set to nothing
|
||||||
if (dataDetail == NoData) {
|
if (dataDetail == NoData) {
|
||||||
AvatarDataPacket::HasFlags packetStateFlags = 0;
|
AvatarDataPacket::HasFlags packetStateFlags = 0;
|
||||||
itemFlags = packetStateFlags;
|
sendStatus.itemFlags = packetStateFlags;
|
||||||
|
|
||||||
QByteArray avatarDataByteArray(getSessionUUID().toRfc4122().data(), NUM_BYTES_RFC4122_UUID + sizeof(packetStateFlags));
|
QByteArray avatarDataByteArray(getSessionUUID().toRfc4122().data(), NUM_BYTES_RFC4122_UUID + sizeof(packetStateFlags));
|
||||||
avatarDataByteArray.append((char*) &packetStateFlags, sizeof packetStateFlags);
|
avatarDataByteArray.append((char*) &packetStateFlags, sizeof packetStateFlags);
|
||||||
|
@ -274,7 +274,7 @@ QByteArray AvatarData::toByteArray(AvatarDataDetail dataDetail, quint64 lastSent
|
||||||
// 3 translations * 6 bytes = 6.48kbps
|
// 3 translations * 6 bytes = 6.48kbps
|
||||||
//
|
//
|
||||||
|
|
||||||
auto parentID = getParentID();
|
QUuid parentID;
|
||||||
|
|
||||||
glm::mat4 leftFarGrabMatrix;
|
glm::mat4 leftFarGrabMatrix;
|
||||||
glm::mat4 rightFarGrabMatrix;
|
glm::mat4 rightFarGrabMatrix;
|
||||||
|
@ -283,7 +283,7 @@ QByteArray AvatarData::toByteArray(AvatarDataDetail dataDetail, quint64 lastSent
|
||||||
// Leading flags, to indicate how much data is actually included in the packet...
|
// Leading flags, to indicate how much data is actually included in the packet...
|
||||||
AvatarDataPacket::HasFlags packetStateFlags = 0;
|
AvatarDataPacket::HasFlags packetStateFlags = 0;
|
||||||
|
|
||||||
if (itemFlags == 0) {
|
if (sendStatus.itemFlags == 0) {
|
||||||
bool hasAvatarGlobalPosition = true; // always include global position
|
bool hasAvatarGlobalPosition = true; // always include global position
|
||||||
bool hasAvatarOrientation = false;
|
bool hasAvatarOrientation = false;
|
||||||
bool hasAvatarBoundingBox = false;
|
bool hasAvatarBoundingBox = false;
|
||||||
|
@ -340,13 +340,11 @@ QByteArray AvatarData::toByteArray(AvatarDataDetail dataDetail, quint64 lastSent
|
||||||
| (hasJointDefaultPoseFlags ? AvatarDataPacket::PACKET_HAS_JOINT_DEFAULT_POSE_FLAGS : 0)
|
| (hasJointDefaultPoseFlags ? AvatarDataPacket::PACKET_HAS_JOINT_DEFAULT_POSE_FLAGS : 0)
|
||||||
| (hasJointData ? AvatarDataPacket::PACKET_HAS_GRAB_JOINTS : 0);
|
| (hasJointData ? AvatarDataPacket::PACKET_HAS_GRAB_JOINTS : 0);
|
||||||
|
|
||||||
itemFlags = packetStateFlags;
|
sendStatus.itemFlags = packetStateFlags;
|
||||||
|
sendStatus.rotationsSent = 0;
|
||||||
|
sendStatus.translationsSent = 0;
|
||||||
} else {
|
} else {
|
||||||
packetStateFlags = itemFlags;
|
packetStateFlags = sendStatus.itemFlags;
|
||||||
if (packetStateFlags & AvatarDataPacket::PACKET_HAS_JOINT_DATA) {
|
|
||||||
// Force all joints upon continuation, as deltas aren't valid.
|
|
||||||
sendAll = true;
|
|
||||||
}
|
|
||||||
if (packetStateFlags & AvatarDataPacket::PACKET_HAS_GRAB_JOINTS) {
|
if (packetStateFlags & AvatarDataPacket::PACKET_HAS_GRAB_JOINTS) {
|
||||||
packetStateFlags |= AvatarDataPacket::PACKET_HAS_JOINT_DATA;
|
packetStateFlags |= AvatarDataPacket::PACKET_HAS_JOINT_DATA;
|
||||||
}
|
}
|
||||||
|
@ -372,6 +370,9 @@ QByteArray AvatarData::toByteArray(AvatarDataDetail dataDetail, quint64 lastSent
|
||||||
packetStateFlags &= ~AvatarDataPacket::PACKET_HAS_GRAB_JOINTS;
|
packetStateFlags &= ~AvatarDataPacket::PACKET_HAS_GRAB_JOINTS;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (packetStateFlags & (AvatarDataPacket::PACKET_HAS_ADDITIONAL_FLAGS | AvatarDataPacket::PACKET_HAS_PARENT_INFO)) {
|
||||||
|
parentID = getParentID();
|
||||||
|
}
|
||||||
|
|
||||||
const size_t byteArraySize = AvatarDataPacket::MAX_CONSTANT_HEADER_SIZE + NUM_BYTES_RFC4122_UUID +
|
const size_t byteArraySize = AvatarDataPacket::MAX_CONSTANT_HEADER_SIZE + NUM_BYTES_RFC4122_UUID +
|
||||||
AvatarDataPacket::maxFaceTrackerInfoSize(_headData->getBlendshapeCoefficients().size()) +
|
AvatarDataPacket::maxFaceTrackerInfoSize(_headData->getBlendshapeCoefficients().size()) +
|
||||||
|
@ -388,6 +389,7 @@ QByteArray AvatarData::toByteArray(AvatarDataDetail dataDetail, quint64 lastSent
|
||||||
const unsigned char* const packetEnd = destinationBuffer + maxDataSize;
|
const unsigned char* const packetEnd = destinationBuffer + maxDataSize;
|
||||||
|
|
||||||
AvatarDataPacket::HasFlags includedFlags = 0;
|
AvatarDataPacket::HasFlags includedFlags = 0;
|
||||||
|
AvatarDataPacket::HasFlags extraReturnedFlags = 0;
|
||||||
|
|
||||||
// Packets always have UUID.
|
// Packets always have UUID.
|
||||||
memcpy(destinationBuffer, getSessionUUID().toRfc4122(), NUM_BYTES_RFC4122_UUID);
|
memcpy(destinationBuffer, getSessionUUID().toRfc4122(), NUM_BYTES_RFC4122_UUID);
|
||||||
|
@ -594,13 +596,11 @@ QByteArray AvatarData::toByteArray(AvatarDataDetail dataDetail, quint64 lastSent
|
||||||
const int numJoints = jointData.size();
|
const int numJoints = jointData.size();
|
||||||
assert(numJoints <= 255);
|
assert(numJoints <= 255);
|
||||||
const int jointBitVectorSize = calcBitVectorSize(numJoints);
|
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
|
IF_AVATAR_SPACE(PACKET_HAS_JOINT_DATA, 1 + 2 * jointBitVectorSize + AvatarDataPacket::FAUX_JOINT_SIZE) {
|
||||||
const size_t approxJointSpace = sendAll ? AvatarDataPacket::maxJointDataSize(cappedNumJoints, false) :
|
// Allow for faux joints + translation bit-vector:
|
||||||
1 + 2 * jointBitVectorSize + 2 * (sizeof(AvatarDataPacket::SixByteQuat) + sizeof(AvatarDataPacket::SixByteTrans));
|
static const ptrdiff_t MIN_SIZE_FOR_JOINT = sizeof(AvatarDataPacket::SixByteQuat)
|
||||||
|
+ jointBitVectorSize + AvatarDataPacket::FAUX_JOINT_SIZE;
|
||||||
IF_AVATAR_SPACE(PACKET_HAS_JOINT_DATA, approxJointSpace) {
|
|
||||||
auto startSection = destinationBuffer;
|
auto startSection = destinationBuffer;
|
||||||
|
|
||||||
// joint rotation data
|
// joint rotation data
|
||||||
|
@ -608,8 +608,6 @@ QByteArray AvatarData::toByteArray(AvatarDataDetail dataDetail, quint64 lastSent
|
||||||
|
|
||||||
unsigned char* validityPosition = destinationBuffer;
|
unsigned char* validityPosition = destinationBuffer;
|
||||||
memset(validityPosition, 0, jointBitVectorSize);
|
memset(validityPosition, 0, jointBitVectorSize);
|
||||||
unsigned char validity = 0;
|
|
||||||
int validityBit = 0;
|
|
||||||
|
|
||||||
#ifdef WANT_DEBUG
|
#ifdef WANT_DEBUG
|
||||||
int rotationSentCount = 0;
|
int rotationSentCount = 0;
|
||||||
|
@ -625,44 +623,41 @@ QByteArray AvatarData::toByteArray(AvatarDataDetail dataDetail, quint64 lastSent
|
||||||
|
|
||||||
float minRotationDOT = (distanceAdjust && cullSmallChanges) ? getDistanceBasedMinRotationDOT(viewerPosition) : AVATAR_MIN_ROTATION_DOT;
|
float minRotationDOT = (distanceAdjust && cullSmallChanges) ? getDistanceBasedMinRotationDOT(viewerPosition) : AVATAR_MIN_ROTATION_DOT;
|
||||||
|
|
||||||
for (int i = 0; i < cappedNumJoints; i++) {
|
int i = sendStatus.rotationsSent;
|
||||||
|
for (; i < numJoints; ++i) {
|
||||||
const JointData& data = jointData[i];
|
const JointData& data = jointData[i];
|
||||||
const JointData& last = lastSentJointData[i];
|
const JointData& last = lastSentJointData[i];
|
||||||
|
|
||||||
if (!data.rotationIsDefaultPose) {
|
if ((packetEnd - destinationBuffer) >= MIN_SIZE_FOR_JOINT) {
|
||||||
// The dot product for larger rotations is a lower number,
|
if (!data.rotationIsDefaultPose) {
|
||||||
// so if the dot() is less than the value, then the rotation is a larger angle of rotation
|
// The dot product for larger rotations is a lower number,
|
||||||
if (sendAll || last.rotationIsDefaultPose || (!cullSmallChanges && last.rotation != data.rotation)
|
// so if the dot() is less than the value, then the rotation is a larger angle of rotation
|
||||||
|| (cullSmallChanges && glm::dot(last.rotation, data.rotation) < minRotationDOT) ) {
|
if (sendAll || last.rotationIsDefaultPose || (!cullSmallChanges && last.rotation != data.rotation)
|
||||||
validity |= (1 << validityBit);
|
|| (cullSmallChanges && glm::dot(last.rotation, data.rotation) < minRotationDOT)) {
|
||||||
|
validityPosition[i / BITS_IN_BYTE] |= 1 << (i % BITS_IN_BYTE);
|
||||||
#ifdef WANT_DEBUG
|
#ifdef WANT_DEBUG
|
||||||
rotationSentCount++;
|
rotationSentCount++;
|
||||||
#endif
|
#endif
|
||||||
destinationBuffer += packOrientationQuatToSixBytes(destinationBuffer, data.rotation);
|
destinationBuffer += packOrientationQuatToSixBytes(destinationBuffer, data.rotation);
|
||||||
|
|
||||||
if (sentJointDataOut) {
|
if (sentJointDataOut) {
|
||||||
(*sentJointDataOut)[i].rotation = data.rotation;
|
(*sentJointDataOut)[i].rotation = data.rotation;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sentJointDataOut) {
|
if (sentJointDataOut) {
|
||||||
(*sentJointDataOut)[i].rotationIsDefaultPose = data.rotationIsDefaultPose;
|
(*sentJointDataOut)[i].rotationIsDefaultPose = data.rotationIsDefaultPose;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (++validityBit == BITS_IN_BYTE) {
|
|
||||||
*validityPosition++ = validity;
|
|
||||||
validityBit = validity = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (validityBit != 0) {
|
|
||||||
*validityPosition++ = validity;
|
|
||||||
}
|
}
|
||||||
|
sendStatus.rotationsSent = i;
|
||||||
|
|
||||||
// joint translation data
|
// joint translation data
|
||||||
validityPosition = destinationBuffer;
|
validityPosition = destinationBuffer;
|
||||||
validity = 0;
|
|
||||||
validityBit = 0;
|
|
||||||
|
|
||||||
#ifdef WANT_DEBUG
|
#ifdef WANT_DEBUG
|
||||||
int translationSentCount = 0;
|
int translationSentCount = 0;
|
||||||
|
@ -675,44 +670,41 @@ QByteArray AvatarData::toByteArray(AvatarDataDetail dataDetail, quint64 lastSent
|
||||||
float minTranslation = (distanceAdjust && cullSmallChanges) ? getDistanceBasedMinTranslationDistance(viewerPosition) : AVATAR_MIN_TRANSLATION;
|
float minTranslation = (distanceAdjust && cullSmallChanges) ? getDistanceBasedMinTranslationDistance(viewerPosition) : AVATAR_MIN_TRANSLATION;
|
||||||
|
|
||||||
float maxTranslationDimension = 0.0;
|
float maxTranslationDimension = 0.0;
|
||||||
for (int i = 0; i < cappedNumJoints; i++) {
|
i = sendStatus.translationsSent;
|
||||||
|
for (; i < numJoints; ++i) {
|
||||||
const JointData& data = jointData[i];
|
const JointData& data = jointData[i];
|
||||||
const JointData& last = lastSentJointData[i];
|
const JointData& last = lastSentJointData[i];
|
||||||
|
|
||||||
if (!data.translationIsDefaultPose) {
|
if (packetEnd - destinationBuffer > MIN_SIZE_FOR_JOINT) {
|
||||||
if (sendAll || last.translationIsDefaultPose || (!cullSmallChanges && last.translation != data.translation)
|
if (!data.translationIsDefaultPose) {
|
||||||
|| (cullSmallChanges && glm::distance(data.translation, lastSentJointData[i].translation) > minTranslation)) {
|
if (sendAll || last.translationIsDefaultPose || (!cullSmallChanges && last.translation != data.translation)
|
||||||
|
|| (cullSmallChanges && glm::distance(data.translation, lastSentJointData[i].translation) > minTranslation)) {
|
||||||
validity |= (1 << validityBit);
|
validityPosition[i / BITS_IN_BYTE] |= 1 << (i % BITS_IN_BYTE);
|
||||||
#ifdef WANT_DEBUG
|
#ifdef WANT_DEBUG
|
||||||
translationSentCount++;
|
translationSentCount++;
|
||||||
#endif
|
#endif
|
||||||
maxTranslationDimension = glm::max(fabsf(data.translation.x), maxTranslationDimension);
|
maxTranslationDimension = glm::max(fabsf(data.translation.x), maxTranslationDimension);
|
||||||
maxTranslationDimension = glm::max(fabsf(data.translation.y), maxTranslationDimension);
|
maxTranslationDimension = glm::max(fabsf(data.translation.y), maxTranslationDimension);
|
||||||
maxTranslationDimension = glm::max(fabsf(data.translation.z), maxTranslationDimension);
|
maxTranslationDimension = glm::max(fabsf(data.translation.z), maxTranslationDimension);
|
||||||
|
|
||||||
destinationBuffer +=
|
destinationBuffer +=
|
||||||
packFloatVec3ToSignedTwoByteFixed(destinationBuffer, data.translation, TRANSLATION_COMPRESSION_RADIX);
|
packFloatVec3ToSignedTwoByteFixed(destinationBuffer, data.translation, TRANSLATION_COMPRESSION_RADIX);
|
||||||
|
|
||||||
if (sentJointDataOut) {
|
if (sentJointDataOut) {
|
||||||
(*sentJointDataOut)[i].translation = data.translation;
|
(*sentJointDataOut)[i].translation = data.translation;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sentJointDataOut) {
|
if (sentJointDataOut) {
|
||||||
(*sentJointDataOut)[i].translationIsDefaultPose = data.translationIsDefaultPose;
|
(*sentJointDataOut)[i].translationIsDefaultPose = data.translationIsDefaultPose;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (++validityBit == BITS_IN_BYTE) {
|
|
||||||
*validityPosition++ = validity;
|
|
||||||
validityBit = validity = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (validityBit != 0) {
|
|
||||||
*validityPosition++ = validity;
|
|
||||||
}
|
}
|
||||||
|
sendStatus.translationsSent = i;
|
||||||
|
|
||||||
// faux joints
|
// faux joints
|
||||||
Transform controllerLeftHandTransform = Transform(getControllerLeftHandMatrix());
|
Transform controllerLeftHandTransform = Transform(getControllerLeftHandMatrix());
|
||||||
|
@ -775,16 +767,14 @@ QByteArray AvatarData::toByteArray(AvatarDataDetail dataDetail, quint64 lastSent
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (destinationBuffer >= packetEnd) {
|
if (sendStatus.rotationsSent != numJoints || sendStatus.translationsSent != numJoints) {
|
||||||
// Joint data too large - revert
|
extraReturnedFlags |= AvatarDataPacket::PACKET_HAS_JOINT_DATA;
|
||||||
destinationBuffer = startSection;
|
}
|
||||||
includedFlags &= ~(AvatarDataPacket::PACKET_HAS_GRAB_JOINTS | AvatarDataPacket::PACKET_HAS_JOINT_DATA);
|
|
||||||
} else {
|
int numBytes = destinationBuffer - startSection;
|
||||||
int numBytes = destinationBuffer - startSection;
|
if (outboundDataRateOut) {
|
||||||
if (outboundDataRateOut) {
|
outboundDataRateOut->jointDataRate.increment(numBytes);
|
||||||
outboundDataRateOut->jointDataRate.increment(numBytes);
|
outboundDataRateOut->farGrabJointRate.increment(numGrabJointBytes);
|
||||||
outboundDataRateOut->farGrabJointRate.increment(numGrabJointBytes);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -812,7 +802,7 @@ QByteArray AvatarData::toByteArray(AvatarDataDetail dataDetail, quint64 lastSent
|
||||||
|
|
||||||
memcpy(packetFlagsLocation, &includedFlags, sizeof(includedFlags));
|
memcpy(packetFlagsLocation, &includedFlags, sizeof(includedFlags));
|
||||||
// Return dropped items.
|
// Return dropped items.
|
||||||
itemFlags = packetStateFlags & ~includedFlags;
|
sendStatus.itemFlags = (packetStateFlags & ~includedFlags) | extraReturnedFlags;
|
||||||
|
|
||||||
int avatarDataSize = destinationBuffer - startPosition;
|
int avatarDataSize = destinationBuffer - startPosition;
|
||||||
|
|
||||||
|
|
|
@ -298,7 +298,14 @@ namespace AvatarDataPacket {
|
||||||
static_assert(sizeof(FarGrabJoints) == FAR_GRAB_JOINTS_SIZE, "AvatarDataPacket::FarGrabJoints size doesn't match.");
|
static_assert(sizeof(FarGrabJoints) == FAR_GRAB_JOINTS_SIZE, "AvatarDataPacket::FarGrabJoints size doesn't match.");
|
||||||
|
|
||||||
static 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;
|
static const size_t FAUX_JOINT_SIZE = 2 * (sizeof(SixByteQuat) + sizeof(SixByteTrans));
|
||||||
|
|
||||||
|
struct SendStatus {
|
||||||
|
HasFlags itemFlags { 0 };
|
||||||
|
int rotationsSent { 0 };
|
||||||
|
int translationsSent { 0 };
|
||||||
|
operator bool() { return itemFlags == 0; }
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
const float MAX_AUDIO_LOUDNESS = 1000.0f; // close enough for mouth animation
|
const float MAX_AUDIO_LOUDNESS = 1000.0f; // close enough for mouth animation
|
||||||
|
@ -452,7 +459,7 @@ public:
|
||||||
virtual QByteArray toByteArrayStateful(AvatarDataDetail dataDetail, bool dropFaceTracking = false);
|
virtual QByteArray toByteArrayStateful(AvatarDataDetail dataDetail, bool dropFaceTracking = false);
|
||||||
|
|
||||||
virtual QByteArray toByteArray(AvatarDataDetail dataDetail, quint64 lastSentTime, const QVector<JointData>& lastSentJointData,
|
virtual QByteArray toByteArray(AvatarDataDetail dataDetail, quint64 lastSentTime, const QVector<JointData>& lastSentJointData,
|
||||||
AvatarDataPacket::HasFlags& hasFlagsOut, bool dropFaceTracking, bool distanceAdjust, glm::vec3 viewerPosition,
|
AvatarDataPacket::SendStatus& sendStatus, bool dropFaceTracking, bool distanceAdjust, glm::vec3 viewerPosition,
|
||||||
QVector<JointData>* sentJointDataOut, int maxDataSize = 0, AvatarDataRate* outboundDataRateOut = nullptr) const;
|
QVector<JointData>* sentJointDataOut, int maxDataSize = 0, AvatarDataRate* outboundDataRateOut = nullptr) const;
|
||||||
|
|
||||||
virtual void doneEncoding(bool cullSmallChanges);
|
virtual void doneEncoding(bool cullSmallChanges);
|
||||||
|
|
Loading…
Reference in a new issue