From 4e9d162172c7c28c3d813373e1d8d4566ec164a3 Mon Sep 17 00:00:00 2001 From: David Rowe Date: Sun, 24 Feb 2019 13:23:20 +1300 Subject: [PATCH 01/18] AccountServices, HifiAbout, and WalletScriptingInterface JSDoc review --- interface/src/AboutUtil.h | 14 ++++---- interface/src/commerce/Wallet.h | 8 ++--- .../AccountServicesScriptingInterface.cpp | 4 +-- .../AccountServicesScriptingInterface.h | 32 +++++++++---------- .../src/scripting/WalletScriptingInterface.h | 22 ++++++------- 5 files changed, 40 insertions(+), 40 deletions(-) diff --git a/interface/src/AboutUtil.h b/interface/src/AboutUtil.h index c06255aaa5..4a5074857d 100644 --- a/interface/src/AboutUtil.h +++ b/interface/src/AboutUtil.h @@ -16,8 +16,8 @@ #include /**jsdoc - * The HifiAbout API provides information about the version of Interface that is currently running. It also - * provides the ability to open a Web page in an Interface browser window. + * The HifiAbout API provides information about the version of Interface that is currently running. It also + * has the functionality to open a web page in an Interface browser window. * * @namespace HifiAbout * @@ -30,9 +30,9 @@ * @property {string} qtVersion - The Qt version used in Interface that is currently running. Read-only. * * @example Report build information for the version of Interface currently running. - * print("HiFi build date: " + HifiAbout.buildDate); // 11 Feb 2019 - * print("HiFi version: " + HifiAbout.buildVersion); // 0.78.0 - * print("Qt version: " + HifiAbout.qtVersion); // 5.10.1 + * print("HiFi build date: " + HifiAbout.buildDate); // Returns the build date of the version of Interface currently running on your machine. + * print("HiFi version: " + HifiAbout.buildVersion); // Returns the build version of Interface currently running on your machine. + * print("Qt version: " + HifiAbout.qtVersion); // Returns the Qt version details of the version of Interface currently running on your machine. */ class AboutUtil : public QObject { @@ -52,9 +52,9 @@ public: public slots: /**jsdoc - * Display a Web page in an Interface browser window. + * Display a web page in an Interface browser window. * @function HifiAbout.openUrl - * @param {string} url - The URL of the Web page to display. + * @param {string} url - The URL of the web page you want to view in Interface. */ void openUrl(const QString &url) const; private: diff --git a/interface/src/commerce/Wallet.h b/interface/src/commerce/Wallet.h index 5e5e6c9b4f..fdd6b5e2a6 100644 --- a/interface/src/commerce/Wallet.h +++ b/interface/src/commerce/Wallet.h @@ -62,8 +62,8 @@ public: * ValueMeaningDescription * * - * 0Not logged inThe user isn't logged in. - * 1Not set upThe user's wallet isn't set up. + * 0Not logged inThe user is not logged in. + * 1Not set upThe user's wallet has not been set up. * 2Pre-existingThere is a wallet present on the server but not one * locally. * 3ConflictingThere is a wallet present on the server plus one present locally, @@ -73,8 +73,8 @@ public: * 5ReadyThe wallet is ready for use. * * - *

Wallets used to be stored locally but now they're stored on the server, unless the computer once had a wallet stored - * locally in which case the wallet may be present in both places.

+ *

Wallets used to be stored locally but now they're only stored on the server. A wallet is present in both places if + * your computer previously stored its information locally.

* @typedef {number} WalletScriptingInterface.WalletStatus */ enum WalletStatus { diff --git a/interface/src/scripting/AccountServicesScriptingInterface.cpp b/interface/src/scripting/AccountServicesScriptingInterface.cpp index a3597886e9..5ede7c7a98 100644 --- a/interface/src/scripting/AccountServicesScriptingInterface.cpp +++ b/interface/src/scripting/AccountServicesScriptingInterface.cpp @@ -115,8 +115,8 @@ DownloadInfoResult::DownloadInfoResult() : /**jsdoc * Information on the assets currently being downloaded and pending download. * @typedef {object} AccountServices.DownloadInfoResult - * @property {number[]} downloading - The percentage complete for each asset currently being downloaded. - * @property {number} pending - The number of assets waiting to be download. + * @property {number[]} downloading - The download percentage of each asset currently downloading. + * @property {number} pending - The number of assets pending download. */ QScriptValue DownloadInfoResultToScriptValue(QScriptEngine* engine, const DownloadInfoResult& result) { QScriptValue object = engine->newObject(); diff --git a/interface/src/scripting/AccountServicesScriptingInterface.h b/interface/src/scripting/AccountServicesScriptingInterface.h index c08181d7c9..b5c4a6e0df 100644 --- a/interface/src/scripting/AccountServicesScriptingInterface.h +++ b/interface/src/scripting/AccountServicesScriptingInterface.h @@ -38,19 +38,19 @@ class AccountServicesScriptingInterface : public QObject { Q_OBJECT /**jsdoc - * The AccountServices API provides functions related to user connectivity, visibility, and asset download - * progress. + * The AccountServices API provides functions that give information on user connectivity, visibility, and + * asset download progress. * * @hifi-interface * @hifi-client-entity * @hifi-avatar * * @namespace AccountServices - * @property {string} username - The user name if the user is logged in, otherwise "Unknown user". - * Read-only. + * @property {string} username - The user name of the user logged in. If there is no user logged in, it is + * "Unknown user". Read-only. * @property {boolean} loggedIn - true if the user is logged in, otherwise false. * Read-only. - * @property {string} findableBy - The user's visibility to other people:
+ * @property {string} findableBy - The user's visibility to other users:
* "none" - user appears offline.
* "friends" - user is visible only to friends.
* "connections" - user is visible to friends and connections.
@@ -74,23 +74,23 @@ public: public slots: /**jsdoc - * Get information on the progress of downloading assets in the domain. + * Gets information on the download progress of assets in the domain. * @function AccountServices.getDownloadInfo - * @returns {AccountServices.DownloadInfoResult} Information on the progress of assets download. + * @returns {AccountServices.DownloadInfoResult} Information on the download progress of assets. */ DownloadInfoResult getDownloadInfo(); /**jsdoc - * Cause a {@link AccountServices.downloadInfoChanged|downloadInfoChanged} signal to be triggered with information on the - * current progress of the download of assets in the domain. + * Triggers a {@link AccountServices.downloadInfoChanged|downloadInfoChanged} signal with information on the current + * download progress of the assets in the domain. * @function AccountServices.updateDownloadInfo */ void updateDownloadInfo(); /**jsdoc - * Check whether the user is logged in. + * Checks whether the user is logged in. * @function AccountServices.isLoggedIn - * @returns {boolean} true if the user is logged in, false otherwise. + * @returns {boolean} true if the user is logged in, false if not. * @example Report whether you are logged in. * var isLoggedIn = AccountServices.isLoggedIn(); * print("You are logged in: " + isLoggedIn); // true or false @@ -100,7 +100,7 @@ public slots: /**jsdoc * Prompts the user to log in (the login dialog is displayed) if they're not already logged in. * @function AccountServices.checkAndSignalForAccessToken - * @returns {boolean} true if the user is already logged in, false otherwise. + * @returns {boolean} true if the user is logged in, false if not. */ bool checkAndSignalForAccessToken(); @@ -140,7 +140,7 @@ signals: /**jsdoc * Triggered when the username logged in with changes, i.e., when the user logs in or out. * @function AccountServices.myUsernameChanged - * @param {string} username - The username logged in with if the user is logged in, otherwise "". + * @param {string} username - The user name of the user logged in. If there is no user logged in, it is "". * @returns {Signal} * @example Report when your username changes. * AccountServices.myUsernameChanged.connect(function (username) { @@ -150,9 +150,9 @@ signals: void myUsernameChanged(const QString& username); /**jsdoc - * Triggered when the progress of the download of assets for the domain changes. + * Triggered when the download progress of the assets in the domain changes. * @function AccountServices.downloadInfoChanged - * @param {AccountServices.DownloadInfoResult} downloadInfo - Information on the progress of assets download. + * @param {AccountServices.DownloadInfoResult} downloadInfo - Information on the download progress of assets. * @returns {Signal} */ void downloadInfoChanged(DownloadInfoResult info); @@ -186,7 +186,7 @@ signals: /**jsdoc * Triggered when the login status of the user changes. * @function AccountServices.loggedInChanged - * @param {boolean} loggedIn - true if the user is logged in, otherwise false. + * @param {boolean} loggedIn - true if the user is logged in, false if not. * @returns {Signal} * @example Report when your login status changes. * AccountServices.loggedInChanged.connect(function(loggedIn) { diff --git a/interface/src/scripting/WalletScriptingInterface.h b/interface/src/scripting/WalletScriptingInterface.h index 7482b8be00..3ef9c7953a 100644 --- a/interface/src/scripting/WalletScriptingInterface.h +++ b/interface/src/scripting/WalletScriptingInterface.h @@ -41,8 +41,8 @@ public: * * @property {WalletScriptingInterface.WalletStatus} walletStatus - The status of the user's wallet. Read-only. * @property {boolean} limitedCommerce - true if Interface is running in limited commerce mode. In limited commerce - * mode, certain Interface functionality is disabled, e.g., users can't buy non-free items from the Marketplace. The Oculus - * Store version of Interface runs in limited commerce mode. Read-only. + * mode, certain Interface functionalities are disabled, e.g., users can't buy items that are not free from the Marketplace. + * The Oculus Store version of Interface runs in limited commerce mode. Read-only. */ class WalletScriptingInterface : public QObject, public Dependency { Q_OBJECT @@ -55,16 +55,16 @@ public: WalletScriptingInterface(); /**jsdoc - * Check and update the user's wallet status. + * Checks and updates the user's wallet status. * @function WalletScriptingInterface.refreshWalletStatus */ Q_INVOKABLE void refreshWalletStatus(); /**jsdoc - * Get the current status of the user's wallet. + * Gets the current status of the user's wallet. * @function WalletScriptingInterface.getWalletStatus * @returns {WalletScriptingInterface.WalletStatus} - * @example Two ways to report your wallet status. + * @example Use two methods to report your wallet's status. * print("Wallet status: " + WalletScriptingInterface.walletStatus); // Same value as next line. * print("Wallet status: " + WalletScriptingInterface.getWalletStatus()); */ @@ -74,11 +74,11 @@ public: * Check that a certified avatar entity is owned by the avatar whose entity it is. The result of the check is provided via * the {@link WalletScriptingInterface.ownershipVerificationSuccess|ownershipVerificationSuccess} and * {@link WalletScriptingInterface.ownershipVerificationFailed|ownershipVerificationFailed} signals.
- * Warning: Neither of these signals fire if the entity is not an avatar entity or it's not a certified - * entity. + * Warning: Neither of these signals are triggered if the entity is not an avatar entity or is not + * certified. * @function WalletScriptingInterface.proveAvatarEntityOwnershipVerification - * @param {Uuid} entityID - The ID of the avatar entity to check. - * @example Check ownership of all nearby certified avatar entities. + * @param {Uuid} entityID - The avatar entity's ID. + * @example Check the ownership of all nearby certified avatar entities. * // Set up response handling. * function ownershipSuccess(entityID) { * print("Ownership test succeeded for: " + entityID); @@ -118,7 +118,7 @@ public: signals: /**jsdoc - * Triggered when the status of the user's wallet changes. + * Triggered when the user's wallet status changes. * @function WalletScriptingInterface.walletStatusChanged * @returns {Signal} * @example Report when your wallet status changes, e.g., when you log in and out. @@ -136,7 +136,7 @@ signals: void limitedCommerceChanged(); /**jsdoc - * Triggered when the user rezzes a certified entity but the user's wallet is not ready and so the certified location of the + * Triggered when the user rezzes a certified entity but the user's wallet is not ready. So the certified location of the * entity cannot be updated in the metaverse. * @function WalletScriptingInterface.walletNotSetup * @returns {Signal} From 2bcee4e454f4a727800e3d6081a9367079b319ae Mon Sep 17 00:00:00 2001 From: nimisha20 Date: Mon, 25 Feb 2019 08:54:47 -0800 Subject: [PATCH 02/18] Update AccountServicesScriptingInterface.cpp Changes according to ctrlaltdavid's comments. --- interface/src/scripting/AccountServicesScriptingInterface.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/interface/src/scripting/AccountServicesScriptingInterface.cpp b/interface/src/scripting/AccountServicesScriptingInterface.cpp index 5ede7c7a98..5f8fb065ff 100644 --- a/interface/src/scripting/AccountServicesScriptingInterface.cpp +++ b/interface/src/scripting/AccountServicesScriptingInterface.cpp @@ -115,7 +115,7 @@ DownloadInfoResult::DownloadInfoResult() : /**jsdoc * Information on the assets currently being downloaded and pending download. * @typedef {object} AccountServices.DownloadInfoResult - * @property {number[]} downloading - The download percentage of each asset currently downloading. + * @property {number[]} downloading - The download percentage remaining of each asset currently downloading. * @property {number} pending - The number of assets pending download. */ QScriptValue DownloadInfoResultToScriptValue(QScriptEngine* engine, const DownloadInfoResult& result) { From e20f13f0ae8a17aa01ed0911a86228e94a905dea Mon Sep 17 00:00:00 2001 From: nimisha20 Date: Mon, 25 Feb 2019 09:28:56 -0800 Subject: [PATCH 03/18] Update AccountServicesScriptingInterface.h Adding ctrlaltdavid's changes --- interface/src/scripting/AccountServicesScriptingInterface.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/interface/src/scripting/AccountServicesScriptingInterface.h b/interface/src/scripting/AccountServicesScriptingInterface.h index b5c4a6e0df..415b405e53 100644 --- a/interface/src/scripting/AccountServicesScriptingInterface.h +++ b/interface/src/scripting/AccountServicesScriptingInterface.h @@ -98,7 +98,7 @@ public slots: bool isLoggedIn(); /**jsdoc - * Prompts the user to log in (the login dialog is displayed) if they're not already logged in. + * Prompts the user to log in (with a login dialog) if they're not already logged in. The function returns if the user is logged in or not before the user completes the login dialog. * @function AccountServices.checkAndSignalForAccessToken * @returns {boolean} true if the user is logged in, false if not. */ From 4825ecdbf35c78b624c739128a790f147530e52c Mon Sep 17 00:00:00 2001 From: nimisha20 Date: Mon, 25 Feb 2019 22:44:16 -0800 Subject: [PATCH 04/18] Update AccountServicesScriptingInterface.h --- interface/src/scripting/AccountServicesScriptingInterface.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/interface/src/scripting/AccountServicesScriptingInterface.h b/interface/src/scripting/AccountServicesScriptingInterface.h index 415b405e53..1555caba3c 100644 --- a/interface/src/scripting/AccountServicesScriptingInterface.h +++ b/interface/src/scripting/AccountServicesScriptingInterface.h @@ -98,7 +98,7 @@ public slots: bool isLoggedIn(); /**jsdoc - * Prompts the user to log in (with a login dialog) if they're not already logged in. The function returns if the user is logged in or not before the user completes the login dialog. + * Prompts the user to log in (with a login dialog) if they're not already logged in. The function returns a value before the user completes the login dialog. * @function AccountServices.checkAndSignalForAccessToken * @returns {boolean} true if the user is logged in, false if not. */ From 736a050e6808ff0913e819558937d3b06d8d9e3c Mon Sep 17 00:00:00 2001 From: nimisha20 Date: Mon, 25 Feb 2019 22:55:56 -0800 Subject: [PATCH 05/18] Update AccountServicesScriptingInterface.h --- interface/src/scripting/AccountServicesScriptingInterface.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/interface/src/scripting/AccountServicesScriptingInterface.h b/interface/src/scripting/AccountServicesScriptingInterface.h index 1555caba3c..b5bee6a7e4 100644 --- a/interface/src/scripting/AccountServicesScriptingInterface.h +++ b/interface/src/scripting/AccountServicesScriptingInterface.h @@ -98,7 +98,7 @@ public slots: bool isLoggedIn(); /**jsdoc - * Prompts the user to log in (with a login dialog) if they're not already logged in. The function returns a value before the user completes the login dialog. + * The function returns the log in status of the user and prompts the user to log in (with a login dialog) if they're not already logged in. * @function AccountServices.checkAndSignalForAccessToken * @returns {boolean} true if the user is logged in, false if not. */ From ba3895efdd942ed40d24ad5134b23d5bc05c4756 Mon Sep 17 00:00:00 2001 From: nimisha20 Date: Mon, 25 Feb 2019 22:56:36 -0800 Subject: [PATCH 06/18] Update AccountServicesScriptingInterface.h Minor copy-edit --- interface/src/scripting/AccountServicesScriptingInterface.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/interface/src/scripting/AccountServicesScriptingInterface.h b/interface/src/scripting/AccountServicesScriptingInterface.h index b5bee6a7e4..b188b4e63b 100644 --- a/interface/src/scripting/AccountServicesScriptingInterface.h +++ b/interface/src/scripting/AccountServicesScriptingInterface.h @@ -98,7 +98,7 @@ public slots: bool isLoggedIn(); /**jsdoc - * The function returns the log in status of the user and prompts the user to log in (with a login dialog) if they're not already logged in. + * The function returns the login status of the user and prompts the user to log in (with a login dialog) if they're not already logged in. * @function AccountServices.checkAndSignalForAccessToken * @returns {boolean} true if the user is logged in, false if not. */ From db1c78246fc640971ea55f273a1132ac4966e2ce Mon Sep 17 00:00:00 2001 From: luiscuenca Date: Tue, 26 Feb 2019 11:32:43 -0700 Subject: [PATCH 07/18] Read and apply the FBX upVector parameter --- libraries/fbx/src/FBXSerializer.cpp | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/libraries/fbx/src/FBXSerializer.cpp b/libraries/fbx/src/FBXSerializer.cpp index 9e7f422b40..3c8aa8f799 100644 --- a/libraries/fbx/src/FBXSerializer.cpp +++ b/libraries/fbx/src/FBXSerializer.cpp @@ -167,7 +167,6 @@ glm::mat4 getGlobalTransform(const QMultiMap& _connectionParen } } } - return globalTransform; } @@ -436,6 +435,8 @@ HFMModel* FBXSerializer::extractHFMModel(const QVariantHash& mapping, const QStr hfmModel.originalURL = url; float unitScaleFactor = 1.0f; + glm::quat upAxisZRotation; + bool applyUpAxisZRotation = false; glm::vec3 ambientColor; QString hifiGlobalNodeID; unsigned int meshIndex = 0; @@ -473,11 +474,20 @@ HFMModel* FBXSerializer::extractHFMModel(const QVariantHash& mapping, const QStr if (subobject.name == propertyName) { static const QVariant UNIT_SCALE_FACTOR = QByteArray("UnitScaleFactor"); static const QVariant AMBIENT_COLOR = QByteArray("AmbientColor"); + static const QVariant UP_AXIS = QByteArray("UpAxis"); const auto& subpropName = subobject.properties.at(0); if (subpropName == UNIT_SCALE_FACTOR) { unitScaleFactor = subobject.properties.at(index).toFloat(); } else if (subpropName == AMBIENT_COLOR) { ambientColor = getVec3(subobject.properties, index); + } else if (subpropName == UP_AXIS) { + constexpr int UP_AXIS_Y = 1; + constexpr int UP_AXIS_Z = 2; + int upAxis = subobject.properties.at(index).toInt(); + if (upAxis == UP_AXIS_Z) { + upAxisZRotation = glm::angleAxis(glm::radians(-90.0f), glm::vec3(1.0f, 0.0f, 0.0f)); + applyUpAxisZRotation = true; + } } } } @@ -1271,7 +1281,6 @@ HFMModel* FBXSerializer::extractHFMModel(const QVariantHash& mapping, const QStr hfmModel.hasSkeletonJoints = (hfmModel.hasSkeletonJoints || joint.isSkeletonJoint); glm::quat combinedRotation = joint.preRotation * joint.rotation * joint.postRotation; - if (joint.parentIndex == -1) { joint.transform = hfmModel.offset * glm::translate(joint.translation) * joint.preTransform * glm::mat4_cast(combinedRotation) * joint.postTransform; @@ -1664,6 +1673,9 @@ HFMModel* FBXSerializer::extractHFMModel(const QVariantHash& mapping, const QStr } } + if (applyUpAxisZRotation) { + hfmModelPtr->bindExtents.rotate(upAxisZRotation); + } return hfmModelPtr; } From f47ec099273548a1300be6699571727bc29aaf32 Mon Sep 17 00:00:00 2001 From: luiscuenca Date: Tue, 26 Feb 2019 14:01:30 -0700 Subject: [PATCH 08/18] use UP_AXIS_Y --- libraries/fbx/src/FBXSerializer.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/libraries/fbx/src/FBXSerializer.cpp b/libraries/fbx/src/FBXSerializer.cpp index 3c8aa8f799..0b31eda94b 100644 --- a/libraries/fbx/src/FBXSerializer.cpp +++ b/libraries/fbx/src/FBXSerializer.cpp @@ -484,7 +484,9 @@ HFMModel* FBXSerializer::extractHFMModel(const QVariantHash& mapping, const QStr constexpr int UP_AXIS_Y = 1; constexpr int UP_AXIS_Z = 2; int upAxis = subobject.properties.at(index).toInt(); - if (upAxis == UP_AXIS_Z) { + if (upAxis == UP_AXIS_Y) { + // No update necessary, y up is the default + } else if (upAxis == UP_AXIS_Z) { upAxisZRotation = glm::angleAxis(glm::radians(-90.0f), glm::vec3(1.0f, 0.0f, 0.0f)); applyUpAxisZRotation = true; } From ff7995ae18a9e6262fbb58167912ce9240f9b586 Mon Sep 17 00:00:00 2001 From: luiscuenca Date: Tue, 26 Feb 2019 18:29:55 -0700 Subject: [PATCH 09/18] Right fix --- libraries/fbx/src/FBXSerializer.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/libraries/fbx/src/FBXSerializer.cpp b/libraries/fbx/src/FBXSerializer.cpp index 0b31eda94b..e022ca8921 100644 --- a/libraries/fbx/src/FBXSerializer.cpp +++ b/libraries/fbx/src/FBXSerializer.cpp @@ -1281,7 +1281,9 @@ HFMModel* FBXSerializer::extractHFMModel(const QVariantHash& mapping, const QStr joint.geometricScaling = fbxModel.geometricScaling; joint.isSkeletonJoint = fbxModel.isLimbNode; hfmModel.hasSkeletonJoints = (hfmModel.hasSkeletonJoints || joint.isSkeletonJoint); - + if (applyUpAxisZRotation && joint.parentIndex == -1 && !joint.isSkeletonJoint) { + joint.rotation *= upAxisZRotation; + } glm::quat combinedRotation = joint.preRotation * joint.rotation * joint.postRotation; if (joint.parentIndex == -1) { joint.transform = hfmModel.offset * glm::translate(joint.translation) * joint.preTransform * @@ -1676,6 +1678,7 @@ HFMModel* FBXSerializer::extractHFMModel(const QVariantHash& mapping, const QStr } if (applyUpAxisZRotation) { + hfmModelPtr->meshExtents.rotate(upAxisZRotation); hfmModelPtr->bindExtents.rotate(upAxisZRotation); } return hfmModelPtr; From 3e6061e4350684f88e2313cbed423a40a324821b Mon Sep 17 00:00:00 2001 From: SamGondelman Date: Fri, 1 Mar 2019 13:45:00 -0800 Subject: [PATCH 10/18] try to not clear my avatar entities on domain switch --- interface/src/Application.cpp | 2 +- .../src/EntityTreeRenderer.cpp | 24 +++++++++---------- .../src/EntityTreeRenderer.h | 6 ++--- libraries/entities/src/EntityTree.cpp | 16 +++++++------ libraries/entities/src/EntityTree.h | 3 ++- libraries/entities/src/EntityTreeElement.cpp | 4 ++-- libraries/entities/src/EntityTreeElement.h | 2 +- libraries/octree/src/Octree.h | 2 +- libraries/octree/src/OctreeProcessor.cpp | 4 ++-- libraries/octree/src/OctreeProcessor.h | 2 +- 10 files changed, 34 insertions(+), 31 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 29d260cb5f..1a64378c36 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -6948,7 +6948,7 @@ void Application::clearDomainOctreeDetails(bool clearAll) { }); // reset the model renderer - clearAll ? getEntities()->clear() : getEntities()->clearNonLocalEntities(); + clearAll ? getEntities()->clear() : getEntities()->clearDomainAndNonOwnedEntities(); auto skyStage = DependencyManager::get()->getSkyStage(); diff --git a/libraries/entities-renderer/src/EntityTreeRenderer.cpp b/libraries/entities-renderer/src/EntityTreeRenderer.cpp index e54258fc3e..1e2c17fa8e 100644 --- a/libraries/entities-renderer/src/EntityTreeRenderer.cpp +++ b/libraries/entities-renderer/src/EntityTreeRenderer.cpp @@ -196,8 +196,8 @@ void EntityTreeRenderer::resetEntitiesScriptEngine() { }); } -void EntityTreeRenderer::stopNonLocalEntityScripts() { - leaveNonLocalEntities(); +void EntityTreeRenderer::stopDomainAndNonOwnedEntities() { + leaveDomainAndNonOwnedEntities(); // unload and stop the engine if (_entitiesScriptEngine) { QList entitiesWithEntityScripts = _entitiesScriptEngine->getListOfEntityScriptIDs(); @@ -206,7 +206,7 @@ void EntityTreeRenderer::stopNonLocalEntityScripts() { EntityItemPointer entityItem = getTree()->findEntityByEntityItemID(entityID); if (entityItem) { - if (!entityItem->isLocalEntity()) { + if (!(entityItem->isLocalEntity() || (entityItem->isAvatarEntity() && entityItem->getOwningAvatarID() == getTree()->getMyAvatarSessionUUID()))) { _entitiesScriptEngine->unloadEntityScript(entityID, true); } } @@ -214,8 +214,8 @@ void EntityTreeRenderer::stopNonLocalEntityScripts() { } } -void EntityTreeRenderer::clearNonLocalEntities() { - stopNonLocalEntityScripts(); +void EntityTreeRenderer::clearDomainAndNonOwnedEntities() { + stopDomainAndNonOwnedEntities(); std::unordered_map savedEntities; // remove all entities from the scene @@ -225,7 +225,7 @@ void EntityTreeRenderer::clearNonLocalEntities() { for (const auto& entry : _entitiesInScene) { const auto& renderer = entry.second; const EntityItemPointer& entityItem = renderer->getEntity(); - if (!entityItem->isLocalEntity()) { + if (!(entityItem->isLocalEntity() || (entityItem->isAvatarEntity() && entityItem->getOwningAvatarID() == getTree()->getMyAvatarSessionUUID()))) { renderer->removeFromScene(scene, transaction); } else { savedEntities[entry.first] = entry.second; @@ -239,7 +239,7 @@ void EntityTreeRenderer::clearNonLocalEntities() { _layeredZones.clearNonLocalLayeredZones(); - OctreeProcessor::clearNonLocalEntities(); + OctreeProcessor::clearDomainAndNonOwnedEntities(); } void EntityTreeRenderer::clear() { @@ -655,22 +655,22 @@ bool EntityTreeRenderer::checkEnterLeaveEntities() { return didUpdate; } -void EntityTreeRenderer::leaveNonLocalEntities() { +void EntityTreeRenderer::leaveDomainAndNonOwnedEntities() { if (_tree && !_shuttingDown) { - QVector currentLocalEntitiesInside; + QVector currentEntitiesInsideToSave; foreach (const EntityItemID& entityID, _currentEntitiesInside) { EntityItemPointer entityItem = getTree()->findEntityByEntityItemID(entityID); - if (!entityItem->isLocalEntity()) { + if (!(entityItem->isLocalEntity() || (entityItem->isAvatarEntity() && entityItem->getOwningAvatarID() == getTree()->getMyAvatarSessionUUID()))) { emit leaveEntity(entityID); if (_entitiesScriptEngine) { _entitiesScriptEngine->callEntityScriptMethod(entityID, "leaveEntity"); } } else { - currentLocalEntitiesInside.push_back(entityID); + currentEntitiesInsideToSave.push_back(entityID); } } - _currentEntitiesInside = currentLocalEntitiesInside; + _currentEntitiesInside = currentEntitiesInsideToSave; forceRecheckEntities(); } } diff --git a/libraries/entities-renderer/src/EntityTreeRenderer.h b/libraries/entities-renderer/src/EntityTreeRenderer.h index 51568ab744..b4d3507c17 100644 --- a/libraries/entities-renderer/src/EntityTreeRenderer.h +++ b/libraries/entities-renderer/src/EntityTreeRenderer.h @@ -87,7 +87,7 @@ public: virtual void init() override; /// clears the tree - virtual void clearNonLocalEntities() override; + virtual void clearDomainAndNonOwnedEntities() override; virtual void clear() override; /// reloads the entity scripts, calling unload and preload @@ -170,7 +170,7 @@ private: bool findBestZoneAndMaybeContainingEntities(QVector* entitiesContainingAvatar = nullptr); bool applyLayeredZones(); - void stopNonLocalEntityScripts(); + void stopDomainAndNonOwnedEntities(); void checkAndCallPreload(const EntityItemID& entityID, bool reload = false, bool unloadFirst = false); @@ -179,7 +179,7 @@ private: QScriptValueList createEntityArgs(const EntityItemID& entityID); bool checkEnterLeaveEntities(); - void leaveNonLocalEntities(); + void leaveDomainAndNonOwnedEntities(); void leaveAllEntities(); void forceRecheckEntities(); diff --git a/libraries/entities/src/EntityTree.cpp b/libraries/entities/src/EntityTree.cpp index 6e404ce690..cdf021638b 100644 --- a/libraries/entities/src/EntityTree.cpp +++ b/libraries/entities/src/EntityTree.cpp @@ -78,13 +78,14 @@ OctreeElementPointer EntityTree::createNewElement(unsigned char* octalCode) { return std::static_pointer_cast(newElement); } -void EntityTree::eraseNonLocalEntities() { +void EntityTree::eraseDomainAndNonOwnedEntities() { emit clearingEntities(); if (_simulation) { // local entities are not in the simulation, so we clear ALL _simulation->clearEntities(); } + this->withWriteLock([&] { QHash savedEntities; // NOTE: lock the Tree first, then lock the _entityMap. @@ -93,10 +94,10 @@ void EntityTree::eraseNonLocalEntities() { foreach(EntityItemPointer entity, _entityMap) { EntityTreeElementPointer element = entity->getElement(); if (element) { - element->cleanupNonLocalEntities(); + element->cleanupDomainAndNonOwnedEntities(); } - if (entity->isLocalEntity()) { + if (entity->isLocalEntity() || (entity->isAvatarEntity() && entity->getOwningAvatarID() == getMyAvatarSessionUUID())) { savedEntities[entity->getEntityItemID()] = entity; } else { int32_t spaceIndex = entity->getSpaceIndex(); @@ -114,15 +115,16 @@ void EntityTree::eraseNonLocalEntities() { { QWriteLocker locker(&_needsParentFixupLock); - QVector localEntitiesNeedsParentFixup; + QVector needParentFixup; foreach (EntityItemWeakPointer entityItem, _needsParentFixup) { - if (!entityItem.expired() && entityItem.lock()->isLocalEntity()) { - localEntitiesNeedsParentFixup.push_back(entityItem); + auto entity = entityItem.lock(); + if (entity && (entity->isLocalEntity() || (entity->isAvatarEntity() && entity->getOwningAvatarID() == getMyAvatarSessionUUID()))) { + needParentFixup.push_back(entityItem); } } - _needsParentFixup = localEntitiesNeedsParentFixup; + _needsParentFixup = needParentFixup; } } diff --git a/libraries/entities/src/EntityTree.h b/libraries/entities/src/EntityTree.h index dcce0e4b99..9da0ecedd8 100644 --- a/libraries/entities/src/EntityTree.h +++ b/libraries/entities/src/EntityTree.h @@ -75,7 +75,7 @@ public: } - virtual void eraseNonLocalEntities() override; + virtual void eraseDomainAndNonOwnedEntities() override; virtual void eraseAllOctreeElements(bool createNewRoot = true) override; virtual void readBitstreamToTree(const unsigned char* bitstream, @@ -255,6 +255,7 @@ public: QByteArray computeNonce(const QString& certID, const QString ownerKey); bool verifyNonce(const QString& certID, const QString& nonce, EntityItemID& id); + QUuid getMyAvatarSessionUUID() { return _myAvatar ? _myAvatar->getSessionUUID() : QUuid(); } void setMyAvatar(std::shared_ptr myAvatar) { _myAvatar = myAvatar; } void swapStaleProxies(std::vector& proxies) { proxies.swap(_staleProxies); } diff --git a/libraries/entities/src/EntityTreeElement.cpp b/libraries/entities/src/EntityTreeElement.cpp index ce6f20262f..aab98adb52 100644 --- a/libraries/entities/src/EntityTreeElement.cpp +++ b/libraries/entities/src/EntityTreeElement.cpp @@ -697,11 +697,11 @@ EntityItemPointer EntityTreeElement::getEntityWithEntityItemID(const EntityItemI return foundEntity; } -void EntityTreeElement::cleanupNonLocalEntities() { +void EntityTreeElement::cleanupDomainAndNonOwnedEntities() { withWriteLock([&] { EntityItems savedEntities; foreach(EntityItemPointer entity, _entityItems) { - if (!entity->isLocalEntity()) { + if (!(entity->isLocalEntity() || (entity->isAvatarEntity() && entity->getOwningAvatarID() == getTree()->getMyAvatarSessionUUID()))) { entity->preDelete(); entity->_element = NULL; } else { diff --git a/libraries/entities/src/EntityTreeElement.h b/libraries/entities/src/EntityTreeElement.h index f82eaa7fb1..f94da44138 100644 --- a/libraries/entities/src/EntityTreeElement.h +++ b/libraries/entities/src/EntityTreeElement.h @@ -190,7 +190,7 @@ public: EntityItemPointer getEntityWithEntityItemID(const EntityItemID& id) const; void getEntitiesInside(const AACube& box, QVector& foundEntities); - void cleanupNonLocalEntities(); + void cleanupDomainAndNonOwnedEntities(); void cleanupEntities(); /// called by EntityTree on cleanup this will free all entities bool removeEntityItem(EntityItemPointer entity, bool deletion = false); diff --git a/libraries/octree/src/Octree.h b/libraries/octree/src/Octree.h index aac29201f1..82076f618b 100644 --- a/libraries/octree/src/Octree.h +++ b/libraries/octree/src/Octree.h @@ -149,7 +149,7 @@ public: OctreeElementPointer getRoot() { return _rootElement; } - virtual void eraseNonLocalEntities() { _isDirty = true; }; + virtual void eraseDomainAndNonOwnedEntities() { _isDirty = true; }; virtual void eraseAllOctreeElements(bool createNewRoot = true); virtual void readBitstreamToTree(const unsigned char* bitstream, uint64_t bufferSizeBytes, ReadBitstreamToTreeParams& args); diff --git a/libraries/octree/src/OctreeProcessor.cpp b/libraries/octree/src/OctreeProcessor.cpp index 18c8630391..03c8b9ca2f 100644 --- a/libraries/octree/src/OctreeProcessor.cpp +++ b/libraries/octree/src/OctreeProcessor.cpp @@ -198,10 +198,10 @@ void OctreeProcessor::processDatagram(ReceivedMessage& message, SharedNodePointe } -void OctreeProcessor::clearNonLocalEntities() { +void OctreeProcessor::clearDomainAndNonOwnedEntities() { if (_tree) { _tree->withWriteLock([&] { - _tree->eraseNonLocalEntities(); + _tree->eraseDomainAndNonOwnedEntities(); }); } } diff --git a/libraries/octree/src/OctreeProcessor.h b/libraries/octree/src/OctreeProcessor.h index bc5618e657..40af7a39f8 100644 --- a/libraries/octree/src/OctreeProcessor.h +++ b/libraries/octree/src/OctreeProcessor.h @@ -43,7 +43,7 @@ public: virtual void init(); /// clears the tree - virtual void clearNonLocalEntities(); + virtual void clearDomainAndNonOwnedEntities(); virtual void clear(); float getAverageElementsPerPacket() const { return _elementsPerPacket.getAverage(); } From 708632ee82ce326c25dc7ee73e9b83fa63998673 Mon Sep 17 00:00:00 2001 From: SamGondelman Date: Mon, 4 Mar 2019 10:00:26 -0800 Subject: [PATCH 11/18] possible fix for model crash --- libraries/render-utils/src/Model.cpp | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/libraries/render-utils/src/Model.cpp b/libraries/render-utils/src/Model.cpp index 9bb3f72b31..683c517a15 100644 --- a/libraries/render-utils/src/Model.cpp +++ b/libraries/render-utils/src/Model.cpp @@ -1346,14 +1346,18 @@ void Model::updateRig(float deltaTime, glm::mat4 parentTransform) { } void Model::computeMeshPartLocalBounds() { - for (auto& part : _modelMeshRenderItems) { - const Model::MeshState& state = _meshStates.at(part->_meshIndex); - if (_useDualQuaternionSkinning) { - part->computeAdjustedLocalBound(state.clusterDualQuaternions); - } else { - part->computeAdjustedLocalBound(state.clusterMatrices); - } + render::Transaction transaction; + for (auto renderItem : _modelMeshRenderItemIDs) { + transaction.updateItem(renderItem, [&](ModelMeshPartPayload& data) { + const Model::MeshState& state = _meshStates.at(data._meshIndex); + if (_useDualQuaternionSkinning) { + data.computeAdjustedLocalBound(state.clusterDualQuaternions); + } else { + data.computeAdjustedLocalBound(state.clusterMatrices); + } + }); } + AbstractViewStateInterface::instance()->getMain3DScene()->enqueueTransaction(transaction); } // virtual From b2d08e9d42f152c4beff350b37842f4af93bcf0c Mon Sep 17 00:00:00 2001 From: luiscuenca Date: Mon, 4 Mar 2019 15:33:21 -0700 Subject: [PATCH 12/18] apply axis rotation to translation and meshes --- libraries/fbx/src/FBXSerializer.cpp | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/libraries/fbx/src/FBXSerializer.cpp b/libraries/fbx/src/FBXSerializer.cpp index e022ca8921..5246242a1e 100644 --- a/libraries/fbx/src/FBXSerializer.cpp +++ b/libraries/fbx/src/FBXSerializer.cpp @@ -1281,8 +1281,9 @@ HFMModel* FBXSerializer::extractHFMModel(const QVariantHash& mapping, const QStr joint.geometricScaling = fbxModel.geometricScaling; joint.isSkeletonJoint = fbxModel.isLimbNode; hfmModel.hasSkeletonJoints = (hfmModel.hasSkeletonJoints || joint.isSkeletonJoint); - if (applyUpAxisZRotation && joint.parentIndex == -1 && !joint.isSkeletonJoint) { + if (applyUpAxisZRotation && joint.parentIndex == -1) { joint.rotation *= upAxisZRotation; + joint.translation = upAxisZRotation * joint.translation; } glm::quat combinedRotation = joint.preRotation * joint.rotation * joint.postRotation; if (joint.parentIndex == -1) { @@ -1678,8 +1679,12 @@ HFMModel* FBXSerializer::extractHFMModel(const QVariantHash& mapping, const QStr } if (applyUpAxisZRotation) { - hfmModelPtr->meshExtents.rotate(upAxisZRotation); - hfmModelPtr->bindExtents.rotate(upAxisZRotation); + hfmModelPtr->meshExtents.transform(glm::mat4_cast(upAxisZRotation)); + hfmModelPtr->bindExtents.transform(glm::mat4_cast(upAxisZRotation)); + for (auto &mesh : hfmModelPtr->meshes) { + mesh.modelTransform *= glm::mat4_cast(upAxisZRotation); + mesh.meshExtents.transform(glm::mat4_cast(upAxisZRotation)); + } } return hfmModelPtr; } From 12f5a735d93e61e74c1824d1f5b0f9c88e3a2342 Mon Sep 17 00:00:00 2001 From: SamGondelman Date: Mon, 4 Mar 2019 14:50:09 -0800 Subject: [PATCH 13/18] simplifying mouse events and fix mouse on create --- interface/src/Application.cpp | 11 +- interface/src/ui/overlays/Overlays.cpp | 239 ++++++------------ interface/src/ui/overlays/Overlays.h | 17 +- .../src/EntityTreeRenderer.cpp | 34 +-- .../src/EntityTreeRenderer.h | 2 +- scripts/system/edit.js | 6 +- 6 files changed, 103 insertions(+), 206 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 2c8d71af00..e41d51de47 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -4392,7 +4392,6 @@ void Application::mouseMoveEvent(QMouseEvent* event) { if (compositor.getReticleVisible() || !isHMDMode() || !compositor.getReticleOverDesktop() || getOverlays().getOverlayAtPoint(glm::vec2(transformedPos.x(), transformedPos.y())) != UNKNOWN_ENTITY_ID) { getEntities()->mouseMoveEvent(&mappedEvent); - getOverlays().mouseMoveEvent(&mappedEvent); } _controllerScriptingInterface->emitMouseMoveEvent(&mappedEvent); // send events to any registered scripts @@ -4426,14 +4425,10 @@ void Application::mousePressEvent(QMouseEvent* event) { #endif QMouseEvent mappedEvent(event->type(), transformedPos, event->screenPos(), event->button(), event->buttons(), event->modifiers()); - std::pair entityResult; if (!_controllerScriptingInterface->areEntityClicksCaptured()) { - entityResult = getEntities()->mousePressEvent(&mappedEvent); + QUuid result = getEntities()->mousePressEvent(&mappedEvent); + setKeyboardFocusEntity(getEntities()->wantsKeyboardFocus(result) ? result : UNKNOWN_ENTITY_ID); } - std::pair overlayResult = getOverlays().mousePressEvent(&mappedEvent); - - QUuid focusedEntity = entityResult.first < overlayResult.first ? entityResult.second : overlayResult.second; - setKeyboardFocusEntity(getEntities()->wantsKeyboardFocus(focusedEntity) ? focusedEntity : UNKNOWN_ENTITY_ID); _controllerScriptingInterface->emitMousePressEvent(&mappedEvent); // send events to any registered scripts @@ -4476,7 +4471,6 @@ void Application::mouseDoublePressEvent(QMouseEvent* event) { if (!_controllerScriptingInterface->areEntityClicksCaptured()) { getEntities()->mouseDoublePressEvent(&mappedEvent); } - getOverlays().mouseDoublePressEvent(&mappedEvent); // if one of our scripts have asked to capture this event, then stop processing it if (_controllerScriptingInterface->isMouseCaptured()) { @@ -4501,7 +4495,6 @@ void Application::mouseReleaseEvent(QMouseEvent* event) { event->buttons(), event->modifiers()); getEntities()->mouseReleaseEvent(&mappedEvent); - getOverlays().mouseReleaseEvent(&mappedEvent); _controllerScriptingInterface->emitMouseReleaseEvent(&mappedEvent); // send events to any registered scripts diff --git a/interface/src/ui/overlays/Overlays.cpp b/interface/src/ui/overlays/Overlays.cpp index 5ae3f7d38e..dfd698f6c5 100644 --- a/interface/src/ui/overlays/Overlays.cpp +++ b/interface/src/ui/overlays/Overlays.cpp @@ -43,14 +43,6 @@ std::unordered_map Overlays::_entityToOverlayTypes; std::unordered_map Overlays::_overlayToEntityTypes; Overlays::Overlays() { - auto pointerManager = DependencyManager::get(); - connect(pointerManager.data(), &PointerManager::hoverBeginOverlay, this, &Overlays::hoverEnterPointerEvent); - connect(pointerManager.data(), &PointerManager::hoverContinueOverlay, this, &Overlays::hoverOverPointerEvent); - connect(pointerManager.data(), &PointerManager::hoverEndOverlay, this, &Overlays::hoverLeavePointerEvent); - connect(pointerManager.data(), &PointerManager::triggerBeginOverlay, this, &Overlays::mousePressPointerEvent); - connect(pointerManager.data(), &PointerManager::triggerContinueOverlay, this, &Overlays::mouseMovePointerEvent); - connect(pointerManager.data(), &PointerManager::triggerEndOverlay, this, &Overlays::mouseReleasePointerEvent); - ADD_TYPE_MAP(Box, cube); ADD_TYPE_MAP(Sphere, sphere); _overlayToEntityTypes["rectangle3d"] = "Shape"; @@ -81,13 +73,23 @@ void Overlays::cleanupAllOverlays() { void Overlays::init() { auto entityScriptingInterface = DependencyManager::get().data(); - auto pointerManager = DependencyManager::get(); - connect(pointerManager.data(), &PointerManager::hoverBeginOverlay, entityScriptingInterface , &EntityScriptingInterface::hoverEnterEntity); - connect(pointerManager.data(), &PointerManager::hoverContinueOverlay, entityScriptingInterface, &EntityScriptingInterface::hoverOverEntity); - connect(pointerManager.data(), &PointerManager::hoverEndOverlay, entityScriptingInterface, &EntityScriptingInterface::hoverLeaveEntity); - connect(pointerManager.data(), &PointerManager::triggerBeginOverlay, entityScriptingInterface, &EntityScriptingInterface::mousePressOnEntity); - connect(pointerManager.data(), &PointerManager::triggerContinueOverlay, entityScriptingInterface, &EntityScriptingInterface::mouseMoveOnEntity); - connect(pointerManager.data(), &PointerManager::triggerEndOverlay, entityScriptingInterface, &EntityScriptingInterface::mouseReleaseOnEntity); + auto pointerManager = DependencyManager::get().data(); + connect(pointerManager, &PointerManager::hoverBeginOverlay, entityScriptingInterface , &EntityScriptingInterface::hoverEnterEntity); + connect(pointerManager, &PointerManager::hoverContinueOverlay, entityScriptingInterface, &EntityScriptingInterface::hoverOverEntity); + connect(pointerManager, &PointerManager::hoverEndOverlay, entityScriptingInterface, &EntityScriptingInterface::hoverLeaveEntity); + connect(pointerManager, &PointerManager::triggerBeginOverlay, entityScriptingInterface, &EntityScriptingInterface::mousePressOnEntity); + connect(pointerManager, &PointerManager::triggerContinueOverlay, entityScriptingInterface, &EntityScriptingInterface::mouseMoveOnEntity); + connect(pointerManager, &PointerManager::triggerEndOverlay, entityScriptingInterface, &EntityScriptingInterface::mouseReleaseOnEntity); + + connect(entityScriptingInterface, &EntityScriptingInterface::mousePressOnEntity, this, &Overlays::mousePressOnPointerEvent); + connect(entityScriptingInterface, &EntityScriptingInterface::mousePressOffEntity, this, &Overlays::mousePressOffPointerEvent); + connect(entityScriptingInterface, &EntityScriptingInterface::mouseDoublePressOnEntity, this, &Overlays::mouseDoublePressOnPointerEvent); + connect(entityScriptingInterface, &EntityScriptingInterface::mouseDoublePressOffEntity, this, &Overlays::mouseDoublePressOffPointerEvent); + connect(entityScriptingInterface, &EntityScriptingInterface::mouseReleaseOnEntity, this, &Overlays::mouseReleasePointerEvent); + connect(entityScriptingInterface, &EntityScriptingInterface::mouseMoveOnEntity, this, &Overlays::mouseMovePointerEvent); + connect(entityScriptingInterface, &EntityScriptingInterface::hoverEnterEntity , this, &Overlays::hoverEnterPointerEvent); + connect(entityScriptingInterface, &EntityScriptingInterface::hoverOverEntity, this, &Overlays::hoverOverPointerEvent); + connect(entityScriptingInterface, &EntityScriptingInterface::hoverLeaveEntity, this, &Overlays::hoverLeavePointerEvent); } void Overlays::update(float deltatime) { @@ -1159,7 +1161,7 @@ bool Overlays::isAddedOverlay(const QUuid& id) { } void Overlays::sendMousePressOnOverlay(const QUuid& id, const PointerEvent& event) { - mousePressPointerEvent(id, event); + mousePressOnPointerEvent(id, event); } void Overlays::sendMouseReleaseOnOverlay(const QUuid& id, const PointerEvent& event) { @@ -1206,57 +1208,66 @@ float Overlays::height() { return offscreenUi->getWindow()->size().height(); } -static uint32_t toPointerButtons(const QMouseEvent& event) { - uint32_t buttons = 0; - buttons |= event.buttons().testFlag(Qt::LeftButton) ? PointerEvent::PrimaryButton : 0; - buttons |= event.buttons().testFlag(Qt::RightButton) ? PointerEvent::SecondaryButton : 0; - buttons |= event.buttons().testFlag(Qt::MiddleButton) ? PointerEvent::TertiaryButton : 0; - return buttons; -} - -static PointerEvent::Button toPointerButton(const QMouseEvent& event) { - switch (event.button()) { - case Qt::LeftButton: - return PointerEvent::PrimaryButton; - case Qt::RightButton: - return PointerEvent::SecondaryButton; - case Qt::MiddleButton: - return PointerEvent::TertiaryButton; - default: - return PointerEvent::NoButtons; - } -} - -RayToOverlayIntersectionResult getPrevPickResult() { - RayToOverlayIntersectionResult overlayResult; - overlayResult.intersects = false; - auto pickResult = DependencyManager::get()->getPrevPickResultTyped(DependencyManager::get()->getMouseRayPickID()); - if (pickResult) { - overlayResult.intersects = pickResult->type == IntersectionType::LOCAL_ENTITY; - if (overlayResult.intersects) { - overlayResult.intersection = pickResult->intersection; - overlayResult.distance = pickResult->distance; - overlayResult.surfaceNormal = pickResult->surfaceNormal; - overlayResult.overlayID = pickResult->objectID; - overlayResult.extraInfo = pickResult->extraInfo; +void Overlays::mousePressOnPointerEvent(const QUuid& id, const PointerEvent& event) { + auto keyboard = DependencyManager::get(); + // Do not send keyboard key event to scripts to prevent malignant scripts from gathering what you typed + if (!keyboard->getKeyIDs().contains(id)) { + auto entity = DependencyManager::get()->getEntity(id); + if (entity && entity->isLocalEntity()) { + emit mousePressOnOverlay(id, event); } } - return overlayResult; } -PointerEvent Overlays::calculateOverlayPointerEvent(const QUuid& id, const PickRay& ray, - const RayToOverlayIntersectionResult& rayPickResult, QMouseEvent* event, - PointerEvent::EventType eventType) { - glm::vec2 pos2D = RayPick::projectOntoEntityXYPlane(id, rayPickResult.intersection); - return PointerEvent(eventType, PointerManager::MOUSE_POINTER_ID, pos2D, rayPickResult.intersection, rayPickResult.surfaceNormal, - ray.direction, toPointerButton(*event), toPointerButtons(*event), event->modifiers()); +void Overlays::mousePressOffPointerEvent() { + emit mousePressOffOverlay(); +} + +void Overlays::mouseDoublePressOnPointerEvent(const QUuid& id, const PointerEvent& event) { + auto keyboard = DependencyManager::get(); + // Do not send keyboard key event to scripts to prevent malignant scripts from gathering what you typed + if (!keyboard->getKeyIDs().contains(id)) { + auto entity = DependencyManager::get()->getEntity(id); + if (entity && entity->isLocalEntity()) { + emit mouseDoublePressOnOverlay(id, event); + } + } +} + +void Overlays::mouseDoublePressOffPointerEvent() { + emit mouseDoublePressOffOverlay(); +} + +void Overlays::mouseReleasePointerEvent(const QUuid& id, const PointerEvent& event) { + auto keyboard = DependencyManager::get(); + // Do not send keyboard key event to scripts to prevent malignant scripts from gathering what you typed + if (!keyboard->getKeyIDs().contains(id)) { + auto entity = DependencyManager::get()->getEntity(id); + if (entity && entity->isLocalEntity()) { + emit mouseReleaseOnOverlay(id, event); + } + } +} + +void Overlays::mouseMovePointerEvent(const QUuid& id, const PointerEvent& event) { + auto keyboard = DependencyManager::get(); + // Do not send keyboard key event to scripts to prevent malignant scripts from gathering what you typed + if (!keyboard->getKeyIDs().contains(id)) { + auto entity = DependencyManager::get()->getEntity(id); + if (entity && entity->isLocalEntity()) { + emit mouseMoveOnOverlay(id, event); + } + } } void Overlays::hoverEnterPointerEvent(const QUuid& id, const PointerEvent& event) { auto keyboard = DependencyManager::get(); // Do not send keyboard key event to scripts to prevent malignant scripts from gathering what you typed if (!keyboard->getKeyIDs().contains(id)) { - emit hoverEnterOverlay(id, event); + auto entity = DependencyManager::get()->getEntity(id); + if (entity && entity->isLocalEntity()) { + emit hoverEnterOverlay(id, event); + } } } @@ -1264,7 +1275,10 @@ void Overlays::hoverOverPointerEvent(const QUuid& id, const PointerEvent& event) auto keyboard = DependencyManager::get(); // Do not send keyboard key event to scripts to prevent malignant scripts from gathering what you typed if (!keyboard->getKeyIDs().contains(id)) { - emit hoverOverOverlay(id, event); + auto entity = DependencyManager::get()->getEntity(id); + if (entity && entity->isLocalEntity()) { + emit hoverOverOverlay(id, event); + } } } @@ -1272,113 +1286,10 @@ void Overlays::hoverLeavePointerEvent(const QUuid& id, const PointerEvent& event auto keyboard = DependencyManager::get(); // Do not send keyboard key event to scripts to prevent malignant scripts from gathering what you typed if (!keyboard->getKeyIDs().contains(id)) { - emit hoverLeaveOverlay(id, event); - } -} - -std::pair Overlays::mousePressEvent(QMouseEvent* event) { - PerformanceTimer perfTimer("Overlays::mousePressEvent"); - - PickRay ray = qApp->computePickRay(event->x(), event->y()); - RayToOverlayIntersectionResult rayPickResult = getPrevPickResult(); - if (rayPickResult.intersects) { - _currentClickingOnOverlayID = rayPickResult.overlayID; - - PointerEvent pointerEvent = calculateOverlayPointerEvent(_currentClickingOnOverlayID, ray, rayPickResult, event, PointerEvent::Press); - mousePressPointerEvent(_currentClickingOnOverlayID, pointerEvent); - return { rayPickResult.distance, rayPickResult.overlayID }; - } - emit mousePressOffOverlay(); - return { FLT_MAX, UNKNOWN_ENTITY_ID }; -} - -void Overlays::mousePressPointerEvent(const QUuid& id, const PointerEvent& event) { - auto keyboard = DependencyManager::get(); - // Do not send keyboard key event to scripts to prevent malignant scripts from gathering what you typed - if (!keyboard->getKeyIDs().contains(id)) { - emit mousePressOnOverlay(id, event); - } -} - -bool Overlays::mouseDoublePressEvent(QMouseEvent* event) { - PerformanceTimer perfTimer("Overlays::mouseDoublePressEvent"); - - PickRay ray = qApp->computePickRay(event->x(), event->y()); - RayToOverlayIntersectionResult rayPickResult = getPrevPickResult(); - if (rayPickResult.intersects) { - _currentClickingOnOverlayID = rayPickResult.overlayID; - - auto pointerEvent = calculateOverlayPointerEvent(_currentClickingOnOverlayID, ray, rayPickResult, event, PointerEvent::Press); - emit mouseDoublePressOnOverlay(_currentClickingOnOverlayID, pointerEvent); - return true; - } - emit mouseDoublePressOffOverlay(); - return false; -} - -bool Overlays::mouseReleaseEvent(QMouseEvent* event) { - PerformanceTimer perfTimer("Overlays::mouseReleaseEvent"); - - PickRay ray = qApp->computePickRay(event->x(), event->y()); - RayToOverlayIntersectionResult rayPickResult = getPrevPickResult(); - if (rayPickResult.intersects) { - auto pointerEvent = calculateOverlayPointerEvent(rayPickResult.overlayID, ray, rayPickResult, event, PointerEvent::Release); - mouseReleasePointerEvent(rayPickResult.overlayID, pointerEvent); - } - - _currentClickingOnOverlayID = UNKNOWN_ENTITY_ID; - return false; -} - -void Overlays::mouseReleasePointerEvent(const QUuid& id, const PointerEvent& event) { - auto keyboard = DependencyManager::get(); - // Do not send keyboard key event to scripts to prevent malignant scripts from gathering what you typed - if (!keyboard->getKeyIDs().contains(id)) { - emit mouseReleaseOnOverlay(id, event); - } -} - -bool Overlays::mouseMoveEvent(QMouseEvent* event) { - PerformanceTimer perfTimer("Overlays::mouseMoveEvent"); - - PickRay ray = qApp->computePickRay(event->x(), event->y()); - RayToOverlayIntersectionResult rayPickResult = getPrevPickResult(); - if (rayPickResult.intersects) { - auto pointerEvent = calculateOverlayPointerEvent(rayPickResult.overlayID, ray, rayPickResult, event, PointerEvent::Move); - mouseMovePointerEvent(rayPickResult.overlayID, pointerEvent); - - // If previously hovering over a different overlay then leave hover on that overlay. - if (_currentHoverOverOverlayID != UNKNOWN_ENTITY_ID && rayPickResult.overlayID != _currentHoverOverOverlayID) { - auto pointerEvent = calculateOverlayPointerEvent(_currentHoverOverOverlayID, ray, rayPickResult, event, PointerEvent::Move); - hoverLeavePointerEvent(_currentHoverOverOverlayID, pointerEvent); + auto entity = DependencyManager::get()->getEntity(id); + if (entity && entity->isLocalEntity()) { + emit hoverLeaveOverlay(id, event); } - - // If hovering over a new overlay then enter hover on that overlay. - if (rayPickResult.overlayID != _currentHoverOverOverlayID) { - hoverEnterPointerEvent(rayPickResult.overlayID, pointerEvent); - } - - // Hover over current overlay. - hoverOverPointerEvent(rayPickResult.overlayID, pointerEvent); - - _currentHoverOverOverlayID = rayPickResult.overlayID; - } else { - // If previously hovering an overlay then leave hover. - if (_currentHoverOverOverlayID != UNKNOWN_ENTITY_ID) { - auto pointerEvent = calculateOverlayPointerEvent(_currentHoverOverOverlayID, ray, rayPickResult, event, PointerEvent::Move); - hoverLeavePointerEvent(_currentHoverOverOverlayID, pointerEvent); - - _currentHoverOverOverlayID = UNKNOWN_ENTITY_ID; - } - } - return false; -} - -void Overlays::mouseMovePointerEvent(const QUuid& id, const PointerEvent& event) { - auto keyboard = DependencyManager::get(); - // Do not send keyboard key event to scripts to prevent malignant scripts from gathering what you typed - if (!keyboard->getKeyIDs().contains(id)) { - emit mouseMoveOnOverlay(id, event); } } diff --git a/interface/src/ui/overlays/Overlays.h b/interface/src/ui/overlays/Overlays.h index 93efc2bc0b..0b2994b872 100644 --- a/interface/src/ui/overlays/Overlays.h +++ b/interface/src/ui/overlays/Overlays.h @@ -112,11 +112,6 @@ public: const QVector& discard, bool visibleOnly = false, bool collidableOnly = false); - std::pair mousePressEvent(QMouseEvent* event); - bool mouseDoublePressEvent(QMouseEvent* event); - bool mouseReleaseEvent(QMouseEvent* event); - bool mouseMoveEvent(QMouseEvent* event); - void cleanupAllOverlays(); mutable QScriptEngine _scriptEngine; @@ -719,9 +714,6 @@ private: PointerEvent calculateOverlayPointerEvent(const QUuid& id, const PickRay& ray, const RayToOverlayIntersectionResult& rayPickResult, QMouseEvent* event, PointerEvent::EventType eventType); - QUuid _currentClickingOnOverlayID; - QUuid _currentHoverOverOverlayID; - static QString entityToOverlayType(const QString& type); static QString overlayToEntityType(const QString& type); static std::unordered_map _entityToOverlayTypes; @@ -732,12 +724,17 @@ private: EntityItemProperties convertOverlayToEntityProperties(QVariantMap& overlayProps, std::pair& rotationToSave, const QString& type, bool add, const QUuid& id = QUuid()); private slots: - void mousePressPointerEvent(const QUuid& id, const PointerEvent& event); - void mouseMovePointerEvent(const QUuid& id, const PointerEvent& event); + void mousePressOnPointerEvent(const QUuid& id, const PointerEvent& event); + void mousePressOffPointerEvent(); + void mouseDoublePressOnPointerEvent(const QUuid& id, const PointerEvent& event); + void mouseDoublePressOffPointerEvent(); void mouseReleasePointerEvent(const QUuid& id, const PointerEvent& event); + void mouseMovePointerEvent(const QUuid& id, const PointerEvent& event); void hoverEnterPointerEvent(const QUuid& id, const PointerEvent& event); void hoverOverPointerEvent(const QUuid& id, const PointerEvent& event); void hoverLeavePointerEvent(const QUuid& id, const PointerEvent& event); + + }; #define ADD_TYPE_MAP(entity, overlay) \ diff --git a/libraries/entities-renderer/src/EntityTreeRenderer.cpp b/libraries/entities-renderer/src/EntityTreeRenderer.cpp index e54258fc3e..c7457c6443 100644 --- a/libraries/entities-renderer/src/EntityTreeRenderer.cpp +++ b/libraries/entities-renderer/src/EntityTreeRenderer.cpp @@ -73,14 +73,14 @@ EntityTreeRenderer::EntityTreeRenderer(bool wantScripts, AbstractViewStateInterf _currentHoverOverEntityID = UNKNOWN_ENTITY_ID; _currentClickingOnEntityID = UNKNOWN_ENTITY_ID; - auto entityScriptingInterface = DependencyManager::get(); + auto entityScriptingInterface = DependencyManager::get().data(); auto pointerManager = DependencyManager::get(); - connect(pointerManager.data(), &PointerManager::hoverBeginEntity, entityScriptingInterface.data(), &EntityScriptingInterface::hoverEnterEntity); - connect(pointerManager.data(), &PointerManager::hoverContinueEntity, entityScriptingInterface.data(), &EntityScriptingInterface::hoverOverEntity); - connect(pointerManager.data(), &PointerManager::hoverEndEntity, entityScriptingInterface.data(), &EntityScriptingInterface::hoverLeaveEntity); - connect(pointerManager.data(), &PointerManager::triggerBeginEntity, entityScriptingInterface.data(), &EntityScriptingInterface::mousePressOnEntity); - connect(pointerManager.data(), &PointerManager::triggerContinueEntity, entityScriptingInterface.data(), &EntityScriptingInterface::mouseMoveOnEntity); - connect(pointerManager.data(), &PointerManager::triggerEndEntity, entityScriptingInterface.data(), &EntityScriptingInterface::mouseReleaseOnEntity); + connect(pointerManager.data(), &PointerManager::hoverBeginEntity, entityScriptingInterface, &EntityScriptingInterface::hoverEnterEntity); + connect(pointerManager.data(), &PointerManager::hoverContinueEntity, entityScriptingInterface, &EntityScriptingInterface::hoverOverEntity); + connect(pointerManager.data(), &PointerManager::hoverEndEntity, entityScriptingInterface, &EntityScriptingInterface::hoverLeaveEntity); + connect(pointerManager.data(), &PointerManager::triggerBeginEntity, entityScriptingInterface, &EntityScriptingInterface::mousePressOnEntity); + connect(pointerManager.data(), &PointerManager::triggerContinueEntity, entityScriptingInterface, &EntityScriptingInterface::mouseMoveOnEntity); + connect(pointerManager.data(), &PointerManager::triggerEndEntity, entityScriptingInterface, &EntityScriptingInterface::mouseReleaseOnEntity); // Forward mouse events to web entities auto handlePointerEvent = [&](const QUuid& entityID, const PointerEvent& event) { @@ -93,10 +93,10 @@ EntityTreeRenderer::EntityTreeRenderer(bool wantScripts, AbstractViewStateInterf QMetaObject::invokeMethod(thisEntity.get(), "handlePointerEvent", Q_ARG(const PointerEvent&, event)); } }; - connect(entityScriptingInterface.data(), &EntityScriptingInterface::mousePressOnEntity, this, handlePointerEvent); - connect(entityScriptingInterface.data(), &EntityScriptingInterface::mouseMoveOnEntity, this, handlePointerEvent); - connect(entityScriptingInterface.data(), &EntityScriptingInterface::mouseReleaseOnEntity, this, handlePointerEvent); - connect(entityScriptingInterface.data(), &EntityScriptingInterface::hoverEnterEntity, this, [&](const QUuid& entityID, const PointerEvent& event) { + connect(entityScriptingInterface, &EntityScriptingInterface::mousePressOnEntity, this, handlePointerEvent); + connect(entityScriptingInterface, &EntityScriptingInterface::mouseMoveOnEntity, this, handlePointerEvent); + connect(entityScriptingInterface, &EntityScriptingInterface::mouseReleaseOnEntity, this, handlePointerEvent); + connect(entityScriptingInterface, &EntityScriptingInterface::hoverEnterEntity, this, [&](const QUuid& entityID, const PointerEvent& event) { std::shared_ptr thisEntity; auto entity = getEntity(entityID); if (entity && entity->isVisible() && entity->getType() == EntityTypes::Web) { @@ -106,8 +106,8 @@ EntityTreeRenderer::EntityTreeRenderer(bool wantScripts, AbstractViewStateInterf QMetaObject::invokeMethod(thisEntity.get(), "hoverEnterEntity", Q_ARG(const PointerEvent&, event)); } }); - connect(entityScriptingInterface.data(), &EntityScriptingInterface::hoverOverEntity, this, handlePointerEvent); - connect(entityScriptingInterface.data(), &EntityScriptingInterface::hoverLeaveEntity, this, [&](const QUuid& entityID, const PointerEvent& event) { + connect(entityScriptingInterface, &EntityScriptingInterface::hoverOverEntity, this, handlePointerEvent); + connect(entityScriptingInterface, &EntityScriptingInterface::hoverLeaveEntity, this, [&](const QUuid& entityID, const PointerEvent& event) { std::shared_ptr thisEntity; auto entity = getEntity(entityID); if (entity && entity->isVisible() && entity->getType() == EntityTypes::Web) { @@ -792,11 +792,11 @@ static PointerEvent::Button toPointerButton(const QMouseEvent& event) { } } -std::pair EntityTreeRenderer::mousePressEvent(QMouseEvent* event) { +QUuid EntityTreeRenderer::mousePressEvent(QMouseEvent* event) { // If we don't have a tree, or we're in the process of shutting down, then don't // process these events. if (!_tree || _shuttingDown) { - return { FLT_MAX, UNKNOWN_ENTITY_ID }; + return UNKNOWN_ENTITY_ID; } PerformanceTimer perfTimer("EntityTreeRenderer::mousePressEvent"); @@ -827,10 +827,10 @@ std::pair EntityTreeRenderer::mousePressEvent(QMouseEvent* event) _lastPointerEvent = pointerEvent; _lastPointerEventValid = true; - return { rayPickResult.distance, rayPickResult.entityID }; + return rayPickResult.entityID; } emit entityScriptingInterface->mousePressOffEntity(); - return { FLT_MAX, UNKNOWN_ENTITY_ID }; + return UNKNOWN_ENTITY_ID; } void EntityTreeRenderer::mouseDoublePressEvent(QMouseEvent* event) { diff --git a/libraries/entities-renderer/src/EntityTreeRenderer.h b/libraries/entities-renderer/src/EntityTreeRenderer.h index 51568ab744..8cc34cda10 100644 --- a/libraries/entities-renderer/src/EntityTreeRenderer.h +++ b/libraries/entities-renderer/src/EntityTreeRenderer.h @@ -94,7 +94,7 @@ public: void reloadEntityScripts(); // event handles which may generate entity related events - std::pair mousePressEvent(QMouseEvent* event); + QUuid mousePressEvent(QMouseEvent* event); void mouseReleaseEvent(QMouseEvent* event); void mouseDoublePressEvent(QMouseEvent* event); void mouseMoveEvent(QMouseEvent* event); diff --git a/scripts/system/edit.js b/scripts/system/edit.js index 9d807264aa..bce308d5fc 100644 --- a/scripts/system/edit.js +++ b/scripts/system/edit.js @@ -924,11 +924,7 @@ var toolBar = (function () { that.setActive = function (active) { ContextOverlay.enabled = !active; Settings.setValue(EDIT_SETTING, active); - if (active) { - Controller.captureEntityClickEvents(); - } else { - Controller.releaseEntityClickEvents(); - + if (!active) { closeExistingDialogWindow(); } if (active === isActive) { From fd88ec0d16caafe1bef84a4287b3b9e1b5cec846 Mon Sep 17 00:00:00 2001 From: SamGondelman Date: Mon, 4 Mar 2019 15:25:02 -0800 Subject: [PATCH 14/18] need to copy meshStates on main thread --- libraries/render-utils/src/Model.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/libraries/render-utils/src/Model.cpp b/libraries/render-utils/src/Model.cpp index 683c517a15..dd9b0280ca 100644 --- a/libraries/render-utils/src/Model.cpp +++ b/libraries/render-utils/src/Model.cpp @@ -1347,9 +1347,10 @@ void Model::updateRig(float deltaTime, glm::mat4 parentTransform) { void Model::computeMeshPartLocalBounds() { render::Transaction transaction; + auto meshStates = _meshStates; for (auto renderItem : _modelMeshRenderItemIDs) { - transaction.updateItem(renderItem, [&](ModelMeshPartPayload& data) { - const Model::MeshState& state = _meshStates.at(data._meshIndex); + transaction.updateItem(renderItem, [this, meshStates](ModelMeshPartPayload& data) { + const Model::MeshState& state = meshStates.at(data._meshIndex); if (_useDualQuaternionSkinning) { data.computeAdjustedLocalBound(state.clusterDualQuaternions); } else { From f2c248c0a26a56b8c7969a14e274422524322cf3 Mon Sep 17 00:00:00 2001 From: SamGondelman Date: Mon, 4 Mar 2019 17:08:09 -0800 Subject: [PATCH 15/18] disable href and entity script events when in edit mode --- interface/src/Application.cpp | 15 +++++++-------- .../entities-renderer/src/EntityTreeRenderer.cpp | 12 +++++++----- libraries/entities/src/EntityTree.cpp | 8 ++++++++ libraries/entities/src/EntityTree.h | 4 ++++ libraries/script-engine/src/ScriptEngine.cpp | 4 +++- scripts/system/edit.js | 6 +++++- 6 files changed, 34 insertions(+), 15 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index e41d51de47..c85ced5dee 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -1061,6 +1061,10 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo connect(PluginManager::getInstance().data(), &PluginManager::inputDeviceRunningChanged, controllerScriptingInterface, &controller::ScriptingInterface::updateRunningInputDevices); + EntityTree::setEntityClicksCapturedOperator([this] { + return _controllerScriptingInterface->areEntityClicksCaptured(); + }); + _entityClipboard->createRootElement(); #ifdef Q_OS_WIN @@ -4425,10 +4429,8 @@ void Application::mousePressEvent(QMouseEvent* event) { #endif QMouseEvent mappedEvent(event->type(), transformedPos, event->screenPos(), event->button(), event->buttons(), event->modifiers()); - if (!_controllerScriptingInterface->areEntityClicksCaptured()) { - QUuid result = getEntities()->mousePressEvent(&mappedEvent); - setKeyboardFocusEntity(getEntities()->wantsKeyboardFocus(result) ? result : UNKNOWN_ENTITY_ID); - } + QUuid result = getEntities()->mousePressEvent(&mappedEvent); + setKeyboardFocusEntity(getEntities()->wantsKeyboardFocus(result) ? result : UNKNOWN_ENTITY_ID); _controllerScriptingInterface->emitMousePressEvent(&mappedEvent); // send events to any registered scripts @@ -4467,10 +4469,7 @@ void Application::mouseDoublePressEvent(QMouseEvent* event) { transformedPos, event->screenPos(), event->button(), event->buttons(), event->modifiers()); - - if (!_controllerScriptingInterface->areEntityClicksCaptured()) { - getEntities()->mouseDoublePressEvent(&mappedEvent); - } + getEntities()->mouseDoublePressEvent(&mappedEvent); // if one of our scripts have asked to capture this event, then stop processing it if (_controllerScriptingInterface->isMouseCaptured()) { diff --git a/libraries/entities-renderer/src/EntityTreeRenderer.cpp b/libraries/entities-renderer/src/EntityTreeRenderer.cpp index c7457c6443..576137390e 100644 --- a/libraries/entities-renderer/src/EntityTreeRenderer.cpp +++ b/libraries/entities-renderer/src/EntityTreeRenderer.cpp @@ -805,11 +805,13 @@ QUuid EntityTreeRenderer::mousePressEvent(QMouseEvent* event) { RayToEntityIntersectionResult rayPickResult = _getPrevRayPickResultOperator(_mouseRayPickID); EntityItemPointer entity; if (rayPickResult.intersects && (entity = getTree()->findEntityByID(rayPickResult.entityID))) { - auto properties = entity->getProperties(); - QString urlString = properties.getHref(); - QUrl url = QUrl(urlString, QUrl::StrictMode); - if (url.isValid() && !url.isEmpty()){ - DependencyManager::get()->handleLookupString(urlString); + if (!EntityTree::areEntityClicksCaptured()) { + auto properties = entity->getProperties(); + QString urlString = properties.getHref(); + QUrl url = QUrl(urlString, QUrl::StrictMode); + if (url.isValid() && !url.isEmpty()) { + DependencyManager::get()->handleLookupString(urlString); + } } glm::vec2 pos2D = projectOntoEntityXYPlane(entity, ray, rayPickResult); diff --git a/libraries/entities/src/EntityTree.cpp b/libraries/entities/src/EntityTree.cpp index 6e404ce690..644fe0620e 100644 --- a/libraries/entities/src/EntityTree.cpp +++ b/libraries/entities/src/EntityTree.cpp @@ -2972,6 +2972,7 @@ QStringList EntityTree::getJointNames(const QUuid& entityID) const { std::function EntityTree::_getEntityObjectOperator = nullptr; std::function EntityTree::_textSizeOperator = nullptr; +std::function EntityTree::_areEntityClicksCapturedOperator = nullptr; QObject* EntityTree::getEntityObject(const QUuid& id) { if (_getEntityObjectOperator) { @@ -2987,6 +2988,13 @@ QSizeF EntityTree::textSize(const QUuid& id, const QString& text) { return QSizeF(0.0f, 0.0f); } +bool EntityTree::areEntityClicksCaptured() { + if (_areEntityClicksCapturedOperator) { + return _areEntityClicksCapturedOperator(); + } + return false; +} + void EntityTree::updateEntityQueryAACubeWorker(SpatiallyNestablePointer object, EntityEditPacketSender* packetSender, MovingEntitiesOperator& moveOperator, bool force, bool tellServer) { // if the queryBox has changed, tell the entity-server diff --git a/libraries/entities/src/EntityTree.h b/libraries/entities/src/EntityTree.h index dcce0e4b99..01829df7f8 100644 --- a/libraries/entities/src/EntityTree.h +++ b/libraries/entities/src/EntityTree.h @@ -268,6 +268,9 @@ public: static void setTextSizeOperator(std::function textSizeOperator) { _textSizeOperator = textSizeOperator; } static QSizeF textSize(const QUuid& id, const QString& text); + static void setEntityClicksCapturedOperator(std::function areEntityClicksCapturedOperator) { _areEntityClicksCapturedOperator = areEntityClicksCapturedOperator; } + static bool areEntityClicksCaptured(); + std::map getNamedPaths() const { return _namedPaths; } void updateEntityQueryAACube(SpatiallyNestablePointer object, EntityEditPacketSender* packetSender, @@ -378,6 +381,7 @@ private: static std::function _getEntityObjectOperator; static std::function _textSizeOperator; + static std::function _areEntityClicksCapturedOperator; std::vector _staleProxies; diff --git a/libraries/script-engine/src/ScriptEngine.cpp b/libraries/script-engine/src/ScriptEngine.cpp index 5d33a6a061..825017b1fe 100644 --- a/libraries/script-engine/src/ScriptEngine.cpp +++ b/libraries/script-engine/src/ScriptEngine.cpp @@ -976,7 +976,9 @@ void ScriptEngine::addEventHandler(const EntityItemID& entityID, const QString& using PointerHandler = std::function; auto makePointerHandler = [this](QString eventName) -> PointerHandler { return [this, eventName](const EntityItemID& entityItemID, const PointerEvent& event) { - forwardHandlerCall(entityItemID, eventName, { entityItemID.toScriptValue(this), event.toScriptValue(this) }); + if (!EntityTree::areEntityClicksCaptured()) { + forwardHandlerCall(entityItemID, eventName, { entityItemID.toScriptValue(this), event.toScriptValue(this) }); + } }; }; diff --git a/scripts/system/edit.js b/scripts/system/edit.js index bce308d5fc..9d807264aa 100644 --- a/scripts/system/edit.js +++ b/scripts/system/edit.js @@ -924,7 +924,11 @@ var toolBar = (function () { that.setActive = function (active) { ContextOverlay.enabled = !active; Settings.setValue(EDIT_SETTING, active); - if (!active) { + if (active) { + Controller.captureEntityClickEvents(); + } else { + Controller.releaseEntityClickEvents(); + closeExistingDialogWindow(); } if (active === isActive) { From 29a308dcaacfa138b721d183a146b38befe3988a Mon Sep 17 00:00:00 2001 From: amer cerkic Date: Tue, 5 Mar 2019 10:07:33 -0800 Subject: [PATCH 16/18] adding modelScale initialization so that it does not fail the validScale check assert --- libraries/entities/src/ModelEntityItem.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/libraries/entities/src/ModelEntityItem.cpp b/libraries/entities/src/ModelEntityItem.cpp index 505ee26c0f..87d80ee044 100644 --- a/libraries/entities/src/ModelEntityItem.cpp +++ b/libraries/entities/src/ModelEntityItem.cpp @@ -40,6 +40,7 @@ ModelEntityItem::ModelEntityItem(const EntityItemID& entityItemID) : EntityItem( _type = EntityTypes::Model; _lastKnownCurrentFrame = -1; _visuallyReady = false; + _modelScale=glm::vec3(1.0f); } const QString ModelEntityItem::getTextures() const { From 36e9c604e9e70efde65c5a7f64044d0da052a022 Mon Sep 17 00:00:00 2001 From: amer cerkic Date: Tue, 5 Mar 2019 10:45:15 -0800 Subject: [PATCH 17/18] fixed based on comment --- libraries/entities/src/ModelEntityItem.cpp | 1 - libraries/entities/src/ModelEntityItem.h | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/libraries/entities/src/ModelEntityItem.cpp b/libraries/entities/src/ModelEntityItem.cpp index 87d80ee044..505ee26c0f 100644 --- a/libraries/entities/src/ModelEntityItem.cpp +++ b/libraries/entities/src/ModelEntityItem.cpp @@ -40,7 +40,6 @@ ModelEntityItem::ModelEntityItem(const EntityItemID& entityItemID) : EntityItem( _type = EntityTypes::Model; _lastKnownCurrentFrame = -1; _visuallyReady = false; - _modelScale=glm::vec3(1.0f); } const QString ModelEntityItem::getTextures() const { diff --git a/libraries/entities/src/ModelEntityItem.h b/libraries/entities/src/ModelEntityItem.h index 0efbbbb16c..89acd6179b 100644 --- a/libraries/entities/src/ModelEntityItem.h +++ b/libraries/entities/src/ModelEntityItem.h @@ -164,7 +164,7 @@ protected: int _lastKnownCurrentFrame{-1}; glm::u8vec3 _color; - glm::vec3 _modelScale; + glm::vec3 _modelScale {1.0f}; QString _modelURL; bool _relayParentJoints; bool _groupCulled { false }; From fab343a1d4d703009c585aca2bc7eba64e983cfe Mon Sep 17 00:00:00 2001 From: amer cerkic Date: Tue, 5 Mar 2019 10:52:54 -0800 Subject: [PATCH 18/18] correcting spacing --- libraries/entities/src/ModelEntityItem.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/entities/src/ModelEntityItem.h b/libraries/entities/src/ModelEntityItem.h index 89acd6179b..08468617ba 100644 --- a/libraries/entities/src/ModelEntityItem.h +++ b/libraries/entities/src/ModelEntityItem.h @@ -164,7 +164,7 @@ protected: int _lastKnownCurrentFrame{-1}; glm::u8vec3 _color; - glm::vec3 _modelScale {1.0f}; + glm::vec3 _modelScale { 1.0f }; QString _modelURL; bool _relayParentJoints; bool _groupCulled { false };