From 754f55e091358cd715c3fc6bcf56a5542cfd253f Mon Sep 17 00:00:00 2001 From: howard-stearns Date: Wed, 23 Jan 2019 20:33:05 -0800 Subject: [PATCH 01/21] Include your own NFS items in marketplace listings, so you can stock up. --- scripts/system/html/js/marketplacesInject.js | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/scripts/system/html/js/marketplacesInject.js b/scripts/system/html/js/marketplacesInject.js index f1931192e4..aafdc65606 100644 --- a/scripts/system/html/js/marketplacesInject.js +++ b/scripts/system/html/js/marketplacesInject.js @@ -402,11 +402,15 @@ purchaseButton.attr('href', '#'); var cost = $('.item-cost').text(); var costInt = parseInt(cost, 10); + // One of 'invalidated', 'not for sale', 'sold out', or 'available' var availability = $.trim($('.item-availability').text()); if (limitedCommerce && (costInt > 0)) { availability = ''; } - if (availability === 'available') { + var isUpdating = window.location.href.indexOf('edition=') > -1; + // NFS only shows for artist stocking inventory + var isBuyEnabled = ('available' === availability) || isUpdating || ('not for sale' === availability); + if (isBuyEnabled) { purchaseButton.css({ "background": "linear-gradient(#00b4ef, #0093C5)", "color": "#FFF", @@ -422,11 +426,11 @@ }); } - var type = $('.item-type').text(); - var isUpdating = window.location.href.indexOf('edition=') > -1; var urlParams = new URLSearchParams(window.location.search); if (isUpdating) { purchaseButton.html('UPDATE FOR FREE'); + } else if (availability == 'not for sale') { + purchaseButton.html("Free artist's stock to inventory"); } else if (availability !== 'available') { purchaseButton.html('UNAVAILABLE ' + (availability ? ('(' + availability + ')') : '')); } else if (parseInt(cost) > 0 && $('#side-info').find('#buyItemButton').size() === 0) { @@ -435,7 +439,7 @@ } purchaseButton.on('click', function () { - if ('available' === availability || isUpdating) { + if (isBuyEnabled) { buyButtonClicked(window.location.pathname.split("/")[3], "itemPage", urlParams.get('edition')); From bede1d9b00b214f890c8cd1c389a31a32c33dbd4 Mon Sep 17 00:00:00 2001 From: Howard Stearns Date: Fri, 25 Jan 2019 11:50:46 -0800 Subject: [PATCH 02/21] make nfs label fit in button --- scripts/system/html/js/marketplacesInject.js | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/scripts/system/html/js/marketplacesInject.js b/scripts/system/html/js/marketplacesInject.js index aafdc65606..d27387c6e8 100644 --- a/scripts/system/html/js/marketplacesInject.js +++ b/scripts/system/html/js/marketplacesInject.js @@ -258,12 +258,13 @@ priceElement.text() === 'not for sale') { available = false; priceElement.css({ - "padding": "3px 5px 10px 5px", + "padding": "3px 5px", "height": "40px", + "width": "100px", "background": "linear-gradient(#a2a2a2, #fefefe)", "color": "#000", "font-weight": "600", - "line-height": "34px" + "line-height": "20px" }); } else { priceElement.css({ From 52a43ca4cdfbb4dcbfca484beff662413edae5ce Mon Sep 17 00:00:00 2001 From: Howard Stearns Date: Fri, 25 Jan 2019 14:09:00 -0800 Subject: [PATCH 03/21] support artist's stocking to inventory --- .../qml/hifi/commerce/checkout/Checkout.qml | 55 ++++++++++++------- 1 file changed, 34 insertions(+), 21 deletions(-) diff --git a/interface/resources/qml/hifi/commerce/checkout/Checkout.qml b/interface/resources/qml/hifi/commerce/checkout/Checkout.qml index c76f5a428a..2c2d23964b 100644 --- a/interface/resources/qml/hifi/commerce/checkout/Checkout.qml +++ b/interface/resources/qml/hifi/commerce/checkout/Checkout.qml @@ -33,15 +33,19 @@ Rectangle { property bool balanceReceived: false; property bool availableUpdatesReceived: false; property bool itemInfoReceived: false; + property bool dataReady: itemInfoReceived && ownershipStatusReceived && balanceReceived && availableUpdatesReceived; property string baseItemName: ""; property string itemName; property string itemId; property string itemHref; property string itemAuthor; property int itemEdition: -1; + property bool hasSomethingToTradeIn: alreadyOwned && (itemEdition > 0); // i.e., don't trade in your artist's proof + property bool isTradingIn: isUpdating && hasSomethingToTradeIn; + property bool isStocking: availability === 'not for sale' && creator === Account.username; property string certificateId; property double balanceAfterPurchase; - property bool alreadyOwned: false; + property bool alreadyOwned: false; // Including proofs property int itemPrice: -1; property bool isCertified; property string itemType: "unknown"; @@ -56,6 +60,8 @@ Rectangle { property string referrer; property bool isInstalled; property bool isUpdating; + property string availability: "available"; + property string creator: ""; property string baseAppURL; property int currentUpdatesPage: 1; // Style @@ -454,10 +460,10 @@ Rectangle { height: 30; width: itemPriceTextLabel.width + itemPriceText.width + 20; - // "HFC" balance label + // "HFC" label HiFiGlyphs { id: itemPriceTextLabel; - visible: !(root.isUpdating && root.itemEdition > 0) && (root.itemPrice > 0); + visible: !isTradingIn && (root.itemPrice > 0); text: hifi.glyphs.hfc; // Size size: 30; @@ -473,9 +479,11 @@ Rectangle { } FiraSansSemiBold { id: itemPriceText; - text: (root.isUpdating && root.itemEdition > 0) ? "FREE\nUPDATE" : ((root.itemPrice === -1) ? "--" : ((root.itemPrice > 0) ? root.itemPrice : "FREE")); + text: isTradingIn ? "FREE\nUPDATE" : + (isStocking ? "Free for creator" : + ((root.itemPrice === -1) ? "--" : ((root.itemPrice > 0) ? root.itemPrice : "FREE"))); // Text size - size: (root.isUpdating && root.itemEdition > 0) ? 20 : 26; + size: isTradingIn ? 20 : 26; // Anchors anchors.top: parent.top; anchors.right: parent.right; @@ -571,7 +579,7 @@ Rectangle { // "View in Inventory" button HifiControlsUit.Button { id: viewInMyPurchasesButton; - visible: false; + visible: isCertified && dataReady && (isUpdating ? !hasSomethingToTradeIn : alreadyOwned); color: hifi.buttons.blue; colorScheme: hifi.colorSchemes.light; anchors.top: buyTextContainer.visible ? buyTextContainer.bottom : checkoutActionButtonsContainer.top; @@ -592,8 +600,8 @@ Rectangle { // "Buy" button HifiControlsUit.Button { id: buyButton; - visible: !((root.itemType === "avatar" || root.itemType === "app") && viewInMyPurchasesButton.visible) - enabled: (root.balanceAfterPurchase >= 0 && ownershipStatusReceived && balanceReceived && availableUpdatesReceived) || (!root.isCertified) || root.isUpdating; + visible: isTradingIn || !alreadyOwned || isStocking || !(root.itemType === "avatar" || root.itemType === "app"); + enabled: (root.balanceAfterPurchase >= 0 && dataReady) || (!root.isCertified) || root.isUpdating; color: viewInMyPurchasesButton.visible ? hifi.buttons.white : hifi.buttons.blue; colorScheme: hifi.colorSchemes.light; anchors.top: viewInMyPurchasesButton.visible ? viewInMyPurchasesButton.bottom : @@ -602,10 +610,15 @@ Rectangle { height: 50; anchors.left: parent.left; anchors.right: parent.right; - text: (root.isUpdating && root.itemEdition > 0) ? "CONFIRM UPDATE" : (((root.isCertified) ? ((ownershipStatusReceived && balanceReceived && availableUpdatesReceived) ? - ((viewInMyPurchasesButton.visible && !root.isUpdating) ? "Get It Again" : "Confirm") : "--") : "Get Item")); + text: isTradingIn ? + "CONFIRM UPDATE" : + (((root.isCertified) ? + (dataReady ? + ((viewInMyPurchasesButton.visible && !root.isUpdating) ? "Get It Again" : "Confirm") : + "--") : + "Get Item")); onClicked: { - if (root.isUpdating && root.itemEdition > 0) { + if (isTradingIn) { // If we're updating an app, the existing app needs to be uninstalled. // This call will fail/return `false` if the app isn't installed, but that's OK. if (root.itemType === "app") { @@ -1063,7 +1076,11 @@ Rectangle { buyButton.color = hifi.buttons.red; root.shouldBuyWithControlledFailure = true; } else { - buyButton.text = (root.isCertified ? ((ownershipStatusReceived && balanceReceived && availableUpdatesReceived) ? (root.alreadyOwned ? "Buy Another" : "Buy"): "--") : "Get Item"); + buyButton.text = (root.isCertified ? + (dataReady ? + (root.alreadyOwned ? "Buy Another" : "Buy") : + "--") : + "Get Item"); buyButton.color = hifi.buttons.blue; root.shouldBuyWithControlledFailure = false; } @@ -1091,6 +1108,8 @@ Rectangle { root.itemPrice = result.data.cost; root.itemAuthor = result.data.creator; root.itemType = result.data.item_type || "unknown"; + root.availability = result.data.availability; + root.creator = result.data.creator; if (root.itemType === "unknown") { root.itemHref = result.data.review_url; } else { @@ -1139,7 +1158,7 @@ Rectangle { signal sendToScript(var message); function canBuyAgain() { - return (root.itemType === "entity" || root.itemType === "wearable" || root.itemType === "contentSet" || root.itemType === "unknown"); + return root.itemType === "entity" || root.itemType === "wearable" || root.itemType === "contentSet" || root.itemType === "unknown" || isStocking; } function handleContentSets() { @@ -1185,29 +1204,23 @@ Rectangle { function refreshBuyUI() { if (root.isCertified) { - if (root.ownershipStatusReceived && root.balanceReceived && root.availableUpdatesReceived) { + if (dataReady) { buyText.text = ""; // If the user IS on the checkout page for the updated version of an owned item... if (root.isUpdating) { // If the user HAS already selected a specific edition to update... - if (root.itemEdition > 0) { + if (hasSomethingToTradeIn) { buyText.text = "By pressing \"Confirm Update\", you agree to trade in your old item for the updated item that replaces it."; buyTextContainer.color = "#FFFFFF"; buyTextContainer.border.color = "#FFFFFF"; // Else if the user HAS NOT selected a specific edition to update... } else { - viewInMyPurchasesButton.visible = true; - handleBuyAgainLogic(); } // If the user IS NOT on the checkout page for the updated verison of an owned item... // (i.e. they are checking out an item "normally") } else { - if (root.alreadyOwned) { - viewInMyPurchasesButton.visible = true; - } - handleBuyAgainLogic(); } } else { From 49a3a13d5721f38777f1685ccc828fe42d76fa80 Mon Sep 17 00:00:00 2001 From: Howard Stearns Date: Fri, 25 Jan 2019 14:13:58 -0800 Subject: [PATCH 04/21] use space a bit better --- .../resources/qml/hifi/commerce/checkout/Checkout.qml | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/interface/resources/qml/hifi/commerce/checkout/Checkout.qml b/interface/resources/qml/hifi/commerce/checkout/Checkout.qml index 2c2d23964b..700459032f 100644 --- a/interface/resources/qml/hifi/commerce/checkout/Checkout.qml +++ b/interface/resources/qml/hifi/commerce/checkout/Checkout.qml @@ -440,7 +440,7 @@ Rectangle { anchors.top: parent.top; anchors.left: itemPreviewImage.right; anchors.leftMargin: 12; - anchors.right: itemPriceContainer.left; + anchors.right: parent.right; anchors.rightMargin: 8; height: 30; // Style @@ -455,10 +455,11 @@ Rectangle { Item { id: itemPriceContainer; // Anchors - anchors.top: parent.top; - anchors.right: parent.right; + anchors.top: itemNameText.bottom; + anchors.topMargin: 8; + anchors.left: itemNameText.left; height: 30; - width: itemPriceTextLabel.width + itemPriceText.width + 20; + width: itemPriceText.width + 20; // "HFC" label HiFiGlyphs { From bed2732d342eb0d09310fae2bfdcbc788aad43be Mon Sep 17 00:00:00 2001 From: SamGondelman Date: Thu, 14 Feb 2019 12:59:16 -0800 Subject: [PATCH 05/21] start moving materials to rendering only --- interface/src/Application.cpp | 39 +-- .../src/EntityTreeRenderer.cpp | 33 +++ .../src/EntityTreeRenderer.h | 15 + .../src/RenderableEntityItem.cpp | 1 - .../src/RenderableMaterialEntityItem.cpp | 146 ++++++++-- .../src/RenderableMaterialEntityItem.h | 32 ++- libraries/entities/src/EntityItem.cpp | 19 -- libraries/entities/src/EntityItem.h | 10 - libraries/entities/src/EntityTree.cpp | 49 ---- libraries/entities/src/EntityTree.h | 22 -- libraries/entities/src/MaterialEntityItem.cpp | 262 +++++------------- libraries/entities/src/MaterialEntityItem.h | 50 +--- 12 files changed, 285 insertions(+), 393 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 1029398794..ca7678c233 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -1926,46 +1926,32 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo } }); - EntityTree::setAddMaterialToEntityOperator([this](const QUuid& entityID, graphics::MaterialLayer material, const std::string& parentMaterialName) { + EntityTreeRenderer::setAddMaterialToEntityOperator([this](const QUuid& entityID, graphics::MaterialLayer material, const std::string& parentMaterialName) { if (_aboutToQuit) { return false; } - // try to find the renderable auto renderable = getEntities()->renderableForEntityId(entityID); if (renderable) { renderable->addMaterial(material, parentMaterialName); } - // even if we don't find it, try to find the entity - auto entity = getEntities()->getEntity(entityID); - if (entity) { - entity->addMaterial(material, parentMaterialName); - return true; - } return false; }); - EntityTree::setRemoveMaterialFromEntityOperator([this](const QUuid& entityID, graphics::MaterialPointer material, const std::string& parentMaterialName) { + EntityTreeRenderer::setRemoveMaterialFromEntityOperator([this](const QUuid& entityID, graphics::MaterialPointer material, const std::string& parentMaterialName) { if (_aboutToQuit) { return false; } - // try to find the renderable auto renderable = getEntities()->renderableForEntityId(entityID); if (renderable) { renderable->removeMaterial(material, parentMaterialName); } - // even if we don't find it, try to find the entity - auto entity = getEntities()->getEntity(entityID); - if (entity) { - entity->removeMaterial(material, parentMaterialName); - return true; - } return false; }); - EntityTree::setAddMaterialToAvatarOperator([](const QUuid& avatarID, graphics::MaterialLayer material, const std::string& parentMaterialName) { + EntityTreeRenderer::setAddMaterialToAvatarOperator([](const QUuid& avatarID, graphics::MaterialLayer material, const std::string& parentMaterialName) { auto avatarManager = DependencyManager::get(); auto avatar = avatarManager->getAvatarBySessionID(avatarID); if (avatar) { @@ -1974,7 +1960,7 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo } return false; }); - EntityTree::setRemoveMaterialFromAvatarOperator([](const QUuid& avatarID, graphics::MaterialPointer material, const std::string& parentMaterialName) { + EntityTreeRenderer::setRemoveMaterialFromAvatarOperator([](const QUuid& avatarID, graphics::MaterialPointer material, const std::string& parentMaterialName) { auto avatarManager = DependencyManager::get(); auto avatar = avatarManager->getAvatarBySessionID(avatarID); if (avatar) { @@ -1984,23 +1970,6 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo return false; }); - EntityTree::setAddMaterialToOverlayOperator([this](const QUuid& overlayID, graphics::MaterialLayer material, const std::string& parentMaterialName) { - auto overlay = _overlays.getOverlay(overlayID); - if (overlay) { - overlay->addMaterial(material, parentMaterialName); - return true; - } - return false; - }); - EntityTree::setRemoveMaterialFromOverlayOperator([this](const QUuid& overlayID, graphics::MaterialPointer material, const std::string& parentMaterialName) { - auto overlay = _overlays.getOverlay(overlayID); - if (overlay) { - overlay->removeMaterial(material, parentMaterialName); - return true; - } - return false; - }); - // Keyboard focus handling for Web overlays. auto overlays = &(qApp->getOverlays()); connect(overlays, &Overlays::overlayDeleted, [this](const OverlayID& overlayID) { diff --git a/libraries/entities-renderer/src/EntityTreeRenderer.cpp b/libraries/entities-renderer/src/EntityTreeRenderer.cpp index 2b3a915235..c0774c795c 100644 --- a/libraries/entities-renderer/src/EntityTreeRenderer.cpp +++ b/libraries/entities-renderer/src/EntityTreeRenderer.cpp @@ -1360,3 +1360,36 @@ EntityEditPacketSender* EntityTreeRenderer::getPacketSender() { EntityEditPacketSender* packetSender = peSimulation ? peSimulation->getPacketSender() : nullptr; return packetSender; } + +std::function EntityTreeRenderer::_addMaterialToEntityOperator = nullptr; +std::function EntityTreeRenderer::_removeMaterialFromEntityOperator = nullptr; +std::function EntityTreeRenderer::_addMaterialToAvatarOperator = nullptr; +std::function EntityTreeRenderer::_removeMaterialFromAvatarOperator = nullptr; + +bool EntityTreeRenderer::addMaterialToEntity(const QUuid& entityID, graphics::MaterialLayer material, const std::string& parentMaterialName) { + if (_addMaterialToEntityOperator) { + return _addMaterialToEntityOperator(entityID, material, parentMaterialName); + } + return false; +} + +bool EntityTreeRenderer::removeMaterialFromEntity(const QUuid& entityID, graphics::MaterialPointer material, const std::string& parentMaterialName) { + if (_removeMaterialFromEntityOperator) { + return _removeMaterialFromEntityOperator(entityID, material, parentMaterialName); + } + return false; +} + +bool EntityTreeRenderer::addMaterialToAvatar(const QUuid& avatarID, graphics::MaterialLayer material, const std::string& parentMaterialName) { + if (_addMaterialToAvatarOperator) { + return _addMaterialToAvatarOperator(avatarID, material, parentMaterialName); + } + return false; +} + +bool EntityTreeRenderer::removeMaterialFromAvatar(const QUuid& avatarID, graphics::MaterialPointer material, const std::string& parentMaterialName) { + if (_removeMaterialFromAvatarOperator) { + return _removeMaterialFromAvatarOperator(avatarID, material, parentMaterialName); + } + return false; +} \ No newline at end of file diff --git a/libraries/entities-renderer/src/EntityTreeRenderer.h b/libraries/entities-renderer/src/EntityTreeRenderer.h index 725416e2cc..00a78bf9e4 100644 --- a/libraries/entities-renderer/src/EntityTreeRenderer.h +++ b/libraries/entities-renderer/src/EntityTreeRenderer.h @@ -123,6 +123,16 @@ public: EntityEditPacketSender* getPacketSender(); + static void setAddMaterialToEntityOperator(std::function addMaterialToEntityOperator) { _addMaterialToEntityOperator = addMaterialToEntityOperator; } + static void setRemoveMaterialFromEntityOperator(std::function removeMaterialFromEntityOperator) { _removeMaterialFromEntityOperator = removeMaterialFromEntityOperator; } + static bool addMaterialToEntity(const QUuid& entityID, graphics::MaterialLayer material, const std::string& parentMaterialName); + static bool removeMaterialFromEntity(const QUuid& entityID, graphics::MaterialPointer material, const std::string& parentMaterialName); + + static void setAddMaterialToAvatarOperator(std::function addMaterialToAvatarOperator) { _addMaterialToAvatarOperator = addMaterialToAvatarOperator; } + static void setRemoveMaterialFromAvatarOperator(std::function removeMaterialFromAvatarOperator) { _removeMaterialFromAvatarOperator = removeMaterialFromAvatarOperator; } + static bool addMaterialToAvatar(const QUuid& avatarID, graphics::MaterialLayer material, const std::string& parentMaterialName); + static bool removeMaterialFromAvatar(const QUuid& avatarID, graphics::MaterialPointer material, const std::string& parentMaterialName); + signals: void enterEntity(const EntityItemID& entityItemID); void leaveEntity(const EntityItemID& entityItemID); @@ -259,6 +269,11 @@ private: workload::Transaction::Updates _spaceUpdates; static std::function _getAvatarUpOperator; + + static std::function _addMaterialToEntityOperator; + static std::function _removeMaterialFromEntityOperator; + static std::function _addMaterialToAvatarOperator; + static std::function _removeMaterialFromAvatarOperator; }; diff --git a/libraries/entities-renderer/src/RenderableEntityItem.cpp b/libraries/entities-renderer/src/RenderableEntityItem.cpp index 83f0bdcff3..5c73b9576d 100644 --- a/libraries/entities-renderer/src/RenderableEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableEntityItem.cpp @@ -146,7 +146,6 @@ EntityRenderer::EntityRenderer(const EntityItemPointer& entity) : _created(entit _needsRenderUpdate = true; emit requestRenderUpdate(); }); - _materials = entity->getMaterials(); } EntityRenderer::~EntityRenderer() { } diff --git a/libraries/entities-renderer/src/RenderableMaterialEntityItem.cpp b/libraries/entities-renderer/src/RenderableMaterialEntityItem.cpp index 483f9ffe1c..6cc342f68a 100644 --- a/libraries/entities-renderer/src/RenderableMaterialEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableMaterialEntityItem.cpp @@ -14,23 +14,54 @@ using namespace render; using namespace render::entities; -bool MaterialEntityRenderer::needsRenderUpdateFromTypedEntity(const TypedEntityPointer& entity) const { - if (entity->getMaterial() != _drawMaterial) { - return true; - } - if (entity->getParentID() != _parentID) { - return true; - } - if (entity->getMaterialMappingPos() != _materialMappingPos || entity->getMaterialMappingScale() != _materialMappingScale || entity->getMaterialMappingRot() != _materialMappingRot) { +bool MaterialEntityRenderer::needsRenderUpdate() const { + if (_retryApply) { return true; } if (!_texturesLoaded) { return true; } + return Parent::needsRenderUpdate(); +} + +bool MaterialEntityRenderer::needsRenderUpdateFromTypedEntity(const TypedEntityPointer& entity) const { + // Could require material re-apply + if (entity->getMaterialURL() != _materialURL) { + return true; + } + if (entity->getMaterialData() != _materialData) { + return true; + } + if (entity->getParentMaterialName() != _parentMaterialName) { + return true; + } + if (entity->getParentID() != _parentID) { + return true; + } + if (entity->getPriority() != _priority) { + return true; + } + + // Won't cause material re-apply + if (entity->getMaterialMappingMode() != _materialMappingMode) { + return true; + } + if (entity->getMaterialRepeat() != _materialRepeat) { + return true; + } + if (entity->getMaterialMappingPos() != _materialMappingPos || entity->getMaterialMappingScale() != _materialMappingScale || entity->getMaterialMappingRot() != _materialMappingRot) { + return true; + } + if (entity->getTransform() != _transform) { + return true; + } + if (entity->getUnscaledDimensions() != _dimensions) { + return true; + } return false; } -void MaterialEntityRenderer::doRenderUpdateSynchronousTyped(const ScenePointer& scene, Transaction& transaction, const TypedEntityPointer& entity) { +void MaterialEntityRenderer::doRenderUpdateAsynchronousTyped(const TypedEntityPointer& entity) { withWriteLock([&] { if (_drawMaterial != entity->getMaterial()) { _texturesLoaded = false; @@ -61,8 +92,9 @@ ItemKey MaterialEntityRenderer::getKey() { builder.withInvisible(); } - if (_drawMaterial) { - auto matKey = _drawMaterial->getKey(); + const auto& drawMaterial = getMaterial(); + if (drawMaterial) { + auto matKey = drawMaterial->getKey(); if (matKey.isTranslucent()) { builder.withTransparent(); } @@ -73,8 +105,9 @@ ItemKey MaterialEntityRenderer::getKey() { ShapeKey MaterialEntityRenderer::getShapeKey() { graphics::MaterialKey drawMaterialKey; - if (_drawMaterial) { - drawMaterialKey = _drawMaterial->getKey(); + const auto& drawMaterial = getMaterial(); + if (drawMaterial) { + drawMaterialKey = drawMaterial->getKey(); } bool isTranslucent = drawMaterialKey.isTranslucent(); @@ -112,18 +145,24 @@ void MaterialEntityRenderer::doRender(RenderArgs* args) { // Don't render if our parent is set or our material is null QUuid parentID; + withReadLock([&] { + parentID = _parentID; + }); + if (!parentID.isNull()) { + return; + } + Transform renderTransform; graphics::MaterialPointer drawMaterial; Transform textureTransform; withReadLock([&] { - parentID = _parentID; renderTransform = _renderTransform; - drawMaterial = _drawMaterial; + drawMaterial = getMaterial(); textureTransform.setTranslation(glm::vec3(_materialMappingPos, 0)); textureTransform.setRotation(glm::vec3(0, 0, glm::radians(_materialMappingRot))); textureTransform.setScale(glm::vec3(_materialMappingScale, 1)); }); - if (!parentID.isNull() || !drawMaterial) { + if (!drawMaterial) { return; } @@ -142,3 +181,78 @@ void MaterialEntityRenderer::doRender(RenderArgs* args) { args->_details._trianglesRendered += (int)DependencyManager::get()->getSphereTriangleCount(); } + +void MaterialEntityRenderer::setCurrentMaterialName(const std::string& currentMaterialName) { + if (_parsedMaterials.networkMaterials.find(currentMaterialName) != _parsedMaterials.networkMaterials.end()) { + _currentMaterialName = currentMaterialName; + } else if (_parsedMaterials.names.size() > 0) { + _currentMaterialName = _parsedMaterials.names[0]; + } +} + +std::shared_ptr MaterialEntityRenderer::getMaterial() const { + auto material = _parsedMaterials.networkMaterials.find(_currentMaterialName); + if (material != _parsedMaterials.networkMaterials.end()) { + return material->second; + } else { + return nullptr; + } +} + +void MaterialEntityRenderer::deleteMaterial() { + std::shared_ptr material = getMaterial(); + if (!material) { + return; + } + QUuid parentID = _parentID; + if (parentID.isNull()) { + return; + } + + // Our parent could be an entity or an avatar + if (EntityTreeRenderer::removeMaterialFromEntity(parentID, material, _parentMaterialName.toStdString())) { + return; + } + + if (EntityTreeRenderer::removeMaterialFromAvatar(parentID, material, _parentMaterialName.toStdString())) { + return; + } + + // if a remove fails, our parent is gone, so we don't need to retry +} + +void MaterialEntityRenderer::applyMaterial() { + _retryApply = false; + std::shared_ptr material = getMaterial(); + QUuid parentID = _parentID; + if (!material || parentID.isNull()) { + return; + } + + Transform textureTransform; + if (_materialMappingMode == MaterialMappingMode::UV) { + textureTransform.setTranslation(glm::vec3(_materialMappingPos, 0.0f)); + textureTransform.setRotation(glm::vec3(0.0f, 0.0f, glm::radians(_materialMappingRot))); + textureTransform.setScale(glm::vec3(_materialMappingScale, 1.0f)); + } else if (_materialMappingMode == MaterialMappingMode::PROJECTED) { + textureTransform = _transform; + textureTransform.postScale(_dimensions); + // Pass the inverse transform here so we don't need to compute it in the shaders + textureTransform.evalFromRawMatrix(textureTransform.getInverseMatrix()); + } + material->setTextureTransforms(textureTransform, _materialMappingMode, _materialRepeat); + + graphics::MaterialLayer materialLayer = graphics::MaterialLayer(material, _priority); + + // Our parent could be an entity or an avatar + if (EntityTreeRenderer::addMaterialToEntity(parentID, materialLayer, _parentMaterialName.toStdString())) { + return; + } + + if (EntityTreeRenderer::addMaterialToAvatar(parentID, materialLayer, _parentMaterialName.toStdString())) { + return; + } + + // if we've reached this point, we couldn't find our parent, so we need to try again later + _retryApply = true; +} \ No newline at end of file diff --git a/libraries/entities-renderer/src/RenderableMaterialEntityItem.h b/libraries/entities-renderer/src/RenderableMaterialEntityItem.h index c90048ecf5..5ccbb33312 100644 --- a/libraries/entities-renderer/src/RenderableMaterialEntityItem.h +++ b/libraries/entities-renderer/src/RenderableMaterialEntityItem.h @@ -13,6 +13,9 @@ #include +#include +#include + class NetworkMaterial; namespace render { namespace entities { @@ -22,22 +25,45 @@ class MaterialEntityRenderer : public TypedEntityRenderer { using Pointer = std::shared_ptr; public: MaterialEntityRenderer(const EntityItemPointer& entity) : Parent(entity) {} + ~MaterialEntityRenderer() { deleteMaterial(); } private: + virtual bool needsRenderUpdate() const override; virtual bool needsRenderUpdateFromTypedEntity(const TypedEntityPointer& entity) const override; - virtual void doRenderUpdateSynchronousTyped(const ScenePointer& scene, Transaction& transaction, const TypedEntityPointer& entity) override; + virtual void doRenderUpdateAsynchronousTyped(const TypedEntityPointer& entity) override; virtual void doRender(RenderArgs* args) override; ItemKey getKey() override; ShapeKey getShapeKey() override; + QString _materialURL; + QString _materialData; + QString _parentMaterialName; + quint16 _priority; QUuid _parentID; + + MaterialMappingMode _materialMappingMode; + bool _materialRepeat; glm::vec2 _materialMappingPos; glm::vec2 _materialMappingScale; float _materialMappingRot; - bool _texturesLoaded { false }; + Transform _transform; + glm::vec3 _dimensions; + + bool _texturesLoaded { false }; + bool _retryApply { false }; + + std::shared_ptr getMaterial() const; + void setMaterialURL(const QString& materialURLString, bool materialDataChanged = false); + void setCurrentMaterialName(const std::string& currentMaterialName); + + void applyMaterial(); + void deleteMaterial(); + + NetworkMaterialResourcePointer _networkMaterial; + NetworkMaterialResource::ParsedMaterials _parsedMaterials; + std::string _currentMaterialName; - std::shared_ptr _drawMaterial; }; } } diff --git a/libraries/entities/src/EntityItem.cpp b/libraries/entities/src/EntityItem.cpp index 7e5be384a7..ad9acb3775 100644 --- a/libraries/entities/src/EntityItem.cpp +++ b/libraries/entities/src/EntityItem.cpp @@ -3234,25 +3234,6 @@ void EntityItem::setSpaceIndex(int32_t index) { void EntityItem::preDelete() { } -void EntityItem::addMaterial(graphics::MaterialLayer material, const std::string& parentMaterialName) { - std::lock_guard lock(_materialsLock); - _materials[parentMaterialName].push(material); -} - -void EntityItem::removeMaterial(graphics::MaterialPointer material, const std::string& parentMaterialName) { - std::lock_guard lock(_materialsLock); - _materials[parentMaterialName].remove(material); -} - -std::unordered_map EntityItem::getMaterials() { - std::unordered_map toReturn; - { - std::lock_guard lock(_materialsLock); - toReturn = _materials; - } - return toReturn; -} - bool EntityItem::getCloneable() const { bool result; withReadLock([&] { diff --git a/libraries/entities/src/EntityItem.h b/libraries/entities/src/EntityItem.h index 27b207b6f3..75fa30b3a3 100644 --- a/libraries/entities/src/EntityItem.h +++ b/libraries/entities/src/EntityItem.h @@ -37,8 +37,6 @@ #include "EntityDynamicInterface.h" #include "GrabPropertyGroup.h" -#include "graphics/Material.h" - class EntitySimulation; class EntityTreeElement; class EntityTreeElementExtraEncodeData; @@ -542,10 +540,6 @@ public: virtual void preDelete(); virtual void postParentFixup() {} - void addMaterial(graphics::MaterialLayer material, const std::string& parentMaterialName); - void removeMaterial(graphics::MaterialPointer material, const std::string& parentMaterialName); - std::unordered_map getMaterials(); - void setSimulationOwnershipExpiry(uint64_t expiry) { _simulationOwnershipExpiry = expiry; } uint64_t getSimulationOwnershipExpiry() const { return _simulationOwnershipExpiry; } @@ -750,10 +744,6 @@ protected: QHash _grabActions; -private: - std::unordered_map _materials; - std::mutex _materialsLock; - }; #endif // hifi_EntityItem_h diff --git a/libraries/entities/src/EntityTree.cpp b/libraries/entities/src/EntityTree.cpp index 954462a9f2..bf91d71050 100644 --- a/libraries/entities/src/EntityTree.cpp +++ b/libraries/entities/src/EntityTree.cpp @@ -2953,55 +2953,6 @@ QStringList EntityTree::getJointNames(const QUuid& entityID) const { return entity->getJointNames(); } -std::function EntityTree::_addMaterialToEntityOperator = nullptr; -std::function EntityTree::_removeMaterialFromEntityOperator = nullptr; -std::function EntityTree::_addMaterialToAvatarOperator = nullptr; -std::function EntityTree::_removeMaterialFromAvatarOperator = nullptr; -std::function EntityTree::_addMaterialToOverlayOperator = nullptr; -std::function EntityTree::_removeMaterialFromOverlayOperator = nullptr; - -bool EntityTree::addMaterialToEntity(const QUuid& entityID, graphics::MaterialLayer material, const std::string& parentMaterialName) { - if (_addMaterialToEntityOperator) { - return _addMaterialToEntityOperator(entityID, material, parentMaterialName); - } - return false; -} - -bool EntityTree::removeMaterialFromEntity(const QUuid& entityID, graphics::MaterialPointer material, const std::string& parentMaterialName) { - if (_removeMaterialFromEntityOperator) { - return _removeMaterialFromEntityOperator(entityID, material, parentMaterialName); - } - return false; -} - -bool EntityTree::addMaterialToAvatar(const QUuid& avatarID, graphics::MaterialLayer material, const std::string& parentMaterialName) { - if (_addMaterialToAvatarOperator) { - return _addMaterialToAvatarOperator(avatarID, material, parentMaterialName); - } - return false; -} - -bool EntityTree::removeMaterialFromAvatar(const QUuid& avatarID, graphics::MaterialPointer material, const std::string& parentMaterialName) { - if (_removeMaterialFromAvatarOperator) { - return _removeMaterialFromAvatarOperator(avatarID, material, parentMaterialName); - } - return false; -} - -bool EntityTree::addMaterialToOverlay(const QUuid& overlayID, graphics::MaterialLayer material, const std::string& parentMaterialName) { - if (_addMaterialToOverlayOperator) { - return _addMaterialToOverlayOperator(overlayID, material, parentMaterialName); - } - return false; -} - -bool EntityTree::removeMaterialFromOverlay(const QUuid& overlayID, graphics::MaterialPointer material, const std::string& parentMaterialName) { - if (_removeMaterialFromOverlayOperator) { - return _removeMaterialFromOverlayOperator(overlayID, material, parentMaterialName); - } - 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 f9b7b8d67f..367af7ba1e 100644 --- a/libraries/entities/src/EntityTree.h +++ b/libraries/entities/src/EntityTree.h @@ -262,21 +262,6 @@ public: void setIsServerlessMode(bool value) { _serverlessDomain = value; } bool isServerlessMode() const { return _serverlessDomain; } - static void setAddMaterialToEntityOperator(std::function addMaterialToEntityOperator) { _addMaterialToEntityOperator = addMaterialToEntityOperator; } - static void setRemoveMaterialFromEntityOperator(std::function removeMaterialFromEntityOperator) { _removeMaterialFromEntityOperator = removeMaterialFromEntityOperator; } - static bool addMaterialToEntity(const QUuid& entityID, graphics::MaterialLayer material, const std::string& parentMaterialName); - static bool removeMaterialFromEntity(const QUuid& entityID, graphics::MaterialPointer material, const std::string& parentMaterialName); - - static void setAddMaterialToAvatarOperator(std::function addMaterialToAvatarOperator) { _addMaterialToAvatarOperator = addMaterialToAvatarOperator; } - static void setRemoveMaterialFromAvatarOperator(std::function removeMaterialFromAvatarOperator) { _removeMaterialFromAvatarOperator = removeMaterialFromAvatarOperator; } - static bool addMaterialToAvatar(const QUuid& avatarID, graphics::MaterialLayer material, const std::string& parentMaterialName); - static bool removeMaterialFromAvatar(const QUuid& avatarID, graphics::MaterialPointer material, const std::string& parentMaterialName); - - static void setAddMaterialToOverlayOperator(std::function addMaterialToOverlayOperator) { _addMaterialToOverlayOperator = addMaterialToOverlayOperator; } - static void setRemoveMaterialFromOverlayOperator(std::function removeMaterialFromOverlayOperator) { _removeMaterialFromOverlayOperator = removeMaterialFromOverlayOperator; } - static bool addMaterialToOverlay(const QUuid& overlayID, graphics::MaterialLayer material, const std::string& parentMaterialName); - static bool removeMaterialFromOverlay(const QUuid& overlayID, graphics::MaterialPointer material, const std::string& parentMaterialName); - std::map getNamedPaths() const { return _namedPaths; } void updateEntityQueryAACube(SpatiallyNestablePointer object, EntityEditPacketSender* packetSender, @@ -385,13 +370,6 @@ private: std::shared_ptr _myAvatar{ nullptr }; - static std::function _addMaterialToEntityOperator; - static std::function _removeMaterialFromEntityOperator; - static std::function _addMaterialToAvatarOperator; - static std::function _removeMaterialFromAvatarOperator; - static std::function _addMaterialToOverlayOperator; - static std::function _removeMaterialFromOverlayOperator; - std::vector _staleProxies; bool _serverlessDomain { false }; diff --git a/libraries/entities/src/MaterialEntityItem.cpp b/libraries/entities/src/MaterialEntityItem.cpp index cec602a5e1..3a363f2e83 100644 --- a/libraries/entities/src/MaterialEntityItem.cpp +++ b/libraries/entities/src/MaterialEntityItem.cpp @@ -16,9 +16,6 @@ EntityItemPointer MaterialEntityItem::factory(const EntityItemID& entityID, const EntityItemProperties& properties) { Pointer entity(new MaterialEntityItem(entityID), [](EntityItem* ptr) { ptr->deleteLater(); }); entity->setProperties(properties); - // When you reload content, setProperties doesn't have any of the propertiesChanged flags set, so it won't trigger a material add - entity->removeMaterial(); - entity->applyMaterial(); return entity; } @@ -27,10 +24,6 @@ MaterialEntityItem::MaterialEntityItem(const EntityItemID& entityItemID) : Entit _type = EntityTypes::Material; } -MaterialEntityItem::~MaterialEntityItem() { - removeMaterial(); -} - EntityItemProperties MaterialEntityItem::getProperties(const EntityPropertyFlags& desiredProperties, bool allowEmptyDesiredProperties) const { EntityItemProperties properties = EntityItem::getProperties(desiredProperties, allowEmptyDesiredProperties); // get the properties from our base class COPY_ENTITY_PROPERTY_TO_PROPERTIES(materialURL, getMaterialURL); @@ -131,7 +124,6 @@ void MaterialEntityItem::debugDump() const { qCDebug(entities) << " MATERIAL EntityItem id:" << getEntityItemID() << "---------------------------------------------"; qCDebug(entities) << " name:" << _name; qCDebug(entities) << " material url:" << _materialURL; - qCDebug(entities) << " current material name:" << _currentMaterialName.c_str(); qCDebug(entities) << " material mapping mode:" << _materialMappingMode; qCDebug(entities) << " material repeat:" << _materialRepeat; qCDebug(entities) << " priority:" << _priority; @@ -154,216 +146,101 @@ void MaterialEntityItem::setUnscaledDimensions(const glm::vec3& value) { } } -std::shared_ptr MaterialEntityItem::getMaterial() const { - auto material = _parsedMaterials.networkMaterials.find(_currentMaterialName); - if (material != _parsedMaterials.networkMaterials.end()) { - return material->second; - } else { - return nullptr; - } +QString MaterialEntityItem::getMaterialURL() const { + return resultWithReadLock([&] { + return _materialURL; + }); } -void MaterialEntityItem::setMaterialURL(const QString& materialURLString, bool materialDataChanged) { - bool usingMaterialData = materialDataChanged || materialURLString.startsWith("materialData"); - if (_materialURL != materialURLString || (usingMaterialData && materialDataChanged)) { - removeMaterial(); - _materialURL = materialURLString; - - if (materialURLString.contains("?")) { - auto split = materialURLString.split("?"); - _currentMaterialName = split.last().toStdString(); - } - - if (usingMaterialData) { - _parsedMaterials = NetworkMaterialResource::parseJSONMaterials(QJsonDocument::fromJson(getMaterialData().toUtf8()), materialURLString); - - // Since our material changed, the current name might not be valid anymore, so we need to update - setCurrentMaterialName(_currentMaterialName); - applyMaterial(); - } else { - _networkMaterial = MaterialCache::instance().getMaterial(materialURLString); - auto onMaterialRequestFinished = [&](bool success) { - if (success) { - _parsedMaterials = _networkMaterial->parsedMaterials; - - setCurrentMaterialName(_currentMaterialName); - applyMaterial(); - } - }; - if (_networkMaterial) { - if (_networkMaterial->isLoaded()) { - onMaterialRequestFinished(!_networkMaterial->isFailed()); - } else { - connect(_networkMaterial.data(), &Resource::finished, this, onMaterialRequestFinished); - } - } - } - } +void MaterialEntityItem::setMaterialURL(const QString& materialURL) { + withWriteLock([&] { + _materialURL = materialURL; + }); } -void MaterialEntityItem::setCurrentMaterialName(const std::string& currentMaterialName) { - if (_parsedMaterials.networkMaterials.find(currentMaterialName) != _parsedMaterials.networkMaterials.end()) { - _currentMaterialName = currentMaterialName; - } else if (_parsedMaterials.names.size() > 0) { - _currentMaterialName = _parsedMaterials.names[0]; - } +QString MaterialEntityItem::getMaterialData() const { + return resultWithReadLock([&] { + return _materialData; + }); } void MaterialEntityItem::setMaterialData(const QString& materialData) { - if (_materialData != materialData) { + withWriteLock([&] { _materialData = materialData; - if (_materialURL.startsWith("materialData")) { - // Trigger material update when material data changes - setMaterialURL(_materialURL, true); - } - } + }); +} + +MaterialMappingMode MaterialEntityItem::getMaterialMappingMode() const { + return resultWithReadLock([&] { + return _materialMappingMode; + }); } void MaterialEntityItem::setMaterialMappingMode(MaterialMappingMode mode) { - if (_materialMappingMode != mode) { - removeMaterial(); + withWriteLock([&] { _materialMappingMode = mode; - setUnscaledDimensions(_desiredDimensions); - applyMaterial(); - } + }); + setUnscaledDimensions(_desiredDimensions); } -void MaterialEntityItem::setMaterialRepeat(bool repeat) { - if (_materialRepeat != repeat) { - removeMaterial(); - _materialRepeat = repeat; - applyMaterial(); - } -} - -void MaterialEntityItem::setMaterialMappingPos(const glm::vec2& materialMappingPos) { - if (_materialMappingPos != materialMappingPos) { - removeMaterial(); - _materialMappingPos = materialMappingPos; - applyMaterial(); - } -} - -void MaterialEntityItem::setMaterialMappingScale(const glm::vec2& materialMappingScale) { - if (_materialMappingScale != materialMappingScale) { - removeMaterial(); - _materialMappingScale = materialMappingScale; - applyMaterial(); - } -} - -void MaterialEntityItem::setMaterialMappingRot(const float& materialMappingRot) { - if (_materialMappingRot != materialMappingRot) { - removeMaterial(); - _materialMappingRot = materialMappingRot; - applyMaterial(); - } +quint16 MaterialEntityItem::getPriority() const { + return resultWithReadLock([&] { + return _priority; + }); } void MaterialEntityItem::setPriority(quint16 priority) { - if (_priority != priority) { - removeMaterial(); + withWriteLock([&] { _priority = priority; - applyMaterial(); - } + }); +} + +QString MaterialEntityItem::getParentMaterialName() const { + return resultWithReadLock([&] { + return _parentMaterialName; + }); } void MaterialEntityItem::setParentMaterialName(const QString& parentMaterialName) { - if (_parentMaterialName != parentMaterialName) { - removeMaterial(); + withWriteLock([&] { _parentMaterialName = parentMaterialName; - applyMaterial(); - } + }); } -void MaterialEntityItem::setParentID(const QUuid& parentID) { - if (getParentID() != parentID) { - removeMaterial(); - EntityItem::setParentID(parentID); - applyMaterial(); - } +glm::vec2 MaterialEntityItem::getMaterialMappingPos() const { + return resultWithReadLock([&] { + return _materialMappingPos; + }); } -void MaterialEntityItem::locationChanged(bool tellPhysics) { - EntityItem::locationChanged(); - if (_materialMappingMode == MaterialMappingMode::PROJECTED) { - removeMaterial(); - applyMaterial(); - } +void MaterialEntityItem::setMaterialMappingPos(const glm::vec2& materialMappingPos) { + withWriteLock([&] { + _materialMappingPos = materialMappingPos; + }); } -void MaterialEntityItem::dimensionsChanged() { - EntityItem::dimensionsChanged(); - if (_materialMappingMode == MaterialMappingMode::PROJECTED) { - removeMaterial(); - applyMaterial(); - } +glm::vec2 MaterialEntityItem::getMaterialMappingScale() const { + return resultWithReadLock([&] { + return _materialMappingScale; + }); } -void MaterialEntityItem::removeMaterial() { - graphics::MaterialPointer material = getMaterial(); - if (!material) { - return; - } - QUuid parentID = getParentID(); - if (parentID.isNull()) { - return; - } - - // Our parent could be an entity, an avatar, or an overlay - if (EntityTree::removeMaterialFromEntity(parentID, material, getParentMaterialName().toStdString())) { - return; - } - - if (EntityTree::removeMaterialFromAvatar(parentID, material, getParentMaterialName().toStdString())) { - return; - } - - if (EntityTree::removeMaterialFromOverlay(parentID, material, getParentMaterialName().toStdString())) { - return; - } - - // if a remove fails, our parent is gone, so we don't need to retry +void MaterialEntityItem::setMaterialMappingScale(const glm::vec2& materialMappingScale) { + withWriteLock([&] { + _materialMappingScale = materialMappingScale; + }); } -void MaterialEntityItem::applyMaterial() { - _retryApply = false; - graphics::MaterialPointer material = getMaterial(); - QUuid parentID = getParentID(); - if (!material || parentID.isNull()) { - return; - } +float MaterialEntityItem::getMaterialMappingRot() const { + return resultWithReadLock([&] { + return _materialMappingRot; + }); +} - Transform textureTransform; - if (_materialMappingMode == MaterialMappingMode::UV) { - textureTransform.setTranslation(glm::vec3(_materialMappingPos, 0.0f)); - textureTransform.setRotation(glm::vec3(0.0f, 0.0f, glm::radians(_materialMappingRot))); - textureTransform.setScale(glm::vec3(_materialMappingScale, 1.0f)); - } else if (_materialMappingMode == MaterialMappingMode::PROJECTED) { - textureTransform = getTransform(); - textureTransform.postScale(getUnscaledDimensions()); - // Pass the inverse transform here so we don't need to compute it in the shaders - textureTransform.evalFromRawMatrix(textureTransform.getInverseMatrix()); - } - material->setTextureTransforms(textureTransform, _materialMappingMode, _materialRepeat); - - graphics::MaterialLayer materialLayer = graphics::MaterialLayer(material, getPriority()); - - // Our parent could be an entity, an avatar, or an overlay - if (EntityTree::addMaterialToEntity(parentID, materialLayer, getParentMaterialName().toStdString())) { - return; - } - - if (EntityTree::addMaterialToAvatar(parentID, materialLayer, getParentMaterialName().toStdString())) { - return; - } - - if (EntityTree::addMaterialToOverlay(parentID, materialLayer, getParentMaterialName().toStdString())) { - return; - } - - // if we've reached this point, we couldn't find our parent, so we need to try again later - _retryApply = true; +void MaterialEntityItem::setMaterialMappingRot(float materialMappingRot) { + withWriteLock([&] { + _materialMappingRot = materialMappingRot; + }); } AACube MaterialEntityItem::calculateInitialQueryAACube(bool& success) { @@ -380,18 +257,3 @@ AACube MaterialEntityItem::calculateInitialQueryAACube(bool& success) { } return aaCube; } - -void MaterialEntityItem::postParentFixup() { - removeMaterial(); - _queryAACubeSet = false; // force an update so we contain our parent - updateQueryAACube(); - applyMaterial(); -} - -void MaterialEntityItem::update(const quint64& now) { - if (_retryApply) { - applyMaterial(); - } - - EntityItem::update(now); -} diff --git a/libraries/entities/src/MaterialEntityItem.h b/libraries/entities/src/MaterialEntityItem.h index ba142d7719..b9e83a7fe5 100644 --- a/libraries/entities/src/MaterialEntityItem.h +++ b/libraries/entities/src/MaterialEntityItem.h @@ -12,8 +12,6 @@ #include "EntityItem.h" #include "MaterialMappingMode.h" -#include -#include class MaterialEntityItem : public EntityItem { using Pointer = std::shared_ptr; @@ -21,13 +19,9 @@ public: static EntityItemPointer factory(const EntityItemID& entityID, const EntityItemProperties& properties); MaterialEntityItem(const EntityItemID& entityItemID); - ~MaterialEntityItem(); ALLOW_INSTANTIATION // This class can be instantiated - void update(const quint64& now) override; - bool needsToCallUpdate() const override { return true; } - // methods for getting/setting all properties of an entity virtual EntityItemProperties getProperties(const EntityPropertyFlags& desiredProperties, bool allowEmptyDesiredProperties) const override; virtual bool setProperties(const EntityItemProperties& properties) override; @@ -52,44 +46,30 @@ public: virtual void setUnscaledDimensions(const glm::vec3& value) override; - QString getMaterialURL() const { return _materialURL; } - void setMaterialURL(const QString& materialURLString, bool materialDataChanged = false); + QString getMaterialURL() const; + void setMaterialURL(const QString& materialURL); - void setCurrentMaterialName(const std::string& currentMaterialName); + QString getMaterialData() const; + void setMaterialData(const QString& materialData); - MaterialMappingMode getMaterialMappingMode() const { return _materialMappingMode; } + MaterialMappingMode getMaterialMappingMode() const; void setMaterialMappingMode(MaterialMappingMode mode); bool getMaterialRepeat() const { return _materialRepeat; } - void setMaterialRepeat(bool repeat); + void setMaterialRepeat(bool repeat) { _materialRepeat = repeat; } - quint16 getPriority() const { return _priority; } + quint16 getPriority() const; void setPriority(quint16 priority); - QString getParentMaterialName() const { return _parentMaterialName; } + QString getParentMaterialName() const; void setParentMaterialName(const QString& parentMaterialName); - glm::vec2 getMaterialMappingPos() const { return _materialMappingPos; } + glm::vec2 getMaterialMappingPos() const; void setMaterialMappingPos(const glm::vec2& materialMappingPos); - glm::vec2 getMaterialMappingScale() const { return _materialMappingScale; } + glm::vec2 getMaterialMappingScale() const; void setMaterialMappingScale(const glm::vec2& materialMappingScale); - float getMaterialMappingRot() const { return _materialMappingRot; } - void setMaterialMappingRot(const float& materialMappingRot); - - QString getMaterialData() const { return _materialData; } - void setMaterialData(const QString& materialData); - - std::shared_ptr getMaterial() const; - - void setParentID(const QUuid& parentID) override; - - void locationChanged(bool tellPhysics) override; - void dimensionsChanged() override; - - void applyMaterial(); - void removeMaterial(); - - void postParentFixup() override; + float getMaterialMappingRot() const; + void setMaterialMappingRot(float materialMappingRot); AACube calculateInitialQueryAACube(bool& success) override; @@ -128,12 +108,6 @@ private: float _materialMappingRot { 0 }; QString _materialData; - NetworkMaterialResourcePointer _networkMaterial; - NetworkMaterialResource::ParsedMaterials _parsedMaterials; - std::string _currentMaterialName; - - bool _retryApply { false }; - }; #endif // hifi_MaterialEntityItem_h From 490ef3542eaa398c69f105e7c71b1aefb3ceeb6d Mon Sep 17 00:00:00 2001 From: Howard Stearns Date: Fri, 15 Feb 2019 10:58:09 -0800 Subject: [PATCH 06/21] update for marketplace-in-qml, and make specific to username --- .../qml/hifi/commerce/marketplace/Marketplace.qml | 8 ++++---- .../hifi/commerce/marketplace/MarketplaceItem.qml | 14 ++++++++++---- .../commerce/marketplace/MarketplaceListItem.qml | 14 +++++++++++--- 3 files changed, 25 insertions(+), 11 deletions(-) diff --git a/interface/resources/qml/hifi/commerce/marketplace/Marketplace.qml b/interface/resources/qml/hifi/commerce/marketplace/Marketplace.qml index 0d42cb599e..b7d3a22e44 100644 --- a/interface/resources/qml/hifi/commerce/marketplace/Marketplace.qml +++ b/interface/resources/qml/hifi/commerce/marketplace/Marketplace.qml @@ -120,7 +120,7 @@ Rectangle { marketplaceItem.description = result.data.description; marketplaceItem.attributions = result.data.attributions; marketplaceItem.license = result.data.license; - marketplaceItem.available = result.data.availability === "available"; + marketplaceItem.availability = result.data.availability; marketplaceItem.created_at = result.data.created_at; marketplaceItemScrollView.contentHeight = marketplaceItemContent.height; itemsList.visible = false; @@ -532,7 +532,7 @@ Rectangle { creator: model.creator category: model.primary_category price: model.cost - available: model.availability === "available" + availability: model.availability isLoggedIn: root.isLoggedIn; onShowItem: { @@ -704,7 +704,7 @@ Rectangle { topMargin: 10; leftMargin: 15; } - height: visible ? childrenRect.height : 0 + height: visible ? 36 : 0 RalewayRegular { id: sortText @@ -727,7 +727,7 @@ Rectangle { leftMargin: 20 } width: root.isLoggedIn ? 322 : 242 - height: 36 + height: parent.height radius: 4 border.width: 1 diff --git a/interface/resources/qml/hifi/commerce/marketplace/MarketplaceItem.qml b/interface/resources/qml/hifi/commerce/marketplace/MarketplaceItem.qml index 0a57e56099..bbf9be908a 100644 --- a/interface/resources/qml/hifi/commerce/marketplace/MarketplaceItem.qml +++ b/interface/resources/qml/hifi/commerce/marketplace/MarketplaceItem.qml @@ -33,11 +33,11 @@ Rectangle { property string creator: "" property var categories: [] property int price: 0 + property string availability: "unknown" property var attributions: [] property string description: "" property string license: "" property string posted: "" - property bool available: false property string created_at: "" property bool isLoggedIn: false; property int edition: -1; @@ -264,9 +264,15 @@ Rectangle { } height: 50 - text: root.edition >= 0 ? "UPGRADE FOR FREE" : (root.available ? (root.price ? root.price : "FREE") : "UNAVAILABLE (not for sale)") - enabled: root.edition >= 0 || root.available - buttonGlyph: root.available ? (root.price ? hifi.glyphs.hfc : "") : "" + property bool isNFS: availability === "not for sale" // Note: server will say "sold out" or "invalidated" before it says NFS + property bool isMine: creator === Account.username + property bool isUpgrade: root.edition >= 0 + property int costToMe: ((isMine && isNFS) || isUpgrade) ? 0 : price + property bool isAvailable: costToMe >= 0 + + text: isUpgrade ? "UPGRADE FOR FREE" : (isAvailable ? (costToMe || "FREE") : ("UNAVAILABLE (" + availibility + ")")) + enabled: isAvailable + buttonGlyph: isAvailable ? (costToMe ? hifi.glyphs.hfc : "") : "" color: hifi.buttons.blue onClicked: root.buy(); diff --git a/interface/resources/qml/hifi/commerce/marketplace/MarketplaceListItem.qml b/interface/resources/qml/hifi/commerce/marketplace/MarketplaceListItem.qml index 2f37637e40..fd3b960002 100644 --- a/interface/resources/qml/hifi/commerce/marketplace/MarketplaceListItem.qml +++ b/interface/resources/qml/hifi/commerce/marketplace/MarketplaceListItem.qml @@ -34,7 +34,7 @@ Rectangle { property string creator: "" property string category: "" property int price: 0 - property bool available: false + property string availability: "unknown" property bool isLoggedIn: false; signal buy() @@ -299,8 +299,16 @@ Rectangle { bottomMargin: 10 } - text: root.price ? root.price : "FREE" - buttonGlyph: root.price ? hifi.glyphs.hfc : "" + property bool isNFS: availability === "not for sale" // Note: server will say "sold out" or "invalidated" before it says NFS + property bool isMine: creator === Account.username + property bool isUpgrade: root.edition >= 0 + property int costToMe: ((isMine && isNFS) || isUpgrade) ? 0 : price + property bool isAvailable: costToMe >= 0 + + text: isUpgrade ? "UPGRADE FOR FREE" : (isAvailable ? (costToMe || "FREE") : ("UNAVAILABLE (" + availibility + ")")) + enabled: isAvailable + buttonGlyph: isAvailable ? (costToMe ? hifi.glyphs.hfc : "") : "" + color: hifi.buttons.blue; onClicked: root.buy(); From 87ab255115bc8e4bbc25e07d00a28da1f0723b46 Mon Sep 17 00:00:00 2001 From: SamGondelman Date: Fri, 15 Feb 2019 11:49:20 -0800 Subject: [PATCH 07/21] finish moving materials to rendering --- interface/src/Application.cpp | 8 -- .../src/RenderableMaterialEntityItem.cpp | 132 +++++++++++++----- .../src/RenderableMaterialEntityItem.h | 4 +- 3 files changed, 100 insertions(+), 44 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index b8fb05daf4..e7910ddfae 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -1970,14 +1970,6 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo return renderable->textSize(text); } } - }); - - // Keyboard focus handling for Web overlays. - auto overlays = &(qApp->getOverlays()); - connect(overlays, &Overlays::overlayDeleted, [this](const OverlayID& overlayID) { - if (overlayID == _keyboardFocusedOverlay.get()) { - setKeyboardFocusOverlay(UNKNOWN_OVERLAY_ID); - } return QSizeF(0.0f, 0.0f); }); diff --git a/libraries/entities-renderer/src/RenderableMaterialEntityItem.cpp b/libraries/entities-renderer/src/RenderableMaterialEntityItem.cpp index b986702f5a..31b862000b 100644 --- a/libraries/entities-renderer/src/RenderableMaterialEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableMaterialEntityItem.cpp @@ -105,45 +105,106 @@ void MaterialEntityRenderer::doRenderUpdateAsynchronousTyped(const TypedEntityPo } } - auto& material = getMaterial(); - // Update the old material regardless of if it's going to change - if (transformChanged && material && !_parentID.isNull()) { - Transform textureTransform; - if (_materialMappingMode == MaterialMappingMode::UV) { - textureTransform.setTranslation(glm::vec3(_materialMappingPos, 0.0f)); - textureTransform.setRotation(glm::vec3(0.0f, 0.0f, glm::radians(_materialMappingRot))); - textureTransform.setScale(glm::vec3(_materialMappingScale, 1.0f)); - } else if (_materialMappingMode == MaterialMappingMode::PROJECTED) { - textureTransform = _transform; - textureTransform.postScale(_dimensions); - // Pass the inverse transform here so we don't need to compute it in the shaders - textureTransform.evalFromRawMatrix(textureTransform.getInverseMatrix()); + { + auto& material = getMaterial(); + // Update the old material regardless of if it's going to change + if (transformChanged && material && !_parentID.isNull()) { + applyTextureTransform(material); } - material->setTextureTransforms(textureTransform, _materialMappingMode, _materialRepeat); } bool deleteNeeded = false; bool addNeeded = _retryApply; + bool urlChanged = false; { QString materialURL = entity->getMaterialURL(); if (materialURL != _materialURL) { _materialURL = materialURL; + if (_materialURL.contains("?")) { + auto split = _materialURL.split("?"); + _currentMaterialName = split.last().toStdString(); + } + urlChanged = true; + } + } + + bool usingMaterialData = _materialURL.startsWith("materialData"); + { + QString materialData = entity->getMaterialData(); + if (materialData != _materialData) { + _materialData = materialData; + if (usingMaterialData) { + _texturesLoaded = false; + deleteNeeded = true; + addNeeded = true; + _parsedMaterials = NetworkMaterialResource::parseJSONMaterials(QJsonDocument::fromJson(_materialData.toUtf8()), _materialURL); + // Since our material changed, the current name might not be valid anymore, so we need to update + setCurrentMaterialName(_currentMaterialName); + } + } + } + { + QString parentMaterialName = entity->getParentMaterialName(); + if (parentMaterialName != _parentMaterialName) { + _parentMaterialName = parentMaterialName; + deleteNeeded = true; + addNeeded = true; + } + } + QUuid oldParentID = _parentID; + { + QUuid parentID = entity->getParentID(); + if (parentID != _parentID) { + _parentID = parentID; + deleteNeeded = true; + addNeeded = true; + } + } + { + quint16 priority = entity->getPriority(); + if (priority != _priority) { + _priority = priority; deleteNeeded = true; addNeeded = true; } } - if (_drawMaterial != entity->getMaterial()) { - _texturesLoaded = false; - _drawMaterial = entity->getMaterial(); + if (urlChanged && !usingMaterialData) { + _networkMaterial = MaterialCache::instance().getMaterial(_materialURL); + auto onMaterialRequestFinished = [&, oldParentID](bool success) { + if (success) { + _texturesLoaded = false; + _parsedMaterials = _networkMaterial->parsedMaterials; + setCurrentMaterialName(_currentMaterialName); + deleteMaterial(oldParentID); + applyMaterial(); + } + }; + if (_networkMaterial) { + if (_networkMaterial->isLoaded()) { + onMaterialRequestFinished(!_networkMaterial->isFailed()); + } else { + connect(_networkMaterial.data(), &Resource::finished, this, onMaterialRequestFinished); + } + } + } else { + if (deleteNeeded) { + deleteMaterial(oldParentID); + } + if (addNeeded) { + applyMaterial(); + } } - bool newTexturesLoaded = _drawMaterial ? !_drawMaterial->isMissingTexture() : false; - if (!_texturesLoaded && newTexturesLoaded) { - _drawMaterial->checkResetOpacityMap(); + { + auto& material = getMaterial(); + bool newTexturesLoaded = material ? !material->isMissingTexture() : false; + if (!_texturesLoaded && newTexturesLoaded) { + material->checkResetOpacityMap(); + } + _texturesLoaded = newTexturesLoaded; } - _texturesLoaded = newTexturesLoaded; _renderTransform = getModelTransform(); const float MATERIAL_ENTITY_SCALE = 0.5f; @@ -267,36 +328,28 @@ std::shared_ptr MaterialEntityRenderer::getMaterial() const { } } -void MaterialEntityRenderer::deleteMaterial() { +void MaterialEntityRenderer::deleteMaterial(const QUuid& oldParentID) { std::shared_ptr material = getMaterial(); if (!material) { return; } - QUuid parentID = _parentID; - if (parentID.isNull()) { + if (oldParentID.isNull()) { return; } // Our parent could be an entity or an avatar - if (EntityTreeRenderer::removeMaterialFromEntity(parentID, material, _parentMaterialName.toStdString())) { + if (EntityTreeRenderer::removeMaterialFromEntity(oldParentID, material, _parentMaterialName.toStdString())) { return; } - if (EntityTreeRenderer::removeMaterialFromAvatar(parentID, material, _parentMaterialName.toStdString())) { + if (EntityTreeRenderer::removeMaterialFromAvatar(oldParentID, material, _parentMaterialName.toStdString())) { return; } // if a remove fails, our parent is gone, so we don't need to retry } -void MaterialEntityRenderer::applyMaterial() { - _retryApply = false; - std::shared_ptr material = getMaterial(); - QUuid parentID = _parentID; - if (!material || parentID.isNull()) { - return; - } - +void MaterialEntityRenderer::applyTextureTransform(std::shared_ptr& material) { Transform textureTransform; if (_materialMappingMode == MaterialMappingMode::UV) { textureTransform.setTranslation(glm::vec3(_materialMappingPos, 0.0f)); @@ -309,6 +362,17 @@ void MaterialEntityRenderer::applyMaterial() { textureTransform.evalFromRawMatrix(textureTransform.getInverseMatrix()); } material->setTextureTransforms(textureTransform, _materialMappingMode, _materialRepeat); +} + +void MaterialEntityRenderer::applyMaterial() { + _retryApply = false; + std::shared_ptr& material = getMaterial(); + QUuid parentID = _parentID; + if (!material || parentID.isNull()) { + return; + } + + applyTextureTransform(material); graphics::MaterialLayer materialLayer = graphics::MaterialLayer(material, _priority); diff --git a/libraries/entities-renderer/src/RenderableMaterialEntityItem.h b/libraries/entities-renderer/src/RenderableMaterialEntityItem.h index 5ccbb33312..639cc6c9fe 100644 --- a/libraries/entities-renderer/src/RenderableMaterialEntityItem.h +++ b/libraries/entities-renderer/src/RenderableMaterialEntityItem.h @@ -54,11 +54,11 @@ private: bool _retryApply { false }; std::shared_ptr getMaterial() const; - void setMaterialURL(const QString& materialURLString, bool materialDataChanged = false); void setCurrentMaterialName(const std::string& currentMaterialName); + void applyTextureTransform(std::shared_ptr& material); void applyMaterial(); - void deleteMaterial(); + void deleteMaterial(const QUuid& oldParentID); NetworkMaterialResourcePointer _networkMaterial; NetworkMaterialResource::ParsedMaterials _parsedMaterials; From 3df231f1e06cf48bdcadf21d217354465c10715d Mon Sep 17 00:00:00 2001 From: SamGondelman Date: Fri, 15 Feb 2019 14:43:22 -0800 Subject: [PATCH 08/21] it's working! --- interface/src/Application.cpp | 2 + .../src/RenderableMaterialEntityItem.cpp | 58 ++++++++++++------- .../src/RenderableMaterialEntityItem.h | 5 +- 3 files changed, 41 insertions(+), 24 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 7691e06b5d..1bbe7a814d 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -1919,6 +1919,7 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo auto renderable = getEntities()->renderableForEntityId(entityID); if (renderable) { renderable->addMaterial(material, parentMaterialName); + return true; } return false; @@ -1931,6 +1932,7 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo auto renderable = getEntities()->renderableForEntityId(entityID); if (renderable) { renderable->removeMaterial(material, parentMaterialName); + return true; } return false; diff --git a/libraries/entities-renderer/src/RenderableMaterialEntityItem.cpp b/libraries/entities-renderer/src/RenderableMaterialEntityItem.cpp index 31b862000b..8f11bdc31f 100644 --- a/libraries/entities-renderer/src/RenderableMaterialEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableMaterialEntityItem.cpp @@ -117,30 +117,29 @@ void MaterialEntityRenderer::doRenderUpdateAsynchronousTyped(const TypedEntityPo bool addNeeded = _retryApply; bool urlChanged = false; + std::string newCurrentMaterialName = _currentMaterialName; { QString materialURL = entity->getMaterialURL(); if (materialURL != _materialURL) { _materialURL = materialURL; if (_materialURL.contains("?")) { auto split = _materialURL.split("?"); - _currentMaterialName = split.last().toStdString(); + newCurrentMaterialName = split.last().toStdString(); } urlChanged = true; } } bool usingMaterialData = _materialURL.startsWith("materialData"); + bool materialDataChanged = false; + QUuid oldParentID = _parentID; + QString oldParentMaterialName = _parentMaterialName; { QString materialData = entity->getMaterialData(); if (materialData != _materialData) { _materialData = materialData; if (usingMaterialData) { - _texturesLoaded = false; - deleteNeeded = true; - addNeeded = true; - _parsedMaterials = NetworkMaterialResource::parseJSONMaterials(QJsonDocument::fromJson(_materialData.toUtf8()), _materialURL); - // Since our material changed, the current name might not be valid anymore, so we need to update - setCurrentMaterialName(_currentMaterialName); + materialDataChanged = true; } } } @@ -152,7 +151,6 @@ void MaterialEntityRenderer::doRenderUpdateAsynchronousTyped(const TypedEntityPo addNeeded = true; } } - QUuid oldParentID = _parentID; { QUuid parentID = entity->getParentID(); if (parentID != _parentID) { @@ -172,13 +170,17 @@ void MaterialEntityRenderer::doRenderUpdateAsynchronousTyped(const TypedEntityPo if (urlChanged && !usingMaterialData) { _networkMaterial = MaterialCache::instance().getMaterial(_materialURL); - auto onMaterialRequestFinished = [&, oldParentID](bool success) { + auto onMaterialRequestFinished = [&, oldParentID, oldParentMaterialName, newCurrentMaterialName](bool success) { if (success) { + deleteMaterial(oldParentID, oldParentMaterialName); _texturesLoaded = false; _parsedMaterials = _networkMaterial->parsedMaterials; - setCurrentMaterialName(_currentMaterialName); - deleteMaterial(oldParentID); + setCurrentMaterialName(newCurrentMaterialName); applyMaterial(); + } else { + deleteMaterial(oldParentID, oldParentMaterialName); + _retryApply = false; + _texturesLoaded = true; } }; if (_networkMaterial) { @@ -188,9 +190,16 @@ void MaterialEntityRenderer::doRenderUpdateAsynchronousTyped(const TypedEntityPo connect(_networkMaterial.data(), &Resource::finished, this, onMaterialRequestFinished); } } + } else if (materialDataChanged && usingMaterialData) { + deleteMaterial(oldParentID, oldParentMaterialName); + _texturesLoaded = false; + _parsedMaterials = NetworkMaterialResource::parseJSONMaterials(QJsonDocument::fromJson(_materialData.toUtf8()), _materialURL); + // Since our material changed, the current name might not be valid anymore, so we need to update + setCurrentMaterialName(newCurrentMaterialName); + applyMaterial(); } else { if (deleteNeeded) { - deleteMaterial(oldParentID); + deleteMaterial(oldParentID, oldParentMaterialName); } if (addNeeded) { applyMaterial(); @@ -328,21 +337,21 @@ std::shared_ptr MaterialEntityRenderer::getMaterial() const { } } -void MaterialEntityRenderer::deleteMaterial(const QUuid& oldParentID) { - std::shared_ptr material = getMaterial(); - if (!material) { - return; - } - if (oldParentID.isNull()) { +void MaterialEntityRenderer::deleteMaterial(const QUuid& oldParentID, const QString& oldParentMaterialName) { + std::shared_ptr material = _appliedMaterial; + if (!material || oldParentID.isNull()) { return; } // Our parent could be an entity or an avatar - if (EntityTreeRenderer::removeMaterialFromEntity(oldParentID, material, _parentMaterialName.toStdString())) { + std::string oldParentMaterialNameStd = oldParentMaterialName.toStdString(); + if (EntityTreeRenderer::removeMaterialFromEntity(oldParentID, material, oldParentMaterialNameStd)) { + _appliedMaterial = nullptr; return; } - if (EntityTreeRenderer::removeMaterialFromAvatar(oldParentID, material, _parentMaterialName.toStdString())) { + if (EntityTreeRenderer::removeMaterialFromAvatar(oldParentID, material, oldParentMaterialNameStd)) { + _appliedMaterial = nullptr; return; } @@ -366,9 +375,11 @@ void MaterialEntityRenderer::applyTextureTransform(std::shared_ptr& material = getMaterial(); QUuid parentID = _parentID; if (!material || parentID.isNull()) { + _appliedMaterial = nullptr; return; } @@ -377,11 +388,14 @@ void MaterialEntityRenderer::applyMaterial() { graphics::MaterialLayer materialLayer = graphics::MaterialLayer(material, _priority); // Our parent could be an entity or an avatar - if (EntityTreeRenderer::addMaterialToEntity(parentID, materialLayer, _parentMaterialName.toStdString())) { + std::string parentMaterialName = _parentMaterialName.toStdString(); + if (EntityTreeRenderer::addMaterialToEntity(parentID, materialLayer, parentMaterialName)) { + _appliedMaterial = material; return; } - if (EntityTreeRenderer::addMaterialToAvatar(parentID, materialLayer, _parentMaterialName.toStdString())) { + if (EntityTreeRenderer::addMaterialToAvatar(parentID, materialLayer, parentMaterialName)) { + _appliedMaterial = material; return; } diff --git a/libraries/entities-renderer/src/RenderableMaterialEntityItem.h b/libraries/entities-renderer/src/RenderableMaterialEntityItem.h index b68aee9d48..d714727c7a 100644 --- a/libraries/entities-renderer/src/RenderableMaterialEntityItem.h +++ b/libraries/entities-renderer/src/RenderableMaterialEntityItem.h @@ -24,7 +24,7 @@ class MaterialEntityRenderer : public TypedEntityRenderer { using Pointer = std::shared_ptr; public: MaterialEntityRenderer(const EntityItemPointer& entity) : Parent(entity) {} - ~MaterialEntityRenderer() { deleteMaterial(_parentID); } + ~MaterialEntityRenderer() { deleteMaterial(_parentID, _parentMaterialName); } private: virtual bool needsRenderUpdate() const override; @@ -57,10 +57,11 @@ private: void applyTextureTransform(std::shared_ptr& material); void applyMaterial(); - void deleteMaterial(const QUuid& oldParentID); + void deleteMaterial(const QUuid& oldParentID, const QString& oldParentMaterialName); NetworkMaterialResourcePointer _networkMaterial; NetworkMaterialResource::ParsedMaterials _parsedMaterials; + std::shared_ptr _appliedMaterial; std::string _currentMaterialName; }; From b00746c096a1098ded35b06944d233db9af82f78 Mon Sep 17 00:00:00 2001 From: danteruiz Date: Thu, 14 Feb 2019 09:46:41 -0800 Subject: [PATCH 09/21] Trim picks in use during quest: --- .../src/raypick/PickScriptingInterface.cpp | 12 ++++ .../src/raypick/PointerScriptingInterface.cpp | 11 ++++ libraries/pointers/src/PickCacheOptimizer.h | 2 + libraries/pointers/src/PickManager.cpp | 26 +++++++-- libraries/shared/src/Profile.cpp | 1 + libraries/shared/src/Profile.h | 1 + .../controllerScripts.js | 58 +++++++++++++++++++ .../controllers/controllerDispatcher.js | 1 + 8 files changed, 108 insertions(+), 4 deletions(-) create mode 100644 scripts/system/controllers/+android_questInterface/controllerScripts.js diff --git a/interface/src/raypick/PickScriptingInterface.cpp b/interface/src/raypick/PickScriptingInterface.cpp index ce01db3a56..cf7680bb6c 100644 --- a/interface/src/raypick/PickScriptingInterface.cpp +++ b/interface/src/raypick/PickScriptingInterface.cpp @@ -71,6 +71,18 @@ PickFilter getPickFilter(unsigned int filter) { unsigned int PickScriptingInterface::createRayPick(const QVariant& properties) { QVariantMap propMap = properties.toMap(); + +#if defined (Q_OS_ANDROID) + QString jointName { "" }; + if (propMap["joint"].isValid()) { + QString jointName = propMap["joint"].toString(); + QString mouseJoint { "Mouse" }; + if (jointName == mouseJoint) { + return PointerEvent::INVALID_POINTER_ID; + } + } +#endif + bool enabled = false; if (propMap["enabled"].isValid()) { enabled = propMap["enabled"].toBool(); diff --git a/interface/src/raypick/PointerScriptingInterface.cpp b/interface/src/raypick/PointerScriptingInterface.cpp index 19c20f0c06..10761e0696 100644 --- a/interface/src/raypick/PointerScriptingInterface.cpp +++ b/interface/src/raypick/PointerScriptingInterface.cpp @@ -150,6 +150,17 @@ unsigned int PointerScriptingInterface::createStylus(const QVariant& properties) unsigned int PointerScriptingInterface::createLaserPointer(const QVariant& properties) const { QVariantMap propertyMap = properties.toMap(); +#if defined (Q_OS_ANDROID) + QString jointName { "" }; + if (propertyMap["joint"].isValid()) { + QString jointName = propertyMap["joint"].toString(); + QString mouseJoint { "Mouse" }; + if (jointName == mouseJoint) { + return PointerEvent::INVALID_POINTER_ID; + } + } +#endif + bool faceAvatar = false; if (propertyMap["faceAvatar"].isValid()) { faceAvatar = propertyMap["faceAvatar"].toBool(); diff --git a/libraries/pointers/src/PickCacheOptimizer.h b/libraries/pointers/src/PickCacheOptimizer.h index 0bbdfea8e4..6aa343480b 100644 --- a/libraries/pointers/src/PickCacheOptimizer.h +++ b/libraries/pointers/src/PickCacheOptimizer.h @@ -11,6 +11,8 @@ #include #include "Pick.h" +#include "PerfStat.h" +#include "Profile.h" typedef struct PickCacheKey { PickFilter::Flags mask; diff --git a/libraries/pointers/src/PickManager.cpp b/libraries/pointers/src/PickManager.cpp index d3326ea8b4..0cf5f90e3d 100644 --- a/libraries/pointers/src/PickManager.cpp +++ b/libraries/pointers/src/PickManager.cpp @@ -6,6 +6,8 @@ // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // #include "PickManager.h" +#include "PerfStat.h" +#include "Profile.h" PickManager::PickManager() { setShouldPickHUDOperator([]() { return false; }); @@ -119,10 +121,26 @@ void PickManager::update() { bool shouldPickHUD = _shouldPickHUDOperator(); // FIXME: give each type its own expiry // Each type will update at least one pick, regardless of the expiry - _updatedPickCounts[PickQuery::Stylus] = _stylusPickCacheOptimizer.update(cachedPicks[PickQuery::Stylus], _nextPickToUpdate[PickQuery::Stylus], expiry, false); - _updatedPickCounts[PickQuery::Ray] = _rayPickCacheOptimizer.update(cachedPicks[PickQuery::Ray], _nextPickToUpdate[PickQuery::Ray], expiry, shouldPickHUD); - _updatedPickCounts[PickQuery::Parabola] = _parabolaPickCacheOptimizer.update(cachedPicks[PickQuery::Parabola], _nextPickToUpdate[PickQuery::Parabola], expiry, shouldPickHUD); - _updatedPickCounts[PickQuery::Collision] = _collisionPickCacheOptimizer.update(cachedPicks[PickQuery::Collision], _nextPickToUpdate[PickQuery::Collision], expiry, false); + { + PROFILE_RANGE(picks, "StylusPicks"); + PerformanceTimer perfTimer("StylusPicks"); + _updatedPickCounts[PickQuery::Stylus] = _stylusPickCacheOptimizer.update(cachedPicks[PickQuery::Stylus], _nextPickToUpdate[PickQuery::Stylus], expiry, false); + } + { + PROFILE_RANGE(picks, "RayPicks"); + PerformanceTimer perfTimer("RayPicks"); + _updatedPickCounts[PickQuery::Ray] = _rayPickCacheOptimizer.update(cachedPicks[PickQuery::Ray], _nextPickToUpdate[PickQuery::Ray], expiry, shouldPickHUD); + } + { + PROFILE_RANGE(picks, "ParabolaPick"); + PerformanceTimer perfTimer("ParabolaPick"); + _updatedPickCounts[PickQuery::Parabola] = _parabolaPickCacheOptimizer.update(cachedPicks[PickQuery::Parabola], _nextPickToUpdate[PickQuery::Parabola], expiry, shouldPickHUD); + } + { + PROFILE_RANGE(picks, "CollisoinPicks"); + PerformanceTimer perfTimer("CollisionPicks"); + _updatedPickCounts[PickQuery::Collision] = _collisionPickCacheOptimizer.update(cachedPicks[PickQuery::Collision], _nextPickToUpdate[PickQuery::Collision], expiry, false); + } } bool PickManager::isLeftHand(unsigned int uid) { diff --git a/libraries/shared/src/Profile.cpp b/libraries/shared/src/Profile.cpp index 778b39aca5..272538e26d 100644 --- a/libraries/shared/src/Profile.cpp +++ b/libraries/shared/src/Profile.cpp @@ -12,6 +12,7 @@ Q_LOGGING_CATEGORY(trace_app, "trace.app") Q_LOGGING_CATEGORY(trace_app_detail, "trace.app.detail") Q_LOGGING_CATEGORY(trace_metadata, "trace.metadata") Q_LOGGING_CATEGORY(trace_network, "trace.network") +Q_LOGGING_CATEGORY(trace_picks, "trace.picks") Q_LOGGING_CATEGORY(trace_parse, "trace.parse") Q_LOGGING_CATEGORY(trace_render, "trace.render") Q_LOGGING_CATEGORY(trace_render_detail, "trace.render.detail") diff --git a/libraries/shared/src/Profile.h b/libraries/shared/src/Profile.h index 01d86f8f2e..dc2ed6e754 100644 --- a/libraries/shared/src/Profile.h +++ b/libraries/shared/src/Profile.h @@ -18,6 +18,7 @@ Q_DECLARE_LOGGING_CATEGORY(trace_app) Q_DECLARE_LOGGING_CATEGORY(trace_app_detail) Q_DECLARE_LOGGING_CATEGORY(trace_metadata) Q_DECLARE_LOGGING_CATEGORY(trace_network) +Q_DECLARE_LOGGING_CATEGORY(trace_picks) Q_DECLARE_LOGGING_CATEGORY(trace_render) Q_DECLARE_LOGGING_CATEGORY(trace_render_detail) Q_DECLARE_LOGGING_CATEGORY(trace_render_gpu) diff --git a/scripts/system/controllers/+android_questInterface/controllerScripts.js b/scripts/system/controllers/+android_questInterface/controllerScripts.js new file mode 100644 index 0000000000..d313efaca1 --- /dev/null +++ b/scripts/system/controllers/+android_questInterface/controllerScripts.js @@ -0,0 +1,58 @@ +"use strict"; + +// controllerScripts.js +// +// Created by David Rowe on 15 Mar 2017. +// 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 +// + +/* global Script, Menu */ + +var CONTOLLER_SCRIPTS = [ + "squeezeHands.js", + "controllerDisplayManager.js", + "toggleAdvancedMovementForHandControllers.js", + "controllerDispatcher.js", + "controllerModules/nearParentGrabOverlay.js", + "controllerModules/stylusInput.js", + "controllerModules/equipEntity.js", + "controllerModules/nearTrigger.js", + "controllerModules/webSurfaceLaserInput.js", + "controllerModules/inVREditMode.js", + "controllerModules/disableOtherModule.js", + "controllerModules/farTrigger.js", + "controllerModules/teleport.js", + "controllerModules/hudOverlayPointer.js", + "controllerModules/scaleEntity.js", + "controllerModules/nearGrabHyperLinkEntity.js", + "controllerModules/nearTabletHighlight.js", + "controllerModules/nearGrabEntity.js", + "controllerModules/farGrabEntity.js" +]; + +var DEBUG_MENU_ITEM = "Debug defaultScripts.js"; + +function runDefaultsTogether() { + for (var j in CONTOLLER_SCRIPTS) { + if (CONTOLLER_SCRIPTS.hasOwnProperty(j)) { + Script.include(CONTOLLER_SCRIPTS[j]); + } + } +} + +function runDefaultsSeparately() { + for (var i in CONTOLLER_SCRIPTS) { + if (CONTOLLER_SCRIPTS.hasOwnProperty(i)) { + Script.load(CONTOLLER_SCRIPTS[i]); + } + } +} + +if (Menu.isOptionChecked(DEBUG_MENU_ITEM)) { + runDefaultsSeparately(); +} else { + runDefaultsTogether(); +} diff --git a/scripts/system/controllers/controllerDispatcher.js b/scripts/system/controllers/controllerDispatcher.js index 2a5cf5a727..28c3e2a299 100644 --- a/scripts/system/controllers/controllerDispatcher.js +++ b/scripts/system/controllers/controllerDispatcher.js @@ -497,6 +497,7 @@ Script.include("/~/system/libraries/controllerDispatcherUtils.js"); distanceScaleEnd: true, hand: RIGHT_HAND }); + this.mouseRayPick = Pointers.createPointer(PickType.Ray, { joint: "Mouse", filter: Picks.PICK_OVERLAYS | Picks.PICK_ENTITIES | Picks.PICK_INCLUDE_NONCOLLIDABLE, From 6bf154528598efa3ed8509a8f4be0903c9da0367 Mon Sep 17 00:00:00 2001 From: SamGondelman Date: Fri, 15 Feb 2019 16:44:28 -0800 Subject: [PATCH 10/21] fix build error --- .../src/RenderableMaterialEntityItem.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/libraries/entities-renderer/src/RenderableMaterialEntityItem.cpp b/libraries/entities-renderer/src/RenderableMaterialEntityItem.cpp index 8f11bdc31f..57d8fd76f7 100644 --- a/libraries/entities-renderer/src/RenderableMaterialEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableMaterialEntityItem.cpp @@ -106,7 +106,7 @@ void MaterialEntityRenderer::doRenderUpdateAsynchronousTyped(const TypedEntityPo } { - auto& material = getMaterial(); + auto material = getMaterial(); // Update the old material regardless of if it's going to change if (transformChanged && material && !_parentID.isNull()) { applyTextureTransform(material); @@ -207,7 +207,7 @@ void MaterialEntityRenderer::doRenderUpdateAsynchronousTyped(const TypedEntityPo } { - auto& material = getMaterial(); + auto material = getMaterial(); bool newTexturesLoaded = material ? !material->isMissingTexture() : false; if (!_texturesLoaded && newTexturesLoaded) { material->checkResetOpacityMap(); @@ -230,7 +230,7 @@ ItemKey MaterialEntityRenderer::getKey() { builder.withInvisible(); } - const auto& drawMaterial = getMaterial(); + const auto drawMaterial = getMaterial(); if (drawMaterial) { auto matKey = drawMaterial->getKey(); if (matKey.isTranslucent()) { @@ -243,7 +243,7 @@ ItemKey MaterialEntityRenderer::getKey() { ShapeKey MaterialEntityRenderer::getShapeKey() { graphics::MaterialKey drawMaterialKey; - const auto& drawMaterial = getMaterial(); + const auto drawMaterial = getMaterial(); if (drawMaterial) { drawMaterialKey = drawMaterial->getKey(); } @@ -376,7 +376,7 @@ void MaterialEntityRenderer::applyTextureTransform(std::shared_ptr& material = getMaterial(); + std::shared_ptr material = getMaterial(); QUuid parentID = _parentID; if (!material || parentID.isNull()) { _appliedMaterial = nullptr; From e9b323a8078cfaac63b746d50899bbedbd738220 Mon Sep 17 00:00:00 2001 From: Howard Stearns Date: Fri, 15 Feb 2019 16:56:31 -0800 Subject: [PATCH 11/21] fix HFC symbol location at checkout, and the display of unavailable items --- .../resources/qml/hifi/commerce/checkout/Checkout.qml | 8 ++++---- .../qml/hifi/commerce/marketplace/MarketplaceItem.qml | 2 +- .../qml/hifi/commerce/marketplace/MarketplaceListItem.qml | 2 +- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/interface/resources/qml/hifi/commerce/checkout/Checkout.qml b/interface/resources/qml/hifi/commerce/checkout/Checkout.qml index 5ea9b2d4b4..9589c842e6 100644 --- a/interface/resources/qml/hifi/commerce/checkout/Checkout.qml +++ b/interface/resources/qml/hifi/commerce/checkout/Checkout.qml @@ -469,8 +469,8 @@ Rectangle { // Size size: 30; // Anchors - anchors.right: itemPriceText.left; - anchors.rightMargin: 4; + anchors.right: parent.right; + //anchors.rightMargin: 4; anchors.top: parent.top; anchors.topMargin: 0; width: paintedWidth; @@ -487,8 +487,8 @@ Rectangle { size: isTradingIn ? 20 : 26; // Anchors anchors.top: parent.top; - anchors.right: parent.right; - anchors.rightMargin: 16; + anchors.left: itemPriceTextLabel.visible ? itemPriceTextLabel.right : parent.left; + anchors.leftMargin: 4; width: paintedWidth; height: paintedHeight; // Style diff --git a/interface/resources/qml/hifi/commerce/marketplace/MarketplaceItem.qml b/interface/resources/qml/hifi/commerce/marketplace/MarketplaceItem.qml index 45ed213660..97e5c10a6b 100644 --- a/interface/resources/qml/hifi/commerce/marketplace/MarketplaceItem.qml +++ b/interface/resources/qml/hifi/commerce/marketplace/MarketplaceItem.qml @@ -270,7 +270,7 @@ Rectangle { property int costToMe: ((isMine && isNFS) || isUpgrade) ? 0 : price property bool isAvailable: costToMe >= 0 - text: isUpgrade ? "UPGRADE FOR FREE" : (isAvailable ? (costToMe || "FREE") : ("UNAVAILABLE (" + availibility + ")")) + text: isUpgrade ? "UPGRADE FOR FREE" : (isAvailable ? (costToMe || "FREE") : availability) enabled: isAvailable buttonGlyph: isAvailable ? (costToMe ? hifi.glyphs.hfc : "") : "" color: hifi.buttons.blue diff --git a/interface/resources/qml/hifi/commerce/marketplace/MarketplaceListItem.qml b/interface/resources/qml/hifi/commerce/marketplace/MarketplaceListItem.qml index fd3b960002..587d71da28 100644 --- a/interface/resources/qml/hifi/commerce/marketplace/MarketplaceListItem.qml +++ b/interface/resources/qml/hifi/commerce/marketplace/MarketplaceListItem.qml @@ -305,7 +305,7 @@ Rectangle { property int costToMe: ((isMine && isNFS) || isUpgrade) ? 0 : price property bool isAvailable: costToMe >= 0 - text: isUpgrade ? "UPGRADE FOR FREE" : (isAvailable ? (costToMe || "FREE") : ("UNAVAILABLE (" + availibility + ")")) + text: isUpgrade ? "UPGRADE FOR FREE" : (isAvailable ? (costToMe || "FREE") : availability) enabled: isAvailable buttonGlyph: isAvailable ? (costToMe ? hifi.glyphs.hfc : "") : "" From 3e3bd2ffd85be7b474a0ab4b35cd050cc0c838db Mon Sep 17 00:00:00 2001 From: SamGondelman Date: Fri, 15 Feb 2019 16:57:29 -0800 Subject: [PATCH 12/21] fix transform properties not changing --- .../src/RenderableMaterialEntityItem.cpp | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/libraries/entities-renderer/src/RenderableMaterialEntityItem.cpp b/libraries/entities-renderer/src/RenderableMaterialEntityItem.cpp index 57d8fd76f7..2eb877b0e1 100644 --- a/libraries/entities-renderer/src/RenderableMaterialEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableMaterialEntityItem.cpp @@ -26,7 +26,6 @@ bool MaterialEntityRenderer::needsRenderUpdate() const { bool MaterialEntityRenderer::needsRenderUpdateFromTypedEntity(const TypedEntityPointer& entity) const { if (resultWithReadLock([&] { - // Won't cause material re-apply if (entity->getMaterialMappingMode() != _materialMappingMode) { return true; } @@ -43,7 +42,6 @@ bool MaterialEntityRenderer::needsRenderUpdateFromTypedEntity(const TypedEntityP return true; } - // Could require material re-apply if (entity->getMaterialURL() != _materialURL) { return true; } @@ -69,6 +67,8 @@ bool MaterialEntityRenderer::needsRenderUpdateFromTypedEntity(const TypedEntityP void MaterialEntityRenderer::doRenderUpdateAsynchronousTyped(const TypedEntityPointer& entity) { withWriteLock([&] { + bool deleteNeeded = false; + bool addNeeded = _retryApply; bool transformChanged = false; { MaterialMappingMode mode = entity->getMaterialMappingMode(); @@ -109,14 +109,13 @@ void MaterialEntityRenderer::doRenderUpdateAsynchronousTyped(const TypedEntityPo auto material = getMaterial(); // Update the old material regardless of if it's going to change if (transformChanged && material && !_parentID.isNull()) { + deleteNeeded = true; + addNeeded = true; applyTextureTransform(material); } } - bool deleteNeeded = false; - bool addNeeded = _retryApply; bool urlChanged = false; - std::string newCurrentMaterialName = _currentMaterialName; { QString materialURL = entity->getMaterialURL(); From d50904dd4a209c0da209095133a336b7118d4362 Mon Sep 17 00:00:00 2001 From: SamGondelman Date: Fri, 15 Feb 2019 17:08:24 -0800 Subject: [PATCH 13/21] fix avatar deadlock --- libraries/avatars/src/AvatarHashMap.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/libraries/avatars/src/AvatarHashMap.cpp b/libraries/avatars/src/AvatarHashMap.cpp index 5f30d98ed6..c16d65506a 100644 --- a/libraries/avatars/src/AvatarHashMap.cpp +++ b/libraries/avatars/src/AvatarHashMap.cpp @@ -208,16 +208,16 @@ AvatarSharedPointer AvatarHashMap::addAvatar(const QUuid& sessionUUID, const QWe avatar->setSessionUUID(sessionUUID); avatar->setOwningAvatarMixer(mixerWeakPointer); - // addAvatar is only called from newOrExistingAvatar, which already locks _hashLock - _avatarHash.insert(sessionUUID, avatar); + { + QWriteLocker locker(&_hashLock); + _avatarHash.insert(sessionUUID, avatar); + } emit avatarAddedEvent(sessionUUID); return avatar; } -AvatarSharedPointer AvatarHashMap::newOrExistingAvatar(const QUuid& sessionUUID, const QWeakPointer& mixerWeakPointer, - bool& isNew) { - QWriteLocker locker(&_hashLock); - auto avatar = _avatarHash.value(sessionUUID); +AvatarSharedPointer AvatarHashMap::newOrExistingAvatar(const QUuid& sessionUUID, const QWeakPointer& mixerWeakPointer, bool& isNew) { + auto avatar = findAvatar(sessionUUID); if (!avatar) { avatar = addAvatar(sessionUUID, mixerWeakPointer); isNew = true; From c8ab7ac37f5ff6624c1b8ad6cb74cb02a2357304 Mon Sep 17 00:00:00 2001 From: Sam Gondelman Date: Sat, 16 Feb 2019 18:08:05 -0800 Subject: [PATCH 14/21] fix bad copy --- libraries/entities-renderer/src/EntityTreeRenderer.h | 2 -- 1 file changed, 2 deletions(-) diff --git a/libraries/entities-renderer/src/EntityTreeRenderer.h b/libraries/entities-renderer/src/EntityTreeRenderer.h index 154ad08811..def17ac835 100644 --- a/libraries/entities-renderer/src/EntityTreeRenderer.h +++ b/libraries/entities-renderer/src/EntityTreeRenderer.h @@ -265,8 +265,6 @@ private: workload::SpacePointer _space{ new workload::Space() }; workload::Transaction::Updates _spaceUpdates; - static std::function _getAvatarUpOperator; - static std::function _addMaterialToEntityOperator; static std::function _removeMaterialFromEntityOperator; static std::function _addMaterialToAvatarOperator; From 71653f95d7b51a6677d5bbab7f85023162842795 Mon Sep 17 00:00:00 2001 From: SamGondelman Date: Sat, 16 Feb 2019 20:08:36 -0800 Subject: [PATCH 15/21] working on overlay bugs --- interface/src/Application.cpp | 2 +- .../ui/overlays/ContextOverlayInterface.cpp | 19 +++++++---------- .../src/ui/overlays/ContextOverlayInterface.h | 1 - interface/src/ui/overlays/Overlays.cpp | 21 +++++++------------ interface/src/ui/overlays/Overlays.h | 1 - .../src/EntityTreeRenderer.h | 1 + .../controllers/controllerModules/teleport.js | 2 +- scripts/system/pal.js | 3 ++- 8 files changed, 19 insertions(+), 31 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index b65f39ffd7..fc53253b00 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -2282,7 +2282,7 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer, bo // Setup the mouse ray pick and related operators { - auto mouseRayPick = std::make_shared(Vectors::ZERO, Vectors::UP, PickFilter(PickScriptingInterface::PICK_ENTITIES()), 0.0f, true); + auto mouseRayPick = std::make_shared(Vectors::ZERO, Vectors::UP, PickFilter(PickScriptingInterface::PICK_ENTITIES() | PickScriptingInterface::PICK_LOCAL_ENTITIES()), 0.0f, true); mouseRayPick->parentTransform = std::make_shared(); mouseRayPick->setJointState(PickQuery::JOINT_STATE_MOUSE); auto mouseRayPickID = DependencyManager::get()->addPick(PickQuery::Ray, mouseRayPick); diff --git a/interface/src/ui/overlays/ContextOverlayInterface.cpp b/interface/src/ui/overlays/ContextOverlayInterface.cpp index c382c3de43..24c0986d09 100644 --- a/interface/src/ui/overlays/ContextOverlayInterface.cpp +++ b/interface/src/ui/overlays/ContextOverlayInterface.cpp @@ -70,7 +70,6 @@ ContextOverlayInterface::ContextOverlayInterface() { } }); connect(entityScriptingInterface, &EntityScriptingInterface::deletingEntity, this, &ContextOverlayInterface::deletingEntity); - connect(&qApp->getOverlays(), &Overlays::mousePressOnOverlay, this, &ContextOverlayInterface::contextOverlays_mousePressOnOverlay); connect(&qApp->getOverlays(), &Overlays::hoverEnterOverlay, this, &ContextOverlayInterface::contextOverlays_hoverEnterOverlay); connect(&qApp->getOverlays(), &Overlays::hoverLeaveOverlay, this, &ContextOverlayInterface::contextOverlays_hoverLeaveOverlay); @@ -103,10 +102,14 @@ void ContextOverlayInterface::setEnabled(bool enabled) { } } -void ContextOverlayInterface::clickDownOnEntity(const EntityItemID& entityItemID, const PointerEvent& event) { - if (_enabled && event.getButton() == PointerEvent::SecondaryButton && contextOverlayFilterPassed(entityItemID)) { - _mouseDownEntity = entityItemID; +void ContextOverlayInterface::clickDownOnEntity(const EntityItemID& id, const PointerEvent& event) { + if (_enabled && event.getButton() == PointerEvent::SecondaryButton && contextOverlayFilterPassed(id)) { + _mouseDownEntity = id; _mouseDownEntityTimestamp = usecTimestampNow(); + } else if (id == _contextOverlayID && event.getButton() == PointerEvent::PrimaryButton) { + qCDebug(context_overlay) << "Clicked Context Overlay. Entity ID:" << _currentEntityWithContextOverlay << "ID:" << id; + emit contextOverlayClicked(_currentEntityWithContextOverlay); + _contextOverlayJustClicked = true; } else { if (!_currentEntityWithContextOverlay.isNull()) { disableEntityHighlight(_currentEntityWithContextOverlay); @@ -249,14 +252,6 @@ bool ContextOverlayInterface::destroyContextOverlay(const EntityItemID& entityIt return ContextOverlayInterface::destroyContextOverlay(entityItemID, PointerEvent()); } -void ContextOverlayInterface::contextOverlays_mousePressOnOverlay(const QUuid& id, const PointerEvent& event) { - if (id == _contextOverlayID && event.getButton() == PointerEvent::PrimaryButton) { - qCDebug(context_overlay) << "Clicked Context Overlay. Entity ID:" << _currentEntityWithContextOverlay << "ID:" << id; - emit contextOverlayClicked(_currentEntityWithContextOverlay); - _contextOverlayJustClicked = true; - } -} - void ContextOverlayInterface::contextOverlays_hoverEnterOverlay(const QUuid& id, const PointerEvent& event) { if (_contextOverlayID != UNKNOWN_ENTITY_ID) { qCDebug(context_overlay) << "Started hovering over Context Overlay. ID:" << id; diff --git a/interface/src/ui/overlays/ContextOverlayInterface.h b/interface/src/ui/overlays/ContextOverlayInterface.h index b87535acf2..57fc8ebe6e 100644 --- a/interface/src/ui/overlays/ContextOverlayInterface.h +++ b/interface/src/ui/overlays/ContextOverlayInterface.h @@ -65,7 +65,6 @@ public slots: bool createOrDestroyContextOverlay(const EntityItemID& entityItemID, const PointerEvent& event); bool destroyContextOverlay(const EntityItemID& entityItemID, const PointerEvent& event); bool destroyContextOverlay(const EntityItemID& entityItemID); - void contextOverlays_mousePressOnOverlay(const QUuid& id, const PointerEvent& event); void contextOverlays_hoverEnterOverlay(const QUuid& id, const PointerEvent& event); void contextOverlays_hoverLeaveOverlay(const QUuid& id, const PointerEvent& event); void contextOverlays_hoverEnterEntity(const EntityItemID& entityID, const PointerEvent& event); diff --git a/interface/src/ui/overlays/Overlays.cpp b/interface/src/ui/overlays/Overlays.cpp index e1708c14fe..2ec67070ba 100644 --- a/interface/src/ui/overlays/Overlays.cpp +++ b/interface/src/ui/overlays/Overlays.cpp @@ -63,13 +63,6 @@ Overlays::Overlays() { ADD_TYPE_MAP(PolyLine, line3d); ADD_TYPE_MAP(Grid, grid); ADD_TYPE_MAP(Gizmo, circle3d); - - auto mouseRayPick = std::make_shared(Vectors::ZERO, Vectors::UP, - PickFilter(PickFilter::getBitMask(PickFilter::FlagBit::LOCAL_ENTITIES) | - PickFilter::getBitMask(PickFilter::FlagBit::VISIBLE)), 0.0f, true); - mouseRayPick->parentTransform = std::make_shared(); - mouseRayPick->setJointState(PickQuery::JOINT_STATE_MOUSE); - _mouseRayPickID = DependencyManager::get()->addPick(PickQuery::Ray, mouseRayPick); } void Overlays::cleanupAllOverlays() { @@ -1228,12 +1221,12 @@ static PointerEvent::Button toPointerButton(const QMouseEvent& event) { } } -RayToOverlayIntersectionResult getPrevPickResult(unsigned int mouseRayPickID) { +RayToOverlayIntersectionResult getPrevPickResult() { RayToOverlayIntersectionResult overlayResult; overlayResult.intersects = false; - auto pickResult = DependencyManager::get()->getPrevPickResultTyped(mouseRayPickID); + auto pickResult = DependencyManager::get()->getPrevPickResultTyped(DependencyManager::get()->getMouseRayPickID()); if (pickResult) { - overlayResult.intersects = pickResult->type != IntersectionType::NONE; + overlayResult.intersects = pickResult->type == IntersectionType::LOCAL_ENTITY; if (overlayResult.intersects) { overlayResult.intersection = pickResult->intersection; overlayResult.distance = pickResult->distance; @@ -1281,7 +1274,7 @@ std::pair Overlays::mousePressEvent(QMouseEvent* event) { PerformanceTimer perfTimer("Overlays::mousePressEvent"); PickRay ray = qApp->computePickRay(event->x(), event->y()); - RayToOverlayIntersectionResult rayPickResult = getPrevPickResult(_mouseRayPickID); + RayToOverlayIntersectionResult rayPickResult = getPrevPickResult(); if (rayPickResult.intersects) { _currentClickingOnOverlayID = rayPickResult.overlayID; @@ -1305,7 +1298,7 @@ bool Overlays::mouseDoublePressEvent(QMouseEvent* event) { PerformanceTimer perfTimer("Overlays::mouseDoublePressEvent"); PickRay ray = qApp->computePickRay(event->x(), event->y()); - RayToOverlayIntersectionResult rayPickResult = getPrevPickResult(_mouseRayPickID); + RayToOverlayIntersectionResult rayPickResult = getPrevPickResult(); if (rayPickResult.intersects) { _currentClickingOnOverlayID = rayPickResult.overlayID; @@ -1321,7 +1314,7 @@ bool Overlays::mouseReleaseEvent(QMouseEvent* event) { PerformanceTimer perfTimer("Overlays::mouseReleaseEvent"); PickRay ray = qApp->computePickRay(event->x(), event->y()); - RayToOverlayIntersectionResult rayPickResult = getPrevPickResult(_mouseRayPickID); + RayToOverlayIntersectionResult rayPickResult = getPrevPickResult(); if (rayPickResult.intersects) { auto pointerEvent = calculateOverlayPointerEvent(rayPickResult.overlayID, ray, rayPickResult, event, PointerEvent::Release); mouseReleasePointerEvent(rayPickResult.overlayID, pointerEvent); @@ -1343,7 +1336,7 @@ bool Overlays::mouseMoveEvent(QMouseEvent* event) { PerformanceTimer perfTimer("Overlays::mouseMoveEvent"); PickRay ray = qApp->computePickRay(event->x(), event->y()); - RayToOverlayIntersectionResult rayPickResult = getPrevPickResult(_mouseRayPickID); + RayToOverlayIntersectionResult rayPickResult = getPrevPickResult(); if (rayPickResult.intersects) { auto pointerEvent = calculateOverlayPointerEvent(rayPickResult.overlayID, ray, rayPickResult, event, PointerEvent::Move); mouseMovePointerEvent(rayPickResult.overlayID, pointerEvent); diff --git a/interface/src/ui/overlays/Overlays.h b/interface/src/ui/overlays/Overlays.h index 7612779099..838a38eb54 100644 --- a/interface/src/ui/overlays/Overlays.h +++ b/interface/src/ui/overlays/Overlays.h @@ -719,7 +719,6 @@ private: PointerEvent calculateOverlayPointerEvent(const QUuid& id, const PickRay& ray, const RayToOverlayIntersectionResult& rayPickResult, QMouseEvent* event, PointerEvent::EventType eventType); - unsigned int _mouseRayPickID; QUuid _currentClickingOnOverlayID; QUuid _currentHoverOverOverlayID; diff --git a/libraries/entities-renderer/src/EntityTreeRenderer.h b/libraries/entities-renderer/src/EntityTreeRenderer.h index 204dc50c45..50e74f7cea 100644 --- a/libraries/entities-renderer/src/EntityTreeRenderer.h +++ b/libraries/entities-renderer/src/EntityTreeRenderer.h @@ -73,6 +73,7 @@ public: static void setEntityLoadingPriorityFunction(CalculateEntityLoadingPriority fn) { _calculateEntityLoadingPriorityFunc = fn; } void setMouseRayPickID(unsigned int rayPickID) { _mouseRayPickID = rayPickID; } + unsigned int getMouseRayPickID() { return _mouseRayPickID; } void setMouseRayPickResultOperator(std::function getPrevRayPickResultOperator) { _getPrevRayPickResultOperator = getPrevRayPickResultOperator; } void setSetPrecisionPickingOperator(std::function setPrecisionPickingOperator) { _setPrecisionPickingOperator = setPrecisionPickingOperator; } diff --git a/scripts/system/controllers/controllerModules/teleport.js b/scripts/system/controllers/controllerModules/teleport.js index 8770ae8dde..48b23d834e 100644 --- a/scripts/system/controllers/controllerModules/teleport.js +++ b/scripts/system/controllers/controllerModules/teleport.js @@ -578,7 +578,7 @@ Script.include("/~/system/libraries/controllers.js"); } } _this.teleportedFadeTimer = null; - Selection.disableListHighlight(this.teleporterSelectionName); + Selection.disableListHighlight(_this.teleporterSelectionName); } }; diff --git a/scripts/system/pal.js b/scripts/system/pal.js index 141ea03330..0c4338b31d 100644 --- a/scripts/system/pal.js +++ b/scripts/system/pal.js @@ -161,7 +161,8 @@ ExtendedOverlay.unHover = function () { // calls hover(false) on lastHoveringId // hit(overlay) on the one overlay intersected by pickRay, if any. // noHit() if no ExtendedOverlay was intersected (helps with hover) ExtendedOverlay.applyPickRay = function (pickRay, hit, noHit) { - var pickedOverlay = Overlays.findRayIntersection(pickRay); // Depends on nearer coverOverlays to extend closer to us than farther ones. + // TODO: this could just include the necessary overlays for better performance + var pickedOverlay = Overlays.findRayIntersection(pickRay, true); // Depends on nearer coverOverlays to extend closer to us than farther ones. if (!pickedOverlay.intersects) { if (noHit) { return noHit(); From 7677e3bf4444a63fc2533087fd83ef875aca5757 Mon Sep 17 00:00:00 2001 From: SamGondelman Date: Sat, 16 Feb 2019 20:41:57 -0800 Subject: [PATCH 16/21] just in case --- .../controllers/controllerModules/teleport.js | 174 +++++++++--------- 1 file changed, 87 insertions(+), 87 deletions(-) diff --git a/scripts/system/controllers/controllerModules/teleport.js b/scripts/system/controllers/controllerModules/teleport.js index 48b23d834e..23457cdd85 100644 --- a/scripts/system/controllers/controllerModules/teleport.js +++ b/scripts/system/controllers/controllerModules/teleport.js @@ -196,14 +196,14 @@ Script.include("/~/system/libraries/controllers.js"); var playAreaOverlayProperties = { dimensions: - Vec3.multiply(this.teleportScaleFactor * avatarScale, { - x: this.playArea.width, - y: this.PLAY_AREA_OVERLAY_MODEL_DIMENSIONS.y, - z: this.playArea.height + Vec3.multiply(_this.teleportScaleFactor * avatarScale, { + x: _this.playArea.width, + y: _this.PLAY_AREA_OVERLAY_MODEL_DIMENSIONS.y, + z: _this.playArea.height }) }; - if (this.teleportScaleFactor < 1) { + if (_this.teleportScaleFactor < 1) { // Adjust position of playAreOverlay so that its base is at correct height. // Always parenting to teleport target is good enough for this. var sensorToWorldMatrix = MyAvatar.sensorToWorldMatrix; @@ -212,37 +212,37 @@ Script.include("/~/system/libraries/controllers.js"); var avatarSensorPosition = Mat4.transformPoint(worldToSensorMatrix, MyAvatar.position); avatarSensorPosition.y = 0; - var targetRotation = Overlays.getProperty(this.targetOverlayID, "rotation"); + var targetRotation = Overlays.getProperty(_this.targetOverlayID, "rotation"); var relativePlayAreaCenterOffset = - Vec3.sum(this.playAreaCenterOffset, { x: 0, y: -TARGET_MODEL_DIMENSIONS.y / 2, z: 0 }); + Vec3.sum(_this.playAreaCenterOffset, { x: 0, y: -TARGET_MODEL_DIMENSIONS.y / 2, z: 0 }); var localPosition = Vec3.multiplyQbyV(Quat.inverse(targetRotation), Vec3.multiplyQbyV(sensorToWorldRotation, Vec3.multiply(avatarScale, Vec3.subtract(relativePlayAreaCenterOffset, avatarSensorPosition)))); - localPosition.y = this.teleportScaleFactor * localPosition.y; + localPosition.y = _this.teleportScaleFactor * localPosition.y; - playAreaOverlayProperties.parentID = this.targetOverlayID; + playAreaOverlayProperties.parentID = _this.targetOverlayID; playAreaOverlayProperties.localPosition = localPosition; } - Overlays.editOverlay(this.playAreaOverlay, playAreaOverlayProperties); + Overlays.editOverlay(_this.playAreaOverlay, playAreaOverlayProperties); - for (var i = 0; i < this.playAreaSensorPositionOverlays.length; i++) { - localPosition = this.playAreaSensorPositions[i]; + for (var i = 0; i < _this.playAreaSensorPositionOverlays.length; i++) { + localPosition = _this.playAreaSensorPositions[i]; localPosition = Vec3.multiply(avatarScale, localPosition); // Position relative to the play area. - localPosition.y = avatarScale * (this.PLAY_AREA_SENSOR_OVERLAY_DIMENSIONS.y / 2 - - this.PLAY_AREA_OVERLAY_MODEL_DIMENSIONS.y / 2); - Overlays.editOverlay(this.playAreaSensorPositionOverlays[i], { - dimensions: Vec3.multiply(this.teleportScaleFactor * avatarScale, this.PLAY_AREA_SENSOR_OVERLAY_DIMENSIONS), - parentID: this.playAreaOverlay, + localPosition.y = avatarScale * (_this.PLAY_AREA_SENSOR_OVERLAY_DIMENSIONS.y / 2 + - _this.PLAY_AREA_OVERLAY_MODEL_DIMENSIONS.y / 2); + Overlays.editOverlay(_this.playAreaSensorPositionOverlays[i], { + dimensions: Vec3.multiply(_this.teleportScaleFactor * avatarScale, _this.PLAY_AREA_SENSOR_OVERLAY_DIMENSIONS), + parentID: _this.playAreaOverlay, localPosition: localPosition }); } }; this.updatePlayAreaScale = function () { - if (this.isPlayAreaAvailable) { - this.setPlayAreaDimensions(); + if (_this.isPlayAreaAvailable) { + _this.setPlayAreaDimensions(); } }; @@ -265,7 +265,7 @@ Script.include("/~/system/libraries/controllers.js"); for (var i = 0, length = teleportRenderStates.length; i < length; i++) { var state = properties.renderStates[teleportRenderStates[i].name]; if (state && state.end) { - Selection.addToSelectedItemsList(this.teleporterSelectionName, "overlay", state.end); + Selection.addToSelectedItemsList(_this.teleporterSelectionName, "overlay", state.end); } } }; @@ -448,34 +448,34 @@ Script.include("/~/system/libraries/controllers.js"); this.translateZAction = Controller.findAction("TranslateZ"); this.setPlayAreaVisible = function (visible, targetOverlayID, fade) { - if (!this.isPlayAreaAvailable || this.isPlayAreaVisible === visible) { + if (!_this.isPlayAreaAvailable || _this.isPlayAreaVisible === visible) { return; } - this.wasPlayAreaVisible = this.isPlayAreaVisible; - this.isPlayAreaVisible = visible; - this.targetOverlayID = targetOverlayID; + _this.wasPlayAreaVisible = _this.isPlayAreaVisible; + _this.isPlayAreaVisible = visible; + _this.targetOverlayID = targetOverlayID; - if (this.teleportedFadeTimer !== null) { - Script.clearTimeout(this.teleportedFadeTimer); - this.teleportedFadeTimer = null; + if (_this.teleportedFadeTimer !== null) { + Script.clearTimeout(_this.teleportedFadeTimer); + _this.teleportedFadeTimer = null; } if (visible || !fade) { // Immediately make visible or invisible. - this.isPlayAreaVisible = visible; - Overlays.editOverlay(this.playAreaOverlay, { + _this.isPlayAreaVisible = visible; + Overlays.editOverlay(_this.playAreaOverlay, { dimensions: Vec3.ZERO, - alpha: this.PLAY_AREA_BOX_ALPHA, + alpha: _this.PLAY_AREA_BOX_ALPHA, visible: visible }); - for (var i = 0; i < this.playAreaSensorPositionOverlays.length; i++) { - Overlays.editOverlay(this.playAreaSensorPositionOverlays[i], { + for (var i = 0; i < _this.playAreaSensorPositionOverlays.length; i++) { + Overlays.editOverlay(_this.playAreaSensorPositionOverlays[i], { dimensions: Vec3.ZERO, - alpha: this.PLAY_AREA_SENSOR_ALPHA, + alpha: _this.PLAY_AREA_SENSOR_ALPHA, visible: visible }); } - Overlays.editOverlay(this.teleportedTargetOverlay, { visible: false }); + Overlays.editOverlay(_this.teleportedTargetOverlay, { visible: false }); } else { // Fading out of overlays is initiated in setTeleportVisible(). } @@ -494,22 +494,22 @@ Script.include("/~/system/libraries/controllers.js"); var MIN_PARENTING_DISTANCE = 0.2; // Parenting under this distance results in the play area's rotation jittering. if (Vec3.distance(targetXZPosition, avatarXZPosition) < MIN_PARENTING_DISTANCE) { // Set play area position and rotation in world coordinates with no parenting. - Overlays.editOverlay(this.playAreaOverlay, { + Overlays.editOverlay(_this.playAreaOverlay, { parentID: Uuid.NULL, position: Vec3.sum(position, Vec3.multiplyQbyV(sensorToWorldRotation, Vec3.multiply(MyAvatar.sensorToWorldScale, - Vec3.subtract(this.playAreaCenterOffset, avatarSensorPosition)))), + Vec3.subtract(_this.playAreaCenterOffset, avatarSensorPosition)))), rotation: sensorToWorldRotation }); } else { // Set play area position and rotation in local coordinates with parenting. - var targetRotation = Overlays.getProperty(this.targetOverlayID, "rotation"); + var targetRotation = Overlays.getProperty(_this.targetOverlayID, "rotation"); var sensorToTargetRotation = Quat.multiply(Quat.inverse(targetRotation), sensorToWorldRotation); var relativePlayAreaCenterOffset = - Vec3.sum(this.playAreaCenterOffset, { x: 0, y: -TARGET_MODEL_DIMENSIONS.y / 2, z: 0 }); - Overlays.editOverlay(this.playAreaOverlay, { - parentID: this.targetOverlayID, + Vec3.sum(_this.playAreaCenterOffset, { x: 0, y: -TARGET_MODEL_DIMENSIONS.y / 2, z: 0 }); + Overlays.editOverlay(_this.playAreaOverlay, { + parentID: _this.targetOverlayID, localPosition: Vec3.multiplyQbyV(Quat.inverse(targetRotation), Vec3.multiplyQbyV(sensorToWorldRotation, Vec3.multiply(MyAvatar.sensorToWorldScale, @@ -585,26 +585,26 @@ Script.include("/~/system/libraries/controllers.js"); this.cancelFade = function () { // Other hand may call this to immediately hide fading overlays. var i, length; - if (this.teleportedFadeTimer) { - Overlays.editOverlay(this.teleportedTargetOverlay, { visible: false }); - if (this.wasPlayAreaVisible) { - Overlays.editOverlay(this.playAreaOverlay, { visible: false }); - for (i = 0, length = this.playAreaSensorPositionOverlays.length; i < length; i++) { - Overlays.editOverlay(this.playAreaSensorPositionOverlays[i], { visible: false }); + if (_this.teleportedFadeTimer) { + Overlays.editOverlay(_this.teleportedTargetOverlay, { visible: false }); + if (_this.wasPlayAreaVisible) { + Overlays.editOverlay(_this.playAreaOverlay, { visible: false }); + for (i = 0, length = _this.playAreaSensorPositionOverlays.length; i < length; i++) { + Overlays.editOverlay(_this.playAreaSensorPositionOverlays[i], { visible: false }); } } - this.teleportedFadeTimer = null; + _this.teleportedFadeTimer = null; } }; this.setTeleportVisible = function (visible, mode, fade) { // Scales in teleport target and play area when start displaying them. - if (visible === this.isTeleportVisible) { + if (visible === _this.isTeleportVisible) { return; } if (visible) { - this.teleportScaleMode = mode; + _this.teleportScaleMode = mode; Pointers.editRenderState( mode === "head" ? _this.teleportParabolaHeadVisuals : _this.teleportParabolaHandVisuals, "teleport", @@ -613,42 +613,42 @@ Script.include("/~/system/libraries/controllers.js"); end: { dimensions: Vec3.ZERO } } ); - this.getOtherModule().cancelFade(); - this.teleportScaleStart = Date.now(); - this.teleportScaleFactor = 0; - this.scaleInTeleport(); - Selection.enableListHighlight(this.teleporterSelectionName, this.TELEPORTER_SELECTION_STYLE); + _this.getOtherModule().cancelFade(); + _this.teleportScaleStart = Date.now(); + _this.teleportScaleFactor = 0; + _this.scaleInTeleport(); + Selection.enableListHighlight(_this.teleporterSelectionName, _this.TELEPORTER_SELECTION_STYLE); } else { - if (this.teleportScaleTimer !== null) { - Script.clearTimeout(this.teleportScaleTimer); - this.teleportScaleTimer = null; + if (_this.teleportScaleTimer !== null) { + Script.clearTimeout(_this.teleportScaleTimer); + _this.teleportScaleTimer = null; } if (fade) { // Copy of target at teleported position for fading. var avatarScale = MyAvatar.sensorToWorldScale; - Overlays.editOverlay(this.teleportedTargetOverlay, { - position: Vec3.sum(this.teleportedPosition, { + Overlays.editOverlay(_this.teleportedTargetOverlay, { + position: Vec3.sum(_this.teleportedPosition, { x: 0, y: -getAvatarFootOffset() + avatarScale * TARGET_MODEL_DIMENSIONS.y / 2, z: 0 }), - rotation: Quat.multiply(this.TELEPORTED_TARGET_ROTATION, MyAvatar.orientation), + rotation: Quat.multiply(_this.TELEPORTED_TARGET_ROTATION, MyAvatar.orientation), dimensions: Vec3.multiply(avatarScale, TARGET_MODEL_DIMENSIONS), - alpha: this.TELEPORTED_TARGET_ALPHA, + alpha: _this.TELEPORTED_TARGET_ALPHA, visible: true }); // Fade out over time. - this.teleportedFadeDelayFactor = 1.0; - this.teleportedFadeFactor = 1.0; - this.teleportedFadeTimer = Script.setTimeout(this.fadeOutTeleport, this.TELEPORTED_FADE_DELAY); + _this.teleportedFadeDelayFactor = 1.0; + _this.teleportedFadeFactor = 1.0; + _this.teleportedFadeTimer = Script.setTimeout(_this.fadeOutTeleport, _this.TELEPORTED_FADE_DELAY); } else { - Selection.disableListHighlight(this.teleporterSelectionName); + Selection.disableListHighlight(_this.teleporterSelectionName); } } - this.isTeleportVisible = visible; + _this.isTeleportVisible = visible; }; @@ -697,7 +697,7 @@ Script.include("/~/system/libraries/controllers.js"); 100); this.enterTeleport = function() { - this.state = TELEPORTER_STATES.TARGETTING; + _this.state = TELEPORTER_STATES.TARGETTING; }; this.isReady = function(controllerData, deltaTime) { @@ -761,23 +761,23 @@ Script.include("/~/system/libraries/controllers.js"); if (teleportLocationType === TARGET.NONE) { // Use the cancel default state - this.setTeleportState(mode, "cancel", ""); + _this.setTeleportState(mode, "cancel", ""); } else if (teleportLocationType === TARGET.INVALID) { - this.setTeleportState(mode, "", "cancel"); + _this.setTeleportState(mode, "", "cancel"); } else if (teleportLocationType === TARGET.COLLIDES) { - this.setTeleportState(mode, "cancel", "collision"); + _this.setTeleportState(mode, "cancel", "collision"); } else if (teleportLocationType === TARGET.SURFACE || teleportLocationType === TARGET.DISCREPANCY) { - this.setTeleportState(mode, "teleport", "collision"); - this.updatePlayArea(result.intersection); + _this.setTeleportState(mode, "teleport", "collision"); + _this.updatePlayArea(result.intersection); } else if (teleportLocationType === TARGET.SEAT) { - this.setTeleportState(mode, "collision", "seat"); + _this.setTeleportState(mode, "collision", "seat"); } - return this.teleport(result, teleportLocationType); + return _this.teleport(result, teleportLocationType); }; this.teleport = function(newResult, target) { var result = newResult; - this.teleportedPosition = newResult.intersection; + _this.teleportedPosition = newResult.intersection; if (_this.buttonValue !== 0) { return makeRunningValues(true, [], []); } @@ -795,14 +795,14 @@ Script.include("/~/system/libraries/controllers.js"); MyAvatar.centerBody(); } - this.disableLasers(); - this.active = false; + _this.disableLasers(); + _this.active = false; return makeRunningValues(false, [], []); }; this.disableLasers = function() { - this.setPlayAreaVisible(false, null, true); - this.setTeleportVisible(false, null, true); + _this.setPlayAreaVisible(false, null, true); + _this.setTeleportVisible(false, null, true); Pointers.disablePointer(_this.teleportParabolaHandVisuals); Pointers.disablePointer(_this.teleportParabolaHandCollisions); Pointers.disablePointer(_this.teleportParabolaHeadVisuals); @@ -815,10 +815,10 @@ Script.include("/~/system/libraries/controllers.js"); this.setTeleportState = function (mode, visibleState, invisibleState) { var teleportState = mode + visibleState + invisibleState; - if (teleportState === this.teleportState) { + if (teleportState === _this.teleportState) { return; } - this.teleportState = teleportState; + _this.teleportState = teleportState; var pointerID; if (mode === 'head') { @@ -831,16 +831,16 @@ Script.include("/~/system/libraries/controllers.js"); pointerID = _this.teleportParabolaHandVisuals; } var visible = visibleState === "teleport"; - this.setPlayAreaVisible(visible && MyAvatar.showPlayArea, + _this.setPlayAreaVisible(visible && MyAvatar.showPlayArea, Pointers.getPointerProperties(pointerID).renderStates.teleport.end, false); - this.setTeleportVisible(visible, mode, false); + _this.setTeleportVisible(visible, mode, false); }; this.setIgnoreEntities = function(entitiesToIgnore) { - Pointers.setIgnoreItems(this.teleportParabolaHandVisuals, entitiesToIgnore); - Pointers.setIgnoreItems(this.teleportParabolaHandCollisions, entitiesToIgnore); - Pointers.setIgnoreItems(this.teleportParabolaHeadVisuals, entitiesToIgnore); - Pointers.setIgnoreItems(this.teleportParabolaHeadCollisions, entitiesToIgnore); + Pointers.setIgnoreItems(_this.teleportParabolaHandVisuals, entitiesToIgnore); + Pointers.setIgnoreItems(_this.teleportParabolaHandCollisions, entitiesToIgnore); + Pointers.setIgnoreItems(_this.teleportParabolaHeadVisuals, entitiesToIgnore); + Pointers.setIgnoreItems(_this.teleportParabolaHeadCollisions, entitiesToIgnore); Picks.setIgnoreItems(_this.teleportHeadCollisionPick, entitiesToIgnore); Picks.setIgnoreItems(_this.teleportHandCollisionPick, entitiesToIgnore); }; From 85421cd6eef37c214d464fb89949c0bca7d03dfc Mon Sep 17 00:00:00 2001 From: SamGondelman Date: Sat, 16 Feb 2019 21:16:46 -0800 Subject: [PATCH 17/21] speed up stylus picks --- interface/src/raypick/StylusPick.cpp | 29 +++++++++++----------------- 1 file changed, 11 insertions(+), 18 deletions(-) diff --git a/interface/src/raypick/StylusPick.cpp b/interface/src/raypick/StylusPick.cpp index 0e95959566..9c3ffb972f 100644 --- a/interface/src/raypick/StylusPick.cpp +++ b/interface/src/raypick/StylusPick.cpp @@ -137,7 +137,7 @@ PickResultPointer StylusPick::getDefaultResult(const QVariantMap& pickVariant) c } PickResultPointer StylusPick::getEntityIntersection(const StylusTip& pick) { - std::vector results; + StylusPickResult nearestTarget(pick.toVariantMap()); for (const auto& target : getIncludeItems()) { if (target.isNull()) { continue; @@ -157,28 +157,21 @@ PickResultPointer StylusPick::getEntityIntersection(const StylusTip& pick) { glm::vec3 normal = entityRotation * Vectors::UNIT_Z; float distance = glm::dot(pick.position - entityPosition, normal); - glm::vec3 intersection = pick.position - (normal * distance); - - glm::vec2 pos2D = RayPick::projectOntoEntityXYPlane(target, intersection, false); - if (pos2D == glm::clamp(pos2D, glm::vec2(0), glm::vec2(1))) { - IntersectionType type = IntersectionType::ENTITY; - if (getFilter().doesPickLocalEntities()) { - EntityPropertyFlags desiredProperties; - desiredProperties += PROP_ENTITY_HOST_TYPE; - if (DependencyManager::get()->getEntityProperties(target, desiredProperties).getEntityHostType() == entity::HostType::LOCAL) { - type = IntersectionType::LOCAL_ENTITY; + if (distance < nearestTarget.distance) { + glm::vec3 intersection = pick.position - (normal * distance); + glm::vec2 pos2D = RayPick::projectOntoEntityXYPlane(target, intersection, false); + if (pos2D == glm::clamp(pos2D, glm::vec2(0), glm::vec2(1))) { + IntersectionType type = IntersectionType::ENTITY; + if (getFilter().doesPickLocalEntities()) { + if (entity->getEntityHostType() == entity::HostType::LOCAL) { + type = IntersectionType::LOCAL_ENTITY; + } } + nearestTarget = StylusPickResult(type, target, distance, intersection, pick, normal); } - results.push_back(StylusPickResult(type, target, distance, intersection, pick, normal)); } } - StylusPickResult nearestTarget(pick.toVariantMap()); - for (const auto& result : results) { - if (result.distance < nearestTarget.distance) { - nearestTarget = result; - } - } return std::make_shared(nearestTarget); } From 1163cbea706447338e1267ffcba4d536acdf424a Mon Sep 17 00:00:00 2001 From: SamGondelman Date: Sat, 16 Feb 2019 22:03:55 -0800 Subject: [PATCH 18/21] improving web surface interaction and tablet hiding --- interface/src/ui/overlays/Overlays.cpp | 10 +--------- .../src/EntityTreeRenderer.cpp | 6 +++--- scripts/system/away.js | 3 ++- scripts/system/tablet-ui/tabletUI.js | 17 ++++++++--------- 4 files changed, 14 insertions(+), 22 deletions(-) diff --git a/interface/src/ui/overlays/Overlays.cpp b/interface/src/ui/overlays/Overlays.cpp index 2ec67070ba..a7e7681b74 100644 --- a/interface/src/ui/overlays/Overlays.cpp +++ b/interface/src/ui/overlays/Overlays.cpp @@ -79,15 +79,7 @@ void Overlays::cleanupAllOverlays() { cleanupOverlaysToDelete(); } -void Overlays::init() { - auto entityScriptingInterface = DependencyManager::get(); - connect(this, &Overlays::hoverEnterOverlay, entityScriptingInterface.data(), &EntityScriptingInterface::hoverEnterEntity); - connect(this, &Overlays::hoverOverOverlay, entityScriptingInterface.data(), &EntityScriptingInterface::hoverOverEntity); - connect(this, &Overlays::hoverLeaveOverlay, entityScriptingInterface.data(), &EntityScriptingInterface::hoverLeaveEntity); - connect(this, &Overlays::mousePressOnOverlay, entityScriptingInterface.data(), &EntityScriptingInterface::mousePressOnEntity); - connect(this, &Overlays::mouseMoveOnOverlay, entityScriptingInterface.data(), &EntityScriptingInterface::mouseMoveOnEntity); - connect(this, &Overlays::mouseReleaseOnOverlay, entityScriptingInterface.data(), &EntityScriptingInterface::mouseReleaseOnEntity); -} +void Overlays::init() {} void Overlays::update(float deltatime) { cleanupOverlaysToDelete(); diff --git a/libraries/entities-renderer/src/EntityTreeRenderer.cpp b/libraries/entities-renderer/src/EntityTreeRenderer.cpp index 319acc750f..673957a9d8 100644 --- a/libraries/entities-renderer/src/EntityTreeRenderer.cpp +++ b/libraries/entities-renderer/src/EntityTreeRenderer.cpp @@ -86,7 +86,7 @@ EntityTreeRenderer::EntityTreeRenderer(bool wantScripts, AbstractViewStateInterf auto handlePointerEvent = [&](const QUuid& entityID, const PointerEvent& event) { std::shared_ptr thisEntity; auto entity = getEntity(entityID); - if (entity && entity->getType() == EntityTypes::Web) { + if (entity && entity->isVisible() && entity->getType() == EntityTypes::Web) { thisEntity = std::static_pointer_cast(renderableForEntityId(entityID)); } if (thisEntity) { @@ -99,7 +99,7 @@ EntityTreeRenderer::EntityTreeRenderer(bool wantScripts, AbstractViewStateInterf connect(entityScriptingInterface.data(), &EntityScriptingInterface::hoverEnterEntity, this, [&](const QUuid& entityID, const PointerEvent& event) { std::shared_ptr thisEntity; auto entity = getEntity(entityID); - if (entity && entity->getType() == EntityTypes::Web) { + if (entity && entity->isVisible() && entity->getType() == EntityTypes::Web) { thisEntity = std::static_pointer_cast(renderableForEntityId(entityID)); } if (thisEntity) { @@ -110,7 +110,7 @@ EntityTreeRenderer::EntityTreeRenderer(bool wantScripts, AbstractViewStateInterf connect(entityScriptingInterface.data(), &EntityScriptingInterface::hoverLeaveEntity, this, [&](const QUuid& entityID, const PointerEvent& event) { std::shared_ptr thisEntity; auto entity = getEntity(entityID); - if (entity && entity->getType() == EntityTypes::Web) { + if (entity && entity->isVisible() && entity->getType() == EntityTypes::Web) { thisEntity = std::static_pointer_cast(renderableForEntityId(entityID)); } if (thisEntity) { diff --git a/scripts/system/away.js b/scripts/system/away.js index a2e73ae63c..45b6f43b73 100644 --- a/scripts/system/away.js +++ b/scripts/system/away.js @@ -45,7 +45,8 @@ var OVERLAY_DATA_HMD = { emissive: true, drawInFront: true, parentID: MyAvatar.SELF_ID, - parentJointIndex: CAMERA_MATRIX + parentJointIndex: CAMERA_MATRIX, + ignorePickIntersection: true }; var AWAY_INTRO = { diff --git a/scripts/system/tablet-ui/tabletUI.js b/scripts/system/tablet-ui/tabletUI.js index f9e9165f2e..60848224bb 100644 --- a/scripts/system/tablet-ui/tabletUI.js +++ b/scripts/system/tablet-ui/tabletUI.js @@ -137,11 +137,11 @@ UIWebTablet.calculateTabletAttachmentProperties(activeHand, true, tabletProperties); } tabletProperties.visible = true; + tabletProperties.ignorePickIntersection = false; Overlays.editOverlay(HMD.tabletID, tabletProperties); - Overlays.editOverlay(HMD.homeButtonID, { visible: true }); - Overlays.editOverlay(HMD.homeButtonHighlightID, { visible: true }); - Overlays.editOverlay(HMD.tabletScreenID, { visible: true }); - Overlays.editOverlay(HMD.tabletScreenID, { maxFPS: 90 }); + Overlays.editOverlay(HMD.homeButtonID, { visible: true, ignorePickIntersection: false }); + Overlays.editOverlay(HMD.homeButtonHighlightID, { visible: true, ignorePickIntersection: false }); + Overlays.editOverlay(HMD.tabletScreenID, { visible: true, ignorePickIntersection: false, maxFPS: 90 }); updateTabletWidthFromSettings(true); } gTablet.tabletShown = true; @@ -158,11 +158,10 @@ print("TABLET hide"); } - Overlays.editOverlay(HMD.tabletID, { visible: false }); - Overlays.editOverlay(HMD.homeButtonID, { visible: false }); - Overlays.editOverlay(HMD.homeButtonHighlightID, { visible: false }); - Overlays.editOverlay(HMD.tabletScreenID, { visible: false }); - Overlays.editOverlay(HMD.tabletScreenID, { maxFPS: 1 }); + Overlays.editOverlay(HMD.tabletID, { visible: false, ignorePickIntersection: true }); + Overlays.editOverlay(HMD.homeButtonID, { visible: false, ignorePickIntersection: true }); + Overlays.editOverlay(HMD.homeButtonHighlightID, { visible: false, ignorePickIntersection: true }); + Overlays.editOverlay(HMD.tabletScreenID, { visible: false, ignorePickIntersection: true, maxFPS: 1 }); } function closeTabletUI() { From 27f05db8253e0bb61e0ce6e8608dd291c35c6382 Mon Sep 17 00:00:00 2001 From: SamGondelman Date: Mon, 18 Feb 2019 01:10:19 -0800 Subject: [PATCH 19/21] fix ao --- libraries/render-utils/src/AmbientOcclusionEffect.cpp | 2 +- libraries/render-utils/src/LightingModel.h | 8 +++----- scripts/developer/utilities/render/deferredLighting.qml | 2 +- 3 files changed, 5 insertions(+), 7 deletions(-) diff --git a/libraries/render-utils/src/AmbientOcclusionEffect.cpp b/libraries/render-utils/src/AmbientOcclusionEffect.cpp index b1ca24de1f..ee53347158 100644 --- a/libraries/render-utils/src/AmbientOcclusionEffect.cpp +++ b/libraries/render-utils/src/AmbientOcclusionEffect.cpp @@ -205,7 +205,7 @@ gpu::TexturePointer AmbientOcclusionFramebuffer::getNormalTexture() { } AmbientOcclusionEffectConfig::AmbientOcclusionEffectConfig() : - render::GPUJobConfig::Persistent(QStringList() << "Render" << "Engine" << "Ambient Occlusion", false), + render::GPUJobConfig::Persistent(QStringList() << "Render" << "Engine" << "Ambient Occlusion"), perspectiveScale{ 1.0f }, edgeSharpness{ 1.0f }, blurRadius{ 4 }, diff --git a/libraries/render-utils/src/LightingModel.h b/libraries/render-utils/src/LightingModel.h index 571eadb60b..f6bd6dcd46 100644 --- a/libraries/render-utils/src/LightingModel.h +++ b/libraries/render-utils/src/LightingModel.h @@ -118,7 +118,7 @@ protected: float enableSkinning{ 1.0f }; float enableBlendshape{ 1.0f }; - float enableAmbientOcclusion{ 0.0f }; + float enableAmbientOcclusion{ 0.0f }; // false by default float enableShadow{ 1.0f }; float spare1{ 1.0f }; float spare2{ 1.0f }; @@ -196,15 +196,13 @@ public: bool enableSkinning{ true }; bool enableBlendshape{ true }; - bool enableAmbientOcclusion{ true }; + bool enableAmbientOcclusion{ false }; // false by default bool enableShadow{ true }; void setAmbientOcclusion(bool enable) { enableAmbientOcclusion = enable; emit dirty();} bool isAmbientOcclusionEnabled() const { return enableAmbientOcclusion; } - void setShadow(bool enable) { - enableShadow = enable; emit dirty(); - } + void setShadow(bool enable) { enableShadow = enable; emit dirty(); } bool isShadowEnabled() const { return enableShadow; } signals: diff --git a/scripts/developer/utilities/render/deferredLighting.qml b/scripts/developer/utilities/render/deferredLighting.qml index 6d98e96780..f5c0b8c5da 100644 --- a/scripts/developer/utilities/render/deferredLighting.qml +++ b/scripts/developer/utilities/render/deferredLighting.qml @@ -47,7 +47,7 @@ Rectangle { "Lightmap:LightingModel:enableLightmap", "Background:LightingModel:enableBackground", "Haze:LightingModel:enableHaze", - "ssao:LightingModel:enableAmbientOcclusion", + "AO:LightingModel:enableAmbientOcclusion", "Textures:LightingModel:enableMaterialTexturing" ] HifiControls.CheckBox { From 927e824610331c560117a6bfe73660257baf5dc4 Mon Sep 17 00:00:00 2001 From: SamGondelman Date: Mon, 18 Feb 2019 16:14:07 -0800 Subject: [PATCH 20/21] fix missing color for text overlays --- interface/src/ui/overlays/Overlays.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/interface/src/ui/overlays/Overlays.cpp b/interface/src/ui/overlays/Overlays.cpp index e1708c14fe..6fb0c99c90 100644 --- a/interface/src/ui/overlays/Overlays.cpp +++ b/interface/src/ui/overlays/Overlays.cpp @@ -375,6 +375,8 @@ EntityItemProperties Overlays::convertOverlayToEntityProperties(QVariantMap& ove RENAME_PROP(animationSettings, animation); } else if (type == "Image") { RENAME_PROP(url, imageURL); + } else if (type == "Text") { + RENAME_PROP(color, textColor); } else if (type == "Web") { RENAME_PROP(url, sourceUrl); RENAME_PROP_CONVERT(inputMode, inputMode, [](const QVariant& v) { return v.toString() == "Mouse" ? "mouse" : "touch"; }); @@ -675,6 +677,8 @@ QVariantMap Overlays::convertEntityToOverlayProperties(const EntityItemPropertie RENAME_PROP(animation, animationSettings); } else if (type == "Image") { RENAME_PROP(imageURL, url); + } else if (type == "Text") { + RENAME_PROP(textColor, color); } else if (type == "Web") { RENAME_PROP(sourceUrl, url); RENAME_PROP_CONVERT(inputMode, inputMode, [](const QVariant& v) { return v.toString() == "mouse" ? "Mouse" : "Touch"; }); From 4bbae1230d74a0784f2391480bdf6b5aeb657e18 Mon Sep 17 00:00:00 2001 From: danteruiz Date: Tue, 19 Feb 2019 10:07:36 -0800 Subject: [PATCH 21/21] making requested chantges --- interface/src/raypick/PickScriptingInterface.cpp | 4 ++-- interface/src/raypick/PointerScriptingInterface.cpp | 4 ++-- libraries/pointers/src/PickCacheOptimizer.h | 2 -- 3 files changed, 4 insertions(+), 6 deletions(-) diff --git a/interface/src/raypick/PickScriptingInterface.cpp b/interface/src/raypick/PickScriptingInterface.cpp index cf7680bb6c..09f4b68cb9 100644 --- a/interface/src/raypick/PickScriptingInterface.cpp +++ b/interface/src/raypick/PickScriptingInterface.cpp @@ -76,8 +76,8 @@ unsigned int PickScriptingInterface::createRayPick(const QVariant& properties) { QString jointName { "" }; if (propMap["joint"].isValid()) { QString jointName = propMap["joint"].toString(); - QString mouseJoint { "Mouse" }; - if (jointName == mouseJoint) { + const QString MOUSE_JOINT = "Mouse"; + if (jointName == MOUSE_JOINT) { return PointerEvent::INVALID_POINTER_ID; } } diff --git a/interface/src/raypick/PointerScriptingInterface.cpp b/interface/src/raypick/PointerScriptingInterface.cpp index 10761e0696..1c80caff88 100644 --- a/interface/src/raypick/PointerScriptingInterface.cpp +++ b/interface/src/raypick/PointerScriptingInterface.cpp @@ -154,8 +154,8 @@ unsigned int PointerScriptingInterface::createLaserPointer(const QVariant& prope QString jointName { "" }; if (propertyMap["joint"].isValid()) { QString jointName = propertyMap["joint"].toString(); - QString mouseJoint { "Mouse" }; - if (jointName == mouseJoint) { + const QString MOUSE_JOINT = "Mouse"; + if (jointName == MOUSE_JOINT) { return PointerEvent::INVALID_POINTER_ID; } } diff --git a/libraries/pointers/src/PickCacheOptimizer.h b/libraries/pointers/src/PickCacheOptimizer.h index 6aa343480b..0bbdfea8e4 100644 --- a/libraries/pointers/src/PickCacheOptimizer.h +++ b/libraries/pointers/src/PickCacheOptimizer.h @@ -11,8 +11,6 @@ #include #include "Pick.h" -#include "PerfStat.h" -#include "Profile.h" typedef struct PickCacheKey { PickFilter::Flags mask;