From fd67a2b86fd86f1f8a9f055d192eed6d4253741e Mon Sep 17 00:00:00 2001 From: "James B. Pollack" Date: Mon, 21 Sep 2015 16:10:08 -0700 Subject: [PATCH] Add on/off by pressure; add point bulb to end of flashlight --- examples/toys/flashlight/createFlashlight.js | 33 +-- examples/toys/flashlight/flashlight.js | 240 +++++++++++-------- 2 files changed, 153 insertions(+), 120 deletions(-) diff --git a/examples/toys/flashlight/createFlashlight.js b/examples/toys/flashlight/createFlashlight.js index bf03de547b..ad089e001a 100644 --- a/examples/toys/flashlight/createFlashlight.js +++ b/examples/toys/flashlight/createFlashlight.js @@ -15,30 +15,33 @@ Script.include("https://hifi-public.s3.amazonaws.com/scripts/utilities.js"); -var scriptURL = "https://hifi-public.s3.amazonaws.com/scripts/toys/flashlight/flashlight.js?"+randInt(0,1000); +var scriptURL = Script.resolvePath('flashlight.js?12322'); var modelURL = "https://hifi-public.s3.amazonaws.com/models/props/flashlight.fbx"; - -var center = Vec3.sum(Vec3.sum(MyAvatar.position, {x: 0, y: 0.5, z: 0}), Vec3.multiply(0.5, Quat.getFront(Camera.getOrientation()))); +var center = Vec3.sum(Vec3.sum(MyAvatar.position, { + x: 0, + y: 0.5, + z: 0 +}), Vec3.multiply(0.5, Quat.getFront(Camera.getOrientation()))); var flashlight = Entities.addEntity({ - type: "Model", - modelURL: modelURL, - position: center, - dimensions: { - x: 0.04, - y: 0.15, - z: 0.04 - }, - collisionsWillMove: true, - shapeType: 'box', - script: scriptURL + type: "Model", + modelURL: modelURL, + position: center, + dimensions: { + x: 0.04, + y: 0.15, + z: 0.04 + }, + collisionsWillMove: true, + shapeType: 'box', + script: scriptURL }); function cleanup() { - Entities.deleteEntity(flashlight); + Entities.deleteEntity(flashlight); } diff --git a/examples/toys/flashlight/flashlight.js b/examples/toys/flashlight/flashlight.js index 9aa64a4435..7f2bd210da 100644 --- a/examples/toys/flashlight/flashlight.js +++ b/examples/toys/flashlight/flashlight.js @@ -4,6 +4,7 @@ // Script Type: Entity // // Created by Sam Gateau on 9/9/15. +// Additions by James B. Pollack @imgntn on 9/21/2015 // Copyright 2015 High Fidelity, Inc. // // This is a toy script that can be added to the Flashlight model entity: @@ -13,15 +14,9 @@ // Distributed under the Apache License, Version 2.0. // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // -// TODO: update to use new grab signals, which will include handedness. -// BONUS: dim the light with pressure instead of binary on/off (function() { - function debugPrint(message) { - //print(message); - } - Script.include("../../libraries/utils.js"); var _this; @@ -30,11 +25,11 @@ // our this object, so we can access it in cases where we're called without a this (like in the case of various global signals) Flashlight = function() { _this = this; - _this._hasSpotlight = false; - _this._spotlight = null; }; - var DISABLE_LIGHT_THRESHOLD = 0.5; + //if the trigger value goes below this while held, the flashlight will turn off. if it goes above, it will + var DISABLE_LIGHT_THRESHOLD = 0.7; + // These constants define the Spotlight position and orientation relative to the model var MODEL_LIGHT_POSITION = { x: 0, @@ -47,101 +42,131 @@ z: 0 }); - // Evaluate the world light entity position and orientation from the model ones + var GLOW_LIGHT_POSITION = { + x: 0, + y: -0.1, + z: 0 + } + + // Evaluate the world light entity positions and orientations from the model ones function evalLightWorldTransform(modelPos, modelRot) { + return { p: Vec3.sum(modelPos, Vec3.multiplyQbyV(modelRot, MODEL_LIGHT_POSITION)), q: Quat.multiply(modelRot, MODEL_LIGHT_ROTATION) }; }; + function glowLightWorldTransform(modelPos, modelRot) { + return { + p: Vec3.sum(modelPos, Vec3.multiplyQbyV(modelRot, GLOW_LIGHT_POSITION)), + q: Quat.multiply(modelRot, MODEL_LIGHT_ROTATION) + }; + }; + + Flashlight.prototype = { lightOn: false, + hand: null, + whichHand: null, + hasSpotlight: false, + spotlight: null, + setRightHand: function() { + this.hand = 'RIGHT'; + }, + setLeftHand: function() { + this.hand = 'LEFT'; + }, + startNearGrab: function() { + if (!_this.hasSpotlight) { + //this light casts the beam + this.spotlight = Entities.addEntity({ + type: "Light", + isSpotlight: true, + dimensions: { + x: 2, + y: 2, + z: 20 + }, + color: { + red: 255, + green: 255, + blue: 255 + }, + intensity: 2, + exponent: 0.3, + cutoff: 20 + }); - // update() will be called regulary, because we've hooked the update signal in our preload() function - // we will check out userData for the grabData. In the case of the hydraGrab script, it will tell us - // if we're currently being grabbed and if the person grabbing us is the current interfaces avatar. - // we will watch this for state changes and print out if we're being grabbed or released when it changes. - update: function() { - var GRAB_USER_DATA_KEY = "grabKey"; + //this light creates the effect of a bulb at the end of the flashlight + this.glowLight = Entities.addEntity({ + type: "Light", + dimensions: { + x: 0.25, + y: 0.25, + z: 0.25 + }, + isSpotlight: false, + color: { + red: 255, + green: 255, + blue: 255 + }, + exponent: 0, + cutoff: 90, // in degrees + }); - // because the update() signal doesn't have a valid this, we need to use our memorized _this to access our entityID - var entityID = _this.entityID; + this.hasSpotlight = true; - // we want to assume that if there is no grab data, then we are not being grabbed - var defaultGrabData = { - activated: false, - avatarId: null - }; - - // this handy function getEntityCustomData() is available in utils.js and it will return just the specific section - // of user data we asked for. If it's not available it returns our default data. - var grabData = getEntityCustomData(GRAB_USER_DATA_KEY, entityID, defaultGrabData); - - - // if the grabData says we're being grabbed, and the owner ID is our session, then we are being grabbed by this interface - if (grabData.activated && grabData.avatarId == MyAvatar.sessionUUID) { - - // remember we're being grabbed so we can detect being released - _this.beingGrabbed = true; - - var modelProperties = Entities.getEntityProperties(entityID); - var lightTransform = evalLightWorldTransform(modelProperties.position, modelProperties.rotation); - - // Create the spot light driven by this model if we don;t have one yet - // Or make sure to keep it's position in sync - if (!_this._hasSpotlight) { - - _this._spotlight = Entities.addEntity({ - type: "Light", - position: lightTransform.p, - rotation: lightTransform.q, - isSpotlight: true, - dimensions: { - x: 2, - y: 2, - z: 20 - }, - color: { - red: 255, - green: 255, - blue: 255 - }, - intensity: 2, - exponent: 0.3, - cutoff: 20 - }); - _this._hasSpotlight = true; - - - debugPrint("Flashlight:: creating a spotlight"); - } else { - // Updating the spotlight - Entities.editEntity(_this._spotlight, { - position: lightTransform.p, - rotation: lightTransform.q - }); - _this.changeLightWithTriggerPressure(); - debugPrint("Flashlight:: updating the spotlight"); - } - - debugPrint("I'm being grabbed..."); - - } else if (_this.beingGrabbed) { - - if (_this._hasSpotlight) { - Entities.deleteEntity(_this._spotlight); - debugPrint("Destroying flashlight spotlight..."); - } - _this._hasSpotlight = false; - _this._spotlight = null; - - // if we are not being grabbed, and we previously were, then we were just released, remember that - // and print out a message - _this.beingGrabbed = false; - debugPrint("I'm was released..."); } + + }, + setWhichHand: function() { + this.whichHand = this.hand; + }, + continueNearGrab: function() { + if (this.whichHand === null) { + //only set the active hand once -- if we always read the current hand, our 'holding' hand will get overwritten + this.setWhichHand(); + } else { + this.updateLightPositions(); + this.changeLightWithTriggerPressure(this.whichHand); + } + }, + releaseGrab: function() { + //delete the lights and reset state + if (this.hasSpotlight) { + Entities.deleteEntity(this.spotlight); + Entities.deleteEntity(this.glowLight); + this.hasSpotlight = false; + this.glowLight = null; + this.spotlight = null; + this.whichHand = null; + + } + }, + updateLightPositions: function() { + var modelProperties = Entities.getEntityProperties(this.entityID, ['position', 'rotation']); + + //move the two lights along the vectors we set above + var lightTransform = evalLightWorldTransform(modelProperties.position, modelProperties.rotation); + var glowLightTransform = glowLightWorldTransform(modelProperties.position, modelProperties.rotation); + + + //move them with the entity model + Entities.editEntity(this.spotlight, { + position: lightTransform.p, + rotation: lightTransform.q, + }) + + + Entities.editEntity(this.glowLight, { + position: glowLightTransform.p, + rotation: glowLightTransform.q, + }) + + }, changeLightWithTriggerPressure: function(flashLightHand) { @@ -156,33 +181,34 @@ } else if (this.triggerValue >= DISABLE_LIGHT_THRESHOLD && this.lightOn === false) { this.turnLightOn(); } - - return triggerValue + return }, turnLightOff: function() { - Entities.editEntity(_this._spotlight, { + print('turn light off') + Entities.editEntity(this.spotlight, { + intensity: 0 + }); + Entities.editEntity(this.glowLight, { intensity: 0 }); this.lightOn = false }, turnLightOn: function() { - Entities.editEntity(_this._spotlight, { + print('turn light on') + Entities.editEntity(this.glowLight, { + intensity: 2 + }); + Entities.editEntity(this.spotlight, { intensity: 2 }); this.lightOn = true }, - // preload() will be called when the entity has become visible (or known) to the interface // it gives us a chance to set our local JavaScript object up. In this case it means: // * remembering our entityID, so we can access it in cases where we're called without an entityID // * connecting to the update signal so we can check our grabbed state preload: function(entityID) { - _this.entityID = entityID; - - var modelProperties = Entities.getEntityProperties(entityID); - - - + this.entityID = entityID; Script.update.connect(this.update); }, @@ -191,11 +217,15 @@ // to the update signal unload: function(entityID) { - if (_this._hasSpotlight) { - Entities.deleteEntity(_this._spotlight); + if (this.hasSpotlight) { + Entities.deleteEntity(this.spotlight); + Entities.deleteEntity(this.glowLight); + this.hasSpotlight = false; + this.glowLight = null; + this.spotlight = null; + this.whichHand = null; } - _this._hasSpotlight = false; - _this._spotlight = null; + Script.update.disconnect(this.update); },