mirror of
https://github.com/overte-org/overte.git
synced 2025-08-08 13:58:51 +02:00
Avatar Mixer Protocol: Normalize translation before compression
This commit is contained in:
parent
a115af6353
commit
104084d811
2 changed files with 30 additions and 9 deletions
|
@ -677,7 +677,6 @@ QByteArray AvatarData::toByteArray(AvatarDataDetail dataDetail, quint64 lastSent
|
||||||
validityPosition = destinationBuffer;
|
validityPosition = destinationBuffer;
|
||||||
|
|
||||||
#ifdef WANT_DEBUG
|
#ifdef WANT_DEBUG
|
||||||
int translationSentCount = 0;
|
|
||||||
unsigned char* beforeTranslations = destinationBuffer;
|
unsigned char* beforeTranslations = destinationBuffer;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -686,7 +685,13 @@ 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.0f;
|
||||||
|
const int MAX_NUM_JOINTS = 256;
|
||||||
|
|
||||||
|
assert(numJoints < MAX_NUM_JOINTS);
|
||||||
|
glm::vec3 translationsSentArray[MAX_NUM_JOINTS]; // 3060 bytes allocated on the stack for performance.
|
||||||
|
int translationsSent = 0;
|
||||||
|
|
||||||
i = sendStatus.translationsSent;
|
i = sendStatus.translationsSent;
|
||||||
for (; i < numJoints; ++i) {
|
for (; i < numJoints; ++i) {
|
||||||
const JointData& data = joints[i];
|
const JointData& data = joints[i];
|
||||||
|
@ -697,15 +702,11 @@ QByteArray AvatarData::toByteArray(AvatarDataDetail dataDetail, quint64 lastSent
|
||||||
if (sendAll || last.translationIsDefaultPose || (!cullSmallChanges && last.translation != data.translation)
|
if (sendAll || last.translationIsDefaultPose || (!cullSmallChanges && last.translation != data.translation)
|
||||||
|| (cullSmallChanges && glm::distance(data.translation, lastSentJointData[i].translation) > minTranslation)) {
|
|| (cullSmallChanges && glm::distance(data.translation, lastSentJointData[i].translation) > minTranslation)) {
|
||||||
validityPosition[i / BITS_IN_BYTE] |= 1 << (i % BITS_IN_BYTE);
|
validityPosition[i / BITS_IN_BYTE] |= 1 << (i % BITS_IN_BYTE);
|
||||||
#ifdef WANT_DEBUG
|
|
||||||
translationSentCount++;
|
|
||||||
#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 +=
|
translationsSentArray[translationsSent++] = data.translation;
|
||||||
packFloatVec3ToSignedTwoByteFixed(destinationBuffer, data.translation, TRANSLATION_COMPRESSION_RADIX);
|
|
||||||
|
|
||||||
if (sentJoints) {
|
if (sentJoints) {
|
||||||
sentJoints[i].translation = data.translation;
|
sentJoints[i].translation = data.translation;
|
||||||
|
@ -721,6 +722,16 @@ QByteArray AvatarData::toByteArray(AvatarDataDetail dataDetail, quint64 lastSent
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// AJT: TODO make sure size computation is properly up to date!
|
||||||
|
// Write maxTranslationDimension into packet
|
||||||
|
memcpy(destinationBuffer, &maxTranslationDimension, sizeof(float));
|
||||||
|
destinationBuffer += sizeof(float);
|
||||||
|
|
||||||
|
// Write normalized and compressed translations into packet
|
||||||
|
for (i = 0; i < translationsSent; ++i) {
|
||||||
|
destinationBuffer += packFloatVec3ToSignedTwoByteFixed(destinationBuffer, translationsSentArray[i] / maxTranslationDimension, TRANSLATION_COMPRESSION_RADIX);
|
||||||
|
}
|
||||||
sendStatus.translationsSent = i;
|
sendStatus.translationsSent = i;
|
||||||
|
|
||||||
// faux joints
|
// faux joints
|
||||||
|
@ -766,7 +777,7 @@ QByteArray AvatarData::toByteArray(AvatarDataDetail dataDetail, quint64 lastSent
|
||||||
#ifdef WANT_DEBUG
|
#ifdef WANT_DEBUG
|
||||||
if (sendAll) {
|
if (sendAll) {
|
||||||
qCDebug(avatars) << "AvatarData::toByteArray" << cullSmallChanges << sendAll
|
qCDebug(avatars) << "AvatarData::toByteArray" << cullSmallChanges << sendAll
|
||||||
<< "rotations:" << rotationSentCount << "translations:" << translationSentCount
|
<< "rotations:" << rotationSentCount << "translations:" << translationsSentCount
|
||||||
<< "largest:" << maxTranslationDimension
|
<< "largest:" << maxTranslationDimension
|
||||||
<< "size:"
|
<< "size:"
|
||||||
<< (beforeRotations - startPosition) << "+"
|
<< (beforeRotations - startPosition) << "+"
|
||||||
|
@ -1280,6 +1291,13 @@ int AvatarData::parseDataFromBuffer(const QByteArray& buffer) {
|
||||||
}
|
}
|
||||||
} // 1 + bytesOfValidity bytes
|
} // 1 + bytesOfValidity bytes
|
||||||
|
|
||||||
|
|
||||||
|
// AJT: read maxTranslationDimension
|
||||||
|
float maxTranslationDimension;
|
||||||
|
PACKET_READ_CHECK(MaxTranslationDimension, sizeof(float));
|
||||||
|
memcpy(&maxTranslationDimension, sourceBuffer, sizeof(float));
|
||||||
|
sourceBuffer += sizeof(float);
|
||||||
|
|
||||||
// each joint translation component is stored in 6 bytes.
|
// each joint translation component is stored in 6 bytes.
|
||||||
const int COMPRESSED_TRANSLATION_SIZE = 6;
|
const int COMPRESSED_TRANSLATION_SIZE = 6;
|
||||||
PACKET_READ_CHECK(JointTranslation, numValidJointTranslations * COMPRESSED_TRANSLATION_SIZE);
|
PACKET_READ_CHECK(JointTranslation, numValidJointTranslations * COMPRESSED_TRANSLATION_SIZE);
|
||||||
|
@ -1288,6 +1306,8 @@ int AvatarData::parseDataFromBuffer(const QByteArray& buffer) {
|
||||||
JointData& data = _jointData[i];
|
JointData& data = _jointData[i];
|
||||||
if (validTranslations[i]) {
|
if (validTranslations[i]) {
|
||||||
sourceBuffer += unpackFloatVec3FromSignedTwoByteFixed(sourceBuffer, data.translation, TRANSLATION_COMPRESSION_RADIX);
|
sourceBuffer += unpackFloatVec3FromSignedTwoByteFixed(sourceBuffer, data.translation, TRANSLATION_COMPRESSION_RADIX);
|
||||||
|
// un-normalize translation
|
||||||
|
data.translation *= maxTranslationDimension;
|
||||||
_hasNewJointData = true;
|
_hasNewJointData = true;
|
||||||
data.translationIsDefaultPose = false;
|
data.translationIsDefaultPose = false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -277,7 +277,8 @@ namespace AvatarDataPacket {
|
||||||
uint8_t rotationValidityBits[ceil(numJoints / 8)]; // one bit per joint, if true then a compressed rotation follows.
|
uint8_t rotationValidityBits[ceil(numJoints / 8)]; // one bit per joint, if true then a compressed rotation follows.
|
||||||
SixByteQuat rotation[numValidRotations]; // encodeded and compressed by packOrientationQuatToSixBytes()
|
SixByteQuat rotation[numValidRotations]; // encodeded and compressed by packOrientationQuatToSixBytes()
|
||||||
uint8_t translationValidityBits[ceil(numJoints / 8)]; // one bit per joint, if true then a compressed translation follows.
|
uint8_t translationValidityBits[ceil(numJoints / 8)]; // one bit per joint, if true then a compressed translation follows.
|
||||||
SixByteTrans translation[numValidTranslations]; // encodeded and compressed by packFloatVec3ToSignedTwoByteFixed()
|
float maxTranslationDimension; // used to normalize fixed point translation values.
|
||||||
|
SixByteTrans translation[numValidTranslations]; // normalized and compressed by packFloatVec3ToSignedTwoByteFixed()
|
||||||
|
|
||||||
SixByteQuat leftHandControllerRotation;
|
SixByteQuat leftHandControllerRotation;
|
||||||
SixByteTrans leftHandControllerTranslation;
|
SixByteTrans leftHandControllerTranslation;
|
||||||
|
|
Loading…
Reference in a new issue