mirror of
https://github.com/overte-org/overte.git
synced 2025-08-09 15:49:24 +02:00
Merge pull request #12909 from hyperlogic/bug-fix/case-12628-rc66
RC66: Fix for avatar glitches, head and legs folding into chest.
This commit is contained in:
commit
ab4d328d4f
4 changed files with 39 additions and 8 deletions
|
@ -5940,6 +5940,9 @@ void Application::nodeActivated(SharedNodePointer node) {
|
||||||
}
|
}
|
||||||
getMyAvatar()->markIdentityDataChanged();
|
getMyAvatar()->markIdentityDataChanged();
|
||||||
getMyAvatar()->resetLastSent();
|
getMyAvatar()->resetLastSent();
|
||||||
|
|
||||||
|
// transmit a "sendAll" packet to the AvatarMixer we just connected to.
|
||||||
|
getMyAvatar()->sendAvatarDataPacket(true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -58,6 +58,13 @@ void SkeletonModel::initJointStates() {
|
||||||
glm::mat4 modelOffset = glm::scale(_scale) * glm::translate(_offset);
|
glm::mat4 modelOffset = glm::scale(_scale) * glm::translate(_offset);
|
||||||
_rig.initJointStates(geometry, modelOffset);
|
_rig.initJointStates(geometry, modelOffset);
|
||||||
|
|
||||||
|
{
|
||||||
|
// initialize _jointData with proper values for default joints
|
||||||
|
QVector<JointData> defaultJointData;
|
||||||
|
_rig.copyJointsIntoJointData(defaultJointData);
|
||||||
|
_owningAvatar->setRawJointData(defaultJointData);
|
||||||
|
}
|
||||||
|
|
||||||
// Determine the default eye position for avatar scale = 1.0
|
// Determine the default eye position for avatar scale = 1.0
|
||||||
int headJointIndex = geometry.headJointIndex;
|
int headJointIndex = geometry.headJointIndex;
|
||||||
if (0 > headJointIndex || headJointIndex >= _rig.getJointStateCount()) {
|
if (0 > headJointIndex || headJointIndex >= _rig.getJointStateCount()) {
|
||||||
|
|
|
@ -559,7 +559,8 @@ QByteArray AvatarData::toByteArray(AvatarDataDetail dataDetail, quint64 lastSent
|
||||||
const JointData& last = lastSentJointData[i];
|
const JointData& last = lastSentJointData[i];
|
||||||
|
|
||||||
if (!data.rotationIsDefaultPose) {
|
if (!data.rotationIsDefaultPose) {
|
||||||
if (sendAll || last.rotationIsDefaultPose || last.rotation != data.rotation) {
|
bool mustSend = sendAll || last.rotationIsDefaultPose;
|
||||||
|
if (mustSend || last.rotation != data.rotation) {
|
||||||
|
|
||||||
bool largeEnoughRotation = true;
|
bool largeEnoughRotation = true;
|
||||||
if (cullSmallChanges) {
|
if (cullSmallChanges) {
|
||||||
|
@ -568,7 +569,7 @@ QByteArray AvatarData::toByteArray(AvatarDataDetail dataDetail, quint64 lastSent
|
||||||
largeEnoughRotation = fabsf(glm::dot(last.rotation, data.rotation)) < minRotationDOT;
|
largeEnoughRotation = fabsf(glm::dot(last.rotation, data.rotation)) < minRotationDOT;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sendAll || !cullSmallChanges || largeEnoughRotation) {
|
if (mustSend || !cullSmallChanges || largeEnoughRotation) {
|
||||||
validity |= (1 << validityBit);
|
validity |= (1 << validityBit);
|
||||||
#ifdef WANT_DEBUG
|
#ifdef WANT_DEBUG
|
||||||
rotationSentCount++;
|
rotationSentCount++;
|
||||||
|
@ -608,10 +609,12 @@ QByteArray AvatarData::toByteArray(AvatarDataDetail dataDetail, quint64 lastSent
|
||||||
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];
|
||||||
|
const JointData& last = lastSentJointData[i];
|
||||||
|
|
||||||
if (!data.translationIsDefaultPose) {
|
if (!data.translationIsDefaultPose) {
|
||||||
if (sendAll || lastSentJointData[i].translation != data.translation) {
|
bool mustSend = sendAll || last.translationIsDefaultPose;
|
||||||
if (sendAll || !cullSmallChanges || glm::distance(data.translation, lastSentJointData[i].translation) > minTranslation) {
|
if (mustSend || last.translation != data.translation) {
|
||||||
|
if (mustSend || !cullSmallChanges || glm::distance(data.translation, lastSentJointData[i].translation) > minTranslation) {
|
||||||
validity |= (1 << validityBit);
|
validity |= (1 << validityBit);
|
||||||
#ifdef WANT_DEBUG
|
#ifdef WANT_DEBUG
|
||||||
translationSentCount++;
|
translationSentCount++;
|
||||||
|
@ -669,6 +672,19 @@ QByteArray AvatarData::toByteArray(AvatarDataDetail dataDetail, quint64 lastSent
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sentJointDataOut) {
|
if (sentJointDataOut) {
|
||||||
|
|
||||||
|
// Mark default poses in lastSentJointData, so when they become non-default we send them.
|
||||||
|
for (int i = 0; i < _jointData.size(); i++) {
|
||||||
|
const JointData& data = _jointData[i];
|
||||||
|
JointData& local = localSentJointDataOut[i];
|
||||||
|
if (data.rotationIsDefaultPose) {
|
||||||
|
local.rotationIsDefaultPose = true;
|
||||||
|
}
|
||||||
|
if (data.translationIsDefaultPose) {
|
||||||
|
local.translationIsDefaultPose = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Push new sent joint data to sentJointDataOut
|
// Push new sent joint data to sentJointDataOut
|
||||||
sentJointDataOut->swap(localSentJointDataOut);
|
sentJointDataOut->swap(localSentJointDataOut);
|
||||||
}
|
}
|
||||||
|
@ -1816,13 +1832,13 @@ void AvatarData::setJointMappingsFromNetworkReply() {
|
||||||
networkReply->deleteLater();
|
networkReply->deleteLater();
|
||||||
}
|
}
|
||||||
|
|
||||||
void AvatarData::sendAvatarDataPacket() {
|
void AvatarData::sendAvatarDataPacket(bool sendAll) {
|
||||||
auto nodeList = DependencyManager::get<NodeList>();
|
auto nodeList = DependencyManager::get<NodeList>();
|
||||||
|
|
||||||
// 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.
|
||||||
|
|
||||||
bool cullSmallData = (randFloat() < AVATAR_SEND_FULL_UPDATE_RATIO);
|
bool cullSmallData = !sendAll && (randFloat() < AVATAR_SEND_FULL_UPDATE_RATIO);
|
||||||
auto dataDetail = cullSmallData ? SendAllData : CullSmallData;
|
auto dataDetail = cullSmallData ? SendAllData : CullSmallData;
|
||||||
QByteArray avatarByteArray = toByteArrayStateful(dataDetail);
|
QByteArray avatarByteArray = toByteArrayStateful(dataDetail);
|
||||||
|
|
||||||
|
|
|
@ -256,6 +256,11 @@ namespace AvatarDataPacket {
|
||||||
SixByteQuat rotation[numValidRotations]; // encodeded and compressed by packOrientationQuatToSixBytes()
|
SixByteQuat rotation[numValidRotations]; // encodeded and compressed by packOrientationQuatToSixBytes()
|
||||||
uint8_t translationValidityBits[ceil(numJoints / 8)]; // one bit per joint, if true then a compressed translation follows.
|
uint8_t translationValidityBits[ceil(numJoints / 8)]; // one bit per joint, if true then a compressed translation follows.
|
||||||
SixByteTrans translation[numValidTranslations]; // encodeded and compressed by packFloatVec3ToSignedTwoByteFixed()
|
SixByteTrans translation[numValidTranslations]; // encodeded and compressed by packFloatVec3ToSignedTwoByteFixed()
|
||||||
|
|
||||||
|
SixByteQuat leftHandControllerRotation;
|
||||||
|
SixByteTrans leftHandControllerTranslation;
|
||||||
|
SixByteQuat rightHandControllerRotation;
|
||||||
|
SixByteTrans rightHandControllerTranslation;
|
||||||
};
|
};
|
||||||
*/
|
*/
|
||||||
size_t maxJointDataSize(size_t numJoints);
|
size_t maxJointDataSize(size_t numJoints);
|
||||||
|
@ -707,11 +712,11 @@ signals:
|
||||||
void sessionUUIDChanged();
|
void sessionUUIDChanged();
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void sendAvatarDataPacket();
|
void sendAvatarDataPacket(bool sendAll = false);
|
||||||
void sendIdentityPacket();
|
void sendIdentityPacket();
|
||||||
|
|
||||||
void setJointMappingsFromNetworkReply();
|
void setJointMappingsFromNetworkReply();
|
||||||
void setSessionUUID(const QUuid& sessionUUID) {
|
virtual void setSessionUUID(const QUuid& sessionUUID) {
|
||||||
if (sessionUUID != getID()) {
|
if (sessionUUID != getID()) {
|
||||||
if (sessionUUID == QUuid()) {
|
if (sessionUUID == QUuid()) {
|
||||||
setID(AVATAR_SELF_ID);
|
setID(AVATAR_SELF_ID);
|
||||||
|
|
Loading…
Reference in a new issue