mirror of
https://github.com/lubosz/overte.git
synced 2025-04-15 19:47:38 +02:00
Merge pull request #7253 from hyperlogic/tony/distance-holding-fixes
HandControllerGrab: fixes for distance holding
This commit is contained in:
commit
247ebb380b
1 changed files with 36 additions and 64 deletions
|
@ -1049,9 +1049,14 @@ function MyController(hand) {
|
|||
}
|
||||
|
||||
this.distanceHolding = function() {
|
||||
var handControllerPosition = (this.hand === RIGHT_HAND) ? MyAvatar.rightHandPosition : MyAvatar.leftHandPosition;
|
||||
var controllerHandInput = (this.hand === RIGHT_HAND) ? Controller.Standard.RightHand : Controller.Standard.LeftHand;
|
||||
var handRotation = Quat.multiply(MyAvatar.orientation, Controller.getPoseValue(controllerHandInput).rotation);
|
||||
|
||||
// controller pose is in avatar frame
|
||||
var avatarControllerPose = Controller.getPoseValue((this.hand === RIGHT_HAND) ? Controller.Standard.RightHand : Controller.Standard.LeftHand);
|
||||
|
||||
// transform it into world frame
|
||||
var controllerPosition = Vec3.sum(MyAvatar.position, Vec3.multiplyQbyV(MyAvatar.orientation, avatarControllerPose.translation));
|
||||
var controllerRotation = Quat.multiply(MyAvatar.orientation, avatarControllerPose.rotation);
|
||||
|
||||
var grabbedProperties = Entities.getEntityProperties(this.grabbedEntity, GRABBABLE_PROPERTIES);
|
||||
var now = Date.now();
|
||||
|
||||
|
@ -1059,12 +1064,10 @@ function MyController(hand) {
|
|||
this.currentObjectPosition = grabbedProperties.position;
|
||||
this.currentObjectRotation = grabbedProperties.rotation;
|
||||
this.currentObjectTime = now;
|
||||
this.handRelativePreviousPosition = Vec3.subtract(handControllerPosition, MyAvatar.position);
|
||||
this.handPreviousRotation = handRotation;
|
||||
this.currentCameraOrientation = Camera.orientation;
|
||||
|
||||
// compute a constant based on the initial conditions which we use below to exagerate hand motion onto the held object
|
||||
this.radiusScalar = Math.log(Vec3.distance(this.currentObjectPosition, handControllerPosition) + 1.0);
|
||||
this.radiusScalar = Math.log(Vec3.distance(this.currentObjectPosition, controllerPosition) + 1.0);
|
||||
if (this.radiusScalar < 1.0) {
|
||||
this.radiusScalar = 1.0;
|
||||
}
|
||||
|
@ -1094,10 +1097,10 @@ function MyController(hand) {
|
|||
this.callEntityMethodOnGrabbed("startDistanceGrab");
|
||||
}
|
||||
|
||||
this.currentAvatarPosition = MyAvatar.position;
|
||||
this.currentAvatarOrientation = MyAvatar.orientation;
|
||||
|
||||
this.turnOffVisualizations();
|
||||
|
||||
this.previousControllerPosition = controllerPosition;
|
||||
this.previousControllerRotation = controllerRotation;
|
||||
};
|
||||
|
||||
this.continueDistanceHolding = function() {
|
||||
|
@ -1109,10 +1112,13 @@ function MyController(hand) {
|
|||
|
||||
this.heartBeat(this.grabbedEntity);
|
||||
|
||||
var handPosition = this.getHandPosition();
|
||||
var handControllerPosition = (this.hand === RIGHT_HAND) ? MyAvatar.rightHandPosition : MyAvatar.leftHandPosition;
|
||||
var controllerHandInput = (this.hand === RIGHT_HAND) ? Controller.Standard.RightHand : Controller.Standard.LeftHand;
|
||||
var handRotation = Quat.multiply(MyAvatar.orientation, Controller.getPoseValue(controllerHandInput).rotation);
|
||||
// controller pose is in avatar frame
|
||||
var avatarControllerPose = Controller.getPoseValue((this.hand === RIGHT_HAND) ? Controller.Standard.RightHand : Controller.Standard.LeftHand);
|
||||
|
||||
// transform it into world frame
|
||||
var controllerPosition = Vec3.sum(MyAvatar.position, Vec3.multiplyQbyV(MyAvatar.orientation, avatarControllerPose.translation));
|
||||
var controllerRotation = Quat.multiply(MyAvatar.orientation, avatarControllerPose.rotation);
|
||||
|
||||
var grabbedProperties = Entities.getEntityProperties(this.grabbedEntity, GRABBABLE_PROPERTIES);
|
||||
var grabbableData = getEntityCustomData(GRABBABLE_DATA_KEY, this.grabbedEntity, DEFAULT_GRABBABLE_DATA);
|
||||
|
||||
|
@ -1125,66 +1131,27 @@ function MyController(hand) {
|
|||
return;
|
||||
}
|
||||
|
||||
var now = Date.now();
|
||||
this.currentObjectTime = now;
|
||||
|
||||
// the action was set up on a previous call. update the targets.
|
||||
var radius = Vec3.distance(this.currentObjectPosition, handControllerPosition) *
|
||||
var radius = Vec3.distance(this.currentObjectPosition, controllerPosition) *
|
||||
this.radiusScalar * DISTANCE_HOLDING_RADIUS_FACTOR;
|
||||
if (radius < 1.0) {
|
||||
radius = 1.0;
|
||||
}
|
||||
|
||||
// how far did avatar move this timestep?
|
||||
var currentPosition = MyAvatar.position;
|
||||
var avatarDeltaPosition = Vec3.subtract(currentPosition, this.currentAvatarPosition);
|
||||
this.currentAvatarPosition = currentPosition;
|
||||
// scale delta controller hand movement by radius.
|
||||
var handMoved = Vec3.multiply(Vec3.subtract(controllerPosition, this.previousControllerPosition), radius);
|
||||
|
||||
// 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;
|
||||
// double delta controller rotation
|
||||
var handChange = Quat.multiply(Quat.slerp(this.previousControllerRotation,
|
||||
controllerRotation,
|
||||
DISTANCE_HOLDING_ROTATION_EXAGGERATION_FACTOR),
|
||||
Quat.inverse(this.previousControllerRotation));
|
||||
|
||||
// how far did hand move this timestep?
|
||||
var handMoved = Vec3.subtract(handToAvatar, this.handRelativePreviousPosition);
|
||||
this.handRelativePreviousPosition = handToAvatar;
|
||||
|
||||
// magnify the hand movement but not the change from avatar movement & rotation
|
||||
handMoved = Vec3.subtract(handMoved, handMovementFromTurning);
|
||||
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);
|
||||
newObjectPosition = Vec3.sum(newObjectPosition, avatarDeltaPosition);
|
||||
newObjectPosition = Vec3.sum(newObjectPosition, objectMovementFromTurning);
|
||||
|
||||
var deltaPosition = Vec3.subtract(newObjectPosition, this.currentObjectPosition); // meters
|
||||
var now = Date.now();
|
||||
var deltaTime = (now - this.currentObjectTime) / MSEC_PER_SEC; // convert to seconds
|
||||
|
||||
this.currentObjectPosition = newObjectPosition;
|
||||
this.currentObjectTime = now;
|
||||
|
||||
// this doubles hand rotation
|
||||
var handChange = Quat.multiply(Quat.slerp(this.handPreviousRotation,
|
||||
handRotation,
|
||||
DISTANCE_HOLDING_ROTATION_EXAGGERATION_FACTOR),
|
||||
Quat.inverse(this.handPreviousRotation));
|
||||
this.handPreviousRotation = handRotation;
|
||||
// update the currentObject position and rotation.
|
||||
this.currentObjectPosition = Vec3.sum(this.currentObjectPosition, handMoved);
|
||||
this.currentObjectRotation = Quat.multiply(handChange, this.currentObjectRotation);
|
||||
|
||||
this.callEntityMethodOnGrabbed("continueDistantGrab");
|
||||
|
@ -1195,6 +1162,7 @@ function MyController(hand) {
|
|||
|
||||
var handControllerData = getEntityCustomData('handControllerKey', this.grabbedEntity, defaultMoveWithHeadData);
|
||||
|
||||
var objectToAvatar = Vec3.subtract(this.currentObjectPosition, MyAvatar.position);
|
||||
if (handControllerData.disableMoveWithHead !== true) {
|
||||
// mix in head motion
|
||||
if (MOVE_WITH_HEAD) {
|
||||
|
@ -1234,6 +1202,7 @@ function MyController(hand) {
|
|||
}
|
||||
}
|
||||
|
||||
var handPosition = this.getHandPosition();
|
||||
|
||||
//visualizations
|
||||
if (USE_ENTITY_LINES_FOR_MOVING === true) {
|
||||
|
@ -1265,6 +1234,9 @@ function MyController(hand) {
|
|||
} else {
|
||||
print("continueDistanceHolding -- updateAction failed");
|
||||
}
|
||||
|
||||
this.previousControllerPosition = controllerPosition;
|
||||
this.previousControllerRotation = controllerRotation;
|
||||
};
|
||||
|
||||
this.setupHoldAction = function() {
|
||||
|
|
Loading…
Reference in a new issue