From 72ed5f6d91852e0463e69f5876ceb9deb81adaca Mon Sep 17 00:00:00 2001 From: LaShonda Hopper Date: Tue, 23 Jan 2018 13:40:31 -0500 Subject: [PATCH 01/24] [Case 4315] Fixes OK button hard to use within HMD mode (details below). * Shape Color picker dynamically updates entity color. * This removes the OK button which was hard to interact with in HMD mode. The user no longer needs to click the OK button to submit changes to the color; rather the color of the entity updates as the user manipulates the color wheel and/or slider. Known Issue/TODO(s): * Color Picker's Color Preview area has a bug where the original/starting color preview is black as opposed to reflecting the entity's color upon clicking the color picker. * Color preview restore color functionality isn't working. Clicking the initial color preview doesn't restore the color. * In HMD Mode: While interacting with the picker the user is able to control scrolling navigation for the edit menu. For example, when moving up or down to change the hue the edit menu behind the picker will scroll up and down correlatively. * In HMD Mode: When the picker is dismissed (user clicks outside the picker), the RGB fields for the color still receive input. Tested in Desktop & HMD Modes. Changes Committed: modified: scripts/system/html/js/entityProperties.js --- scripts/system/html/js/entityProperties.js | 36 +++++++++++----------- 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/scripts/system/html/js/entityProperties.js b/scripts/system/html/js/entityProperties.js index 72092b66ca..3b6e207ccb 100644 --- a/scripts/system/html/js/entityProperties.js +++ b/scripts/system/html/js/entityProperties.js @@ -1040,9 +1040,9 @@ function loaded() { elZoneAmbientLightURL.value = properties.ambientLight.ambientURL; // Haze - elZoneHazeModeInherit.checked = (properties.hazeMode === 'inherit'); + elZoneHazeModeInherit.checked = (properties.hazeMode === 'inherit'); elZoneHazeModeDisabled.checked = (properties.hazeMode === 'disabled'); - elZoneHazeModeEnabled.checked = (properties.hazeMode === 'enabled'); + elZoneHazeModeEnabled.checked = (properties.hazeMode === 'enabled'); elZoneHazeRange.value = properties.haze.hazeRange.toFixed(0); elZoneHazeColor.style.backgroundColor = "rgb(" + @@ -1308,15 +1308,15 @@ function loaded() { colorScheme: 'dark', layout: 'hex', color: '000000', + submit: false, // We don't want to have a submission button onShow: function(colpick) { $('#property-color-control2').attr('active', 'true'); }, onHide: function(colpick) { $('#property-color-control2').attr('active', 'false'); }, - onSubmit: function(hsb, hex, rgb, el) { + onChange: function(hsb, hex, rgb, el) { $(el).css('background-color', '#' + hex); - $(el).colpickHide(); emitColorPropertyUpdate('color', rgb.r, rgb.g, rgb.b); } })); @@ -1332,15 +1332,15 @@ function loaded() { colorScheme: 'dark', layout: 'hex', color: '000000', + submit: false, // We don't want to have a submission button onShow: function(colpick) { $('#property-light-color').attr('active', 'true'); }, onHide: function(colpick) { $('#property-light-color').attr('active', 'false'); }, - onSubmit: function(hsb, hex, rgb, el) { + onChange: function(hsb, hex, rgb, el) { $(el).css('background-color', '#' + hex); - $(el).colpickHide(); emitColorPropertyUpdate('color', rgb.r, rgb.g, rgb.b); } })); @@ -1387,15 +1387,15 @@ function loaded() { colorScheme: 'dark', layout: 'hex', color: '000000', + submit: false, // We don't want to have a submission button onShow: function(colpick) { $('#property-text-text-color').attr('active', 'true'); }, onHide: function(colpick) { $('#property-text-text-color').attr('active', 'false'); }, - onSubmit: function(hsb, hex, rgb, el) { + onChange: function(hsb, hex, rgb, el) { $(el).css('background-color', '#' + hex); - $(el).colpickHide(); $(el).attr('active', 'false'); emitColorPropertyUpdate('textColor', rgb.r, rgb.g, rgb.b); } @@ -1411,15 +1411,15 @@ function loaded() { colorScheme: 'dark', layout: 'hex', color: '000000', + submit: false, // We don't want to have a submission button onShow: function(colpick) { $('#property-text-background-color').attr('active', 'true'); }, onHide: function(colpick) { $('#property-text-background-color').attr('active', 'false'); }, - onSubmit: function(hsb, hex, rgb, el) { + onChange: function(hsb, hex, rgb, el) { $(el).css('background-color', '#' + hex); - $(el).colpickHide(); emitColorPropertyUpdate('backgroundColor', rgb.r, rgb.g, rgb.b); } })); @@ -1436,15 +1436,15 @@ function loaded() { colorScheme: 'dark', layout: 'hex', color: '000000', + submit: false, // We don't want to have a submission button onShow: function(colpick) { $('#property-zone-key-light-color').attr('active', 'true'); }, onHide: function(colpick) { $('#property-zone-key-light-color').attr('active', 'false'); }, - onSubmit: function(hsb, hex, rgb, el) { + onChange: function(hsb, hex, rgb, el) { $(el).css('background-color', '#' + hex); - $(el).colpickHide(); emitColorPropertyUpdate('color', rgb.r, rgb.g, rgb.b, 'keyLight'); } })); @@ -1505,15 +1505,15 @@ function loaded() { colorScheme: 'dark', layout: 'hex', color: '000000', + submit: false, // We don't want to have a submission button onShow: function(colpick) { $('#property-zone-haze-color').attr('active', 'true'); }, onHide: function(colpick) { $('#property-zone-haze-color').attr('active', 'false'); }, - onSubmit: function(hsb, hex, rgb, el) { + onChange: function(hsb, hex, rgb, el) { $(el).css('background-color', '#' + hex); - $(el).colpickHide(); emitColorPropertyUpdate('hazeColor', rgb.r, rgb.g, rgb.b, 'haze'); } })); @@ -1530,15 +1530,15 @@ function loaded() { colorScheme: 'dark', layout: 'hex', color: '000000', + submit: false, // We don't want to have a submission button onShow: function(colpick) { $('#property-zone-haze-glare-color').attr('active', 'true'); }, onHide: function(colpick) { $('#property-zone-haze-glare-color').attr('active', 'false'); }, - onSubmit: function(hsb, hex, rgb, el) { + onChange: function(hsb, hex, rgb, el) { $(el).css('background-color', '#' + hex); - $(el).colpickHide(); emitColorPropertyUpdate('hazeGlareColor', rgb.r, rgb.g, rgb.b, 'haze'); } })); @@ -1572,15 +1572,15 @@ function loaded() { colorScheme: 'dark', layout: 'hex', color: '000000', + submit: false, // We don't want to have a submission button onShow: function(colpick) { $('#property-zone-skybox-color').attr('active', 'true'); }, onHide: function(colpick) { $('#property-zone-skybox-color').attr('active', 'false'); }, - onSubmit: function(hsb, hex, rgb, el) { + onChange: function(hsb, hex, rgb, el) { $(el).css('background-color', '#' + hex); - $(el).colpickHide(); emitColorPropertyUpdate('color', rgb.r, rgb.g, rgb.b, 'skybox'); } })); From 4da7a1e65ae28a4927ceb5a20938625fc5ab5a18 Mon Sep 17 00:00:00 2001 From: LaShonda Hopper Date: Tue, 23 Jan 2018 13:48:47 -0500 Subject: [PATCH 02/24] [Case 4315] ESLint pass on entityProperties.js. Re-ran after changes and issue count was 0. Changes Committed: modified: scripts/system/html/js/entityProperties.js --- scripts/system/html/js/entityProperties.js | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/scripts/system/html/js/entityProperties.js b/scripts/system/html/js/entityProperties.js index 3b6e207ccb..7008d0df66 100644 --- a/scripts/system/html/js/entityProperties.js +++ b/scripts/system/html/js/entityProperties.js @@ -653,16 +653,16 @@ function loaded() { var elZoneKeyLightDirectionY = document.getElementById("property-zone-key-light-direction-y"); // Skybox - var elZoneSkyboxModeInherit = document.getElementById("property-zone-skybox-mode-inherit"); + var elZoneSkyboxModeInherit = document.getElementById("property-zone-skybox-mode-inherit"); var elZoneSkyboxModeDisabled = document.getElementById("property-zone-skybox-mode-disabled"); - var elZoneSkyboxModeEnabled = document.getElementById("property-zone-skybox-mode-enabled"); + var elZoneSkyboxModeEnabled = document.getElementById("property-zone-skybox-mode-enabled"); // Ambient light var elCopySkyboxURLToAmbientURL = document.getElementById("copy-skybox-url-to-ambient-url"); - var elZoneAmbientLightModeInherit = document.getElementById("property-zone-ambient-light-mode-inherit"); + var elZoneAmbientLightModeInherit = document.getElementById("property-zone-ambient-light-mode-inherit"); var elZoneAmbientLightModeDisabled = document.getElementById("property-zone-ambient-light-mode-disabled"); - var elZoneAmbientLightModeEnabled = document.getElementById("property-zone-ambient-light-mode-enabled"); + var elZoneAmbientLightModeEnabled = document.getElementById("property-zone-ambient-light-mode-enabled"); var elZoneAmbientLightIntensity = document.getElementById("property-zone-key-ambient-intensity"); var elZoneAmbientLightURL = document.getElementById("property-zone-key-ambient-url"); @@ -1013,9 +1013,9 @@ function loaded() { } else if (properties.type === "Zone") { // Key light - elZoneKeyLightModeInherit.checked = (properties.keyLightMode === 'inherit'); + elZoneKeyLightModeInherit.checked = (properties.keyLightMode === 'inherit'); elZoneKeyLightModeDisabled.checked = (properties.keyLightMode === 'disabled'); - elZoneKeyLightModeEnabled.checked = (properties.keyLightMode === 'enabled'); + elZoneKeyLightModeEnabled.checked = (properties.keyLightMode === 'enabled'); elZoneKeyLightColor.style.backgroundColor = "rgb(" + properties.keyLight.color.red + "," + properties.keyLight.color.green + "," + properties.keyLight.color.blue + ")"; @@ -1027,14 +1027,14 @@ function loaded() { elZoneKeyLightDirectionY.value = properties.keyLight.direction.y.toFixed(2); // Skybox - elZoneSkyboxModeInherit.checked = (properties.skyboxMode === 'inherit'); + elZoneSkyboxModeInherit.checked = (properties.skyboxMode === 'inherit'); elZoneSkyboxModeDisabled.checked = (properties.skyboxMode === 'disabled'); - elZoneSkyboxModeEnabled.checked = (properties.skyboxMode === 'enabled'); + elZoneSkyboxModeEnabled.checked = (properties.skyboxMode === 'enabled'); // Ambient light - elZoneAmbientLightModeInherit.checked = (properties.ambientLightMode === 'inherit'); + elZoneAmbientLightModeInherit.checked = (properties.ambientLightMode === 'inherit'); elZoneAmbientLightModeDisabled.checked = (properties.ambientLightMode === 'disabled'); - elZoneAmbientLightModeEnabled.checked = (properties.ambientLightMode === 'enabled'); + elZoneAmbientLightModeEnabled.checked = (properties.ambientLightMode === 'enabled'); elZoneAmbientLightIntensity.value = properties.ambientLight.ambientIntensity.toFixed(2); elZoneAmbientLightURL.value = properties.ambientLight.ambientURL; From 180be18178139099b9e42662d8c1e9282b438238 Mon Sep 17 00:00:00 2001 From: LaShonda Hopper Date: Tue, 23 Jan 2018 14:02:31 -0500 Subject: [PATCH 03/24] [Case 4315] Fixes color picker issue in HMD mode (details below). Previously when in HMD mode, using the color picker to select a color via the gradient or hue areas would result in the page scrolling making it difficult to select the color or hue desired. This resolves the issue by turning off touch actions for the elements of the color picker that should have it when using the color picker. Tested in HMD & Desktop mode. Changes Committed: modified: scripts/system/html/css/colpick.css --- scripts/system/html/css/colpick.css | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/scripts/system/html/css/colpick.css b/scripts/system/html/css/colpick.css index 564f60cb3b..98417a5e9a 100644 --- a/scripts/system/html/css/colpick.css +++ b/scripts/system/html/css/colpick.css @@ -26,6 +26,7 @@ colpick Color Picker / colpick.com /*Color selection box with gradients*/ .colpick_color { position: absolute; + touch-action: none; left: 7px; top: 7px; width: 156px; @@ -84,6 +85,7 @@ colpick Color Picker / colpick.com /*Vertical hue bar*/ .colpick_hue { position: absolute; + touch-action: none; top: 6px; left: 175px; width: 19px; @@ -94,6 +96,7 @@ colpick Color Picker / colpick.com /*Hue bar sliding indicator*/ .colpick_hue_arrs { position: absolute; + touch-action: none; left: -8px; width: 35px; height: 7px; @@ -101,6 +104,7 @@ colpick Color Picker / colpick.com } .colpick_hue_larr { position:absolute; + touch-action: none; width: 0; height: 0; border-top: 6px solid transparent; @@ -109,6 +113,7 @@ colpick Color Picker / colpick.com } .colpick_hue_rarr { position:absolute; + touch-action: none; right:0; width: 0; height: 0; @@ -119,6 +124,7 @@ colpick Color Picker / colpick.com /*New color box*/ .colpick_new_color { position: absolute; + touch-action: none; left: 207px; top: 6px; width: 60px; @@ -129,6 +135,7 @@ colpick Color Picker / colpick.com /*Current color box*/ .colpick_current_color { position: absolute; + touch-action: none; left: 277px; top: 6px; width: 60px; @@ -139,6 +146,7 @@ colpick Color Picker / colpick.com /*Input field containers*/ .colpick_field, .colpick_hex_field { position: absolute; + touch-action: none; height: 20px; width: 60px; overflow:hidden; @@ -198,6 +206,7 @@ colpick Color Picker / colpick.com /*Text inputs*/ .colpick_field input, .colpick_hex_field input { position: absolute; + touch-action: none; right: 11px; margin: 0; padding: 0; @@ -217,6 +226,7 @@ colpick Color Picker / colpick.com /*Field up/down arrows*/ .colpick_field_arrs { position: absolute; + touch-action: none; top: 0; right: 0; width: 9px; @@ -225,6 +235,7 @@ colpick Color Picker / colpick.com } .colpick_field_uarr { position: absolute; + touch-action: none; top: 5px; width: 0; height: 0; @@ -234,6 +245,7 @@ colpick Color Picker / colpick.com } .colpick_field_darr { position: absolute; + touch-action: none; bottom:5px; width: 0; height: 0; @@ -244,6 +256,7 @@ colpick Color Picker / colpick.com /*Submit/Select button*/ .colpick_submit { position: absolute; + touch-action: none; left: 207px; top: 149px; width: 130px; From 7ee560899222142202291afee62979926a9c3dd5 Mon Sep 17 00:00:00 2001 From: Liv Erickson Date: Thu, 25 Jan 2018 12:02:26 -0800 Subject: [PATCH 04/24] initial first pass of exposing headless verification --- .../ui/overlays/ContextOverlayInterface.cpp | 192 ++++++++++-------- .../src/ui/overlays/ContextOverlayInterface.h | 30 +-- 2 files changed, 126 insertions(+), 96 deletions(-) diff --git a/interface/src/ui/overlays/ContextOverlayInterface.cpp b/interface/src/ui/overlays/ContextOverlayInterface.cpp index d690880f99..3886d5ad10 100644 --- a/interface/src/ui/overlays/ContextOverlayInterface.cpp +++ b/interface/src/ui/overlays/ContextOverlayInterface.cpp @@ -168,7 +168,7 @@ bool ContextOverlayInterface::createOrDestroyContextOverlay(const EntityItemID& _contextOverlay->setColorPulse(CONTEXT_OVERLAY_UNHOVERED_COLORPULSE); _contextOverlay->setIgnoreRayIntersection(false); _contextOverlay->setDrawInFront(true); - _contextOverlay->setURL(PathUtils::resourcesPath() + "images/inspect-icon.png"); + _contextOverlay->setURL(PathUtils::resourcesUrl() + "images/inspect-icon.png"); _contextOverlay->setIsFacingAvatar(true); _contextOverlayID = qApp->getOverlays().addOverlay(_contextOverlay); } @@ -189,6 +189,7 @@ bool ContextOverlayInterface::createOrDestroyContextOverlay(const EntityItemID& return false; } + bool ContextOverlayInterface::contextOverlayFilterPassed(const EntityItemID& entityItemID) { EntityItemProperties entityProperties = _entityScriptingInterface->getEntityProperties(entityItemID, _entityPropertyFlags); Setting::Handle _settingSwitch{ "commerce", true }; @@ -266,6 +267,112 @@ void ContextOverlayInterface::contextOverlays_hoverLeaveEntity(const EntityItemI } } +bool ContextOverlayInterface::getLastInspectedEntityWasValid() { + if (!_lastInspectedEntity.isNull() && !_lastInspectedValidEntity.isNull()) { + return _lastInspectedEntity == _lastInspectedValidEntity; + } + return false; +} + +void ContextOverlayInterface::requestEntityOwnershipVerification(const QUuid& entityItemID) { + EntityItemProperties entityProperties = _entityScriptingInterface->getEntityProperties(entityItemID, _entityPropertyFlags); + _entityMarketplaceID = entityProperties.getMarketplaceID(); + if (!entityItemID.isNull() && _entityMarketplaceID.length() > 0) { + setLastInspectedEntity(entityItemID); + requestOwnershipVerification(); + } +} + +void ContextOverlayInterface::requestOwnershipVerification() { + EntityItemProperties entityProperties = _entityScriptingInterface->getEntityProperties(_lastInspectedEntity, _entityPropertyFlags); + + auto nodeList = DependencyManager::get(); + + if (entityProperties.getClientOnly()) { + if (entityProperties.verifyStaticCertificateProperties()) { + SharedNodePointer entityServer = nodeList->soloNodeOfType(NodeType::EntityServer); + + if (entityServer) { + QNetworkAccessManager& networkAccessManager = NetworkAccessManager::getInstance(); + QNetworkRequest networkRequest; + networkRequest.setAttribute(QNetworkRequest::FollowRedirectsAttribute, true); + networkRequest.setHeader(QNetworkRequest::ContentTypeHeader, "application/json"); + QUrl requestURL = NetworkingConstants::METAVERSE_SERVER_URL(); + requestURL.setPath("/api/v1/commerce/proof_of_purchase_status/transfer"); + QJsonObject request; + request["certificate_id"] = entityProperties.getCertificateID(); + networkRequest.setUrl(requestURL); + + QNetworkReply* networkReply = NULL; + networkReply = networkAccessManager.put(networkRequest, QJsonDocument(request).toJson()); + + connect(networkReply, &QNetworkReply::finished, [=]() { + QJsonObject jsonObject = QJsonDocument::fromJson(networkReply->readAll()).object(); + jsonObject = jsonObject["data"].toObject(); + + if (networkReply->error() == QNetworkReply::NoError) { + if (!jsonObject["invalid_reason"].toString().isEmpty()) { + qCDebug(entities) << "invalid_reason not empty"; + } + else if (jsonObject["transfer_status"].toArray().first().toString() == "failed") { + qCDebug(entities) << "'transfer_status' is 'failed'"; + } + else if (jsonObject["transfer_status"].toArray().first().toString() == "pending") { + qCDebug(entities) << "'transfer_status' is 'pending'"; + } + else { + QString ownerKey = jsonObject["transfer_recipient_key"].toString(); + + QByteArray certID = entityProperties.getCertificateID().toUtf8(); + QByteArray text = DependencyManager::get()->getTree()->computeNonce(certID, ownerKey); + QByteArray nodeToChallengeByteArray = entityProperties.getOwningAvatarID().toRfc4122(); + + int certIDByteArraySize = certID.length(); + int textByteArraySize = text.length(); + int nodeToChallengeByteArraySize = nodeToChallengeByteArray.length(); + + auto challengeOwnershipPacket = NLPacket::create(PacketType::ChallengeOwnershipRequest, + certIDByteArraySize + textByteArraySize + nodeToChallengeByteArraySize + 3 * sizeof(int), + true); + challengeOwnershipPacket->writePrimitive(certIDByteArraySize); + challengeOwnershipPacket->writePrimitive(textByteArraySize); + challengeOwnershipPacket->writePrimitive(nodeToChallengeByteArraySize); + challengeOwnershipPacket->write(certID); + challengeOwnershipPacket->write(text); + challengeOwnershipPacket->write(nodeToChallengeByteArray); + nodeList->sendPacket(std::move(challengeOwnershipPacket), *entityServer); + + // Kickoff a 10-second timeout timer that marks the cert if we don't get an ownership response in time + if (thread() != QThread::currentThread()) { + QMetaObject::invokeMethod(this, "startChallengeOwnershipTimer"); + return; + } + else { + startChallengeOwnershipTimer(); + } + } + } + else { + qCDebug(entities) << "Call to" << networkReply->url() << "failed with error" << networkReply->error() << + "More info:" << networkReply->readAll(); + } + + networkReply->deleteLater(); + }); + } + else { + qCWarning(context_overlay) << "Couldn't get Entity Server!"; + } + } + else { + auto ledger = DependencyManager::get(); + _challengeOwnershipTimeoutTimer.stop(); + emit ledger->updateCertificateStatus(entityProperties.getCertificateID(), (uint)(ledger->CERTIFICATE_STATUS_STATIC_VERIFICATION_FAILED)); + qCDebug(context_overlay) << "Entity" << _lastInspectedEntity << "failed static certificate verification!"; + } + } +} + static const QString INSPECTION_CERTIFICATE_QML_PATH = "hifi/commerce/inspectionCertificate/InspectionCertificate.qml"; void ContextOverlayInterface::openInspectionCertificate() { // lets open the tablet to the inspection certificate QML @@ -275,87 +382,7 @@ void ContextOverlayInterface::openInspectionCertificate() { _hmdScriptingInterface->openTablet(); setLastInspectedEntity(_currentEntityWithContextOverlay); - - EntityItemProperties entityProperties = _entityScriptingInterface->getEntityProperties(_lastInspectedEntity, _entityPropertyFlags); - - auto nodeList = DependencyManager::get(); - - if (entityProperties.getClientOnly()) { - if (entityProperties.verifyStaticCertificateProperties()) { - SharedNodePointer entityServer = nodeList->soloNodeOfType(NodeType::EntityServer); - - if (entityServer) { - QNetworkAccessManager& networkAccessManager = NetworkAccessManager::getInstance(); - QNetworkRequest networkRequest; - networkRequest.setAttribute(QNetworkRequest::FollowRedirectsAttribute, true); - networkRequest.setHeader(QNetworkRequest::ContentTypeHeader, "application/json"); - QUrl requestURL = NetworkingConstants::METAVERSE_SERVER_URL(); - requestURL.setPath("/api/v1/commerce/proof_of_purchase_status/transfer"); - QJsonObject request; - request["certificate_id"] = entityProperties.getCertificateID(); - networkRequest.setUrl(requestURL); - - QNetworkReply* networkReply = NULL; - networkReply = networkAccessManager.put(networkRequest, QJsonDocument(request).toJson()); - - connect(networkReply, &QNetworkReply::finished, [=]() { - QJsonObject jsonObject = QJsonDocument::fromJson(networkReply->readAll()).object(); - jsonObject = jsonObject["data"].toObject(); - - if (networkReply->error() == QNetworkReply::NoError) { - if (!jsonObject["invalid_reason"].toString().isEmpty()) { - qCDebug(entities) << "invalid_reason not empty"; - } else if (jsonObject["transfer_status"].toArray().first().toString() == "failed") { - qCDebug(entities) << "'transfer_status' is 'failed'"; - } else if (jsonObject["transfer_status"].toArray().first().toString() == "pending") { - qCDebug(entities) << "'transfer_status' is 'pending'"; - } else { - QString ownerKey = jsonObject["transfer_recipient_key"].toString(); - - QByteArray certID = entityProperties.getCertificateID().toUtf8(); - QByteArray text = DependencyManager::get()->getTree()->computeNonce(certID, ownerKey); - QByteArray nodeToChallengeByteArray = entityProperties.getOwningAvatarID().toRfc4122(); - - int certIDByteArraySize = certID.length(); - int textByteArraySize = text.length(); - int nodeToChallengeByteArraySize = nodeToChallengeByteArray.length(); - - auto challengeOwnershipPacket = NLPacket::create(PacketType::ChallengeOwnershipRequest, - certIDByteArraySize + textByteArraySize + nodeToChallengeByteArraySize + 3 * sizeof(int), - true); - challengeOwnershipPacket->writePrimitive(certIDByteArraySize); - challengeOwnershipPacket->writePrimitive(textByteArraySize); - challengeOwnershipPacket->writePrimitive(nodeToChallengeByteArraySize); - challengeOwnershipPacket->write(certID); - challengeOwnershipPacket->write(text); - challengeOwnershipPacket->write(nodeToChallengeByteArray); - nodeList->sendPacket(std::move(challengeOwnershipPacket), *entityServer); - - // Kickoff a 10-second timeout timer that marks the cert if we don't get an ownership response in time - if (thread() != QThread::currentThread()) { - QMetaObject::invokeMethod(this, "startChallengeOwnershipTimer"); - return; - } else { - startChallengeOwnershipTimer(); - } - } - } else { - qCDebug(entities) << "Call to" << networkReply->url() << "failed with error" << networkReply->error() << - "More info:" << networkReply->readAll(); - } - - networkReply->deleteLater(); - }); - } else { - qCWarning(context_overlay) << "Couldn't get Entity Server!"; - } - } else { - auto ledger = DependencyManager::get(); - _challengeOwnershipTimeoutTimer.stop(); - emit ledger->updateCertificateStatus(entityProperties.getCertificateID(), (uint)(ledger->CERTIFICATE_STATUS_STATIC_VERIFICATION_FAILED)); - qCDebug(context_overlay) << "Entity" << _lastInspectedEntity << "failed static certificate verification!"; - } - } + requestOwnershipVerification(); } } @@ -421,6 +448,7 @@ void ContextOverlayInterface::handleChallengeOwnershipReplyPacket(QSharedPointer if (verificationSuccess) { emit ledger->updateCertificateStatus(certID, (uint)(ledger->CERTIFICATE_STATUS_VERIFICATION_SUCCESS)); + _lastInspectedValidEntity = _lastInspectedEntity; } else { emit ledger->updateCertificateStatus(certID, (uint)(ledger->CERTIFICATE_STATUS_OWNER_VERIFICATION_FAILED)); } diff --git a/interface/src/ui/overlays/ContextOverlayInterface.h b/interface/src/ui/overlays/ContextOverlayInterface.h index 990a7fe599..389b377bd5 100644 --- a/interface/src/ui/overlays/ContextOverlayInterface.h +++ b/interface/src/ui/overlays/ContextOverlayInterface.h @@ -33,24 +33,25 @@ /**jsdoc * @namespace ContextOverlay */ -class ContextOverlayInterface : public QObject, public Dependency { +class ContextOverlayInterface : public QObject, public Dependency { Q_OBJECT - Q_PROPERTY(QUuid entityWithContextOverlay READ getCurrentEntityWithContextOverlay WRITE setCurrentEntityWithContextOverlay) - Q_PROPERTY(bool enabled READ getEnabled WRITE setEnabled) - Q_PROPERTY(bool isInMarketplaceInspectionMode READ getIsInMarketplaceInspectionMode WRITE setIsInMarketplaceInspectionMode) - QSharedPointer _entityScriptingInterface; + Q_PROPERTY(QUuid entityWithContextOverlay READ getCurrentEntityWithContextOverlay WRITE setCurrentEntityWithContextOverlay) + Q_PROPERTY(bool enabled READ getEnabled WRITE setEnabled) + Q_PROPERTY(bool isInMarketplaceInspectionMode READ getIsInMarketplaceInspectionMode WRITE setIsInMarketplaceInspectionMode) + + QSharedPointer _entityScriptingInterface; EntityPropertyFlags _entityPropertyFlags; QSharedPointer _hmdScriptingInterface; QSharedPointer _tabletScriptingInterface; QSharedPointer _selectionScriptingInterface; - OverlayID _contextOverlayID { UNKNOWN_OVERLAY_ID }; - std::shared_ptr _contextOverlay { nullptr }; + OverlayID _contextOverlayID{ UNKNOWN_OVERLAY_ID }; + std::shared_ptr _contextOverlay{ nullptr }; public: - ContextOverlayInterface(); - Q_INVOKABLE QUuid getCurrentEntityWithContextOverlay() { return _currentEntityWithContextOverlay; } + Q_INVOKABLE bool getLastInspectedEntityWasValid(); + Q_INVOKABLE void requestEntityOwnershipVerification(const QUuid& entityID); void setCurrentEntityWithContextOverlay(const QUuid& entityID) { _currentEntityWithContextOverlay = entityID; } void setLastInspectedEntity(const QUuid& entityID) { _challengeOwnershipTimeoutTimer.stop(); _lastInspectedEntity = entityID; } void setEnabled(bool enabled); @@ -61,7 +62,7 @@ public: signals: void contextOverlayClicked(const QUuid& currentEntityWithContextOverlay); -public slots: + public slots: bool createOrDestroyContextOverlay(const EntityItemID& entityItemID, const PointerEvent& event); bool destroyContextOverlay(const EntityItemID& entityItemID, const PointerEvent& event); bool destroyContextOverlay(const EntityItemID& entityItemID); @@ -72,7 +73,7 @@ public slots: void contextOverlays_hoverLeaveEntity(const EntityItemID& entityID, const PointerEvent& event); bool contextOverlayFilterPassed(const EntityItemID& entityItemID); -private slots: + private slots: void handleChallengeOwnershipReplyPacket(QSharedPointer packet, SharedNodePointer sendingNode); private: @@ -80,17 +81,18 @@ private: enum { MAX_SELECTION_COUNT = 16 }; - - bool _verboseLogging { true }; - bool _enabled { true }; + bool _verboseLogging{ true }; + bool _enabled{ true }; EntityItemID _currentEntityWithContextOverlay{}; EntityItemID _lastInspectedEntity{}; + EntityItemID _lastInspectedValidEntity{}; QString _entityMarketplaceID; bool _contextOverlayJustClicked { false }; bool _isInMarketplaceInspectionMode { false }; void openInspectionCertificate(); + void requestOwnershipVerification(); void openMarketplace(); void enableEntityHighlight(const EntityItemID& entityItemID); void disableEntityHighlight(const EntityItemID& entityItemID); From 7e5684c439abc1399963ce1e9866d57af8d8a309 Mon Sep 17 00:00:00 2001 From: Liv Erickson Date: Thu, 25 Jan 2018 15:04:12 -0800 Subject: [PATCH 05/24] use signals --- .../ui/overlays/ContextOverlayInterface.cpp | 12 ++++------- .../src/ui/overlays/ContextOverlayInterface.h | 20 +++++++++---------- 2 files changed, 14 insertions(+), 18 deletions(-) diff --git a/interface/src/ui/overlays/ContextOverlayInterface.cpp b/interface/src/ui/overlays/ContextOverlayInterface.cpp index 3886d5ad10..069446494f 100644 --- a/interface/src/ui/overlays/ContextOverlayInterface.cpp +++ b/interface/src/ui/overlays/ContextOverlayInterface.cpp @@ -267,13 +267,6 @@ void ContextOverlayInterface::contextOverlays_hoverLeaveEntity(const EntityItemI } } -bool ContextOverlayInterface::getLastInspectedEntityWasValid() { - if (!_lastInspectedEntity.isNull() && !_lastInspectedValidEntity.isNull()) { - return _lastInspectedEntity == _lastInspectedValidEntity; - } - return false; -} - void ContextOverlayInterface::requestEntityOwnershipVerification(const QUuid& entityItemID) { EntityItemProperties entityProperties = _entityScriptingInterface->getEntityProperties(entityItemID, _entityPropertyFlags); _entityMarketplaceID = entityProperties.getMarketplaceID(); @@ -368,6 +361,7 @@ void ContextOverlayInterface::requestOwnershipVerification() { auto ledger = DependencyManager::get(); _challengeOwnershipTimeoutTimer.stop(); emit ledger->updateCertificateStatus(entityProperties.getCertificateID(), (uint)(ledger->CERTIFICATE_STATUS_STATIC_VERIFICATION_FAILED)); + emit ownershipVerificationFailed(_lastInspectedEntity); qCDebug(context_overlay) << "Entity" << _lastInspectedEntity << "failed static certificate verification!"; } } @@ -424,6 +418,7 @@ void ContextOverlayInterface::startChallengeOwnershipTimer() { connect(&_challengeOwnershipTimeoutTimer, &QTimer::timeout, this, [=]() { qCDebug(entities) << "Ownership challenge timed out for" << _lastInspectedEntity; emit ledger->updateCertificateStatus(entityProperties.getCertificateID(), (uint)(ledger->CERTIFICATE_STATUS_VERIFICATION_TIMEOUT)); + emit ownershipVerificationFailed(_lastInspectedEntity); }); _challengeOwnershipTimeoutTimer.start(5000); @@ -448,8 +443,9 @@ void ContextOverlayInterface::handleChallengeOwnershipReplyPacket(QSharedPointer if (verificationSuccess) { emit ledger->updateCertificateStatus(certID, (uint)(ledger->CERTIFICATE_STATUS_VERIFICATION_SUCCESS)); - _lastInspectedValidEntity = _lastInspectedEntity; + emit ownershipVerificationSuccess(_lastInspectedEntity); } else { emit ledger->updateCertificateStatus(certID, (uint)(ledger->CERTIFICATE_STATUS_OWNER_VERIFICATION_FAILED)); + emit ownershipVerificationFailed(_lastInspectedEntity); } } diff --git a/interface/src/ui/overlays/ContextOverlayInterface.h b/interface/src/ui/overlays/ContextOverlayInterface.h index 389b377bd5..c96c5989a6 100644 --- a/interface/src/ui/overlays/ContextOverlayInterface.h +++ b/interface/src/ui/overlays/ContextOverlayInterface.h @@ -36,21 +36,20 @@ class ContextOverlayInterface : public QObject, public Dependency { Q_OBJECT - Q_PROPERTY(QUuid entityWithContextOverlay READ getCurrentEntityWithContextOverlay WRITE setCurrentEntityWithContextOverlay) - Q_PROPERTY(bool enabled READ getEnabled WRITE setEnabled) - Q_PROPERTY(bool isInMarketplaceInspectionMode READ getIsInMarketplaceInspectionMode WRITE setIsInMarketplaceInspectionMode) + Q_PROPERTY(QUuid entityWithContextOverlay READ getCurrentEntityWithContextOverlay WRITE setCurrentEntityWithContextOverlay) + Q_PROPERTY(bool enabled READ getEnabled WRITE setEnabled) + Q_PROPERTY(bool isInMarketplaceInspectionMode READ getIsInMarketplaceInspectionMode WRITE setIsInMarketplaceInspectionMode) - QSharedPointer _entityScriptingInterface; + QSharedPointer _entityScriptingInterface; EntityPropertyFlags _entityPropertyFlags; QSharedPointer _hmdScriptingInterface; QSharedPointer _tabletScriptingInterface; QSharedPointer _selectionScriptingInterface; - OverlayID _contextOverlayID{ UNKNOWN_OVERLAY_ID }; - std::shared_ptr _contextOverlay{ nullptr }; + OverlayID _contextOverlayID { UNKNOWN_OVERLAY_ID }; + std::shared_ptr _contextOverlay { nullptr }; public: ContextOverlayInterface(); Q_INVOKABLE QUuid getCurrentEntityWithContextOverlay() { return _currentEntityWithContextOverlay; } - Q_INVOKABLE bool getLastInspectedEntityWasValid(); Q_INVOKABLE void requestEntityOwnershipVerification(const QUuid& entityID); void setCurrentEntityWithContextOverlay(const QUuid& entityID) { _currentEntityWithContextOverlay = entityID; } void setLastInspectedEntity(const QUuid& entityID) { _challengeOwnershipTimeoutTimer.stop(); _lastInspectedEntity = entityID; } @@ -61,8 +60,10 @@ public: signals: void contextOverlayClicked(const QUuid& currentEntityWithContextOverlay); + void ownershipVerificationSuccess(const QUuid& entityID); + void ownershipVerificationFailed(const QUuid& entityID); - public slots: +public slots: bool createOrDestroyContextOverlay(const EntityItemID& entityItemID, const PointerEvent& event); bool destroyContextOverlay(const EntityItemID& entityItemID, const PointerEvent& event); bool destroyContextOverlay(const EntityItemID& entityItemID); @@ -73,7 +74,7 @@ signals: void contextOverlays_hoverLeaveEntity(const EntityItemID& entityID, const PointerEvent& event); bool contextOverlayFilterPassed(const EntityItemID& entityItemID); - private slots: +private slots: void handleChallengeOwnershipReplyPacket(QSharedPointer packet, SharedNodePointer sendingNode); private: @@ -85,7 +86,6 @@ private: bool _enabled{ true }; EntityItemID _currentEntityWithContextOverlay{}; EntityItemID _lastInspectedEntity{}; - EntityItemID _lastInspectedValidEntity{}; QString _entityMarketplaceID; bool _contextOverlayJustClicked { false }; From 3a6f184278946aff8bdbb914918f95728cadbdc9 Mon Sep 17 00:00:00 2001 From: Liv Erickson Date: Thu, 25 Jan 2018 15:13:14 -0800 Subject: [PATCH 06/24] make clear function is for avatar entities only, add error handling in non-client entity cases --- interface/src/ui/overlays/ContextOverlayInterface.cpp | 7 ++++++- interface/src/ui/overlays/ContextOverlayInterface.h | 2 +- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/interface/src/ui/overlays/ContextOverlayInterface.cpp b/interface/src/ui/overlays/ContextOverlayInterface.cpp index 069446494f..d86d441e3b 100644 --- a/interface/src/ui/overlays/ContextOverlayInterface.cpp +++ b/interface/src/ui/overlays/ContextOverlayInterface.cpp @@ -267,10 +267,15 @@ void ContextOverlayInterface::contextOverlays_hoverLeaveEntity(const EntityItemI } } -void ContextOverlayInterface::requestEntityOwnershipVerification(const QUuid& entityItemID) { +void ContextOverlayInterface::proveAvatarEntityOwnershipVerification(const QUuid& entityItemID) { EntityItemProperties entityProperties = _entityScriptingInterface->getEntityProperties(entityItemID, _entityPropertyFlags); _entityMarketplaceID = entityProperties.getMarketplaceID(); if (!entityItemID.isNull() && _entityMarketplaceID.length() > 0) { + if (!entityProperties.getClientOnly()) { + qCDebug(entities) << "Failed to prove ownership of:" << entityItemID << "is not an avatar entity"; + emit ownershipVerificationFailed(entityItemID); + return; + } setLastInspectedEntity(entityItemID); requestOwnershipVerification(); } diff --git a/interface/src/ui/overlays/ContextOverlayInterface.h b/interface/src/ui/overlays/ContextOverlayInterface.h index c96c5989a6..04416299d6 100644 --- a/interface/src/ui/overlays/ContextOverlayInterface.h +++ b/interface/src/ui/overlays/ContextOverlayInterface.h @@ -50,7 +50,7 @@ class ContextOverlayInterface : public QObject, public Dependency { public: ContextOverlayInterface(); Q_INVOKABLE QUuid getCurrentEntityWithContextOverlay() { return _currentEntityWithContextOverlay; } - Q_INVOKABLE void requestEntityOwnershipVerification(const QUuid& entityID); + Q_INVOKABLE void proveAvatarEntityOwnershipVerification(const QUuid& entityID); void setCurrentEntityWithContextOverlay(const QUuid& entityID) { _currentEntityWithContextOverlay = entityID; } void setLastInspectedEntity(const QUuid& entityID) { _challengeOwnershipTimeoutTimer.stop(); _lastInspectedEntity = entityID; } void setEnabled(bool enabled); From 20635acf27d5501e431288576ac5cad98dac571c Mon Sep 17 00:00:00 2001 From: Liv Erickson Date: Fri, 26 Jan 2018 17:13:39 -0800 Subject: [PATCH 07/24] moving logic to wallet, crashes currently --- .../scripting/WalletScriptingInterface.cpp | 22 +++++++++++++++++++ .../src/scripting/WalletScriptingInterface.h | 5 +++++ .../ui/overlays/ContextOverlayInterface.cpp | 19 ++++------------ .../src/ui/overlays/ContextOverlayInterface.h | 3 +-- 4 files changed, 32 insertions(+), 17 deletions(-) diff --git a/interface/src/scripting/WalletScriptingInterface.cpp b/interface/src/scripting/WalletScriptingInterface.cpp index 71a7076bdf..8d6dc7bbcd 100644 --- a/interface/src/scripting/WalletScriptingInterface.cpp +++ b/interface/src/scripting/WalletScriptingInterface.cpp @@ -16,6 +16,16 @@ CheckoutProxy::CheckoutProxy(QObject* qmlObject, QObject* parent) : QmlWrapper(q } WalletScriptingInterface::WalletScriptingInterface() { + _contextOverlayInterface = DependencyManager::get(); + + _entityPropertyFlags += PROP_POSITION; + _entityPropertyFlags += PROP_ROTATION; + _entityPropertyFlags += PROP_MARKETPLACE_ID; + _entityPropertyFlags += PROP_DIMENSIONS; + _entityPropertyFlags += PROP_REGISTRATION_POINT; + _entityPropertyFlags += PROP_CERTIFICATE_ID; + _entityPropertyFlags += PROP_CLIENT_ONLY; + _entityPropertyFlags += PROP_OWNING_AVATAR_ID; } void WalletScriptingInterface::refreshWalletStatus() { @@ -26,4 +36,16 @@ void WalletScriptingInterface::refreshWalletStatus() { void WalletScriptingInterface::setWalletStatus(const uint& status) { _walletStatus = status; emit DependencyManager::get()->walletStatusResult(status); +} + +void WalletScriptingInterface::proveAvatarEntityOwnershipVerification(const QUuid& entityID) { + EntityItemProperties entityProperties = DependencyManager::get()->getEntityProperties(entityID, _entityPropertyFlags); + if (!entityID.isNull() && entityProperties.getMarketplaceID().length() > 0) { + if (!entityProperties.getClientOnly()) { + qCDebug(entities) << "Failed to prove ownership of:" << entityID << "is not an avatar entity"; + emit _contextOverlayInterface->ownershipVerificationFailed(entityID); + return; + } + _contextOverlayInterface->requestOwnershipVerification(entityID); + } } \ No newline at end of file diff --git a/interface/src/scripting/WalletScriptingInterface.h b/interface/src/scripting/WalletScriptingInterface.h index 5469e732c7..c725c34685 100644 --- a/interface/src/scripting/WalletScriptingInterface.h +++ b/interface/src/scripting/WalletScriptingInterface.h @@ -21,6 +21,7 @@ #include #include "Application.h" #include "commerce/Wallet.h" +#include "ui/overlays/ContextOverlayInterface.h" class CheckoutProxy : public QmlWrapper { Q_OBJECT @@ -33,12 +34,15 @@ class WalletScriptingInterface : public QObject, public Dependency { Q_OBJECT Q_PROPERTY(uint walletStatus READ getWalletStatus WRITE setWalletStatus NOTIFY walletStatusChanged) + QSharedPointer _contextOverlayInterface; + public: WalletScriptingInterface(); Q_INVOKABLE void refreshWalletStatus(); Q_INVOKABLE uint getWalletStatus() { return _walletStatus; } + Q_INVOKABLE void proveAvatarEntityOwnershipVerification(const QUuid& entityID); // setWalletStatus() should never be made Q_INVOKABLE. If it were, // scripts could cause the Wallet to incorrectly report its status. void setWalletStatus(const uint& status); @@ -49,6 +53,7 @@ signals: private: uint _walletStatus; + EntityPropertyFlags _entityPropertyFlags; }; #endif // hifi_WalletScriptingInterface_h diff --git a/interface/src/ui/overlays/ContextOverlayInterface.cpp b/interface/src/ui/overlays/ContextOverlayInterface.cpp index d86d441e3b..4a5aa3d0f4 100644 --- a/interface/src/ui/overlays/ContextOverlayInterface.cpp +++ b/interface/src/ui/overlays/ContextOverlayInterface.cpp @@ -267,21 +267,10 @@ void ContextOverlayInterface::contextOverlays_hoverLeaveEntity(const EntityItemI } } -void ContextOverlayInterface::proveAvatarEntityOwnershipVerification(const QUuid& entityItemID) { - EntityItemProperties entityProperties = _entityScriptingInterface->getEntityProperties(entityItemID, _entityPropertyFlags); - _entityMarketplaceID = entityProperties.getMarketplaceID(); - if (!entityItemID.isNull() && _entityMarketplaceID.length() > 0) { - if (!entityProperties.getClientOnly()) { - qCDebug(entities) << "Failed to prove ownership of:" << entityItemID << "is not an avatar entity"; - emit ownershipVerificationFailed(entityItemID); - return; - } - setLastInspectedEntity(entityItemID); - requestOwnershipVerification(); - } -} +void ContextOverlayInterface::requestOwnershipVerification(const QUuid& entityID) { + + setLastInspectedEntity(entityID); -void ContextOverlayInterface::requestOwnershipVerification() { EntityItemProperties entityProperties = _entityScriptingInterface->getEntityProperties(_lastInspectedEntity, _entityPropertyFlags); auto nodeList = DependencyManager::get(); @@ -381,7 +370,7 @@ void ContextOverlayInterface::openInspectionCertificate() { _hmdScriptingInterface->openTablet(); setLastInspectedEntity(_currentEntityWithContextOverlay); - requestOwnershipVerification(); + requestOwnershipVerification(_lastInspectedEntity); } } diff --git a/interface/src/ui/overlays/ContextOverlayInterface.h b/interface/src/ui/overlays/ContextOverlayInterface.h index 04416299d6..4063b28785 100644 --- a/interface/src/ui/overlays/ContextOverlayInterface.h +++ b/interface/src/ui/overlays/ContextOverlayInterface.h @@ -50,13 +50,13 @@ class ContextOverlayInterface : public QObject, public Dependency { public: ContextOverlayInterface(); Q_INVOKABLE QUuid getCurrentEntityWithContextOverlay() { return _currentEntityWithContextOverlay; } - Q_INVOKABLE void proveAvatarEntityOwnershipVerification(const QUuid& entityID); void setCurrentEntityWithContextOverlay(const QUuid& entityID) { _currentEntityWithContextOverlay = entityID; } void setLastInspectedEntity(const QUuid& entityID) { _challengeOwnershipTimeoutTimer.stop(); _lastInspectedEntity = entityID; } void setEnabled(bool enabled); bool getEnabled() { return _enabled; } bool getIsInMarketplaceInspectionMode() { return _isInMarketplaceInspectionMode; } void setIsInMarketplaceInspectionMode(bool mode) { _isInMarketplaceInspectionMode = mode; } + void requestOwnershipVerification(const QUuid& entityID); signals: void contextOverlayClicked(const QUuid& currentEntityWithContextOverlay); @@ -92,7 +92,6 @@ private: bool _isInMarketplaceInspectionMode { false }; void openInspectionCertificate(); - void requestOwnershipVerification(); void openMarketplace(); void enableEntityHighlight(const EntityItemID& entityItemID); void disableEntityHighlight(const EntityItemID& entityItemID); From 0e3a01f1e8a1b1671076731f274d27b612bb65bd Mon Sep 17 00:00:00 2001 From: Liv Erickson Date: Mon, 29 Jan 2018 10:20:16 -0800 Subject: [PATCH 08/24] it's working! removed my null pointer and just get it from the dependency manager when required --- interface/src/scripting/WalletScriptingInterface.cpp | 5 ++--- interface/src/scripting/WalletScriptingInterface.h | 2 -- 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/interface/src/scripting/WalletScriptingInterface.cpp b/interface/src/scripting/WalletScriptingInterface.cpp index 8d6dc7bbcd..87c5c89ab3 100644 --- a/interface/src/scripting/WalletScriptingInterface.cpp +++ b/interface/src/scripting/WalletScriptingInterface.cpp @@ -16,7 +16,6 @@ CheckoutProxy::CheckoutProxy(QObject* qmlObject, QObject* parent) : QmlWrapper(q } WalletScriptingInterface::WalletScriptingInterface() { - _contextOverlayInterface = DependencyManager::get(); _entityPropertyFlags += PROP_POSITION; _entityPropertyFlags += PROP_ROTATION; @@ -43,9 +42,9 @@ void WalletScriptingInterface::proveAvatarEntityOwnershipVerification(const QUui if (!entityID.isNull() && entityProperties.getMarketplaceID().length() > 0) { if (!entityProperties.getClientOnly()) { qCDebug(entities) << "Failed to prove ownership of:" << entityID << "is not an avatar entity"; - emit _contextOverlayInterface->ownershipVerificationFailed(entityID); + emit DependencyManager::get()->ownershipVerificationFailed(entityID); return; } - _contextOverlayInterface->requestOwnershipVerification(entityID); + DependencyManager::get()->requestOwnershipVerification(entityID); } } \ No newline at end of file diff --git a/interface/src/scripting/WalletScriptingInterface.h b/interface/src/scripting/WalletScriptingInterface.h index c725c34685..8e2dcd47a8 100644 --- a/interface/src/scripting/WalletScriptingInterface.h +++ b/interface/src/scripting/WalletScriptingInterface.h @@ -34,8 +34,6 @@ class WalletScriptingInterface : public QObject, public Dependency { Q_OBJECT Q_PROPERTY(uint walletStatus READ getWalletStatus WRITE setWalletStatus NOTIFY walletStatusChanged) - QSharedPointer _contextOverlayInterface; - public: WalletScriptingInterface(); From 6a971e136296f962695f142a22570661465d7287 Mon Sep 17 00:00:00 2001 From: Liv Erickson Date: Mon, 29 Jan 2018 11:27:30 -0800 Subject: [PATCH 09/24] remove restriction to be avatar only --- interface/src/scripting/WalletScriptingInterface.cpp | 9 +++------ interface/src/scripting/WalletScriptingInterface.h | 2 +- 2 files changed, 4 insertions(+), 7 deletions(-) diff --git a/interface/src/scripting/WalletScriptingInterface.cpp b/interface/src/scripting/WalletScriptingInterface.cpp index 87c5c89ab3..3e125caeeb 100644 --- a/interface/src/scripting/WalletScriptingInterface.cpp +++ b/interface/src/scripting/WalletScriptingInterface.cpp @@ -37,14 +37,11 @@ void WalletScriptingInterface::setWalletStatus(const uint& status) { emit DependencyManager::get()->walletStatusResult(status); } -void WalletScriptingInterface::proveAvatarEntityOwnershipVerification(const QUuid& entityID) { +void WalletScriptingInterface::proveEntityOwnershipVerification(const QUuid& entityID) { EntityItemProperties entityProperties = DependencyManager::get()->getEntityProperties(entityID, _entityPropertyFlags); if (!entityID.isNull() && entityProperties.getMarketplaceID().length() > 0) { - if (!entityProperties.getClientOnly()) { - qCDebug(entities) << "Failed to prove ownership of:" << entityID << "is not an avatar entity"; - emit DependencyManager::get()->ownershipVerificationFailed(entityID); - return; - } DependencyManager::get()->requestOwnershipVerification(entityID); + } else { + qCDebug(entities) << "Failed to prove ownership of:" << entityID << "is null or not a marketplace item"; } } \ No newline at end of file diff --git a/interface/src/scripting/WalletScriptingInterface.h b/interface/src/scripting/WalletScriptingInterface.h index 8e2dcd47a8..960c38d6fb 100644 --- a/interface/src/scripting/WalletScriptingInterface.h +++ b/interface/src/scripting/WalletScriptingInterface.h @@ -40,7 +40,7 @@ public: Q_INVOKABLE void refreshWalletStatus(); Q_INVOKABLE uint getWalletStatus() { return _walletStatus; } - Q_INVOKABLE void proveAvatarEntityOwnershipVerification(const QUuid& entityID); + Q_INVOKABLE void proveEntityOwnershipVerification(const QUuid& entityID); // setWalletStatus() should never be made Q_INVOKABLE. If it were, // scripts could cause the Wallet to incorrectly report its status. void setWalletStatus(const uint& status); From f8f76d6757ae6c089ae1b562b0d5efd815e71f6f Mon Sep 17 00:00:00 2001 From: Liv Erickson Date: Mon, 29 Jan 2018 12:46:00 -0800 Subject: [PATCH 10/24] changing back to avatar only and making some changes to avoid multiple calls to dependency manager --- .../scripting/WalletScriptingInterface.cpp | 24 +++++++++---------- .../src/scripting/WalletScriptingInterface.h | 3 +-- .../ui/overlays/ContextOverlayInterface.cpp | 1 - .../src/ui/overlays/ContextOverlayInterface.h | 1 + 4 files changed, 13 insertions(+), 16 deletions(-) diff --git a/interface/src/scripting/WalletScriptingInterface.cpp b/interface/src/scripting/WalletScriptingInterface.cpp index 3e125caeeb..e2158b9fd7 100644 --- a/interface/src/scripting/WalletScriptingInterface.cpp +++ b/interface/src/scripting/WalletScriptingInterface.cpp @@ -17,14 +17,6 @@ CheckoutProxy::CheckoutProxy(QObject* qmlObject, QObject* parent) : QmlWrapper(q WalletScriptingInterface::WalletScriptingInterface() { - _entityPropertyFlags += PROP_POSITION; - _entityPropertyFlags += PROP_ROTATION; - _entityPropertyFlags += PROP_MARKETPLACE_ID; - _entityPropertyFlags += PROP_DIMENSIONS; - _entityPropertyFlags += PROP_REGISTRATION_POINT; - _entityPropertyFlags += PROP_CERTIFICATE_ID; - _entityPropertyFlags += PROP_CLIENT_ONLY; - _entityPropertyFlags += PROP_OWNING_AVATAR_ID; } void WalletScriptingInterface::refreshWalletStatus() { @@ -37,11 +29,17 @@ void WalletScriptingInterface::setWalletStatus(const uint& status) { emit DependencyManager::get()->walletStatusResult(status); } -void WalletScriptingInterface::proveEntityOwnershipVerification(const QUuid& entityID) { - EntityItemProperties entityProperties = DependencyManager::get()->getEntityProperties(entityID, _entityPropertyFlags); - if (!entityID.isNull() && entityProperties.getMarketplaceID().length() > 0) { - DependencyManager::get()->requestOwnershipVerification(entityID); +void WalletScriptingInterface::proveAvatarEntityOwnershipVerification(const QUuid& entityID) { + QSharedPointer contextOverlayInterface = DependencyManager::get(); + EntityItemProperties entityProperties = DependencyManager::get()->getEntityProperties(entityID, + contextOverlayInterface->getEntityPropertyFlags()); + if (entityProperties.getClientOnly()) { + if (!entityID.isNull() && entityProperties.getCertificateID().length() > 0) { + contextOverlayInterface->requestOwnershipVerification(entityID); + } else { + qCDebug(entities) << "Failed to prove ownership of:" << entityID << "is null or not a certified item"; + } } else { - qCDebug(entities) << "Failed to prove ownership of:" << entityID << "is null or not a marketplace item"; + qCDebug(entities) << "Failed to prove ownership of:" << entityID << "is not an avatar entity"; } } \ No newline at end of file diff --git a/interface/src/scripting/WalletScriptingInterface.h b/interface/src/scripting/WalletScriptingInterface.h index 960c38d6fb..8f5c65e335 100644 --- a/interface/src/scripting/WalletScriptingInterface.h +++ b/interface/src/scripting/WalletScriptingInterface.h @@ -40,7 +40,7 @@ public: Q_INVOKABLE void refreshWalletStatus(); Q_INVOKABLE uint getWalletStatus() { return _walletStatus; } - Q_INVOKABLE void proveEntityOwnershipVerification(const QUuid& entityID); + Q_INVOKABLE void proveAvatarEntityOwnershipVerification(const QUuid& entityID); // setWalletStatus() should never be made Q_INVOKABLE. If it were, // scripts could cause the Wallet to incorrectly report its status. void setWalletStatus(const uint& status); @@ -51,7 +51,6 @@ signals: private: uint _walletStatus; - EntityPropertyFlags _entityPropertyFlags; }; #endif // hifi_WalletScriptingInterface_h diff --git a/interface/src/ui/overlays/ContextOverlayInterface.cpp b/interface/src/ui/overlays/ContextOverlayInterface.cpp index 4a5aa3d0f4..a273304eaa 100644 --- a/interface/src/ui/overlays/ContextOverlayInterface.cpp +++ b/interface/src/ui/overlays/ContextOverlayInterface.cpp @@ -189,7 +189,6 @@ bool ContextOverlayInterface::createOrDestroyContextOverlay(const EntityItemID& return false; } - bool ContextOverlayInterface::contextOverlayFilterPassed(const EntityItemID& entityItemID) { EntityItemProperties entityProperties = _entityScriptingInterface->getEntityProperties(entityItemID, _entityPropertyFlags); Setting::Handle _settingSwitch{ "commerce", true }; diff --git a/interface/src/ui/overlays/ContextOverlayInterface.h b/interface/src/ui/overlays/ContextOverlayInterface.h index 4063b28785..5bb0b522a3 100644 --- a/interface/src/ui/overlays/ContextOverlayInterface.h +++ b/interface/src/ui/overlays/ContextOverlayInterface.h @@ -57,6 +57,7 @@ public: bool getIsInMarketplaceInspectionMode() { return _isInMarketplaceInspectionMode; } void setIsInMarketplaceInspectionMode(bool mode) { _isInMarketplaceInspectionMode = mode; } void requestOwnershipVerification(const QUuid& entityID); + EntityPropertyFlags getEntityPropertyFlags() { return _entityPropertyFlags; } signals: void contextOverlayClicked(const QUuid& currentEntityWithContextOverlay); From 634bc83ed5e6ef325a206a9bbde9213a92af7156 Mon Sep 17 00:00:00 2001 From: Liv Erickson Date: Mon, 29 Jan 2018 12:54:52 -0800 Subject: [PATCH 11/24] fix elses --- .../ui/overlays/ContextOverlayInterface.cpp | 21 +++++++------------ 1 file changed, 7 insertions(+), 14 deletions(-) diff --git a/interface/src/ui/overlays/ContextOverlayInterface.cpp b/interface/src/ui/overlays/ContextOverlayInterface.cpp index a273304eaa..a7f8861882 100644 --- a/interface/src/ui/overlays/ContextOverlayInterface.cpp +++ b/interface/src/ui/overlays/ContextOverlayInterface.cpp @@ -299,14 +299,11 @@ void ContextOverlayInterface::requestOwnershipVerification(const QUuid& entityID if (networkReply->error() == QNetworkReply::NoError) { if (!jsonObject["invalid_reason"].toString().isEmpty()) { qCDebug(entities) << "invalid_reason not empty"; - } - else if (jsonObject["transfer_status"].toArray().first().toString() == "failed") { + } else if (jsonObject["transfer_status"].toArray().first().toString() == "failed") { qCDebug(entities) << "'transfer_status' is 'failed'"; - } - else if (jsonObject["transfer_status"].toArray().first().toString() == "pending") { + } else if (jsonObject["transfer_status"].toArray().first().toString() == "pending") { qCDebug(entities) << "'transfer_status' is 'pending'"; - } - else { + } else { QString ownerKey = jsonObject["transfer_recipient_key"].toString(); QByteArray certID = entityProperties.getCertificateID().toUtf8(); @@ -332,25 +329,21 @@ void ContextOverlayInterface::requestOwnershipVerification(const QUuid& entityID if (thread() != QThread::currentThread()) { QMetaObject::invokeMethod(this, "startChallengeOwnershipTimer"); return; - } - else { + } else { startChallengeOwnershipTimer(); } } - } - else { + } else { qCDebug(entities) << "Call to" << networkReply->url() << "failed with error" << networkReply->error() << "More info:" << networkReply->readAll(); } networkReply->deleteLater(); }); - } - else { + } else { qCWarning(context_overlay) << "Couldn't get Entity Server!"; } - } - else { + } else { auto ledger = DependencyManager::get(); _challengeOwnershipTimeoutTimer.stop(); emit ledger->updateCertificateStatus(entityProperties.getCertificateID(), (uint)(ledger->CERTIFICATE_STATUS_STATIC_VERIFICATION_FAILED)); From ce8159340b31c3372018409b70c5f968e4557b28 Mon Sep 17 00:00:00 2001 From: Liv Erickson Date: Mon, 29 Jan 2018 15:51:09 -0800 Subject: [PATCH 12/24] fix vs autoformatting --- interface/src/ui/overlays/ContextOverlayInterface.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/interface/src/ui/overlays/ContextOverlayInterface.h b/interface/src/ui/overlays/ContextOverlayInterface.h index 5bb0b522a3..a260c9cc39 100644 --- a/interface/src/ui/overlays/ContextOverlayInterface.h +++ b/interface/src/ui/overlays/ContextOverlayInterface.h @@ -84,7 +84,7 @@ private: MAX_SELECTION_COUNT = 16 }; bool _verboseLogging{ true }; - bool _enabled{ true }; + bool _enabled { true }; EntityItemID _currentEntityWithContextOverlay{}; EntityItemID _lastInspectedEntity{}; QString _entityMarketplaceID; From 8b7c9895081d957aba5242488dde56465295cda5 Mon Sep 17 00:00:00 2001 From: Liv Erickson Date: Mon, 29 Jan 2018 16:34:44 -0800 Subject: [PATCH 13/24] move emit signals to wallet interface --- interface/src/scripting/WalletScriptingInterface.h | 2 ++ interface/src/ui/overlays/ContextOverlayInterface.cpp | 8 ++++---- interface/src/ui/overlays/ContextOverlayInterface.h | 3 +-- 3 files changed, 7 insertions(+), 6 deletions(-) diff --git a/interface/src/scripting/WalletScriptingInterface.h b/interface/src/scripting/WalletScriptingInterface.h index 8f5c65e335..9e40aad087 100644 --- a/interface/src/scripting/WalletScriptingInterface.h +++ b/interface/src/scripting/WalletScriptingInterface.h @@ -48,6 +48,8 @@ public: signals: void walletStatusChanged(); void walletNotSetup(); + void ownershipVerificationSuccess(const QUuid& entityID); + void ownershipVerificationFailed(const QUuid& entityID); private: uint _walletStatus; diff --git a/interface/src/ui/overlays/ContextOverlayInterface.cpp b/interface/src/ui/overlays/ContextOverlayInterface.cpp index a7f8861882..ed7b811fb0 100644 --- a/interface/src/ui/overlays/ContextOverlayInterface.cpp +++ b/interface/src/ui/overlays/ContextOverlayInterface.cpp @@ -347,7 +347,7 @@ void ContextOverlayInterface::requestOwnershipVerification(const QUuid& entityID auto ledger = DependencyManager::get(); _challengeOwnershipTimeoutTimer.stop(); emit ledger->updateCertificateStatus(entityProperties.getCertificateID(), (uint)(ledger->CERTIFICATE_STATUS_STATIC_VERIFICATION_FAILED)); - emit ownershipVerificationFailed(_lastInspectedEntity); + emit DependencyManager::get()->ownershipVerificationFailed(_lastInspectedEntity); qCDebug(context_overlay) << "Entity" << _lastInspectedEntity << "failed static certificate verification!"; } } @@ -404,7 +404,7 @@ void ContextOverlayInterface::startChallengeOwnershipTimer() { connect(&_challengeOwnershipTimeoutTimer, &QTimer::timeout, this, [=]() { qCDebug(entities) << "Ownership challenge timed out for" << _lastInspectedEntity; emit ledger->updateCertificateStatus(entityProperties.getCertificateID(), (uint)(ledger->CERTIFICATE_STATUS_VERIFICATION_TIMEOUT)); - emit ownershipVerificationFailed(_lastInspectedEntity); + emit DependencyManager::get()->ownershipVerificationFailed(_lastInspectedEntity); }); _challengeOwnershipTimeoutTimer.start(5000); @@ -429,9 +429,9 @@ void ContextOverlayInterface::handleChallengeOwnershipReplyPacket(QSharedPointer if (verificationSuccess) { emit ledger->updateCertificateStatus(certID, (uint)(ledger->CERTIFICATE_STATUS_VERIFICATION_SUCCESS)); - emit ownershipVerificationSuccess(_lastInspectedEntity); + emit DependencyManager::get()->ownershipVerificationSuccess(_lastInspectedEntity); } else { emit ledger->updateCertificateStatus(certID, (uint)(ledger->CERTIFICATE_STATUS_OWNER_VERIFICATION_FAILED)); - emit ownershipVerificationFailed(_lastInspectedEntity); + emit DependencyManager::get()->ownershipVerificationFailed(_lastInspectedEntity); } } diff --git a/interface/src/ui/overlays/ContextOverlayInterface.h b/interface/src/ui/overlays/ContextOverlayInterface.h index a260c9cc39..6aad2a773b 100644 --- a/interface/src/ui/overlays/ContextOverlayInterface.h +++ b/interface/src/ui/overlays/ContextOverlayInterface.h @@ -26,6 +26,7 @@ #include "ui/overlays/Overlays.h" #include "scripting/HMDScriptingInterface.h" #include "scripting/SelectionScriptingInterface.h" +#include "scripting/WalletScriptingInterface.h" #include "EntityTree.h" #include "ContextOverlayLogging.h" @@ -61,8 +62,6 @@ public: signals: void contextOverlayClicked(const QUuid& currentEntityWithContextOverlay); - void ownershipVerificationSuccess(const QUuid& entityID); - void ownershipVerificationFailed(const QUuid& entityID); public slots: bool createOrDestroyContextOverlay(const EntityItemID& entityItemID, const PointerEvent& event); From c4f57877dd4e28c96d06dab04eac26f59351d005 Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Wed, 31 Jan 2018 10:06:20 -0800 Subject: [PATCH 14/24] if hand is already in 'drop gesture' position when equipping something, don't unequip until the hand has been upright --- .../controllerModules/equipEntity.js | 38 ++++++++++++------- 1 file changed, 24 insertions(+), 14 deletions(-) diff --git a/scripts/system/controllers/controllerModules/equipEntity.js b/scripts/system/controllers/controllerModules/equipEntity.js index a250f77b2e..252f6efa9e 100644 --- a/scripts/system/controllers/controllerModules/equipEntity.js +++ b/scripts/system/controllers/controllerModules/equipEntity.js @@ -10,7 +10,7 @@ getControllerJointIndex, enableDispatcherModule, disableDispatcherModule, Messages, makeDispatcherModuleParameters, makeRunningValues, Settings, entityHasActions, Vec3, Overlays, flatten, Xform, getControllerWorldLocation, ensureDynamic, entityIsCloneable, - cloneEntity, DISPATCHER_PROPERTIES, TEAR_AWAY_DISTANCE + cloneEntity, DISPATCHER_PROPERTIES, TEAR_AWAY_DISTANCE, Uuid */ Script.include("/~/system/libraries/Xform.js"); @@ -269,6 +269,7 @@ EquipHotspotBuddy.prototype.update = function(deltaTime, timestamp, controllerDa this.grabEntityProps = null; this.shouldSendStart = false; this.equipedWithSecondary = false; + this.handHasBeenRightsideUp = false; this.parameters = makeDispatcherModuleParameters( 300, @@ -486,15 +487,17 @@ EquipHotspotBuddy.prototype.update = function(deltaTime, timestamp, controllerDa var grabbedProperties = Entities.getEntityProperties(this.targetEntityID); // if an object is "equipped" and has a predefined offset, use it. - var offsets = getAttachPointForHotspotFromSettings(this.grabbedHotspot, this.hand); - if (offsets) { - this.offsetPosition = offsets[0]; - this.offsetRotation = offsets[1]; - } else { - var handJointName = this.hand === RIGHT_HAND ? "RightHand" : "LeftHand"; - if (this.grabbedHotspot.joints[handJointName]) { - this.offsetPosition = this.grabbedHotspot.joints[handJointName][0]; - this.offsetRotation = this.grabbedHotspot.joints[handJointName][1]; + if (this.grabbedHotspot) { + var offsets = getAttachPointForHotspotFromSettings(this.grabbedHotspot, this.hand); + if (offsets) { + this.offsetPosition = offsets[0]; + this.offsetRotation = offsets[1]; + } else { + var handJointName = this.hand === RIGHT_HAND ? "RightHand" : "LeftHand"; + if (this.grabbedHotspot.joints[handJointName]) { + this.offsetPosition = this.grabbedHotspot.joints[handJointName][0]; + this.offsetRotation = this.grabbedHotspot.joints[handJointName][1]; + } } } @@ -549,7 +552,6 @@ EquipHotspotBuddy.prototype.update = function(deltaTime, timestamp, controllerDa // 100 ms seems to be sufficient time to force the check even occur after the object has been initialized. Script.setTimeout(grabEquipCheck, 100); } - }; this.endEquipEntity = function () { @@ -624,7 +626,7 @@ EquipHotspotBuddy.prototype.update = function(deltaTime, timestamp, controllerDa this.grabbedHotspot = potentialEquipHotspot; this.targetEntityID = this.grabbedHotspot.entityID; this.startEquipEntity(controllerData); - this.messageGrabEnity = false; + this.messageGrabEntity = false; this.equipedWithSecondary = this.secondarySmoothedSqueezed(); return makeRunningValues(true, [potentialEquipHotspot.entityID], []); } else { @@ -640,6 +642,7 @@ EquipHotspotBuddy.prototype.update = function(deltaTime, timestamp, controllerDa this.isReady = function (controllerData, deltaTime) { var timestamp = Date.now(); this.updateInputs(controllerData); + this.handHasBeenRightsideUp = false; return this.checkNearbyHotspots(controllerData, deltaTime, timestamp); }; @@ -671,7 +674,14 @@ EquipHotspotBuddy.prototype.update = function(deltaTime, timestamp, controllerDa return makeRunningValues(false, [], []); } - var dropDetected = this.dropGestureProcess(deltaTime); + var handIsUpsideDown = this.dropGestureProcess(deltaTime); + var dropDetected = false; + if (this.handHasBeenRightsideUp) { + dropDetected = handIsUpsideDown; + } + if (!handIsUpsideDown) { + this.handHasBeenRightsideUp = true; + } if (this.triggerSmoothedReleased() || this.secondaryReleased()) { if (this.shouldSendStart) { @@ -692,7 +702,7 @@ EquipHotspotBuddy.prototype.update = function(deltaTime, timestamp, controllerDa } // highlight the grabbed hotspot when the dropGesture is detected. - if (dropDetected) { + if (dropDetected && this.grabbedHotspot) { equipHotspotBuddy.updateHotspot(this.grabbedHotspot, timestamp); equipHotspotBuddy.highlightHotspot(this.grabbedHotspot); } From a596e07464ef8746e54dd4c7d249d129f9214231 Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Wed, 31 Jan 2018 11:05:35 -0800 Subject: [PATCH 15/24] fix left-over run button when scripts are reloaded --- scripts/system/run.js | 1 + 1 file changed, 1 insertion(+) diff --git a/scripts/system/run.js b/scripts/system/run.js index c34271b18d..8d1fb62619 100644 --- a/scripts/system/run.js +++ b/scripts/system/run.js @@ -35,4 +35,5 @@ button.editProperties({isActive: true}); } + Script.scriptEnding.connect(cleanup); }()); From 579d9a864070f81043a1e1b5e2cde0c3dd0c3e68 Mon Sep 17 00:00:00 2001 From: Alexander Ivash Date: Thu, 1 Feb 2018 00:48:03 +0300 Subject: [PATCH 16/24] fix slots invocation --- libraries/ui/src/QmlWindowClass.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/libraries/ui/src/QmlWindowClass.cpp b/libraries/ui/src/QmlWindowClass.cpp index 1209d39dcf..0825d238bc 100644 --- a/libraries/ui/src/QmlWindowClass.cpp +++ b/libraries/ui/src/QmlWindowClass.cpp @@ -227,7 +227,7 @@ bool QmlWindowClass::isVisible() { glm::vec2 QmlWindowClass::getPosition() { if (QThread::currentThread() != thread()) { vec2 result; - BLOCKING_INVOKE_METHOD(this, "getPosition", Q_RETURN_ARG(vec2, result)); + BLOCKING_INVOKE_METHOD(this, "getPosition", Q_RETURN_ARG(glm::vec2, result)); return result; } @@ -241,7 +241,7 @@ glm::vec2 QmlWindowClass::getPosition() { void QmlWindowClass::setPosition(const glm::vec2& position) { if (QThread::currentThread() != thread()) { - QMetaObject::invokeMethod(this, "setPosition", Q_ARG(vec2, position)); + QMetaObject::invokeMethod(this, "setPosition", Q_ARG(const glm::vec2&, position)); return; } @@ -262,7 +262,7 @@ glm::vec2 toGlm(const QSizeF& size) { glm::vec2 QmlWindowClass::getSize() { if (QThread::currentThread() != thread()) { vec2 result; - BLOCKING_INVOKE_METHOD(this, "getSize", Q_RETURN_ARG(vec2, result)); + BLOCKING_INVOKE_METHOD(this, "getSize", Q_RETURN_ARG(glm::vec2, result)); return result; } @@ -275,7 +275,7 @@ glm::vec2 QmlWindowClass::getSize() { void QmlWindowClass::setSize(const glm::vec2& size) { if (QThread::currentThread() != thread()) { - QMetaObject::invokeMethod(this, "setSize", Q_ARG(vec2, size)); + QMetaObject::invokeMethod(this, "setSize", Q_ARG(const glm::vec2&, size)); return; } From 257932cedcd22d9979ccb5399cd18a715d65622f Mon Sep 17 00:00:00 2001 From: Triplelexx Date: Wed, 31 Jan 2018 22:00:30 +0000 Subject: [PATCH 17/24] remove cache buster --- scripts/tutorials/createTetherballStick.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/tutorials/createTetherballStick.js b/scripts/tutorials/createTetherballStick.js index 35f5fb0344..1b5bc36932 100644 --- a/scripts/tutorials/createTetherballStick.js +++ b/scripts/tutorials/createTetherballStick.js @@ -23,7 +23,7 @@ var BALL_DENSITY = 1000; var ACTION_DISTANCE = 0.35; var ACTION_TIMESCALE = 0.035; var MAX_DISTANCE_MULTIPLIER = 4; -var STICK_SCRIPT_URL = Script.resolvePath("./entity_scripts/tetherballStick.js?v=" + Date.now()); +var STICK_SCRIPT_URL = Script.resolvePath("./entity_scripts/tetherballStick.js"); var STICK_MODEL_URL = "http://hifi-content.s3.amazonaws.com/caitlyn/production/raveStick/newRaveStick2.fbx"; var COLLISION_SOUND_URL = "http://public.highfidelity.io/sounds/Footsteps/FootstepW3Left-12db.wav"; From 1ed7d164c45dcb45be34d8a0633372bbe47502dc Mon Sep 17 00:00:00 2001 From: Alexander Ivash Date: Thu, 1 Feb 2018 01:15:03 +0300 Subject: [PATCH 18/24] FB11511 - position of log windows should be persistent between invocations of interface --- interface/src/ui/LogDialog.cpp | 12 ++++++- interface/src/ui/LogDialog.h | 4 +++ scripts/developer/debugging/debugWindow.js | 37 ++++++++++++++++++++-- 3 files changed, 49 insertions(+), 4 deletions(-) diff --git a/interface/src/ui/LogDialog.cpp b/interface/src/ui/LogDialog.cpp index 00dc9be959..108edbfd39 100644 --- a/interface/src/ui/LogDialog.cpp +++ b/interface/src/ui/LogDialog.cpp @@ -38,7 +38,7 @@ const QString FATAL_TEXT = "[FATAL]"; const QString SUPPRESS_TEXT = "[SUPPRESS]"; const QString UNKNOWN_TEXT = "[UNKNOWN]"; -LogDialog::LogDialog(QWidget* parent, AbstractLoggerInterface* logger) : BaseLogDialog(parent) { +LogDialog::LogDialog(QWidget* parent, AbstractLoggerInterface* logger) : BaseLogDialog(parent), _windowGeometry("logDialogGeometry", QRect()) { _logger = logger; setWindowTitle("Log"); @@ -155,6 +155,11 @@ LogDialog::LogDialog(QWidget* parent, AbstractLoggerInterface* logger) : BaseLog _clearFilterButton->show(); connect(_clearFilterButton, &QPushButton::clicked, this, &LogDialog::handleClearFilterButton); handleClearFilterButton(); + + auto windowGeometry = _windowGeometry.get(); + if (windowGeometry.isValid()) { + setGeometry(windowGeometry); + } } void LogDialog::resizeEvent(QResizeEvent* event) { @@ -173,6 +178,11 @@ void LogDialog::resizeEvent(QResizeEvent* event) { ELEMENT_HEIGHT); } +void LogDialog::closeEvent(QCloseEvent* event) { + BaseLogDialog::closeEvent(event); + _windowGeometry.set(geometry()); +} + void LogDialog::handleRevealButton() { _logger->locateLog(); } diff --git a/interface/src/ui/LogDialog.h b/interface/src/ui/LogDialog.h index 5e4e084d5a..3cc7584fe8 100644 --- a/interface/src/ui/LogDialog.h +++ b/interface/src/ui/LogDialog.h @@ -13,6 +13,7 @@ #define hifi_LogDialog_h #include "BaseLogDialog.h" +#include class QCheckBox; class QPushButton; @@ -44,6 +45,8 @@ private slots: protected: void resizeEvent(QResizeEvent* event) override; + void closeEvent(QCloseEvent* event) override; + QString getCurrentLog() override; void printLogFile(); @@ -62,6 +65,7 @@ private: QString _filterSelection; AbstractLoggerInterface* _logger; + Setting::Handle _windowGeometry; }; #endif // hifi_LogDialog_h diff --git a/scripts/developer/debugging/debugWindow.js b/scripts/developer/debugging/debugWindow.js index 068efb351b..9522676007 100644 --- a/scripts/developer/debugging/debugWindow.js +++ b/scripts/developer/debugging/debugWindow.js @@ -22,14 +22,37 @@ if (scripts.length >= 2) { // Set up the qml ui var qml = Script.resolvePath('debugWindow.qml'); +var HMD_DEBUG_WINDOW_GEOMETRY_KEY = 'hmdDebugWindowGeometry'; +var hmdDebugWindowGeometryValue = Settings.getValue(HMD_DEBUG_WINDOW_GEOMETRY_KEY) + +var windowWidth = 400; +var windowHeight = 900; + +var hasPosition = false; +var windowX = 0; +var windowY = 0; + +if (hmdDebugWindowGeometryValue !== '') { + var geometry = JSON.parse(hmdDebugWindowGeometryValue); + + windowWidth = geometry.width + windowHeight = geometry.height + windowX = geometry.x + windowY = geometry.y + hasPosition = true; +} + var window = new OverlayWindow({ title: 'Debug Window', source: qml, - width: 400, height: 900, + width: windowWidth, height: windowHeight, }); -window.setPosition(25, 50); -window.closed.connect(function() { Script.stop(); }); +if (hasPosition) { + window.setPosition(windowX, windowY); +} + +window.closed.connect(function () { Script.stop(); }); var getFormattedDate = function() { var date = new Date(); @@ -65,6 +88,14 @@ ScriptDiscoveryService.clearDebugWindow.connect(function() { }); Script.scriptEnding.connect(function () { + var geometry = JSON.stringify({ + x: window.position.x, + y: window.position.y, + width: window.size.x, + height: window.size.y + }) + + Settings.setValue(HMD_DEBUG_WINDOW_GEOMETRY_KEY, geometry); window.close(); }) From 4cd130dd63d21e3459d4b0e3d50a1309bf02db26 Mon Sep 17 00:00:00 2001 From: David Rowe Date: Thu, 1 Feb 2018 13:39:57 +1300 Subject: [PATCH 19/24] Don't reparent model node with clusters if it's a root node --- libraries/fbx/src/FBXReader.cpp | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/libraries/fbx/src/FBXReader.cpp b/libraries/fbx/src/FBXReader.cpp index 14462e0558..14f12b5d1b 100644 --- a/libraries/fbx/src/FBXReader.cpp +++ b/libraries/fbx/src/FBXReader.cpp @@ -1455,18 +1455,22 @@ FBXGeometry* FBXReader::extractFBXGeometry(const QVariantHash& mapping, const QS QSet remainingModels; for (QHash::const_iterator model = models.constBegin(); model != models.constEnd(); model++) { // models with clusters must be parented to the cluster top - foreach (const QString& deformerID, _connectionChildMap.values(model.key())) { - foreach (const QString& clusterID, _connectionChildMap.values(deformerID)) { - if (!clusters.contains(clusterID)) { - continue; + // Unless the model is a root node. + bool isARootNode = !modelIDs.contains(_connectionParentMap.value(model.key())); + if (!isARootNode) { + foreach(const QString& deformerID, _connectionChildMap.values(model.key())) { + foreach(const QString& clusterID, _connectionChildMap.values(deformerID)) { + if (!clusters.contains(clusterID)) { + continue; + } + QString topID = getTopModelID(_connectionParentMap, models, _connectionChildMap.value(clusterID), url); + _connectionChildMap.remove(_connectionParentMap.take(model.key()), model.key()); + _connectionParentMap.insert(model.key(), topID); + goto outerBreak; } - QString topID = getTopModelID(_connectionParentMap, models, _connectionChildMap.value(clusterID), url); - _connectionChildMap.remove(_connectionParentMap.take(model.key()), model.key()); - _connectionParentMap.insert(model.key(), topID); - goto outerBreak; } + outerBreak: ; } - outerBreak: // make sure the parent is in the child map QString parent = _connectionParentMap.value(model.key()); From a7ec4501e65396d4c7bf2316dd73188cea7a3c7d Mon Sep 17 00:00:00 2001 From: David Rowe Date: Thu, 1 Feb 2018 13:43:14 +1300 Subject: [PATCH 20/24] FBX node IDs aren't alphanumerically ordered per logical structure --- libraries/fbx/src/FBXReader.cpp | 5 ----- 1 file changed, 5 deletions(-) diff --git a/libraries/fbx/src/FBXReader.cpp b/libraries/fbx/src/FBXReader.cpp index 14f12b5d1b..4ed1ca38dc 100644 --- a/libraries/fbx/src/FBXReader.cpp +++ b/libraries/fbx/src/FBXReader.cpp @@ -1481,11 +1481,6 @@ FBXGeometry* FBXReader::extractFBXGeometry(const QVariantHash& mapping, const QS } while (!remainingModels.isEmpty()) { QString first = *remainingModels.constBegin(); - foreach (const QString& id, remainingModels) { - if (id < first) { - first = id; - } - } QString topID = getTopModelID(_connectionParentMap, models, first, url); appendModelIDs(_connectionParentMap.value(topID), _connectionChildMap, models, remainingModels, modelIDs, true); } From b23f98b31116dd3ea0da8f8f8d45dcd3c3b5a873 Mon Sep 17 00:00:00 2001 From: "Anthony J. Thibault" Date: Wed, 31 Jan 2018 17:56:33 -0800 Subject: [PATCH 21/24] Removal of hips offset shifting from AnimInverseKinematics node With the addition of the hips IK target, the hips offset shifting code is no longer necessary. This PR should not effect any behavior, but it removes this unused code from the animation system. --- interface/src/avatar/MyAvatar.cpp | 8 -- interface/src/avatar/MySkeletonModel.cpp | 2 - .../animation/src/AnimInverseKinematics.cpp | 108 ------------------ .../animation/src/AnimInverseKinematics.h | 7 -- libraries/animation/src/Rig.cpp | 12 -- libraries/animation/src/Rig.h | 1 - 6 files changed, 138 deletions(-) diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp index 19a2d39a05..4ab741e32c 100755 --- a/interface/src/avatar/MyAvatar.cpp +++ b/interface/src/avatar/MyAvatar.cpp @@ -3238,8 +3238,6 @@ bool MyAvatar::pinJoint(int index, const glm::vec3& position, const glm::quat& o slamPosition(position); setWorldOrientation(orientation); - _skeletonModel->getRig().setMaxHipsOffsetLength(0.05f); - auto it = std::find(_pinnedJoints.begin(), _pinnedJoints.end(), index); if (it == _pinnedJoints.end()) { _pinnedJoints.push_back(index); @@ -3259,12 +3257,6 @@ bool MyAvatar::clearPinOnJoint(int index) { auto it = std::find(_pinnedJoints.begin(), _pinnedJoints.end(), index); if (it != _pinnedJoints.end()) { _pinnedJoints.erase(it); - - auto hipsIndex = getJointIndex("Hips"); - if (index == hipsIndex) { - _skeletonModel->getRig().setMaxHipsOffsetLength(FLT_MAX); - } - return true; } return false; diff --git a/interface/src/avatar/MySkeletonModel.cpp b/interface/src/avatar/MySkeletonModel.cpp index 9280899a1e..fd57657d33 100644 --- a/interface/src/avatar/MySkeletonModel.cpp +++ b/interface/src/avatar/MySkeletonModel.cpp @@ -43,8 +43,6 @@ static AnimPose computeHipsInSensorFrame(MyAvatar* myAvatar, bool isFlying) { AnimPose result = AnimPose(worldToSensorMat * avatarTransform.getMatrix() * Matrices::Y_180); result.scale() = glm::vec3(1.0f, 1.0f, 1.0f); return result; - } else { - DebugDraw::getInstance().removeMarker("pinnedHips"); } glm::mat4 hipsMat = myAvatar->deriveBodyFromHMDSensor(); diff --git a/libraries/animation/src/AnimInverseKinematics.cpp b/libraries/animation/src/AnimInverseKinematics.cpp index e9f9f8818f..849ea5ee6b 100644 --- a/libraries/animation/src/AnimInverseKinematics.cpp +++ b/libraries/animation/src/AnimInverseKinematics.cpp @@ -880,25 +880,6 @@ const AnimPoseVec& AnimInverseKinematics::evaluate(const AnimVariantMap& animVar return _relativePoses; } -AnimPose AnimInverseKinematics::applyHipsOffset() const { - glm::vec3 hipsOffset = _hipsOffset; - AnimPose relHipsPose = _relativePoses[_hipsIndex]; - float offsetLength = glm::length(hipsOffset); - const float MIN_HIPS_OFFSET_LENGTH = 0.03f; - if (offsetLength > MIN_HIPS_OFFSET_LENGTH) { - float scaleFactor = ((offsetLength - MIN_HIPS_OFFSET_LENGTH) / offsetLength); - glm::vec3 scaledHipsOffset = scaleFactor * hipsOffset; - if (_hipsParentIndex == -1) { - relHipsPose.trans() = _relativePoses[_hipsIndex].trans() + scaledHipsOffset; - } else { - AnimPose absHipsPose = _skeleton->getAbsolutePose(_hipsIndex, _relativePoses); - absHipsPose.trans() += scaledHipsOffset; - relHipsPose = _skeleton->getAbsolutePose(_hipsParentIndex, _relativePoses).inverse() * absHipsPose; - } - } - return relHipsPose; -} - //virtual const AnimPoseVec& AnimInverseKinematics::overlay(const AnimVariantMap& animVars, const AnimContext& context, float dt, Triggers& triggersOut, const AnimPoseVec& underPoses) { // allows solutionSource to be overridden by an animVar @@ -996,27 +977,6 @@ const AnimPoseVec& AnimInverseKinematics::overlay(const AnimVariantMap& animVars _relativePoses[_hipsIndex] = parentAbsPose.inverse() * absPose; _relativePoses[_hipsIndex].scale() = glm::vec3(1.0f); - _hipsOffset = Vectors::ZERO; - - } else if (_hipsIndex >= 0) { - - // if there is no hips target, shift hips according to the _hipsOffset from the previous frame - AnimPose relHipsPose = applyHipsOffset(); - - // determine if we should begin interpolating the hips. - for (size_t i = 0; i < targets.size(); i++) { - if (_prevJointChainInfoVec[i].target.getIndex() == _hipsIndex) { - if (_prevJointChainInfoVec[i].timer > 0.0f) { - // smoothly lerp in hipsOffset - float alpha = (JOINT_CHAIN_INTERP_TIME - _prevJointChainInfoVec[i].timer) / JOINT_CHAIN_INTERP_TIME; - AnimPose prevRelHipsPose(_prevJointChainInfoVec[i].jointInfoVec[0].rot, _prevJointChainInfoVec[i].jointInfoVec[0].trans); - ::blend(1, &prevRelHipsPose, &relHipsPose, alpha, &relHipsPose); - } - break; - } - } - - _relativePoses[_hipsIndex] = relHipsPose; } // if there is an active jointChainInfo for the hips store the post shifted hips into it. @@ -1084,11 +1044,6 @@ const AnimPoseVec& AnimInverseKinematics::overlay(const AnimVariantMap& animVars solve(context, targets, dt, jointChainInfoVec); } - - if (_hipsTargetIndex < 0) { - PROFILE_RANGE_EX(simulation_animation, "ik/measureHipsOffset", 0xffff00ff, 0); - _hipsOffset = computeHipsOffset(targets, underPoses, dt, _hipsOffset); - } } if (context.getEnableDebugDrawIKConstraints()) { @@ -1099,69 +1054,6 @@ const AnimPoseVec& AnimInverseKinematics::overlay(const AnimVariantMap& animVars return _relativePoses; } -glm::vec3 AnimInverseKinematics::computeHipsOffset(const std::vector& targets, const AnimPoseVec& underPoses, float dt, glm::vec3 prevHipsOffset) const { - - // measure new _hipsOffset for next frame - // by looking for discrepancies between where a targeted endEffector is - // and where it wants to be (after IK solutions are done) - glm::vec3 hipsOffset = prevHipsOffset; - glm::vec3 newHipsOffset = Vectors::ZERO; - for (auto& target: targets) { - int targetIndex = target.getIndex(); - if (targetIndex == _headIndex && _headIndex != -1) { - // special handling for headTarget - if (target.getType() == IKTarget::Type::RotationOnly) { - // we want to shift the hips to bring the underPose closer - // to where the head happens to be (overpose) - glm::vec3 under = _skeleton->getAbsolutePose(_headIndex, underPoses).trans(); - glm::vec3 actual = _skeleton->getAbsolutePose(_headIndex, _relativePoses).trans(); - const float HEAD_OFFSET_SLAVE_FACTOR = 0.65f; - newHipsOffset += HEAD_OFFSET_SLAVE_FACTOR * (actual - under); - } else if (target.getType() == IKTarget::Type::HmdHead) { - // we want to shift the hips to bring the head to its designated position - glm::vec3 actual = _skeleton->getAbsolutePose(_headIndex, _relativePoses).trans(); - hipsOffset += target.getTranslation() - actual; - // and ignore all other targets - newHipsOffset = hipsOffset; - break; - } else if (target.getType() == IKTarget::Type::RotationAndPosition) { - glm::vec3 actualPosition = _skeleton->getAbsolutePose(targetIndex, _relativePoses).trans(); - glm::vec3 targetPosition = target.getTranslation(); - newHipsOffset += targetPosition - actualPosition; - - // Add downward pressure on the hips - const float PRESSURE_SCALE_FACTOR = 0.95f; - const float PRESSURE_TRANSLATION_OFFSET = 1.0f; - newHipsOffset *= PRESSURE_SCALE_FACTOR; - newHipsOffset -= PRESSURE_TRANSLATION_OFFSET; - } - } else if (target.getType() == IKTarget::Type::RotationAndPosition) { - glm::vec3 actualPosition = _skeleton->getAbsolutePose(targetIndex, _relativePoses).trans(); - glm::vec3 targetPosition = target.getTranslation(); - newHipsOffset += targetPosition - actualPosition; - } - } - - // smooth transitions by relaxing hipsOffset toward the new value - const float HIPS_OFFSET_SLAVE_TIMESCALE = 0.10f; - float tau = dt < HIPS_OFFSET_SLAVE_TIMESCALE ? dt / HIPS_OFFSET_SLAVE_TIMESCALE : 1.0f; - hipsOffset += (newHipsOffset - hipsOffset) * tau; - - // clamp the hips offset - float hipsOffsetLength = glm::length(hipsOffset); - if (hipsOffsetLength > _maxHipsOffsetLength) { - hipsOffset *= _maxHipsOffsetLength / hipsOffsetLength; - } - - return hipsOffset; -} - -void AnimInverseKinematics::setMaxHipsOffsetLength(float maxLength) { - // manually adjust scale here - const float METERS_TO_CENTIMETERS = 100.0f; - _maxHipsOffsetLength = METERS_TO_CENTIMETERS * maxLength; -} - void AnimInverseKinematics::clearIKJointLimitHistory() { for (auto& pair : _constraints) { pair.second->clearHistory(); diff --git a/libraries/animation/src/AnimInverseKinematics.h b/libraries/animation/src/AnimInverseKinematics.h index bdfbad408d..ee1f9f43ad 100644 --- a/libraries/animation/src/AnimInverseKinematics.h +++ b/libraries/animation/src/AnimInverseKinematics.h @@ -57,8 +57,6 @@ public: void clearIKJointLimitHistory(); - void setMaxHipsOffsetLength(float maxLength); - float getMaxErrorOnLastSolve() { return _maxErrorOnLastSolve; } enum class SolutionSource { @@ -92,7 +90,6 @@ protected: void blendToPoses(const AnimPoseVec& targetPoses, const AnimPoseVec& underPose, float blendFactor); void preconditionRelativePosesToAvoidLimbLock(const AnimContext& context, const std::vector& targets); void setSecondaryTargets(const AnimContext& context); - AnimPose applyHipsOffset() const; // used to pre-compute information about each joint influeced by a spline IK target. struct SplineJointInfo { @@ -111,7 +108,6 @@ protected: void clearConstraints(); void initConstraints(); void initLimitCenterPoses(); - glm::vec3 computeHipsOffset(const std::vector& targets, const AnimPoseVec& underPoses, float dt, glm::vec3 prevHipsOffset) const; // no copies AnimInverseKinematics(const AnimInverseKinematics&) = delete; @@ -150,9 +146,6 @@ protected: mutable std::map> _splineJointInfoMap; - // experimental data for moving hips during IK - glm::vec3 _hipsOffset { Vectors::ZERO }; - float _maxHipsOffsetLength{ FLT_MAX }; int _headIndex { -1 }; int _hipsIndex { -1 }; int _hipsParentIndex { -1 }; diff --git a/libraries/animation/src/Rig.cpp b/libraries/animation/src/Rig.cpp index 309bb59cff..a939db92aa 100644 --- a/libraries/animation/src/Rig.cpp +++ b/libraries/animation/src/Rig.cpp @@ -372,18 +372,6 @@ void Rig::clearIKJointLimitHistory() { } } -void Rig::setMaxHipsOffsetLength(float maxLength) { - _maxHipsOffsetLength = maxLength; - auto ikNode = getAnimInverseKinematicsNode(); - if (ikNode) { - ikNode->setMaxHipsOffsetLength(_maxHipsOffsetLength); - } -} - -float Rig::getMaxHipsOffsetLength() const { - return _maxHipsOffsetLength; -} - float Rig::getIKErrorOnLastSolve() const { float result = 0.0f; diff --git a/libraries/animation/src/Rig.h b/libraries/animation/src/Rig.h index 87277af754..a7db86abf9 100644 --- a/libraries/animation/src/Rig.h +++ b/libraries/animation/src/Rig.h @@ -346,7 +346,6 @@ protected: bool _enabledAnimations { true }; mutable uint32_t _jointNameWarningCount { 0 }; - float _maxHipsOffsetLength { 1.0f }; bool _enableDebugDrawIKTargets { false }; bool _enableDebugDrawIKConstraints { false }; From a8d2be045cfbec6c7cd3b2dd07d4e703465bf627 Mon Sep 17 00:00:00 2001 From: Triplelexx Date: Thu, 1 Feb 2018 07:09:24 +0000 Subject: [PATCH 22/24] fix typos --- libraries/entities/src/EntityScriptServerLogClient.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libraries/entities/src/EntityScriptServerLogClient.cpp b/libraries/entities/src/EntityScriptServerLogClient.cpp index 4405af5b1b..5853c9585e 100644 --- a/libraries/entities/src/EntityScriptServerLogClient.cpp +++ b/libraries/entities/src/EntityScriptServerLogClient.cpp @@ -51,9 +51,9 @@ void EntityScriptServerLogClient::enableToEntityServerScriptLog(bool enable) { if (_subscribed != enable) { if (enable) { - emit receivedNewLogLines("====================== Subscribded to the Entity Script Server's log ======================"); + emit receivedNewLogLines("====================== Subscribed to the Entity Script Server's log ======================"); } else { - emit receivedNewLogLines("==================== Unsubscribded from the Entity Script Server's log ===================="); + emit receivedNewLogLines("==================== Unsubscribed from the Entity Script Server's log ===================="); } } _subscribed = enable; From a1b67afabfbf0f4da47805458445207462aad322 Mon Sep 17 00:00:00 2001 From: "Anthony J. Thibault" Date: Thu, 1 Feb 2018 11:57:50 -0800 Subject: [PATCH 23/24] Fix for rigidly bound mesh not being properly cauterized. For example, sometimes in first person view, you can see the back of your avatar's eyes or the brim of your avatar's hat. --- libraries/render-utils/src/CauterizedModel.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/libraries/render-utils/src/CauterizedModel.cpp b/libraries/render-utils/src/CauterizedModel.cpp index 0b8c636678..efca0c3267 100644 --- a/libraries/render-utils/src/CauterizedModel.cpp +++ b/libraries/render-utils/src/CauterizedModel.cpp @@ -238,9 +238,9 @@ void CauterizedModel::updateRenderItems() { renderTransform = modelTransform; if (clusterTransformsCauterized.size() == 1) { #if defined(SKIN_DQ) - Transform transform(clusterTransforms[0].getRotation(), - clusterTransforms[0].getScale(), - clusterTransforms[0].getTranslation()); + Transform transform(clusterTransformsCauterized[0].getRotation(), + clusterTransformsCauterized[0].getScale(), + clusterTransformsCauterized[0].getTranslation()); renderTransform = modelTransform.worldTransform(Transform(transform)); #else renderTransform = modelTransform.worldTransform(Transform(clusterTransformsCauterized[0])); From f46362906dfe344ab967ffcfa85129e0a004d565 Mon Sep 17 00:00:00 2001 From: David Rowe Date: Fri, 2 Feb 2018 10:02:20 +1300 Subject: [PATCH 24/24] Bump avatar mixer packet version --- libraries/networking/src/udt/PacketHeaders.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/libraries/networking/src/udt/PacketHeaders.h b/libraries/networking/src/udt/PacketHeaders.h index 0f69691bd5..d186ed41c3 100644 --- a/libraries/networking/src/udt/PacketHeaders.h +++ b/libraries/networking/src/udt/PacketHeaders.h @@ -248,7 +248,8 @@ enum class AvatarMixerPacketVersion : PacketVersion { IsReplicatedInAvatarIdentity, AvatarIdentityLookAtSnapping, UpdatedMannequinDefaultAvatar, - AvatarJointDefaultPoseFlags + AvatarJointDefaultPoseFlags, + FBXReaderNodeReparenting }; enum class DomainConnectRequestVersion : PacketVersion {