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);