From f9e8ada954215deb111a3c743a8d18fcf919e540 Mon Sep 17 00:00:00 2001 From: "James B. Pollack" Date: Thu, 21 Jul 2016 17:18:45 -0700 Subject: [PATCH] new whiteboard for home --- .../DomainContent/Home/reset.js | 29 +- .../Home/whiteboard/eraserEntityScript.js | 113 ++---- .../Home/whiteboard/markerEntityScript.js | 123 ++----- .../Home/whiteboard/singleSpawner.js | 23 -- .../DomainContent/Home/whiteboard/swiper.js | 62 ++++ .../DomainContent/Home/whiteboard/utils.js | 347 ++++++++++++++++++ .../Home/whiteboard/whiteboard.js | 211 +++++++++++ .../Home/whiteboard/whiteboardWithSwiper.json | 149 ++++++++ .../DomainContent/Home/whiteboard/wrapper.js | 282 -------------- 9 files changed, 845 insertions(+), 494 deletions(-) delete mode 100644 unpublishedScripts/DomainContent/Home/whiteboard/singleSpawner.js create mode 100644 unpublishedScripts/DomainContent/Home/whiteboard/swiper.js create mode 100644 unpublishedScripts/DomainContent/Home/whiteboard/utils.js create mode 100644 unpublishedScripts/DomainContent/Home/whiteboard/whiteboard.js create mode 100644 unpublishedScripts/DomainContent/Home/whiteboard/whiteboardWithSwiper.json delete mode 100644 unpublishedScripts/DomainContent/Home/whiteboard/wrapper.js diff --git a/unpublishedScripts/DomainContent/Home/reset.js b/unpublishedScripts/DomainContent/Home/reset.js index cd1dcea76e..bfb2807bfb 100644 --- a/unpublishedScripts/DomainContent/Home/reset.js +++ b/unpublishedScripts/DomainContent/Home/reset.js @@ -35,8 +35,6 @@ var tiltMazePath = Script.resolvePath("atp:/tiltMaze/wrapper.js") - var whiteboardPath = Script.resolvePath("atp:/whiteboard/wrapper.js"); - var cuckooClockPath = Script.resolvePath("atp:/cuckooClock/wrapper.js"); var pingPongGunPath = Script.resolvePath("atp:/pingPongGun/wrapper.js"); @@ -51,7 +49,6 @@ Script.include(fishTankPath); Script.include(tiltMazePath); - Script.include(whiteboardPath); Script.include(cuckooClockPath); Script.include(pingPongGunPath); Script.include(transformerPath); @@ -201,6 +198,7 @@ Script.setTimeout(function() { _this.createKineticEntities(); _this.createScriptedEntities(); + _this.createWhiteboard(); _this.setupDressingRoom(); _this.createMilkPailBalls(); _this.createTarget(); @@ -296,6 +294,21 @@ print('HOME after deleting home entities'); }, + createWhiteboard: function() { + var WHITEBOARD_URL = "atp:/whiteboard/whiteboardWithSwiper.json" + var success = Clipboard.importEntities(WHITEBOARD_URL); + if (success === true) { + created = Clipboard.pasteEntities({ + x: 1105.0955, + y: 460.5000, + z: -77.4409 + }) + print('created ' + created); + } else { + print('failed to import whiteboard'); + } + }, + createScriptedEntities: function() { var fishTank = new FishTank({ x: 1099.2200, @@ -313,16 +326,6 @@ z: -80.4891 }); - var whiteboard = new Whiteboard({ - x: 1105.0955, - y: 460.5000, - z: -77.4409 - }, { - x: -0.0013, - y: -133.0056, - z: -0.0013 - }); - var pingPongGun = new HomePingPongGun({ x: 1101.2123, y: 460.2328, diff --git a/unpublishedScripts/DomainContent/Home/whiteboard/eraserEntityScript.js b/unpublishedScripts/DomainContent/Home/whiteboard/eraserEntityScript.js index 4175c65e96..ad915086fa 100644 --- a/unpublishedScripts/DomainContent/Home/whiteboard/eraserEntityScript.js +++ b/unpublishedScripts/DomainContent/Home/whiteboard/eraserEntityScript.js @@ -1,128 +1,59 @@ // // eraserEntityScript.js -// examples/homeContent/eraserEntityScript // // Created by Eric Levin on 2/17/15. +// Additions by James B. Pollack @imgntn 6/9/2016 // Copyright 2016 High Fidelity, Inc. // // This entity script provides logic for an object with attached script to erase nearby marker strokes // Distributed under the Apache License, Version 2.0. // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html - - (function() { - Script.include('../utils.js'); - var TRIGGER_CONTROLS = [ - Controller.Standard.LT, - Controller.Standard.RT, - ]; + Script.include('atp:/whiteboard/utils.js'); + var _this; + Eraser = function() { _this = this; - - _this.ERASER_TRIGGER_THRESHOLD = 0.2; - _this.STROKE_NAME = "home_polyline_markerStroke"; - _this.ERASER_TO_STROKE_SEARCH_RADIUS = 0.7; - _this.ERASER_RESET_WAIT_TIME = 3000; + _this.STROKE_NAME = "hifi_polyline_markerStroke"; + _this.ERASER_TO_STROKE_SEARCH_RADIUS = 0.1; }; Eraser.prototype = { - startEquip: function(id, params) { - _this.equipped = true; - _this.hand = params[0] == "left" ? 0 : 1; - // We really only need to grab position of marker strokes once, and then just check to see if eraser comes near enough to those strokes - Overlays.editOverlay(_this.searchSphere, { - visible: true - }); - }, - continueEquip: function() { + continueNearGrab: function() { _this.eraserPosition = Entities.getEntityProperties(_this.entityID, "position").position; - Overlays.editOverlay(_this.searchSphere, { - position: _this.eraserPosition - }); - this.triggerValue = Controller.getValue(TRIGGER_CONTROLS[_this.hand]); - if (_this.triggerValue > _this.ERASER_TRIGGER_THRESHOLD) { - _this.continueHolding(); - } + _this.continueHolding(); }, - continueHolding: function() { - var strokeIDs = Entities.findEntities(_this.eraserPosition, _this.ERASER_TO_STROKE_SEARCH_RADIUS); + var results = Entities.findEntities(_this.eraserPosition, _this.ERASER_TO_STROKE_SEARCH_RADIUS); // Create a map of stroke entities and their positions - strokeIDs.forEach(function(strokeID) { - var strokeProps = Entities.getEntityProperties(strokeID, ["position", "name"]); - if (strokeProps.name === _this.STROKE_NAME && Vec3.distance(_this.eraserPosition, strokeProps.position) < _this.ERASER_TO_STROKE_SEARCH_RADIUS) { - Entities.deleteEntity(strokeID); + results.forEach(function(stroke) { + var props = Entities.getEntityProperties(stroke, ["position", "name"]); + if (props.name === _this.STROKE_NAME && Vec3.distance(_this.eraserPosition, props.position) < _this.ERASER_TO_STROKE_SEARCH_RADIUS) { + Entities.deleteEntity(stroke); } }); }, - releaseEquip: function() { - Overlays.editOverlay(_this.searchSphere, { - visible: false - }); - - // Once user releases eraser, wait a bit then put marker back to its original position and rotation - // Script.setTimeout(function() { - // var userData = getEntityUserData(_this.entityID); - // Entities.editEntity(_this.entityID, { - // position: userData.originalPosition, - // rotation: userData.originalRotation, - // velocity: { - // x: 0, - // y: -0.01, - // z: 0 - // } - // }); - // }, _this.ERASER_RESET_WAIT_TIME); - }, - collisionWithEntity: function(myID, otherID, collision) { - var otherProps = Entities.getEntityProperties(otherID); - if (otherProps.name === 'home_model_homeset') { - var userData = getEntityUserData(_this.entityID); - Entities.editEntity(_this.entityID, { - position: userData.originalPosition, - rotation: userData.originalRotation, - velocity: { - x: 0, - y: -0.01, - z: 0 - }, - angularVelocity: { - x: 0, - y: 0, - z: 0 - } - }); - } - }, - - preload: function(entityID) { _this.entityID = entityID; - _this.searchSphere = Overlays.addOverlay('sphere', { - size: _this.ERASER_TO_STROKE_SEARCH_RADIUS, - color: { - red: 200, - green: 10, - blue: 10 - }, - alpha: 0.2, - solid: true, - visible: false - }) }, - unload: function() { - Overlays.deleteOverlay(_this.searchSphere); - } + startEquip: function() { + _this.startNearGrab(); + }, + + continueEquip: function() { + _this.continueNearGrab(); + }, + + }; - // entity scripts always need to return a newly constructed object of our type return new Eraser(); }); \ No newline at end of file diff --git a/unpublishedScripts/DomainContent/Home/whiteboard/markerEntityScript.js b/unpublishedScripts/DomainContent/Home/whiteboard/markerEntityScript.js index 1f07172a45..599f8979d1 100644 --- a/unpublishedScripts/DomainContent/Home/whiteboard/markerEntityScript.js +++ b/unpublishedScripts/DomainContent/Home/whiteboard/markerEntityScript.js @@ -1,8 +1,8 @@ // // markerTipEntityScript.js -// examples/homeContent/markerTipEntityScript // // Created by Eric Levin on 2/17/15. +// Additions by James B. Pollack @imgntn 6/9/2016 // Copyright 2016 High Fidelity, Inc. // // This script provides the logic for an object to draw marker strokes on its associated whiteboard @@ -10,15 +10,9 @@ // Distributed under the Apache License, Version 2.0. // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html - - (function() { - Script.include('../utils.js'); - var TRIGGER_CONTROLS = [ - Controller.Standard.LT, - Controller.Standard.RT, - ]; + Script.include('atp:/whiteboard/utils.js'); var MAX_POINTS_PER_STROKE = 40; var _this; @@ -31,95 +25,74 @@ min: 0.002, max: 0.01 }; - _this.MAX_MARKER_TO_BOARD_DISTANCE = 1.4; _this.MIN_DISTANCE_BETWEEN_POINTS = 0.002; _this.MAX_DISTANCE_BETWEEN_POINTS = 0.1; _this.strokes = []; - _this.PAINTING_TRIGGER_THRESHOLD = 0.2; - _this.STROKE_NAME = "home_polyline_markerStroke"; - _this.WHITEBOARD_SURFACE_NAME = "home_box_whiteboardDrawingSurface" - _this.MARKER_RESET_WAIT_TIME = 3000; + _this.STROKE_NAME = "hifi_polyline_markerStroke"; + _this.WHITEBOARD_SURFACE_NAME = "hifi-whiteboardDrawingSurface" }; MarkerTip.prototype = { - startEquip: function(id, params) { - print('start equip') + startNearGrab: function() { _this.whiteboards = []; - _this.equipped = true; - _this.hand = params[0] == "left" ? 0 : 1; _this.markerColor = getEntityUserData(_this.entityID).markerColor; - // search for whiteboards - var markerPosition = Entities.getEntityProperties(_this.entityID, "position").position; - var entities = Entities.findEntities(markerPosition, 10); - entities.forEach(function(entity) { - + var markerProps = Entities.getEntityProperties(_this.entityID); + _this.DRAW_ON_BOARD_DISTANCE = markerProps.dimensions.z / 2; + var markerPosition = markerProps.position; + var results = Entities.findEntities(markerPosition, 5); + results.forEach(function(entity) { var entityName = Entities.getEntityProperties(entity, "name").name; if (entityName === _this.WHITEBOARD_SURFACE_NAME) { _this.whiteboards.push(entity); } }); + }, - releaseEquip: function() { + releaseGrab: function() { _this.resetStroke(); - Overlays.editOverlay(_this.laserPointer, { - visible: false - }); }, - collisionWithEntity: function(myID, otherID, collision) { - var otherProps = Entities.getEntityProperties(otherID); - if (otherProps.name === 'home_model_homeset') { - var userData = getEntityUserData(_this.entityID); - Entities.editEntity(_this.entityID, { - position: userData.originalPosition, - rotation: userData.originalRotation, - velocity: { - x: 0, - y: -0.01, - z: 0 - }, - angularVelocity: {x: 0, y: 0, z: 0} - }) - } - }, - continueEquip: function() { + continueNearGrab: function() { // cast a ray from marker and see if it hits anything - var markerProps = Entities.getEntityProperties(_this.entityID, ["position", "rotation"]); + var markerProps = Entities.getEntityProperties(_this.entityID); + + //need to back up the ray to the back of the marker + + var markerFront = Quat.getFront(markerProps.rotation); + var howFarBack = markerProps.dimensions.z / 2; + var pulledBack = Vec3.multiply(markerFront, -howFarBack); + var backedOrigin = Vec3.sum(markerProps.position, pulledBack); var pickRay = { - origin: markerProps.position, + origin: backedOrigin, direction: Quat.getFront(markerProps.rotation) } - var intersection = Entities.findRayIntersectionBlocking(pickRay, true, _this.whiteboards); + var intersection = Entities.findRayIntersection(pickRay, true, _this.whiteboards); - if (intersection.intersects && Vec3.distance(intersection.intersection, markerProps.position) < _this.MAX_MARKER_TO_BOARD_DISTANCE) { + if (intersection.intersects && Vec3.distance(intersection.intersection, markerProps.position) <= _this.DRAW_ON_BOARD_DISTANCE) { _this.currentWhiteboard = intersection.entityID; var whiteboardRotation = Entities.getEntityProperties(_this.currentWhiteboard, "rotation").rotation; _this.whiteboardNormal = Quat.getFront(whiteboardRotation); - Overlays.editOverlay(_this.laserPointer, { - visible: true, - position: intersection.intersection, - rotation: whiteboardRotation - }) - _this.triggerValue = Controller.getValue(TRIGGER_CONTROLS[_this.hand]); - if (_this.triggerValue > _this.PAINTING_TRIGGER_THRESHOLD) { - _this.paint(intersection.intersection) - } else { - _this.resetStroke(); - } + + _this.paint(intersection.intersection) + } else { if (_this.currentStroke) { _this.resetStroke(); } - Overlays.editOverlay(_this.laserPointer, { - visible: false - }); } + }, + startEquip: function() { + _this.startNearGrab(); + }, + + continueEquip: function() { + _this.continueNearGrab(); }, newStroke: function(position) { @@ -135,12 +108,7 @@ position: position, textures: _this.MARKER_TEXTURE_URL, color: _this.markerColor, - lifetime: 5000, - userData: JSON.stringify({ - 'hifiHomeKey': { - 'reset': true - } - }), + lifetime: 5000 }); _this.linePoints = []; @@ -170,7 +138,8 @@ _this.normals.push(_this.whiteboardNormal); var strokeWidths = []; - for (var i = 0; i < _this.linePoints.length; i++) { + var i; + for (i = 0; i < _this.linePoints.length; i++) { // Create a temp array of stroke widths for calligraphy effect - start and end should be less wide var pointsFromCenter = Math.abs(_this.linePoints.length / 2 - i); var pointWidth = map(pointsFromCenter, 0, this.linePoints.length / 2, _this.STROKE_WIDTH_RANGE.max, this.STROKE_WIDTH_RANGE.min); @@ -191,6 +160,7 @@ _this.oldPosition = position; } }, + resetStroke: function() { Entities.editEntity(_this.currentStroke, { @@ -203,26 +173,9 @@ preload: function(entityID) { this.entityID = entityID; - _this.laserPointer = Overlays.addOverlay("circle3d", { - color: { - red: 220, - green: 35, - blue: 53 - }, - solid: true, - size: 0.01, - }); - }, - unload: function() { - Overlays.deleteOverlay(_this.laserPointer); - _this.strokes.forEach(function(stroke) { - Entities.deleteEntity(stroke); - }); - } }; - // entity scripts always need to return a newly constructed object of our type return new MarkerTip(); }); \ No newline at end of file diff --git a/unpublishedScripts/DomainContent/Home/whiteboard/singleSpawner.js b/unpublishedScripts/DomainContent/Home/whiteboard/singleSpawner.js deleted file mode 100644 index 48c0a48755..0000000000 --- a/unpublishedScripts/DomainContent/Home/whiteboard/singleSpawner.js +++ /dev/null @@ -1,23 +0,0 @@ -// -// -// Created by The Content Team 4/10/216 -// Copyright 2016 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 -// - -var whiteboardPath = Script.resolvePath('wrapper.js'); -Script.include(whiteboardPath); - -var whiteboard = new Whiteboard({ - x: 1104, - y: 460.5, - z: -77 -}, { - x: 0, - y: -133, - z: 0 -}); \ No newline at end of file diff --git a/unpublishedScripts/DomainContent/Home/whiteboard/swiper.js b/unpublishedScripts/DomainContent/Home/whiteboard/swiper.js new file mode 100644 index 0000000000..cd19c6eeee --- /dev/null +++ b/unpublishedScripts/DomainContent/Home/whiteboard/swiper.js @@ -0,0 +1,62 @@ +// Created by James B. Pollack @imgntn 6/8/2016 +// Copyright 2016 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 +// +// + +(function() { + + var _this; + + Swiper = function() { + _this = this; + } + + Swiper.prototype = { + busy: false, + preload: function(entityID) { + this.entityID = entityID; + Script.update.connect(this.update); + }, + clickReleaseOnEntity: function() { + this.createSupplies(); + }, + update: function() { + if (_this.busy === true) { + return; + } + + var position = Entities.getEntityProperties(_this.entityID).position; + var TRIGGER_THRESHOLD = 0.11; + + var leftHandPosition = MyAvatar.getLeftPalmPosition(); + var rightHandPosition = MyAvatar.getRightPalmPosition(); + + var leftDistance = Vec3.distance(leftHandPosition, position) + var rightDistance = Vec3.distance(rightHandPosition, position) + + if (rightDistance < TRIGGER_THRESHOLD || leftDistance < TRIGGER_THRESHOLD) { + _this.createSupplies(); + _this.busy = true; + Script.setTimeout(function() { + _this.busy = false; + }, 2000) + } + }, + + createSupplies: function() { + var myProperties = Entities.getEntityProperties(this.entityID); + + Entities.callEntityMethod(myProperties.parentID, "createMarkers"); + Entities.callEntityMethod(myProperties.parentID, "createEraser"); + + }, + unload: function() { + Script.update.disconnect(this.update); + } + + } + return new Swiper +}) \ No newline at end of file diff --git a/unpublishedScripts/DomainContent/Home/whiteboard/utils.js b/unpublishedScripts/DomainContent/Home/whiteboard/utils.js new file mode 100644 index 0000000000..d960fea5df --- /dev/null +++ b/unpublishedScripts/DomainContent/Home/whiteboard/utils.js @@ -0,0 +1,347 @@ +// +// Created by Bradley Austin Davis on 2015/08/29 +// Copyright 2015 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 +// + +map = function(value, min1, max1, min2, max2) { + return min2 + (max2 - min2) * ((value - min1) / (max1 - min1)); +} + +vec3toStr = function(v, digits) { + if (!digits) { + digits = 3; + } + return "{ " + v.x.toFixed(digits) + ", " + v.y.toFixed(digits) + ", " + v.z.toFixed(digits) + " }"; +} + +quatToStr = function(q, digits) { + if (!digits) { + digits = 3; + } + return "{ " + q.w.toFixed(digits) + ", " + q.x.toFixed(digits) + ", " + + q.y.toFixed(digits) + ", " + q.z.toFixed(digits) + " }"; +} + +vec3equal = function(v0, v1) { + return (v0.x == v1.x) && (v0.y == v1.y) && (v0.z == v1.z); +} + +colorMix = function(colorA, colorB, mix) { + var result = {}; + for (var key in colorA) { + result[key] = (colorA[key] * (1 - mix)) + (colorB[key] * mix); + } + return result; +} + +scaleLine = function(start, end, scale) { + var v = Vec3.subtract(end, start); + var length = Vec3.length(v); + v = Vec3.multiply(scale, v); + return Vec3.sum(start, v); +} + +findAction = function(name) { + return Controller.findAction(name); +} + +addLine = function(origin, vector, color) { + if (!color) { + color = COLORS.WHITE + } + return Entities.addEntity(mergeObjects(LINE_PROTOTYPE, { + position: origin, + linePoints: [ + ZERO_VECTOR, + vector, + ], + color: color + })); +} + +// FIXME fetch from a subkey of user data to support non-destructive modifications +setEntityUserData = function(id, data) { + var json = JSON.stringify(data) + Entities.editEntity(id, { + userData: json + }); +} + +// FIXME do non-destructive modification of the existing user data +getEntityUserData = function(id) { + var results = null; + var properties = Entities.getEntityProperties(id, "userData"); + if (properties.userData) { + try { + results = JSON.parse(properties.userData); + } catch (err) { + logDebug(err); + logDebug(properties.userData); + } + } + return results ? results : {}; +} + + +// Non-destructively modify the user data of an entity. +setEntityCustomData = function(customKey, id, data) { + var userData = getEntityUserData(id); + if (data == null) { + delete userData[customKey]; + } else { + userData[customKey] = data; + } + setEntityUserData(id, userData); +} + +getEntityCustomData = function(customKey, id, defaultValue) { + var userData = getEntityUserData(id); + if (undefined != userData[customKey]) { + return userData[customKey]; + } else { + return defaultValue; + } +} + +mergeObjects = function(proto, custom) { + var result = {}; + for (var attrname in proto) { + result[attrname] = proto[attrname]; + } + for (var attrname in custom) { + result[attrname] = custom[attrname]; + } + return result; +} + +LOG_WARN = 1; + +logWarn = function(str) { + if (LOG_WARN) { + print(str); + } +} + +LOG_ERROR = 1; + +logError = function(str) { + if (LOG_ERROR) { + print(str); + } +} + +LOG_INFO = 1; + +logInfo = function(str) { + if (LOG_INFO) { + print(str); + } +} + +LOG_DEBUG = 0; + +logDebug = function(str) { + if (LOG_DEBUG) { + print(str); + } +} + +LOG_TRACE = 0; + +logTrace = function(str) { + if (LOG_TRACE) { + print(str); + } +} + +// Computes the penetration between a point and a sphere (centered at the origin) +// if point is inside sphere: returns true and stores the result in 'penetration' +// (the vector that would move the point outside the sphere) +// otherwise returns false +findSphereHit = function(point, sphereRadius) { + var EPSILON = 0.000001; //smallish positive number - used as margin of error for some computations + var vectorLength = Vec3.length(point); + if (vectorLength < EPSILON) { + return true; + } + var distance = vectorLength - sphereRadius; + if (distance < 0.0) { + return true; + } + return false; +} + +findSpherePointHit = function(sphereCenter, sphereRadius, point) { + return findSphereHit(Vec3.subtract(point, sphereCenter), sphereRadius); +} + +findSphereSphereHit = function(firstCenter, firstRadius, secondCenter, secondRadius) { + return findSpherePointHit(firstCenter, firstRadius + secondRadius, secondCenter); +} + +// Given a vec3 v, return a vec3 that is the same vector relative to the avatars +// DEFAULT eye position, rotated into the avatars reference frame. +getEyeRelativePosition = function(v) { + return Vec3.sum(MyAvatar.getDefaultEyePosition(), Vec3.multiplyQbyV(MyAvatar.orientation, v)); +} + +getAvatarRelativeRotation = function(q) { + return Quat.multiply(MyAvatar.orientation, q); +} + +pointInExtents = function(point, minPoint, maxPoint) { + return (point.x >= minPoint.x && point.x <= maxPoint.x) && + (point.y >= minPoint.y && point.y <= maxPoint.y) && + (point.z >= minPoint.z && point.z <= maxPoint.z); +} + +/** + * Converts an HSL color value to RGB. Conversion formula + * adapted from http://en.wikipedia.org/wiki/HSL_color_space. + * Assumes h, s, and l are contained in the set [0, 1] and + * returns r, g, and b in the set [0, 255]. + * + * @param Number h The hue + * @param Number s The saturation + * @param Number l The lightness + * @return Array The RGB representation + */ +hslToRgb = function(hsl) { + var r, g, b; + if (hsl.s == 0) { + r = g = b = hsl.l; // achromatic + } else { + var hue2rgb = function hue2rgb(p, q, t) { + if (t < 0) t += 1; + if (t > 1) t -= 1; + if (t < 1 / 6) return p + (q - p) * 6 * t; + if (t < 1 / 2) return q; + if (t < 2 / 3) return p + (q - p) * (2 / 3 - t) * 6; + return p; + } + + var q = hsl.l < 0.5 ? hsl.l * (1 + hsl.s) : hsl.l + hsl.s - hsl.l * hsl.s; + var p = 2 * hsl.l - q; + r = hue2rgb(p, q, hsl.h + 1 / 3); + g = hue2rgb(p, q, hsl.h); + b = hue2rgb(p, q, hsl.h - 1 / 3); + } + + return { + red: Math.round(r * 255), + green: Math.round(g * 255), + blue: Math.round(b * 255) + }; +} + + + +orientationOf = function(vector) { + var Y_AXIS = { + x: 0, + y: 1, + z: 0 + }; + var X_AXIS = { + x: 1, + y: 0, + z: 0 + }; + + var theta = 0.0; + + var RAD_TO_DEG = 180.0 / Math.PI; + var direction, yaw, pitch; + direction = Vec3.normalize(vector); + yaw = Quat.angleAxis(Math.atan2(direction.x, direction.z) * RAD_TO_DEG, Y_AXIS); + pitch = Quat.angleAxis(Math.asin(-direction.y) * RAD_TO_DEG, X_AXIS); + return Quat.multiply(yaw, pitch); +} + +randFloat = function(low, high) { + return low + Math.random() * (high - low); +} + + +randInt = function(low, high) { + return Math.floor(randFloat(low, high)); +} + +hexToRgb = function(hex) { + var result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex); + return result ? { + red: parseInt(result[1], 16), + green: parseInt(result[2], 16), + blue: parseInt(result[3], 16) + } : null; +} + +calculateHandSizeRatio = function() { + // Get the ratio of the current avatar's hand to Owen's hand + + var standardCenterHandPoint = 0.11288; + var jointNames = MyAvatar.getJointNames(); + //get distance from handJoint up to leftHandIndex3 as a proxy for center of hand + var wristToFingertipDistance = 0;; + for (var i = 0; i < jointNames.length; i++) { + var jointName = jointNames[i]; + print(jointName) + if (jointName.indexOf("LeftHandIndex") !== -1) { + // translations are relative to parent joint, so simply add them together + // joints face down the y-axis + var translation = MyAvatar.getDefaultJointTranslation(i).y; + wristToFingertipDistance += translation; + } + } + // Right now units are in cm, so convert to meters + wristToFingertipDistance /= 100; + + var centerHandPoint = wristToFingertipDistance / 2; + + // Compare against standard hand (Owen) + var handSizeRatio = centerHandPoint / standardCenterHandPoint; + return handSizeRatio; +} + +clamp = function(val, min, max) { + return Math.max(min, Math.min(max, val)) +} + +attachChildToParent = function(childName, parentName, position, searchRadius) { + var childEntity, parentEntity; + var entities = Entities.findEntities(position, searchRadius) + for (var i = 0; i < entities.length; i++) { + // first go through and find the entity we want to attach to its parent + var entity = entities[i]; + var name = Entities.getEntityProperties(entity, "name").name; + if (name === childName) { + childEntity = entity; + break; + } + } + + if (!childEntity) { + print("You are trying to attach an entity that doesn't exist! Returning"); + } + + for (var i = 0; i < entities.length; i++) { + // first go through and find the entity we want to attach to its parent + var entity = entities[i]; + var name = Entities.getEntityProperties(entity, "name").name; + if (name === parentName) { + parentEntity = entity; + break; + } + } + + if (!parentEntity) { + print("You are trying to attach an entity to a parent that doesn't exist! Returning"); + return; + } + + print("Successfully attached " + childName + " to " + parentName); + Entities.editEntity(childEntity, {parentID: parentEntity}); +} \ No newline at end of file diff --git a/unpublishedScripts/DomainContent/Home/whiteboard/whiteboard.js b/unpublishedScripts/DomainContent/Home/whiteboard/whiteboard.js new file mode 100644 index 0000000000..3847e580c8 --- /dev/null +++ b/unpublishedScripts/DomainContent/Home/whiteboard/whiteboard.js @@ -0,0 +1,211 @@ +// Created by James B. Pollack @imgntn 6/8/2016 +// Copyright 2016 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 +// +// + +(function() { + + var _this; + var MARKER_SCRIPT_URL = "atp:/whiteboard/markerEntityScript.js"; + var ERASER_SCRIPT_URL = "atp:/whiteboard/eraserEntityScript.js"; + + Whiteboard = function() { + _this = this; + } + + Whiteboard.prototype = { + preload: function(entityID) { + this.entityID = entityID; + this.setup(); + }, + unload: function() { + + }, + setup: function() { + + var props = Entities.getEntityProperties(_this.entityID); + this.spawnRotation = Quat.safeEulerAngles(props.rotation); + this.spawnPosition = props.position; + this.orientation = Quat.fromPitchYawRollDegrees(this.spawnRotation.x, this.spawnRotation.y, this.spawnRotation.z); + this.markerRotation = Quat.fromVec3Degrees({ + x: this.spawnRotation.x + 10, + y: this.spawnRotation.y - 90, + z: this.spawnRotation.z + }); + + }, + createMarkers: function() { + _this.setup(); + var modelURLS = [ + "atp:/whiteboard/marker-blue.fbx", + "atp:/whiteboard/marker-red.fbx", + "atp:/whiteboard/marker-black.fbx", + ]; + + var markerPosition = Vec3.sum(_this.spawnPosition, Vec3.multiply(Quat.getFront(_this.orientation), -0.1)); + + _this.createMarker(modelURLS[0], markerPosition, { + red: 10, + green: 10, + blue: 200 + }); + + _this.createMarker(modelURLS[1], markerPosition, { + red: 200, + green: 10, + blue: 10 + }); + + _this.createMarker(modelURLS[2], markerPosition, { + red: 10, + green: 10, + blue: 10 + }); + }, + createMarker: function(modelURL, markerPosition, markerColor) { + + var markerProperties = { + type: "Model", + modelURL: modelURL, + rotation: _this.markerRotation, + shapeType: "box", + name: "hifi_model_marker", + dynamic: true, + gravity: { + x: 0, + y: -5, + z: 0 + }, + velocity: { + x: 0, + y: -0.1, + z: 0 + }, + position: markerPosition, + dimensions: { + x: 0.027, + y: 0.027, + z: 0.164 + }, + lifetime: 86400, + script: MARKER_SCRIPT_URL, + userData: JSON.stringify({ + 'grabbableKey': { + 'grabbable': true + }, + 'hifiHomeKey': { + 'reset': true + }, + originalPosition: markerPosition, + originalRotation: _this.markerRotation, + markerColor: markerColor, + wearable: { + joints: { + RightHand: [{ + x: 0.001, + y: 0.139, + z: 0.050 + }, { + x: -0.73, + y: -0.043, + z: -0.108, + w: -0.666 + }], + LeftHand: [{ + x: 0.007, + y: 0.151, + z: 0.061 + }, { + x: -0.417, + y: 0.631, + z: -0.389, + w: -0.525 + }] + } + } + }) + } + + var marker = Entities.addEntity(markerProperties); + + }, + createEraser: function() { + _this.setup(); + var ERASER_MODEL_URL = "atp:/whiteboard/eraser-2.fbx"; + + var eraserPosition = Vec3.sum(_this.spawnPosition, Vec3.multiply(Quat.getFront(_this.orientation), -0.1)); + eraserPosition = Vec3.sum(eraserPosition, Vec3.multiply(-0.5, Quat.getRight(_this.orientation))); + var eraserRotation = _this.markerRotation; + + var eraserProps = { + type: "Model", + name: "hifi_model_whiteboardEraser", + modelURL: ERASER_MODEL_URL, + position: eraserPosition, + script: ERASER_SCRIPT_URL, + shapeType: "box", + lifetime: 86400, + dimensions: { + x: 0.0858, + y: 0.0393, + z: 0.2083 + }, + rotation: eraserRotation, + dynamic: true, + gravity: { + x: 0, + y: -10, + z: 0 + }, + velocity: { + x: 0, + y: -0.1, + z: 0 + }, + userData: JSON.stringify({ + 'hifiHomeKey': { + 'reset': true + }, + 'grabbableKey': { + 'grabbable': true + }, + originalPosition: eraserPosition, + originalRotation: eraserRotation, + wearable: { + joints: { + RightHand: [{ + x: 0.020, + y: 0.120, + z: 0.049 + }, { + x: 0.1004, + y: 0.6424, + z: 0.717, + w: 0.250 + }], + LeftHand: [{ + x: -0.005, + y: 0.1101, + z: 0.053 + }, { + x: 0.723, + y: 0.289, + z: 0.142, + w: 0.610 + }] + } + } + }) + } + + var eraser = Entities.addEntity(eraserProps); + } + + } + + + return new Whiteboard(); +}) \ No newline at end of file diff --git a/unpublishedScripts/DomainContent/Home/whiteboard/whiteboardWithSwiper.json b/unpublishedScripts/DomainContent/Home/whiteboard/whiteboardWithSwiper.json new file mode 100644 index 0000000000..9bebb6a492 --- /dev/null +++ b/unpublishedScripts/DomainContent/Home/whiteboard/whiteboardWithSwiper.json @@ -0,0 +1,149 @@ +{ + "Entities": [{ + "clientOnly": 0, + "compoundShapeURL": "atp:/whiteboard/handScannerSwitch_phys.obj", + "created": "2016-06-14T18:08:49Z", + "dimensions": { + "x": 0.11707025021314621, + "y": 0.16469044983386993, + "z": 0.10442595928907394 + }, + "id": "{21d2185f-4161-484d-bb0f-70bdc307700d}", + "modelURL": "atp:/whiteboard/handScannerSwitch_tall_VR.fbx", + "name": "hifi_whiteboardSwiper", + "owningAvatarID": "{00000000-0000-0000-0000-000000000000}", + "parentID": "{7b380903-a6d5-46e8-a4b3-4d58eaaa0419}", + "position": { + "x": -0.86872124671936035, + "y": -0.33092412352561951, + "z": 0.072394371032714844 + }, + "queryAACube": { + "scale": 0.22744926810264587, + "x": 4.9953713417053223, + "y": 0.33575963973999023, + "z": 1.1766284704208374 + }, + "rotation": { + "w": 0.71929502487182617, + "x": -4.57763671875e-05, + "y": -0.69472801685333252, + "z": -1.52587890625e-05 + }, + "script": "atp:/whiteboard/swiper.js", + "shapeType": "compound", + "type": "Model", + "userData": "{\"hifiHomeKey\":{\"reset\":true}}" + }, { + "clientOnly": 0, + "color": { + "blue": 200, + "green": 10, + "red": 200 + }, + "created": "2016-06-14T18:08:49Z", + "dimensions": { + "x": 1.8200000524520874, + "y": 1.7999999523162842, + "z": 0.0099999997764825821 + }, + "id": "{5572abff-1575-48e8-bc79-1d6373046fe9}", + "name": "hifi-whiteboardDrawingSurface", + "owningAvatarID": "{00000000-0000-0000-0000-000000000000}", + "parentID": "{7b380903-a6d5-46e8-a4b3-4d58eaaa0419}", + "position": { + "x": -0.019987192004919052, + "y": 0.45400944352149963, + "z": 0.020008884370326996 + }, + "queryAACube": { + "scale": 2.5597851276397705, + "x": 3.3173346519470215, + "y": -0.045509219169616699, + "z": -0.66857552528381348 + }, + "rotation": { + "w": 1, + "x": -1.52587890625e-05, + "y": -1.52587890625e-05, + "z": -1.52587890625e-05 + }, + "shape": "Cube", + "type": "Box", + "visible": 0, + "userData": "{\"hifiHomeKey\":{\"reset\":true}}" + }, { + "clientOnly": 0, + "color": { + "blue": 200, + "green": 10, + "red": 200 + }, + "created": "2016-06-14T18:08:49Z", + "dimensions": { + "x": 1.8200000524520874, + "y": 1.7999999523162842, + "z": 0.0099999997764825821 + }, + "id": "{22152131-5ac7-4758-a5bc-3dda3f034eb4}", + "name": "hifi-whiteboardDrawingSurface", + "owningAvatarID": "{00000000-0000-0000-0000-000000000000}", + "parentID": "{7b380903-a6d5-46e8-a4b3-4d58eaaa0419}", + "position": { + "x": -0.020041000097990036, + "y": 0.45001220703125, + "z": -0.019985578954219818 + }, + "queryAACube": { + "scale": 2.5597851276397705, + "x": 3.2840065956115723, + "y": -0.049505829811096191, + "z": -0.6464693546295166 + }, + "rotation": { + "w": 1, + "x": -1.52587890625e-05, + "y": -1.52587890625e-05, + "z": -1.52587890625e-05 + }, + "shape": "Cube", + "type": "Box", + "visible": 0, + "userData": "{\"hifiHomeKey\":{\"reset\":true}}" + }, { + "clientOnly": 0, + "compoundShapeURL": "atp:/whiteboard/whiteboardCollisionHull.obj", + "created": "2016-06-14T18:08:49Z", + "dimensions": { + "x": 1.8600000143051147, + "y": 2.7000000476837158, + "z": 0.46360000967979431 + }, + "gravity": { + "x": 0, + "y": -9.8, + "z": 0 + }, + "id": "{7b380903-a6d5-46e8-a4b3-4d58eaaa0419}", + "modelURL": "atp:/whiteboard/Whiteboard-4.fbx", + "name": "hifi_whiteboard", + "owningAvatarID": "{00000000-0000-0000-0000-000000000000}", + "queryAACube": { + "scale": 3.3112723827362061, + "x": -1.655636191368103, + "y": -1.655636191368103, + "z": -1.655636191368103 + }, + "rotation": { + "w": -0.30053186416625977, + "x": -2.1577336156042293e-05, + "y": 0.95376050472259521, + "z": 2.824626790243201e-07 + }, + "script": "atp:/whiteboard/whiteboard.js", + "shapeType": "compound", + "type": "Model", + "userData": "{\"hifiHomeKey\":{\"reset\":true}}" + }], + "Version": 60 +} \ No newline at end of file diff --git a/unpublishedScripts/DomainContent/Home/whiteboard/wrapper.js b/unpublishedScripts/DomainContent/Home/whiteboard/wrapper.js deleted file mode 100644 index 67712c840d..0000000000 --- a/unpublishedScripts/DomainContent/Home/whiteboard/wrapper.js +++ /dev/null @@ -1,282 +0,0 @@ -// -// whiteboardSpawner.js -// examples/homeContent/whiteboardV2 -// -// Created by Eric Levina on 2/17/16 -// Copyright 2016 High Fidelity, Inc. -// -// Run this script to spawn a whiteboard, markers, and an eraser. -// To draw on the whiteboard, equip a marker and hold down trigger with marker tip pointed at whiteboard -// -// Distributed under the Apache License, Version 2.0. -// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html -var ERASER_SCRIPT_URL = Script.resolvePath("eraserEntityScript.js"); - -var MARKER_SCRIPT_URL = Script.resolvePath("markerEntityScript.js"); - -Whiteboard = function(spawnPosition, spawnRotation) { - - var orientation = Quat.fromPitchYawRollDegrees(spawnRotation.x, spawnRotation.y, spawnRotation.z); - var markers = []; - var markerRotation = Quat.fromVec3Degrees({ - x: spawnRotation.x + 10, - y: spawnRotation.y - 90, - z: spawnRotation.z - }); - var whiteboardPosition = spawnPosition; - var whiteboardRotation = orientation; - - var WHITEBOARD_MODEL_URL = "atp:/whiteboard/Whiteboard-6.fbx"; - var WHITEBOARD_COLLISION_HULL_URL = "atp:/whiteboard/whiteboardCollisionHull.obj"; - - var whiteboard = Entities.addEntity({ - type: "Model", - name: "home_model_whiteboard", - modelURL: WHITEBOARD_MODEL_URL, - position: whiteboardPosition, - rotation: whiteboardRotation, - shapeType: 'compound', - compoundShapeURL: WHITEBOARD_COLLISION_HULL_URL, - dimensions: { - x: 1.86, - y: 2.7, - z: 0.4636 - }, - userData: JSON.stringify({ - 'hifiHomeKey': { - 'reset': true - } - }), - }); - - - - var whiteboardSurfacePosition = Vec3.sum(whiteboardPosition, { - x: 0.0, - y: 0.45, - z: 0.0 - }); - whiteboardSurfacePosition = Vec3.sum(whiteboardSurfacePosition, Vec3.multiply(-0.02, Quat.getRight(whiteboardRotation))); - var moveForwardDistance = 0.02; - whiteboardFrontSurfacePosition = Vec3.sum(whiteboardSurfacePosition, Vec3.multiply(-moveForwardDistance, Quat.getFront(whiteboardRotation))); - var WHITEBOARD_SURFACE_NAME = "home_box_whiteboardDrawingSurface"; - var whiteboardSurfaceSettings = { - type: "Box", - name: WHITEBOARD_SURFACE_NAME, - dimensions: { - x: 1.82, - y: 1.8, - z: 0.01 - }, - color: { - red: 200, - green: 10, - blue: 200 - }, - position: whiteboardFrontSurfacePosition, - rotation: whiteboardRotation, - visible: false, - parentID: whiteboard, - userData: JSON.stringify({ - 'hifiHomeKey': { - 'reset': true - } - }), - } - var whiteboardFrontDrawingSurface = Entities.addEntity(whiteboardSurfaceSettings); - - - whiteboardBackSurfacePosition = Vec3.sum(whiteboardSurfacePosition, Vec3.multiply(moveForwardDistance, Quat.getFront(whiteboardRotation))); - whiteboardSurfaceSettings.position = whiteboardBackSurfacePosition; - - var whiteboardBackDrawingSurface = Entities.addEntity(whiteboardSurfaceSettings); - - - var WHITEBOARD_RACK_DEPTH = 1.9; - - - - // ************ ERASER ************************************************ - var ERASER_MODEL_URL = "atp:/whiteboard/eraser-2.fbx"; - - - - var eraserPosition = Vec3.sum(spawnPosition, Vec3.multiply(Quat.getFront(whiteboardRotation), -0.1)); - eraserPosition = Vec3.sum(eraserPosition, Vec3.multiply(-0.5, Quat.getRight(whiteboardRotation))); - var eraserRotation = markerRotation; - - var eraserProps = { - type: "Model", - name: "home_model_whiteboardEraser", - modelURL: ERASER_MODEL_URL, - position: eraserPosition, - script: ERASER_SCRIPT_URL, - shapeType: "box", - dimensions: { - x: 0.0858, - y: 0.0393, - z: 0.2083 - }, - rotation: eraserRotation, - dynamic: true, - gravity: { - x: 0, - y: -10, - z: 0 - }, - velocity: { - x: 0, - y: -0.1, - z: 0 - }, - userData: JSON.stringify({ - 'hifiHomeKey': { - 'reset': true - }, - originalPosition: eraserPosition, - originalRotation: eraserRotation, - wearable: { - joints: { - RightHand: [{ - x: 0.020, - y: 0.120, - z: 0.049 - }, { - x: 0.1004, - y: 0.6424, - z: 0.717, - w: 0.250 - }], - LeftHand: [{ - x: -0.005, - y: 0.1101, - z: 0.053 - }, { - x: 0.723, - y: 0.289, - z: 0.142, - w: 0.610 - }] - } - } - }) - } - - - // ************************************************************************************************* - - function createMarkers() { - var modelURLS = [ - "atp:/whiteboard/marker-blue.fbx", - "atp:/whiteboard/marker-red.fbx", - "atp:/whiteboard/marker-black.fbx", - ]; - - - var markerPosition = Vec3.sum(spawnPosition, Vec3.multiply(Quat.getFront(whiteboardRotation), -0.1)); - - createMarker(modelURLS[0], markerPosition, { - red: 10, - green: 10, - blue: 200 - }); - - markerPosition = Vec3.sum(markerPosition, Vec3.multiply(-0.2, Quat.getFront(markerRotation))); - createMarker(modelURLS[1], markerPosition, { - red: 200, - green: 10, - blue: 10 - }); - - markerPosition = Vec3.sum(markerPosition, Vec3.multiply(0.4, Quat.getFront(markerRotation))); - createMarker(modelURLS[2], markerPosition, { - red: 10, - green: 10, - blue: 10 - }); - } - - - function createMarker(modelURL, markerPosition, markerColor) { - var marker = Entities.addEntity({ - type: "Model", - modelURL: modelURL, - rotation: markerRotation, - shapeType: "box", - name: "home_model_marker", - dynamic: true, - gravity: { - x: 0, - y: -5, - z: 0 - }, - velocity: { - x: 0, - y: -0.1, - z: 0 - }, - position: markerPosition, - dimensions: { - x: 0.027, - y: 0.027, - z: 0.164 - }, - script: MARKER_SCRIPT_URL, - userData: JSON.stringify({ - 'hifiHomeKey': { - 'reset': true - }, - originalPosition: markerPosition, - originalRotation: markerRotation, - markerColor: markerColor, - wearable: { - joints: { - RightHand: [{ - x: 0.001, - y: 0.139, - z: 0.050 - }, { - x: -0.73, - y: -0.043, - z: -0.108, - w: -0.666 - }], - LeftHand: [{ - x: 0.007, - y: 0.151, - z: 0.061 - }, { - x: -0.417, - y: 0.631, - z: -0.389, - w: -0.525 - }] - } - } - }) - }); - - markers.push(marker); - - } - var eraser; - Script.setTimeout(function() { - eraser = Entities.addEntity(eraserProps); - createMarkers(); - }, 1500) - - function cleanup() { - print('WHITEBOARD CLEANUP') - Entities.deleteEntity(whiteboard); - Entities.deleteEntity(whiteboardFrontDrawingSurface); - Entities.deleteEntity(whiteboardBackDrawingSurface); - Entities.deleteEntity(eraser); - markers.forEach(function(marker) { - Entities.deleteEntity(marker); - }); - } - - this.cleanup = cleanup; - - print('CREATED WHITEBOARD') -} \ No newline at end of file