mirror of
https://github.com/overte-org/overte.git
synced 2025-08-09 18:13:05 +02:00
checkpoint - got first cut at distance based rotation tolerance working
This commit is contained in:
parent
060c63045b
commit
292d472a59
8 changed files with 71 additions and 29 deletions
|
@ -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;
|
||||||
|
|
|
@ -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();
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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:
|
||||||
|
|
|
@ -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() {
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
|
|
|
@ -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();
|
||||||
|
|
Loading…
Reference in a new issue