From 8fbf081223396acd9bf1a46a04a04b54065d6a5c Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Mon, 19 Oct 2015 14:51:18 -0700 Subject: [PATCH] git rid of sphere test --- examples/controllers/handControllerGrab.js | 113 ++++++++++----------- 1 file changed, 53 insertions(+), 60 deletions(-) diff --git a/examples/controllers/handControllerGrab.js b/examples/controllers/handControllerGrab.js index faa90efdff..e6fedd8f25 100644 --- a/examples/controllers/handControllerGrab.js +++ b/examples/controllers/handControllerGrab.js @@ -34,18 +34,18 @@ var NO_INTERSECT_COLOR = { red: 10, green: 10, blue: 255}; // line color when pi var INTERSECT_COLOR = { red: 250, green: 10, blue: 10}; // line color when pick hits var LINE_ENTITY_DIMENSIONS = { x: 1000, y: 1000,z: 1000}; var LINE_LENGTH = 500; - +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.6; // max length of pick-ray for close grabbing to be selected +var NEAR_PICK_MAX_DISTANCE = 0.1; // max length of pick-ray for close grabbing to be selected var RELEASE_VELOCITY_MULTIPLIER = 1.5; // affects throwing things +var PICK_BACKOFF_DISTANCE = 0.2; // helps when hand is intersecting the grabble object ///////////////////////////////////////////////////////////////// // @@ -256,12 +256,18 @@ function MyController(hand, triggerAction) { // the trigger is being pressed, do a ray test var handPosition = this.getHandPosition(); - var pickRay = { + var distantPickRay = { origin: handPosition, - direction: Quat.getUp(this.getHandRotation()) + direction: Quat.getUp(this.getHandRotation()), + length: PICK_MAX_DISTANCE + }; + var palmPickRay = { + origin: handPosition, + direction: Quat.getFront(this.getHandRotation()), + length: NEAR_PICK_MAX_DISTANCE }; - this.lineOn(pickRay.origin, Vec3.multiply(pickRay.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. var now = Date.now(); @@ -270,67 +276,54 @@ function MyController(hand, triggerAction) { } this.lastPickTime = now; - var intersection = Entities.findRayIntersection(pickRay, true); - if (intersection.intersects && intersection.properties.locked === 0) { - // the ray is intersecting something we can move. - var handControllerPosition = Controller.getSpatialControlPosition(this.palm); - var intersectionDistance = Vec3.distance(handControllerPosition, intersection.intersection); - this.grabbedEntity = intersection.entityID; + var pickRays = [distantPickRay, palmPickRay]; + for (var index=0; index < pickRays.length; ++index) { + var pickRay = pickRays[index]; + var directionNormalized = Vec3.normalize(pickRay.direction); + var directionBacked = Vec3.multiply(directionNormalized, PICK_BACKOFF_DISTANCE); + var pickRayBacked = { + origin: Vec3.subtract(pickRay.origin, directionBacked), + direction: pickRay.direction + }; - var grabbableData = getEntityCustomData(GRABBABLE_DATA_KEY, intersection.entityID, DEFAULT_GRABBABLE_DATA); - if (grabbableData.grabbable === false) { - this.grabbedEntity = null; - return; - } - if (intersectionDistance < NEAR_PICK_MAX_DISTANCE) { - // the hand is very close to the intersected object. go into close-grabbing mode. - if (intersection.properties.collisionsWillMove === 1) { - this.setState(STATE_NEAR_GRABBING); - } else { - this.setState(STATE_NEAR_GRABBING_NON_COLLIDING); - } - } else { - // don't allow two people to distance grab the same object - if (entityIsGrabbedByOther(intersection.entityID)) { + var intersection = Entities.findRayIntersection(pickRayBacked, true); + if (intersection.intersects && intersection.properties.locked === 0) { + // the ray is intersecting something we can move. + var intersectionDistance = Vec3.distance(pickRay.origin, intersection.intersection); + this.grabbedEntity = intersection.entityID; + + var grabbableData = getEntityCustomData(GRABBABLE_DATA_KEY, + intersection.entityID, + DEFAULT_GRABBABLE_DATA); + if (grabbableData.grabbable === false) { this.grabbedEntity = null; - } else { - // the hand is far from the intersected object. go into distance-holding mode + continue; + } + if (intersectionDistance > pickRay.length) { + // too far away for this ray. + continue; + } + if (intersectionDistance <= NEAR_PICK_MAX_DISTANCE) { + // the hand is very close to the intersected object. go into close-grabbing mode. if (intersection.properties.collisionsWillMove === 1) { - this.setState(STATE_DISTANCE_HOLDING); + this.setState(STATE_NEAR_GRABBING); } else { - this.setState(STATE_FAR_GRABBING_NON_COLLIDING); + this.setState(STATE_NEAR_GRABBING_NON_COLLIDING); + } + } else { + // don't allow two people to distance grab the same object + if (entityIsGrabbedByOther(intersection.entityID)) { + this.grabbedEntity = null; + } else { + // the hand is far from the intersected object. go into distance-holding mode + if (intersection.properties.collisionsWillMove === 1) { + this.setState(STATE_DISTANCE_HOLDING); + } else { + this.setState(STATE_FAR_GRABBING_NON_COLLIDING); + } } } } - } else { - // forward ray test failed, try sphere test. - var nearbyEntities = Entities.findEntities(handPosition, GRAB_RADIUS); - var minDistance = GRAB_RADIUS; - var i, props, distance; - - for (i = 0; i < nearbyEntities.length; i++) { - - var grabbableData = getEntityCustomData(GRABBABLE_DATA_KEY, nearbyEntities[i], DEFAULT_GRABBABLE_DATA); - if (grabbableData.grabbable === false) { - return; - } - - props = Entities.getEntityProperties(nearbyEntities[i], ["position", "name", "collisionsWillMove", "locked"]); - - distance = Vec3.distance(props.position, handPosition); - if (distance < minDistance && props.name !== "pointer") { - this.grabbedEntity = nearbyEntities[i]; - minDistance = distance; - } - } - if (this.grabbedEntity === null) { - // this.lineOn(pickRay.origin, Vec3.multiply(pickRay.direction, LINE_LENGTH), NO_INTERSECT_COLOR); - } else if (props.locked === 0 && props.collisionsWillMove === 1) { - this.setState(STATE_NEAR_GRABBING); - } else if (props.collisionsWillMove === 0) { - // 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); - } } };