diff --git a/examples/controllers/handControllerGrab.js b/examples/controllers/handControllerGrab.js index 3c8f1f0014..0dce72803c 100644 --- a/examples/controllers/handControllerGrab.js +++ b/examples/controllers/handControllerGrab.js @@ -96,7 +96,7 @@ var MSEC_PER_SEC = 1000.0; var LIFETIME = 10; var ACTION_TTL = 15; // seconds var ACTION_TTL_REFRESH = 5; -var PICKS_PER_SECOND_PER_HAND = 5; +var PICKS_PER_SECOND_PER_HAND = 60; var MSECS_PER_SEC = 1000.0; var GRABBABLE_PROPERTIES = [ "position", @@ -123,8 +123,8 @@ var blacklist = []; //we've created various ways of visualizing looking for and moving distant objects var USE_ENTITY_LINES_FOR_SEARCHING = false; -var USE_OVERLAY_LINES_FOR_SEARCHING = false; -var USE_PARTICLE_BEAM_FOR_SEARCHING = true; +var USE_OVERLAY_LINES_FOR_SEARCHING = true; +var USE_PARTICLE_BEAM_FOR_SEARCHING = false; var USE_ENTITY_LINES_FOR_MOVING = false; var USE_OVERLAY_LINES_FOR_MOVING = false; @@ -290,6 +290,11 @@ function MyController(hand) { this.spotlight = null; this.pointlight = null; this.overlayLine = null; + this.searchSphere = null; + + // how far from camera to search intersection? + this.intersectionDistance = 0.0; + this.searchSphereDistance = 0.0; this.ignoreIK = false; this.offsetPosition = Vec3.ZERO; @@ -409,6 +414,23 @@ function MyController(hand) { } }; + var SEARCH_SPHERE_ALPHA = 0.5; + this.searchSphereOn = function(location, size, color) { + if (this.searchSphere === null) { + var sphereProperties = { + position: location, + size: size, + color: color, + alpha: SEARCH_SPHERE_ALPHA, + solid: true, + visible: true + } + this.searchSphere = Overlays.addOverlay("sphere", sphereProperties); + } else { + Overlays.editOverlay(this.searchSphere, { position: location, size: size, color: color, visible: true }); + } + } + this.overlayLineOn = function(closePoint, farPoint, color) { if (this.overlayLine === null) { var lineProperties = { @@ -654,6 +676,17 @@ function MyController(hand) { this.overlayLine = null; }; + this.searchSphereOff = function() { + if (this.searchSphere !== null) { + //Overlays.editOverlay(this.searchSphere, { visible: false }); + Overlays.deleteOverlay(this.searchSphere); + this.searchSphere = null; + this.searchSphereDistance = 0.0; + this.intersectionDistance = 0.0; + } + + }; + this.particleBeamOff = function() { if (this.particleBeam !== null) { Entities.editEntity(this.particleBeam, { @@ -687,6 +720,7 @@ function MyController(hand) { if (USE_PARTICLE_BEAM_FOR_SEARCHING === true || USE_PARTICLE_BEAM_FOR_MOVING === true) { this.particleBeamOff(); } + this.searchSphereOff(); }; this.triggerPress = function(value) { @@ -712,11 +746,6 @@ function MyController(hand) { return this.triggerValue < TRIGGER_OFF_VALUE; }; - this.triggerSqueezed = function() { - var triggerValue = this.rawTriggerValue; - return triggerValue > TRIGGER_ON_VALUE; - }; - this.bumperSqueezed = function() { return _this.rawBumperValue > BUMPER_ON_VALUE; }; @@ -726,15 +755,15 @@ function MyController(hand) { }; this.off = function() { - if (this.triggerSmoothedSqueezed()) { + if (this.triggerSmoothedSqueezed() || this.bumperSqueezed()) { this.lastPickTime = 0; - this.setState(STATE_SEARCHING); - return; - } - if (this.bumperSqueezed()) { - this.lastPickTime = 0; - this.setState(STATE_EQUIP_SEARCHING); - return; + var controllerHandInput = (this.hand === RIGHT_HAND) ? Controller.Standard.RightHand : Controller.Standard.LeftHand; + this.startingHandRotation = Controller.getPoseValue(controllerHandInput).rotation; + if (this.triggerSmoothedSqueezed()) { + this.setState(STATE_SEARCHING); + } else { + this.setState(STATE_EQUIP_SEARCHING); + } } }; @@ -748,9 +777,14 @@ function MyController(hand) { // the trigger is being pressed, do a ray test var handPosition = this.getHandPosition(); + + var controllerHandInput = (this.hand === RIGHT_HAND) ? Controller.Standard.RightHand : Controller.Standard.LeftHand; + var currentHandRotation = Controller.getPoseValue(controllerHandInput).rotation; + var handDeltaRotation = Quat.multiply(currentHandRotation, Quat.inverse(this.startingHandRotation)); + var distantPickRay = { - origin: handPosition, - direction: Quat.getUp(this.getHandRotation()), + origin: Camera.position, + direction: Quat.getFront(Quat.multiply(Camera.orientation, handDeltaRotation)), length: PICK_MAX_DISTANCE }; @@ -789,7 +823,7 @@ function MyController(hand) { if (intersection.intersects) { // the ray is intersecting something we can move. - var intersectionDistance = Vec3.distance(pickRay.origin, intersection.intersection); + this.intersectionDistance = Vec3.distance(pickRay.origin, intersection.intersection); var grabbableData = getEntityCustomData(GRABBABLE_DATA_KEY, intersection.entityID, DEFAULT_GRABBABLE_DATA); @@ -800,11 +834,11 @@ function MyController(hand) { if (typeof grabbableData.grabbable !== 'undefined' && !grabbableData.grabbable) { continue; } - if (intersectionDistance > pickRay.length) { + if (this.intersectionDistance > pickRay.length) { // too far away for this ray. continue; } - if (intersectionDistance <= NEAR_PICK_MAX_DISTANCE) { + if (this.intersectionDistance <= NEAR_PICK_MAX_DISTANCE) { // the hand is very close to the intersected object. go into close-grabbing mode. if (grabbableData.wantsTrigger) { this.grabbedEntity = intersection.entityID; @@ -851,6 +885,7 @@ function MyController(hand) { } } + // forward ray test failed, try sphere test. if (WANT_DEBUG) { Entities.addEntity({ @@ -946,14 +981,23 @@ function MyController(hand) { this.lineOn(distantPickRay.origin, Vec3.multiply(distantPickRay.direction, LINE_LENGTH), NO_INTERSECT_COLOR); } - if (USE_OVERLAY_LINES_FOR_SEARCHING === true) { - this.overlayLineOn(distantPickRay.origin, Vec3.sum(distantPickRay.origin, Vec3.multiply(distantPickRay.direction, LINE_LENGTH)), NO_INTERSECT_COLOR); - } - if (USE_PARTICLE_BEAM_FOR_SEARCHING === true) { this.handleParticleBeam(distantPickRay.origin, this.getHandRotation(), NO_INTERSECT_COLOR); } - + if (this.intersectionDistance > 0) { + var SPHERE_INTERSECTION_SIZE = 0.011; + var SEARCH_SPHERE_FOLLOW_RATE = 0.50; + var SEARCH_SPHERE_CHASE_DROP = 0.2; + this.searchSphereDistance = this.searchSphereDistance * SEARCH_SPHERE_FOLLOW_RATE + this.intersectionDistance * (1.0 - SEARCH_SPHERE_FOLLOW_RATE); + var searchSphereLocation = Vec3.sum(distantPickRay.origin, Vec3.multiply(distantPickRay.direction, this.searchSphereDistance)); + searchSphereLocation.y -= ((this.intersectionDistance - this.searchSphereDistance) / this.intersectionDistance) * SEARCH_SPHERE_CHASE_DROP; + this.searchSphereOn(searchSphereLocation, SPHERE_INTERSECTION_SIZE * this.intersectionDistance, NO_INTERSECT_COLOR); + if (USE_OVERLAY_LINES_FOR_SEARCHING === true) { + var OVERLAY_BEAM_SETBACK = 0.9; + var startBeam = Vec3.sum(handPosition, Vec3.multiply(Vec3.subtract(searchSphereLocation, handPosition), OVERLAY_BEAM_SETBACK)); + this.overlayLineOn(startBeam, searchSphereLocation, NO_INTERSECT_COLOR); + } + } }; this.distanceHolding = function() {