mirror of
https://github.com/overte-org/overte.git
synced 2025-08-06 17:00:13 +02:00
Merge pull request #6129 from imgntn/grab_two_hand_and_debugging
[Scripts] handControllerGrab.js - add some logic for two-handed situations, add debugging visualization
This commit is contained in:
commit
d0118e80a7
1 changed files with 78 additions and 15 deletions
|
@ -1,8 +1,9 @@
|
||||||
// hydraGrab.js
|
// handControllerGrab.js
|
||||||
// examples
|
// examples
|
||||||
//
|
//
|
||||||
// Created by Eric Levin on 9/2/15
|
// Created by Eric Levin on 9/2/15
|
||||||
// Additions by James B. Pollack @imgntn on 9/24/2015
|
// Additions by James B. Pollack @imgntn on 9/24/2015
|
||||||
|
// Additions By Seth Alves on 10/20/2015
|
||||||
// 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.
|
||||||
|
@ -13,6 +14,13 @@
|
||||||
|
|
||||||
Script.include("../libraries/utils.js");
|
Script.include("../libraries/utils.js");
|
||||||
|
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// add lines where the hand ray picking is happening
|
||||||
|
//
|
||||||
|
var DEBUG_HAND_RAY_PICKING = false;
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////
|
||||||
//
|
//
|
||||||
// these tune time-averaging and "on" value for analog trigger
|
// these tune time-averaging and "on" value for analog trigger
|
||||||
|
@ -43,9 +51,9 @@ var PICK_MAX_DISTANCE = 500; // max length of pick-ray
|
||||||
|
|
||||||
var NEAR_GRABBING_ACTION_TIMEFRAME = 0.05; // how quickly objects move to their new position
|
var NEAR_GRABBING_ACTION_TIMEFRAME = 0.05; // how quickly objects move to their new position
|
||||||
var NEAR_GRABBING_VELOCITY_SMOOTH_RATIO = 1.0; // adjust time-averaging of held object's velocity. 1.0 to disable.
|
var NEAR_GRABBING_VELOCITY_SMOOTH_RATIO = 1.0; // adjust time-averaging of held object's velocity. 1.0 to disable.
|
||||||
var NEAR_PICK_MAX_DISTANCE = 0.2; // max length of pick-ray for close grabbing to be selected
|
var NEAR_PICK_MAX_DISTANCE = 0.3; // max length of pick-ray for close grabbing to be selected
|
||||||
var RELEASE_VELOCITY_MULTIPLIER = 1.5; // affects throwing things
|
var RELEASE_VELOCITY_MULTIPLIER = 1.5; // affects throwing things
|
||||||
var PICK_BACKOFF_DISTANCE = 0.1; // helps when hand is intersecting the grabble object
|
var PICK_BACKOFF_DISTANCE = 0.2; // helps when hand is intersecting the grabble object
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////
|
||||||
//
|
//
|
||||||
|
@ -91,6 +99,8 @@ var DEFAULT_GRABBABLE_DATA = {
|
||||||
invertSolidWhileHeld: false
|
invertSolidWhileHeld: false
|
||||||
};
|
};
|
||||||
|
|
||||||
|
var disabledHand ='none';
|
||||||
|
|
||||||
function getTag() {
|
function getTag() {
|
||||||
return "grab-" + MyAvatar.sessionUUID;
|
return "grab-" + MyAvatar.sessionUUID;
|
||||||
}
|
}
|
||||||
|
@ -188,6 +198,19 @@ function MyController(hand, triggerAction) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
this.debugLine = function(closePoint, farPoint, color){
|
||||||
|
Entities.addEntity({
|
||||||
|
type: "Line",
|
||||||
|
name: "Debug Line",
|
||||||
|
dimensions: LINE_ENTITY_DIMENSIONS,
|
||||||
|
visible: true,
|
||||||
|
position: closePoint,
|
||||||
|
linePoints: [ZERO_VEC, farPoint],
|
||||||
|
color: color,
|
||||||
|
lifetime: 0.1
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
this.lineOn = function(closePoint, farPoint, color) {
|
this.lineOn = function(closePoint, farPoint, color) {
|
||||||
// draw a line
|
// draw a line
|
||||||
if (this.pointer === null) {
|
if (this.pointer === null) {
|
||||||
|
@ -249,11 +272,17 @@ function MyController(hand, triggerAction) {
|
||||||
}
|
}
|
||||||
|
|
||||||
this.search = function() {
|
this.search = function() {
|
||||||
|
//if this hand is the one that's disabled, we don't want to search for anything at all
|
||||||
|
if (this.hand === disabledHand) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (this.triggerSmoothedReleased()) {
|
if (this.triggerSmoothedReleased()) {
|
||||||
this.setState(STATE_RELEASE);
|
this.setState(STATE_RELEASE);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// the trigger is being pressed, do a ray test
|
// the trigger is being pressed, do a ray test
|
||||||
var handPosition = this.getHandPosition();
|
var handPosition = this.getHandPosition();
|
||||||
var distantPickRay = {
|
var distantPickRay = {
|
||||||
|
@ -267,6 +296,13 @@ function MyController(hand, triggerAction) {
|
||||||
length: NEAR_PICK_MAX_DISTANCE
|
length: NEAR_PICK_MAX_DISTANCE
|
||||||
};
|
};
|
||||||
|
|
||||||
|
var otherPickRay = {
|
||||||
|
origin: handPosition,
|
||||||
|
direction: Quat.getRight(this.getHandRotation()),
|
||||||
|
length: NEAR_PICK_MAX_DISTANCE
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
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);
|
||||||
|
|
||||||
// don't pick 60x per second. do this check after updating the line so it's not jumpy.
|
// don't pick 60x per second. do this check after updating the line so it's not jumpy.
|
||||||
|
@ -276,7 +312,7 @@ function MyController(hand, triggerAction) {
|
||||||
}
|
}
|
||||||
this.lastPickTime = now;
|
this.lastPickTime = now;
|
||||||
|
|
||||||
var pickRays = [distantPickRay, palmPickRay];
|
var pickRays = [distantPickRay, palmPickRay, otherPickRay];
|
||||||
for (var index=0; index < pickRays.length; ++index) {
|
for (var index=0; index < pickRays.length; ++index) {
|
||||||
var pickRay = pickRays[index];
|
var pickRay = pickRays[index];
|
||||||
var directionNormalized = Vec3.normalize(pickRay.direction);
|
var directionNormalized = Vec3.normalize(pickRay.direction);
|
||||||
|
@ -286,15 +322,34 @@ function MyController(hand, triggerAction) {
|
||||||
direction: pickRay.direction
|
direction: pickRay.direction
|
||||||
};
|
};
|
||||||
|
|
||||||
|
if (DEBUG_HAND_RAY_PICKING)
|
||||||
|
this.debugLine(pickRayBacked.origin, Vec3.multiply(pickRayBacked.direction, NEAR_PICK_MAX_DISTANCE), {
|
||||||
|
red: 0,
|
||||||
|
green: 255,
|
||||||
|
blue: 0
|
||||||
|
})
|
||||||
|
|
||||||
var intersection = Entities.findRayIntersection(pickRayBacked, true);
|
var intersection = Entities.findRayIntersection(pickRayBacked, true);
|
||||||
|
|
||||||
if (intersection.intersects && intersection.properties.locked === 0) {
|
if (intersection.intersects && intersection.properties.locked === 0) {
|
||||||
// the ray is intersecting something we can move.
|
// the ray is intersecting something we can move.
|
||||||
var intersectionDistance = Vec3.distance(pickRay.origin, intersection.intersection);
|
var intersectionDistance = Vec3.distance(pickRay.origin, intersection.intersection);
|
||||||
this.grabbedEntity = intersection.entityID;
|
this.grabbedEntity = intersection.entityID;
|
||||||
|
|
||||||
var grabbableData = getEntityCustomData(GRABBABLE_DATA_KEY,
|
|
||||||
intersection.entityID,
|
//this code will disabled the beam for the opposite hand of the one that grabbed it if the entity says so
|
||||||
DEFAULT_GRABBABLE_DATA);
|
var grabbableData = getEntityCustomData(GRABBABLE_DATA_KEY, intersection.entityID, DEFAULT_GRABBABLE_DATA);
|
||||||
|
if (grabbableData["turnOffOppositeBeam"] === true) {
|
||||||
|
if (this.hand === RIGHT_HAND) {
|
||||||
|
disabledHand = LEFT_HAND;
|
||||||
|
} else {
|
||||||
|
disabledHand = RIGHT_HAND;
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
disabledHand = 'none';
|
||||||
|
}
|
||||||
|
|
||||||
if (grabbableData.grabbable === false) {
|
if (grabbableData.grabbable === false) {
|
||||||
this.grabbedEntity = null;
|
this.grabbedEntity = null;
|
||||||
continue;
|
continue;
|
||||||
|
@ -386,9 +441,7 @@ function MyController(hand, triggerAction) {
|
||||||
this.lineOn(handPosition, Vec3.subtract(grabbedProperties.position, handPosition), INTERSECT_COLOR);
|
this.lineOn(handPosition, Vec3.subtract(grabbedProperties.position, handPosition), INTERSECT_COLOR);
|
||||||
|
|
||||||
// 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) *
|
var radius = Math.max(Vec3.distance(this.currentObjectPosition, handControllerPosition) * DISTANCE_HOLDING_RADIUS_FACTOR, DISTANCE_HOLDING_RADIUS_FACTOR);
|
||||||
DISTANCE_HOLDING_RADIUS_FACTOR, DISTANCE_HOLDING_RADIUS_FACTOR);
|
|
||||||
|
|
||||||
// how far did avatar move this timestep?
|
// how far did avatar move this timestep?
|
||||||
var currentPosition = MyAvatar.position;
|
var currentPosition = MyAvatar.position;
|
||||||
var avatarDeltaPosition = Vec3.subtract(currentPosition, this.currentAvatarPosition);
|
var avatarDeltaPosition = Vec3.subtract(currentPosition, this.currentAvatarPosition);
|
||||||
|
@ -438,9 +491,7 @@ function MyController(hand, triggerAction) {
|
||||||
this.currentObjectTime = now;
|
this.currentObjectTime = now;
|
||||||
|
|
||||||
// this doubles hand rotation
|
// this doubles hand rotation
|
||||||
var handChange = Quat.multiply(Quat.slerp(this.handPreviousRotation, handRotation,
|
var handChange = Quat.multiply(Quat.slerp(this.handPreviousRotation, handRotation, DISTANCE_HOLDING_ROTATION_EXAGGERATION_FACTOR), Quat.inverse(this.handPreviousRotation));
|
||||||
DISTANCE_HOLDING_ROTATION_EXAGGERATION_FACTOR),
|
|
||||||
Quat.inverse(this.handPreviousRotation));
|
|
||||||
this.handPreviousRotation = handRotation;
|
this.handPreviousRotation = handRotation;
|
||||||
this.currentObjectRotation = Quat.multiply(handChange, this.currentObjectRotation);
|
this.currentObjectRotation = Quat.multiply(handChange, this.currentObjectRotation);
|
||||||
|
|
||||||
|
@ -459,15 +510,23 @@ function MyController(hand, triggerAction) {
|
||||||
this.nearGrabbing = function() {
|
this.nearGrabbing = function() {
|
||||||
var now = Date.now();
|
var now = Date.now();
|
||||||
|
|
||||||
|
var grabbableData = getEntityCustomData(GRABBABLE_DATA_KEY, this.grabbedEntity, DEFAULT_GRABBABLE_DATA);
|
||||||
|
|
||||||
|
var turnOffOtherHand = grabbableData["turnOffOtherHand"];
|
||||||
|
if (turnOffOtherHand === true) {
|
||||||
|
//don't activate the second hand grab because the script is handling the second hand logic
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (this.triggerSmoothedReleased()) {
|
if (this.triggerSmoothedReleased()) {
|
||||||
this.setState(STATE_RELEASE);
|
this.setState(STATE_RELEASE);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
this.lineOff();
|
this.lineOff();
|
||||||
|
|
||||||
var grabbedProperties = Entities.getEntityProperties(this.grabbedEntity,
|
var grabbedProperties = Entities.getEntityProperties(this.grabbedEntity, ["position", "rotation", "gravity", "ignoreForCollisions"]);
|
||||||
["position", "rotation", "gravity", "ignoreForCollisions"]);
|
|
||||||
this.activateEntity(this.grabbedEntity, grabbedProperties);
|
this.activateEntity(this.grabbedEntity, grabbedProperties);
|
||||||
|
|
||||||
var handRotation = this.getHandRotation();
|
var handRotation = this.getHandRotation();
|
||||||
|
@ -705,6 +764,10 @@ function MyController(hand, triggerAction) {
|
||||||
|
|
||||||
this.release = function() {
|
this.release = function() {
|
||||||
|
|
||||||
|
if(this.hand!==disabledHand){
|
||||||
|
//release the disabled hand when we let go with the main one
|
||||||
|
disabledHand='none';
|
||||||
|
}
|
||||||
this.lineOff();
|
this.lineOff();
|
||||||
|
|
||||||
if (this.grabbedEntity !== null) {
|
if (this.grabbedEntity !== null) {
|
||||||
|
|
Loading…
Reference in a new issue