// springAway.js // // If you attach this entity script to an object, the object will spring away from // your avatar's hands. Useful for making a beachball or basketball, because you // can bounce it on your hands. // // Copyright 2016 High Fidelity, Inc. // // Distributed under the Apache License, Version 2.0. // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // // // (function(){ var UPDATE_INTERVAL_MSECS = 1000/90; // Update the spring/object at 45Hz var entity; var props; var checkTimer = false; var _this; var WANT_DEBUG = false; function debugPrint(string) { if (WANT_DEBUG) { print(string); } } function howFarAway(position) { return Vec3.distance(MyAvatar.position, position); } function springForce(position, center, radius) { // // Return a vector corresponding to a normalized spring force ranging from 1 at // exact center to zero at distance radius from center. // var distance = Vec3.distance(position, center); return Vec3.multiply(1.0 - distance / radius, Vec3.normalize(Vec3.subtract(center, position))); } function fingerPosition(which) { // Get the worldspace position of either the tip of the index finger (jointName "RightHandIndex3", etc), or // fall back to the controller position if that doesn't exist. var joint = MyAvatar.getJointPosition(which === "RIGHT" ? "RightHandIndex3" : "LeftHandIndex3"); if (Vec3.length(joint) > 0) { return joint; } else { return Vec3.sum(MyAvatar.position, Vec3.multiplyQbyV(MyAvatar.orientation, Controller.getPoseValue(which === "RIGHT" ? Controller.Standard.RightHand : Controller.Standard.LeftHand).translation)); } } this.preload = function(entityID) { // Load the sound and range from the entity userData fields, and note the position of the entity. debugPrint("springAway preload"); entity = entityID; _this = this; checkTimer = Script.setInterval(this.maybeUpdate, UPDATE_INTERVAL_MSECS); }; this.maybeUpdate = function() { props = Entities.getEntityProperties(entity, [ "position", "dimensions", "velocity" ]); // First, check if the entity is far enough away to not need to do anything with it var TOO_FAR = 2.5; if (howFarAway(props.position) - props.dimensions.x / 2 > TOO_FAR) { return; } var rightFingerPosition = fingerPosition("RIGHT"); var leftFingerPosition = fingerPosition("LEFT"); var addVelocity = { x: 0, y: 0, z: 0 }; var STRENGTH = 3.0; if (Vec3.distance(leftFingerPosition, props.position) < props.dimensions.x / 2) { addVelocity = Vec3.sum(addVelocity, Vec3.multiply(springForce(leftFingerPosition, props.position, props.dimensions.x), STRENGTH)); } if (Vec3.distance(rightFingerPosition, props.position) < props.dimensions.x / 2) { addVelocity = Vec3.sum(addVelocity, Vec3.multiply(springForce(rightFingerPosition, props.position, props.dimensions.x), STRENGTH)); } if (Vec3.length(addVelocity) > 0) { Entities.editEntity(entity, { velocity: Vec3.sum(props.velocity, addVelocity) }); } } this.unload = function(entityID) { debugPrint("springAway unload"); if (checkTimer) { Script.clearInterval(checkTimer); } }; })