Merge pull request #6130 from sethalves/grab

grab script changes
This commit is contained in:
Brad Hefta-Gaub 2015-10-21 09:02:41 -07:00
commit 6902f5c54f

View file

@ -19,7 +19,7 @@ Script.include("../libraries/utils.js");
//
// add lines where the hand ray picking is happening
//
var DEBUG_HAND_RAY_PICKING = false;
var WANT_DEBUG = false;
/////////////////////////////////////////////////////////////////
//
@ -49,6 +49,7 @@ var PICK_MAX_DISTANCE = 500; // max length of pick-ray
// near grabbing
//
var GRAB_RADIUS = 0.3; // if the ray misses but an object is this close, it will still be selected
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_PICK_MAX_DISTANCE = 0.3; // max length of pick-ray for close grabbing to be selected
@ -193,22 +194,23 @@ function MyController(hand, triggerAction) {
};
this.setState = function(newState) {
// print("STATE: " + this.state + " --> " + newState);
if (WANT_DEBUG) {
print("STATE: " + this.state + " --> " + newState);
}
this.state = newState;
}
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
});
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) {
@ -226,14 +228,13 @@ function MyController(hand, triggerAction) {
});
} else {
var age = Entities.getEntityProperties(this.pointer, "age").age;
Entities.editEntity(this.pointer, {
this.pointer = Entities.editEntity(this.pointer, {
position: closePoint,
linePoints: [ZERO_VEC, farPoint],
color: color,
lifetime: age + LIFETIME
});
}
};
this.lineOff = function() {
@ -282,7 +283,6 @@ function MyController(hand, triggerAction) {
return;
}
// the trigger is being pressed, do a ray test
var handPosition = this.getHandPosition();
var distantPickRay = {
@ -290,29 +290,17 @@ function MyController(hand, triggerAction) {
direction: Quat.getUp(this.getHandRotation()),
length: PICK_MAX_DISTANCE
};
var palmPickRay = {
origin: handPosition,
direction: Quat.getFront(this.getHandRotation()),
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);
// don't pick 60x per second. do this check after updating the line so it's not jumpy.
// don't pick 60x per second.
var pickRays = [];
var now = Date.now();
if (now - this.lastPickTime < MSECS_PER_SEC / PICKS_PER_SECOND_PER_HAND) {
return;
if (now - this.lastPickTime > MSECS_PER_SEC / PICKS_PER_SECOND_PER_HAND) {
pickRays = [distantPickRay];
this.lastPickTime = now;
}
this.lastPickTime = now;
var pickRays = [distantPickRay, palmPickRay, otherPickRay];
for (var index=0; index < pickRays.length; ++index) {
var pickRay = pickRays[index];
var directionNormalized = Vec3.normalize(pickRay.direction);
@ -322,12 +310,13 @@ function MyController(hand, triggerAction) {
direction: pickRay.direction
};
if (DEBUG_HAND_RAY_PICKING)
if (WANT_DEBUG) {
this.debugLine(pickRayBacked.origin, Vec3.multiply(pickRayBacked.direction, NEAR_PICK_MAX_DISTANCE), {
red: 0,
green: 255,
blue: 0
})
}
var intersection = Entities.findRayIntersection(pickRayBacked, true);
@ -336,7 +325,6 @@ function MyController(hand, triggerAction) {
var intersectionDistance = Vec3.distance(pickRay.origin, intersection.intersection);
this.grabbedEntity = intersection.entityID;
//this code will disabled the beam for the opposite hand of the one that grabbed it if the entity says so
var grabbableData = getEntityCustomData(GRABBABLE_DATA_KEY, intersection.entityID, DEFAULT_GRABBABLE_DATA);
if (grabbableData["turnOffOppositeBeam"] === true) {
@ -345,7 +333,6 @@ function MyController(hand, triggerAction) {
} else {
disabledHand = RIGHT_HAND;
}
} else {
disabledHand = 'none';
}
@ -380,6 +367,37 @@ function MyController(hand, triggerAction) {
}
}
}
if (this.grabbedEntity === null) {
// forward ray test failed, try sphere test.
var nearbyEntities = Entities.findEntities(handPosition, GRAB_RADIUS);
var minDistance = PICK_MAX_DISTANCE;
var i, props, distance, grabbableData;
for (i = 0; i < nearbyEntities.length; i++) {
var grabbableDataForCandidate =
getEntityCustomData(GRABBABLE_DATA_KEY, nearbyEntities[i], DEFAULT_GRABBABLE_DATA);
if (grabbableDataForCandidate.grabbable === false) {
continue;
}
var propsForCandidate =
Entities.getEntityProperties(nearbyEntities[i], ["position", "name", "collisionsWillMove", "locked"]);
distance = Vec3.distance(propsForCandidate.position, handPosition);
if (distance < minDistance && propsForCandidate.name !== "pointer") {
this.grabbedEntity = nearbyEntities[i];
minDistance = distance;
props = propsForCandidate;
grabbableData = grabbableDataForCandidate;
}
}
if (this.grabbedEntity === null) {
return;
} else if (props.locked === 0 && props.collisionsWillMove === 1) {
this.setState(STATE_NEAR_GRABBING);
} else if (props.collisionsWillMove === 0 && grabbableData.wantsTrigger) {
// We have grabbed a non-physical object, so we want to trigger a non-colliding event as opposed to a grab event
this.setState(STATE_NEAR_GRABBING_NON_COLLIDING);
}
}
};
this.distanceHolding = function() {
@ -441,7 +459,8 @@ function MyController(hand, triggerAction) {
this.lineOn(handPosition, Vec3.subtract(grabbedProperties.position, handPosition), INTERSECT_COLOR);
// 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);
@ -491,7 +510,10 @@ function MyController(hand, triggerAction) {
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));
var handChange = Quat.multiply(Quat.slerp(this.handPreviousRotation,
handRotation,
DISTANCE_HOLDING_ROTATION_EXAGGERATION_FACTOR),
Quat.inverse(this.handPreviousRotation));
this.handPreviousRotation = handRotation;
this.currentObjectRotation = Quat.multiply(handChange, this.currentObjectRotation);
@ -526,7 +548,8 @@ function MyController(hand, triggerAction) {
this.lineOff();
var grabbedProperties = Entities.getEntityProperties(this.grabbedEntity, ["position", "rotation", "gravity", "ignoreForCollisions"]);
var grabbedProperties = Entities.getEntityProperties(this.grabbedEntity,
["position", "rotation", "gravity", "ignoreForCollisions"]);
this.activateEntity(this.grabbedEntity, grabbedProperties);
var handRotation = this.getHandRotation();
@ -764,9 +787,9 @@ function MyController(hand, triggerAction) {
this.release = function() {
if(this.hand!==disabledHand){
if(this.hand !== disabledHand){
//release the disabled hand when we let go with the main one
disabledHand='none';
disabledHand = 'none';
}
this.lineOff();