From fe19b5511ce5b1f04c42e6db7369c1c9f075c289 Mon Sep 17 00:00:00 2001 From: Menithal Date: Sat, 4 Mar 2017 21:55:21 +0200 Subject: [PATCH] Fixed up blocks scripts --- .../tutorials/entity_scripts/magneticBlock.js | 240 ++++++++++-------- scripts/tutorials/makeBlocks.js | 79 ++++-- 2 files changed, 193 insertions(+), 126 deletions(-) diff --git a/scripts/tutorials/entity_scripts/magneticBlock.js b/scripts/tutorials/entity_scripts/magneticBlock.js index 73f317e3b2..a375025671 100644 --- a/scripts/tutorials/entity_scripts/magneticBlock.js +++ b/scripts/tutorials/entity_scripts/magneticBlock.js @@ -1,115 +1,133 @@ -(function(){ +// +// magneticBlock.js +// +// Created by Matti Lahtinen 4/3/2017 +// Copyright 2017 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 +// +// Makes the entity the script is bound to connect to nearby, similarly sized entities, like a magnet. +(function() { + const SNAPSOUND_SOURCE = SoundCache.getSound(Script.resolvePath("../../system/assets/sounds/entitySnap.wav?xrs")); + // Preload trick for faster playback + const RANGE_MULTIPLER = 1.5; - const SNAPSOUND = SoundCache.getSound(Script.resolvePath("../../system/assets/sounds/entitySnap.wav?xrs")); - const RANGE_MULTIPLER = 1.5; - - // Helper for detecting nearby objects - function findEntitiesInRange(releasedProperties) { - var dimensions = releasedProperties.dimensions; - return Entities.findEntities(releasedProperties.position, ((dimensions.x + dimensions.y + dimensions.z) / 3) * RANGE_MULTIPLER); - } - - function getNearestValidEntityProperties(releasedProperties) { - var entities = findEntitiesInRange(releasedProperties); - var nearestEntity = null; - var nearest = 9999999999999; - var releaseSize = Vec3.length(releasedProperties.dimensions); - entities.forEach(function(entityId) { - if(entityId !== releasedProperties.id) { - var entity = Entities.getEntityProperties(entityId, ['position', 'rotation', 'dimensions']); - var distance = Vec3.distance(releasedProperties.position, entity.position); - var scale = releaseSize/Vec3.length(entity.dimensions); - - if (distance < nearest && (scale >= 0.5 && scale <= 2)) { - nearestEntity = entity; - nearest = distance; - } - } - }) - return nearestEntity; - } - // Create the 'class' - function MagneticBlock () { } - // Bind pre-emptive events - MagneticBlock.prototype = { - // When script is bound to an entity, preload is the first callback called with the entityID. It will behave as the constructor - preload: function (id) { - /* - We will now override any existing userdata with the grabbable property. - Only retrieving userData - */ - var val = Entities.getEntityProperties(id, ['userData']) - var userData = {}; - if (val.userData && val.userData.length > 0 ) { - try { - userData = JSON.parse(val.userData); - } catch (e) {} - } - // Object must be triggerable inorder to bind events. - userData.grabbableKey = {grabbable: true}; - // Apply the new properties to entity of id - Entities.editEntity(id, {userData: JSON.stringify(userData)}); - this.held = false; - - // We will now create a custom binding, to keep the 'current' context as these are callbacks called without context - var t = this; - this.callbacks = {}; - this.callbacks["releaseGrab"] = function () { - var released = Entities.getEntityProperties(id,["position", "rotation", "dimensions"]); - var target = getNearestValidEntityProperties(released); - if (target !== null) { - // We found nearest, now lets do the snap calculations - // Plays the snap sound between the two objects. - Audio.playSound(SNAPSOUND, { - volume: 1, - position: Vec3.mix(target.position, released.position, 0.5) - }); - // Check Nearest Axis - var difference = Vec3.subtract(released.position, target.position); - var relativeDifference = Vec3.multiplyQbyV(Quat.inverse(target.rotation), difference); - - var abs = { - x: Math.abs(relativeDifference.x), - y: Math.abs(relativeDifference.y), - z: Math.abs(relativeDifference.z) - }; - - if (abs.x >= abs.y && abs.x >= abs.z) { - relativeDifference.y = 0; - relativeDifference.z = 0; - if (relativeDifference.x > 0) { - relativeDifference.x = target.dimensions.x / 2 + released.dimensions.x / 2; - } else { - relativeDifference.x = -target.dimensions.x / 2 - released.dimensions.x / 2; - } - } else if (abs.y >= abs.x && abs.y >= abs.z) { - relativeDifference.x = 0; - relativeDifference.z = 0; - if (relativeDifference.y > 0) { - relativeDifference.y = target.dimensions.y / 2 + released.dimensions.y / 2; - } else { - relativeDifference.y = -target.dimensions.y / 2 - released.dimensions.y / 2; - } - } else if (abs.z >= abs.x && abs.z >= abs.y ) { - relativeDifference.x = 0; - relativeDifference.y = 0; - if (relativeDifference.z > 0) { - relativeDifference.z = target.dimensions.z / 2 + released.dimensions.z / 2; - } else { - relativeDifference.z = -target.dimensions.z / 2 - released.dimensions.z / 2; - } - } - var newPosition = Vec3.multiplyQbyV(target.rotation, relativeDifference); - Entities.editEntity(id, {rotation: target.rotation, position: Vec3.sum(target.position, newPosition)}) - } - } - - this.releaseGrab = this.callbacks["releaseGrab"]; - Script.scriptEnding.connect( function () { - Script.removeEventHandler(id, "releaseGrab", this.callbacks["releaseGrab"]); //continueNearGrab - }) + // Helper for detecting nearby objects + function findEntitiesInRange(releasedProperties) { + var dimensions = releasedProperties.dimensions; + return Entities.findEntities(releasedProperties.position, ((dimensions.x + dimensions.y + dimensions.z) / 3) * RANGE_MULTIPLER); } - } - return new MagneticBlock(); + + function getNearestValidEntityProperties(releasedProperties) { + var entities = findEntitiesInRange(releasedProperties); + var nearestEntity = null; + var nearest = 9999999999999; + var releaseSize = Vec3.length(releasedProperties.dimensions); + entities.forEach(function(entityId) { + if (entityId !== releasedProperties.id) { + var entity = Entities.getEntityProperties(entityId, ['position', 'rotation', 'dimensions']); + var distance = Vec3.distance(releasedProperties.position, entity.position); + var scale = releaseSize / Vec3.length(entity.dimensions); + + if (distance < nearest && (scale >= 0.5 && scale <= 2)) { + nearestEntity = entity; + nearest = distance; + } + } + }) + return nearestEntity; + } + // Create the 'class' + function MagneticBlock() {} + // Bind pre-emptive events + MagneticBlock.prototype = { + // When script is bound to an entity, preload is the first callback called with the entityID. It will behave as the constructor + preload: function(id) { + /* + We will now override any existing userdata with the grabbable property. + Only retrieving userData + */ + var val = Entities.getEntityProperties(id, ['userData']) + var userData = {grabbableKey: {}}; + + if (val.userData && val.userData.length > 0) { + try { + userData = JSON.parse(val.userData); + } catch (e) { + } + } + // Object must be triggerable inorder to bind events. + userData.grabbableKey.grabbable = true; + + // Apply the new properties to entity of id + Entities.editEntity(id, { + userData: JSON.stringify(userData) + }); + this.held = false; + // We will now create a custom binding, to keep the 'current' context as these are callbacks called without context + var t = this; + this.callbacks = {}; + this.releaseGrab = function() { + var released = Entities.getEntityProperties(id, ["position", "rotation", "dimensions"]); + var target = getNearestValidEntityProperties(released); + if (target !== null) { + // We found nearest, now lets do the snap calculations + // Plays the snap sound between the two objects. + Audio.playSound(SNAPSOUND_SOURCE, { + volume: 1, + position: Vec3.mix(target.position, released.position, 0.5) + }); + // Check Nearest Axis + var difference = Vec3.subtract(released.position, target.position); + var relativeDifference = Vec3.multiplyQbyV(Quat.inverse(target.rotation), difference); + + var abs = { + x: Math.abs(relativeDifference.x), + y: Math.abs(relativeDifference.y), + z: Math.abs(relativeDifference.z) + }; + // Check what value is greater. Simplified. + if (abs.x >= abs.y && abs.x >= abs.z) { + relativeDifference.y = 0; + relativeDifference.z = 0; + if (relativeDifference.x > 0) { + relativeDifference.x = target.dimensions.x / 2 + released.dimensions.x / 2; + } else { + relativeDifference.x = -target.dimensions.x / 2 - released.dimensions.x / 2; + } + } else if (abs.y >= abs.x && abs.y >= abs.z) { + relativeDifference.x = 0; + relativeDifference.z = 0; + if (relativeDifference.y > 0) { + relativeDifference.y = target.dimensions.y / 2 + released.dimensions.y / 2; + } else { + relativeDifference.y = -target.dimensions.y / 2 - released.dimensions.y / 2; + } + } else if (abs.z >= abs.x && abs.z >= abs.y) { + relativeDifference.x = 0; + relativeDifference.y = 0; + if (relativeDifference.z > 0) { + relativeDifference.z = target.dimensions.z / 2 + released.dimensions.z / 2; + } else { + relativeDifference.z = -target.dimensions.z / 2 - released.dimensions.z / 2; + } + } + // Can be expanded upon to work in nearest rotation as well, but was not in spec. + var newPosition = Vec3.multiplyQbyV(target.rotation, relativeDifference); + Entities.editEntity(id, { + rotation: target.rotation, + position: Vec3.sum(target.position, newPosition) + }) + } + } + + Script.scriptEnding.connect(function() { + Script.removeEventHandler(id, "releaseGrab", this.releaseGrab); + }) + } + } + return new MagneticBlock(); }) diff --git a/scripts/tutorials/makeBlocks.js b/scripts/tutorials/makeBlocks.js index 6a8b95bb3f..bb4974498c 100644 --- a/scripts/tutorials/makeBlocks.js +++ b/scripts/tutorials/makeBlocks.js @@ -1,15 +1,64 @@ -// Toy -const MAX_RGB_COMPONENT_VALUE = 256 / 2; // Limit the values to half the maximum. -const MIN_COLOR_VALUE = 127; -function newColor() { - color = { - red: randomPastelRGBComponent(), - green: randomPastelRGBComponent(), - blue: randomPastelRGBComponent() - }; - return color; - } -// Helper functions. -function randomPastelRGBComponent() { - return Math.floor(Math.random() * MAX_RGB_COMPONENT_VALUE) + MIN_COLOR_VALUE; -} +// +// makeBlocks.js +// +// Created by Matti Lahtinen 4/3/2017 +// Copyright 2017 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 +// +// Creates multiple "magnetic" blocks with random colors that users clones of and snap together. + + +(function() { + const MAX_RGB_COMPONENT_VALUE = 256 / 2; // Limit the values to half the maximum. + const MIN_COLOR_VALUE = 127; + const SIZE = 0.3; + const LIFETIME = 600; + + // Random Pastel Generator based on Piper's script + function newColor() { + color = { + red: randomPastelRGBComponent(), + green: randomPastelRGBComponent(), + blue: randomPastelRGBComponent() + }; + return color; + } + // Helper functions. + function randomPastelRGBComponent() { + return Math.floor(Math.random() * MAX_RGB_COMPONENT_VALUE) + MIN_COLOR_VALUE; + } + + var SCRIPT_URL = Script.resolvePath("./entity_scripts/magneticBlock.js"); + + var frontVector = Quat.getFront(MyAvatar.orientation); + frontVector.y -=.25; + for(var x =0; x < 3; x++) { + for (var y = 0; y < 3; y++) { + + var frontOffset = { + x: 0, + y: SIZE * y + SIZE, + z: SIZE * x + SIZE + }; + + Entities.addEntity({ + type: "Box", + name: "MagneticBlock-" + y +'-' + x, + dimensions: { + x: SIZE, + y: SIZE, + z: SIZE + }, + userData: JSON.stringify({grabbableKey: { cloneable: true, grabbable: true, cloneLifetime : LIFETIME, cloneLimit: 9999}}), + position: Vec3.sum(MyAvatar.position, Vec3.sum(frontOffset, frontVector)), + color: newColor(), + script: SCRIPT_URL + }); + } + } + + Script.stop(); +})();