From 7d2fa8d7ce40c5b73107210c91193b3917a9ab61 Mon Sep 17 00:00:00 2001 From: Eric Levin Date: Tue, 7 Apr 2015 10:20:19 -0700 Subject: [PATCH] Updated lightcontroller.js logic to find the nearest light when user clicks on light switch entity- this will allow lights to work even when a user has disabled other users from spawning items in his domain --- examples/entityScripts/lightController.js | 306 +++++++--------------- 1 file changed, 88 insertions(+), 218 deletions(-) diff --git a/examples/entityScripts/lightController.js b/examples/entityScripts/lightController.js index 6d6c0a59bd..de338b8d33 100644 --- a/examples/entityScripts/lightController.js +++ b/examples/entityScripts/lightController.js @@ -1,228 +1,98 @@ (function() { - this.entityID = null; - this.lightID = null; - this.sound = null; - this.soundURLs = ["https://hifi-public.s3.amazonaws.com/sounds/Switches%20and%20sliders/lamp_switch_1.wav", - "https://hifi-public.s3.amazonaws.com/sounds/Switches%20and%20sliders/lamp_switch_2.wav", - "https://hifi-public.s3.amazonaws.com/sounds/Switches%20and%20sliders/lamp_switch_3.wav"] - var DEFAULT_USER_DATA = { - creatingLight: false, - lightID: null, - lightDefaultProperties: { - type: "Light", - position: { x: 0, y: 0, z: 0 }, - dimensions: { x: 5, y: 5, z: 5 }, - isSpotlight: false, - color: { red: 255, green: 48, blue: 0 }, - diffuseColor: { red: 255, green: 255, blue: 255 }, - ambientColor: { red: 255, green: 255, blue: 255 }, - specularColor: { red: 0, green: 0, blue: 0 }, - constantAttenuation: 1, - linearAttenuation: 0, - quadraticAttenuation: 0, - intensity: 10, - exponent: 0, - cutoff: 180, // in degrees - }, - soundIndex: Math.floor(Math.random() * this.soundURLs.length) - }; - - function copyObject(object) { - return JSON.parse(JSON.stringify(object)); - } - function didEntityExist(entityID) { - return entityID && entityID.isKnownID; - } - function doesEntityExistNow(entityID) { - return entityID && getTrueID(entityID).isKnownID; - } - function getTrueID(entityID) { - var properties = Entities.getEntityProperties(entityID); - return { id: properties.id, creatorTokenID: properties.creatorTokenID, isKnownID: properties.isKnownID }; - } - function getUserData(entityID) { - var properties = Entities.getEntityProperties(entityID); - if (properties.userData) { - return JSON.parse(properties.userData); - } else { - print("Warning: light controller has no user data."); - return null; - } - } - function updateUserData(entityID, userData) { - Entities.editEntity(entityID, { userData: JSON.stringify(userData) }); - } - - // Download sound if needed - this.maybeDownloadSound = function() { - if (this.sound === null) { - var soundIndex = getUserData(this.entityID).soundIndex; - this.sound = SoundCache.getSound(this.soundURLs[soundIndex]); - } - } - // Play switch sound - this.playSound = function() { - if (this.sound && this.sound.downloaded) { - Audio.playSound(this.sound, { - position: Entities.getEntityProperties(this.entityID).position, - volume: 0.2 - }); - } else { - print("Warning: Couldn't play sound."); - } - } - - // Checks whether the userData is well-formed and updates it if not - this.checkUserData = function() { - var userData = getUserData(this.entityID); - if (!userData) { - userData = DEFAULT_USER_DATA; - } else if (!userData.lightDefaultProperties) { - userData.lightDefaultProperties = DEFAULT_USER_DATA.lightDefaultProperties; - } else if (!userData.soundIndex) { - userData.soundIndex = DEFAULT_USER_DATA.soundIndex; - } - updateUserData(this.entityID, userData); - } - - // Create a Light entity - this.createLight = function(userData) { - var lightProperties = copyObject(userData.lightDefaultProperties); - if (lightProperties) { - var entityProperties = Entities.getEntityProperties(this.entityID); - - lightProperties.visible = false; - lightProperties.position = Vec3.sum(entityProperties.position, - Vec3.multiplyQbyV(entityProperties.rotation, - lightProperties.position)); - return Entities.addEntity(lightProperties); - } else { - print("Warning: light controller has no default light."); - return null; - } - } - - // Tries to find a valid light, creates one otherwise - this.updateLightID = function() { - // Find valid light - if (doesEntityExistNow(this.lightID)) { - return; - } - - var userData = getUserData(this.entityID); - if (doesEntityExistNow(userData.lightID)) { - this.lightID = userData.lightID; - return; - } - - if (!userData.creatingLight) { - // No valid light, create one - userData.creatingLight = true; - updateUserData(this.entityID, userData); - this.lightID = this.createLight(userData); - this.maybeUpdateLightIDInUserData(); - print("Created new light entity"); - } - } - - this.maybeUpdateLightIDInUserData = function() { - if (getTrueID(this.lightID).isKnownID) { - this.lightID = getTrueID(this.lightID); - this.updateLightIDInUserData(); - } else { - var that = this; - Script.setTimeout(function() { that.maybeUpdateLightIDInUserData() }, 500); - } - } - - // Update user data with new lightID - this.updateLightIDInUserData = function() { - var userData = getUserData(this.entityID); - userData.lightID = this.lightID; - userData.creatingLight = false; - updateUserData(this.entityID, userData); - } - - // Moves light entity if the lamp entity moved - this.maybeMoveLight = function() { - var entityProperties = Entities.getEntityProperties(this.entityID); - var lightProperties = Entities.getEntityProperties(this.lightID); - var lightDefaultProperties = getUserData(this.entityID).lightDefaultProperties; - - var position = Vec3.sum(entityProperties.position, - Vec3.multiplyQbyV(entityProperties.rotation, - lightDefaultProperties.position)); - - if (!Vec3.equal(position, lightProperties.position)) { - print("Lamp entity moved, moving light entity as well"); - Entities.editEntity(this.lightID, { position: position }); - } + this.preload = function(entityId) { + this.sound = SoundCache.getSound("https://hifi-public.s3.amazonaws.com/sounds/Switches%20and%20sliders/lamp_switch_1.wav"); + this.entityId = entityId; + this.properties = Entities.getEntityProperties(this.entityId); + this.previousPosition = this.properties.position; + this.getUserData() + if (!this.userData) { + this.userData = {}; + this.userData.lightOn = false; } - // Stores light entity relative position in the lamp metadata - this.updateRelativeLightPosition = function() { - if (!doesEntityExistNow(this.lightID)) { - print("Warning: ID invalid, couldn't save relative position."); - return; - } + } - var userData = getUserData(this.entityID); - var entityProperties = Entities.getEntityProperties(this.entityID); - var lightProperties = Entities.getEntityProperties(this.lightID); - var newProperties = {}; - - // Copy only meaningful properties (trying to save space in userData here) - for (var key in userData.lightDefaultProperties) { - if (userData.lightDefaultProperties.hasOwnProperty(key)) { - newProperties[key] = lightProperties[key]; - } - } - - // Compute new relative position - newProperties.position = Quat.multiply(Quat.inverse(entityProperties.rotation), - Vec3.subtract(lightProperties.position, - entityProperties.position)); - // inverse "visible" because right after we loaded the properties, the light entity is toggled. - newProperties.visible = !lightProperties.visible; - - userData.lightDefaultProperties = copyObject(newProperties); - updateUserData(this.entityID, userData); - print("Relative properties of light entity saved."); + this.getUserData = function() { + if (this.properties.userData) { + this.userData = JSON.parse(this.properties.userData); } - - // This function should be called before any callback is executed - this.preOperation = function(entityID) { - this.entityID = entityID; - - this.checkUserData(); - this.maybeDownloadSound(); + return false; + } + + this.updateUserData = function() { + Entities.editEntity(this.entityId, { + userData: JSON.stringify(this.userData) + }); + } + + this.clickReleaseOnEntity = function(entityId, mouseEvent) { + if (!mouseEvent.isLeftButton) { + return; + } + //first find closest light + this.entityId = entityId + this.playSound(); + this.properties = Entities.getEntityProperties(this.entityId) + this.light = this.findClosestLight(); + if (this.light) { + this.lightProperties = Entities.getEntityProperties(this.light); + this.getUserData(); + Entities.editEntity(this.light, { + visible: !this.userData.lightOn + }); + + this.userData.lightOn = !this.userData.lightOn; + this.updateUserData(); + this.tryMoveLight(); + } + } + + this.playSound = function() { + if (this.sound && this.sound.downloaded) { + Audio.playSound(this.sound, { + position: this.properties.position, + volume: 0.3 + }); + } else { + print("Warning: Couldn't play sound."); + } + } + + this.tryMoveLight = function() { + if (this.light) { + if (!Vec3.equal(this.properties.position, this.previousPosition)) { + //just get new offset + var offset = Vec3.subtract(this.properties.position, this.previousPosition); + var newWorldLightPosition = Vec3.sum(this.lightProperties.position, offset); + Entities.editEntity(this.light, { + position: newWorldLightPosition + }) + this.previousPosition = this.properties.position; + + } } - // Toggles the associated light entity - this.toggleLight = function() { - if (this.lightID) { - var lightProperties = Entities.getEntityProperties(this.lightID); - Entities.editEntity(this.lightID, { visible: !lightProperties.visible }); - this.playSound(); - } else { - print("Warning: No light to turn on/off"); - } - } + } - this.preload = function(entityID) { - this.preOperation(entityID); - } - - this.clickReleaseOnEntity = function(entityID, mouseEvent) { - this.preOperation(entityID); - - if (mouseEvent.isLeftButton) { - this.updateLightID(); - this.maybeMoveLight(); - this.toggleLight(); - } else if (mouseEvent.isRightButton) { - this.updateRelativeLightPosition(); + + this.findClosestLight = function() { + var entities = Entities.findEntities(this.properties.position, 10); + var lightEntities = []; + var closestLight = null; + var nearestDistance = 20 + + for (var i = 0; i < entities.length; i++) { + var props = Entities.getEntityProperties(entities[i]); + if (props.type === "Light") { + var distance = Vec3.distance(props.position, this.properties.position) + if (distance < nearestDistance) { + closestLight = entities[i]; + nearestDistance = distance } - }; -}) \ No newline at end of file + } + } + return closestLight; + } + +}); \ No newline at end of file