checkpoint - got first cut at distance based rotation tolerance working

This commit is contained in:
ZappoMan 2017-01-23 13:06:29 -08:00
parent 060c63045b
commit 292d472a59
8 changed files with 71 additions and 29 deletions

View file

@ -507,6 +507,7 @@ void Agent::processAgentAvatar() {
glm::vec3 viewerPosition(0); glm::vec3 viewerPosition(0);
QByteArray avatarByteArray = scriptedAvatar->toByteArray(dataDetail, lastSentTime, lastSentJointData, distanceAdjust, viewerPosition); QByteArray avatarByteArray = scriptedAvatar->toByteArray(dataDetail, lastSentTime, lastSentJointData, distanceAdjust, viewerPosition);
scriptedAvatar->doneEncoding(true); scriptedAvatar->doneEncoding(true);
static AvatarDataSequenceNumber sequenceNumber = 0; static AvatarDataSequenceNumber sequenceNumber = 0;

View file

@ -422,10 +422,10 @@ void AvatarMixer::broadcastAvatarData() {
numAvatarDataBytes += avatarPacketList->write(otherNode->getUUID().toRfc4122()); numAvatarDataBytes += avatarPacketList->write(otherNode->getUUID().toRfc4122());
auto lastEncodeForOther = nodeData->getLastOtherAvatarEncodeTime(otherNode->getUUID()); auto lastEncodeForOther = nodeData->getLastOtherAvatarEncodeTime(otherNode->getUUID());
auto lastSentJointsForOther = nodeData->getLastOtherAvatarSentJoints(otherNode->getUUID()); QVector<JointData>& lastSentJointsForOther = nodeData->getLastOtherAvatarSentJoints(otherNode->getUUID());
bool distanceAdjust = true; bool distanceAdjust = true;
glm::vec3 viewerPosition = nodeData->getPosition(); glm::vec3 viewerPosition = nodeData->getPosition();
auto bytes = otherAvatar.toByteArray(detail, lastEncodeForOther, lastSentJointsForOther, distanceAdjust, viewerPosition); auto bytes = otherAvatar.toByteArray(detail, lastEncodeForOther, lastSentJointsForOther, distanceAdjust, viewerPosition, &lastSentJointsForOther);
numAvatarDataBytes += avatarPacketList->write(bytes); numAvatarDataBytes += avatarPacketList->write(bytes);
avatarPacketList->endSegment(); avatarPacketList->endSegment();

View file

@ -14,8 +14,8 @@
#include <GLMHelpers.h> #include <GLMHelpers.h>
#include "ScriptableAvatar.h" #include "ScriptableAvatar.h"
QByteArray ScriptableAvatar::toByteArray(AvatarDataDetail dataDetail, quint64 lastSentTime, QVector<JointData>& lastSentJointData, QByteArray ScriptableAvatar::toByteArray(AvatarDataDetail dataDetail, quint64 lastSentTime, const QVector<JointData>& lastSentJointData,
bool distanceAdjust, glm::vec3 viewerPosition) { bool distanceAdjust, glm::vec3 viewerPosition, QVector<JointData>* sentJointDataOut) {
_globalPosition = getPosition(); _globalPosition = getPosition();
return AvatarData::toByteArray(dataDetail, lastSentTime, lastSentJointData, distanceAdjust, viewerPosition); return AvatarData::toByteArray(dataDetail, lastSentTime, lastSentJointData, distanceAdjust, viewerPosition);
} }

View file

@ -28,8 +28,8 @@ public:
Q_INVOKABLE AnimationDetails getAnimationDetails(); Q_INVOKABLE AnimationDetails getAnimationDetails();
virtual void setSkeletonModelURL(const QUrl& skeletonModelURL) override; virtual void setSkeletonModelURL(const QUrl& skeletonModelURL) override;
virtual QByteArray toByteArray(AvatarDataDetail dataDetail, quint64 lastSentTime, QVector<JointData>& lastSentJointData, virtual QByteArray toByteArray(AvatarDataDetail dataDetail, quint64 lastSentTime, const QVector<JointData>& lastSentJointData,
bool distanceAdjust, glm::vec3 viewerPosition) override; bool distanceAdjust, glm::vec3 viewerPosition, QVector<JointData>* sentJointDataOut = nullptr) override;
private slots: private slots:

View file

@ -226,8 +226,8 @@ void MyAvatar::simulateAttachments(float deltaTime) {
// don't update attachments here, do it in harvestResultsFromPhysicsSimulation() // don't update attachments here, do it in harvestResultsFromPhysicsSimulation()
} }
QByteArray MyAvatar::toByteArray(AvatarDataDetail dataDetail, quint64 lastSentTime, QVector<JointData>& lastSentJointData, QByteArray MyAvatar::toByteArray(AvatarDataDetail dataDetail, quint64 lastSentTime, const QVector<JointData>& lastSentJointData,
bool distanceAdjust, glm::vec3 viewerPosition) { bool distanceAdjust, glm::vec3 viewerPosition, QVector<JointData>* sentJointDataOut) {
CameraMode mode = qApp->getCamera()->getMode(); CameraMode mode = qApp->getCamera()->getMode();
_globalPosition = getPosition(); _globalPosition = getPosition();
_globalBoundingBoxDimensions.x = _characterController.getCapsuleRadius(); _globalBoundingBoxDimensions.x = _characterController.getCapsuleRadius();
@ -238,12 +238,12 @@ QByteArray MyAvatar::toByteArray(AvatarDataDetail dataDetail, quint64 lastSentTi
// 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();
setPosition(getSkeletonPosition()); setPosition(getSkeletonPosition());
QByteArray array = AvatarData::toByteArray(dataDetail, lastSentTime, lastSentJointData, distanceAdjust, viewerPosition); QByteArray array = AvatarData::toByteArray(dataDetail, lastSentTime, lastSentJointData, distanceAdjust, viewerPosition, sentJointDataOut);
// copy the correct position back // copy the correct position back
setPosition(oldPosition); setPosition(oldPosition);
return array; return array;
} }
return AvatarData::toByteArray(dataDetail, lastSentTime, lastSentJointData, distanceAdjust, viewerPosition); return AvatarData::toByteArray(dataDetail, lastSentTime, lastSentJointData, distanceAdjust, viewerPosition, sentJointDataOut);
} }
void MyAvatar::centerBody() { void MyAvatar::centerBody() {

View file

@ -333,8 +333,11 @@ private:
glm::vec3 getWorldBodyPosition() const; glm::vec3 getWorldBodyPosition() const;
glm::quat getWorldBodyOrientation() const; glm::quat getWorldBodyOrientation() const;
QByteArray toByteArray(AvatarDataDetail dataDetail, quint64 lastSentTime, QVector<JointData>& lastSentJointData,
bool distanceAdjust, glm::vec3 viewerPosition) override;
virtual QByteArray toByteArray(AvatarDataDetail dataDetail, quint64 lastSentTime, const QVector<JointData>& lastSentJointData,
bool distanceAdjust, glm::vec3 viewerPosition, QVector<JointData>* sentJointDataOut = nullptr) override;
void simulate(float deltaTime); void simulate(float deltaTime);
void updateFromTrackers(float deltaTime); void updateFromTrackers(float deltaTime);
virtual void render(RenderArgs* renderArgs, const glm::vec3& cameraPositio) override; virtual void render(RenderArgs* renderArgs, const glm::vec3& cameraPositio) override;

View file

@ -196,15 +196,18 @@ bool AvatarData::faceTrackerInfoChangedSince(quint64 time) {
float AvatarData::getDistanceBasedMinRotationDOT(glm::vec3 viewerPosition) { float AvatarData::getDistanceBasedMinRotationDOT(glm::vec3 viewerPosition) {
auto distance = glm::distance(_globalPosition, viewerPosition); auto distance = glm::distance(_globalPosition, viewerPosition);
//qDebug() << "_globalPosition:" << _globalPosition << "viewerPosition:" << viewerPosition << "distance:" << distance; //qDebug() << "_globalPosition:" << _globalPosition << "viewerPosition:" << viewerPosition << "distance:" << distance;
float result = ROTATION_90D_DOT; // assume worst float result = ROTATION_179D_DOT; // assume worst
if (distance < 1.0f) { if (distance < 1.0f) {
result = AVATAR_MIN_ROTATION_DOT; result = AVATAR_MIN_ROTATION_DOT;
} else if (distance < 5.0f) { } else if (distance < 5.0f) {
result = ROTATION_15D_DOT; result = ROTATION_15D_DOT;
} else if (distance < 10.0f) { } else if (distance < 10.0f) {
result = ROTATION_45D_DOT; result = ROTATION_45D_DOT;
} else if (distance < 20.0f) {
result = ROTATION_90D_DOT;
} }
//qDebug() << __FUNCTION__ << "result:" << result; //qDebug() << __FUNCTION__ << "result:" << result;
return result; return result;
} }
@ -213,8 +216,8 @@ float AvatarData::getDistanceBasedMinTranslationDistance(glm::vec3 viewerPositio
} }
QByteArray AvatarData::toByteArray(AvatarDataDetail dataDetail, quint64 lastSentTime, QVector<JointData>& lastSentJointData, QByteArray AvatarData::toByteArray(AvatarDataDetail dataDetail, quint64 lastSentTime, const QVector<JointData>& lastSentJointData,
bool distanceAdjust, glm::vec3 viewerPosition) { bool distanceAdjust, glm::vec3 viewerPosition, QVector<JointData>* sentJointDataOut) {
// if no timestamp was included, then assume the avatarData is single instance // if no timestamp was included, then assume the avatarData is single instance
// and is tracking its own last encoding time. // and is tracking its own last encoding time.
@ -455,25 +458,43 @@ QByteArray AvatarData::toByteArray(AvatarDataDetail dataDetail, quint64 lastSent
unsigned char* beforeRotations = destinationBuffer; unsigned char* beforeRotations = destinationBuffer;
#endif #endif
lastSentJointData.resize(_jointData.size()); if (sentJointDataOut) {
if (sentJointDataOut->size() != _jointData.size()) {
sentJointDataOut->resize(_jointData.size());
}
}
float minRotationDOT = !distanceAdjust ? AVATAR_MIN_ROTATION_DOT : getDistanceBasedMinRotationDOT(viewerPosition); float minRotationDOT = !distanceAdjust ? AVATAR_MIN_ROTATION_DOT : getDistanceBasedMinRotationDOT(viewerPosition);
//qDebug() << "sendAll:" << sendAll << "cullSmallChanges:" << cullSmallChanges; auto distance = glm::distance(_globalPosition, viewerPosition);
//qDebug() << "sendAll:" << sendAll << "cullSmallChanges:" << cullSmallChanges << "minRotationDOT:" << minRotationDOT << "distance:" << distance;
for (int i = 0; i < _jointData.size(); i++) { for (int i = 0; i < _jointData.size(); i++) {
const JointData& data = _jointData[i]; const JointData& data = _jointData[i];
//qDebug() << "joint[" << i << "].dot:" << fabsf(glm::dot(data.rotation, lastSentJointData[i].rotation));
// The dot product for smaller rotations is a smaller number.
//
// const float AVATAR_MIN_ROTATION_DOT = 0.9999999f;
// const float ROTATION_15D_DOT = 0.9914449f;
// const float ROTATION_45D_DOT = 0.9238795f;
// const float ROTATION_90D_DOT = 0.7071068f;
// So if the dot() is less than the value, then the rotation is a larger angle of rotation
//
bool largeEnoughRotation = fabsf(glm::dot(data.rotation, lastSentJointData[i].rotation)) < minRotationDOT;
//qDebug() << "joint[" << i << "].dot:" << fabsf(glm::dot(data.rotation, lastSentJointData[i].rotation)) << "minRotationDOT:" << minRotationDOT << "largeEnoughRotation:" << largeEnoughRotation;
if (sendAll || lastSentJointData[i].rotation != data.rotation) { if (sendAll || lastSentJointData[i].rotation != data.rotation) {
if (sendAll || if (sendAll || !cullSmallChanges || largeEnoughRotation) {
!cullSmallChanges ||
fabsf(glm::dot(data.rotation, lastSentJointData[i].rotation)) > minRotationDOT) {
if (data.rotationSet) { if (data.rotationSet) {
validity |= (1 << validityBit); validity |= (1 << validityBit);
#if 1 //def WANT_DEBUG #if 1 //def WANT_DEBUG
rotationSentCount++; rotationSentCount++;
#endif #endif
if (sentJointDataOut) {
auto jointDataOut = *sentJointDataOut;
jointDataOut[i].rotation = data.rotation;
}
} }
} }
} }
@ -527,6 +548,12 @@ QByteArray AvatarData::toByteArray(AvatarDataDetail dataDetail, quint64 lastSent
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);
if (sentJointDataOut) {
auto jointDataOut = *sentJointDataOut;
jointDataOut[i].translation = data.translation;
}
} }
} }
} }
@ -585,6 +612,7 @@ QByteArray AvatarData::toByteArray(AvatarDataDetail dataDetail, quint64 lastSent
return avatarDataByteArray.left(avatarDataSize); return avatarDataByteArray.left(avatarDataSize);
} }
// NOTE: This is never used in a "distanceAdjust" mode, so it's ok that it doesn't use a variable minimum rotation/translation
void AvatarData::doneEncoding(bool cullSmallChanges) { void AvatarData::doneEncoding(bool cullSmallChanges) {
// The server has finished sending this version of the joint-data to other nodes. Update _lastSentJointData. // The server has finished sending this version of the joint-data to other nodes. Update _lastSentJointData.
QReadLocker readLock(&_jointDataLock); QReadLocker readLock(&_jointDataLock);
@ -1549,14 +1577,19 @@ void AvatarData::sendAvatarDataPacket() {
// about 2% of the time, we send a full update (meaning, we transmit all the joint data), even if nothing has changed. // about 2% of the time, we send a full update (meaning, we transmit all the joint data), even if nothing has changed.
// this is to guard against a joint moving once, the packet getting lost, and the joint never moving again. // this is to guard against a joint moving once, the packet getting lost, and the joint never moving again.
auto dataDetail = (randFloat() < AVATAR_SEND_FULL_UPDATE_RATIO) ? SendAllData : CullSmallData; bool cullSmallData = (randFloat() < AVATAR_SEND_FULL_UPDATE_RATIO);
auto dataDetail = cullSmallData ? SendAllData : CullSmallData;
quint64 lastSentTime = 0; quint64 lastSentTime = 0;
QVector<JointData>& lastSentJointData = _lastSentJointData; QVector<JointData> lastSentJointData;
{
QReadLocker readLock(&_jointDataLock);
lastSentJointData = _lastSentJointData;
}
bool distanceAdjust = false; bool distanceAdjust = false;
glm::vec3 viewerPosition(0); glm::vec3 viewerPosition(0);
QByteArray avatarByteArray = toByteArray(dataDetail, lastSentTime, lastSentJointData, distanceAdjust, viewerPosition); QByteArray avatarByteArray = toByteArray(dataDetail, lastSentTime, lastSentJointData, distanceAdjust, viewerPosition);
doneEncoding(true); // FIXME - doneEncoding() takes a bool for culling small changes, that's janky! doneEncoding(cullSmallData); // FIXME - doneEncoding() takes a bool for culling small changes, that's janky!
static AvatarDataSequenceNumber sequenceNumber = 0; static AvatarDataSequenceNumber sequenceNumber = 0;

View file

@ -260,7 +260,8 @@ const float AVATAR_MIN_TRANSLATION = 0.0001f;
const float ROTATION_15D_DOT = 0.9914449f; const float ROTATION_15D_DOT = 0.9914449f;
const float ROTATION_45D_DOT = 0.9238795f; const float ROTATION_45D_DOT = 0.9238795f;
const float ROTATION_90D_DOT = 0.7071068f; const float ROTATION_90D_DOT = 0.7071068f;
const float ROTATION_179D_DOT = 0.0087266f;
// Where one's own Avatar begins in the world (will be overwritten if avatar data file is found). // Where one's own Avatar begins in the world (will be overwritten if avatar data file is found).
// This is the start location in the Sandbox (xyz: 6270, 211, 6000). // This is the start location in the Sandbox (xyz: 6270, 211, 6000).
@ -350,8 +351,8 @@ public:
SendAllData SendAllData
} AvatarDataDetail; } AvatarDataDetail;
virtual QByteArray toByteArray(AvatarDataDetail dataDetail, quint64 lastSentTime, QVector<JointData>& lastSentJointData, virtual QByteArray toByteArray(AvatarDataDetail dataDetail, quint64 lastSentTime, const QVector<JointData>& lastSentJointData,
bool distanceAdjust, glm::vec3 viewerPosition); bool distanceAdjust, glm::vec3 viewerPosition, QVector<JointData>* sentJointDataOut = nullptr);
virtual void doneEncoding(bool cullSmallChanges); virtual void doneEncoding(bool cullSmallChanges);
@ -531,7 +532,11 @@ public:
float getDataRate(const QString& rateName = QString("")); float getDataRate(const QString& rateName = QString(""));
QVector<JointData>& getLastSentJointData() { return _lastSentJointData; } QVector<JointData> getLastSentJointData() {
QReadLocker readLock(&_jointDataLock);
return _lastSentJointData;
}
public slots: public slots:
void sendAvatarDataPacket(); void sendAvatarDataPacket();