diff --git a/interface/resources/qml/hifi/AvatarApp.qml b/interface/resources/qml/hifi/AvatarApp.qml index 10e71062ac..c74ff73c8a 100644 --- a/interface/resources/qml/hifi/AvatarApp.qml +++ b/interface/resources/qml/hifi/AvatarApp.qml @@ -682,6 +682,14 @@ Rectangle { PropertyChanges { target: container; y: -5 } PropertyChanges { target: favoriteAvatarImage; dropShadowRadius: 10 } PropertyChanges { target: favoriteAvatarImage; dropShadowVerticalOffset: 6 } + }, + State { + name: "getMoreAvatarsHovered" + when: getMoreAvatarsMouseArea.containsMouse; + PropertyChanges { target: getMoreAvatarsMouseArea; anchors.bottomMargin: -5 } + PropertyChanges { target: container; y: -5 } + PropertyChanges { target: getMoreAvatarsImage; dropShadowRadius: 10 } + PropertyChanges { target: getMoreAvatarsImage; dropShadowVerticalOffset: 6 } } ] @@ -741,6 +749,7 @@ Rectangle { } ShadowRectangle { + id: getMoreAvatarsImage width: 92 height: 92 radius: 5 @@ -756,7 +765,9 @@ Rectangle { } MouseArea { + id: getMoreAvatarsMouseArea anchors.fill: parent + hoverEnabled: true onClicked: { popup.showBuyAvatars(function() { diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp index 27a52fd0b2..98fbd8fea2 100755 --- a/interface/src/avatar/MyAvatar.cpp +++ b/interface/src/avatar/MyAvatar.cpp @@ -1137,7 +1137,6 @@ void MyAvatar::saveData() { settings.setValue("userHeight", getUserHeight()); settings.setValue("flyingDesktop", getFlyingDesktopPref()); settings.setValue("flyingHMD", getFlyingHMDPref()); - settings.setValue("enabledFlying", getFlyingEnabled()); settings.endGroup(); } diff --git a/scripts/system/controllers/controllerModules/nearParentGrabEntity.js b/scripts/system/controllers/controllerModules/nearParentGrabEntity.js index 38334f5523..a0a4608fbc 100644 --- a/scripts/system/controllers/controllerModules/nearParentGrabEntity.js +++ b/scripts/system/controllers/controllerModules/nearParentGrabEntity.js @@ -12,17 +12,32 @@ findGroupParent, Vec3, cloneEntity, entityIsCloneable, propsAreCloneDynamic, HAPTIC_PULSE_STRENGTH, HAPTIC_PULSE_DURATION, BUMPER_ON_VALUE, findHandChildEntities, TEAR_AWAY_DISTANCE, MSECS_PER_SEC, TEAR_AWAY_CHECK_TIME, TEAR_AWAY_COUNT, distanceBetweenPointAndEntityBoundingBox, print, Uuid, highlightTargetEntity, unhighlightTargetEntity, - distanceBetweenEntityLocalPositionAndBoundingBox + distanceBetweenEntityLocalPositionAndBoundingBox, GRAB_POINT_SPHERE_OFFSET */ Script.include("/~/system/libraries/controllerDispatcherUtils.js"); Script.include("/~/system/libraries/cloneEntityUtils.js"); +Script.include("/~/system/libraries/controllers.js"); (function() { // XXX this.ignoreIK = (grabbableData.ignoreIK !== undefined) ? grabbableData.ignoreIK : true; // XXX this.kinematicGrab = (grabbableData.kinematic !== undefined) ? grabbableData.kinematic : NEAR_GRABBING_KINEMATIC; + function getGrabOffset(handController) { + var offset = GRAB_POINT_SPHERE_OFFSET; + if (handController === Controller.Standard.LeftHand) { + offset = { + x: -GRAB_POINT_SPHERE_OFFSET.x, + y: GRAB_POINT_SPHERE_OFFSET.y, + z: GRAB_POINT_SPHERE_OFFSET.z + }; + } + + offset.y = -GRAB_POINT_SPHERE_OFFSET.y; + return Vec3.multiply(MyAvatar.sensorToWorldScale, offset); + } + function NearParentingGrabEntity(hand) { this.hand = hand; this.targetEntityID = null; @@ -174,7 +189,9 @@ Script.include("/~/system/libraries/cloneEntityUtils.js"); this.lastUnequipCheckTime = now; if (props.parentID === MyAvatar.SELF_ID) { var tearAwayDistance = TEAR_AWAY_DISTANCE * MyAvatar.sensorToWorldScale; - var distance = distanceBetweenEntityLocalPositionAndBoundingBox(props); + var controllerIndex = (this.hand === LEFT_HAND ? Controller.Standard.LeftHand : Controller.Standard.RightHand); + var controllerGrabOffset = getGrabOffset(controllerIndex); + var distance = distanceBetweenEntityLocalPositionAndBoundingBox(props, controllerGrabOffset); if (distance > tearAwayDistance) { this.autoUnequipCounter++; } else { diff --git a/scripts/system/html/entityProperties.html b/scripts/system/html/entityProperties.html index 8d63261f4c..9614f8b8fe 100644 --- a/scripts/system/html/entityProperties.html +++ b/scripts/system/html/entityProperties.html @@ -126,8 +126,8 @@
- - + +
diff --git a/scripts/system/html/js/entityProperties.js b/scripts/system/html/js/entityProperties.js index 8b876304b7..d2cea2d394 100644 --- a/scripts/system/html/js/entityProperties.js +++ b/scripts/system/html/js/entityProperties.js @@ -308,9 +308,10 @@ function setUserDataFromEditor(noUpdate) { } } -function multiDataUpdater(groupName, updateKeyPair, userDataElement, defaults) { +function multiDataUpdater(groupName, updateKeyPair, userDataElement, defaults, removeKeys) { var properties = {}; var parsedData = {}; + var keysToBeRemoved = removeKeys ? removeKeys : []; try { if ($('#userdata-editor').css('height') !== "0px") { // if there is an expanded, we want to use its json. @@ -342,6 +343,12 @@ function multiDataUpdater(groupName, updateKeyPair, userDataElement, defaults) { parsedData[groupName][key] = defaults[key]; } }); + keysToBeRemoved.forEach(function(key) { + if (parsedData[groupName].hasOwnProperty(key)) { + delete parsedData[groupName][key]; + } + }); + if (Object.keys(parsedData[groupName]).length === 0) { delete parsedData[groupName]; } @@ -355,11 +362,11 @@ function multiDataUpdater(groupName, updateKeyPair, userDataElement, defaults) { updateProperties(properties); } -function userDataChanger(groupName, keyName, values, userDataElement, defaultValue) { +function userDataChanger(groupName, keyName, values, userDataElement, defaultValue, removeKeys) { var val = {}, def = {}; val[keyName] = values; def[keyName] = defaultValue; - multiDataUpdater(groupName, val, userDataElement, def); + multiDataUpdater(groupName, val, userDataElement, def, removeKeys); } function setMaterialDataFromEditor(noUpdate) { @@ -711,7 +718,7 @@ function loaded() { var elCloneableLifetime = document.getElementById("property-cloneable-lifetime"); var elCloneableLimit = document.getElementById("property-cloneable-limit"); - var elWantsTrigger = document.getElementById("property-wants-trigger"); + var elTriggerable = document.getElementById("property-triggerable"); var elIgnoreIK = document.getElementById("property-ignore-ik"); var elLifetime = document.getElementById("property-lifetime"); @@ -1234,7 +1241,7 @@ function loaded() { elGrabbable.checked = properties.dynamic; - elWantsTrigger.checked = false; + elTriggerable.checked = false; elIgnoreIK.checked = true; elCloneable.checked = properties.cloneable; @@ -1257,10 +1264,12 @@ function loaded() { } else { elGrabbable.checked = true; } - if ("wantsTrigger" in grabbableData) { - elWantsTrigger.checked = grabbableData.wantsTrigger; + if ("triggerable" in grabbableData) { + elTriggerable.checked = grabbableData.triggerable; + } else if ("wantsTrigger" in grabbableData) { + elTriggerable.checked = grabbableData.wantsTrigger; } else { - elWantsTrigger.checked = false; + elTriggerable.checked = false; } if ("ignoreIK" in grabbableData) { elIgnoreIK.checked = grabbableData.ignoreIK; @@ -1273,7 +1282,7 @@ function loaded() { } if (!grabbablesSet) { elGrabbable.checked = true; - elWantsTrigger.checked = false; + elTriggerable.checked = false; elIgnoreIK.checked = true; elCloneable.checked = false; } @@ -1647,8 +1656,8 @@ function loaded() { elCloneableLifetime.addEventListener('change', createEmitNumberPropertyUpdateFunction('cloneLifetime')); elCloneableLimit.addEventListener('change', createEmitNumberPropertyUpdateFunction('cloneLimit')); - elWantsTrigger.addEventListener('change', function() { - userDataChanger("grabbableKey", "wantsTrigger", elWantsTrigger, elUserData, false); + elTriggerable.addEventListener('change', function() { + userDataChanger("grabbableKey", "triggerable", elTriggerable, elUserData, false, ['wantsTrigger']); }); elIgnoreIK.addEventListener('change', function() { userDataChanger("grabbableKey", "ignoreIK", elIgnoreIK, elUserData, true); diff --git a/scripts/system/libraries/controllerDispatcherUtils.js b/scripts/system/libraries/controllerDispatcherUtils.js index e817bb4ee1..60c4553da7 100644 --- a/scripts/system/libraries/controllerDispatcherUtils.js +++ b/scripts/system/libraries/controllerDispatcherUtils.js @@ -58,7 +58,7 @@ entityIsFarGrabbedByOther:true, highlightTargetEntity:true, clearHighlightedEntities:true, - unhighlightTargetEntity:true + unhighlightTargetEntity:true, distanceBetweenEntityLocalPositionAndBoundingBox: true */ @@ -95,7 +95,7 @@ COLORS_GRAB_DISTANCE_HOLD = { red: 238, green: 75, blue: 214 }; NEAR_GRAB_RADIUS = 1.0; -TEAR_AWAY_DISTANCE = 0.1; // ungrab an entity if its bounding-box moves this far from the hand +TEAR_AWAY_DISTANCE = 0.15; // ungrab an entity if its bounding-box moves this far from the hand TEAR_AWAY_COUNT = 2; // multiply by TEAR_AWAY_CHECK_TIME to know how long the item must be away TEAR_AWAY_CHECK_TIME = 0.15; // seconds, duration between checks DISPATCHER_HOVERING_LIST = "dispactherHoveringList"; @@ -416,13 +416,18 @@ findHandChildEntities = function(hand) { }); }; -distanceBetweenEntityLocalPositionAndBoundingBox = function(entityProps) { - var localPoint = entityProps.localPosition; - var entityXform = new Xform(entityProps.rotation, entityProps.position); - var minOffset = Vec3.multiplyVbyV(entityProps.registrationPoint, entityProps.dimensions); - var maxOffset = Vec3.multiplyVbyV(Vec3.subtract(ONE_VEC, entityProps.registrationPoint), entityProps.dimensions); - var localMin = Vec3.subtract(entityXform.trans, minOffset); - var localMax = Vec3.sum(entityXform.trans, maxOffset); +distanceBetweenEntityLocalPositionAndBoundingBox = function(entityProps, jointGrabOffset) { + var DEFAULT_REGISTRATION_POINT = { x: 0.5, y: 0.5, z: 0.5 }; + var rotInv = Quat.inverse(entityProps.localRotation); + var localPosition = Vec3.sum(entityProps.localPosition, jointGrabOffset); + var localPoint = Vec3.multiplyQbyV(rotInv, Vec3.multiply(localPosition, -1.0)); + + var halfDims = Vec3.multiply(entityProps.dimensions, 0.5); + var regRatio = Vec3.subtract(DEFAULT_REGISTRATION_POINT, entityProps.registrationPoint); + var entityCenter = Vec3.multiplyVbyV(regRatio, entityProps.dimensions); + var localMin = Vec3.subtract(entityCenter, halfDims); + var localMax = Vec3.sum(entityCenter, halfDims); + var v = {x: localPoint.x, y: localPoint.y, z: localPoint.z}; v.x = Math.max(v.x, localMin.x);