diff --git a/examples/grab.js b/examples/grab.js index cd7d59701e..9609354abf 100644 --- a/examples/grab.js +++ b/examples/grab.js @@ -1,3 +1,16 @@ + +// grab.js +// examples +// +// Created by Eric Levin on May 1, 2015 +// Copyright 2015 High Fidelity, Inc. +// +// Grab's physically moveable entities with the mouse, by applying a spring force. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + var isGrabbing = false; var grabbedEntity = null; var prevMouse = {}; @@ -8,7 +21,7 @@ var entityProps; var targetPosition; var moveUpDown = false; -var currentPosition, currentVelocity; +var currentPosition, currentVelocity, cameraEntityDistance; 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"); @@ -23,16 +36,6 @@ var DROP_WIDTH = 2; var dropLine = Overlays.addOverlay("line3d", { - start: { - x: 0, - y: 0, - z: 0 - }, - end: { - x: 0, - y: 0, - z: 0 - }, color: DROP_COLOR, alpha: 1, visible: false, @@ -64,12 +67,8 @@ function mousePressEvent(event) { function updateDropLine(position) { Overlays.editOverlay(dropLine, { visible: true, - start: position, - end: Vec3.sum(position, { - x: 0, - y: -DROP_DISTANCE, - z: 0 - }) + start: { x: position.x, y: position.y + DROP_DISTANCE, z: position.z }, + end: { x: position.x, y: position.y - DROP_DISTANCE, z: position.z } }) } @@ -103,11 +102,11 @@ function mouseMoveEvent(event) { var camYaw = Quat.safeEulerAngles(Camera.getOrientation()).y; var dPosition = Vec3.multiplyQbyV(Quat.fromPitchYawRollDegrees(0, camYaw, 0), deltaMouse); // Adjust target position for the object by the mouse move - var avatarEntityDistance = Vec3.distance(Camera.getPosition(), currentPosition); + cameraEntityDistance = Vec3.distance(Camera.getPosition(), currentPosition); // Scale distance we want to move by the distance from the camera to the grabbed object // TODO: Correct SCREEN_TO_METERS to be correct for the actual FOV, resolution var SCREEN_TO_METERS = 0.001; - targetPosition = Vec3.sum(targetPosition, Vec3.multiply(dPosition, avatarEntityDistance * SCREEN_TO_METERS)); + targetPosition = Vec3.sum(targetPosition, Vec3.multiply(dPosition, cameraEntityDistance * SCREEN_TO_METERS)); } prevMouse.x = event.x; prevMouse.y = event.y; @@ -136,15 +135,21 @@ function update(deltaTime) { var dPosition = Vec3.subtract(targetPosition, currentPosition); var CLOSE_ENOUGH = 0.001; - if (Vec3.length(dPosition) > CLOSE_ENOUGH) { + var FULL_STRENGTH = 0.025; + var distanceToTarget = Vec3.length(dPosition); + if (distanceToTarget / cameraEntityDistance > CLOSE_ENOUGH) { // compute current velocity in the direction we want to move var velocityTowardTarget = Vec3.dot(currentVelocity, Vec3.normalize(dPosition)); // compute the speed we would like to be going toward the target position - var SPRING_RATE = 0.35; - var DAMPING_RATE = 0.55; + var SPRING_RATE = 1.5; + var DAMPING_RATE = 0.80; var desiredVelocity = Vec3.multiply(dPosition, (1.0 / deltaTime) * SPRING_RATE); // compute how much we want to add to the existing velocity var addedVelocity = Vec3.subtract(desiredVelocity, velocityTowardTarget); + // If target is too far, roll off the force as inverse square of distance + if (distanceToTarget / cameraEntityDistance > FULL_STRENGTH) { + addedVelocity = Vec3.multiply(addedVelocity, Math.pow(FULL_STRENGTH / distanceToTarget, 2.0)); + } var newVelocity = Vec3.sum(currentVelocity, addedVelocity); // Add Damping newVelocity = Vec3.subtract(newVelocity, Vec3.multiply(newVelocity, DAMPING_RATE)); @@ -153,7 +158,7 @@ function update(deltaTime) { velocity: newVelocity }) } - updateDropLine(currentPosition); + updateDropLine(targetPosition); } }