diff --git a/scripts/tutorials/createFloatingLanternBox.js b/scripts/tutorials/createFloatingLanternBox.js new file mode 100644 index 0000000000..611e995fcb --- /dev/null +++ b/scripts/tutorials/createFloatingLanternBox.js @@ -0,0 +1,42 @@ +"use strict"; +/* jslint vars: true, plusplus: true, forin: true*/ +/* globals Tablet, Script, AvatarList, Users, Entities, MyAvatar, Camera, Overlays, Vec3, Quat, Controller, print, getControllerWorldLocation */ +/* eslint indent: ["error", 4, { "outerIIFEBody": 0 }] */ +// +// createFloatinLanternBox.js +// +// Created by MrRoboman on 17/05/04 +// Copyright 2017 High Fidelity, Inc. +// +// Creates a crate that spawn floating lanterns +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html + +var COMPOUND_SHAPE_URL = "http://hifi-content.s3.amazonaws.com/Examples%20Content/production/maracas/woodenCrate_phys.obj"; +var MODEL_URL = "http://hifi-content.s3.amazonaws.com/Examples%20Content/production/maracas/woodenCrate_VR.fbx"; +var SCRIPT_URL = Script.resolvePath("./entity_scripts/floatingLanternBox.js?v=" + Date.now()); +var START_POSITION = Vec3.sum(MyAvatar.position, Vec3.multiply(Quat.getFront(MyAvatar.orientation), 2)); +START_POSITION.y -= .6; +var LIFETIME = 3600; + +var lanternBox = { + type: "Model", + name: "Floating Lantern Box", + description: "Spawns Lanterns that float away when grabbed and released!", + script: SCRIPT_URL, + modelURL: MODEL_URL, + shapeType: "Compound", + compoundShapeURL: COMPOUND_SHAPE_URL, + position: START_POSITION, + lifetime: LIFETIME, + dimensions: { + x: 0.8696, + y: 0.58531, + z: 0.9264 + }, + owningAvatarID: MyAvatar.sessionUUID +}; + +Entities.addEntity(lanternBox); +Script.stop(); diff --git a/scripts/tutorials/entity_scripts/floatingLantern.js b/scripts/tutorials/entity_scripts/floatingLantern.js new file mode 100644 index 0000000000..8fa2828c90 --- /dev/null +++ b/scripts/tutorials/entity_scripts/floatingLantern.js @@ -0,0 +1,106 @@ +"use strict"; +/* jslint vars: true, plusplus: true, forin: true*/ +/* globals Tablet, Script, AvatarList, Users, Entities, MyAvatar, Camera, Overlays, Vec3, Quat, Controller, print, getControllerWorldLocation */ +/* eslint indent: ["error", 4, { "outerIIFEBody": 0 }] */ +// +// floatinLantern.js +// +// Created by MrRoboman on 17/05/04 +// Copyright 2017 High Fidelity, Inc. +// +// Makes floating lanterns rise upon being released and corrects their rotation as the fly. +// +// 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 _this; + + var SLOW_SPIN_THRESHOLD = 0.1; + var ROTATION_COMPLETE_THRESHOLD = 0.01; + var ROTATION_SPEED = 0.2; + var HOME_ROTATION = {x: 0, y: 0, z: 0, w: 0}; + + + floatingLantern = function() { + _this = this; + this.updateConnected = false; + }; + + floatingLantern.prototype = { + + preload: function(entityID) { + this.entityID = entityID; + }, + + unload: function(entityID) { + this.disconnectUpdate(); + }, + + startNearGrab: function() { + this.disconnectUpdate(); + }, + + startDistantGrab: function() { + this.disconnectUpdate(); + }, + + releaseGrab: function() { + Entities.editEntity(this.entityID, { + gravity: { + x: 0, + y: 0.5, + z: 0 + } + }); + }, + + update: function(dt) { + var lanternProps = Entities.getEntityProperties(_this.entityID); + + if(lanternProps && lanternProps.rotation && lanternProps.owningAvatarID === MyAvatar.sessionUUID) { + + var spinningSlowly = ( + Math.abs(lanternProps.angularVelocity.x) < SLOW_SPIN_THRESHOLD && + Math.abs(lanternProps.angularVelocity.y) < SLOW_SPIN_THRESHOLD && + Math.abs(lanternProps.angularVelocity.z) < SLOW_SPIN_THRESHOLD + ); + + var rotationComplete = ( + Math.abs(lanternProps.rotation.x - HOME_ROTATION.x) < ROTATION_COMPLETE_THRESHOLD && + Math.abs(lanternProps.rotation.y - HOME_ROTATION.y) < ROTATION_COMPLETE_THRESHOLD && + Math.abs(lanternProps.rotation.z - HOME_ROTATION.z) < ROTATION_COMPLETE_THRESHOLD + ); + + if(spinningSlowly && !rotationComplete) { + var newRotation = Quat.slerp(lanternProps.rotation, HOME_ROTATION, ROTATION_SPEED * dt); + + Entities.editEntity(_this.entityID, { + rotation: newRotation, + angularVelocity: { + x: 0, + y: 0, + z: 0 + } + }); + } + } + }, + + connectUpdate: function() { + if(!this.updateConnected) { + this.updateConnected = true; + Script.update.connect(this.update); + } + }, + + disconnectUpdate: function() { + if(this.updateConnected) { + this.updateConnected = false; + Script.update.disconnect(this.update); + } + } + }; + + return new floatingLantern(); +}); diff --git a/scripts/tutorials/entity_scripts/floatingLanternBox.js b/scripts/tutorials/entity_scripts/floatingLanternBox.js new file mode 100644 index 0000000000..2c483f6129 --- /dev/null +++ b/scripts/tutorials/entity_scripts/floatingLanternBox.js @@ -0,0 +1,101 @@ +"use strict"; +/* jslint vars: true, plusplus: true, forin: true*/ +/* globals Tablet, Script, AvatarList, Users, Entities, MyAvatar, Camera, Overlays, Vec3, Quat, Controller, print, getControllerWorldLocation */ +/* eslint indent: ["error", 4, { "outerIIFEBody": 0 }] */ +// +// floatingLanternBox.js +// +// Created by MrRoboman on 17/05/04 +// Copyright 2017 High Fidelity, Inc. +// +// Spawns new floating lanterns every couple seconds if the old ones have been removed. +// +// 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 _this; + var LANTERN_MODEL_URL = "http://hifi-content.s3.amazonaws.com/DomainContent/Welcome%20Area/Models/chinaLantern_capsule.fbx"; + var LANTERN_SCRIPT_URL = Script.resolvePath("floatingLantern.js?v=" + Date.now()); + var LIFETIME = 120; + var RESPAWN_INTERVAL = 1000; + var MAX_LANTERNS = 4; + + var LANTERN = { + type: "Model", + name: "Floating Lantern", + description: "Spawns Lanterns that float away when grabbed and released!", + modelURL: LANTERN_MODEL_URL, + script: LANTERN_SCRIPT_URL, + dimensions: { + x: 0.2049, + y: 0.4, + z: 0.2049 + }, + gravity: { + x: 0, + y: -1, + z: 0 + }, + velocity: { + x: 0, y: .01, z: 0 + }, + linearDampening: 0, + shapeType: 'Box', + lifetime: LIFETIME, + dynamic: true + }; + + lanternBox = function() { + _this = this; + }; + + lanternBox.prototype = { + + preload: function(entityID) { + this.entityID = entityID; + var props = Entities.getEntityProperties(this.entityID); + + if(props.owningAvatarID === MyAvatar.sessionUUID){ + this.respawnTimer = Script.setInterval(this.spawnAllLanterns.bind(this), RESPAWN_INTERVAL); + } + }, + + unload: function(entityID) { + if(this.respawnTimer) + Script.clearInterval(this.respawnTimer); + }, + + spawnAllLanterns: function() { + var props = Entities.getEntityProperties(this.entityID); + var lanternCount = 0; + var nearbyEntities = Entities.findEntities(props.position, props.dimensions.x * 0.75); + + for(var i = 0; i < nearbyEntities.length; i++) { + var name = Entities.getEntityProperties(nearbyEntities[i], ["name"]).name; + if(name === "Floating Lantern") { + lanternCount++; + } + } + + while(lanternCount++ < MAX_LANTERNS) { + this.spawnLantern(); + } + }, + + spawnLantern: function() { + var boxProps = Entities.getEntityProperties(this.entityID); + + LANTERN.position = boxProps.position; + LANTERN.position.x += Math.random() * .2 - .1; + LANTERN.position.y += Math.random() * .2 + .1; + LANTERN.position.z += Math.random() * .2 - .1; + LANTERN.owningAvatarID = boxProps.owningAvatarID; + + return Entities.addEntity(LANTERN); + } + }; + + return new lanternBox(); +});