more work on only sending changes

This commit is contained in:
Brad Hefta-Gaub 2016-12-27 17:19:55 -08:00
parent be61052368
commit 73bfc069da
10 changed files with 174 additions and 99 deletions

View file

@ -400,7 +400,9 @@ void AvatarMixer::broadcastAvatarData() {
numAvatarDataBytes += avatarPacketList->write(otherNode->getUUID().toRfc4122());
//qDebug() << "about to write data for:" << otherNode->getUUID();
numAvatarDataBytes += avatarPacketList->write(otherAvatar.toByteArray(detail));
quint64 lastEncodeForOther = nodeData->getLastOtherAvatarEncodeTime(otherNode->getUUID());
qDebug() << "about to write data for:" << otherNode->getUUID() << "last encoded at:" << lastEncodeForOther;
numAvatarDataBytes += avatarPacketList->write(otherAvatar.toByteArray(detail, lastEncodeForOther));
avatarPacketList->endSegment();
});

View file

@ -102,6 +102,15 @@ public:
const QString& getBaseDisplayName() { return _baseDisplayName; }
void setBaseDisplayName(const QString& baseDisplayName) { _baseDisplayName = baseDisplayName; }
quint64 getLastOtherAvatarEncodeTime(QUuid otherAvatar) {
quint64 result = 0;
if (_lastOtherAvatarEncodeTime.find(otherAvatar) != _lastOtherAvatarEncodeTime.end()) {
result = _lastOtherAvatarEncodeTime[otherAvatar];
}
_lastOtherAvatarEncodeTime[otherAvatar] = usecTimestampNow();
return result;
}
private:
AvatarSharedPointer _avatar { new AvatarData() };
@ -109,6 +118,10 @@ private:
std::unordered_map<QUuid, uint16_t> _lastBroadcastSequenceNumbers;
std::unordered_set<QUuid> _hasReceivedFirstPacketsFrom;
// this is a map of the last time we encoded an "other" avatar for
// sending to "this" node
std::unordered_map<QUuid, quint64> _lastOtherAvatarEncodeTime;
HRCTime _identityChangeTimestamp;
bool _gotIdentity { false };

View file

@ -5068,6 +5068,7 @@ void Application::nodeAdded(SharedNodePointer node) const {
if (node->getType() == NodeType::AvatarMixer) {
// new avatar mixer, send off our identity packet right away
getMyAvatar()->sendIdentityPacket();
getMyAvatar()->resetLastSent();
}
}

View file

@ -226,7 +226,7 @@ void MyAvatar::simulateAttachments(float deltaTime) {
// don't update attachments here, do it in harvestResultsFromPhysicsSimulation()
}
QByteArray MyAvatar::toByteArray(AvatarDataDetail dataDetail) {
QByteArray MyAvatar::toByteArray(AvatarDataDetail dataDetail, quint64 lastSentTime) {
CameraMode mode = qApp->getCamera()->getMode();
_globalPosition = getPosition();
_globalBoundingBoxCorner.x = _characterController.getCapsuleRadius();
@ -237,12 +237,12 @@ QByteArray MyAvatar::toByteArray(AvatarDataDetail dataDetail) {
// fake the avatar position that is sent up to the AvatarMixer
glm::vec3 oldPosition = getPosition();
setPosition(getSkeletonPosition());
QByteArray array = AvatarData::toByteArray(dataDetail);
QByteArray array = AvatarData::toByteArray(dataDetail, lastSentTime);
// copy the correct position back
setPosition(oldPosition);
return array;
}
return AvatarData::toByteArray(dataDetail);
return AvatarData::toByteArray(dataDetail, lastSentTime);
}
void MyAvatar::centerBody() {

View file

@ -333,7 +333,7 @@ private:
glm::vec3 getWorldBodyPosition() const;
glm::quat getWorldBodyOrientation() const;
QByteArray toByteArray(AvatarDataDetail dataDetail) override;
QByteArray toByteArray(AvatarDataDetail dataDetail, quint64 lastSentTime) override;
void simulate(float deltaTime);
void updateFromTrackers(float deltaTime);
virtual void render(RenderArgs* renderArgs, const glm::vec3& cameraPositio) override;

View file

@ -132,6 +132,7 @@ float AvatarData::getTargetScale() const {
void AvatarData::setTargetScale(float targetScale) {
_targetScale = glm::clamp(targetScale, MIN_AVATAR_SCALE, MAX_AVATAR_SCALE);
_scaleChanged = usecTimestampNow();
}
void AvatarData::setTargetScaleVerbose(float targetScale) {
@ -159,48 +160,47 @@ void AvatarData::lazyInitHeadData() {
}
bool AvatarData::avatarLocalPositionChanged() {
return _lastSentLocalPosition != getLocalPosition();
bool AvatarData::avatarDimensionsChangedSince(quint64 time) {
return _avatarDimensionsChanged >= time;
}
bool AvatarData::avatarDimensionsChanged() {
auto avatarDimensions = getPosition() - _globalBoundingBoxCorner;
return _lastSentAvatarDimensions != avatarDimensions;
bool AvatarData::avatarScaleChangedSince(quint64 time) {
return _avatarScaleChanged >= time;
}
bool AvatarData::avatarOrientationChanged() {
return _lastSentLocalOrientation != getLocalOrientation();
bool AvatarData::lookAtPositionChangedSince(quint64 time) {
return _headData->lookAtPositionChangedSince(time);
}
bool AvatarData::avatarScaleChanged() {
return _lastSentScale != getDomainLimitedScale();
bool AvatarData::audioLoudnessChangedSince(quint64 time) {
return _headData->audioLoudnessChangedSince(time);
}
bool AvatarData::lookAtPositionChanged() {
return _lastSentLookAt != _headData->_lookAtPosition;
bool AvatarData::sensorToWorldMatrixChangedSince(quint64 time) {
return _sensorToWorldMatrixChanged >= time;
}
bool AvatarData::audioLoudnessChanged() {
return _lastSentAudioLoudness != glm::min(_headData->_audioLoudness, MAX_AUDIO_LOUDNESS);
}
bool AvatarData::sensorToWorldMatrixChanged() {
return _lastSentSensorToWorldMatrix != getSensorToWorldMatrix();
}
bool AvatarData::additionalFlagsChanged() {
bool AvatarData::additionalFlagsChangedSince(quint64 time) {
return true; // FIXME!
}
bool AvatarData::parentInfoChanged() {
return (_lastSentParentID != getParentID()) || (_lastSentParentJointIndex != _parentJointIndex);
bool AvatarData::parentInfoChangedSince(quint64 time) {
return _parentChanged >= time;
}
bool AvatarData::faceTrackerInfoChanged() {
bool AvatarData::faceTrackerInfoChangedSince(quint64 time) {
return true; // FIXME!
}
QByteArray AvatarData::toByteArray(AvatarDataDetail dataDetail) {
QByteArray AvatarData::toByteArray(AvatarDataDetail dataDetail, quint64 lastSentTime) {
// if no timestamp was included, then assume the avatarData is single instance
// and is tracking its own last encoding time.
if (lastSentTime == 0) {
lastSentTime = _lastToByteArray;
_lastToByteArray = usecTimestampNow();
}
bool cullSmallChanges = (dataDetail == CullSmallData);
bool sendAll = (dataDetail == SendAllData);
bool sendMinimum = (dataDetail == MinimumData);
@ -261,18 +261,25 @@ QByteArray AvatarData::toByteArray(AvatarDataDetail dataDetail) {
// the others will be partial.
// we need some way of keeping track of what was sent the last time.
// AvatarDataRegulator
// .lastSent = time
//
// hasAvatarGlobalPosition = (globalPositionChanged > lastSent)
// hasAvatarLocalPosition = (localPositionChanged > lastSent)
// ...
bool hasAvatarGlobalPosition = true; // always include global position
bool hasAvatarLocalPosition = sendAll || avatarLocalPositionChanged();
bool hasAvatarDimensions = sendAll || avatarDimensionsChanged();
bool hasAvatarOrientation = sendAll || avatarOrientationChanged();
bool hasAvatarScale = sendAll || avatarScaleChanged();
bool hasLookAtPosition = sendAll || lookAtPositionChanged();
bool hasAudioLoudness = sendAll || audioLoudnessChanged();
bool hasSensorToWorldMatrix = sendAll || sensorToWorldMatrixChanged();
bool hasAdditionalFlags = sendAll || additionalFlagsChanged();
bool hasParentInfo = hasParent() && (sendAll || parentInfoChanged());
bool hasFaceTrackerInfo = hasFaceTracker() && (sendAll || faceTrackerInfoChanged());
bool hasAvatarLocalPosition = sendAll || tranlationChangedSince(lastSentTime);
bool hasAvatarOrientation = sendAll || rotationChangedSince(lastSentTime);
bool hasAvatarDimensions = sendAll || avatarDimensionsChangedSince(lastSentTime);
bool hasAvatarScale = sendAll || avatarScaleChangedSince(lastSentTime);
bool hasLookAtPosition = sendAll || lookAtPositionChangedSince(lastSentTime);
bool hasAudioLoudness = sendAll || audioLoudnessChangedSince(lastSentTime);
bool hasSensorToWorldMatrix = sendAll || sensorToWorldMatrixChangedSince(lastSentTime);
bool hasAdditionalFlags = sendAll || additionalFlagsChangedSince(lastSentTime);
bool hasParentInfo = hasParent() && (sendAll || parentInfoChangedSince(lastSentTime));
bool hasFaceTrackerInfo = hasFaceTracker() && (sendAll || faceTrackerInfoChangedSince(lastSentTime));
bool hasJointData = sendAll || !sendMinimum;
//qDebug() << __FUNCTION__ << "sendAll:" << sendAll;
@ -294,7 +301,12 @@ QByteArray AvatarData::toByteArray(AvatarDataDetail dataDetail) {
| (hasFaceTrackerInfo ? AvatarDataPacket::PACKET_HAS_FACE_TRACKER_INFO : 0)
| (hasJointData ? AvatarDataPacket::PACKET_HAS_JOINT_DATA : 0);
qDebug() << __FUNCTION__ << "packetStateFlags:" << packetStateFlags;
qDebug() << __FUNCTION__ << "packetStateFlags:" << packetStateFlags << "lastSentTime:" << lastSentTime;
qDebug() << "..." << "tranlationChangedSince():" << tranlationChangedSince(lastSentTime);
qDebug() << "..." << "rotationChangedSince():" << rotationChangedSince(lastSentTime);
qDebug() << "..." << "lookAtPositionChangedSince():" << lookAtPositionChangedSince(lastSentTime);
qDebug() << "..." << "audioLoudnessChangedSince():" << audioLoudnessChangedSince(lastSentTime);
qDebug() << "..." << "parentInfoChangedSince():" << parentInfoChangedSince(lastSentTime);
memcpy(destinationBuffer, &packetStateFlags, sizeof(packetStateFlags));
destinationBuffer += sizeof(packetStateFlags);
@ -305,8 +317,6 @@ QByteArray AvatarData::toByteArray(AvatarDataDetail dataDetail) {
data->globalPosition[1] = _globalPosition.y;
data->globalPosition[2] = _globalPosition.z;
destinationBuffer += sizeof(AvatarDataPacket::AvatarGlobalPosition);
_lastSentGlobalPosition = _globalPosition;
//qDebug() << "hasAvatarGlobalPosition _globalPosition:" << _globalPosition;
}
@ -321,17 +331,18 @@ QByteArray AvatarData::toByteArray(AvatarDataDetail dataDetail) {
data->localPosition[1] = localPosition.y;
data->localPosition[2] = localPosition.z;
destinationBuffer += sizeof(AvatarDataPacket::AvatarLocalPosition);
_lastSentLocalPosition = localPosition;
}
if (hasAvatarDimensions) {
auto data = reinterpret_cast<AvatarDataPacket::AvatarDimensions*>(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);
_lastSentAvatarDimensions = avatarDimensions;
qDebug() << "hasAvatarDimensions avatarDimensions:" << avatarDimensions;
}
if (hasAvatarOrientation) {
@ -342,7 +353,7 @@ QByteArray AvatarData::toByteArray(AvatarDataDetail dataDetail) {
packFloatAngleToTwoByte((uint8_t*)(data->localOrientation + 1), bodyEulerAngles.x);
packFloatAngleToTwoByte((uint8_t*)(data->localOrientation + 2), bodyEulerAngles.z);
destinationBuffer += sizeof(AvatarDataPacket::AvatarOrientation);
_lastSentLocalOrientation = localOrientation;
qDebug() << "hasAvatarOrientation bodyEulerAngles:" << bodyEulerAngles;
}
if (hasAvatarScale) {
@ -350,27 +361,25 @@ QByteArray AvatarData::toByteArray(AvatarDataDetail dataDetail) {
auto scale = getDomainLimitedScale();
packFloatRatioToTwoByte((uint8_t*)(&data->scale), scale);
destinationBuffer += sizeof(AvatarDataPacket::AvatarScale);
_lastSentScale = scale;
qDebug() << "hasAvatarScale scale:" << scale;
}
if (hasLookAtPosition) {
auto data = reinterpret_cast<AvatarDataPacket::LookAtPosition*>(destinationBuffer);
auto lookAt = _headData->_lookAtPosition;
auto lookAt = _headData->getLookAtPosition();
data->lookAtPosition[0] = lookAt.x;
data->lookAtPosition[1] = lookAt.y;
data->lookAtPosition[2] = lookAt.z;
destinationBuffer += sizeof(AvatarDataPacket::LookAtPosition);
_lastSentLookAt = lookAt;
//qDebug() << "hasLookAtPosition lookAt:" << lookAt;
qDebug() << "hasLookAtPosition lookAt:" << lookAt;
}
if (hasAudioLoudness) {
auto data = reinterpret_cast<AvatarDataPacket::AudioLoudness*>(destinationBuffer);
auto audioLoudness = glm::min(_headData->_audioLoudness, MAX_AUDIO_LOUDNESS);
auto audioLoudness = glm::min(_headData->getAudioLoudness(), MAX_AUDIO_LOUDNESS);
packFloatScalarToSignedTwoByteFixed((uint8_t*)&data->audioLoudness, audioLoudness, AUDIO_LOUDNESS_RADIX);
destinationBuffer += sizeof(AvatarDataPacket::AudioLoudness);
_lastSentAudioLoudness = audioLoudness;
//qDebug() << "hasAudioLoudness audioLoudness:" << audioLoudness;
qDebug() << "hasAudioLoudness audioLoudness:" << audioLoudness;
}
if (hasSensorToWorldMatrix) {
@ -383,7 +392,7 @@ QByteArray AvatarData::toByteArray(AvatarDataDetail dataDetail) {
data->sensorToWorldTrans[1] = sensorToWorldMatrix[3][1];
data->sensorToWorldTrans[2] = sensorToWorldMatrix[3][2];
destinationBuffer += sizeof(AvatarDataPacket::SensorToWorldMatrix);
_lastSentSensorToWorldMatrix = sensorToWorldMatrix;
qDebug() << "hasSensorToWorldMatrix...";
}
QUuid parentID = getParentID();
@ -415,7 +424,6 @@ QByteArray AvatarData::toByteArray(AvatarDataDetail dataDetail) {
}
data->flags = flags;
destinationBuffer += sizeof(AvatarDataPacket::AdditionalFlags);
_lastSentAdditionalFlags = flags;
//qDebug() << "hasAdditionalFlags _keyState:" << _keyState;
//qDebug() << "hasAdditionalFlags _handState:" << _handState;
@ -430,8 +438,6 @@ QByteArray AvatarData::toByteArray(AvatarDataDetail dataDetail) {
memcpy(parentInfo->parentUUID, referentialAsBytes.data(), referentialAsBytes.size());
parentInfo->parentJointIndex = _parentJointIndex;
destinationBuffer += sizeof(AvatarDataPacket::ParentInfo);
_lastSentParentID = parentID;
_lastSentParentJointIndex = _parentJointIndex;
}
// If it is connected, pack up the data
@ -701,8 +707,9 @@ int AvatarData::parseDataFromBuffer(const QByteArray& buffer) {
PACKET_READ_CHECK(AvatarGlobalPosition, sizeof(AvatarDataPacket::AvatarGlobalPosition));
auto data = reinterpret_cast<const AvatarDataPacket::AvatarGlobalPosition*>(sourceBuffer);
_globalPosition = glm::vec3(data->globalPosition[0], data->globalPosition[1], data->globalPosition[2]);
_globalPositionChanged = usecTimestampNow();
sourceBuffer += sizeof(AvatarDataPacket::AvatarGlobalPosition);
//qDebug() << "hasAvatarGlobalPosition _globalPosition:" << _globalPosition;
qDebug() << "hasAvatarGlobalPosition _globalPosition:" << _globalPosition;
}
if (hasAvatarLocalPosition) {
@ -717,7 +724,7 @@ int AvatarData::parseDataFromBuffer(const QByteArray& buffer) {
}
setLocalPosition(position);
sourceBuffer += sizeof(AvatarDataPacket::AvatarLocalPosition);
//qDebug() << "hasAvatarLocalPosition position:" << position;
qDebug() << "hasAvatarLocalPosition position:" << position;
}
if (hasAvatarDimensions) {
@ -726,8 +733,9 @@ int AvatarData::parseDataFromBuffer(const QByteArray& buffer) {
// FIXME - this is suspicious looking!
_globalBoundingBoxCorner = glm::vec3(data->avatarDimensions[0], data->avatarDimensions[1], data->avatarDimensions[2]);
_avatarDimensionsChanged = usecTimestampNow();
sourceBuffer += sizeof(AvatarDataPacket::AvatarDimensions);
//qDebug() << "hasAvatarDimensions _globalBoundingBoxCorner:" << _globalBoundingBoxCorner;
qDebug() << "hasAvatarDimensions _globalBoundingBoxCorner:" << _globalBoundingBoxCorner;
}
if (hasAvatarOrientation) {
@ -752,7 +760,7 @@ int AvatarData::parseDataFromBuffer(const QByteArray& buffer) {
setLocalOrientation(newOrientation);
}
sourceBuffer += sizeof(AvatarDataPacket::AvatarOrientation);
//qDebug() << "hasAvatarOrientation newOrientation:" << newOrientation;
qDebug() << "hasAvatarOrientation newOrientation:" << newOrientation;
}
if (hasAvatarScale) {
@ -768,7 +776,7 @@ int AvatarData::parseDataFromBuffer(const QByteArray& buffer) {
}
setTargetScale(scale);
sourceBuffer += sizeof(AvatarDataPacket::AvatarScale);
//qDebug() << "hasAvatarOrientation scale:" << scale;
qDebug() << "hasAvatarOrientation scale:" << scale;
}
if (hasLookAtPosition) {
@ -781,9 +789,9 @@ int AvatarData::parseDataFromBuffer(const QByteArray& buffer) {
}
return buffer.size();
}
_headData->_lookAtPosition = lookAt;
_headData->setLookAtPosition(lookAt);
sourceBuffer += sizeof(AvatarDataPacket::LookAtPosition);
//qDebug() << "hasLookAtPosition lookAt:" << lookAt;
qDebug() << "hasLookAtPosition lookAt:" << lookAt;
}
if (hasAudioLoudness) {
@ -798,9 +806,9 @@ int AvatarData::parseDataFromBuffer(const QByteArray& buffer) {
}
return buffer.size();
}
_headData->_audioLoudness = audioLoudness;
_headData->setAudioLoudness(audioLoudness);
sourceBuffer += sizeof(AvatarDataPacket::AudioLoudness);
//qDebug() << "hasAudioLoudness audioLoudness:" << audioLoudness;
qDebug() << "hasAudioLoudness audioLoudness:" << audioLoudness;
}
if (hasSensorToWorldMatrix) {
@ -813,8 +821,9 @@ int AvatarData::parseDataFromBuffer(const QByteArray& buffer) {
glm::vec3 sensorToWorldTrans(data->sensorToWorldTrans[0], data->sensorToWorldTrans[1], data->sensorToWorldTrans[2]);
glm::mat4 sensorToWorldMatrix = createMatFromScaleQuatAndPos(glm::vec3(sensorToWorldScale), sensorToWorldQuat, sensorToWorldTrans);
_sensorToWorldMatrixCache.set(sensorToWorldMatrix);
_sensorToWorldMatrixChanged = usecTimestampNow();
sourceBuffer += sizeof(AvatarDataPacket::SensorToWorldMatrix);
//qDebug() << "hasSensorToWorldMatrix sensorToWorldMatrix:" << sensorToWorldMatrix;
qDebug() << "hasSensorToWorldMatrix sensorToWorldMatrix:" << sensorToWorldMatrix;
}
if (hasAdditionalFlags) {
@ -844,8 +853,10 @@ int AvatarData::parseDataFromBuffer(const QByteArray& buffer) {
//qDebug() << "hasAdditionalFlags _isFaceTrackerConnected:" << _headData->_isFaceTrackerConnected;
//qDebug() << "hasAdditionalFlags _isEyeTrackerConnected:" << _headData->_isEyeTrackerConnected;
//qDebug() << "hasAdditionalFlags bitItems:" << bitItems;
qDebug() << "hasAdditionalFlags bitItems:" << bitItems;
sourceBuffer += sizeof(AvatarDataPacket::AdditionalFlags);
_additionalFlagsChanged = usecTimestampNow();
}
// FIXME -- make sure to handle the existance of a parent vs a change in the parent...
@ -858,8 +869,11 @@ int AvatarData::parseDataFromBuffer(const QByteArray& buffer) {
QByteArray byteArray((const char*)parentInfo->parentUUID, NUM_BYTES_RFC4122_UUID);
_parentID = QUuid::fromRfc4122(byteArray);
_parentJointIndex = parentInfo->parentJointIndex;
//qDebug() << "hasParentInfo _parentID:" << _parentID;
qDebug() << "hasParentInfo _parentID:" << _parentID;
_parentChanged = usecTimestampNow();
} else {
// FIXME - this aint totally right, for switching to parent/no-parent
_parentID = QUuid();
}
@ -879,13 +893,13 @@ int AvatarData::parseDataFromBuffer(const QByteArray& buffer) {
_headData->_blendshapeCoefficients.resize(numCoefficients); // make sure there's room for the copy!
memcpy(_headData->_blendshapeCoefficients.data(), sourceBuffer, coefficientsSize);
sourceBuffer += coefficientsSize;
//qDebug() << "hasFaceTrackerInfo numCoefficients:" << numCoefficients;
qDebug() << "hasFaceTrackerInfo numCoefficients:" << numCoefficients;
}
if (hasJointData) {
PACKET_READ_CHECK(NumJoints, sizeof(uint8_t));
int numJoints = *sourceBuffer++;
//qDebug() << "hasJointData numJoints:" << numJoints;
qDebug() << "hasJointData numJoints:" << numJoints;
const int bytesOfValidity = (int)ceil((float)numJoints / (float)BITS_IN_BYTE);
PACKET_READ_CHECK(JointRotationValidityBits, bytesOfValidity);

View file

@ -412,7 +412,7 @@ public:
SendAllData
} AvatarDataDetail;
virtual QByteArray toByteArray(AvatarDataDetail dataDetail);
virtual QByteArray toByteArray(AvatarDataDetail dataDetail, quint64 lastSentTime = 0);
virtual void doneEncoding(bool cullSmallChanges);
/// \return true if an error should be logged
@ -464,10 +464,11 @@ public:
void setTargetScaleVerbose(float targetScale);
float getDomainLimitedScale() const { return glm::clamp(_targetScale, _domainMinimumScale, _domainMaximumScale); }
void setDomainMinimumScale(float domainMinimumScale)
{ _domainMinimumScale = glm::clamp(domainMinimumScale, MIN_AVATAR_SCALE, MAX_AVATAR_SCALE); }
void setDomainMaximumScale(float domainMaximumScale)
{ _domainMaximumScale = glm::clamp(domainMaximumScale, MIN_AVATAR_SCALE, MAX_AVATAR_SCALE); }
{ _domainMinimumScale = glm::clamp(domainMinimumScale, MIN_AVATAR_SCALE, MAX_AVATAR_SCALE); _scaleChanged = usecTimestampNow(); }
void setDomainMaximumScale(float domainMaximumScale)
{ _domainMaximumScale = glm::clamp(domainMaximumScale, MIN_AVATAR_SCALE, MAX_AVATAR_SCALE); _scaleChanged = usecTimestampNow(); }
// Hand State
Q_INVOKABLE void setHandState(char s) { _handState = s; }
@ -602,23 +603,23 @@ public slots:
float getTargetScale() { return _targetScale; }
void resetLastSent() { _lastToByteArray = 0; }
protected:
void lazyInitHeadData();
bool avatarLocalPositionChanged();
bool avatarDimensionsChanged();
bool avatarOrientationChanged();
bool avatarScaleChanged();
bool lookAtPositionChanged();
bool audioLoudnessChanged();
bool sensorToWorldMatrixChanged();
bool additionalFlagsChanged();
bool avatarDimensionsChangedSince(quint64 time);
bool avatarScaleChangedSince(quint64 time);
bool lookAtPositionChangedSince(quint64 time);
bool audioLoudnessChangedSince(quint64 time);
bool sensorToWorldMatrixChangedSince(quint64 time);
bool additionalFlagsChangedSince(quint64 time);
bool hasParent() { return !getParentID().isNull(); }
bool parentInfoChanged();
bool parentInfoChangedSince(quint64 time);
bool hasFaceTracker() { return _headData ? _headData->_isFaceTrackerConnected : false; }
bool faceTrackerInfoChanged();
bool faceTrackerInfoChangedSince(quint64 time);
glm::vec3 _handPosition;
virtual const QString& getSessionDisplayNameForTransport() const { return _sessionDisplayName; }
@ -681,17 +682,17 @@ protected:
// updates about one avatar to another.
glm::vec3 _globalPosition { 0, 0, 0 };
glm::vec3 _lastSentGlobalPosition { 0, 0, 0 };
glm::vec3 _lastSentLocalPosition { 0, 0, 0 };
glm::vec3 _lastSentAvatarDimensions { 0, 0, 0 };
glm::quat _lastSentLocalOrientation;
float _lastSentScale { 0 };
glm::vec3 _lastSentLookAt { 0, 0, 0 };
float _lastSentAudioLoudness { 0 };
glm::mat4 _lastSentSensorToWorldMatrix;
uint8_t _lastSentAdditionalFlags { 0 };
QUuid _lastSentParentID;
quint16 _lastSentParentJointIndex { 0 };
quint64 _globalPositionChanged { 0 };
quint64 _avatarDimensionsChanged { 0 };
quint64 _avatarScaleChanged { 0 };
quint64 _lookAtChanged { 0 };
quint64 _audioLoudnessChanged { 0 };
quint64 _sensorToWorldMatrixChanged { 0 };
quint64 _additionalFlagsChanged { 0 };
quint64 _parentChanged { 0 };
quint64 _lastToByteArray { 0 }; // tracks the last time we did a toByteArray
glm::vec3 _globalBoundingBoxCorner;
@ -710,7 +711,6 @@ protected:
int getFauxJointIndex(const QString& name) const;
AvatarDataPacket::AvatarInfo _lastAvatarInfo;
glm::mat4 _lastSensorToWorldMatrix;
private:
friend void avatarStateFromFrame(const QByteArray& frameData, AvatarData* _avatar);

View file

@ -19,6 +19,8 @@
#include <glm/glm.hpp>
#include <glm/gtc/quaternion.hpp>
#include <SharedUtil.h>
// degrees
const float MIN_HEAD_YAW = -180.0f;
const float MAX_HEAD_YAW = 180.0f;
@ -56,7 +58,13 @@ public:
void setOrientation(const glm::quat& orientation);
float getAudioLoudness() const { return _audioLoudness; }
void setAudioLoudness(float audioLoudness) { _audioLoudness = audioLoudness; }
void setAudioLoudness(float audioLoudness) {
if (audioLoudness != _audioLoudness) {
_audioLoudnessChanged = usecTimestampNow();
}
_audioLoudness = audioLoudness;
}
bool audioLoudnessChangedSince(quint64 time) { return _audioLoudnessChanged >= time; }
float getAudioAverageLoudness() const { return _audioAverageLoudness; }
void setAudioAverageLoudness(float audioAverageLoudness) { _audioAverageLoudness = audioAverageLoudness; }
@ -66,7 +74,13 @@ public:
void setBlendshapeCoefficients(const QVector<float>& blendshapeCoefficients) { _blendshapeCoefficients = blendshapeCoefficients; }
const glm::vec3& getLookAtPosition() const { return _lookAtPosition; }
void setLookAtPosition(const glm::vec3& lookAtPosition) { _lookAtPosition = lookAtPosition; }
void setLookAtPosition(const glm::vec3& lookAtPosition) {
if (_lookAtPosition != lookAtPosition) {
_lookAtPositionChanged = usecTimestampNow();
}
_lookAtPosition = lookAtPosition;
}
bool lookAtPositionChangedSince(quint64 time) { return _lookAtPositionChanged >= time; }
friend class AvatarData;
@ -80,7 +94,11 @@ protected:
float _baseRoll;
glm::vec3 _lookAtPosition;
quint64 _lookAtPositionChanged { 0 };
float _audioLoudness;
quint64 _audioLoudnessChanged { 0 };
bool _isFaceTrackerConnected;
bool _isEyeTrackerConnected;
float _leftEyeBlink;

View file

@ -26,6 +26,9 @@ SpatiallyNestable::SpatiallyNestable(NestableType nestableType, QUuid id) :
// set flags in _transform
_transform.setTranslation(glm::vec3(0.0f));
_transform.setRotation(glm::quat());
_scaleChanged = usecTimestampNow();
_translationChanged = usecTimestampNow();
_rotationChanged = usecTimestampNow();
}
SpatiallyNestable::~SpatiallyNestable() {
@ -403,6 +406,7 @@ void SpatiallyNestable::setPosition(const glm::vec3& position, bool& success, bo
});
if (success && changed) {
locationChanged(tellPhysics);
_translationChanged = usecTimestampNow();
}
}
@ -455,6 +459,7 @@ void SpatiallyNestable::setOrientation(const glm::quat& orientation, bool& succe
});
if (success && changed) {
locationChanged(tellPhysics);
_rotationChanged = usecTimestampNow();
}
}
@ -653,6 +658,8 @@ void SpatiallyNestable::setTransform(const Transform& transform, bool& success)
});
if (success && changed) {
locationChanged();
_translationChanged = usecTimestampNow();
_rotationChanged = usecTimestampNow();
}
}
@ -693,6 +700,7 @@ void SpatiallyNestable::setScale(const glm::vec3& scale) {
});
if (changed) {
dimensionsChanged();
_scaleChanged = usecTimestampNow();
}
}
@ -715,6 +723,7 @@ void SpatiallyNestable::setScale(float value) {
if (changed) {
dimensionsChanged();
_scaleChanged = usecTimestampNow();
}
}
@ -743,6 +752,9 @@ void SpatiallyNestable::setLocalTransform(const Transform& transform) {
if (changed) {
locationChanged();
_scaleChanged = usecTimestampNow();
_translationChanged = usecTimestampNow();
_rotationChanged = usecTimestampNow();
}
}
@ -769,6 +781,7 @@ void SpatiallyNestable::setLocalPosition(const glm::vec3& position, bool tellPhy
});
if (changed) {
locationChanged(tellPhysics);
_translationChanged = usecTimestampNow();
}
}
@ -795,6 +808,7 @@ void SpatiallyNestable::setLocalOrientation(const glm::quat& orientation) {
});
if (changed) {
locationChanged();
_rotationChanged = usecTimestampNow();
}
}
@ -850,7 +864,10 @@ void SpatiallyNestable::setLocalScale(const glm::vec3& scale) {
changed = true;
}
});
dimensionsChanged();
if (changed) {
dimensionsChanged();
_scaleChanged = usecTimestampNow();
}
}
QList<SpatiallyNestablePointer> SpatiallyNestable::getChildren() const {
@ -1072,6 +1089,9 @@ void SpatiallyNestable::setLocalTransformAndVelocities(
if (changed) {
locationChanged(false);
_scaleChanged = usecTimestampNow();
_translationChanged = usecTimestampNow();
_rotationChanged = usecTimestampNow();
}
}

View file

@ -176,6 +176,10 @@ public:
const glm::vec3& localVelocity,
const glm::vec3& localAngularVelocity);
bool scaleChangedSince(quint64 time) { return _scaleChanged > time; }
bool tranlationChangedSince(quint64 time) { return _translationChanged > time; }
bool rotationChangedSince(quint64 time) { return _rotationChanged > time; }
protected:
const NestableType _nestableType; // EntityItem or an AvatarData
QUuid _id;
@ -199,6 +203,9 @@ protected:
mutable bool _queryAACubeSet { false };
bool _missingAncestor { false };
quint64 _scaleChanged { 0 };
quint64 _translationChanged { 0 };
quint64 _rotationChanged { 0 };
private:
mutable ReadWriteLockable _transformLock;