From 8613cd35ea370fd5d6a473fb18d675d02d36b202 Mon Sep 17 00:00:00 2001 From: August Rosedale Date: Fri, 30 Dec 2016 07:11:02 -0800 Subject: [PATCH] entity script to push entities with hands --- .../tutorials/entity_scripts/springAway.js | 130 ++++++++++++++++++ 1 file changed, 130 insertions(+) create mode 100644 scripts/tutorials/entity_scripts/springAway.js diff --git a/scripts/tutorials/entity_scripts/springAway.js b/scripts/tutorials/entity_scripts/springAway.js new file mode 100644 index 0000000000..1652db216f --- /dev/null +++ b/scripts/tutorials/entity_scripts/springAway.js @@ -0,0 +1,130 @@ +// 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. +// +// You can change the force applied by the script by setting userData to contain +// a value 'strength', which will otherwise default to DEFAULT_STRENGTH +// +// Note that the use of dimensions.x as the size of the entity means that it +// needs to be spherical for this to look correct. +// +// 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/45; // Update the spring/object at 45Hz + var SETTINGS_INTERVAL_MSECS = 1000; // Periodically check user data for updates + var TOO_FAR = 5.0; // If the object + var DEFAULT_STRENGTH = 3.0; // How strong/stiff is the spring? + + + var entity; + var props; + var checkTimer = false; + var settingsTimer = false; + var strength = DEFAULT_STRENGTH; + 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.maybePush, UPDATE_INTERVAL_MSECS); + settingsTimer = Script.setInterval(this.checkSettings, SETTINGS_INTERVAL_MSECS); + }; + + this.maybePush = 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 + + 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 }; + + + 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.checkSettings = function() { + var dataProps = Entities.getEntityProperties(entity, [ "userData" ]); + if (dataProps.userData) { + var data = JSON.parse(dataProps.userData); + if (data.strength) { + if (!(strength === data.strength)) { + debugPrint("Read new spring strength: " + data.strength); + } + strength = data.strength; + } + } + } + + this.unload = function(entityID) { + debugPrint("springAway unload"); + if (checkTimer) { + Script.clearInterval(checkTimer); + } + if (settingsTimer) { + Script.clearInterval(settingsTimer); + } + }; + +})