checkpoint for distance joints

This commit is contained in:
ZappoMan 2017-01-15 11:47:48 -08:00
parent c884b276e2
commit c9c311e275
9 changed files with 82 additions and 17 deletions

View file

@ -499,8 +499,14 @@ void Agent::processAgentAvatar() {
if (!_scriptEngine->isFinished() && _isAvatar) {
auto scriptedAvatar = DependencyManager::get<ScriptableAvatar>();
QByteArray avatarByteArray = scriptedAvatar->toByteArray((randFloat() < AVATAR_SEND_FULL_UPDATE_RATIO)
? AvatarData::SendAllData : AvatarData::CullSmallData);
AvatarData::AvatarDataDetail dataDetail = (randFloat() < AVATAR_SEND_FULL_UPDATE_RATIO) ? 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);
static AvatarDataSequenceNumber sequenceNumber = 0;

View file

@ -421,8 +421,11 @@ void AvatarMixer::broadcastAvatarData() {
}
numAvatarDataBytes += avatarPacketList->write(otherNode->getUUID().toRfc4122());
quint64 lastEncodeForOther = nodeData->getLastOtherAvatarEncodeTime(otherNode->getUUID());
auto bytes = otherAvatar.toByteArray(detail, lastEncodeForOther);
auto lastEncodeForOther = nodeData->getLastOtherAvatarEncodeTime(otherNode->getUUID());
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);
avatarPacketList->endSegment();

View file

@ -113,6 +113,12 @@ public:
return result;
}
QVector<JointData>& getLastOtherAvatarSentJoints(QUuid otherAvatar) {
return _lastOtherAvatarSentJoints[otherAvatar];
}
private:
AvatarSharedPointer _avatar { new AvatarData() };
@ -123,6 +129,7 @@ private:
// this is a map of the last time we encoded an "other" avatar for
// sending to "this" node
std::unordered_map<QUuid, quint64> _lastOtherAvatarEncodeTime;
std::unordered_map<QUuid, QVector<JointData>> _lastOtherAvatarSentJoints;
HRCTime _identityChangeTimestamp;
bool _gotIdentity { false };

View file

@ -14,6 +14,13 @@
#include <GLMHelpers.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.
void ScriptableAvatar::startAnimation(const QString& url, float fps, float priority,
bool loop, bool hold, float firstFrame, float lastFrame, const QStringList& maskedJoints) {

View file

@ -27,6 +27,10 @@ public:
Q_INVOKABLE void stopAnimation();
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;
private slots:
void update(float deltatime);

View file

@ -226,7 +226,8 @@ void MyAvatar::simulateAttachments(float deltaTime) {
// 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();
_globalPosition = getPosition();
_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
glm::vec3 oldPosition = getPosition();
setPosition(getSkeletonPosition());
QByteArray array = AvatarData::toByteArray(dataDetail, lastSentTime);
QByteArray array = AvatarData::toByteArray(dataDetail, lastSentTime, lastSentJointData, distanceAdjust, viewerPosition);
// copy the correct position back
setPosition(oldPosition);
return array;
}
return AvatarData::toByteArray(dataDetail, lastSentTime);
return AvatarData::toByteArray(dataDetail, lastSentTime, lastSentJointData, distanceAdjust, viewerPosition);
}
void MyAvatar::centerBody() {

View file

@ -333,7 +333,8 @@ private:
glm::vec3 getWorldBodyPosition() 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 updateFromTrackers(float deltaTime);
virtual void render(RenderArgs* renderArgs, const glm::vec3& cameraPositio) override;

View file

@ -193,7 +193,17 @@ bool AvatarData::faceTrackerInfoChangedSince(quint64 time) {
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
// 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...
// 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 -
@ -242,8 +254,15 @@ QByteArray AvatarData::toByteArray(AvatarDataDetail dataDetail, quint64 lastSent
// 63 rotations * 6 bytes = 136kbps
// 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();
bool hasAvatarGlobalPosition = true; // always include global position
@ -426,14 +445,16 @@ QByteArray AvatarData::toByteArray(AvatarDataDetail dataDetail, quint64 lastSent
unsigned char* beforeRotations = destinationBuffer;
#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++) {
const JointData& data = _jointData[i];
if (sendAll || _lastSentJointData[i].rotation != data.rotation) {
if (sendAll || lastSentJointData[i].rotation != data.rotation) {
if (sendAll ||
!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) {
validity |= (1 << validityBit);
#if 1 //def WANT_DEBUG
@ -475,13 +496,15 @@ QByteArray AvatarData::toByteArray(AvatarDataDetail dataDetail, quint64 lastSent
unsigned char* beforeTranslations = destinationBuffer;
#endif
float minTranslation = !distanceAdjust ? AVATAR_MIN_TRANSLATION : getDistanceBasedMinTranslationDistance(viewerPosition);
float maxTranslationDimension = 0.0;
for (int i = 0; i < _jointData.size(); i++) {
const JointData& data = _jointData[i];
if (sendAll || _lastSentJointData[i].translation != data.translation) {
if (sendAll || lastSentJointData[i].translation != data.translation) {
if (sendAll ||
!cullSmallChanges ||
glm::distance(data.translation, _lastSentJointData[i].translation) > AVATAR_MIN_TRANSLATION) {
glm::distance(data.translation, lastSentJointData[i].translation) > minTranslation) {
if (data.translationSet) {
validity |= (1 << validityBit);
#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.
// 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!

View file

@ -347,7 +347,9 @@ public:
SendAllData
} 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);
/// \return true if an error should be logged
@ -526,6 +528,8 @@ public:
float getDataRate(const QString& rateName = QString(""));
QVector<JointData>& getLastSentJointData() { return _lastSentJointData; }
public slots:
void sendAvatarDataPacket();
void sendIdentityPacket();
@ -545,6 +549,9 @@ public slots:
protected:
void lazyInitHeadData();
float getDistanceBasedMinRotationDOT(glm::vec3 viewerPosition);
float getDistanceBasedMinTranslationDistance(glm::vec3 viewerPosition);
bool avatarBoundingBoxChangedSince(quint64 time);
bool avatarScaleChangedSince(quint64 time);
bool lookAtPositionChangedSince(quint64 time);