Merge pull request #13903 from birarda/bug/av-entity-delete-master

send MyAvatar avatar entity updates through entity tree
This commit is contained in:
John Conklin II 2018-08-30 10:25:31 -07:00 committed by GitHub
commit bf0ab865bb
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 48 additions and 27 deletions

View file

@ -145,20 +145,9 @@ void AvatarBookmarks::removeBookmark(const QString& bookmarkName) {
emit bookmarkDeleted(bookmarkName); emit bookmarkDeleted(bookmarkName);
} }
bool isWearableEntity(const EntityItemPointer& entity) {
return entity->isVisible() && (entity->getParentJointIndex() != INVALID_JOINT_INDEX || (entity->getType() == EntityTypes::Model && (std::static_pointer_cast<ModelEntityItem>(entity))->getRelayParentJoints()))
&& (entity->getParentID() == DependencyManager::get<NodeList>()->getSessionUUID() || entity->getParentID() == DependencyManager::get<AvatarManager>()->getMyAvatar()->getSelfID());
}
void AvatarBookmarks::updateAvatarEntities(const QVariantList &avatarEntities) { void AvatarBookmarks::updateAvatarEntities(const QVariantList &avatarEntities) {
auto myAvatar = DependencyManager::get<AvatarManager>()->getMyAvatar(); auto myAvatar = DependencyManager::get<AvatarManager>()->getMyAvatar();
auto treeRenderer = DependencyManager::get<EntityTreeRenderer>(); myAvatar->removeWearableAvatarEntities();
EntityTreePointer entityTree = treeRenderer ? treeRenderer->getTree() : nullptr;
myAvatar->removeAvatarEntities([&](const QUuid& entityID) {
auto entity = entityTree->findEntityByID(entityID);
return entity && isWearableEntity(entity);
});
addAvatarEntities(avatarEntities); addAvatarEntities(avatarEntities);
} }
@ -183,10 +172,7 @@ void AvatarBookmarks::loadBookmark(const QString& bookmarkName) {
auto myAvatar = DependencyManager::get<AvatarManager>()->getMyAvatar(); auto myAvatar = DependencyManager::get<AvatarManager>()->getMyAvatar();
auto treeRenderer = DependencyManager::get<EntityTreeRenderer>(); auto treeRenderer = DependencyManager::get<EntityTreeRenderer>();
EntityTreePointer entityTree = treeRenderer ? treeRenderer->getTree() : nullptr; EntityTreePointer entityTree = treeRenderer ? treeRenderer->getTree() : nullptr;
myAvatar->removeAvatarEntities([&](const QUuid& entityID) { myAvatar->removeWearableAvatarEntities();
auto entity = entityTree->findEntityByID(entityID);
return entity && isWearableEntity(entity);
});
const QString& avatarUrl = bookmark.value(ENTRY_AVATAR_URL, "").toString(); const QString& avatarUrl = bookmark.value(ENTRY_AVATAR_URL, "").toString();
myAvatar->useFullAvatarURL(avatarUrl); myAvatar->useFullAvatarURL(avatarUrl);
qCDebug(interfaceapp) << "Avatar On " << avatarUrl; qCDebug(interfaceapp) << "Avatar On " << avatarUrl;

View file

@ -1703,18 +1703,50 @@ void MyAvatar::setSkeletonModelURL(const QUrl& skeletonModelURL) {
emit skeletonChanged(); emit skeletonChanged();
} }
void MyAvatar::removeAvatarEntities(const std::function<bool(const QUuid& entityID)>& condition) { bool isWearableEntity(const EntityItemPointer& entity) {
return entity->isVisible()
&& (entity->getParentJointIndex() != INVALID_JOINT_INDEX
|| (entity->getType() == EntityTypes::Model && (std::static_pointer_cast<ModelEntityItem>(entity))->getRelayParentJoints()))
&& (entity->getParentID() == DependencyManager::get<NodeList>()->getSessionUUID()
|| entity->getParentID() == AVATAR_SELF_ID);
}
void MyAvatar::clearAvatarEntities() {
auto treeRenderer = DependencyManager::get<EntityTreeRenderer>(); auto treeRenderer = DependencyManager::get<EntityTreeRenderer>();
EntityTreePointer entityTree = treeRenderer ? treeRenderer->getTree() : nullptr; EntityTreePointer entityTree = treeRenderer ? treeRenderer->getTree() : nullptr;
if (entityTree) {
entityTree->withWriteLock([&] { AvatarEntityMap avatarEntities = getAvatarEntityData();
AvatarEntityMap avatarEntities = getAvatarEntityData(); for (auto entityID : avatarEntities.keys()) {
for (auto entityID : avatarEntities.keys()) { entityTree->withWriteLock([&entityID, &entityTree] {
if (!condition || condition(entityID)) { // remove this entity first from the entity tree
entityTree->deleteEntity(entityID, true, true); entityTree->deleteEntity(entityID, true, true);
}
}
}); });
// remove the avatar entity from our internal list
// (but indicate it doesn't need to be pulled from the tree)
clearAvatarEntity(entityID, false);
}
}
void MyAvatar::removeWearableAvatarEntities() {
auto treeRenderer = DependencyManager::get<EntityTreeRenderer>();
EntityTreePointer entityTree = treeRenderer ? treeRenderer->getTree() : nullptr;
if (entityTree) {
AvatarEntityMap avatarEntities = getAvatarEntityData();
for (auto entityID : avatarEntities.keys()) {
auto entity = entityTree->findEntityByID(entityID);
if (entity && isWearableEntity(entity)) {
entityTree->withWriteLock([&entityID, &entityTree] {
// remove this entity first from the entity tree
entityTree->deleteEntity(entityID, true, true);
});
// remove the avatar entity from our internal list
// (but indicate it doesn't need to be pulled from the tree)
clearAvatarEntity(entityID, false);
}
}
} }
} }
@ -2116,7 +2148,7 @@ void MyAvatar::setAttachmentData(const QVector<AttachmentData>& attachmentData)
} }
// clear any existing avatar entities // clear any existing avatar entities
setAvatarEntityData(AvatarEntityMap()); clearAvatarEntities();
for (auto& properties : newEntitiesProperties) { for (auto& properties : newEntitiesProperties) {
DependencyManager::get<EntityScriptingInterface>()->addEntity(properties, true); DependencyManager::get<EntityScriptingInterface>()->addEntity(properties, true);

View file

@ -931,7 +931,8 @@ public:
* @returns {object[]} * @returns {object[]}
*/ */
Q_INVOKABLE QVariantList getAvatarEntitiesVariant(); Q_INVOKABLE QVariantList getAvatarEntitiesVariant();
void removeAvatarEntities(const std::function<bool(const QUuid& entityID)>& condition = {}); void clearAvatarEntities();
void removeWearableAvatarEntities();
/**jsdoc /**jsdoc
* @function MyAvatar.isFlying * @function MyAvatar.isFlying
@ -1782,4 +1783,6 @@ void audioListenModeFromScriptValue(const QScriptValue& object, AudioListenerMod
QScriptValue driveKeysToScriptValue(QScriptEngine* engine, const MyAvatar::DriveKeys& driveKeys); QScriptValue driveKeysToScriptValue(QScriptEngine* engine, const MyAvatar::DriveKeys& driveKeys);
void driveKeysFromScriptValue(const QScriptValue& object, MyAvatar::DriveKeys& driveKeys); void driveKeysFromScriptValue(const QScriptValue& object, MyAvatar::DriveKeys& driveKeys);
bool isWearableEntity(const EntityItemPointer& entity);
#endif // hifi_MyAvatar_h #endif // hifi_MyAvatar_h