From fb8640de4778fc2b58d663c559fea4f2b3a3fb71 Mon Sep 17 00:00:00 2001 From: Alexander Ivash Date: Fri, 20 Jul 2018 01:30:22 +0300 Subject: [PATCH 1/4] FB16870: Avatar Wearables showing incorrect number --- interface/src/AvatarBookmarks.cpp | 37 ++++++++++++++++++++++++++++--- interface/src/avatar/MyAvatar.cpp | 6 +++-- interface/src/avatar/MyAvatar.h | 3 ++- scripts/system/avatarapp.js | 23 ++++++++++++++----- 4 files changed, 57 insertions(+), 12 deletions(-) diff --git a/interface/src/AvatarBookmarks.cpp b/interface/src/AvatarBookmarks.cpp index 4e3e539dea..e2d5b648bb 100644 --- a/interface/src/AvatarBookmarks.cpp +++ b/interface/src/AvatarBookmarks.cpp @@ -144,9 +144,16 @@ void AvatarBookmarks::removeBookmark(const QString& bookmarkName) { emit bookmarkDeleted(bookmarkName); } +bool isWearableEntity(const EntityItemPointer& entity) { + return entity->isVisible() && entity->getParentJointIndex() != INVALID_JOINT_INDEX && entity->getParentID() == DependencyManager::get()->getSessionUUID(); +} + void AvatarBookmarks::updateAvatarEntities(const QVariantList &avatarEntities) { auto myAvatar = DependencyManager::get()->getMyAvatar(); - myAvatar->removeAvatarEntities(); + myAvatar->removeAvatarEntities([&](const EntityTreePointer& entityTree, const QUuid& entityID) { + auto entity = entityTree->findEntityByID(entityID); + return entity && isWearableEntity(entity); + }); addAvatarEntities(avatarEntities); } @@ -163,7 +170,10 @@ void AvatarBookmarks::loadBookmark(const QString& bookmarkName) { QVariantMap bookmark = bookmarkEntry.value().toMap(); if (!bookmark.empty()) { auto myAvatar = DependencyManager::get()->getMyAvatar(); - myAvatar->removeAvatarEntities(); + myAvatar->removeAvatarEntities([&](const EntityTreePointer& entityTree, const QUuid& entityID) { + auto entity = entityTree->findEntityByID(entityID); + return entity && isWearableEntity(entity); + }); const QString& avatarUrl = bookmark.value(ENTRY_AVATAR_URL, "").toString(); myAvatar->useFullAvatarURL(avatarUrl); qCDebug(interfaceapp) << "Avatar On " << avatarUrl; @@ -233,6 +243,27 @@ QVariantMap AvatarBookmarks::getAvatarDataToBookmark() { bookmark.insert(ENTRY_AVATAR_URL, avatarUrl); bookmark.insert(ENTRY_AVATAR_SCALE, avatarScale); bookmark.insert(ENTRY_AVATAR_ATTACHMENTS, myAvatar->getAttachmentsVariant()); - bookmark.insert(ENTRY_AVATAR_ENTITIES, myAvatar->getAvatarEntitiesVariant()); + + QScriptEngine scriptEngine; + QVariantList wearableEntities; + auto treeRenderer = DependencyManager::get(); + EntityTreePointer entityTree = treeRenderer ? treeRenderer->getTree() : nullptr; + auto avatarEntities = myAvatar->getAvatarEntityData(); + for (auto entityID : avatarEntities.keys()) { + auto entity = entityTree->findEntityByID(entityID); + if (!entity || !isWearableEntity(entity)) { + continue; + } + QVariantMap avatarEntityData; + EncodeBitstreamParams params; + auto desiredProperties = entity->getEntityProperties(params); + desiredProperties += PROP_LOCAL_POSITION; + desiredProperties += PROP_LOCAL_ROTATION; + EntityItemProperties entityProperties = entity->getProperties(desiredProperties); + QScriptValue scriptProperties = EntityItemPropertiesToScriptValue(&scriptEngine, entityProperties); + avatarEntityData["properties"] = scriptProperties.toVariant(); + wearableEntities.append(QVariant(avatarEntityData)); + } + bookmark.insert(ENTRY_AVATAR_ENTITIES, wearableEntities); return bookmark; } diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp index fd121055a1..fa3ce565a3 100755 --- a/interface/src/avatar/MyAvatar.cpp +++ b/interface/src/avatar/MyAvatar.cpp @@ -1607,14 +1607,16 @@ void MyAvatar::setSkeletonModelURL(const QUrl& skeletonModelURL) { emit skeletonModelURLChanged(); } -void MyAvatar::removeAvatarEntities() { +void MyAvatar::removeAvatarEntities(const std::function& condition) { auto treeRenderer = DependencyManager::get(); EntityTreePointer entityTree = treeRenderer ? treeRenderer->getTree() : nullptr; if (entityTree) { entityTree->withWriteLock([&] { AvatarEntityMap avatarEntities = getAvatarEntityData(); for (auto entityID : avatarEntities.keys()) { - entityTree->deleteEntity(entityID, true, true); + if(!condition || condition(entityTree, entityID)) { + entityTree->deleteEntity(entityID, true, true); + } } }); } diff --git a/interface/src/avatar/MyAvatar.h b/interface/src/avatar/MyAvatar.h index 9b5ddd360d..dfb4c4ab42 100644 --- a/interface/src/avatar/MyAvatar.h +++ b/interface/src/avatar/MyAvatar.h @@ -33,6 +33,7 @@ #include "MyCharacterController.h" #include "RingBufferHistory.h" #include +#include class AvatarActionHold; class ModelItemID; @@ -926,7 +927,7 @@ public: * @returns {object[]} */ Q_INVOKABLE QVariantList getAvatarEntitiesVariant(); - void removeAvatarEntities(); + void removeAvatarEntities(const std::function& condition = {}); /**jsdoc * @function MyAvatar.isFlying diff --git a/scripts/system/avatarapp.js b/scripts/system/avatarapp.js index f692128fa3..77fe1ea755 100644 --- a/scripts/system/avatarapp.js +++ b/scripts/system/avatarapp.js @@ -29,13 +29,24 @@ function executeLater(callback) { Script.setTimeout(callback, 300); } -function getMyAvatarWearables() { - var wearablesArray = MyAvatar.getAvatarEntitiesVariant(); +var INVALID_JOINT_INDEX = -1 +function isWearable(avatarEntity) { + return avatarEntity.properties.visible === true && avatarEntity.properties.parentJointIndex !== INVALID_JOINT_INDEX && avatarEntity.properties.parentID === MyAvatar.sessionUUID; +} - for(var i = 0; i < wearablesArray.length; ++i) { - var wearable = wearablesArray[i]; - var localRotation = wearable.properties.localRotation; - wearable.properties.localRotationAngles = Quat.safeEulerAngles(localRotation) +function getMyAvatarWearables() { + var entitiesArray = MyAvatar.getAvatarEntitiesVariant(); + var wearablesArray = []; + + for (var i = 0; i < entitiesArray.length; ++i) { + var entity = entitiesArray[i]; + if (!isWearable(entity)) { + continue; + } + + var localRotation = entity.properties.localRotation; + entity.properties.localRotationAngles = Quat.safeEulerAngles(localRotation) + wearablesArray.push(entity); } return wearablesArray; From 849c91d8f6fd92dcdf53263b9561658a205d6316 Mon Sep 17 00:00:00 2001 From: Alexander Ivash Date: Fri, 20 Jul 2018 19:32:58 +0300 Subject: [PATCH 2/4] remove not necessary EntityTreeRenderer from removeAvatarEntities's condition --- interface/src/AvatarBookmarks.cpp | 8 ++++++-- interface/src/avatar/MyAvatar.cpp | 4 ++-- interface/src/avatar/MyAvatar.h | 2 +- 3 files changed, 9 insertions(+), 5 deletions(-) diff --git a/interface/src/AvatarBookmarks.cpp b/interface/src/AvatarBookmarks.cpp index e2d5b648bb..5a2a3b4623 100644 --- a/interface/src/AvatarBookmarks.cpp +++ b/interface/src/AvatarBookmarks.cpp @@ -150,7 +150,9 @@ bool isWearableEntity(const EntityItemPointer& entity) { void AvatarBookmarks::updateAvatarEntities(const QVariantList &avatarEntities) { auto myAvatar = DependencyManager::get()->getMyAvatar(); - myAvatar->removeAvatarEntities([&](const EntityTreePointer& entityTree, const QUuid& entityID) { + auto treeRenderer = DependencyManager::get(); + EntityTreePointer entityTree = treeRenderer ? treeRenderer->getTree() : nullptr; + myAvatar->removeAvatarEntities([&](const QUuid& entityID) { auto entity = entityTree->findEntityByID(entityID); return entity && isWearableEntity(entity); }); @@ -170,7 +172,9 @@ void AvatarBookmarks::loadBookmark(const QString& bookmarkName) { QVariantMap bookmark = bookmarkEntry.value().toMap(); if (!bookmark.empty()) { auto myAvatar = DependencyManager::get()->getMyAvatar(); - myAvatar->removeAvatarEntities([&](const EntityTreePointer& entityTree, const QUuid& entityID) { + auto treeRenderer = DependencyManager::get(); + EntityTreePointer entityTree = treeRenderer ? treeRenderer->getTree() : nullptr; + myAvatar->removeAvatarEntities([&](const QUuid& entityID) { auto entity = entityTree->findEntityByID(entityID); return entity && isWearableEntity(entity); }); diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp index fa3ce565a3..81b3ab37e2 100755 --- a/interface/src/avatar/MyAvatar.cpp +++ b/interface/src/avatar/MyAvatar.cpp @@ -1607,14 +1607,14 @@ void MyAvatar::setSkeletonModelURL(const QUrl& skeletonModelURL) { emit skeletonModelURLChanged(); } -void MyAvatar::removeAvatarEntities(const std::function& condition) { +void MyAvatar::removeAvatarEntities(const std::function& condition) { auto treeRenderer = DependencyManager::get(); EntityTreePointer entityTree = treeRenderer ? treeRenderer->getTree() : nullptr; if (entityTree) { entityTree->withWriteLock([&] { AvatarEntityMap avatarEntities = getAvatarEntityData(); for (auto entityID : avatarEntities.keys()) { - if(!condition || condition(entityTree, entityID)) { + if(!condition || condition(entityID)) { entityTree->deleteEntity(entityID, true, true); } } diff --git a/interface/src/avatar/MyAvatar.h b/interface/src/avatar/MyAvatar.h index dfb4c4ab42..add00962da 100644 --- a/interface/src/avatar/MyAvatar.h +++ b/interface/src/avatar/MyAvatar.h @@ -927,7 +927,7 @@ public: * @returns {object[]} */ Q_INVOKABLE QVariantList getAvatarEntitiesVariant(); - void removeAvatarEntities(const std::function& condition = {}); + void removeAvatarEntities(const std::function& condition = {}); /**jsdoc * @function MyAvatar.isFlying From f5717b764835fe3a112bdf2974e2585d3f763ece Mon Sep 17 00:00:00 2001 From: Alexander Ivash Date: Fri, 20 Jul 2018 19:33:16 +0300 Subject: [PATCH 3/4] add check for SELF_ID --- interface/src/AvatarBookmarks.cpp | 3 ++- scripts/system/avatarapp.js | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/interface/src/AvatarBookmarks.cpp b/interface/src/AvatarBookmarks.cpp index 5a2a3b4623..3e0e643bd8 100644 --- a/interface/src/AvatarBookmarks.cpp +++ b/interface/src/AvatarBookmarks.cpp @@ -145,7 +145,8 @@ void AvatarBookmarks::removeBookmark(const QString& bookmarkName) { } bool isWearableEntity(const EntityItemPointer& entity) { - return entity->isVisible() && entity->getParentJointIndex() != INVALID_JOINT_INDEX && entity->getParentID() == DependencyManager::get()->getSessionUUID(); + return entity->isVisible() && entity->getParentJointIndex() != INVALID_JOINT_INDEX && + (entity->getParentID() == DependencyManager::get()->getSessionUUID() || entity->getParentID() == DependencyManager::get()->getMyAvatar()->getSelfID()); } void AvatarBookmarks::updateAvatarEntities(const QVariantList &avatarEntities) { diff --git a/scripts/system/avatarapp.js b/scripts/system/avatarapp.js index 77fe1ea755..612fcccea2 100644 --- a/scripts/system/avatarapp.js +++ b/scripts/system/avatarapp.js @@ -31,7 +31,8 @@ function executeLater(callback) { var INVALID_JOINT_INDEX = -1 function isWearable(avatarEntity) { - return avatarEntity.properties.visible === true && avatarEntity.properties.parentJointIndex !== INVALID_JOINT_INDEX && avatarEntity.properties.parentID === MyAvatar.sessionUUID; + return avatarEntity.properties.visible === true && avatarEntity.properties.parentJointIndex !== INVALID_JOINT_INDEX && + (avatarEntity.properties.parentID === MyAvatar.sessionUUID || avatarEntity.properties.parentID === MyAvatar.SELF_ID); } function getMyAvatarWearables() { From 33c858774bc1db76e2fcb3e7d89c53f90b597db1 Mon Sep 17 00:00:00 2001 From: Alexander Ivash Date: Mon, 23 Jul 2018 21:01:43 +0300 Subject: [PATCH 4/4] fix coding standard compliance --- interface/src/avatar/MyAvatar.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp index 81b3ab37e2..b5e0098b81 100755 --- a/interface/src/avatar/MyAvatar.cpp +++ b/interface/src/avatar/MyAvatar.cpp @@ -1614,7 +1614,7 @@ void MyAvatar::removeAvatarEntities(const std::functionwithWriteLock([&] { AvatarEntityMap avatarEntities = getAvatarEntityData(); for (auto entityID : avatarEntities.keys()) { - if(!condition || condition(entityID)) { + if (!condition || condition(entityID)) { entityTree->deleteEntity(entityID, true, true); } }