From 69389116f5f4b21b93f7b3935f7e33847566785f Mon Sep 17 00:00:00 2001 From: Dante Ruiz Date: Mon, 15 Jan 2018 16:47:48 -0800 Subject: [PATCH 1/9] add menu option for AvatarEntitiesBookmarks --- interface/src/Application.cpp | 4 ++ interface/src/AvatarEntitiesBookmarks.cpp | 85 +++++++++++++++++++++++ interface/src/AvatarEntitiesBookmarks.h | 45 ++++++++++++ interface/src/Menu.cpp | 4 ++ interface/src/Menu.h | 2 + 5 files changed, 140 insertions(+) create mode 100644 interface/src/AvatarEntitiesBookmarks.cpp create mode 100644 interface/src/AvatarEntitiesBookmarks.h diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 449b014c13..a23ff2bf8d 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -64,6 +64,7 @@ #include #include #include +#include #include #include #include @@ -701,6 +702,7 @@ bool setupEssentials(int& argc, char** argv, bool runningMarkerExisted) { DependencyManager::set(); DependencyManager::set(nullptr, qApp->getOcteeSceneStats()); DependencyManager::set(); + DependencyManager::set(); DependencyManager::set(); DependencyManager::set(); DependencyManager::set(); @@ -2367,6 +2369,7 @@ void Application::initializeUi() { surfaceContext->setContextProperty("Settings", SettingsScriptingInterface::getInstance()); surfaceContext->setContextProperty("ScriptDiscoveryService", DependencyManager::get().data()); surfaceContext->setContextProperty("AvatarBookmarks", DependencyManager::get().data()); + surfaceContext->setContextProperty("AvatarEntitiesBookmarks", DependencyManager::get().data()); surfaceContext->setContextProperty("LocationBookmarks", DependencyManager::get().data()); // Caches @@ -5762,6 +5765,7 @@ void Application::registerScriptEngineWithApplicationServices(ScriptEnginePointe scriptEngine->registerGlobalObject("AudioStats", DependencyManager::get()->getStats().data()); scriptEngine->registerGlobalObject("AudioScope", DependencyManager::get().data()); scriptEngine->registerGlobalObject("AvatarBookmarks", DependencyManager::get().data()); + scriptEngine->registerGlobalObject("AvatarEntitiesBookmarks", DependencyManager::get().data()); scriptEngine->registerGlobalObject("LocationBookmarks", DependencyManager::get().data()); scriptEngine->registerGlobalObject("RayPick", DependencyManager::get().data()); diff --git a/interface/src/AvatarEntitiesBookmarks.cpp b/interface/src/AvatarEntitiesBookmarks.cpp new file mode 100644 index 0000000000..e034aec458 --- /dev/null +++ b/interface/src/AvatarEntitiesBookmarks.cpp @@ -0,0 +1,85 @@ +// +// AvatarEntitiesBookmarks.cpp +// interface/src +// +// Created by Dante Ruiz on /01/18. +// Copyright 2017 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include "MainWindow.h" +#include "Menu.h" +#include "AvatarEntitiesBookmarks.h" +#include "InterfaceLogging.h" + +#include "QVariantGLM.h" + +#include + +AvatarEntitiesBookmarks::AvatarEntitiesBookmarks() { + _bookmarksFilename = PathUtils::getAppDataPath() + "/" + AVATAR_ENTITIES_BOOKMARKS_FILENAME; + readFromFile(); +} + +void AvatarEntitiesBookmarks::readFromFile() { + QString oldConfigPath = QStandardPaths::writableLocation(QStandardPaths::DataLocation) + "/" + AVATAR_ENTITIES_BOOKMARKS_FILENAME; + QFile oldConfig(oldConfigPath); + // I imagine that in a year from now, this code for migrating (as well as the two lines above) + // may be removed since all bookmarks should have been migrated by then + // - Robbie Uvanni (6.8.2017) + if (oldConfig.exists()) { + if (QDir().rename(oldConfigPath, _bookmarksFilename)) { + qCDebug(interfaceapp) << "Successfully migrated" << AVATAR_ENTITIES_BOOKMARKS_FILENAME; + } else { + qCDebug(interfaceapp) << "Failed to migrate" << AVATAR_ENTITIES_BOOKMARKS_FILENAME; + } + } + + Bookmarks::readFromFile(); +} + +void AvatarEntitiesBookmarks::setupMenus(Menu* menubar, MenuWrapper* menu) { + auto bookmarkAction = menubar->addActionToQMenuAndActionHash(menu, MenuOption::BookmarkAvatarEntities); + QObject::connect(bookmarkAction, SIGNAL(triggered()), this, SLOT(addBookmark()), Qt::QueuedConnection); + _bookmarksMenu = menu->addMenu(MenuOption::AvatarEntitiesBookmarks); + _deleteBookmarksAction = menubar->addActionToQMenuAndActionHash(menu, MenuOption::DeleteAvatarBookmark); + QObject::connect(_deleteBookmarksAction, SIGNAL(triggered()), this, SLOT(deleteBookmark()), Qt::QueuedConnection); + + for (auto it = _bookmarks.begin(); it != _bookmarks.end(); ++it) { + addBookmarkToMenu(menubar, it.key(), it.value()); + } + + Bookmarks::sortActions(menubar, _bookmarksMenu); +} + +void AvatarEntitiesBookmarks::applyBookmarkedAvatarEntities() { +} + +void AvatarEntitiesBookmarks::addBookmark() { +} + +void AvatarEntitiesBookmarks::addBookmarkToMenu(Menu* menubar, const QString& name, const QVariant& bookmark) { + QAction* changeAction = _bookmarksMenu->newAction(); + changeAction->setData(bookmark); + connect(changeAction, SIGNAL(triggered()), this, SLOT(applyBookedAvatarEntities())); + if (!_isMenuSorted) { + menubar->addActionToQMenuAndActionHash(_bookmarksMenu, changeAction, name, 0, QAction::NoRole); + } else { + // TODO: this is aggressive but other alternatives have proved less fruitful so far. + menubar->addActionToQMenuAndActionHash(_bookmarksMenu, changeAction, name, 0, QAction::NoRole); + Bookmarks::sortActions(menubar, _bookmarksMenu); + } +} diff --git a/interface/src/AvatarEntitiesBookmarks.h b/interface/src/AvatarEntitiesBookmarks.h new file mode 100644 index 0000000000..995b75a88d --- /dev/null +++ b/interface/src/AvatarEntitiesBookmarks.h @@ -0,0 +1,45 @@ +// +// AvatarEntitiesBookmarks.h +// interface/src +// +// Created by Dante Ruiz on 15/01/18. +// Copyright 2017 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + +#ifndef hifi_AvatarEntitiesBookmarks_h +#define hifi_AvatarEntitiesBookmarks_h + +#include +#include "Bookmarks.h" + +class AvatarEntitiesBookmarks: public Bookmarks, public Dependency { + Q_OBJECT + SINGLETON_DEPENDENCY + +public: + AvatarEntitiesBookmarks(); + void setupMenus(Menu* menubar, MenuWrapper* menu) override; + +public slots: + void addBookmark(); + +protected: + void addBookmarkToMenu(Menu* menubar, const QString& name, const QVariant& bookmark) override; + void readFromFile() override; + +private: + const QString AVATAR_ENTITIES_BOOKMARKS_FILENAME = "AvatarEntitiesbookmarks.json"; + const QString AVATAR_ENTITIES_ATTACHMENTS = "AvatarEntitiesName"; + const QString ENTITY_PROPERTIES = "AvatarEntitiesData"; + const QString ENTRY_VERSION = "version"; + + const int ATTACHMENT_BOOKMARK_VERSION = 1; + +private slots: + void applyBookmarkedAvatarEntities(); +}; + +#endif diff --git a/interface/src/Menu.cpp b/interface/src/Menu.cpp index 3072ecf240..6d18575cbe 100644 --- a/interface/src/Menu.cpp +++ b/interface/src/Menu.cpp @@ -34,6 +34,7 @@ #include "audio/AudioScope.h" #include "avatar/AvatarManager.h" #include "AvatarBookmarks.h" +#include "AvatarEntitiesBookmarks.h" #include "devices/DdeFaceTracker.h" #include "MainWindow.h" #include "render/DrawStatus.h" @@ -206,6 +207,9 @@ Menu::Menu() { auto avatarBookmarks = DependencyManager::get(); avatarBookmarks->setupMenus(this, avatarMenu); + auto avatarEntitiesBookmarks = DependencyManager::get(); + avatarBookmarks->setupMenus(this, avatarMenu); + // Display menu ---------------------------------- // FIXME - this is not yet matching Alan's spec because it doesn't have // menus for "2D"/"3D" - we need to add support for detecting the appropriate diff --git a/interface/src/Menu.h b/interface/src/Menu.h index 854f8d8c2b..6dee53a4ed 100644 --- a/interface/src/Menu.h +++ b/interface/src/Menu.h @@ -46,9 +46,11 @@ namespace MenuOption { const QString AutoMuteAudio = "Auto Mute Microphone"; const QString AvatarReceiveStats = "Show Receive Stats"; const QString AvatarBookmarks = "Avatar Bookmarks"; + const QString AvatarEntitiesBookmarks = "Avatar Entities Bookmarks"; const QString Back = "Back"; const QString BinaryEyelidControl = "Binary Eyelid Control"; const QString BookmarkAvatar = "Bookmark Avatar"; + const QString BookmarkAvatarEntities = "Bookmark Avatar Entities"; const QString BookmarkLocation = "Bookmark Location"; const QString CalibrateCamera = "Calibrate Camera"; const QString CameraEntityMode = "Entity Mode"; From 7707e682349895f80e16459492a8c01c66ad6773 Mon Sep 17 00:00:00 2001 From: Dante Ruiz Date: Tue, 16 Jan 2018 15:37:03 -0800 Subject: [PATCH 2/9] bookmarks add back avatar-entities --- interface/src/AvatarEntitiesBookmarks.cpp | 106 +++++++++++++++++++++- interface/src/AvatarEntitiesBookmarks.h | 9 +- interface/src/Menu.cpp | 2 +- interface/src/Menu.h | 1 + interface/src/avatar/MyAvatar.cpp | 25 +++++ interface/src/avatar/MyAvatar.h | 2 + 6 files changed, 138 insertions(+), 7 deletions(-) diff --git a/interface/src/AvatarEntitiesBookmarks.cpp b/interface/src/AvatarEntitiesBookmarks.cpp index e034aec458..012c0d6f1a 100644 --- a/interface/src/AvatarEntitiesBookmarks.cpp +++ b/interface/src/AvatarEntitiesBookmarks.cpp @@ -18,7 +18,13 @@ #include #include +#include +#include #include +#include +#include +#include +#include #include "MainWindow.h" #include "Menu.h" @@ -29,6 +35,64 @@ #include +void addAvatarEntities(const QVariantList& avatarEntities, const QUuid& avatarSessionID) { + EntityTreePointer entityTree = DependencyManager::get()->getTree(); + if (!entityTree) { + return; + } + EntitySimulationPointer entitySimulation = entityTree->getSimulation(); + PhysicalEntitySimulationPointer physicalEntitySimulation = std::static_pointer_cast(entitySimulation); + EntityEditPacketSender* entityPacketSender = physicalEntitySimulation->getPacketSender(); + for (int index = 0; index < avatarEntities.count(); index++) { + qDebug() << "-----------> " << index; + const QVariantList& avatarEntityProperties = avatarEntities.at(index).toList(); + EntityItemProperties entityProperties; + entityProperties.setParentID(avatarSessionID); + entityProperties.setClientOnly(true); + QString typeName = avatarEntityProperties.value(0).toString(); + entityProperties.setType(EntityTypes::getEntityTypeFromName(typeName)); + QString marketplaceID = avatarEntityProperties.value(1).toString(); + entityProperties.setMarketplaceID(marketplaceID); + quint32 editionNumber = (quint32) avatarEntityProperties.value(2).toUInt(); + entityProperties.setEditionNumber(editionNumber); + QString modelURL = avatarEntityProperties.value(3).toString(); + entityProperties.setModelURL(modelURL); + quint16 parentJointIndex = (quint16) avatarEntityProperties.value(4).toUInt(); + glm::vec3 localPosition = vec3FromJsonValue(avatarEntityProperties.value(5).toJsonValue()); + entityProperties.setLocalPosition(localPosition); + glm::quat localRotation = quatFromJsonValue(avatarEntityProperties.value(6).toJsonValue()); + entityProperties.setLocalRotation(localRotation); + + EntityItemID id = EntityItemID(QUuid::createUuid()); + bool success = true; + entityTree->withWriteLock([&] { + EntityItemPointer entity = entityTree->addEntity(id, entityProperties); + if (entity) { + if (entityProperties.queryAACubeRelatedPropertyChanged()) { + // due to parenting, the server may not know where something is in world-space, so include the bounding cube. + bool success; + AACube queryAACube = entity->getQueryAACube(success); + if (success) { + entityProperties.setQueryAACube(queryAACube); + } + } + + entity->setLastBroadcast(usecTimestampNow()); + // since we're creating this object we will immediately volunteer to own its simulation + entity->flagForOwnershipBid(VOLUNTEER_SIMULATION_PRIORITY); + entityProperties.setLastEdited(entity->getLastEdited()); + } else { + qCDebug(entities) << "AvatarEntitiesBookmark failed to add new Entity to local Octree"; + success = false; + } + }); + + if (success) { + entityPacketSender->queueEditEntityMessage(PacketType::EntityAdd, entityTree, id, entityProperties); + } + } +} + AvatarEntitiesBookmarks::AvatarEntitiesBookmarks() { _bookmarksFilename = PathUtils::getAppDataPath() + "/" + AVATAR_ENTITIES_BOOKMARKS_FILENAME; readFromFile(); @@ -55,7 +119,7 @@ void AvatarEntitiesBookmarks::setupMenus(Menu* menubar, MenuWrapper* menu) { auto bookmarkAction = menubar->addActionToQMenuAndActionHash(menu, MenuOption::BookmarkAvatarEntities); QObject::connect(bookmarkAction, SIGNAL(triggered()), this, SLOT(addBookmark()), Qt::QueuedConnection); _bookmarksMenu = menu->addMenu(MenuOption::AvatarEntitiesBookmarks); - _deleteBookmarksAction = menubar->addActionToQMenuAndActionHash(menu, MenuOption::DeleteAvatarBookmark); + _deleteBookmarksAction = menubar->addActionToQMenuAndActionHash(menu, MenuOption::DeleteAvatarEntitiesBookmark); QObject::connect(_deleteBookmarksAction, SIGNAL(triggered()), this, SLOT(deleteBookmark()), Qt::QueuedConnection); for (auto it = _bookmarks.begin(); it != _bookmarks.end(); ++it) { @@ -66,15 +130,53 @@ void AvatarEntitiesBookmarks::setupMenus(Menu* menubar, MenuWrapper* menu) { } void AvatarEntitiesBookmarks::applyBookmarkedAvatarEntities() { + qDebug() << "AvatarEntitiesBookmarks::applyBookmarkedAvatarEntities"; + QAction* action = qobject_cast(sender()); + auto myAvatar = DependencyManager::get()->getMyAvatar(); + + const QMap bookmark = action->data().toMap(); + + if (bookmark.value(ENTRY_VERSION) == AVATAR_ENTITIES_BOOKMARK_VERSION) { + const QString& avatarUrl = bookmark.value(ENTRY_AVATAR_URL, "").toString(); + myAvatar->useFullAvatarURL(avatarUrl); + const QVariantList& avatarEntities = bookmark.value(ENTRY_AVATAR_ENTITIES, QVariantList()).toList(); + addAvatarEntities(avatarEntities, myAvatar->getSelfID()); + const float& avatarScale = bookmark.value(ENTRY_AVATAR_SCALE, 1.0f).toFloat(); + myAvatar->setAvatarScale(avatarScale); + } else { + qCDebug(interfaceapp) << " Bookmark entry does not match client version, make sure client has a handler for the new AvatarEntitiesBookmark"; + } } void AvatarEntitiesBookmarks::addBookmark() { + ModalDialogListener* dlg = OffscreenUi::getTextAsync(OffscreenUi::ICON_PLACEMARK, "Bookmark Avatar Entities", "Name", QString()); + connect(dlg, &ModalDialogListener::response, this, [=] (QVariant response) { + disconnect(dlg, &ModalDialogListener::response, this, nullptr); + auto bookmarkName = response.toString(); + bookmarkName = bookmarkName.trimmed().replace(QRegExp("(\r\n|[\r\n\t\v ])+"), " "); + if (bookmarkName.length() == 0) { + return; + } + + auto myAvatar = DependencyManager::get()->getMyAvatar(); + + const QString& avatarUrl = myAvatar->getSkeletonModelURL().toString(); + const QVariant& avatarScale = myAvatar->getAvatarScale(); + + QVariantMap *bookmark = new QVariantMap; + bookmark->insert(ENTRY_VERSION, AVATAR_ENTITIES_BOOKMARK_VERSION); + bookmark->insert(ENTRY_AVATAR_URL, avatarUrl); + bookmark->insert(ENTRY_AVATAR_SCALE, avatarScale); + bookmark->insert(ENTRY_AVATAR_ENTITIES, myAvatar->getAvatarEntitiesVariant()); + + Bookmarks::addBookmarkToFile(bookmarkName, *bookmark); + }); } void AvatarEntitiesBookmarks::addBookmarkToMenu(Menu* menubar, const QString& name, const QVariant& bookmark) { QAction* changeAction = _bookmarksMenu->newAction(); changeAction->setData(bookmark); - connect(changeAction, SIGNAL(triggered()), this, SLOT(applyBookedAvatarEntities())); + connect(changeAction, SIGNAL(triggered()), this, SLOT(applyBookmarkedAvatarEntities())); if (!_isMenuSorted) { menubar->addActionToQMenuAndActionHash(_bookmarksMenu, changeAction, name, 0, QAction::NoRole); } else { diff --git a/interface/src/AvatarEntitiesBookmarks.h b/interface/src/AvatarEntitiesBookmarks.h index 995b75a88d..12e8c47768 100644 --- a/interface/src/AvatarEntitiesBookmarks.h +++ b/interface/src/AvatarEntitiesBookmarks.h @@ -31,12 +31,13 @@ protected: void readFromFile() override; private: - const QString AVATAR_ENTITIES_BOOKMARKS_FILENAME = "AvatarEntitiesbookmarks.json"; - const QString AVATAR_ENTITIES_ATTACHMENTS = "AvatarEntitiesName"; - const QString ENTITY_PROPERTIES = "AvatarEntitiesData"; + const QString AVATAR_ENTITIES_BOOKMARKS_FILENAME = "AvatarEntitiesBookmarks.json"; + const QString ENTRY_AVATAR_URL = "AvatarUrl"; + const QString ENTRY_AVATAR_SCALE = "AvatarScale"; + const QString ENTRY_AVATAR_ENTITIES = "AvatarEntities"; const QString ENTRY_VERSION = "version"; - const int ATTACHMENT_BOOKMARK_VERSION = 1; + const int AVATAR_ENTITIES_BOOKMARK_VERSION = 1; private slots: void applyBookmarkedAvatarEntities(); diff --git a/interface/src/Menu.cpp b/interface/src/Menu.cpp index 6d18575cbe..14bc53950f 100644 --- a/interface/src/Menu.cpp +++ b/interface/src/Menu.cpp @@ -208,7 +208,7 @@ Menu::Menu() { avatarBookmarks->setupMenus(this, avatarMenu); auto avatarEntitiesBookmarks = DependencyManager::get(); - avatarBookmarks->setupMenus(this, avatarMenu); + avatarEntitiesBookmarks->setupMenus(this, avatarMenu); // Display menu ---------------------------------- // FIXME - this is not yet matching Alan's spec because it doesn't have diff --git a/interface/src/Menu.h b/interface/src/Menu.h index 6dee53a4ed..8c41c66041 100644 --- a/interface/src/Menu.h +++ b/interface/src/Menu.h @@ -80,6 +80,7 @@ namespace MenuOption { const QString DecreaseAvatarSize = "Decrease Avatar Size"; const QString DefaultSkybox = "Default Skybox"; const QString DeleteAvatarBookmark = "Delete Avatar Bookmark..."; + const QString DeleteAvatarEntitiesBookmark = "Delete Avatar Entities Bookmark"; const QString DeleteBookmark = "Delete Bookmark..."; const QString DisableActivityLogger = "Disable Activity Logger"; const QString DisableEyelidAdjustment = "Disable Eyelid Adjustment"; diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp index e863a58e14..42b72beb7d 100755 --- a/interface/src/avatar/MyAvatar.cpp +++ b/interface/src/avatar/MyAvatar.cpp @@ -35,6 +35,8 @@ #include #include #include +#include +#include #include #include #include @@ -1419,6 +1421,29 @@ void MyAvatar::setSkeletonModelURL(const QUrl& skeletonModelURL) { } +QVariantList MyAvatar::getAvatarEntitiesVariant() { + QVariantList avatarEntitiesData; + forEachChild([&](SpatiallyNestablePointer child) { + if (child->getNestableType() == NestableType::Entity) { + auto modelEntity = std::dynamic_pointer_cast(child); + if (modelEntity) { + QVariantList avatarEntityProperties; + EntityItemProperties entityProperties = modelEntity->getProperties(); + avatarEntityProperties.append(QVariant(EntityTypes::getEntityTypeName(entityProperties.getType()))); + avatarEntityProperties.append(QVariant(entityProperties.getMarketplaceID())); + avatarEntityProperties.append(QVariant(entityProperties.getEditionNumber())); + avatarEntityProperties.append(QVariant(entityProperties.getModelURL())); + avatarEntityProperties.append(QVariant(entityProperties.getParentJointIndex())); + avatarEntityProperties.append(QVariant(toJsonValue(entityProperties.getLocalPosition()))); + avatarEntityProperties.append(QVariant(toJsonValue(entityProperties.getLocalRotation()))); + avatarEntityProperties.append(QVariant(entityProperties.getUserData())); + avatarEntitiesData.append(QVariant(avatarEntityProperties)); + } + } + }); + return avatarEntitiesData; +} + void MyAvatar::resetFullAvatarURL() { auto lastAvatarURL = getFullAvatarURLFromPreferences(); diff --git a/interface/src/avatar/MyAvatar.h b/interface/src/avatar/MyAvatar.h index ab74460d4e..45a3773e1a 100644 --- a/interface/src/avatar/MyAvatar.h +++ b/interface/src/avatar/MyAvatar.h @@ -510,6 +510,8 @@ public: bool hasDriveInput() const; + QVariantList getAvatarEntitiesVariant(); + Q_INVOKABLE bool isFlying(); Q_INVOKABLE bool isInAir(); Q_INVOKABLE void setFlyingEnabled(bool enabled); From 92a259fd63ad4f8c051e20f91f0b2751393453ca Mon Sep 17 00:00:00 2001 From: Dante Ruiz Date: Tue, 16 Jan 2018 16:41:06 -0800 Subject: [PATCH 3/9] fix setting correct joint index --- interface/src/AvatarEntitiesBookmarks.cpp | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/interface/src/AvatarEntitiesBookmarks.cpp b/interface/src/AvatarEntitiesBookmarks.cpp index 012c0d6f1a..7798c0b84b 100644 --- a/interface/src/AvatarEntitiesBookmarks.cpp +++ b/interface/src/AvatarEntitiesBookmarks.cpp @@ -35,7 +35,9 @@ #include -void addAvatarEntities(const QVariantList& avatarEntities, const QUuid& avatarSessionID) { +void addAvatarEntities(const QVariantList& avatarEntities, std::shared_ptr myAvatar) { + auto nodeList = DependencyManager::get(); + const QUuid myNodeID = nodeList->getSessionUUID(); EntityTreePointer entityTree = DependencyManager::get()->getTree(); if (!entityTree) { return; @@ -44,24 +46,25 @@ void addAvatarEntities(const QVariantList& avatarEntities, const QUuid& avatarSe PhysicalEntitySimulationPointer physicalEntitySimulation = std::static_pointer_cast(entitySimulation); EntityEditPacketSender* entityPacketSender = physicalEntitySimulation->getPacketSender(); for (int index = 0; index < avatarEntities.count(); index++) { - qDebug() << "-----------> " << index; const QVariantList& avatarEntityProperties = avatarEntities.at(index).toList(); EntityItemProperties entityProperties; - entityProperties.setParentID(avatarSessionID); - entityProperties.setClientOnly(true); + entityProperties.setParentID(myNodeID); QString typeName = avatarEntityProperties.value(0).toString(); entityProperties.setType(EntityTypes::getEntityTypeFromName(typeName)); QString marketplaceID = avatarEntityProperties.value(1).toString(); entityProperties.setMarketplaceID(marketplaceID); - quint32 editionNumber = (quint32) avatarEntityProperties.value(2).toUInt(); + int editionNumber = avatarEntityProperties.value(2).toInt(); entityProperties.setEditionNumber(editionNumber); QString modelURL = avatarEntityProperties.value(3).toString(); entityProperties.setModelURL(modelURL); - quint16 parentJointIndex = (quint16) avatarEntityProperties.value(4).toUInt(); + int parentJointIndex = avatarEntityProperties.value(4).toInt(); + entityProperties.setParentJointIndex(parentJointIndex); glm::vec3 localPosition = vec3FromJsonValue(avatarEntityProperties.value(5).toJsonValue()); entityProperties.setLocalPosition(localPosition); glm::quat localRotation = quatFromJsonValue(avatarEntityProperties.value(6).toJsonValue()); entityProperties.setLocalRotation(localRotation); + QString userData = avatarEntityProperties.value(7).toString(); + entityProperties.setUserData(userData); EntityItemID id = EntityItemID(QUuid::createUuid()); bool success = true; @@ -140,7 +143,7 @@ void AvatarEntitiesBookmarks::applyBookmarkedAvatarEntities() { const QString& avatarUrl = bookmark.value(ENTRY_AVATAR_URL, "").toString(); myAvatar->useFullAvatarURL(avatarUrl); const QVariantList& avatarEntities = bookmark.value(ENTRY_AVATAR_ENTITIES, QVariantList()).toList(); - addAvatarEntities(avatarEntities, myAvatar->getSelfID()); + addAvatarEntities(avatarEntities, myAvatar); const float& avatarScale = bookmark.value(ENTRY_AVATAR_SCALE, 1.0f).toFloat(); myAvatar->setAvatarScale(avatarScale); } else { From 3abb3d6fcc75c5f6b204d5dd00882b860b5b79bf Mon Sep 17 00:00:00 2001 From: Dante Ruiz Date: Wed, 17 Jan 2018 11:04:32 -0800 Subject: [PATCH 4/9] trying to add offset --- interface/src/AvatarEntitiesBookmarks.cpp | 14 ++++++++++---- interface/src/avatar/MyAvatar.cpp | 17 ++++++++++++++--- 2 files changed, 24 insertions(+), 7 deletions(-) diff --git a/interface/src/AvatarEntitiesBookmarks.cpp b/interface/src/AvatarEntitiesBookmarks.cpp index 7798c0b84b..e2de915061 100644 --- a/interface/src/AvatarEntitiesBookmarks.cpp +++ b/interface/src/AvatarEntitiesBookmarks.cpp @@ -59,12 +59,18 @@ void addAvatarEntities(const QVariantList& avatarEntities, std::shared_ptrgetJointPosition(parentJointIndex); + glm::vec3 positionOffset = vec3FromJsonValue(avatarEntityProperties.value(5).toJsonValue()); + glm::vec3 finalPosition = jointPosition + positionOffset; + entityProperties.setLocalPosition(finalPosition); + glm::quat jointRotation = myAvatar->getJointRotation(parentJointIndex); + glm::quat rotationOffset = quatFromJsonValue(avatarEntityProperties.value(6).toJsonValue()); + glm::quat finalRotation = jointRotation * rotationOffset; + entityProperties.setRotation(finalRotation); QString userData = avatarEntityProperties.value(7).toString(); entityProperties.setUserData(userData); + glm::vec3 dimensions = vec3FromJsonValue(avatarEntityProperties.value(8).toJsonValue()); + entityProperties.setDimensions(dimensions); EntityItemID id = EntityItemID(QUuid::createUuid()); bool success = true; diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp index 42b72beb7d..e370054652 100755 --- a/interface/src/avatar/MyAvatar.cpp +++ b/interface/src/avatar/MyAvatar.cpp @@ -1429,14 +1429,25 @@ QVariantList MyAvatar::getAvatarEntitiesVariant() { if (modelEntity) { QVariantList avatarEntityProperties; EntityItemProperties entityProperties = modelEntity->getProperties(); + + // calculate the entity offset from the parentJointIndex + int jointIndex = entityProperties.getParentJointIndex(); + glm::quat jointRotation = getJointRotation(jointIndex); + glm::quat entityRotation = modelEntity->getWorldOrientation(); + glm::vec3 jointPosition = getJointPosition(jointIndex); + glm::vec3 entityPosition = modelEntity->getWorldPosition(); + glm::quat rotationOffset = glm::inverse(jointRotation) * entityRotation; + glm::vec3 positionOffset = entityPosition - jointPosition; + avatarEntityProperties.append(QVariant(EntityTypes::getEntityTypeName(entityProperties.getType()))); avatarEntityProperties.append(QVariant(entityProperties.getMarketplaceID())); avatarEntityProperties.append(QVariant(entityProperties.getEditionNumber())); avatarEntityProperties.append(QVariant(entityProperties.getModelURL())); - avatarEntityProperties.append(QVariant(entityProperties.getParentJointIndex())); - avatarEntityProperties.append(QVariant(toJsonValue(entityProperties.getLocalPosition()))); - avatarEntityProperties.append(QVariant(toJsonValue(entityProperties.getLocalRotation()))); + avatarEntityProperties.append(QVariant(jointIndex)); + avatarEntityProperties.append(QVariant(toJsonValue(positionOffset))); + avatarEntityProperties.append(QVariant(toJsonValue(rotationOffset))); avatarEntityProperties.append(QVariant(entityProperties.getUserData())); + avatarEntityProperties.append(QVariant(toJsonValue(entityProperties.getDimensions()))); avatarEntitiesData.append(QVariant(avatarEntityProperties)); } } From 3ba0eaa13d9906aaf1ef3787e17be4845242190f Mon Sep 17 00:00:00 2001 From: Dante Ruiz Date: Wed, 17 Jan 2018 11:05:55 -0800 Subject: [PATCH 5/9] fix typo --- interface/src/AvatarEntitiesBookmarks.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/interface/src/AvatarEntitiesBookmarks.cpp b/interface/src/AvatarEntitiesBookmarks.cpp index e2de915061..ddc606455d 100644 --- a/interface/src/AvatarEntitiesBookmarks.cpp +++ b/interface/src/AvatarEntitiesBookmarks.cpp @@ -62,7 +62,7 @@ void addAvatarEntities(const QVariantList& avatarEntities, std::shared_ptrgetJointPosition(parentJointIndex); glm::vec3 positionOffset = vec3FromJsonValue(avatarEntityProperties.value(5).toJsonValue()); glm::vec3 finalPosition = jointPosition + positionOffset; - entityProperties.setLocalPosition(finalPosition); + entityProperties.setPosition(finalPosition); glm::quat jointRotation = myAvatar->getJointRotation(parentJointIndex); glm::quat rotationOffset = quatFromJsonValue(avatarEntityProperties.value(6).toJsonValue()); glm::quat finalRotation = jointRotation * rotationOffset; From eadd3b48bd8d820cfc2bcd3a93f1be6170c2c25a Mon Sep 17 00:00:00 2001 From: Dante Ruiz Date: Wed, 17 Jan 2018 15:42:07 -0800 Subject: [PATCH 6/9] bookmark avatar-entities-done --- interface/src/AvatarEntitiesBookmarks.cpp | 40 +++++++++-------------- interface/src/avatar/MyAvatar.cpp | 39 ++++++++++------------ interface/src/avatar/MyAvatar.h | 1 + 3 files changed, 34 insertions(+), 46 deletions(-) diff --git a/interface/src/AvatarEntitiesBookmarks.cpp b/interface/src/AvatarEntitiesBookmarks.cpp index ddc606455d..11d0d88368 100644 --- a/interface/src/AvatarEntitiesBookmarks.cpp +++ b/interface/src/AvatarEntitiesBookmarks.cpp @@ -25,6 +25,7 @@ #include #include #include +#include #include "MainWindow.h" #include "Menu.h" @@ -35,7 +36,7 @@ #include -void addAvatarEntities(const QVariantList& avatarEntities, std::shared_ptr myAvatar) { +void addAvatarEntities(const QVariantList& avatarEntities) { auto nodeList = DependencyManager::get(); const QUuid myNodeID = nodeList->getSessionUUID(); EntityTreePointer entityTree = DependencyManager::get()->getTree(); @@ -45,32 +46,20 @@ void addAvatarEntities(const QVariantList& avatarEntities, std::shared_ptrgetSimulation(); PhysicalEntitySimulationPointer physicalEntitySimulation = std::static_pointer_cast(entitySimulation); EntityEditPacketSender* entityPacketSender = physicalEntitySimulation->getPacketSender(); + QScriptEngine scriptEngine; for (int index = 0; index < avatarEntities.count(); index++) { - const QVariantList& avatarEntityProperties = avatarEntities.at(index).toList(); + const QVariantMap& avatarEntityProperties = avatarEntities.at(index).toMap(); + QVariant variantProperties = avatarEntityProperties["properties"]; + QVariantMap asMap = variantProperties.toMap(); + QScriptValue scriptProperties = variantMapToScriptValue(asMap, scriptEngine); EntityItemProperties entityProperties; + EntityItemPropertiesFromScriptValueHonorReadOnly(scriptProperties, entityProperties); + entityProperties.setParentID(myNodeID); - QString typeName = avatarEntityProperties.value(0).toString(); - entityProperties.setType(EntityTypes::getEntityTypeFromName(typeName)); - QString marketplaceID = avatarEntityProperties.value(1).toString(); - entityProperties.setMarketplaceID(marketplaceID); - int editionNumber = avatarEntityProperties.value(2).toInt(); - entityProperties.setEditionNumber(editionNumber); - QString modelURL = avatarEntityProperties.value(3).toString(); - entityProperties.setModelURL(modelURL); - int parentJointIndex = avatarEntityProperties.value(4).toInt(); - entityProperties.setParentJointIndex(parentJointIndex); - glm::vec3 jointPosition = myAvatar->getJointPosition(parentJointIndex); - glm::vec3 positionOffset = vec3FromJsonValue(avatarEntityProperties.value(5).toJsonValue()); - glm::vec3 finalPosition = jointPosition + positionOffset; - entityProperties.setPosition(finalPosition); - glm::quat jointRotation = myAvatar->getJointRotation(parentJointIndex); - glm::quat rotationOffset = quatFromJsonValue(avatarEntityProperties.value(6).toJsonValue()); - glm::quat finalRotation = jointRotation * rotationOffset; - entityProperties.setRotation(finalRotation); - QString userData = avatarEntityProperties.value(7).toString(); - entityProperties.setUserData(userData); - glm::vec3 dimensions = vec3FromJsonValue(avatarEntityProperties.value(8).toJsonValue()); - entityProperties.setDimensions(dimensions); + entityProperties.setClientOnly(true); + entityProperties.setOwningAvatarID(myNodeID); + entityProperties.setSimulationOwner(myNodeID, AVATAR_ENTITY_SIMULATION_PRIORITY); + entityProperties.markAllChanged(); EntityItemID id = EntityItemID(QUuid::createUuid()); bool success = true; @@ -146,10 +135,11 @@ void AvatarEntitiesBookmarks::applyBookmarkedAvatarEntities() { const QMap bookmark = action->data().toMap(); if (bookmark.value(ENTRY_VERSION) == AVATAR_ENTITIES_BOOKMARK_VERSION) { + myAvatar->removeAvatarEntities(); const QString& avatarUrl = bookmark.value(ENTRY_AVATAR_URL, "").toString(); myAvatar->useFullAvatarURL(avatarUrl); const QVariantList& avatarEntities = bookmark.value(ENTRY_AVATAR_ENTITIES, QVariantList()).toList(); - addAvatarEntities(avatarEntities, myAvatar); + addAvatarEntities(avatarEntities); const float& avatarScale = bookmark.value(ENTRY_AVATAR_SCALE, 1.0f).toFloat(); myAvatar->setAvatarScale(avatarScale); } else { diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp index 7998c150d6..a63f1fb279 100755 --- a/interface/src/avatar/MyAvatar.cpp +++ b/interface/src/avatar/MyAvatar.cpp @@ -1422,34 +1422,31 @@ void MyAvatar::setSkeletonModelURL(const QUrl& skeletonModelURL) { } +void MyAvatar::removeAvatarEntities() { + 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); + } + }); + } +} + QVariantList MyAvatar::getAvatarEntitiesVariant() { QVariantList avatarEntitiesData; + QScriptEngine scriptEngine; forEachChild([&](SpatiallyNestablePointer child) { if (child->getNestableType() == NestableType::Entity) { auto modelEntity = std::dynamic_pointer_cast(child); if (modelEntity) { - QVariantList avatarEntityProperties; + QVariantMap avatarEntityData; EntityItemProperties entityProperties = modelEntity->getProperties(); - - // calculate the entity offset from the parentJointIndex - int jointIndex = entityProperties.getParentJointIndex(); - glm::quat jointRotation = getJointRotation(jointIndex); - glm::quat entityRotation = modelEntity->getWorldOrientation(); - glm::vec3 jointPosition = getJointPosition(jointIndex); - glm::vec3 entityPosition = modelEntity->getWorldPosition(); - glm::quat rotationOffset = glm::inverse(jointRotation) * entityRotation; - glm::vec3 positionOffset = entityPosition - jointPosition; - - avatarEntityProperties.append(QVariant(EntityTypes::getEntityTypeName(entityProperties.getType()))); - avatarEntityProperties.append(QVariant(entityProperties.getMarketplaceID())); - avatarEntityProperties.append(QVariant(entityProperties.getEditionNumber())); - avatarEntityProperties.append(QVariant(entityProperties.getModelURL())); - avatarEntityProperties.append(QVariant(jointIndex)); - avatarEntityProperties.append(QVariant(toJsonValue(positionOffset))); - avatarEntityProperties.append(QVariant(toJsonValue(rotationOffset))); - avatarEntityProperties.append(QVariant(entityProperties.getUserData())); - avatarEntityProperties.append(QVariant(toJsonValue(entityProperties.getDimensions()))); - avatarEntitiesData.append(QVariant(avatarEntityProperties)); + QScriptValue scriptProperties = EntityItemPropertiesToScriptValue(&scriptEngine, entityProperties); + avatarEntityData["properties"] = scriptProperties.toVariant(); + avatarEntitiesData.append(QVariant(avatarEntityData)); } } }); diff --git a/interface/src/avatar/MyAvatar.h b/interface/src/avatar/MyAvatar.h index 45a3773e1a..ad9c227ecf 100644 --- a/interface/src/avatar/MyAvatar.h +++ b/interface/src/avatar/MyAvatar.h @@ -511,6 +511,7 @@ public: bool hasDriveInput() const; QVariantList getAvatarEntitiesVariant(); + void removeAvatarEntities(); Q_INVOKABLE bool isFlying(); Q_INVOKABLE bool isInAir(); From 139266fe80c1662d40190c1c2a9286b853721858 Mon Sep 17 00:00:00 2001 From: Dante Ruiz Date: Fri, 19 Jan 2018 11:24:06 -0800 Subject: [PATCH 7/9] remove unneeded code --- interface/src/AvatarEntitiesBookmarks.cpp | 17 ----------------- interface/src/AvatarEntitiesBookmarks.h | 1 - 2 files changed, 18 deletions(-) diff --git a/interface/src/AvatarEntitiesBookmarks.cpp b/interface/src/AvatarEntitiesBookmarks.cpp index 11d0d88368..437db595d3 100644 --- a/interface/src/AvatarEntitiesBookmarks.cpp +++ b/interface/src/AvatarEntitiesBookmarks.cpp @@ -93,23 +93,6 @@ void addAvatarEntities(const QVariantList& avatarEntities) { AvatarEntitiesBookmarks::AvatarEntitiesBookmarks() { _bookmarksFilename = PathUtils::getAppDataPath() + "/" + AVATAR_ENTITIES_BOOKMARKS_FILENAME; - readFromFile(); -} - -void AvatarEntitiesBookmarks::readFromFile() { - QString oldConfigPath = QStandardPaths::writableLocation(QStandardPaths::DataLocation) + "/" + AVATAR_ENTITIES_BOOKMARKS_FILENAME; - QFile oldConfig(oldConfigPath); - // I imagine that in a year from now, this code for migrating (as well as the two lines above) - // may be removed since all bookmarks should have been migrated by then - // - Robbie Uvanni (6.8.2017) - if (oldConfig.exists()) { - if (QDir().rename(oldConfigPath, _bookmarksFilename)) { - qCDebug(interfaceapp) << "Successfully migrated" << AVATAR_ENTITIES_BOOKMARKS_FILENAME; - } else { - qCDebug(interfaceapp) << "Failed to migrate" << AVATAR_ENTITIES_BOOKMARKS_FILENAME; - } - } - Bookmarks::readFromFile(); } diff --git a/interface/src/AvatarEntitiesBookmarks.h b/interface/src/AvatarEntitiesBookmarks.h index 12e8c47768..310ec09f70 100644 --- a/interface/src/AvatarEntitiesBookmarks.h +++ b/interface/src/AvatarEntitiesBookmarks.h @@ -28,7 +28,6 @@ public slots: protected: void addBookmarkToMenu(Menu* menubar, const QString& name, const QVariant& bookmark) override; - void readFromFile() override; private: const QString AVATAR_ENTITIES_BOOKMARKS_FILENAME = "AvatarEntitiesBookmarks.json"; From c71fa110dbda9a69ba225f8f29e88ecdefcd4525 Mon Sep 17 00:00:00 2001 From: Dante Ruiz Date: Fri, 19 Jan 2018 11:31:13 -0800 Subject: [PATCH 8/9] update file dates and remove debug state --- interface/src/AvatarEntitiesBookmarks.cpp | 4 ++-- interface/src/AvatarEntitiesBookmarks.h | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/interface/src/AvatarEntitiesBookmarks.cpp b/interface/src/AvatarEntitiesBookmarks.cpp index 437db595d3..2a70d1a42f 100644 --- a/interface/src/AvatarEntitiesBookmarks.cpp +++ b/interface/src/AvatarEntitiesBookmarks.cpp @@ -2,8 +2,8 @@ // AvatarEntitiesBookmarks.cpp // interface/src // -// Created by Dante Ruiz on /01/18. -// Copyright 2017 High Fidelity, Inc. +// Created by Dante Ruiz on 15/01/18. +// Copyright 2018 High Fidelity, Inc. // // Distributed under the Apache License, Version 2.0. // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html diff --git a/interface/src/AvatarEntitiesBookmarks.h b/interface/src/AvatarEntitiesBookmarks.h index 310ec09f70..0c70e4dbc0 100644 --- a/interface/src/AvatarEntitiesBookmarks.h +++ b/interface/src/AvatarEntitiesBookmarks.h @@ -3,7 +3,7 @@ // interface/src // // Created by Dante Ruiz on 15/01/18. -// Copyright 2017 High Fidelity, Inc. +// Copyright 2018 High Fidelity, Inc. // // Distributed under the Apache License, Version 2.0. // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html From a637bac2fee71c2e4a78f885462bea5c568b81ab Mon Sep 17 00:00:00 2001 From: Dante Ruiz Date: Mon, 29 Jan 2018 11:26:28 -0800 Subject: [PATCH 9/9] remove debug statement --- interface/src/AvatarEntitiesBookmarks.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/interface/src/AvatarEntitiesBookmarks.cpp b/interface/src/AvatarEntitiesBookmarks.cpp index 2a70d1a42f..d108bf3a23 100644 --- a/interface/src/AvatarEntitiesBookmarks.cpp +++ b/interface/src/AvatarEntitiesBookmarks.cpp @@ -111,7 +111,6 @@ void AvatarEntitiesBookmarks::setupMenus(Menu* menubar, MenuWrapper* menu) { } void AvatarEntitiesBookmarks::applyBookmarkedAvatarEntities() { - qDebug() << "AvatarEntitiesBookmarks::applyBookmarkedAvatarEntities"; QAction* action = qobject_cast(sender()); auto myAvatar = DependencyManager::get()->getMyAvatar();