mirror of
https://github.com/HifiExperiments/overte.git
synced 2025-07-24 09:54:19 +02:00
checkpoint for distance joints
This commit is contained in:
parent
c884b276e2
commit
c9c311e275
9 changed files with 82 additions and 17 deletions
|
@ -499,8 +499,14 @@ void Agent::processAgentAvatar() {
|
||||||
if (!_scriptEngine->isFinished() && _isAvatar) {
|
if (!_scriptEngine->isFinished() && _isAvatar) {
|
||||||
auto scriptedAvatar = DependencyManager::get<ScriptableAvatar>();
|
auto scriptedAvatar = DependencyManager::get<ScriptableAvatar>();
|
||||||
|
|
||||||
QByteArray avatarByteArray = scriptedAvatar->toByteArray((randFloat() < AVATAR_SEND_FULL_UPDATE_RATIO)
|
AvatarData::AvatarDataDetail dataDetail = (randFloat() < AVATAR_SEND_FULL_UPDATE_RATIO) ? AvatarData::SendAllData : AvatarData::CullSmallData;
|
||||||
? AvatarData::SendAllData : AvatarData::CullSmallData);
|
//AvatarData::AvatarDataDetail dataDetail = AvatarData::SendAllData;
|
||||||
|
quint64 lastSentTime = 0;
|
||||||
|
QVector<JointData>& lastSentJointData = scriptedAvatar->getLastSentJointData();
|
||||||
|
bool distanceAdjust = false;
|
||||||
|
glm::vec3 viewerPosition(0);
|
||||||
|
|
||||||
|
QByteArray avatarByteArray = scriptedAvatar->toByteArray(dataDetail, lastSentTime, lastSentJointData, distanceAdjust, viewerPosition);
|
||||||
scriptedAvatar->doneEncoding(true);
|
scriptedAvatar->doneEncoding(true);
|
||||||
|
|
||||||
static AvatarDataSequenceNumber sequenceNumber = 0;
|
static AvatarDataSequenceNumber sequenceNumber = 0;
|
||||||
|
|
|
@ -421,8 +421,11 @@ void AvatarMixer::broadcastAvatarData() {
|
||||||
}
|
}
|
||||||
|
|
||||||
numAvatarDataBytes += avatarPacketList->write(otherNode->getUUID().toRfc4122());
|
numAvatarDataBytes += avatarPacketList->write(otherNode->getUUID().toRfc4122());
|
||||||
quint64 lastEncodeForOther = nodeData->getLastOtherAvatarEncodeTime(otherNode->getUUID());
|
auto lastEncodeForOther = nodeData->getLastOtherAvatarEncodeTime(otherNode->getUUID());
|
||||||
auto bytes = otherAvatar.toByteArray(detail, lastEncodeForOther);
|
auto lastSentJointsForOther = nodeData->getLastOtherAvatarSentJoints(otherNode->getUUID());
|
||||||
|
bool distanceAdjust = true;
|
||||||
|
glm::vec3 viewerPosition = otherAvatar.getPosition();
|
||||||
|
auto bytes = otherAvatar.toByteArray(detail, lastEncodeForOther, lastSentJointsForOther, distanceAdjust, viewerPosition);
|
||||||
numAvatarDataBytes += avatarPacketList->write(bytes);
|
numAvatarDataBytes += avatarPacketList->write(bytes);
|
||||||
|
|
||||||
avatarPacketList->endSegment();
|
avatarPacketList->endSegment();
|
||||||
|
|
|
@ -113,6 +113,12 @@ public:
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QVector<JointData>& getLastOtherAvatarSentJoints(QUuid otherAvatar) {
|
||||||
|
return _lastOtherAvatarSentJoints[otherAvatar];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
AvatarSharedPointer _avatar { new AvatarData() };
|
AvatarSharedPointer _avatar { new AvatarData() };
|
||||||
|
|
||||||
|
@ -123,6 +129,7 @@ private:
|
||||||
// this is a map of the last time we encoded an "other" avatar for
|
// this is a map of the last time we encoded an "other" avatar for
|
||||||
// sending to "this" node
|
// sending to "this" node
|
||||||
std::unordered_map<QUuid, quint64> _lastOtherAvatarEncodeTime;
|
std::unordered_map<QUuid, quint64> _lastOtherAvatarEncodeTime;
|
||||||
|
std::unordered_map<QUuid, QVector<JointData>> _lastOtherAvatarSentJoints;
|
||||||
|
|
||||||
HRCTime _identityChangeTimestamp;
|
HRCTime _identityChangeTimestamp;
|
||||||
bool _gotIdentity { false };
|
bool _gotIdentity { false };
|
||||||
|
|
|
@ -14,6 +14,13 @@
|
||||||
#include <GLMHelpers.h>
|
#include <GLMHelpers.h>
|
||||||
#include "ScriptableAvatar.h"
|
#include "ScriptableAvatar.h"
|
||||||
|
|
||||||
|
QByteArray ScriptableAvatar::toByteArray(AvatarDataDetail dataDetail, quint64 lastSentTime, QVector<JointData>& lastSentJointData,
|
||||||
|
bool distanceAdjust, glm::vec3 viewerPosition) {
|
||||||
|
_globalPosition = getPosition();
|
||||||
|
return AvatarData::toByteArray(dataDetail, lastSentTime, lastSentJointData, distanceAdjust, viewerPosition);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// hold and priority unused but kept so that client side JS can run.
|
// hold and priority unused but kept so that client side JS can run.
|
||||||
void ScriptableAvatar::startAnimation(const QString& url, float fps, float priority,
|
void ScriptableAvatar::startAnimation(const QString& url, float fps, float priority,
|
||||||
bool loop, bool hold, float firstFrame, float lastFrame, const QStringList& maskedJoints) {
|
bool loop, bool hold, float firstFrame, float lastFrame, const QStringList& maskedJoints) {
|
||||||
|
|
|
@ -27,6 +27,10 @@ public:
|
||||||
Q_INVOKABLE void stopAnimation();
|
Q_INVOKABLE void stopAnimation();
|
||||||
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,
|
||||||
|
bool distanceAdjust, glm::vec3 viewerPosition) override;
|
||||||
|
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void update(float deltatime);
|
void update(float deltatime);
|
||||||
|
|
|
@ -226,7 +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) {
|
QByteArray MyAvatar::toByteArray(AvatarDataDetail dataDetail, quint64 lastSentTime, QVector<JointData>& lastSentJointData,
|
||||||
|
bool distanceAdjust, glm::vec3 viewerPosition) {
|
||||||
CameraMode mode = qApp->getCamera()->getMode();
|
CameraMode mode = qApp->getCamera()->getMode();
|
||||||
_globalPosition = getPosition();
|
_globalPosition = getPosition();
|
||||||
_globalBoundingBoxDimensions.x = _characterController.getCapsuleRadius();
|
_globalBoundingBoxDimensions.x = _characterController.getCapsuleRadius();
|
||||||
|
@ -237,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);
|
QByteArray array = AvatarData::toByteArray(dataDetail, lastSentTime, lastSentJointData, distanceAdjust, viewerPosition);
|
||||||
// copy the correct position back
|
// copy the correct position back
|
||||||
setPosition(oldPosition);
|
setPosition(oldPosition);
|
||||||
return array;
|
return array;
|
||||||
}
|
}
|
||||||
return AvatarData::toByteArray(dataDetail, lastSentTime);
|
return AvatarData::toByteArray(dataDetail, lastSentTime, lastSentJointData, distanceAdjust, viewerPosition);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MyAvatar::centerBody() {
|
void MyAvatar::centerBody() {
|
||||||
|
|
|
@ -333,7 +333,8 @@ private:
|
||||||
|
|
||||||
glm::vec3 getWorldBodyPosition() const;
|
glm::vec3 getWorldBodyPosition() const;
|
||||||
glm::quat getWorldBodyOrientation() const;
|
glm::quat getWorldBodyOrientation() const;
|
||||||
QByteArray toByteArray(AvatarDataDetail dataDetail, quint64 lastSentTime) override;
|
QByteArray toByteArray(AvatarDataDetail dataDetail, quint64 lastSentTime, QVector<JointData>& lastSentJointData,
|
||||||
|
bool distanceAdjust, glm::vec3 viewerPosition) 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;
|
||||||
|
|
|
@ -193,7 +193,17 @@ bool AvatarData::faceTrackerInfoChangedSince(quint64 time) {
|
||||||
return true; // FIXME!
|
return true; // FIXME!
|
||||||
}
|
}
|
||||||
|
|
||||||
QByteArray AvatarData::toByteArray(AvatarDataDetail dataDetail, quint64 lastSentTime) {
|
float AvatarData::getDistanceBasedMinRotationDOT(glm::vec3 viewerPosition) {
|
||||||
|
return AVATAR_MIN_ROTATION_DOT; // FIXME
|
||||||
|
}
|
||||||
|
|
||||||
|
float AvatarData::getDistanceBasedMinTranslationDistance(glm::vec3 viewerPosition) {
|
||||||
|
return AVATAR_MIN_TRANSLATION; // FIXME
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
QByteArray AvatarData::toByteArray(AvatarDataDetail dataDetail, quint64 lastSentTime, QVector<JointData>& lastSentJointData,
|
||||||
|
bool distanceAdjust, glm::vec3 viewerPosition) {
|
||||||
|
|
||||||
// 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.
|
||||||
|
@ -230,6 +240,8 @@ QByteArray AvatarData::toByteArray(AvatarDataDetail dataDetail, quint64 lastSent
|
||||||
// BUG -- if you enter a space bubble, and then back away, the avatar has wrong orientation until "send all" happens...
|
// BUG -- if you enter a space bubble, and then back away, the avatar has wrong orientation until "send all" happens...
|
||||||
// this is an iFrame issue... what to do about that?
|
// this is an iFrame issue... what to do about that?
|
||||||
//
|
//
|
||||||
|
// BUG -- Resizing avatar seems to "take too long"... the avatar doesn't redraw at smaller size right away
|
||||||
|
// BUG -- summoned avatars seem low?
|
||||||
//
|
//
|
||||||
|
|
||||||
// TODO -
|
// TODO -
|
||||||
|
@ -242,8 +254,15 @@ QByteArray AvatarData::toByteArray(AvatarDataDetail dataDetail, quint64 lastSent
|
||||||
// 63 rotations * 6 bytes = 136kbps
|
// 63 rotations * 6 bytes = 136kbps
|
||||||
// 3 translations * 6 bytes = 6.48kbps
|
// 3 translations * 6 bytes = 6.48kbps
|
||||||
//
|
//
|
||||||
|
// How we need to handle joints:
|
||||||
|
// 1) need to track "_lastSentJointData" for each "viewer" so it can't be a member variable of the
|
||||||
|
// AvatarData. instead it should be like lastSentTime where it's passed in. Store it in the node data
|
||||||
|
// and in AvatarMixer pass it accordingly
|
||||||
|
//
|
||||||
|
// 2) we also want to know the "distance" to the viewer to adjust the relative tolerance for changes and
|
||||||
|
// whether or not we actually want to do this distance adjust
|
||||||
|
//
|
||||||
|
|
||||||
auto localPosition = getLocalPosition();
|
|
||||||
auto parentID = getParentID();
|
auto parentID = getParentID();
|
||||||
|
|
||||||
bool hasAvatarGlobalPosition = true; // always include global position
|
bool hasAvatarGlobalPosition = true; // always include global position
|
||||||
|
@ -426,14 +445,16 @@ QByteArray AvatarData::toByteArray(AvatarDataDetail dataDetail, quint64 lastSent
|
||||||
unsigned char* beforeRotations = destinationBuffer;
|
unsigned char* beforeRotations = destinationBuffer;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
_lastSentJointData.resize(_jointData.size());
|
lastSentJointData.resize(_jointData.size());
|
||||||
|
|
||||||
|
float minRotationDOT = !distanceAdjust ? AVATAR_MIN_ROTATION_DOT : getDistanceBasedMinRotationDOT(viewerPosition);
|
||||||
|
|
||||||
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];
|
||||||
if (sendAll || _lastSentJointData[i].rotation != data.rotation) {
|
if (sendAll || lastSentJointData[i].rotation != data.rotation) {
|
||||||
if (sendAll ||
|
if (sendAll ||
|
||||||
!cullSmallChanges ||
|
!cullSmallChanges ||
|
||||||
fabsf(glm::dot(data.rotation, _lastSentJointData[i].rotation)) <= AVATAR_MIN_ROTATION_DOT) {
|
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
|
||||||
|
@ -475,13 +496,15 @@ QByteArray AvatarData::toByteArray(AvatarDataDetail dataDetail, quint64 lastSent
|
||||||
unsigned char* beforeTranslations = destinationBuffer;
|
unsigned char* beforeTranslations = destinationBuffer;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
float minTranslation = !distanceAdjust ? AVATAR_MIN_TRANSLATION : getDistanceBasedMinTranslationDistance(viewerPosition);
|
||||||
|
|
||||||
float maxTranslationDimension = 0.0;
|
float maxTranslationDimension = 0.0;
|
||||||
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];
|
||||||
if (sendAll || _lastSentJointData[i].translation != data.translation) {
|
if (sendAll || lastSentJointData[i].translation != data.translation) {
|
||||||
if (sendAll ||
|
if (sendAll ||
|
||||||
!cullSmallChanges ||
|
!cullSmallChanges ||
|
||||||
glm::distance(data.translation, _lastSentJointData[i].translation) > AVATAR_MIN_TRANSLATION) {
|
glm::distance(data.translation, lastSentJointData[i].translation) > minTranslation) {
|
||||||
if (data.translationSet) {
|
if (data.translationSet) {
|
||||||
validity |= (1 << validityBit);
|
validity |= (1 << validityBit);
|
||||||
#if 1 //def WANT_DEBUG
|
#if 1 //def WANT_DEBUG
|
||||||
|
@ -1508,7 +1531,13 @@ 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.
|
||||||
QByteArray avatarByteArray = toByteArray((randFloat() < AVATAR_SEND_FULL_UPDATE_RATIO) ? SendAllData : CullSmallData);
|
|
||||||
|
auto dataDetail = (randFloat() < AVATAR_SEND_FULL_UPDATE_RATIO) ? SendAllData : CullSmallData;
|
||||||
|
quint64 lastSentTime = 0;
|
||||||
|
QVector<JointData>& 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(true); // FIXME - doneEncoding() takes a bool for culling small changes, that's janky!
|
||||||
|
|
||||||
|
|
|
@ -347,7 +347,9 @@ public:
|
||||||
SendAllData
|
SendAllData
|
||||||
} AvatarDataDetail;
|
} AvatarDataDetail;
|
||||||
|
|
||||||
virtual QByteArray toByteArray(AvatarDataDetail dataDetail, quint64 lastSentTime = 0);
|
virtual QByteArray toByteArray(AvatarDataDetail dataDetail, quint64 lastSentTime, QVector<JointData>& lastSentJointData,
|
||||||
|
bool distanceAdjust, glm::vec3 viewerPosition);
|
||||||
|
|
||||||
virtual void doneEncoding(bool cullSmallChanges);
|
virtual void doneEncoding(bool cullSmallChanges);
|
||||||
|
|
||||||
/// \return true if an error should be logged
|
/// \return true if an error should be logged
|
||||||
|
@ -526,6 +528,8 @@ public:
|
||||||
|
|
||||||
float getDataRate(const QString& rateName = QString(""));
|
float getDataRate(const QString& rateName = QString(""));
|
||||||
|
|
||||||
|
QVector<JointData>& getLastSentJointData() { return _lastSentJointData; }
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void sendAvatarDataPacket();
|
void sendAvatarDataPacket();
|
||||||
void sendIdentityPacket();
|
void sendIdentityPacket();
|
||||||
|
@ -545,6 +549,9 @@ public slots:
|
||||||
protected:
|
protected:
|
||||||
void lazyInitHeadData();
|
void lazyInitHeadData();
|
||||||
|
|
||||||
|
float getDistanceBasedMinRotationDOT(glm::vec3 viewerPosition);
|
||||||
|
float getDistanceBasedMinTranslationDistance(glm::vec3 viewerPosition);
|
||||||
|
|
||||||
bool avatarBoundingBoxChangedSince(quint64 time);
|
bool avatarBoundingBoxChangedSince(quint64 time);
|
||||||
bool avatarScaleChangedSince(quint64 time);
|
bool avatarScaleChangedSince(quint64 time);
|
||||||
bool lookAtPositionChangedSince(quint64 time);
|
bool lookAtPositionChangedSince(quint64 time);
|
||||||
|
|
Loading…
Reference in a new issue