update packet creation in AvatarData to new API

This commit is contained in:
Stephen Birarda 2015-07-08 16:50:35 -07:00
parent 546268be55
commit 4d3659b627

View file

@ -87,7 +87,7 @@ glm::quat AvatarData::getOrientation() const {
if (_referential) { if (_referential) {
_referential->update(); _referential->update();
} }
return glm::quat(glm::radians(glm::vec3(_bodyPitch, _bodyYaw, _bodyRoll))); return glm::quat(glm::radians(glm::vec3(_bodyPitch, _bodyYaw, _bodyRoll)));
} }
@ -104,7 +104,7 @@ float AvatarData::getTargetScale() const {
if (_referential) { if (_referential) {
_referential->update(); _referential->update();
} }
return _targetScale; return _targetScale;
} }
@ -115,9 +115,9 @@ void AvatarData::setTargetScale(float targetScale, bool overideReferential) {
} }
void AvatarData::setClampedTargetScale(float targetScale, bool overideReferential) { void AvatarData::setClampedTargetScale(float targetScale, bool overideReferential) {
targetScale = glm::clamp(targetScale, MIN_AVATAR_SCALE, MAX_AVATAR_SCALE); targetScale = glm::clamp(targetScale, MIN_AVATAR_SCALE, MAX_AVATAR_SCALE);
setTargetScale(targetScale, overideReferential); setTargetScale(targetScale, overideReferential);
qCDebug(avatars) << "Changed scale to " << _targetScale; qCDebug(avatars) << "Changed scale to " << _targetScale;
} }
@ -135,7 +135,7 @@ QByteArray AvatarData::toByteArray() {
// TODO: DRY this up to a shared method // TODO: DRY this up to a shared method
// that can pack any type given the number of bytes // that can pack any type given the number of bytes
// and return the number of bytes to push the pointer // and return the number of bytes to push the pointer
// lazily allocate memory for HeadData in case we're not an Avatar instance // lazily allocate memory for HeadData in case we're not an Avatar instance
if (!_headData) { if (!_headData) {
_headData = new HeadData(this); _headData = new HeadData(this);
@ -143,21 +143,21 @@ QByteArray AvatarData::toByteArray() {
if (_forceFaceTrackerConnected) { if (_forceFaceTrackerConnected) {
_headData->_isFaceTrackerConnected = true; _headData->_isFaceTrackerConnected = true;
} }
QByteArray avatarDataByteArray; QByteArray avatarDataByteArray;
avatarDataByteArray.resize(MAX_PACKET_SIZE); avatarDataByteArray.resize(MAX_PACKET_SIZE);
unsigned char* destinationBuffer = reinterpret_cast<unsigned char*>(avatarDataByteArray.data()); unsigned char* destinationBuffer = reinterpret_cast<unsigned char*>(avatarDataByteArray.data());
unsigned char* startPosition = destinationBuffer; unsigned char* startPosition = destinationBuffer;
memcpy(destinationBuffer, &_position, sizeof(_position)); memcpy(destinationBuffer, &_position, sizeof(_position));
destinationBuffer += sizeof(_position); destinationBuffer += sizeof(_position);
// Body rotation (NOTE: This needs to become a quaternion to save two bytes) // Body rotation (NOTE: This needs to become a quaternion to save two bytes)
destinationBuffer += packFloatAngleToTwoByte(destinationBuffer, _bodyYaw); destinationBuffer += packFloatAngleToTwoByte(destinationBuffer, _bodyYaw);
destinationBuffer += packFloatAngleToTwoByte(destinationBuffer, _bodyPitch); destinationBuffer += packFloatAngleToTwoByte(destinationBuffer, _bodyPitch);
destinationBuffer += packFloatAngleToTwoByte(destinationBuffer, _bodyRoll); destinationBuffer += packFloatAngleToTwoByte(destinationBuffer, _bodyRoll);
// Body scale // Body scale
destinationBuffer += packFloatRatioToTwoByte(destinationBuffer, _targetScale); destinationBuffer += packFloatRatioToTwoByte(destinationBuffer, _targetScale);
@ -178,11 +178,11 @@ QByteArray AvatarData::toByteArray() {
// Lookat Position // Lookat Position
memcpy(destinationBuffer, &_headData->_lookAtPosition, sizeof(_headData->_lookAtPosition)); memcpy(destinationBuffer, &_headData->_lookAtPosition, sizeof(_headData->_lookAtPosition));
destinationBuffer += sizeof(_headData->_lookAtPosition); destinationBuffer += sizeof(_headData->_lookAtPosition);
// Instantaneous audio loudness (used to drive facial animation) // Instantaneous audio loudness (used to drive facial animation)
memcpy(destinationBuffer, &_headData->_audioLoudness, sizeof(float)); memcpy(destinationBuffer, &_headData->_audioLoudness, sizeof(float));
destinationBuffer += sizeof(float); destinationBuffer += sizeof(float);
// bitMask of less than byte wide items // bitMask of less than byte wide items
unsigned char bitItems = 0; unsigned char bitItems = 0;
@ -202,7 +202,7 @@ QByteArray AvatarData::toByteArray() {
setAtBit(bitItems, HAS_REFERENTIAL); setAtBit(bitItems, HAS_REFERENTIAL);
} }
*destinationBuffer++ = bitItems; *destinationBuffer++ = bitItems;
// Add referential // Add referential
if (_referential != NULL && _referential->isValid()) { if (_referential != NULL && _referential->isValid()) {
destinationBuffer += _referential->packReferential(destinationBuffer); destinationBuffer += _referential->packReferential(destinationBuffer);
@ -221,13 +221,13 @@ QByteArray AvatarData::toByteArray() {
memcpy(destinationBuffer, &_headData->_browAudioLift, sizeof(float)); memcpy(destinationBuffer, &_headData->_browAudioLift, sizeof(float));
destinationBuffer += sizeof(float); destinationBuffer += sizeof(float);
*destinationBuffer++ = _headData->_blendshapeCoefficients.size(); *destinationBuffer++ = _headData->_blendshapeCoefficients.size();
memcpy(destinationBuffer, _headData->_blendshapeCoefficients.data(), memcpy(destinationBuffer, _headData->_blendshapeCoefficients.data(),
_headData->_blendshapeCoefficients.size() * sizeof(float)); _headData->_blendshapeCoefficients.size() * sizeof(float));
destinationBuffer += _headData->_blendshapeCoefficients.size() * sizeof(float); destinationBuffer += _headData->_blendshapeCoefficients.size() * sizeof(float);
} }
// pupil dilation // pupil dilation
destinationBuffer += packFloatToByte(destinationBuffer, _headData->_pupilDilation, 1.0f); destinationBuffer += packFloatToByte(destinationBuffer, _headData->_pupilDilation, 1.0f);
@ -252,7 +252,7 @@ QByteArray AvatarData::toByteArray() {
destinationBuffer += packOrientationQuatToBytes(destinationBuffer, data.rotation); destinationBuffer += packOrientationQuatToBytes(destinationBuffer, data.rotation);
} }
} }
return avatarDataByteArray.left(destinationBuffer - startPosition); return avatarDataByteArray.left(destinationBuffer - startPosition);
} }
@ -266,17 +266,17 @@ bool AvatarData::shouldLogError(const quint64& now) {
// read data in packet starting at byte offset and return number of bytes parsed // read data in packet starting at byte offset and return number of bytes parsed
int AvatarData::parseDataAtOffset(const QByteArray& packet, int offset) { int AvatarData::parseDataAtOffset(const QByteArray& packet, int offset) {
// lazily allocate memory for HeadData in case we're not an Avatar instance // lazily allocate memory for HeadData in case we're not an Avatar instance
if (!_headData) { if (!_headData) {
_headData = new HeadData(this); _headData = new HeadData(this);
} }
// lazily allocate memory for HandData in case we're not an Avatar instance // lazily allocate memory for HandData in case we're not an Avatar instance
if (!_handData) { if (!_handData) {
_handData = new HandData(this); _handData = new HandData(this);
} }
const unsigned char* startPosition = reinterpret_cast<const unsigned char*>(packet.data()) + offset; const unsigned char* startPosition = reinterpret_cast<const unsigned char*>(packet.data()) + offset;
const unsigned char* sourceBuffer = startPosition; const unsigned char* sourceBuffer = startPosition;
quint64 now = usecTimestampNow(); quint64 now = usecTimestampNow();
@ -298,13 +298,13 @@ int AvatarData::parseDataAtOffset(const QByteArray& packet, int offset) {
// + 1 byte for numJoints (0) // + 1 byte for numJoints (0)
// = 45 bytes // = 45 bytes
int minPossibleSize = 45; int minPossibleSize = 45;
int maxAvailableSize = packet.size() - offset; int maxAvailableSize = packet.size() - offset;
if (minPossibleSize > maxAvailableSize) { if (minPossibleSize > maxAvailableSize) {
if (shouldLogError(now)) { if (shouldLogError(now)) {
qCDebug(avatars) << "Malformed AvatarData packet at the start; " qCDebug(avatars) << "Malformed AvatarData packet at the start; "
<< " displayName = '" << _displayName << "'" << " displayName = '" << _displayName << "'"
<< " minPossibleSize = " << minPossibleSize << " minPossibleSize = " << minPossibleSize
<< " maxAvailableSize = " << maxAvailableSize; << " maxAvailableSize = " << maxAvailableSize;
} }
// this packet is malformed so we report all bytes as consumed // this packet is malformed so we report all bytes as consumed
@ -316,7 +316,7 @@ int AvatarData::parseDataAtOffset(const QByteArray& packet, int offset) {
glm::vec3 position; glm::vec3 position;
memcpy(&position, sourceBuffer, sizeof(position)); memcpy(&position, sourceBuffer, sizeof(position));
sourceBuffer += sizeof(position); sourceBuffer += sizeof(position);
if (glm::isnan(position.x) || glm::isnan(position.y) || glm::isnan(position.z)) { if (glm::isnan(position.x) || glm::isnan(position.y) || glm::isnan(position.z)) {
if (shouldLogError(now)) { if (shouldLogError(now)) {
qCDebug(avatars) << "Discard nan AvatarData::position; displayName = '" << _displayName << "'"; qCDebug(avatars) << "Discard nan AvatarData::position; displayName = '" << _displayName << "'";
@ -324,7 +324,7 @@ int AvatarData::parseDataAtOffset(const QByteArray& packet, int offset) {
return maxAvailableSize; return maxAvailableSize;
} }
setPosition(position); setPosition(position);
// rotation (NOTE: This needs to become a quaternion to save two bytes) // rotation (NOTE: This needs to become a quaternion to save two bytes)
float yaw, pitch, roll; float yaw, pitch, roll;
sourceBuffer += unpackFloatAngleFromTwoByte((uint16_t*) sourceBuffer, &yaw); sourceBuffer += unpackFloatAngleFromTwoByte((uint16_t*) sourceBuffer, &yaw);
@ -342,7 +342,7 @@ int AvatarData::parseDataAtOffset(const QByteArray& packet, int offset) {
_bodyPitch = pitch; _bodyPitch = pitch;
_bodyRoll = roll; _bodyRoll = roll;
} }
// scale // scale
float scale; float scale;
sourceBuffer += unpackFloatRatioFromTwoByte(sourceBuffer, scale); sourceBuffer += unpackFloatRatioFromTwoByte(sourceBuffer, scale);
@ -354,8 +354,8 @@ int AvatarData::parseDataAtOffset(const QByteArray& packet, int offset) {
} }
_targetScale = scale; _targetScale = scale;
} // 20 bytes } // 20 bytes
{ // Head rotation { // Head rotation
//(NOTE: This needs to become a quaternion to save two bytes) //(NOTE: This needs to become a quaternion to save two bytes)
float headYaw, headPitch, headRoll; float headYaw, headPitch, headRoll;
sourceBuffer += unpackFloatAngleFromTwoByte((uint16_t*) sourceBuffer, &headPitch); sourceBuffer += unpackFloatAngleFromTwoByte((uint16_t*) sourceBuffer, &headPitch);
@ -371,7 +371,7 @@ int AvatarData::parseDataAtOffset(const QByteArray& packet, int offset) {
_headData->setBaseYaw(headYaw); _headData->setBaseYaw(headYaw);
_headData->setBaseRoll(headRoll); _headData->setBaseRoll(headRoll);
} // 6 bytes } // 6 bytes
{ // Lookat Position { // Lookat Position
glm::vec3 lookAt; glm::vec3 lookAt;
memcpy(&lookAt, sourceBuffer, sizeof(lookAt)); memcpy(&lookAt, sourceBuffer, sizeof(lookAt));
@ -384,7 +384,7 @@ int AvatarData::parseDataAtOffset(const QByteArray& packet, int offset) {
} }
_headData->_lookAtPosition = lookAt; _headData->_lookAtPosition = lookAt;
} // 12 bytes } // 12 bytes
{ // AudioLoudness { // AudioLoudness
// Instantaneous audio loudness (used to drive facial animation) // Instantaneous audio loudness (used to drive facial animation)
float audioLoudness; float audioLoudness;
@ -398,26 +398,26 @@ int AvatarData::parseDataAtOffset(const QByteArray& packet, int offset) {
} }
_headData->_audioLoudness = audioLoudness; _headData->_audioLoudness = audioLoudness;
} // 4 bytes } // 4 bytes
{ // bitFlags and face data { // bitFlags and face data
unsigned char bitItems = *sourceBuffer++; unsigned char bitItems = *sourceBuffer++;
// key state, stored as a semi-nibble in the bitItems // key state, stored as a semi-nibble in the bitItems
_keyState = (KeyState)getSemiNibbleAt(bitItems,KEY_STATE_START_BIT); _keyState = (KeyState)getSemiNibbleAt(bitItems,KEY_STATE_START_BIT);
// hand state, stored as a semi-nibble plus a bit in the bitItems // hand state, stored as a semi-nibble plus a bit in the bitItems
// we store the hand state as well as other items in a shared bitset. The hand state is an octal, but is split // we store the hand state as well as other items in a shared bitset. The hand state is an octal, but is split
// into two sections to maintain backward compatibility. The bits are ordered as such (0-7 left to right). // into two sections to maintain backward compatibility. The bits are ordered as such (0-7 left to right).
// +---+-----+-----+--+ // +---+-----+-----+--+
// |x,x|H0,H1|x,x,x|H2| // |x,x|H0,H1|x,x,x|H2|
// +---+-----+-----+--+ // +---+-----+-----+--+
// Hand state - H0,H1,H2 is found in the 3rd, 4th, and 8th bits // Hand state - H0,H1,H2 is found in the 3rd, 4th, and 8th bits
_handState = getSemiNibbleAt(bitItems, HAND_STATE_START_BIT) _handState = getSemiNibbleAt(bitItems, HAND_STATE_START_BIT)
+ (oneAtBit(bitItems, HAND_STATE_FINGER_POINTING_BIT) ? IS_FINGER_POINTING_FLAG : 0); + (oneAtBit(bitItems, HAND_STATE_FINGER_POINTING_BIT) ? IS_FINGER_POINTING_FLAG : 0);
_headData->_isFaceTrackerConnected = oneAtBit(bitItems, IS_FACESHIFT_CONNECTED); _headData->_isFaceTrackerConnected = oneAtBit(bitItems, IS_FACESHIFT_CONNECTED);
bool hasReferential = oneAtBit(bitItems, HAS_REFERENTIAL); bool hasReferential = oneAtBit(bitItems, HAS_REFERENTIAL);
// Referential // Referential
if (hasReferential) { if (hasReferential) {
Referential* ref = new Referential(sourceBuffer, this); Referential* ref = new Referential(sourceBuffer, this);
@ -431,8 +431,8 @@ int AvatarData::parseDataAtOffset(const QByteArray& packet, int offset) {
} else if (_referential != NULL) { } else if (_referential != NULL) {
changeReferential(NULL); changeReferential(NULL);
} }
if (_headData->_isFaceTrackerConnected) { if (_headData->_isFaceTrackerConnected) {
float leftEyeBlink, rightEyeBlink, averageLoudness, browAudioLift; float leftEyeBlink, rightEyeBlink, averageLoudness, browAudioLift;
minPossibleSize += sizeof(leftEyeBlink) + sizeof(rightEyeBlink) + sizeof(averageLoudness) + sizeof(browAudioLift); minPossibleSize += sizeof(leftEyeBlink) + sizeof(rightEyeBlink) + sizeof(averageLoudness) + sizeof(browAudioLift);
@ -441,7 +441,7 @@ int AvatarData::parseDataAtOffset(const QByteArray& packet, int offset) {
if (shouldLogError(now)) { if (shouldLogError(now)) {
qCDebug(avatars) << "Malformed AvatarData packet after BitItems;" qCDebug(avatars) << "Malformed AvatarData packet after BitItems;"
<< " displayName = '" << _displayName << "'" << " displayName = '" << _displayName << "'"
<< " minPossibleSize = " << minPossibleSize << " minPossibleSize = " << minPossibleSize
<< " maxAvailableSize = " << maxAvailableSize; << " maxAvailableSize = " << maxAvailableSize;
} }
return maxAvailableSize; return maxAvailableSize;
@ -449,17 +449,17 @@ int AvatarData::parseDataAtOffset(const QByteArray& packet, int offset) {
// unpack face data // unpack face data
memcpy(&leftEyeBlink, sourceBuffer, sizeof(float)); memcpy(&leftEyeBlink, sourceBuffer, sizeof(float));
sourceBuffer += sizeof(float); sourceBuffer += sizeof(float);
memcpy(&rightEyeBlink, sourceBuffer, sizeof(float)); memcpy(&rightEyeBlink, sourceBuffer, sizeof(float));
sourceBuffer += sizeof(float); sourceBuffer += sizeof(float);
memcpy(&averageLoudness, sourceBuffer, sizeof(float)); memcpy(&averageLoudness, sourceBuffer, sizeof(float));
sourceBuffer += sizeof(float); sourceBuffer += sizeof(float);
memcpy(&browAudioLift, sourceBuffer, sizeof(float)); memcpy(&browAudioLift, sourceBuffer, sizeof(float));
sourceBuffer += sizeof(float); sourceBuffer += sizeof(float);
if (glm::isnan(leftEyeBlink) || glm::isnan(rightEyeBlink) if (glm::isnan(leftEyeBlink) || glm::isnan(rightEyeBlink)
|| glm::isnan(averageLoudness) || glm::isnan(browAudioLift)) { || glm::isnan(averageLoudness) || glm::isnan(browAudioLift)) {
if (shouldLogError(now)) { if (shouldLogError(now)) {
qCDebug(avatars) << "Discard nan AvatarData::faceData; displayName = '" << _displayName << "'"; qCDebug(avatars) << "Discard nan AvatarData::faceData; displayName = '" << _displayName << "'";
@ -470,7 +470,7 @@ int AvatarData::parseDataAtOffset(const QByteArray& packet, int offset) {
_headData->_rightEyeBlink = rightEyeBlink; _headData->_rightEyeBlink = rightEyeBlink;
_headData->_averageLoudness = averageLoudness; _headData->_averageLoudness = averageLoudness;
_headData->_browAudioLift = browAudioLift; _headData->_browAudioLift = browAudioLift;
int numCoefficients = (int)(*sourceBuffer++); int numCoefficients = (int)(*sourceBuffer++);
int blendDataSize = numCoefficients * sizeof(float); int blendDataSize = numCoefficients * sizeof(float);
minPossibleSize += blendDataSize; minPossibleSize += blendDataSize;
@ -478,7 +478,7 @@ int AvatarData::parseDataAtOffset(const QByteArray& packet, int offset) {
if (shouldLogError(now)) { if (shouldLogError(now)) {
qCDebug(avatars) << "Malformed AvatarData packet after Blendshapes;" qCDebug(avatars) << "Malformed AvatarData packet after Blendshapes;"
<< " displayName = '" << _displayName << "'" << " displayName = '" << _displayName << "'"
<< " minPossibleSize = " << minPossibleSize << " minPossibleSize = " << minPossibleSize
<< " maxAvailableSize = " << maxAvailableSize; << " maxAvailableSize = " << maxAvailableSize;
} }
return maxAvailableSize; return maxAvailableSize;
@ -487,15 +487,15 @@ int AvatarData::parseDataAtOffset(const QByteArray& packet, int offset) {
_headData->_blendshapeCoefficients.resize(numCoefficients); _headData->_blendshapeCoefficients.resize(numCoefficients);
memcpy(_headData->_blendshapeCoefficients.data(), sourceBuffer, blendDataSize); memcpy(_headData->_blendshapeCoefficients.data(), sourceBuffer, blendDataSize);
sourceBuffer += numCoefficients * sizeof(float); sourceBuffer += numCoefficients * sizeof(float);
//bitItemsDataSize = 4 * sizeof(float) + 1 + blendDataSize; //bitItemsDataSize = 4 * sizeof(float) + 1 + blendDataSize;
} }
} // 1 + bitItemsDataSize bytes } // 1 + bitItemsDataSize bytes
{ // pupil dilation { // pupil dilation
sourceBuffer += unpackFloatFromByte(sourceBuffer, _headData->_pupilDilation, 1.0f); sourceBuffer += unpackFloatFromByte(sourceBuffer, _headData->_pupilDilation, 1.0f);
} // 1 byte } // 1 byte
// joint data // joint data
int numJoints = *sourceBuffer++; int numJoints = *sourceBuffer++;
int bytesOfValidity = (int)ceil((float)numJoints / (float)BITS_IN_BYTE); int bytesOfValidity = (int)ceil((float)numJoints / (float)BITS_IN_BYTE);
@ -504,7 +504,7 @@ int AvatarData::parseDataAtOffset(const QByteArray& packet, int offset) {
if (shouldLogError(now)) { if (shouldLogError(now)) {
qCDebug(avatars) << "Malformed AvatarData packet after JointValidityBits;" qCDebug(avatars) << "Malformed AvatarData packet after JointValidityBits;"
<< " displayName = '" << _displayName << "'" << " displayName = '" << _displayName << "'"
<< " minPossibleSize = " << minPossibleSize << " minPossibleSize = " << minPossibleSize
<< " maxAvailableSize = " << maxAvailableSize; << " maxAvailableSize = " << maxAvailableSize;
} }
return maxAvailableSize; return maxAvailableSize;
@ -523,7 +523,7 @@ int AvatarData::parseDataAtOffset(const QByteArray& packet, int offset) {
++numValidJoints; ++numValidJoints;
} }
_jointData[i].valid = valid; _jointData[i].valid = valid;
validityBit = (validityBit + 1) % BITS_IN_BYTE; validityBit = (validityBit + 1) % BITS_IN_BYTE;
} }
} }
// 1 + bytesOfValidity bytes // 1 + bytesOfValidity bytes
@ -535,7 +535,7 @@ int AvatarData::parseDataAtOffset(const QByteArray& packet, int offset) {
if (shouldLogError(now)) { if (shouldLogError(now)) {
qCDebug(avatars) << "Malformed AvatarData packet after JointData;" qCDebug(avatars) << "Malformed AvatarData packet after JointData;"
<< " displayName = '" << _displayName << "'" << " displayName = '" << _displayName << "'"
<< " minPossibleSize = " << minPossibleSize << " minPossibleSize = " << minPossibleSize
<< " maxAvailableSize = " << maxAvailableSize; << " maxAvailableSize = " << maxAvailableSize;
} }
return maxAvailableSize; return maxAvailableSize;
@ -550,18 +550,18 @@ int AvatarData::parseDataAtOffset(const QByteArray& packet, int offset) {
} }
} }
} // numJoints * 8 bytes } // numJoints * 8 bytes
int numBytesRead = sourceBuffer - startPosition; int numBytesRead = sourceBuffer - startPosition;
_averageBytesReceived.updateAverage(numBytesRead); _averageBytesReceived.updateAverage(numBytesRead);
return numBytesRead; return numBytesRead;
} }
int AvatarData::getAverageBytesReceivedPerSecond() const { int AvatarData::getAverageBytesReceivedPerSecond() const {
return lrint(_averageBytesReceived.getAverageSampleValuePerSecond()); return lrint(_averageBytesReceived.getAverageSampleValuePerSecond());
} }
int AvatarData::getReceiveRate() const { int AvatarData::getReceiveRate() const {
return lrint(1.0f / _averageBytesReceived.getEventDeltaAverage()); return lrint(1.0f / _averageBytesReceived.getEventDeltaAverage());
} }
bool AvatarData::hasReferential() { bool AvatarData::hasReferential() {
@ -619,7 +619,7 @@ void AvatarData::loadRecording(QString filename) {
if (!_player) { if (!_player) {
_player = PlayerPointer(new Player(this)); _player = PlayerPointer(new Player(this));
} }
_player->loadFromFile(filename); _player->loadFromFile(filename);
} }
@ -700,7 +700,7 @@ void AvatarData::play() {
QMetaObject::invokeMethod(this, "play", Qt::BlockingQueuedConnection); QMetaObject::invokeMethod(this, "play", Qt::BlockingQueuedConnection);
return; return;
} }
_player->play(); _player->play();
} }
} }
@ -870,20 +870,20 @@ void AvatarData::clearJointsData() {
bool AvatarData::hasIdentityChangedAfterParsing(const QByteArray &packet) { bool AvatarData::hasIdentityChangedAfterParsing(const QByteArray &packet) {
QDataStream packetStream(packet); QDataStream packetStream(packet);
packetStream.skipRawData(numBytesForPacketHeader(packet)); packetStream.skipRawData(numBytesForPacketHeader(packet));
QUuid avatarUUID; QUuid avatarUUID;
QUrl faceModelURL, skeletonModelURL; QUrl faceModelURL, skeletonModelURL;
QVector<AttachmentData> attachmentData; QVector<AttachmentData> attachmentData;
QString displayName; QString displayName;
packetStream >> avatarUUID >> faceModelURL >> skeletonModelURL >> attachmentData >> displayName; packetStream >> avatarUUID >> faceModelURL >> skeletonModelURL >> attachmentData >> displayName;
bool hasIdentityChanged = false; bool hasIdentityChanged = false;
if (faceModelURL != _faceModelURL) { if (faceModelURL != _faceModelURL) {
setFaceModelURL(faceModelURL); setFaceModelURL(faceModelURL);
hasIdentityChanged = true; hasIdentityChanged = true;
} }
if (skeletonModelURL != _skeletonModelURL) { if (skeletonModelURL != _skeletonModelURL) {
setSkeletonModelURL(skeletonModelURL); setSkeletonModelURL(skeletonModelURL);
hasIdentityChanged = true; hasIdentityChanged = true;
@ -893,12 +893,12 @@ bool AvatarData::hasIdentityChangedAfterParsing(const QByteArray &packet) {
setDisplayName(displayName); setDisplayName(displayName);
hasIdentityChanged = true; hasIdentityChanged = true;
} }
if (attachmentData != _attachmentData) { if (attachmentData != _attachmentData) {
setAttachmentData(attachmentData); setAttachmentData(attachmentData);
hasIdentityChanged = true; hasIdentityChanged = true;
} }
return hasIdentityChanged; return hasIdentityChanged;
} }
@ -907,7 +907,7 @@ QByteArray AvatarData::identityByteArray() {
QDataStream identityStream(&identityData, QIODevice::Append); QDataStream identityStream(&identityData, QIODevice::Append);
identityStream << QUuid() << _faceModelURL << _skeletonModelURL << _attachmentData << _displayName; identityStream << QUuid() << _faceModelURL << _skeletonModelURL << _attachmentData << _displayName;
return identityData; return identityData;
} }
@ -922,15 +922,15 @@ bool AvatarData::hasBillboardChangedAfterParsing(const QByteArray& packet) {
void AvatarData::setFaceModelURL(const QUrl& faceModelURL) { void AvatarData::setFaceModelURL(const QUrl& faceModelURL) {
_faceModelURL = faceModelURL; _faceModelURL = faceModelURL;
qCDebug(avatars) << "Changing face model for avatar to" << _faceModelURL.toString(); qCDebug(avatars) << "Changing face model for avatar to" << _faceModelURL.toString();
} }
void AvatarData::setSkeletonModelURL(const QUrl& skeletonModelURL) { void AvatarData::setSkeletonModelURL(const QUrl& skeletonModelURL) {
_skeletonModelURL = skeletonModelURL.isEmpty() ? DEFAULT_BODY_MODEL_URL : skeletonModelURL; _skeletonModelURL = skeletonModelURL.isEmpty() ? DEFAULT_BODY_MODEL_URL : skeletonModelURL;
qCDebug(avatars) << "Changing skeleton model for avatar to" << _skeletonModelURL.toString(); qCDebug(avatars) << "Changing skeleton model for avatar to" << _skeletonModelURL.toString();
updateJointMappings(); updateJointMappings();
} }
@ -1017,20 +1017,20 @@ void AvatarData::detachAll(const QString& modelURL, const QString& jointName) {
void AvatarData::setBillboard(const QByteArray& billboard) { void AvatarData::setBillboard(const QByteArray& billboard) {
_billboard = billboard; _billboard = billboard;
qCDebug(avatars) << "Changing billboard for avatar."; qCDebug(avatars) << "Changing billboard for avatar.";
} }
void AvatarData::setBillboardFromURL(const QString &billboardURL) { void AvatarData::setBillboardFromURL(const QString &billboardURL) {
_billboardURL = billboardURL; _billboardURL = billboardURL;
qCDebug(avatars) << "Changing billboard for avatar to PNG at" << qPrintable(billboardURL); qCDebug(avatars) << "Changing billboard for avatar to PNG at" << qPrintable(billboardURL);
QNetworkRequest billboardRequest; QNetworkRequest billboardRequest;
billboardRequest.setHeader(QNetworkRequest::UserAgentHeader, HIGH_FIDELITY_USER_AGENT); billboardRequest.setHeader(QNetworkRequest::UserAgentHeader, HIGH_FIDELITY_USER_AGENT);
billboardRequest.setUrl(QUrl(billboardURL)); billboardRequest.setUrl(QUrl(billboardURL));
QNetworkAccessManager& networkAccessManager = NetworkAccessManager::getInstance(); QNetworkAccessManager& networkAccessManager = NetworkAccessManager::getInstance();
QNetworkReply* networkReply = networkAccessManager.get(billboardRequest); QNetworkReply* networkReply = networkAccessManager.get(billboardRequest);
connect(networkReply, SIGNAL(finished()), this, SLOT(setBillboardFromNetworkReply())); connect(networkReply, SIGNAL(finished()), this, SLOT(setBillboardFromNetworkReply()));
@ -1044,7 +1044,7 @@ void AvatarData::setBillboardFromNetworkReply() {
void AvatarData::setJointMappingsFromNetworkReply() { void AvatarData::setJointMappingsFromNetworkReply() {
QNetworkReply* networkReply = static_cast<QNetworkReply*>(sender()); QNetworkReply* networkReply = static_cast<QNetworkReply*>(sender());
QByteArray line; QByteArray line;
while (!(line = networkReply->readLine()).isEmpty()) { while (!(line = networkReply->readLine()).isEmpty()) {
if (!(line = line.trimmed()).startsWith("jointIndex")) { if (!(line = line.trimmed()).startsWith("jointIndex")) {
@ -1071,43 +1071,47 @@ void AvatarData::setJointMappingsFromNetworkReply() {
for (int i = 0; i < _jointNames.size(); i++) { for (int i = 0; i < _jointNames.size(); i++) {
_jointIndices.insert(_jointNames.at(i), i + 1); _jointIndices.insert(_jointNames.at(i), i + 1);
} }
networkReply->deleteLater(); networkReply->deleteLater();
} }
void AvatarData::sendAvatarDataPacket() { void AvatarData::sendAvatarDataPacket() {
auto nodeList = DependencyManager::get<NodeList>(); auto nodeList = DependencyManager::get<NodeList>();
QByteArray dataPacket = nodeList->byteArrayWithPopulatedHeader(PacketType::AvatarData); QByteArray avatarByteArray = toByteArray();
dataPacket.append(toByteArray());
auto avatarPacket = NLPacket::create(PacketType::AvatarData, avatarByteArray.size());
nodeList->broadcastToNodes(dataPacket, NodeSet() << NodeType::AvatarMixer); avatarPacket->write(avatarByteArray);
nodeList->broadcastToNodes(std::move(avatarPacket), NodeSet() << NodeType::AvatarMixer);
} }
void AvatarData::sendIdentityPacket() { void AvatarData::sendIdentityPacket() {
auto nodeList = DependencyManager::get<NodeList>(); auto nodeList = DependencyManager::get<NodeList>();
QByteArray identityPacket = nodeList->byteArrayWithPopulatedHeader(PacketType::AvatarIdentity); QByteArray identityByteArray = identityByteArray();
identityPacket.append(identityByteArray());
auto identityPacket = NLPacket::create(PacketType::AvatarIdentity, identityByteArray.size());
nodeList->broadcastToNodes(identityPacket, NodeSet() << NodeType::AvatarMixer); identityPacket->write(identityByteArray);
nodeList->broadcastToNodes(std::move(identityPacket), NodeSet() << NodeType::AvatarMixer);
} }
void AvatarData::sendBillboardPacket() { void AvatarData::sendBillboardPacket() {
if (!_billboard.isEmpty()) { if (!_billboard.isEmpty()) {
auto nodeList = DependencyManager::get<NodeList>(); auto nodeList = DependencyManager::get<NodeList>();
QByteArray billboardPacket = nodeList->byteArrayWithPopulatedHeader(PacketType::AvatarBillboard); auto billboardPacket = NLPacket::create(PacketType::AvatarBillboard, _billboard.size());
billboardPacket.append(_billboard); billboardPacket->write(_billboard);
nodeList->broadcastToNodes(billboardPacket, NodeSet() << NodeType::AvatarMixer); nodeList->broadcastToNodes(std::move(billboardPacket), NodeSet() << NodeType::AvatarMixer);
} }
} }
void AvatarData::updateJointMappings() { void AvatarData::updateJointMappings() {
_jointIndices.clear(); _jointIndices.clear();
_jointNames.clear(); _jointNames.clear();
if (_skeletonModelURL.fileName().toLower().endsWith(".fst")) { if (_skeletonModelURL.fileName().toLower().endsWith(".fst")) {
QNetworkAccessManager& networkAccessManager = NetworkAccessManager::getInstance(); QNetworkAccessManager& networkAccessManager = NetworkAccessManager::getInstance();
QNetworkRequest networkRequest = QNetworkRequest(_skeletonModelURL); QNetworkRequest networkRequest = QNetworkRequest(_skeletonModelURL);