Andrew Meadowsarchive remaining JS scriptsc0b446c10 years agoHistory
228 lines · 8.5 KB · JavaScript
RawDownload
(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;    }    function doesEntityExistNow(entityID) {        return entityID;    }    function getTrueID(entityID) {        var properties = Entities.getEntityProperties(entityID);        return { id: properties.id };    }    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 });        }    }     // 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 function should be called before any callback is executed    this.preOperation = function(entityID) {        this.entityID = entityID;                this.checkUserData();        this.maybeDownloadSound();    }     // 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();        }    };})