music box and revert hand grab

This commit is contained in:
James B. Pollack 2016-04-05 18:49:33 -07:00
parent cb8adf6c2f
commit 078fe7db90
3 changed files with 208 additions and 367 deletions

View file

@ -7,7 +7,6 @@
// Copyright 2015 High Fidelity, Inc. // Copyright 2015 High Fidelity, Inc.
// //
// Grabs physically moveable entities with hydra-like controllers; it works for either near or far objects. // Grabs physically moveable entities with hydra-like controllers; it works for either near or far objects.
// Also supports touch and equipping objects.
// //
// Distributed under the Apache License, Version 2.0. // Distributed under the Apache License, Version 2.0.
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
@ -46,8 +45,8 @@ var PICK_WITH_HAND_RAY = true;
var DISTANCE_HOLDING_RADIUS_FACTOR = 3.5; // multiplied by distance between hand and object var DISTANCE_HOLDING_RADIUS_FACTOR = 3.5; // multiplied by distance between hand and object
var DISTANCE_HOLDING_ACTION_TIMEFRAME = 0.1; // how quickly objects move to their new position var DISTANCE_HOLDING_ACTION_TIMEFRAME = 0.1; // how quickly objects move to their new position
var DISTANCE_HOLDING_UNITY_MASS = 1200; // The mass at which the distance holding action timeframe is unmodified var DISTANCE_HOLDING_UNITY_MASS = 1200; // The mass at which the distance holding action timeframe is unmodified
var DISTANCE_HOLDING_UNITY_DISTANCE = 6; // The distance at which the distance holding action timeframe is unmodified var DISTANCE_HOLDING_UNITY_DISTANCE = 6; // The distance at which the distance holding action timeframe is unmodified
var DISTANCE_HOLDING_ROTATION_EXAGGERATION_FACTOR = 2.0; // object rotates this much more than hand did var DISTANCE_HOLDING_ROTATION_EXAGGERATION_FACTOR = 2.0; // object rotates this much more than hand did
var MOVE_WITH_HEAD = true; // experimental head-control of distantly held objects var MOVE_WITH_HEAD = true; // experimental head-control of distantly held objects
var FAR_TO_NEAR_GRAB_PADDING_FACTOR = 1.2; var FAR_TO_NEAR_GRAB_PADDING_FACTOR = 1.2;
@ -129,7 +128,6 @@ var GRABBABLE_PROPERTIES = [
var GRABBABLE_DATA_KEY = "grabbableKey"; // shared with grab.js var GRABBABLE_DATA_KEY = "grabbableKey"; // shared with grab.js
var GRAB_USER_DATA_KEY = "grabKey"; // shared with grab.js var GRAB_USER_DATA_KEY = "grabKey"; // shared with grab.js
var GRAB_CONSTRAINTS_USER_DATA_KEY = "grabConstraintsKey"
var DEFAULT_GRABBABLE_DATA = { var DEFAULT_GRABBABLE_DATA = {
disableReleaseVelocity: false disableReleaseVelocity: false
@ -306,7 +304,6 @@ function MyController(hand) {
switch (this.state) { switch (this.state) {
case STATE_OFF: case STATE_OFF:
this.off(); this.off();
this.touchTest();
break; break;
case STATE_SEARCHING: case STATE_SEARCHING:
case STATE_HOLD_SEARCHING: case STATE_HOLD_SEARCHING:
@ -361,7 +358,7 @@ function MyController(hand) {
this.grabSphereOff(); this.grabSphereOff();
if (WANT_DEBUG || WANT_DEBUG_STATE) { if (WANT_DEBUG || WANT_DEBUG_STATE) {
print("STATE (" + this.hand + "): " + stateToName(this.state) + " --> " + print("STATE (" + this.hand + "): " + stateToName(this.state) + " --> " +
stateToName(newState) + ", hand: " + this.hand); stateToName(newState) + ", hand: " + this.hand);
} }
this.state = newState; this.state = newState;
}; };
@ -440,15 +437,11 @@ function MyController(hand) {
} }
this.grabSphereOn = function() { this.grabSphereOn = function() {
var color = { var color = {red: 0, green: 255, blue: 0};
red: 0,
green: 255,
blue: 0
};
if (this.grabSphere === null) { if (this.grabSphere === null) {
var sphereProperties = { var sphereProperties = {
position: this.getHandPosition(), position: this.getHandPosition(),
size: GRAB_RADIUS * 2, size: GRAB_RADIUS*2,
color: color, color: color,
alpha: 0.1, alpha: 0.1,
solid: true, solid: true,
@ -458,7 +451,7 @@ function MyController(hand) {
} else { } else {
Overlays.editOverlay(this.grabSphere, { Overlays.editOverlay(this.grabSphere, {
position: this.getHandPosition(), position: this.getHandPosition(),
size: GRAB_RADIUS * 2, size: GRAB_RADIUS*2,
color: color, color: color,
alpha: 0.1, alpha: 0.1,
solid: true, solid: true,
@ -500,7 +493,8 @@ function MyController(hand) {
} }
}; };
this.searchIndicatorOn = function(handPosition, distantPickRay) { this.searchIndicatorOn = function(distantPickRay) {
var handPosition = distantPickRay.origin;
var SEARCH_SPHERE_SIZE = 0.011; var SEARCH_SPHERE_SIZE = 0.011;
var SEARCH_SPHERE_FOLLOW_RATE = 0.50; var SEARCH_SPHERE_FOLLOW_RATE = 0.50;
@ -511,10 +505,12 @@ function MyController(hand) {
} }
var searchSphereLocation = Vec3.sum(distantPickRay.origin, var searchSphereLocation = Vec3.sum(distantPickRay.origin,
Vec3.multiply(distantPickRay.direction, this.searchSphereDistance)); Vec3.multiply(distantPickRay.direction, this.searchSphereDistance));
this.searchSphereOn(searchSphereLocation, SEARCH_SPHERE_SIZE * this.searchSphereDistance, (this.triggerSmoothedGrab() || this.bumperSqueezed()) ? INTERSECT_COLOR : NO_INTERSECT_COLOR); this.searchSphereOn(searchSphereLocation, SEARCH_SPHERE_SIZE * this.searchSphereDistance,
(this.triggerSmoothedGrab() || this.bumperSqueezed()) ? INTERSECT_COLOR : NO_INTERSECT_COLOR);
if ((USE_OVERLAY_LINES_FOR_SEARCHING === true) && PICK_WITH_HAND_RAY) { if ((USE_OVERLAY_LINES_FOR_SEARCHING === true) && PICK_WITH_HAND_RAY) {
this.overlayLineOn(handPosition, searchSphereLocation, (this.triggerSmoothedGrab() || this.bumperSqueezed()) ? INTERSECT_COLOR : NO_INTERSECT_COLOR); this.overlayLineOn(handPosition, searchSphereLocation,
(this.triggerSmoothedGrab() || this.bumperSqueezed()) ? INTERSECT_COLOR : NO_INTERSECT_COLOR);
} }
} }
@ -860,25 +856,20 @@ function MyController(hand) {
var controllerHandInput = (this.hand === RIGHT_HAND) ? Controller.Standard.RightHand : Controller.Standard.LeftHand; var controllerHandInput = (this.hand === RIGHT_HAND) ? Controller.Standard.RightHand : Controller.Standard.LeftHand;
var currentHandRotation = Controller.getPoseValue(controllerHandInput).rotation; var currentHandRotation = Controller.getPoseValue(controllerHandInput).rotation;
var currentControllerPosition = Controller.getPoseValue(controllerHandInput).position; var currentControllerPosition = Vec3.sum(Vec3.multiplyQbyV(MyAvatar.orientation,
Controller.getPoseValue(controllerHandInput).translation),
MyAvatar.position);
var handDeltaRotation = Quat.multiply(currentHandRotation, Quat.inverse(this.startingHandRotation)); var handDeltaRotation = Quat.multiply(currentHandRotation, Quat.inverse(this.startingHandRotation));
var avatarControllerPose = Controller.getPoseValue((this.hand === RIGHT_HAND) ? var avatarControllerPose = Controller.getPoseValue((this.hand === RIGHT_HAND) ?
Controller.Standard.RightHand : Controller.Standard.LeftHand); Controller.Standard.RightHand : Controller.Standard.LeftHand);
var controllerRotation = Quat.multiply(MyAvatar.orientation, avatarControllerPose.rotation); var controllerRotation = Quat.multiply(MyAvatar.orientation, avatarControllerPose.rotation);
var distantPickRay = { var distantPickRay = {
origin: PICK_WITH_HAND_RAY ? handPosition : Camera.position, origin: PICK_WITH_HAND_RAY ? currentControllerPosition : Camera.position,
direction: PICK_WITH_HAND_RAY ? Quat.getUp(controllerRotation) : Vec3.mix(Quat.getUp(controllerRotation), direction: PICK_WITH_HAND_RAY ? Quat.getUp(controllerRotation) : Vec3.mix(Quat.getUp(controllerRotation),
Quat.getFront(Camera.orientation), Quat.getFront(Camera.orientation),
HAND_HEAD_MIX_RATIO), HAND_HEAD_MIX_RATIO),
length: PICK_MAX_DISTANCE
};
var searchVisualizationPickRay = {
origin: currentControllerPosition,
direction: Quat.getUp(this.getHandRotation()),
length: PICK_MAX_DISTANCE length: PICK_MAX_DISTANCE
}; };
@ -1051,10 +1042,8 @@ function MyController(hand) {
intersectionPointToCenterDistance * intersectionPointToCenterDistance *
FAR_TO_NEAR_GRAB_PADDING_FACTOR); FAR_TO_NEAR_GRAB_PADDING_FACTOR);
} }
this.setState(STATE_DISTANCE_HOLDING); this.setState(STATE_DISTANCE_HOLDING);
this.searchSphereOff(); this.searchSphereOff();
return; return;
} }
@ -1092,7 +1081,7 @@ function MyController(hand) {
this.lineOn(distantPickRay.origin, Vec3.multiply(distantPickRay.direction, LINE_LENGTH), NO_INTERSECT_COLOR); this.lineOn(distantPickRay.origin, Vec3.multiply(distantPickRay.direction, LINE_LENGTH), NO_INTERSECT_COLOR);
} }
this.searchIndicatorOn(handPosition, distantPickRay); this.searchIndicatorOn(distantPickRay);
Reticle.setVisible(false); Reticle.setVisible(false);
}; };
@ -1119,7 +1108,7 @@ function MyController(hand) {
// transform it into world frame // transform it into world frame
var controllerPosition = Vec3.sum(MyAvatar.position, var controllerPosition = Vec3.sum(MyAvatar.position,
Vec3.multiplyQbyV(MyAvatar.orientation, avatarControllerPose.translation)); Vec3.multiplyQbyV(MyAvatar.orientation, avatarControllerPose.translation));
var controllerRotation = Quat.multiply(MyAvatar.orientation, avatarControllerPose.rotation); var controllerRotation = Quat.multiply(MyAvatar.orientation, avatarControllerPose.rotation);
var grabbedProperties = Entities.getEntityProperties(this.grabbedEntity, GRABBABLE_PROPERTIES); var grabbedProperties = Entities.getEntityProperties(this.grabbedEntity, GRABBABLE_PROPERTIES);
@ -1182,11 +1171,11 @@ function MyController(hand) {
// controller pose is in avatar frame // controller pose is in avatar frame
var avatarControllerPose = Controller.getPoseValue((this.hand === RIGHT_HAND) ? var avatarControllerPose = Controller.getPoseValue((this.hand === RIGHT_HAND) ?
Controller.Standard.RightHand : Controller.Standard.LeftHand); Controller.Standard.RightHand : Controller.Standard.LeftHand);
// transform it into world frame // transform it into world frame
var controllerPosition = Vec3.sum(MyAvatar.position, var controllerPosition = Vec3.sum(MyAvatar.position,
Vec3.multiplyQbyV(MyAvatar.orientation, avatarControllerPose.translation)); Vec3.multiplyQbyV(MyAvatar.orientation, avatarControllerPose.translation));
var controllerRotation = Quat.multiply(MyAvatar.orientation, avatarControllerPose.rotation); var controllerRotation = Quat.multiply(MyAvatar.orientation, avatarControllerPose.rotation);
var grabbedProperties = Entities.getEntityProperties(this.grabbedEntity, GRABBABLE_PROPERTIES); var grabbedProperties = Entities.getEntityProperties(this.grabbedEntity, GRABBABLE_PROPERTIES);
@ -1207,9 +1196,9 @@ function MyController(hand) {
// double delta controller rotation // double delta controller rotation
var handChange = Quat.multiply(Quat.slerp(this.previousControllerRotation, var handChange = Quat.multiply(Quat.slerp(this.previousControllerRotation,
controllerRotation, controllerRotation,
DISTANCE_HOLDING_ROTATION_EXAGGERATION_FACTOR), DISTANCE_HOLDING_ROTATION_EXAGGERATION_FACTOR),
Quat.inverse(this.previousControllerRotation)); Quat.inverse(this.previousControllerRotation));
// update the currentObject position and rotation. // update the currentObject position and rotation.
this.currentObjectPosition = Vec3.sum(this.currentObjectPosition, handMoved); this.currentObjectPosition = Vec3.sum(this.currentObjectPosition, handMoved);
@ -1227,7 +1216,7 @@ function MyController(hand) {
var lastVelocity = Vec3.subtract(controllerPosition, this.previousControllerPosition); var lastVelocity = Vec3.subtract(controllerPosition, this.previousControllerPosition);
lastVelocity = Vec3.multiply(lastVelocity, 1.0 / deltaTime); lastVelocity = Vec3.multiply(lastVelocity, 1.0 / deltaTime);
var newRadialVelocity = Vec3.dot(lastVelocity, var newRadialVelocity = Vec3.dot(lastVelocity,
Vec3.normalize(Vec3.subtract(grabbedProperties.position, controllerPosition))); Vec3.normalize(Vec3.subtract(grabbedProperties.position, controllerPosition)));
var VELOCITY_AVERAGING_TIME = 0.016; var VELOCITY_AVERAGING_TIME = 0.016;
this.grabRadialVelocity = (deltaTime / VELOCITY_AVERAGING_TIME) * newRadialVelocity + this.grabRadialVelocity = (deltaTime / VELOCITY_AVERAGING_TIME) * newRadialVelocity +
@ -1356,9 +1345,7 @@ function MyController(hand) {
}; };
this.hasPresetOffsets = function() { this.hasPresetOffsets = function() {
var wearableData = getEntityCustomData('wearable', this.grabbedEntity, { var wearableData = getEntityCustomData('wearable', this.grabbedEntity, {joints: {}});
joints: {}
});
if ("joints" in wearableData) { if ("joints" in wearableData) {
var allowedJoints = wearableData.joints; var allowedJoints = wearableData.joints;
var handJointName = this.hand === RIGHT_HAND ? "RightHand" : "LeftHand"; var handJointName = this.hand === RIGHT_HAND ? "RightHand" : "LeftHand";
@ -1370,9 +1357,7 @@ function MyController(hand) {
} }
this.getPresetPosition = function() { this.getPresetPosition = function() {
var wearableData = getEntityCustomData('wearable', this.grabbedEntity, { var wearableData = getEntityCustomData('wearable', this.grabbedEntity, {joints: {}});
joints: {}
});
var allowedJoints = wearableData.joints; var allowedJoints = wearableData.joints;
var handJointName = this.hand === RIGHT_HAND ? "RightHand" : "LeftHand"; var handJointName = this.hand === RIGHT_HAND ? "RightHand" : "LeftHand";
if (handJointName in allowedJoints) { if (handJointName in allowedJoints) {
@ -1381,9 +1366,7 @@ function MyController(hand) {
} }
this.getPresetRotation = function() { this.getPresetRotation = function() {
var wearableData = getEntityCustomData('wearable', this.grabbedEntity, { var wearableData = getEntityCustomData('wearable', this.grabbedEntity, {joints: {}});
joints: {}
});
var allowedJoints = wearableData.joints; var allowedJoints = wearableData.joints;
var handJointName = this.hand === RIGHT_HAND ? "RightHand" : "LeftHand"; var handJointName = this.hand === RIGHT_HAND ? "RightHand" : "LeftHand";
if (handJointName in allowedJoints) { if (handJointName in allowedJoints) {
@ -1391,23 +1374,7 @@ function MyController(hand) {
} }
} }
this.getGrabConstraints = function() {
var defaultConstraints = {
positionLocked: false,
rotationLocked: false,
positionMod: false,
rotationMod: {
pitch: false,
yaw: false,
roll: false
}
}
var constraints = getEntityCustomData(GRAB_CONSTRAINTS_USER_DATA_KEY, this.grabbedEntity, defaultConstraints);
return constraints;
}
this.nearGrabbing = function() { this.nearGrabbing = function() {
print('NEAR GRAB')
var now = Date.now(); var now = Date.now();
if (this.state == STATE_NEAR_GRABBING && this.triggerSmoothedReleased()) { if (this.state == STATE_NEAR_GRABBING && this.triggerSmoothedReleased()) {
@ -1487,16 +1454,8 @@ function MyController(hand) {
} }
Entities.editEntity(this.grabbedEntity, { Entities.editEntity(this.grabbedEntity, {
velocity: { velocity: {x: 0, y: 0, z: 0},
x: 0, angularVelocity: {x: 0, y: 0, z: 0},
y: 0,
z: 0
},
angularVelocity: {
x: 0,
y: 0,
z: 0
},
dynamic: false dynamic: false
}); });
@ -1528,7 +1487,6 @@ function MyController(hand) {
}; };
this.continueNearGrabbing = function() { this.continueNearGrabbing = function() {
print('CONTINUE NEAR GRAB')
if (this.state == STATE_CONTINUE_NEAR_GRABBING && this.triggerSmoothedReleased()) { if (this.state == STATE_CONTINUE_NEAR_GRABBING && this.triggerSmoothedReleased()) {
this.setState(STATE_RELEASE); this.setState(STATE_RELEASE);
this.callEntityMethodOnGrabbed("releaseGrab"); this.callEntityMethodOnGrabbed("releaseGrab");
@ -1569,7 +1527,7 @@ function MyController(hand) {
Vec3.length(props.localPosition) > NEAR_PICK_MAX_DISTANCE * 2.0) { Vec3.length(props.localPosition) > NEAR_PICK_MAX_DISTANCE * 2.0) {
// for whatever reason, the held/equipped entity has been pulled away. ungrab or unequip. // for whatever reason, the held/equipped entity has been pulled away. ungrab or unequip.
print("handControllerGrab -- autoreleasing held or equipped item because it is far from hand." + print("handControllerGrab -- autoreleasing held or equipped item because it is far from hand." +
props.parentID + " " + vec3toStr(props.position)); props.parentID + " " + vec3toStr(props.position));
this.setState(STATE_RELEASE); this.setState(STATE_RELEASE);
if (this.state == STATE_CONTINUE_NEAR_GRABBING) { if (this.state == STATE_CONTINUE_NEAR_GRABBING) {
this.callEntityMethodOnGrabbed("releaseGrab"); this.callEntityMethodOnGrabbed("releaseGrab");
@ -1617,19 +1575,7 @@ function MyController(hand) {
this.callEntityMethodOnGrabbed("continueNearGrab"); this.callEntityMethodOnGrabbed("continueNearGrab");
} }
var constraints = this.getGrabConstraints();
if (constraints.positionLocked === true) {
print('IT HAS ITS POSITION LOCKED!!')
}
if (constraints.rotationMod !== false) {
print('IT HAS A ROTATION MOD!!!')
}
// so it never seems to hit this currently
if (this.actionID && this.actionTimeout - now < ACTION_TTL_REFRESH * MSEC_PER_SEC) { if (this.actionID && this.actionTimeout - now < ACTION_TTL_REFRESH * MSEC_PER_SEC) {
// if less than a 5 seconds left, refresh the actions ttl // if less than a 5 seconds left, refresh the actions ttl
var success = Entities.updateAction(this.grabbedEntity, this.actionID, { var success = Entities.updateAction(this.grabbedEntity, this.actionID, {
hand: this.hand === RIGHT_HAND ? "right" : "left", hand: this.hand === RIGHT_HAND ? "right" : "left",
@ -1670,9 +1616,6 @@ function MyController(hand) {
} }
this.callEntityMethodOnGrabbed("startNearTrigger"); this.callEntityMethodOnGrabbed("startNearTrigger");
this.setState(STATE_CONTINUE_NEAR_TRIGGER); this.setState(STATE_CONTINUE_NEAR_TRIGGER);
print('START NEAR TRIGGER')
}; };
this.farTrigger = function() { this.farTrigger = function() {
@ -1691,76 +1634,6 @@ function MyController(hand) {
this.callEntityMethodOnGrabbed("stopNearTrigger"); this.callEntityMethodOnGrabbed("stopNearTrigger");
return; return;
} }
var constraints = this.getGrabConstraints();
if (constraints.rotationMod !== false) {
//implement the rotation modifier
var grabbedProps = Entities.getEntityProperties(this.grabbedEntity);
var handPosition = this.getHandPosition();
var modTypes = [];
if (constraints.rotationMod.pitch !== false) {
modTypes.push('pitch')
}
if (constraints.rotationMod.yaw !== false) {
modTypes.push('yaw')
}
if (constraints.rotationMod.roll !== false) {
modTypes.push('roll')
}
var safeEuler = Quat.safeEulerAngles(grabbedProps.rotation);
print('SAFE EULER FOR ROTAITON IS:: ' + JSON.stringify(safeEuler))
finalRotation = {
x: 0,
y: 0,
z: 0
}
finalRotation = safeEuler;
modTypes.forEach(function(modType) {
var value = handPosition[constraints.rotationMod[modType].startingAxis];
var min1 = constraints.rotationMod[modType].startingPoint;
var finalAngle = scale(value, min1, constraints.rotationMod[modType].distanceToMax, constraints.rotationMod[modType].min, constraints.rotationMod[modType].max)
// print('VARS: ')
// print('CONSTRAINTS:: ' + JSON.stringify(constraints))
// print('value: ' + value)
// print('min1:' + min1)
// print('max1:' + constraints.rotationMod[modType].distanceToMax)
// print('min2: ' + constraints.rotationMod[modType].min)
// print('max2: ' + constraints.rotationMod[modType].max)
// print('FINAL ANGLE::' + finalAngle)
if (finalAngle < constraints.rotationMod[modType].min) {
finalAngle = constraints.rotationMod[modType].min;
}
if (finalAngle > constraints.rotationMod[modType].max) {
finalAngle = constraints.rotationMod[modType].max;
}
if (modType === 'pitch') {
finalRotation.x = finalAngle
}
if (modType === 'yaw') {
finalRotation.y = finalAngle
}
if (modType === 'roll') {
finalRotation.z = finalAngle
}
});
Entities.callEntityMethod(this.grabbedEntity, constraints.callback, [JSON.stringify(finalRotation)]);
}
this.callEntityMethodOnGrabbed("continueNearTrigger"); this.callEntityMethodOnGrabbed("continueNearTrigger");
}; };
@ -1790,78 +1663,13 @@ function MyController(hand) {
if (intersection.intersects) { if (intersection.intersects) {
this.intersectionDistance = Vec3.distance(pickRay.origin, intersection.intersection); this.intersectionDistance = Vec3.distance(pickRay.origin, intersection.intersection);
} }
this.searchIndicatorOn(handPosition, pickRay); this.searchIndicatorOn(pickRay);
} }
} }
this.callEntityMethodOnGrabbed("continueFarTrigger"); this.callEntityMethodOnGrabbed("continueFarTrigger");
}; };
_this.allTouchedIDs = {};
this.touchTest = function() {
var maxDistance = 0.05;
var leftHandPosition = MyAvatar.getLeftPalmPosition();
var rightHandPosition = MyAvatar.getRightPalmPosition();
var leftEntities = Entities.findEntities(leftHandPosition, maxDistance);
var rightEntities = Entities.findEntities(rightHandPosition, maxDistance);
var ids = [];
if (leftEntities.length !== 0) {
leftEntities.forEach(function(entity) {
ids.push(entity);
});
}
if (rightEntities.length !== 0) {
rightEntities.forEach(function(entity) {
ids.push(entity);
});
}
ids.forEach(function(id) {
var props = Entities.getEntityProperties(id, ["boundingBox", "name"]);
if (!props ||
!props.boundingBox ||
props.name === 'pointer') {
return;
}
var entityMinPoint = props.boundingBox.brn;
var entityMaxPoint = props.boundingBox.tfl;
var leftIsTouching = pointInExtents(leftHandPosition, entityMinPoint, entityMaxPoint);
var rightIsTouching = pointInExtents(rightHandPosition, entityMinPoint, entityMaxPoint);
if ((leftIsTouching || rightIsTouching) && _this.allTouchedIDs[id] === undefined) {
// we haven't been touched before, but either right or left is touching us now
_this.allTouchedIDs[id] = true;
_this.startTouch(id);
} else if ((leftIsTouching || rightIsTouching) && _this.allTouchedIDs[id]) {
// we have been touched before and are still being touched
// continue touch
_this.continueTouch(id);
} else if (_this.allTouchedIDs[id]) {
delete _this.allTouchedIDs[id];
_this.stopTouch(id);
}
});
};
this.startTouch = function(entityID) {
var args = [this.hand === RIGHT_HAND ? "right" : "left", MyAvatar.sessionUUID];
Entities.callEntityMethod(entityID, "startTouch", args);
};
this.continueTouch = function(entityID) {
var args = [this.hand === RIGHT_HAND ? "right" : "left", MyAvatar.sessionUUID];
Entities.callEntityMethod(entityID, "continueTouch", args);
};
this.stopTouch = function(entityID) {
var args = [this.hand === RIGHT_HAND ? "right" : "left", MyAvatar.sessionUUID];
Entities.callEntityMethod(entityID, "stopTouch", args);
};
this.release = function() { this.release = function() {
this.turnLightsOff(); this.turnLightsOff();
this.turnOffVisualizations(); this.turnOffVisualizations();
@ -1873,7 +1681,6 @@ function MyController(hand) {
// sometimes we want things to stay right where they are when we let go. // sometimes we want things to stay right where they are when we let go.
var grabData = getEntityCustomData(GRAB_USER_DATA_KEY, this.grabbedEntity, {}); var grabData = getEntityCustomData(GRAB_USER_DATA_KEY, this.grabbedEntity, {});
var releaseVelocityData = getEntityCustomData(GRABBABLE_DATA_KEY, this.grabbedEntity, DEFAULT_GRABBABLE_DATA); var releaseVelocityData = getEntityCustomData(GRABBABLE_DATA_KEY, this.grabbedEntity, DEFAULT_GRABBABLE_DATA);
print('RELEASE DATA::' + JSON.stringify(releaseVelocityData))
if (releaseVelocityData.disableReleaseVelocity === true || if (releaseVelocityData.disableReleaseVelocity === true ||
// this next line allowed both: // this next line allowed both:
// (1) far-grab, pull to self, near grab, then throw // (1) far-grab, pull to self, near grab, then throw
@ -1888,7 +1695,6 @@ function MyController(hand) {
this.actionID = null; this.actionID = null;
this.setState(STATE_OFF); this.setState(STATE_OFF);
print('HAS VELOCITY AT RELEASE?? ' + noVelocity)
Messages.sendMessage('Hifi-Object-Manipulation', JSON.stringify({ Messages.sendMessage('Hifi-Object-Manipulation', JSON.stringify({
action: 'release', action: 'release',
grabbedEntity: this.grabbedEntity, grabbedEntity: this.grabbedEntity,
@ -1961,7 +1767,6 @@ function MyController(hand) {
// when using string values // when using string values
"collidesWith": COLLIDES_WITH_WHILE_GRABBED "collidesWith": COLLIDES_WITH_WHILE_GRABBED
}; };
print('ACTIVATING ENTITY')
Entities.editEntity(entityID, whileHeldProperties); Entities.editEntity(entityID, whileHeldProperties);
} else if (data["refCount"] > 1) { } else if (data["refCount"] > 1) {
if (data["heartBeat"] === undefined || if (data["heartBeat"] === undefined ||
@ -1979,12 +1784,9 @@ function MyController(hand) {
// people are holding something and one of them will be able (if the other releases at the right time) to // people are holding something and one of them will be able (if the other releases at the right time) to
// bootstrap themselves with the held object. This happens because the meaning of "otherAvatar" in // bootstrap themselves with the held object. This happens because the meaning of "otherAvatar" in
// the collision mask hinges on who the physics simulation owner is. // the collision mask hinges on who the physics simulation owner is.
Entities.editEntity(entityID, { Entities.editEntity(entityID, {"collidesWith": COLLIDES_WITH_WHILE_MULTI_GRABBED});
"collidesWith": COLLIDES_WITH_WHILE_MULTI_GRABBED
});
} }
} }
print('ACTIVATED ENTITY!!!')
setEntityCustomData(GRAB_USER_DATA_KEY, entityID, data); setEntityCustomData(GRAB_USER_DATA_KEY, entityID, data);
return data; return data;
}; };
@ -1996,9 +1798,7 @@ function MyController(hand) {
var children = Entities.getChildrenIDsOfJoint(MyAvatar.sessionUUID, handJointIndex); var children = Entities.getChildrenIDsOfJoint(MyAvatar.sessionUUID, handJointIndex);
children.forEach(function(childID) { children.forEach(function(childID) {
print("disconnecting stray child of hand: (" + _this.hand + ") " + childID); print("disconnecting stray child of hand: (" + _this.hand + ") " + childID);
Entities.editEntity(childID, { Entities.editEntity(childID, {parentID: NULL_UUID});
parentID: NULL_UUID
});
}); });
} }
@ -2043,27 +1843,13 @@ function MyController(hand) {
data["dynamic"] && data["dynamic"] &&
data["parentID"] == NULL_UUID && data["parentID"] == NULL_UUID &&
!data["collisionless"]) { !data["collisionless"]) {
deactiveProps["velocity"] = {x: 0.0, y: 0.1, z: 0.0};
deactiveProps["velocity"] = {
x: 0.0,
y: 0.1,
z: 0.0
};
doSetVelocity = false; doSetVelocity = false;
} }
if (noVelocity) { if (noVelocity) {
deactiveProps["velocity"] = { deactiveProps["velocity"] = {x: 0.0, y: 0.0, z: 0.0};
x: 0.0, deactiveProps["angularVelocity"] = {x: 0.0, y: 0.0, z: 0.0};
y: 0.0,
z: 0.0
};
deactiveProps["angularVelocity"] = {
x: 0.0,
y: 0.0,
z: 0.0
};
doSetVelocity = false; doSetVelocity = false;
} }
Entities.editEntity(entityID, deactiveProps); Entities.editEntity(entityID, deactiveProps);
@ -2085,31 +1871,13 @@ function MyController(hand) {
var deactiveProps = { var deactiveProps = {
parentID: this.previousParentID, parentID: this.previousParentID,
parentJointIndex: this.previousParentJointIndex, parentJointIndex: this.previousParentJointIndex,
velocity: { velocity: {x: 0.0, y: 0.0, z: 0.0},
x: 0.0, angularVelocity: {x: 0.0, y: 0.0, z: 0.0}
y: 0.0,
z: 0.0
},
angularVelocity: {
x: 0.0,
y: 0.0,
z: 0.0
}
}; };
Entities.editEntity(entityID, deactiveProps); Entities.editEntity(entityID, deactiveProps);
} else if (noVelocity) { } else if (noVelocity) {
Entities.editEntity(entityID, { Entities.editEntity(entityID, {velocity: {x: 0.0, y: 0.0, z: 0.0},
velocity: { angularVelocity: {x: 0.0, y: 0.0, z: 0.0}});
x: 0.0,
y: 0.0,
z: 0.0
},
angularVelocity: {
x: 0.0,
y: 0.0,
z: 0.0
}
});
} }
} else { } else {
data = null; data = null;
@ -2244,8 +2012,3 @@ function cleanup() {
} }
Script.scriptEnding.connect(cleanup); Script.scriptEnding.connect(cleanup);
Script.update.connect(update); Script.update.connect(update);
function scale(value, min1, max1, min2, max2) {
return min2 + (max2 - min2) * ((value - min1) / (max1 - min1));
}

View file

@ -1,6 +1,8 @@
(function() { (function() {
//TODO -- At the part of the animation where the user starts to close the lid we need to rewind any frames past the one where it is aligned for going up/down before switching to the down animation //TODO -- At the part of the animation where the user starts to close the lid we need to rewind any frames past the one where it is aligned for going up/down before switching to the down animation
Script.include('../utils.js');
var GRAB_CONSTRAINTS_USER_DATA_KEY = "grabConstraintsKey"
var _this; var _this;
@ -44,9 +46,166 @@
startNearTrigger: function() { startNearTrigger: function() {
this.getParts(); this.getParts();
}, },
getGrabConstraints: function() {
var defaultConstraints = {
positionLocked: false,
rotationLocked: false,
positionMod: false,
rotationMod: {
pitch: false,
yaw: false,
roll: false
}
}
var constraints = getEntityCustomData(GRAB_CONSTRAINTS_USER_DATA_KEY, this.grabbedEntity, defaultConstraints);
return constraints;
},
getHandPosition: function() {
if (this.hand === 'left') {
return MyAvatar.getLeftPalmPosition();
}
if (this.hand === 'right') {
return MyAvatar.getRightPalmPosition();
}
},
continueNearTrigger: function(myID, paramsArray) {
paramsArray.forEach(function(param, index) {
print('PARAM::' + param)
if (index === 0) {
_this.hand = param;
}
});
print('HAND:: ' + _this.hand);
var constraints = this.getGrabConstraints();
var handPosition = this.getHandPosition();
var modTypes = [];
if (constraints.rotationMod !== false) {
if (constraints.rotationMod.pitch !== false) {
modTypes.push('pitch')
}
if (constraints.rotationMod.yaw !== false) {
modTypes.push('yaw')
}
if (constraints.rotationMod.roll !== false) {
modTypes.push('roll')
}
}
// var properties = Entities.getEntityProperties(this.entityID);
// var constraints = this.getGrabConstraints();
// if (constraints.rotationMod !== false) {
// //implement the rotation modifier
// var grabbedProps = Entities.getEntityProperties(this.grabbedEntity);
var handPosition = this.getHandPosition();
var modTypes = [];
if (constraints.rotationMod.pitch !== false) {
modTypes.push('pitch')
}
if (constraints.rotationMod.yaw !== false) {
modTypes.push('yaw')
}
if (constraints.rotationMod.roll !== false) {
modTypes.push('roll')
}
// get the base position
// get the hand position
//
var baseProps = Entities.getEntityProperties(_this.base);
var baseBoxPosition = baseProps.position;
var handPosition = _this.getHandPosition();
var lidProps = Entities.getEntityProperties(_this.entityID);
var distaceHandToBaseBox = Vec3.distance(baseBoxPosition, handPosition);
var safeEuler = Quat.safeEulerAngles()
var finalRotation = {
x: 0,
y: 0,
z: 0
}
var min1 = 0;
var max1 = 75;
var maxDistance = 0.4;
var finalAngle = scale(distance, 0, maxDistance, 0, 75)
print('FINAL ANGLE:: ' + finalAngle);
if (finalAngle < 0) {
finalAngle = 0;
}
if (finalAngle > 75) {
finalAngle = 75;
}
finalRotation.z = finalAngle;
_this.handleLidActivities(finalRotation)
},
handleLidActivities: function(finalRotation) {
var constraint = finalRotation.z;
//handle sound on open, close, and actually play the song
if (constraint > 20 && this.musicIsPlaying === false) {
this.playMusic();
print('play music!!')
}
if (constraint <= 20 && this.musicIsPlaying === true) {
print('stop music!!')
this.stopMusic();
}
if (constraint > 0 && this.shut === true) {
print('play open sound!!')
this.shut = false;
this.playOpenSound();
this.startHat();
this.startKey();
} else if (constraint <= 0 && this.shut === false) {
print('play shut sound!!')
this.shut = true;
this.playShutSound();
this.stopKey();
this.stopHat();
}
var hatHeight = scaleValue(constraint, MIN_LID_ROTATION, MAX_LID_ROTATION, 0, 0.04);
Entities.editEntity(this.entityID, {
rotation: Quat.fromPitchYawRollDegrees(finalRotation.x, finalRotation.y, finalRotation.z)
})
var VERTICAL_OFFSET = 0.025;
var FORWARD_OFFSET = 0.0;
var LATERAL_OFFSET = 0.0;
var hatOffset = getOffsetFromCenter(VERTICAL_OFFSET, FORWARD_OFFSET, LATERAL_OFFSET)
var baseProps = Entities.getEntityProperties(this.base);
var upOffset = Vec3.multiply(hatHeight, Quat.getUp(baseProps.rotation));
var hatPosition = Vec3.sum(hatOffset, upOffset)
Entities.editEntity(this.hat, {
position: hatPosition
})
continueNearTrigger: function() {
var properties = Entities.getEntityProperties(this.entityID);
}, },
playMusic: function() { playMusic: function() {
@ -103,83 +262,6 @@
} }
}, },
rotateLid: function(myID, paramsArray) {
var finalRotation;
paramsArray.forEach(function(param) {
var p;
// print('param is:' + param)
try {
p = JSON.parse(param);
finalRotation = p;
} catch (err) {
// print('not a json param')
return;
p = param;
}
});
//this might be z now that its roll
var constraint = finalRotation.z
var MIN_LID_ROTATION = 0;
var MAX_LID_ROTATION = 75;
//handle sound on open, close, and actually play the song
if (constraint > 20 && this.musicIsPlaying === false) {
this.playMusic();
print('play music!!')
}
if (constraint <= 20 && this.musicIsPlaying === true) {
print('stop music!!')
this.stopMusic();
}
if (constraint > 0 && this.shut === true) {
print('play open sound!!')
this.shut = false;
this.playOpenSound();
this.startHat();
this.startKey();
} else if (constraint <= 0 && this.shut === false) {
print('play shut sound!!')
this.shut = true;
this.playShutSound();
this.stopKey();
this.stopHat();
}
//handle scaling the lid angle to the animation frame
//0 to 30 hat going up
//30-90 hat spinning
//scale for going up down, and then spin when fully open ;)
var hatHeight = scaleValue(constraint, MIN_LID_ROTATION, MAX_LID_ROTATION, 0, 0.04);
Entities.editEntity(this.entityID, {
rotation: Quat.fromPitchYawRollDegrees(finalRotation.x, finalRotation.y, finalRotation.z)
})
var VERTICAL_OFFSET = 0.025;
var FORWARD_OFFSET = 0.0;
var LATERAL_OFFSET = 0.0;
var hatOffset = getOffsetFromCenter(VERTICAL_OFFSET, FORWARD_OFFSET, LATERAL_OFFSET)
var baseProps = Entities.getEntityProperties(this.base);
var upOffset = Vec3.multiply(hatHeight,Quat.getUp(baseProps.rotation));
var hatPosition = Vec3.sum(hatOffset, upOffset)
Entities.editEntity(this.hat, {
position: hatPosition
})
},
getParts: function() { getParts: function() {
var properties = Entities.getEntityProperties(this.entityID); var properties = Entities.getEntityProperties(this.entityID);
var results = Entities.findEntities(properties.position, 2); var results = Entities.findEntities(properties.position, 2);

View file

@ -88,10 +88,6 @@ HomeMusicBox = function(spawnPosition, spawnRotation) {
'reset': true 'reset': true
}, },
grabConstraintsKey: { grabConstraintsKey: {
callback: 'rotateLid',
positionLocked: true,
rotationLocked: false,
positionMod: false,
rotationMod: { rotationMod: {
pitch: false, pitch: false,
yaw: false, yaw: false,
@ -188,9 +184,9 @@ HomeMusicBox = function(spawnPosition, spawnRotation) {
name: 'home_music_box_base', name: 'home_music_box_base',
type: 'Model', type: 'Model',
position: BASE_POSITION, position: BASE_POSITION,
dynamic: true, // dynamic: true,
shapeType: 'compound', // shapeType: 'compound',
compoundShapeURL: 'atp:/boxHull2.obj', // compoundShapeURL: 'atp:/boxHull2.obj',
dimensions: { dimensions: {
x: 0.1661, x: 0.1661,
y: 0.0928, y: 0.0928,