From 5e6c0870e7d20cfd43a1a78531bd5dd2676d9ee6 Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Tue, 17 Oct 2017 12:36:15 -0700 Subject: [PATCH 01/60] handle camera-relative controller joints for other avatars --- libraries/avatars-renderer/src/avatars-renderer/Avatar.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/libraries/avatars-renderer/src/avatars-renderer/Avatar.cpp b/libraries/avatars-renderer/src/avatars-renderer/Avatar.cpp index 87d4a2d343..f674a2206e 100644 --- a/libraries/avatars-renderer/src/avatars-renderer/Avatar.cpp +++ b/libraries/avatars-renderer/src/avatars-renderer/Avatar.cpp @@ -994,10 +994,12 @@ glm::quat Avatar::getAbsoluteJointRotationInObjectFrame(int index) const { glm::mat4 finalMat = glm::inverse(avatarMatrix) * sensorToWorldMatrix; return glmExtractRotation(finalMat); } + case CAMERA_RELATIVE_CONTROLLER_LEFTHAND_INDEX: case CONTROLLER_LEFTHAND_INDEX: { Transform controllerLeftHandTransform = Transform(getControllerLeftHandMatrix()); return controllerLeftHandTransform.getRotation(); } + case CAMERA_RELATIVE_CONTROLLER_RIGHTHAND_INDEX: case CONTROLLER_RIGHTHAND_INDEX: { Transform controllerRightHandTransform = Transform(getControllerRightHandMatrix()); return controllerRightHandTransform.getRotation(); @@ -1032,10 +1034,12 @@ glm::vec3 Avatar::getAbsoluteJointTranslationInObjectFrame(int index) const { glm::mat4 finalMat = glm::inverse(avatarMatrix) * sensorToWorldMatrix; return extractTranslation(finalMat); } + case CAMERA_RELATIVE_CONTROLLER_LEFTHAND_INDEX: case CONTROLLER_LEFTHAND_INDEX: { Transform controllerLeftHandTransform = Transform(getControllerLeftHandMatrix()); return controllerLeftHandTransform.getTranslation(); } + case CAMERA_RELATIVE_CONTROLLER_RIGHTHAND_INDEX: case CONTROLLER_RIGHTHAND_INDEX: { Transform controllerRightHandTransform = Transform(getControllerRightHandMatrix()); return controllerRightHandTransform.getTranslation(); From f1abb0cd5510bf563f69670a869776377aae2405 Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Tue, 17 Oct 2017 18:59:12 -0700 Subject: [PATCH 02/60] don't send avatar-entity updates for queryCube-changes, because avatar-entities don't use them --- interface/src/avatar/MyAvatar.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp index 5d82405aee..cccc13711d 100755 --- a/interface/src/avatar/MyAvatar.cpp +++ b/interface/src/avatar/MyAvatar.cpp @@ -594,7 +594,9 @@ void MyAvatar::simulate(float deltaTime) { if (success) { moveOperator.addEntityToMoveList(entity, newCube); } - if (packetSender) { + // send an edit packet to update the entity-server about the queryAABox. If it's an + // avatar-entity, don't. + if (packetSender && !entity->getClientOnly()) { EntityItemProperties properties = entity->getProperties(); properties.setQueryAACubeDirty(); properties.setLastEdited(now); From 949da1704606238df551e4c93543db069c1e0e6f Mon Sep 17 00:00:00 2001 From: Zach Fox Date: Wed, 18 Oct 2017 13:51:58 -0700 Subject: [PATCH 03/60] Wear It button for items with category 'Wearables' --- interface/resources/qml/hifi/commerce/checkout/Checkout.qml | 4 +++- .../resources/qml/hifi/commerce/purchases/PurchasedItem.qml | 5 +++-- .../resources/qml/hifi/commerce/purchases/Purchases.qml | 1 + scripts/system/marketplaces/marketplaces.js | 1 + 4 files changed, 8 insertions(+), 3 deletions(-) diff --git a/interface/resources/qml/hifi/commerce/checkout/Checkout.qml b/interface/resources/qml/hifi/commerce/checkout/Checkout.qml index 8d94e284ed..b76deb41fc 100644 --- a/interface/resources/qml/hifi/commerce/checkout/Checkout.qml +++ b/interface/resources/qml/hifi/commerce/checkout/Checkout.qml @@ -40,6 +40,7 @@ Rectangle { property bool shouldBuyWithControlledFailure: false; property bool debugCheckoutSuccess: false; property bool canRezCertifiedItems: Entities.canRezCertified || Entities.canRezTmpCertified; + property bool isWearable; // Style color: hifi.colors.white; Hifi.QmlCommerce { @@ -573,7 +574,7 @@ Rectangle { height: 50; anchors.left: parent.left; anchors.right: parent.right; - text: "Rez It" + text: root.isWearable ? "Wear It" : "Rez It" onClicked: { if (urlHandler.canHandleUrl(root.itemHref)) { urlHandler.handleUrl(root.itemHref); @@ -832,6 +833,7 @@ Rectangle { itemName = message.params.itemName; root.itemPrice = message.params.itemPrice; itemHref = message.params.itemHref; + root.isWearable = message.params.categories.indexOf("Wearables") > -1; setBuyText(); break; default: diff --git a/interface/resources/qml/hifi/commerce/purchases/PurchasedItem.qml b/interface/resources/qml/hifi/commerce/purchases/PurchasedItem.qml index e7e16668fe..fb42865ba4 100644 --- a/interface/resources/qml/hifi/commerce/purchases/PurchasedItem.qml +++ b/interface/resources/qml/hifi/commerce/purchases/PurchasedItem.qml @@ -39,6 +39,7 @@ Item { property int itemEdition; property int numberSold; property int limitedRun; + property bool isWearable; property string originalStatusText; property string originalStatusColor; @@ -342,7 +343,7 @@ Item { anchors.bottom: parent.bottom; anchors.right: parent.right; width: height; - enabled: root.canRezCertifiedItems && root.purchaseStatus !== "invalidated"; + enabled: (root.canRezCertifiedItems || root.isWearable) && root.purchaseStatus !== "invalidated"; onClicked: { if (urlHandler.canHandleUrl(root.itemHref)) { @@ -415,7 +416,7 @@ Item { size: 16; verticalAlignment: Text.AlignVCenter horizontalAlignment: Text.AlignHCenter - text: "Rez It" + text: root.isWearable ? "Wear It" : "Rez It" } } } diff --git a/interface/resources/qml/hifi/commerce/purchases/Purchases.qml b/interface/resources/qml/hifi/commerce/purchases/Purchases.qml index b5697f687d..6b0dc961ea 100644 --- a/interface/resources/qml/hifi/commerce/purchases/Purchases.qml +++ b/interface/resources/qml/hifi/commerce/purchases/Purchases.qml @@ -434,6 +434,7 @@ Rectangle { numberSold: model.number_sold; limitedRun: model.limited_run; displayedItemCount: model.displayedItemCount; + isWearable: model.categories.indexOf("Wearables") > -1; anchors.topMargin: 12; anchors.bottomMargin: 12; diff --git a/scripts/system/marketplaces/marketplaces.js b/scripts/system/marketplaces/marketplaces.js index 6880d10c18..22d9b6025b 100644 --- a/scripts/system/marketplaces/marketplaces.js +++ b/scripts/system/marketplaces/marketplaces.js @@ -74,6 +74,7 @@ itemName: 'Test Flaregun', itemPrice: (debugError ? 10 : 17), itemHref: 'http://mpassets.highfidelity.com/0d90d21c-ce7a-4990-ad18-e9d2cf991027-v1/flaregun.json', + categories: ["Wearables", "Miscellaneous"] }, canRezCertifiedItems: Entities.canRezCertified || Entities.canRezTmpCertified }); From de50eef9c77399d23f4307149df027f80a5b829b Mon Sep 17 00:00:00 2001 From: Zach Fox Date: Tue, 17 Oct 2017 13:18:29 -0700 Subject: [PATCH 04/60] Fix rez certified... --- .../resources/qml/hifi/commerce/checkout/Checkout.qml | 2 +- .../resources/qml/hifi/commerce/purchases/Purchases.qml | 2 +- scripts/system/marketplaces/marketplaces.js | 7 ++----- 3 files changed, 4 insertions(+), 7 deletions(-) diff --git a/interface/resources/qml/hifi/commerce/checkout/Checkout.qml b/interface/resources/qml/hifi/commerce/checkout/Checkout.qml index b76deb41fc..d136caccfe 100644 --- a/interface/resources/qml/hifi/commerce/checkout/Checkout.qml +++ b/interface/resources/qml/hifi/commerce/checkout/Checkout.qml @@ -39,7 +39,7 @@ Rectangle { property bool itemIsJson: true; property bool shouldBuyWithControlledFailure: false; property bool debugCheckoutSuccess: false; - property bool canRezCertifiedItems: Entities.canRezCertified || Entities.canRezTmpCertified; + property bool canRezCertifiedItems: Entities.canRezCertified() || Entities.canRezTmpCertified(); property bool isWearable; // Style color: hifi.colors.white; diff --git a/interface/resources/qml/hifi/commerce/purchases/Purchases.qml b/interface/resources/qml/hifi/commerce/purchases/Purchases.qml index 6b0dc961ea..c98f212c53 100644 --- a/interface/resources/qml/hifi/commerce/purchases/Purchases.qml +++ b/interface/resources/qml/hifi/commerce/purchases/Purchases.qml @@ -32,7 +32,7 @@ Rectangle { property bool securityImageResultReceived: false; property bool purchasesReceived: false; property bool punctuationMode: false; - property bool canRezCertifiedItems: Entities.canRezCertified || Entities.canRezTmpCertified; + property bool canRezCertifiedItems: Entities.canRezCertified() || Entities.canRezTmpCertified(); property bool pendingInventoryReply: true; property bool isShowingMyItems: false; property bool isDebuggingFirstUseTutorial: false; diff --git a/scripts/system/marketplaces/marketplaces.js b/scripts/system/marketplaces/marketplaces.js index 22d9b6025b..5ffc35e6e5 100644 --- a/scripts/system/marketplaces/marketplaces.js +++ b/scripts/system/marketplaces/marketplaces.js @@ -75,8 +75,7 @@ itemPrice: (debugError ? 10 : 17), itemHref: 'http://mpassets.highfidelity.com/0d90d21c-ce7a-4990-ad18-e9d2cf991027-v1/flaregun.json', categories: ["Wearables", "Miscellaneous"] - }, - canRezCertifiedItems: Entities.canRezCertified || Entities.canRezTmpCertified + } }); } } @@ -116,7 +115,6 @@ if (url === MARKETPLACE_PURCHASES_QML_PATH) { tablet.sendToQml({ method: 'updatePurchases', - canRezCertifiedItems: Entities.canRezCertified || Entities.canRezTmpCertified, referrerURL: referrerURL, filterText: filterText }); @@ -204,8 +202,7 @@ tablet.pushOntoStack(MARKETPLACE_CHECKOUT_QML_PATH); tablet.sendToQml({ method: 'updateCheckoutQML', - params: parsedJsonMessage, - canRezCertifiedItems: Entities.canRezCertified || Entities.canRezTmpCertified + params: parsedJsonMessage }); } else if (parsedJsonMessage.type === "REQUEST_SETTING") { sendCommerceSettings(); From 876001146a1fe0d7e15f4f07fbc9f7a3cd52af9f Mon Sep 17 00:00:00 2001 From: Zach Fox Date: Wed, 18 Oct 2017 14:05:47 -0700 Subject: [PATCH 05/60] Get categories from backend instead of site --- interface/resources/qml/hifi/commerce/checkout/Checkout.qml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/interface/resources/qml/hifi/commerce/checkout/Checkout.qml b/interface/resources/qml/hifi/commerce/checkout/Checkout.qml index d136caccfe..b997cc9671 100644 --- a/interface/resources/qml/hifi/commerce/checkout/Checkout.qml +++ b/interface/resources/qml/hifi/commerce/checkout/Checkout.qml @@ -81,6 +81,7 @@ Rectangle { root.activeView = "checkoutFailure"; } else { root.itemHref = result.data.download_url; + root.isWearable = result.data.categories.indexOf("Wearables") > -1; root.activeView = "checkoutSuccess"; } } @@ -833,7 +834,6 @@ Rectangle { itemName = message.params.itemName; root.itemPrice = message.params.itemPrice; itemHref = message.params.itemHref; - root.isWearable = message.params.categories.indexOf("Wearables") > -1; setBuyText(); break; default: From 322bac035ce08f7756ddf7eb12be013045a9ea86 Mon Sep 17 00:00:00 2001 From: Zach Fox Date: Wed, 18 Oct 2017 16:19:54 -0700 Subject: [PATCH 06/60] Don't show 'no permission' text on wearables --- interface/resources/qml/hifi/commerce/checkout/Checkout.qml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/interface/resources/qml/hifi/commerce/checkout/Checkout.qml b/interface/resources/qml/hifi/commerce/checkout/Checkout.qml index b997cc9671..767164d38c 100644 --- a/interface/resources/qml/hifi/commerce/checkout/Checkout.qml +++ b/interface/resources/qml/hifi/commerce/checkout/Checkout.qml @@ -586,7 +586,7 @@ Rectangle { } RalewaySemiBold { id: noPermissionText; - visible: !root.canRezCertifiedItems; + visible: !root.canRezCertifiedItems && !root.isWearable; text: 'You do not have Certified Rez permissions in this domain.' // Text size size: 16; From a02ee5b7d551006cb4b22bdb8238fcc8a2a52c94 Mon Sep 17 00:00:00 2001 From: Daniela Date: Thu, 19 Oct 2017 18:05:51 +0100 Subject: [PATCH 07/60] Grabber Tool Move up, remove billboard on grabbermoveupoverlay --- .../system/libraries/entitySelectionTool.js | 246 +++++------------- 1 file changed, 65 insertions(+), 181 deletions(-) diff --git a/scripts/system/libraries/entitySelectionTool.js b/scripts/system/libraries/entitySelectionTool.js index 9715cc454c..6db9564c77 100644 --- a/scripts/system/libraries/entitySelectionTool.js +++ b/scripts/system/libraries/entitySelectionTool.js @@ -3,7 +3,7 @@ // examples // // Created by Brad hefta-Gaub on 10/1/14. -// Modified by Daniela Fontes @DanielaFifo and Tiago Andrade @TagoWill on 4/7/2017 +// Modified by Daniela Fontes * @DanielaFifo and Tiago Andrade @TagoWill on 4/7/2017 // Copyright 2014 High Fidelity, Inc. // // This script implements a class useful for building tools for editing entities. @@ -71,44 +71,16 @@ SelectionManager = (function() { that.selections = []; var listeners = []; - that.localRotation = Quat.fromPitchYawRollDegrees(0, 0, 0); - that.localPosition = { - x: 0, - y: 0, - z: 0 - }; - that.localDimensions = { - x: 0, - y: 0, - z: 0 - }; - that.localRegistrationPoint = { - x: 0.5, - y: 0.5, - z: 0.5 - }; + that.localRotation = Quat.IDENTITY; + that.localPosition = Vec3.ZERO; + that.localDimensions = Vec3.ZERO; + that.localRegistrationPoint = Vec3.HALF; - that.worldRotation = Quat.fromPitchYawRollDegrees(0, 0, 0); - that.worldPosition = { - x: 0, - y: 0, - z: 0 - }; - that.worldDimensions = { - x: 0, - y: 0, - z: 0 - }; - that.worldRegistrationPoint = { - x: 0.5, - y: 0.5, - z: 0.5 - }; - that.centerPosition = { - x: 0, - y: 0, - z: 0 - }; + that.worldRotation = Quat.IDENTITY; + that.worldPosition = Vec3.ZERO; + that.worldDimensions = Vec3.ZERO; + that.worldRegistrationPoint = Vec3.HALF; + that.centerPosition = Vec3.ZERO; that.saveProperties = function() { that.savedProperties = {}; @@ -231,6 +203,14 @@ SelectionManager = (function() { print("ERROR: entitySelectionTool.update got exception: " + JSON.stringify(e)); } } + + //update overlay to face Avatar + if ((!activeTool) || isActiveTool(grabberMoveUp)) { + Overlays.editOverlay(grabberMoveUp, { + rotation: Quat.lookAt(grabberMoveUpPosition, Camera.position, Quat.getUp(MyAvatar.orientation)) + }); + } + }; return that; @@ -350,11 +330,7 @@ SelectionDisplay = (function() { }; var grabberLineWidth = 0.5; var grabberSolid = true; - var grabberMoveUpPosition = { - x: 0, - y: 0, - z: 0 - }; + var grabberMoveUpPosition = Vec3.ZERO; var lightOverlayColor = { red: 255, @@ -363,11 +339,7 @@ SelectionDisplay = (function() { }; var grabberPropertiesCorner = { - position: { - x: 0, - y: 0, - z: 0 - }, + position: Vec3.ZERO, size: grabberSizeCorner, color: grabberColorCorner, alpha: 1, @@ -380,11 +352,7 @@ SelectionDisplay = (function() { }; var grabberPropertiesEdge = { - position: { - x: 0, - y: 0, - z: 0 - }, + position: Vec3.ZERO, size: grabberSizeEdge, color: grabberColorEdge, alpha: 1, @@ -397,11 +365,7 @@ SelectionDisplay = (function() { }; var grabberPropertiesFace = { - position: { - x: 0, - y: 0, - z: 0 - }, + position: Vec3.ZERO, size: grabberSizeFace, color: grabberColorFace, alpha: 1, @@ -414,11 +378,7 @@ SelectionDisplay = (function() { }; var grabberPropertiesCloner = { - position: { - x: 0, - y: 0, - z: 0 - }, + position: Vec3.ZERO, size: grabberSizeCorner, color: grabberColorCloner, alpha: 1, @@ -436,11 +396,7 @@ SelectionDisplay = (function() { }; var highlightBox = Overlays.addOverlay("cube", { - position: { - x: 0, - y: 0, - z: 0 - }, + position: Vec3.ZERO, size: 1, color: { red: 90, @@ -457,11 +413,7 @@ SelectionDisplay = (function() { }); var selectionBox = Overlays.addOverlay("cube", { - position: { - x: 0, - y: 0, - z: 0 - }, + position: Vec3.ZERO, size: 1, color: { red: 255, @@ -478,11 +430,7 @@ SelectionDisplay = (function() { var selectionBoxes = []; var rotationDegreesDisplay = Overlays.addOverlay("text3d", { - position: { - x: 0, - y: 0, - z: 0 - }, + position: Vec3.ZERO, text: "", color: { red: 0, @@ -513,17 +461,12 @@ SelectionDisplay = (function() { var grabberMoveUp = Overlays.addOverlay("image3d", { url: HIFI_PUBLIC_BUCKET + "images/up-arrow.svg", - position: { - x: 0, - y: 0, - z: 0 - }, + position: Vec3.ZERO, color: handleColor, alpha: handleAlpha, visible: false, size: 0.1, scale: 0.1, - isFacingAvatar: true, drawInFront: true }); @@ -720,16 +663,8 @@ SelectionDisplay = (function() { var xRailOverlay = Overlays.addOverlay("line3d", { visible: false, lineWidth: 1.0, - start: { - x: 0, - y: 0, - z: 0 - }, - end: { - x: 0, - y: 0, - z: 0 - }, + start: Vec3.ZERO, + end: Vec3.ZERO, color: { red: 255, green: 0, @@ -740,16 +675,8 @@ SelectionDisplay = (function() { var yRailOverlay = Overlays.addOverlay("line3d", { visible: false, lineWidth: 1.0, - start: { - x: 0, - y: 0, - z: 0 - }, - end: { - x: 0, - y: 0, - z: 0 - }, + start: Vec3.ZERO, + end: Vec3.ZERO, color: { red: 0, green: 255, @@ -760,16 +687,8 @@ SelectionDisplay = (function() { var zRailOverlay = Overlays.addOverlay("line3d", { visible: false, lineWidth: 1.0, - start: { - x: 0, - y: 0, - z: 0 - }, - end: { - x: 0, - y: 0, - z: 0 - }, + start: Vec3.ZERO, + end: Vec3.ZERO, color: { red: 0, green: 0, @@ -781,16 +700,8 @@ SelectionDisplay = (function() { var rotateZeroOverlay = Overlays.addOverlay("line3d", { visible: false, lineWidth: 2.0, - start: { - x: 0, - y: 0, - z: 0 - }, - end: { - x: 0, - y: 0, - z: 0 - }, + start: Vec3.ZERO, + end: Vec3.ZERO, color: { red: 255, green: 0, @@ -802,16 +713,8 @@ SelectionDisplay = (function() { var rotateCurrentOverlay = Overlays.addOverlay("line3d", { visible: false, lineWidth: 2.0, - start: { - x: 0, - y: 0, - z: 0 - }, - end: { - x: 0, - y: 0, - z: 0 - }, + start: Vec3.ZERO, + end: Vec3.ZERO, color: { red: 0, green: 0, @@ -822,11 +725,7 @@ SelectionDisplay = (function() { var rotateOverlayInner = Overlays.addOverlay("circle3d", { - position: { - x: 0, - y: 0, - z: 0 - }, + position: Vec3.ZERO, size: 1, color: { red: 51, @@ -856,11 +755,7 @@ SelectionDisplay = (function() { }); var rotateOverlayOuter = Overlays.addOverlay("circle3d", { - position: { - x: 0, - y: 0, - z: 0 - }, + position: Vec3.ZERO, size: 1, color: { red: 51, @@ -891,11 +786,7 @@ SelectionDisplay = (function() { }); var rotateOverlayCurrent = Overlays.addOverlay("circle3d", { - position: { - x: 0, - y: 0, - z: 0 - }, + position: Vec3.ZERO, size: 1, color: { red: 224, @@ -922,11 +813,7 @@ SelectionDisplay = (function() { var yawHandle = Overlays.addOverlay("image3d", { url: ROTATE_ARROW_WEST_NORTH_URL, - position: { - x: 0, - y: 0, - z: 0 - }, + position: Vec3.ZERO, color: handleColor, alpha: handleAlpha, visible: false, @@ -939,11 +826,7 @@ SelectionDisplay = (function() { var pitchHandle = Overlays.addOverlay("image3d", { url: ROTATE_ARROW_WEST_NORTH_URL, - position: { - x: 0, - y: 0, - z: 0 - }, + position: Vec3.ZERO, color: handleColor, alpha: handleAlpha, visible: false, @@ -956,11 +839,7 @@ SelectionDisplay = (function() { var rollHandle = Overlays.addOverlay("image3d", { url: ROTATE_ARROW_WEST_NORTH_URL, - position: { - x: 0, - y: 0, - z: 0 - }, + position: Vec3.ZERO, color: handleColor, alpha: handleAlpha, visible: false, @@ -1550,11 +1429,11 @@ SelectionDisplay = (function() { Overlays.editOverlay(rollHandle, { scale: handleSize }); - var pos = Vec3.sum(grabberMoveUpPosition, { - x: 0, - y: Vec3.length(diff) * GRABBER_DISTANCE_TO_SIZE_RATIO * 3, - z: 0 - }); + var upDiff = Vec3.multiply(( + Vec3.length(diff) * GRABBER_DISTANCE_TO_SIZE_RATIO * 3), + Quat.getUp(MyAvatar.orientation) + ); + var pos = Vec3.sum(grabberMoveUpPosition, upDiff); Overlays.editOverlay(grabberMoveUp, { position: pos, scale: handleSize / 1.25 @@ -1636,7 +1515,7 @@ SelectionDisplay = (function() { position = SelectionManager.localPosition; registrationPoint = SelectionManager.localRegistrationPoint; } else { - rotation = Quat.fromPitchYawRollDegrees(0, 0, 0); + rotation = Quat.IDENTITY; dimensions = SelectionManager.worldDimensions; position = SelectionManager.worldPosition; registrationPoint = SelectionManager.worldRegistrationPoint; @@ -2227,13 +2106,15 @@ SelectionDisplay = (function() { }); var grabberMoveUpOffset = 0.1; + var upVec = Quat.getUp(MyAvatar.orientation); grabberMoveUpPosition = { - x: position.x, - y: position.y + worldTop + grabberMoveUpOffset, - z: position.z + x: position.x + (grabberMoveUpOffset + worldTop) * upVec.x , + y: position.y+ (grabberMoveUpOffset + worldTop) * upVec.y, + z: position.z + (grabberMoveUpOffset + worldTop) * upVec.z }; Overlays.editOverlay(grabberMoveUp, { - visible: (!activeTool) || isActiveTool(grabberMoveUp) + visible: (!activeTool) || isActiveTool(grabberMoveUp), + rotation: Quat.lookAt(grabberMoveUpPosition, Camera.position, upVec) }); Overlays.editOverlay(baseOfEntityProjectionOverlay, { @@ -2544,9 +2425,6 @@ SelectionDisplay = (function() { mode: "TRANSLATE_UP_DOWN", onBegin: function(event, pickRay, pickResult) { upDownPickNormal = Quat.getForward(lastCameraOrientation); - // Remove y component so the y-axis lies along the plane we're picking on - this will - // give movements that follow the mouse. - upDownPickNormal.y = 0; lastXYPick = rayPlaneIntersection(pickRay, SelectionManager.worldPosition, upDownPickNormal); SelectionManager.saveProperties(); @@ -2583,11 +2461,17 @@ SelectionDisplay = (function() { var newIntersection = rayPlaneIntersection(pickRay, SelectionManager.worldPosition, upDownPickNormal); var vector = Vec3.subtract(newIntersection, lastXYPick); + + // project vector onto avatar up vector + // we want the avatar referential not the camera. + var avatarUpVector = Quat.getUp(MyAvatar.orientation); + var dotVectorUp = Vec3.dot(vector, avatarUpVector); + vector = Vec3.multiply(dotVectorUp, avatarUpVector); + + vector = grid.snapToGrid(vector); - // we only care about the Y axis - vector.x = 0; - vector.z = 0; + var wantDebug = false; if (wantDebug) { @@ -2692,7 +2576,7 @@ SelectionDisplay = (function() { var onBegin = function(event, pickRay, pickResult) { var properties = Entities.getEntityProperties(SelectionManager.selections[0]); initialProperties = properties; - rotation = (spaceMode === SPACE_LOCAL) ? properties.rotation : Quat.fromPitchYawRollDegrees(0, 0, 0); + rotation = (spaceMode === SPACE_LOCAL) ? properties.rotation : Quat.IDENTITY; if (spaceMode === SPACE_LOCAL) { rotation = SelectionManager.localRotation; From f75e59c0a6f8146f207e0fba48a424e82463652c Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Thu, 12 Oct 2017 11:33:42 -0700 Subject: [PATCH 08/60] keep grabbed and worn entities from spamming entity-server --- libraries/entities/src/EntityItem.cpp | 149 +++++++++++--------- libraries/entities/src/EntityItem.h | 2 + libraries/physics/src/EntityMotionState.cpp | 6 +- libraries/shared/src/SpatiallyNestable.cpp | 14 +- libraries/shared/src/SpatiallyNestable.h | 2 +- 5 files changed, 98 insertions(+), 75 deletions(-) diff --git a/libraries/entities/src/EntityItem.cpp b/libraries/entities/src/EntityItem.cpp index 58b8dd22bf..cdba87ff69 100644 --- a/libraries/entities/src/EntityItem.cpp +++ b/libraries/entities/src/EntityItem.cpp @@ -43,7 +43,7 @@ int EntityItem::_maxActionsDataSize = 800; quint64 EntityItem::_rememberDeletedActionTime = 20 * USECS_PER_SECOND; EntityItem::EntityItem(const EntityItemID& entityItemID) : - SpatiallyNestable(NestableType::Entity, entityItemID) + SpatiallyNestable(NestableType::Entity, entityItemID) { setLocalVelocity(ENTITY_ITEM_DEFAULT_VELOCITY); setLocalAngularVelocity(ENTITY_ITEM_DEFAULT_ANGULAR_VELOCITY); @@ -719,7 +719,7 @@ int EntityItem::readEntityDataFromBuffer(const unsigned char* data, int bytesLef } { // When we own the simulation we don't accept updates to the entity's transform/velocities // we also want to ignore any duplicate packets that have the same "recently updated" values - // as a packet we've already recieved. This is because we want multiple edits of the same + // as a packet we've already recieved. This is because we want multiple edits of the same // information to be idempotent, but if we applied new physics properties we'd resimulation // with small differences in results. @@ -727,7 +727,7 @@ int EntityItem::readEntityDataFromBuffer(const unsigned char* data, int bytesLef // made these lambdas that can access other details about the previous updates to suppress // any duplicates. - // Note: duplicate packets are expected and not wrong. They may be sent for any number of + // Note: duplicate packets are expected and not wrong. They may be sent for any number of // reasons and the contract is that the client handles them in an idempotent manner. auto lastEdited = lastEditedFromBufferAdjusted; bool otherOverwrites = overwriteLocalData && !weOwnSimulation; @@ -1659,7 +1659,7 @@ bool EntityItem::verifyStaticCertificateProperties() { const auto hash = getStaticCertificateHash(); const auto text = reinterpret_cast(hash.constData()); const unsigned int textLength = hash.length(); - + // After DEBUG_CERT ends, we will get/cache this once from the marketplace when needed, and it likely won't be RSA. const char publicKey[] = "-----BEGIN PUBLIC KEY-----\n\ MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBALCoBiDAZOClO26tC5pd7JikBL61WIgp\n\ @@ -2016,9 +2016,7 @@ void EntityItem::computeCollisionGroupAndFinalMask(int16_t& group, int16_t& mask // if this entity is a descendant of MyAvatar, don't collide with MyAvatar. This avoids the // "bootstrapping" problem where you can shoot yourself across the room by grabbing something // and holding it against your own avatar. - QUuid ancestorID = findAncestorOfType(NestableType::Avatar); - if (!ancestorID.isNull() && - (ancestorID == Physics::getSessionUUID() || ancestorID == AVATAR_SELF_ID)) { + if (isChildOfMyAvatar()) { iAmHoldingThis = true; } // also, don't bootstrap our own avatar with a hold action @@ -2425,6 +2423,7 @@ QVariantMap EntityItem::getActionArguments(const QUuid& actionID) const { } bool EntityItem::shouldSuppressLocationEdits() const { + // if any of the actions indicate they'd like suppression, suppress QHash::const_iterator i = _objectActions.begin(); while (i != _objectActions.end()) { if (i.value()->shouldSuppressLocationEdits()) { @@ -2433,6 +2432,11 @@ bool EntityItem::shouldSuppressLocationEdits() const { i++; } + // if any of the ancestors are MyAvatar, suppress + if (isChildOfMyAvatar()) { + return true; + } + return false; } @@ -2495,16 +2499,16 @@ void EntityItem::globalizeProperties(EntityItemProperties& properties, const QSt bool EntityItem::matchesJSONFilters(const QJsonObject& jsonFilters) const { - + // The intention for the query JSON filter and this method is to be flexible to handle a variety of filters for // ALL entity properties. Some work will need to be done to the property system so that it can be more flexible // (to grab the value and default value of a property given the string representation of that property, for example) - + // currently the only property filter we handle is '+' for serverScripts // which means that we only handle a filtered query asking for entities where the serverScripts property is non-default - + static const QString SERVER_SCRIPTS_PROPERTY = "serverScripts"; - + foreach(const auto& property, jsonFilters.keys()) { if (property == SERVER_SCRIPTS_PROPERTY && jsonFilters[property] == EntityQueryFilterSymbol::NonDefault) { // check if this entity has a non-default value for serverScripts @@ -2515,7 +2519,7 @@ bool EntityItem::matchesJSONFilters(const QJsonObject& jsonFilters) const { } } } - + // the json filter syntax did not match what we expected, return a match return true; } @@ -2528,7 +2532,7 @@ quint64 EntityItem::getLastSimulated() const { return result; } -void EntityItem::setLastSimulated(quint64 now) { +void EntityItem::setLastSimulated(quint64 now) { withWriteLock([&] { _lastSimulated = now; }); @@ -2549,7 +2553,7 @@ void EntityItem::setLastEdited(quint64 lastEdited) { }); } -quint64 EntityItem::getLastBroadcast() const { +quint64 EntityItem::getLastBroadcast() const { quint64 result; withReadLock([&] { result = _lastBroadcast; @@ -2557,19 +2561,19 @@ quint64 EntityItem::getLastBroadcast() const { return result; } -void EntityItem::setLastBroadcast(quint64 lastBroadcast) { +void EntityItem::setLastBroadcast(quint64 lastBroadcast) { withWriteLock([&] { _lastBroadcast = lastBroadcast; }); } -void EntityItem::markAsChangedOnServer() { +void EntityItem::markAsChangedOnServer() { withWriteLock([&] { _changedOnServer = usecTimestampNow(); }); } -quint64 EntityItem::getLastChangedOnServer() const { +quint64 EntityItem::getLastChangedOnServer() const { quint64 result; withReadLock([&] { result = _changedOnServer; @@ -2577,13 +2581,13 @@ quint64 EntityItem::getLastChangedOnServer() const { return result; } -void EntityItem::update(const quint64& now) { +void EntityItem::update(const quint64& now) { withWriteLock([&] { - _lastUpdated = now; + _lastUpdated = now; }); } -quint64 EntityItem::getLastUpdated() const { +quint64 EntityItem::getLastUpdated() const { quint64 result; withReadLock([&] { result = _lastUpdated; @@ -2591,10 +2595,10 @@ quint64 EntityItem::getLastUpdated() const { return result; } -void EntityItem::requiresRecalcBoxes() { +void EntityItem::requiresRecalcBoxes() { withWriteLock([&] { - _recalcAABox = true; - _recalcMinAACube = true; + _recalcAABox = true; + _recalcMinAACube = true; _recalcMaxAACube = true; }); } @@ -2607,7 +2611,7 @@ QString EntityItem::getHref() const { return result; } -QString EntityItem::getDescription() const { +QString EntityItem::getDescription() const { QString result; withReadLock([&] { result = _description; @@ -2629,54 +2633,54 @@ float EntityItem::getLocalRenderAlpha() const { return result; } -void EntityItem::setLocalRenderAlpha(float localRenderAlpha) { +void EntityItem::setLocalRenderAlpha(float localRenderAlpha) { withWriteLock([&] { _localRenderAlpha = localRenderAlpha; }); } -glm::vec3 EntityItem::getGravity() const { +glm::vec3 EntityItem::getGravity() const { glm::vec3 result; withReadLock([&] { result = _gravity; }); return result; -} +} -void EntityItem::setGravity(const glm::vec3& value) { +void EntityItem::setGravity(const glm::vec3& value) { withWriteLock([&] { _gravity = value; }); } -glm::vec3 EntityItem::getAcceleration() const { +glm::vec3 EntityItem::getAcceleration() const { glm::vec3 result; withReadLock([&] { result = _acceleration; }); return result; -} +} -void EntityItem::setAcceleration(const glm::vec3& value) { +void EntityItem::setAcceleration(const glm::vec3& value) { withWriteLock([&] { _acceleration = value; }); } -float EntityItem::getDamping() const { +float EntityItem::getDamping() const { float result; withReadLock([&] { result = _damping; }); return result; } -void EntityItem::setDamping(float value) { +void EntityItem::setDamping(float value) { withWriteLock([&] { _damping = value; }); } -float EntityItem::getRestitution() const { +float EntityItem::getRestitution() const { float result; withReadLock([&] { result = _restitution; @@ -2684,7 +2688,7 @@ float EntityItem::getRestitution() const { return result; } -float EntityItem::getFriction() const { +float EntityItem::getFriction() const { float result; withReadLock([&] { result = _friction; @@ -2693,35 +2697,35 @@ float EntityItem::getFriction() const { } // lifetime related properties. -float EntityItem::getLifetime() const { +float EntityItem::getLifetime() const { float result; withReadLock([&] { result = _lifetime; }); return result; -} +} -void EntityItem::setLifetime(float value) { +void EntityItem::setLifetime(float value) { withWriteLock([&] { _lifetime = value; }); } -quint64 EntityItem::getCreated() const { +quint64 EntityItem::getCreated() const { quint64 result; withReadLock([&] { result = _created; }); return result; -} +} -void EntityItem::setCreated(quint64 value) { +void EntityItem::setCreated(quint64 value) { withWriteLock([&] { _created = value; }); } -QString EntityItem::getScript() const { +QString EntityItem::getScript() const { QString result; withReadLock([&] { result = _script; @@ -2729,13 +2733,13 @@ QString EntityItem::getScript() const { return result; } -void EntityItem::setScript(const QString& value) { +void EntityItem::setScript(const QString& value) { withWriteLock([&] { _script = value; }); } -quint64 EntityItem::getScriptTimestamp() const { +quint64 EntityItem::getScriptTimestamp() const { quint64 result; withReadLock([&] { result = _scriptTimestamp; @@ -2743,13 +2747,13 @@ quint64 EntityItem::getScriptTimestamp() const { return result; } -void EntityItem::setScriptTimestamp(const quint64 value) { +void EntityItem::setScriptTimestamp(const quint64 value) { withWriteLock([&] { _scriptTimestamp = value; }); } -QString EntityItem::getServerScripts() const { +QString EntityItem::getServerScripts() const { QString result; withReadLock([&] { result = _serverScripts; @@ -2759,12 +2763,12 @@ QString EntityItem::getServerScripts() const { void EntityItem::setServerScripts(const QString& serverScripts) { withWriteLock([&] { - _serverScripts = serverScripts; + _serverScripts = serverScripts; _serverScriptsChangedTimestamp = usecTimestampNow(); }); } -QString EntityItem::getCollisionSoundURL() const { +QString EntityItem::getCollisionSoundURL() const { QString result; withReadLock([&] { result = _collisionSoundURL; @@ -2772,22 +2776,22 @@ QString EntityItem::getCollisionSoundURL() const { return result; } -glm::vec3 EntityItem::getRegistrationPoint() const { +glm::vec3 EntityItem::getRegistrationPoint() const { glm::vec3 result; withReadLock([&] { result = _registrationPoint; }); return result; -} +} void EntityItem::setRegistrationPoint(const glm::vec3& value) { withWriteLock([&] { - _registrationPoint = glm::clamp(value, 0.0f, 1.0f); + _registrationPoint = glm::clamp(value, 0.0f, 1.0f); }); dimensionsChanged(); // Registration Point affects the bounding box } -float EntityItem::getAngularDamping() const { +float EntityItem::getAngularDamping() const { float result; withReadLock([&] { result = _angularDamping; @@ -2795,13 +2799,13 @@ float EntityItem::getAngularDamping() const { return result; } -void EntityItem::setAngularDamping(float value) { +void EntityItem::setAngularDamping(float value) { withWriteLock([&] { _angularDamping = value; }); } -QString EntityItem::getName() const { +QString EntityItem::getName() const { QString result; withReadLock([&] { result = _name; @@ -2809,13 +2813,13 @@ QString EntityItem::getName() const { return result; } -void EntityItem::setName(const QString& value) { +void EntityItem::setName(const QString& value) { withWriteLock([&] { _name = value; }); } -QString EntityItem::getDebugName() { +QString EntityItem::getDebugName() { QString result = getName(); if (result.isEmpty()) { result = getID().toString(); @@ -2823,7 +2827,7 @@ QString EntityItem::getDebugName() { return result; } -bool EntityItem::getVisible() const { +bool EntityItem::getVisible() const { bool result; withReadLock([&] { result = _visible; @@ -2831,13 +2835,18 @@ bool EntityItem::getVisible() const { return result; } -void EntityItem::setVisible(bool value) { +void EntityItem::setVisible(bool value) { withWriteLock([&] { _visible = value; }); } -bool EntityItem::getCollisionless() const { +bool EntityItem::isChildOfMyAvatar() const { + QUuid ancestorID = findAncestorOfType(NestableType::Avatar); + return !ancestorID.isNull() && (ancestorID == Physics::getSessionUUID() || ancestorID == AVATAR_SELF_ID); +} + +bool EntityItem::getCollisionless() const { bool result; withReadLock([&] { result = _collisionless; @@ -2845,13 +2854,13 @@ bool EntityItem::getCollisionless() const { return result; } -void EntityItem::setCollisionless(bool value) { +void EntityItem::setCollisionless(bool value) { withWriteLock([&] { _collisionless = value; }); } -uint8_t EntityItem::getCollisionMask() const { +uint8_t EntityItem::getCollisionMask() const { uint8_t result; withReadLock([&] { result = _collisionMask; @@ -2859,13 +2868,13 @@ uint8_t EntityItem::getCollisionMask() const { return result; } -void EntityItem::setCollisionMask(uint8_t value) { +void EntityItem::setCollisionMask(uint8_t value) { withWriteLock([&] { _collisionMask = value; }); } -bool EntityItem::getDynamic() const { +bool EntityItem::getDynamic() const { if (SHAPE_TYPE_STATIC_MESH == getShapeType()) { return false; } @@ -2876,13 +2885,13 @@ bool EntityItem::getDynamic() const { return result; } -void EntityItem::setDynamic(bool value) { +void EntityItem::setDynamic(bool value) { withWriteLock([&] { _dynamic = value; }); } -bool EntityItem::getLocked() const { +bool EntityItem::getLocked() const { bool result; withReadLock([&] { result = _locked; @@ -2890,7 +2899,7 @@ bool EntityItem::getLocked() const { return result; } -void EntityItem::setLocked(bool value) { +void EntityItem::setLocked(bool value) { withWriteLock([&] { _locked = value; }); @@ -2913,7 +2922,7 @@ void EntityItem::updateLocked(bool value) { } } -QString EntityItem::getUserData() const { +QString EntityItem::getUserData() const { QString result; withReadLock([&] { result = _userData; @@ -2921,7 +2930,7 @@ QString EntityItem::getUserData() const { return result; } -void EntityItem::setUserData(const QString& value) { +void EntityItem::setUserData(const QString& value) { withWriteLock([&] { _userData = value; }); @@ -2955,7 +2964,7 @@ DEFINE_PROPERTY_ACCESSOR(quint32, EditionNumber, editionNumber) DEFINE_PROPERTY_ACCESSOR(quint32, EntityInstanceNumber, entityInstanceNumber) DEFINE_PROPERTY_ACCESSOR(QString, CertificateID, certificateID) -uint32_t EntityItem::getDirtyFlags() const { +uint32_t EntityItem::getDirtyFlags() const { uint32_t result; withReadLock([&] { result = _dirtyFlags; @@ -2970,7 +2979,7 @@ void EntityItem::markDirtyFlags(uint32_t mask) { }); } -void EntityItem::clearDirtyFlags(uint32_t mask) { +void EntityItem::clearDirtyFlags(uint32_t mask) { withWriteLock([&] { _dirtyFlags &= ~mask; }); diff --git a/libraries/entities/src/EntityItem.h b/libraries/entities/src/EntityItem.h index c26f1694a9..d1f34217fa 100644 --- a/libraries/entities/src/EntityItem.h +++ b/libraries/entities/src/EntityItem.h @@ -273,6 +273,8 @@ public: inline bool isVisible() const { return getVisible(); } inline bool isInvisible() const { return !getVisible(); } + bool isChildOfMyAvatar() const; + bool getCollisionless() const; void setCollisionless(bool value); diff --git a/libraries/physics/src/EntityMotionState.cpp b/libraries/physics/src/EntityMotionState.cpp index 7c84017758..df46f7ada7 100644 --- a/libraries/physics/src/EntityMotionState.cpp +++ b/libraries/physics/src/EntityMotionState.cpp @@ -491,6 +491,10 @@ bool EntityMotionState::shouldSendUpdate(uint32_t simulationStep) { return true; } + if (_entity->shouldSuppressLocationEdits()) { + return false; + } + if (!isLocallyOwned()) { // we don't own the simulation @@ -577,7 +581,7 @@ void EntityMotionState::sendUpdate(OctreeEditPacketSender* packetSender, uint32_ } if (properties.transformChanged()) { - if (_entity->checkAndMaybeUpdateQueryAACube()) { + if (_entity->checkAndMaybeUpdateQueryAACube(true)) { // due to parenting, the server may not know where something is in world-space, so include the bounding cube. properties.setQueryAACube(_entity->getQueryAACube()); } diff --git a/libraries/shared/src/SpatiallyNestable.cpp b/libraries/shared/src/SpatiallyNestable.cpp index 8c43632456..e76e3dfe27 100644 --- a/libraries/shared/src/SpatiallyNestable.cpp +++ b/libraries/shared/src/SpatiallyNestable.cpp @@ -963,19 +963,21 @@ AACube SpatiallyNestable::getMaximumAACube(bool& success) const { const float PARENTED_EXPANSION_FACTOR = 3.0f; -bool SpatiallyNestable::checkAndMaybeUpdateQueryAACube() { +bool SpatiallyNestable::checkAndMaybeUpdateQueryAACube(bool forcePuffed) { + bool updated = false; bool success = false; AACube maxAACube = getMaximumAACube(success); if (success) { // maybe update _queryAACube if (!_queryAACubeSet || (_parentID.isNull() && _children.size() == 0) || !_queryAACube.contains(maxAACube)) { - if (_parentJointIndex != INVALID_JOINT_INDEX || _children.size() > 0 ) { + if (forcePuffed || _parentJointIndex != INVALID_JOINT_INDEX || _children.size() > 0 ) { // make an expanded AACube centered on the object float scale = PARENTED_EXPANSION_FACTOR * maxAACube.getScale(); _queryAACube = AACube(maxAACube.calcCenter() - glm::vec3(0.5f * scale), scale); } else { _queryAACube = maxAACube; } + updated = true; forEachDescendant([&](const SpatiallyNestablePointer& descendant) { bool childSuccess; @@ -991,7 +993,7 @@ bool SpatiallyNestable::checkAndMaybeUpdateQueryAACube() { _queryAACubeSet = true; } } - return success; + return updated; } void SpatiallyNestable::setQueryAACube(const AACube& queryAACube) { @@ -1008,6 +1010,12 @@ bool SpatiallyNestable::queryAACubeNeedsUpdate() const { return true; } + bool success; + AACube maxAACube = getMaximumAACube(success); + if (success && !_queryAACube.contains(maxAACube)) { + return true; + } + // make sure children are still in their boxes, also. bool childNeedsUpdate = false; forEachDescendantTest([&](const SpatiallyNestablePointer& descendant) { diff --git a/libraries/shared/src/SpatiallyNestable.h b/libraries/shared/src/SpatiallyNestable.h index b6be4dc056..9be6dc14ef 100644 --- a/libraries/shared/src/SpatiallyNestable.h +++ b/libraries/shared/src/SpatiallyNestable.h @@ -106,7 +106,7 @@ public: virtual glm::vec3 getParentAngularVelocity(bool& success) const; virtual AACube getMaximumAACube(bool& success) const; - bool checkAndMaybeUpdateQueryAACube(); + bool checkAndMaybeUpdateQueryAACube(bool forcePuffed = false); void updateQueryAACube(); virtual void setQueryAACube(const AACube& queryAACube); From ae70f091c3b681c215a7dfb36e9d414123badb76 Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Thu, 12 Oct 2017 14:04:50 -0700 Subject: [PATCH 09/60] don't accept updates to queryAACube if this interface is simulation owner --- libraries/entities/src/EntityItem.cpp | 36 ++++++++++++++++++++------- libraries/entities/src/EntityItem.h | 3 +++ 2 files changed, 30 insertions(+), 9 deletions(-) diff --git a/libraries/entities/src/EntityItem.cpp b/libraries/entities/src/EntityItem.cpp index cdba87ff69..9e48876cfb 100644 --- a/libraries/entities/src/EntityItem.cpp +++ b/libraries/entities/src/EntityItem.cpp @@ -717,6 +717,14 @@ int EntityItem::readEntityDataFromBuffer(const unsigned char* data, int bytesLef weOwnSimulation = _simulationOwner.matchesValidID(myNodeID); } } + + auto lastEdited = lastEditedFromBufferAdjusted; + bool otherOverwrites = overwriteLocalData && !weOwnSimulation; + auto shouldUpdate = [lastEdited, otherOverwrites, filterRejection](quint64 updatedTimestamp, bool valueChanged) { + bool simulationChanged = lastEdited > updatedTimestamp; + return otherOverwrites && simulationChanged && (valueChanged || filterRejection); + }; + { // When we own the simulation we don't accept updates to the entity's transform/velocities // we also want to ignore any duplicate packets that have the same "recently updated" values // as a packet we've already recieved. This is because we want multiple edits of the same @@ -729,12 +737,6 @@ int EntityItem::readEntityDataFromBuffer(const unsigned char* data, int bytesLef // Note: duplicate packets are expected and not wrong. They may be sent for any number of // reasons and the contract is that the client handles them in an idempotent manner. - auto lastEdited = lastEditedFromBufferAdjusted; - bool otherOverwrites = overwriteLocalData && !weOwnSimulation; - auto shouldUpdate = [lastEdited, otherOverwrites, filterRejection](quint64 updatedTimestamp, bool valueChanged) { - bool simulationChanged = lastEdited > updatedTimestamp; - return otherOverwrites && simulationChanged && (valueChanged || filterRejection); - }; auto customUpdatePositionFromNetwork = [this, shouldUpdate, lastEdited](glm::vec3 value){ if (shouldUpdate(_lastUpdatedPositionTimestamp, value != _lastUpdatedPositionValue)) { updatePositionFromNetwork(value); @@ -780,8 +782,6 @@ int EntityItem::readEntityDataFromBuffer(const unsigned char* data, int bytesLef READ_ENTITY_PROPERTY(PROP_VELOCITY, glm::vec3, customUpdateVelocityFromNetwork); READ_ENTITY_PROPERTY(PROP_ANGULAR_VELOCITY, glm::vec3, customUpdateAngularVelocityFromNetwork); READ_ENTITY_PROPERTY(PROP_ACCELERATION, glm::vec3, customSetAcceleration); - - } READ_ENTITY_PROPERTY(PROP_DIMENSIONS, glm::vec3, updateDimensions); @@ -846,7 +846,18 @@ int EntityItem::readEntityDataFromBuffer(const unsigned char* data, int bytesLef overwriteLocalData = oldOverwrite; } - READ_ENTITY_PROPERTY(PROP_QUERY_AA_CUBE, AACube, setQueryAACube); + + { + auto customUpdateQueryAACubeFromNetwork = [this, shouldUpdate, lastEdited](AACube value){ + if (shouldUpdate(_lastUpdatedQueryAACubeTimestamp, value != _lastUpdatedQueryAACubeValue)) { + updateQueryAACubeFromNetwork(value); + _lastUpdatedQueryAACubeTimestamp = lastEdited; + _lastUpdatedQueryAACubeValue = value; + } + }; + READ_ENTITY_PROPERTY(PROP_QUERY_AA_CUBE, AACube, customUpdateQueryAACubeFromNetwork); + } + READ_ENTITY_PROPERTY(PROP_LAST_EDITED_BY, QUuid, setLastEditedBy); bytesRead += readEntitySubclassDataFromBuffer(dataAt, (bytesLeftToRead - bytesRead), args, @@ -1846,6 +1857,13 @@ void EntityItem::updateVelocityFromNetwork(const glm::vec3& value) { updateVelocity(value); } +void EntityItem::updateQueryAACubeFromNetwork(const AACube& value) { + if (shouldSuppressLocationEdits()) { + return; + } + setQueryAACube(value); +} + void EntityItem::updateDamping(float value) { auto clampedDamping = glm::clamp(value, 0.0f, 1.0f); if (_damping != clampedDamping) { diff --git a/libraries/entities/src/EntityItem.h b/libraries/entities/src/EntityItem.h index d1f34217fa..01a4f67b2c 100644 --- a/libraries/entities/src/EntityItem.h +++ b/libraries/entities/src/EntityItem.h @@ -364,6 +364,7 @@ public: void updateMass(float value); void updateVelocity(const glm::vec3& value); void updateVelocityFromNetwork(const glm::vec3& value); + void updateQueryAACubeFromNetwork(const AACube& value); void updateDamping(float value); void updateRestitution(float value); void updateFriction(float value); @@ -631,12 +632,14 @@ protected: glm::vec3 _lastUpdatedVelocityValue; glm::vec3 _lastUpdatedAngularVelocityValue; glm::vec3 _lastUpdatedAccelerationValue; + AACube _lastUpdatedQueryAACubeValue; quint64 _lastUpdatedPositionTimestamp { 0 }; quint64 _lastUpdatedRotationTimestamp { 0 }; quint64 _lastUpdatedVelocityTimestamp { 0 }; quint64 _lastUpdatedAngularVelocityTimestamp { 0 }; quint64 _lastUpdatedAccelerationTimestamp { 0 }; + quint64 _lastUpdatedQueryAACubeTimestamp { 0 }; }; From cf960dc44b925a4370fac17ee98b101d11fc1112 Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Fri, 13 Oct 2017 09:29:50 -0700 Subject: [PATCH 10/60] not a parent or child doesn't mean always recompute queryAACube --- libraries/shared/src/SpatiallyNestable.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/shared/src/SpatiallyNestable.cpp b/libraries/shared/src/SpatiallyNestable.cpp index e76e3dfe27..58456f7e9a 100644 --- a/libraries/shared/src/SpatiallyNestable.cpp +++ b/libraries/shared/src/SpatiallyNestable.cpp @@ -969,7 +969,7 @@ bool SpatiallyNestable::checkAndMaybeUpdateQueryAACube(bool forcePuffed) { AACube maxAACube = getMaximumAACube(success); if (success) { // maybe update _queryAACube - if (!_queryAACubeSet || (_parentID.isNull() && _children.size() == 0) || !_queryAACube.contains(maxAACube)) { + if (!_queryAACubeSet || !_queryAACube.contains(maxAACube)) { if (forcePuffed || _parentJointIndex != INVALID_JOINT_INDEX || _children.size() > 0 ) { // make an expanded AACube centered on the object float scale = PARENTED_EXPANSION_FACTOR * maxAACube.getScale(); From f2cb5d4aff1c36847f483c8ade1ce65974d1749c Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Fri, 13 Oct 2017 11:26:58 -0700 Subject: [PATCH 11/60] clean-up concept of puffed queryAACube --- interface/src/avatar/MyAvatar.cpp | 2 +- .../RenderableParticleEffectEntityItem.cpp | 4 +- libraries/entities/src/EntityItem.cpp | 6 +- libraries/entities/src/EntityItem.h | 1 + .../entities/src/EntityScriptingInterface.cpp | 4 +- libraries/entities/src/EntityTree.cpp | 2 +- .../entities/src/SimpleEntitySimulation.cpp | 2 +- libraries/physics/src/EntityMotionState.cpp | 4 +- libraries/shared/src/SpatiallyNestable.cpp | 85 +++++++------------ libraries/shared/src/SpatiallyNestable.h | 5 +- 10 files changed, 50 insertions(+), 65 deletions(-) diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp index cccc13711d..3189ad3c77 100755 --- a/interface/src/avatar/MyAvatar.cpp +++ b/interface/src/avatar/MyAvatar.cpp @@ -587,7 +587,7 @@ void MyAvatar::simulate(float deltaTime) { MovingEntitiesOperator moveOperator; forEachDescendant([&](SpatiallyNestablePointer object) { // if the queryBox has changed, tell the entity-server - if (object->getNestableType() == NestableType::Entity && object->checkAndMaybeUpdateQueryAACube()) { + if (object->getNestableType() == NestableType::Entity && object->updateQueryAACube()) { EntityItemPointer entity = std::static_pointer_cast(object); bool success; AACube newCube = entity->getQueryAACube(success); diff --git a/libraries/entities-renderer/src/RenderableParticleEffectEntityItem.cpp b/libraries/entities-renderer/src/RenderableParticleEffectEntityItem.cpp index 3328076911..047217b6aa 100644 --- a/libraries/entities-renderer/src/RenderableParticleEffectEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableParticleEffectEntityItem.cpp @@ -69,8 +69,8 @@ ParticleEffectEntityRenderer::ParticleEffectEntityRenderer(const EntityItemPoint } bool ParticleEffectEntityRenderer::needsRenderUpdateFromTypedEntity(const TypedEntityPointer& entity) const { - entity->checkAndMaybeUpdateQueryAACube(); - + entity->updateQueryAACube(); + if (_emitting != entity->getIsEmitting()) { return true; } diff --git a/libraries/entities/src/EntityItem.cpp b/libraries/entities/src/EntityItem.cpp index 9e48876cfb..421efac687 100644 --- a/libraries/entities/src/EntityItem.cpp +++ b/libraries/entities/src/EntityItem.cpp @@ -1392,8 +1392,7 @@ bool EntityItem::setProperties(const EntityItemProperties& properties) { SET_ENTITY_PROPERTY_FROM_PROPERTIES(lastEditedBy, setLastEditedBy); - AACube saveQueryAACube = _queryAACube; - if (checkAndMaybeUpdateQueryAACube() && saveQueryAACube != _queryAACube) { + if (updateQueryAACube()) { somethingChanged = true; } @@ -1557,6 +1556,9 @@ AACube EntityItem::getQueryAACube(bool& success) const { return result; } +bool EntityItem::shouldPuffQueryAACube() const { + return hasActions() || isChildOfMyAvatar(); +} // NOTE: This should only be used in cases of old bitstreams which only contain radius data // 0,0,0 --> maxDimension,maxDimension,maxDimension diff --git a/libraries/entities/src/EntityItem.h b/libraries/entities/src/EntityItem.h index 01a4f67b2c..764ff34f99 100644 --- a/libraries/entities/src/EntityItem.h +++ b/libraries/entities/src/EntityItem.h @@ -240,6 +240,7 @@ public: using SpatiallyNestable::getQueryAACube; virtual AACube getQueryAACube(bool& success) const override; + virtual bool shouldPuffQueryAACube() const override; QString getScript() const; void setScript(const QString& value); diff --git a/libraries/entities/src/EntityScriptingInterface.cpp b/libraries/entities/src/EntityScriptingInterface.cpp index f5117dddc0..66bb24825f 100644 --- a/libraries/entities/src/EntityScriptingInterface.cpp +++ b/libraries/entities/src/EntityScriptingInterface.cpp @@ -457,7 +457,7 @@ QUuid EntityScriptingInterface::editEntity(QUuid id, const EntityItemProperties& // if they've changed. entity->forEachDescendant([&](SpatiallyNestablePointer descendant) { if (descendant->getNestableType() == NestableType::Entity) { - if (descendant->checkAndMaybeUpdateQueryAACube()) { + if (descendant->updateQueryAACube()) { EntityItemPointer entityDescendant = std::static_pointer_cast(descendant); EntityItemProperties newQueryCubeProperties; newQueryCubeProperties.setQueryAACube(descendant->getQueryAACube()); @@ -1792,4 +1792,4 @@ QString EntityScriptingInterface::computeCertificateID(const QUuid& entityID) { } return result; } -#endif \ No newline at end of file +#endif diff --git a/libraries/entities/src/EntityTree.cpp b/libraries/entities/src/EntityTree.cpp index d16aeaa6e1..e4de39a799 100644 --- a/libraries/entities/src/EntityTree.cpp +++ b/libraries/entities/src/EntityTree.cpp @@ -1804,7 +1804,7 @@ QVector EntityTree::sendEntities(EntityEditPacketSender* packetSen addToNeedsParentFixupList(entity); } entity->forceQueryAACubeUpdate(); - entity->checkAndMaybeUpdateQueryAACube(); + entity->updateQueryAACube(); moveOperator.addEntityToMoveList(entity, entity->getQueryAACube()); i++; } else { diff --git a/libraries/entities/src/SimpleEntitySimulation.cpp b/libraries/entities/src/SimpleEntitySimulation.cpp index d41b22137e..3203c2968c 100644 --- a/libraries/entities/src/SimpleEntitySimulation.cpp +++ b/libraries/entities/src/SimpleEntitySimulation.cpp @@ -136,7 +136,7 @@ void SimpleEntitySimulation::sortEntitiesThatMoved() { SetOfEntities::iterator itemItr = _entitiesToSort.begin(); while (itemItr != _entitiesToSort.end()) { EntityItemPointer entity = *itemItr; - entity->checkAndMaybeUpdateQueryAACube(); + entity->updateQueryAACube(); ++itemItr; } EntitySimulation::sortEntitiesThatMoved(); diff --git a/libraries/physics/src/EntityMotionState.cpp b/libraries/physics/src/EntityMotionState.cpp index df46f7ada7..6884482074 100644 --- a/libraries/physics/src/EntityMotionState.cpp +++ b/libraries/physics/src/EntityMotionState.cpp @@ -581,7 +581,7 @@ void EntityMotionState::sendUpdate(OctreeEditPacketSender* packetSender, uint32_ } if (properties.transformChanged()) { - if (_entity->checkAndMaybeUpdateQueryAACube(true)) { + if (_entity->updateQueryAACube()) { // due to parenting, the server may not know where something is in world-space, so include the bounding cube. properties.setQueryAACube(_entity->getQueryAACube()); } @@ -648,7 +648,7 @@ void EntityMotionState::sendUpdate(OctreeEditPacketSender* packetSender, uint32_ _entity->forEachDescendant([&](SpatiallyNestablePointer descendant) { if (descendant->getNestableType() == NestableType::Entity) { EntityItemPointer entityDescendant = std::static_pointer_cast(descendant); - if (descendant->checkAndMaybeUpdateQueryAACube()) { + if (descendant->updateQueryAACube()) { EntityItemProperties newQueryCubeProperties; newQueryCubeProperties.setQueryAACube(descendant->getQueryAACube()); newQueryCubeProperties.setLastEdited(properties.getLastEdited()); diff --git a/libraries/shared/src/SpatiallyNestable.cpp b/libraries/shared/src/SpatiallyNestable.cpp index 58456f7e9a..baa289095d 100644 --- a/libraries/shared/src/SpatiallyNestable.cpp +++ b/libraries/shared/src/SpatiallyNestable.cpp @@ -963,37 +963,39 @@ AACube SpatiallyNestable::getMaximumAACube(bool& success) const { const float PARENTED_EXPANSION_FACTOR = 3.0f; -bool SpatiallyNestable::checkAndMaybeUpdateQueryAACube(bool forcePuffed) { - bool updated = false; - bool success = false; +bool SpatiallyNestable::updateQueryAACube() { + if (!queryAACubeNeedsUpdate()) { + return false; + } + + bool success; AACube maxAACube = getMaximumAACube(success); if (success) { - // maybe update _queryAACube - if (!_queryAACubeSet || !_queryAACube.contains(maxAACube)) { - if (forcePuffed || _parentJointIndex != INVALID_JOINT_INDEX || _children.size() > 0 ) { - // make an expanded AACube centered on the object - float scale = PARENTED_EXPANSION_FACTOR * maxAACube.getScale(); - _queryAACube = AACube(maxAACube.calcCenter() - glm::vec3(0.5f * scale), scale); - } else { - _queryAACube = maxAACube; - } - updated = true; - - forEachDescendant([&](const SpatiallyNestablePointer& descendant) { - bool childSuccess; - AACube descendantAACube = descendant->getQueryAACube(childSuccess); - if (childSuccess) { - if (_queryAACube.contains(descendantAACube)) { - return ; - } - _queryAACube += descendantAACube.getMinimumPoint(); - _queryAACube += descendantAACube.getMaximumPoint(); - } - }); - _queryAACubeSet = true; + if (shouldPuffQueryAACube()) { + // make an expanded AACube centered on the object + float scale = PARENTED_EXPANSION_FACTOR * maxAACube.getScale(); + _queryAACube = AACube(maxAACube.calcCenter() - glm::vec3(0.5f * scale), scale); + _queryAACubeIsPuffed = true; + } else { + _queryAACube = maxAACube; + _queryAACubeIsPuffed = false; } + + forEachDescendant([&](const SpatiallyNestablePointer& descendant) { + bool childSuccess; + AACube descendantAACube = descendant->getQueryAACube(childSuccess); + if (childSuccess) { + if (_queryAACube.contains(descendantAACube)) { + return; // from lambda + } + _queryAACube += descendantAACube.getMinimumPoint(); + _queryAACube += descendantAACube.getMaximumPoint(); + } + }); + + _queryAACubeSet = true; } - return updated; + return true; } void SpatiallyNestable::setQueryAACube(const AACube& queryAACube) { @@ -1016,6 +1018,10 @@ bool SpatiallyNestable::queryAACubeNeedsUpdate() const { return true; } + if (shouldPuffQueryAACube() != _queryAACubeIsPuffed) { + return true; + } + // make sure children are still in their boxes, also. bool childNeedsUpdate = false; forEachDescendantTest([&](const SpatiallyNestablePointer& descendant) { @@ -1029,31 +1035,6 @@ bool SpatiallyNestable::queryAACubeNeedsUpdate() const { return childNeedsUpdate; } -void SpatiallyNestable::updateQueryAACube() { - bool success; - AACube maxAACube = getMaximumAACube(success); - if (_parentJointIndex != INVALID_JOINT_INDEX || _children.size() > 0 ) { - // make an expanded AACube centered on the object - float scale = PARENTED_EXPANSION_FACTOR * maxAACube.getScale(); - _queryAACube = AACube(maxAACube.calcCenter() - glm::vec3(0.5f * scale), scale); - } else { - _queryAACube = maxAACube; - } - - forEachDescendant([&](const SpatiallyNestablePointer& descendant) { - bool success; - AACube descendantAACube = descendant->getQueryAACube(success); - if (success) { - if (_queryAACube.contains(descendantAACube)) { - return; - } - _queryAACube += descendantAACube.getMinimumPoint(); - _queryAACube += descendantAACube.getMaximumPoint(); - } - }); - _queryAACubeSet = true; -} - AACube SpatiallyNestable::getQueryAACube(bool& success) const { if (_queryAACubeSet) { success = true; diff --git a/libraries/shared/src/SpatiallyNestable.h b/libraries/shared/src/SpatiallyNestable.h index 9be6dc14ef..37f6cfdfd9 100644 --- a/libraries/shared/src/SpatiallyNestable.h +++ b/libraries/shared/src/SpatiallyNestable.h @@ -106,11 +106,11 @@ public: virtual glm::vec3 getParentAngularVelocity(bool& success) const; virtual AACube getMaximumAACube(bool& success) const; - bool checkAndMaybeUpdateQueryAACube(bool forcePuffed = false); - void updateQueryAACube(); virtual void setQueryAACube(const AACube& queryAACube); virtual bool queryAACubeNeedsUpdate() const; + virtual bool shouldPuffQueryAACube() const { return false; } + bool updateQueryAACube(); void forceQueryAACubeUpdate() { _queryAACubeSet = false; } virtual AACube getQueryAACube(bool& success) const; virtual AACube getQueryAACube() const; @@ -234,6 +234,7 @@ private: glm::vec3 _angularVelocity; mutable bool _parentKnowsMe { false }; bool _isDead { false }; + bool _queryAACubeIsPuffed { false }; }; From 633f63df54041b6f53e2a0c47fa7fcdcd2ad7189 Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Fri, 13 Oct 2017 13:11:18 -0700 Subject: [PATCH 12/60] fix updateQueryAACube return-value --- libraries/shared/src/SpatiallyNestable.cpp | 50 +++++++++++----------- 1 file changed, 26 insertions(+), 24 deletions(-) diff --git a/libraries/shared/src/SpatiallyNestable.cpp b/libraries/shared/src/SpatiallyNestable.cpp index baa289095d..8dbd2dd5e0 100644 --- a/libraries/shared/src/SpatiallyNestable.cpp +++ b/libraries/shared/src/SpatiallyNestable.cpp @@ -970,31 +970,33 @@ bool SpatiallyNestable::updateQueryAACube() { bool success; AACube maxAACube = getMaximumAACube(success); - if (success) { - if (shouldPuffQueryAACube()) { - // make an expanded AACube centered on the object - float scale = PARENTED_EXPANSION_FACTOR * maxAACube.getScale(); - _queryAACube = AACube(maxAACube.calcCenter() - glm::vec3(0.5f * scale), scale); - _queryAACubeIsPuffed = true; - } else { - _queryAACube = maxAACube; - _queryAACubeIsPuffed = false; - } - - forEachDescendant([&](const SpatiallyNestablePointer& descendant) { - bool childSuccess; - AACube descendantAACube = descendant->getQueryAACube(childSuccess); - if (childSuccess) { - if (_queryAACube.contains(descendantAACube)) { - return; // from lambda - } - _queryAACube += descendantAACube.getMinimumPoint(); - _queryAACube += descendantAACube.getMaximumPoint(); - } - }); - - _queryAACubeSet = true; + if (!success) { + return false; } + + if (shouldPuffQueryAACube()) { + // make an expanded AACube centered on the object + float scale = PARENTED_EXPANSION_FACTOR * maxAACube.getScale(); + _queryAACube = AACube(maxAACube.calcCenter() - glm::vec3(0.5f * scale), scale); + _queryAACubeIsPuffed = true; + } else { + _queryAACube = maxAACube; + _queryAACubeIsPuffed = false; + } + + forEachDescendant([&](const SpatiallyNestablePointer& descendant) { + bool childSuccess; + AACube descendantAACube = descendant->getQueryAACube(childSuccess); + if (childSuccess) { + if (_queryAACube.contains(descendantAACube)) { + return; // from lambda + } + _queryAACube += descendantAACube.getMinimumPoint(); + _queryAACube += descendantAACube.getMaximumPoint(); + } + }); + + _queryAACubeSet = true; return true; } From c1e8d5144c14dce5912bce3e0f7ee21d04047316 Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Fri, 13 Oct 2017 14:53:36 -0700 Subject: [PATCH 13/60] remove code which is no longer needed because of custom physics setters --- libraries/entities/src/EntityItem.cpp | 15 --------------- libraries/entities/src/EntityTree.cpp | 3 ++- 2 files changed, 2 insertions(+), 16 deletions(-) diff --git a/libraries/entities/src/EntityItem.cpp b/libraries/entities/src/EntityItem.cpp index 421efac687..705867c8d9 100644 --- a/libraries/entities/src/EntityItem.cpp +++ b/libraries/entities/src/EntityItem.cpp @@ -1767,9 +1767,6 @@ void EntityItem::updateParentID(const QUuid& value) { } void EntityItem::updatePositionFromNetwork(const glm::vec3& value) { - if (shouldSuppressLocationEdits()) { - return; - } updatePosition(value); } @@ -1796,9 +1793,6 @@ void EntityItem::updateRotation(const glm::quat& rotation) { } void EntityItem::updateRotationFromNetwork(const glm::quat& rotation) { - if (shouldSuppressLocationEdits()) { - return; - } updateRotation(rotation); } @@ -1853,16 +1847,10 @@ void EntityItem::updateVelocity(const glm::vec3& value) { } void EntityItem::updateVelocityFromNetwork(const glm::vec3& value) { - if (shouldSuppressLocationEdits()) { - return; - } updateVelocity(value); } void EntityItem::updateQueryAACubeFromNetwork(const AACube& value) { - if (shouldSuppressLocationEdits()) { - return; - } setQueryAACube(value); } @@ -1918,9 +1906,6 @@ void EntityItem::updateAngularVelocity(const glm::vec3& value) { } void EntityItem::updateAngularVelocityFromNetwork(const glm::vec3& value) { - if (shouldSuppressLocationEdits()) { - return; - } updateAngularVelocity(value); } diff --git a/libraries/entities/src/EntityTree.cpp b/libraries/entities/src/EntityTree.cpp index e4de39a799..b58d10ce24 100644 --- a/libraries/entities/src/EntityTree.cpp +++ b/libraries/entities/src/EntityTree.cpp @@ -1028,7 +1028,8 @@ void EntityTree::fixupTerseEditLogging(EntityItemProperties& properties, QList Date: Fri, 13 Oct 2017 15:40:08 -0700 Subject: [PATCH 14/60] cleanups + call updateQueryAACube when parent changes or action is deleted --- libraries/entities/src/EntityItem.cpp | 32 ++++++--------------------- libraries/entities/src/EntityItem.h | 5 ----- 2 files changed, 7 insertions(+), 30 deletions(-) diff --git a/libraries/entities/src/EntityItem.cpp b/libraries/entities/src/EntityItem.cpp index 705867c8d9..79e78f9dc7 100644 --- a/libraries/entities/src/EntityItem.cpp +++ b/libraries/entities/src/EntityItem.cpp @@ -739,7 +739,7 @@ int EntityItem::readEntityDataFromBuffer(const unsigned char* data, int bytesLef // reasons and the contract is that the client handles them in an idempotent manner. auto customUpdatePositionFromNetwork = [this, shouldUpdate, lastEdited](glm::vec3 value){ if (shouldUpdate(_lastUpdatedPositionTimestamp, value != _lastUpdatedPositionValue)) { - updatePositionFromNetwork(value); + updatePosition(value); _lastUpdatedPositionTimestamp = lastEdited; _lastUpdatedPositionValue = value; } @@ -747,7 +747,7 @@ int EntityItem::readEntityDataFromBuffer(const unsigned char* data, int bytesLef auto customUpdateRotationFromNetwork = [this, shouldUpdate, lastEdited](glm::quat value){ if (shouldUpdate(_lastUpdatedRotationTimestamp, value != _lastUpdatedRotationValue)) { - updateRotationFromNetwork(value); + updateRotation(value); _lastUpdatedRotationTimestamp = lastEdited; _lastUpdatedRotationValue = value; } @@ -755,7 +755,7 @@ int EntityItem::readEntityDataFromBuffer(const unsigned char* data, int bytesLef auto customUpdateVelocityFromNetwork = [this, shouldUpdate, lastEdited](glm::vec3 value){ if (shouldUpdate(_lastUpdatedVelocityTimestamp, value != _lastUpdatedVelocityValue)) { - updateVelocityFromNetwork(value); + updateVelocity(value); _lastUpdatedVelocityTimestamp = lastEdited; _lastUpdatedVelocityValue = value; } @@ -763,7 +763,7 @@ int EntityItem::readEntityDataFromBuffer(const unsigned char* data, int bytesLef auto customUpdateAngularVelocityFromNetwork = [this, shouldUpdate, lastEdited](glm::vec3 value){ if (shouldUpdate(_lastUpdatedAngularVelocityTimestamp, value != _lastUpdatedAngularVelocityValue)) { - updateAngularVelocityFromNetwork(value); + updateAngularVelocity(value); _lastUpdatedAngularVelocityTimestamp = lastEdited; _lastUpdatedAngularVelocityValue = value; } @@ -850,7 +850,7 @@ int EntityItem::readEntityDataFromBuffer(const unsigned char* data, int bytesLef { auto customUpdateQueryAACubeFromNetwork = [this, shouldUpdate, lastEdited](AACube value){ if (shouldUpdate(_lastUpdatedQueryAACubeTimestamp, value != _lastUpdatedQueryAACubeValue)) { - updateQueryAACubeFromNetwork(value); + setQueryAACube(value); _lastUpdatedQueryAACubeTimestamp = lastEdited; _lastUpdatedQueryAACubeValue = value; } @@ -1763,13 +1763,10 @@ void EntityItem::updateParentID(const QUuid& value) { if (tree) { tree->addToNeedsParentFixupList(getThisPointer()); } + updateQueryAACube(); } } -void EntityItem::updatePositionFromNetwork(const glm::vec3& value) { - updatePosition(value); -} - void EntityItem::updateDimensions(const glm::vec3& value) { if (getDimensions() != value) { setDimensions(value); @@ -1792,10 +1789,6 @@ void EntityItem::updateRotation(const glm::quat& rotation) { } } -void EntityItem::updateRotationFromNetwork(const glm::quat& rotation) { - updateRotation(rotation); -} - void EntityItem::updateMass(float mass) { // Setting the mass actually changes the _density (at fixed volume), however // we must protect the density range to help maintain stability of physics simulation @@ -1846,14 +1839,6 @@ void EntityItem::updateVelocity(const glm::vec3& value) { } } -void EntityItem::updateVelocityFromNetwork(const glm::vec3& value) { - updateVelocity(value); -} - -void EntityItem::updateQueryAACubeFromNetwork(const AACube& value) { - setQueryAACube(value); -} - void EntityItem::updateDamping(float value) { auto clampedDamping = glm::clamp(value, 0.0f, 1.0f); if (_damping != clampedDamping) { @@ -1905,10 +1890,6 @@ void EntityItem::updateAngularVelocity(const glm::vec3& value) { } } -void EntityItem::updateAngularVelocityFromNetwork(const glm::vec3& value) { - updateAngularVelocity(value); -} - void EntityItem::updateAngularDamping(float value) { auto clampedDamping = glm::clamp(value, 0.0f, 1.0f); if (_angularDamping != clampedDamping) { @@ -2213,6 +2194,7 @@ bool EntityItem::removeActionInternal(const QUuid& actionID, EntitySimulationPoi _dirtyFlags |= Simulation::DIRTY_PHYSICS_ACTIVATION; _dirtyFlags |= Simulation::DIRTY_COLLISION_GROUP; // may need to not collide with own avatar setDynamicDataNeedsTransmit(true); + updateQueryAACube(); return success; } return false; diff --git a/libraries/entities/src/EntityItem.h b/libraries/entities/src/EntityItem.h index 764ff34f99..ce4bf13896 100644 --- a/libraries/entities/src/EntityItem.h +++ b/libraries/entities/src/EntityItem.h @@ -357,21 +357,16 @@ public: virtual void updateRegistrationPoint(const glm::vec3& value); void updatePosition(const glm::vec3& value); void updateParentID(const QUuid& value); - void updatePositionFromNetwork(const glm::vec3& value); void updateDimensions(const glm::vec3& value); void updateRotation(const glm::quat& rotation); - void updateRotationFromNetwork(const glm::quat& rotation); void updateDensity(float value); void updateMass(float value); void updateVelocity(const glm::vec3& value); - void updateVelocityFromNetwork(const glm::vec3& value); - void updateQueryAACubeFromNetwork(const AACube& value); void updateDamping(float value); void updateRestitution(float value); void updateFriction(float value); void updateGravity(const glm::vec3& value); void updateAngularVelocity(const glm::vec3& value); - void updateAngularVelocityFromNetwork(const glm::vec3& value); void updateAngularDamping(float value); void updateCollisionless(bool value); void updateCollisionMask(uint8_t value); From 2c8c5e214cec55ba95f5ae52f192d88d1a24e78a Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Fri, 13 Oct 2017 16:10:58 -0700 Subject: [PATCH 15/60] puff querybox if entity is in motion --- libraries/entities/src/EntityItem.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/entities/src/EntityItem.cpp b/libraries/entities/src/EntityItem.cpp index 79e78f9dc7..9af39254ed 100644 --- a/libraries/entities/src/EntityItem.cpp +++ b/libraries/entities/src/EntityItem.cpp @@ -1557,7 +1557,7 @@ AACube EntityItem::getQueryAACube(bool& success) const { } bool EntityItem::shouldPuffQueryAACube() const { - return hasActions() || isChildOfMyAvatar(); + return hasActions() || isChildOfMyAvatar() || isMovingRelativeToParent(); } // NOTE: This should only be used in cases of old bitstreams which only contain radius data From ae1b2bd9312a34f5f0476b5e7f8b7b10837c8580 Mon Sep 17 00:00:00 2001 From: Zach Fox Date: Fri, 20 Oct 2017 11:11:23 -0700 Subject: [PATCH 16/60] 'Tis a silly hack --- scripts/system/marketplaces/marketplaces.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/scripts/system/marketplaces/marketplaces.js b/scripts/system/marketplaces/marketplaces.js index 5ffc35e6e5..3bf6435a25 100644 --- a/scripts/system/marketplaces/marketplaces.js +++ b/scripts/system/marketplaces/marketplaces.js @@ -135,9 +135,10 @@ function setCertificateInfo(currentEntityWithContextOverlay, itemCertificateId) { wireEventBridge(true); + var certificateId = itemCertificateId || (Entities.getEntityProperties(currentEntityWithContextOverlay, ['certificateID']).certificateID + "\n"); tablet.sendToQml({ method: 'inspectionCertificate_setCertificateId', - certificateId: itemCertificateId || Entities.getEntityProperties(currentEntityWithContextOverlay, ['certificateID']).certificateID + certificateId: certificateId }); } From c217992866261b898b82699662a29ad7baab1709 Mon Sep 17 00:00:00 2001 From: Zach Fox Date: Fri, 20 Oct 2017 11:42:03 -0700 Subject: [PATCH 17/60] Order of operations lol --- interface/src/ui/overlays/ContextOverlayInterface.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/interface/src/ui/overlays/ContextOverlayInterface.cpp b/interface/src/ui/overlays/ContextOverlayInterface.cpp index 8cbb214857..e39a4edc11 100644 --- a/interface/src/ui/overlays/ContextOverlayInterface.cpp +++ b/interface/src/ui/overlays/ContextOverlayInterface.cpp @@ -140,8 +140,8 @@ bool ContextOverlayInterface::createOrDestroyContextOverlay(const EntityItemID& if (event.getID() == LEFT_HAND_HW_ID) { offsetAngle *= -1.0f; } - contextOverlayPosition = (glm::quat(glm::radians(glm::vec3(0.0f, offsetAngle, 0.0f)))) * - ((cameraPosition + direction * (distance - CONTEXT_OVERLAY_OFFSET_DISTANCE))); + contextOverlayPosition = cameraPosition + + (glm::quat(glm::radians(glm::vec3(0.0f, offsetAngle, 0.0f)))) * (direction * (distance - CONTEXT_OVERLAY_OFFSET_DISTANCE)); contextOverlayDimensions = glm::vec2(CONTEXT_OVERLAY_SIZE, CONTEXT_OVERLAY_SIZE) * glm::distance(contextOverlayPosition, cameraPosition); } From 2b0285adc2fdf50fa9e70827e61bc7dead647958 Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Fri, 20 Oct 2017 15:05:21 -0700 Subject: [PATCH 18/60] fix action (grab) deadlock --- libraries/entities/src/EntityItem.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/libraries/entities/src/EntityItem.cpp b/libraries/entities/src/EntityItem.cpp index 9af39254ed..2d3aeeba38 100644 --- a/libraries/entities/src/EntityItem.cpp +++ b/libraries/entities/src/EntityItem.cpp @@ -2109,6 +2109,7 @@ bool EntityItem::addAction(EntitySimulationPointer simulation, EntityDynamicPoin removeActionInternal(action->getID()); } }); + updateQueryAACube(); return result; } @@ -2167,6 +2168,8 @@ bool EntityItem::removeAction(EntitySimulationPointer simulation, const QUuid& a checkWaitingToRemove(simulation); success = removeActionInternal(actionID); }); + updateQueryAACube(); + return success; } @@ -2194,7 +2197,6 @@ bool EntityItem::removeActionInternal(const QUuid& actionID, EntitySimulationPoi _dirtyFlags |= Simulation::DIRTY_PHYSICS_ACTIVATION; _dirtyFlags |= Simulation::DIRTY_COLLISION_GROUP; // may need to not collide with own avatar setDynamicDataNeedsTransmit(true); - updateQueryAACube(); return success; } return false; From 5c8451a6266200726e5c848f6e34663ac8dffd0e Mon Sep 17 00:00:00 2001 From: Zach Fox Date: Mon, 23 Oct 2017 10:36:23 -0700 Subject: [PATCH 19/60] Auto-refresh Wallet Home & Purchases on 4s timer --- .../qml/hifi/commerce/purchases/Purchases.qml | 4 +++- .../qml/hifi/commerce/wallet/WalletHome.qml | 14 ++++++++++++++ 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/interface/resources/qml/hifi/commerce/purchases/Purchases.qml b/interface/resources/qml/hifi/commerce/purchases/Purchases.qml index c98f212c53..f41bdf55ba 100644 --- a/interface/resources/qml/hifi/commerce/purchases/Purchases.qml +++ b/interface/resources/qml/hifi/commerce/purchases/Purchases.qml @@ -583,9 +583,11 @@ Rectangle { Timer { id: inventoryTimer; - interval: 90000; + interval: 4000; // Change this back to 90000 after demo + //interval: 90000; onTriggered: { if (root.activeView === "purchasesMain" && !root.pendingInventoryReply) { + console.log("Refreshing Purchases..."); root.pendingInventoryReply = true; commerce.inventory(); } diff --git a/interface/resources/qml/hifi/commerce/wallet/WalletHome.qml b/interface/resources/qml/hifi/commerce/wallet/WalletHome.qml index 50891deb60..9323d97fe4 100644 --- a/interface/resources/qml/hifi/commerce/wallet/WalletHome.qml +++ b/interface/resources/qml/hifi/commerce/wallet/WalletHome.qml @@ -43,6 +43,7 @@ Item { calculatePendingAndInvalidated(); } + refreshTimer.start(); } } @@ -117,6 +118,8 @@ Item { historyReceived = false; commerce.balance(); commerce.history(); + } else { + refreshTimer.stop(); } } } @@ -138,6 +141,17 @@ Item { } } + Timer { + id: refreshTimer; + interval: 4000; // Remove this after demo? + onTriggered: { + console.log("Refreshing Wallet Home..."); + historyReceived = false; + commerce.balance(); + commerce.history(); + } + } + // Recent Activity Rectangle { id: recentActivityContainer; From f15038c54fe58671d34d7d4a82f8f1cbb8d50528 Mon Sep 17 00:00:00 2001 From: Daniela Date: Mon, 23 Oct 2017 19:11:32 +0100 Subject: [PATCH 20/60] Re-add isFacingAvatar to true and delete rotation of the grabbermoveup tool. --- interface/src/ui/overlays/Billboardable.cpp | 10 ++++++---- scripts/system/libraries/entitySelectionTool.js | 15 ++++----------- 2 files changed, 10 insertions(+), 15 deletions(-) diff --git a/interface/src/ui/overlays/Billboardable.cpp b/interface/src/ui/overlays/Billboardable.cpp index 34a4ef6df5..e71e8bb951 100644 --- a/interface/src/ui/overlays/Billboardable.cpp +++ b/interface/src/ui/overlays/Billboardable.cpp @@ -13,6 +13,7 @@ #include #include +#include "avatar/AvatarManager.h" void Billboardable::setProperties(const QVariantMap& properties) { auto isFacingAvatar = properties["isFacingAvatar"]; @@ -32,10 +33,11 @@ bool Billboardable::pointTransformAtCamera(Transform& transform, glm::quat offse if (isFacingAvatar()) { glm::vec3 billboardPos = transform.getTranslation(); glm::vec3 cameraPos = qApp->getCamera().getPosition(); - glm::vec3 look = cameraPos - billboardPos; - float elevation = -asinf(look.y / glm::length(look)); - float azimuth = atan2f(look.x, look.z); - glm::quat rotation(glm::vec3(elevation, azimuth, 0)); + + glm::vec3 avatarUP = DependencyManager::get()->getMyAvatar()->getOrientation()*Vectors::UP; + + glm::quat rotation(conjugate(toQuat(glm::lookAt(billboardPos, cameraPos, avatarUP)))); + transform.setRotation(rotation); transform.postRotate(offsetRotation); return true; diff --git a/scripts/system/libraries/entitySelectionTool.js b/scripts/system/libraries/entitySelectionTool.js index 6db9564c77..3a422bcb8a 100644 --- a/scripts/system/libraries/entitySelectionTool.js +++ b/scripts/system/libraries/entitySelectionTool.js @@ -203,14 +203,7 @@ SelectionManager = (function() { print("ERROR: entitySelectionTool.update got exception: " + JSON.stringify(e)); } } - - //update overlay to face Avatar - if ((!activeTool) || isActiveTool(grabberMoveUp)) { - Overlays.editOverlay(grabberMoveUp, { - rotation: Quat.lookAt(grabberMoveUpPosition, Camera.position, Quat.getUp(MyAvatar.orientation)) - }); - } - + }; return that; @@ -467,6 +460,7 @@ SelectionDisplay = (function() { visible: false, size: 0.1, scale: 0.1, + isFacingAvatar: true, drawInFront: true }); @@ -2113,8 +2107,7 @@ SelectionDisplay = (function() { z: position.z + (grabberMoveUpOffset + worldTop) * upVec.z }; Overlays.editOverlay(grabberMoveUp, { - visible: (!activeTool) || isActiveTool(grabberMoveUp), - rotation: Quat.lookAt(grabberMoveUpPosition, Camera.position, upVec) + visible: (!activeTool) || isActiveTool(grabberMoveUp) }); Overlays.editOverlay(baseOfEntityProjectionOverlay, { @@ -2463,7 +2456,7 @@ SelectionDisplay = (function() { var vector = Vec3.subtract(newIntersection, lastXYPick); // project vector onto avatar up vector - // we want the avatar referential not the camera. + // we want the avatar referential not the camera. var avatarUpVector = Quat.getUp(MyAvatar.orientation); var dotVectorUp = Vec3.dot(vector, avatarUpVector); vector = Vec3.multiply(dotVectorUp, avatarUpVector); From 30bffdea3234239d25fe806fa30de7f551059f8b Mon Sep 17 00:00:00 2001 From: Zach Fox Date: Mon, 23 Oct 2017 11:45:51 -0700 Subject: [PATCH 21/60] Quick bugfix --- interface/resources/qml/hifi/commerce/purchases/Purchases.qml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/interface/resources/qml/hifi/commerce/purchases/Purchases.qml b/interface/resources/qml/hifi/commerce/purchases/Purchases.qml index f41bdf55ba..27737aa0a9 100644 --- a/interface/resources/qml/hifi/commerce/purchases/Purchases.qml +++ b/interface/resources/qml/hifi/commerce/purchases/Purchases.qml @@ -663,6 +663,8 @@ Rectangle { currentPurchasesModelStatus !== previousPurchasesModelStatus) { purchasesModel.setProperty(i, "statusChanged", true); + } else { + purchasesModel.setProperty(i, "statusChanged", false); } } } From 0242e8e4bad25b0101c6a6b4159a207194d29420 Mon Sep 17 00:00:00 2001 From: Dante Ruiz Date: Mon, 23 Oct 2017 16:33:49 -0700 Subject: [PATCH 22/60] fixed crash and login password --- .../qml/LoginDialog/LinkAccountBody.qml | 22 ++++----- .../resources/qml/LoginDialog/SignUpBody.qml | 26 +++++----- .../resources/qml/controls-uit/Keyboard.qml | 4 ++ .../qml/dialogs/TabletLoginDialog.qml | 3 ++ libraries/ui/src/ui/OffscreenQmlSurface.cpp | 49 ------------------- 5 files changed, 31 insertions(+), 73 deletions(-) diff --git a/interface/resources/qml/LoginDialog/LinkAccountBody.qml b/interface/resources/qml/LoginDialog/LinkAccountBody.qml index c73aab08c3..a710c76477 100644 --- a/interface/resources/qml/LoginDialog/LinkAccountBody.qml +++ b/interface/resources/qml/LoginDialog/LinkAccountBody.qml @@ -119,6 +119,7 @@ Item { width: parent.width focus: true label: "Username or Email" + activeFocusOnPress: true ShortcutText { anchors { @@ -135,6 +136,10 @@ Item { onLinkActivated: loginDialog.openUrl(link) } + onFocusChanged: { + console.log("-------> setting variable <-------"); + root.text = ""; + } } TextField { @@ -143,6 +148,7 @@ Item { label: "Password" echoMode: showPassword.checked ? TextInput.Normal : TextInput.Password + activeFocusOnPress: true ShortcutText { anchors { @@ -159,6 +165,10 @@ Item { onLinkActivated: loginDialog.openUrl(link) } + onFocusChanged: { + root.text = ""; + root.isPassword = true; + } } CheckBoxQQC2 { @@ -233,18 +243,6 @@ Item { } } - // Override ScrollingWindow's keyboard that would be at very bottom of dialog. - Keyboard { - raised: keyboardEnabled && keyboardRaised - numeric: punctuationMode - anchors { - left: parent.left - right: parent.right - bottom: parent.bottom - bottomMargin: keyboardRaised ? 2 * hifi.dimensions.contentSpacing.y : 0 - } - } - Component.onCompleted: { root.title = qsTr("Sign Into High Fidelity") root.iconText = "<" diff --git a/interface/resources/qml/LoginDialog/SignUpBody.qml b/interface/resources/qml/LoginDialog/SignUpBody.qml index f6cf40db8e..9d55998b40 100644 --- a/interface/resources/qml/LoginDialog/SignUpBody.qml +++ b/interface/resources/qml/LoginDialog/SignUpBody.qml @@ -108,12 +108,17 @@ Item { id: emailField width: parent.width label: "Email" + activeFocusOnPress: true + onFocusChanged: { + root.text = ""; + } } TextField { id: usernameField width: parent.width label: "Username" + activeFocusOnPress: true ShortcutText { anchors { @@ -128,6 +133,9 @@ Item { horizontalAlignment: Text.AlignHCenter color: hifi.colors.blueAccent + onFocusChanged: { + root.text = ""; + } } } @@ -136,6 +144,7 @@ Item { width: parent.width label: "Password" echoMode: TextInput.Password + activeFocusOnPress: true ShortcutText { anchors { @@ -151,6 +160,11 @@ Item { color: hifi.colors.blueAccent } + + onFocusChanged: { + root.text = ""; + root.isPassword = focus + } } Row { @@ -202,18 +216,6 @@ Item { } } - // Override ScrollingWindow's keyboard that would be at very bottom of dialog. - Keyboard { - raised: keyboardEnabled && keyboardRaised - numeric: punctuationMode - anchors { - left: parent.left - right: parent.right - bottom: parent.bottom - bottomMargin: keyboardRaised ? 2 * hifi.dimensions.contentSpacing.y : 0 - } - } - Component.onCompleted: { root.title = qsTr("Create an Account") root.iconText = "<" diff --git a/interface/resources/qml/controls-uit/Keyboard.qml b/interface/resources/qml/controls-uit/Keyboard.qml index 8d6634c9b4..66a61742c9 100644 --- a/interface/resources/qml/controls-uit/Keyboard.qml +++ b/interface/resources/qml/controls-uit/Keyboard.qml @@ -39,6 +39,10 @@ Rectangle { property bool shiftMode: false property bool numericShiftMode: false + onRaisedChanged: { + mirroredText = ""; + } + function resetShiftMode(mode) { shiftMode = mode; shiftKey.resetToggledMode(mode); diff --git a/interface/resources/qml/dialogs/TabletLoginDialog.qml b/interface/resources/qml/dialogs/TabletLoginDialog.qml index 9722f31144..269788a808 100644 --- a/interface/resources/qml/dialogs/TabletLoginDialog.qml +++ b/interface/resources/qml/dialogs/TabletLoginDialog.qml @@ -37,6 +37,8 @@ TabletModalWindow { property bool keyboardEnabled: false property bool keyboardRaised: false property bool punctuationMode: false + property bool isPassword: false + property alias text: loginKeyboard.mirroredText readonly property bool isTablet: true @@ -130,6 +132,7 @@ TabletModalWindow { id: loginKeyboard raised: root.keyboardEnabled && root.keyboardRaised numeric: root.punctuationMode + password: root.isPassword anchors { left: parent.left right: parent.right diff --git a/libraries/ui/src/ui/OffscreenQmlSurface.cpp b/libraries/ui/src/ui/OffscreenQmlSurface.cpp index 8646bee3ca..ddc9c2e5f3 100644 --- a/libraries/ui/src/ui/OffscreenQmlSurface.cpp +++ b/libraries/ui/src/ui/OffscreenQmlSurface.cpp @@ -1082,36 +1082,6 @@ void OffscreenQmlSurface::synthesizeKeyPress(QString key, QObject* targetOverrid } } -static void forEachKeyboard(QQuickItem* parent, std::function function) { - if (!function) { - return; - } - - auto keyboards = parent->findChildren("keyboard"); - - for (auto keyboardObject : keyboards) { - auto keyboard = qobject_cast(keyboardObject); - if (keyboard) { - function(keyboard); - } - } -} - -static const int TEXTINPUT_PASSWORD = 2; - -static QQuickItem* getTopmostParent(QQuickItem* item) { - QObject* itemObject = item; - while (itemObject) { - if (itemObject->parent()) { - itemObject = itemObject->parent(); - } else { - break; - } - } - - return qobject_cast (itemObject); -} - void OffscreenQmlSurface::setKeyboardRaised(QObject* object, bool raised, bool numeric) { #if Q_OS_ANDROID return; @@ -1128,21 +1098,6 @@ void OffscreenQmlSurface::setKeyboardRaised(QObject* object, bool raised, bool n return; } - auto echoMode = item->property("echoMode"); - bool isPasswordField = echoMode.isValid() && echoMode.toInt() == TEXTINPUT_PASSWORD; - - // we need to somehow pass 'isPasswordField' to visible keyboard so it will change its 'mirror text' to asterixes - // the issue in some cases there might be more than one keyboard in object tree and it is hard to understand which one is being used at the moment - // unfortunately attempts to check for visibility failed becuase visibility is not updated yet. So... I don't see other way than just update properties for all the keyboards - - auto topmostParent = getTopmostParent(item); - if (topmostParent) { - forEachKeyboard(topmostParent, [&](QQuickItem* keyboard) { - keyboard->setProperty("mirroredText", QVariant::fromValue(QString(""))); - keyboard->setProperty("password", isPasswordField); - }); - } - // for future probably makes sense to consider one of the following: // 1. make keyboard a singleton, which will be dynamically re-parented before showing // 2. track currently visible keyboard somewhere, allow to subscribe for this signal @@ -1153,10 +1108,6 @@ void OffscreenQmlSurface::setKeyboardRaised(QObject* object, bool raised, bool n numeric = numeric || QString(item->metaObject()->className()).left(7) == "SpinBox"; if (item->property("keyboardRaised").isValid()) { - forEachKeyboard(item, [&](QQuickItem* keyboard) { - keyboard->setProperty("mirroredText", QVariant::fromValue(QString(""))); - keyboard->setProperty("password", isPasswordField); - }); // FIXME - HMD only: Possibly set value of "keyboardEnabled" per isHMDMode() for use in WebView.qml. if (item->property("punctuationMode").isValid()) { From a34db5f26dcc802420dd849413d294f3679c012e Mon Sep 17 00:00:00 2001 From: Olivier Prat Date: Tue, 24 Oct 2017 11:09:36 +0200 Subject: [PATCH 23/60] Shadows are now cast by the current zone key light (sun) --- .../src/RenderableZoneEntityItem.cpp | 1 + .../src/RenderableZoneEntityItem.h | 1 + .../render-utils/src/DebugDeferredBuffer.cpp | 2 +- .../src/DeferredLightingEffect.cpp | 4 +-- libraries/render-utils/src/LightStage.cpp | 5 ++++ libraries/render-utils/src/LightStage.h | 24 ++++++++++++++++ .../render-utils/src/RenderShadowTask.cpp | 28 +++++++++---------- 7 files changed, 48 insertions(+), 17 deletions(-) diff --git a/libraries/entities-renderer/src/RenderableZoneEntityItem.cpp b/libraries/entities-renderer/src/RenderableZoneEntityItem.cpp index f0f5506f8c..0235f1b7a3 100644 --- a/libraries/entities-renderer/src/RenderableZoneEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableZoneEntityItem.cpp @@ -112,6 +112,7 @@ void ZoneEntityRenderer::doRender(RenderArgs* args) { // Do we need to allocate the light in the stage ? if (LightStage::isIndexInvalid(_sunIndex)) { _sunIndex = _stage->addLight(_sunLight); + _shadowIndex = _stage->addShadow(_sunIndex); } else { _stage->updateLightArrayBuffer(_sunIndex); } diff --git a/libraries/entities-renderer/src/RenderableZoneEntityItem.h b/libraries/entities-renderer/src/RenderableZoneEntityItem.h index f39a2e6299..050a8a4386 100644 --- a/libraries/entities-renderer/src/RenderableZoneEntityItem.h +++ b/libraries/entities-renderer/src/RenderableZoneEntityItem.h @@ -88,6 +88,7 @@ private: ComponentMode _hazeMode{ COMPONENT_MODE_INHERIT }; indexed_container::Index _sunIndex{ LightStage::INVALID_INDEX }; + indexed_container::Index _shadowIndex{ LightStage::INVALID_INDEX }; indexed_container::Index _ambientIndex{ LightStage::INVALID_INDEX }; BackgroundStagePointer _backgroundStage; diff --git a/libraries/render-utils/src/DebugDeferredBuffer.cpp b/libraries/render-utils/src/DebugDeferredBuffer.cpp index 44e2bd290b..d334a53fa1 100644 --- a/libraries/render-utils/src/DebugDeferredBuffer.cpp +++ b/libraries/render-utils/src/DebugDeferredBuffer.cpp @@ -435,7 +435,7 @@ void DebugDeferredBuffer::run(const RenderContextPointer& renderContext, const I auto lightStage = renderContext->_scene->getStage(); assert(lightStage); assert(lightStage->getNumLights() > 0); - auto lightAndShadow = lightStage->getLightAndShadow(0); + auto lightAndShadow = lightStage->getCurrentKeyLightAndShadow(); const auto& globalShadow = lightAndShadow.second; if (globalShadow) { batch.setResourceTexture(Shadow, globalShadow->map); diff --git a/libraries/render-utils/src/DeferredLightingEffect.cpp b/libraries/render-utils/src/DeferredLightingEffect.cpp index e6a33a9911..b6a91888a1 100644 --- a/libraries/render-utils/src/DeferredLightingEffect.cpp +++ b/libraries/render-utils/src/DeferredLightingEffect.cpp @@ -498,7 +498,7 @@ void RenderDeferredSetup::run(const render::RenderContextPointer& renderContext, auto lightStage = renderContext->_scene->getStage(); assert(lightStage); assert(lightStage->getNumLights() > 0); - auto lightAndShadow = lightStage->getLightAndShadow(0); + auto lightAndShadow = lightStage->getCurrentKeyLightAndShadow(); const auto& globalShadow = lightAndShadow.second; // Bind the shadow buffer @@ -509,7 +509,7 @@ void RenderDeferredSetup::run(const render::RenderContextPointer& renderContext, auto& program = deferredLightingEffect->_directionalSkyboxLight; LightLocationsPtr locations = deferredLightingEffect->_directionalSkyboxLightLocations; - auto keyLight = lightStage->getLight(0); + auto keyLight = lightAndShadow.first; // Setup the global directional pass pipeline { diff --git a/libraries/render-utils/src/LightStage.cpp b/libraries/render-utils/src/LightStage.cpp index d0e9f2467e..079c63f367 100644 --- a/libraries/render-utils/src/LightStage.cpp +++ b/libraries/render-utils/src/LightStage.cpp @@ -142,6 +142,11 @@ LightStage::LightPointer LightStage::removeLight(Index index) { LightPointer removed = _lights.freeElement(index); if (removed) { + auto shadowId = _descs[index].shadowId; + // Remove shadow if one exists for this light + if (shadowId != INVALID_INDEX) { + _shadows.freeElement(shadowId); + } _lightMap.erase(removed); _descs[index] = Desc(); } diff --git a/libraries/render-utils/src/LightStage.h b/libraries/render-utils/src/LightStage.h index f946cf699e..66d73c9a6e 100644 --- a/libraries/render-utils/src/LightStage.h +++ b/libraries/render-utils/src/LightStage.h @@ -116,6 +116,30 @@ public: return LightAndShadow(getLight(lightId), getShadow(lightId)); } + LightPointer getCurrentKeyLight() const { + Index keyLightId{ 0 }; + if (!_currentFrame._sunLights.empty()) { + keyLightId = _currentFrame._sunLights.front(); + } + return _lights.get(keyLightId); + } + + ShadowPointer getCurrentKeyShadow() const { + Index keyLightId{ 0 }; + if (!_currentFrame._sunLights.empty()) { + keyLightId = _currentFrame._sunLights.front(); + } + return getShadow(keyLightId); + } + + LightAndShadow getCurrentKeyLightAndShadow() const { + Index keyLightId{ 0 }; + if (!_currentFrame._sunLights.empty()) { + keyLightId = _currentFrame._sunLights.front(); + } + return LightAndShadow(getLight(keyLightId), getShadow(keyLightId)); + } + LightStage(); Lights _lights; LightMap _lightMap; diff --git a/libraries/render-utils/src/RenderShadowTask.cpp b/libraries/render-utils/src/RenderShadowTask.cpp index d32857bc65..7171543abc 100644 --- a/libraries/render-utils/src/RenderShadowTask.cpp +++ b/libraries/render-utils/src/RenderShadowTask.cpp @@ -33,10 +33,8 @@ void RenderShadowMap::run(const render::RenderContextPointer& renderContext, auto lightStage = renderContext->_scene->getStage(); assert(lightStage); - LightStage::Index globalLightIndex { 0 }; - const auto globalLight = lightStage->getLight(globalLightIndex); - const auto shadow = lightStage->getShadow(globalLightIndex); + const auto shadow = lightStage->getCurrentKeyShadow(); if (!shadow) return; const auto& fbo = shadow->framebuffer; @@ -128,20 +126,22 @@ void RenderShadowTask::configure(const Config& configuration) { void RenderShadowSetup::run(const render::RenderContextPointer& renderContext, Output& output) { auto lightStage = renderContext->_scene->getStage(); assert(lightStage); - const auto globalShadow = lightStage->getShadow(0); - // Cache old render args - RenderArgs* args = renderContext->args; - output = args->_renderMode; + const auto globalShadow = lightStage->getCurrentKeyShadow(); + if (globalShadow) { + // Cache old render args + RenderArgs* args = renderContext->args; + output = args->_renderMode; - auto nearClip = args->getViewFrustum().getNearClip(); - float nearDepth = -args->_boomOffset.z; - const int SHADOW_FAR_DEPTH = 20; - globalShadow->setKeylightFrustum(args->getViewFrustum(), nearDepth, nearClip + SHADOW_FAR_DEPTH); + auto nearClip = args->getViewFrustum().getNearClip(); + float nearDepth = -args->_boomOffset.z; + const int SHADOW_FAR_DEPTH = 20; + globalShadow->setKeylightFrustum(args->getViewFrustum(), nearDepth, nearClip + SHADOW_FAR_DEPTH); - // Set the keylight render args - args->pushViewFrustum(*(globalShadow->getFrustum())); - args->_renderMode = RenderArgs::SHADOW_RENDER_MODE; + // Set the keylight render args + args->pushViewFrustum(*(globalShadow->getFrustum())); + args->_renderMode = RenderArgs::SHADOW_RENDER_MODE; + } } void RenderShadowTeardown::run(const render::RenderContextPointer& renderContext, const Input& input) { From 059c5c1806d287e3072b6f0a9b56d86fb0325a79 Mon Sep 17 00:00:00 2001 From: Daniela Date: Tue, 24 Oct 2017 14:49:17 +0100 Subject: [PATCH 24/60] billboard is now using a general formula to calculate the rotation, where we don't assume y is up. Added dependency on the avatar. --- interface/src/ui/overlays/Billboardable.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/interface/src/ui/overlays/Billboardable.cpp b/interface/src/ui/overlays/Billboardable.cpp index e71e8bb951..892a9d998d 100644 --- a/interface/src/ui/overlays/Billboardable.cpp +++ b/interface/src/ui/overlays/Billboardable.cpp @@ -3,6 +3,7 @@ // interface/src/ui/overlays // // Created by Zander Otavka on 8/7/15. +// Modified by Daniela Fontes on 24/10/17. // Copyright 2014 High Fidelity, Inc. // // Distributed under the Apache License, Version 2.0. @@ -33,7 +34,7 @@ bool Billboardable::pointTransformAtCamera(Transform& transform, glm::quat offse if (isFacingAvatar()) { glm::vec3 billboardPos = transform.getTranslation(); glm::vec3 cameraPos = qApp->getCamera().getPosition(); - + // use the referencial from the avatar, y isn't always up glm::vec3 avatarUP = DependencyManager::get()->getMyAvatar()->getOrientation()*Vectors::UP; glm::quat rotation(conjugate(toQuat(glm::lookAt(billboardPos, cameraPos, avatarUP)))); From 9981a44b710974457d8150f8e039b38783689ce3 Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Thu, 7 Sep 2017 09:29:04 -0700 Subject: [PATCH 25/60] add hook for ShapeInfo calculator --- libraries/entities/src/ShapeEntityItem.cpp | 18 ++++++++++++++++-- libraries/entities/src/ShapeEntityItem.h | 4 +++- 2 files changed, 19 insertions(+), 3 deletions(-) diff --git a/libraries/entities/src/ShapeEntityItem.cpp b/libraries/entities/src/ShapeEntityItem.cpp index 6e3bdc27a4..6f3025881b 100644 --- a/libraries/entities/src/ShapeEntityItem.cpp +++ b/libraries/entities/src/ShapeEntityItem.cpp @@ -51,6 +51,14 @@ namespace entity { } } +// shapeCalculator is a hook for external code that knows how to configure a ShapeInfo +// for given entity::Shape and dimensions +ShapeEntityItem::ShapeInfoCalculator shapeCalculator = nullptr; + +void ShapeEntityItem::setShapeInfoCalulator(ShapeEntityItem::ShapeInfoCalculator callback) { + shapeCalculator = callback; +} + ShapeEntityItem::Pointer ShapeEntityItem::baseFactory(const EntityItemID& entityID, const EntityItemProperties& properties) { Pointer entity(new ShapeEntityItem(entityID), [](EntityItem* ptr) { ptr->deleteLater(); }); entity->setProperties(properties); @@ -278,8 +286,14 @@ void ShapeEntityItem::computeShapeInfo(ShapeInfo& info) { case entity::Shape::Icosahedron: case entity::Shape::Cone: { - //TODO WL21389: SHAPE_TYPE_SIMPLE_HULL and pointCollection (later) - _collisionShapeType = SHAPE_TYPE_ELLIPSOID; + if (shapeCalculator) { + shapeCalculator(info, _shape, getDimensions()); + // shapeCalculator only supports convex shapes (e.g. SHAPE_TYPE_HULL) + // TODO: figure out how to support concave shapes + _collisionShapeType = SHAPE_TYPE_HULL; + } else { + _collisionShapeType = SHAPE_TYPE_ELLIPSOID; + } } break; case entity::Shape::Torus: diff --git a/libraries/entities/src/ShapeEntityItem.h b/libraries/entities/src/ShapeEntityItem.h index a20cecb60b..0f8197787b 100644 --- a/libraries/entities/src/ShapeEntityItem.h +++ b/libraries/entities/src/ShapeEntityItem.h @@ -34,7 +34,6 @@ namespace entity { ::QString stringFromShape(Shape shape); } - class ShapeEntityItem : public EntityItem { using Pointer = std::shared_ptr; static Pointer baseFactory(const EntityItemID& entityID, const EntityItemProperties& properties); @@ -43,6 +42,9 @@ public: static EntityItemPointer sphereFactory(const EntityItemID& entityID, const EntityItemProperties& properties); static EntityItemPointer boxFactory(const EntityItemID& entityID, const EntityItemProperties& properties); + using ShapeInfoCalculator = std::function; + static void setShapeInfoCalulator(ShapeInfoCalculator callback); + ShapeEntityItem(const EntityItemID& entityItemID); void pureVirtualFunctionPlaceHolder() override { }; From 1128a98e887f67d79d2e8f744b7f0c1348480032 Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Tue, 24 Oct 2017 11:15:57 -0700 Subject: [PATCH 26/60] implement callEntityClientMethod --- .../src/scripts/EntityScriptServer.cpp | 5 +++ .../entities/src/EntityScriptingInterface.cpp | 39 +++++++++++++++++++ .../entities/src/EntityScriptingInterface.h | 32 ++++++++++++--- .../networking/src/EntityScriptClient.cpp | 25 ++++++++++++ libraries/networking/src/EntityScriptClient.h | 7 ++++ libraries/script-engine/src/ScriptEngine.cpp | 4 ++ 6 files changed, 107 insertions(+), 5 deletions(-) diff --git a/assignment-client/src/scripts/EntityScriptServer.cpp b/assignment-client/src/scripts/EntityScriptServer.cpp index 0ced0a632e..d627b019ef 100644 --- a/assignment-client/src/scripts/EntityScriptServer.cpp +++ b/assignment-client/src/scripts/EntityScriptServer.cpp @@ -30,6 +30,8 @@ #include #include +#include // for EntityScriptServerStub + #include "EntityScriptServerLogging.h" #include "../entities/AssignmentParentFinder.h" @@ -68,6 +70,9 @@ EntityScriptServer::EntityScriptServer(ReceivedMessage& message) : ThreadedAssig DependencyManager::set(); DependencyManager::set(ScriptEngine::ENTITY_SERVER_SCRIPT); + DependencyManager::set(); + + // Needed to ensure the creation of the DebugDraw instance on the main thread DebugDraw::getInstance(); diff --git a/libraries/entities/src/EntityScriptingInterface.cpp b/libraries/entities/src/EntityScriptingInterface.cpp index 39f19323e3..4e556c83a3 100644 --- a/libraries/entities/src/EntityScriptingInterface.cpp +++ b/libraries/entities/src/EntityScriptingInterface.cpp @@ -50,6 +50,10 @@ EntityScriptingInterface::EntityScriptingInterface(bool bidOnSimulationOwnership connect(nodeList.data(), &NodeList::canRezCertifiedChanged, this, &EntityScriptingInterface::canRezCertifiedChanged); connect(nodeList.data(), &NodeList::canRezTmpCertifiedChanged, this, &EntityScriptingInterface::canRezTmpCertifiedChanged); connect(nodeList.data(), &NodeList::canWriteAssetsChanged, this, &EntityScriptingInterface::canWriteAssetsChanged); + + + auto& packetReceiver = nodeList->getPacketReceiver(); + packetReceiver.registerListener(PacketType::EntityScriptCallMethod, this, "handleEntityScriptCallMethodPacket"); } void EntityScriptingInterface::queueEntityMessage(PacketType packetType, @@ -571,6 +575,41 @@ void EntityScriptingInterface::callEntityServerMethod(QUuid id, const QString& m DependencyManager::get()->callEntityServerMethod(id, method, params); } +void EntityScriptingInterface::callEntityClientMethod(QUuid clientSessionID, QUuid entityID, const QString& method, const QStringList& params) { + PROFILE_RANGE(script_entities, __FUNCTION__); + DependencyManager::get()->callEntityClientMethod(clientSessionID, entityID, method, params); +} + + +void EntityScriptingInterface::handleEntityScriptCallMethodPacket(QSharedPointer receivedMessage, SharedNodePointer senderNode) { + PROFILE_RANGE(script_entities, __FUNCTION__); + + auto nodeList = DependencyManager::get(); + SharedNodePointer entityScriptServer = nodeList->soloNodeOfType(NodeType::EntityScriptServer); + + if (entityScriptServer == senderNode) { + auto entityID = QUuid::fromRfc4122(receivedMessage->read(NUM_BYTES_RFC4122_UUID)); + + auto method = receivedMessage->readString(); + + quint16 paramCount; + receivedMessage->readPrimitive(¶mCount); + + QStringList params; + for (int param = 0; param < paramCount; param++) { + auto paramString = receivedMessage->readString(); + params << paramString; + } + + std::lock_guard lock(_entitiesScriptEngineLock); + if (_entitiesScriptEngine) { + _entitiesScriptEngine->callEntityScriptMethod(entityID, method, params, senderNode->getUUID()); + } + } +} + + + QUuid EntityScriptingInterface::findClosestEntity(const glm::vec3& center, float radius) const { PROFILE_RANGE(script_entities, __FUNCTION__); diff --git a/libraries/entities/src/EntityScriptingInterface.h b/libraries/entities/src/EntityScriptingInterface.h index ee5011e99d..a6d754cf9e 100644 --- a/libraries/entities/src/EntityScriptingInterface.h +++ b/libraries/entities/src/EntityScriptingInterface.h @@ -189,12 +189,15 @@ public slots: Q_INVOKABLE void deleteEntity(QUuid entityID); /**jsdoc - * Call a method on an entity. Allows a script to call a method on an entity's script. - * The method will execute in the entity script engine. If the entity does not have an - * entity script or the method does not exist, this call will have no effect. - * If it is running an entity script (specified by the `script` property) + * Call a method on an entity in the same context as this function is called. Allows a script + * to call a method on an entity's script. The method will execute in the entity script engine. + * If the entity does not have an entity script or the method does not exist, this call will + * have no effect. If it is running an entity script (specified by the `script` property) * and it exposes a property with the specified name `method`, it will be called - * using `params` as the list of arguments. + * using `params` as the list of arguments. If this is called within an entity script, the + * method will be executed on the client in the entity script engine in which it was called. If + * this is called in an entity server script, the method will be executed on the entity server + * script engine. * * @function Entities.callEntityMethod * @param {EntityID} entityID The ID of the entity to call the method on. @@ -218,6 +221,21 @@ public slots: */ Q_INVOKABLE void callEntityServerMethod(QUuid entityID, const QString& method, const QStringList& params = QStringList()); + /**jsdoc + * Call a client method on an entity on a specific client node. Allows a server entity script to call a + * method on an entity's client script for a particular client. The method will execute in the entity script + * engine on that single client. If the entity does not have an entity script or the method does not exist, or + * the client is not connected to the domain, or you attempt to make this call outside of the entity server + * script, this call will have no effect. + * + * @function Entities.callEntityClientMethod + * @param {SessionID} clientSessionID The session ID of the client to call the method on. + * @param {EntityID} entityID The ID of the entity to call the method on. + * @param {string} method The name of the method to call. + * @param {string[]} params The list of parameters to call the specified method with. + */ + Q_INVOKABLE void callEntityClientMethod(QUuid clientSessionID, QUuid entityID, const QString& method, const QStringList& params = QStringList()); + /**jsdoc * finds the closest model to the center point, within the radius * will return a EntityItemID.isKnownID = false if no models are in the radius @@ -447,6 +465,10 @@ protected: std::lock_guard lock(_entitiesScriptEngineLock); function(_entitiesScriptEngine); }; + +private slots: + void handleEntityScriptCallMethodPacket(QSharedPointer receivedMessage, SharedNodePointer senderNode); + private: bool actionWorker(const QUuid& entityID, std::function actor); bool polyVoxWorker(QUuid entityID, std::function actor); diff --git a/libraries/networking/src/EntityScriptClient.cpp b/libraries/networking/src/EntityScriptClient.cpp index 399cb80bfa..b3a6a1b59d 100644 --- a/libraries/networking/src/EntityScriptClient.cpp +++ b/libraries/networking/src/EntityScriptClient.cpp @@ -92,6 +92,31 @@ void EntityScriptClient::callEntityServerMethod(QUuid entityID, const QString& m } } +void EntityScriptServerStub::callEntityClientMethod(QUuid clientSessionID, QUuid entityID, const QString& method, const QStringList& params) { + qDebug() << __FUNCTION__; + + + // only valid to call this function if you are the entity script server + auto nodeList = DependencyManager::get(); + SharedNodePointer targetClient = nodeList->nodeWithUUID(clientSessionID); + + if (nodeList->getOwnerType() == NodeType::EntityScriptServer && targetClient) { + auto packetList = NLPacketList::create(PacketType::EntityScriptCallMethod, QByteArray(), true, true); + + packetList->write(entityID.toRfc4122()); + + packetList->writeString(method); + + quint16 paramCount = params.length(); + packetList->writePrimitive(paramCount); + + foreach(const QString& param, params) { + packetList->writeString(param); + } + + nodeList->sendPacketList(std::move(packetList), *targetClient); + } +} MessageID EntityScriptClient::getEntityServerScriptStatus(QUuid entityID, GetScriptStatusCallback callback) { auto nodeList = DependencyManager::get(); diff --git a/libraries/networking/src/EntityScriptClient.h b/libraries/networking/src/EntityScriptClient.h index 6f1a0376ea..43e89611da 100644 --- a/libraries/networking/src/EntityScriptClient.h +++ b/libraries/networking/src/EntityScriptClient.h @@ -74,4 +74,11 @@ private: void forceFailureOfPendingRequests(SharedNodePointer node); }; + +class EntityScriptServerStub : public QObject, public Dependency { + Q_OBJECT +public: + void callEntityClientMethod(QUuid clientSessionID, QUuid entityID, const QString& method, const QStringList& params); +}; + #endif diff --git a/libraries/script-engine/src/ScriptEngine.cpp b/libraries/script-engine/src/ScriptEngine.cpp index 98846c5213..92aab79219 100644 --- a/libraries/script-engine/src/ScriptEngine.cpp +++ b/libraries/script-engine/src/ScriptEngine.cpp @@ -2510,6 +2510,8 @@ void ScriptEngine::callEntityScriptMethod(const EntityItemID& entityID, const QS if (remoteCallerID == QUuid()) { callAllowed = true; } else { + qDebug() << __FUNCTION__ << "checking remotelyCallable method: " << methodName << " on entityID:" << entityID; + if (entityScript.property("remotelyCallable").isArray()) { auto callables = entityScript.property("remotelyCallable"); auto callableCount = callables.property("length").toInteger(); @@ -2536,6 +2538,8 @@ void ScriptEngine::callEntityScriptMethod(const EntityItemID& entityID, const QS callWithEnvironment(entityID, details.definingSandboxURL, entityScript.property(methodName), entityScript, args); this->globalObject().property("Script").setProperty("remoteCallerID", oldData); } + } else { + qDebug() << "Entity script not running for EntityID: " << entityID << " - Method [" << methodName << "] not callable."; } } From 5b50b362f14dd30b36d9e5aff707b1a0fd1ee622 Mon Sep 17 00:00:00 2001 From: LaShonda Hopper Date: Fri, 8 Sep 2017 15:49:18 -0400 Subject: [PATCH 27/60] [WL21389] WL21389 PR2: Representation of collision shapes need updating (details below). This commit adds support for the polyhedrons and polygons sans Torus and Quad which aren't currently supported within GeometryCache. * Moves GeometryCache::_shapes from public to private scope * Nothing aside from the class should be directly altering this, only querying * Updated instances of direct referencing which looks to have been limited to prior testing of instancing and shapes. * Adds an accessor function for ShapeData to GeometryCache * Consolidates point list generation to helper function * GeometryCache::computeSimpleHullPointListForShape * Moves GeometryCache::Shape to entity::Shape mapping to GeometryCache from RenderableShapeEntityItem * Adds conversion accessor to GeometryCache, GeometryCache::Shape getShapeForEntityShape * Sets ShapeEntityItem::ShapeInfoCalculator callback committed earlier. * This helps circumvent the issue with library inclusion. entity-render knows about entity; however, entity doesn't know about entity-renderer; however, GeometryCache data is needed within entity::ShapeEntityItem to compose the ShapeInfo point list data. * This callback is set up within Application::init of the Interface as it knows about both halves of the equation, and the callback needs to be setup prior to any entities collision data getting generated. * Removes _type reset within ShapeInfo::setPointCollection * This should avoid any issues due to subversively setting the type or incorrectly setting the type as a tangential operation. * Audited instances of ShapeInfo::setPointCollection and all seemed to be calling the function immediately after having set the type via ShapeInfo::setParams * Adds new ShapeType: SHAPE_TYPE_CIRCLE * This type is reserved for the circle which is now treated as a special type of Cylinder_Y with regard to collision as opposed to a simple hull. * Fixes the issue where jumping on a circle, at times, would result in the avatar sliding off towards an edge as if atop a squished cone. * Also updates ShapeInfo::getType() to return ShapeType as opposed to int * Auditing calls showed that majority of places were comparing against ShapeType * ShapeType::_type is a ShapeType so returning the type explicitly is more consistent. * ShapeInfo file houses ShapeType enum so any file aware of ShapeInfo is aware of ShapeType enumeration. * entity::Quad defaults to SHAPE_TYPE_ELLIPSOID * Like entity::Shape::Torus, entity::Shape::Quad is currently unsupported within GeometryCache::buildShapes. * Also it appears that a Quad shape can't be created within world via the creation menu. * There's no explicit option at present to create one. * Trying subvert the Cube/Box creation option to generate one results in an enforced stubby box as opposed to a quad. * Given the aforementioned points, entity::Shape::Quad will default to SHAPE_TYPE_ELLIPSOID as opposed to SHAPE_TYPE_BOX. * Added Todo regarding the shape being unsupported along with a notation to create a special ShapeType, SHAPE_TYPE_QUAD, for it should it be added in the future. * Adds some comments and has some minor clean up. Reviewed-by: Leander Hasty Changes Committed: modified: interface/src/Application.cpp modified: interface/src/Util.cpp modified: interface/src/Util.h modified: libraries/entities-renderer/src/RenderableShapeEntityItem.cpp modified: libraries/entities/src/ShapeEntityItem.cpp modified: libraries/entities/src/ShapeEntityItem.h modified: libraries/physics/src/ShapeFactory.cpp modified: libraries/render-utils/src/GeometryCache.cpp modified: libraries/render-utils/src/GeometryCache.h modified: libraries/shared/src/ShapeInfo.cpp modified: libraries/shared/src/ShapeInfo.h modified: tests/gpu-test/src/TestInstancedShapes.cpp --- interface/src/Application.cpp | 5 + interface/src/Util.cpp | 11 ++ interface/src/Util.h | 5 + .../src/RenderableShapeEntityItem.cpp | 27 +--- libraries/entities/src/ShapeEntityItem.cpp | 130 ++++++++++-------- libraries/entities/src/ShapeEntityItem.h | 2 +- libraries/physics/src/ShapeFactory.cpp | 1 + libraries/render-utils/src/GeometryCache.cpp | 81 +++++++++++ libraries/render-utils/src/GeometryCache.h | 18 ++- libraries/shared/src/ShapeInfo.cpp | 8 +- libraries/shared/src/ShapeInfo.h | 5 +- tests/gpu-test/src/TestInstancedShapes.cpp | 25 ++-- 12 files changed, 221 insertions(+), 97 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 6e7a405181..87d4db9936 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -120,6 +120,7 @@ #include #include #include +#include #include #include #include @@ -4228,6 +4229,10 @@ void Application::init() { // fire off an immediate domain-server check in now that settings are loaded DependencyManager::get()->sendDomainServerCheckIn(); + // This allows collision to be set up properly for shape entities supported by GeometryCache. + // This is before entity setup to ensure that it's ready for whenever instance collision is initialized. + ShapeEntityItem::setShapeInfoCalulator(ShapeEntityItem::ShapeInfoCalculator(&shapeInfoCalculator)); + getEntities()->init(); getEntities()->setEntityLoadingPriorityFunction([this](const EntityItem& item) { auto dims = item.getDimensions(); diff --git a/interface/src/Util.cpp b/interface/src/Util.cpp index 7822b78244..3e3f514117 100644 --- a/interface/src/Util.cpp +++ b/interface/src/Util.cpp @@ -28,6 +28,8 @@ #include #include #include +#include +#include #include "InterfaceLogging.h" #include "world.h" @@ -393,4 +395,13 @@ void runUnitTests() { } } +void shapeInfoCalculator(const ShapeEntityItem * const shapeEntity, ShapeInfo &shapeInfo) { + ShapeInfo::PointCollection pointCollection; + ShapeInfo::PointList points; + + GeometryCache::computeSimpleHullPointListForShape(shapeEntity, points); + pointCollection.push_back(points); + shapeInfo.setPointCollection(pointCollection); +} + diff --git a/interface/src/Util.h b/interface/src/Util.h index 48acb53936..976a26ce82 100644 --- a/interface/src/Util.h +++ b/interface/src/Util.h @@ -18,6 +18,9 @@ #include #include +class ShapeEntityItem; +class ShapeInfo; + void renderWorldBox(RenderArgs* args, gpu::Batch& batch); void runTimingTests(); @@ -28,4 +31,6 @@ bool rayIntersectsSphere(const glm::vec3& rayStarting, const glm::vec3& rayNorma bool pointInSphere(glm::vec3& point, glm::vec3& sphereCenter, double sphereRadius); +void shapeInfoCalculator(const ShapeEntityItem * const shapeEntity, ShapeInfo &shapeInfo); + #endif // hifi_Util_h diff --git a/libraries/entities-renderer/src/RenderableShapeEntityItem.cpp b/libraries/entities-renderer/src/RenderableShapeEntityItem.cpp index 7d7de0c08f..a72320fda0 100644 --- a/libraries/entities-renderer/src/RenderableShapeEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableShapeEntityItem.cpp @@ -30,23 +30,6 @@ using namespace render::entities; // is a half unit sphere. However, the geometry cache renders a UNIT sphere, so we need to scale down. static const float SPHERE_ENTITY_SCALE = 0.5f; -static std::array MAPPING { { - GeometryCache::Triangle, - GeometryCache::Quad, - GeometryCache::Hexagon, - GeometryCache::Octagon, - GeometryCache::Circle, - GeometryCache::Cube, - GeometryCache::Sphere, - GeometryCache::Tetrahedron, - GeometryCache::Octahedron, - GeometryCache::Dodecahedron, - GeometryCache::Icosahedron, - GeometryCache::Torus, - GeometryCache::Cone, - GeometryCache::Cylinder, -} }; - ShapeEntityRenderer::ShapeEntityRenderer(const EntityItemPointer& entity) : Parent(entity) { _procedural._vertexSource = simple_vert; @@ -137,11 +120,12 @@ void ShapeEntityRenderer::doRender(RenderArgs* args) { gpu::Batch& batch = *args->_batch; + auto geometryCache = DependencyManager::get(); GeometryCache::Shape geometryShape; bool proceduralRender = false; glm::vec4 outColor; withReadLock([&] { - geometryShape = MAPPING[_shape]; + geometryShape = geometryCache->getShapeForEntityShape(_shape); batch.setModelTransform(_renderTransform); // use a transform with scale, rotation, registration point and translation outColor = _color; if (_procedural.isReady()) { @@ -155,14 +139,13 @@ void ShapeEntityRenderer::doRender(RenderArgs* args) { if (proceduralRender) { batch._glColor4f(outColor.r, outColor.g, outColor.b, outColor.a); if (render::ShapeKey(args->_globalShapeKey).isWireframe()) { - DependencyManager::get()->renderWireShape(batch, geometryShape); + geometryCache->renderWireShape(batch, geometryShape); } else { - DependencyManager::get()->renderShape(batch, geometryShape); + geometryCache->renderShape(batch, geometryShape); } } else { // FIXME, support instanced multi-shape rendering using multidraw indirect outColor.a *= _isFading ? Interpolate::calculateFadeRatio(_fadeStartTime) : 1.0f; - auto geometryCache = DependencyManager::get(); auto pipeline = outColor.a < 1.0f ? geometryCache->getTransparentShapePipeline() : geometryCache->getOpaqueShapePipeline(); if (render::ShapeKey(args->_globalShapeKey).isWireframe()) { geometryCache->renderWireShapeInstance(args, batch, geometryShape, outColor, pipeline); @@ -171,6 +154,6 @@ void ShapeEntityRenderer::doRender(RenderArgs* args) { } } - static const auto triCount = DependencyManager::get()->getShapeTriangleCount(geometryShape); + static const auto triCount = geometryCache->getShapeTriangleCount(geometryShape); args->_details._trianglesRendered += (int)triCount; } diff --git a/libraries/entities/src/ShapeEntityItem.cpp b/libraries/entities/src/ShapeEntityItem.cpp index 6f3025881b..655283a601 100644 --- a/libraries/entities/src/ShapeEntityItem.cpp +++ b/libraries/entities/src/ShapeEntityItem.cpp @@ -241,79 +241,95 @@ void ShapeEntityItem::computeShapeInfo(ShapeInfo& info) { const glm::vec3 entityDimensions = getDimensions(); - switch (_shape) { - case entity::Shape::Quad: - case entity::Shape::Cube: - { - _collisionShapeType = SHAPE_TYPE_BOX; + switch (_shape){ + case entity::Shape::Quad: { + // Not in GeometryCache::buildShapes, unsupported. + _collisionShapeType = SHAPE_TYPE_ELLIPSOID; + //TODO WL21389: Add a SHAPE_TYPE_QUAD ShapeType and treat + // as a special box (later if desired support) + } + break; + case entity::Shape::Cube: { + _collisionShapeType = SHAPE_TYPE_BOX; + } + break; + case entity::Shape::Sphere: { + + float diameter = entityDimensions.x; + const float MIN_DIAMETER = 0.001f; + const float MIN_RELATIVE_SPHERICAL_ERROR = 0.001f; + if (diameter > MIN_DIAMETER + && fabsf(diameter - entityDimensions.y) / diameter < MIN_RELATIVE_SPHERICAL_ERROR + && fabsf(diameter - entityDimensions.z) / diameter < MIN_RELATIVE_SPHERICAL_ERROR) { + + _collisionShapeType = SHAPE_TYPE_SPHERE; + } else { + _collisionShapeType = SHAPE_TYPE_ELLIPSOID; } - break; - case entity::Shape::Sphere: - { + } + break; + case entity::Shape::Circle: { + _collisionShapeType = SHAPE_TYPE_CIRCLE; + } + break; + case entity::Shape::Cylinder: { + _collisionShapeType = SHAPE_TYPE_CYLINDER_Y; + // TODO WL21389: determine if rotation is axis-aligned + //const Transform::Quat & rot = _transform.getRotation(); - float diameter = entityDimensions.x; - const float MIN_DIAMETER = 0.001f; - const float MIN_RELATIVE_SPHERICAL_ERROR = 0.001f; - if (diameter > MIN_DIAMETER - && fabsf(diameter - entityDimensions.y) / diameter < MIN_RELATIVE_SPHERICAL_ERROR - && fabsf(diameter - entityDimensions.z) / diameter < MIN_RELATIVE_SPHERICAL_ERROR) { + // TODO WL21389: some way to tell apart SHAPE_TYPE_CYLINDER_Y, _X, _Z based on rotation and + // hull ( or dimensions, need circular cross section) + // Should allow for minor variance along axes? - _collisionShapeType = SHAPE_TYPE_SPHERE; - } else { - _collisionShapeType = SHAPE_TYPE_ELLIPSOID; - } - } - break; - case entity::Shape::Cylinder: - { - _collisionShapeType = SHAPE_TYPE_CYLINDER_Y; - // TODO WL21389: determine if rotation is axis-aligned - //const Transform::Quat & rot = _transform.getRotation(); - - // TODO WL21389: some way to tell apart SHAPE_TYPE_CYLINDER_Y, _X, _Z based on rotation and - // hull ( or dimensions, need circular cross section) - // Should allow for minor variance along axes? - - } - break; + } + break; + // gons, ones, & angles built via GeometryCache::extrudePolygon case entity::Shape::Triangle: case entity::Shape::Hexagon: case entity::Shape::Octagon: - case entity::Shape::Circle: + case entity::Shape::Cone: { + if (shapeCalculator) { + shapeCalculator(this, info); + // shapeCalculator only supports convex shapes (e.g. SHAPE_TYPE_HULL) + // TODO: figure out how to support concave shapes + _collisionShapeType = SHAPE_TYPE_SIMPLE_HULL; + } else { + _collisionShapeType = SHAPE_TYPE_ELLIPSOID; + } + } + break; + // hedrons built via GeometryCache::setUpFlatShapes case entity::Shape::Tetrahedron: case entity::Shape::Octahedron: case entity::Shape::Dodecahedron: - case entity::Shape::Icosahedron: - case entity::Shape::Cone: - { - if (shapeCalculator) { - shapeCalculator(info, _shape, getDimensions()); - // shapeCalculator only supports convex shapes (e.g. SHAPE_TYPE_HULL) - // TODO: figure out how to support concave shapes - _collisionShapeType = SHAPE_TYPE_HULL; - } else { - _collisionShapeType = SHAPE_TYPE_ELLIPSOID; - } - } - break; - case entity::Shape::Torus: - { - // Not in GeometryCache::buildShapes, unsupported. - _collisionShapeType = SHAPE_TYPE_ELLIPSOID; - //TODO WL21389: SHAPE_TYPE_SIMPLE_HULL and pointCollection (later if desired support) - } - break; - default: - { + case entity::Shape::Icosahedron: { + if ( shapeCalculator ) { + shapeCalculator(this, info); + // shapeCalculator only supports convex shapes (e.g. SHAPE_TYPE_HULL) + // TODO: figure out how to support concave shapes + _collisionShapeType = SHAPE_TYPE_SIMPLE_HULL; + } else { _collisionShapeType = SHAPE_TYPE_ELLIPSOID; } - break; + + } + break; + case entity::Shape::Torus: { + // Not in GeometryCache::buildShapes, unsupported. + _collisionShapeType = SHAPE_TYPE_ELLIPSOID; + //TODO WL21389: SHAPE_TYPE_SIMPLE_HULL and pointCollection (later if desired support) + } + break; + default: { + _collisionShapeType = SHAPE_TYPE_ELLIPSOID; + } + break; } EntityItem::computeShapeInfo(info); } -// This value specifes how the shape should be treated by physics calculations. +// This value specifies how the shape should be treated by physics calculations. ShapeType ShapeEntityItem::getShapeType() const { return _collisionShapeType; } diff --git a/libraries/entities/src/ShapeEntityItem.h b/libraries/entities/src/ShapeEntityItem.h index 0f8197787b..a88a2098e9 100644 --- a/libraries/entities/src/ShapeEntityItem.h +++ b/libraries/entities/src/ShapeEntityItem.h @@ -42,7 +42,7 @@ public: static EntityItemPointer sphereFactory(const EntityItemID& entityID, const EntityItemProperties& properties); static EntityItemPointer boxFactory(const EntityItemID& entityID, const EntityItemProperties& properties); - using ShapeInfoCalculator = std::function; + using ShapeInfoCalculator = std::function; static void setShapeInfoCalulator(ShapeInfoCalculator callback); ShapeEntityItem(const EntityItemID& entityItemID); diff --git a/libraries/physics/src/ShapeFactory.cpp b/libraries/physics/src/ShapeFactory.cpp index 18dfd2317e..cd0fba848a 100644 --- a/libraries/physics/src/ShapeFactory.cpp +++ b/libraries/physics/src/ShapeFactory.cpp @@ -314,6 +314,7 @@ const btCollisionShape* ShapeFactory::createShapeFromInfo(const ShapeInfo& info) shape = new btCylinderShapeZ(btHalfExtents); } break; + case SHAPE_TYPE_CIRCLE: case SHAPE_TYPE_CYLINDER_Y: { const glm::vec3 halfExtents = info.getHalfExtents(); const btVector3 btHalfExtents(halfExtents.x, halfExtents.y, halfExtents.z); diff --git a/libraries/render-utils/src/GeometryCache.cpp b/libraries/render-utils/src/GeometryCache.cpp index cf8e268681..38994cfa02 100644 --- a/libraries/render-utils/src/GeometryCache.cpp +++ b/libraries/render-utils/src/GeometryCache.cpp @@ -23,6 +23,7 @@ #include #include +#include #include "TextureCache.h" #include "RenderUtilsLogging.h" @@ -52,6 +53,24 @@ //#define WANT_DEBUG +static std::array MAPPING{ { + GeometryCache::Triangle, + GeometryCache::Quad, + GeometryCache::Hexagon, + GeometryCache::Octagon, + GeometryCache::Circle, + GeometryCache::Cube, + GeometryCache::Sphere, + GeometryCache::Tetrahedron, + GeometryCache::Octahedron, + GeometryCache::Dodecahedron, + GeometryCache::Icosahedron, + GeometryCache::Torus, + GeometryCache::Cone, + GeometryCache::Cylinder, +} }; + + const int GeometryCache::UNKNOWN_ID = -1; @@ -69,6 +88,52 @@ static gpu::Stream::FormatPointer INSTANCED_SOLID_FADE_STREAM_FORMAT; static const uint SHAPE_VERTEX_STRIDE = sizeof(glm::vec3) * 2; // vertices and normals static const uint SHAPE_NORMALS_OFFSET = sizeof(glm::vec3); +void GeometryCache::computeSimpleHullPointListForShape(const ShapeEntityItem * const shapePtr, QVector &outPointList){ + + if (shapePtr == nullptr){ + //--EARLY EXIT-- + return; + } + + auto geometryCache = DependencyManager::get(); + const GeometryCache::ShapeData * shapeData = geometryCache->getShapeData(MAPPING[shapePtr->getShape()]); + if (!shapeData){ + //--EARLY EXIT--( data isn't ready for some reason... ) + return; + } + const gpu::BufferView & shapeVerts = shapeData->_positionView; + const gpu::BufferView & shapeNorms = shapeData->_normalView; + assert(shapeVerts._size == shapeNorms._size); + + const gpu::BufferView::Size numItems = shapeVerts.getNumElements(); + const glm::vec3 halfExtents = shapePtr->getDimensions() * 0.5f; +#if DEBUG_SIMPLE_HULL_POINT_GENERATION + shapePtr->debugDump(); + qCDebug(entities) << "------------------ Begin Vert Info( ComputeShapeInfo )[FlatShapes] -----------------------------"; + qCDebug(entities) << " name:" << shapePtr->getName() << ": has " << numItems << " vert info pairs."; +#endif + outPointList.reserve(numItems); + for (gpu::BufferView::Index i = 0; i < (gpu::BufferView::Index)numItems; ++i) { + const geometry::Vec &curNorm = shapeNorms.get(i); +#if DEBUG_SIMPLE_HULL_POINT_GENERATION + const geometry::Vec &curVert = shapeVerts.get(i); + qCDebug(entities) << " --------------------"; + qCDebug(entities) << " Vert( " << i << " ): " << debugTreeVector(curVert); + qCDebug(entities) << " Norm( " << i << " ): " << debugTreeVector(curNorm); +#endif + outPointList.push_back(curNorm * halfExtents); + +#if DEBUG_SIMPLE_HULL_POINT_GENERATION + qCDebug(entities) << " Point( " << i << " ): " << debugTreeVector((curNorm * halfExtents)); +#endif + } + +#if DEBUG_SIMPLE_HULL_POINT_GENERATION + qCDebug(entities) << "-------------------- End Vert Info( ComputeShapeInfo ) -----------------------------"; +#endif + +} + template std::vector polygon() { std::vector result; @@ -447,6 +512,22 @@ void GeometryCache::buildShapes() { } +const GeometryCache::ShapeData * GeometryCache::getShapeData(const Shape shape) const { + if (((int)shape < 0) || ((int)shape >= _shapes.size())){ + return nullptr; + } + + return &_shapes[shape]; +} + +GeometryCache::Shape GeometryCache::getShapeForEntityShape(int entityShape) { + if ((entityShape < 0) || (entityShape >= MAPPING.size())){ + return NUM_SHAPES; + } + + return MAPPING[entityShape]; +} + gpu::Stream::FormatPointer& getSolidStreamFormat() { if (!SOLID_STREAM_FORMAT) { SOLID_STREAM_FORMAT = std::make_shared(); // 1 for everyone diff --git a/libraries/render-utils/src/GeometryCache.h b/libraries/render-utils/src/GeometryCache.h index 5a437cf5e9..867c4bc3ee 100644 --- a/libraries/render-utils/src/GeometryCache.h +++ b/libraries/render-utils/src/GeometryCache.h @@ -32,6 +32,7 @@ #include class SimpleProgramKey; +class ShapeEntityItem; typedef QPair Vec2FloatPair; typedef QPair Vec2FloatPairPair; @@ -147,6 +148,15 @@ public: NUM_SHAPES, }; + /// @param entityShapeEnum: The entity::Shape enumeration for the shape + /// whose GeometryCache::Shape is desired. + /// @return GeometryCache::NUM_SHAPES in the event of an error; otherwise, + /// the GeometryCache::Shape enum which aligns with the + /// specified entityShapeEnum + static GeometryCache::Shape getShapeForEntityShape(int entityShapeEnum); + + static void computeSimpleHullPointListForShape(const ShapeEntityItem * const shapePtr, QVector &outPointList); + static uint8_t CUSTOM_PIPELINE_NUMBER; static render::ShapePipelinePointer shapePipelineFactory(const render::ShapePlumber& plumber, const render::ShapeKey& key); static void registerShapePipeline() { @@ -355,15 +365,21 @@ public: using VShape = std::array; - VShape _shapes; + /// returns ShapeData associated with the specified shape, + /// otherwise nullptr in the event of an error. + const ShapeData * getShapeData(Shape shape) const; private: + GeometryCache(); virtual ~GeometryCache(); void buildShapes(); typedef QPair IntPair; typedef QPair VerticesIndices; + + + VShape _shapes; gpu::PipelinePointer _standardDrawPipeline; gpu::PipelinePointer _standardDrawPipelineNoBlend; diff --git a/libraries/shared/src/ShapeInfo.cpp b/libraries/shared/src/ShapeInfo.cpp index a556548b25..c56b722b61 100644 --- a/libraries/shared/src/ShapeInfo.cpp +++ b/libraries/shared/src/ShapeInfo.cpp @@ -45,6 +45,10 @@ void ShapeInfo::setParams(ShapeType type, const glm::vec3& halfExtents, QString _halfExtents = glm::vec3(radius); } break; + case SHAPE_TYPE_CIRCLE: { + _halfExtents = glm::vec3(_halfExtents.x, MIN_HALF_EXTENT, _halfExtents.z); + } + break; case SHAPE_TYPE_COMPOUND: case SHAPE_TYPE_STATIC_MESH: _url = QUrl(url); @@ -75,9 +79,7 @@ void ShapeInfo::setSphere(float radius) { } void ShapeInfo::setPointCollection(const ShapeInfo::PointCollection& pointCollection) { - //TODO WL21389: May need to skip resetting type here. _pointCollection = pointCollection; - _type = (_pointCollection.size() > 0) ? SHAPE_TYPE_COMPOUND : SHAPE_TYPE_NONE; _doubleHashKey.clear(); } @@ -124,7 +126,7 @@ int ShapeInfo::getLargestSubshapePointCount() const { } float ShapeInfo::computeVolume() const { - //TODO WL21389: Add support for other ShapeTypes( CYLINDER_X, CYLINDER_Y, etc). + //TODO WL21389: Add support for other ShapeTypes( CYLINDER_X, CYLINDER_Z, etc). const float DEFAULT_VOLUME = 1.0f; float volume = DEFAULT_VOLUME; switch(_type) { diff --git a/libraries/shared/src/ShapeInfo.h b/libraries/shared/src/ShapeInfo.h index 0ffdf1310d..cab487e07a 100644 --- a/libraries/shared/src/ShapeInfo.h +++ b/libraries/shared/src/ShapeInfo.h @@ -46,7 +46,8 @@ enum ShapeType { SHAPE_TYPE_SIMPLE_HULL, SHAPE_TYPE_SIMPLE_COMPOUND, SHAPE_TYPE_STATIC_MESH, - SHAPE_TYPE_ELLIPSOID + SHAPE_TYPE_ELLIPSOID, + SHAPE_TYPE_CIRCLE }; class ShapeInfo { @@ -66,7 +67,7 @@ public: void setCapsuleY(float radius, float halfHeight); void setOffset(const glm::vec3& offset); - int getType() const { return _type; } + ShapeType getType() const { return _type; } const glm::vec3& getHalfExtents() const { return _halfExtents; } const glm::vec3& getOffset() const { return _offset; } diff --git a/tests/gpu-test/src/TestInstancedShapes.cpp b/tests/gpu-test/src/TestInstancedShapes.cpp index 6a98ee58b9..da50f8521f 100644 --- a/tests/gpu-test/src/TestInstancedShapes.cpp +++ b/tests/gpu-test/src/TestInstancedShapes.cpp @@ -10,18 +10,18 @@ gpu::Stream::FormatPointer& getInstancedSolidStreamFormat(); -static const size_t TYPE_COUNT = 4; -static const size_t ITEM_COUNT = 50; -static const float SHAPE_INTERVAL = (PI * 2.0f) / ITEM_COUNT; -static const float ITEM_INTERVAL = SHAPE_INTERVAL / TYPE_COUNT; - -static GeometryCache::Shape SHAPE[TYPE_COUNT] = { +static GeometryCache::Shape SHAPE[] = { GeometryCache::Icosahedron, GeometryCache::Cube, GeometryCache::Sphere, GeometryCache::Tetrahedron, }; +static const size_t TYPE_COUNT = (sizeof(SHAPE) / sizeof((SHAPE)[0])); +static const size_t ITEM_COUNT = 50; +static const float SHAPE_INTERVAL = (PI * 2.0f) / ITEM_COUNT; +static const float ITEM_INTERVAL = SHAPE_INTERVAL / TYPE_COUNT; + const gpu::Element POSITION_ELEMENT { gpu::VEC3, gpu::FLOAT, gpu::XYZ }; const gpu::Element NORMAL_ELEMENT { gpu::VEC3, gpu::FLOAT, gpu::XYZ }; const gpu::Element COLOR_ELEMENT { gpu::VEC4, gpu::NUINT8, gpu::RGBA }; @@ -34,8 +34,6 @@ TestInstancedShapes::TestInstancedShapes() { static const float ITEM_RADIUS = 20; static const vec3 ITEM_TRANSLATION { 0, 0, -ITEM_RADIUS }; for (size_t i = 0; i < TYPE_COUNT; ++i) { - GeometryCache::Shape shape = SHAPE[i]; - GeometryCache::ShapeData shapeData = geometryCache->_shapes[shape]; //indirectCommand._count float startingInterval = ITEM_INTERVAL * i; std::vector typeTransforms; @@ -62,7 +60,12 @@ void TestInstancedShapes::renderTest(size_t testId, RenderArgs* args) { batch.setInputFormat(getInstancedSolidStreamFormat()); for (size_t i = 0; i < TYPE_COUNT; ++i) { GeometryCache::Shape shape = SHAPE[i]; - GeometryCache::ShapeData shapeData = geometryCache->_shapes[shape]; + const GeometryCache::ShapeData *shapeData = geometryCache->getShapeData( shape ); + if (!shapeData) { + + //--EARLY ITERATION EXIT--( didn't have shape data yet ) + continue; + } std::string namedCall = __FUNCTION__ + std::to_string(i); @@ -71,13 +74,13 @@ void TestInstancedShapes::renderTest(size_t testId, RenderArgs* args) { batch.setModelTransform(transforms[i][j]); batch.setupNamedCalls(namedCall, [=](gpu::Batch& batch, gpu::Batch::NamedBatchData&) { batch.setInputBuffer(gpu::Stream::COLOR, gpu::BufferView(colorBuffer, i * ITEM_COUNT * 4, colorBuffer->getSize(), COLOR_ELEMENT)); - shapeData.drawInstances(batch, ITEM_COUNT); + shapeData->drawInstances(batch, ITEM_COUNT); }); } //for (size_t j = 0; j < ITEM_COUNT; ++j) { // batch.setModelTransform(transforms[j + i * ITEM_COUNT]); - // shapeData.draw(batch); + // shapeData->draw(batch); //} } } From d2350974b5e80291206f3869d04a23b9b8cd7471 Mon Sep 17 00:00:00 2001 From: LaShonda Hopper Date: Mon, 11 Sep 2017 13:16:11 -0400 Subject: [PATCH 28/60] [WL21389] Avoid vector copy within shapeInfoCalculator. Reviewed-by: Leander Hasty Changes Committed: modified: interface/src/Util.cpp --- interface/src/Util.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/interface/src/Util.cpp b/interface/src/Util.cpp index 3e3f514117..6077c8ec42 100644 --- a/interface/src/Util.cpp +++ b/interface/src/Util.cpp @@ -398,9 +398,9 @@ void runUnitTests() { void shapeInfoCalculator(const ShapeEntityItem * const shapeEntity, ShapeInfo &shapeInfo) { ShapeInfo::PointCollection pointCollection; ShapeInfo::PointList points; - - GeometryCache::computeSimpleHullPointListForShape(shapeEntity, points); pointCollection.push_back(points); + + GeometryCache::computeSimpleHullPointListForShape(shapeEntity, pointCollection.back()); shapeInfo.setPointCollection(pointCollection); } From 070c664ff2a9d3a7c65a48709ee63e62d0db1391 Mon Sep 17 00:00:00 2001 From: LaShonda Hopper Date: Mon, 11 Sep 2017 13:27:59 -0400 Subject: [PATCH 29/60] [WL21389] Add out of bounds safeguard to computeShapeInfo helper (details below). * Switched direct map indexing to helper function which has out of bounds safeguard. * Also updated GeometryCache::getShapeForEntityShape default fallback return from GeometryCache::NUM_SHAPES to GeometryCache::Sphere inline with general preference to act as if a shape is a sphere in the event of an error. Changes Committed: modified: libraries/render-utils/src/GeometryCache.cpp --- libraries/render-utils/src/GeometryCache.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/libraries/render-utils/src/GeometryCache.cpp b/libraries/render-utils/src/GeometryCache.cpp index 38994cfa02..492a492bf9 100644 --- a/libraries/render-utils/src/GeometryCache.cpp +++ b/libraries/render-utils/src/GeometryCache.cpp @@ -96,7 +96,8 @@ void GeometryCache::computeSimpleHullPointListForShape(const ShapeEntityItem * c } auto geometryCache = DependencyManager::get(); - const GeometryCache::ShapeData * shapeData = geometryCache->getShapeData(MAPPING[shapePtr->getShape()]); + const GeometryCache::Shape entityGeometryShape = GeometryCache::getShapeForEntityShape(shapePtr->getShape()); + const GeometryCache::ShapeData * shapeData = geometryCache->getShapeData( entityGeometryShape ); if (!shapeData){ //--EARLY EXIT--( data isn't ready for some reason... ) return; @@ -522,7 +523,7 @@ const GeometryCache::ShapeData * GeometryCache::getShapeData(const Shape shape) GeometryCache::Shape GeometryCache::getShapeForEntityShape(int entityShape) { if ((entityShape < 0) || (entityShape >= MAPPING.size())){ - return NUM_SHAPES; + return GeometryCache::Sphere; } return MAPPING[entityShape]; From 8a4ac9ebc4b86e6a62abf6b9ca6084bab4c97411 Mon Sep 17 00:00:00 2001 From: LaShonda Hopper Date: Mon, 11 Sep 2017 15:10:56 -0400 Subject: [PATCH 30/60] [WL21389] Resolves size_t vs int warnings in GeometryCache. Reviewed-by: Kris Pivin Changes Committed: modified: libraries/render-utils/src/GeometryCache.cpp --- libraries/render-utils/src/GeometryCache.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/libraries/render-utils/src/GeometryCache.cpp b/libraries/render-utils/src/GeometryCache.cpp index 492a492bf9..004f33cd1c 100644 --- a/libraries/render-utils/src/GeometryCache.cpp +++ b/libraries/render-utils/src/GeometryCache.cpp @@ -113,7 +113,7 @@ void GeometryCache::computeSimpleHullPointListForShape(const ShapeEntityItem * c qCDebug(entities) << "------------------ Begin Vert Info( ComputeShapeInfo )[FlatShapes] -----------------------------"; qCDebug(entities) << " name:" << shapePtr->getName() << ": has " << numItems << " vert info pairs."; #endif - outPointList.reserve(numItems); + outPointList.reserve((int)numItems); for (gpu::BufferView::Index i = 0; i < (gpu::BufferView::Index)numItems; ++i) { const geometry::Vec &curNorm = shapeNorms.get(i); #if DEBUG_SIMPLE_HULL_POINT_GENERATION @@ -514,7 +514,7 @@ void GeometryCache::buildShapes() { } const GeometryCache::ShapeData * GeometryCache::getShapeData(const Shape shape) const { - if (((int)shape < 0) || ((int)shape >= _shapes.size())){ + if (((int)shape < 0) || ((int)shape >= (int)_shapes.size())){ return nullptr; } @@ -522,7 +522,7 @@ const GeometryCache::ShapeData * GeometryCache::getShapeData(const Shape shape) } GeometryCache::Shape GeometryCache::getShapeForEntityShape(int entityShape) { - if ((entityShape < 0) || (entityShape >= MAPPING.size())){ + if ((entityShape < 0) || (entityShape >= (int)MAPPING.size())){ return GeometryCache::Sphere; } From 789b850846f9f3d9f61e3c8df50ff3acf09ccffe Mon Sep 17 00:00:00 2001 From: LaShonda Hopper Date: Tue, 12 Sep 2017 12:26:15 -0400 Subject: [PATCH 31/60] [WL21389] Addresses feedback from PR #11336. * Removes todos from ShapeEntityItem::shapeCalculator stub commit. * Removes defined out debugging, as requested, from GeometryCache::computeSimpleHullPointListForShape. * Moves cone handling to its own section for better contextual flow. Changes Committed: modified: libraries/entities/src/ShapeEntityItem.cpp modified: libraries/render-utils/src/GeometryCache.cpp --- libraries/entities/src/ShapeEntityItem.cpp | 20 ++++++++++++------- libraries/render-utils/src/GeometryCache.cpp | 21 +------------------- 2 files changed, 14 insertions(+), 27 deletions(-) diff --git a/libraries/entities/src/ShapeEntityItem.cpp b/libraries/entities/src/ShapeEntityItem.cpp index 655283a601..8d68e0ab00 100644 --- a/libraries/entities/src/ShapeEntityItem.cpp +++ b/libraries/entities/src/ShapeEntityItem.cpp @@ -283,15 +283,23 @@ void ShapeEntityItem::computeShapeInfo(ShapeInfo& info) { } break; - // gons, ones, & angles built via GeometryCache::extrudePolygon - case entity::Shape::Triangle: - case entity::Shape::Hexagon: - case entity::Shape::Octagon: case entity::Shape::Cone: { if (shapeCalculator) { shapeCalculator(this, info); // shapeCalculator only supports convex shapes (e.g. SHAPE_TYPE_HULL) - // TODO: figure out how to support concave shapes + _collisionShapeType = SHAPE_TYPE_SIMPLE_HULL; + } else { + _collisionShapeType = SHAPE_TYPE_ELLIPSOID; + } + } + break; + // gons, ones, & angles built via GeometryCache::extrudePolygon + case entity::Shape::Triangle: + case entity::Shape::Hexagon: + case entity::Shape::Octagon: { + if (shapeCalculator) { + shapeCalculator(this, info); + // shapeCalculator only supports convex shapes (e.g. SHAPE_TYPE_HULL) _collisionShapeType = SHAPE_TYPE_SIMPLE_HULL; } else { _collisionShapeType = SHAPE_TYPE_ELLIPSOID; @@ -306,12 +314,10 @@ void ShapeEntityItem::computeShapeInfo(ShapeInfo& info) { if ( shapeCalculator ) { shapeCalculator(this, info); // shapeCalculator only supports convex shapes (e.g. SHAPE_TYPE_HULL) - // TODO: figure out how to support concave shapes _collisionShapeType = SHAPE_TYPE_SIMPLE_HULL; } else { _collisionShapeType = SHAPE_TYPE_ELLIPSOID; } - } break; case entity::Shape::Torus: { diff --git a/libraries/render-utils/src/GeometryCache.cpp b/libraries/render-utils/src/GeometryCache.cpp index 004f33cd1c..8164a54a57 100644 --- a/libraries/render-utils/src/GeometryCache.cpp +++ b/libraries/render-utils/src/GeometryCache.cpp @@ -108,31 +108,12 @@ void GeometryCache::computeSimpleHullPointListForShape(const ShapeEntityItem * c const gpu::BufferView::Size numItems = shapeVerts.getNumElements(); const glm::vec3 halfExtents = shapePtr->getDimensions() * 0.5f; -#if DEBUG_SIMPLE_HULL_POINT_GENERATION - shapePtr->debugDump(); - qCDebug(entities) << "------------------ Begin Vert Info( ComputeShapeInfo )[FlatShapes] -----------------------------"; - qCDebug(entities) << " name:" << shapePtr->getName() << ": has " << numItems << " vert info pairs."; -#endif + outPointList.reserve((int)numItems); for (gpu::BufferView::Index i = 0; i < (gpu::BufferView::Index)numItems; ++i) { const geometry::Vec &curNorm = shapeNorms.get(i); -#if DEBUG_SIMPLE_HULL_POINT_GENERATION - const geometry::Vec &curVert = shapeVerts.get(i); - qCDebug(entities) << " --------------------"; - qCDebug(entities) << " Vert( " << i << " ): " << debugTreeVector(curVert); - qCDebug(entities) << " Norm( " << i << " ): " << debugTreeVector(curNorm); -#endif outPointList.push_back(curNorm * halfExtents); - -#if DEBUG_SIMPLE_HULL_POINT_GENERATION - qCDebug(entities) << " Point( " << i << " ): " << debugTreeVector((curNorm * halfExtents)); -#endif } - -#if DEBUG_SIMPLE_HULL_POINT_GENERATION - qCDebug(entities) << "-------------------- End Vert Info( ComputeShapeInfo ) -----------------------------"; -#endif - } template From 7f9ce5a4cd3749482a9e7446aa0a3a064620b51d Mon Sep 17 00:00:00 2001 From: LaShonda Hopper Date: Mon, 2 Oct 2017 17:47:51 -0400 Subject: [PATCH 32/60] [WL21389][BuildFix] Minor refactor due to render-utils lib change (details below). As of Commit b93e91b9, render-utils no longer knows about entity lib. This commit adjusts for that by altering the signature of GeometryCache::computeSimpleHullPointListForShape to take in portions of ShapeEntityItem data as opposed to the entity pointer. Fixes build failure mentioned in: https://github.com/highfidelity/hifi/pull/11336#issuecomment-333635794 Reviewed-by: Leander Hasty Changes Committed: modified: interface/src/Util.cpp modified: libraries/render-utils/src/GeometryCache.cpp modified: libraries/render-utils/src/GeometryCache.h --- interface/src/Util.cpp | 9 +++++- libraries/render-utils/src/GeometryCache.cpp | 34 +++++++++++--------- libraries/render-utils/src/GeometryCache.h | 3 +- 3 files changed, 28 insertions(+), 18 deletions(-) diff --git a/interface/src/Util.cpp b/interface/src/Util.cpp index 6077c8ec42..9fdd5e4b76 100644 --- a/interface/src/Util.cpp +++ b/interface/src/Util.cpp @@ -396,11 +396,18 @@ void runUnitTests() { } void shapeInfoCalculator(const ShapeEntityItem * const shapeEntity, ShapeInfo &shapeInfo) { + + if (shapeEntity == nullptr) { + + //--EARLY EXIT-- + return; + } + ShapeInfo::PointCollection pointCollection; ShapeInfo::PointList points; pointCollection.push_back(points); - GeometryCache::computeSimpleHullPointListForShape(shapeEntity, pointCollection.back()); + GeometryCache::computeSimpleHullPointListForShape((int)shapeEntity->getShape(), shapeEntity->getDimensions() * 0.5f, pointCollection.back()); shapeInfo.setPointCollection(pointCollection); } diff --git a/libraries/render-utils/src/GeometryCache.cpp b/libraries/render-utils/src/GeometryCache.cpp index 8164a54a57..6a624e2cd8 100644 --- a/libraries/render-utils/src/GeometryCache.cpp +++ b/libraries/render-utils/src/GeometryCache.cpp @@ -23,7 +23,6 @@ #include #include -#include #include "TextureCache.h" #include "RenderUtilsLogging.h" @@ -53,7 +52,12 @@ //#define WANT_DEBUG -static std::array MAPPING{ { +// @note: Originally size entity::NUM_SHAPES +// As of Commit b93e91b9, render-utils no longer retains knowledge of +// entity lib, and thus doesn't know about entity::NUM_SHAPES. Should +// the enumerations be altered, this will need to be updated. +// @see ShapeEntityItem.h +static std::array MAPPING{ { GeometryCache::Triangle, GeometryCache::Quad, GeometryCache::Hexagon, @@ -88,16 +92,11 @@ static gpu::Stream::FormatPointer INSTANCED_SOLID_FADE_STREAM_FORMAT; static const uint SHAPE_VERTEX_STRIDE = sizeof(glm::vec3) * 2; // vertices and normals static const uint SHAPE_NORMALS_OFFSET = sizeof(glm::vec3); -void GeometryCache::computeSimpleHullPointListForShape(const ShapeEntityItem * const shapePtr, QVector &outPointList){ - - if (shapePtr == nullptr){ - //--EARLY EXIT-- - return; - } +void GeometryCache::computeSimpleHullPointListForShape(const int entityShape, const glm::vec3 &entityHalfExtents, QVector &outPointList) { auto geometryCache = DependencyManager::get(); - const GeometryCache::Shape entityGeometryShape = GeometryCache::getShapeForEntityShape(shapePtr->getShape()); - const GeometryCache::ShapeData * shapeData = geometryCache->getShapeData( entityGeometryShape ); + const GeometryCache::Shape geometryShape = GeometryCache::getShapeForEntityShape( entityShape ); + const GeometryCache::ShapeData * shapeData = geometryCache->getShapeData( geometryShape ); if (!shapeData){ //--EARLY EXIT--( data isn't ready for some reason... ) return; @@ -107,12 +106,11 @@ void GeometryCache::computeSimpleHullPointListForShape(const ShapeEntityItem * c assert(shapeVerts._size == shapeNorms._size); const gpu::BufferView::Size numItems = shapeVerts.getNumElements(); - const glm::vec3 halfExtents = shapePtr->getDimensions() * 0.5f; outPointList.reserve((int)numItems); for (gpu::BufferView::Index i = 0; i < (gpu::BufferView::Index)numItems; ++i) { const geometry::Vec &curNorm = shapeNorms.get(i); - outPointList.push_back(curNorm * halfExtents); + outPointList.push_back(curNorm * entityHalfExtents); } } @@ -488,14 +486,17 @@ void GeometryCache::buildShapes() { extrudePolygon<64>(_shapes[Cone], _shapeVertices, _shapeIndices, true); //Circle drawCircle(_shapes[Circle], _shapeVertices, _shapeIndices); - // Not implememented yet: + // Not implemented yet: //Quad, //Torus, } const GeometryCache::ShapeData * GeometryCache::getShapeData(const Shape shape) const { - if (((int)shape < 0) || ((int)shape >= (int)_shapes.size())){ + if (((int)shape < 0) || ((int)shape >= (int)_shapes.size())) { + qCWarning(renderutils) << "GeometryCache::getShapeData - Invalid shape " << shape << " specified. Returning default fallback."; + + //--EARLY EXIT--( No valid shape data for shape ) return nullptr; } @@ -503,7 +504,10 @@ const GeometryCache::ShapeData * GeometryCache::getShapeData(const Shape shape) } GeometryCache::Shape GeometryCache::getShapeForEntityShape(int entityShape) { - if ((entityShape < 0) || (entityShape >= (int)MAPPING.size())){ + if ((entityShape < 0) || (entityShape >= (int)MAPPING.size())) { + qCWarning(renderutils) << "GeometryCache::getShapeForEntityShape - Invalid shape " << entityShape << " specified. Returning default fallback."; + + //--EARLY EXIT--( fall back to default assumption ) return GeometryCache::Sphere; } diff --git a/libraries/render-utils/src/GeometryCache.h b/libraries/render-utils/src/GeometryCache.h index 867c4bc3ee..2e81c825be 100644 --- a/libraries/render-utils/src/GeometryCache.h +++ b/libraries/render-utils/src/GeometryCache.h @@ -32,7 +32,6 @@ #include class SimpleProgramKey; -class ShapeEntityItem; typedef QPair Vec2FloatPair; typedef QPair Vec2FloatPairPair; @@ -155,7 +154,7 @@ public: /// specified entityShapeEnum static GeometryCache::Shape getShapeForEntityShape(int entityShapeEnum); - static void computeSimpleHullPointListForShape(const ShapeEntityItem * const shapePtr, QVector &outPointList); + static void computeSimpleHullPointListForShape(int entityShape, const glm::vec3 &entityHalfExtents, QVector &outPointList); static uint8_t CUSTOM_PIPELINE_NUMBER; static render::ShapePipelinePointer shapePipelineFactory(const render::ShapePlumber& plumber, const render::ShapeKey& key); From dbd1a800467ccdf171ecba39144a120856114c04 Mon Sep 17 00:00:00 2001 From: LaShonda Hopper Date: Mon, 9 Oct 2017 17:49:13 -0400 Subject: [PATCH 33/60] [WL21389] Set Simulation::DIRTY_SHAPE flag when entity::Shape changes (details below). * Fixes an issue where ShapeEntityItem's collisionShapeType wasn't updated when its entity::Shape type was changed. * Adds getNameForShapeType static method to ShapeInfo. ** Moves shapeTypeNames[] from EntityItemProperties.cpp to ShapeInfo.cpp * Adds collisionShapeType to ShapeEntityItem::debugDump * Tested creating shapes within the Creation Menu: ** Create Menu -> (Box/Sphere) *** Observe Properties tab auto-focus ** From Properties tab elect alternate shape type from the Shape Dropdown list. NOTE: While this fixes an issue with the collision shape, it doesn't completely resolve the issues seen with the polyhedra or polygonal shapes noticed on RELEASE-7130 rebase. Reviewed-by: Leander Hasty Changes Committed: modified: libraries/entities/src/EntityItemProperties.cpp modified: libraries/entities/src/ShapeEntityItem.cpp modified: libraries/shared/src/ShapeInfo.cpp modified: libraries/shared/src/ShapeInfo.h --- .../entities/src/EntityItemProperties.cpp | 23 ++------------- libraries/entities/src/ShapeEntityItem.cpp | 7 +++++ libraries/shared/src/ShapeInfo.cpp | 29 +++++++++++++++++++ libraries/shared/src/ShapeInfo.h | 2 ++ 4 files changed, 40 insertions(+), 21 deletions(-) diff --git a/libraries/entities/src/EntityItemProperties.cpp b/libraries/entities/src/EntityItemProperties.cpp index 51ed66bb23..3bbd6ce8e6 100644 --- a/libraries/entities/src/EntityItemProperties.cpp +++ b/libraries/entities/src/EntityItemProperties.cpp @@ -84,28 +84,11 @@ void EntityItemProperties::setLastEdited(quint64 usecTime) { _lastEdited = usecTime > _created ? usecTime : _created; } -const char* shapeTypeNames[] = { - "none", - "box", - "sphere", - "capsule-x", - "capsule-y", - "capsule-z", - "cylinder-x", - "cylinder-y", - "cylinder-z", - "hull", - "plane", - "compound", - "simple-hull", - "simple-compound", - "static-mesh" -}; QHash stringToShapeTypeLookup; void addShapeType(ShapeType type) { - stringToShapeTypeLookup[shapeTypeNames[type]] = type; + stringToShapeTypeLookup[ShapeInfo::getNameForShapeType(type)] = type; } void buildStringToShapeTypeLookup() { @@ -180,9 +163,7 @@ void EntityItemProperties::setCollisionMaskFromString(const QString& maskString) } QString EntityItemProperties::getShapeTypeAsString() const { - if (_shapeType < sizeof(shapeTypeNames) / sizeof(char *)) - return QString(shapeTypeNames[_shapeType]); - return QString(shapeTypeNames[SHAPE_TYPE_NONE]); + return ShapeInfo::getNameForShapeType(_shapeType); } void EntityItemProperties::setShapeTypeFromString(const QString& shapeName) { diff --git a/libraries/entities/src/ShapeEntityItem.cpp b/libraries/entities/src/ShapeEntityItem.cpp index 8d68e0ab00..9a1a500a54 100644 --- a/libraries/entities/src/ShapeEntityItem.cpp +++ b/libraries/entities/src/ShapeEntityItem.cpp @@ -95,6 +95,7 @@ EntityItemProperties ShapeEntityItem::getProperties(EntityPropertyFlags desiredP } void ShapeEntityItem::setShape(const entity::Shape& shape) { + const entity::Shape prevShape = _shape; _shape = shape; switch (_shape) { case entity::Shape::Cube: @@ -107,6 +108,11 @@ void ShapeEntityItem::setShape(const entity::Shape& shape) { _type = EntityTypes::Shape; break; } + + if (_shape != prevShape) { + // Internally grabs writeLock + markDirtyFlags(Simulation::DIRTY_SHAPE); + } } bool ShapeEntityItem::setProperties(const EntityItemProperties& properties) { @@ -227,6 +233,7 @@ void ShapeEntityItem::debugDump() const { qCDebug(entities) << "SHAPE EntityItem id:" << getEntityItemID() << "---------------------------------------------"; qCDebug(entities) << " name:" << _name; qCDebug(entities) << " shape:" << stringFromShape(_shape) << " (EnumId: " << _shape << " )"; + qCDebug(entities) << " collisionShapeType:" << ShapeInfo::getNameForShapeType(getShapeType()); qCDebug(entities) << " color:" << _color[0] << "," << _color[1] << "," << _color[2]; qCDebug(entities) << " position:" << debugTreeVector(getPosition()); qCDebug(entities) << " dimensions:" << debugTreeVector(getDimensions()); diff --git a/libraries/shared/src/ShapeInfo.cpp b/libraries/shared/src/ShapeInfo.cpp index c56b722b61..592f692f5a 100644 --- a/libraries/shared/src/ShapeInfo.cpp +++ b/libraries/shared/src/ShapeInfo.cpp @@ -15,9 +15,38 @@ #include "NumericalConstants.h" // for MILLIMETERS_PER_METER +// Originally within EntityItemProperties.cpp +const char* shapeTypeNames[] = { + "none", + "box", + "sphere", + "capsule-x", + "capsule-y", + "capsule-z", + "cylinder-x", + "cylinder-y", + "cylinder-z", + "hull", + "plane", + "compound", + "simple-hull", + "simple-compound", + "static-mesh" +}; + +static const size_t SHAPETYPE_NAME_COUNT = (sizeof(shapeTypeNames) / sizeof((shapeTypeNames)[0])); + // Bullet doesn't support arbitrarily small shapes const float MIN_HALF_EXTENT = 0.005f; // 0.5 cm +QString ShapeInfo::getNameForShapeType(ShapeType type) { + if (((int)type <= 0) || ((int)type >= SHAPETYPE_NAME_COUNT)) { + type = (ShapeType)0; + } + + return shapeTypeNames[(int)type]; +} + void ShapeInfo::clear() { _url.clear(); _pointCollection.clear(); diff --git a/libraries/shared/src/ShapeInfo.h b/libraries/shared/src/ShapeInfo.h index cab487e07a..d658b936a3 100644 --- a/libraries/shared/src/ShapeInfo.h +++ b/libraries/shared/src/ShapeInfo.h @@ -58,6 +58,8 @@ public: using PointCollection = QVector; using TriangleIndices = QVector; + static QString getNameForShapeType(ShapeType type); + void clear(); void setParams(ShapeType type, const glm::vec3& halfExtents, QString url=""); From a9fea4c7d326b770cb639cc979497c575deb5d72 Mon Sep 17 00:00:00 2001 From: LaShonda Hopper Date: Tue, 10 Oct 2017 15:36:45 -0400 Subject: [PATCH 34/60] [WL21389] Minor fix to RenderableShapeEntityItem::doRender (details below). Shape isn't guaranteed to be permanent and thus the triangle count isn't guaranteed to be the same since inception, so grab it each time. Changes to be committed: modified: libraries/entities-renderer/src/RenderableShapeEntityItem.cpp --- libraries/entities-renderer/src/RenderableShapeEntityItem.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/entities-renderer/src/RenderableShapeEntityItem.cpp b/libraries/entities-renderer/src/RenderableShapeEntityItem.cpp index a72320fda0..332d87f930 100644 --- a/libraries/entities-renderer/src/RenderableShapeEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableShapeEntityItem.cpp @@ -154,6 +154,6 @@ void ShapeEntityRenderer::doRender(RenderArgs* args) { } } - static const auto triCount = geometryCache->getShapeTriangleCount(geometryShape); + const auto triCount = geometryCache->getShapeTriangleCount(geometryShape); args->_details._trianglesRendered += (int)triCount; } From 8cc20e6b7155f682a2fcc4961cb3c0d65687cc6a Mon Sep 17 00:00:00 2001 From: LaShonda Hopper Date: Tue, 10 Oct 2017 15:39:49 -0400 Subject: [PATCH 35/60] Minor: Fixes comment typo. Changes to be committed: modified: libraries/physics/src/ObjectMotionState.h --- libraries/physics/src/ObjectMotionState.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/physics/src/ObjectMotionState.h b/libraries/physics/src/ObjectMotionState.h index 81bfbc72b4..0b91ede574 100644 --- a/libraries/physics/src/ObjectMotionState.h +++ b/libraries/physics/src/ObjectMotionState.h @@ -66,7 +66,7 @@ class PhysicsEngine; class ObjectMotionState : public btMotionState { public: - // These poroperties of the PhysicsEngine are "global" within the context of all ObjectMotionStates + // These properties of the PhysicsEngine are "global" within the context of all ObjectMotionStates // (assuming just one PhysicsEngine). They are cached as statics for fast calculations in the // ObjectMotionState context. static void setWorldOffset(const glm::vec3& offset); From 9d64a3b9916eab5f008a7f6964f59529ad91a36e Mon Sep 17 00:00:00 2001 From: LaShonda Hopper Date: Wed, 11 Oct 2017 13:13:07 -0400 Subject: [PATCH 36/60] [WL21389] Fixes warnings from last commit (details below). * Fixes int vs size_t comparison warning within ShapeInfo. * Fixes unused var warning for shapeVerts local var within GeometryCache. This should fix the mac & ubuntu builds. Changes Committed: modified: libraries/render-utils/src/GeometryCache.cpp modified: libraries/shared/src/ShapeInfo.cpp --- libraries/render-utils/src/GeometryCache.cpp | 5 +++-- libraries/shared/src/ShapeInfo.cpp | 2 +- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/libraries/render-utils/src/GeometryCache.cpp b/libraries/render-utils/src/GeometryCache.cpp index 6a624e2cd8..5cced0fcaa 100644 --- a/libraries/render-utils/src/GeometryCache.cpp +++ b/libraries/render-utils/src/GeometryCache.cpp @@ -101,13 +101,14 @@ void GeometryCache::computeSimpleHullPointListForShape(const int entityShape, co //--EARLY EXIT--( data isn't ready for some reason... ) return; } - const gpu::BufferView & shapeVerts = shapeData->_positionView; + const gpu::BufferView & shapeNorms = shapeData->_normalView; - assert(shapeVerts._size == shapeNorms._size); + assert(shapeData->_positionView._size == shapeNorms._size); const gpu::BufferView::Size numItems = shapeVerts.getNumElements(); outPointList.reserve((int)numItems); + for (gpu::BufferView::Index i = 0; i < (gpu::BufferView::Index)numItems; ++i) { const geometry::Vec &curNorm = shapeNorms.get(i); outPointList.push_back(curNorm * entityHalfExtents); diff --git a/libraries/shared/src/ShapeInfo.cpp b/libraries/shared/src/ShapeInfo.cpp index 592f692f5a..d93b70e98c 100644 --- a/libraries/shared/src/ShapeInfo.cpp +++ b/libraries/shared/src/ShapeInfo.cpp @@ -40,7 +40,7 @@ static const size_t SHAPETYPE_NAME_COUNT = (sizeof(shapeTypeNames) / sizeof((sha const float MIN_HALF_EXTENT = 0.005f; // 0.5 cm QString ShapeInfo::getNameForShapeType(ShapeType type) { - if (((int)type <= 0) || ((int)type >= SHAPETYPE_NAME_COUNT)) { + if (((int)type <= 0) || ((int)type >= (int)SHAPETYPE_NAME_COUNT)) { type = (ShapeType)0; } From e74ebd53c62f725837f8a74c83bb4c00a84ad71e Mon Sep 17 00:00:00 2001 From: LaShonda Hopper Date: Wed, 11 Oct 2017 17:11:15 -0400 Subject: [PATCH 37/60] [WL21389] Add SHAPE_TYPE_SIMPLE_HULL case to ShapeInfo::getHash (details below). Generates hashes for Simple Hull instances by incorporating their point list into the hash as opposed to the extents. Reviewed-by: Leander Hasty Changes Committed: modified: libraries/shared/src/ShapeInfo.cpp --- libraries/shared/src/ShapeInfo.cpp | 92 +++++++++++++++++++++--------- 1 file changed, 66 insertions(+), 26 deletions(-) diff --git a/libraries/shared/src/ShapeInfo.cpp b/libraries/shared/src/ShapeInfo.cpp index d93b70e98c..9397f834f9 100644 --- a/libraries/shared/src/ShapeInfo.cpp +++ b/libraries/shared/src/ShapeInfo.cpp @@ -234,7 +234,6 @@ bool ShapeInfo::contains(const glm::vec3& point) const { } const DoubleHashKey& ShapeInfo::getHash() const { - //TODO WL21389: Need to include the pointlist for SIMPLE_HULL in hash // NOTE: we cache the key so we only ever need to compute it once for any valid ShapeInfo instance. if (_doubleHashKey.isNull() && _type != SHAPE_TYPE_NONE) { bool useOffset = glm::length2(_offset) > MIN_SHAPE_OFFSET * MIN_SHAPE_OFFSET; @@ -245,41 +244,82 @@ const DoubleHashKey& ShapeInfo::getHash() const { uint32_t primeIndex = 0; _doubleHashKey.computeHash((uint32_t)_type, primeIndex++); - // compute hash1 - uint32_t hash = _doubleHashKey.getHash(); - for (int j = 0; j < 3; ++j) { - // NOTE: 0.49f is used to bump the float up almost half a millimeter - // so the cast to int produces a round() effect rather than a floor() - hash ^= DoubleHashKey::hashFunction( + if (_type != SHAPE_TYPE_SIMPLE_HULL) { + // compute hash1 + uint32_t hash = _doubleHashKey.getHash(); + for (int j = 0; j < 3; ++j) { + // NOTE: 0.49f is used to bump the float up almost half a millimeter + // so the cast to int produces a round() effect rather than a floor() + hash ^= DoubleHashKey::hashFunction( (uint32_t)(_halfExtents[j] * MILLIMETERS_PER_METER + copysignf(1.0f, _halfExtents[j]) * 0.49f), primeIndex++); - if (useOffset) { - hash ^= DoubleHashKey::hashFunction( + if (useOffset) { + hash ^= DoubleHashKey::hashFunction( (uint32_t)(_offset[j] * MILLIMETERS_PER_METER + copysignf(1.0f, _offset[j]) * 0.49f), primeIndex++); + } } - } - _doubleHashKey.setHash(hash); + _doubleHashKey.setHash(hash); - // compute hash2 - hash = _doubleHashKey.getHash2(); - for (int j = 0; j < 3; ++j) { - // NOTE: 0.49f is used to bump the float up almost half a millimeter - // so the cast to int produces a round() effect rather than a floor() - uint32_t floatHash = DoubleHashKey::hashFunction2( + // compute hash2 + hash = _doubleHashKey.getHash2(); + for (int j = 0; j < 3; ++j) { + // NOTE: 0.49f is used to bump the float up almost half a millimeter + // so the cast to int produces a round() effect rather than a floor() + uint32_t floatHash = DoubleHashKey::hashFunction2( (uint32_t)(_halfExtents[j] * MILLIMETERS_PER_METER + copysignf(1.0f, _halfExtents[j]) * 0.49f)); - if (useOffset) { - floatHash ^= DoubleHashKey::hashFunction2( + if (useOffset) { + floatHash ^= DoubleHashKey::hashFunction2( (uint32_t)(_offset[j] * MILLIMETERS_PER_METER + copysignf(1.0f, _offset[j]) * 0.49f)); + } + hash += ~(floatHash << 17); + hash ^= (floatHash >> 11); + hash += (floatHash << 4); + hash ^= (floatHash >> 7); + hash += ~(floatHash << 10); + hash = (hash << 16) | (hash >> 16); } - hash += ~(floatHash << 17); - hash ^= (floatHash >> 11); - hash += (floatHash << 4); - hash ^= (floatHash >> 7); - hash += ~(floatHash << 10); - hash = (hash << 16) | (hash >> 16); + _doubleHashKey.setHash2(hash); + } else { + + assert(_pointCollection.size() == (size_t)1); + const PointList & points = _pointCollection.back(); + const size_t numPoints = points.size(); + uint32_t hash = _doubleHashKey.getHash(); + uint32_t hash2 = _doubleHashKey.getHash2(); + + for (int pointIndex = 0; pointIndex < numPoints; ++pointIndex) { + // compute hash1 & 2 + const glm::vec3 &curPoint = points[pointIndex]; + for (int vecCompIndex = 0; vecCompIndex < 3; ++vecCompIndex) { + + // NOTE: 0.49f is used to bump the float up almost half a millimeter + // so the cast to int produces a round() effect rather than a floor() + uint32_t valueToHash = (uint32_t)(curPoint[vecCompIndex] * MILLIMETERS_PER_METER + copysignf(1.0f, curPoint[vecCompIndex]) * 0.49f); + + hash ^= DoubleHashKey::hashFunction(valueToHash, primeIndex++); + uint32_t floatHash = DoubleHashKey::hashFunction2(valueToHash); + + if (useOffset) { + + const uint32_t offsetValToHash = (uint32_t)(_offset[vecCompIndex] * MILLIMETERS_PER_METER + copysignf(1.0f, _offset[vecCompIndex])* 0.49f); + + hash ^= DoubleHashKey::hashFunction(offsetValToHash, primeIndex++); + floatHash ^= DoubleHashKey::hashFunction2(offsetValToHash); + } + + hash2 += ~(floatHash << 17); + hash2 ^= (floatHash >> 11); + hash2 += (floatHash << 4); + hash2 ^= (floatHash >> 7); + hash2 += ~(floatHash << 10); + hash2 = (hash2 << 16) | (hash2 >> 16); + } + } + + _doubleHashKey.setHash(hash); + _doubleHashKey.setHash2(hash2); } - _doubleHashKey.setHash2(hash); if (_type == SHAPE_TYPE_COMPOUND || _type == SHAPE_TYPE_STATIC_MESH) { QString url = _url.toString(); From 0ad95806e3868cb21616b2deb481b79f19702320 Mon Sep 17 00:00:00 2001 From: LaShonda Hopper Date: Thu, 12 Oct 2017 16:51:03 -0400 Subject: [PATCH 38/60] [WL21389] Update point list function in line with GeometryCache::ShapeData update. Changes Committed: modified: libraries/render-utils/src/GeometryCache.cpp --- libraries/render-utils/src/GeometryCache.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/render-utils/src/GeometryCache.cpp b/libraries/render-utils/src/GeometryCache.cpp index 5cced0fcaa..1cbb33252a 100644 --- a/libraries/render-utils/src/GeometryCache.cpp +++ b/libraries/render-utils/src/GeometryCache.cpp @@ -105,7 +105,7 @@ void GeometryCache::computeSimpleHullPointListForShape(const int entityShape, co const gpu::BufferView & shapeNorms = shapeData->_normalView; assert(shapeData->_positionView._size == shapeNorms._size); - const gpu::BufferView::Size numItems = shapeVerts.getNumElements(); + const gpu::BufferView::Size numItems = shapeNorms.getNumElements(); outPointList.reserve((int)numItems); From 5c8e73bb54023a0930967df5e1b183517e5dd39b Mon Sep 17 00:00:00 2001 From: LaShonda Hopper Date: Thu, 12 Oct 2017 16:57:07 -0400 Subject: [PATCH 39/60] [WL21389] Minor: Fix size_t vs int comparison warning. Changes Committed: modified: libraries/shared/src/ShapeInfo.cpp --- libraries/shared/src/ShapeInfo.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/shared/src/ShapeInfo.cpp b/libraries/shared/src/ShapeInfo.cpp index 9397f834f9..d9931abbd5 100644 --- a/libraries/shared/src/ShapeInfo.cpp +++ b/libraries/shared/src/ShapeInfo.cpp @@ -284,7 +284,7 @@ const DoubleHashKey& ShapeInfo::getHash() const { assert(_pointCollection.size() == (size_t)1); const PointList & points = _pointCollection.back(); - const size_t numPoints = points.size(); + const int numPoints = (int)points.size(); uint32_t hash = _doubleHashKey.getHash(); uint32_t hash2 = _doubleHashKey.getHash2(); From d3e4d22ce1aad0841e6374b1292a09745f62cfaf Mon Sep 17 00:00:00 2001 From: LaShonda Hopper Date: Fri, 13 Oct 2017 14:34:24 -0400 Subject: [PATCH 40/60] [WL21389] Resolve ShapeInfo todos (details below). * Added remaining cylinder/capsule shapes to computeVolume * Point lists are generated during computeShapeInfo, so shouldn't need to be cleared within setParams. ** setSphere/setBox appear to be clear as they're used in tests or in local scopes without using point data. Reviewed-by: Leander Hasty Changes Committed: modified: libraries/shared/src/ShapeInfo.cpp --- libraries/shared/src/ShapeInfo.cpp | 52 +++++++++++++++++++++--------- 1 file changed, 37 insertions(+), 15 deletions(-) diff --git a/libraries/shared/src/ShapeInfo.cpp b/libraries/shared/src/ShapeInfo.cpp index d9931abbd5..59ce859790 100644 --- a/libraries/shared/src/ShapeInfo.cpp +++ b/libraries/shared/src/ShapeInfo.cpp @@ -58,7 +58,6 @@ void ShapeInfo::clear() { } void ShapeInfo::setParams(ShapeType type, const glm::vec3& halfExtents, QString url) { - //TODO WL21389: Does this need additional cases and handling added? _url = ""; _type = type; setHalfExtents(halfExtents); @@ -67,6 +66,8 @@ void ShapeInfo::setParams(ShapeType type, const glm::vec3& halfExtents, QString _halfExtents = glm::vec3(0.0f); break; case SHAPE_TYPE_BOX: + case SHAPE_TYPE_HULL: + case SHAPE_TYPE_SIMPLE_HULL: break; case SHAPE_TYPE_SPHERE: { float radius = glm::length(halfExtents) / SQUARE_ROOT_OF_3; @@ -89,9 +90,6 @@ void ShapeInfo::setParams(ShapeType type, const glm::vec3& halfExtents, QString } void ShapeInfo::setBox(const glm::vec3& halfExtents) { - //TODO WL21389: Should this pointlist clearance added in case - // this is a re-purposed instance? - // See https://github.com/highfidelity/hifi/pull/11024#discussion_r128885491 _url = ""; _type = SHAPE_TYPE_BOX; setHalfExtents(halfExtents); @@ -99,7 +97,6 @@ void ShapeInfo::setBox(const glm::vec3& halfExtents) { } void ShapeInfo::setSphere(float radius) { - //TODO WL21389: See comment in setBox regarding clearance _url = ""; _type = SHAPE_TYPE_SPHERE; radius = glm::max(radius, MIN_HALF_EXTENT); @@ -113,7 +110,6 @@ void ShapeInfo::setPointCollection(const ShapeInfo::PointCollection& pointCollec } void ShapeInfo::setCapsuleY(float radius, float halfHeight) { - //TODO WL21389: See comment in setBox regarding clearance _url = ""; _type = SHAPE_TYPE_CAPSULE_Y; radius = glm::max(radius, MIN_HALF_EXTENT); @@ -154,8 +150,15 @@ int ShapeInfo::getLargestSubshapePointCount() const { return numPoints; } +float computeCylinderVolume(const float radius, const float height) { + return PI * radius * radius * 2.0f * height; +} + +float computeCapsuleVolume(const float radius, const float cylinderHeight) { + return PI * radius * radius * (cylinderHeight + 4.0f * radius / 3.0f); +} + float ShapeInfo::computeVolume() const { - //TODO WL21389: Add support for other ShapeTypes( CYLINDER_X, CYLINDER_Z, etc). const float DEFAULT_VOLUME = 1.0f; float volume = DEFAULT_VOLUME; switch(_type) { @@ -168,17 +171,37 @@ float ShapeInfo::computeVolume() const { volume = 4.0f * PI * _halfExtents.x * _halfExtents.y * _halfExtents.z / 3.0f; break; } + case SHAPE_TYPE_CYLINDER_X: { + volume = computeCylinderVolume(_halfExtents.y, _halfExtents.x); + break; + } case SHAPE_TYPE_CYLINDER_Y: { - float radius = _halfExtents.x; - volume = PI * radius * radius * 2.0f * _halfExtents.y; + volume = computeCylinderVolume(_halfExtents.x, _halfExtents.y); + break; + } + case SHAPE_TYPE_CYLINDER_Z: { + volume = computeCylinderVolume(_halfExtents.x, _halfExtents.z); + break; + } + case SHAPE_TYPE_CAPSULE_X: { + // Need to offset halfExtents.x by y to account for the system treating + // the x extent of the capsule as the cylindrical height + spherical radius. + const float cylinderHeight = 2.0f * (_halfExtents.x - _halfExtents.y); + volume = computeCapsuleVolume(_halfExtents.y, cylinderHeight); break; } case SHAPE_TYPE_CAPSULE_Y: { - float radius = _halfExtents.x; // Need to offset halfExtents.y by x to account for the system treating // the y extent of the capsule as the cylindrical height + spherical radius. - float cylinderHeight = 2.0f * (_halfExtents.y - _halfExtents.x); - volume = PI * radius * radius * (cylinderHeight + 4.0f * radius / 3.0f); + const float cylinderHeight = 2.0f * (_halfExtents.y - _halfExtents.x); + volume = computeCapsuleVolume(_halfExtents.x, cylinderHeight); + break; + } + case SHAPE_TYPE_CAPSULE_Z: { + // Need to offset halfExtents.z by x to account for the system treating + // the z extent of the capsule as the cylindrical height + spherical radius. + const float cylinderHeight = 2.0f * (_halfExtents.z - _halfExtents.x); + volume = computeCapsuleVolume(_halfExtents.x, cylinderHeight); break; } default: @@ -189,7 +212,6 @@ float ShapeInfo::computeVolume() const { } bool ShapeInfo::contains(const glm::vec3& point) const { - //TODO WL21389: Add support for other ShapeTypes like Ellipsoid/Compound. switch(_type) { case SHAPE_TYPE_SPHERE: return glm::length(point) <= _halfExtents.x; @@ -296,7 +318,7 @@ const DoubleHashKey& ShapeInfo::getHash() const { // NOTE: 0.49f is used to bump the float up almost half a millimeter // so the cast to int produces a round() effect rather than a floor() uint32_t valueToHash = (uint32_t)(curPoint[vecCompIndex] * MILLIMETERS_PER_METER + copysignf(1.0f, curPoint[vecCompIndex]) * 0.49f); - + hash ^= DoubleHashKey::hashFunction(valueToHash, primeIndex++); uint32_t floatHash = DoubleHashKey::hashFunction2(valueToHash); @@ -307,7 +329,7 @@ const DoubleHashKey& ShapeInfo::getHash() const { hash ^= DoubleHashKey::hashFunction(offsetValToHash, primeIndex++); floatHash ^= DoubleHashKey::hashFunction2(offsetValToHash); } - + hash2 += ~(floatHash << 17); hash2 ^= (floatHash >> 11); hash2 += (floatHash << 4); From 070660eb04328813168c938ed410e51a5de759b2 Mon Sep 17 00:00:00 2001 From: LaShonda Hopper Date: Tue, 17 Oct 2017 18:18:10 -0400 Subject: [PATCH 41/60] [WL21389] Switch to _positionView & filter dupe verts for ShapeInfo (details below). * Adjusts GeometryCache::computeSimpleHullPointListForShape to utilize ShapeData::_positionView as opposed to _normalView. ** Also filters out duplicate points or points close enough to be considered duplicate vertices. This provides ShapeFactory with better point data and should reduce hits to the dedupe pass within createConvexHull. Tested: * Octagon & Tetrahedron ** They looked better than the prior commit, behaved closer to their shape as opposed to cone or narrow cylinder like. Note: * These changes are based on debug info observations using the Octagon and discussion with Andrew Meadows via Slack & https://github.com/highfidelity/hifi/pull/11336#pullrequestreview-69939120 Changes Committed: modified: libraries/render-utils/src/GeometryCache.cpp modified: libraries/render-utils/src/GeometryCache.h --- libraries/render-utils/src/GeometryCache.cpp | 63 ++++++++++++++++++-- libraries/render-utils/src/GeometryCache.h | 1 + 2 files changed, 58 insertions(+), 6 deletions(-) diff --git a/libraries/render-utils/src/GeometryCache.cpp b/libraries/render-utils/src/GeometryCache.cpp index 1cbb33252a..f83e8ae14f 100644 --- a/libraries/render-utils/src/GeometryCache.cpp +++ b/libraries/render-utils/src/GeometryCache.cpp @@ -74,6 +74,23 @@ static std::array MAPPING GeometryCache::Cylinder, } }; +static const std::array GEOCACHE_SHAPE_STRINGS{ { + "Line", + "Triangle", + "Quad", + "Hexagon", + "Octagon", + "Circle", + "Cube", + "Sphere", + "Tetrahedron", + "Octahedron", + "Dodecahedron", + "Icosahedron", + "Torus", + "Cone", + "Cylinder" + } }; const int GeometryCache::UNKNOWN_ID = -1; @@ -102,16 +119,38 @@ void GeometryCache::computeSimpleHullPointListForShape(const int entityShape, co return; } - const gpu::BufferView & shapeNorms = shapeData->_normalView; - assert(shapeData->_positionView._size == shapeNorms._size); - - const gpu::BufferView::Size numItems = shapeNorms.getNumElements(); + const gpu::BufferView & shapeVerts = shapeData->_positionView; + const gpu::BufferView::Size numItems = shapeVerts.getNumElements(); outPointList.reserve((int)numItems); + QVector uniqueVerts; + uniqueVerts.reserve((int)numItems); + const float SQUARED_MAX_INCLUSIVE_FILTER_DISTANCE = 0.0025f; for (gpu::BufferView::Index i = 0; i < (gpu::BufferView::Index)numItems; ++i) { - const geometry::Vec &curNorm = shapeNorms.get(i); - outPointList.push_back(curNorm * entityHalfExtents); + const int numUniquePoints = (int)uniqueVerts.size(); + const geometry::Vec &curVert = shapeVerts.get(i); + bool isUniquePoint = true; + + for (int uniqueIndex = 0; uniqueIndex < numUniquePoints; ++uniqueIndex) { + const geometry::Vec knownVert = uniqueVerts[uniqueIndex]; + const float distToKnownPoint = glm::length2(knownVert - curVert); + + if (fabsf(distToKnownPoint) <= SQUARED_MAX_INCLUSIVE_FILTER_DISTANCE) { + isUniquePoint = false; + break; + } + } + + if (!isUniquePoint) { + + //--EARLY ITERATION EXIT-- + continue; + } + + + uniqueVerts.push_back(curVert); + outPointList.push_back(curVert * entityHalfExtents); } } @@ -515,6 +554,18 @@ GeometryCache::Shape GeometryCache::getShapeForEntityShape(int entityShape) { return MAPPING[entityShape]; } +QString GeometryCache::stringFromShape(GeometryCache::Shape geoShape) +{ + if (((int)geoShape < 0) || ((int)geoShape >= (int)GeometryCache::NUM_SHAPES)) { + qCWarning(renderutils) << "GeometryCache::stringFromShape - Invalid shape " << geoShape << " specified."; + + //--EARLY EXIT-- + return "INVALID_GEOCACHE_SHAPE"; + } + + return GEOCACHE_SHAPE_STRINGS[geoShape]; +} + gpu::Stream::FormatPointer& getSolidStreamFormat() { if (!SOLID_STREAM_FORMAT) { SOLID_STREAM_FORMAT = std::make_shared(); // 1 for everyone diff --git a/libraries/render-utils/src/GeometryCache.h b/libraries/render-utils/src/GeometryCache.h index 2e81c825be..5ee627bb93 100644 --- a/libraries/render-utils/src/GeometryCache.h +++ b/libraries/render-utils/src/GeometryCache.h @@ -153,6 +153,7 @@ public: /// the GeometryCache::Shape enum which aligns with the /// specified entityShapeEnum static GeometryCache::Shape getShapeForEntityShape(int entityShapeEnum); + static QString stringFromShape(GeometryCache::Shape geoShape); static void computeSimpleHullPointListForShape(int entityShape, const glm::vec3 &entityHalfExtents, QVector &outPointList); From d027993ac0a8040088765144bb79a636a6f933dd Mon Sep 17 00:00:00 2001 From: LaShonda Hopper Date: Wed, 18 Oct 2017 12:11:42 -0400 Subject: [PATCH 42/60] [WL21389] Address code review feedback (details below). * Renamed squared var to be consistent with format of others in the code base. * Removed fabsf() that was accidentally left in. * Reduced squared distance filter within GeometryCache::computeSimpleHullPointListForShape as suggested from 0.0025f to recommended 1.0e-6f (1mm^2). Feedback Link: https://github.com/highfidelity/hifi/pull/11336#pullrequestreview-70060918 Changes Committed: modified: libraries/render-utils/src/GeometryCache.cpp --- libraries/render-utils/src/GeometryCache.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libraries/render-utils/src/GeometryCache.cpp b/libraries/render-utils/src/GeometryCache.cpp index f83e8ae14f..3014fe9593 100644 --- a/libraries/render-utils/src/GeometryCache.cpp +++ b/libraries/render-utils/src/GeometryCache.cpp @@ -126,7 +126,7 @@ void GeometryCache::computeSimpleHullPointListForShape(const int entityShape, co QVector uniqueVerts; uniqueVerts.reserve((int)numItems); - const float SQUARED_MAX_INCLUSIVE_FILTER_DISTANCE = 0.0025f; + const float MAX_INCLUSIVE_FILTER_DISTANCE_SQUARED = 1.0e-6f; //< 1mm^2 for (gpu::BufferView::Index i = 0; i < (gpu::BufferView::Index)numItems; ++i) { const int numUniquePoints = (int)uniqueVerts.size(); const geometry::Vec &curVert = shapeVerts.get(i); @@ -136,7 +136,7 @@ void GeometryCache::computeSimpleHullPointListForShape(const int entityShape, co const geometry::Vec knownVert = uniqueVerts[uniqueIndex]; const float distToKnownPoint = glm::length2(knownVert - curVert); - if (fabsf(distToKnownPoint) <= SQUARED_MAX_INCLUSIVE_FILTER_DISTANCE) { + if (distToKnownPoint <= MAX_INCLUSIVE_FILTER_DISTANCE_SQUARED) { isUniquePoint = false; break; } From 226d51b8f52e9b2d5fa74eca55f162ceedc91cb7 Mon Sep 17 00:00:00 2001 From: LaShonda Hopper Date: Mon, 23 Oct 2017 16:44:33 -0400 Subject: [PATCH 43/60] [WL21389] Fix scaling issue when computing hull point list (details below). The entity dimensions should be scaled by 1 as opposed to 0.5. Changes Committed: modified: interface/src/Util.cpp modified: libraries/render-utils/src/GeometryCache.cpp modified: libraries/render-utils/src/GeometryCache.h --- interface/src/Util.cpp | 2 +- libraries/render-utils/src/GeometryCache.cpp | 4 ++-- libraries/render-utils/src/GeometryCache.h | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/interface/src/Util.cpp b/interface/src/Util.cpp index 9fdd5e4b76..aad7768b99 100644 --- a/interface/src/Util.cpp +++ b/interface/src/Util.cpp @@ -407,7 +407,7 @@ void shapeInfoCalculator(const ShapeEntityItem * const shapeEntity, ShapeInfo &s ShapeInfo::PointList points; pointCollection.push_back(points); - GeometryCache::computeSimpleHullPointListForShape((int)shapeEntity->getShape(), shapeEntity->getDimensions() * 0.5f, pointCollection.back()); + GeometryCache::computeSimpleHullPointListForShape((int)shapeEntity->getShape(), shapeEntity->getDimensions(), pointCollection.back()); shapeInfo.setPointCollection(pointCollection); } diff --git a/libraries/render-utils/src/GeometryCache.cpp b/libraries/render-utils/src/GeometryCache.cpp index 3014fe9593..9b73b371f7 100644 --- a/libraries/render-utils/src/GeometryCache.cpp +++ b/libraries/render-utils/src/GeometryCache.cpp @@ -109,7 +109,7 @@ static gpu::Stream::FormatPointer INSTANCED_SOLID_FADE_STREAM_FORMAT; static const uint SHAPE_VERTEX_STRIDE = sizeof(glm::vec3) * 2; // vertices and normals static const uint SHAPE_NORMALS_OFFSET = sizeof(glm::vec3); -void GeometryCache::computeSimpleHullPointListForShape(const int entityShape, const glm::vec3 &entityHalfExtents, QVector &outPointList) { +void GeometryCache::computeSimpleHullPointListForShape(const int entityShape, const glm::vec3 &entityExtents, QVector &outPointList) { auto geometryCache = DependencyManager::get(); const GeometryCache::Shape geometryShape = GeometryCache::getShapeForEntityShape( entityShape ); @@ -150,7 +150,7 @@ void GeometryCache::computeSimpleHullPointListForShape(const int entityShape, co uniqueVerts.push_back(curVert); - outPointList.push_back(curVert * entityHalfExtents); + outPointList.push_back(curVert * entityExtents); } } diff --git a/libraries/render-utils/src/GeometryCache.h b/libraries/render-utils/src/GeometryCache.h index 5ee627bb93..cd8c43f1df 100644 --- a/libraries/render-utils/src/GeometryCache.h +++ b/libraries/render-utils/src/GeometryCache.h @@ -155,7 +155,7 @@ public: static GeometryCache::Shape getShapeForEntityShape(int entityShapeEnum); static QString stringFromShape(GeometryCache::Shape geoShape); - static void computeSimpleHullPointListForShape(int entityShape, const glm::vec3 &entityHalfExtents, QVector &outPointList); + static void computeSimpleHullPointListForShape(int entityShape, const glm::vec3 &entityExtents, QVector &outPointList); static uint8_t CUSTOM_PIPELINE_NUMBER; static render::ShapePipelinePointer shapePipelineFactory(const render::ShapePlumber& plumber, const render::ShapeKey& key); From d1ab1c5e2632fe0db8a761b16978c60b6bfa770c Mon Sep 17 00:00:00 2001 From: LaShonda Hopper Date: Mon, 23 Oct 2017 16:47:23 -0400 Subject: [PATCH 44/60] [WL21389] Fixes issue with the ShapeData vert buffer offset (details below). When computing the buffer view offset for ShapeData the vertex vector size should be scaled by a single vec3 size as opposed to 2. This fix is taken from PR discussion: https://github.com/1P-Cusack/hifi/pull/10 Proposed by: Andrew Meadows Changes Committed: modified: libraries/render-utils/src/GeometryCache.cpp --- libraries/render-utils/src/GeometryCache.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/render-utils/src/GeometryCache.cpp b/libraries/render-utils/src/GeometryCache.cpp index 9b73b371f7..f35fb9f830 100644 --- a/libraries/render-utils/src/GeometryCache.cpp +++ b/libraries/render-utils/src/GeometryCache.cpp @@ -170,7 +170,7 @@ void GeometryCache::ShapeData::setupVertices(gpu::BufferPointer& vertexBuffer, c gpu::Buffer::Size offset = vertexBuffer->getSize(); vertexBuffer->append(vertices); - gpu::Buffer::Size viewSize = vertices.size() * 2 * sizeof(glm::vec3); + gpu::Buffer::Size viewSize = vertices.size() * sizeof(glm::vec3); _positionView = gpu::BufferView(vertexBuffer, offset, viewSize, SHAPE_VERTEX_STRIDE, POSITION_ELEMENT); From a1885926b57f8071c255bd8b605072e54c781435 Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Tue, 24 Oct 2017 11:46:42 -0700 Subject: [PATCH 45/60] some cleanup --- assignment-client/src/scripts/EntityScriptServer.cpp | 4 ++-- libraries/entities/src/EntityScriptingInterface.cpp | 9 ++++++++- libraries/networking/src/EntityScriptClient.cpp | 5 +---- libraries/networking/src/EntityScriptClient.h | 2 +- libraries/script-engine/src/ScriptEngine.cpp | 2 -- 5 files changed, 12 insertions(+), 10 deletions(-) diff --git a/assignment-client/src/scripts/EntityScriptServer.cpp b/assignment-client/src/scripts/EntityScriptServer.cpp index d627b019ef..8f4ce65579 100644 --- a/assignment-client/src/scripts/EntityScriptServer.cpp +++ b/assignment-client/src/scripts/EntityScriptServer.cpp @@ -30,7 +30,7 @@ #include #include -#include // for EntityScriptServerStub +#include // for EntityScriptServerServices #include "EntityScriptServerLogging.h" #include "../entities/AssignmentParentFinder.h" @@ -70,7 +70,7 @@ EntityScriptServer::EntityScriptServer(ReceivedMessage& message) : ThreadedAssig DependencyManager::set(); DependencyManager::set(ScriptEngine::ENTITY_SERVER_SCRIPT); - DependencyManager::set(); + DependencyManager::set(); // Needed to ensure the creation of the DebugDraw instance on the main thread diff --git a/libraries/entities/src/EntityScriptingInterface.cpp b/libraries/entities/src/EntityScriptingInterface.cpp index 4e556c83a3..d34c1e923f 100644 --- a/libraries/entities/src/EntityScriptingInterface.cpp +++ b/libraries/entities/src/EntityScriptingInterface.cpp @@ -577,7 +577,14 @@ void EntityScriptingInterface::callEntityServerMethod(QUuid id, const QString& m void EntityScriptingInterface::callEntityClientMethod(QUuid clientSessionID, QUuid entityID, const QString& method, const QStringList& params) { PROFILE_RANGE(script_entities, __FUNCTION__); - DependencyManager::get()->callEntityClientMethod(clientSessionID, entityID, method, params); + auto scriptServerServices = DependencyManager::get(); + + // this won't be available on clients + if (scriptServerServices) { + scriptServerServices->callEntityClientMethod(clientSessionID, entityID, method, params); + } else { + qWarning() << "Entities.callEntityClientMethod() not allowed in client"; + } } diff --git a/libraries/networking/src/EntityScriptClient.cpp b/libraries/networking/src/EntityScriptClient.cpp index b3a6a1b59d..75ae7369fb 100644 --- a/libraries/networking/src/EntityScriptClient.cpp +++ b/libraries/networking/src/EntityScriptClient.cpp @@ -92,10 +92,7 @@ void EntityScriptClient::callEntityServerMethod(QUuid entityID, const QString& m } } -void EntityScriptServerStub::callEntityClientMethod(QUuid clientSessionID, QUuid entityID, const QString& method, const QStringList& params) { - qDebug() << __FUNCTION__; - - +void EntityScriptServerServices::callEntityClientMethod(QUuid clientSessionID, QUuid entityID, const QString& method, const QStringList& params) { // only valid to call this function if you are the entity script server auto nodeList = DependencyManager::get(); SharedNodePointer targetClient = nodeList->nodeWithUUID(clientSessionID); diff --git a/libraries/networking/src/EntityScriptClient.h b/libraries/networking/src/EntityScriptClient.h index 43e89611da..4cfb03dca7 100644 --- a/libraries/networking/src/EntityScriptClient.h +++ b/libraries/networking/src/EntityScriptClient.h @@ -75,7 +75,7 @@ private: }; -class EntityScriptServerStub : public QObject, public Dependency { +class EntityScriptServerServices : public QObject, public Dependency { Q_OBJECT public: void callEntityClientMethod(QUuid clientSessionID, QUuid entityID, const QString& method, const QStringList& params); diff --git a/libraries/script-engine/src/ScriptEngine.cpp b/libraries/script-engine/src/ScriptEngine.cpp index 92aab79219..4ef4180447 100644 --- a/libraries/script-engine/src/ScriptEngine.cpp +++ b/libraries/script-engine/src/ScriptEngine.cpp @@ -2510,8 +2510,6 @@ void ScriptEngine::callEntityScriptMethod(const EntityItemID& entityID, const QS if (remoteCallerID == QUuid()) { callAllowed = true; } else { - qDebug() << __FUNCTION__ << "checking remotelyCallable method: " << methodName << " on entityID:" << entityID; - if (entityScript.property("remotelyCallable").isArray()) { auto callables = entityScript.property("remotelyCallable"); auto callableCount = callables.property("length").toInteger(); From ed408e09d0904d1e1b6b60cd9ef1b9a100da43fa Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Tue, 24 Oct 2017 11:50:25 -0700 Subject: [PATCH 46/60] remove some log spam --- libraries/script-engine/src/ScriptEngine.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/libraries/script-engine/src/ScriptEngine.cpp b/libraries/script-engine/src/ScriptEngine.cpp index 4ef4180447..98846c5213 100644 --- a/libraries/script-engine/src/ScriptEngine.cpp +++ b/libraries/script-engine/src/ScriptEngine.cpp @@ -2536,8 +2536,6 @@ void ScriptEngine::callEntityScriptMethod(const EntityItemID& entityID, const QS callWithEnvironment(entityID, details.definingSandboxURL, entityScript.property(methodName), entityScript, args); this->globalObject().property("Script").setProperty("remoteCallerID", oldData); } - } else { - qDebug() << "Entity script not running for EntityID: " << entityID << " - Method [" << methodName << "] not callable."; } } From 12c32d58349f6151e14268b4de143174be5b3160 Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Tue, 24 Oct 2017 13:08:48 -0700 Subject: [PATCH 47/60] bump protocol version --- libraries/networking/src/udt/PacketHeaders.cpp | 3 +++ libraries/networking/src/udt/PacketHeaders.h | 6 ++++++ 2 files changed, 9 insertions(+) diff --git a/libraries/networking/src/udt/PacketHeaders.cpp b/libraries/networking/src/udt/PacketHeaders.cpp index efb38eede1..4ce84c64f1 100644 --- a/libraries/networking/src/udt/PacketHeaders.cpp +++ b/libraries/networking/src/udt/PacketHeaders.cpp @@ -62,6 +62,9 @@ PacketVersion versionForPacketType(PacketType packetType) { case PacketType::DomainServerAddedNode: return static_cast(DomainServerAddedNodeVersion::PermissionsGrid); + case PacketType::EntityScriptCallMethod: + return static_cast(EntityScriptCallMethodVersion::ClientCallable); + case PacketType::MixedAudio: case PacketType::SilentAudioFrame: case PacketType::InjectAudio: diff --git a/libraries/networking/src/udt/PacketHeaders.h b/libraries/networking/src/udt/PacketHeaders.h index 9e2eb51fdd..fa5f910810 100644 --- a/libraries/networking/src/udt/PacketHeaders.h +++ b/libraries/networking/src/udt/PacketHeaders.h @@ -274,6 +274,12 @@ const PacketVersion VERSION_ENTITIES_UV_MODE_PROPERTY = 76; const PacketVersion VERSION_ENTITIES_STROKE_COLOR_PROPERTY = 77; + +enum class EntityScriptCallMethodVersion : PacketVersion { + ServerCallable = 18, + ClientCallable = 19 +}; + enum class EntityQueryPacketVersion: PacketVersion { JSONFilter = 18, JSONFilterWithFamilyTree = 19 From f81675e3b4ae824aa2fbbb969a52915e73b42773 Mon Sep 17 00:00:00 2001 From: Nissim Hadar Date: Tue, 24 Oct 2017 13:17:09 -0700 Subject: [PATCH 48/60] Changed blend range from 32,000 m to 30,000m --- libraries/render-utils/src/Haze.slf | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/libraries/render-utils/src/Haze.slf b/libraries/render-utils/src/Haze.slf index f9eca755f2..bf46037fd5 100644 --- a/libraries/render-utils/src/Haze.slf +++ b/libraries/render-utils/src/Haze.slf @@ -138,7 +138,8 @@ void main(void) { } // Mix with background at far range - if (distance > 32000.0) { + const float BLEND_DISTANCE = 30000.0; + if (distance > BLEND_DISTANCE) { outFragColor = mix(potentialFragColor, fragColor, hazeParams.backgroundBlendValue); } else { outFragColor = potentialFragColor; From 996b71fa9a09c69cd4f9da652ff8cc25ef8f41d5 Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Mon, 23 Oct 2017 10:44:14 -0700 Subject: [PATCH 49/60] avoid incorrect ShapeManager dupes for compound shapes --- libraries/shared/src/ShapeInfo.cpp | 32 ++++++++++++++++++++---------- 1 file changed, 22 insertions(+), 10 deletions(-) diff --git a/libraries/shared/src/ShapeInfo.cpp b/libraries/shared/src/ShapeInfo.cpp index a556548b25..f3dd9d11a6 100644 --- a/libraries/shared/src/ShapeInfo.cpp +++ b/libraries/shared/src/ShapeInfo.cpp @@ -46,6 +46,8 @@ void ShapeInfo::setParams(ShapeType type, const glm::vec3& halfExtents, QString } break; case SHAPE_TYPE_COMPOUND: + case SHAPE_TYPE_SIMPLE_HULL: + case SHAPE_TYPE_SIMPLE_COMPOUND: case SHAPE_TYPE_STATIC_MESH: _url = QUrl(url); break; @@ -250,16 +252,26 @@ const DoubleHashKey& ShapeInfo::getHash() const { } _doubleHashKey.setHash2(hash); - if (_type == SHAPE_TYPE_COMPOUND || _type == SHAPE_TYPE_STATIC_MESH) { - QString url = _url.toString(); - if (!url.isEmpty()) { - // fold the urlHash into both parts - QByteArray baUrl = url.toLocal8Bit(); - const char *cUrl = baUrl.data(); - uint32_t urlHash = qChecksum(cUrl, baUrl.count()); - _doubleHashKey.setHash(_doubleHashKey.getHash() ^ urlHash); - _doubleHashKey.setHash2(_doubleHashKey.getHash2() ^ urlHash); - } + QString url = _url.toString(); + if (!url.isEmpty()) { + // fold the urlHash into both parts + QByteArray baUrl = url.toLocal8Bit(); + uint32_t urlHash = qChecksum(baUrl.data(), baUrl.size()); + _doubleHashKey.setHash(_doubleHashKey.getHash() ^ urlHash); + _doubleHashKey.setHash2(_doubleHashKey.getHash2() ^ urlHash); + } + + uint32_t numHulls = 0; + if (_type == SHAPE_TYPE_COMPOUND || _type == SHAPE_TYPE_SIMPLE_COMPOUND) { + numHulls = (uint32_t)_pointCollection.size(); + } else if (_type == SHAPE_TYPE_SIMPLE_HULL) { + numHulls = 1; + } + if (numHulls > 0) { + hash = DoubleHashKey::hashFunction(numHulls, primeIndex++); + _doubleHashKey.setHash(_doubleHashKey.getHash() ^ hash); + hash = DoubleHashKey::hashFunction2(numHulls); + _doubleHashKey.setHash2(_doubleHashKey.getHash2() ^ hash); } } return _doubleHashKey; From 29efe53f74574488cda7e5543c3c8e0a7ab0bb77 Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Mon, 23 Oct 2017 17:55:19 -0700 Subject: [PATCH 50/60] repair debug rendering of collision shapes --- .../src/RenderableModelEntityItem.cpp | 70 ++++++++++++------- .../src/RenderableModelEntityItem.h | 10 ++- 2 files changed, 53 insertions(+), 27 deletions(-) diff --git a/libraries/entities-renderer/src/RenderableModelEntityItem.cpp b/libraries/entities-renderer/src/RenderableModelEntityItem.cpp index ff5bce4607..7db19704b4 100644 --- a/libraries/entities-renderer/src/RenderableModelEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableModelEntityItem.cpp @@ -695,12 +695,8 @@ void RenderableModelEntityItem::computeShapeInfo(ShapeInfo& shapeInfo) { void RenderableModelEntityItem::setCollisionShape(const btCollisionShape* shape) { const void* key = static_cast(shape); if (_collisionMeshKey != key) { - if (_collisionMeshKey) { - collisionMeshCache.releaseMesh(_collisionMeshKey); - } _collisionMeshKey = key; - // toggle _showCollisionGeometry forces re-evaluation later - _showCollisionGeometry = !_showCollisionGeometry; + emit requestCollisionGeometryUpdate(); } } @@ -1103,6 +1099,10 @@ bool ModelEntityRenderer::needsRenderUpdate() const { if (model->getRenderItemsNeedUpdate()) { return true; } + + if (_needsCollisionGeometryUpdate) { + return true; + } } return Parent::needsRenderUpdate(); } @@ -1169,6 +1169,15 @@ bool ModelEntityRenderer::needsRenderUpdateFromTypedEntity(const TypedEntityPoin return false; } +void ModelEntityRenderer::setCollisionMeshKey(const void*key) { + if (key != _collisionMeshKey) { + if (_collisionMeshKey) { + collisionMeshCache.releaseMesh(_collisionMeshKey); + } + _collisionMeshKey = key; + } +} + void ModelEntityRenderer::doRenderUpdateSynchronousTyped(const ScenePointer& scene, Transaction& transaction, const TypedEntityPointer& entity) { DETAILED_PROFILE_RANGE(simulation_physics, __FUNCTION__); if (_hasModel != entity->hasModel()) { @@ -1201,6 +1210,7 @@ void ModelEntityRenderer::doRenderUpdateSynchronousTyped(const ScenePointer& sce model = std::make_shared(nullptr, entity.get()); connect(model.get(), &Model::setURLFinished, this, &ModelEntityRenderer::requestRenderUpdate); connect(model.get(), &Model::requestRenderUpdate, this, &ModelEntityRenderer::requestRenderUpdate); + connect(entity.get(), &RenderableModelEntityItem::requestCollisionGeometryUpdate, this, &ModelEntityRenderer::flagForCollisionGeometryUpdate); model->setLoadingPriority(EntityTreeRenderer::getEntityLoadingPriority(*entity)); model->init(); entity->setModel(model); @@ -1259,6 +1269,26 @@ void ModelEntityRenderer::doRenderUpdateSynchronousTyped(const ScenePointer& sce } // TODO? early exit here when not visible? + if (_needsCollisionGeometryUpdate) { + setCollisionMeshKey(entity->getCollisionMeshKey()); + _needsCollisionGeometryUpdate = false; + ShapeType type = entity->getShapeType(); + if (_showCollisionGeometry && type != SHAPE_TYPE_STATIC_MESH && type != SHAPE_TYPE_NONE) { + // NOTE: it is OK if _collisionMeshKey is nullptr + model::MeshPointer mesh = collisionMeshCache.getMesh(_collisionMeshKey); + // NOTE: the model will render the collisionGeometry if it has one + _model->setCollisionMesh(mesh); + } else { + if (_collisionMeshKey) { + // release mesh + collisionMeshCache.releaseMesh(_collisionMeshKey); + } + // clear model's collision geometry + model::MeshPointer mesh = nullptr; + _model->setCollisionMesh(mesh); + } + } + { DETAILED_PROFILE_RANGE(simulation_physics, "Fixup"); if (model->needsFixupInScene()) { @@ -1297,6 +1327,11 @@ void ModelEntityRenderer::doRenderUpdateSynchronousTyped(const ScenePointer& sce } } +void ModelEntityRenderer::flagForCollisionGeometryUpdate() { + _needsCollisionGeometryUpdate = true; + emit requestRenderUpdate(); +} + // NOTE: this only renders the "meta" portion of the Model, namely it renders debugging items void ModelEntityRenderer::doRender(RenderArgs* args) { DETAILED_PROFILE_RANGE(render_detail, "MetaModelRender"); @@ -1327,28 +1362,11 @@ void ModelEntityRenderer::doRender(RenderArgs* args) { // Remap textures for the next frame to avoid flicker // remapTextures(); -#if 0 - // update whether the model should be showing collision mesh (this may flag for fixupInScene) - bool showingCollisionGeometry = (bool)(args->_debugFlags & (int)RenderArgs::RENDER_DEBUG_HULLS); - if (showingCollisionGeometry != _showCollisionGeometry) { - ShapeType type = _entity->getShapeType(); - _showCollisionGeometry = showingCollisionGeometry; - if (_showCollisionGeometry && type != SHAPE_TYPE_STATIC_MESH && type != SHAPE_TYPE_NONE) { - // NOTE: it is OK if _collisionMeshKey is nullptr - model::MeshPointer mesh = collisionMeshCache.getMesh(_collisionMeshKey); - // NOTE: the model will render the collisionGeometry if it has one - _model->setCollisionMesh(mesh); - } else { - // release mesh - if (_collisionMeshKey) { - collisionMeshCache.releaseMesh(_collisionMeshKey); - } - // clear model's collision geometry - model::MeshPointer mesh = nullptr; - _model->setCollisionMesh(mesh); - } + bool showCollisionGeometry = (bool)(args->_debugFlags & (int)RenderArgs::RENDER_DEBUG_HULLS); + if (showCollisionGeometry != _showCollisionGeometry) { + _showCollisionGeometry = showCollisionGeometry; + flagForCollisionGeometryUpdate(); } -#endif } void ModelEntityRenderer::mapJoints(const TypedEntityPointer& entity, const QStringList& modelJointNames) { diff --git a/libraries/entities-renderer/src/RenderableModelEntityItem.h b/libraries/entities-renderer/src/RenderableModelEntityItem.h index a50ca63382..0272bed575 100644 --- a/libraries/entities-renderer/src/RenderableModelEntityItem.h +++ b/libraries/entities-renderer/src/RenderableModelEntityItem.h @@ -50,6 +50,8 @@ private: }; class RenderableModelEntityItem : public ModelEntityWrapper { + Q_OBJECT + friend class render::entities::ModelEntityRenderer; using Parent = ModelEntityWrapper; public: @@ -105,6 +107,10 @@ public: virtual QStringList getJointNames() const override; bool getMeshes(MeshProxyList& result) override; + const void* getCollisionMeshKey() const { return _collisionMeshKey; } + +signals: + void requestCollisionGeometryUpdate(); private: bool needsUpdateModelBounds() const; @@ -117,7 +123,6 @@ private: QVariantMap _originalTextures; bool _dimensionsInitialized { true }; bool _needsJointSimulation { false }; - bool _showCollisionGeometry { false }; const void* _collisionMeshKey { nullptr }; }; @@ -141,6 +146,8 @@ protected: virtual bool needsRenderUpdate() const override; virtual void doRender(RenderArgs* args) override; virtual void doRenderUpdateSynchronousTyped(const ScenePointer& scene, Transaction& transaction, const TypedEntityPointer& entity) override; + void flagForCollisionGeometryUpdate(); + void setCollisionMeshKey(const void* key); private: void animate(const TypedEntityPointer& entity); @@ -163,6 +170,7 @@ private: bool _needsJointSimulation{ false }; bool _showCollisionGeometry{ false }; + bool _needsCollisionGeometryUpdate{ false }; const void* _collisionMeshKey{ nullptr }; // used on client side From 27f4d182d97c9c7b74b757c6a8bdab78e7274083 Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Mon, 23 Oct 2017 17:56:26 -0700 Subject: [PATCH 51/60] fix scale of rendered collision geometry --- libraries/render-utils/src/Model.cpp | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/libraries/render-utils/src/Model.cpp b/libraries/render-utils/src/Model.cpp index 964a1961d6..97f62a3ce0 100644 --- a/libraries/render-utils/src/Model.cpp +++ b/libraries/render-utils/src/Model.cpp @@ -235,7 +235,6 @@ void Model::updateRenderItems() { self->updateClusterMatrices(); Transform modelTransform = self->getTransform(); - Transform physicsTransform = modelTransform; modelTransform.setScale(glm::vec3(1.0f)); uint32_t deleteGeometryCounter = self->_deleteGeometryCounter; @@ -259,13 +258,12 @@ void Model::updateRenderItems() { }); } - // collision mesh does not share the same unit scale as the FBX file's mesh: only apply offset Transform collisionMeshOffset; collisionMeshOffset.setIdentity(); foreach(auto itemID, self->_collisionRenderItemsMap.keys()) { - transaction.updateItem(itemID, [physicsTransform, collisionMeshOffset](MeshPartPayload& data) { + transaction.updateItem(itemID, [modelTransform, collisionMeshOffset](MeshPartPayload& data) { // update the model transform for this render item. - data.updateTransform(physicsTransform, collisionMeshOffset); + data.updateTransform(modelTransform, collisionMeshOffset); }); } From 046e5ca7161abe121ca921f7d410bf77dc9bb231 Mon Sep 17 00:00:00 2001 From: SamGondelman Date: Tue, 24 Oct 2017 13:24:09 -0700 Subject: [PATCH 52/60] fix backwards HUD in mirror mode --- .../display-plugins/OpenGLDisplayPlugin.cpp | 20 ++++++++++++++--- .../src/display-plugins/OpenGLDisplayPlugin.h | 4 +++- .../display-plugins/hmd/HmdDisplayPlugin.cpp | 12 ++++++---- .../display-plugins/hmd/HmdDisplayPlugin.h | 4 ++-- .../gpu/src/gpu/DrawTextureMirroredX.slf | 22 +++++++++++++++++++ libraries/gpu/src/gpu/StandardShaderLib.cpp | 9 ++++++++ libraries/gpu/src/gpu/StandardShaderLib.h | 2 ++ .../plugins/src/plugins/DisplayPlugin.cpp | 4 ++-- libraries/plugins/src/plugins/DisplayPlugin.h | 4 ++-- .../render-utils/src/RenderDeferredTask.cpp | 2 +- libraries/render/src/render/Args.h | 2 +- 11 files changed, 69 insertions(+), 16 deletions(-) create mode 100644 libraries/gpu/src/gpu/DrawTextureMirroredX.slf diff --git a/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.cpp b/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.cpp index 88aa56cccf..0993daaa8b 100644 --- a/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.cpp +++ b/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.cpp @@ -418,6 +418,19 @@ void OpenGLDisplayPlugin::customizeContext() { _hudPipeline = gpu::Pipeline::create(program, state); } + { + auto vs = gpu::StandardShaderLib::getDrawUnitQuadTexcoordVS(); + auto ps = gpu::StandardShaderLib::getDrawTextureMirroredXPS(); + gpu::ShaderPointer program = gpu::Shader::createProgram(vs, ps); + gpu::Shader::makeProgram(*program); + gpu::StatePointer state = gpu::StatePointer(new gpu::State()); + state->setDepthTest(gpu::State::DepthTest(false)); + state->setBlendFunction(true, + gpu::State::SRC_ALPHA, gpu::State::BLEND_OP_ADD, gpu::State::INV_SRC_ALPHA, + gpu::State::FACTOR_ALPHA, gpu::State::BLEND_OP_ADD, gpu::State::ONE); + _mirrorHUDPipeline = gpu::Pipeline::create(program, state); + } + { auto vs = gpu::StandardShaderLib::getDrawTransformUnitQuadVS(); auto ps = gpu::StandardShaderLib::getDrawTexturePS(); @@ -438,6 +451,7 @@ void OpenGLDisplayPlugin::uncustomizeContext() { _presentPipeline.reset(); _cursorPipeline.reset(); _hudPipeline.reset(); + _mirrorHUDPipeline.reset(); _compositeFramebuffer.reset(); withPresentThreadLock([&] { _currentFrame.reset(); @@ -562,11 +576,11 @@ void OpenGLDisplayPlugin::updateFrameData() { }); } -std::function OpenGLDisplayPlugin::getHUDOperator() { - return [this](gpu::Batch& batch, const gpu::TexturePointer& hudTexture) { +std::function OpenGLDisplayPlugin::getHUDOperator() { + return [this](gpu::Batch& batch, const gpu::TexturePointer& hudTexture, bool mirror) { if (_hudPipeline) { batch.enableStereo(false); - batch.setPipeline(_hudPipeline); + batch.setPipeline(mirror ? _mirrorHUDPipeline : _hudPipeline); batch.setResourceTexture(0, hudTexture); if (isStereo()) { for_each_eye([&](Eye eye) { diff --git a/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.h b/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.h index ec775aed4c..d67c0b8663 100644 --- a/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.h +++ b/libraries/display-plugins/src/display-plugins/OpenGLDisplayPlugin.h @@ -95,7 +95,7 @@ protected: virtual QThread::Priority getPresentPriority() { return QThread::HighPriority; } virtual void compositeLayers(); virtual void compositeScene(); - virtual std::function getHUDOperator(); + virtual std::function getHUDOperator(); virtual void compositePointer(); virtual void compositeExtra() {}; @@ -140,6 +140,8 @@ protected: gpu::Frame* _lastFrame { nullptr }; gpu::FramebufferPointer _compositeFramebuffer; gpu::PipelinePointer _hudPipeline; + gpu::PipelinePointer _mirrorHUDPipeline; + gpu::ShaderPointer _mirrorHUDPS; gpu::PipelinePointer _simplePipeline; gpu::PipelinePointer _presentPipeline; gpu::PipelinePointer _cursorPipeline; diff --git a/libraries/display-plugins/src/display-plugins/hmd/HmdDisplayPlugin.cpp b/libraries/display-plugins/src/display-plugins/hmd/HmdDisplayPlugin.cpp index 0785226836..1d7fee38eb 100644 --- a/libraries/display-plugins/src/display-plugins/hmd/HmdDisplayPlugin.cpp +++ b/libraries/display-plugins/src/display-plugins/hmd/HmdDisplayPlugin.cpp @@ -419,9 +419,9 @@ void HmdDisplayPlugin::HUDRenderer::updatePipeline() { } } -std::function HmdDisplayPlugin::HUDRenderer::render(HmdDisplayPlugin& plugin) { +std::function HmdDisplayPlugin::HUDRenderer::render(HmdDisplayPlugin& plugin) { updatePipeline(); - return [this](gpu::Batch& batch, const gpu::TexturePointer& hudTexture) { + return [this](gpu::Batch& batch, const gpu::TexturePointer& hudTexture, bool mirror) { if (pipeline) { batch.setPipeline(pipeline); @@ -436,7 +436,11 @@ std::function HmdDisplayPlugin::H batch.setUniformBuffer(uniformsLocation, uniformsBuffer); auto compositorHelper = DependencyManager::get(); - batch.setModelTransform(compositorHelper->getUiTransform()); + glm::mat4 modelTransform = compositorHelper->getUiTransform(); + if (mirror) { + modelTransform = glm::scale(modelTransform, glm::vec3(-1, 1, 1)); + } + batch.setModelTransform(modelTransform); batch.setResourceTexture(0, hudTexture); batch.drawIndexed(gpu::TRIANGLES, indexCount); @@ -468,7 +472,7 @@ void HmdDisplayPlugin::compositePointer() { }); } -std::function HmdDisplayPlugin::getHUDOperator() { +std::function HmdDisplayPlugin::getHUDOperator() { return _hudRenderer.render(*this); } diff --git a/libraries/display-plugins/src/display-plugins/hmd/HmdDisplayPlugin.h b/libraries/display-plugins/src/display-plugins/hmd/HmdDisplayPlugin.h index a7a6d2938d..d2d30df093 100644 --- a/libraries/display-plugins/src/display-plugins/hmd/HmdDisplayPlugin.h +++ b/libraries/display-plugins/src/display-plugins/hmd/HmdDisplayPlugin.h @@ -53,7 +53,7 @@ protected: bool internalActivate() override; void internalDeactivate() override; - std::function getHUDOperator() override; + std::function getHUDOperator() override; void compositePointer() override; void internalPresent() override; void customizeContext() override; @@ -116,6 +116,6 @@ private: void build(); void updatePipeline(); - std::function render(HmdDisplayPlugin& plugin); + std::function render(HmdDisplayPlugin& plugin); } _hudRenderer; }; diff --git a/libraries/gpu/src/gpu/DrawTextureMirroredX.slf b/libraries/gpu/src/gpu/DrawTextureMirroredX.slf new file mode 100644 index 0000000000..aef4033496 --- /dev/null +++ b/libraries/gpu/src/gpu/DrawTextureMirroredX.slf @@ -0,0 +1,22 @@ +<@include gpu/Config.slh@> +<$VERSION_HEADER$> +// Generated on <$_SCRIBE_DATE$> +// +// Draw texture 0 fetched at (1.0 - texcoord.x, texcoord.y) +// +// Created by Sam Gondelman on 10/24/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 +// + + +uniform sampler2D colorMap; + +in vec2 varTexCoord0; +out vec4 outFragColor; + +void main(void) { + outFragColor = texture(colorMap, vec2(1.0 - varTexCoord0.x, varTexCoord0.y)); +} diff --git a/libraries/gpu/src/gpu/StandardShaderLib.cpp b/libraries/gpu/src/gpu/StandardShaderLib.cpp index 756070ff68..7143242618 100755 --- a/libraries/gpu/src/gpu/StandardShaderLib.cpp +++ b/libraries/gpu/src/gpu/StandardShaderLib.cpp @@ -23,6 +23,7 @@ const char DrawNada_frag[] = "void main(void) {}"; // DrawNada is really simple. #include "DrawWhite_frag.h" #include "DrawTexture_frag.h" +#include "DrawTextureMirroredX_frag.h" #include "DrawTextureOpaque_frag.h" #include "DrawColoredTexture_frag.h" @@ -37,6 +38,7 @@ ShaderPointer StandardShaderLib::_drawTransformVertexPositionVS; ShaderPointer StandardShaderLib::_drawNadaPS; ShaderPointer StandardShaderLib::_drawWhitePS; ShaderPointer StandardShaderLib::_drawTexturePS; +ShaderPointer StandardShaderLib::_drawTextureMirroredXPS; ShaderPointer StandardShaderLib::_drawTextureOpaquePS; ShaderPointer StandardShaderLib::_drawColoredTexturePS; StandardShaderLib::ProgramMap StandardShaderLib::_programs; @@ -130,6 +132,13 @@ ShaderPointer StandardShaderLib::getDrawTexturePS() { return _drawTexturePS; } +ShaderPointer StandardShaderLib::getDrawTextureMirroredXPS() { + if (!_drawTextureMirroredXPS) { + _drawTextureMirroredXPS = gpu::Shader::createPixel(std::string(DrawTextureMirroredX_frag)); + } + return _drawTextureMirroredXPS; +} + ShaderPointer StandardShaderLib::getDrawTextureOpaquePS() { if (!_drawTextureOpaquePS) { _drawTextureOpaquePS = gpu::Shader::createPixel(std::string(DrawTextureOpaque_frag)); diff --git a/libraries/gpu/src/gpu/StandardShaderLib.h b/libraries/gpu/src/gpu/StandardShaderLib.h index a21d4dea9a..94885b8ca0 100755 --- a/libraries/gpu/src/gpu/StandardShaderLib.h +++ b/libraries/gpu/src/gpu/StandardShaderLib.h @@ -47,6 +47,7 @@ public: static ShaderPointer getDrawWhitePS(); static ShaderPointer getDrawTexturePS(); + static ShaderPointer getDrawTextureMirroredXPS(); static ShaderPointer getDrawTextureOpaquePS(); static ShaderPointer getDrawColoredTexturePS(); @@ -67,6 +68,7 @@ protected: static ShaderPointer _drawNadaPS; static ShaderPointer _drawWhitePS; static ShaderPointer _drawTexturePS; + static ShaderPointer _drawTextureMirroredXPS; static ShaderPointer _drawTextureOpaquePS; static ShaderPointer _drawColoredTexturePS; diff --git a/libraries/plugins/src/plugins/DisplayPlugin.cpp b/libraries/plugins/src/plugins/DisplayPlugin.cpp index e43d5e76f3..2a8a72f594 100644 --- a/libraries/plugins/src/plugins/DisplayPlugin.cpp +++ b/libraries/plugins/src/plugins/DisplayPlugin.cpp @@ -35,8 +35,8 @@ void DisplayPlugin::waitForPresent() { } } -std::function DisplayPlugin::getHUDOperator() { - std::function hudOperator; +std::function DisplayPlugin::getHUDOperator() { + std::function hudOperator; { QMutexLocker locker(&_presentMutex); hudOperator = _hudOperator; diff --git a/libraries/plugins/src/plugins/DisplayPlugin.h b/libraries/plugins/src/plugins/DisplayPlugin.h index 11ca6f754a..efce158864 100644 --- a/libraries/plugins/src/plugins/DisplayPlugin.h +++ b/libraries/plugins/src/plugins/DisplayPlugin.h @@ -204,7 +204,7 @@ public: void waitForPresent(); - std::function getHUDOperator(); + std::function getHUDOperator(); static const QString& MENU_PATH(); @@ -218,7 +218,7 @@ protected: gpu::ContextPointer _gpuContext; - std::function _hudOperator { std::function() }; + std::function _hudOperator { std::function() }; private: QMutex _presentMutex; diff --git a/libraries/render-utils/src/RenderDeferredTask.cpp b/libraries/render-utils/src/RenderDeferredTask.cpp index ac4e717d60..6a3b560167 100644 --- a/libraries/render-utils/src/RenderDeferredTask.cpp +++ b/libraries/render-utils/src/RenderDeferredTask.cpp @@ -441,7 +441,7 @@ void CompositeHUD::run(const RenderContextPointer& renderContext) { // Grab the HUD texture gpu::doInBatch(renderContext->args->_context, [&](gpu::Batch& batch) { if (renderContext->args->_hudOperator) { - renderContext->args->_hudOperator(batch, renderContext->args->_hudTexture); + renderContext->args->_hudOperator(batch, renderContext->args->_hudTexture, renderContext->args->_renderMode == RenderArgs::RenderMode::MIRROR_RENDER_MODE); } }); } diff --git a/libraries/render/src/render/Args.h b/libraries/render/src/render/Args.h index a76b60ffe6..627d4f17b2 100644 --- a/libraries/render/src/render/Args.h +++ b/libraries/render/src/render/Args.h @@ -122,7 +122,7 @@ namespace render { render::ScenePointer _scene; int8_t _cameraMode { -1 }; - std::function _hudOperator; + std::function _hudOperator; gpu::TexturePointer _hudTexture; }; From 5901d1a3110e0d5b4be6c37c6193e87bd1dde001 Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Tue, 24 Oct 2017 13:48:27 -0700 Subject: [PATCH 53/60] clean up VERSION_ENTITIES stuff --- libraries/entities/src/EntityItem.cpp | 82 +++++------ libraries/entities/src/EntityTree.h | 5 - libraries/entities/src/EntityTypes.cpp | 6 - libraries/entities/src/LightEntityItem.cpp | 35 +---- libraries/entities/src/ModelEntityItem.cpp | 39 ++--- .../entities/src/ParticleEffectEntityItem.cpp | 86 ++++------- .../networking/src/udt/PacketHeaders.cpp | 4 +- libraries/networking/src/udt/PacketHeaders.h | 5 + libraries/octree/src/Octree.cpp | 135 +----------------- libraries/octree/src/Octree.h | 7 - 10 files changed, 82 insertions(+), 322 deletions(-) diff --git a/libraries/entities/src/EntityItem.cpp b/libraries/entities/src/EntityItem.cpp index 58b8dd22bf..a5586f03ce 100644 --- a/libraries/entities/src/EntityItem.cpp +++ b/libraries/entities/src/EntityItem.cpp @@ -355,14 +355,6 @@ int EntityItem::expectedBytes() { // clients use this method to unpack FULL updates from entity-server int EntityItem::readEntityDataFromBuffer(const unsigned char* data, int bytesLeftToRead, ReadBitstreamToTreeParams& args) { - if (args.bitstreamVersion < VERSION_ENTITIES_SUPPORT_SPLIT_MTU) { - - // NOTE: This shouldn't happen. The only versions of the bit stream that didn't support split mtu buffers should - // be handled by the model subclass and shouldn't call this routine. - qCDebug(entities) << "EntityItem::readEntityDataFromBuffer()... " - "ERROR CASE...args.bitstreamVersion < VERSION_ENTITIES_SUPPORT_SPLIT_MTU"; - return 0; - } setSourceUUID(args.sourceUUID); args.entitiesPerPacket++; @@ -588,34 +580,32 @@ int EntityItem::readEntityDataFromBuffer(const unsigned char* data, int bytesLef // Newer bitstreams will have a last simulated and a last updated value quint64 lastSimulatedFromBufferAdjusted = now; - if (args.bitstreamVersion >= VERSION_ENTITIES_HAS_LAST_SIMULATED_TIME) { - // last simulated is stored as ByteCountCoded delta from lastEdited - quint64 simulatedDelta; - parser.readCompressedCount(simulatedDelta); + // last simulated is stored as ByteCountCoded delta from lastEdited + quint64 simulatedDelta; + parser.readCompressedCount(simulatedDelta); #ifdef VALIDATE_ENTITY_ITEM_PARSER - { - QByteArray encodedSimulatedDelta = originalDataBuffer.mid(bytesRead); // maximum possible size - ByteCountCoded simulatedDeltaCoder = encodedSimulatedDelta; - quint64 simulatedDelta2 = simulatedDeltaCoder; - Q_ASSERT(simulatedDelta2 == simulatedDelta); - encodedSimulatedDelta = simulatedDeltaCoder; // determine true length - dataAt += encodedSimulatedDelta.size(); - bytesRead += encodedSimulatedDelta.size(); - Q_ASSERT(parser.offset() == (unsigned int) bytesRead); - } + { + QByteArray encodedSimulatedDelta = originalDataBuffer.mid(bytesRead); // maximum possible size + ByteCountCoded simulatedDeltaCoder = encodedSimulatedDelta; + quint64 simulatedDelta2 = simulatedDeltaCoder; + Q_ASSERT(simulatedDelta2 == simulatedDelta); + encodedSimulatedDelta = simulatedDeltaCoder; // determine true length + dataAt += encodedSimulatedDelta.size(); + bytesRead += encodedSimulatedDelta.size(); + Q_ASSERT(parser.offset() == (unsigned int) bytesRead); + } #endif - if (overwriteLocalData) { - lastSimulatedFromBufferAdjusted = lastEditedFromBufferAdjusted + simulatedDelta; // don't adjust for clock skew since we already did that - if (lastSimulatedFromBufferAdjusted > now) { - lastSimulatedFromBufferAdjusted = now; - } - #ifdef WANT_DEBUG - qCDebug(entities) << " _lastEdited:" << debugTime(_lastEdited, now); - qCDebug(entities) << " lastEditedFromBufferAdjusted:" << debugTime(lastEditedFromBufferAdjusted, now); - qCDebug(entities) << " lastSimulatedFromBufferAdjusted:" << debugTime(lastSimulatedFromBufferAdjusted, now); - #endif + if (overwriteLocalData) { + lastSimulatedFromBufferAdjusted = lastEditedFromBufferAdjusted + simulatedDelta; // don't adjust for clock skew since we already did that + if (lastSimulatedFromBufferAdjusted > now) { + lastSimulatedFromBufferAdjusted = now; } + #ifdef WANT_DEBUG + qCDebug(entities) << " _lastEdited:" << debugTime(_lastEdited, now); + qCDebug(entities) << " lastEditedFromBufferAdjusted:" << debugTime(lastEditedFromBufferAdjusted, now); + qCDebug(entities) << " lastSimulatedFromBufferAdjusted:" << debugTime(lastSimulatedFromBufferAdjusted, now); + #endif } #ifdef WANT_DEBUG @@ -817,20 +807,16 @@ int EntityItem::readEntityDataFromBuffer(const unsigned char* data, int bytesLef READ_ENTITY_PROPERTY(PROP_LOCKED, bool, updateLocked); READ_ENTITY_PROPERTY(PROP_USER_DATA, QString, setUserData); - if (args.bitstreamVersion >= VERSION_ENTITIES_HAS_MARKETPLACE_ID) { - READ_ENTITY_PROPERTY(PROP_MARKETPLACE_ID, QString, setMarketplaceID); - } - if (args.bitstreamVersion >= VERSION_ENTITIES_HAS_CERTIFICATE_PROPERTIES) { - READ_ENTITY_PROPERTY(PROP_ITEM_NAME, QString, setItemName); - READ_ENTITY_PROPERTY(PROP_ITEM_DESCRIPTION, QString, setItemDescription); - READ_ENTITY_PROPERTY(PROP_ITEM_CATEGORIES, QString, setItemCategories); - READ_ENTITY_PROPERTY(PROP_ITEM_ARTIST, QString, setItemArtist); - READ_ENTITY_PROPERTY(PROP_ITEM_LICENSE, QString, setItemLicense); - READ_ENTITY_PROPERTY(PROP_LIMITED_RUN, quint32, setLimitedRun); - READ_ENTITY_PROPERTY(PROP_EDITION_NUMBER, quint32, setEditionNumber); - READ_ENTITY_PROPERTY(PROP_ENTITY_INSTANCE_NUMBER, quint32, setEntityInstanceNumber); - READ_ENTITY_PROPERTY(PROP_CERTIFICATE_ID, QString, setCertificateID); - } + READ_ENTITY_PROPERTY(PROP_MARKETPLACE_ID, QString, setMarketplaceID); + READ_ENTITY_PROPERTY(PROP_ITEM_NAME, QString, setItemName); + READ_ENTITY_PROPERTY(PROP_ITEM_DESCRIPTION, QString, setItemDescription); + READ_ENTITY_PROPERTY(PROP_ITEM_CATEGORIES, QString, setItemCategories); + READ_ENTITY_PROPERTY(PROP_ITEM_ARTIST, QString, setItemArtist); + READ_ENTITY_PROPERTY(PROP_ITEM_LICENSE, QString, setItemLicense); + READ_ENTITY_PROPERTY(PROP_LIMITED_RUN, quint32, setLimitedRun); + READ_ENTITY_PROPERTY(PROP_EDITION_NUMBER, quint32, setEditionNumber); + READ_ENTITY_PROPERTY(PROP_ENTITY_INSTANCE_NUMBER, quint32, setEntityInstanceNumber); + READ_ENTITY_PROPERTY(PROP_CERTIFICATE_ID, QString, setCertificateID); READ_ENTITY_PROPERTY(PROP_NAME, QString, setName); READ_ENTITY_PROPERTY(PROP_COLLISION_SOUND_URL, QString, setCollisionSoundURL); @@ -858,10 +844,6 @@ int EntityItem::readEntityDataFromBuffer(const unsigned char* data, int bytesLef // NOTE: we had a bad version of the stream that we added stream data after the subclass. We can attempt to recover // by doing this parsing here... but it's not likely going to fully recover the content. // - // TODO: Remove this code once we've sufficiently migrated content past this damaged version - if (args.bitstreamVersion == VERSION_ENTITIES_HAS_MARKETPLACE_ID_DAMAGED) { - READ_ENTITY_PROPERTY(PROP_MARKETPLACE_ID, QString, setMarketplaceID); - } if (overwriteLocalData && (getDirtyFlags() & (Simulation::DIRTY_TRANSFORM | Simulation::DIRTY_VELOCITIES))) { // NOTE: This code is attempting to "repair" the old data we just got from the server to make it more diff --git a/libraries/entities/src/EntityTree.h b/libraries/entities/src/EntityTree.h index 53e36bc7c7..25e36c8ffb 100644 --- a/libraries/entities/src/EntityTree.h +++ b/libraries/entities/src/EntityTree.h @@ -89,8 +89,6 @@ public: // own definition. Implement these to allow your octree based server to support editing virtual bool getWantSVOfileVersions() const override { return true; } virtual PacketType expectedDataPacketType() const override { return PacketType::EntityData; } - virtual bool canProcessVersion(PacketVersion thisVersion) const override - { return thisVersion >= VERSION_ENTITIES_USE_METERS_AND_RADIANS; } virtual bool handlesEditPacketType(PacketType packetType) const override; void fixupTerseEditLogging(EntityItemProperties& properties, QList& changedProperties); virtual int processEditPacketData(ReceivedMessage& message, const unsigned char* editData, int maxLength, @@ -111,9 +109,6 @@ public: virtual void releaseSceneEncodeData(OctreeElementExtraEncodeData* extraEncodeData) const override; virtual bool mustIncludeAllChildData() const override { return false; } - virtual bool versionHasSVOfileBreaks(PacketVersion thisVersion) const override - { return thisVersion >= VERSION_ENTITIES_HAS_FILE_BREAKS; } - virtual void update() override { update(true); } void update(bool simulate); diff --git a/libraries/entities/src/EntityTypes.cpp b/libraries/entities/src/EntityTypes.cpp index 4ba4ad5676..cb17c28fd7 100644 --- a/libraries/entities/src/EntityTypes.cpp +++ b/libraries/entities/src/EntityTypes.cpp @@ -102,12 +102,6 @@ EntityItemPointer EntityTypes::constructEntityItem(EntityType entityType, const EntityItemPointer EntityTypes::constructEntityItem(const unsigned char* data, int bytesToRead, ReadBitstreamToTreeParams& args) { - if (args.bitstreamVersion < VERSION_ENTITIES_SUPPORT_SPLIT_MTU) { - EntityItemID tempEntityID; - EntityItemProperties tempProperties; - return constructEntityItem(Model, tempEntityID, tempProperties); - } - // Header bytes // object ID [16 bytes] // ByteCountCoded(type code) [~1 byte] diff --git a/libraries/entities/src/LightEntityItem.cpp b/libraries/entities/src/LightEntityItem.cpp index e1ccf8556b..f4944603f1 100644 --- a/libraries/entities/src/LightEntityItem.cpp +++ b/libraries/entities/src/LightEntityItem.cpp @@ -175,35 +175,12 @@ int LightEntityItem::readEntitySubclassDataFromBuffer(const unsigned char* data, int bytesRead = 0; const unsigned char* dataAt = data; - if (args.bitstreamVersion < VERSION_ENTITIES_LIGHT_HAS_INTENSITY_AND_COLOR_PROPERTIES) { - READ_ENTITY_PROPERTY(PROP_IS_SPOTLIGHT, bool, setIsSpotlight); - - // _diffuseColor has been renamed to _color - READ_ENTITY_PROPERTY(PROP_DIFFUSE_COLOR, rgbColor, setColor); - - // Ambient and specular color are from an older format and are no longer supported. - // Their values will be ignored. - READ_ENTITY_PROPERTY(PROP_AMBIENT_COLOR_UNUSED, rgbColor, setIgnoredColor); - READ_ENTITY_PROPERTY(PROP_SPECULAR_COLOR_UNUSED, rgbColor, setIgnoredColor); - - // _constantAttenuation has been renamed to _intensity - READ_ENTITY_PROPERTY(PROP_INTENSITY, float, setIntensity); - - // Linear and quadratic attenuation are from an older format and are no longer supported. - // Their values will be ignored. - READ_ENTITY_PROPERTY(PROP_LINEAR_ATTENUATION_UNUSED, float, setIgnoredAttenuation); - READ_ENTITY_PROPERTY(PROP_QUADRATIC_ATTENUATION_UNUSED, float, setIgnoredAttenuation); - - READ_ENTITY_PROPERTY(PROP_EXPONENT, float, setExponent); - READ_ENTITY_PROPERTY(PROP_CUTOFF, float, setCutoff); - } else { - READ_ENTITY_PROPERTY(PROP_IS_SPOTLIGHT, bool, setIsSpotlight); - READ_ENTITY_PROPERTY(PROP_COLOR, rgbColor, setColor); - READ_ENTITY_PROPERTY(PROP_INTENSITY, float, setIntensity); - READ_ENTITY_PROPERTY(PROP_EXPONENT, float, setExponent); - READ_ENTITY_PROPERTY(PROP_CUTOFF, float, setCutoff); - READ_ENTITY_PROPERTY(PROP_FALLOFF_RADIUS, float, setFalloffRadius); - } + READ_ENTITY_PROPERTY(PROP_IS_SPOTLIGHT, bool, setIsSpotlight); + READ_ENTITY_PROPERTY(PROP_COLOR, rgbColor, setColor); + READ_ENTITY_PROPERTY(PROP_INTENSITY, float, setIntensity); + READ_ENTITY_PROPERTY(PROP_EXPONENT, float, setExponent); + READ_ENTITY_PROPERTY(PROP_CUTOFF, float, setCutoff); + READ_ENTITY_PROPERTY(PROP_FALLOFF_RADIUS, float, setFalloffRadius); return bytesRead; } diff --git a/libraries/entities/src/ModelEntityItem.cpp b/libraries/entities/src/ModelEntityItem.cpp index a5d259ea87..26f063f7cc 100644 --- a/libraries/entities/src/ModelEntityItem.cpp +++ b/libraries/entities/src/ModelEntityItem.cpp @@ -111,38 +111,19 @@ int ModelEntityItem::readEntitySubclassDataFromBuffer(const unsigned char* data, READ_ENTITY_PROPERTY(PROP_COLOR, rgbColor, setColor); READ_ENTITY_PROPERTY(PROP_MODEL_URL, QString, setModelURL); - if (args.bitstreamVersion < VERSION_ENTITIES_HAS_COLLISION_MODEL) { - setCompoundShapeURL(""); - } else { - READ_ENTITY_PROPERTY(PROP_COMPOUND_SHAPE_URL, QString, setCompoundShapeURL); - } - - // Because we're using AnimationLoop which will reset the frame index if you change it's running state - // we want to read these values in the order they appear in the buffer, but call our setters in an - // order that allows AnimationLoop to preserve the correct frame rate. - if (args.bitstreamVersion < VERSION_ENTITIES_ANIMATION_PROPERTIES_GROUP) { - READ_ENTITY_PROPERTY(PROP_ANIMATION_URL, QString, setAnimationURL); - READ_ENTITY_PROPERTY(PROP_ANIMATION_FPS, float, setAnimationFPS); - READ_ENTITY_PROPERTY(PROP_ANIMATION_FRAME_INDEX, float, setAnimationCurrentFrame); - READ_ENTITY_PROPERTY(PROP_ANIMATION_PLAYING, bool, setAnimationIsPlaying); - } - + READ_ENTITY_PROPERTY(PROP_COMPOUND_SHAPE_URL, QString, setCompoundShapeURL); READ_ENTITY_PROPERTY(PROP_TEXTURES, QString, setTextures); - if (args.bitstreamVersion < VERSION_ENTITIES_ANIMATION_PROPERTIES_GROUP) { - READ_ENTITY_PROPERTY(PROP_ANIMATION_SETTINGS, QString, setAnimationSettings); - } else { - int bytesFromAnimation; - withWriteLock([&] { - // Note: since we've associated our _animationProperties with our _animationLoop, the readEntitySubclassDataFromBuffer() - // will automatically read into the animation loop - bytesFromAnimation = _animationProperties.readEntitySubclassDataFromBuffer(dataAt, (bytesLeftToRead - bytesRead), args, - propertyFlags, overwriteLocalData, animationPropertiesChanged); - }); + int bytesFromAnimation; + withWriteLock([&] { + // Note: since we've associated our _animationProperties with our _animationLoop, the readEntitySubclassDataFromBuffer() + // will automatically read into the animation loop + bytesFromAnimation = _animationProperties.readEntitySubclassDataFromBuffer(dataAt, (bytesLeftToRead - bytesRead), args, + propertyFlags, overwriteLocalData, animationPropertiesChanged); + }); - bytesRead += bytesFromAnimation; - dataAt += bytesFromAnimation; - } + bytesRead += bytesFromAnimation; + dataAt += bytesFromAnimation; READ_ENTITY_PROPERTY(PROP_SHAPE_TYPE, ShapeType, setShapeType); diff --git a/libraries/entities/src/ParticleEffectEntityItem.cpp b/libraries/entities/src/ParticleEffectEntityItem.cpp index 1a815de632..b216144ded 100644 --- a/libraries/entities/src/ParticleEffectEntityItem.cpp +++ b/libraries/entities/src/ParticleEffectEntityItem.cpp @@ -464,76 +464,40 @@ int ParticleEffectEntityItem::readEntitySubclassDataFromBuffer(const unsigned ch const unsigned char* dataAt = data; READ_ENTITY_PROPERTY(PROP_COLOR, rgbColor, setColor); - // Because we're using AnimationLoop which will reset the frame index if you change it's running state - // we want to read these values in the order they appear in the buffer, but call our setters in an - // order that allows AnimationLoop to preserve the correct frame rate. - if (args.bitstreamVersion < VERSION_ENTITIES_ANIMATION_PROPERTIES_GROUP) { - SKIP_ENTITY_PROPERTY(PROP_ANIMATION_FPS, float); - SKIP_ENTITY_PROPERTY(PROP_ANIMATION_FRAME_INDEX, float); - SKIP_ENTITY_PROPERTY(PROP_ANIMATION_PLAYING, bool); - SKIP_ENTITY_PROPERTY(PROP_ANIMATION_SETTINGS, QString); - } else { - READ_ENTITY_PROPERTY(PROP_EMITTING_PARTICLES, bool, setIsEmitting); - } - + READ_ENTITY_PROPERTY(PROP_EMITTING_PARTICLES, bool, setIsEmitting); READ_ENTITY_PROPERTY(PROP_SHAPE_TYPE, ShapeType, setShapeType); READ_ENTITY_PROPERTY(PROP_MAX_PARTICLES, quint32, setMaxParticles); READ_ENTITY_PROPERTY(PROP_LIFESPAN, float, setLifespan); READ_ENTITY_PROPERTY(PROP_EMIT_RATE, float, setEmitRate); - if (args.bitstreamVersion < VERSION_ENTITIES_PARTICLE_ELLIPSOID_EMITTER) { - // OLD PROP_EMIT_VELOCITY FAKEOUT - SKIP_ENTITY_PROPERTY(PROP_EMIT_SPEED, glm::vec3); - } - if (args.bitstreamVersion >= VERSION_ENTITIES_PARTICLE_MODIFICATIONS) { - READ_ENTITY_PROPERTY(PROP_EMIT_ACCELERATION, glm::vec3, setEmitAcceleration); - READ_ENTITY_PROPERTY(PROP_ACCELERATION_SPREAD, glm::vec3, setAccelerationSpread); - READ_ENTITY_PROPERTY(PROP_PARTICLE_RADIUS, float, setParticleRadius); - READ_ENTITY_PROPERTY(PROP_TEXTURES, QString, setTextures); - if (args.bitstreamVersion < VERSION_ENTITIES_PARTICLE_ELLIPSOID_EMITTER) { - // OLD PROP_VELOCITY_SPREAD FAKEOUT - SKIP_ENTITY_PROPERTY(PROP_SPEED_SPREAD, glm::vec3); - } - } else { - // OLD PROP_EMIT_ACCELERATION FAKEOUT - SKIP_ENTITY_PROPERTY(PROP_PARTICLE_RADIUS, float); - // OLD PROP_ACCELERATION_SPREAD FAKEOUT - SKIP_ENTITY_PROPERTY(PROP_PARTICLE_RADIUS, float); - READ_ENTITY_PROPERTY(PROP_PARTICLE_RADIUS, float, setParticleRadius); - READ_ENTITY_PROPERTY(PROP_TEXTURES, QString, setTextures); - } + READ_ENTITY_PROPERTY(PROP_EMIT_ACCELERATION, glm::vec3, setEmitAcceleration); + READ_ENTITY_PROPERTY(PROP_ACCELERATION_SPREAD, glm::vec3, setAccelerationSpread); + READ_ENTITY_PROPERTY(PROP_PARTICLE_RADIUS, float, setParticleRadius); + READ_ENTITY_PROPERTY(PROP_TEXTURES, QString, setTextures); - if (args.bitstreamVersion >= VERSION_ENTITIES_PARTICLE_RADIUS_PROPERTIES) { - READ_ENTITY_PROPERTY(PROP_RADIUS_SPREAD, float, setRadiusSpread); - READ_ENTITY_PROPERTY(PROP_RADIUS_START, float, setRadiusStart); - READ_ENTITY_PROPERTY(PROP_RADIUS_FINISH, float, setRadiusFinish); - } + READ_ENTITY_PROPERTY(PROP_RADIUS_SPREAD, float, setRadiusSpread); + READ_ENTITY_PROPERTY(PROP_RADIUS_START, float, setRadiusStart); + READ_ENTITY_PROPERTY(PROP_RADIUS_FINISH, float, setRadiusFinish); - if (args.bitstreamVersion >= VERSION_ENTITIES_PARTICLE_COLOR_PROPERTIES) { - READ_ENTITY_PROPERTY(PROP_COLOR_SPREAD, xColor, setColorSpread); - READ_ENTITY_PROPERTY(PROP_COLOR_START, xColor, setColorStart); - READ_ENTITY_PROPERTY(PROP_COLOR_FINISH, xColor, setColorFinish); - READ_ENTITY_PROPERTY(PROP_ALPHA, float, setAlpha); - READ_ENTITY_PROPERTY(PROP_ALPHA_SPREAD, float, setAlphaSpread); - READ_ENTITY_PROPERTY(PROP_ALPHA_START, float, setAlphaStart); - READ_ENTITY_PROPERTY(PROP_ALPHA_FINISH, float, setAlphaFinish); - } + READ_ENTITY_PROPERTY(PROP_COLOR_SPREAD, xColor, setColorSpread); + READ_ENTITY_PROPERTY(PROP_COLOR_START, xColor, setColorStart); + READ_ENTITY_PROPERTY(PROP_COLOR_FINISH, xColor, setColorFinish); + READ_ENTITY_PROPERTY(PROP_ALPHA, float, setAlpha); + READ_ENTITY_PROPERTY(PROP_ALPHA_SPREAD, float, setAlphaSpread); + READ_ENTITY_PROPERTY(PROP_ALPHA_START, float, setAlphaStart); + READ_ENTITY_PROPERTY(PROP_ALPHA_FINISH, float, setAlphaFinish); - if (args.bitstreamVersion >= VERSION_ENTITIES_PARTICLE_ELLIPSOID_EMITTER) { - READ_ENTITY_PROPERTY(PROP_EMIT_SPEED, float, setEmitSpeed); - READ_ENTITY_PROPERTY(PROP_SPEED_SPREAD, float, setSpeedSpread); - READ_ENTITY_PROPERTY(PROP_EMIT_ORIENTATION, glm::quat, setEmitOrientation); - READ_ENTITY_PROPERTY(PROP_EMIT_DIMENSIONS, glm::vec3, setEmitDimensions); - READ_ENTITY_PROPERTY(PROP_EMIT_RADIUS_START, float, setEmitRadiusStart); - READ_ENTITY_PROPERTY(PROP_POLAR_START, float, setPolarStart); - READ_ENTITY_PROPERTY(PROP_POLAR_FINISH, float, setPolarFinish); - READ_ENTITY_PROPERTY(PROP_AZIMUTH_START, float, setAzimuthStart); - READ_ENTITY_PROPERTY(PROP_AZIMUTH_FINISH, float, setAzimuthFinish); - } + READ_ENTITY_PROPERTY(PROP_EMIT_SPEED, float, setEmitSpeed); + READ_ENTITY_PROPERTY(PROP_SPEED_SPREAD, float, setSpeedSpread); + READ_ENTITY_PROPERTY(PROP_EMIT_ORIENTATION, glm::quat, setEmitOrientation); + READ_ENTITY_PROPERTY(PROP_EMIT_DIMENSIONS, glm::vec3, setEmitDimensions); + READ_ENTITY_PROPERTY(PROP_EMIT_RADIUS_START, float, setEmitRadiusStart); + READ_ENTITY_PROPERTY(PROP_POLAR_START, float, setPolarStart); + READ_ENTITY_PROPERTY(PROP_POLAR_FINISH, float, setPolarFinish); + READ_ENTITY_PROPERTY(PROP_AZIMUTH_START, float, setAzimuthStart); + READ_ENTITY_PROPERTY(PROP_AZIMUTH_FINISH, float, setAzimuthFinish); - if (args.bitstreamVersion >= VERSION_ENTITIES_PARTICLES_ADDITIVE_BLENDING) { - READ_ENTITY_PROPERTY(PROP_EMITTER_SHOULD_TRAIL, bool, setEmitterShouldTrail); - } + READ_ENTITY_PROPERTY(PROP_EMITTER_SHOULD_TRAIL, bool, setEmitterShouldTrail); return bytesRead; } diff --git a/libraries/networking/src/udt/PacketHeaders.cpp b/libraries/networking/src/udt/PacketHeaders.cpp index 4ce84c64f1..ef2768b0af 100644 --- a/libraries/networking/src/udt/PacketHeaders.cpp +++ b/libraries/networking/src/udt/PacketHeaders.cpp @@ -29,9 +29,9 @@ PacketVersion versionForPacketType(PacketType packetType) { case PacketType::EntityAdd: case PacketType::EntityEdit: case PacketType::EntityData: - return VERSION_ENTITIES_STROKE_COLOR_PROPERTY; case PacketType::EntityPhysics: - return VERSION_ENTITIES_HAZE; + return static_cast(EntityVersion::StrokeColorProperty); + case PacketType::EntityQuery: return static_cast(EntityQueryPacketVersion::JSONFilterWithFamilyTree); case PacketType::AvatarIdentity: diff --git a/libraries/networking/src/udt/PacketHeaders.h b/libraries/networking/src/udt/PacketHeaders.h index fa5f910810..825682d742 100644 --- a/libraries/networking/src/udt/PacketHeaders.h +++ b/libraries/networking/src/udt/PacketHeaders.h @@ -194,6 +194,7 @@ void sendWrongProtocolVersionsSignature(bool sendWrongVersion); /// for debuggin uint qHash(const PacketType& key, uint seed); QDebug operator<<(QDebug debug, const PacketType& type); +/* const PacketVersion VERSION_OCTREE_HAS_FILE_BREAKS = 1; const PacketVersion VERSION_ENTITIES_HAVE_ANIMATION = 1; const PacketVersion VERSION_ROOT_ELEMENT_HAS_DATA = 2; @@ -272,7 +273,11 @@ const PacketVersion VERSION_ENTITIES_HAS_CERTIFICATE_PROPERTIES = 74; const PacketVersion VERSION_ENTITIES_HAZE = 75; const PacketVersion VERSION_ENTITIES_UV_MODE_PROPERTY = 76; const PacketVersion VERSION_ENTITIES_STROKE_COLOR_PROPERTY = 77; +*/ +enum class EntityVersion : PacketVersion { + StrokeColorProperty = 77 +}; enum class EntityScriptCallMethodVersion : PacketVersion { diff --git a/libraries/octree/src/Octree.cpp b/libraries/octree/src/Octree.cpp index ad16a97bf6..7563122290 100644 --- a/libraries/octree/src/Octree.cpp +++ b/libraries/octree/src/Octree.cpp @@ -1721,8 +1721,8 @@ bool Octree::readFromStream(uint64_t streamLength, QDataStream& inputStream, con device->ungetChar(firstChar); if (firstChar == (char) PacketType::EntityData) { - qCDebug(octree) << "Reading from binary SVO Stream length:" << streamLength; - return readSVOFromStream(streamLength, inputStream); + qCWarning(octree) << "Reading from binary SVO no longer supported"; + return false; } else { qCDebug(octree) << "Reading from JSON SVO Stream length:" << streamLength; return readJSONFromStream(streamLength, inputStream, marketplaceID); @@ -1730,137 +1730,6 @@ bool Octree::readFromStream(uint64_t streamLength, QDataStream& inputStream, con } -bool Octree::readSVOFromStream(uint64_t streamLength, QDataStream& inputStream) { - qWarning() << "SVO file format depricated. Support for reading SVO files is no longer support and will be removed soon."; - - bool fileOk = false; - - PacketVersion gotVersion = 0; - - uint64_t headerLength = 0; // bytes in the header - - bool wantImportProgress = true; - - PacketType expectedType = expectedDataPacketType(); - PacketVersion expectedVersion = versionForPacketType(expectedType); - bool hasBufferBreaks = versionHasSVOfileBreaks(expectedVersion); - - // before reading the file, check to see if this version of the Octree supports file versions - if (getWantSVOfileVersions()) { - - // read just enough of the file to parse the header... - const uint64_t HEADER_LENGTH = sizeof(int) + sizeof(PacketVersion); - unsigned char fileHeader[HEADER_LENGTH]; - inputStream.readRawData((char*)&fileHeader, HEADER_LENGTH); - - headerLength = HEADER_LENGTH; // we need this later to skip to the data - - unsigned char* dataAt = (unsigned char*)&fileHeader; - uint64_t dataLength = HEADER_LENGTH; - - // if so, read the first byte of the file and see if it matches the expected version code - int intPacketType; - memcpy(&intPacketType, dataAt, sizeof(intPacketType)); - PacketType gotType = (PacketType) intPacketType; - - dataAt += sizeof(expectedType); - dataLength -= sizeof(expectedType); - gotVersion = *dataAt; - - if (gotType == expectedType) { - if (canProcessVersion(gotVersion)) { - dataAt += sizeof(gotVersion); - dataLength -= sizeof(gotVersion); - fileOk = true; - qCDebug(octree, "SVO file version match. Expected: %d Got: %d", - versionForPacketType(expectedDataPacketType()), gotVersion); - - hasBufferBreaks = versionHasSVOfileBreaks(gotVersion); - } else { - qCDebug(octree, "SVO file version mismatch. Expected: %d Got: %d", - versionForPacketType(expectedDataPacketType()), gotVersion); - } - } else { - qCDebug(octree) << "SVO file type mismatch. Expected: " << expectedType - << " Got: " << gotType; - } - - } else { - qCDebug(octree) << " NOTE: this file type does not include type and version information."; - fileOk = true; // assume the file is ok - } - - if (hasBufferBreaks) { - qCDebug(octree) << " this version includes buffer breaks"; - } else { - qCDebug(octree) << " this version does not include buffer breaks"; - } - - if (fileOk) { - - // if this version of the file does not include buffer breaks, then we need to load the entire file at once - if (!hasBufferBreaks) { - - // read the entire file into a buffer, WHAT!? Why not. - uint64_t dataLength = streamLength - headerLength; - unsigned char* entireFileDataSection = new unsigned char[dataLength]; - inputStream.readRawData((char*)entireFileDataSection, dataLength); - - unsigned char* dataAt = entireFileDataSection; - - ReadBitstreamToTreeParams args(NO_EXISTS_BITS, NULL, 0, - SharedNodePointer(), wantImportProgress, gotVersion); - - readBitstreamToTree(dataAt, dataLength, args); - delete[] entireFileDataSection; - - } else { - - - uint64_t dataLength = streamLength - headerLength; - uint64_t remainingLength = dataLength; - const uint64_t MAX_CHUNK_LENGTH = MAX_OCTREE_PACKET_SIZE * 2; - unsigned char* fileChunk = new unsigned char[MAX_CHUNK_LENGTH]; - - while (remainingLength > 0) { - quint16 chunkLength = 0; - - inputStream.readRawData((char*)&chunkLength, sizeof(chunkLength)); - remainingLength -= sizeof(chunkLength); - - if (chunkLength > remainingLength) { - qCDebug(octree) << "UNEXPECTED chunk size of:" << chunkLength - << "greater than remaining length:" << remainingLength; - break; - } - - if (chunkLength > MAX_CHUNK_LENGTH) { - qCDebug(octree) << "UNEXPECTED chunk size of:" << chunkLength - << "greater than MAX_CHUNK_LENGTH:" << MAX_CHUNK_LENGTH; - break; - } - - inputStream.readRawData((char*)fileChunk, chunkLength); - - remainingLength -= chunkLength; - - unsigned char* dataAt = fileChunk; - uint64_t dataLength = chunkLength; - - ReadBitstreamToTreeParams args(NO_EXISTS_BITS, NULL, 0, - SharedNodePointer(), wantImportProgress, gotVersion); - - readBitstreamToTree(dataAt, dataLength, args); - } - - delete[] fileChunk; - } - } - - - return fileOk; -} - // hack to get the marketplace id into the entities. We will create a way to get this from a hash of // the entity later, but this helps us move things along for now QJsonDocument addMarketplaceIDToDocumentEntities(QJsonDocument& doc, const QString& marketplaceID) { diff --git a/libraries/octree/src/Octree.h b/libraries/octree/src/Octree.h index a2df5f44e5..a252011ba0 100644 --- a/libraries/octree/src/Octree.h +++ b/libraries/octree/src/Octree.h @@ -208,8 +208,6 @@ public: // own definition. Implement these to allow your octree based server to support editing virtual bool getWantSVOfileVersions() const { return false; } virtual PacketType expectedDataPacketType() const { return PacketType::Unknown; } - virtual bool canProcessVersion(PacketVersion thisVersion) const { - return thisVersion == versionForPacketType(expectedDataPacketType()); } virtual PacketVersion expectedVersion() const { return versionForPacketType(expectedDataPacketType()); } virtual bool handlesEditPacketType(PacketType packetType) const { return false; } virtual int processEditPacketData(ReceivedMessage& message, const unsigned char* editData, int maxLength, @@ -222,11 +220,6 @@ public: virtual void releaseSceneEncodeData(OctreeElementExtraEncodeData* extraEncodeData) const { } virtual bool mustIncludeAllChildData() const { return true; } - /// some versions of the SVO file will include breaks with buffer lengths between each buffer chunk in the SVO - /// file. If the Octree subclass expects this for this particular version of the file, it should override this - /// method and return true. - virtual bool versionHasSVOfileBreaks(PacketVersion thisVersion) const { return false; } - virtual void update() { } // nothing to do by default OctreeElementPointer getRoot() { return _rootElement; } From 92f765fe5250523da50c796b2271dd747544794b Mon Sep 17 00:00:00 2001 From: Dante Ruiz Date: Tue, 24 Oct 2017 13:53:50 -0700 Subject: [PATCH 54/60] property set echomode for keyboard for wallet and webviews --- .../resources/html/raiseAndLowerKeyboard.js | 13 ++++++++-- .../qml/LoginDialog/LinkAccountBody.qml | 1 - .../resources/qml/controls/TabletWebView.qml | 10 ++++++-- interface/resources/qml/controls/WebView.qml | 2 ++ .../hifi/commerce/wallet/PassphraseModal.qml | 4 ++++ .../commerce/wallet/PassphraseSelection.qml | 24 ++++++++++++------- .../qml/hifi/commerce/wallet/Wallet.qml | 5 ++++ libraries/ui/src/ui/OffscreenQmlSurface.cpp | 12 ++++++++-- libraries/ui/src/ui/OffscreenQmlSurface.h | 2 +- 9 files changed, 56 insertions(+), 17 deletions(-) diff --git a/interface/resources/html/raiseAndLowerKeyboard.js b/interface/resources/html/raiseAndLowerKeyboard.js index 2535416fd8..23f3a7e9a8 100644 --- a/interface/resources/html/raiseAndLowerKeyboard.js +++ b/interface/resources/html/raiseAndLowerKeyboard.js @@ -14,6 +14,12 @@ var isWindowFocused = true; var isKeyboardRaised = false; var isNumericKeyboard = false; + var isPasswordField = false; + + function shouldSetPasswordField() { + var nodeType = document.activeElement.type; + return nodeType === "password"; + } function shouldRaiseKeyboard() { var nodeName = document.activeElement.nodeName; @@ -53,12 +59,14 @@ setInterval(function () { var keyboardRaised = shouldRaiseKeyboard(); var numericKeyboard = shouldSetNumeric(); + var passwordField = shouldSetPasswordField(); - if (isWindowFocused && (keyboardRaised !== isKeyboardRaised || numericKeyboard !== isNumericKeyboard)) { + if (isWindowFocused && + (keyboardRaised !== isKeyboardRaised || numericKeyboard !== isNumericKeyboard || passwordField !== isPasswordField)) { if (typeof EventBridge !== "undefined" && EventBridge !== null) { EventBridge.emitWebEvent( - keyboardRaised ? ("_RAISE_KEYBOARD" + (numericKeyboard ? "_NUMERIC" : "")) : "_LOWER_KEYBOARD" + keyboardRaised ? ("_RAISE_KEYBOARD" + (numericKeyboard ? "_NUMERIC" : "") + (passwordField ? "_PASSWORD" : "")) : "_LOWER_KEYBOARD" ); } else { if (numWarnings < MAX_WARNINGS) { @@ -74,6 +82,7 @@ isKeyboardRaised = keyboardRaised; isNumericKeyboard = numericKeyboard; + isPasswordField = passwordField; } }, POLL_FREQUENCY); diff --git a/interface/resources/qml/LoginDialog/LinkAccountBody.qml b/interface/resources/qml/LoginDialog/LinkAccountBody.qml index a710c76477..300bcd46f0 100644 --- a/interface/resources/qml/LoginDialog/LinkAccountBody.qml +++ b/interface/resources/qml/LoginDialog/LinkAccountBody.qml @@ -137,7 +137,6 @@ Item { onLinkActivated: loginDialog.openUrl(link) } onFocusChanged: { - console.log("-------> setting variable <-------"); root.text = ""; } } diff --git a/interface/resources/qml/controls/TabletWebView.qml b/interface/resources/qml/controls/TabletWebView.qml index 23143db3ba..8cd61bc90b 100644 --- a/interface/resources/qml/controls/TabletWebView.qml +++ b/interface/resources/qml/controls/TabletWebView.qml @@ -16,6 +16,7 @@ Item { property bool keyboardEnabled: false property bool keyboardRaised: false property bool punctuationMode: false + property bool passwordField: false property bool isDesktop: false property alias webView: web.webViewCore property alias profile: web.webViewCoreProfile @@ -41,7 +42,7 @@ Item { horizontalCenter: parent.horizontalCenter } spacing: 120 - + TabletWebButton { id: back enabledColor: hifi.colors.darkGray @@ -165,6 +166,11 @@ Item { id: keyboard raised: parent.keyboardEnabled && parent.keyboardRaised numeric: parent.punctuationMode + password: parent.passwordField + + onPasswordChanged: { + keyboard.mirroredText = ""; + } anchors { left: parent.left @@ -172,7 +178,7 @@ Item { bottom: parent.bottom } } - + Component.onCompleted: { root.isDesktop = (typeof desktop !== "undefined"); keyboardEnabled = HMD.active; diff --git a/interface/resources/qml/controls/WebView.qml b/interface/resources/qml/controls/WebView.qml index c38c5df9cf..923c8f3fa1 100644 --- a/interface/resources/qml/controls/WebView.qml +++ b/interface/resources/qml/controls/WebView.qml @@ -13,6 +13,7 @@ Item { property bool keyboardEnabled: true // FIXME - Keyboard HMD only: Default to false property bool keyboardRaised: false property bool punctuationMode: false + property bool passwordField: false property alias flickable: webroot.interactive // FIXME - Keyboard HMD only: Make Interface either set keyboardRaised property directly in OffscreenQmlSurface @@ -50,6 +51,7 @@ Item { id: keyboard raised: parent.keyboardEnabled && parent.keyboardRaised numeric: parent.punctuationMode + password: parent.passwordField anchors { left: parent.left right: parent.right diff --git a/interface/resources/qml/hifi/commerce/wallet/PassphraseModal.qml b/interface/resources/qml/hifi/commerce/wallet/PassphraseModal.qml index 2243143906..d967a36b68 100644 --- a/interface/resources/qml/hifi/commerce/wallet/PassphraseModal.qml +++ b/interface/resources/qml/hifi/commerce/wallet/PassphraseModal.qml @@ -27,6 +27,7 @@ Item { id: root; z: 997; property bool keyboardRaised: false; + property bool isPasswordField: false; property string titleBarIcon: ""; property string titleBarText: ""; @@ -202,6 +203,7 @@ Item { onFocusChanged: { root.keyboardRaised = focus; + root.isPasswordField = (focus && passphraseField.echoMode === TextInput.Password); } MouseArea { @@ -209,6 +211,7 @@ Item { onClicked: { root.keyboardRaised = true; + root.isPasswordField = (passphraseField.echoMode === TextInput.Password); mouse.accepted = false; } } @@ -382,6 +385,7 @@ Item { id: keyboard; raised: HMD.mounted && root.keyboardRaised; numeric: parent.punctuationMode; + password: root.isPasswordField; anchors { bottom: parent.bottom; left: parent.left; diff --git a/interface/resources/qml/hifi/commerce/wallet/PassphraseSelection.qml b/interface/resources/qml/hifi/commerce/wallet/PassphraseSelection.qml index 7c0cecd98d..ffeedde8f0 100644 --- a/interface/resources/qml/hifi/commerce/wallet/PassphraseSelection.qml +++ b/interface/resources/qml/hifi/commerce/wallet/PassphraseSelection.qml @@ -80,16 +80,18 @@ Item { onFocusChanged: { if (focus) { - sendSignalToWallet({method: 'walletSetup_raiseKeyboard'}); + var hidePassword = (currentPassphraseField.echoMode === TextInput.Password); + sendSignalToWallet({method: 'walletSetup_raiseKeyboard', isPasswordField: hidePassword}); } else if (!passphraseFieldAgain.focus) { - sendSignalToWallet({method: 'walletSetup_lowerKeyboard'}); + sendSignalToWallet({method: 'walletSetup_lowerKeyboard', isPasswordField: false}); } } MouseArea { anchors.fill: parent; onPressed: { - sendSignalToWallet({method: 'walletSetup_raiseKeyboard'}); + var hidePassword = (currentPassphraseField.echoMode === TextInput.Password); + sendSignalToWallet({method: 'walletSetup_raiseKeyboard', isPasswordField: hidePassword}); mouse.accepted = false; } } @@ -116,16 +118,18 @@ Item { MouseArea { anchors.fill: parent; onPressed: { - sendSignalToWallet({method: 'walletSetup_raiseKeyboard'}); + var hidePassword = (passphraseField.echoMode === TextInput.Password); + sendSignalToWallet({method: 'walletSetup_raiseKeyboard', isPasswordField: hidePassword}); mouse.accepted = false; } } onFocusChanged: { if (focus) { - sendMessageToLightbox({method: 'walletSetup_raiseKeyboard'}); + var hidePassword = (passphraseField.echoMode === TextInput.Password); + sendMessageToLightbox({method: 'walletSetup_raiseKeyboard', isPasswordField: hidePassword}); } else if (!passphraseFieldAgain.focus) { - sendMessageToLightbox({method: 'walletSetup_lowerKeyboard'}); + sendMessageToLightbox({method: 'walletSetup_lowerKeyboard', isPasswordField: false}); } } @@ -150,16 +154,18 @@ Item { MouseArea { anchors.fill: parent; onPressed: { - sendSignalToWallet({method: 'walletSetup_raiseKeyboard'}); + var hidePassword = (passphraseFieldAgain.echoMode === TextInput.Password); + sendSignalToWallet({method: 'walletSetup_raiseKeyboard', isPasswordField: hidePassword}); mouse.accepted = false; } } onFocusChanged: { if (focus) { - sendMessageToLightbox({method: 'walletSetup_raiseKeyboard'}); + var hidePassword = (passphraseFieldAgain.echoMode === TextInput.Password); + sendMessageToLightbox({method: 'walletSetup_raiseKeyboard', isPasswordField: hidePassword}); } else if (!passphraseField.focus) { - sendMessageToLightbox({method: 'walletSetup_lowerKeyboard'}); + sendMessageToLightbox({method: 'walletSetup_lowerKeyboard', isPasswordField: false}); } } diff --git a/interface/resources/qml/hifi/commerce/wallet/Wallet.qml b/interface/resources/qml/hifi/commerce/wallet/Wallet.qml index 472dd50b7d..759d7a37eb 100644 --- a/interface/resources/qml/hifi/commerce/wallet/Wallet.qml +++ b/interface/resources/qml/hifi/commerce/wallet/Wallet.qml @@ -29,6 +29,7 @@ Rectangle { property string activeView: "initialize"; property bool keyboardRaised: false; + property bool isPassword: false; Image { anchors.fill: parent; @@ -181,8 +182,10 @@ Rectangle { } } else if (msg.method === 'walletSetup_raiseKeyboard') { root.keyboardRaised = true; + root.isPassword = msg.isPasswordField; } else if (msg.method === 'walletSetup_lowerKeyboard') { root.keyboardRaised = false; + root.isPassword = msg.isPasswordField; } else { sendToScript(msg); } @@ -202,6 +205,7 @@ Rectangle { onSendSignalToWallet: { if (msg.method === 'walletSetup_raiseKeyboard') { root.keyboardRaised = true; + root.isPassword = msg.isPasswordField; } else if (msg.method === 'walletSetup_lowerKeyboard') { root.keyboardRaised = false; } else if (msg.method === 'walletSecurity_changePassphraseCancelled') { @@ -685,6 +689,7 @@ Rectangle { id: keyboard; raised: HMD.mounted && root.keyboardRaised; numeric: parent.punctuationMode; + password: root.isPassword; anchors { bottom: parent.bottom; left: parent.left; diff --git a/libraries/ui/src/ui/OffscreenQmlSurface.cpp b/libraries/ui/src/ui/OffscreenQmlSurface.cpp index ddc9c2e5f3..ecd07a5874 100644 --- a/libraries/ui/src/ui/OffscreenQmlSurface.cpp +++ b/libraries/ui/src/ui/OffscreenQmlSurface.cpp @@ -1082,7 +1082,7 @@ void OffscreenQmlSurface::synthesizeKeyPress(QString key, QObject* targetOverrid } } -void OffscreenQmlSurface::setKeyboardRaised(QObject* object, bool raised, bool numeric) { +void OffscreenQmlSurface::setKeyboardRaised(QObject* object, bool raised, bool numeric, bool passwordField) { #if Q_OS_ANDROID return; #endif @@ -1113,6 +1113,10 @@ void OffscreenQmlSurface::setKeyboardRaised(QObject* object, bool raised, bool n if (item->property("punctuationMode").isValid()) { item->setProperty("punctuationMode", QVariant(numeric)); } + if (item->property("passwordField").isValid()) { + item->setProperty("passwordField", QVariant(passwordField)); + } + item->setProperty("keyboardRaised", QVariant(raised)); return; } @@ -1137,9 +1141,13 @@ void OffscreenQmlSurface::emitWebEvent(const QVariant& message) { const QString RAISE_KEYBOARD = "_RAISE_KEYBOARD"; const QString RAISE_KEYBOARD_NUMERIC = "_RAISE_KEYBOARD_NUMERIC"; const QString LOWER_KEYBOARD = "_LOWER_KEYBOARD"; + const QString RAISE_KEYBOARD_NUMERIC_PASSWORD = "_RAISE_KEYBOARD_NUMERIC_PASSWORD"; + const QString RAISE_KEYBOARD_PASSWORD = "_RAISE_KEYBOARD_PASSWORD"; QString messageString = message.type() == QVariant::String ? message.toString() : ""; if (messageString.left(RAISE_KEYBOARD.length()) == RAISE_KEYBOARD) { - setKeyboardRaised(_currentFocusItem, true, messageString == RAISE_KEYBOARD_NUMERIC); + bool numeric = (messageString == RAISE_KEYBOARD_NUMERIC || messageString == RAISE_KEYBOARD_NUMERIC_PASSWORD); + bool passwordField = (messageString == RAISE_KEYBOARD_PASSWORD || messageString == RAISE_KEYBOARD_NUMERIC_PASSWORD); + setKeyboardRaised(_currentFocusItem, true, numeric, passwordField); } else if (messageString == LOWER_KEYBOARD) { setKeyboardRaised(_currentFocusItem, false); } else { diff --git a/libraries/ui/src/ui/OffscreenQmlSurface.h b/libraries/ui/src/ui/OffscreenQmlSurface.h index 74eafe9f13..12ee9e59a1 100644 --- a/libraries/ui/src/ui/OffscreenQmlSurface.h +++ b/libraries/ui/src/ui/OffscreenQmlSurface.h @@ -82,7 +82,7 @@ public: QPointF mapToVirtualScreen(const QPointF& originalPoint, QObject* originalWidget); bool eventFilter(QObject* originalDestination, QEvent* event) override; - void setKeyboardRaised(QObject* object, bool raised, bool numeric = false); + void setKeyboardRaised(QObject* object, bool raised, bool numeric = false, bool passwordField = false); Q_INVOKABLE void synthesizeKeyPress(QString key, QObject* targetOverride = nullptr); using TextureAndFence = std::pair; From 275fff4609dafc6f35b40e688062f88f4a4b582f Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Tue, 24 Oct 2017 14:02:47 -0700 Subject: [PATCH 55/60] more CR feedback --- assignment-client/src/scripts/EntityScriptServer.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/assignment-client/src/scripts/EntityScriptServer.cpp b/assignment-client/src/scripts/EntityScriptServer.cpp index 8f4ce65579..c8067ce81f 100644 --- a/assignment-client/src/scripts/EntityScriptServer.cpp +++ b/assignment-client/src/scripts/EntityScriptServer.cpp @@ -588,6 +588,7 @@ void EntityScriptServer::aboutToFinish() { // cleanup the AudioInjectorManager (and any still running injectors) DependencyManager::destroy(); DependencyManager::destroy(); + DependencyManager::destroy(); // cleanup codec & encoder if (_codec && _encoder) { From aad91edba202a7bdf6e8cc016b08e08ed387eaa4 Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Tue, 24 Oct 2017 14:45:33 -0700 Subject: [PATCH 56/60] actually remove all those defines --- libraries/networking/src/udt/PacketHeaders.h | 82 -------------------- 1 file changed, 82 deletions(-) diff --git a/libraries/networking/src/udt/PacketHeaders.h b/libraries/networking/src/udt/PacketHeaders.h index 825682d742..9443ee570d 100644 --- a/libraries/networking/src/udt/PacketHeaders.h +++ b/libraries/networking/src/udt/PacketHeaders.h @@ -194,92 +194,10 @@ void sendWrongProtocolVersionsSignature(bool sendWrongVersion); /// for debuggin uint qHash(const PacketType& key, uint seed); QDebug operator<<(QDebug debug, const PacketType& type); -/* -const PacketVersion VERSION_OCTREE_HAS_FILE_BREAKS = 1; -const PacketVersion VERSION_ENTITIES_HAVE_ANIMATION = 1; -const PacketVersion VERSION_ROOT_ELEMENT_HAS_DATA = 2; -const PacketVersion VERSION_ENTITIES_SUPPORT_SPLIT_MTU = 3; -const PacketVersion VERSION_ENTITIES_HAS_FILE_BREAKS = VERSION_ENTITIES_SUPPORT_SPLIT_MTU; -const PacketVersion VERSION_ENTITIES_SUPPORT_DIMENSIONS = 4; -const PacketVersion VERSION_ENTITIES_MODELS_HAVE_ANIMATION_SETTINGS = 5; -const PacketVersion VERSION_ENTITIES_HAVE_USER_DATA = 6; -const PacketVersion VERSION_ENTITIES_HAS_LAST_SIMULATED_TIME = 7; -const PacketVersion VERSION_MODEL_ENTITIES_SUPPORT_SHAPE_TYPE = 8; -const PacketVersion VERSION_ENTITIES_LIGHT_HAS_INTENSITY_AND_COLOR_PROPERTIES = 9; -const PacketVersion VERSION_ENTITIES_HAS_PARTICLES = 10; -const PacketVersion VERSION_ENTITIES_USE_METERS_AND_RADIANS = 11; -const PacketVersion VERSION_ENTITIES_HAS_COLLISION_MODEL = 12; -const PacketVersion VERSION_ENTITIES_HAS_MARKETPLACE_ID_DAMAGED = 13; -const PacketVersion VERSION_ENTITIES_HAS_MARKETPLACE_ID = 14; -const PacketVersion VERSION_ENTITIES_HAVE_ACCELERATION = 15; -const PacketVersion VERSION_ENTITIES_HAVE_UUIDS = 16; -const PacketVersion VERSION_ENTITIES_ZONE_ENTITIES_EXIST = 17; -const PacketVersion VERSION_ENTITIES_ZONE_ENTITIES_HAVE_DYNAMIC_SHAPE = 18; -const PacketVersion VERSION_ENTITIES_HAVE_NAMES = 19; -const PacketVersion VERSION_ENTITIES_ZONE_ENTITIES_HAVE_ATMOSPHERE = 20; -const PacketVersion VERSION_ENTITIES_ZONE_ENTITIES_HAVE_SKYBOX = 21; -const PacketVersion VERSION_ENTITIES_ZONE_ENTITIES_STAGE_HAS_AUTOMATIC_HOURDAY = 22; -const PacketVersion VERSION_ENTITIES_PARTICLE_ENTITIES_HAVE_TEXTURES = 23; -const PacketVersion VERSION_ENTITIES_HAVE_LINE_TYPE = 24; -const PacketVersion VERSION_ENTITIES_HAVE_COLLISION_SOUND_URL = 25; -const PacketVersion VERSION_ENTITIES_HAVE_FRICTION = 26; -const PacketVersion VERSION_NO_ENTITY_ID_SWAP = 27; -const PacketVersion VERSION_ENTITIES_PARTICLE_FIX = 28; -const PacketVersion VERSION_ENTITIES_LINE_POINTS = 29; -const PacketVersion VERSION_ENTITIES_FACE_CAMERA = 30; -const PacketVersion VERSION_ENTITIES_SCRIPT_TIMESTAMP = 31; -const PacketVersion VERSION_ENTITIES_SCRIPT_TIMESTAMP_FIX = 32; -const PacketVersion VERSION_ENTITIES_HAVE_SIMULATION_OWNER_AND_ACTIONS_OVER_WIRE = 33; -const PacketVersion VERSION_ENTITIES_NEW_PROTOCOL_LAYER = 35; -const PacketVersion VERSION_POLYVOX_TEXTURES = 36; -const PacketVersion VERSION_ENTITIES_POLYLINE = 37; -const PacketVersion VERSION_OCTREE_CENTERED_ORIGIN = 38; -const PacketVersion VERSION_ENTITIES_PARTICLE_MODIFICATIONS = 39; -const PacketVersion VERSION_ENTITIES_POLYVOX_NEIGHBORS = 40; -const PacketVersion VERSION_ENTITIES_PARTICLE_RADIUS_PROPERTIES = 41; -const PacketVersion VERSION_ENTITIES_PARTICLE_COLOR_PROPERTIES = 42; -const PacketVersion VERSION_ENTITIES_PROTOCOL_HEADER_SWAP = 43; -const PacketVersion VERSION_ENTITIES_PARTICLE_ELLIPSOID_EMITTER = 44; -const PacketVersion VERSION_ENTITIES_PROTOCOL_CHANNELS = 45; -const PacketVersion VERSION_ENTITIES_ANIMATION_PROPERTIES_GROUP = 46; -const PacketVersion VERSION_ENTITIES_KEYLIGHT_PROPERTIES_GROUP = 47; -const PacketVersion VERSION_ENTITIES_KEYLIGHT_PROPERTIES_GROUP_BIS = 48; -const PacketVersion VERSION_ENTITIES_PARTICLES_ADDITIVE_BLENDING = 49; -const PacketVersion VERSION_ENTITIES_POLYLINE_TEXTURE = 50; -const PacketVersion VERSION_ENTITIES_HAVE_PARENTS = 51; -const PacketVersion VERSION_ENTITIES_REMOVED_START_AUTOMATICALLY_FROM_ANIMATION_PROPERTY_GROUP = 52; -const PacketVersion VERSION_MODEL_ENTITIES_JOINTS_ON_WIRE = 53; -const PacketVersion VERSION_ENTITITES_HAVE_QUERY_BOX = 54; -const PacketVersion VERSION_ENTITITES_HAVE_COLLISION_MASK = 55; -const PacketVersion VERSION_ATMOSPHERE_REMOVED = 56; -const PacketVersion VERSION_LIGHT_HAS_FALLOFF_RADIUS = 57; -const PacketVersion VERSION_ENTITIES_NO_FLY_ZONES = 58; -const PacketVersion VERSION_ENTITIES_MORE_SHAPES = 59; -const PacketVersion VERSION_ENTITIES_PROPERLY_ENCODE_SHAPE_EDITS = 60; -const PacketVersion VERSION_MODEL_ENTITIES_SUPPORT_STATIC_MESH = 61; -const PacketVersion VERSION_MODEL_ENTITIES_SUPPORT_SIMPLE_HULLS = 62; -const PacketVersion VERSION_WEB_ENTITIES_SUPPORT_DPI = 63; -const PacketVersion VERSION_ENTITIES_ARROW_ACTION = 64; -const PacketVersion VERSION_ENTITIES_LAST_EDITED_BY = 65; -const PacketVersion VERSION_ENTITIES_SERVER_SCRIPTS = 66; -const PacketVersion VERSION_ENTITIES_PHYSICS_PACKET = 67; -const PacketVersion VERSION_ENTITIES_ZONE_FILTERS = 68; -const PacketVersion VERSION_ENTITIES_HINGE_CONSTRAINT = 69; -const PacketVersion VERSION_ENTITIES_BULLET_DYNAMICS = 70; -const PacketVersion VERSION_ENTITIES_HAS_SHOULD_HIGHLIGHT = 71; -const PacketVersion VERSION_ENTITIES_HAS_HIGHLIGHT_SCRIPTING_INTERFACE = 72; -const PacketVersion VERSION_ENTITIES_ANIMATION_ALLOW_TRANSLATION_PROPERTIES = 73; -const PacketVersion VERSION_ENTITIES_HAS_CERTIFICATE_PROPERTIES = 74; -const PacketVersion VERSION_ENTITIES_HAZE = 75; -const PacketVersion VERSION_ENTITIES_UV_MODE_PROPERTY = 76; -const PacketVersion VERSION_ENTITIES_STROKE_COLOR_PROPERTY = 77; -*/ - enum class EntityVersion : PacketVersion { StrokeColorProperty = 77 }; - enum class EntityScriptCallMethodVersion : PacketVersion { ServerCallable = 18, ClientCallable = 19 From 39b2c0f83a6588d317dac179fe12525117a4548e Mon Sep 17 00:00:00 2001 From: beholder Date: Wed, 25 Oct 2017 01:59:56 +0300 Subject: [PATCH 57/60] fix for FB 8553 & FB 8380 --- .../src/display-plugins/CompositorHelper.cpp | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/libraries/display-plugins/src/display-plugins/CompositorHelper.cpp b/libraries/display-plugins/src/display-plugins/CompositorHelper.cpp index 2f57cc29d0..7b639e8308 100644 --- a/libraries/display-plugins/src/display-plugins/CompositorHelper.cpp +++ b/libraries/display-plugins/src/display-plugins/CompositorHelper.cpp @@ -234,7 +234,8 @@ void CompositorHelper::handleLeaveEvent() { bool CompositorHelper::handleRealMouseMoveEvent(bool sendFakeEvent) { // If the mouse move came from a capture mouse related move, we completely ignore it. - if (_ignoreMouseMove) { + // Note: if not going to synthesize event - do not touch _ignoreMouseMove flag + if (_ignoreMouseMove && sendFakeEvent) { _ignoreMouseMove = false; return true; // swallow the event } @@ -246,7 +247,12 @@ bool CompositorHelper::handleRealMouseMoveEvent(bool sendFakeEvent) { auto changeInRealMouse = newPosition - _lastKnownRealMouse; auto newReticlePosition = _reticlePositionInHMD + toGlm(changeInRealMouse); setReticlePosition(newReticlePosition, sendFakeEvent); - _ignoreMouseMove = true; + + // Note: if not going to synthesize event - do not touch _ignoreMouseMove flag + if (sendFakeEvent) { + _ignoreMouseMove = true; + } + QCursor::setPos(QPoint(_lastKnownRealMouse.x(), _lastKnownRealMouse.y())); // move cursor back to where it was return true; // swallow the event } else { From ff0af9f5ccf627117b82d4547072a82617ab2b17 Mon Sep 17 00:00:00 2001 From: utkarshgautamnyu Date: Tue, 24 Oct 2017 20:14:02 -0700 Subject: [PATCH 58/60] Fixed issue with QTextStream --- libraries/baking/src/JSBaker.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/baking/src/JSBaker.cpp b/libraries/baking/src/JSBaker.cpp index 75811bea49..a97a7fe5b3 100644 --- a/libraries/baking/src/JSBaker.cpp +++ b/libraries/baking/src/JSBaker.cpp @@ -72,7 +72,7 @@ void JSBaker::bake() { bool JSBaker::bakeJS(const QByteArray& inputFile, QByteArray& outputFile) { // Read from inputFile and write to outputFile per character QTextStream in(inputFile, QIODevice::ReadOnly); - QTextStream out(outputFile, QIODevice::WriteOnly); + QTextStream out(&outputFile, QIODevice::WriteOnly); // Algorithm requires the knowledge of previous and next character for each character read QChar currentCharacter; From 9b94f3330411474d6092793686dedcd8a974977f Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Tue, 24 Oct 2017 20:48:59 -0700 Subject: [PATCH 59/60] fix ray pick in cases where origin is inside of outer bounding box --- libraries/shared/src/TriangleSet.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/libraries/shared/src/TriangleSet.cpp b/libraries/shared/src/TriangleSet.cpp index 68c99a9753..ce7dd18921 100644 --- a/libraries/shared/src/TriangleSet.cpp +++ b/libraries/shared/src/TriangleSet.cpp @@ -104,8 +104,9 @@ bool TriangleSet::TriangleOctreeCell::findRayIntersectionInternal(const glm::vec if (_bounds.findRayIntersection(origin, direction, boxDistance, face, surfaceNormal)) { // if our bounding box intersects at a distance greater than the current known - // best distance, than we can safely not check any of our triangles - if (boxDistance > bestDistance) { + // best distance, and our origin isn't inside the boounds, then we can safely + // not check any of our triangles + if (boxDistance > bestDistance && !_bounds.contains(origin)) { return false; } From c14bbb76e63d5ae159ddf27afc16b7511fe52a3b Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Wed, 25 Oct 2017 11:57:44 -0700 Subject: [PATCH 60/60] fix compile errors after merge --- libraries/shared/src/ShapeInfo.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/libraries/shared/src/ShapeInfo.cpp b/libraries/shared/src/ShapeInfo.cpp index fd14a9c251..36ce38335a 100644 --- a/libraries/shared/src/ShapeInfo.cpp +++ b/libraries/shared/src/ShapeInfo.cpp @@ -67,7 +67,6 @@ void ShapeInfo::setParams(ShapeType type, const glm::vec3& halfExtents, QString break; case SHAPE_TYPE_BOX: case SHAPE_TYPE_HULL: - case SHAPE_TYPE_SIMPLE_HULL: break; case SHAPE_TYPE_SPHERE: { float radius = glm::length(halfExtents) / SQUARE_ROOT_OF_3; @@ -361,7 +360,7 @@ const DoubleHashKey& ShapeInfo::getHash() const { numHulls = 1; } if (numHulls > 0) { - hash = DoubleHashKey::hashFunction(numHulls, primeIndex++); + uint32_t hash = DoubleHashKey::hashFunction(numHulls, primeIndex++); _doubleHashKey.setHash(_doubleHashKey.getHash() ^ hash); hash = DoubleHashKey::hashFunction2(numHulls); _doubleHashKey.setHash2(_doubleHashKey.getHash2() ^ hash);