Merge pull request #5918 from PhilipRosedale/master

Throw held objects with velocity from fingertip
This commit is contained in:
Brad Hefta-Gaub 2015-09-29 14:37:44 -07:00
commit 07515ce710

View file

@ -89,9 +89,11 @@ function MyController(hand, triggerAction) {
this.getHandRotation = MyAvatar.getLeftPalmRotation; this.getHandRotation = MyAvatar.getLeftPalmRotation;
} }
var SPATIAL_CONTROLLERS_PER_PALM = 2;
var TIP_CONTROLLER_OFFSET = 1;
this.triggerAction = triggerAction; this.triggerAction = triggerAction;
this.palm = 2 * hand; this.palm = SPATIAL_CONTROLLERS_PER_PALM * hand;
// this.tip = 2 * hand + 1; // unused, but I'm leaving this here for fear it will be needed this.tip = SPATIAL_CONTROLLERS_PER_PALM * hand + TIP_CONTROLLER_OFFSET;
this.actionID = null; // action this script created... this.actionID = null; // action this script created...
this.grabbedEntity = null; // on this entity. this.grabbedEntity = null; // on this entity.
@ -280,6 +282,9 @@ function MyController(hand, triggerAction) {
Entities.callEntityMethod(this.grabbedEntity, "startDistantGrab"); Entities.callEntityMethod(this.grabbedEntity, "startDistantGrab");
} }
this.currentAvatarPosition = MyAvatar.position;
this.currentAvatarOrientation = MyAvatar.orientation;
}; };
this.continueDistanceHolding = function() { this.continueDistanceHolding = function() {
@ -298,11 +303,46 @@ function MyController(hand, triggerAction) {
// the action was set up on a previous call. update the targets. // the action was set up on a previous call. update the targets.
var radius = Math.max(Vec3.distance(this.currentObjectPosition, handControllerPosition) * DISTANCE_HOLDING_RADIUS_FACTOR, DISTANCE_HOLDING_RADIUS_FACTOR); var radius = Math.max(Vec3.distance(this.currentObjectPosition, handControllerPosition) * DISTANCE_HOLDING_RADIUS_FACTOR, DISTANCE_HOLDING_RADIUS_FACTOR);
// how far did avatar move this timestep?
var currentPosition = MyAvatar.position;
var avatarDeltaPosition = Vec3.subtract(currentPosition, this.currentAvatarPosition);
this.currentAvatarPosition = currentPosition;
// How far did the avatar turn this timestep?
// Note: The following code is too long because we need a Quat.quatBetween() function
// that returns the minimum quaternion between two quaternions.
var currentOrientation = MyAvatar.orientation;
if (Quat.dot(currentOrientation, this.currentAvatarOrientation) < 0.0) {
var negativeCurrentOrientation = {
x: -currentOrientation.x,
y: -currentOrientation.y,
z: -currentOrientation.z,
w: -currentOrientation.w
};
var avatarDeltaOrientation = Quat.multiply(negativeCurrentOrientation, Quat.inverse(this.currentAvatarOrientation));
} else {
var avatarDeltaOrientation = Quat.multiply(currentOrientation, Quat.inverse(this.currentAvatarOrientation));
}
var handToAvatar = Vec3.subtract(handControllerPosition, this.currentAvatarPosition);
var objectToAvatar = Vec3.subtract(this.currentObjectPosition, this.currentAvatarPosition);
var handMovementFromTurning = Vec3.subtract(Quat.multiply(avatarDeltaOrientation, handToAvatar), handToAvatar);
var objectMovementFromTurning = Vec3.subtract(Quat.multiply(avatarDeltaOrientation, objectToAvatar), objectToAvatar);
this.currentAvatarOrientation = currentOrientation;
// how far did hand move this timestep?
var handMoved = Vec3.subtract(handControllerPosition, this.handPreviousPosition); var handMoved = Vec3.subtract(handControllerPosition, this.handPreviousPosition);
this.handPreviousPosition = handControllerPosition; this.handPreviousPosition = handControllerPosition;
// magnify the hand movement but not the change from avatar movement & rotation
handMoved = Vec3.subtract(handMoved, avatarDeltaPosition);
handMoved = Vec3.subtract(handMoved, handMovementFromTurning);
var superHandMoved = Vec3.multiply(handMoved, radius); var superHandMoved = Vec3.multiply(handMoved, radius);
// Move the object by the magnified amount and then by amount from avatar movement & rotation
var newObjectPosition = Vec3.sum(this.currentObjectPosition, superHandMoved); var newObjectPosition = Vec3.sum(this.currentObjectPosition, superHandMoved);
newObjectPosition = Vec3.sum(newObjectPosition, avatarDeltaPosition);
newObjectPosition = Vec3.sum(newObjectPosition, objectMovementFromTurning);
var deltaPosition = Vec3.subtract(newObjectPosition, this.currentObjectPosition); // meters var deltaPosition = Vec3.subtract(newObjectPosition, this.currentObjectPosition); // meters
var now = Date.now(); var now = Date.now();
var deltaTime = (now - this.currentObjectTime) / MSEC_PER_SEC; // convert to seconds var deltaTime = (now - this.currentObjectTime) / MSEC_PER_SEC; // convert to seconds
@ -367,7 +407,8 @@ function MyController(hand, triggerAction) {
} }
this.currentHandControllerPosition = Controller.getSpatialControlPosition(this.palm); this.currentHandControllerTipPosition = Controller.getSpatialControlPosition(this.tip);
this.currentObjectTime = Date.now(); this.currentObjectTime = Date.now();
}; };
@ -377,15 +418,21 @@ function MyController(hand, triggerAction) {
return; return;
} }
// keep track of the measured velocity of the held object // Keep track of the fingertip velocity to impart when we release the object
var handControllerPosition = Controller.getSpatialControlPosition(this.palm); // Note that the idea of using a constant 'tip' velocity regardless of the
// object's actual held offset is an idea intended to make it easier to throw things:
// Because we might catch something or transfer it between hands without a good idea
// of it's actual offset, let's try imparting a velocity which is at a fixed radius
// from the palm.
var handControllerPosition = Controller.getSpatialControlPosition(this.tip);
var now = Date.now(); var now = Date.now();
var deltaPosition = Vec3.subtract(handControllerPosition, this.currentHandControllerPosition); // meters var deltaPosition = Vec3.subtract(handControllerPosition, this.currentHandControllerTipPosition); // meters
var deltaTime = (now - this.currentObjectTime) / MSEC_PER_SEC; // convert to seconds var deltaTime = (now - this.currentObjectTime) / MSEC_PER_SEC; // convert to seconds
this.computeReleaseVelocity(deltaPosition, deltaTime, true); this.computeReleaseVelocity(deltaPosition, deltaTime, true);
this.currentHandControllerPosition = handControllerPosition; this.currentHandControllerTipPosition = handControllerPosition;
this.currentObjectTime = now; this.currentObjectTime = now;
Entities.callEntityMethod(this.grabbedEntity, "continueNearGrab"); Entities.callEntityMethod(this.grabbedEntity, "continueNearGrab");
}; };
@ -468,17 +515,14 @@ function MyController(hand, triggerAction) {
}; };
this.startTouch = function(entityID) { this.startTouch = function(entityID) {
// print('START TOUCH' + entityID);
Entities.callEntityMethod(entityID, "startTouch"); Entities.callEntityMethod(entityID, "startTouch");
}; };
this.continueTouch = function(entityID) { this.continueTouch = function(entityID) {
// print('CONTINUE TOUCH' + entityID);
Entities.callEntityMethod(entityID, "continueTouch"); Entities.callEntityMethod(entityID, "continueTouch");
}; };
this.stopTouch = function(entityID) { this.stopTouch = function(entityID) {
// print('STOP TOUCH' + entityID);
Entities.callEntityMethod(entityID, "stopTouch"); Entities.callEntityMethod(entityID, "stopTouch");
}; };