From bfc619497e735861ccd9ae4f956a51df2cb6becd Mon Sep 17 00:00:00 2001 From: ericrius1 Date: Wed, 17 Feb 2016 13:33:19 -0800 Subject: [PATCH 01/58] spawning model --- .../whiteboardV2/whiteboardSpawner.js | 32 +++++++++++++++++++ 1 file changed, 32 insertions(+) create mode 100644 examples/homeContent/whiteboardV2/whiteboardSpawner.js diff --git a/examples/homeContent/whiteboardV2/whiteboardSpawner.js b/examples/homeContent/whiteboardV2/whiteboardSpawner.js new file mode 100644 index 0000000000..76992062dc --- /dev/null +++ b/examples/homeContent/whiteboardV2/whiteboardSpawner.js @@ -0,0 +1,32 @@ +// +// 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 and associated acoutrements that one can paint on usignmarkers +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html + + +var orientation = Camera.getOrientation(); +orientation = Quat.safeEulerAngles(orientation); +orientation.x = 0; +orientation = Quat.fromVec3Degrees(orientation); +var center = Vec3.sum(MyAvatar.position, Vec3.multiply(2, Quat.getFront(orientation))); + +var WHITEBOARD_MODEL_URL = "http://hifi-content.s3.amazonaws.com/alan/dev/Whiteboard-3.fbx"; +var whiteboard = Entities.addEntity({ + type: "Model", + modelURL: WHITEBOARD_MODEL_URL, + position: center +}); + + +function cleanup() { + Entities.deleteEntity(whiteboard); +} + +Script.scriptEnding.connect(cleanup); \ No newline at end of file From bb2fd0072c1533881780ec7c2cf3688e7b1ef882 Mon Sep 17 00:00:00 2001 From: ericrius1 Date: Wed, 17 Feb 2016 13:41:58 -0800 Subject: [PATCH 02/58] collision hull --- examples/homeContent/whiteboardV2/whiteboardSpawner.js | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/examples/homeContent/whiteboardV2/whiteboardSpawner.js b/examples/homeContent/whiteboardV2/whiteboardSpawner.js index 76992062dc..7cdbef5a7a 100644 --- a/examples/homeContent/whiteboardV2/whiteboardSpawner.js +++ b/examples/homeContent/whiteboardV2/whiteboardSpawner.js @@ -17,11 +17,16 @@ orientation.x = 0; orientation = Quat.fromVec3Degrees(orientation); var center = Vec3.sum(MyAvatar.position, Vec3.multiply(2, Quat.getFront(orientation))); + var WHITEBOARD_MODEL_URL = "http://hifi-content.s3.amazonaws.com/alan/dev/Whiteboard-3.fbx"; +var WHITEBOARD_COLLISION_HULL_URL = "http://hifi-content.s3.amazonaws.com/alan/dev/Whiteboard.obj"; var whiteboard = Entities.addEntity({ type: "Model", modelURL: WHITEBOARD_MODEL_URL, - position: center + position: center, + shapeType: 'compound', + compoundShapeURL: WHITEBOARD_COLLISION_HULL_URL, + dimensions: { x: 0.4636, y: 2.7034, z: 1.8653} }); From 9e8d123b1664a6a189859eaeef9c31fe957f2451 Mon Sep 17 00:00:00 2001 From: ericrius1 Date: Wed, 17 Feb 2016 13:58:04 -0800 Subject: [PATCH 03/58] spawning marker and whiteboard correctly --- .../whiteboardV2/whiteboardSpawner.js | 21 +++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/examples/homeContent/whiteboardV2/whiteboardSpawner.js b/examples/homeContent/whiteboardV2/whiteboardSpawner.js index 7cdbef5a7a..c101d3df9a 100644 --- a/examples/homeContent/whiteboardV2/whiteboardSpawner.js +++ b/examples/homeContent/whiteboardV2/whiteboardSpawner.js @@ -14,24 +14,41 @@ var orientation = Camera.getOrientation(); orientation = Quat.safeEulerAngles(orientation); orientation.x = 0; +var whiteboardRotation = Quat.fromVec3Degrees({x: orientation.x, y: orientation.y - 90, z: orientation.z}); orientation = Quat.fromVec3Degrees(orientation); -var center = Vec3.sum(MyAvatar.position, Vec3.multiply(2, Quat.getFront(orientation))); +var whiteboardPosition = Vec3.sum(MyAvatar.position, Vec3.multiply(2, Quat.getFront(orientation))); var WHITEBOARD_MODEL_URL = "http://hifi-content.s3.amazonaws.com/alan/dev/Whiteboard-3.fbx"; var WHITEBOARD_COLLISION_HULL_URL = "http://hifi-content.s3.amazonaws.com/alan/dev/Whiteboard.obj"; var whiteboard = Entities.addEntity({ type: "Model", modelURL: WHITEBOARD_MODEL_URL, - position: center, + position: whiteboardPosition, + rotation: whiteboardRotation, shapeType: 'compound', compoundShapeURL: WHITEBOARD_COLLISION_HULL_URL, dimensions: { x: 0.4636, y: 2.7034, z: 1.8653} }); +var markerPosition = Vec3.sum(MyAvatar.position, Vec3.multiply(1.9, Quat.getFront(orientation))); +var MARKER_MODEL_URL = "http://hifi-content.s3.amazonaws.com/alan/dev/marker-blue.fbx"; +var marker = Entities.addEntity({ + type: "Model", + modelURL: MARKER_MODEL_URL, + shapeType: "box", + dynamic: true, + gravity: {x: 0, y: -1, z: 0}, + rotation: whiteboardRotation, + velocity: {x: 0, y: -0.1, z: 0}, + position: markerPosition, + dimensions: {x: 0.0270, y: 0.0272, z: 0.1641} +}); + function cleanup() { Entities.deleteEntity(whiteboard); + Entities.deleteEntity(marker); } Script.scriptEnding.connect(cleanup); \ No newline at end of file From 073661b78de92f751e3160a3d03e0caa6aa7a46c Mon Sep 17 00:00:00 2001 From: ericrius1 Date: Wed, 17 Feb 2016 14:25:21 -0800 Subject: [PATCH 04/58] markers in right spot --- .../whiteboardV2/whiteboardSpawner.js | 56 +++++++++++++++++-- 1 file changed, 51 insertions(+), 5 deletions(-) diff --git a/examples/homeContent/whiteboardV2/whiteboardSpawner.js b/examples/homeContent/whiteboardV2/whiteboardSpawner.js index c101d3df9a..a8796f56fb 100644 --- a/examples/homeContent/whiteboardV2/whiteboardSpawner.js +++ b/examples/homeContent/whiteboardV2/whiteboardSpawner.js @@ -14,7 +14,11 @@ var orientation = Camera.getOrientation(); orientation = Quat.safeEulerAngles(orientation); orientation.x = 0; -var whiteboardRotation = Quat.fromVec3Degrees({x: orientation.x, y: orientation.y - 90, z: orientation.z}); +var whiteboardRotation = Quat.fromVec3Degrees({ + x: orientation.x, + y: orientation.y - 90, + z: orientation.z +}); orientation = Quat.fromVec3Degrees(orientation); @@ -28,7 +32,11 @@ var whiteboard = Entities.addEntity({ rotation: whiteboardRotation, shapeType: 'compound', compoundShapeURL: WHITEBOARD_COLLISION_HULL_URL, - dimensions: { x: 0.4636, y: 2.7034, z: 1.8653} + dimensions: { + x: 0.4636, + y: 2.7034, + z: 1.8653 + } }); var markerPosition = Vec3.sum(MyAvatar.position, Vec3.multiply(1.9, Quat.getFront(orientation))); @@ -38,11 +46,49 @@ var marker = Entities.addEntity({ modelURL: MARKER_MODEL_URL, shapeType: "box", dynamic: true, - gravity: {x: 0, y: -1, z: 0}, + gravity: { + x: 0, + y: -1, + z: 0 + }, rotation: whiteboardRotation, - velocity: {x: 0, y: -0.1, z: 0}, + velocity: { + x: 0, + y: -0.1, + z: 0 + }, position: markerPosition, - dimensions: {x: 0.0270, y: 0.0272, z: 0.1641} + dimensions: { + x: 0.0270, + y: 0.0272, + z: 0.1641 + }, + userData: JSON.stringify({ + wearable: { + joints: { + RightHand: [{ + "x": 0.03257002681493759, + "y": 0.15036098659038544, + "z": 0.051217660307884216 + }, { + "x": -0.5274277329444885, + "y": -0.23446641862392426, + "z": -0.05400913953781128, + "w": 0.8148180246353149 + }], + LeftHand: [{ + "x": -0.031699854880571365, + "y": 0.15150733292102814, + "z": 0.041107177734375 + }, { + "x": 0.649201512336731, + "y": 0.1007731482386589, + "z": 0.3215889632701874, + "w": -0.6818817853927612 + }] + } + } + }) }); From df84a166e483439d842ded12065b4e690c7eda43 Mon Sep 17 00:00:00 2001 From: ericrius1 Date: Wed, 17 Feb 2016 15:08:42 -0800 Subject: [PATCH 05/58] spawning marker tips- parenting to markers --- .../homeContent/whiteboardV2/whiteboardSpawner.js | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/examples/homeContent/whiteboardV2/whiteboardSpawner.js b/examples/homeContent/whiteboardV2/whiteboardSpawner.js index a8796f56fb..4a1a89c250 100644 --- a/examples/homeContent/whiteboardV2/whiteboardSpawner.js +++ b/examples/homeContent/whiteboardV2/whiteboardSpawner.js @@ -51,7 +51,7 @@ var marker = Entities.addEntity({ y: -1, z: 0 }, - rotation: whiteboardRotation, + // rotation: whiteboardRotation, velocity: { x: 0, y: -0.1, @@ -91,10 +91,20 @@ var marker = Entities.addEntity({ }) }); +var markerTip = Entities.addEntity({ + type: "Box", + dimensions: {x: 0.05, y: 0.05, z: 0.05}, + position: Vec3.sum(markerPosition, {x: 0.0, y: 0.001, z: 0.1}), + parentID: marker, + color: {red: 200, green: 10, blue: 200}, + collisionless: true +}) + function cleanup() { Entities.deleteEntity(whiteboard); Entities.deleteEntity(marker); + Entities.deleteEntity(markerTip); } Script.scriptEnding.connect(cleanup); \ No newline at end of file From 7f23ee04be9995f11b55731c48103ddcada0315b Mon Sep 17 00:00:00 2001 From: ericrius1 Date: Wed, 17 Feb 2016 17:16:43 -0800 Subject: [PATCH 06/58] basic marker entity script --- .../whiteboardV2/markerEntityScript.js | 35 +++++++++++++++++++ .../whiteboardV2/whiteboardSpawner.js | 12 ++----- 2 files changed, 37 insertions(+), 10 deletions(-) create mode 100644 examples/homeContent/whiteboardV2/markerEntityScript.js diff --git a/examples/homeContent/whiteboardV2/markerEntityScript.js b/examples/homeContent/whiteboardV2/markerEntityScript.js new file mode 100644 index 0000000000..43a7ec1788 --- /dev/null +++ b/examples/homeContent/whiteboardV2/markerEntityScript.js @@ -0,0 +1,35 @@ +// +// markerTipEntityScript.js +// examples/homeContent/markerTipEntityScript +// +// Created by Eric Levin on 2/17/15. +// 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() { + Script.include("../../libraries/utils.js"); + + MarkerTip = function() { + _this = this; + }; + + MarkerTip.prototype = { + + continueNearGrab: function() { + print("EBL Conintue ") + }, + + preload: function(entityID) { + this.entityID = entityID; + + } + }; + + // entity scripts always need to return a newly constructed object of our type + return new MarkerTip(); +}); diff --git a/examples/homeContent/whiteboardV2/whiteboardSpawner.js b/examples/homeContent/whiteboardV2/whiteboardSpawner.js index 4a1a89c250..a699bcafa2 100644 --- a/examples/homeContent/whiteboardV2/whiteboardSpawner.js +++ b/examples/homeContent/whiteboardV2/whiteboardSpawner.js @@ -41,6 +41,7 @@ var whiteboard = Entities.addEntity({ var markerPosition = Vec3.sum(MyAvatar.position, Vec3.multiply(1.9, Quat.getFront(orientation))); var MARKER_MODEL_URL = "http://hifi-content.s3.amazonaws.com/alan/dev/marker-blue.fbx"; +var MARKER_SCRIPT_URL = Script.resolvePath("markerEntityScript.js?v1" + Math.random()); var marker = Entities.addEntity({ type: "Model", modelURL: MARKER_MODEL_URL, @@ -51,7 +52,6 @@ var marker = Entities.addEntity({ y: -1, z: 0 }, - // rotation: whiteboardRotation, velocity: { x: 0, y: -0.1, @@ -63,6 +63,7 @@ var marker = Entities.addEntity({ y: 0.0272, z: 0.1641 }, + script: MARKER_SCRIPT_URL, userData: JSON.stringify({ wearable: { joints: { @@ -91,20 +92,11 @@ var marker = Entities.addEntity({ }) }); -var markerTip = Entities.addEntity({ - type: "Box", - dimensions: {x: 0.05, y: 0.05, z: 0.05}, - position: Vec3.sum(markerPosition, {x: 0.0, y: 0.001, z: 0.1}), - parentID: marker, - color: {red: 200, green: 10, blue: 200}, - collisionless: true -}) function cleanup() { Entities.deleteEntity(whiteboard); Entities.deleteEntity(marker); - Entities.deleteEntity(markerTip); } Script.scriptEnding.connect(cleanup); \ No newline at end of file From 728e8c763d43033f4d788821fc8fe57cc959173a Mon Sep 17 00:00:00 2001 From: ericrius1 Date: Wed, 17 Feb 2016 17:30:01 -0800 Subject: [PATCH 07/58] ray cast --- .../whiteboardV2/markerEntityScript.js | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/examples/homeContent/whiteboardV2/markerEntityScript.js b/examples/homeContent/whiteboardV2/markerEntityScript.js index 43a7ec1788..ef6f6b005d 100644 --- a/examples/homeContent/whiteboardV2/markerEntityScript.js +++ b/examples/homeContent/whiteboardV2/markerEntityScript.js @@ -21,12 +21,25 @@ MarkerTip.prototype = { continueNearGrab: function() { - print("EBL Conintue ") + + // cast a ray from marker and see if it hits anything + + var props = Entities.getEntityProperties(_this.entityID, ["position", "rotation"]); + + var pickRay = { + origin: props.position, + direction: Quat.getFront(props.rotation) + } + + var intersection = Entities.findRayIntersection(pickRay, true); + + if (intersection.intersects) { + print("INTERSECTION!") + } }, preload: function(entityID) { this.entityID = entityID; - } }; From 39d4fbf19dba163eda9b7bcd3e685cab55ff4e50 Mon Sep 17 00:00:00 2001 From: ericrius1 Date: Thu, 18 Feb 2016 15:23:32 -0800 Subject: [PATCH 08/58] refactoring --- .../whiteboardV2/markerEntityScript.js | 17 +++++++---- .../whiteboardV2/whiteboardSpawner.js | 30 ++----------------- 2 files changed, 14 insertions(+), 33 deletions(-) diff --git a/examples/homeContent/whiteboardV2/markerEntityScript.js b/examples/homeContent/whiteboardV2/markerEntityScript.js index ef6f6b005d..3ed89e82c1 100644 --- a/examples/homeContent/whiteboardV2/markerEntityScript.js +++ b/examples/homeContent/whiteboardV2/markerEntityScript.js @@ -13,7 +13,7 @@ (function() { Script.include("../../libraries/utils.js"); - + MarkerTip = function() { _this = this; }; @@ -22,22 +22,29 @@ continueNearGrab: function() { + _this.continueHolding(); + }, + + continueEquip: function() { + _this.continueHolding(); + }, + + continueHolding: function() { // cast a ray from marker and see if it hits anything var props = Entities.getEntityProperties(_this.entityID, ["position", "rotation"]); var pickRay = { - origin: props.position, + origin: props.position, direction: Quat.getFront(props.rotation) } var intersection = Entities.findRayIntersection(pickRay, true); if (intersection.intersects) { - print("INTERSECTION!") } }, - + preload: function(entityID) { this.entityID = entityID; } @@ -45,4 +52,4 @@ // 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/examples/homeContent/whiteboardV2/whiteboardSpawner.js b/examples/homeContent/whiteboardV2/whiteboardSpawner.js index a699bcafa2..535c817121 100644 --- a/examples/homeContent/whiteboardV2/whiteboardSpawner.js +++ b/examples/homeContent/whiteboardV2/whiteboardSpawner.js @@ -40,7 +40,7 @@ var whiteboard = Entities.addEntity({ }); var markerPosition = Vec3.sum(MyAvatar.position, Vec3.multiply(1.9, Quat.getFront(orientation))); -var MARKER_MODEL_URL = "http://hifi-content.s3.amazonaws.com/alan/dev/marker-blue.fbx"; +var MARKER_MODEL_URL = "https://s3-us-west-1.amazonaws.com/hifi-content/eric/models/marker-blue.fbx"; var MARKER_SCRIPT_URL = Script.resolvePath("markerEntityScript.js?v1" + Math.random()); var marker = Entities.addEntity({ type: "Model", @@ -63,33 +63,7 @@ var marker = Entities.addEntity({ y: 0.0272, z: 0.1641 }, - script: MARKER_SCRIPT_URL, - userData: JSON.stringify({ - wearable: { - joints: { - RightHand: [{ - "x": 0.03257002681493759, - "y": 0.15036098659038544, - "z": 0.051217660307884216 - }, { - "x": -0.5274277329444885, - "y": -0.23446641862392426, - "z": -0.05400913953781128, - "w": 0.8148180246353149 - }], - LeftHand: [{ - "x": -0.031699854880571365, - "y": 0.15150733292102814, - "z": 0.041107177734375 - }, { - "x": 0.649201512336731, - "y": 0.1007731482386589, - "z": 0.3215889632701874, - "w": -0.6818817853927612 - }] - } - } - }) + script: MARKER_SCRIPT_URL }); From f4ee9acb9c0ea5eca8271fc0cf9d69a913cd272a Mon Sep 17 00:00:00 2001 From: ericrius1 Date: Fri, 19 Feb 2016 09:49:22 -0800 Subject: [PATCH 09/58] intersecting --- examples/homeContent/whiteboardV2/markerEntityScript.js | 5 ++++- examples/homeContent/whiteboardV2/whiteboardSpawner.js | 2 ++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/examples/homeContent/whiteboardV2/markerEntityScript.js b/examples/homeContent/whiteboardV2/markerEntityScript.js index 3ed89e82c1..4faf64b542 100644 --- a/examples/homeContent/whiteboardV2/markerEntityScript.js +++ b/examples/homeContent/whiteboardV2/markerEntityScript.js @@ -39,14 +39,17 @@ direction: Quat.getFront(props.rotation) } - var intersection = Entities.findRayIntersection(pickRay, true); + var intersection = Entities.findRayIntersection(pickRay, true, [], [_this.entityID]); if (intersection.intersects) { + var name = Entities.getEntityProperties(intersection.entityID); + print("intersection") } }, preload: function(entityID) { this.entityID = entityID; + print("EBL PRELOAD"); } }; diff --git a/examples/homeContent/whiteboardV2/whiteboardSpawner.js b/examples/homeContent/whiteboardV2/whiteboardSpawner.js index 535c817121..68c4422364 100644 --- a/examples/homeContent/whiteboardV2/whiteboardSpawner.js +++ b/examples/homeContent/whiteboardV2/whiteboardSpawner.js @@ -27,6 +27,7 @@ var WHITEBOARD_MODEL_URL = "http://hifi-content.s3.amazonaws.com/alan/dev/Whiteb var WHITEBOARD_COLLISION_HULL_URL = "http://hifi-content.s3.amazonaws.com/alan/dev/Whiteboard.obj"; var whiteboard = Entities.addEntity({ type: "Model", + name: "whiteboard", modelURL: WHITEBOARD_MODEL_URL, position: whiteboardPosition, rotation: whiteboardRotation, @@ -63,6 +64,7 @@ var marker = Entities.addEntity({ y: 0.0272, z: 0.1641 }, + name: "marker", script: MARKER_SCRIPT_URL }); From 6765973a4a98d2b4b310c52cbb4c538bcabe7af7 Mon Sep 17 00:00:00 2001 From: ericrius1 Date: Fri, 19 Feb 2016 09:56:30 -0800 Subject: [PATCH 10/58] correct positioning on equip --- .../whiteboardV2/markerEntityScript.js | 3 +- .../whiteboardV2/whiteboardSpawner.js | 28 ++++++++++++++++++- 2 files changed, 28 insertions(+), 3 deletions(-) diff --git a/examples/homeContent/whiteboardV2/markerEntityScript.js b/examples/homeContent/whiteboardV2/markerEntityScript.js index 4faf64b542..47a308d564 100644 --- a/examples/homeContent/whiteboardV2/markerEntityScript.js +++ b/examples/homeContent/whiteboardV2/markerEntityScript.js @@ -39,11 +39,10 @@ direction: Quat.getFront(props.rotation) } - var intersection = Entities.findRayIntersection(pickRay, true, [], [_this.entityID]); + var intersection = Entities.findRayIntersection(pickRay, true); if (intersection.intersects) { var name = Entities.getEntityProperties(intersection.entityID); - print("intersection") } }, diff --git a/examples/homeContent/whiteboardV2/whiteboardSpawner.js b/examples/homeContent/whiteboardV2/whiteboardSpawner.js index 68c4422364..fdecb01f21 100644 --- a/examples/homeContent/whiteboardV2/whiteboardSpawner.js +++ b/examples/homeContent/whiteboardV2/whiteboardSpawner.js @@ -65,7 +65,33 @@ var marker = Entities.addEntity({ z: 0.1641 }, name: "marker", - script: MARKER_SCRIPT_URL + script: MARKER_SCRIPT_URL, + userData: JSON.stringify({ + wearable: { + joints: { + RightHand: [{ + x: 0.001109793782234192, + y: 0.13991504907608032, + z: 0.05035984516143799 + }, { + x: -0.7360993027687073, + y: -0.04330085217952728, + z: -0.10863728821277618, + w: -0.6666942238807678 + }], + LeftHand: [{ + x: 0.007193896919488907, + y: 0.15147076547145844, + z: 0.06174466013908386 + }, { + x: -0.4174973964691162, + y: 0.631147563457489, + z: -0.3890438377857208, + w: -0.52535080909729 + }] + } + } + }) }); From 8e9cd3ae2a62f2f414183f32ccbb4e6c5d10e62b Mon Sep 17 00:00:00 2001 From: ericrius1 Date: Fri, 19 Feb 2016 10:38:13 -0800 Subject: [PATCH 11/58] passing whiteboard in to marker --- examples/homeContent/whiteboardV2/markerEntityScript.js | 8 ++++++++ examples/homeContent/whiteboardV2/whiteboardSpawner.js | 4 ++++ 2 files changed, 12 insertions(+) diff --git a/examples/homeContent/whiteboardV2/markerEntityScript.js b/examples/homeContent/whiteboardV2/markerEntityScript.js index 47a308d564..d3a4f97fe9 100644 --- a/examples/homeContent/whiteboardV2/markerEntityScript.js +++ b/examples/homeContent/whiteboardV2/markerEntityScript.js @@ -43,12 +43,20 @@ if (intersection.intersects) { var name = Entities.getEntityProperties(intersection.entityID); + + this.paint() } }, preload: function(entityID) { this.entityID = entityID; print("EBL PRELOAD"); + }, + + setWhiteboard: function(myId, data) { + _this.whiteboard = JSON.parse(data[0]); + var props = Entities.getEntityProperties(_this.whiteboard, ["rotation"]); + Entities.editEntity(_this.whiteboard, {position: {x: 0, y: 1, z: 0}}); } }; diff --git a/examples/homeContent/whiteboardV2/whiteboardSpawner.js b/examples/homeContent/whiteboardV2/whiteboardSpawner.js index fdecb01f21..b5d1c07959 100644 --- a/examples/homeContent/whiteboardV2/whiteboardSpawner.js +++ b/examples/homeContent/whiteboardV2/whiteboardSpawner.js @@ -94,6 +94,10 @@ var marker = Entities.addEntity({ }) }); +Script.setTimeout(function() { + Entities.callEntityMethod(marker, "setWhiteboard", [JSON.stringify(whiteboard)]); +}, 1000) + function cleanup() { From ddce8d5a3a8a63a95774a9404ed8edbc014029da Mon Sep 17 00:00:00 2001 From: ericrius1 Date: Fri, 19 Feb 2016 10:59:05 -0800 Subject: [PATCH 12/58] Marker basics working, now just need to tweak --- .../whiteboardV2/markerEntityScript.js | 43 +++++++++++++++++-- 1 file changed, 40 insertions(+), 3 deletions(-) diff --git a/examples/homeContent/whiteboardV2/markerEntityScript.js b/examples/homeContent/whiteboardV2/markerEntityScript.js index d3a4f97fe9..e879b71144 100644 --- a/examples/homeContent/whiteboardV2/markerEntityScript.js +++ b/examples/homeContent/whiteboardV2/markerEntityScript.js @@ -16,6 +16,7 @@ MarkerTip = function() { _this = this; + _this.MARKER_TEXTURE_URL = "https://s3-us-west-1.amazonaws.com/hifi-content/eric/textures/paintStroke.png"; }; MarkerTip.prototype = { @@ -42,12 +43,48 @@ var intersection = Entities.findRayIntersection(pickRay, true); if (intersection.intersects) { - var name = Entities.getEntityProperties(intersection.entityID); - this.paint() + this.paint(intersection.intersection) } }, + newStroke: function(position) { + _this.strokeBasePosition = position; + _this.currentStroke = Entities.addEntity({ + type: "PolyLine", + name: "marker stroke", + dimensions: { + x: 10, + y: 10, + z: 10 + }, + position: position, + textures: _this.MARKER_TEXTURE_URL, + color: {red: 0, green: 10, blue: 200} + }); + + _this.linePoints = []; + _this.normals = []; + _this.strokeWidths = []; + }, + + paint: function(position) { + if (!_this.currentStroke) { + _this.newStroke(position); + } + + var localPoint = Vec3.subtract(position, this.strokeBasePosition); + _this.linePoints.push(localPoint); + _this.normals.push(_this._whiteboardNormal); + this.strokeWidths.push(0.02); + + Entities.editEntity(_this.currentStroke, { + linePoints: _this.linePoints, + normals: _this.normals, + strokeWidths: _this.strokeWidths + }); + }, + preload: function(entityID) { this.entityID = entityID; print("EBL PRELOAD"); @@ -56,7 +93,7 @@ setWhiteboard: function(myId, data) { _this.whiteboard = JSON.parse(data[0]); var props = Entities.getEntityProperties(_this.whiteboard, ["rotation"]); - Entities.editEntity(_this.whiteboard, {position: {x: 0, y: 1, z: 0}}); + this._whiteboardNormal = Vec3.multiply(Quat.getFront(props.rotation), -1); } }; From b58026bf4bf83ab071b61558887090dcc9f32f75 Mon Sep 17 00:00:00 2001 From: ericrius1 Date: Fri, 19 Feb 2016 11:04:17 -0800 Subject: [PATCH 13/58] max points --- .../homeContent/whiteboardV2/markerEntityScript.js | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/examples/homeContent/whiteboardV2/markerEntityScript.js b/examples/homeContent/whiteboardV2/markerEntityScript.js index e879b71144..81e65cacb9 100644 --- a/examples/homeContent/whiteboardV2/markerEntityScript.js +++ b/examples/homeContent/whiteboardV2/markerEntityScript.js @@ -14,6 +14,8 @@ (function() { Script.include("../../libraries/utils.js"); + var MAX_POINTS_PER_STROKE = 40; + MarkerTip = function() { _this = this; _this.MARKER_TEXTURE_URL = "https://s3-us-west-1.amazonaws.com/hifi-content/eric/textures/paintStroke.png"; @@ -40,7 +42,7 @@ direction: Quat.getFront(props.rotation) } - var intersection = Entities.findRayIntersection(pickRay, true); + var intersection = Entities.findRayIntersection(pickRay, true, [_this.whiteboard]); if (intersection.intersects) { @@ -83,6 +85,10 @@ normals: _this.normals, strokeWidths: _this.strokeWidths }); + + if (_this.linePoints.length > MAX_POINTS_PER_STROKE) { + _this.currentStroke = null; + } }, preload: function(entityID) { @@ -93,7 +99,7 @@ setWhiteboard: function(myId, data) { _this.whiteboard = JSON.parse(data[0]); var props = Entities.getEntityProperties(_this.whiteboard, ["rotation"]); - this._whiteboardNormal = Vec3.multiply(Quat.getFront(props.rotation), -1); + this._whiteboardNormal = Vec3.multiply(Quat.getRight(props.rotation), -1); } }; From 94bf15f3284e8a5c13fb466556474c2b3cf7c09a Mon Sep 17 00:00:00 2001 From: ericrius1 Date: Fri, 19 Feb 2016 11:21:17 -0800 Subject: [PATCH 14/58] need to fix zfighting --- .../homeContent/whiteboardV2/markerEntityScript.js | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/examples/homeContent/whiteboardV2/markerEntityScript.js b/examples/homeContent/whiteboardV2/markerEntityScript.js index 81e65cacb9..73e8ce86db 100644 --- a/examples/homeContent/whiteboardV2/markerEntityScript.js +++ b/examples/homeContent/whiteboardV2/markerEntityScript.js @@ -18,7 +18,9 @@ MarkerTip = function() { _this = this; - _this.MARKER_TEXTURE_URL = "https://s3-us-west-1.amazonaws.com/hifi-content/eric/textures/paintStroke.png"; + _this.MARKER_TEXTURE_URL = "https://s3-us-west-1.amazonaws.com/hifi-content/eric/textures/markerStroke.png"; + this.strokeForwardOffset = 0.0005; + this.STROKE_FORWARD_OFFSET_INCRERMENT = 0.00001; }; MarkerTip.prototype = { @@ -76,8 +78,11 @@ } var localPoint = Vec3.subtract(position, this.strokeBasePosition); + // localPoint = Vec3.sum(localPoint, Vec3.multiply(_this.whiteboardNormal, _this.strokeForwardOffset)); + _this.strokeForwardOffset += _this.STROKE_FORWARD_OFFSET_INCRERMENT; + _this.linePoints.push(localPoint); - _this.normals.push(_this._whiteboardNormal); + _this.normals.push(_this.whiteboardNormal); this.strokeWidths.push(0.02); Entities.editEntity(_this.currentStroke, { @@ -99,7 +104,7 @@ setWhiteboard: function(myId, data) { _this.whiteboard = JSON.parse(data[0]); var props = Entities.getEntityProperties(_this.whiteboard, ["rotation"]); - this._whiteboardNormal = Vec3.multiply(Quat.getRight(props.rotation), -1); + _this.whiteboardNormal = Vec3.multiply(Quat.getRight(props.rotation), -1); } }; From 9a8b76df476547c4b4cf51e9ee5d371a226d701a Mon Sep 17 00:00:00 2001 From: ericrius1 Date: Fri, 19 Feb 2016 11:32:13 -0800 Subject: [PATCH 15/58] no more zfighting --- examples/homeContent/whiteboardV2/markerEntityScript.js | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/examples/homeContent/whiteboardV2/markerEntityScript.js b/examples/homeContent/whiteboardV2/markerEntityScript.js index 73e8ce86db..a2ab8ac285 100644 --- a/examples/homeContent/whiteboardV2/markerEntityScript.js +++ b/examples/homeContent/whiteboardV2/markerEntityScript.js @@ -21,6 +21,7 @@ _this.MARKER_TEXTURE_URL = "https://s3-us-west-1.amazonaws.com/hifi-content/eric/textures/markerStroke.png"; this.strokeForwardOffset = 0.0005; this.STROKE_FORWARD_OFFSET_INCRERMENT = 0.00001; + this.STROKE_WIDTH = 0.003; }; MarkerTip.prototype = { @@ -78,12 +79,12 @@ } var localPoint = Vec3.subtract(position, this.strokeBasePosition); - // localPoint = Vec3.sum(localPoint, Vec3.multiply(_this.whiteboardNormal, _this.strokeForwardOffset)); - _this.strokeForwardOffset += _this.STROKE_FORWARD_OFFSET_INCRERMENT; + localPoint = Vec3.sum(localPoint, Vec3.multiply(_this.whiteboardNormal, _this.strokeForwardOffset)); + // _this.strokeForwardOffset += _this.STROKE_FORWARD_OFFSET_INCRERMENT; _this.linePoints.push(localPoint); _this.normals.push(_this.whiteboardNormal); - this.strokeWidths.push(0.02); + this.strokeWidths.push(_this.STROKE_WIDTH); Entities.editEntity(_this.currentStroke, { linePoints: _this.linePoints, @@ -104,7 +105,7 @@ setWhiteboard: function(myId, data) { _this.whiteboard = JSON.parse(data[0]); var props = Entities.getEntityProperties(_this.whiteboard, ["rotation"]); - _this.whiteboardNormal = Vec3.multiply(Quat.getRight(props.rotation), -1); + _this.whiteboardNormal = Quat.getRight(props.rotation); } }; From 0564cd8145848d0f24f85277b03f75c4bdf53976 Mon Sep 17 00:00:00 2001 From: ericrius1 Date: Fri, 19 Feb 2016 12:02:34 -0800 Subject: [PATCH 16/58] returning if less than min distance --- .../whiteboardV2/markerEntityScript.js | 34 ++++++++++++++----- 1 file changed, 26 insertions(+), 8 deletions(-) diff --git a/examples/homeContent/whiteboardV2/markerEntityScript.js b/examples/homeContent/whiteboardV2/markerEntityScript.js index a2ab8ac285..d4bd7bc272 100644 --- a/examples/homeContent/whiteboardV2/markerEntityScript.js +++ b/examples/homeContent/whiteboardV2/markerEntityScript.js @@ -21,7 +21,11 @@ _this.MARKER_TEXTURE_URL = "https://s3-us-west-1.amazonaws.com/hifi-content/eric/textures/markerStroke.png"; this.strokeForwardOffset = 0.0005; this.STROKE_FORWARD_OFFSET_INCRERMENT = 0.00001; - this.STROKE_WIDTH = 0.003; + this.STROKE_WIDTH = 0.003 + _this.MAX_MARKER_TO_BOARD_DISTANCE = 0.5; + _this.MIN_DISTANCE_BETWEEN_POINTS = 0.002; + _this.MAX_DISTANCE_BETWEEN_POINTS = 0.1; + _this.strokes = []; }; MarkerTip.prototype = { @@ -38,18 +42,20 @@ continueHolding: function() { // cast a ray from marker and see if it hits anything - var props = Entities.getEntityProperties(_this.entityID, ["position", "rotation"]); + var markerProps = Entities.getEntityProperties(_this.entityID, ["position", "rotation"]); + var pickRay = { - origin: props.position, - direction: Quat.getFront(props.rotation) + origin: markerProps.position, + direction: Quat.getFront(markerProps.rotation) } var intersection = Entities.findRayIntersection(pickRay, true, [_this.whiteboard]); - if (intersection.intersects) { - + if (intersection.intersects && Vec3.distance(intersection.intersection, markerProps.position) < _this.MAX_MARKER_TO_BOARD_DISTANCE) { this.paint(intersection.intersection) + } else { + _this.currentStroke = null; } }, @@ -71,6 +77,8 @@ _this.linePoints = []; _this.normals = []; _this.strokeWidths = []; + + _this.strokes.push(_this.currentStroke); }, paint: function(position) { @@ -82,6 +90,15 @@ localPoint = Vec3.sum(localPoint, Vec3.multiply(_this.whiteboardNormal, _this.strokeForwardOffset)); // _this.strokeForwardOffset += _this.STROKE_FORWARD_OFFSET_INCRERMENT; + if (_this.linePoints.length > 0) { + var distance = Vec3.distance(localPoint, _this.linePoints[_this.linePoints.length-1]); + if (distance < _this.MIN_DISTANCE_BETWEEN_POINTS) { + print("EBL not enough distance") + return; + } + } + + _this.linePoints.push(localPoint); _this.normals.push(_this.whiteboardNormal); this.strokeWidths.push(_this.STROKE_WIDTH); @@ -99,13 +116,14 @@ preload: function(entityID) { this.entityID = entityID; + print("EBL PRELOAD"); }, setWhiteboard: function(myId, data) { _this.whiteboard = JSON.parse(data[0]); - var props = Entities.getEntityProperties(_this.whiteboard, ["rotation"]); - _this.whiteboardNormal = Quat.getRight(props.rotation); + var whiteboardProps = Entities.getEntityProperties(_this.whiteboard, ["rotation"]); + _this.whiteboardNormal = Quat.getRight(whiteboardProps.rotation); } }; From 40176b04244dedaa5bcea1170c72c7f9e6102ce5 Mon Sep 17 00:00:00 2001 From: ericrius1 Date: Fri, 19 Feb 2016 14:06:55 -0800 Subject: [PATCH 17/58] no gaps --- .../homeContent/whiteboardV2/markerEntityScript.js | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/examples/homeContent/whiteboardV2/markerEntityScript.js b/examples/homeContent/whiteboardV2/markerEntityScript.js index d4bd7bc272..1bd7acf1d9 100644 --- a/examples/homeContent/whiteboardV2/markerEntityScript.js +++ b/examples/homeContent/whiteboardV2/markerEntityScript.js @@ -22,7 +22,7 @@ this.strokeForwardOffset = 0.0005; this.STROKE_FORWARD_OFFSET_INCRERMENT = 0.00001; this.STROKE_WIDTH = 0.003 - _this.MAX_MARKER_TO_BOARD_DISTANCE = 0.5; + _this.MAX_MARKER_TO_BOARD_DISTANCE = 0.2; _this.MIN_DISTANCE_BETWEEN_POINTS = 0.002; _this.MAX_DISTANCE_BETWEEN_POINTS = 0.1; _this.strokes = []; @@ -56,6 +56,7 @@ this.paint(intersection.intersection) } else { _this.currentStroke = null; + _this.oldPosition = null; } }, @@ -82,11 +83,16 @@ }, paint: function(position) { + var basePosition = position; if (!_this.currentStroke) { - _this.newStroke(position); + if (_this.oldPosition) { + basePosition = _this.oldPosition; + print("EBL USE OLD POSITION FOR NEW STROKE!") + } + _this.newStroke(basePosition); } - var localPoint = Vec3.subtract(position, this.strokeBasePosition); + var localPoint = Vec3.subtract(basePosition, this.strokeBasePosition); localPoint = Vec3.sum(localPoint, Vec3.multiply(_this.whiteboardNormal, _this.strokeForwardOffset)); // _this.strokeForwardOffset += _this.STROKE_FORWARD_OFFSET_INCRERMENT; @@ -111,6 +117,7 @@ if (_this.linePoints.length > MAX_POINTS_PER_STROKE) { _this.currentStroke = null; + _this.oldPosition = position; } }, From 9ae1ccee50016f4cb03590ff3f39d556f746bd01 Mon Sep 17 00:00:00 2001 From: ericrius1 Date: Fri, 19 Feb 2016 14:15:55 -0800 Subject: [PATCH 18/58] passing marker color accross --- examples/homeContent/whiteboardV2/markerEntityScript.js | 8 +++++--- examples/homeContent/whiteboardV2/whiteboardSpawner.js | 6 +++++- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/examples/homeContent/whiteboardV2/markerEntityScript.js b/examples/homeContent/whiteboardV2/markerEntityScript.js index 1bd7acf1d9..bc5304ea7f 100644 --- a/examples/homeContent/whiteboardV2/markerEntityScript.js +++ b/examples/homeContent/whiteboardV2/markerEntityScript.js @@ -72,7 +72,7 @@ }, position: position, textures: _this.MARKER_TEXTURE_URL, - color: {red: 0, green: 10, blue: 200} + color: _this.markerColor }); _this.linePoints = []; @@ -127,10 +127,12 @@ print("EBL PRELOAD"); }, - setWhiteboard: function(myId, data) { - _this.whiteboard = JSON.parse(data[0]); + setProperties: function(myId, data) { + var data = JSON.parse(data); + _this.whiteboard = data.whiteboard; var whiteboardProps = Entities.getEntityProperties(_this.whiteboard, ["rotation"]); _this.whiteboardNormal = Quat.getRight(whiteboardProps.rotation); + _this.markerColor = data.markerColor; } }; diff --git a/examples/homeContent/whiteboardV2/whiteboardSpawner.js b/examples/homeContent/whiteboardV2/whiteboardSpawner.js index b5d1c07959..24b5d2a046 100644 --- a/examples/homeContent/whiteboardV2/whiteboardSpawner.js +++ b/examples/homeContent/whiteboardV2/whiteboardSpawner.js @@ -95,7 +95,11 @@ var marker = Entities.addEntity({ }); Script.setTimeout(function() { - Entities.callEntityMethod(marker, "setWhiteboard", [JSON.stringify(whiteboard)]); + var data = { + whiteboard: whiteboard, + markerColor: {red: 10, green: 10, blue: 200} + } + Entities.callEntityMethod(marker, "setProperties", [JSON.stringify(data)]); }, 1000) From 756b7e223d96508d03ec17ef2e59dfd5646396d0 Mon Sep 17 00:00:00 2001 From: ericrius1 Date: Fri, 19 Feb 2016 15:56:12 -0800 Subject: [PATCH 19/58] need to figure out why only one marker working --- .../whiteboardV2/markerEntityScript.js | 3 +- .../whiteboardV2/whiteboardSpawner.js | 173 +++++++++++------- 2 files changed, 110 insertions(+), 66 deletions(-) diff --git a/examples/homeContent/whiteboardV2/markerEntityScript.js b/examples/homeContent/whiteboardV2/markerEntityScript.js index bc5304ea7f..66ca061c05 100644 --- a/examples/homeContent/whiteboardV2/markerEntityScript.js +++ b/examples/homeContent/whiteboardV2/markerEntityScript.js @@ -99,12 +99,10 @@ if (_this.linePoints.length > 0) { var distance = Vec3.distance(localPoint, _this.linePoints[_this.linePoints.length-1]); if (distance < _this.MIN_DISTANCE_BETWEEN_POINTS) { - print("EBL not enough distance") return; } } - _this.linePoints.push(localPoint); _this.normals.push(_this.whiteboardNormal); this.strokeWidths.push(_this.STROKE_WIDTH); @@ -131,6 +129,7 @@ var data = JSON.parse(data); _this.whiteboard = data.whiteboard; var whiteboardProps = Entities.getEntityProperties(_this.whiteboard, ["rotation"]); + print("EBL: MARKER COLOR " + JSON.stringify(data.markerColor)); _this.whiteboardNormal = Quat.getRight(whiteboardProps.rotation); _this.markerColor = data.markerColor; } diff --git a/examples/homeContent/whiteboardV2/whiteboardSpawner.js b/examples/homeContent/whiteboardV2/whiteboardSpawner.js index 24b5d2a046..33b559838b 100644 --- a/examples/homeContent/whiteboardV2/whiteboardSpawner.js +++ b/examples/homeContent/whiteboardV2/whiteboardSpawner.js @@ -13,13 +13,19 @@ var orientation = Camera.getOrientation(); orientation = Quat.safeEulerAngles(orientation); -orientation.x = 0; -var whiteboardRotation = Quat.fromVec3Degrees({ - x: orientation.x, +var markerRotation = Quat.fromVec3Degrees({ + x: orientation.x + 10, y: orientation.y - 90, z: orientation.z +}) +orientation.x = 0; +var whiteboardRotation = Quat.fromVec3Degrees({ + x: 0, + y: orientation.y - 90, + z: 0 }); orientation = Quat.fromVec3Degrees(orientation); +var markers = []; var whiteboardPosition = Vec3.sum(MyAvatar.position, Vec3.multiply(2, Quat.getFront(orientation))); @@ -40,73 +46,112 @@ var whiteboard = Entities.addEntity({ } }); -var markerPosition = Vec3.sum(MyAvatar.position, Vec3.multiply(1.9, Quat.getFront(orientation))); -var MARKER_MODEL_URL = "https://s3-us-west-1.amazonaws.com/hifi-content/eric/models/marker-blue.fbx"; -var MARKER_SCRIPT_URL = Script.resolvePath("markerEntityScript.js?v1" + Math.random()); -var marker = Entities.addEntity({ - type: "Model", - modelURL: MARKER_MODEL_URL, - shapeType: "box", - dynamic: true, - gravity: { - x: 0, - y: -1, - z: 0 - }, - velocity: { - x: 0, - y: -0.1, - z: 0 - }, - position: markerPosition, - dimensions: { - x: 0.0270, - y: 0.0272, - z: 0.1641 - }, - name: "marker", - script: MARKER_SCRIPT_URL, - userData: JSON.stringify({ - wearable: { - joints: { - RightHand: [{ - x: 0.001109793782234192, - y: 0.13991504907608032, - z: 0.05035984516143799 - }, { - x: -0.7360993027687073, - y: -0.04330085217952728, - z: -0.10863728821277618, - w: -0.6666942238807678 - }], - LeftHand: [{ - x: 0.007193896919488907, - y: 0.15147076547145844, - z: 0.06174466013908386 - }, { - x: -0.4174973964691162, - y: 0.631147563457489, - z: -0.3890438377857208, - w: -0.52535080909729 - }] - } - } - }) -}); +createMarkers(); +function createMarkers() { + var modelURLS = [ + "https://s3-us-west-1.amazonaws.com/hifi-content/eric/models/marker-blue.fbx", + "https://s3-us-west-1.amazonaws.com/hifi-content/eric/models/marker-red.fbx", + "https://s3-us-west-1.amazonaws.com/hifi-content/eric/models/marker-black.fbx", + ]; -Script.setTimeout(function() { - var data = { - whiteboard: whiteboard, - markerColor: {red: 10, green: 10, blue: 200} - } - Entities.callEntityMethod(marker, "setProperties", [JSON.stringify(data)]); -}, 1000) + var markerPosition = Vec3.sum(MyAvatar.position, Vec3.multiply(1.9, Quat.getFront(orientation))); + + 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_SCRIPT_URL = Script.resolvePath("markerEntityScript.js?v1" + Math.random()); + var marker = Entities.addEntity({ + type: "Model", + modelURL: modelURL, + rotation: markerRotation, + shapeType: "box", + dynamic: true, + gravity: { + x: 0, + y: -1, + z: 0 + }, + velocity: { + x: 0, + y: -0.1, + z: 0 + }, + position: markerPosition, + dimensions: { + x: 0.0270, + y: 0.0272, + z: 0.1641 + }, + name: "marker", + script: MARKER_SCRIPT_URL, + userData: JSON.stringify({ + wearable: { + joints: { + RightHand: [{ + x: 0.001109793782234192, + y: 0.13991504907608032, + z: 0.05035984516143799 + }, { + x: -0.7360993027687073, + y: -0.04330085217952728, + z: -0.10863728821277618, + w: -0.6666942238807678 + }], + LeftHand: [{ + x: 0.007193896919488907, + y: 0.15147076547145844, + z: 0.06174466013908386 + }, { + x: -0.4174973964691162, + y: 0.631147563457489, + z: -0.3890438377857208, + w: -0.52535080909729 + }] + } + } + }) + }); + + markers.push(marker); + + Script.setTimeout(function() { + var data = { + whiteboard: whiteboard, + markerColor: markerColor + } + Entities.callEntityMethod(marker, "setProperties", [JSON.stringify(data)]); + }, 1000) + + +} function cleanup() { Entities.deleteEntity(whiteboard); - Entities.deleteEntity(marker); + markers.forEach(function(marker){ + Entities.deleteEntity(marker); + }); } Script.scriptEnding.connect(cleanup); \ No newline at end of file From 68e289b433db8836cda12d857a36de047a30bbe1 Mon Sep 17 00:00:00 2001 From: ericrius1 Date: Fri, 19 Feb 2016 17:32:33 -0800 Subject: [PATCH 20/58] Fixed bug where spawning one marker would destroy the other --- .../whiteboardV2/markerEntityScript.js | 15 ++++++--- .../whiteboardV2/whiteboardSpawner.js | 33 ++++++++++++------- 2 files changed, 32 insertions(+), 16 deletions(-) diff --git a/examples/homeContent/whiteboardV2/markerEntityScript.js b/examples/homeContent/whiteboardV2/markerEntityScript.js index 66ca061c05..d905db07dd 100644 --- a/examples/homeContent/whiteboardV2/markerEntityScript.js +++ b/examples/homeContent/whiteboardV2/markerEntityScript.js @@ -15,7 +15,7 @@ Script.include("../../libraries/utils.js"); var MAX_POINTS_PER_STROKE = 40; - +var _this; MarkerTip = function() { _this = this; _this.MARKER_TEXTURE_URL = "https://s3-us-west-1.amazonaws.com/hifi-content/eric/textures/markerStroke.png"; @@ -49,12 +49,17 @@ origin: markerProps.position, direction: Quat.getFront(markerProps.rotation) } - + print('MARKER ID'+_this.entityID) + print('MARKER POSITION'+JSON.stringify(markerProps.position)) var intersection = Entities.findRayIntersection(pickRay, true, [_this.whiteboard]); - + print('WHITEBOARD AT CONTINUE:: '+_this.whiteboard); + print('DOES INTERSECT??'+intersection.intersects) + print('MARKER DISTANCE::'+Vec3.distance(intersection.intersection, markerProps.position)) + print('MAX DISTANCE::'+_this.MAX_MARKER_TO_BOARD_DISTANCE) if (intersection.intersects && Vec3.distance(intersection.intersection, markerProps.position) < _this.MAX_MARKER_TO_BOARD_DISTANCE) { this.paint(intersection.intersection) } else { + print('not painting because intersection') _this.currentStroke = null; _this.oldPosition = null; } @@ -103,6 +108,7 @@ } } + print("PAINT " + JSON.stringify(_this.markerColor)); _this.linePoints.push(localPoint); _this.normals.push(_this.whiteboardNormal); this.strokeWidths.push(_this.STROKE_WIDTH); @@ -127,9 +133,10 @@ setProperties: function(myId, data) { var data = JSON.parse(data); + print("EBL SET PROPERTIES! ON " + JSON.stringify(data.markerColor)+ "id:"+ JSON.stringify(myId)); + _this.whiteboard = data.whiteboard; var whiteboardProps = Entities.getEntityProperties(_this.whiteboard, ["rotation"]); - print("EBL: MARKER COLOR " + JSON.stringify(data.markerColor)); _this.whiteboardNormal = Quat.getRight(whiteboardProps.rotation); _this.markerColor = data.markerColor; } diff --git a/examples/homeContent/whiteboardV2/whiteboardSpawner.js b/examples/homeContent/whiteboardV2/whiteboardSpawner.js index 33b559838b..c3dcd3e6d7 100644 --- a/examples/homeContent/whiteboardV2/whiteboardSpawner.js +++ b/examples/homeContent/whiteboardV2/whiteboardSpawner.js @@ -10,6 +10,7 @@ // Distributed under the Apache License, Version 2.0. // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +Script.include("../../libraries/utils.js") var orientation = Camera.getOrientation(); orientation = Quat.safeEulerAngles(orientation); @@ -62,19 +63,23 @@ function createMarkers() { 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 - }); + Script.setTimeout(function() { + + markerPosition = Vec3.sum(markerPosition, Vec3.multiply(-0.2, Quat.getFront(markerRotation))); + createMarker(modelURLS[1], markerPosition, { + red: 200, + green: 10, + blue: 10 + }); + }, 1000); + + // markerPosition = Vec3.sum(markerPosition, Vec3.multiply(0.4, Quat.getFront(markerRotation))); + // createMarker(modelURLS[2], markerPosition, { + // red: 10, + // green: 10, + // blue: 10 + // }); } @@ -139,6 +144,10 @@ function createMarker(modelURL, markerPosition, markerColor) { whiteboard: whiteboard, markerColor: markerColor } + var modelURL = Entities.getEntityProperties(marker, "modelURL").modelURL; + print("EBL MARKER URL " + JSON.stringify(modelURL)) + print("EBL MARKER COLOR " + JSON.stringify(markerColor)) + Entities.callEntityMethod(marker, "setProperties", [JSON.stringify(data)]); }, 1000) From 6fe9730897c4c62a79595d82f6fac09e3d097136 Mon Sep 17 00:00:00 2001 From: ericrius1 Date: Fri, 19 Feb 2016 17:33:54 -0800 Subject: [PATCH 21/58] all three markers --- .../whiteboardV2/whiteboardSpawner.js | 33 +++++++++---------- 1 file changed, 16 insertions(+), 17 deletions(-) diff --git a/examples/homeContent/whiteboardV2/whiteboardSpawner.js b/examples/homeContent/whiteboardV2/whiteboardSpawner.js index c3dcd3e6d7..a566e69f52 100644 --- a/examples/homeContent/whiteboardV2/whiteboardSpawner.js +++ b/examples/homeContent/whiteboardV2/whiteboardSpawner.js @@ -15,7 +15,7 @@ Script.include("../../libraries/utils.js") var orientation = Camera.getOrientation(); orientation = Quat.safeEulerAngles(orientation); var markerRotation = Quat.fromVec3Degrees({ - x: orientation.x + 10, + x: orientation.x + 10, y: orientation.y - 90, z: orientation.z }) @@ -48,6 +48,7 @@ var whiteboard = Entities.addEntity({ }); createMarkers(); + function createMarkers() { var modelURLS = [ "https://s3-us-west-1.amazonaws.com/hifi-content/eric/models/marker-blue.fbx", @@ -64,22 +65,20 @@ function createMarkers() { }); - Script.setTimeout(function() { - markerPosition = Vec3.sum(markerPosition, Vec3.multiply(-0.2, Quat.getFront(markerRotation))); - createMarker(modelURLS[1], markerPosition, { - red: 200, - green: 10, - blue: 10 - }); - }, 1000); + 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 - // }); + markerPosition = Vec3.sum(markerPosition, Vec3.multiply(0.4, Quat.getFront(markerRotation))); + createMarker(modelURLS[2], markerPosition, { + red: 10, + green: 10, + blue: 10 + }); } @@ -147,7 +146,7 @@ function createMarker(modelURL, markerPosition, markerColor) { var modelURL = Entities.getEntityProperties(marker, "modelURL").modelURL; print("EBL MARKER URL " + JSON.stringify(modelURL)) print("EBL MARKER COLOR " + JSON.stringify(markerColor)) - + Entities.callEntityMethod(marker, "setProperties", [JSON.stringify(data)]); }, 1000) @@ -158,7 +157,7 @@ function createMarker(modelURL, markerPosition, markerColor) { function cleanup() { Entities.deleteEntity(whiteboard); - markers.forEach(function(marker){ + markers.forEach(function(marker) { Entities.deleteEntity(marker); }); } From ec369959088612210df8761b53d8f963ff04e0cf Mon Sep 17 00:00:00 2001 From: ericrius1 Date: Fri, 19 Feb 2016 17:36:02 -0800 Subject: [PATCH 22/58] moar whiteboard logging removal --- .../homeContent/whiteboardV2/markerEntityScript.js | 11 ----------- .../homeContent/whiteboardV2/whiteboardSpawner.js | 2 -- 2 files changed, 13 deletions(-) diff --git a/examples/homeContent/whiteboardV2/markerEntityScript.js b/examples/homeContent/whiteboardV2/markerEntityScript.js index d905db07dd..74b7746514 100644 --- a/examples/homeContent/whiteboardV2/markerEntityScript.js +++ b/examples/homeContent/whiteboardV2/markerEntityScript.js @@ -49,17 +49,10 @@ var _this; origin: markerProps.position, direction: Quat.getFront(markerProps.rotation) } - print('MARKER ID'+_this.entityID) - print('MARKER POSITION'+JSON.stringify(markerProps.position)) var intersection = Entities.findRayIntersection(pickRay, true, [_this.whiteboard]); - print('WHITEBOARD AT CONTINUE:: '+_this.whiteboard); - print('DOES INTERSECT??'+intersection.intersects) - print('MARKER DISTANCE::'+Vec3.distance(intersection.intersection, markerProps.position)) - print('MAX DISTANCE::'+_this.MAX_MARKER_TO_BOARD_DISTANCE) if (intersection.intersects && Vec3.distance(intersection.intersection, markerProps.position) < _this.MAX_MARKER_TO_BOARD_DISTANCE) { this.paint(intersection.intersection) } else { - print('not painting because intersection') _this.currentStroke = null; _this.oldPosition = null; } @@ -92,7 +85,6 @@ var _this; if (!_this.currentStroke) { if (_this.oldPosition) { basePosition = _this.oldPosition; - print("EBL USE OLD POSITION FOR NEW STROKE!") } _this.newStroke(basePosition); } @@ -108,7 +100,6 @@ var _this; } } - print("PAINT " + JSON.stringify(_this.markerColor)); _this.linePoints.push(localPoint); _this.normals.push(_this.whiteboardNormal); this.strokeWidths.push(_this.STROKE_WIDTH); @@ -128,12 +119,10 @@ var _this; preload: function(entityID) { this.entityID = entityID; - print("EBL PRELOAD"); }, setProperties: function(myId, data) { var data = JSON.parse(data); - print("EBL SET PROPERTIES! ON " + JSON.stringify(data.markerColor)+ "id:"+ JSON.stringify(myId)); _this.whiteboard = data.whiteboard; var whiteboardProps = Entities.getEntityProperties(_this.whiteboard, ["rotation"]); diff --git a/examples/homeContent/whiteboardV2/whiteboardSpawner.js b/examples/homeContent/whiteboardV2/whiteboardSpawner.js index a566e69f52..26d373266b 100644 --- a/examples/homeContent/whiteboardV2/whiteboardSpawner.js +++ b/examples/homeContent/whiteboardV2/whiteboardSpawner.js @@ -144,8 +144,6 @@ function createMarker(modelURL, markerPosition, markerColor) { markerColor: markerColor } var modelURL = Entities.getEntityProperties(marker, "modelURL").modelURL; - print("EBL MARKER URL " + JSON.stringify(modelURL)) - print("EBL MARKER COLOR " + JSON.stringify(markerColor)) Entities.callEntityMethod(marker, "setProperties", [JSON.stringify(data)]); }, 1000) From 69dc9ef68f8a6da5751a76b7809d5078a9c6df08 Mon Sep 17 00:00:00 2001 From: ericrius1 Date: Tue, 23 Feb 2016 09:06:35 -0800 Subject: [PATCH 23/58] added lifetime --- examples/homeContent/whiteboardV2/markerEntityScript.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/examples/homeContent/whiteboardV2/markerEntityScript.js b/examples/homeContent/whiteboardV2/markerEntityScript.js index 74b7746514..155077af9c 100644 --- a/examples/homeContent/whiteboardV2/markerEntityScript.js +++ b/examples/homeContent/whiteboardV2/markerEntityScript.js @@ -70,7 +70,8 @@ var _this; }, position: position, textures: _this.MARKER_TEXTURE_URL, - color: _this.markerColor + color: _this.markerColor, + lifetime: 1000 }); _this.linePoints = []; From b5ec79fd6db48c5317759a7f355173e1873349ea Mon Sep 17 00:00:00 2001 From: ericrius1 Date: Tue, 23 Feb 2016 09:53:20 -0800 Subject: [PATCH 24/58] marker only draws when equipped and held down --- .../whiteboardV2/markerEntityScript.js | 31 ++++++++++++------- 1 file changed, 19 insertions(+), 12 deletions(-) diff --git a/examples/homeContent/whiteboardV2/markerEntityScript.js b/examples/homeContent/whiteboardV2/markerEntityScript.js index 155077af9c..d19e09bb34 100644 --- a/examples/homeContent/whiteboardV2/markerEntityScript.js +++ b/examples/homeContent/whiteboardV2/markerEntityScript.js @@ -13,9 +13,12 @@ (function() { Script.include("../../libraries/utils.js"); - + var TRIGGER_CONTROLS = [ + Controller.Standard.LT, + Controller.Standard.RT, + ]; var MAX_POINTS_PER_STROKE = 40; -var _this; + var _this; MarkerTip = function() { _this = this; _this.MARKER_TEXTURE_URL = "https://s3-us-west-1.amazonaws.com/hifi-content/eric/textures/markerStroke.png"; @@ -30,21 +33,25 @@ var _this; MarkerTip.prototype = { - continueNearGrab: function() { - - _this.continueHolding(); + startEquip: function(id, params) { + _this.equipped = true; + _this.hand = params[0] == "left" ? 0 : 1; }, - continueEquip: function() { - _this.continueHolding(); + this.triggerValue = Controller.getValue(TRIGGER_CONTROLS[_this.hand]); + if (_this.triggerValue > 0.2) { + print("EBL PAINZT"); + _this.continueHolding(); + } else { + _this.currentStroke = null; + } }, + continueHolding: function() { // cast a ray from marker and see if it hits anything - var markerProps = Entities.getEntityProperties(_this.entityID, ["position", "rotation"]); - var pickRay = { origin: markerProps.position, direction: Quat.getFront(markerProps.rotation) @@ -87,7 +94,7 @@ var _this; if (_this.oldPosition) { basePosition = _this.oldPosition; } - _this.newStroke(basePosition); + _this.newStroke(basePosition); } var localPoint = Vec3.subtract(basePosition, this.strokeBasePosition); @@ -95,7 +102,7 @@ var _this; // _this.strokeForwardOffset += _this.STROKE_FORWARD_OFFSET_INCRERMENT; if (_this.linePoints.length > 0) { - var distance = Vec3.distance(localPoint, _this.linePoints[_this.linePoints.length-1]); + var distance = Vec3.distance(localPoint, _this.linePoints[_this.linePoints.length - 1]); if (distance < _this.MIN_DISTANCE_BETWEEN_POINTS) { return; } @@ -119,7 +126,7 @@ var _this; preload: function(entityID) { this.entityID = entityID; - + }, setProperties: function(myId, data) { From 81ed89531da0ce3eb52372c017f2406e7e8c0f50 Mon Sep 17 00:00:00 2001 From: ericrius1 Date: Tue, 23 Feb 2016 10:11:13 -0800 Subject: [PATCH 25/58] whiteboard surface parented to whiteboard --- .../whiteboardV2/markerEntityScript.js | 23 ++++++++++++------- .../whiteboardV2/whiteboardSpawner.js | 15 +++++++++++- 2 files changed, 29 insertions(+), 9 deletions(-) diff --git a/examples/homeContent/whiteboardV2/markerEntityScript.js b/examples/homeContent/whiteboardV2/markerEntityScript.js index d19e09bb34..ae8e19c759 100644 --- a/examples/homeContent/whiteboardV2/markerEntityScript.js +++ b/examples/homeContent/whiteboardV2/markerEntityScript.js @@ -29,6 +29,7 @@ _this.MIN_DISTANCE_BETWEEN_POINTS = 0.002; _this.MAX_DISTANCE_BETWEEN_POINTS = 0.1; _this.strokes = []; + _this.PAINTING_TRIGGER_THRESHOLD = 0.2; }; MarkerTip.prototype = { @@ -39,14 +40,17 @@ }, continueEquip: function() { this.triggerValue = Controller.getValue(TRIGGER_CONTROLS[_this.hand]); - if (_this.triggerValue > 0.2) { - print("EBL PAINZT"); + if (_this.triggerValue > _this.PAINTING_TRIGGER_THRESHOLD) { _this.continueHolding(); } else { - _this.currentStroke = null; + _this.resetStroke(); } }, + releaseEquip: function() { + _this.resetStroke(); + }, + continueHolding: function() { // cast a ray from marker and see if it hits anything @@ -60,8 +64,7 @@ if (intersection.intersects && Vec3.distance(intersection.intersection, markerProps.position) < _this.MAX_MARKER_TO_BOARD_DISTANCE) { this.paint(intersection.intersection) } else { - _this.currentStroke = null; - _this.oldPosition = null; + _this.resetStroke(); } }, @@ -119,11 +122,15 @@ }); if (_this.linePoints.length > MAX_POINTS_PER_STROKE) { - _this.currentStroke = null; - _this.oldPosition = position; + _this.resetStroke(); } }, + resetStroke: function() { + _this.currentStroke = null; + _this.oldPosition = position; + }, + preload: function(entityID) { this.entityID = entityID; @@ -134,7 +141,7 @@ _this.whiteboard = data.whiteboard; var whiteboardProps = Entities.getEntityProperties(_this.whiteboard, ["rotation"]); - _this.whiteboardNormal = Quat.getRight(whiteboardProps.rotation); + _this.whiteboardNormal = Quat.getFront(whiteboardProps.rotation); _this.markerColor = data.markerColor; } }; diff --git a/examples/homeContent/whiteboardV2/whiteboardSpawner.js b/examples/homeContent/whiteboardV2/whiteboardSpawner.js index 26d373266b..90476a3b3d 100644 --- a/examples/homeContent/whiteboardV2/whiteboardSpawner.js +++ b/examples/homeContent/whiteboardV2/whiteboardSpawner.js @@ -47,6 +47,18 @@ var whiteboard = Entities.addEntity({ } }); +var whiteboardSurfacePosition = Vec3.sum(whiteboardPosition, {x: 0.0, y: 0.45, z: 0.0}) +var whiteboardDrawingSurface = Entities.addEntity({ + type: "Box", + name: "whiteboardDrawingSurface", + dimensions: {x: 1.85, y: 1.8, z: 0.03}, + color: {red: 200, green: 10, blue: 200}, + position: whiteboardSurfacePosition, + rotation: orientation, + visible: false, + parentID: whiteboard +}); + createMarkers(); function createMarkers() { @@ -140,7 +152,7 @@ function createMarker(modelURL, markerPosition, markerColor) { Script.setTimeout(function() { var data = { - whiteboard: whiteboard, + whiteboard: whiteboardDrawingSurface, markerColor: markerColor } var modelURL = Entities.getEntityProperties(marker, "modelURL").modelURL; @@ -155,6 +167,7 @@ function createMarker(modelURL, markerPosition, markerColor) { function cleanup() { Entities.deleteEntity(whiteboard); + Entities.deleteEntity(whiteboardDrawingSurface); markers.forEach(function(marker) { Entities.deleteEntity(marker); }); From 6682b9bd580892e492a598246cb3701f4e8436ea Mon Sep 17 00:00:00 2001 From: ericrius1 Date: Tue, 23 Feb 2016 10:36:17 -0800 Subject: [PATCH 26/58] eraser is spawing --- .../whiteboardV2/whiteboardSpawner.js | 52 +++++++++++++++++-- 1 file changed, 48 insertions(+), 4 deletions(-) diff --git a/examples/homeContent/whiteboardV2/whiteboardSpawner.js b/examples/homeContent/whiteboardV2/whiteboardSpawner.js index 90476a3b3d..b408fcc126 100644 --- a/examples/homeContent/whiteboardV2/whiteboardSpawner.js +++ b/examples/homeContent/whiteboardV2/whiteboardSpawner.js @@ -47,18 +47,61 @@ var whiteboard = Entities.addEntity({ } }); -var whiteboardSurfacePosition = Vec3.sum(whiteboardPosition, {x: 0.0, y: 0.45, z: 0.0}) +var whiteboardSurfacePosition = Vec3.sum(whiteboardPosition, { + x: 0.0, + y: 0.45, + z: 0.0 +}) var whiteboardDrawingSurface = Entities.addEntity({ type: "Box", name: "whiteboardDrawingSurface", - dimensions: {x: 1.85, y: 1.8, z: 0.03}, - color: {red: 200, green: 10, blue: 200}, + dimensions: { + x: 1.85, + y: 1.8, + z: 0.03 + }, + color: { + red: 200, + green: 10, + blue: 200 + }, position: whiteboardSurfacePosition, rotation: orientation, visible: false, parentID: whiteboard }); + +var WHITEBOARD_RACK_DEPTH = 1.9; + +var ERASER_MODEL_URL = "http://hifi-content.s3.amazonaws.com/alan/dev/eraser.fbx"; +var eraserPosition = Vec3.sum(MyAvatar.position, Vec3.multiply(WHITEBOARD_RACK_DEPTH, Quat.getFront(orientation))); +eraserPosition = Vec3.sum(eraserPosition, Vec3.multiply(-0.5, Quat.getFront(whiteboardRotation))); + +var eraser = Entities.addEntity({ + type: "Model", + modelURL: ERASER_MODEL_URL, + position: eraserPosition, + shapeType: "box", + dimensions: { + x: 0.0858, + y: 0.0393, + z: 0.2083 + }, + rotation: whiteboardRotation, + dynamic: true, + gravity: { + x: 0, + y: -1, + z: 0 + }, + velocity: { + x: 0, + y: -0.1, + z: 0 + } +}); + createMarkers(); function createMarkers() { @@ -68,7 +111,7 @@ function createMarkers() { "https://s3-us-west-1.amazonaws.com/hifi-content/eric/models/marker-black.fbx", ]; - var markerPosition = Vec3.sum(MyAvatar.position, Vec3.multiply(1.9, Quat.getFront(orientation))); + var markerPosition = Vec3.sum(MyAvatar.position, Vec3.multiply(WHITEBOARD_RACK_DEPTH, Quat.getFront(orientation))); createMarker(modelURLS[0], markerPosition, { red: 10, @@ -168,6 +211,7 @@ function createMarker(modelURL, markerPosition, markerColor) { function cleanup() { Entities.deleteEntity(whiteboard); Entities.deleteEntity(whiteboardDrawingSurface); + Entities.deleteEntity(eraser); markers.forEach(function(marker) { Entities.deleteEntity(marker); }); From 20fd79fc43f1370c8e65050d1de953d4f1679294 Mon Sep 17 00:00:00 2001 From: ericrius1 Date: Tue, 23 Feb 2016 11:25:46 -0800 Subject: [PATCH 27/58] Lines markers --- examples/homeContent/whiteboardV2/markerEntityScript.js | 7 ++++--- examples/homeContent/whiteboardV2/whiteboardSpawner.js | 7 ++++--- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/examples/homeContent/whiteboardV2/markerEntityScript.js b/examples/homeContent/whiteboardV2/markerEntityScript.js index ae8e19c759..3b734cc2ad 100644 --- a/examples/homeContent/whiteboardV2/markerEntityScript.js +++ b/examples/homeContent/whiteboardV2/markerEntityScript.js @@ -25,7 +25,7 @@ this.strokeForwardOffset = 0.0005; this.STROKE_FORWARD_OFFSET_INCRERMENT = 0.00001; this.STROKE_WIDTH = 0.003 - _this.MAX_MARKER_TO_BOARD_DISTANCE = 0.2; + _this.MAX_MARKER_TO_BOARD_DISTANCE = 1.4; _this.MIN_DISTANCE_BETWEEN_POINTS = 0.002; _this.MAX_DISTANCE_BETWEEN_POINTS = 0.1; _this.strokes = []; @@ -122,13 +122,14 @@ }); if (_this.linePoints.length > MAX_POINTS_PER_STROKE) { - _this.resetStroke(); + _this.currentStroke = null; + _this.oldPosition = position; } }, resetStroke: function() { _this.currentStroke = null; - _this.oldPosition = position; + _this.oldPosition = null; }, preload: function(entityID) { diff --git a/examples/homeContent/whiteboardV2/whiteboardSpawner.js b/examples/homeContent/whiteboardV2/whiteboardSpawner.js index b408fcc126..e714070bff 100644 --- a/examples/homeContent/whiteboardV2/whiteboardSpawner.js +++ b/examples/homeContent/whiteboardV2/whiteboardSpawner.js @@ -44,7 +44,8 @@ var whiteboard = Entities.addEntity({ x: 0.4636, y: 2.7034, z: 1.8653 - } + }, + // visible: false }); var whiteboardSurfacePosition = Vec3.sum(whiteboardPosition, { @@ -58,7 +59,7 @@ var whiteboardDrawingSurface = Entities.addEntity({ dimensions: { x: 1.85, y: 1.8, - z: 0.03 + z: 0.04 }, color: { red: 200, @@ -68,7 +69,7 @@ var whiteboardDrawingSurface = Entities.addEntity({ position: whiteboardSurfacePosition, rotation: orientation, visible: false, - parentID: whiteboard + // parentID: whiteboard }); From 8d058c2bb380a170062060b661263d2a05483997 Mon Sep 17 00:00:00 2001 From: ericrius1 Date: Tue, 23 Feb 2016 11:53:27 -0800 Subject: [PATCH 28/58] eraser working --- .../whiteboardV2/eraserEntityScript.js | 80 +++++++++++++++++++ .../whiteboardV2/markerEntityScript.js | 3 +- .../whiteboardV2/whiteboardSpawner.js | 2 + 3 files changed, 84 insertions(+), 1 deletion(-) create mode 100644 examples/homeContent/whiteboardV2/eraserEntityScript.js diff --git a/examples/homeContent/whiteboardV2/eraserEntityScript.js b/examples/homeContent/whiteboardV2/eraserEntityScript.js new file mode 100644 index 0000000000..5662fdafc5 --- /dev/null +++ b/examples/homeContent/whiteboardV2/eraserEntityScript.js @@ -0,0 +1,80 @@ +// +// eraserEntityScript.js +// examples/homeContent/eraserEntityScript +// +// Created by Eric Levin on 2/17/15. +// 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("../../libraries/utils.js"); + var TRIGGER_CONTROLS = [ + Controller.Standard.LT, + Controller.Standard.RT, + ]; + var _this; + Eraser = function() { + _this = this; + + _this.ERASER_TRIGGER_THRESHOLD = 0.1; + _this.STROKE_NAME = "hifi-marker-stroke"; + _this.ERASER_TO_STROKE_SEARCH_RADIUS = 0.2; + }; + + 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 + var eraserPosition = Entities.getEntityProperties(_this.entityID, "position").position; + var strokeIDs = Entities.findEntities(eraserPosition, _this.ERASER_TO_STROKE_SEARCH_RADIUS); + // Create a map of stroke entities and their positions + _this.strokeMap = []; + strokeIDs.forEach(function(strokeID) { + var strokeProps = Entities.getEntityProperties(strokeID, ["position", "name"]); + if (strokeProps.name === _this.STROKE_NAME) { + _this.strokeMap.push({ + strokeID: strokeID, + strokePosition: strokeProps.position + }); + } + }); + }, + continueEquip: function() { + this.triggerValue = Controller.getValue(TRIGGER_CONTROLS[_this.hand]); + if (_this.triggerValue > _this.ERASER_TRIGGER_THRESHOLD) { + _this.continueHolding(); + } else {} + }, + + releaseEquip: function() {}, + + + continueHolding: function() { + // search for marker strokes within certain radius of eraser + var eraserPosition = Entities.getEntityProperties(_this.entityID, "position").position; + _this.strokeMap.forEach(function(strokeData, index) { + if (Vec3.distance(eraserPosition, strokeData.strokePosition) < _this.ERASER_TO_STROKE_SEARCH_RADIUS) { + Entities.deleteEntity(strokeData.strokeID); + _this.strokeMap.splice(index, 1); + } + }) + + }, + + + preload: function(entityID) { + this.entityID = entityID; + + }, + }; + + // 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/examples/homeContent/whiteboardV2/markerEntityScript.js b/examples/homeContent/whiteboardV2/markerEntityScript.js index 3b734cc2ad..da37983d74 100644 --- a/examples/homeContent/whiteboardV2/markerEntityScript.js +++ b/examples/homeContent/whiteboardV2/markerEntityScript.js @@ -30,6 +30,7 @@ _this.MAX_DISTANCE_BETWEEN_POINTS = 0.1; _this.strokes = []; _this.PAINTING_TRIGGER_THRESHOLD = 0.2; + this.STROKE_NAME = "hifi-marker-stroke"; }; MarkerTip.prototype = { @@ -72,7 +73,7 @@ _this.strokeBasePosition = position; _this.currentStroke = Entities.addEntity({ type: "PolyLine", - name: "marker stroke", + name: _this.STROKE_NAME, dimensions: { x: 10, y: 10, diff --git a/examples/homeContent/whiteboardV2/whiteboardSpawner.js b/examples/homeContent/whiteboardV2/whiteboardSpawner.js index e714070bff..e1ccc16c89 100644 --- a/examples/homeContent/whiteboardV2/whiteboardSpawner.js +++ b/examples/homeContent/whiteboardV2/whiteboardSpawner.js @@ -76,6 +76,7 @@ var whiteboardDrawingSurface = Entities.addEntity({ var WHITEBOARD_RACK_DEPTH = 1.9; var ERASER_MODEL_URL = "http://hifi-content.s3.amazonaws.com/alan/dev/eraser.fbx"; +var ERASER_SCRIPT_URL = Script.resolvePath("eraserEntityScript.js?v1" + Math.random()); var eraserPosition = Vec3.sum(MyAvatar.position, Vec3.multiply(WHITEBOARD_RACK_DEPTH, Quat.getFront(orientation))); eraserPosition = Vec3.sum(eraserPosition, Vec3.multiply(-0.5, Quat.getFront(whiteboardRotation))); @@ -83,6 +84,7 @@ var eraser = Entities.addEntity({ type: "Model", modelURL: ERASER_MODEL_URL, position: eraserPosition, + script: ERASER_SCRIPT_URL, shapeType: "box", dimensions: { x: 0.0858, From a2ece772ef3491a580732518b316669464f898b0 Mon Sep 17 00:00:00 2001 From: ericrius1 Date: Tue, 23 Feb 2016 12:08:51 -0800 Subject: [PATCH 29/58] refactor for laser pointer --- .../whiteboardV2/markerEntityScript.js | 38 ++++++++++++++----- 1 file changed, 28 insertions(+), 10 deletions(-) diff --git a/examples/homeContent/whiteboardV2/markerEntityScript.js b/examples/homeContent/whiteboardV2/markerEntityScript.js index da37983d74..685accfb13 100644 --- a/examples/homeContent/whiteboardV2/markerEntityScript.js +++ b/examples/homeContent/whiteboardV2/markerEntityScript.js @@ -40,12 +40,8 @@ _this.hand = params[0] == "left" ? 0 : 1; }, continueEquip: function() { - this.triggerValue = Controller.getValue(TRIGGER_CONTROLS[_this.hand]); - if (_this.triggerValue > _this.PAINTING_TRIGGER_THRESHOLD) { - _this.continueHolding(); - } else { - _this.resetStroke(); - } + _this.continueHolding(); + }, releaseEquip: function() { @@ -62,13 +58,22 @@ direction: Quat.getFront(markerProps.rotation) } var intersection = Entities.findRayIntersection(pickRay, true, [_this.whiteboard]); - if (intersection.intersects && Vec3.distance(intersection.intersection, markerProps.position) < _this.MAX_MARKER_TO_BOARD_DISTANCE) { - this.paint(intersection.intersection) + + if (intersection.intersects) { + _this.triggerValue = Controller.getValue(TRIGGER_CONTROLS[_this.hand]); + if (_this.triggerValue > _this.PAINTING_TRIGGER_THRESHOLD && Vec3.distance(intersection.intersection, markerProps.position) < _this.MAX_MARKER_TO_BOARD_DISTANCE) { + _this.paint(intersection.intersection) + } else { + _this.resetStroke(); + } } else { - _this.resetStroke(); + _this.resetStroke(); } + }, + + newStroke: function(position) { _this.strokeBasePosition = position; _this.currentStroke = Entities.addEntity({ @@ -103,7 +108,7 @@ var localPoint = Vec3.subtract(basePosition, this.strokeBasePosition); localPoint = Vec3.sum(localPoint, Vec3.multiply(_this.whiteboardNormal, _this.strokeForwardOffset)); - // _this.strokeForwardOffset += _this.STROKE_FORWARD_OFFSET_INCRERMENT; + _this.strokeForwardOffset += _this.STROKE_FORWARD_OFFSET_INCRERMENT; if (_this.linePoints.length > 0) { var distance = Vec3.distance(localPoint, _this.linePoints[_this.linePoints.length - 1]); @@ -138,12 +143,25 @@ }, + unload: function() { + Overlays.deleteOverlay(_this.laserPointer); + }, + setProperties: function(myId, data) { var data = JSON.parse(data); _this.whiteboard = data.whiteboard; var whiteboardProps = Entities.getEntityProperties(_this.whiteboard, ["rotation"]); _this.whiteboardNormal = Quat.getFront(whiteboardProps.rotation); + _this.laserPointer = Overlays.addOverlay("circle3d", { + color: { + red: 200, + green: 10, + blue: 10 + }, + solid: true, + rotation: whiteboardProps.rotation + }); _this.markerColor = data.markerColor; } }; From 5e0de4bdee04b648e8bdc84580fa57ffd9c3d5c3 Mon Sep 17 00:00:00 2001 From: ericrius1 Date: Tue, 23 Feb 2016 12:16:22 -0800 Subject: [PATCH 30/58] tweaks --- .../whiteboardV2/eraserEntityScript.js | 3 +-- .../whiteboardV2/markerEntityScript.js | 16 ++++++++++------ .../whiteboardV2/whiteboardSpawner.js | 10 +++++----- 3 files changed, 16 insertions(+), 13 deletions(-) diff --git a/examples/homeContent/whiteboardV2/eraserEntityScript.js b/examples/homeContent/whiteboardV2/eraserEntityScript.js index 5662fdafc5..89ce4aded6 100644 --- a/examples/homeContent/whiteboardV2/eraserEntityScript.js +++ b/examples/homeContent/whiteboardV2/eraserEntityScript.js @@ -23,7 +23,7 @@ _this.ERASER_TRIGGER_THRESHOLD = 0.1; _this.STROKE_NAME = "hifi-marker-stroke"; - _this.ERASER_TO_STROKE_SEARCH_RADIUS = 0.2; + _this.ERASER_TO_STROKE_SEARCH_RADIUS = 0.4; }; Eraser.prototype = { @@ -68,7 +68,6 @@ }, - preload: function(entityID) { this.entityID = entityID; diff --git a/examples/homeContent/whiteboardV2/markerEntityScript.js b/examples/homeContent/whiteboardV2/markerEntityScript.js index 685accfb13..4bf90b6562 100644 --- a/examples/homeContent/whiteboardV2/markerEntityScript.js +++ b/examples/homeContent/whiteboardV2/markerEntityScript.js @@ -5,6 +5,7 @@ // Created by Eric Levin on 2/17/15. // Copyright 2016 High Fidelity, Inc. // +// This script provides the logic for an object to draw marker strokes on its associated whiteboard // Distributed under the Apache License, Version 2.0. // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html @@ -39,17 +40,13 @@ _this.equipped = true; _this.hand = params[0] == "left" ? 0 : 1; }, - continueEquip: function() { - _this.continueHolding(); - - }, releaseEquip: function() { _this.resetStroke(); }, - continueHolding: function() { + continueEquip: function() { // cast a ray from marker and see if it hits anything var markerProps = Entities.getEntityProperties(_this.entityID, ["position", "rotation"]); @@ -58,8 +55,11 @@ direction: Quat.getFront(markerProps.rotation) } var intersection = Entities.findRayIntersection(pickRay, true, [_this.whiteboard]); - if (intersection.intersects) { + Overlays.editOverlay(_this.laserPointer, { + visible: true, + position: intersection.intersection + }) _this.triggerValue = Controller.getValue(TRIGGER_CONTROLS[_this.hand]); if (_this.triggerValue > _this.PAINTING_TRIGGER_THRESHOLD && Vec3.distance(intersection.intersection, markerProps.position) < _this.MAX_MARKER_TO_BOARD_DISTANCE) { _this.paint(intersection.intersection) @@ -68,6 +68,9 @@ } } else { _this.resetStroke(); + Overlays.editOverlay(_this.laserPointer, { + visible: true + }) } }, @@ -160,6 +163,7 @@ blue: 10 }, solid: true, + size: 0.01, rotation: whiteboardProps.rotation }); _this.markerColor = data.markerColor; diff --git a/examples/homeContent/whiteboardV2/whiteboardSpawner.js b/examples/homeContent/whiteboardV2/whiteboardSpawner.js index e1ccc16c89..05aaff3565 100644 --- a/examples/homeContent/whiteboardV2/whiteboardSpawner.js +++ b/examples/homeContent/whiteboardV2/whiteboardSpawner.js @@ -5,7 +5,8 @@ // Created by Eric Levina on 2/17/16 // Copyright 2016 High Fidelity, Inc. // -// Run this script to spawn a whiteboard and associated acoutrements that one can paint on usignmarkers +// 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 @@ -45,7 +46,6 @@ var whiteboard = Entities.addEntity({ y: 2.7034, z: 1.8653 }, - // visible: false }); var whiteboardSurfacePosition = Vec3.sum(whiteboardPosition, { @@ -69,14 +69,14 @@ var whiteboardDrawingSurface = Entities.addEntity({ position: whiteboardSurfacePosition, rotation: orientation, visible: false, - // parentID: whiteboard + parentID: whiteboard }); var WHITEBOARD_RACK_DEPTH = 1.9; var ERASER_MODEL_URL = "http://hifi-content.s3.amazonaws.com/alan/dev/eraser.fbx"; -var ERASER_SCRIPT_URL = Script.resolvePath("eraserEntityScript.js?v1" + Math.random()); +var ERASER_SCRIPT_URL = Script.resolvePath("eraserEntityScript.js"); var eraserPosition = Vec3.sum(MyAvatar.position, Vec3.multiply(WHITEBOARD_RACK_DEPTH, Quat.getFront(orientation))); eraserPosition = Vec3.sum(eraserPosition, Vec3.multiply(-0.5, Quat.getFront(whiteboardRotation))); @@ -141,7 +141,7 @@ function createMarkers() { function createMarker(modelURL, markerPosition, markerColor) { - var MARKER_SCRIPT_URL = Script.resolvePath("markerEntityScript.js?v1" + Math.random()); + var MARKER_SCRIPT_URL = Script.resolvePath("markerEntityScript.js"); var marker = Entities.addEntity({ type: "Model", modelURL: modelURL, From d1d4a9d6b1f6dacbfe9fdf9789e93fcbf00d66b0 Mon Sep 17 00:00:00 2001 From: ericrius1 Date: Tue, 23 Feb 2016 14:48:45 -0800 Subject: [PATCH 31/58] adjusted surface position --- .../whiteboardV2/markerEntityScript.js | 17 +++++++++-------- .../whiteboardV2/whiteboardSpawner.js | 11 ++++++----- 2 files changed, 15 insertions(+), 13 deletions(-) diff --git a/examples/homeContent/whiteboardV2/markerEntityScript.js b/examples/homeContent/whiteboardV2/markerEntityScript.js index 4bf90b6562..618a190587 100644 --- a/examples/homeContent/whiteboardV2/markerEntityScript.js +++ b/examples/homeContent/whiteboardV2/markerEntityScript.js @@ -23,7 +23,7 @@ MarkerTip = function() { _this = this; _this.MARKER_TEXTURE_URL = "https://s3-us-west-1.amazonaws.com/hifi-content/eric/textures/markerStroke.png"; - this.strokeForwardOffset = 0.0005; + this.strokeForwardOffset = 0.0001; this.STROKE_FORWARD_OFFSET_INCRERMENT = 0.00001; this.STROKE_WIDTH = 0.003 _this.MAX_MARKER_TO_BOARD_DISTANCE = 1.4; @@ -43,6 +43,9 @@ releaseEquip: function() { _this.resetStroke(); + Overlays.editOverlay(_this.laserPointer, { + visible: false + }); }, @@ -69,14 +72,12 @@ } else { _this.resetStroke(); Overlays.editOverlay(_this.laserPointer, { - visible: true - }) + visible: false + }); } }, - - newStroke: function(position) { _this.strokeBasePosition = position; _this.currentStroke = Entities.addEntity({ @@ -158,9 +159,9 @@ _this.whiteboardNormal = Quat.getFront(whiteboardProps.rotation); _this.laserPointer = Overlays.addOverlay("circle3d", { color: { - red: 200, - green: 10, - blue: 10 + red: 220, + green: 35, + blue: 53 }, solid: true, size: 0.01, diff --git a/examples/homeContent/whiteboardV2/whiteboardSpawner.js b/examples/homeContent/whiteboardV2/whiteboardSpawner.js index 05aaff3565..378bd9ff5c 100644 --- a/examples/homeContent/whiteboardV2/whiteboardSpawner.js +++ b/examples/homeContent/whiteboardV2/whiteboardSpawner.js @@ -13,7 +13,7 @@ Script.include("../../libraries/utils.js") -var orientation = Camera.getOrientation(); +var orientation = MyAvatar.orientation; orientation = Quat.safeEulerAngles(orientation); var markerRotation = Quat.fromVec3Degrees({ x: orientation.x + 10, @@ -52,12 +52,13 @@ var whiteboardSurfacePosition = Vec3.sum(whiteboardPosition, { x: 0.0, y: 0.45, z: 0.0 -}) +}); +whiteboardSurfacePosition = Vec3.sum(whiteboardSurfacePosition, Vec3.multiply(-0.02, Quat.getRight(orientation))); var whiteboardDrawingSurface = Entities.addEntity({ type: "Box", name: "whiteboardDrawingSurface", dimensions: { - x: 1.85, + x: 1.82, y: 1.8, z: 0.04 }, @@ -75,7 +76,7 @@ var whiteboardDrawingSurface = Entities.addEntity({ var WHITEBOARD_RACK_DEPTH = 1.9; -var ERASER_MODEL_URL = "http://hifi-content.s3.amazonaws.com/alan/dev/eraser.fbx"; +var ERASER_MODEL_URL = "http://hifi-content.s3.amazonaws.com/alan/dev/eraser-2.fbx"; var ERASER_SCRIPT_URL = Script.resolvePath("eraserEntityScript.js"); var eraserPosition = Vec3.sum(MyAvatar.position, Vec3.multiply(WHITEBOARD_RACK_DEPTH, Quat.getFront(orientation))); eraserPosition = Vec3.sum(eraserPosition, Vec3.multiply(-0.5, Quat.getFront(whiteboardRotation))); @@ -102,7 +103,7 @@ var eraser = Entities.addEntity({ x: 0, y: -0.1, z: 0 - } + }, }); createMarkers(); From 0b569a0fabf2e67120233c00ae08257cd6f9c421 Mon Sep 17 00:00:00 2001 From: ericrius1 Date: Tue, 23 Feb 2016 16:49:03 -0800 Subject: [PATCH 32/58] only show overlay if within painting range --- .../homeContent/whiteboardV2/markerEntityScript.js | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/examples/homeContent/whiteboardV2/markerEntityScript.js b/examples/homeContent/whiteboardV2/markerEntityScript.js index 618a190587..3461e31076 100644 --- a/examples/homeContent/whiteboardV2/markerEntityScript.js +++ b/examples/homeContent/whiteboardV2/markerEntityScript.js @@ -58,13 +58,14 @@ direction: Quat.getFront(markerProps.rotation) } var intersection = Entities.findRayIntersection(pickRay, true, [_this.whiteboard]); - if (intersection.intersects) { + + if (intersection.intersects && Vec3.distance(intersection.intersection, markerProps.position) < _this.MAX_MARKER_TO_BOARD_DISTANCE) { Overlays.editOverlay(_this.laserPointer, { visible: true, position: intersection.intersection }) _this.triggerValue = Controller.getValue(TRIGGER_CONTROLS[_this.hand]); - if (_this.triggerValue > _this.PAINTING_TRIGGER_THRESHOLD && Vec3.distance(intersection.intersection, markerProps.position) < _this.MAX_MARKER_TO_BOARD_DISTANCE) { + if (_this.triggerValue > _this.PAINTING_TRIGGER_THRESHOLD) { _this.paint(intersection.intersection) } else { _this.resetStroke(); @@ -91,7 +92,7 @@ position: position, textures: _this.MARKER_TEXTURE_URL, color: _this.markerColor, - lifetime: 1000 + lifetime: 200 }); _this.linePoints = []; @@ -149,6 +150,9 @@ unload: function() { Overlays.deleteOverlay(_this.laserPointer); + _this.strokes.forEach( function(stroke) { + Entities.deleteEntity(stroke); + }); }, setProperties: function(myId, data) { From 045d542f11d2ffe7766090814bc985e28fd5ebbf Mon Sep 17 00:00:00 2001 From: ericrius1 Date: Tue, 23 Feb 2016 18:03:38 -0800 Subject: [PATCH 33/58] lines no longer disapear after drawing for a while --- examples/homeContent/whiteboardV2/markerEntityScript.js | 7 +++---- examples/homeContent/whiteboardV2/whiteboardSpawner.js | 3 ++- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/examples/homeContent/whiteboardV2/markerEntityScript.js b/examples/homeContent/whiteboardV2/markerEntityScript.js index 3461e31076..8f22910d4f 100644 --- a/examples/homeContent/whiteboardV2/markerEntityScript.js +++ b/examples/homeContent/whiteboardV2/markerEntityScript.js @@ -92,7 +92,7 @@ position: position, textures: _this.MARKER_TEXTURE_URL, color: _this.markerColor, - lifetime: 200 + lifetime: 10 }); _this.linePoints = []; @@ -111,9 +111,9 @@ _this.newStroke(basePosition); } - var localPoint = Vec3.subtract(basePosition, this.strokeBasePosition); + var localPoint = Vec3.subtract(basePosition, _this.strokeBasePosition); localPoint = Vec3.sum(localPoint, Vec3.multiply(_this.whiteboardNormal, _this.strokeForwardOffset)); - _this.strokeForwardOffset += _this.STROKE_FORWARD_OFFSET_INCRERMENT; + _this.strokeForwardOffset -= _this.STROKE_FORWARD_OFFSET_INCRERMENT; if (_this.linePoints.length > 0) { var distance = Vec3.distance(localPoint, _this.linePoints[_this.linePoints.length - 1]); @@ -121,7 +121,6 @@ return; } } - _this.linePoints.push(localPoint); _this.normals.push(_this.whiteboardNormal); this.strokeWidths.push(_this.STROKE_WIDTH); diff --git a/examples/homeContent/whiteboardV2/whiteboardSpawner.js b/examples/homeContent/whiteboardV2/whiteboardSpawner.js index 378bd9ff5c..6d5c74e273 100644 --- a/examples/homeContent/whiteboardV2/whiteboardSpawner.js +++ b/examples/homeContent/whiteboardV2/whiteboardSpawner.js @@ -142,12 +142,13 @@ function createMarkers() { function createMarker(modelURL, markerPosition, markerColor) { - var MARKER_SCRIPT_URL = Script.resolvePath("markerEntityScript.js"); + var MARKER_SCRIPT_URL = Script.resolvePath("markerEntityScript.js?v1" + Math.random()); var marker = Entities.addEntity({ type: "Model", modelURL: modelURL, rotation: markerRotation, shapeType: "box", + name: "marker", dynamic: true, gravity: { x: 0, From 0ff820199420d4c3510dbe5b43523c6e07a53bf0 Mon Sep 17 00:00:00 2001 From: ericrius1 Date: Tue, 23 Feb 2016 18:45:41 -0800 Subject: [PATCH 34/58] fixed line gaps --- .../acAudioSearching/howardAcAudio.js | 248 ++++++++++++++++++ .../acAudioSearching/howardSpawner.js | 248 ++++++++++++++++++ .../whiteboardV2/markerEntityScript.js | 7 +- 3 files changed, 500 insertions(+), 3 deletions(-) create mode 100644 examples/audioExamples/acAudioSearching/howardAcAudio.js create mode 100644 examples/audioExamples/acAudioSearching/howardSpawner.js diff --git a/examples/audioExamples/acAudioSearching/howardAcAudio.js b/examples/audioExamples/acAudioSearching/howardAcAudio.js new file mode 100644 index 0000000000..f5b1302e06 --- /dev/null +++ b/examples/audioExamples/acAudioSearching/howardAcAudio.js @@ -0,0 +1,248 @@ +"use strict"; +/*jslint nomen: true, plusplus: true, vars: true*/ +/*global AvatarList, Entities, EntityViewer, Script, SoundCache, Audio, print, randFloat*/ +// +// ACAudioSearchAndInject.js +// audio +// +// Created by Eric Levin and Howard Stearns 2/1/2016 +// Copyright 2016 High Fidelity, Inc. +// +// Keeps track of all sounds within QUERY_RADIUS of an avatar, where a "sound" is specified in entity userData. +// Inject as many as practical into the audio mixer. +// See acAudioSearchAndCompatibilityEntitySpawner.js. +// +// This implementation takes some precautions to scale well: +// - It doesn't hastle the entity server because it issues at most one octree query every UPDATE_TIME period, regardless of the number of avatars. +// - It does not load itself because it only gathers entities once every UPDATE_TIME period, and only +// checks entity properties for those small number of entities that are currently playing (plus a RECHECK_TIME period examination of all entities). +// This implementation tries to use all the available injectors. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html + +var SOUND_DATA_KEY = "io.highfidelity.soundKey"; // Sound data is specified in userData under this key. +var old_sound_data_key = "soundKey"; // For backwards compatibility. +var QUERY_RADIUS = 50; // meters +var UPDATE_TIME = 100; // ms. We'll update just one thing on this period. +var EXPIRATION_TIME = 5 * 1000; // ms. Remove sounds that have been out of range for this time. +var RECHECK_TIME = 10 * 1000; // ms. Check for new userData properties this often when not currently playing. +// (By not checking most of the time when not playing, we can efficiently go through all entities without getEntityProperties.) +var UPDATES_PER_STATS_LOG = 50; + +var DEFAULT_SOUND_DATA = { + volume: 0.5, // userData cannot specify zero volume with our current method of defaulting. + loop: false, // Default must be false with our current method of defaulting, else there's no way to get a false value. + playbackGap: 1000, // in ms + playbackGapRange: 0 // in ms +}; + +Script.include("../../libraries/utils.js"); +Agent.isAvatar = true; // This puts a robot at 0,0,0, but is currently necessary in order to use AvatarList. + +function ignore() {} + +function debug() { // Display the arguments not just [Object object]. + //print.apply(null, [].map.call(arguments, JSON.stringify)); +} + +EntityViewer.setKeyholeRadius(QUERY_RADIUS); + +// ENTITY DATA CACHE +// +var entityCache = {}; // A dictionary of unexpired EntityData objects. + +function EntityDatum(entityIdentifier) { // Just the data of an entity that we need to know about. + // This data is only use for our sound injection. There is no need to store such info in the replicated entity on everyone's computer. + var that = this; + that.lastUserDataUpdate = 0; // new entity is in need of rechecking user data + // State Transitions: + // no data => no data | sound data | expired + // expired => stop => remove + // sound data => downloading + // downloading => downloading | waiting + // waiting => playing | waiting (if too many already playing) + // playing => update position etc | no data + that.stop = function stop() { + if (!that.sound) { + return; + } + print("stopping sound", entityIdentifier, that.url); + delete that.sound; + delete that.url; + if (!that.injector) { + return; + } + that.injector.stop(); + delete that.injector; + }; + this.update = function stateTransitions(expirationCutoff, userDataCutoff, now) { + if (that.timestamp < expirationCutoff) { // EXPIRED => STOP => REMOVE + that.stop(); // Alternatively, we could fade out and then stop... + delete entityCache[entityIdentifier]; + return; + } + var properties, soundData; // Latest data, pulled from local octree. + // getEntityProperties locks the tree, which competes with the asynchronous processing of queryOctree results. + // Most entity updates are fast and only a very few do getEntityProperties. + + function ensureSoundData() { // We only getEntityProperities when we need to. + if (properties) { + return; + } + properties = Entities.getEntityProperties(entityIdentifier, ['userData', 'position']); + debug("updating", that, properties); + try { + var userData = properties.userData && JSON.parse(properties.userData); + soundData = userData && (userData[SOUND_DATA_KEY] || userData[old_sound_data_key]); // Don't store soundData yet. Let state changes compare. + that.lastUserDataUpdate = now; // But do update these ... + that.url = soundData && soundData.url; + that.playAfter = that.url && now; + } catch (err) { + print(err, properties.userData); + } + } + // Stumbling on big new pile of entities will do a lot of getEntityProperties. Once. + if (that.lastUserDataUpdate < userDataCutoff) { // NO DATA => SOUND DATA + ensureSoundData(); + } + if (!that.url) { // NO DATA => NO DATA + return that.stop(); + } + if (!that.sound) { // SOUND DATA => DOWNLOADING + that.sound = SoundCache.getSound(soundData.url); // SoundCache can manage duplicates better than we can. + } + if (!that.sound.downloaded) { // DOWNLOADING => DOWNLOADING + return; + } + if (that.playAfter > now) { // DOWNLOADING | WAITING => WAITING + return; + } + ensureSoundData(); // We'll play and will need position, so we might as well get soundData, too. + if (soundData.url !== that.url) { // WAITING => NO DATA (update next time around) + return that.stop(); + } + var options = { + position: properties.position, + loop: soundData.loop || DEFAULT_SOUND_DATA.loop, + volume: soundData.volume || DEFAULT_SOUND_DATA.volume + }; + if (!that.injector) { // WAITING => PLAYING | WAITING + debug("starting", that, options); + that.injector = Audio.playSound(that.sound, options); // Might be null if at at injector limit. Will try again later. + if (that.injector) { + print("started", entityIdentifier, that.url); + } else { // Don't hammer ensureSoundData or injector manager. + that.playAfter = now + (soundData.playbackGap || RECHECK_TIME); + } + return; + } + that.injector.setOptions(options); // PLAYING => UPDATE POSITION ETC + if (!that.injector.isPlaying) { // Subtle: a looping sound will not check playbackGap. + var gap = soundData.playbackGap || DEFAULT_SOUND_DATA; + if (gap) { // WAITING => PLAYING + gap = gap + randFloat(-Math.max(gap, soundData.playbackGapRange), soundData.playbackGapRange); // gapRange is bad name. Meant as +/- value. + // Setup next play just once, now. Changes won't be looked at while we wait. + that.playAfter = now + (that.sound.duration * 1000) + gap; + // Subtle: if the restart fails b/c we're at injector limit, we won't try again until next playAfter. + that.injector.restart(); + } else { // PLAYING => NO DATA + that.playAfter = Infinity; + } + } + }; +} + +function internEntityDatum(entityIdentifier, timestamp, avatarPosition, avatar) { + ignore(avatarPosition, avatar); // We could use avatars and/or avatarPositions to prioritize which ones to play. + var entitySound = entityCache[entityIdentifier]; + if (!entitySound) { + entitySound = entityCache[entityIdentifier] = new EntityDatum(entityIdentifier); + } + entitySound.timestamp = timestamp; // Might be updated for multiple avatars. That's fine. +} +var nUpdates = UPDATES_PER_STATS_LOG, + lastStats = Date.now(); + +function updateAllEntityData() { // A fast update of all entities we know about. A few make sounds. + var now = Date.now(), + expirationCutoff = now - EXPIRATION_TIME, + userDataRecheckCutoff = now - RECHECK_TIME; + Object.keys(entityCache).forEach(function(entityIdentifier) { + entityCache[entityIdentifier].update(expirationCutoff, userDataRecheckCutoff, now); + }); + if (nUpdates-- <= 0) { // Report statistics. + // My figures using acAudioSearchCompatibleEntitySpawner.js with ONE user, N_SOUNDS = 2000, N_SILENT_ENTITIES_PER_SOUND = 5: + // audio-mixer: 23% of cpu (on Mac Activity Monitor) + // this script's assignment client: 106% of cpu. (overloaded) + // entities:12003 + // sounds:2000 + // playing:40 (correct) + // millisecondsPerUpdate:135 (100 requested, so behind by 35%. It would be nice to dig into why...) + var stats = { + entities: 0, + sounds: 0, + playing: 0, + millisecondsPerUpdate: (now - lastStats) / UPDATES_PER_STATS_LOG + }; + nUpdates = UPDATES_PER_STATS_LOG; + lastStats = now; + Object.keys(entityCache).forEach(function(entityIdentifier) { + var datum = entityCache[entityIdentifier]; + stats.entities++; + if (datum.url) { + stats.sounds++; + if (datum.injector && datum.injector.isPlaying) { + stats.playing++; + } + } + }); + print(JSON.stringify(stats)); + } +} + +// Update the set of which EntityData we know about. +// + +function updateEntiesForAvatar(avatarIdentifier) { // Just one piece of update work. + // This does at most: + // one queryOctree request of the entity server, and + // one findEntities geometry query of our own octree, and + // a quick internEntityDatum of each of what may be a large number of entityIdentifiers. + // The idea is that this is a nice bounded piece of work that should not be done too frequently. + // However, it means that we won't learn about new entities until, on average (nAvatars * UPDATE_TIME) + query round trip. + var avatar = AvatarList.getAvatar(avatarIdentifier), + avatarPosition = avatar && avatar.position; + if (!avatarPosition) { // No longer here. + return; + } + var timestamp = Date.now(); + EntityViewer.setPosition(avatarPosition); + EntityViewer.queryOctree(); // Requests an update, but there's no telling when we'll actually see different results. + var entities = Entities.findEntities(avatarPosition, QUERY_RADIUS); + debug("found", entities.length, "entities near", avatar.name || "unknown", "at", avatarPosition); + entities.forEach(function(entityIdentifier) { + internEntityDatum(entityIdentifier, timestamp, avatarPosition, avatar); + }); +} + +// Slowly update the set of data we have to work with. +// +var workQueue = []; + +function updateWorkQueueForAvatarsPresent() { // when nothing else to do, fill queue with individual avatar updates + workQueue = AvatarList.getAvatarIdentifiers().map(function(avatarIdentifier) { + return function() { + updateEntiesForAvatar(avatarIdentifier); + }; + }); +} +Script.setInterval(function() { + // There might be thousands of EntityData known to us, but only a few will require any work to update. + updateAllEntityData(); // i.e., this better be pretty fast. + // Each interval, we do no more than one updateEntitiesforAvatar. + if (!workQueue.length) { + workQueue = [updateWorkQueueForAvatarsPresent]; + } + workQueue.pop()(); // There's always one +}, UPDATE_TIME); \ No newline at end of file diff --git a/examples/audioExamples/acAudioSearching/howardSpawner.js b/examples/audioExamples/acAudioSearching/howardSpawner.js new file mode 100644 index 0000000000..f5b1302e06 --- /dev/null +++ b/examples/audioExamples/acAudioSearching/howardSpawner.js @@ -0,0 +1,248 @@ +"use strict"; +/*jslint nomen: true, plusplus: true, vars: true*/ +/*global AvatarList, Entities, EntityViewer, Script, SoundCache, Audio, print, randFloat*/ +// +// ACAudioSearchAndInject.js +// audio +// +// Created by Eric Levin and Howard Stearns 2/1/2016 +// Copyright 2016 High Fidelity, Inc. +// +// Keeps track of all sounds within QUERY_RADIUS of an avatar, where a "sound" is specified in entity userData. +// Inject as many as practical into the audio mixer. +// See acAudioSearchAndCompatibilityEntitySpawner.js. +// +// This implementation takes some precautions to scale well: +// - It doesn't hastle the entity server because it issues at most one octree query every UPDATE_TIME period, regardless of the number of avatars. +// - It does not load itself because it only gathers entities once every UPDATE_TIME period, and only +// checks entity properties for those small number of entities that are currently playing (plus a RECHECK_TIME period examination of all entities). +// This implementation tries to use all the available injectors. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html + +var SOUND_DATA_KEY = "io.highfidelity.soundKey"; // Sound data is specified in userData under this key. +var old_sound_data_key = "soundKey"; // For backwards compatibility. +var QUERY_RADIUS = 50; // meters +var UPDATE_TIME = 100; // ms. We'll update just one thing on this period. +var EXPIRATION_TIME = 5 * 1000; // ms. Remove sounds that have been out of range for this time. +var RECHECK_TIME = 10 * 1000; // ms. Check for new userData properties this often when not currently playing. +// (By not checking most of the time when not playing, we can efficiently go through all entities without getEntityProperties.) +var UPDATES_PER_STATS_LOG = 50; + +var DEFAULT_SOUND_DATA = { + volume: 0.5, // userData cannot specify zero volume with our current method of defaulting. + loop: false, // Default must be false with our current method of defaulting, else there's no way to get a false value. + playbackGap: 1000, // in ms + playbackGapRange: 0 // in ms +}; + +Script.include("../../libraries/utils.js"); +Agent.isAvatar = true; // This puts a robot at 0,0,0, but is currently necessary in order to use AvatarList. + +function ignore() {} + +function debug() { // Display the arguments not just [Object object]. + //print.apply(null, [].map.call(arguments, JSON.stringify)); +} + +EntityViewer.setKeyholeRadius(QUERY_RADIUS); + +// ENTITY DATA CACHE +// +var entityCache = {}; // A dictionary of unexpired EntityData objects. + +function EntityDatum(entityIdentifier) { // Just the data of an entity that we need to know about. + // This data is only use for our sound injection. There is no need to store such info in the replicated entity on everyone's computer. + var that = this; + that.lastUserDataUpdate = 0; // new entity is in need of rechecking user data + // State Transitions: + // no data => no data | sound data | expired + // expired => stop => remove + // sound data => downloading + // downloading => downloading | waiting + // waiting => playing | waiting (if too many already playing) + // playing => update position etc | no data + that.stop = function stop() { + if (!that.sound) { + return; + } + print("stopping sound", entityIdentifier, that.url); + delete that.sound; + delete that.url; + if (!that.injector) { + return; + } + that.injector.stop(); + delete that.injector; + }; + this.update = function stateTransitions(expirationCutoff, userDataCutoff, now) { + if (that.timestamp < expirationCutoff) { // EXPIRED => STOP => REMOVE + that.stop(); // Alternatively, we could fade out and then stop... + delete entityCache[entityIdentifier]; + return; + } + var properties, soundData; // Latest data, pulled from local octree. + // getEntityProperties locks the tree, which competes with the asynchronous processing of queryOctree results. + // Most entity updates are fast and only a very few do getEntityProperties. + + function ensureSoundData() { // We only getEntityProperities when we need to. + if (properties) { + return; + } + properties = Entities.getEntityProperties(entityIdentifier, ['userData', 'position']); + debug("updating", that, properties); + try { + var userData = properties.userData && JSON.parse(properties.userData); + soundData = userData && (userData[SOUND_DATA_KEY] || userData[old_sound_data_key]); // Don't store soundData yet. Let state changes compare. + that.lastUserDataUpdate = now; // But do update these ... + that.url = soundData && soundData.url; + that.playAfter = that.url && now; + } catch (err) { + print(err, properties.userData); + } + } + // Stumbling on big new pile of entities will do a lot of getEntityProperties. Once. + if (that.lastUserDataUpdate < userDataCutoff) { // NO DATA => SOUND DATA + ensureSoundData(); + } + if (!that.url) { // NO DATA => NO DATA + return that.stop(); + } + if (!that.sound) { // SOUND DATA => DOWNLOADING + that.sound = SoundCache.getSound(soundData.url); // SoundCache can manage duplicates better than we can. + } + if (!that.sound.downloaded) { // DOWNLOADING => DOWNLOADING + return; + } + if (that.playAfter > now) { // DOWNLOADING | WAITING => WAITING + return; + } + ensureSoundData(); // We'll play and will need position, so we might as well get soundData, too. + if (soundData.url !== that.url) { // WAITING => NO DATA (update next time around) + return that.stop(); + } + var options = { + position: properties.position, + loop: soundData.loop || DEFAULT_SOUND_DATA.loop, + volume: soundData.volume || DEFAULT_SOUND_DATA.volume + }; + if (!that.injector) { // WAITING => PLAYING | WAITING + debug("starting", that, options); + that.injector = Audio.playSound(that.sound, options); // Might be null if at at injector limit. Will try again later. + if (that.injector) { + print("started", entityIdentifier, that.url); + } else { // Don't hammer ensureSoundData or injector manager. + that.playAfter = now + (soundData.playbackGap || RECHECK_TIME); + } + return; + } + that.injector.setOptions(options); // PLAYING => UPDATE POSITION ETC + if (!that.injector.isPlaying) { // Subtle: a looping sound will not check playbackGap. + var gap = soundData.playbackGap || DEFAULT_SOUND_DATA; + if (gap) { // WAITING => PLAYING + gap = gap + randFloat(-Math.max(gap, soundData.playbackGapRange), soundData.playbackGapRange); // gapRange is bad name. Meant as +/- value. + // Setup next play just once, now. Changes won't be looked at while we wait. + that.playAfter = now + (that.sound.duration * 1000) + gap; + // Subtle: if the restart fails b/c we're at injector limit, we won't try again until next playAfter. + that.injector.restart(); + } else { // PLAYING => NO DATA + that.playAfter = Infinity; + } + } + }; +} + +function internEntityDatum(entityIdentifier, timestamp, avatarPosition, avatar) { + ignore(avatarPosition, avatar); // We could use avatars and/or avatarPositions to prioritize which ones to play. + var entitySound = entityCache[entityIdentifier]; + if (!entitySound) { + entitySound = entityCache[entityIdentifier] = new EntityDatum(entityIdentifier); + } + entitySound.timestamp = timestamp; // Might be updated for multiple avatars. That's fine. +} +var nUpdates = UPDATES_PER_STATS_LOG, + lastStats = Date.now(); + +function updateAllEntityData() { // A fast update of all entities we know about. A few make sounds. + var now = Date.now(), + expirationCutoff = now - EXPIRATION_TIME, + userDataRecheckCutoff = now - RECHECK_TIME; + Object.keys(entityCache).forEach(function(entityIdentifier) { + entityCache[entityIdentifier].update(expirationCutoff, userDataRecheckCutoff, now); + }); + if (nUpdates-- <= 0) { // Report statistics. + // My figures using acAudioSearchCompatibleEntitySpawner.js with ONE user, N_SOUNDS = 2000, N_SILENT_ENTITIES_PER_SOUND = 5: + // audio-mixer: 23% of cpu (on Mac Activity Monitor) + // this script's assignment client: 106% of cpu. (overloaded) + // entities:12003 + // sounds:2000 + // playing:40 (correct) + // millisecondsPerUpdate:135 (100 requested, so behind by 35%. It would be nice to dig into why...) + var stats = { + entities: 0, + sounds: 0, + playing: 0, + millisecondsPerUpdate: (now - lastStats) / UPDATES_PER_STATS_LOG + }; + nUpdates = UPDATES_PER_STATS_LOG; + lastStats = now; + Object.keys(entityCache).forEach(function(entityIdentifier) { + var datum = entityCache[entityIdentifier]; + stats.entities++; + if (datum.url) { + stats.sounds++; + if (datum.injector && datum.injector.isPlaying) { + stats.playing++; + } + } + }); + print(JSON.stringify(stats)); + } +} + +// Update the set of which EntityData we know about. +// + +function updateEntiesForAvatar(avatarIdentifier) { // Just one piece of update work. + // This does at most: + // one queryOctree request of the entity server, and + // one findEntities geometry query of our own octree, and + // a quick internEntityDatum of each of what may be a large number of entityIdentifiers. + // The idea is that this is a nice bounded piece of work that should not be done too frequently. + // However, it means that we won't learn about new entities until, on average (nAvatars * UPDATE_TIME) + query round trip. + var avatar = AvatarList.getAvatar(avatarIdentifier), + avatarPosition = avatar && avatar.position; + if (!avatarPosition) { // No longer here. + return; + } + var timestamp = Date.now(); + EntityViewer.setPosition(avatarPosition); + EntityViewer.queryOctree(); // Requests an update, but there's no telling when we'll actually see different results. + var entities = Entities.findEntities(avatarPosition, QUERY_RADIUS); + debug("found", entities.length, "entities near", avatar.name || "unknown", "at", avatarPosition); + entities.forEach(function(entityIdentifier) { + internEntityDatum(entityIdentifier, timestamp, avatarPosition, avatar); + }); +} + +// Slowly update the set of data we have to work with. +// +var workQueue = []; + +function updateWorkQueueForAvatarsPresent() { // when nothing else to do, fill queue with individual avatar updates + workQueue = AvatarList.getAvatarIdentifiers().map(function(avatarIdentifier) { + return function() { + updateEntiesForAvatar(avatarIdentifier); + }; + }); +} +Script.setInterval(function() { + // There might be thousands of EntityData known to us, but only a few will require any work to update. + updateAllEntityData(); // i.e., this better be pretty fast. + // Each interval, we do no more than one updateEntitiesforAvatar. + if (!workQueue.length) { + workQueue = [updateWorkQueueForAvatarsPresent]; + } + workQueue.pop()(); // There's always one +}, UPDATE_TIME); \ No newline at end of file diff --git a/examples/homeContent/whiteboardV2/markerEntityScript.js b/examples/homeContent/whiteboardV2/markerEntityScript.js index 8f22910d4f..761ef00e33 100644 --- a/examples/homeContent/whiteboardV2/markerEntityScript.js +++ b/examples/homeContent/whiteboardV2/markerEntityScript.js @@ -57,7 +57,7 @@ origin: markerProps.position, direction: Quat.getFront(markerProps.rotation) } - var intersection = Entities.findRayIntersection(pickRay, true, [_this.whiteboard]); + var intersection = Entities.findRayIntersectionBlocking(pickRay, true, [_this.whiteboard]); if (intersection.intersects && Vec3.distance(intersection.intersection, markerProps.position) < _this.MAX_MARKER_TO_BOARD_DISTANCE) { Overlays.editOverlay(_this.laserPointer, { @@ -71,7 +71,8 @@ _this.resetStroke(); } } else { - _this.resetStroke(); + _this.resetStroke(); + Overlays.editOverlay(_this.laserPointer, { visible: false }); @@ -92,7 +93,7 @@ position: position, textures: _this.MARKER_TEXTURE_URL, color: _this.markerColor, - lifetime: 10 + lifetime: 500 }); _this.linePoints = []; From 67ec1732b348e44539770bfddeeaa9239ab429fc Mon Sep 17 00:00:00 2001 From: ericrius1 Date: Tue, 23 Feb 2016 18:46:38 -0800 Subject: [PATCH 35/58] increased eraser range --- examples/homeContent/whiteboardV2/eraserEntityScript.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/homeContent/whiteboardV2/eraserEntityScript.js b/examples/homeContent/whiteboardV2/eraserEntityScript.js index 89ce4aded6..66399a9b8e 100644 --- a/examples/homeContent/whiteboardV2/eraserEntityScript.js +++ b/examples/homeContent/whiteboardV2/eraserEntityScript.js @@ -21,9 +21,9 @@ Eraser = function() { _this = this; - _this.ERASER_TRIGGER_THRESHOLD = 0.1; + _this.ERASER_TRIGGER_THRESHOLD = 0.2; _this.STROKE_NAME = "hifi-marker-stroke"; - _this.ERASER_TO_STROKE_SEARCH_RADIUS = 0.4; + _this.ERASER_TO_STROKE_SEARCH_RADIUS = 0.7; }; Eraser.prototype = { From ef85d0451a4008bf94333dee674858f220244a7e Mon Sep 17 00:00:00 2001 From: ericrius1 Date: Thu, 25 Feb 2016 14:24:06 -0800 Subject: [PATCH 36/58] removed files that shouldn't be there --- .../acAudioSearching/howardAcAudio.js | 248 ------------------ .../acAudioSearching/howardSpawner.js | 248 ------------------ 2 files changed, 496 deletions(-) delete mode 100644 examples/audioExamples/acAudioSearching/howardAcAudio.js delete mode 100644 examples/audioExamples/acAudioSearching/howardSpawner.js diff --git a/examples/audioExamples/acAudioSearching/howardAcAudio.js b/examples/audioExamples/acAudioSearching/howardAcAudio.js deleted file mode 100644 index f5b1302e06..0000000000 --- a/examples/audioExamples/acAudioSearching/howardAcAudio.js +++ /dev/null @@ -1,248 +0,0 @@ -"use strict"; -/*jslint nomen: true, plusplus: true, vars: true*/ -/*global AvatarList, Entities, EntityViewer, Script, SoundCache, Audio, print, randFloat*/ -// -// ACAudioSearchAndInject.js -// audio -// -// Created by Eric Levin and Howard Stearns 2/1/2016 -// Copyright 2016 High Fidelity, Inc. -// -// Keeps track of all sounds within QUERY_RADIUS of an avatar, where a "sound" is specified in entity userData. -// Inject as many as practical into the audio mixer. -// See acAudioSearchAndCompatibilityEntitySpawner.js. -// -// This implementation takes some precautions to scale well: -// - It doesn't hastle the entity server because it issues at most one octree query every UPDATE_TIME period, regardless of the number of avatars. -// - It does not load itself because it only gathers entities once every UPDATE_TIME period, and only -// checks entity properties for those small number of entities that are currently playing (plus a RECHECK_TIME period examination of all entities). -// This implementation tries to use all the available injectors. -// -// Distributed under the Apache License, Version 2.0. -// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html - -var SOUND_DATA_KEY = "io.highfidelity.soundKey"; // Sound data is specified in userData under this key. -var old_sound_data_key = "soundKey"; // For backwards compatibility. -var QUERY_RADIUS = 50; // meters -var UPDATE_TIME = 100; // ms. We'll update just one thing on this period. -var EXPIRATION_TIME = 5 * 1000; // ms. Remove sounds that have been out of range for this time. -var RECHECK_TIME = 10 * 1000; // ms. Check for new userData properties this often when not currently playing. -// (By not checking most of the time when not playing, we can efficiently go through all entities without getEntityProperties.) -var UPDATES_PER_STATS_LOG = 50; - -var DEFAULT_SOUND_DATA = { - volume: 0.5, // userData cannot specify zero volume with our current method of defaulting. - loop: false, // Default must be false with our current method of defaulting, else there's no way to get a false value. - playbackGap: 1000, // in ms - playbackGapRange: 0 // in ms -}; - -Script.include("../../libraries/utils.js"); -Agent.isAvatar = true; // This puts a robot at 0,0,0, but is currently necessary in order to use AvatarList. - -function ignore() {} - -function debug() { // Display the arguments not just [Object object]. - //print.apply(null, [].map.call(arguments, JSON.stringify)); -} - -EntityViewer.setKeyholeRadius(QUERY_RADIUS); - -// ENTITY DATA CACHE -// -var entityCache = {}; // A dictionary of unexpired EntityData objects. - -function EntityDatum(entityIdentifier) { // Just the data of an entity that we need to know about. - // This data is only use for our sound injection. There is no need to store such info in the replicated entity on everyone's computer. - var that = this; - that.lastUserDataUpdate = 0; // new entity is in need of rechecking user data - // State Transitions: - // no data => no data | sound data | expired - // expired => stop => remove - // sound data => downloading - // downloading => downloading | waiting - // waiting => playing | waiting (if too many already playing) - // playing => update position etc | no data - that.stop = function stop() { - if (!that.sound) { - return; - } - print("stopping sound", entityIdentifier, that.url); - delete that.sound; - delete that.url; - if (!that.injector) { - return; - } - that.injector.stop(); - delete that.injector; - }; - this.update = function stateTransitions(expirationCutoff, userDataCutoff, now) { - if (that.timestamp < expirationCutoff) { // EXPIRED => STOP => REMOVE - that.stop(); // Alternatively, we could fade out and then stop... - delete entityCache[entityIdentifier]; - return; - } - var properties, soundData; // Latest data, pulled from local octree. - // getEntityProperties locks the tree, which competes with the asynchronous processing of queryOctree results. - // Most entity updates are fast and only a very few do getEntityProperties. - - function ensureSoundData() { // We only getEntityProperities when we need to. - if (properties) { - return; - } - properties = Entities.getEntityProperties(entityIdentifier, ['userData', 'position']); - debug("updating", that, properties); - try { - var userData = properties.userData && JSON.parse(properties.userData); - soundData = userData && (userData[SOUND_DATA_KEY] || userData[old_sound_data_key]); // Don't store soundData yet. Let state changes compare. - that.lastUserDataUpdate = now; // But do update these ... - that.url = soundData && soundData.url; - that.playAfter = that.url && now; - } catch (err) { - print(err, properties.userData); - } - } - // Stumbling on big new pile of entities will do a lot of getEntityProperties. Once. - if (that.lastUserDataUpdate < userDataCutoff) { // NO DATA => SOUND DATA - ensureSoundData(); - } - if (!that.url) { // NO DATA => NO DATA - return that.stop(); - } - if (!that.sound) { // SOUND DATA => DOWNLOADING - that.sound = SoundCache.getSound(soundData.url); // SoundCache can manage duplicates better than we can. - } - if (!that.sound.downloaded) { // DOWNLOADING => DOWNLOADING - return; - } - if (that.playAfter > now) { // DOWNLOADING | WAITING => WAITING - return; - } - ensureSoundData(); // We'll play and will need position, so we might as well get soundData, too. - if (soundData.url !== that.url) { // WAITING => NO DATA (update next time around) - return that.stop(); - } - var options = { - position: properties.position, - loop: soundData.loop || DEFAULT_SOUND_DATA.loop, - volume: soundData.volume || DEFAULT_SOUND_DATA.volume - }; - if (!that.injector) { // WAITING => PLAYING | WAITING - debug("starting", that, options); - that.injector = Audio.playSound(that.sound, options); // Might be null if at at injector limit. Will try again later. - if (that.injector) { - print("started", entityIdentifier, that.url); - } else { // Don't hammer ensureSoundData or injector manager. - that.playAfter = now + (soundData.playbackGap || RECHECK_TIME); - } - return; - } - that.injector.setOptions(options); // PLAYING => UPDATE POSITION ETC - if (!that.injector.isPlaying) { // Subtle: a looping sound will not check playbackGap. - var gap = soundData.playbackGap || DEFAULT_SOUND_DATA; - if (gap) { // WAITING => PLAYING - gap = gap + randFloat(-Math.max(gap, soundData.playbackGapRange), soundData.playbackGapRange); // gapRange is bad name. Meant as +/- value. - // Setup next play just once, now. Changes won't be looked at while we wait. - that.playAfter = now + (that.sound.duration * 1000) + gap; - // Subtle: if the restart fails b/c we're at injector limit, we won't try again until next playAfter. - that.injector.restart(); - } else { // PLAYING => NO DATA - that.playAfter = Infinity; - } - } - }; -} - -function internEntityDatum(entityIdentifier, timestamp, avatarPosition, avatar) { - ignore(avatarPosition, avatar); // We could use avatars and/or avatarPositions to prioritize which ones to play. - var entitySound = entityCache[entityIdentifier]; - if (!entitySound) { - entitySound = entityCache[entityIdentifier] = new EntityDatum(entityIdentifier); - } - entitySound.timestamp = timestamp; // Might be updated for multiple avatars. That's fine. -} -var nUpdates = UPDATES_PER_STATS_LOG, - lastStats = Date.now(); - -function updateAllEntityData() { // A fast update of all entities we know about. A few make sounds. - var now = Date.now(), - expirationCutoff = now - EXPIRATION_TIME, - userDataRecheckCutoff = now - RECHECK_TIME; - Object.keys(entityCache).forEach(function(entityIdentifier) { - entityCache[entityIdentifier].update(expirationCutoff, userDataRecheckCutoff, now); - }); - if (nUpdates-- <= 0) { // Report statistics. - // My figures using acAudioSearchCompatibleEntitySpawner.js with ONE user, N_SOUNDS = 2000, N_SILENT_ENTITIES_PER_SOUND = 5: - // audio-mixer: 23% of cpu (on Mac Activity Monitor) - // this script's assignment client: 106% of cpu. (overloaded) - // entities:12003 - // sounds:2000 - // playing:40 (correct) - // millisecondsPerUpdate:135 (100 requested, so behind by 35%. It would be nice to dig into why...) - var stats = { - entities: 0, - sounds: 0, - playing: 0, - millisecondsPerUpdate: (now - lastStats) / UPDATES_PER_STATS_LOG - }; - nUpdates = UPDATES_PER_STATS_LOG; - lastStats = now; - Object.keys(entityCache).forEach(function(entityIdentifier) { - var datum = entityCache[entityIdentifier]; - stats.entities++; - if (datum.url) { - stats.sounds++; - if (datum.injector && datum.injector.isPlaying) { - stats.playing++; - } - } - }); - print(JSON.stringify(stats)); - } -} - -// Update the set of which EntityData we know about. -// - -function updateEntiesForAvatar(avatarIdentifier) { // Just one piece of update work. - // This does at most: - // one queryOctree request of the entity server, and - // one findEntities geometry query of our own octree, and - // a quick internEntityDatum of each of what may be a large number of entityIdentifiers. - // The idea is that this is a nice bounded piece of work that should not be done too frequently. - // However, it means that we won't learn about new entities until, on average (nAvatars * UPDATE_TIME) + query round trip. - var avatar = AvatarList.getAvatar(avatarIdentifier), - avatarPosition = avatar && avatar.position; - if (!avatarPosition) { // No longer here. - return; - } - var timestamp = Date.now(); - EntityViewer.setPosition(avatarPosition); - EntityViewer.queryOctree(); // Requests an update, but there's no telling when we'll actually see different results. - var entities = Entities.findEntities(avatarPosition, QUERY_RADIUS); - debug("found", entities.length, "entities near", avatar.name || "unknown", "at", avatarPosition); - entities.forEach(function(entityIdentifier) { - internEntityDatum(entityIdentifier, timestamp, avatarPosition, avatar); - }); -} - -// Slowly update the set of data we have to work with. -// -var workQueue = []; - -function updateWorkQueueForAvatarsPresent() { // when nothing else to do, fill queue with individual avatar updates - workQueue = AvatarList.getAvatarIdentifiers().map(function(avatarIdentifier) { - return function() { - updateEntiesForAvatar(avatarIdentifier); - }; - }); -} -Script.setInterval(function() { - // There might be thousands of EntityData known to us, but only a few will require any work to update. - updateAllEntityData(); // i.e., this better be pretty fast. - // Each interval, we do no more than one updateEntitiesforAvatar. - if (!workQueue.length) { - workQueue = [updateWorkQueueForAvatarsPresent]; - } - workQueue.pop()(); // There's always one -}, UPDATE_TIME); \ No newline at end of file diff --git a/examples/audioExamples/acAudioSearching/howardSpawner.js b/examples/audioExamples/acAudioSearching/howardSpawner.js deleted file mode 100644 index f5b1302e06..0000000000 --- a/examples/audioExamples/acAudioSearching/howardSpawner.js +++ /dev/null @@ -1,248 +0,0 @@ -"use strict"; -/*jslint nomen: true, plusplus: true, vars: true*/ -/*global AvatarList, Entities, EntityViewer, Script, SoundCache, Audio, print, randFloat*/ -// -// ACAudioSearchAndInject.js -// audio -// -// Created by Eric Levin and Howard Stearns 2/1/2016 -// Copyright 2016 High Fidelity, Inc. -// -// Keeps track of all sounds within QUERY_RADIUS of an avatar, where a "sound" is specified in entity userData. -// Inject as many as practical into the audio mixer. -// See acAudioSearchAndCompatibilityEntitySpawner.js. -// -// This implementation takes some precautions to scale well: -// - It doesn't hastle the entity server because it issues at most one octree query every UPDATE_TIME period, regardless of the number of avatars. -// - It does not load itself because it only gathers entities once every UPDATE_TIME period, and only -// checks entity properties for those small number of entities that are currently playing (plus a RECHECK_TIME period examination of all entities). -// This implementation tries to use all the available injectors. -// -// Distributed under the Apache License, Version 2.0. -// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html - -var SOUND_DATA_KEY = "io.highfidelity.soundKey"; // Sound data is specified in userData under this key. -var old_sound_data_key = "soundKey"; // For backwards compatibility. -var QUERY_RADIUS = 50; // meters -var UPDATE_TIME = 100; // ms. We'll update just one thing on this period. -var EXPIRATION_TIME = 5 * 1000; // ms. Remove sounds that have been out of range for this time. -var RECHECK_TIME = 10 * 1000; // ms. Check for new userData properties this often when not currently playing. -// (By not checking most of the time when not playing, we can efficiently go through all entities without getEntityProperties.) -var UPDATES_PER_STATS_LOG = 50; - -var DEFAULT_SOUND_DATA = { - volume: 0.5, // userData cannot specify zero volume with our current method of defaulting. - loop: false, // Default must be false with our current method of defaulting, else there's no way to get a false value. - playbackGap: 1000, // in ms - playbackGapRange: 0 // in ms -}; - -Script.include("../../libraries/utils.js"); -Agent.isAvatar = true; // This puts a robot at 0,0,0, but is currently necessary in order to use AvatarList. - -function ignore() {} - -function debug() { // Display the arguments not just [Object object]. - //print.apply(null, [].map.call(arguments, JSON.stringify)); -} - -EntityViewer.setKeyholeRadius(QUERY_RADIUS); - -// ENTITY DATA CACHE -// -var entityCache = {}; // A dictionary of unexpired EntityData objects. - -function EntityDatum(entityIdentifier) { // Just the data of an entity that we need to know about. - // This data is only use for our sound injection. There is no need to store such info in the replicated entity on everyone's computer. - var that = this; - that.lastUserDataUpdate = 0; // new entity is in need of rechecking user data - // State Transitions: - // no data => no data | sound data | expired - // expired => stop => remove - // sound data => downloading - // downloading => downloading | waiting - // waiting => playing | waiting (if too many already playing) - // playing => update position etc | no data - that.stop = function stop() { - if (!that.sound) { - return; - } - print("stopping sound", entityIdentifier, that.url); - delete that.sound; - delete that.url; - if (!that.injector) { - return; - } - that.injector.stop(); - delete that.injector; - }; - this.update = function stateTransitions(expirationCutoff, userDataCutoff, now) { - if (that.timestamp < expirationCutoff) { // EXPIRED => STOP => REMOVE - that.stop(); // Alternatively, we could fade out and then stop... - delete entityCache[entityIdentifier]; - return; - } - var properties, soundData; // Latest data, pulled from local octree. - // getEntityProperties locks the tree, which competes with the asynchronous processing of queryOctree results. - // Most entity updates are fast and only a very few do getEntityProperties. - - function ensureSoundData() { // We only getEntityProperities when we need to. - if (properties) { - return; - } - properties = Entities.getEntityProperties(entityIdentifier, ['userData', 'position']); - debug("updating", that, properties); - try { - var userData = properties.userData && JSON.parse(properties.userData); - soundData = userData && (userData[SOUND_DATA_KEY] || userData[old_sound_data_key]); // Don't store soundData yet. Let state changes compare. - that.lastUserDataUpdate = now; // But do update these ... - that.url = soundData && soundData.url; - that.playAfter = that.url && now; - } catch (err) { - print(err, properties.userData); - } - } - // Stumbling on big new pile of entities will do a lot of getEntityProperties. Once. - if (that.lastUserDataUpdate < userDataCutoff) { // NO DATA => SOUND DATA - ensureSoundData(); - } - if (!that.url) { // NO DATA => NO DATA - return that.stop(); - } - if (!that.sound) { // SOUND DATA => DOWNLOADING - that.sound = SoundCache.getSound(soundData.url); // SoundCache can manage duplicates better than we can. - } - if (!that.sound.downloaded) { // DOWNLOADING => DOWNLOADING - return; - } - if (that.playAfter > now) { // DOWNLOADING | WAITING => WAITING - return; - } - ensureSoundData(); // We'll play and will need position, so we might as well get soundData, too. - if (soundData.url !== that.url) { // WAITING => NO DATA (update next time around) - return that.stop(); - } - var options = { - position: properties.position, - loop: soundData.loop || DEFAULT_SOUND_DATA.loop, - volume: soundData.volume || DEFAULT_SOUND_DATA.volume - }; - if (!that.injector) { // WAITING => PLAYING | WAITING - debug("starting", that, options); - that.injector = Audio.playSound(that.sound, options); // Might be null if at at injector limit. Will try again later. - if (that.injector) { - print("started", entityIdentifier, that.url); - } else { // Don't hammer ensureSoundData or injector manager. - that.playAfter = now + (soundData.playbackGap || RECHECK_TIME); - } - return; - } - that.injector.setOptions(options); // PLAYING => UPDATE POSITION ETC - if (!that.injector.isPlaying) { // Subtle: a looping sound will not check playbackGap. - var gap = soundData.playbackGap || DEFAULT_SOUND_DATA; - if (gap) { // WAITING => PLAYING - gap = gap + randFloat(-Math.max(gap, soundData.playbackGapRange), soundData.playbackGapRange); // gapRange is bad name. Meant as +/- value. - // Setup next play just once, now. Changes won't be looked at while we wait. - that.playAfter = now + (that.sound.duration * 1000) + gap; - // Subtle: if the restart fails b/c we're at injector limit, we won't try again until next playAfter. - that.injector.restart(); - } else { // PLAYING => NO DATA - that.playAfter = Infinity; - } - } - }; -} - -function internEntityDatum(entityIdentifier, timestamp, avatarPosition, avatar) { - ignore(avatarPosition, avatar); // We could use avatars and/or avatarPositions to prioritize which ones to play. - var entitySound = entityCache[entityIdentifier]; - if (!entitySound) { - entitySound = entityCache[entityIdentifier] = new EntityDatum(entityIdentifier); - } - entitySound.timestamp = timestamp; // Might be updated for multiple avatars. That's fine. -} -var nUpdates = UPDATES_PER_STATS_LOG, - lastStats = Date.now(); - -function updateAllEntityData() { // A fast update of all entities we know about. A few make sounds. - var now = Date.now(), - expirationCutoff = now - EXPIRATION_TIME, - userDataRecheckCutoff = now - RECHECK_TIME; - Object.keys(entityCache).forEach(function(entityIdentifier) { - entityCache[entityIdentifier].update(expirationCutoff, userDataRecheckCutoff, now); - }); - if (nUpdates-- <= 0) { // Report statistics. - // My figures using acAudioSearchCompatibleEntitySpawner.js with ONE user, N_SOUNDS = 2000, N_SILENT_ENTITIES_PER_SOUND = 5: - // audio-mixer: 23% of cpu (on Mac Activity Monitor) - // this script's assignment client: 106% of cpu. (overloaded) - // entities:12003 - // sounds:2000 - // playing:40 (correct) - // millisecondsPerUpdate:135 (100 requested, so behind by 35%. It would be nice to dig into why...) - var stats = { - entities: 0, - sounds: 0, - playing: 0, - millisecondsPerUpdate: (now - lastStats) / UPDATES_PER_STATS_LOG - }; - nUpdates = UPDATES_PER_STATS_LOG; - lastStats = now; - Object.keys(entityCache).forEach(function(entityIdentifier) { - var datum = entityCache[entityIdentifier]; - stats.entities++; - if (datum.url) { - stats.sounds++; - if (datum.injector && datum.injector.isPlaying) { - stats.playing++; - } - } - }); - print(JSON.stringify(stats)); - } -} - -// Update the set of which EntityData we know about. -// - -function updateEntiesForAvatar(avatarIdentifier) { // Just one piece of update work. - // This does at most: - // one queryOctree request of the entity server, and - // one findEntities geometry query of our own octree, and - // a quick internEntityDatum of each of what may be a large number of entityIdentifiers. - // The idea is that this is a nice bounded piece of work that should not be done too frequently. - // However, it means that we won't learn about new entities until, on average (nAvatars * UPDATE_TIME) + query round trip. - var avatar = AvatarList.getAvatar(avatarIdentifier), - avatarPosition = avatar && avatar.position; - if (!avatarPosition) { // No longer here. - return; - } - var timestamp = Date.now(); - EntityViewer.setPosition(avatarPosition); - EntityViewer.queryOctree(); // Requests an update, but there's no telling when we'll actually see different results. - var entities = Entities.findEntities(avatarPosition, QUERY_RADIUS); - debug("found", entities.length, "entities near", avatar.name || "unknown", "at", avatarPosition); - entities.forEach(function(entityIdentifier) { - internEntityDatum(entityIdentifier, timestamp, avatarPosition, avatar); - }); -} - -// Slowly update the set of data we have to work with. -// -var workQueue = []; - -function updateWorkQueueForAvatarsPresent() { // when nothing else to do, fill queue with individual avatar updates - workQueue = AvatarList.getAvatarIdentifiers().map(function(avatarIdentifier) { - return function() { - updateEntiesForAvatar(avatarIdentifier); - }; - }); -} -Script.setInterval(function() { - // There might be thousands of EntityData known to us, but only a few will require any work to update. - updateAllEntityData(); // i.e., this better be pretty fast. - // Each interval, we do no more than one updateEntitiesforAvatar. - if (!workQueue.length) { - workQueue = [updateWorkQueueForAvatarsPresent]; - } - workQueue.pop()(); // There's always one -}, UPDATE_TIME); \ No newline at end of file From e9ad06fca767f0d7e899b025a159e1a67d3c55a5 Mon Sep 17 00:00:00 2001 From: ericrius1 Date: Thu, 25 Feb 2016 14:25:12 -0800 Subject: [PATCH 37/58] removed query string --- examples/homeContent/whiteboardV2/whiteboardSpawner.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/homeContent/whiteboardV2/whiteboardSpawner.js b/examples/homeContent/whiteboardV2/whiteboardSpawner.js index 6d5c74e273..17c44eae41 100644 --- a/examples/homeContent/whiteboardV2/whiteboardSpawner.js +++ b/examples/homeContent/whiteboardV2/whiteboardSpawner.js @@ -142,7 +142,7 @@ function createMarkers() { function createMarker(modelURL, markerPosition, markerColor) { - var MARKER_SCRIPT_URL = Script.resolvePath("markerEntityScript.js?v1" + Math.random()); + var MARKER_SCRIPT_URL = Script.resolvePath("markerEntityScript.js"); var marker = Entities.addEntity({ type: "Model", modelURL: modelURL, From 338427ed3e11a5556d401b6ca46c1a1b865575cc Mon Sep 17 00:00:00 2001 From: ericrius1 Date: Thu, 25 Feb 2016 14:28:35 -0800 Subject: [PATCH 38/58] wait longer before sending message --- examples/homeContent/whiteboardV2/whiteboardSpawner.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/homeContent/whiteboardV2/whiteboardSpawner.js b/examples/homeContent/whiteboardV2/whiteboardSpawner.js index 17c44eae41..3d63eb4643 100644 --- a/examples/homeContent/whiteboardV2/whiteboardSpawner.js +++ b/examples/homeContent/whiteboardV2/whiteboardSpawner.js @@ -206,7 +206,7 @@ function createMarker(modelURL, markerPosition, markerColor) { var modelURL = Entities.getEntityProperties(marker, "modelURL").modelURL; Entities.callEntityMethod(marker, "setProperties", [JSON.stringify(data)]); - }, 1000) + }, 2000) } From 22a5f3dcc0aca96ee2439be2ad62590013dfe3a6 Mon Sep 17 00:00:00 2001 From: ericrius1 Date: Thu, 25 Feb 2016 14:28:48 -0800 Subject: [PATCH 39/58] wait even longer --- examples/homeContent/whiteboardV2/whiteboardSpawner.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/homeContent/whiteboardV2/whiteboardSpawner.js b/examples/homeContent/whiteboardV2/whiteboardSpawner.js index 3d63eb4643..2974db8f59 100644 --- a/examples/homeContent/whiteboardV2/whiteboardSpawner.js +++ b/examples/homeContent/whiteboardV2/whiteboardSpawner.js @@ -206,7 +206,7 @@ function createMarker(modelURL, markerPosition, markerColor) { var modelURL = Entities.getEntityProperties(marker, "modelURL").modelURL; Entities.callEntityMethod(marker, "setProperties", [JSON.stringify(data)]); - }, 2000) + }, 3000) } From 4de951242cb63558d06e62ec1af83766083c8712 Mon Sep 17 00:00:00 2001 From: ericrius1 Date: Thu, 25 Feb 2016 14:54:34 -0800 Subject: [PATCH 40/58] eraser positioned correctly --- .../whiteboardV2/whiteboardSpawner.js | 28 ++++++++++++++++++- 1 file changed, 27 insertions(+), 1 deletion(-) diff --git a/examples/homeContent/whiteboardV2/whiteboardSpawner.js b/examples/homeContent/whiteboardV2/whiteboardSpawner.js index 2974db8f59..3fcf93e628 100644 --- a/examples/homeContent/whiteboardV2/whiteboardSpawner.js +++ b/examples/homeContent/whiteboardV2/whiteboardSpawner.js @@ -104,6 +104,32 @@ var eraser = Entities.addEntity({ y: -0.1, z: 0 }, + userData: JSON.stringify({ + wearable: { + joints: { + RightHand: [{ + x: 0.0207, + y: 0.1202, + z: 0.0493 + }, { + x: 0.1004, + y: 0.6424, + z: 0.717, + w: 0.250 + }], + LeftHand: [{ + x: -0.005, + y: 0.1101, + z: 0.053 + }, { + x: 0.7234, + y: 0.289, + z: 0.142, + w: 0.610 + }] + } + } + }) }); createMarkers(); @@ -206,7 +232,7 @@ function createMarker(modelURL, markerPosition, markerColor) { var modelURL = Entities.getEntityProperties(marker, "modelURL").modelURL; Entities.callEntityMethod(marker, "setProperties", [JSON.stringify(data)]); - }, 3000) + }, 5000) } From ddae2d4f749a8aa1cd30bbcb75145367908dbb47 Mon Sep 17 00:00:00 2001 From: ericrius1 Date: Thu, 25 Feb 2016 15:00:54 -0800 Subject: [PATCH 41/58] only erase stroke map on release and preload --- examples/homeContent/whiteboardV2/eraserEntityScript.js | 9 ++++++--- examples/homeContent/whiteboardV2/whiteboardSpawner.js | 2 -- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/examples/homeContent/whiteboardV2/eraserEntityScript.js b/examples/homeContent/whiteboardV2/eraserEntityScript.js index 66399a9b8e..c78707e129 100644 --- a/examples/homeContent/whiteboardV2/eraserEntityScript.js +++ b/examples/homeContent/whiteboardV2/eraserEntityScript.js @@ -24,6 +24,7 @@ _this.ERASER_TRIGGER_THRESHOLD = 0.2; _this.STROKE_NAME = "hifi-marker-stroke"; _this.ERASER_TO_STROKE_SEARCH_RADIUS = 0.7; + _this.strokeMap = []; }; Eraser.prototype = { @@ -35,10 +36,10 @@ var eraserPosition = Entities.getEntityProperties(_this.entityID, "position").position; var strokeIDs = Entities.findEntities(eraserPosition, _this.ERASER_TO_STROKE_SEARCH_RADIUS); // Create a map of stroke entities and their positions - _this.strokeMap = []; + strokeIDs.forEach(function(strokeID) { var strokeProps = Entities.getEntityProperties(strokeID, ["position", "name"]); - if (strokeProps.name === _this.STROKE_NAME) { + if (strokeProps.name === _this.STROKE_NAME) { _this.strokeMap.push({ strokeID: strokeID, strokePosition: strokeProps.position @@ -53,7 +54,9 @@ } else {} }, - releaseEquip: function() {}, + releaseEquip: function() { + _this.strokeMap = []; + }, continueHolding: function() { diff --git a/examples/homeContent/whiteboardV2/whiteboardSpawner.js b/examples/homeContent/whiteboardV2/whiteboardSpawner.js index 3fcf93e628..8402b241ed 100644 --- a/examples/homeContent/whiteboardV2/whiteboardSpawner.js +++ b/examples/homeContent/whiteboardV2/whiteboardSpawner.js @@ -149,8 +149,6 @@ function createMarkers() { blue: 200 }); - - markerPosition = Vec3.sum(markerPosition, Vec3.multiply(-0.2, Quat.getFront(markerRotation))); createMarker(modelURLS[1], markerPosition, { red: 200, From 24bf4f851f52fff5620b8462eaefcb2b3a8c775d Mon Sep 17 00:00:00 2001 From: ericrius1 Date: Thu, 25 Feb 2016 15:23:02 -0800 Subject: [PATCH 42/58] can erase any stroke at any time --- .../whiteboardV2/eraserEntityScript.js | 42 ++++++------------- 1 file changed, 13 insertions(+), 29 deletions(-) diff --git a/examples/homeContent/whiteboardV2/eraserEntityScript.js b/examples/homeContent/whiteboardV2/eraserEntityScript.js index c78707e129..da67288829 100644 --- a/examples/homeContent/whiteboardV2/eraserEntityScript.js +++ b/examples/homeContent/whiteboardV2/eraserEntityScript.js @@ -24,7 +24,6 @@ _this.ERASER_TRIGGER_THRESHOLD = 0.2; _this.STROKE_NAME = "hifi-marker-stroke"; _this.ERASER_TO_STROKE_SEARCH_RADIUS = 0.7; - _this.strokeMap = []; }; Eraser.prototype = { @@ -33,43 +32,28 @@ _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 + + }, + continueEquip: function() { + this.triggerValue = Controller.getValue(TRIGGER_CONTROLS[_this.hand]); + if (_this.triggerValue > _this.ERASER_TRIGGER_THRESHOLD) { + _this.continueHolding(); + } + }, + + + continueHolding: function() { var eraserPosition = Entities.getEntityProperties(_this.entityID, "position").position; var strokeIDs = Entities.findEntities(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) { - _this.strokeMap.push({ - strokeID: strokeID, - strokePosition: strokeProps.position - }); + if (strokeProps.name === _this.STROKE_NAME && Vec3.distance(eraserPosition, strokeProps.position) < _this.ERASER_TO_STROKE_SEARCH_RADIUS) { + Entities.deleteEntity(strokeID); } }); }, - continueEquip: function() { - this.triggerValue = Controller.getValue(TRIGGER_CONTROLS[_this.hand]); - if (_this.triggerValue > _this.ERASER_TRIGGER_THRESHOLD) { - _this.continueHolding(); - } else {} - }, - - releaseEquip: function() { - _this.strokeMap = []; - }, - - - continueHolding: function() { - // search for marker strokes within certain radius of eraser - var eraserPosition = Entities.getEntityProperties(_this.entityID, "position").position; - _this.strokeMap.forEach(function(strokeData, index) { - if (Vec3.distance(eraserPosition, strokeData.strokePosition) < _this.ERASER_TO_STROKE_SEARCH_RADIUS) { - Entities.deleteEntity(strokeData.strokeID); - _this.strokeMap.splice(index, 1); - } - }) - - }, preload: function(entityID) { this.entityID = entityID; From 668894b3e06714be35da275127858f1505a7bfd0 Mon Sep 17 00:00:00 2001 From: ericrius1 Date: Thu, 25 Feb 2016 16:05:03 -0800 Subject: [PATCH 43/58] should work multiuser now --- .../whiteboardV2/markerEntityScript.js | 58 ++++++++++--------- .../whiteboardV2/whiteboardSpawner.js | 16 +---- 2 files changed, 34 insertions(+), 40 deletions(-) diff --git a/examples/homeContent/whiteboardV2/markerEntityScript.js b/examples/homeContent/whiteboardV2/markerEntityScript.js index 761ef00e33..80ba1cea7e 100644 --- a/examples/homeContent/whiteboardV2/markerEntityScript.js +++ b/examples/homeContent/whiteboardV2/markerEntityScript.js @@ -23,22 +23,34 @@ MarkerTip = function() { _this = this; _this.MARKER_TEXTURE_URL = "https://s3-us-west-1.amazonaws.com/hifi-content/eric/textures/markerStroke.png"; - this.strokeForwardOffset = 0.0001; - this.STROKE_FORWARD_OFFSET_INCRERMENT = 0.00001; - this.STROKE_WIDTH = 0.003 + _this.strokeForwardOffset = 0.0001; + _this.STROKE_FORWARD_OFFSET_INCRERMENT = 0.00001; + _this.STROKE_WIDTH = 0.003 _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 = "hifi-marker-stroke"; + _this.STROKE_NAME = "hifi-marker-stroke"; + _this.WHITEBOARD_SURFACE_NAME = "hifi-whiteboardDrawingSurface"; }; MarkerTip.prototype = { startEquip: function(id, params) { + _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 entityName = Entities.getEntityProperties(entity, "name").name; + if (entityName === _this.WHITEBOARD_SURFACE_NAME) { + _this.whiteboards.push(entity); + } + }); }, releaseEquip: function() { @@ -57,12 +69,14 @@ origin: markerProps.position, direction: Quat.getFront(markerProps.rotation) } - var intersection = Entities.findRayIntersectionBlocking(pickRay, true, [_this.whiteboard]); - + var intersection = Entities.findRayIntersectionBlocking(pickRay, true, _this.whiteboards); + _this.whiteboardNormal = Quat.getFront(intersection.properties.rotation); if (intersection.intersects && Vec3.distance(intersection.intersection, markerProps.position) < _this.MAX_MARKER_TO_BOARD_DISTANCE) { + print("EBL HIT") Overlays.editOverlay(_this.laserPointer, { visible: true, - position: intersection.intersection + position: intersection.intersection, + rotation: intersection.properties.rotation }) _this.triggerValue = Controller.getValue(TRIGGER_CONTROLS[_this.hand]); if (_this.triggerValue > _this.PAINTING_TRIGGER_THRESHOLD) { @@ -71,8 +85,8 @@ _this.resetStroke(); } } else { - _this.resetStroke(); - + _this.resetStroke(); + Overlays.editOverlay(_this.laserPointer, { visible: false }); @@ -145,22 +159,6 @@ preload: function(entityID) { this.entityID = entityID; - - }, - - unload: function() { - Overlays.deleteOverlay(_this.laserPointer); - _this.strokes.forEach( function(stroke) { - Entities.deleteEntity(stroke); - }); - }, - - setProperties: function(myId, data) { - var data = JSON.parse(data); - - _this.whiteboard = data.whiteboard; - var whiteboardProps = Entities.getEntityProperties(_this.whiteboard, ["rotation"]); - _this.whiteboardNormal = Quat.getFront(whiteboardProps.rotation); _this.laserPointer = Overlays.addOverlay("circle3d", { color: { red: 220, @@ -169,9 +167,15 @@ }, solid: true, size: 0.01, - rotation: whiteboardProps.rotation }); - _this.markerColor = data.markerColor; + + }, + + unload: function() { + Overlays.deleteOverlay(_this.laserPointer); + _this.strokes.forEach(function(stroke) { + Entities.deleteEntity(stroke); + }); } }; diff --git a/examples/homeContent/whiteboardV2/whiteboardSpawner.js b/examples/homeContent/whiteboardV2/whiteboardSpawner.js index 8402b241ed..08cd2b5a5f 100644 --- a/examples/homeContent/whiteboardV2/whiteboardSpawner.js +++ b/examples/homeContent/whiteboardV2/whiteboardSpawner.js @@ -56,7 +56,7 @@ var whiteboardSurfacePosition = Vec3.sum(whiteboardPosition, { whiteboardSurfacePosition = Vec3.sum(whiteboardSurfacePosition, Vec3.multiply(-0.02, Quat.getRight(orientation))); var whiteboardDrawingSurface = Entities.addEntity({ type: "Box", - name: "whiteboardDrawingSurface", + name: "hifi-whiteboardDrawingSurface", dimensions: { x: 1.82, y: 1.8, @@ -166,7 +166,7 @@ function createMarkers() { function createMarker(modelURL, markerPosition, markerColor) { - var MARKER_SCRIPT_URL = Script.resolvePath("markerEntityScript.js"); + var MARKER_SCRIPT_URL = Script.resolvePath("markerEntityScript.js?v1" + Math.random()); var marker = Entities.addEntity({ type: "Model", modelURL: modelURL, @@ -193,6 +193,7 @@ function createMarker(modelURL, markerPosition, markerColor) { name: "marker", script: MARKER_SCRIPT_URL, userData: JSON.stringify({ + markerColor: markerColor, wearable: { joints: { RightHand: [{ @@ -222,17 +223,6 @@ function createMarker(modelURL, markerPosition, markerColor) { markers.push(marker); - Script.setTimeout(function() { - var data = { - whiteboard: whiteboardDrawingSurface, - markerColor: markerColor - } - var modelURL = Entities.getEntityProperties(marker, "modelURL").modelURL; - - Entities.callEntityMethod(marker, "setProperties", [JSON.stringify(data)]); - }, 5000) - - } From a79d334beda04001f48626fc4058b4a98ba131d2 Mon Sep 17 00:00:00 2001 From: ericrius1 Date: Thu, 25 Feb 2016 16:12:34 -0800 Subject: [PATCH 44/58] no query string --- examples/homeContent/whiteboardV2/whiteboardSpawner.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/homeContent/whiteboardV2/whiteboardSpawner.js b/examples/homeContent/whiteboardV2/whiteboardSpawner.js index 08cd2b5a5f..a5cc219240 100644 --- a/examples/homeContent/whiteboardV2/whiteboardSpawner.js +++ b/examples/homeContent/whiteboardV2/whiteboardSpawner.js @@ -166,7 +166,7 @@ function createMarkers() { function createMarker(modelURL, markerPosition, markerColor) { - var MARKER_SCRIPT_URL = Script.resolvePath("markerEntityScript.js?v1" + Math.random()); + var MARKER_SCRIPT_URL = Script.resolvePath("markerEntityScript.js?"); var marker = Entities.addEntity({ type: "Model", modelURL: modelURL, From 0602bf7f1af7c3176874538da11d1afc4372d1cf Mon Sep 17 00:00:00 2001 From: ericrius1 Date: Thu, 25 Feb 2016 16:20:35 -0800 Subject: [PATCH 45/58] logging --- examples/homeContent/whiteboardV2/markerEntityScript.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/examples/homeContent/whiteboardV2/markerEntityScript.js b/examples/homeContent/whiteboardV2/markerEntityScript.js index 80ba1cea7e..a9b8173097 100644 --- a/examples/homeContent/whiteboardV2/markerEntityScript.js +++ b/examples/homeContent/whiteboardV2/markerEntityScript.js @@ -48,9 +48,12 @@ entities.forEach(function(entity) { var entityName = Entities.getEntityProperties(entity, "name").name; if (entityName === _this.WHITEBOARD_SURFACE_NAME) { + _this.whiteboards.push(entity); } }); + + print("intersectable entities " + JSON.stringify(_this.whiteboards)) }, releaseEquip: function() { @@ -72,7 +75,6 @@ var intersection = Entities.findRayIntersectionBlocking(pickRay, true, _this.whiteboards); _this.whiteboardNormal = Quat.getFront(intersection.properties.rotation); if (intersection.intersects && Vec3.distance(intersection.intersection, markerProps.position) < _this.MAX_MARKER_TO_BOARD_DISTANCE) { - print("EBL HIT") Overlays.editOverlay(_this.laserPointer, { visible: true, position: intersection.intersection, From 4d2a65926ca81c68b810d53e650265d8186a8802 Mon Sep 17 00:00:00 2001 From: ericrius1 Date: Thu, 25 Feb 2016 18:06:13 -0800 Subject: [PATCH 46/58] test --- examples/homeContent/whiteboardV2/whiteboardSpawner.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/homeContent/whiteboardV2/whiteboardSpawner.js b/examples/homeContent/whiteboardV2/whiteboardSpawner.js index a5cc219240..ff2c593ea1 100644 --- a/examples/homeContent/whiteboardV2/whiteboardSpawner.js +++ b/examples/homeContent/whiteboardV2/whiteboardSpawner.js @@ -166,7 +166,7 @@ function createMarkers() { function createMarker(modelURL, markerPosition, markerColor) { - var MARKER_SCRIPT_URL = Script.resolvePath("markerEntityScript.js?"); + var MARKER_SCRIPT_URL = Script.resolvePath("markerEntityScript.js"); var marker = Entities.addEntity({ type: "Model", modelURL: modelURL, From 0ce4385554d4461db0d6b91af79fd64a798dc89a Mon Sep 17 00:00:00 2001 From: ericrius1 Date: Thu, 25 Feb 2016 18:22:54 -0800 Subject: [PATCH 47/58] no offset increment --- examples/homeContent/whiteboardV2/markerEntityScript.js | 2 -- 1 file changed, 2 deletions(-) diff --git a/examples/homeContent/whiteboardV2/markerEntityScript.js b/examples/homeContent/whiteboardV2/markerEntityScript.js index a9b8173097..82ea1a2b69 100644 --- a/examples/homeContent/whiteboardV2/markerEntityScript.js +++ b/examples/homeContent/whiteboardV2/markerEntityScript.js @@ -24,7 +24,6 @@ _this = this; _this.MARKER_TEXTURE_URL = "https://s3-us-west-1.amazonaws.com/hifi-content/eric/textures/markerStroke.png"; _this.strokeForwardOffset = 0.0001; - _this.STROKE_FORWARD_OFFSET_INCRERMENT = 0.00001; _this.STROKE_WIDTH = 0.003 _this.MAX_MARKER_TO_BOARD_DISTANCE = 1.4; _this.MIN_DISTANCE_BETWEEN_POINTS = 0.002; @@ -130,7 +129,6 @@ var localPoint = Vec3.subtract(basePosition, _this.strokeBasePosition); localPoint = Vec3.sum(localPoint, Vec3.multiply(_this.whiteboardNormal, _this.strokeForwardOffset)); - _this.strokeForwardOffset -= _this.STROKE_FORWARD_OFFSET_INCRERMENT; if (_this.linePoints.length > 0) { var distance = Vec3.distance(localPoint, _this.linePoints[_this.linePoints.length - 1]); From 25a2d1eb93e28f35190b5e89cb2e02353def2b64 Mon Sep 17 00:00:00 2001 From: ericrius1 Date: Fri, 26 Feb 2016 10:14:27 -0800 Subject: [PATCH 48/58] fixed rotation --- .../whiteboardV2/markerEntityScript.js | 2 +- .../whiteboardV2/whiteboardSpawner.js | 56 +++++++++---------- 2 files changed, 29 insertions(+), 29 deletions(-) diff --git a/examples/homeContent/whiteboardV2/markerEntityScript.js b/examples/homeContent/whiteboardV2/markerEntityScript.js index 82ea1a2b69..e6f7e3cf81 100644 --- a/examples/homeContent/whiteboardV2/markerEntityScript.js +++ b/examples/homeContent/whiteboardV2/markerEntityScript.js @@ -72,8 +72,8 @@ direction: Quat.getFront(markerProps.rotation) } var intersection = Entities.findRayIntersectionBlocking(pickRay, true, _this.whiteboards); - _this.whiteboardNormal = Quat.getFront(intersection.properties.rotation); if (intersection.intersects && Vec3.distance(intersection.intersection, markerProps.position) < _this.MAX_MARKER_TO_BOARD_DISTANCE) { + _this.whiteboardNormal = Quat.getFront(intersection.properties.rotation); Overlays.editOverlay(_this.laserPointer, { visible: true, position: intersection.intersection, diff --git a/examples/homeContent/whiteboardV2/whiteboardSpawner.js b/examples/homeContent/whiteboardV2/whiteboardSpawner.js index ff2c593ea1..6689672095 100644 --- a/examples/homeContent/whiteboardV2/whiteboardSpawner.js +++ b/examples/homeContent/whiteboardV2/whiteboardSpawner.js @@ -23,7 +23,7 @@ var markerRotation = Quat.fromVec3Degrees({ orientation.x = 0; var whiteboardRotation = Quat.fromVec3Degrees({ x: 0, - y: orientation.y - 90, + y: orientation.y, z: 0 }); orientation = Quat.fromVec3Degrees(orientation); @@ -31,8 +31,8 @@ var markers = []; var whiteboardPosition = Vec3.sum(MyAvatar.position, Vec3.multiply(2, Quat.getFront(orientation))); -var WHITEBOARD_MODEL_URL = "http://hifi-content.s3.amazonaws.com/alan/dev/Whiteboard-3.fbx"; -var WHITEBOARD_COLLISION_HULL_URL = "http://hifi-content.s3.amazonaws.com/alan/dev/Whiteboard.obj"; +var WHITEBOARD_MODEL_URL = "https://s3-us-west-1.amazonaws.com/hifi-content/eric/models/Whiteboard-3+(1).fbx"; +var WHITEBOARD_COLLISION_HULL_URL = "https://s3-us-west-1.amazonaws.com/hifi-content/eric/models/whiteboardCollisionHull.obj"; var whiteboard = Entities.addEntity({ type: "Model", name: "whiteboard", @@ -42,9 +42,9 @@ var whiteboard = Entities.addEntity({ shapeType: 'compound', compoundShapeURL: WHITEBOARD_COLLISION_HULL_URL, dimensions: { - x: 0.4636, - y: 2.7034, - z: 1.8653 + x: 1.86, + y: 2.7, + z: 0.4636 }, }); @@ -68,7 +68,7 @@ var whiteboardDrawingSurface = Entities.addEntity({ blue: 200 }, position: whiteboardSurfacePosition, - rotation: orientation, + rotation: whiteboardRotation, visible: false, parentID: whiteboard }); @@ -108,9 +108,9 @@ var eraser = Entities.addEntity({ wearable: { joints: { RightHand: [{ - x: 0.0207, - y: 0.1202, - z: 0.0493 + x: 0.020, + y: 0.120, + z: 0.049 }, { x: 0.1004, y: 0.6424, @@ -122,7 +122,7 @@ var eraser = Entities.addEntity({ y: 0.1101, z: 0.053 }, { - x: 0.7234, + x: 0.723, y: 0.289, z: 0.142, w: 0.610 @@ -186,9 +186,9 @@ function createMarker(modelURL, markerPosition, markerColor) { }, position: markerPosition, dimensions: { - x: 0.0270, - y: 0.0272, - z: 0.1641 + x: 0.027, + y: 0.027, + z: 0.164 }, name: "marker", script: MARKER_SCRIPT_URL, @@ -197,24 +197,24 @@ function createMarker(modelURL, markerPosition, markerColor) { wearable: { joints: { RightHand: [{ - x: 0.001109793782234192, - y: 0.13991504907608032, - z: 0.05035984516143799 + x: 0.001, + y: 0.139, + z: 0.050 }, { - x: -0.7360993027687073, - y: -0.04330085217952728, - z: -0.10863728821277618, - w: -0.6666942238807678 + x: -0.73, + y: -0.043, + z: -0.108, + w: -0.666 }], LeftHand: [{ - x: 0.007193896919488907, - y: 0.15147076547145844, - z: 0.06174466013908386 + x: 0.007, + y: 0.151, + z: 0.061 }, { - x: -0.4174973964691162, - y: 0.631147563457489, - z: -0.3890438377857208, - w: -0.52535080909729 + x: -0.417, + y: 0.631, + z: -0.389, + w: -0.525 }] } } From c81f3256ddc2d9376dd134bc531af38ca09a7c68 Mon Sep 17 00:00:00 2001 From: ericrius1 Date: Fri, 26 Feb 2016 10:58:22 -0800 Subject: [PATCH 49/58] rotation --- .../whiteboardV2/eraserEntityScript.js | 26 +++++++++++++++---- .../whiteboardV2/markerEntityScript.js | 2 +- .../whiteboardV2/whiteboardSpawner.js | 10 +++---- 3 files changed, 27 insertions(+), 11 deletions(-) diff --git a/examples/homeContent/whiteboardV2/eraserEntityScript.js b/examples/homeContent/whiteboardV2/eraserEntityScript.js index da67288829..86e80659bf 100644 --- a/examples/homeContent/whiteboardV2/eraserEntityScript.js +++ b/examples/homeContent/whiteboardV2/eraserEntityScript.js @@ -32,9 +32,11 @@ _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() { + _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(); @@ -43,22 +45,36 @@ continueHolding: function() { - var eraserPosition = Entities.getEntityProperties(_this.entityID, "position").position; - var strokeIDs = Entities.findEntities(eraserPosition, _this.ERASER_TO_STROKE_SEARCH_RADIUS); + var strokeIDs = 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(eraserPosition, strokeProps.position) < _this.ERASER_TO_STROKE_SEARCH_RADIUS) { + if (strokeProps.name === _this.STROKE_NAME && Vec3.distance(_this.eraserPosition, strokeProps.position) < _this.ERASER_TO_STROKE_SEARCH_RADIUS) { Entities.deleteEntity(strokeID); } }); }, + releaseEquip: function() { + Overlays.editOverlay(_this.searchSphere, {visible: false}); + }, + preload: function(entityID) { - this.entityID = 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); + } }; // entity scripts always need to return a newly constructed object of our type diff --git a/examples/homeContent/whiteboardV2/markerEntityScript.js b/examples/homeContent/whiteboardV2/markerEntityScript.js index e6f7e3cf81..e379fac016 100644 --- a/examples/homeContent/whiteboardV2/markerEntityScript.js +++ b/examples/homeContent/whiteboardV2/markerEntityScript.js @@ -73,7 +73,7 @@ } var intersection = Entities.findRayIntersectionBlocking(pickRay, true, _this.whiteboards); if (intersection.intersects && Vec3.distance(intersection.intersection, markerProps.position) < _this.MAX_MARKER_TO_BOARD_DISTANCE) { - _this.whiteboardNormal = Quat.getFront(intersection.properties.rotation); + _this.whiteboardNormal = Quat.getRight(intersection.properties.rotation); Overlays.editOverlay(_this.laserPointer, { visible: true, position: intersection.intersection, diff --git a/examples/homeContent/whiteboardV2/whiteboardSpawner.js b/examples/homeContent/whiteboardV2/whiteboardSpawner.js index 6689672095..8826c8387a 100644 --- a/examples/homeContent/whiteboardV2/whiteboardSpawner.js +++ b/examples/homeContent/whiteboardV2/whiteboardSpawner.js @@ -31,7 +31,7 @@ var markers = []; var whiteboardPosition = Vec3.sum(MyAvatar.position, Vec3.multiply(2, Quat.getFront(orientation))); -var WHITEBOARD_MODEL_URL = "https://s3-us-west-1.amazonaws.com/hifi-content/eric/models/Whiteboard-3+(1).fbx"; +var WHITEBOARD_MODEL_URL = "https://s3-us-west-1.amazonaws.com/hifi-content/eric/models/Whiteboard-4.fbx"; var WHITEBOARD_COLLISION_HULL_URL = "https://s3-us-west-1.amazonaws.com/hifi-content/eric/models/whiteboardCollisionHull.obj"; var whiteboard = Entities.addEntity({ type: "Model", @@ -69,7 +69,7 @@ var whiteboardDrawingSurface = Entities.addEntity({ }, position: whiteboardSurfacePosition, rotation: whiteboardRotation, - visible: false, + // visible: false, parentID: whiteboard }); @@ -78,8 +78,8 @@ var WHITEBOARD_RACK_DEPTH = 1.9; var ERASER_MODEL_URL = "http://hifi-content.s3.amazonaws.com/alan/dev/eraser-2.fbx"; var ERASER_SCRIPT_URL = Script.resolvePath("eraserEntityScript.js"); -var eraserPosition = Vec3.sum(MyAvatar.position, Vec3.multiply(WHITEBOARD_RACK_DEPTH, Quat.getFront(orientation))); -eraserPosition = Vec3.sum(eraserPosition, Vec3.multiply(-0.5, Quat.getFront(whiteboardRotation))); +var eraserPosition = Vec3.sum(MyAvatar.position, Vec3.multiply(WHITEBOARD_RACK_DEPTH, Quat.getFront(whiteboardRotation))); +eraserPosition = Vec3.sum(eraserPosition, Vec3.multiply(-0.5, Quat.getRight(whiteboardRotation))); var eraser = Entities.addEntity({ type: "Model", @@ -92,7 +92,7 @@ var eraser = Entities.addEntity({ y: 0.0393, z: 0.2083 }, - rotation: whiteboardRotation, + rotation: markerRotation, dynamic: true, gravity: { x: 0, From 1542b9da12841408836026160d2e18592d88bcf3 Mon Sep 17 00:00:00 2001 From: ericrius1 Date: Fri, 26 Feb 2016 11:33:59 -0800 Subject: [PATCH 50/58] rotation works right now --- examples/homeContent/whiteboardV2/markerEntityScript.js | 6 +++--- examples/homeContent/whiteboardV2/whiteboardSpawner.js | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/examples/homeContent/whiteboardV2/markerEntityScript.js b/examples/homeContent/whiteboardV2/markerEntityScript.js index e379fac016..fc4cbba1bd 100644 --- a/examples/homeContent/whiteboardV2/markerEntityScript.js +++ b/examples/homeContent/whiteboardV2/markerEntityScript.js @@ -24,7 +24,7 @@ _this = this; _this.MARKER_TEXTURE_URL = "https://s3-us-west-1.amazonaws.com/hifi-content/eric/textures/markerStroke.png"; _this.strokeForwardOffset = 0.0001; - _this.STROKE_WIDTH = 0.003 + _this.STROKE_WIDTH = 0.03 _this.MAX_MARKER_TO_BOARD_DISTANCE = 1.4; _this.MIN_DISTANCE_BETWEEN_POINTS = 0.002; _this.MAX_DISTANCE_BETWEEN_POINTS = 0.1; @@ -73,11 +73,11 @@ } var intersection = Entities.findRayIntersectionBlocking(pickRay, true, _this.whiteboards); if (intersection.intersects && Vec3.distance(intersection.intersection, markerProps.position) < _this.MAX_MARKER_TO_BOARD_DISTANCE) { - _this.whiteboardNormal = Quat.getRight(intersection.properties.rotation); + _this.whiteboardNormal = Quat.getFront(intersection.properties.rotation); Overlays.editOverlay(_this.laserPointer, { visible: true, position: intersection.intersection, - rotation: intersection.properties.rotation + // rotation: intersection.properties.rotation }) _this.triggerValue = Controller.getValue(TRIGGER_CONTROLS[_this.hand]); if (_this.triggerValue > _this.PAINTING_TRIGGER_THRESHOLD) { diff --git a/examples/homeContent/whiteboardV2/whiteboardSpawner.js b/examples/homeContent/whiteboardV2/whiteboardSpawner.js index 8826c8387a..da9aad4c33 100644 --- a/examples/homeContent/whiteboardV2/whiteboardSpawner.js +++ b/examples/homeContent/whiteboardV2/whiteboardSpawner.js @@ -69,7 +69,7 @@ var whiteboardDrawingSurface = Entities.addEntity({ }, position: whiteboardSurfacePosition, rotation: whiteboardRotation, - // visible: false, + visible: false, parentID: whiteboard }); @@ -166,7 +166,7 @@ function createMarkers() { function createMarker(modelURL, markerPosition, markerColor) { - var MARKER_SCRIPT_URL = Script.resolvePath("markerEntityScript.js"); + var MARKER_SCRIPT_URL = Script.resolvePath("markerEntityScript.js?v1" + Math.random()); var marker = Entities.addEntity({ type: "Model", modelURL: modelURL, From 6e0ddb39189bf588d42ab4e27f1a1cc55b52cac2 Mon Sep 17 00:00:00 2001 From: ericrius1 Date: Fri, 26 Feb 2016 11:48:15 -0800 Subject: [PATCH 51/58] really fixed rotation --- examples/homeContent/whiteboardV2/markerEntityScript.js | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/examples/homeContent/whiteboardV2/markerEntityScript.js b/examples/homeContent/whiteboardV2/markerEntityScript.js index fc4cbba1bd..064add57be 100644 --- a/examples/homeContent/whiteboardV2/markerEntityScript.js +++ b/examples/homeContent/whiteboardV2/markerEntityScript.js @@ -24,7 +24,7 @@ _this = this; _this.MARKER_TEXTURE_URL = "https://s3-us-west-1.amazonaws.com/hifi-content/eric/textures/markerStroke.png"; _this.strokeForwardOffset = 0.0001; - _this.STROKE_WIDTH = 0.03 + _this.STROKE_WIDTH = 0.03; _this.MAX_MARKER_TO_BOARD_DISTANCE = 1.4; _this.MIN_DISTANCE_BETWEEN_POINTS = 0.002; _this.MAX_DISTANCE_BETWEEN_POINTS = 0.1; @@ -72,12 +72,14 @@ direction: Quat.getFront(markerProps.rotation) } var intersection = Entities.findRayIntersectionBlocking(pickRay, true, _this.whiteboards); + if (intersection.intersects && Vec3.distance(intersection.intersection, markerProps.position) < _this.MAX_MARKER_TO_BOARD_DISTANCE) { - _this.whiteboardNormal = Quat.getFront(intersection.properties.rotation); + var whiteboardRotation = Entities.getEntityProperties(intersection.entityID, "rotation").rotation; + _this.whiteboardNormal = Quat.getFront(whiteboardRotation); Overlays.editOverlay(_this.laserPointer, { visible: true, position: intersection.intersection, - // rotation: intersection.properties.rotation + rotation: whiteboardRotation }) _this.triggerValue = Controller.getValue(TRIGGER_CONTROLS[_this.hand]); if (_this.triggerValue > _this.PAINTING_TRIGGER_THRESHOLD) { From df3e26edd59fe8d3e93a610579e821054f5bb252 Mon Sep 17 00:00:00 2001 From: ericrius1 Date: Fri, 26 Feb 2016 12:05:30 -0800 Subject: [PATCH 52/58] calligraphy --- .../whiteboardV2/markerEntityScript.js | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/examples/homeContent/whiteboardV2/markerEntityScript.js b/examples/homeContent/whiteboardV2/markerEntityScript.js index 064add57be..3943143185 100644 --- a/examples/homeContent/whiteboardV2/markerEntityScript.js +++ b/examples/homeContent/whiteboardV2/markerEntityScript.js @@ -24,7 +24,7 @@ _this = this; _this.MARKER_TEXTURE_URL = "https://s3-us-west-1.amazonaws.com/hifi-content/eric/textures/markerStroke.png"; _this.strokeForwardOffset = 0.0001; - _this.STROKE_WIDTH = 0.03; + _this.STROKE_WIDTH_RANGE = {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; @@ -115,8 +115,6 @@ _this.linePoints = []; _this.normals = []; - _this.strokeWidths = []; - _this.strokes.push(_this.currentStroke); }, @@ -140,12 +138,20 @@ } _this.linePoints.push(localPoint); _this.normals.push(_this.whiteboardNormal); - this.strokeWidths.push(_this.STROKE_WIDTH); + + var strokeWidths = []; + for (var 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); + print("EBL POINTS CENTER " + pointsFromCenter) + var pointWidth = map(pointsFromCenter, 0, this.linePoints.length/2, _this.STROKE_WIDTH_RANGE.max, this.STROKE_WIDTH_RANGE.min); + strokeWidths.push(pointWidth); + } Entities.editEntity(_this.currentStroke, { linePoints: _this.linePoints, normals: _this.normals, - strokeWidths: _this.strokeWidths + strokeWidths: strokeWidths }); if (_this.linePoints.length > MAX_POINTS_PER_STROKE) { From ed9f279a6386823300279526e701a0f3b742bf02 Mon Sep 17 00:00:00 2001 From: ericrius1 Date: Fri, 26 Feb 2016 12:12:27 -0800 Subject: [PATCH 53/58] moved whiteboard Surface up --- examples/homeContent/whiteboardV2/whiteboardSpawner.js | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/examples/homeContent/whiteboardV2/whiteboardSpawner.js b/examples/homeContent/whiteboardV2/whiteboardSpawner.js index da9aad4c33..f89789ab8b 100644 --- a/examples/homeContent/whiteboardV2/whiteboardSpawner.js +++ b/examples/homeContent/whiteboardV2/whiteboardSpawner.js @@ -53,14 +53,15 @@ var whiteboardSurfacePosition = Vec3.sum(whiteboardPosition, { y: 0.45, z: 0.0 }); -whiteboardSurfacePosition = Vec3.sum(whiteboardSurfacePosition, Vec3.multiply(-0.02, Quat.getRight(orientation))); +whiteboardSurfacePosition = Vec3.sum(whiteboardSurfacePosition, Vec3.multiply(-0.02, Quat.getRight(whiteboardRotation))); +whiteboardSurfacePosition = Vec3.sum(whiteboardSurfacePosition, Vec3.multiply(-0.02, Quat.getFront(whiteboardRotation))); var whiteboardDrawingSurface = Entities.addEntity({ type: "Box", name: "hifi-whiteboardDrawingSurface", dimensions: { x: 1.82, y: 1.8, - z: 0.04 + z: 0.01 }, color: { red: 200, From e83c1f71a6059b1100fd94c63c145b0b762c4ebf Mon Sep 17 00:00:00 2001 From: ericrius1 Date: Fri, 26 Feb 2016 12:17:46 -0800 Subject: [PATCH 54/58] front and back --- .../whiteboardV2/whiteboardSpawner.js | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/examples/homeContent/whiteboardV2/whiteboardSpawner.js b/examples/homeContent/whiteboardV2/whiteboardSpawner.js index f89789ab8b..f4f18a164d 100644 --- a/examples/homeContent/whiteboardV2/whiteboardSpawner.js +++ b/examples/homeContent/whiteboardV2/whiteboardSpawner.js @@ -54,8 +54,9 @@ var whiteboardSurfacePosition = Vec3.sum(whiteboardPosition, { z: 0.0 }); whiteboardSurfacePosition = Vec3.sum(whiteboardSurfacePosition, Vec3.multiply(-0.02, Quat.getRight(whiteboardRotation))); -whiteboardSurfacePosition = Vec3.sum(whiteboardSurfacePosition, Vec3.multiply(-0.02, Quat.getFront(whiteboardRotation))); -var whiteboardDrawingSurface = Entities.addEntity({ +var moveForwardDistance = 0.02; +whiteboardFrontSurfacePosition = Vec3.sum(whiteboardSurfacePosition, Vec3.multiply(-moveForwardDistance, Quat.getFront(whiteboardRotation))); +var whiteboardSurfaceSettings = { type: "Box", name: "hifi-whiteboardDrawingSurface", dimensions: { @@ -68,11 +69,18 @@ var whiteboardDrawingSurface = Entities.addEntity({ green: 10, blue: 200 }, - position: whiteboardSurfacePosition, + position: whiteboardFrontSurfacePosition, rotation: whiteboardRotation, visible: false, parentID: whiteboard -}); +} +var whiteboardFrontDrawingSurface = Entities.addEntity(whiteboardSurfaceSettings); + + +whiteboardBackSurfacePosition = Vec3.sum(whiteboardSurfacePosition, Vec3.multiply(moveForwardDistance, Quat.getFront(whiteboardRotation))); +whiteboardSurfaceSettings.position = whiteboardBackSurfacePosition; + +var whiteboardFrontDrawingSurface = Entities.addEntity(whiteboardSurfaceSettings); var WHITEBOARD_RACK_DEPTH = 1.9; @@ -230,7 +238,8 @@ function createMarker(modelURL, markerPosition, markerColor) { function cleanup() { Entities.deleteEntity(whiteboard); - Entities.deleteEntity(whiteboardDrawingSurface); + Entities.deleteEntity(whiteboardFrontDrawingSurface); + Entities.deleteEntity(whiteboardBackDrawingSurface); Entities.deleteEntity(eraser); markers.forEach(function(marker) { Entities.deleteEntity(marker); From 48f03ba476e69a8f4b8a73d0ba3f6e25731ace8b Mon Sep 17 00:00:00 2001 From: ericrius1 Date: Fri, 26 Feb 2016 14:29:43 -0800 Subject: [PATCH 55/58] markers resetting --- .../whiteboardV2/markerEntityScript.js | 26 ++++++++++++++++--- .../whiteboardV2/whiteboardSpawner.js | 2 ++ 2 files changed, 24 insertions(+), 4 deletions(-) diff --git a/examples/homeContent/whiteboardV2/markerEntityScript.js b/examples/homeContent/whiteboardV2/markerEntityScript.js index 3943143185..de5d615dec 100644 --- a/examples/homeContent/whiteboardV2/markerEntityScript.js +++ b/examples/homeContent/whiteboardV2/markerEntityScript.js @@ -24,7 +24,10 @@ _this = this; _this.MARKER_TEXTURE_URL = "https://s3-us-west-1.amazonaws.com/hifi-content/eric/textures/markerStroke.png"; _this.strokeForwardOffset = 0.0001; - _this.STROKE_WIDTH_RANGE = {min: 0.002, max: 0.01}; + _this.STROKE_WIDTH_RANGE = { + 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; @@ -32,6 +35,7 @@ _this.PAINTING_TRIGGER_THRESHOLD = 0.2; _this.STROKE_NAME = "hifi-marker-stroke"; _this.WHITEBOARD_SURFACE_NAME = "hifi-whiteboardDrawingSurface"; + _this.MARKER_RESET_WAIT_TIME = 3000; }; MarkerTip.prototype = { @@ -60,6 +64,20 @@ Overlays.editOverlay(_this.laserPointer, { visible: false }); + + // Once user releases marker, 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.MARKER_RESET_WAIT_TIME); }, @@ -75,7 +93,7 @@ if (intersection.intersects && Vec3.distance(intersection.intersection, markerProps.position) < _this.MAX_MARKER_TO_BOARD_DISTANCE) { var whiteboardRotation = Entities.getEntityProperties(intersection.entityID, "rotation").rotation; - _this.whiteboardNormal = Quat.getFront(whiteboardRotation); + _this.whiteboardNormal = Quat.getFront(whiteboardRotation); Overlays.editOverlay(_this.laserPointer, { visible: true, position: intersection.intersection, @@ -142,9 +160,9 @@ var strokeWidths = []; for (var 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 pointsFromCenter = Math.abs(_this.linePoints.length / 2 - i); print("EBL POINTS CENTER " + pointsFromCenter) - var pointWidth = map(pointsFromCenter, 0, this.linePoints.length/2, _this.STROKE_WIDTH_RANGE.max, this.STROKE_WIDTH_RANGE.min); + var pointWidth = map(pointsFromCenter, 0, this.linePoints.length / 2, _this.STROKE_WIDTH_RANGE.max, this.STROKE_WIDTH_RANGE.min); strokeWidths.push(pointWidth); } diff --git a/examples/homeContent/whiteboardV2/whiteboardSpawner.js b/examples/homeContent/whiteboardV2/whiteboardSpawner.js index f4f18a164d..eb0886229a 100644 --- a/examples/homeContent/whiteboardV2/whiteboardSpawner.js +++ b/examples/homeContent/whiteboardV2/whiteboardSpawner.js @@ -202,6 +202,8 @@ function createMarker(modelURL, markerPosition, markerColor) { name: "marker", script: MARKER_SCRIPT_URL, userData: JSON.stringify({ + originalPosition: markerPosition, + originalRotation: markerRotation, markerColor: markerColor, wearable: { joints: { From d0752143dcaa16a2903b90e4da1339074b410259 Mon Sep 17 00:00:00 2001 From: ericrius1 Date: Fri, 26 Feb 2016 14:49:48 -0800 Subject: [PATCH 56/58] markers and eraser reset to original positions after being dropped --- .../whiteboardV2/eraserEntityScript.js | 37 ++++++++++++++++--- .../whiteboardV2/markerEntityScript.js | 7 ++-- .../whiteboardV2/whiteboardSpawner.js | 9 +++-- 3 files changed, 42 insertions(+), 11 deletions(-) diff --git a/examples/homeContent/whiteboardV2/eraserEntityScript.js b/examples/homeContent/whiteboardV2/eraserEntityScript.js index 86e80659bf..9306c7a5ab 100644 --- a/examples/homeContent/whiteboardV2/eraserEntityScript.js +++ b/examples/homeContent/whiteboardV2/eraserEntityScript.js @@ -24,6 +24,7 @@ _this.ERASER_TRIGGER_THRESHOLD = 0.2; _this.STROKE_NAME = "hifi-marker-stroke"; _this.ERASER_TO_STROKE_SEARCH_RADIUS = 0.7; + _this.ERASER_RESET_WAIT_TIME = 3000; }; Eraser.prototype = { @@ -32,11 +33,15 @@ _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}); + Overlays.editOverlay(_this.searchSphere, { + visible: true + }); }, continueEquip: function() { - _this.eraserPosition = Entities.getEntityProperties(_this.entityID, "position").position; - Overlays.editOverlay(_this.searchSphere, {position: _this.eraserPosition}); + _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(); @@ -57,14 +62,36 @@ }, releaseEquip: function() { - Overlays.editOverlay(_this.searchSphere, {visible: false}); + 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); }, + + 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}, + color: { + red: 200, + green: 10, + blue: 10 + }, alpha: 0.2, solid: true, visible: false diff --git a/examples/homeContent/whiteboardV2/markerEntityScript.js b/examples/homeContent/whiteboardV2/markerEntityScript.js index de5d615dec..64b906dda1 100644 --- a/examples/homeContent/whiteboardV2/markerEntityScript.js +++ b/examples/homeContent/whiteboardV2/markerEntityScript.js @@ -92,7 +92,8 @@ var intersection = Entities.findRayIntersectionBlocking(pickRay, true, _this.whiteboards); if (intersection.intersects && Vec3.distance(intersection.intersection, markerProps.position) < _this.MAX_MARKER_TO_BOARD_DISTANCE) { - var whiteboardRotation = Entities.getEntityProperties(intersection.entityID, "rotation").rotation; + _this.currentWhiteboard = intersection.entityID; + var whiteboardRotation = Entities.getEntityProperties(_this.currentWhiteboard, "rotation").rotation; _this.whiteboardNormal = Quat.getFront(whiteboardRotation); Overlays.editOverlay(_this.laserPointer, { visible: true, @@ -128,7 +129,8 @@ position: position, textures: _this.MARKER_TEXTURE_URL, color: _this.markerColor, - lifetime: 500 + lifetime: 500, + // parentID: _this.currentWhiteboard }); _this.linePoints = []; @@ -161,7 +163,6 @@ for (var 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); - print("EBL POINTS CENTER " + pointsFromCenter) var pointWidth = map(pointsFromCenter, 0, this.linePoints.length / 2, _this.STROKE_WIDTH_RANGE.max, this.STROKE_WIDTH_RANGE.min); strokeWidths.push(pointWidth); } diff --git a/examples/homeContent/whiteboardV2/whiteboardSpawner.js b/examples/homeContent/whiteboardV2/whiteboardSpawner.js index eb0886229a..32c207499a 100644 --- a/examples/homeContent/whiteboardV2/whiteboardSpawner.js +++ b/examples/homeContent/whiteboardV2/whiteboardSpawner.js @@ -80,15 +80,16 @@ var whiteboardFrontDrawingSurface = Entities.addEntity(whiteboardSurfaceSettings whiteboardBackSurfacePosition = Vec3.sum(whiteboardSurfacePosition, Vec3.multiply(moveForwardDistance, Quat.getFront(whiteboardRotation))); whiteboardSurfaceSettings.position = whiteboardBackSurfacePosition; -var whiteboardFrontDrawingSurface = Entities.addEntity(whiteboardSurfaceSettings); +var whiteboardBackDrawingSurface = Entities.addEntity(whiteboardSurfaceSettings); var WHITEBOARD_RACK_DEPTH = 1.9; var ERASER_MODEL_URL = "http://hifi-content.s3.amazonaws.com/alan/dev/eraser-2.fbx"; -var ERASER_SCRIPT_URL = Script.resolvePath("eraserEntityScript.js"); +var ERASER_SCRIPT_URL = Script.resolvePath("eraserEntityScript.js?v43"); var eraserPosition = Vec3.sum(MyAvatar.position, Vec3.multiply(WHITEBOARD_RACK_DEPTH, Quat.getFront(whiteboardRotation))); eraserPosition = Vec3.sum(eraserPosition, Vec3.multiply(-0.5, Quat.getRight(whiteboardRotation))); +var eraserRotation = markerRotation; var eraser = Entities.addEntity({ type: "Model", @@ -101,7 +102,7 @@ var eraser = Entities.addEntity({ y: 0.0393, z: 0.2083 }, - rotation: markerRotation, + rotation: eraserRotation, dynamic: true, gravity: { x: 0, @@ -114,6 +115,8 @@ var eraser = Entities.addEntity({ z: 0 }, userData: JSON.stringify({ + originalPosition: eraserPosition, + originalRotation: eraserRotation, wearable: { joints: { RightHand: [{ From 5762c33cfebb87b56bcacd172cc572759b995115 Mon Sep 17 00:00:00 2001 From: ericrius1 Date: Fri, 26 Feb 2016 15:07:22 -0800 Subject: [PATCH 57/58] strokes are now parented to whiteboard surface --- .../homeContent/whiteboardV2/markerEntityScript.js | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/examples/homeContent/whiteboardV2/markerEntityScript.js b/examples/homeContent/whiteboardV2/markerEntityScript.js index 64b906dda1..d06d5cf8e9 100644 --- a/examples/homeContent/whiteboardV2/markerEntityScript.js +++ b/examples/homeContent/whiteboardV2/markerEntityScript.js @@ -107,7 +107,9 @@ _this.resetStroke(); } } else { - _this.resetStroke(); + if (_this.currentStroke) { + _this.resetStroke(); + } Overlays.editOverlay(_this.laserPointer, { visible: false @@ -130,7 +132,6 @@ textures: _this.MARKER_TEXTURE_URL, color: _this.markerColor, lifetime: 500, - // parentID: _this.currentWhiteboard }); _this.linePoints = []; @@ -174,13 +175,20 @@ }); if (_this.linePoints.length > MAX_POINTS_PER_STROKE) { + Entities.editEntity(_this.currentStroke, { + parentID: _this.currentWhiteboard + }); _this.currentStroke = null; _this.oldPosition = position; } }, - resetStroke: function() { + + Entities.editEntity(_this.currentStroke, { + parentID: _this.currentWhiteboard + }); _this.currentStroke = null; + _this.oldPosition = null; }, From 33fe2e9b36de111a215ea559ef28f70d1fa130b7 Mon Sep 17 00:00:00 2001 From: Eric Levin Date: Mon, 29 Feb 2016 16:11:08 -0800 Subject: [PATCH 58/58] Update markerEntityScript.js --- examples/homeContent/whiteboardV2/markerEntityScript.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/homeContent/whiteboardV2/markerEntityScript.js b/examples/homeContent/whiteboardV2/markerEntityScript.js index d06d5cf8e9..19907b283c 100644 --- a/examples/homeContent/whiteboardV2/markerEntityScript.js +++ b/examples/homeContent/whiteboardV2/markerEntityScript.js @@ -131,7 +131,7 @@ position: position, textures: _this.MARKER_TEXTURE_URL, color: _this.markerColor, - lifetime: 500, + lifetime: 5000, }); _this.linePoints = []; @@ -216,4 +216,4 @@ // entity scripts always need to return a newly constructed object of our type return new MarkerTip(); -}); \ No newline at end of file +});