From 1e6198cf597fef194fc657ce2a992c01cd705409 Mon Sep 17 00:00:00 2001 From: ericrius1 Date: Wed, 2 Sep 2015 11:29:37 -0700 Subject: [PATCH 1/2] update dhydra grab to grab near and far objects, and removed grabbing logic from toybox.js --- examples/controllers/hydra/hydraGrab.js | 524 ++++++++++++------------ examples/controllers/toybox.js | 233 +---------- 2 files changed, 267 insertions(+), 490 deletions(-) diff --git a/examples/controllers/hydra/hydraGrab.js b/examples/controllers/hydra/hydraGrab.js index 34484eb9e8..dfb0fdcadf 100644 --- a/examples/controllers/hydra/hydraGrab.js +++ b/examples/controllers/hydra/hydraGrab.js @@ -1,307 +1,315 @@ -// // hydraGrab.js // examples // -// Created by Clément Brisset on 4/24/14. -// Updated by Eric Levin on 5/14/15. -// Copyright 2014 High Fidelity, Inc. +// Created by Eric Levin on 9/2/15 +// Copyright 2015 High Fidelity, Inc. // -// This script allows you to grab and move/rotate physical objects with the hydra -// -// Using the hydras : -// grab physical entities with the right trigger +// Grab's physically moveable entities with the hydra- works for either near or far objects. User can also grab a far away object and drag it towards them by pressing the "4" button on either the left or ride controller. // // Distributed under the Apache License, Version 2.0. // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // +var RIGHT_HAND_CLICK = Controller.findAction("RIGHT_HAND_CLICK"); +var rightTriggerAction = RIGHT_HAND_CLICK; +var LEFT_HAND_CLICK = Controller.findAction("LEFT_HAND_CLICK"); +var leftTriggerAction = LEFT_HAND_CLICK; -var entityProps, currentPosition, currentVelocity, currentRotation, distanceToTarget, velocityTowardTarget, desiredVelocity; -var addedVelocity, newVelocity, angularVelocity, dT, cameraEntityDistance; -var LEFT = 0; -var RIGHT = 1; -var LASER_WIDTH = 3; -var LASER_COLOR = { - red: 50, - green: 150, - blue: 200 -}; -var LASER_HOVER_COLOR = { - red: 200, - green: 50, - blue: 50 -}; - -var DROP_DISTANCE = 5.0; -var DROP_COLOR = { - red: 200, - green: 200, - blue: 200 -}; - -var FULL_STRENGTH = 0.05; -var LASER_LENGTH_FACTOR = 500; -var CLOSE_ENOUGH = 0.001; -var SPRING_RATE = 1.5; -var DAMPING_RATE = 0.8; -var SCREEN_TO_METERS = 0.001; -var DISTANCE_SCALE_FACTOR = 1000 - -var grabSound = SoundCache.getSound("https://hifi-public.s3.amazonaws.com/eric/sounds/CloseClamp.wav"); -var releaseSound = SoundCache.getSound("https://hifi-public.s3.amazonaws.com/eric/sounds/ReleaseClamp.wav"); - -function getRayIntersection(pickRay) { - var intersection = Entities.findRayIntersection(pickRay, true); - return intersection; -} - - -function controller(side) { - this.triggerHeld = false; - this.triggerThreshold = 0.9; - this.side = side; - this.palm = 2 * side; - this.tip = 2 * side + 1; - this.trigger = side; - this.originalGravity = { +var ZERO_VEC = { x: 0, y: 0, z: 0 - }; +} +var LINE_LENGTH = 500; +var THICK_LINE_WIDTH = 7; +var THIN_LINE_WIDTH = 2; - this.laser = Overlays.addOverlay("line3d", { - start: { - x: 0, - y: 0, - z: 0 - }, - end: { - x: 0, - y: 0, - z: 0 - }, - color: LASER_COLOR, - alpha: 1, - lineWidth: LASER_WIDTH, - anchor: "MyAvatar" - }); +var NO_INTERSECT_COLOR = { + red: 10, + green: 10, + blue: 255 +}; +var INTERSECT_COLOR = { + red: 250, + green: 10, + blue: 10 +}; - this.dropLine = Overlays.addOverlay("line3d", { - color: DROP_COLOR, - alpha: 1, - visible: false, - lineWidth: 2 - }); +var GRAB_RADIUS = 2; +var GRAB_COLOR = { + red: 250, + green: 10, + blue: 250 +}; +var SHOW_LINE_THRESHOLD = 0.2; +var DISTANCE_HOLD_THRESHOLD = 0.8; - this.update = function(deltaTime) { - this.updateControllerState(); - this.moveLaser(); - this.checkTrigger(); - this.checkEntityIntersection(); - if (this.grabbing) { - this.updateEntity(deltaTime); - } +var right4Action = 18; +var left4Action = 17; - this.oldPalmPosition = this.palmPosition; - this.oldTipPosition = this.tipPosition; - } +var TRACTOR_BEAM_VELOCITY_THRESHOLD = 0.5; - this.updateEntity = function(deltaTime) { - this.dControllerPosition = Vec3.subtract(this.palmPosition, this.oldPalmPosition); - this.cameraEntityDistance = Vec3.distance(Camera.getPosition(), this.currentPosition); - this.targetPosition = Vec3.sum(this.targetPosition, Vec3.multiply(this.dControllerPosition, this.cameraEntityDistance * SCREEN_TO_METERS * DISTANCE_SCALE_FACTOR)); +var RIGHT = 1; +var LEFT = 0; +var rightController = new controller(RIGHT, rightTriggerAction, right4Action, "right") +var leftController = new controller(LEFT, leftTriggerAction, left4Action, "left") - this.entityProps = Entities.getEntityProperties(this.grabbedEntity); - this.currentPosition = this.entityProps.position; - this.currentVelocity = this.entityProps.velocity; - - var dPosition = Vec3.subtract(this.targetPosition, this.currentPosition); - this.distanceToTarget = Vec3.length(dPosition); - if (this.distanceToTarget > CLOSE_ENOUGH) { - // compute current velocity in the direction we want to move - this.velocityTowardTarget = Vec3.dot(this.currentVelocity, Vec3.normalize(dPosition)); - this.velocityTowardTarget = Vec3.multiply(Vec3.normalize(dPosition), this.velocityTowardTarget); - // compute the speed we would like to be going toward the target position - - this.desiredVelocity = Vec3.multiply(dPosition, (1.0 / deltaTime) * SPRING_RATE); - // compute how much we want to add to the existing velocity - this.addedVelocity = Vec3.subtract(this.desiredVelocity, this.velocityTowardTarget); - //If target is to far, roll off force as inverse square of distance - if(this.distanceToTarget/ this.cameraEntityDistance > FULL_STRENGTH) { - this.addedVelocity = Vec3.multiply(this.addedVelocity, Math.pow(FULL_STRENGTH/ this.distanceToTarget, 2.0)); - } - this.newVelocity = Vec3.sum(this.currentVelocity, this.addedVelocity); - this.newVelocity = Vec3.subtract(this.newVelocity, Vec3.multiply(this.newVelocity, DAMPING_RATE)); +function controller(side, triggerAction, pullAction, hand) { + this.hand = hand; + if (hand === "right") { + this.getHandPosition = MyAvatar.getRightPalmPosition; + this.getHandRotation = MyAvatar.getRightPalmRotation; } else { - this.newVelocity = { - x: 0, - y: 0, - z: 0 - }; - } - this.transformedAngularVelocity = Controller.getSpatialControlRawAngularVelocity(this.tip); - this.transformedAngularVelocity = Vec3.multiplyQbyV(Camera.getOrientation(), this.transformedAngularVelocity); - Entities.editEntity(this.grabbedEntity, { - velocity: this.newVelocity, - angularVelocity: this.transformedAngularVelocity + this.getHandPosition = MyAvatar.getLeftPalmPosition; + this.getHandRotation = MyAvatar.getLeftPalmRotation; + } + this.triggerAction = triggerAction; + this.pullAction = pullAction; + this.actionID = null; + this.tractorBeamActive = false; + this.distanceHolding = false; + this.triggerValue = 0; + this.prevTriggerValue = 0; + this.palm = 2 * side; + this.tip = 2 * side + 1; + this.pointer = Entities.addEntity({ + type: "Line", + name: "pointer", + color: NO_INTERSECT_COLOR, + dimensions: { + x: 1000, + y: 1000, + z: 1000 + }, + visible: false, + }); +} + + +controller.prototype.updateLine = function() { + var handPosition = Controller.getSpatialControlPosition(this.palm); + var direction = Controller.getSpatialControlNormal(this.tip); + + Entities.editEntity(this.pointer, { + position: handPosition, + linePoints: [ + ZERO_VEC, + Vec3.multiply(direction, LINE_LENGTH) + ] }); - this.updateDropLine(this.targetPosition); - - } - - - this.updateControllerState = function() { - this.palmPosition = Controller.getSpatialControlPosition(this.palm); - this.tipPosition = Controller.getSpatialControlPosition(this.tip); - this.triggerValue = Controller.getTriggerValue(this.trigger); - } - - this.checkTrigger = function() { - if (this.triggerValue > this.triggerThreshold && !this.triggerHeld) { - this.triggerHeld = true; - } else if (this.triggerValue < this.triggerThreshold && this.triggerHeld) { - this.triggerHeld = false; - if (this.grabbing) { - this.release(); - } + //only check if we havent already grabbed an object + if (this.distanceHolding) { + return; } - } + + //move origin a bit away from hand so nothing gets in way + var origin = Vec3.sum(handPosition, direction); + if (this.checkForIntersections(origin, direction)) { + Entities.editEntity(this.pointer, { + color: INTERSECT_COLOR, + }); + } else { + Entities.editEntity(this.pointer, { + color: NO_INTERSECT_COLOR, + }); + } +} - this.updateDropLine = function(position) { - - Overlays.editOverlay(this.dropLine, { - visible: true, - start: { - x: position.x, - y: position.y + DROP_DISTANCE, - z: position.z - }, - end: { - x: position.x, - y: position.y - DROP_DISTANCE, - z: position.z - } - }); - - } - - this.checkEntityIntersection = function() { +controller.prototype.checkForIntersections = function(origin, direction) { var pickRay = { - origin: this.palmPosition, - direction: Vec3.normalize(Vec3.subtract(this.tipPosition, this.palmPosition)) + origin: origin, + direction: direction }; - var intersection = getRayIntersection(pickRay, true); - if (intersection.intersects && intersection.properties.collisionsWillMove) { - this.laserWasHovered = true; - if (this.triggerHeld && !this.grabbing) { - this.grab(intersection.entityID); - } - Overlays.editOverlay(this.laser, { - color: LASER_HOVER_COLOR - }); - } else if (this.laserWasHovered) { - this.laserWasHovered = false; - Overlays.editOverlay(this.laser, { - color: LASER_COLOR - }); + + var intersection = Entities.findRayIntersection(pickRay, true); + + if (intersection.intersects) { + this.distanceToEntity = Vec3.distance(origin, intersection.properties.position); + Entities.editEntity(this.pointer, { + linePoints: [ + ZERO_VEC, + Vec3.multiply(direction, this.distanceToEntity) + ] + }); + this.grabbedEntity = intersection.entityID; + return true; } - } + return false; +} - this.grab = function(entityId) { - this.grabbing = true; - this.grabbedEntity = entityId; - this.entityProps = Entities.getEntityProperties(this.grabbedEntity); - this.targetPosition = this.entityProps.position; - this.currentPosition = this.targetPosition; - this.oldPalmPosition = this.palmPosition; - this.originalGravity = this.entityProps.gravity; - Entities.editEntity(this.grabbedEntity, { - gravity: { - x: 0, - y: 0, - z: 0 - } - }); - Overlays.editOverlay(this.laser, { - visible: false - }); - Audio.playSound(grabSound, { - position: this.entityProps.position, - volume: 0.25 - }); - } +controller.prototype.attemptMove = function() { + if (this.tractorBeamActive) { + return; + } + if (this.grabbedEntity || this.distanceHolding) { + var handPosition = Controller.getSpatialControlPosition(this.palm); + var direction = Controller.getSpatialControlNormal(this.tip); - this.release = function() { - this.grabbing = false; + var newPosition = Vec3.sum(handPosition, Vec3.multiply(direction, this.distanceToEntity)) + this.distanceHolding = true; + //TO DO : USE SPRING ACTION UPDATE FOR MOVING + if (this.actionID === null) { + this.actionID = Entities.addAction("spring", this.grabbedEntity, { + targetPosition: newPosition, + linearTimeScale: 0.1 + }); + } else { + Entities.updateAction(this.grabbedEntity, this.actionID, { + targetPosition: newPosition + }); + } + } + +} + +controller.prototype.showPointer = function() { + Entities.editEntity(this.pointer, { + visible: true + }); + +} + +controller.prototype.hidePointer = function() { + Entities.editEntity(this.pointer, { + visible: false + }); +} + + +controller.prototype.letGo = function() { + Entities.deleteAction(this.grabbedEntity, this.actionID); this.grabbedEntity = null; - Overlays.editOverlay(this.laser, { - visible: true - }); - Overlays.editOverlay(this.dropLine, { - visible: false - }); + this.actionID = null; + this.distanceHolding = false; + this.tractorBeamActive = false; + this.checkForEntityArrival = false; +} - Audio.playSound(releaseSound, { - position: this.entityProps.position, - volume: 0.25 - }); - - // only restore the original gravity if it's not zero. This is to avoid... - // 1. interface A grabs an entity and locally saves off its gravity - // 2. interface A sets the entity's gravity to zero - // 3. interface B grabs the entity and saves off its gravity (which is zero) - // 4. interface A releases the entity and puts the original gravity back - // 5. interface B releases the entity and puts the original gravity back (to zero) - if(vectorIsZero(this.originalGravity)) { - Entities.editEntity(this.grabbedEntity, { - gravity: this.originalGravity - }); +controller.prototype.update = function() { + if (this.tractorBeamActive && this.checkForEntityArrival) { + var entityVelocity = Entities.getEntityProperties(this.grabbedEntity).velocity + if (Vec3.length(entityVelocity) < TRACTOR_BEAM_VELOCITY_THRESHOLD) { + this.letGo(); + } + return; + } + this.triggerValue = Controller.getActionValue(this.triggerAction); + if (this.triggerValue > SHOW_LINE_THRESHOLD && this.prevTriggerValue < SHOW_LINE_THRESHOLD) { + //First check if an object is within close range and then run the close grabbing logic + if (this.checkForInRangeObject()) { + this.grabEntity(); + } else { + this.showPointer(); + this.shouldDisplayLine = true; + } + } else if (this.triggerValue < SHOW_LINE_THRESHOLD && this.prevTriggerValue > SHOW_LINE_THRESHOLD) { + this.hidePointer(); + this.letGo(); + this.shouldDisplayLine = false; } - } - this.moveLaser = function() { - var inverseRotation = Quat.inverse(MyAvatar.orientation); - var startPosition = Vec3.multiplyQbyV(inverseRotation, Vec3.subtract(this.palmPosition, MyAvatar.position)); - // startPosition = Vec3.multiply(startPosition, 1 / MyAvatar.scale); - var direction = Vec3.multiplyQbyV(inverseRotation, Vec3.subtract(this.tipPosition, this.palmPosition)); - direction = Vec3.multiply(direction, LASER_LENGTH_FACTOR / (Vec3.length(direction) * MyAvatar.scale)); - var endPosition = Vec3.sum(startPosition, direction); + if (this.shouldDisplayLine) { + this.updateLine(); + } + if (this.triggerValue > DISTANCE_HOLD_THRESHOLD) { + this.attemptMove(); + } - Overlays.editOverlay(this.laser, { - start: startPosition, - end: endPosition + + this.prevTriggerValue = this.triggerValue; +} + +controller.prototype.grabEntity = function() { + var handRotation = this.getHandRotation(); + var handPosition = this.getHandPosition(); + + var objectRotation = Entities.getEntityProperties(this.grabbedEntity).rotation; + var offsetRotation = Quat.multiply(Quat.inverse(handRotation), objectRotation); + + var objectPosition = Entities.getEntityProperties(this.grabbedEntity).position; + var offset = Vec3.subtract(objectPosition, handPosition); + var offsetPosition = Vec3.multiplyQbyV(Quat.inverse(Quat.multiply(handRotation, offsetRotation)), offset); + this.actionID = Entities.addAction("hold", this.grabbedEntity, { + relativePosition: offsetPosition, + relativeRotation: offsetRotation, + hand: this.hand, + timeScale: 0.05 }); - - } - - this.cleanup = function() { - Overlays.deleteOverlay(this.laser); - Overlays.deleteOverlay(this.dropLine); - } } -function update(deltaTime) { - rightController.update(deltaTime); - leftController.update(deltaTime); + +controller.prototype.checkForInRangeObject = function() { + var handPosition = Controller.getSpatialControlPosition(this.palm); + var entities = Entities.findEntities(handPosition, GRAB_RADIUS); + var minDistance = GRAB_RADIUS; + var grabbedEntity = null; + //Get nearby entities and assign nearest + for (var i = 0; i < entities.length; i++) { + var props = Entities.getEntityProperties(entities[i]); + var distance = Vec3.distance(props.position, handPosition); + if (distance < minDistance && props.name !== "pointer") { + grabbedEntity = entities[i]; + minDistance = distance; + } + } + if (grabbedEntity === null) { + return false; + } else { + this.grabbedEntity = grabbedEntity; + return true; + } } -function scriptEnding() { - rightController.cleanup(); - leftController.cleanup(); + +controller.prototype.onActionEvent = function(action, state) { + if (this.pullAction === action && state === 1) { + if (this.actionID !== null) { + var self = this; + this.tractorBeamActive = true; + //We need to wait a bit before checking for entity arrival at target destination (meaning checking for velocity being close to some + //low threshold) because otherwise we'll think the entity has arrived before its even really gotten moving! + Script.setTimeout(function() { + self.checkForEntityArrival = true; + }, 500); + var handPosition = Controller.getSpatialControlPosition(this.palm); + var direction = Controller.getSpatialControlNormal(this.tip); + //move final destination along line a bit, so it doesnt hit avatar hand + Entities.updateAction(this.grabbedEntity, this.actionID, { + targetPosition: Vec3.sum(handPosition, Vec3.multiply(2, direction)) + }); + } + } + } -function vectorIsZero(v) { - return v.x === 0 && v.y === 0 && v.z === 0; +controller.prototype.cleanup = function() { + Entities.deleteEntity(this.pointer); + Entities.deleteAction(this.grabbedEntity, this.actionID); } -var rightController = new controller(RIGHT); -var leftController = new controller(LEFT); +function update() { + rightController.update(); + leftController.update(); +} + +function onActionEvent(action, state) { + rightController.onActionEvent(action, state); + leftController.onActionEvent(action, state); + +} -Script.update.connect(update); -Script.scriptEnding.connect(scriptEnding); \ No newline at end of file +function cleanup() { + rightController.cleanup(); + leftController.cleanup(); +} + + +Script.scriptEnding.connect(cleanup); +Script.update.connect(update) +Controller.actionEvent.connect(onActionEvent); \ No newline at end of file diff --git a/examples/controllers/toybox.js b/examples/controllers/toybox.js index 4c0925f3b6..bf03974fda 100644 --- a/examples/controllers/toybox.js +++ b/examples/controllers/toybox.js @@ -13,32 +13,7 @@ Script.include("http://s3.amazonaws.com/hifi-public/scripts/libraries/toolBars.j HIFI_PUBLIC_BUCKET = "http://s3.amazonaws.com/hifi-public/"; -var nullActionID = "00000000-0000-0000-0000-000000000000"; -var controllerID; -var controllerActive; -var leftHandObjectID = null; -var rightHandObjectID = null; -var leftHandActionID = nullActionID; -var rightHandActionID = nullActionID; -var TRIGGER_THRESHOLD = 0.2; -var GRAB_RADIUS = 0.15; - -var LEFT_HAND_CLICK = Controller.findAction("LEFT_HAND_CLICK"); -var RIGHT_HAND_CLICK = Controller.findAction("RIGHT_HAND_CLICK"); -var ACTION1 = Controller.findAction("ACTION1"); -var ACTION2 = Controller.findAction("ACTION2"); - -var rightHandGrabAction = RIGHT_HAND_CLICK; -var leftHandGrabAction = LEFT_HAND_CLICK; - -var rightHandGrabValue = 0; -var leftHandGrabValue = 0; -var prevRightHandGrabValue = 0 -var prevLeftHandGrabValue = 0; - -var grabColor = { red: 0, green: 255, blue: 0}; -var releaseColor = { red: 0, green: 0, blue: 255}; var toolBar = new ToolBar(0, 0, ToolBar.vertical, "highfidelity.toybox.toolbar", function() { return { @@ -63,25 +38,6 @@ var cleanupButton = toolBar.addOverlay("image", { alpha: 1 }); -var overlays = false; -var leftHandOverlay; -var rightHandOverlay; -if (overlays) { - leftHandOverlay = Overlays.addOverlay("sphere", { - position: MyAvatar.getLeftPalmPosition(), - size: GRAB_RADIUS, - color: releaseColor, - alpha: 0.5, - solid: false - }); - rightHandOverlay = Overlays.addOverlay("sphere", { - position: MyAvatar.getRightPalmPosition(), - size: GRAB_RADIUS, - color: releaseColor, - alpha: 0.5, - solid: false - }); -} var OBJECT_HEIGHT_OFFSET = 0.5; var MIN_OBJECT_SIZE = 0.05; @@ -98,8 +54,6 @@ var GRAVITY = { z: 0.0 } -var LEFT = 0; -var RIGHT = 1; var tableCreated = false; @@ -108,7 +62,6 @@ var tableEntities = Array(NUM_OBJECTS + 1); // Also includes table var VELOCITY_MAG = 0.3; -var entitiesToResize = []; var MODELS = Array( { modelURL: "https://hifi-public.s3.amazonaws.com/ozan/props/sword/sword.fbx" }, @@ -136,196 +89,15 @@ var COLLISION_SOUNDS = Array( var RESIZE_TIMER = 0.0; var RESIZE_WAIT = 0.05; // 50 milliseconds -var leftFist = Entities.addEntity( { - type: "Sphere", - shapeType: 'sphere', - position: MyAvatar.getLeftPalmPosition(), - dimensions: { x: GRAB_RADIUS, y: GRAB_RADIUS, z: GRAB_RADIUS }, - rotation: MyAvatar.getLeftPalmRotation(), - visible: false, - collisionsWillMove: false, - ignoreForCollisions: true - }); -var rightFist = Entities.addEntity( { - type: "Sphere", - shapeType: 'sphere', - position: MyAvatar.getRightPalmPosition(), - dimensions: { x: GRAB_RADIUS, y: GRAB_RADIUS, z: GRAB_RADIUS }, - rotation: MyAvatar.getRightPalmRotation(), - visible: false, - collisionsWillMove: false, - ignoreForCollisions: true - }); -function letGo(hand) { - var actionIDToRemove = (hand == LEFT) ? leftHandActionID : rightHandActionID; - var entityIDToEdit = (hand == LEFT) ? leftHandObjectID : rightHandObjectID; - var handVelocity = (hand == LEFT) ? MyAvatar.getLeftPalmVelocity() : MyAvatar.getRightPalmVelocity(); - var handAngularVelocity = (hand == LEFT) ? MyAvatar.getLeftPalmAngularVelocity() : - MyAvatar.getRightPalmAngularVelocity(); - if (actionIDToRemove != nullActionID && entityIDToEdit != null) { - Entities.deleteAction(entityIDToEdit, actionIDToRemove); - // TODO: upon successful letGo, restore collision groups - if (hand == LEFT) { - leftHandObjectID = null; - leftHandActionID = nullActionID; - } else { - rightHandObjectID = null; - rightHandActionID = nullActionID; - } - } -} -function setGrabbedObject(hand) { - var handPosition = (hand == LEFT) ? MyAvatar.getLeftPalmPosition() : MyAvatar.getRightPalmPosition(); - var entities = Entities.findEntities(handPosition, GRAB_RADIUS); - var objectID = null; - var minDistance = GRAB_RADIUS; - for (var i = 0; i < entities.length; i++) { - // Don't grab the object in your other hands, your fists, or the table - if ((hand == LEFT && entities[i] == rightHandObjectID) || - (hand == RIGHT && entities[i] == leftHandObjectID) || - entities[i] == leftFist || entities[i] == rightFist || - (tableCreated && entities[i] == tableEntities[0])) { - continue; - } else { - var distance = Vec3.distance(Entities.getEntityProperties(entities[i]).position, handPosition); - if (distance <= minDistance) { - objectID = entities[i]; - minDistance = distance; - } - } - } - if (objectID == null) { - return false; - } - if (hand == LEFT) { - leftHandObjectID = objectID; - } else { - rightHandObjectID = objectID; - } - return true; -} - -function grab(hand) { - if (!setGrabbedObject(hand)) { - // If you don't grab an object, make a fist - Entities.editEntity((hand == LEFT) ? leftFist : rightFist, { ignoreForCollisions: false } ); - return; - } - var objectID = (hand == LEFT) ? leftHandObjectID : rightHandObjectID; - var handRotation = (hand == LEFT) ? MyAvatar.getLeftPalmRotation() : MyAvatar.getRightPalmRotation(); - var handPosition = (hand == LEFT) ? MyAvatar.getLeftPalmPosition() : MyAvatar.getRightPalmPosition(); - - var objectRotation = Entities.getEntityProperties(objectID).rotation; - var offsetRotation = Quat.multiply(Quat.inverse(handRotation), objectRotation); - - var objectPosition = Entities.getEntityProperties(objectID).position; - var offset = Vec3.subtract(objectPosition, handPosition); - var offsetPosition = Vec3.multiplyQbyV(Quat.inverse(Quat.multiply(handRotation, offsetRotation)), offset); - // print(JSON.stringify(offsetPosition)); - var actionID = Entities.addAction("hold", objectID, { - relativePosition: { x: 0, y: 0, z: 0 }, - relativeRotation: offsetRotation, - hand: (hand == LEFT) ? "left" : "right", - timeScale: 0.05 - }); - if (actionID == nullActionID) { - if (hand == LEFT) { - leftHandObjectID = null; - } else { - rightHandObjectID = null; - } - } else { - // TODO: upon successful grab, add to collision group so object doesn't collide with immovable entities - if (hand == LEFT) { - leftHandActionID = actionID; - } else { - rightHandActionID = actionID; - } - } -} - -function resizeModels() { - var newEntitiesToResize = []; - for (var i = 0; i < entitiesToResize.length; i++) { - var naturalDimensions = Entities.getEntityProperties(entitiesToResize[i]).naturalDimensions; - if (naturalDimensions.x != 1.0 || naturalDimensions.y != 1.0 || naturalDimensions.z != 1.0) { - // bigger range of sizes for models - var dimensions = Vec3.multiply(randFloat(MIN_OBJECT_SIZE, 3.0*MAX_OBJECT_SIZE), Vec3.normalize(naturalDimensions)); - Entities.editEntity(entitiesToResize[i], { - dimensions: dimensions, - shapeType: "box" - }); - } else { - newEntitiesToResize.push(entitiesToResize[i]); - } - - } - entitiesToResize = newEntitiesToResize; -} - -function update(deltaTime) { - if (overlays) { - Overlays.editOverlay(leftHandOverlay, { position: MyAvatar.getLeftPalmPosition() }); - Overlays.editOverlay(rightHandOverlay, { position: MyAvatar.getRightPalmPosition() }); - } - - // if (tableCreated && RESIZE_TIMER < RESIZE_WAIT) { - // RESIZE_TIMER += deltaTime; - // } else if (tableCreated) { - // resizeModels(); - // } - - rightHandGrabValue = Controller.getActionValue(rightHandGrabAction); - leftHandGrabValue = Controller.getActionValue(leftHandGrabAction); - - Entities.editEntity(leftFist, { position: MyAvatar.getLeftPalmPosition() }); - Entities.editEntity(rightFist, { position: MyAvatar.getRightPalmPosition() }); - - if (rightHandGrabValue > TRIGGER_THRESHOLD && - prevRightHandGrabValue < TRIGGER_THRESHOLD) { - if (overlays) { - Overlays.editOverlay(rightHandOverlay, { color: grabColor }); - } - grab(RIGHT); - } else if (rightHandGrabValue < TRIGGER_THRESHOLD && - prevRightHandGrabValue > TRIGGER_THRESHOLD) { - Entities.editEntity(rightFist, { ignoreForCollisions: true } ); - if (overlays) { - Overlays.editOverlay(rightHandOverlay, { color: releaseColor }); - } - letGo(RIGHT); - } - - if (leftHandGrabValue > TRIGGER_THRESHOLD && - prevLeftHandGrabValue < TRIGGER_THRESHOLD) { - if (overlays) { - Overlays.editOverlay(leftHandOverlay, { color: grabColor }); - } - grab(LEFT); - } else if (leftHandGrabValue < TRIGGER_THRESHOLD && - prevLeftHandGrabValue > TRIGGER_THRESHOLD) { - Entities.editEntity(leftFist, { ignoreForCollisions: true } ); - if (overlays) { - Overlays.editOverlay(leftHandOverlay, { color: releaseColor }); - } - letGo(LEFT); - } - - prevRightHandGrabValue = rightHandGrabValue; - prevLeftHandGrabValue = leftHandGrabValue; -} function cleanUp() { - letGo(RIGHT); - letGo(LEFT); + print("CLEANUP!!!") if (overlays) { Overlays.deleteOverlay(leftHandOverlay); Overlays.deleteOverlay(rightHandOverlay); } - Entities.deleteEntity(leftFist); - Entities.deleteEntity(rightFist); removeTable(); toolBar.cleanup(); } @@ -405,7 +177,6 @@ function createTable() { density: 0.5, collisionsWillMove: true, color: { red: randInt(0, 255), green: randInt(0, 255), blue: randInt(0, 255) }, - // collisionSoundURL: COLLISION_SOUNDS[randInt(0, COLLISION_SOUNDS.length)] }); if (type == "Model") { var randModel = randInt(0, MODELS.length); @@ -413,7 +184,6 @@ function createTable() { shapeType: "box", modelURL: MODELS[randModel].modelURL }); - entitiesToResize.push(tableEntities[i]); } } } @@ -426,5 +196,4 @@ function removeTable() { } Script.scriptEnding.connect(cleanUp); -Script.update.connect(update); Controller.mousePressEvent.connect(onClick); \ No newline at end of file From d303c7e119021c3fd438c940e6c56e3197d8003c Mon Sep 17 00:00:00 2001 From: ericrius1 Date: Wed, 2 Sep 2015 16:45:50 -0700 Subject: [PATCH 2/2] only add actions to physical objects --- examples/controllers/hydra/hydraGrab.js | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/examples/controllers/hydra/hydraGrab.js b/examples/controllers/hydra/hydraGrab.js index dfb0fdcadf..71e4d2a07e 100644 --- a/examples/controllers/hydra/hydraGrab.js +++ b/examples/controllers/hydra/hydraGrab.js @@ -9,6 +9,8 @@ // Distributed under the Apache License, Version 2.0. // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // + + var RIGHT_HAND_CLICK = Controller.findAction("RIGHT_HAND_CLICK"); var rightTriggerAction = RIGHT_HAND_CLICK; @@ -70,6 +72,7 @@ function controller(side, triggerAction, pullAction, hand) { this.actionID = null; this.tractorBeamActive = false; this.distanceHolding = false; + this.closeGrabbing = false; this.triggerValue = 0; this.prevTriggerValue = 0; this.palm = 2 * side; @@ -127,8 +130,7 @@ controller.prototype.checkForIntersections = function(origin, direction) { }; var intersection = Entities.findRayIntersection(pickRay, true); - - if (intersection.intersects) { + if (intersection.intersects && intersection.properties.collisionsWillMove === 1) { this.distanceToEntity = Vec3.distance(origin, intersection.properties.position); Entities.editEntity(this.pointer, { linePoints: [ @@ -156,7 +158,7 @@ controller.prototype.attemptMove = function() { if (this.actionID === null) { this.actionID = Entities.addAction("spring", this.grabbedEntity, { targetPosition: newPosition, - linearTimeScale: 0.1 + linearTimeScale: .1 }); } else { Entities.updateAction(this.grabbedEntity, this.actionID, { @@ -188,6 +190,7 @@ controller.prototype.letGo = function() { this.distanceHolding = false; this.tractorBeamActive = false; this.checkForEntityArrival = false; + this.closeGrabbing = false; } controller.prototype.update = function() { @@ -216,7 +219,7 @@ controller.prototype.update = function() { if (this.shouldDisplayLine) { this.updateLine(); } - if (this.triggerValue > DISTANCE_HOLD_THRESHOLD) { + if (this.triggerValue > DISTANCE_HOLD_THRESHOLD && !this.closeGrabbing) { this.attemptMove(); } @@ -234,6 +237,7 @@ controller.prototype.grabEntity = function() { var objectPosition = Entities.getEntityProperties(this.grabbedEntity).position; var offset = Vec3.subtract(objectPosition, handPosition); var offsetPosition = Vec3.multiplyQbyV(Quat.inverse(Quat.multiply(handRotation, offsetRotation)), offset); + this.closeGrabbing = true; this.actionID = Entities.addAction("hold", this.grabbedEntity, { relativePosition: offsetPosition, relativeRotation: offsetRotation, @@ -252,7 +256,7 @@ controller.prototype.checkForInRangeObject = function() { for (var i = 0; i < entities.length; i++) { var props = Entities.getEntityProperties(entities[i]); var distance = Vec3.distance(props.position, handPosition); - if (distance < minDistance && props.name !== "pointer") { + if (distance < minDistance && props.name !== "pointer" && props.collisionsWillMove === 1) { grabbedEntity = entities[i]; minDistance = distance; }