130 lines · 4.8 KB · JavaScript
RawDownload
//  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);        }    };  })