diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp index 97ffd45587..6f5de308ac 100644 --- a/interface/src/avatar/MyAvatar.cpp +++ b/interface/src/avatar/MyAvatar.cpp @@ -229,10 +229,10 @@ void MyAvatar::simulateAttachments(float deltaTime) { QByteArray MyAvatar::toByteArray(AvatarDataDetail dataDetail, quint64 lastSentTime) { CameraMode mode = qApp->getCamera()->getMode(); _globalPosition = getPosition(); - _globalBoundingBoxCorner.x = _characterController.getCapsuleRadius(); - _globalBoundingBoxCorner.y = _characterController.getCapsuleHalfHeight(); - _globalBoundingBoxCorner.z = _characterController.getCapsuleRadius(); - _globalBoundingBoxCorner += _characterController.getCapsuleLocalOffset(); + _globalBoundingBoxDimensions.x = _characterController.getCapsuleRadius(); + _globalBoundingBoxDimensions.y = _characterController.getCapsuleHalfHeight(); + _globalBoundingBoxDimensions.z = _characterController.getCapsuleRadius(); + _globalBoundingBoxOffset = _characterController.getCapsuleLocalOffset(); if (mode == CAMERA_MODE_THIRD_PERSON || mode == CAMERA_MODE_INDEPENDENT) { // fake the avatar position that is sent up to the AvatarMixer glm::vec3 oldPosition = getPosition(); diff --git a/libraries/avatars/src/AvatarData.cpp b/libraries/avatars/src/AvatarData.cpp index b277f99c5d..2427198a3e 100644 --- a/libraries/avatars/src/AvatarData.cpp +++ b/libraries/avatars/src/AvatarData.cpp @@ -82,7 +82,7 @@ AvatarData::AvatarData() : ASSERT(sizeof(AvatarDataPacket::Header) == AvatarDataPacket::HEADER_SIZE); ASSERT(sizeof(AvatarDataPacket::AvatarGlobalPosition) == AvatarDataPacket::AVATAR_GLOBAL_POSITION_SIZE); ASSERT(sizeof(AvatarDataPacket::AvatarLocalPosition) == AvatarDataPacket::AVATAR_LOCAL_POSITION_SIZE); - ASSERT(sizeof(AvatarDataPacket::AvatarDimensions) == AvatarDataPacket::AVATAR_DIMENSIONS_SIZE); + ASSERT(sizeof(AvatarDataPacket::AvatarBoundingBox) == AvatarDataPacket::AVATAR_BOUNDING_BOX_SIZE); ASSERT(sizeof(AvatarDataPacket::AvatarOrientation) == AvatarDataPacket::AVATAR_ORIENTATION_SIZE); ASSERT(sizeof(AvatarDataPacket::AvatarScale) == AvatarDataPacket::AVATAR_SCALE_SIZE); ASSERT(sizeof(AvatarDataPacket::LookAtPosition) == AvatarDataPacket::LOOK_AT_POSITION_SIZE); @@ -161,8 +161,8 @@ void AvatarData::lazyInitHeadData() { } -bool AvatarData::avatarDimensionsChangedSince(quint64 time) { - return _avatarDimensionsChanged >= time; +bool AvatarData::avatarBoundingBoxChangedSince(quint64 time) { + return _avatarBoundingBoxChanged >= time; } bool AvatarData::avatarScaleChangedSince(quint64 time) { @@ -235,7 +235,6 @@ QByteArray AvatarData::toByteArray(AvatarDataDetail dataDetail, quint64 lastSent // TODO - // typical -- 1jd 0ft 0p 1af 1stw 0loud 1look 0s 0o 1d 1lp 1gp // - // 1) make the dimensions really be dimensions instead of corner - 12 bytes - 4.32 kbps (when moving) // 2) determine if local position really only matters for parent - 12 bytes - 4.32 kbps (when moving and/or not parented) // 3) SensorToWorld - should we only send this for avatars with attachments?? - 20 bytes - 7.20 kbps // 5) GUIID for the session change to 2byte index (savings) - 14 bytes - 5.04 kbps @@ -253,7 +252,7 @@ QByteArray AvatarData::toByteArray(AvatarDataDetail dataDetail, quint64 lastSent bool hasAvatarLocalPosition = sendAll || tranlationChangedSince(lastSentTime); bool hasAvatarOrientation = sendAll || rotationChangedSince(lastSentTime); - bool hasAvatarDimensions = sendAll || avatarDimensionsChangedSince(lastSentTime); + bool hasAvatarBoundingBox = sendAll || avatarBoundingBoxChangedSince(lastSentTime); bool hasAvatarScale = sendAll || avatarScaleChangedSince(lastSentTime); bool hasLookAtPosition = sendAll || lookAtPositionChangedSince(lastSentTime); bool hasAudioLoudness = sendAll || audioLoudnessChangedSince(lastSentTime); @@ -267,7 +266,7 @@ QByteArray AvatarData::toByteArray(AvatarDataDetail dataDetail, quint64 lastSent AvatarDataPacket::HasFlags packetStateFlags = (hasAvatarGlobalPosition ? AvatarDataPacket::PACKET_HAS_AVATAR_GLOBAL_POSITION : 0) | (hasAvatarLocalPosition ? AvatarDataPacket::PACKET_HAS_AVATAR_LOCAL_POSITION : 0) - | (hasAvatarDimensions ? AvatarDataPacket::PACKET_HAS_AVATAR_DIMENSIONS : 0) + | (hasAvatarBoundingBox ? AvatarDataPacket::PACKET_HAS_AVATAR_BOUNDING_BOX : 0) | (hasAvatarOrientation ? AvatarDataPacket::PACKET_HAS_AVATAR_ORIENTATION : 0) | (hasAvatarScale ? AvatarDataPacket::PACKET_HAS_AVATAR_SCALE : 0) | (hasLookAtPosition ? AvatarDataPacket::PACKET_HAS_LOOK_AT_POSITION : 0) @@ -302,15 +301,18 @@ QByteArray AvatarData::toByteArray(AvatarDataDetail dataDetail, quint64 lastSent destinationBuffer += sizeof(AvatarDataPacket::AvatarLocalPosition); } - if (hasAvatarDimensions) { - auto data = reinterpret_cast(destinationBuffer); + if (hasAvatarBoundingBox) { + auto data = reinterpret_cast(destinationBuffer); - // FIXME - make this just dimensions!!! - auto avatarDimensions = getPosition() - _globalBoundingBoxCorner; - data->avatarDimensions[0] = avatarDimensions.x; - data->avatarDimensions[1] = avatarDimensions.y; - data->avatarDimensions[2] = avatarDimensions.z; - destinationBuffer += sizeof(AvatarDataPacket::AvatarDimensions); + data->avatarDimensions[0] = _globalBoundingBoxDimensions.x; + data->avatarDimensions[1] = _globalBoundingBoxDimensions.y; + data->avatarDimensions[2] = _globalBoundingBoxDimensions.z; + + data->boundOriginOffset[0] = _globalBoundingBoxOffset.x; + data->boundOriginOffset[1] = _globalBoundingBoxOffset.y; + data->boundOriginOffset[2] = _globalBoundingBoxOffset.z; + + destinationBuffer += sizeof(AvatarDataPacket::AvatarBoundingBox); } if (hasAvatarOrientation) { @@ -632,7 +634,7 @@ int AvatarData::parseDataFromBuffer(const QByteArray& buffer) { bool hasAvatarGlobalPosition = HAS_FLAG(packetStateFlags, AvatarDataPacket::PACKET_HAS_AVATAR_GLOBAL_POSITION); bool hasAvatarLocalPosition = HAS_FLAG(packetStateFlags, AvatarDataPacket::PACKET_HAS_AVATAR_LOCAL_POSITION); - bool hasAvatarDimensions = HAS_FLAG(packetStateFlags, AvatarDataPacket::PACKET_HAS_AVATAR_DIMENSIONS); + bool hasAvatarBoundingBox = HAS_FLAG(packetStateFlags, AvatarDataPacket::PACKET_HAS_AVATAR_BOUNDING_BOX); bool hasAvatarOrientation = HAS_FLAG(packetStateFlags, AvatarDataPacket::PACKET_HAS_AVATAR_ORIENTATION); bool hasAvatarScale = HAS_FLAG(packetStateFlags, AvatarDataPacket::PACKET_HAS_AVATAR_SCALE); bool hasLookAtPosition = HAS_FLAG(packetStateFlags, AvatarDataPacket::PACKET_HAS_LOOK_AT_POSITION); @@ -679,20 +681,27 @@ int AvatarData::parseDataFromBuffer(const QByteArray& buffer) { _localPositionRate.increment(numBytesRead); } - if (hasAvatarDimensions) { + if (hasAvatarBoundingBox) { auto startSection = sourceBuffer; - PACKET_READ_CHECK(AvatarDimensions, sizeof(AvatarDataPacket::AvatarDimensions)); - auto data = reinterpret_cast(sourceBuffer); - auto newValue = glm::vec3(data->avatarDimensions[0], data->avatarDimensions[1], data->avatarDimensions[2]); - // FIXME - this is suspicious looking! - if (_globalBoundingBoxCorner != newValue) { - _globalBoundingBoxCorner = newValue; - _avatarDimensionsChanged = usecTimestampNow(); + PACKET_READ_CHECK(AvatarBoundingBox, sizeof(AvatarDataPacket::AvatarBoundingBox)); + auto data = reinterpret_cast(sourceBuffer); + auto newDimensions = glm::vec3(data->avatarDimensions[0], data->avatarDimensions[1], data->avatarDimensions[2]); + auto newOffset = glm::vec3(data->boundOriginOffset[0], data->boundOriginOffset[1], data->boundOriginOffset[2]); + + + if (_globalBoundingBoxDimensions != newDimensions) { + _globalBoundingBoxDimensions = newDimensions; + _avatarBoundingBoxChanged = usecTimestampNow(); } - sourceBuffer += sizeof(AvatarDataPacket::AvatarDimensions); + if (_globalBoundingBoxOffset != newOffset) { + _globalBoundingBoxOffset = newOffset; + _avatarBoundingBoxChanged = usecTimestampNow(); + } + + sourceBuffer += sizeof(AvatarDataPacket::AvatarBoundingBox); int numBytesRead = sourceBuffer - startSection; - _avatarDimensionRate.increment(numBytesRead); + _avatarBoundingBoxRate.increment(numBytesRead); } if (hasAvatarOrientation) { @@ -762,7 +771,7 @@ int AvatarData::parseDataFromBuffer(const QByteArray& buffer) { return buffer.size(); } _headData->setAudioLoudness(audioLoudness); - qDebug() << "audioLoudness:" << audioLoudness; + //qDebug() << "audioLoudness:" << audioLoudness; int numBytesRead = sourceBuffer - startSection; _audioLoudnessRate.increment(numBytesRead); } @@ -985,8 +994,8 @@ float AvatarData::getDataRate(const QString& rateName) { return _globalPositionRate.rate() / BYTES_PER_KILOBIT; } else if (rateName == "localPosition") { return _localPositionRate.rate() / BYTES_PER_KILOBIT; - } else if (rateName == "avatarDimensions") { - return _avatarDimensionRate.rate() / BYTES_PER_KILOBIT; + } else if (rateName == "avatarBoundingBox") { + return _avatarBoundingBoxRate.rate() / BYTES_PER_KILOBIT; } else if (rateName == "avatarOrientation") { return _avatarOrientationRate.rate() / BYTES_PER_KILOBIT; } else if (rateName == "avatarScale") { diff --git a/libraries/avatars/src/AvatarData.h b/libraries/avatars/src/AvatarData.h index 38b90ac726..ce604634b7 100644 --- a/libraries/avatars/src/AvatarData.h +++ b/libraries/avatars/src/AvatarData.h @@ -127,7 +127,7 @@ namespace AvatarDataPacket { using HasFlags = uint16_t; const HasFlags PACKET_HAS_AVATAR_GLOBAL_POSITION = 1U << 0; const HasFlags PACKET_HAS_AVATAR_LOCAL_POSITION = 1U << 1; // FIXME - can this be in the PARENT_INFO?? - const HasFlags PACKET_HAS_AVATAR_DIMENSIONS = 1U << 2; + const HasFlags PACKET_HAS_AVATAR_BOUNDING_BOX = 1U << 2; const HasFlags PACKET_HAS_AVATAR_ORIENTATION = 1U << 3; const HasFlags PACKET_HAS_AVATAR_SCALE = 1U << 4; const HasFlags PACKET_HAS_LOOK_AT_POSITION = 1U << 5; @@ -144,7 +144,7 @@ namespace AvatarDataPacket { HasFlags packetHasFlags; // state flags, indicated which additional records are included in the packet // bit 0 - has AvatarGlobalPosition // bit 1 - has AvatarLocalPosition - // bit 2 - has AvatarDimensions + // bit 2 - has AvatarBoundingBox // bit 3 - has AvatarOrientation // bit 4 - has AvatarScale // bit 5 - has LookAtPosition @@ -164,17 +164,16 @@ namespace AvatarDataPacket { PACKED_BEGIN struct AvatarLocalPosition { float localPosition[3]; // this appears to be the avatar local position?? - // this is a reduced precision radix - // FIXME - could this be changed into compressed floats? + // this is a reduced precision radix + // FIXME - could this be changed into compressed floats? } PACKED_END; const size_t AVATAR_LOCAL_POSITION_SIZE = 12; - PACKED_BEGIN struct AvatarDimensions { - float avatarDimensions[3]; // avatar's bounding box in world space units, but relative to the - // position. Assumed to be centered around the world position - // FIXME - could this be changed into compressed floats? + PACKED_BEGIN struct AvatarBoundingBox { + float avatarDimensions[3]; // avatar's bounding box in world space units, but relative to the position. + float boundOriginOffset[3]; // offset from the position of the avatar to the origin of the bounding box } PACKED_END; - const size_t AVATAR_DIMENSIONS_SIZE = 12; + const size_t AVATAR_BOUNDING_BOX_SIZE = 24; using SixByteQuat = uint8_t[6]; @@ -525,7 +524,7 @@ public: void fromJson(const QJsonObject& json); glm::vec3 getClientGlobalPosition() { return _globalPosition; } - glm::vec3 getGlobalBoundingBoxCorner() { return _globalBoundingBoxCorner; } + glm::vec3 getGlobalBoundingBoxCorner() { return _globalPosition + _globalBoundingBoxOffset - _globalBoundingBoxDimensions; } Q_INVOKABLE AvatarEntityMap getAvatarEntityData() const; Q_INVOKABLE void setAvatarEntityData(const AvatarEntityMap& avatarEntityData); @@ -558,7 +557,7 @@ public slots: protected: void lazyInitHeadData(); - bool avatarDimensionsChangedSince(quint64 time); + bool avatarBoundingBoxChangedSince(quint64 time); bool avatarScaleChangedSince(quint64 time); bool lookAtPositionChangedSince(quint64 time); bool audioLoudnessChangedSince(quint64 time); @@ -634,7 +633,7 @@ protected: quint64 _globalPositionChanged { 0 }; - quint64 _avatarDimensionsChanged { 0 }; + quint64 _avatarBoundingBoxChanged { 0 }; quint64 _avatarScaleChanged { 0 }; quint64 _sensorToWorldMatrixChanged { 0 }; quint64 _additionalFlagsChanged { 0 }; @@ -646,7 +645,7 @@ protected: RateCounter<> _parseBufferRate; RateCounter<> _globalPositionRate; RateCounter<> _localPositionRate; - RateCounter<> _avatarDimensionRate; + RateCounter<> _avatarBoundingBoxRate; RateCounter<> _avatarOrientationRate; RateCounter<> _avatarScaleRate; RateCounter<> _lookAtPositionRate; @@ -657,7 +656,8 @@ protected: RateCounter<> _faceTrackerRate; RateCounter<> _jointDataRate; - glm::vec3 _globalBoundingBoxCorner; + glm::vec3 _globalBoundingBoxDimensions; + glm::vec3 _globalBoundingBoxOffset; mutable ReadWriteLockable _avatarEntitiesLock; AvatarEntityIDs _avatarEntityDetached; // recently detached from this avatar diff --git a/scripts/developer/debugging/debugAvatarMixer.js b/scripts/developer/debugging/debugAvatarMixer.js index 2e7901b962..1a16832e0d 100644 --- a/scripts/developer/debugging/debugAvatarMixer.js +++ b/scripts/developer/debugging/debugAvatarMixer.js @@ -100,7 +100,7 @@ function updateOverlays() { var text = " All: " + AvatarManager.getAvatarDataRate(avatarID).toFixed(2) + "\n" +" GP: " + AvatarManager.getAvatarDataRate(avatarID,"globalPosition").toFixed(2) + "\n" +" LP: " + AvatarManager.getAvatarDataRate(avatarID,"localPosition").toFixed(2) + "\n" - +" AD: " + AvatarManager.getAvatarDataRate(avatarID,"avatarDimensions").toFixed(2) + "\n" + +" BB: " + AvatarManager.getAvatarDataRate(avatarID,"avatarBoundingBox").toFixed(2) + "\n" +" AO: " + AvatarManager.getAvatarDataRate(avatarID,"avatarOrientation").toFixed(2) + "\n" +" AS: " + AvatarManager.getAvatarDataRate(avatarID,"avatarScale").toFixed(2) + "\n" +" LA: " + AvatarManager.getAvatarDataRate(avatarID,"lookAtPosition").toFixed(2) + "\n"