From 286f23d512b0770975050acaff1ccdb298bef5d1 Mon Sep 17 00:00:00 2001 From: Anthony Thibault Date: Thu, 17 Jan 2019 15:19:54 -0800 Subject: [PATCH] Updated protocol version and fixed bugs --- libraries/animation/src/Rig.cpp | 9 ++- libraries/avatars/src/AvatarData.cpp | 56 +++++++++---------- libraries/avatars/src/AvatarData.h | 1 - .../networking/src/udt/PacketHeaders.cpp | 4 +- libraries/networking/src/udt/PacketHeaders.h | 3 +- libraries/shared/src/JointData.h | 2 +- tools/dissectors/3-hf-avatar.lua | 3 + 7 files changed, 39 insertions(+), 39 deletions(-) diff --git a/libraries/animation/src/Rig.cpp b/libraries/animation/src/Rig.cpp index 44fdd8797f..c7a342b0eb 100644 --- a/libraries/animation/src/Rig.cpp +++ b/libraries/animation/src/Rig.cpp @@ -1985,11 +1985,10 @@ void Rig::copyJointsIntoJointData(QVector& jointDataVec) const { data.rotation = !_sendNetworkNode ? _internalPoseSet._absolutePoses[i].rot() : _networkPoseSet._absolutePoses[i].rot(); data.rotationIsDefaultPose = isEqual(data.rotation, defaultAbsRot); - // translations are in relative frame but scaled so that they are in meters, - // instead of model units. + // translations are in relative frame. glm::vec3 defaultRelTrans = _animSkeleton->getRelativeDefaultPose(i).trans(); glm::vec3 currentRelTrans = _sendNetworkNode ? _networkPoseSet._relativePoses[i].trans() : _internalPoseSet._relativePoses[i].trans(); - data.translation = geometryToRigScale * currentRelTrans; + data.translation = currentRelTrans; data.translationIsDefaultPose = isEqual(currentRelTrans, defaultRelTrans); } else { data.translationIsDefaultPose = true; @@ -2042,8 +2041,8 @@ void Rig::copyJointsFromJointData(const QVector& jointDataVec) { if (data.translationIsDefaultPose) { _internalPoseSet._relativePoses[i].trans() = relativeDefaultPoses[i].trans(); } else { - // JointData translations are in scaled relative-frame so we scale back to regular relative-frame - _internalPoseSet._relativePoses[i].trans() = rigToGeometryScale * data.translation; + // JointData translations are in relative-frame + _internalPoseSet._relativePoses[i].trans() = data.translation; } } } diff --git a/libraries/avatars/src/AvatarData.cpp b/libraries/avatars/src/AvatarData.cpp index abd89525fa..b649bd2994 100644 --- a/libraries/avatars/src/AvatarData.cpp +++ b/libraries/avatars/src/AvatarData.cpp @@ -73,6 +73,7 @@ size_t AvatarDataPacket::maxJointDataSize(size_t numJoints, bool hasGrabJoints) totalSize += validityBitsSize; // Orientations mask totalSize += numJoints * sizeof(SixByteQuat); // Orientations totalSize += validityBitsSize; // Translations mask + totalSize += sizeof(float); // maxTranslationDimension totalSize += numJoints * sizeof(SixByteTrans); // Translations size_t NUM_FAUX_JOINT = 2; @@ -612,12 +613,23 @@ QByteArray AvatarData::toByteArray(AvatarDataDetail dataDetail, quint64 lastSent const int jointBitVectorSize = calcBitVectorSize(numJoints); // Start joints if room for at least the faux joints. - IF_AVATAR_SPACE(PACKET_HAS_JOINT_DATA, 1 + 2 * jointBitVectorSize + AvatarDataPacket::FAUX_JOINTS_SIZE) { + IF_AVATAR_SPACE(PACKET_HAS_JOINT_DATA, 1 + 4 + 2 * jointBitVectorSize + AvatarDataPacket::FAUX_JOINTS_SIZE) { // Allow for faux joints + translation bit-vector: const ptrdiff_t minSizeForJoint = sizeof(AvatarDataPacket::SixByteQuat) + jointBitVectorSize + AvatarDataPacket::FAUX_JOINTS_SIZE; auto startSection = destinationBuffer; + // compute maxTranslationDimension before we send any joint data. + float maxTranslationDimension = 0.001f; + for (int i = 0; i < numJoints; ++i) { + const JointData& data = jointData[i]; + if (!data.translationIsDefaultPose) { + maxTranslationDimension = glm::max(fabsf(data.translation.x), maxTranslationDimension); + maxTranslationDimension = glm::max(fabsf(data.translation.y), maxTranslationDimension); + maxTranslationDimension = glm::max(fabsf(data.translation.z), maxTranslationDimension); + } + } + // joint rotation data *destinationBuffer++ = (uint8_t)numJoints; @@ -677,21 +689,19 @@ QByteArray AvatarData::toByteArray(AvatarDataDetail dataDetail, quint64 lastSent validityPosition = destinationBuffer; #ifdef WANT_DEBUG + int translationSentCount = 0; unsigned char* beforeTranslations = destinationBuffer; #endif memset(destinationBuffer, 0, jointBitVectorSize); destinationBuffer += jointBitVectorSize; // Move pointer past the validity bytes + // write maxTranslationDimension + memcpy(destinationBuffer, &maxTranslationDimension, sizeof(float)); + destinationBuffer += sizeof(float); + float minTranslation = (distanceAdjust && cullSmallChanges) ? getDistanceBasedMinTranslationDistance(viewerPosition) : AVATAR_MIN_TRANSLATION; - 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; for (; i < numJoints; ++i) { const JointData& data = joints[i]; @@ -702,11 +712,11 @@ QByteArray AvatarData::toByteArray(AvatarDataDetail dataDetail, quint64 lastSent if (sendAll || last.translationIsDefaultPose || (!cullSmallChanges && last.translation != data.translation) || (cullSmallChanges && glm::distance(data.translation, lastSentJointData[i].translation) > minTranslation)) { validityPosition[i / BITS_IN_BYTE] |= 1 << (i % BITS_IN_BYTE); - maxTranslationDimension = glm::max(fabsf(data.translation.x), maxTranslationDimension); - maxTranslationDimension = glm::max(fabsf(data.translation.y), maxTranslationDimension); - maxTranslationDimension = glm::max(fabsf(data.translation.z), maxTranslationDimension); - - translationsSentArray[translationsSent++] = data.translation; +#ifdef WANT_DEBUG + translationSentCount++; +#endif + destinationBuffer += packFloatVec3ToSignedTwoByteFixed(destinationBuffer, data.translation / maxTranslationDimension, + TRANSLATION_COMPRESSION_RADIX); if (sentJoints) { sentJoints[i].translation = data.translation; @@ -722,16 +732,6 @@ 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; // faux joints @@ -777,7 +777,7 @@ QByteArray AvatarData::toByteArray(AvatarDataDetail dataDetail, quint64 lastSent #ifdef WANT_DEBUG if (sendAll) { qCDebug(avatars) << "AvatarData::toByteArray" << cullSmallChanges << sendAll - << "rotations:" << rotationSentCount << "translations:" << translationsSentCount + << "rotations:" << rotationSentCount << "translations:" << translationSentCount << "largest:" << maxTranslationDimension << "size:" << (beforeRotations - startPosition) << "+" @@ -796,7 +796,7 @@ QByteArray AvatarData::toByteArray(AvatarDataDetail dataDetail, quint64 lastSent outboundDataRateOut->jointDataRate.increment(numBytes); } } - + IF_AVATAR_SPACE(PACKET_HAS_JOINT_DEFAULT_POSE_FLAGS, 1 + 2 * jointBitVectorSize) { auto startSection = destinationBuffer; @@ -1291,10 +1291,9 @@ int AvatarData::parseDataFromBuffer(const QByteArray& buffer) { } } // 1 + bytesOfValidity bytes - - // AJT: read maxTranslationDimension + // read maxTranslationDimension float maxTranslationDimension; - PACKET_READ_CHECK(MaxTranslationDimension, sizeof(float)); + PACKET_READ_CHECK(JointMaxTranslationDimension, sizeof(float)); memcpy(&maxTranslationDimension, sourceBuffer, sizeof(float)); sourceBuffer += sizeof(float); @@ -1306,7 +1305,6 @@ int AvatarData::parseDataFromBuffer(const QByteArray& buffer) { JointData& data = _jointData[i]; if (validTranslations[i]) { sourceBuffer += unpackFloatVec3FromSignedTwoByteFixed(sourceBuffer, data.translation, TRANSLATION_COMPRESSION_RADIX); - // un-normalize translation data.translation *= maxTranslationDimension; _hasNewJointData = true; data.translationIsDefaultPose = false; diff --git a/libraries/avatars/src/AvatarData.h b/libraries/avatars/src/AvatarData.h index 8a3014d043..5bca76b513 100644 --- a/libraries/avatars/src/AvatarData.h +++ b/libraries/avatars/src/AvatarData.h @@ -279,7 +279,6 @@ namespace AvatarDataPacket { uint8_t translationValidityBits[ceil(numJoints / 8)]; // one bit per joint, if true then a compressed translation follows. float maxTranslationDimension; // used to normalize fixed point translation values. SixByteTrans translation[numValidTranslations]; // normalized and compressed by packFloatVec3ToSignedTwoByteFixed() - SixByteQuat leftHandControllerRotation; SixByteTrans leftHandControllerTranslation; SixByteQuat rightHandControllerRotation; diff --git a/libraries/networking/src/udt/PacketHeaders.cpp b/libraries/networking/src/udt/PacketHeaders.cpp index 642914cd56..5634edca05 100644 --- a/libraries/networking/src/udt/PacketHeaders.cpp +++ b/libraries/networking/src/udt/PacketHeaders.cpp @@ -38,10 +38,10 @@ PacketVersion versionForPacketType(PacketType packetType) { return static_cast(EntityQueryPacketVersion::ConicalFrustums); case PacketType::AvatarIdentity: case PacketType::AvatarData: - return static_cast(AvatarMixerPacketVersion::CollisionFlag); + return static_cast(AvatarMixerPacketVersion::SendMaxTranslationDimension); case PacketType::BulkAvatarData: case PacketType::KillAvatar: - return static_cast(AvatarMixerPacketVersion::FasterAvatarEntities); + return static_cast(AvatarMixerPacketVersion::SendMaxTranslationDimension); case PacketType::MessagesData: return static_cast(MessageDataVersion::TextOrBinaryData); // ICE packets diff --git a/libraries/networking/src/udt/PacketHeaders.h b/libraries/networking/src/udt/PacketHeaders.h index f53a287d71..c01b3a47d7 100644 --- a/libraries/networking/src/udt/PacketHeaders.h +++ b/libraries/networking/src/udt/PacketHeaders.h @@ -312,7 +312,8 @@ enum class AvatarMixerPacketVersion : PacketVersion { GrabTraits, CollisionFlag, AvatarTraitsAck, - FasterAvatarEntities + FasterAvatarEntities, + SendMaxTranslationDimension }; enum class DomainConnectRequestVersion : PacketVersion { diff --git a/libraries/shared/src/JointData.h b/libraries/shared/src/JointData.h index f4c8b89e7a..7a2420262a 100644 --- a/libraries/shared/src/JointData.h +++ b/libraries/shared/src/JointData.h @@ -14,7 +14,7 @@ public: }; // Used by the avatar mixer to describe a single joint -// Translations relative to their parent and are in meters. +// Translations relative to their parent joint // Rotations are absolute (i.e. not relative to parent) and are in rig space. class JointData { public: diff --git a/tools/dissectors/3-hf-avatar.lua b/tools/dissectors/3-hf-avatar.lua index 0fa551c6f8..4fc5f44e66 100644 --- a/tools/dissectors/3-hf-avatar.lua +++ b/tools/dissectors/3-hf-avatar.lua @@ -282,6 +282,9 @@ function decode_avatar_data_packet(buf) i = i + num_validity_bytes result["valid_translations"] = "Valid Translations: " .. string.format("(%d/%d) {", #indices, num_joints) .. table.concat(indices, ", ") .. "}" + -- TODO: skip maxTranslationDimension + i = i + 4 + -- TODO: skip translations for now i = i + #indices * 6