make the avatar bounding box be avatar local and only change when it actually changes

This commit is contained in:
ZappoMan 2017-01-12 17:19:06 -08:00
parent dd85cd9558
commit aed1b69ee0
4 changed files with 56 additions and 47 deletions

View file

@ -229,10 +229,10 @@ void MyAvatar::simulateAttachments(float deltaTime) {
QByteArray MyAvatar::toByteArray(AvatarDataDetail dataDetail, quint64 lastSentTime) { QByteArray MyAvatar::toByteArray(AvatarDataDetail dataDetail, quint64 lastSentTime) {
CameraMode mode = qApp->getCamera()->getMode(); CameraMode mode = qApp->getCamera()->getMode();
_globalPosition = getPosition(); _globalPosition = getPosition();
_globalBoundingBoxCorner.x = _characterController.getCapsuleRadius(); _globalBoundingBoxDimensions.x = _characterController.getCapsuleRadius();
_globalBoundingBoxCorner.y = _characterController.getCapsuleHalfHeight(); _globalBoundingBoxDimensions.y = _characterController.getCapsuleHalfHeight();
_globalBoundingBoxCorner.z = _characterController.getCapsuleRadius(); _globalBoundingBoxDimensions.z = _characterController.getCapsuleRadius();
_globalBoundingBoxCorner += _characterController.getCapsuleLocalOffset(); _globalBoundingBoxOffset = _characterController.getCapsuleLocalOffset();
if (mode == CAMERA_MODE_THIRD_PERSON || mode == CAMERA_MODE_INDEPENDENT) { if (mode == CAMERA_MODE_THIRD_PERSON || mode == CAMERA_MODE_INDEPENDENT) {
// fake the avatar position that is sent up to the AvatarMixer // fake the avatar position that is sent up to the AvatarMixer
glm::vec3 oldPosition = getPosition(); glm::vec3 oldPosition = getPosition();

View file

@ -82,7 +82,7 @@ AvatarData::AvatarData() :
ASSERT(sizeof(AvatarDataPacket::Header) == AvatarDataPacket::HEADER_SIZE); ASSERT(sizeof(AvatarDataPacket::Header) == AvatarDataPacket::HEADER_SIZE);
ASSERT(sizeof(AvatarDataPacket::AvatarGlobalPosition) == AvatarDataPacket::AVATAR_GLOBAL_POSITION_SIZE); ASSERT(sizeof(AvatarDataPacket::AvatarGlobalPosition) == AvatarDataPacket::AVATAR_GLOBAL_POSITION_SIZE);
ASSERT(sizeof(AvatarDataPacket::AvatarLocalPosition) == AvatarDataPacket::AVATAR_LOCAL_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::AvatarOrientation) == AvatarDataPacket::AVATAR_ORIENTATION_SIZE);
ASSERT(sizeof(AvatarDataPacket::AvatarScale) == AvatarDataPacket::AVATAR_SCALE_SIZE); ASSERT(sizeof(AvatarDataPacket::AvatarScale) == AvatarDataPacket::AVATAR_SCALE_SIZE);
ASSERT(sizeof(AvatarDataPacket::LookAtPosition) == AvatarDataPacket::LOOK_AT_POSITION_SIZE); ASSERT(sizeof(AvatarDataPacket::LookAtPosition) == AvatarDataPacket::LOOK_AT_POSITION_SIZE);
@ -161,8 +161,8 @@ void AvatarData::lazyInitHeadData() {
} }
bool AvatarData::avatarDimensionsChangedSince(quint64 time) { bool AvatarData::avatarBoundingBoxChangedSince(quint64 time) {
return _avatarDimensionsChanged >= time; return _avatarBoundingBoxChanged >= time;
} }
bool AvatarData::avatarScaleChangedSince(quint64 time) { bool AvatarData::avatarScaleChangedSince(quint64 time) {
@ -235,7 +235,6 @@ QByteArray AvatarData::toByteArray(AvatarDataDetail dataDetail, quint64 lastSent
// TODO - // TODO -
// typical -- 1jd 0ft 0p 1af 1stw 0loud 1look 0s 0o 1d 1lp 1gp // 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) // 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 // 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 // 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 hasAvatarLocalPosition = sendAll || tranlationChangedSince(lastSentTime);
bool hasAvatarOrientation = sendAll || rotationChangedSince(lastSentTime); bool hasAvatarOrientation = sendAll || rotationChangedSince(lastSentTime);
bool hasAvatarDimensions = sendAll || avatarDimensionsChangedSince(lastSentTime); bool hasAvatarBoundingBox = sendAll || avatarBoundingBoxChangedSince(lastSentTime);
bool hasAvatarScale = sendAll || avatarScaleChangedSince(lastSentTime); bool hasAvatarScale = sendAll || avatarScaleChangedSince(lastSentTime);
bool hasLookAtPosition = sendAll || lookAtPositionChangedSince(lastSentTime); bool hasLookAtPosition = sendAll || lookAtPositionChangedSince(lastSentTime);
bool hasAudioLoudness = sendAll || audioLoudnessChangedSince(lastSentTime); bool hasAudioLoudness = sendAll || audioLoudnessChangedSince(lastSentTime);
@ -267,7 +266,7 @@ QByteArray AvatarData::toByteArray(AvatarDataDetail dataDetail, quint64 lastSent
AvatarDataPacket::HasFlags packetStateFlags = AvatarDataPacket::HasFlags packetStateFlags =
(hasAvatarGlobalPosition ? AvatarDataPacket::PACKET_HAS_AVATAR_GLOBAL_POSITION : 0) (hasAvatarGlobalPosition ? AvatarDataPacket::PACKET_HAS_AVATAR_GLOBAL_POSITION : 0)
| (hasAvatarLocalPosition ? AvatarDataPacket::PACKET_HAS_AVATAR_LOCAL_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) | (hasAvatarOrientation ? AvatarDataPacket::PACKET_HAS_AVATAR_ORIENTATION : 0)
| (hasAvatarScale ? AvatarDataPacket::PACKET_HAS_AVATAR_SCALE : 0) | (hasAvatarScale ? AvatarDataPacket::PACKET_HAS_AVATAR_SCALE : 0)
| (hasLookAtPosition ? AvatarDataPacket::PACKET_HAS_LOOK_AT_POSITION : 0) | (hasLookAtPosition ? AvatarDataPacket::PACKET_HAS_LOOK_AT_POSITION : 0)
@ -302,15 +301,18 @@ QByteArray AvatarData::toByteArray(AvatarDataDetail dataDetail, quint64 lastSent
destinationBuffer += sizeof(AvatarDataPacket::AvatarLocalPosition); destinationBuffer += sizeof(AvatarDataPacket::AvatarLocalPosition);
} }
if (hasAvatarDimensions) { if (hasAvatarBoundingBox) {
auto data = reinterpret_cast<AvatarDataPacket::AvatarDimensions*>(destinationBuffer); auto data = reinterpret_cast<AvatarDataPacket::AvatarBoundingBox*>(destinationBuffer);
// FIXME - make this just dimensions!!! data->avatarDimensions[0] = _globalBoundingBoxDimensions.x;
auto avatarDimensions = getPosition() - _globalBoundingBoxCorner; data->avatarDimensions[1] = _globalBoundingBoxDimensions.y;
data->avatarDimensions[0] = avatarDimensions.x; data->avatarDimensions[2] = _globalBoundingBoxDimensions.z;
data->avatarDimensions[1] = avatarDimensions.y;
data->avatarDimensions[2] = avatarDimensions.z; data->boundOriginOffset[0] = _globalBoundingBoxOffset.x;
destinationBuffer += sizeof(AvatarDataPacket::AvatarDimensions); data->boundOriginOffset[1] = _globalBoundingBoxOffset.y;
data->boundOriginOffset[2] = _globalBoundingBoxOffset.z;
destinationBuffer += sizeof(AvatarDataPacket::AvatarBoundingBox);
} }
if (hasAvatarOrientation) { if (hasAvatarOrientation) {
@ -632,7 +634,7 @@ int AvatarData::parseDataFromBuffer(const QByteArray& buffer) {
bool hasAvatarGlobalPosition = HAS_FLAG(packetStateFlags, AvatarDataPacket::PACKET_HAS_AVATAR_GLOBAL_POSITION); bool hasAvatarGlobalPosition = HAS_FLAG(packetStateFlags, AvatarDataPacket::PACKET_HAS_AVATAR_GLOBAL_POSITION);
bool hasAvatarLocalPosition = HAS_FLAG(packetStateFlags, AvatarDataPacket::PACKET_HAS_AVATAR_LOCAL_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 hasAvatarOrientation = HAS_FLAG(packetStateFlags, AvatarDataPacket::PACKET_HAS_AVATAR_ORIENTATION);
bool hasAvatarScale = HAS_FLAG(packetStateFlags, AvatarDataPacket::PACKET_HAS_AVATAR_SCALE); bool hasAvatarScale = HAS_FLAG(packetStateFlags, AvatarDataPacket::PACKET_HAS_AVATAR_SCALE);
bool hasLookAtPosition = HAS_FLAG(packetStateFlags, AvatarDataPacket::PACKET_HAS_LOOK_AT_POSITION); bool hasLookAtPosition = HAS_FLAG(packetStateFlags, AvatarDataPacket::PACKET_HAS_LOOK_AT_POSITION);
@ -679,20 +681,27 @@ int AvatarData::parseDataFromBuffer(const QByteArray& buffer) {
_localPositionRate.increment(numBytesRead); _localPositionRate.increment(numBytesRead);
} }
if (hasAvatarDimensions) { if (hasAvatarBoundingBox) {
auto startSection = sourceBuffer; auto startSection = sourceBuffer;
PACKET_READ_CHECK(AvatarDimensions, sizeof(AvatarDataPacket::AvatarDimensions)); PACKET_READ_CHECK(AvatarBoundingBox, sizeof(AvatarDataPacket::AvatarBoundingBox));
auto data = reinterpret_cast<const AvatarDataPacket::AvatarDimensions*>(sourceBuffer); auto data = reinterpret_cast<const AvatarDataPacket::AvatarBoundingBox*>(sourceBuffer);
auto newValue = glm::vec3(data->avatarDimensions[0], data->avatarDimensions[1], data->avatarDimensions[2]); auto newDimensions = glm::vec3(data->avatarDimensions[0], data->avatarDimensions[1], data->avatarDimensions[2]);
// FIXME - this is suspicious looking! auto newOffset = glm::vec3(data->boundOriginOffset[0], data->boundOriginOffset[1], data->boundOriginOffset[2]);
if (_globalBoundingBoxCorner != newValue) {
_globalBoundingBoxCorner = newValue;
_avatarDimensionsChanged = usecTimestampNow(); 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; int numBytesRead = sourceBuffer - startSection;
_avatarDimensionRate.increment(numBytesRead); _avatarBoundingBoxRate.increment(numBytesRead);
} }
if (hasAvatarOrientation) { if (hasAvatarOrientation) {
@ -762,7 +771,7 @@ int AvatarData::parseDataFromBuffer(const QByteArray& buffer) {
return buffer.size(); return buffer.size();
} }
_headData->setAudioLoudness(audioLoudness); _headData->setAudioLoudness(audioLoudness);
qDebug() << "audioLoudness:" << audioLoudness; //qDebug() << "audioLoudness:" << audioLoudness;
int numBytesRead = sourceBuffer - startSection; int numBytesRead = sourceBuffer - startSection;
_audioLoudnessRate.increment(numBytesRead); _audioLoudnessRate.increment(numBytesRead);
} }
@ -985,8 +994,8 @@ float AvatarData::getDataRate(const QString& rateName) {
return _globalPositionRate.rate() / BYTES_PER_KILOBIT; return _globalPositionRate.rate() / BYTES_PER_KILOBIT;
} else if (rateName == "localPosition") { } else if (rateName == "localPosition") {
return _localPositionRate.rate() / BYTES_PER_KILOBIT; return _localPositionRate.rate() / BYTES_PER_KILOBIT;
} else if (rateName == "avatarDimensions") { } else if (rateName == "avatarBoundingBox") {
return _avatarDimensionRate.rate() / BYTES_PER_KILOBIT; return _avatarBoundingBoxRate.rate() / BYTES_PER_KILOBIT;
} else if (rateName == "avatarOrientation") { } else if (rateName == "avatarOrientation") {
return _avatarOrientationRate.rate() / BYTES_PER_KILOBIT; return _avatarOrientationRate.rate() / BYTES_PER_KILOBIT;
} else if (rateName == "avatarScale") { } else if (rateName == "avatarScale") {

View file

@ -127,7 +127,7 @@ namespace AvatarDataPacket {
using HasFlags = uint16_t; using HasFlags = uint16_t;
const HasFlags PACKET_HAS_AVATAR_GLOBAL_POSITION = 1U << 0; 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_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_ORIENTATION = 1U << 3;
const HasFlags PACKET_HAS_AVATAR_SCALE = 1U << 4; const HasFlags PACKET_HAS_AVATAR_SCALE = 1U << 4;
const HasFlags PACKET_HAS_LOOK_AT_POSITION = 1U << 5; 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 HasFlags packetHasFlags; // state flags, indicated which additional records are included in the packet
// bit 0 - has AvatarGlobalPosition // bit 0 - has AvatarGlobalPosition
// bit 1 - has AvatarLocalPosition // bit 1 - has AvatarLocalPosition
// bit 2 - has AvatarDimensions // bit 2 - has AvatarBoundingBox
// bit 3 - has AvatarOrientation // bit 3 - has AvatarOrientation
// bit 4 - has AvatarScale // bit 4 - has AvatarScale
// bit 5 - has LookAtPosition // bit 5 - has LookAtPosition
@ -164,17 +164,16 @@ namespace AvatarDataPacket {
PACKED_BEGIN struct AvatarLocalPosition { PACKED_BEGIN struct AvatarLocalPosition {
float localPosition[3]; // this appears to be the avatar local position?? float localPosition[3]; // this appears to be the avatar local position??
// this is a reduced precision radix // this is a reduced precision radix
// FIXME - could this be changed into compressed floats? // FIXME - could this be changed into compressed floats?
} PACKED_END; } PACKED_END;
const size_t AVATAR_LOCAL_POSITION_SIZE = 12; const size_t AVATAR_LOCAL_POSITION_SIZE = 12;
PACKED_BEGIN struct AvatarDimensions { PACKED_BEGIN struct AvatarBoundingBox {
float avatarDimensions[3]; // avatar's bounding box in world space units, but relative to the float avatarDimensions[3]; // avatar's bounding box in world space units, but relative to the position.
// position. Assumed to be centered around the world position float boundOriginOffset[3]; // offset from the position of the avatar to the origin of the bounding box
// FIXME - could this be changed into compressed floats?
} PACKED_END; } PACKED_END;
const size_t AVATAR_DIMENSIONS_SIZE = 12; const size_t AVATAR_BOUNDING_BOX_SIZE = 24;
using SixByteQuat = uint8_t[6]; using SixByteQuat = uint8_t[6];
@ -525,7 +524,7 @@ public:
void fromJson(const QJsonObject& json); void fromJson(const QJsonObject& json);
glm::vec3 getClientGlobalPosition() { return _globalPosition; } glm::vec3 getClientGlobalPosition() { return _globalPosition; }
glm::vec3 getGlobalBoundingBoxCorner() { return _globalBoundingBoxCorner; } glm::vec3 getGlobalBoundingBoxCorner() { return _globalPosition + _globalBoundingBoxOffset - _globalBoundingBoxDimensions; }
Q_INVOKABLE AvatarEntityMap getAvatarEntityData() const; Q_INVOKABLE AvatarEntityMap getAvatarEntityData() const;
Q_INVOKABLE void setAvatarEntityData(const AvatarEntityMap& avatarEntityData); Q_INVOKABLE void setAvatarEntityData(const AvatarEntityMap& avatarEntityData);
@ -558,7 +557,7 @@ public slots:
protected: protected:
void lazyInitHeadData(); void lazyInitHeadData();
bool avatarDimensionsChangedSince(quint64 time); bool avatarBoundingBoxChangedSince(quint64 time);
bool avatarScaleChangedSince(quint64 time); bool avatarScaleChangedSince(quint64 time);
bool lookAtPositionChangedSince(quint64 time); bool lookAtPositionChangedSince(quint64 time);
bool audioLoudnessChangedSince(quint64 time); bool audioLoudnessChangedSince(quint64 time);
@ -634,7 +633,7 @@ protected:
quint64 _globalPositionChanged { 0 }; quint64 _globalPositionChanged { 0 };
quint64 _avatarDimensionsChanged { 0 }; quint64 _avatarBoundingBoxChanged { 0 };
quint64 _avatarScaleChanged { 0 }; quint64 _avatarScaleChanged { 0 };
quint64 _sensorToWorldMatrixChanged { 0 }; quint64 _sensorToWorldMatrixChanged { 0 };
quint64 _additionalFlagsChanged { 0 }; quint64 _additionalFlagsChanged { 0 };
@ -646,7 +645,7 @@ protected:
RateCounter<> _parseBufferRate; RateCounter<> _parseBufferRate;
RateCounter<> _globalPositionRate; RateCounter<> _globalPositionRate;
RateCounter<> _localPositionRate; RateCounter<> _localPositionRate;
RateCounter<> _avatarDimensionRate; RateCounter<> _avatarBoundingBoxRate;
RateCounter<> _avatarOrientationRate; RateCounter<> _avatarOrientationRate;
RateCounter<> _avatarScaleRate; RateCounter<> _avatarScaleRate;
RateCounter<> _lookAtPositionRate; RateCounter<> _lookAtPositionRate;
@ -657,7 +656,8 @@ protected:
RateCounter<> _faceTrackerRate; RateCounter<> _faceTrackerRate;
RateCounter<> _jointDataRate; RateCounter<> _jointDataRate;
glm::vec3 _globalBoundingBoxCorner; glm::vec3 _globalBoundingBoxDimensions;
glm::vec3 _globalBoundingBoxOffset;
mutable ReadWriteLockable _avatarEntitiesLock; mutable ReadWriteLockable _avatarEntitiesLock;
AvatarEntityIDs _avatarEntityDetached; // recently detached from this avatar AvatarEntityIDs _avatarEntityDetached; // recently detached from this avatar

View file

@ -100,7 +100,7 @@ function updateOverlays() {
var text = " All: " + AvatarManager.getAvatarDataRate(avatarID).toFixed(2) + "\n" var text = " All: " + AvatarManager.getAvatarDataRate(avatarID).toFixed(2) + "\n"
+" GP: " + AvatarManager.getAvatarDataRate(avatarID,"globalPosition").toFixed(2) + "\n" +" GP: " + AvatarManager.getAvatarDataRate(avatarID,"globalPosition").toFixed(2) + "\n"
+" LP: " + AvatarManager.getAvatarDataRate(avatarID,"localPosition").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" +" AO: " + AvatarManager.getAvatarDataRate(avatarID,"avatarOrientation").toFixed(2) + "\n"
+" AS: " + AvatarManager.getAvatarDataRate(avatarID,"avatarScale").toFixed(2) + "\n" +" AS: " + AvatarManager.getAvatarDataRate(avatarID,"avatarScale").toFixed(2) + "\n"
+" LA: " + AvatarManager.getAvatarDataRate(avatarID,"lookAtPosition").toFixed(2) + "\n" +" LA: " + AvatarManager.getAvatarDataRate(avatarID,"lookAtPosition").toFixed(2) + "\n"