diff --git a/assignment-client/src/avatars/ScriptableAvatar.h b/assignment-client/src/avatars/ScriptableAvatar.h index c08b7e2336..3eae702257 100644 --- a/assignment-client/src/avatars/ScriptableAvatar.h +++ b/assignment-client/src/avatars/ScriptableAvatar.h @@ -173,7 +173,7 @@ public: * Gets details of all avatar entities. *

Warning: Potentially an expensive call. Do not use if possible.

* @function Avatar.getAvatarEntityData - * @returns {AvatarEntityMap} Details of the avatar entities. + * @returns {AvatarEntityMap} Details of all avatar entities. * @example Report the current avatar entities. * var avatarEntityData = Avatar.getAvatarEntityData(); * print("Avatar entities: " + JSON.stringify(avatarEntityData)); diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp index 4287062094..fe4980c873 100644 --- a/interface/src/avatar/MyAvatar.cpp +++ b/interface/src/avatar/MyAvatar.cpp @@ -1810,6 +1810,46 @@ void MyAvatar::prepareAvatarEntityDataForReload() { _reloadAvatarEntityDataFromSettings = true; } +AvatarEntityMap MyAvatar::getAvatarEntityData() const { + // NOTE: the return value is expected to be a map of unfortunately-formatted-binary-blobs + AvatarEntityMap data; + + auto treeRenderer = DependencyManager::get(); + EntityTreePointer entityTree = treeRenderer ? treeRenderer->getTree() : nullptr; + if (!entityTree) { + return data; + } + + QList avatarEntityIDs; + _avatarEntitiesLock.withReadLock([&] { + avatarEntityIDs = _packedAvatarEntityData.keys(); + }); + for (const auto& entityID : avatarEntityIDs) { + auto entity = entityTree->findEntityByID(entityID); + if (!entity) { + continue; + } + + EncodeBitstreamParams params; + auto desiredProperties = entity->getEntityProperties(params); + desiredProperties += PROP_LOCAL_POSITION; + desiredProperties += PROP_LOCAL_ROTATION; + desiredProperties += PROP_LOCAL_VELOCITY; + desiredProperties += PROP_LOCAL_ANGULAR_VELOCITY; + desiredProperties += PROP_LOCAL_DIMENSIONS; + EntityItemProperties properties = entity->getProperties(desiredProperties); + + QByteArray blob; + { + std::lock_guard guard(_scriptEngineLock); + EntityItemProperties::propertiesToBlob(*_scriptEngine, getID(), properties, blob, true); + } + + data[entityID] = blob; + } + return data; +} + AvatarEntityMap MyAvatar::getAvatarEntityDataNonDefault() const { // NOTE: the return value is expected to be a map of unfortunately-formatted-binary-blobs updateStaleAvatarEntityBlobs(); diff --git a/interface/src/avatar/MyAvatar.h b/interface/src/avatar/MyAvatar.h index 2e87f5ef94..e806fe9b3f 100644 --- a/interface/src/avatar/MyAvatar.h +++ b/interface/src/avatar/MyAvatar.h @@ -1856,11 +1856,12 @@ public: /**jsdoc * Gets details of all avatar entities. * @function MyAvatar.getAvatarEntityData - * @returns {AvatarEntityMap} Details of the avatar entities. + * @returns {AvatarEntityMap} Details of all avatar entities. * @example Report the current avatar entities. * var avatarEntityData = MyAvatar.getAvatarEntityData(); * print("Avatar entities: " + JSON.stringify(avatarEntityData)); */ + AvatarEntityMap getAvatarEntityData() const override; AvatarEntityMap getAvatarEntityDataNonDefault() const override; diff --git a/libraries/avatars/src/AvatarData.cpp b/libraries/avatars/src/AvatarData.cpp index 0b7ea76f3f..adb7222ee3 100755 --- a/libraries/avatars/src/AvatarData.cpp +++ b/libraries/avatars/src/AvatarData.cpp @@ -3046,6 +3046,12 @@ void AvatarData::clearAvatarEntity(const QUuid& entityID, bool requiresRemovalFr } } +AvatarEntityMap AvatarData::getAvatarEntityData() const { + // overridden where needed + // NOTE: the return value is expected to be a map of unfortunately-formatted-binary-blobs + return AvatarEntityMap(); +} + AvatarEntityMap AvatarData::getAvatarEntityDataNonDefault() const { // overridden where needed // NOTE: the return value is expected to be a map of unfortunately-formatted-binary-blobs diff --git a/libraries/avatars/src/AvatarData.h b/libraries/avatars/src/AvatarData.h index 5b4e959d03..981882bf98 100755 --- a/libraries/avatars/src/AvatarData.h +++ b/libraries/avatars/src/AvatarData.h @@ -1390,6 +1390,8 @@ public: /**jsdoc * @comment Documented in derived classes' JSDoc because implementations are different. */ + // Get avatar entity data with all property values. Used in API. + Q_INVOKABLE virtual AvatarEntityMap getAvatarEntityData() const; // Get avatar entity data with non-default property values. Used internally. virtual AvatarEntityMap getAvatarEntityDataNonDefault() const; diff --git a/libraries/entities/src/EntityItemProperties.cpp b/libraries/entities/src/EntityItemProperties.cpp index 319dfc922f..79dc62ce56 100644 --- a/libraries/entities/src/EntityItemProperties.cpp +++ b/libraries/entities/src/EntityItemProperties.cpp @@ -5097,10 +5097,13 @@ bool EntityItemProperties::blobToProperties(QScriptEngine& scriptEngine, const Q return true; } -void EntityItemProperties::propertiesToBlob(QScriptEngine& scriptEngine, const QUuid& myAvatarID, const EntityItemProperties& properties, QByteArray& blob) { +void EntityItemProperties::propertiesToBlob(QScriptEngine& scriptEngine, const QUuid& myAvatarID, + const EntityItemProperties& properties, QByteArray& blob, bool allProperties) { // DANGER: this method is NOT efficient. // begin recipe for extracting unfortunately-formatted-binary-blob from EntityItem - QScriptValue scriptValue = EntityItemNonDefaultPropertiesToScriptValue(&scriptEngine, properties); + QScriptValue scriptValue = allProperties + ? EntityItemPropertiesToScriptValue(&scriptEngine, properties) + : EntityItemNonDefaultPropertiesToScriptValue(&scriptEngine, properties); QVariant variantProperties = scriptValue.toVariant(); QJsonDocument jsonProperties = QJsonDocument::fromVariant(variantProperties); // the ID of the parent/avatar changes from session to session. use a special UUID to indicate the avatar diff --git a/libraries/entities/src/EntityItemProperties.h b/libraries/entities/src/EntityItemProperties.h index 63d8183899..166b3ba7e8 100644 --- a/libraries/entities/src/EntityItemProperties.h +++ b/libraries/entities/src/EntityItemProperties.h @@ -118,7 +118,8 @@ class EntityItemProperties { friend class MaterialEntityItem; public: static bool blobToProperties(QScriptEngine& scriptEngine, const QByteArray& blob, EntityItemProperties& properties); - static void propertiesToBlob(QScriptEngine& scriptEngine, const QUuid& myAvatarID, const EntityItemProperties& properties, QByteArray& blob); + static void propertiesToBlob(QScriptEngine& scriptEngine, const QUuid& myAvatarID, const EntityItemProperties& properties, + QByteArray& blob, bool allProperties = false); EntityItemProperties(EntityPropertyFlags desiredProperties = EntityPropertyFlags()); virtual ~EntityItemProperties() = default;