mirror of
https://github.com/overte-org/overte.git
synced 2025-04-20 03:44:02 +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);
|
||||
|
||||
QByteArray avatarByteArray = scriptedAvatar->toByteArray(dataDetail, lastSentTime, lastSentJointData, distanceAdjust, viewerPosition);
|
||||
|
||||
scriptedAvatar->doneEncoding(true);
|
||||
|
||||
static AvatarDataSequenceNumber sequenceNumber = 0;
|
||||
|
|
|
@ -422,10 +422,10 @@ void AvatarMixer::broadcastAvatarData() {
|
|||
|
||||
numAvatarDataBytes += avatarPacketList->write(otherNode->getUUID().toRfc4122());
|
||||
auto lastEncodeForOther = nodeData->getLastOtherAvatarEncodeTime(otherNode->getUUID());
|
||||
auto lastSentJointsForOther = nodeData->getLastOtherAvatarSentJoints(otherNode->getUUID());
|
||||
QVector<JointData>& lastSentJointsForOther = nodeData->getLastOtherAvatarSentJoints(otherNode->getUUID());
|
||||
bool distanceAdjust = true;
|
||||
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);
|
||||
|
||||
avatarPacketList->endSegment();
|
||||
|
|
|
@ -14,8 +14,8 @@
|
|||
#include <GLMHelpers.h>
|
||||
#include "ScriptableAvatar.h"
|
||||
|
||||
QByteArray ScriptableAvatar::toByteArray(AvatarDataDetail dataDetail, quint64 lastSentTime, QVector<JointData>& lastSentJointData,
|
||||
bool distanceAdjust, glm::vec3 viewerPosition) {
|
||||
QByteArray ScriptableAvatar::toByteArray(AvatarDataDetail dataDetail, quint64 lastSentTime, const QVector<JointData>& lastSentJointData,
|
||||
bool distanceAdjust, glm::vec3 viewerPosition, QVector<JointData>* sentJointDataOut) {
|
||||
_globalPosition = getPosition();
|
||||
return AvatarData::toByteArray(dataDetail, lastSentTime, lastSentJointData, distanceAdjust, viewerPosition);
|
||||
}
|
||||
|
|
|
@ -28,8 +28,8 @@ public:
|
|||
Q_INVOKABLE AnimationDetails getAnimationDetails();
|
||||
virtual void setSkeletonModelURL(const QUrl& skeletonModelURL) override;
|
||||
|
||||
virtual 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;
|
||||
|
||||
|
||||
private slots:
|
||||
|
|
|
@ -226,8 +226,8 @@ void MyAvatar::simulateAttachments(float deltaTime) {
|
|||
// don't update attachments here, do it in harvestResultsFromPhysicsSimulation()
|
||||
}
|
||||
|
||||
QByteArray MyAvatar::toByteArray(AvatarDataDetail dataDetail, quint64 lastSentTime, QVector<JointData>& lastSentJointData,
|
||||
bool distanceAdjust, glm::vec3 viewerPosition) {
|
||||
QByteArray MyAvatar::toByteArray(AvatarDataDetail dataDetail, quint64 lastSentTime, const QVector<JointData>& lastSentJointData,
|
||||
bool distanceAdjust, glm::vec3 viewerPosition, QVector<JointData>* sentJointDataOut) {
|
||||
CameraMode mode = qApp->getCamera()->getMode();
|
||||
_globalPosition = getPosition();
|
||||
_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
|
||||
glm::vec3 oldPosition = getPosition();
|
||||
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
|
||||
setPosition(oldPosition);
|
||||
return array;
|
||||
}
|
||||
return AvatarData::toByteArray(dataDetail, lastSentTime, lastSentJointData, distanceAdjust, viewerPosition);
|
||||
return AvatarData::toByteArray(dataDetail, lastSentTime, lastSentJointData, distanceAdjust, viewerPosition, sentJointDataOut);
|
||||
}
|
||||
|
||||
void MyAvatar::centerBody() {
|
||||
|
|
|
@ -333,8 +333,11 @@ private:
|
|||
|
||||
glm::vec3 getWorldBodyPosition() 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 updateFromTrackers(float deltaTime);
|
||||
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) {
|
||||
auto distance = glm::distance(_globalPosition, viewerPosition);
|
||||
//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) {
|
||||
result = AVATAR_MIN_ROTATION_DOT;
|
||||
} else if (distance < 5.0f) {
|
||||
result = ROTATION_15D_DOT;
|
||||
} else if (distance < 10.0f) {
|
||||
result = ROTATION_45D_DOT;
|
||||
} else if (distance < 20.0f) {
|
||||
result = ROTATION_90D_DOT;
|
||||
}
|
||||
//qDebug() << __FUNCTION__ << "result:" << result;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -213,8 +216,8 @@ float AvatarData::getDistanceBasedMinTranslationDistance(glm::vec3 viewerPositio
|
|||
}
|
||||
|
||||
|
||||
QByteArray AvatarData::toByteArray(AvatarDataDetail dataDetail, quint64 lastSentTime, QVector<JointData>& lastSentJointData,
|
||||
bool distanceAdjust, glm::vec3 viewerPosition) {
|
||||
QByteArray AvatarData::toByteArray(AvatarDataDetail dataDetail, quint64 lastSentTime, const QVector<JointData>& lastSentJointData,
|
||||
bool distanceAdjust, glm::vec3 viewerPosition, QVector<JointData>* sentJointDataOut) {
|
||||
|
||||
// if no timestamp was included, then assume the avatarData is single instance
|
||||
// and is tracking its own last encoding time.
|
||||
|
@ -455,25 +458,43 @@ QByteArray AvatarData::toByteArray(AvatarDataDetail dataDetail, quint64 lastSent
|
|||
unsigned char* beforeRotations = destinationBuffer;
|
||||
#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);
|
||||
//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++) {
|
||||
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 ||
|
||||
!cullSmallChanges ||
|
||||
fabsf(glm::dot(data.rotation, lastSentJointData[i].rotation)) > minRotationDOT) {
|
||||
if (sendAll || !cullSmallChanges || largeEnoughRotation) {
|
||||
if (data.rotationSet) {
|
||||
validity |= (1 << validityBit);
|
||||
#if 1 //def WANT_DEBUG
|
||||
rotationSentCount++;
|
||||
#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.y), 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);
|
||||
}
|
||||
|
||||
// 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) {
|
||||
// The server has finished sending this version of the joint-data to other nodes. Update _lastSentJointData.
|
||||
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.
|
||||
// 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;
|
||||
QVector<JointData>& lastSentJointData = _lastSentJointData;
|
||||
QVector<JointData> lastSentJointData;
|
||||
{
|
||||
QReadLocker readLock(&_jointDataLock);
|
||||
lastSentJointData = _lastSentJointData;
|
||||
}
|
||||
bool distanceAdjust = false;
|
||||
glm::vec3 viewerPosition(0);
|
||||
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;
|
||||
|
||||
|
|
|
@ -260,7 +260,8 @@ const float AVATAR_MIN_TRANSLATION = 0.0001f;
|
|||
|
||||
const float ROTATION_15D_DOT = 0.9914449f;
|
||||
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).
|
||||
// This is the start location in the Sandbox (xyz: 6270, 211, 6000).
|
||||
|
@ -350,8 +351,8 @@ public:
|
|||
SendAllData
|
||||
} AvatarDataDetail;
|
||||
|
||||
virtual QByteArray toByteArray(AvatarDataDetail dataDetail, quint64 lastSentTime, QVector<JointData>& lastSentJointData,
|
||||
bool distanceAdjust, glm::vec3 viewerPosition);
|
||||
virtual QByteArray toByteArray(AvatarDataDetail dataDetail, quint64 lastSentTime, const QVector<JointData>& lastSentJointData,
|
||||
bool distanceAdjust, glm::vec3 viewerPosition, QVector<JointData>* sentJointDataOut = nullptr);
|
||||
|
||||
virtual void doneEncoding(bool cullSmallChanges);
|
||||
|
||||
|
@ -531,7 +532,11 @@ public:
|
|||
|
||||
float getDataRate(const QString& rateName = QString(""));
|
||||
|
||||
QVector<JointData>& getLastSentJointData() { return _lastSentJointData; }
|
||||
QVector<JointData> getLastSentJointData() {
|
||||
QReadLocker readLock(&_jointDataLock);
|
||||
return _lastSentJointData;
|
||||
}
|
||||
|
||||
|
||||
public slots:
|
||||
void sendAvatarDataPacket();
|
||||
|
|
Loading…
Reference in a new issue