send AvatarEntities via raw data packet

This commit is contained in:
Andrew Meadows 2018-12-03 18:13:31 -08:00
parent 816de0d684
commit d3fea94540
5 changed files with 53 additions and 36 deletions

View file

@ -378,19 +378,22 @@ void Avatar::updateAvatarEntities() {
}
++dataItr;
// see EntityEditPacketSender::queueEditEntityMessage for the other end of this. unpack properties
// and either add or update the entity.
QJsonDocument jsonProperties = QJsonDocument::fromBinaryData(data);
if (!jsonProperties.isObject()) {
qCDebug(avatars_renderer) << "got bad avatarEntity json" << QString(data.toHex());
continue;
EntityItemProperties properties;
{
// create a temporary EntityItem to unpack the data
int32_t bytesLeftToRead = data.size();
unsigned char* dataAt = (unsigned char*)(data.data());
ReadBitstreamToTreeParams args;
EntityItemPointer tempEntity = EntityTypes::constructEntityItem(dataAt, bytesLeftToRead, args);
if (!tempEntity) {
continue;
}
tempEntity->readEntityDataFromBuffer(dataAt, bytesLeftToRead, args);
// extract the properties from tempEntity
properties = tempEntity->getProperties();
}
QVariant variantProperties = jsonProperties.toVariant();
QVariantMap asMap = variantProperties.toMap();
QScriptValue scriptProperties = variantMapToScriptValue(asMap, scriptEngine);
EntityItemProperties properties;
EntityItemPropertiesFromScriptValueIgnoreReadOnly(scriptProperties, properties);
properties.setEntityHostType(entity::HostType::AVATAR);
properties.setOwningAvatarID(getID());

View file

@ -54,27 +54,23 @@ void EntityEditPacketSender::queueEditAvatarEntityMessage(PacketType type,
return;
}
// the properties that get serialized into the avatar identity packet should be the entire set
// serialize ALL properties in an "AvatarEntity" packet
// rather than just the ones being edited.
EntityItemProperties entityProperties = entity->getProperties();
entityProperties.merge(properties);
std::lock_guard<std::mutex> lock(_mutex);
QScriptValue scriptProperties = EntityItemNonDefaultPropertiesToScriptValue(&_scriptEngine, entityProperties);
QVariant variantProperties = scriptProperties.toVariant();
QJsonDocument jsonProperties = QJsonDocument::fromVariant(variantProperties);
OctreePacketData packetData(false, AvatarTraits::MAXIMUM_TRAIT_SIZE);
EncodeBitstreamParams params;
EntityTreeElementExtraEncodeDataPointer extra { nullptr };
OctreeElement::AppendState appendState = entity->appendEntityData(&packetData, params, extra);
// the ID of the parent/avatar changes from session to session. use a special UUID to indicate the avatar
QJsonObject jsonObject = jsonProperties.object();
if (jsonObject.contains("parentID")) {
if (QUuid(jsonObject["parentID"].toString()) == _myAvatar->getID()) {
jsonObject["parentID"] = AVATAR_SELF_ID.toString();
}
if (appendState != OctreeElement::COMPLETED) {
// this entity is too big
return;
}
jsonProperties = QJsonDocument(jsonObject);
QByteArray binaryProperties = jsonProperties.toBinaryData();
_myAvatar->updateAvatarEntity(entityItemID, binaryProperties);
packetData.shrinkByteArrays();
_myAvatar->updateAvatarEntity(entityItemID, packetData.getUncompressedByteArray());
entity->setLastBroadcast(usecTimestampNow());
}

View file

@ -179,6 +179,11 @@ OctreeElement::AppendState EntityItem::appendEntityData(OctreePacketData* packet
EntityPropertyFlags propertyFlags(PROP_LAST_ITEM);
EntityPropertyFlags requestedProperties = getEntityProperties(params);
// the values of these two properties are known to the receiver by context
// therefore they don't need to be packed
requestedProperties -= PROP_ENTITY_HOST_TYPE;
requestedProperties -= PROP_OWNING_AVATAR_ID;
// If we are being called for a subsequent pass at appendEntityData() that failed to completely encode this item,
// then our entityTreeElementExtraEncodeData should include data about which properties we need to append.
if (entityTreeElementExtraEncodeData && entityTreeElementExtraEncodeData->entities.contains(getEntityItemID())) {

View file

@ -38,7 +38,11 @@ void OctreePacketData::changeSettings(bool enableCompression, unsigned int targe
_enableCompression = enableCompression;
_targetSize = targetSize;
_uncompressedByteArray.resize(_targetSize);
_compressedByteArray.resize(_targetSize);
if (_enableCompression) {
_compressedByteArray.resize(_targetSize);
} else {
_compressedByteArray.resize(0);
}
_uncompressed = (unsigned char*)_uncompressedByteArray.data();
_compressed = (unsigned char*)_compressedByteArray.data();
@ -586,13 +590,10 @@ bool OctreePacketData::appendRawData(QByteArray data) {
AtomicUIntStat OctreePacketData::_compressContentTime { 0 };
AtomicUIntStat OctreePacketData::_compressContentCalls { 0 };
bool OctreePacketData::compressContent() {
bool OctreePacketData::compressContent() {
PerformanceWarning warn(false, "OctreePacketData::compressContent()", false, &_compressContentTime, &_compressContentCalls);
// without compression, we always pass...
if (!_enableCompression) {
return true;
}
assert(_dirty);
assert(_enableCompression);
_bytesInUseLastCheck = _bytesInUse;
@ -605,13 +606,13 @@ bool OctreePacketData::compressContent() {
QByteArray compressedData = qCompress(uncompressedData, uncompressedSize, MAX_COMPRESSION);
if (compressedData.size() < (int)MAX_OCTREE_PACKET_DATA_SIZE) {
if (compressedData.size() < _compressedByteArray.size()) {
_compressedBytes = compressedData.size();
memcpy(_compressed, compressedData.constData(), _compressedBytes);
_dirty = false;
success = true;
} else {
qCWarning(octree) << "OctreePacketData::compressContent -- compressedData.size >= MAX_OCTREE_PACKET_DATA_SIZE";
qCWarning(octree) << "OctreePacketData::compressContent -- compressedData.size >= " << _compressedByteArray.size();
assert(false);
}
return success;
@ -644,8 +645,7 @@ void OctreePacketData::loadFinalizedContent(const unsigned char* data, int lengt
memcpy(_uncompressed, uncompressedData.constData(), _bytesInUse);
} else {
memcpy(_uncompressed, data, length);
memcpy(_compressed, data, length);
_bytesInUse = _compressedBytes = length;
_bytesInUse = length;
}
} else {
if (_debug) {
@ -654,6 +654,15 @@ void OctreePacketData::loadFinalizedContent(const unsigned char* data, int lengt
}
}
void OctreePacketData::shrinkByteArrays() {
_uncompressedByteArray.resize(_bytesInUse);
_compressedByteArray.resize(_compressedBytes);
// if you call this method then you are expected to be done packing to raw pointers
// and you just want the ByteArrays
// therefore we reset
reset();
}
void OctreePacketData::debugContent() {
qCDebug(octree, "OctreePacketData::debugContent()... COMPRESSED DATA.... size=%d",_compressedBytes);
int perline=0;

View file

@ -220,6 +220,8 @@ public:
/// get pointer to the uncompressed stream buffer at the byteOffset
const unsigned char* getUncompressedData(int byteOffset = 0) { return &_uncompressed[byteOffset]; }
const QByteArray& getUncompressedByteArray() { return _uncompressedByteArray; }
/// the size of the packet in uncompressed form
int getUncompressedSize() { return _bytesInUse; }
@ -243,6 +245,8 @@ public:
int getBytesAvailable() { return _bytesAvailable; }
void shrinkByteArrays();
/// displays contents for debugging
void debugContent();
void debugBytes();