From fb4aad1f3224018dcc8198e2eee6a908f6af73e1 Mon Sep 17 00:00:00 2001 From: ericrius1 Date: Mon, 12 Oct 2015 10:11:46 -0700 Subject: [PATCH 01/41] adding whiteboard --- examples/{ => painting}/closePaint.js | 0 examples/{ => painting}/paint.js | 0 .../painting/whiteboard/whiteboardSpawner.js | 32 +++++++++++++++++++ 3 files changed, 32 insertions(+) rename examples/{ => painting}/closePaint.js (100%) rename examples/{ => painting}/paint.js (100%) create mode 100644 examples/painting/whiteboard/whiteboardSpawner.js diff --git a/examples/closePaint.js b/examples/painting/closePaint.js similarity index 100% rename from examples/closePaint.js rename to examples/painting/closePaint.js diff --git a/examples/paint.js b/examples/painting/paint.js similarity index 100% rename from examples/paint.js rename to examples/painting/paint.js diff --git a/examples/painting/whiteboard/whiteboardSpawner.js b/examples/painting/whiteboard/whiteboardSpawner.js new file mode 100644 index 0000000000..bf6253c0ac --- /dev/null +++ b/examples/painting/whiteboard/whiteboardSpawner.js @@ -0,0 +1,32 @@ +// +// whiteBoard.js +// examples/painting +// +// Created by Eric Levina on 10/12/15. +// Copyright 2015 High Fidelity, Inc. +// +// Run this script to spawn a whiteboard that one can paint on +// +// 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 rotation = Quat.safeEulerAngles(Camera.getOrientation()); +rotation = Quat.fromPitchYawRollDegrees(0, rotation.y, 0) +var center = Vec3.sum(MyAvatar.position, Vec3.multiply(3, Quat.getFront(rotation))); +var whiteboard = Entities.addEntity({ + type: "Box", + position: center, + rotation: rotation, + dimensions: {x: 2, y: 1.5, z: 0.01}, + color: {red: 255, green: 255, blue: 255} +}); + +function cleanup() { + Entities.deleteEntity(whiteboard); +} + + +Script.scriptEnding.connect(cleanup); \ No newline at end of file From 56a2aa101cc6d45f93cfeed60134a1598c6c0578 Mon Sep 17 00:00:00 2001 From: ericrius1 Date: Mon, 12 Oct 2015 10:44:18 -0700 Subject: [PATCH 02/41] baseline judder test for whiteboard painting- pre entity ray test --- .../whiteboard/whiteboardEntityScript.js | 48 +++++++++++++++++++ .../painting/whiteboard/whiteboardSpawner.js | 10 +++- 2 files changed, 56 insertions(+), 2 deletions(-) create mode 100644 examples/painting/whiteboard/whiteboardEntityScript.js diff --git a/examples/painting/whiteboard/whiteboardEntityScript.js b/examples/painting/whiteboard/whiteboardEntityScript.js new file mode 100644 index 0000000000..da2e06d397 --- /dev/null +++ b/examples/painting/whiteboard/whiteboardEntityScript.js @@ -0,0 +1,48 @@ +// +// whiteBoardEntityScript.js +// examples/painting/whiteboard +// +// Created by Eric Levin on 10/12/15. +// Copyright 2015 High Fidelity, Inc. +// + +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html + +/*global print, MyAvatar, Entities, AnimationCache, SoundCache, Scene, Camera, Overlays, Audio, HMD, AvatarList, AvatarManager, Controller, UndoStack, Window, Account, GlobalServices, Script, ScriptDiscoveryService, LODManager, Menu, Vec3, Quat, AudioDevice, Paths, Clipboard, Settings, XMLHttpRequest, pointInExtents, vec3equal, setEntityCustomData, getEntityCustomData */ + +/*global Whiteboard */ + +(function() { + + var _this; + Whiteboard = function() { + _this = this; + }; + + Whiteboard.prototype = { + + setRightHand: function() { + this.hand = 'RIGHT'; + }, + + setLeftHand: function() { + this.hand = 'LEFT'; + }, + + startFarGrabNonColliding: function() { + this.whichHand = this.hand; + }, + + continueFarGrabbingNonColliding: function() {}, + + preload: function(entityID) { + this.entityID = entityID; + this.position = Entities.getEntityProperties(this.entityID, "position").position; + }, + + }; + + // entity scripts always need to return a newly constructed object of our type + return new Whiteboard(); +}); \ No newline at end of file diff --git a/examples/painting/whiteboard/whiteboardSpawner.js b/examples/painting/whiteboard/whiteboardSpawner.js index bf6253c0ac..31a72212c3 100644 --- a/examples/painting/whiteboard/whiteboardSpawner.js +++ b/examples/painting/whiteboard/whiteboardSpawner.js @@ -1,5 +1,5 @@ // -// whiteBoard.js +// whiteBoardSpawner.js // examples/painting // // Created by Eric Levina on 10/12/15. @@ -10,16 +10,22 @@ // Distributed under the Apache License, Version 2.0. // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +/*global print, MyAvatar, Entities, AnimationCache, SoundCache, Scene, Camera, Overlays, Audio, HMD, AvatarList, AvatarManager, Controller, UndoStack, Window, Account, GlobalServices, Script, ScriptDiscoveryService, LODManager, Menu, Vec3, Quat, AudioDevice, Paths, Clipboard, Settings, XMLHttpRequest, pointInExtents, vec3equal, setEntityCustomData, getEntityCustomData */ + + Script.include("../../libraries/utils.js"); +var scriptURL = Script.resolvePath("whiteBoardEntityScript.js"); var rotation = Quat.safeEulerAngles(Camera.getOrientation()); -rotation = Quat.fromPitchYawRollDegrees(0, rotation.y, 0) +rotation = Quat.fromPitchYawRollDegrees(0, rotation.y, 0); var center = Vec3.sum(MyAvatar.position, Vec3.multiply(3, Quat.getFront(rotation))); +center.y += 0.4; var whiteboard = Entities.addEntity({ type: "Box", position: center, rotation: rotation, + script: scriptURL, dimensions: {x: 2, y: 1.5, z: 0.01}, color: {red: 255, green: 255, blue: 255} }); From 96fd63413878c5fb75f752fbb4450708bccd91cd Mon Sep 17 00:00:00 2001 From: ericrius1 Date: Mon, 12 Oct 2015 11:02:47 -0700 Subject: [PATCH 03/41] Pre- ray cast --- .../painting/whiteboard/whiteboardEntityScript.js | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/examples/painting/whiteboard/whiteboardEntityScript.js b/examples/painting/whiteboard/whiteboardEntityScript.js index da2e06d397..c8e914b0e0 100644 --- a/examples/painting/whiteboard/whiteboardEntityScript.js +++ b/examples/painting/whiteboard/whiteboardEntityScript.js @@ -16,6 +16,8 @@ (function() { var _this; + var RIGHT_HAND = 1; + var LEFT_HAND = 0; Whiteboard = function() { _this = this; }; @@ -23,18 +25,20 @@ Whiteboard.prototype = { setRightHand: function() { - this.hand = 'RIGHT'; + this.hand = RIGHT_HAND; }, setLeftHand: function() { - this.hand = 'LEFT'; + this.hand = LEFT_HAND; }, startFarGrabNonColliding: function() { - this.whichHand = this.hand; + this.activeHand = this.hand; }, - continueFarGrabbingNonColliding: function() {}, + continueFarGrabbingNonColliding: function() { + var handClick = Controller.findAction(handClickString); + }, preload: function(entityID) { this.entityID = entityID; From 8dddf0e17a3de794c8a36d94fbb0ceb69d189196 Mon Sep 17 00:00:00 2001 From: ericrius1 Date: Mon, 12 Oct 2015 11:15:04 -0700 Subject: [PATCH 04/41] Added findRayIntersection, and confirmed judder grew a lot worse --- .../whiteboard/whiteboardEntityScript.js | 28 +++++++++++++++++-- 1 file changed, 26 insertions(+), 2 deletions(-) diff --git a/examples/painting/whiteboard/whiteboardEntityScript.js b/examples/painting/whiteboard/whiteboardEntityScript.js index c8e914b0e0..f9f272d5a3 100644 --- a/examples/painting/whiteboard/whiteboardEntityScript.js +++ b/examples/painting/whiteboard/whiteboardEntityScript.js @@ -18,6 +18,8 @@ var _this; var RIGHT_HAND = 1; var LEFT_HAND = 0; + var SPATIAL_CONTROLLERS_PER_PALM = 2; + var TIP_CONTROLLER_OFFSET = 1; Whiteboard = function() { _this = this; }; @@ -33,11 +35,33 @@ }, startFarGrabNonColliding: function() { - this.activeHand = this.hand; + if (this.hand === RIGHT_HAND) { + this.getHandPosition = MyAvatar.getRightPalmPosition; + this.getHandRotation = MyAvatar.getRightPalmRotation; + this.triggerAction = Controller.findAction("RIGHT_HAND_CLICK"); + } else if (this.hand === LEFT_HAND) { + this.getHandPosition = MyAvatar.getLeftPalmPosition; + this.getHandRotation = MyAvatar.getLeftPalmRotation; + this.triggerAction = Controller.findAction("LEFT_HAND_CLICK"); + } }, continueFarGrabbingNonColliding: function() { - var handClick = Controller.findAction(handClickString); + var handPosition = this.getHandPosition(); + var pickRay = { + origin: handPosition, + direction: Quat.getUp(this.getHandRotation()) + }; + this.intersection = Entities.findRayIntersection(pickRay, true); + if (this.intersection.intersects) { + if(JSON.stringify(this.intersection.entityID) === JSON.stringify(this.entityID)) { + print('YAAAAA') + } + } + }, + + releaseGrab: function() { + }, preload: function(entityID) { From d01dda9c8185136bd07c7dd6531ca7c90c470b72 Mon Sep 17 00:00:00 2001 From: ericrius1 Date: Mon, 12 Oct 2015 14:40:11 -0700 Subject: [PATCH 05/41] Adding in functionality to include only specified Ids in ray picking --- examples/controllers/handControllerGrab.js | 2 +- libraries/entities/src/EntityScriptingInterface.cpp | 10 +++++----- libraries/entities/src/EntityScriptingInterface.h | 6 +++--- libraries/entities/src/EntityTreeElement.cpp | 4 +++- libraries/entities/src/EntityTreeElement.h | 2 +- libraries/octree/src/Octree.cpp | 7 ++++--- libraries/octree/src/Octree.h | 1 + libraries/octree/src/OctreeElement.cpp | 6 +++--- libraries/octree/src/OctreeElement.h | 4 ++-- 9 files changed, 23 insertions(+), 19 deletions(-) diff --git a/examples/controllers/handControllerGrab.js b/examples/controllers/handControllerGrab.js index 05dfc8e5d5..26cb522f9a 100644 --- a/examples/controllers/handControllerGrab.js +++ b/examples/controllers/handControllerGrab.js @@ -67,7 +67,7 @@ var MSEC_PER_SEC = 1000.0; var startTime = Date.now(); var LIFETIME = 10; var ACTION_LIFETIME = 10; // seconds -var PICKS_PER_SECOND_PER_HAND = 5; +var PICKS_PER_SECOND_PER_HAND = 60; var MSECS_PER_SEC = 1000.0; // states for the state machine diff --git a/libraries/entities/src/EntityScriptingInterface.cpp b/libraries/entities/src/EntityScriptingInterface.cpp index 0dd0129a1e..47fee0ae4e 100644 --- a/libraries/entities/src/EntityScriptingInterface.cpp +++ b/libraries/entities/src/EntityScriptingInterface.cpp @@ -279,16 +279,16 @@ QVector EntityScriptingInterface::findEntitiesInBox(const glm::vec3& corn return result; } -RayToEntityIntersectionResult EntityScriptingInterface::findRayIntersection(const PickRay& ray, bool precisionPicking) { - return findRayIntersectionWorker(ray, Octree::TryLock, precisionPicking); +RayToEntityIntersectionResult EntityScriptingInterface::findRayIntersection(const PickRay& ray, const QVector& entityIdsToIgnore, bool precisionPicking) { + return findRayIntersectionWorker(ray, Octree::TryLock, entityIdsToIgnore, precisionPicking); } -RayToEntityIntersectionResult EntityScriptingInterface::findRayIntersectionBlocking(const PickRay& ray, bool precisionPicking) { - return findRayIntersectionWorker(ray, Octree::Lock, precisionPicking); +RayToEntityIntersectionResult EntityScriptingInterface::findRayIntersectionBlocking(const PickRay& ray, const QVector& entityIdsToIgnore, bool precisionPicking) { + return findRayIntersectionWorker(ray, Octree::Lock, entityIdsToIgnore, precisionPicking); } RayToEntityIntersectionResult EntityScriptingInterface::findRayIntersectionWorker(const PickRay& ray, - Octree::lockType lockType, + Octree::lockType lockType, const QVector& entityIdsToIgnore, bool precisionPicking) { diff --git a/libraries/entities/src/EntityScriptingInterface.h b/libraries/entities/src/EntityScriptingInterface.h index cf10bdb997..632019a575 100644 --- a/libraries/entities/src/EntityScriptingInterface.h +++ b/libraries/entities/src/EntityScriptingInterface.h @@ -111,11 +111,11 @@ public slots: /// If the scripting context has visible entities, this will determine a ray intersection, the results /// may be inaccurate if the engine is unable to access the visible entities, in which case result.accurate /// will be false. - Q_INVOKABLE RayToEntityIntersectionResult findRayIntersection(const PickRay& ray, bool precisionPicking = false); + Q_INVOKABLE RayToEntityIntersectionResult findRayIntersection(const PickRay& ray, const QVector& entityIdsToInclude, bool precisionPicking = false); /// If the scripting context has visible entities, this will determine a ray intersection, and will block in /// order to return an accurate result - Q_INVOKABLE RayToEntityIntersectionResult findRayIntersectionBlocking(const PickRay& ray, bool precisionPicking = false); + Q_INVOKABLE RayToEntityIntersectionResult findRayIntersectionBlocking(const PickRay& ray, const QVector& entityIdsToInclude, bool precisionPicking = false); Q_INVOKABLE void setLightsArePickable(bool value); Q_INVOKABLE bool getLightsArePickable() const; @@ -185,7 +185,7 @@ private: /// actually does the work of finding the ray intersection, can be called in locking mode or tryLock mode - RayToEntityIntersectionResult findRayIntersectionWorker(const PickRay& ray, Octree::lockType lockType, + RayToEntityIntersectionResult findRayIntersectionWorker(const PickRay& ray, Octree::lockType lockType, const QVector& entityIdsToInclude, bool precisionPicking); EntityTreePointer _entityTree; diff --git a/libraries/entities/src/EntityTreeElement.cpp b/libraries/entities/src/EntityTreeElement.cpp index 48c30caf20..d1f7adef94 100644 --- a/libraries/entities/src/EntityTreeElement.cpp +++ b/libraries/entities/src/EntityTreeElement.cpp @@ -495,12 +495,14 @@ bool EntityTreeElement::bestFitBounds(const glm::vec3& minPoint, const glm::vec3 bool EntityTreeElement::findDetailedRayIntersection(const glm::vec3& origin, const glm::vec3& direction, bool& keepSearching, OctreeElementPointer& element, float& distance, BoxFace& face, glm::vec3& surfaceNormal, - void** intersectedObject, bool precisionPicking, float distanceToElementCube) { + const QVector& entityIdsToInclude, void** intersectedObject, bool precisionPicking, float distanceToElementCube) { // only called if we do intersect our bounding cube, but find if we actually intersect with entities... int entityNumber = 0; bool somethingIntersected = false; forEachEntity([&](EntityItemPointer entity) { + + qDebug() << "entity Ids to ignore:************* " << entityIdsToInclude; AABox entityBox = entity->getAABox(); float localDistance; BoxFace localFace; diff --git a/libraries/entities/src/EntityTreeElement.h b/libraries/entities/src/EntityTreeElement.h index c26b5417ed..0a47542e65 100644 --- a/libraries/entities/src/EntityTreeElement.h +++ b/libraries/entities/src/EntityTreeElement.h @@ -144,7 +144,7 @@ public: virtual bool canRayIntersect() const { return hasEntities(); } virtual bool findDetailedRayIntersection(const glm::vec3& origin, const glm::vec3& direction, bool& keepSearching, OctreeElementPointer& element, float& distance, - BoxFace& face, glm::vec3& surfaceNormal, + BoxFace& face, glm::vec3& surfaceNormal, const QVector& entityIdsToInclude, void** intersectedObject, bool precisionPicking, float distanceToElementCube); virtual bool findSpherePenetration(const glm::vec3& center, float radius, diff --git a/libraries/octree/src/Octree.cpp b/libraries/octree/src/Octree.cpp index 758a47bc61..3b6467401c 100644 --- a/libraries/octree/src/Octree.cpp +++ b/libraries/octree/src/Octree.cpp @@ -703,6 +703,7 @@ public: float& distance; BoxFace& face; glm::vec3& surfaceNormal; + const QVector& entityIdsToInclude; void** intersectedObject; bool found; bool precisionPicking; @@ -712,7 +713,7 @@ bool findRayIntersectionOp(OctreeElementPointer element, void* extraData) { RayArgs* args = static_cast(extraData); bool keepSearching = true; if (element->findRayIntersection(args->origin, args->direction, keepSearching, - args->element, args->distance, args->face, args->surfaceNormal, + args->element, args->distance, args->face, args->surfaceNormal, args->entityIdsToInclude, args->intersectedObject, args->precisionPicking)) { args->found = true; } @@ -721,9 +722,9 @@ bool findRayIntersectionOp(OctreeElementPointer element, void* extraData) { bool Octree::findRayIntersection(const glm::vec3& origin, const glm::vec3& direction, OctreeElementPointer& element, float& distance, - BoxFace& face, glm::vec3& surfaceNormal, void** intersectedObject, + BoxFace& face, glm::vec3& surfaceNormal, const QVector& entityIdsToInclude, void** intersectedObject, Octree::lockType lockType, bool* accurateResult, bool precisionPicking) { - RayArgs args = { origin, direction, element, distance, face, surfaceNormal, intersectedObject, false, precisionPicking}; + RayArgs args = { origin, direction, element, distance, face, surfaceNormal, entityIdsToInclude, intersectedObject, false, precisionPicking}; distance = FLT_MAX; bool requireLock = lockType == Octree::Lock; diff --git a/libraries/octree/src/Octree.h b/libraries/octree/src/Octree.h index dececf1456..3ab1ad8ec4 100644 --- a/libraries/octree/src/Octree.h +++ b/libraries/octree/src/Octree.h @@ -300,6 +300,7 @@ public: bool findRayIntersection(const glm::vec3& origin, const glm::vec3& direction, OctreeElementPointer& node, float& distance, BoxFace& face, glm::vec3& surfaceNormal, + const QVector& entityIdsToInclude, void** intersectedObject = NULL, Octree::lockType lockType = Octree::TryLock, bool* accurateResult = NULL, diff --git a/libraries/octree/src/OctreeElement.cpp b/libraries/octree/src/OctreeElement.cpp index 25758c29d9..9a48079338 100644 --- a/libraries/octree/src/OctreeElement.cpp +++ b/libraries/octree/src/OctreeElement.cpp @@ -575,7 +575,7 @@ void OctreeElement::notifyUpdateHooks() { bool OctreeElement::findRayIntersection(const glm::vec3& origin, const glm::vec3& direction, bool& keepSearching, OctreeElementPointer& element, float& distance, - BoxFace& face, glm::vec3& surfaceNormal, + BoxFace& face, glm::vec3& surfaceNormal, const QVector& entityIdsToInclude, void** intersectedObject, bool precisionPicking) { keepSearching = true; // assume that we will continue searching after this. @@ -601,7 +601,7 @@ bool OctreeElement::findRayIntersection(const glm::vec3& origin, const glm::vec3 if (_cube.contains(origin) || distanceToElementCube < distance) { if (findDetailedRayIntersection(origin, direction, keepSearching, element, distanceToElementDetails, - face, localSurfaceNormal, intersectedObject, precisionPicking, distanceToElementCube)) { + face, localSurfaceNormal, entityIdsToInclude, intersectedObject, precisionPicking, distanceToElementCube)) { if (distanceToElementDetails < distance) { distance = distanceToElementDetails; @@ -616,7 +616,7 @@ bool OctreeElement::findRayIntersection(const glm::vec3& origin, const glm::vec3 bool OctreeElement::findDetailedRayIntersection(const glm::vec3& origin, const glm::vec3& direction, bool& keepSearching, OctreeElementPointer& element, float& distance, - BoxFace& face, glm::vec3& surfaceNormal, + BoxFace& face, glm::vec3& surfaceNormal, const QVector& entityIdsToInclude, void** intersectedObject, bool precisionPicking, float distanceToElementCube) { // we did hit this element, so calculate appropriate distances diff --git a/libraries/octree/src/OctreeElement.h b/libraries/octree/src/OctreeElement.h index fcdc9985e3..c132d437cd 100644 --- a/libraries/octree/src/OctreeElement.h +++ b/libraries/octree/src/OctreeElement.h @@ -120,12 +120,12 @@ public: virtual bool canRayIntersect() const { return isLeaf(); } virtual bool findRayIntersection(const glm::vec3& origin, const glm::vec3& direction, bool& keepSearching, OctreeElementPointer& node, float& distance, - BoxFace& face, glm::vec3& surfaceNormal, + BoxFace& face, glm::vec3& surfaceNormal, const QVector& entityIdsToInclude, void** intersectedObject = NULL, bool precisionPicking = false); virtual bool findDetailedRayIntersection(const glm::vec3& origin, const glm::vec3& direction, bool& keepSearching, OctreeElementPointer& element, float& distance, - BoxFace& face, glm::vec3& surfaceNormal, + BoxFace& face, glm::vec3& surfaceNormal, const QVector& entityIdsToInclude, void** intersectedObject, bool precisionPicking, float distanceToElementCube); /// \param center center of sphere in meters From 8d39f9c76059aab08bfabf672340273a669b9a5e Mon Sep 17 00:00:00 2001 From: ericrius1 Date: Mon, 12 Oct 2015 15:02:03 -0700 Subject: [PATCH 06/41] Syntax fixes --- .../painting/whiteboard/whiteboardEntityScript.js | 2 +- .../entities-renderer/src/EntityTreeRenderer.cpp | 4 ++-- .../entities-renderer/src/EntityTreeRenderer.h | 2 +- .../entities/src/EntityScriptingInterface.cpp | 14 +++++++------- libraries/entities/src/EntityScriptingInterface.h | 8 ++++---- libraries/octree/src/Octree.h | 2 +- 6 files changed, 16 insertions(+), 16 deletions(-) diff --git a/examples/painting/whiteboard/whiteboardEntityScript.js b/examples/painting/whiteboard/whiteboardEntityScript.js index f9f272d5a3..139c92c710 100644 --- a/examples/painting/whiteboard/whiteboardEntityScript.js +++ b/examples/painting/whiteboard/whiteboardEntityScript.js @@ -52,7 +52,7 @@ origin: handPosition, direction: Quat.getUp(this.getHandRotation()) }; - this.intersection = Entities.findRayIntersection(pickRay, true); + this.intersection = Entities.findRayIntersection(pickRay, true, [this.entityID]); if (this.intersection.intersects) { if(JSON.stringify(this.intersection.entityID) === JSON.stringify(this.entityID)) { print('YAAAAA') diff --git a/libraries/entities-renderer/src/EntityTreeRenderer.cpp b/libraries/entities-renderer/src/EntityTreeRenderer.cpp index fb9ab6563b..8f316af276 100644 --- a/libraries/entities-renderer/src/EntityTreeRenderer.cpp +++ b/libraries/entities-renderer/src/EntityTreeRenderer.cpp @@ -482,7 +482,7 @@ void EntityTreeRenderer::deleteReleasedModels() { } RayToEntityIntersectionResult EntityTreeRenderer::findRayIntersectionWorker(const PickRay& ray, Octree::lockType lockType, - bool precisionPicking) { + bool precisionPicking, const QVector& entityIdsToInclude) { RayToEntityIntersectionResult result; if (_tree) { EntityTreePointer entityTree = std::static_pointer_cast(_tree); @@ -490,7 +490,7 @@ RayToEntityIntersectionResult EntityTreeRenderer::findRayIntersectionWorker(cons OctreeElementPointer element; EntityItemPointer intersectedEntity = NULL; result.intersects = entityTree->findRayIntersection(ray.origin, ray.direction, element, result.distance, - result.face, result.surfaceNormal, + result.face, result.surfaceNormal, entityIdsToInclude, (void**)&intersectedEntity, lockType, &result.accurate, precisionPicking); if (result.intersects && intersectedEntity) { diff --git a/libraries/entities-renderer/src/EntityTreeRenderer.h b/libraries/entities-renderer/src/EntityTreeRenderer.h index 08ff1ac296..15c030f77e 100644 --- a/libraries/entities-renderer/src/EntityTreeRenderer.h +++ b/libraries/entities-renderer/src/EntityTreeRenderer.h @@ -130,7 +130,7 @@ private: QList _releasedModels; RayToEntityIntersectionResult findRayIntersectionWorker(const PickRay& ray, Octree::lockType lockType, - bool precisionPicking); + bool precisionPicking, const QVector& entityIdsToInclude = QVector()); EntityItemID _currentHoverOverEntityID; EntityItemID _currentClickingOnEntityID; diff --git a/libraries/entities/src/EntityScriptingInterface.cpp b/libraries/entities/src/EntityScriptingInterface.cpp index 47fee0ae4e..d260e73948 100644 --- a/libraries/entities/src/EntityScriptingInterface.cpp +++ b/libraries/entities/src/EntityScriptingInterface.cpp @@ -279,17 +279,17 @@ QVector EntityScriptingInterface::findEntitiesInBox(const glm::vec3& corn return result; } -RayToEntityIntersectionResult EntityScriptingInterface::findRayIntersection(const PickRay& ray, const QVector& entityIdsToIgnore, bool precisionPicking) { - return findRayIntersectionWorker(ray, Octree::TryLock, entityIdsToIgnore, precisionPicking); +RayToEntityIntersectionResult EntityScriptingInterface::findRayIntersection(const PickRay& ray, bool precisionPicking, const QVector& entityIdsToInclude) { + return findRayIntersectionWorker(ray, Octree::TryLock, precisionPicking, entityIdsToInclude); } -RayToEntityIntersectionResult EntityScriptingInterface::findRayIntersectionBlocking(const PickRay& ray, const QVector& entityIdsToIgnore, bool precisionPicking) { - return findRayIntersectionWorker(ray, Octree::Lock, entityIdsToIgnore, precisionPicking); +RayToEntityIntersectionResult EntityScriptingInterface::findRayIntersectionBlocking(const PickRay& ray, bool precisionPicking, const QVector& entityIdsToInclude) { + return findRayIntersectionWorker(ray, Octree::Lock, precisionPicking, entityIdsToInclude); } RayToEntityIntersectionResult EntityScriptingInterface::findRayIntersectionWorker(const PickRay& ray, - Octree::lockType lockType, const QVector& entityIdsToIgnore, - bool precisionPicking) { + Octree::lockType lockType, + bool precisionPicking, const QVector& entityIdsToInclude) { RayToEntityIntersectionResult result; @@ -297,7 +297,7 @@ RayToEntityIntersectionResult EntityScriptingInterface::findRayIntersectionWorke OctreeElementPointer element; EntityItemPointer intersectedEntity = NULL; result.intersects = _entityTree->findRayIntersection(ray.origin, ray.direction, element, result.distance, result.face, - result.surfaceNormal, (void**)&intersectedEntity, lockType, &result.accurate, + result.surfaceNormal, entityIdsToInclude, (void**)&intersectedEntity, lockType, &result.accurate, precisionPicking); if (result.intersects && intersectedEntity) { result.entityID = intersectedEntity->getEntityItemID(); diff --git a/libraries/entities/src/EntityScriptingInterface.h b/libraries/entities/src/EntityScriptingInterface.h index 632019a575..56610f2924 100644 --- a/libraries/entities/src/EntityScriptingInterface.h +++ b/libraries/entities/src/EntityScriptingInterface.h @@ -111,11 +111,11 @@ public slots: /// If the scripting context has visible entities, this will determine a ray intersection, the results /// may be inaccurate if the engine is unable to access the visible entities, in which case result.accurate /// will be false. - Q_INVOKABLE RayToEntityIntersectionResult findRayIntersection(const PickRay& ray, const QVector& entityIdsToInclude, bool precisionPicking = false); + Q_INVOKABLE RayToEntityIntersectionResult findRayIntersection(const PickRay& ray, bool precisionPicking = false, const QVector& entityIdsToInclude = QVector()); /// If the scripting context has visible entities, this will determine a ray intersection, and will block in /// order to return an accurate result - Q_INVOKABLE RayToEntityIntersectionResult findRayIntersectionBlocking(const PickRay& ray, const QVector& entityIdsToInclude, bool precisionPicking = false); + Q_INVOKABLE RayToEntityIntersectionResult findRayIntersectionBlocking(const PickRay& ray, bool precisionPicking = false, const QVector& entityIdsToInclude = QVector()); Q_INVOKABLE void setLightsArePickable(bool value); Q_INVOKABLE bool getLightsArePickable() const; @@ -185,8 +185,8 @@ private: /// actually does the work of finding the ray intersection, can be called in locking mode or tryLock mode - RayToEntityIntersectionResult findRayIntersectionWorker(const PickRay& ray, Octree::lockType lockType, const QVector& entityIdsToInclude, - bool precisionPicking); + RayToEntityIntersectionResult findRayIntersectionWorker(const PickRay& ray, Octree::lockType lockType, + bool precisionPicking, const QVector& entityIdsToInclude); EntityTreePointer _entityTree; EntitiesScriptEngineProvider* _entitiesScriptEngine = nullptr; diff --git a/libraries/octree/src/Octree.h b/libraries/octree/src/Octree.h index 3ab1ad8ec4..f0a4d2c9c0 100644 --- a/libraries/octree/src/Octree.h +++ b/libraries/octree/src/Octree.h @@ -300,7 +300,7 @@ public: bool findRayIntersection(const glm::vec3& origin, const glm::vec3& direction, OctreeElementPointer& node, float& distance, BoxFace& face, glm::vec3& surfaceNormal, - const QVector& entityIdsToInclude, + const QVector& entityIdsToInclude = QVector(), void** intersectedObject = NULL, Octree::lockType lockType = Octree::TryLock, bool* accurateResult = NULL, From f93b1d3325bd12a1f0f1c8e7a08161f6936dc908 Mon Sep 17 00:00:00 2001 From: ericrius1 Date: Mon, 12 Oct 2015 17:05:34 -0700 Subject: [PATCH 07/41] Correctly whitelisting entities for ray picking --- examples/controllers/handControllerGrab.js | 3 ++- .../whiteboard/whiteboardEntityScript.js | 7 ++---- .../painting/whiteboard/whiteboardSpawner.js | 4 +-- .../entities/src/EntityScriptingInterface.cpp | 25 ++++++++++++------- .../entities/src/EntityScriptingInterface.h | 4 +-- libraries/entities/src/EntityTreeElement.cpp | 14 ++++++++++- libraries/shared/src/RegisteredMetaTypes.cpp | 17 +++++++++++++ libraries/shared/src/RegisteredMetaTypes.h | 2 ++ 8 files changed, 56 insertions(+), 20 deletions(-) diff --git a/examples/controllers/handControllerGrab.js b/examples/controllers/handControllerGrab.js index 26cb522f9a..562e5396b1 100644 --- a/examples/controllers/handControllerGrab.js +++ b/examples/controllers/handControllerGrab.js @@ -253,6 +253,7 @@ function MyController(hand, triggerAction) { return; } + // the trigger is being pressed, do a ray test var handPosition = this.getHandPosition(); var pickRay = { @@ -568,7 +569,7 @@ function MyController(hand, triggerAction) { this.setState(STATE_RELEASE); return; } - + print("AHHHHHH") Entities.callEntityMethod(this.grabbedEntity, "continueNearGrabbingNonColliding"); }; diff --git a/examples/painting/whiteboard/whiteboardEntityScript.js b/examples/painting/whiteboard/whiteboardEntityScript.js index 139c92c710..6d651c974e 100644 --- a/examples/painting/whiteboard/whiteboardEntityScript.js +++ b/examples/painting/whiteboard/whiteboardEntityScript.js @@ -22,6 +22,7 @@ var TIP_CONTROLLER_OFFSET = 1; Whiteboard = function() { _this = this; + print("WAAAAAH"); }; Whiteboard.prototype = { @@ -52,12 +53,8 @@ origin: handPosition, direction: Quat.getUp(this.getHandRotation()) }; + this.intersection = Entities.findRayIntersection(pickRay, true, [this.entityID]); - if (this.intersection.intersects) { - if(JSON.stringify(this.intersection.entityID) === JSON.stringify(this.entityID)) { - print('YAAAAA') - } - } }, releaseGrab: function() { diff --git a/examples/painting/whiteboard/whiteboardSpawner.js b/examples/painting/whiteboard/whiteboardSpawner.js index 31a72212c3..506323dd59 100644 --- a/examples/painting/whiteboard/whiteboardSpawner.js +++ b/examples/painting/whiteboard/whiteboardSpawner.js @@ -15,7 +15,7 @@ Script.include("../../libraries/utils.js"); -var scriptURL = Script.resolvePath("whiteBoardEntityScript.js"); +var scriptURL = Script.resolvePath("whiteBoardEntityScript.js?v1" +Math.random()); var rotation = Quat.safeEulerAngles(Camera.getOrientation()); rotation = Quat.fromPitchYawRollDegrees(0, rotation.y, 0); @@ -26,7 +26,7 @@ var whiteboard = Entities.addEntity({ position: center, rotation: rotation, script: scriptURL, - dimensions: {x: 2, y: 1.5, z: 0.01}, + dimensions: {x: 2, y: 1.5, z: 0.1}, color: {red: 255, green: 255, blue: 255} }); diff --git a/libraries/entities/src/EntityScriptingInterface.cpp b/libraries/entities/src/EntityScriptingInterface.cpp index d260e73948..692ca7a638 100644 --- a/libraries/entities/src/EntityScriptingInterface.cpp +++ b/libraries/entities/src/EntityScriptingInterface.cpp @@ -279,12 +279,14 @@ QVector EntityScriptingInterface::findEntitiesInBox(const glm::vec3& corn return result; } -RayToEntityIntersectionResult EntityScriptingInterface::findRayIntersection(const PickRay& ray, bool precisionPicking, const QVector& entityIdsToInclude) { - return findRayIntersectionWorker(ray, Octree::TryLock, precisionPicking, entityIdsToInclude); +RayToEntityIntersectionResult EntityScriptingInterface::findRayIntersection(const PickRay& ray, bool precisionPicking, const QScriptValue& entityIdsToInclude) { + QVector entities = qVectorQUuidFromScriptValue(entityIdsToInclude); + return findRayIntersectionWorker(ray, Octree::TryLock, precisionPicking, entities); } -RayToEntityIntersectionResult EntityScriptingInterface::findRayIntersectionBlocking(const PickRay& ray, bool precisionPicking, const QVector& entityIdsToInclude) { - return findRayIntersectionWorker(ray, Octree::Lock, precisionPicking, entityIdsToInclude); +RayToEntityIntersectionResult EntityScriptingInterface::findRayIntersectionBlocking(const PickRay& ray, bool precisionPicking, const QScriptValue& entityIdsToInclude) { + const QVector& entities = qVectorQUuidFromScriptValue(entityIdsToInclude); + return findRayIntersectionWorker(ray, Octree::Lock, precisionPicking, entities); } RayToEntityIntersectionResult EntityScriptingInterface::findRayIntersectionWorker(const PickRay& ray, @@ -414,15 +416,20 @@ void RayToEntityIntersectionResultFromScriptValue(const QScriptValue& object, Ra QString faceName = object.property("face").toVariant().toString(); if (faceName == "MIN_X_FACE") { value.face = MIN_X_FACE; - } else if (faceName == "MAX_X_FACE") { + } + else if (faceName == "MAX_X_FACE") { value.face = MAX_X_FACE; - } else if (faceName == "MIN_Y_FACE") { + } + else if (faceName == "MIN_Y_FACE") { value.face = MIN_Y_FACE; - } else if (faceName == "MAX_Y_FACE") { + } + else if (faceName == "MAX_Y_FACE") { value.face = MAX_Y_FACE; - } else if (faceName == "MIN_Z_FACE") { + } + else if (faceName == "MIN_Z_FACE") { value.face = MIN_Z_FACE; - } else { + } + else { value.face = MAX_Z_FACE; }; QScriptValue intersection = object.property("intersection"); diff --git a/libraries/entities/src/EntityScriptingInterface.h b/libraries/entities/src/EntityScriptingInterface.h index 56610f2924..48f13e81bd 100644 --- a/libraries/entities/src/EntityScriptingInterface.h +++ b/libraries/entities/src/EntityScriptingInterface.h @@ -111,11 +111,11 @@ public slots: /// If the scripting context has visible entities, this will determine a ray intersection, the results /// may be inaccurate if the engine is unable to access the visible entities, in which case result.accurate /// will be false. - Q_INVOKABLE RayToEntityIntersectionResult findRayIntersection(const PickRay& ray, bool precisionPicking = false, const QVector& entityIdsToInclude = QVector()); + Q_INVOKABLE RayToEntityIntersectionResult findRayIntersection(const PickRay& ray, bool precisionPicking = false, const QScriptValue& entityIdsToInclude = QScriptValue()); /// If the scripting context has visible entities, this will determine a ray intersection, and will block in /// order to return an accurate result - Q_INVOKABLE RayToEntityIntersectionResult findRayIntersectionBlocking(const PickRay& ray, bool precisionPicking = false, const QVector& entityIdsToInclude = QVector()); + Q_INVOKABLE RayToEntityIntersectionResult findRayIntersectionBlocking(const PickRay& ray, bool precisionPicking = false, const QScriptValue& entityIdsToInclude = QScriptValue()); Q_INVOKABLE void setLightsArePickable(bool value); Q_INVOKABLE bool getLightsArePickable() const; diff --git a/libraries/entities/src/EntityTreeElement.cpp b/libraries/entities/src/EntityTreeElement.cpp index d1f7adef94..89e8e2d6d8 100644 --- a/libraries/entities/src/EntityTreeElement.cpp +++ b/libraries/entities/src/EntityTreeElement.cpp @@ -501,8 +501,20 @@ bool EntityTreeElement::findDetailedRayIntersection(const glm::vec3& origin, con int entityNumber = 0; bool somethingIntersected = false; forEachEntity([&](EntityItemPointer entity) { + if (entityIdsToInclude.size() > 0) { + bool entityInWhiteList = false; + //We only want to search whitelist if there is one, otherwise everything except blacklisted items are valid + for (int i = 0; i < entityIdsToInclude.size(); i++) { + if (entityIdsToInclude.at(i) == entity->getID()) { + entityInWhiteList = true; + } + } + if (!entityInWhiteList) { + // qDebug() << "entity not found in whitelist!"; + return; + } + } - qDebug() << "entity Ids to ignore:************* " << entityIdsToInclude; AABox entityBox = entity->getAABox(); float localDistance; BoxFace localFace; diff --git a/libraries/shared/src/RegisteredMetaTypes.cpp b/libraries/shared/src/RegisteredMetaTypes.cpp index b2389f4db6..27921336cf 100644 --- a/libraries/shared/src/RegisteredMetaTypes.cpp +++ b/libraries/shared/src/RegisteredMetaTypes.cpp @@ -104,6 +104,23 @@ QVector qVectorFloatFromScriptValue(const QScriptValue& array) { return newVector; } +QVector qVectorQUuidFromScriptValue(const QScriptValue& array) { + if (!array.isArray()) { + return QVector(); + } + QVector newVector; + int length = array.property("length").toInteger(); + newVector.reserve(length); + for (int i = 0; i < length; i++) { + QString uuidAsString = array.property(i).toString(); + QUuid fromString(uuidAsString); + newVector << fromString; + } + + return newVector; +} + + QScriptValue qVectorFloatToScriptValue(QScriptEngine* engine, const QVector& vector) { QScriptValue array = engine->newArray(); for (int i = 0; i < vector.size(); i++) { diff --git a/libraries/shared/src/RegisteredMetaTypes.h b/libraries/shared/src/RegisteredMetaTypes.h index c419741c3b..cd1e3b0d3e 100644 --- a/libraries/shared/src/RegisteredMetaTypes.h +++ b/libraries/shared/src/RegisteredMetaTypes.h @@ -65,6 +65,8 @@ QScriptValue qVectorFloatToScriptValue(QScriptEngine* engine, const QVector& vector); QVector qVectorFloatFromScriptValue(const QScriptValue& array); +QVector qVectorQUuidFromScriptValue(const QScriptValue& array); + class PickRay { public: PickRay() : origin(0.0f), direction(0.0f) { } From fb040426eb956c4781c730f1dc9ed67c855780e3 Mon Sep 17 00:00:00 2001 From: ericrius1 Date: Mon, 12 Oct 2015 17:34:50 -0700 Subject: [PATCH 08/41] added explanatory comment --- examples/painting/whiteboard/whiteboardEntityScript.js | 1 + examples/painting/whiteboard/whiteboardSpawner.js | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/examples/painting/whiteboard/whiteboardEntityScript.js b/examples/painting/whiteboard/whiteboardEntityScript.js index 6d651c974e..202f296b6e 100644 --- a/examples/painting/whiteboard/whiteboardEntityScript.js +++ b/examples/painting/whiteboard/whiteboardEntityScript.js @@ -55,6 +55,7 @@ }; this.intersection = Entities.findRayIntersection(pickRay, true, [this.entityID]); + // this.intersection = Entities.findRayIntersection(pickRay, true); }, releaseGrab: function() { diff --git a/examples/painting/whiteboard/whiteboardSpawner.js b/examples/painting/whiteboard/whiteboardSpawner.js index 506323dd59..058d2408a7 100644 --- a/examples/painting/whiteboard/whiteboardSpawner.js +++ b/examples/painting/whiteboard/whiteboardSpawner.js @@ -15,7 +15,7 @@ Script.include("../../libraries/utils.js"); -var scriptURL = Script.resolvePath("whiteBoardEntityScript.js?v1" +Math.random()); +var scriptURL = Script.resolvePath("whiteBoardEntityScript.js?v2"); var rotation = Quat.safeEulerAngles(Camera.getOrientation()); rotation = Quat.fromPitchYawRollDegrees(0, rotation.y, 0); From 33ff21f3766386cf94f5bbc7be642e25d854c88b Mon Sep 17 00:00:00 2001 From: ericrius1 Date: Mon, 12 Oct 2015 17:36:07 -0700 Subject: [PATCH 09/41] Got rid of debug message in handControllerGrab script --- examples/controllers/handControllerGrab.js | 1 - examples/painting/whiteboard/whiteboardEntityScript.js | 1 + 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/controllers/handControllerGrab.js b/examples/controllers/handControllerGrab.js index 562e5396b1..9bb293126a 100644 --- a/examples/controllers/handControllerGrab.js +++ b/examples/controllers/handControllerGrab.js @@ -569,7 +569,6 @@ function MyController(hand, triggerAction) { this.setState(STATE_RELEASE); return; } - print("AHHHHHH") Entities.callEntityMethod(this.grabbedEntity, "continueNearGrabbingNonColliding"); }; diff --git a/examples/painting/whiteboard/whiteboardEntityScript.js b/examples/painting/whiteboard/whiteboardEntityScript.js index 202f296b6e..1754bbe6ed 100644 --- a/examples/painting/whiteboard/whiteboardEntityScript.js +++ b/examples/painting/whiteboard/whiteboardEntityScript.js @@ -55,6 +55,7 @@ }; this.intersection = Entities.findRayIntersection(pickRay, true, [this.entityID]); + // Comment above line and uncomment below line to test difference in judder when whitelist is and is not provided // this.intersection = Entities.findRayIntersection(pickRay, true); }, From 04f0d792bb2460845d1cf4b917da0edc7295dad5 Mon Sep 17 00:00:00 2001 From: ericrius1 Date: Mon, 12 Oct 2015 17:36:53 -0700 Subject: [PATCH 10/41] Reverted grab back to 5 hz --- examples/controllers/handControllerGrab.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/controllers/handControllerGrab.js b/examples/controllers/handControllerGrab.js index 9bb293126a..3445547fa1 100644 --- a/examples/controllers/handControllerGrab.js +++ b/examples/controllers/handControllerGrab.js @@ -67,7 +67,7 @@ var MSEC_PER_SEC = 1000.0; var startTime = Date.now(); var LIFETIME = 10; var ACTION_LIFETIME = 10; // seconds -var PICKS_PER_SECOND_PER_HAND = 60; +var PICKS_PER_SECOND_PER_HAND = 5; var MSECS_PER_SEC = 1000.0; // states for the state machine From 2f620e654bf6c5a2b8c2466d39f6039fec4e3731 Mon Sep 17 00:00:00 2001 From: ericrius1 Date: Mon, 12 Oct 2015 17:37:51 -0700 Subject: [PATCH 11/41] Fixed styling --- libraries/entities/src/EntityTreeElement.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/libraries/entities/src/EntityTreeElement.cpp b/libraries/entities/src/EntityTreeElement.cpp index 89e8e2d6d8..b95b0ca673 100644 --- a/libraries/entities/src/EntityTreeElement.cpp +++ b/libraries/entities/src/EntityTreeElement.cpp @@ -503,14 +503,13 @@ bool EntityTreeElement::findDetailedRayIntersection(const glm::vec3& origin, con forEachEntity([&](EntityItemPointer entity) { if (entityIdsToInclude.size() > 0) { bool entityInWhiteList = false; - //We only want to search whitelist if there is one, otherwise everything except blacklisted items are valid + // We only want to search whitelist if there is one, otherwise everything except blacklisted items are valid for (int i = 0; i < entityIdsToInclude.size(); i++) { if (entityIdsToInclude.at(i) == entity->getID()) { entityInWhiteList = true; } } if (!entityInWhiteList) { - // qDebug() << "entity not found in whitelist!"; return; } } From 47c3df7587618e5d28f2cd45d33d00d3f88a5fe5 Mon Sep 17 00:00:00 2001 From: ericrius1 Date: Mon, 12 Oct 2015 17:38:52 -0700 Subject: [PATCH 12/41] Cleaned up spacing --- libraries/shared/src/RegisteredMetaTypes.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/libraries/shared/src/RegisteredMetaTypes.cpp b/libraries/shared/src/RegisteredMetaTypes.cpp index 27921336cf..9ab0eaecb4 100644 --- a/libraries/shared/src/RegisteredMetaTypes.cpp +++ b/libraries/shared/src/RegisteredMetaTypes.cpp @@ -116,11 +116,9 @@ QVector qVectorQUuidFromScriptValue(const QScriptValue& array) { QUuid fromString(uuidAsString); newVector << fromString; } - return newVector; } - QScriptValue qVectorFloatToScriptValue(QScriptEngine* engine, const QVector& vector) { QScriptValue array = engine->newArray(); for (int i = 0; i < vector.size(); i++) { From 470c8f7ef893783bf26b2388715acfa6d31319d4 Mon Sep 17 00:00:00 2001 From: ericrius1 Date: Tue, 13 Oct 2015 11:31:56 -0700 Subject: [PATCH 13/41] Painting on whiteboard with no judder --- .../whiteboard/whiteboardEntityScript.js | 108 +++++++++++++++++- .../painting/whiteboard/whiteboardSpawner.js | 2 +- 2 files changed, 104 insertions(+), 6 deletions(-) diff --git a/examples/painting/whiteboard/whiteboardEntityScript.js b/examples/painting/whiteboard/whiteboardEntityScript.js index 1754bbe6ed..9d62fbae54 100644 --- a/examples/painting/whiteboard/whiteboardEntityScript.js +++ b/examples/painting/whiteboard/whiteboardEntityScript.js @@ -13,16 +13,21 @@ /*global Whiteboard */ -(function() { + +(function() { + Script.include("../../libraries/utils.js"); var _this; var RIGHT_HAND = 1; var LEFT_HAND = 0; var SPATIAL_CONTROLLERS_PER_PALM = 2; var TIP_CONTROLLER_OFFSET = 1; + var MIN_POINT_DISTANCE = 0.02; + var MAX_POINT_DISTANCE = 0.5; + var MAX_POINTS_PER_LINE = 40; + Whiteboard = function() { _this = this; - print("WAAAAAH"); }; Whiteboard.prototype = { @@ -55,19 +60,112 @@ }; this.intersection = Entities.findRayIntersection(pickRay, true, [this.entityID]); - // Comment above line and uncomment below line to test difference in judder when whitelist is and is not provided - // this.intersection = Entities.findRayIntersection(pickRay, true); + if (this.intersection.intersects) { + this.paint(this.intersection.intersection, this.intersection.surfaceNormal); + } else { + this.painting = false; + } + }, + + paint: function(position, normal) { + if (this.painting === false) { + if (this.oldPosition) { + this.newStroke(this.oldPosition); + } else { + this.newStroke(position); + } + this.painting = true; + } + + + var localPoint = Vec3.subtract(position, this.strokeBasePosition); + //Move stroke a bit forward along normal so it doesnt zfight with mesh its drawing on + localPoint = Vec3.sum(localPoint, Vec3.multiply(this.normal, 0.001 + Math.random() * .001)); //rand avoid z fighting + + var distance = Vec3.distance(localPoint, this.strokePoints[this.strokePoints.length - 1]); + if (this.strokePoints.length > 0 && distance < MIN_POINT_DISTANCE) { + //need a minimum distance to avoid binormal NANs + return; + } + if (this.strokePoints.length > 0 && distance > MAX_POINT_DISTANCE) { + //Prevents drawing lines accross models + this.painting = false; + return; + } + if (this.strokePoints.length === 0) { + localPoint = { + x: 0, + y: 0, + z: 0 + }; + } + + this.strokePoints.push(localPoint); + this.strokeNormals.push(this.normal); + this.strokeWidths.push(this.currentStrokeWidth); + Entities.editEntity(this.currentStroke, { + linePoints: this.strokePoints, + normals: this.strokeNormals, + strokeWidths: this.strokeWidths + }); + if (this.strokePoints.length === MAX_POINTS_PER_LINE) { + this.painting = false; + return; + } + this.oldPosition = position; + }, + + + newStroke: function(position) { + + this.strokeBasePosition = position; + this.currentStroke = Entities.addEntity({ + position: position, + type: "PolyLine", + color: this.strokeColor, + dimensions: { + x: 50, + y: 50, + z: 50 + }, + lifetime: 200 + }); + this.strokePoints = []; + this.strokeNormals = []; + this.strokeWidths = []; + + this.strokes.push(this.currentStroke); + }, releaseGrab: function() { + this.painting = false; + this.oldPosition = null; }, preload: function(entityID) { this.entityID = entityID; - this.position = Entities.getEntityProperties(this.entityID, "position").position; + var props = Entities.getEntityProperties(this.entityID, ["position", "rotation"]); + this.position = props.position; + this.rotation = props.rotation; + this.normal = Vec3.multiply(Quat.getFront(this.rotation), -1); + this.painting = false; + this.strokeColor = { + red: 170, + green: 50, + blue: 190 + }; + this.strokes = []; + this.currentStrokeWidth = 0.02; }, + unload: function() { + this.strokes.forEach(function(stroke){ + Entities.deleteEntity(stroke); + }); + } + }; // entity scripts always need to return a newly constructed object of our type diff --git a/examples/painting/whiteboard/whiteboardSpawner.js b/examples/painting/whiteboard/whiteboardSpawner.js index 058d2408a7..6b7f23aecc 100644 --- a/examples/painting/whiteboard/whiteboardSpawner.js +++ b/examples/painting/whiteboard/whiteboardSpawner.js @@ -26,7 +26,7 @@ var whiteboard = Entities.addEntity({ position: center, rotation: rotation, script: scriptURL, - dimensions: {x: 2, y: 1.5, z: 0.1}, + dimensions: {x: 2, y: 1.5, z: 0.01}, color: {red: 255, green: 255, blue: 255} }); From b490f9e2c1967c9891b8f2f8214455e49718cf8d Mon Sep 17 00:00:00 2001 From: ericrius1 Date: Tue, 13 Oct 2015 13:33:24 -0700 Subject: [PATCH 14/41] Drawing line width based on trigger squeeze --- .../whiteboard/whiteboardEntityScript.js | 18 +++++++++++++++--- .../painting/whiteboard/whiteboardSpawner.js | 1 + 2 files changed, 16 insertions(+), 3 deletions(-) diff --git a/examples/painting/whiteboard/whiteboardEntityScript.js b/examples/painting/whiteboard/whiteboardEntityScript.js index 9d62fbae54..6bf7a9fd65 100644 --- a/examples/painting/whiteboard/whiteboardEntityScript.js +++ b/examples/painting/whiteboard/whiteboardEntityScript.js @@ -25,6 +25,11 @@ var MIN_POINT_DISTANCE = 0.02; var MAX_POINT_DISTANCE = 0.5; var MAX_POINTS_PER_LINE = 40; + var MAX_DISTANCE = 5; + + var TRIGGER_ON_VALUE = 0.3; + var MIN_STROKE_WIDTH = 0.001; + var MAX_STROKE_WIDTH = 0.02; Whiteboard = function() { _this = this; @@ -41,6 +46,9 @@ }, startFarGrabNonColliding: function() { + if (this.painting) { + return; + } if (this.hand === RIGHT_HAND) { this.getHandPosition = MyAvatar.getRightPalmPosition; this.getHandRotation = MyAvatar.getRightPalmRotation; @@ -61,7 +69,12 @@ this.intersection = Entities.findRayIntersection(pickRay, true, [this.entityID]); if (this.intersection.intersects) { - this.paint(this.intersection.intersection, this.intersection.surfaceNormal); + var distance = Vec3.distance(handPosition, this.intersection.intersection); + if (distance < MAX_DISTANCE) { + this.triggerValue = Controller.getActionValue(this.triggerAction); + this.currentStrokeWidth = map(this.triggerValue, TRIGGER_ON_VALUE, 1, MIN_STROKE_WIDTH, MAX_STROKE_WIDTH); + this.paint(this.intersection.intersection, this.intersection.surfaceNormal); + } } else { this.painting = false; } @@ -157,11 +170,10 @@ blue: 190 }; this.strokes = []; - this.currentStrokeWidth = 0.02; }, unload: function() { - this.strokes.forEach(function(stroke){ + this.strokes.forEach(function(stroke) { Entities.deleteEntity(stroke); }); } diff --git a/examples/painting/whiteboard/whiteboardSpawner.js b/examples/painting/whiteboard/whiteboardSpawner.js index 6b7f23aecc..4b7b99dc5b 100644 --- a/examples/painting/whiteboard/whiteboardSpawner.js +++ b/examples/painting/whiteboard/whiteboardSpawner.js @@ -30,6 +30,7 @@ var whiteboard = Entities.addEntity({ color: {red: 255, green: 255, blue: 255} }); + function cleanup() { Entities.deleteEntity(whiteboard); } From ad61b89abdaf5a81ba9d5908fc1022458cfbba0f Mon Sep 17 00:00:00 2001 From: ericrius1 Date: Tue, 13 Oct 2015 14:16:28 -0700 Subject: [PATCH 15/41] setting up colors, adding some functions to utils.js --- examples/libraries/utils.js | 18 ++++++ .../painting/whiteboard/whiteboardSpawner.js | 60 +++++++++++++++++-- examples/utilities.js | 60 ------------------- 3 files changed, 74 insertions(+), 64 deletions(-) delete mode 100644 examples/utilities.js diff --git a/examples/libraries/utils.js b/examples/libraries/utils.js index 3583aad76a..ab86007e4b 100644 --- a/examples/libraries/utils.js +++ b/examples/libraries/utils.js @@ -253,3 +253,21 @@ orientationOf = function(vector) { return Quat.multiply(yaw, pitch); } +randFloat = function(low, high) { + return low + Math.random() * (high - low); +} + + +randInt = function(low, high) { + return Math.floor(randFloat(low, high)); +} + +hexToRgb = function(hex) { + var result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex); + return result ? { + red: parseInt(result[1], 16), + green: parseInt(result[2], 16), + blue: parseInt(result[3], 16) + } : null; +} + diff --git a/examples/painting/whiteboard/whiteboardSpawner.js b/examples/painting/whiteboard/whiteboardSpawner.js index 4b7b99dc5b..0702aa0360 100644 --- a/examples/painting/whiteboard/whiteboardSpawner.js +++ b/examples/painting/whiteboard/whiteboardSpawner.js @@ -21,19 +21,71 @@ var rotation = Quat.safeEulerAngles(Camera.getOrientation()); rotation = Quat.fromPitchYawRollDegrees(0, rotation.y, 0); var center = Vec3.sum(MyAvatar.position, Vec3.multiply(3, Quat.getFront(rotation))); center.y += 0.4; +var whiteboardDimensions = { + x: 2, + y: 1.5, + z: 0.01 +}; var whiteboard = Entities.addEntity({ type: "Box", position: center, rotation: rotation, script: scriptURL, - dimensions: {x: 2, y: 1.5, z: 0.01}, - color: {red: 255, green: 255, blue: 255} + dimensions: whiteboardDimensions, + color: { + red: 255, + green: 255, + blue: 255 + } }); +//COLORS + +var colors = [ + hexToRgb("#2F8E84"), + hexToRgb("#66CCB3"), + hexToRgb("#A43C37"), + hexToRgb("#491849"), + hexToRgb("#6AB03B"), + hexToRgb("#993369"), + hexToRgb("#9B47C2") +]; + +var direction = Quat.getRight(rotation); +var colorBoxPosition = Vec3.subtract(center, Vec3.multiply(direction, whiteboardDimensions.x / 2)); +colorBoxPosition.y += whiteboardDimensions.y / 2; + +var colorBoxes = []; + +var colorSquareDimensions = { + x: (whiteboardDimensions.x / 2) / (colors.length - 1), + y: .1, + z: 0.05 +}; +var spaceBetweenColorBoxes = Vec3.multiply(direction, colorSquareDimensions.x * 2); + +for (var i = 0; i < colors.length; i++) { + var colorBox = Entities.addEntity({ + type: "Box", + position: colorBoxPosition, + dimensions: colorSquareDimensions, + rotation: rotation, + color: colors[i] + }); + colorBoxes.push(colorBox); + + colorBoxPosition = Vec3.sum(colorBoxPosition, spaceBetweenColorBoxes); + +} + + function cleanup() { Entities.deleteEntity(whiteboard); -} + colorBoxes.forEach(function(colorBox) { + Entities.deleteEntity(colorBox); + }); + } -Script.scriptEnding.connect(cleanup); \ No newline at end of file + Script.scriptEnding.connect(cleanup); \ No newline at end of file diff --git a/examples/utilities.js b/examples/utilities.js deleted file mode 100644 index 85e27079a8..0000000000 --- a/examples/utilities.js +++ /dev/null @@ -1,60 +0,0 @@ -// utilities.js -// examples -// -// Created by Eric Levin on June 8 -// Copyright 2015 High Fidelity, Inc. -// -// Common utilities -// -// Distributed under the Apache License, Version 2.0. -// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html - - - -map = function(value, min1, max1, min2, max2) { - return min2 + (max2 - min2) * ((value - min1) / (max1 - min1)); -} - -hslToRgb = function(hslColor) { - var h = hslColor.hue; - var s = hslColor.sat; - var l = hslColor.light; - var r, g, b; - - if (s == 0) { - r = g = b = l; // achromatic - } else { - var hue2rgb = function hue2rgb(p, q, t) { - if (t < 0) t += 1; - if (t > 1) t -= 1; - if (t < 1 / 6) return p + (q - p) * 6 * t; - if (t < 1 / 2) return q; - if (t < 2 / 3) return p + (q - p) * (2 / 3 - t) * 6; - return p; - } - - var q = l < 0.5 ? l * (1 + s) : l + s - l * s; - var p = 2 * l - q; - r = hue2rgb(p, q, h + 1 / 3); - g = hue2rgb(p, q, h); - b = hue2rgb(p, q, h - 1 / 3); - } - - return { - red: Math.round(r * 255), - green: Math.round(g * 255), - blue: Math.round(b * 255) - }; - -} - - - -randFloat = function(low, high) { - return low + Math.random() * (high - low); -} - - -randInt = function(low, high) { - return Math.floor(randFloat(low, high)); -} \ No newline at end of file From a3f948acf8712c7d87902a5ca2a9b95785b5058b Mon Sep 17 00:00:00 2001 From: ericrius1 Date: Tue, 13 Oct 2015 15:00:38 -0700 Subject: [PATCH 16/41] Adding entity script to each color box --- .../whiteboard/colorSelectorEntityScript.js | 47 +++++++++++++++++++ .../whiteboard/whiteboardEntityScript.js | 4 +- .../painting/whiteboard/whiteboardSpawner.js | 11 +++-- 3 files changed, 58 insertions(+), 4 deletions(-) create mode 100644 examples/painting/whiteboard/colorSelectorEntityScript.js diff --git a/examples/painting/whiteboard/colorSelectorEntityScript.js b/examples/painting/whiteboard/colorSelectorEntityScript.js new file mode 100644 index 0000000000..13f40446f0 --- /dev/null +++ b/examples/painting/whiteboard/colorSelectorEntityScript.js @@ -0,0 +1,47 @@ +// +// colorSelectorEntityScript.js +// examples/toybox/entityScripts +// +// Created by Eric Levin on 9/21/15. +// Copyright 2015 High Fidelity, Inc. +// + +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +/*global print, MyAvatar, Entities, AnimationCache, SoundCache, Scene, Camera, Overlays, Audio, HMD, AvatarList, AvatarManager, Controller, UndoStack, Window, Account, GlobalServices, Script, ScriptDiscoveryService, LODManager, Menu, Vec3, Quat, AudioDevice, Paths, Clipboard, Settings, XMLHttpRequest, randFloat, randInt */ +/*global ColorSelector */ + +(function() { + + var _this; + ColorSelector = function() { + _this = this; + }; + + ColorSelector.prototype = { + + startFarGrabNonColliding: function() { + this.selectColor(); + }, + + clickReleaseOnEntity: function() { + this.selectColor(); + }, + + selectColor: function() { + print("COLOR SELECTED"); + }, + + preload: function(entityID) { + this.entityID = entityID; + var props = Entities.getEntityProperties(this.entityID, ["position, color, userData"]); + this.position = props.position; + this.color = props.color; + this.whiteboard = JSON.parse(this.userData).whiteboard; + }, + + }; + + // entity scripts always need to return a newly constructed object of our type + return new ColorSelector(); +}); \ No newline at end of file diff --git a/examples/painting/whiteboard/whiteboardEntityScript.js b/examples/painting/whiteboard/whiteboardEntityScript.js index 6bf7a9fd65..aae154a35f 100644 --- a/examples/painting/whiteboard/whiteboardEntityScript.js +++ b/examples/painting/whiteboard/whiteboardEntityScript.js @@ -67,7 +67,7 @@ direction: Quat.getUp(this.getHandRotation()) }; - this.intersection = Entities.findRayIntersection(pickRay, true, [this.entityID]); + this.intersection = Entities.findRayIntersection(pickRay, true, this.whitelist); if (this.intersection.intersects) { var distance = Vec3.distance(handPosition, this.intersection.intersection); if (distance < MAX_DISTANCE) { @@ -170,6 +170,7 @@ blue: 190 }; this.strokes = []; + this.whitelist = [this.entityID]; }, unload: function() { @@ -180,6 +181,7 @@ }; + // entity scripts always need to return a newly constructed object of our type return new Whiteboard(); }); \ No newline at end of file diff --git a/examples/painting/whiteboard/whiteboardSpawner.js b/examples/painting/whiteboard/whiteboardSpawner.js index 0702aa0360..df97a744ef 100644 --- a/examples/painting/whiteboard/whiteboardSpawner.js +++ b/examples/painting/whiteboard/whiteboardSpawner.js @@ -58,19 +58,24 @@ colorBoxPosition.y += whiteboardDimensions.y / 2; var colorBoxes = []; var colorSquareDimensions = { - x: (whiteboardDimensions.x / 2) / (colors.length - 1), + x: (whiteboardDimensions.x / 2) / (colors.length - 1), y: .1, z: 0.05 }; var spaceBetweenColorBoxes = Vec3.multiply(direction, colorSquareDimensions.x * 2); - +var scriptURL = Script.resolvePath("colorSelectorEntityScript.js"); for (var i = 0; i < colors.length; i++) { var colorBox = Entities.addEntity({ type: "Box", position: colorBoxPosition, dimensions: colorSquareDimensions, rotation: rotation, - color: colors[i] + color: colors[i], + script: scriptURL, + userData: JSON.stringify({ + colorPalette: true, + whiteboard: whiteboard + }) }); colorBoxes.push(colorBox); From b54b488b9e262363047c8008a08c80154f2dc5ae Mon Sep 17 00:00:00 2001 From: ericrius1 Date: Tue, 13 Oct 2015 15:23:02 -0700 Subject: [PATCH 17/41] Adding in color selecting --- .../whiteboard/colorSelectorEntityScript.js | 4 +++ .../painting/whiteboard/whiteboardSpawner.js | 31 ++++++++++--------- 2 files changed, 21 insertions(+), 14 deletions(-) diff --git a/examples/painting/whiteboard/colorSelectorEntityScript.js b/examples/painting/whiteboard/colorSelectorEntityScript.js index 13f40446f0..9a77dae196 100644 --- a/examples/painting/whiteboard/colorSelectorEntityScript.js +++ b/examples/painting/whiteboard/colorSelectorEntityScript.js @@ -30,6 +30,10 @@ selectColor: function() { print("COLOR SELECTED"); + Entities.editEntity(this.whiteboard, { + userData: JSON.stringify({currentColor: this.color}) + }); + Entities.callEntityMethod(this.whiteboard, "changeColor"); }, preload: function(entityID) { diff --git a/examples/painting/whiteboard/whiteboardSpawner.js b/examples/painting/whiteboard/whiteboardSpawner.js index df97a744ef..b0a0785c82 100644 --- a/examples/painting/whiteboard/whiteboardSpawner.js +++ b/examples/painting/whiteboard/whiteboardSpawner.js @@ -26,20 +26,6 @@ var whiteboardDimensions = { y: 1.5, z: 0.01 }; -var whiteboard = Entities.addEntity({ - type: "Box", - position: center, - rotation: rotation, - script: scriptURL, - dimensions: whiteboardDimensions, - color: { - red: 255, - green: 255, - blue: 255 - } -}); - -//COLORS var colors = [ hexToRgb("#2F8E84"), @@ -50,6 +36,23 @@ var colors = [ hexToRgb("#993369"), hexToRgb("#9B47C2") ]; +var whiteboard = Entities.addEntity({ + type: "Box", + position: center, + rotation: rotation, + script: scriptURL, + dimensions: whiteboardDimensions, + color: { + red: 255, + green: 255, + blue: 255 + }, + userData: JSON.stringify({ + currentColor: colors[0] + }) +}); + +//COLORS var direction = Quat.getRight(rotation); var colorBoxPosition = Vec3.subtract(center, Vec3.multiply(direction, whiteboardDimensions.x / 2)); From 4c877e82047e780c303ff806146b95caa37acaae Mon Sep 17 00:00:00 2001 From: ericrius1 Date: Tue, 13 Oct 2015 15:46:10 -0700 Subject: [PATCH 18/41] Changing color when grabbing colored boxes --- examples/painting/whiteboard/colorSelectorEntityScript.js | 3 +-- examples/painting/whiteboard/whiteboardEntityScript.js | 5 +++++ examples/painting/whiteboard/whiteboardSpawner.js | 2 +- 3 files changed, 7 insertions(+), 3 deletions(-) diff --git a/examples/painting/whiteboard/colorSelectorEntityScript.js b/examples/painting/whiteboard/colorSelectorEntityScript.js index 9a77dae196..20bfeecdc6 100644 --- a/examples/painting/whiteboard/colorSelectorEntityScript.js +++ b/examples/painting/whiteboard/colorSelectorEntityScript.js @@ -29,7 +29,6 @@ }, selectColor: function() { - print("COLOR SELECTED"); Entities.editEntity(this.whiteboard, { userData: JSON.stringify({currentColor: this.color}) }); @@ -41,7 +40,7 @@ var props = Entities.getEntityProperties(this.entityID, ["position, color, userData"]); this.position = props.position; this.color = props.color; - this.whiteboard = JSON.parse(this.userData).whiteboard; + this.whiteboard = JSON.parse(props.userData).whiteboard; }, }; diff --git a/examples/painting/whiteboard/whiteboardEntityScript.js b/examples/painting/whiteboard/whiteboardEntityScript.js index aae154a35f..9c2fb11ac6 100644 --- a/examples/painting/whiteboard/whiteboardEntityScript.js +++ b/examples/painting/whiteboard/whiteboardEntityScript.js @@ -157,6 +157,11 @@ }, + changeColor: function(){ + print("CHANGE COLOR"); + this.strokeColor = JSON.parse(Entities.getEntityProperties(this.entityID, ["userData"]).userData).currentColor; + }, + preload: function(entityID) { this.entityID = entityID; var props = Entities.getEntityProperties(this.entityID, ["position", "rotation"]); diff --git a/examples/painting/whiteboard/whiteboardSpawner.js b/examples/painting/whiteboard/whiteboardSpawner.js index b0a0785c82..3f0849fee3 100644 --- a/examples/painting/whiteboard/whiteboardSpawner.js +++ b/examples/painting/whiteboard/whiteboardSpawner.js @@ -56,7 +56,6 @@ var whiteboard = Entities.addEntity({ var direction = Quat.getRight(rotation); var colorBoxPosition = Vec3.subtract(center, Vec3.multiply(direction, whiteboardDimensions.x / 2)); -colorBoxPosition.y += whiteboardDimensions.y / 2; var colorBoxes = []; @@ -65,6 +64,7 @@ var colorSquareDimensions = { y: .1, z: 0.05 }; +colorBoxPosition.y += whiteboardDimensions.y / 2 + colorSquareDimensions.y/2 - 0.01; var spaceBetweenColorBoxes = Vec3.multiply(direction, colorSquareDimensions.x * 2); var scriptURL = Script.resolvePath("colorSelectorEntityScript.js"); for (var i = 0; i < colors.length; i++) { From 2c8b85bb5cb587ca9004e1aa49d1f623dbd2d5ba Mon Sep 17 00:00:00 2001 From: ericrius1 Date: Tue, 13 Oct 2015 16:13:24 -0700 Subject: [PATCH 19/41] Displaying overlay laser pointer, user must past threshold to paint --- .../whiteboard/whiteboardEntityScript.js | 46 +++++++++++++------ 1 file changed, 32 insertions(+), 14 deletions(-) diff --git a/examples/painting/whiteboard/whiteboardEntityScript.js b/examples/painting/whiteboard/whiteboardEntityScript.js index 9c2fb11ac6..6e35f5d828 100644 --- a/examples/painting/whiteboard/whiteboardEntityScript.js +++ b/examples/painting/whiteboard/whiteboardEntityScript.js @@ -27,9 +27,9 @@ var MAX_POINTS_PER_LINE = 40; var MAX_DISTANCE = 5; - var TRIGGER_ON_VALUE = 0.3; - var MIN_STROKE_WIDTH = 0.001; - var MAX_STROKE_WIDTH = 0.02; + var PAINT_TRIGGER_THRESHOLD = 0.6; + var MIN_STROKE_WIDTH = 0.0005; + var MAX_STROKE_WIDTH = 0.03; Whiteboard = function() { _this = this; @@ -72,11 +72,25 @@ var distance = Vec3.distance(handPosition, this.intersection.intersection); if (distance < MAX_DISTANCE) { this.triggerValue = Controller.getActionValue(this.triggerAction); - this.currentStrokeWidth = map(this.triggerValue, TRIGGER_ON_VALUE, 1, MIN_STROKE_WIDTH, MAX_STROKE_WIDTH); - this.paint(this.intersection.intersection, this.intersection.surfaceNormal); + this.currentStrokeWidth = map(this.triggerValue, 0, 1, MIN_STROKE_WIDTH, MAX_STROKE_WIDTH); + var displayPoint = this.intersection.intersection; + displayPoint = Vec3.sum(displayPoint, Vec3.multiply(this.intersection.surfaceNormal, -.01)); + Overlays.editOverlay(this.laserPointer, { + position: displayPoint, + size: { + x: this.currentStrokeWidth, + y: this.currentStrokeWidth + } + }); + print("TRIGGER VALUE " + this.triggerValue); + if (this.triggerValue > PAINT_TRIGGER_THRESHOLD) { + this.paint(this.intersection.intersection, this.intersection.surfaceNormal); + } else { + this.releaseGrab(); + } } } else { - this.painting = false; + this.releaseGrab(); } }, @@ -154,34 +168,38 @@ releaseGrab: function() { this.painting = false; this.oldPosition = null; - }, - changeColor: function(){ + changeColor: function() { print("CHANGE COLOR"); this.strokeColor = JSON.parse(Entities.getEntityProperties(this.entityID, ["userData"]).userData).currentColor; + Overlays.editOverlay(this.laserPointer, { + color: this.strokeColor + }); }, preload: function(entityID) { this.entityID = entityID; - var props = Entities.getEntityProperties(this.entityID, ["position", "rotation"]); + var props = Entities.getEntityProperties(this.entityID, ["position", "rotation", "userData"]); this.position = props.position; this.rotation = props.rotation; this.normal = Vec3.multiply(Quat.getFront(this.rotation), -1); this.painting = false; - this.strokeColor = { - red: 170, - green: 50, - blue: 190 - }; this.strokes = []; this.whitelist = [this.entityID]; + this.strokeColor = JSON.parse(props.userData).currentColor; + this.laserPointer = Overlays.addOverlay("circle3d", { + color: this.strokeColor, + solid: true, + rotation: this.rotation + }); }, unload: function() { this.strokes.forEach(function(stroke) { Entities.deleteEntity(stroke); }); + Overlays.deleteOverlay(this.laserPointer); } }; From e42bbbc10da86cf2aa5dfdfa43ea3bc7611c6890 Mon Sep 17 00:00:00 2001 From: ericrius1 Date: Tue, 13 Oct 2015 16:41:05 -0700 Subject: [PATCH 20/41] Adding erase board feature to whiteboard --- .../painting/whiteboard/whiteboardSpawner.js | 46 +++++++++++++++---- 1 file changed, 38 insertions(+), 8 deletions(-) diff --git a/examples/painting/whiteboard/whiteboardSpawner.js b/examples/painting/whiteboard/whiteboardSpawner.js index 3f0849fee3..b9062fdfae 100644 --- a/examples/painting/whiteboard/whiteboardSpawner.js +++ b/examples/painting/whiteboard/whiteboardSpawner.js @@ -60,11 +60,11 @@ var colorBoxPosition = Vec3.subtract(center, Vec3.multiply(direction, whiteboard var colorBoxes = []; var colorSquareDimensions = { - x: (whiteboardDimensions.x / 2) / (colors.length - 1), + x: (whiteboardDimensions.x / 2) / (colors.length - 1), y: .1, z: 0.05 }; -colorBoxPosition.y += whiteboardDimensions.y / 2 + colorSquareDimensions.y/2 - 0.01; +colorBoxPosition.y += whiteboardDimensions.y / 2 + colorSquareDimensions.y / 2 - 0.01; var spaceBetweenColorBoxes = Vec3.multiply(direction, colorSquareDimensions.x * 2); var scriptURL = Script.resolvePath("colorSelectorEntityScript.js"); for (var i = 0; i < colors.length; i++) { @@ -81,19 +81,49 @@ for (var i = 0; i < colors.length; i++) { }) }); colorBoxes.push(colorBox); - colorBoxPosition = Vec3.sum(colorBoxPosition, spaceBetweenColorBoxes); - } +var eraseBoxDimensions = { + x: 0.5, + y: 0.1, + z: 0.01 +}; + + +var eraseBoxPosition = Vec3.sum(center, Vec3.multiply(direction, whiteboardDimensions.x / 2 + eraseBoxDimensions.x/2)); +eraseBoxPosition.y += 0.3; + +var eraseAllText = Entities.addEntity({ + type: "Text", + position: eraseBoxPosition, + rotation: rotation, + dimensions: eraseBoxDimensions, + backgroundColor: { + red: 0, + green: 60, + blue: 0 + }, + textColor: { + red: 255, + green: 10, + blue: 10 + }, + text: "ERASE BOARD", + lineHeight: 0.07 +}); +print(JSON.stringify(Entities.getEntityProperties(eraseAllText))) + + function cleanup() { Entities.deleteEntity(whiteboard); + Entities.deleteEntity(eraseAllText); colorBoxes.forEach(function(colorBox) { - Entities.deleteEntity(colorBox); - }); - } + Entities.deleteEntity(colorBox); + }); +} - Script.scriptEnding.connect(cleanup); \ No newline at end of file +Script.scriptEnding.connect(cleanup); \ No newline at end of file From 8e21999e440576686d03384ad30bde01d133dcb9 Mon Sep 17 00:00:00 2001 From: ericrius1 Date: Tue, 13 Oct 2015 16:54:37 -0700 Subject: [PATCH 21/41] erasing board --- .../whiteboard/colorSelectorEntityScript.js | 2 +- .../whiteboard/eraseBoardEntityScript.js | 45 +++++++++++++++++++ .../whiteboard/whiteboardEntityScript.js | 13 +++++- .../painting/whiteboard/whiteboardSpawner.js | 12 +++-- 4 files changed, 65 insertions(+), 7 deletions(-) create mode 100644 examples/painting/whiteboard/eraseBoardEntityScript.js diff --git a/examples/painting/whiteboard/colorSelectorEntityScript.js b/examples/painting/whiteboard/colorSelectorEntityScript.js index 20bfeecdc6..8ad003035c 100644 --- a/examples/painting/whiteboard/colorSelectorEntityScript.js +++ b/examples/painting/whiteboard/colorSelectorEntityScript.js @@ -1,6 +1,6 @@ // // colorSelectorEntityScript.js -// examples/toybox/entityScripts +// examples/painting/whiteboard // // Created by Eric Levin on 9/21/15. // Copyright 2015 High Fidelity, Inc. diff --git a/examples/painting/whiteboard/eraseBoardEntityScript.js b/examples/painting/whiteboard/eraseBoardEntityScript.js new file mode 100644 index 0000000000..14679c625b --- /dev/null +++ b/examples/painting/whiteboard/eraseBoardEntityScript.js @@ -0,0 +1,45 @@ +// +// eraseBoardEntityScript.js +// examples/painting/whiteboard +// +// Created by Eric Levin on 9/21/15. +// Copyright 2015 High Fidelity, Inc. +// + +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +/*global print, MyAvatar, Entities, AnimationCache, SoundCache, Scene, Camera, Overlays, Audio, HMD, AvatarList, AvatarManager, Controller, UndoStack, Window, Account, GlobalServices, Script, ScriptDiscoveryService, LODManager, Menu, Vec3, Quat, AudioDevice, Paths, Clipboard, Settings, XMLHttpRequest, randFloat, randInt */ +/*global BoardEraser */ + +(function() { + + var _this; + BoardEraser = function() { + _this = this; + }; + + BoardEraser.prototype = { + + startFarGrabNonColliding: function() { + this.eraseBoard(); + }, + + clickReleaseOnEntity: function() { + this.eraseBoard(); + }, + + eraseBoard: function() { + Entities.callEntityMethod(this.whiteboard, "eraseBoard"); + }, + + preload: function(entityID) { + this.entityID = entityID; + var props = Entities.getEntityProperties(this.entityID, ["userData"]); + this.whiteboard = JSON.parse(props.userData).whiteboard; + }, + + }; + + // entity scripts always need to return a newly constructed object of our type + return new BoardEraser(); +}); \ No newline at end of file diff --git a/examples/painting/whiteboard/whiteboardEntityScript.js b/examples/painting/whiteboard/whiteboardEntityScript.js index 6e35f5d828..2550754e2a 100644 --- a/examples/painting/whiteboard/whiteboardEntityScript.js +++ b/examples/painting/whiteboard/whiteboardEntityScript.js @@ -82,7 +82,6 @@ y: this.currentStrokeWidth } }); - print("TRIGGER VALUE " + this.triggerValue); if (this.triggerValue > PAINT_TRIGGER_THRESHOLD) { this.paint(this.intersection.intersection, this.intersection.surfaceNormal); } else { @@ -149,6 +148,7 @@ this.currentStroke = Entities.addEntity({ position: position, type: "PolyLine", + name: "paintStroke", color: this.strokeColor, dimensions: { x: 50, @@ -171,13 +171,22 @@ }, changeColor: function() { - print("CHANGE COLOR"); this.strokeColor = JSON.parse(Entities.getEntityProperties(this.entityID, ["userData"]).userData).currentColor; Overlays.editOverlay(this.laserPointer, { color: this.strokeColor }); }, + eraseBoard: function() { + var entities = Entities.findEntities(this.position, 5); + entities.forEach(function(entity) { + var name = Entities.getEntityProperties(entity, "name").name; + if(name === "paintStroke") { + Entities.deleteEntity(entity); + } + }); + }, + preload: function(entityID) { this.entityID = entityID; var props = Entities.getEntityProperties(this.entityID, ["position", "rotation", "userData"]); diff --git a/examples/painting/whiteboard/whiteboardSpawner.js b/examples/painting/whiteboard/whiteboardSpawner.js index b9062fdfae..691eec5120 100644 --- a/examples/painting/whiteboard/whiteboardSpawner.js +++ b/examples/painting/whiteboard/whiteboardSpawner.js @@ -1,6 +1,6 @@ // // whiteBoardSpawner.js -// examples/painting +// examples/painting/whiteboard // // Created by Eric Levina on 10/12/15. // Copyright 2015 High Fidelity, Inc. @@ -92,12 +92,13 @@ var eraseBoxDimensions = { }; -var eraseBoxPosition = Vec3.sum(center, Vec3.multiply(direction, whiteboardDimensions.x / 2 + eraseBoxDimensions.x/2)); +var eraseBoxPosition = Vec3.sum(center, Vec3.multiply(direction, whiteboardDimensions.x / 2 + eraseBoxDimensions.x / 2)); eraseBoxPosition.y += 0.3; - +scriptURL = Script.resolvePath("eraseBoardEntityScript.js"); var eraseAllText = Entities.addEntity({ type: "Text", position: eraseBoxPosition, + script: scriptURL, rotation: rotation, dimensions: eraseBoxDimensions, backgroundColor: { @@ -111,7 +112,10 @@ var eraseAllText = Entities.addEntity({ blue: 10 }, text: "ERASE BOARD", - lineHeight: 0.07 + lineHeight: 0.07, + userData: JSON.stringify({ + whiteboard: whiteboard + }) }); print(JSON.stringify(Entities.getEntityProperties(eraseAllText))) From caacbcbe789db119829cd5998c202b66da8fb2f2 Mon Sep 17 00:00:00 2001 From: ericrius1 Date: Wed, 14 Oct 2015 10:40:55 -0700 Subject: [PATCH 22/41] Adjust erase box position --- examples/painting/whiteboard/whiteboardEntityScript.js | 5 ++++- examples/painting/whiteboard/whiteboardSpawner.js | 2 +- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/examples/painting/whiteboard/whiteboardEntityScript.js b/examples/painting/whiteboard/whiteboardEntityScript.js index 2550754e2a..fe47ec1810 100644 --- a/examples/painting/whiteboard/whiteboardEntityScript.js +++ b/examples/painting/whiteboard/whiteboardEntityScript.js @@ -58,6 +58,7 @@ this.getHandRotation = MyAvatar.getLeftPalmRotation; this.triggerAction = Controller.findAction("LEFT_HAND_CLICK"); } + Overlays.editOverlay(this.laserPointer, {visible: true}); }, continueFarGrabbingNonColliding: function() { @@ -85,7 +86,8 @@ if (this.triggerValue > PAINT_TRIGGER_THRESHOLD) { this.paint(this.intersection.intersection, this.intersection.surfaceNormal); } else { - this.releaseGrab(); + this.painting = false; + this.oldPosition = null; } } } else { @@ -167,6 +169,7 @@ releaseGrab: function() { this.painting = false; + Overlays.editOverlay(this.laserPointer, {visible: false}); this.oldPosition = null; }, diff --git a/examples/painting/whiteboard/whiteboardSpawner.js b/examples/painting/whiteboard/whiteboardSpawner.js index 691eec5120..32e049aef6 100644 --- a/examples/painting/whiteboard/whiteboardSpawner.js +++ b/examples/painting/whiteboard/whiteboardSpawner.js @@ -92,7 +92,7 @@ var eraseBoxDimensions = { }; -var eraseBoxPosition = Vec3.sum(center, Vec3.multiply(direction, whiteboardDimensions.x / 2 + eraseBoxDimensions.x / 2)); +var eraseBoxPosition = Vec3.sum(center, Vec3.multiply(direction, whiteboardDimensions.x / 2 + eraseBoxDimensions.x / 2 + 0.01)); eraseBoxPosition.y += 0.3; scriptURL = Script.resolvePath("eraseBoardEntityScript.js"); var eraseAllText = Entities.addEntity({ From 20d1a2440c9487defcf5c34180976aa457c638db Mon Sep 17 00:00:00 2001 From: ericrius1 Date: Wed, 14 Oct 2015 11:15:49 -0700 Subject: [PATCH 23/41] Ignoring unknown types in collision --- examples/controllers/handControllerGrab.js | 3 +- .../whiteboard/whiteboardEntityScript.js | 38 ++++++++++++------- .../painting/whiteboard/whiteboardSpawner.js | 24 ++++++++++-- 3 files changed, 47 insertions(+), 18 deletions(-) diff --git a/examples/controllers/handControllerGrab.js b/examples/controllers/handControllerGrab.js index 3445547fa1..0f59e80948 100644 --- a/examples/controllers/handControllerGrab.js +++ b/examples/controllers/handControllerGrab.js @@ -67,7 +67,7 @@ var MSEC_PER_SEC = 1000.0; var startTime = Date.now(); var LIFETIME = 10; var ACTION_LIFETIME = 10; // seconds -var PICKS_PER_SECOND_PER_HAND = 5; +var PICKS_PER_SECOND_PER_HAND = 60; var MSECS_PER_SEC = 1000.0; // states for the state machine @@ -177,6 +177,7 @@ function MyController(hand, triggerAction) { this.continueFarGrabbingNonColliding(); break; case STATE_RELEASE: + print("TRIGGER VALUE " + this.triggerValue); this.release(); break; } diff --git a/examples/painting/whiteboard/whiteboardEntityScript.js b/examples/painting/whiteboard/whiteboardEntityScript.js index fe47ec1810..59977fe52a 100644 --- a/examples/painting/whiteboard/whiteboardEntityScript.js +++ b/examples/painting/whiteboard/whiteboardEntityScript.js @@ -20,8 +20,6 @@ var _this; var RIGHT_HAND = 1; var LEFT_HAND = 0; - var SPATIAL_CONTROLLERS_PER_PALM = 2; - var TIP_CONTROLLER_OFFSET = 1; var MIN_POINT_DISTANCE = 0.02; var MAX_POINT_DISTANCE = 0.5; var MAX_POINTS_PER_LINE = 40; @@ -58,7 +56,9 @@ this.getHandRotation = MyAvatar.getLeftPalmRotation; this.triggerAction = Controller.findAction("LEFT_HAND_CLICK"); } - Overlays.editOverlay(this.laserPointer, {visible: true}); + Overlays.editOverlay(this.laserPointer, { + visible: true + }); }, continueFarGrabbingNonColliding: function() { @@ -69,13 +69,14 @@ }; this.intersection = Entities.findRayIntersection(pickRay, true, this.whitelist); + if (this.intersection.intersects) { var distance = Vec3.distance(handPosition, this.intersection.intersection); if (distance < MAX_DISTANCE) { this.triggerValue = Controller.getActionValue(this.triggerAction); this.currentStrokeWidth = map(this.triggerValue, 0, 1, MIN_STROKE_WIDTH, MAX_STROKE_WIDTH); var displayPoint = this.intersection.intersection; - displayPoint = Vec3.sum(displayPoint, Vec3.multiply(this.intersection.surfaceNormal, -.01)); + displayPoint = Vec3.sum(displayPoint, Vec3.multiply(this.intersection.surfaceNormal, -0.01)); Overlays.editOverlay(this.laserPointer, { position: displayPoint, size: { @@ -90,11 +91,22 @@ this.oldPosition = null; } } - } else { - this.releaseGrab(); + } else if(this.intersection.properties.type !== "Unknown") { + //If type is unknown, ignore + print("entity name " + this.intersection.properties.type); + this.stopPainting(); } }, + stopPainting: function() { + this.painting = false; + Overlays.editOverlay(this.laserPointer, { + visible: false + }); + this.oldPosition = null; + print("STOP PAINTING"); + }, + paint: function(position, normal) { if (this.painting === false) { if (this.oldPosition) { @@ -108,11 +120,12 @@ var localPoint = Vec3.subtract(position, this.strokeBasePosition); //Move stroke a bit forward along normal so it doesnt zfight with mesh its drawing on - localPoint = Vec3.sum(localPoint, Vec3.multiply(this.normal, 0.001 + Math.random() * .001)); //rand avoid z fighting - + localPoint = Vec3.sum(localPoint, Vec3.multiply(this.normal, 0.001 + Math.random() * 0.001)); //rand avoid z fighting + this.oldPosition = position; var distance = Vec3.distance(localPoint, this.strokePoints[this.strokePoints.length - 1]); if (this.strokePoints.length > 0 && distance < MIN_POINT_DISTANCE) { //need a minimum distance to avoid binormal NANs + return; } if (this.strokePoints.length > 0 && distance > MAX_POINT_DISTANCE) { @@ -140,7 +153,6 @@ this.painting = false; return; } - this.oldPosition = position; }, @@ -168,9 +180,9 @@ }, releaseGrab: function() { - this.painting = false; - Overlays.editOverlay(this.laserPointer, {visible: false}); - this.oldPosition = null; + print("RELEASE"); + this.stopPainting(); + }, changeColor: function() { @@ -184,7 +196,7 @@ var entities = Entities.findEntities(this.position, 5); entities.forEach(function(entity) { var name = Entities.getEntityProperties(entity, "name").name; - if(name === "paintStroke") { + if (name === "paintStroke") { Entities.deleteEntity(entity); } }); diff --git a/examples/painting/whiteboard/whiteboardSpawner.js b/examples/painting/whiteboard/whiteboardSpawner.js index 32e049aef6..43a490a67e 100644 --- a/examples/painting/whiteboard/whiteboardSpawner.js +++ b/examples/painting/whiteboard/whiteboardSpawner.js @@ -11,8 +11,8 @@ // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html /*global print, MyAvatar, Entities, AnimationCache, SoundCache, Scene, Camera, Overlays, Audio, HMD, AvatarList, AvatarManager, Controller, UndoStack, Window, Account, GlobalServices, Script, ScriptDiscoveryService, LODManager, Menu, Vec3, Quat, AudioDevice, Paths, Clipboard, Settings, XMLHttpRequest, pointInExtents, vec3equal, setEntityCustomData, getEntityCustomData */ - - +// Script specific +/*global hexToRgb */ Script.include("../../libraries/utils.js"); var scriptURL = Script.resolvePath("whiteBoardEntityScript.js?v2"); @@ -38,6 +38,7 @@ var colors = [ ]; var whiteboard = Entities.addEntity({ type: "Box", + name: "whiteboard", position: center, rotation: rotation, script: scriptURL, @@ -61,7 +62,7 @@ var colorBoxes = []; var colorSquareDimensions = { x: (whiteboardDimensions.x / 2) / (colors.length - 1), - y: .1, + y: 0.1, z: 0.05 }; colorBoxPosition.y += whiteboardDimensions.y / 2 + colorSquareDimensions.y / 2 - 0.01; @@ -76,7 +77,6 @@ for (var i = 0; i < colors.length; i++) { color: colors[i], script: scriptURL, userData: JSON.stringify({ - colorPalette: true, whiteboard: whiteboard }) }); @@ -84,6 +84,21 @@ for (var i = 0; i < colors.length; i++) { colorBoxPosition = Vec3.sum(colorBoxPosition, spaceBetweenColorBoxes); } +var blackBoxDimensions = {x: .2, y: .2, z: 0.05}; +colorBoxPosition = Vec3.subtract(center, Vec3.multiply(direction, whiteboardDimensions.x / 2 + blackBoxDimensions.x/2 - 0.01)); +colorBoxPosition.y += 0.3; +var blackBox = Entities.addEntity({ + type: 'Box', + position: colorBoxPosition, + dimensions: blackBoxDimensions, + rotation: rotation, + color: {red: 0, green: 0, blue: 0}, + script: scriptURL, + userData: JSON.stringify({ + whiteboard: whiteboard + }) +}) + var eraseBoxDimensions = { x: 0.5, @@ -124,6 +139,7 @@ print(JSON.stringify(Entities.getEntityProperties(eraseAllText))) function cleanup() { Entities.deleteEntity(whiteboard); Entities.deleteEntity(eraseAllText); + Entities.deleteEntity(blackBox); colorBoxes.forEach(function(colorBox) { Entities.deleteEntity(colorBox); }); From 1a9c1110c0fe30e61d4ecdaed2b7718710d6fc6d Mon Sep 17 00:00:00 2001 From: ericrius1 Date: Wed, 14 Oct 2015 11:17:54 -0700 Subject: [PATCH 24/41] Fixed gap between strokes --- examples/painting/whiteboard/whiteboardEntityScript.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/painting/whiteboard/whiteboardEntityScript.js b/examples/painting/whiteboard/whiteboardEntityScript.js index 59977fe52a..08cca8a047 100644 --- a/examples/painting/whiteboard/whiteboardEntityScript.js +++ b/examples/painting/whiteboard/whiteboardEntityScript.js @@ -121,7 +121,6 @@ var localPoint = Vec3.subtract(position, this.strokeBasePosition); //Move stroke a bit forward along normal so it doesnt zfight with mesh its drawing on localPoint = Vec3.sum(localPoint, Vec3.multiply(this.normal, 0.001 + Math.random() * 0.001)); //rand avoid z fighting - this.oldPosition = position; var distance = Vec3.distance(localPoint, this.strokePoints[this.strokePoints.length - 1]); if (this.strokePoints.length > 0 && distance < MIN_POINT_DISTANCE) { //need a minimum distance to avoid binormal NANs @@ -153,6 +152,7 @@ this.painting = false; return; } + this.oldPosition = position; }, From d072a2efd37859cb8b8827f26f4f156596c8d56b Mon Sep 17 00:00:00 2001 From: ericrius1 Date: Wed, 14 Oct 2015 11:26:38 -0700 Subject: [PATCH 25/41] laser pointer now showing up all the time --- examples/painting/whiteboard/whiteboardEntityScript.js | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/examples/painting/whiteboard/whiteboardEntityScript.js b/examples/painting/whiteboard/whiteboardEntityScript.js index 08cca8a047..122e1b2e38 100644 --- a/examples/painting/whiteboard/whiteboardEntityScript.js +++ b/examples/painting/whiteboard/whiteboardEntityScript.js @@ -69,6 +69,7 @@ }; this.intersection = Entities.findRayIntersection(pickRay, true, this.whitelist); + //Comment out above line and uncomment below line to see difference in performance between using a whitelist, and not using one if (this.intersection.intersects) { var distance = Vec3.distance(handPosition, this.intersection.intersection); @@ -76,7 +77,7 @@ this.triggerValue = Controller.getActionValue(this.triggerAction); this.currentStrokeWidth = map(this.triggerValue, 0, 1, MIN_STROKE_WIDTH, MAX_STROKE_WIDTH); var displayPoint = this.intersection.intersection; - displayPoint = Vec3.sum(displayPoint, Vec3.multiply(this.intersection.surfaceNormal, -0.01)); + displayPoint = Vec3.sum(displayPoint, Vec3.multiply(this.normal, 0.01)); Overlays.editOverlay(this.laserPointer, { position: displayPoint, size: { @@ -92,8 +93,7 @@ } } } else if(this.intersection.properties.type !== "Unknown") { - //If type is unknown, ignore - print("entity name " + this.intersection.properties.type); + //Sometimes ray will pick against an invisible object with type unkown... so if type is unknown, ignore this.stopPainting(); } }, @@ -104,7 +104,6 @@ visible: false }); this.oldPosition = null; - print("STOP PAINTING"); }, paint: function(position, normal) { @@ -180,7 +179,6 @@ }, releaseGrab: function() { - print("RELEASE"); this.stopPainting(); }, From 7fb6b7e27283d1a51e66936f92cc43a34525949b Mon Sep 17 00:00:00 2001 From: ericrius1 Date: Wed, 14 Oct 2015 11:31:09 -0700 Subject: [PATCH 26/41] Reverted hand controller --- examples/controllers/handControllerGrab.js | 2 +- examples/painting/whiteboard/whiteboardEntityScript.js | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/examples/controllers/handControllerGrab.js b/examples/controllers/handControllerGrab.js index 0f59e80948..0b761c6559 100644 --- a/examples/controllers/handControllerGrab.js +++ b/examples/controllers/handControllerGrab.js @@ -67,7 +67,7 @@ var MSEC_PER_SEC = 1000.0; var startTime = Date.now(); var LIFETIME = 10; var ACTION_LIFETIME = 10; // seconds -var PICKS_PER_SECOND_PER_HAND = 60; +var PICKS_PER_SECOND_PER_HAND = 5; var MSECS_PER_SEC = 1000.0; // states for the state machine diff --git a/examples/painting/whiteboard/whiteboardEntityScript.js b/examples/painting/whiteboard/whiteboardEntityScript.js index 122e1b2e38..0cfa12746a 100644 --- a/examples/painting/whiteboard/whiteboardEntityScript.js +++ b/examples/painting/whiteboard/whiteboardEntityScript.js @@ -70,6 +70,7 @@ this.intersection = Entities.findRayIntersection(pickRay, true, this.whitelist); //Comment out above line and uncomment below line to see difference in performance between using a whitelist, and not using one + // this.intersection = Entities.findRayIntersection(pickRay, true); if (this.intersection.intersects) { var distance = Vec3.distance(handPosition, this.intersection.intersection); From 6cd9bf407f9fb7d59fec862553fefbc275bf414f Mon Sep 17 00:00:00 2001 From: ericrius1 Date: Wed, 14 Oct 2015 11:40:06 -0700 Subject: [PATCH 27/41] Reverted handControllerGrab --- examples/controllers/handControllerGrab.js | 3 +-- examples/painting/whiteboard/whiteboardSpawner.js | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/examples/controllers/handControllerGrab.js b/examples/controllers/handControllerGrab.js index 0b761c6559..d8d7934191 100644 --- a/examples/controllers/handControllerGrab.js +++ b/examples/controllers/handControllerGrab.js @@ -177,7 +177,6 @@ function MyController(hand, triggerAction) { this.continueFarGrabbingNonColliding(); break; case STATE_RELEASE: - print("TRIGGER VALUE " + this.triggerValue); this.release(); break; } @@ -254,7 +253,6 @@ function MyController(hand, triggerAction) { return; } - // the trigger is being pressed, do a ray test var handPosition = this.getHandPosition(); var pickRay = { @@ -570,6 +568,7 @@ function MyController(hand, triggerAction) { this.setState(STATE_RELEASE); return; } + Entities.callEntityMethod(this.grabbedEntity, "continueNearGrabbingNonColliding"); }; diff --git a/examples/painting/whiteboard/whiteboardSpawner.js b/examples/painting/whiteboard/whiteboardSpawner.js index 43a490a67e..3e89775ff0 100644 --- a/examples/painting/whiteboard/whiteboardSpawner.js +++ b/examples/painting/whiteboard/whiteboardSpawner.js @@ -146,4 +146,4 @@ function cleanup() { } -Script.scriptEnding.connect(cleanup); \ No newline at end of file +// Script.scriptEnding.connect(cleanup); \ No newline at end of file From 22615dae0753490fe1f135f335cb1982387acba3 Mon Sep 17 00:00:00 2001 From: ericrius1 Date: Wed, 14 Oct 2015 11:43:05 -0700 Subject: [PATCH 28/41] Don't delete board on script close --- examples/painting/whiteboard/whiteboardSpawner.js | 1 + 1 file changed, 1 insertion(+) diff --git a/examples/painting/whiteboard/whiteboardSpawner.js b/examples/painting/whiteboard/whiteboardSpawner.js index 3e89775ff0..f4ce57ca50 100644 --- a/examples/painting/whiteboard/whiteboardSpawner.js +++ b/examples/painting/whiteboard/whiteboardSpawner.js @@ -146,4 +146,5 @@ function cleanup() { } +// Uncomment this line to delete whiteboard and all associated entity on script close // Script.scriptEnding.connect(cleanup); \ No newline at end of file From 0991be32557f4cd4596b00d6f8ad33bc16fbbf55 Mon Sep 17 00:00:00 2001 From: ericrius1 Date: Wed, 14 Oct 2015 11:44:47 -0700 Subject: [PATCH 29/41] got rid of printing statements --- examples/painting/whiteboard/whiteboardSpawner.js | 1 - 1 file changed, 1 deletion(-) diff --git a/examples/painting/whiteboard/whiteboardSpawner.js b/examples/painting/whiteboard/whiteboardSpawner.js index f4ce57ca50..f6f32eaa4d 100644 --- a/examples/painting/whiteboard/whiteboardSpawner.js +++ b/examples/painting/whiteboard/whiteboardSpawner.js @@ -132,7 +132,6 @@ var eraseAllText = Entities.addEntity({ whiteboard: whiteboard }) }); -print(JSON.stringify(Entities.getEntityProperties(eraseAllText))) From c63ef10c67e11af0816d3a3e20b71bb9b06e9a0f Mon Sep 17 00:00:00 2001 From: ericrius1 Date: Wed, 14 Oct 2015 11:50:35 -0700 Subject: [PATCH 30/41] got rid of query string --- examples/painting/whiteboard/whiteboardSpawner.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/painting/whiteboard/whiteboardSpawner.js b/examples/painting/whiteboard/whiteboardSpawner.js index f6f32eaa4d..02c8399ce7 100644 --- a/examples/painting/whiteboard/whiteboardSpawner.js +++ b/examples/painting/whiteboard/whiteboardSpawner.js @@ -15,7 +15,7 @@ /*global hexToRgb */ Script.include("../../libraries/utils.js"); -var scriptURL = Script.resolvePath("whiteBoardEntityScript.js?v2"); +var scriptURL = Script.resolvePath("whiteBoardEntityScript.js"); var rotation = Quat.safeEulerAngles(Camera.getOrientation()); rotation = Quat.fromPitchYawRollDegrees(0, rotation.y, 0); From db5f7cac8dc5e7f6de489c9fdcc63a2e764c48a9 Mon Sep 17 00:00:00 2001 From: ericrius1 Date: Wed, 14 Oct 2015 12:03:10 -0700 Subject: [PATCH 31/41] Fixed name of whiteboard entity script URL --- examples/painting/whiteboard/whiteboardSpawner.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/painting/whiteboard/whiteboardSpawner.js b/examples/painting/whiteboard/whiteboardSpawner.js index 02c8399ce7..8dc8be1cda 100644 --- a/examples/painting/whiteboard/whiteboardSpawner.js +++ b/examples/painting/whiteboard/whiteboardSpawner.js @@ -15,7 +15,7 @@ /*global hexToRgb */ Script.include("../../libraries/utils.js"); -var scriptURL = Script.resolvePath("whiteBoardEntityScript.js"); +var scriptURL = Script.resolvePath("whiteboardEntityScript.js"); var rotation = Quat.safeEulerAngles(Camera.getOrientation()); rotation = Quat.fromPitchYawRollDegrees(0, rotation.y, 0); From eb7b720945f385cdc318b9b67aed8dbdc5546877 Mon Sep 17 00:00:00 2001 From: ericrius1 Date: Wed, 14 Oct 2015 13:24:22 -0700 Subject: [PATCH 32/41] got rid of whitespace --- examples/controllers/handControllerGrab.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/controllers/handControllerGrab.js b/examples/controllers/handControllerGrab.js index d8d7934191..af23c9278f 100644 --- a/examples/controllers/handControllerGrab.js +++ b/examples/controllers/handControllerGrab.js @@ -568,7 +568,7 @@ function MyController(hand, triggerAction) { this.setState(STATE_RELEASE); return; } - + Entities.callEntityMethod(this.grabbedEntity, "continueNearGrabbingNonColliding"); }; From 0b92bc11f6a47068cbc8814cd651138f824b473e Mon Sep 17 00:00:00 2001 From: Eric Levin Date: Wed, 14 Oct 2015 13:26:10 -0700 Subject: [PATCH 33/41] fixed spacing --- examples/controllers/handControllerGrab.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/controllers/handControllerGrab.js b/examples/controllers/handControllerGrab.js index af23c9278f..d8d7934191 100644 --- a/examples/controllers/handControllerGrab.js +++ b/examples/controllers/handControllerGrab.js @@ -568,7 +568,7 @@ function MyController(hand, triggerAction) { this.setState(STATE_RELEASE); return; } - + Entities.callEntityMethod(this.grabbedEntity, "continueNearGrabbingNonColliding"); }; From cfca0fe8c02bbd06de7dce7965675dd368bbaabc Mon Sep 17 00:00:00 2001 From: ericrius1 Date: Wed, 14 Oct 2015 15:58:10 -0700 Subject: [PATCH 34/41] Adding a color indicator to whiteboard --- .../painting/whiteboard/whiteboardSpawner.js | 46 +++++++++++++------ .../entities/src/EntityScriptingInterface.cpp | 15 ++---- libraries/entities/src/EntityTreeElement.cpp | 13 +----- libraries/octree/src/Octree.cpp | 2 +- 4 files changed, 41 insertions(+), 35 deletions(-) diff --git a/examples/painting/whiteboard/whiteboardSpawner.js b/examples/painting/whiteboard/whiteboardSpawner.js index 8dc8be1cda..6a92be3295 100644 --- a/examples/painting/whiteboard/whiteboardSpawner.js +++ b/examples/painting/whiteboard/whiteboardSpawner.js @@ -16,16 +16,10 @@ Script.include("../../libraries/utils.js"); var scriptURL = Script.resolvePath("whiteboardEntityScript.js"); - var rotation = Quat.safeEulerAngles(Camera.getOrientation()); rotation = Quat.fromPitchYawRollDegrees(0, rotation.y, 0); var center = Vec3.sum(MyAvatar.position, Vec3.multiply(3, Quat.getFront(rotation))); center.y += 0.4; -var whiteboardDimensions = { - x: 2, - y: 1.5, - z: 0.01 -}; var colors = [ hexToRgb("#2F8E84"), @@ -36,8 +30,16 @@ var colors = [ hexToRgb("#993369"), hexToRgb("#9B47C2") ]; + +//WHITEBOARD +var whiteboardDimensions = { + x: 2, + y: 1.5, + z: 0.02 +}; var whiteboard = Entities.addEntity({ - type: "Box", + type: "Model", + modelURL: "https://hifi-public.s3.amazonaws.com/ozan/support/for_eric/whiteboard/whiteboard.fbx", name: "whiteboard", position: center, rotation: rotation, @@ -53,19 +55,34 @@ var whiteboard = Entities.addEntity({ }) }); -//COLORS +// COLOR INDICATOR BOX +var colorIndicatorDimensions = { + x: whiteboardDimensions.x, + y: 0.2, + z: 0.02 +}; +scriptURL = Script.resolvePath("colorIndicatorEntityScript.js"); +var colorIndicatorPosition = Vec3.sum(center, {x: 0, y: whiteboardDimensions.y/2, z: 0}); +var colorIndicatorBox = Entities.addEntity({ + type: "Box", + color: colors[0], + rotation: rotation, + position: colorIndicatorPosition, + dimensions: colorIndicatorDimensions, + script: scriptURL +}); + +//COLOR BOXES var direction = Quat.getRight(rotation); var colorBoxPosition = Vec3.subtract(center, Vec3.multiply(direction, whiteboardDimensions.x / 2)); - var colorBoxes = []; - var colorSquareDimensions = { x: (whiteboardDimensions.x / 2) / (colors.length - 1), y: 0.1, z: 0.05 }; -colorBoxPosition.y += whiteboardDimensions.y / 2 + colorSquareDimensions.y / 2 - 0.01; +colorBoxPosition.y += whiteboardDimensions.y / 2 + colorIndicatorDimensions.y/2 + colorSquareDimensions.y / 2 - 0.01; var spaceBetweenColorBoxes = Vec3.multiply(direction, colorSquareDimensions.x * 2); var scriptURL = Script.resolvePath("colorSelectorEntityScript.js"); for (var i = 0; i < colors.length; i++) { @@ -77,13 +94,16 @@ for (var i = 0; i < colors.length; i++) { color: colors[i], script: scriptURL, userData: JSON.stringify({ - whiteboard: whiteboard + whiteboard: whiteboard, + colorIndicator: colorIndicatorBox }) }); colorBoxes.push(colorBox); colorBoxPosition = Vec3.sum(colorBoxPosition, spaceBetweenColorBoxes); } + +// BLACK BOX var blackBoxDimensions = {x: .2, y: .2, z: 0.05}; colorBoxPosition = Vec3.subtract(center, Vec3.multiply(direction, whiteboardDimensions.x / 2 + blackBoxDimensions.x/2 - 0.01)); colorBoxPosition.y += 0.3; @@ -146,4 +166,4 @@ function cleanup() { // Uncomment this line to delete whiteboard and all associated entity on script close -// Script.scriptEnding.connect(cleanup); \ No newline at end of file +Script.scriptEnding.connect(cleanup); \ No newline at end of file diff --git a/libraries/entities/src/EntityScriptingInterface.cpp b/libraries/entities/src/EntityScriptingInterface.cpp index 692ca7a638..3a530c0f3a 100644 --- a/libraries/entities/src/EntityScriptingInterface.cpp +++ b/libraries/entities/src/EntityScriptingInterface.cpp @@ -416,20 +416,15 @@ void RayToEntityIntersectionResultFromScriptValue(const QScriptValue& object, Ra QString faceName = object.property("face").toVariant().toString(); if (faceName == "MIN_X_FACE") { value.face = MIN_X_FACE; - } - else if (faceName == "MAX_X_FACE") { + } else if (faceName == "MAX_X_FACE") { value.face = MAX_X_FACE; - } - else if (faceName == "MIN_Y_FACE") { + } else if (faceName == "MIN_Y_FACE") { value.face = MIN_Y_FACE; - } - else if (faceName == "MAX_Y_FACE") { + } else if (faceName == "MAX_Y_FACE") { value.face = MAX_Y_FACE; - } - else if (faceName == "MIN_Z_FACE") { + } else if (faceName == "MIN_Z_FACE") { value.face = MIN_Z_FACE; - } - else { + } else { value.face = MAX_Z_FACE; }; QScriptValue intersection = object.property("intersection"); diff --git a/libraries/entities/src/EntityTreeElement.cpp b/libraries/entities/src/EntityTreeElement.cpp index b95b0ca673..56ab27836c 100644 --- a/libraries/entities/src/EntityTreeElement.cpp +++ b/libraries/entities/src/EntityTreeElement.cpp @@ -501,17 +501,8 @@ bool EntityTreeElement::findDetailedRayIntersection(const glm::vec3& origin, con int entityNumber = 0; bool somethingIntersected = false; forEachEntity([&](EntityItemPointer entity) { - if (entityIdsToInclude.size() > 0) { - bool entityInWhiteList = false; - // We only want to search whitelist if there is one, otherwise everything except blacklisted items are valid - for (int i = 0; i < entityIdsToInclude.size(); i++) { - if (entityIdsToInclude.at(i) == entity->getID()) { - entityInWhiteList = true; - } - } - if (!entityInWhiteList) { - return; - } + if (entityIdsToInclude.size() > 0 && !entityIdsToInclude.contains(entity->getID())) { + return; } AABox entityBox = entity->getAABox(); diff --git a/libraries/octree/src/Octree.cpp b/libraries/octree/src/Octree.cpp index 3b6467401c..6f6f5af303 100644 --- a/libraries/octree/src/Octree.cpp +++ b/libraries/octree/src/Octree.cpp @@ -724,7 +724,7 @@ bool Octree::findRayIntersection(const glm::vec3& origin, const glm::vec3& direc OctreeElementPointer& element, float& distance, BoxFace& face, glm::vec3& surfaceNormal, const QVector& entityIdsToInclude, void** intersectedObject, Octree::lockType lockType, bool* accurateResult, bool precisionPicking) { - RayArgs args = { origin, direction, element, distance, face, surfaceNormal, entityIdsToInclude, intersectedObject, false, precisionPicking}; + RayArgs args = { origin, direction, element, distance, face, surfaceNormal, intersectedObject, false, precisionPicking}; distance = FLT_MAX; bool requireLock = lockType == Octree::Lock; From 4c709cba3551763195a6af37a3e6ce105b9cd09c Mon Sep 17 00:00:00 2001 From: ericrius1 Date: Wed, 14 Oct 2015 16:17:57 -0700 Subject: [PATCH 35/41] Fixed color indicator position --- .../whiteboard/colorIndicatorEntityScript.js | 41 +++++++++++++++++++ .../whiteboard/whiteboardEntityScript.js | 4 +- .../painting/whiteboard/whiteboardSpawner.js | 9 ++-- 3 files changed, 50 insertions(+), 4 deletions(-) create mode 100644 examples/painting/whiteboard/colorIndicatorEntityScript.js diff --git a/examples/painting/whiteboard/colorIndicatorEntityScript.js b/examples/painting/whiteboard/colorIndicatorEntityScript.js new file mode 100644 index 0000000000..97deb0bc67 --- /dev/null +++ b/examples/painting/whiteboard/colorIndicatorEntityScript.js @@ -0,0 +1,41 @@ +// +// colorIndicatorEntityScript.js +// examples/painting/whiteboard +// +// Created by Eric Levin on 9/21/15. +// Copyright 2015 High Fidelity, Inc. +// + +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +/*global print, MyAvatar, Entities, AnimationCache, SoundCache, Scene, Camera, Overlays, Audio, HMD, AvatarList, AvatarManager, Controller, UndoStack, Window, Account, GlobalServices, Script, ScriptDiscoveryService, LODManager, Menu, Vec3, Quat, AudioDevice, Paths, Clipboard, Settings, XMLHttpRequest, randFloat, randInt */ +/*global ColorIndicator */ + +(function() { + + var _this; + ColorIndicator = function() { + _this = this; + }; + + ColorIndicator.prototype = { + + changeColor: function() { + var newColor = Entities.getEntityProperties(this.whiteboard, "userData").currentColor; + Entities.editEntity(this.EntityID, { + color: newColor + }); + }, + + preload: function(entityID) { + this.entityID = entityID; + var props = Entities.getEntityProperties(this.entityID, "userData"); + this.position = props.position; + this.whiteboard = JSON.parse(props.userData).whiteboard; + }, + + }; + + // entity scripts always need to return a newly constructed object of our type + return new ColorIndicator(); +}); \ No newline at end of file diff --git a/examples/painting/whiteboard/whiteboardEntityScript.js b/examples/painting/whiteboard/whiteboardEntityScript.js index 0cfa12746a..f376c4f61c 100644 --- a/examples/painting/whiteboard/whiteboardEntityScript.js +++ b/examples/painting/whiteboard/whiteboardEntityScript.js @@ -210,7 +210,9 @@ this.painting = false; this.strokes = []; this.whitelist = [this.entityID]; - this.strokeColor = JSON.parse(props.userData).currentColor; + var userData = JSON.parse(props.userData); + this.strokeColor = userData.currentColor; + this.colorIndicator = userData.colorIndicator; this.laserPointer = Overlays.addOverlay("circle3d", { color: this.strokeColor, solid: true, diff --git a/examples/painting/whiteboard/whiteboardSpawner.js b/examples/painting/whiteboard/whiteboardSpawner.js index 6a92be3295..2624fba9b2 100644 --- a/examples/painting/whiteboard/whiteboardSpawner.js +++ b/examples/painting/whiteboard/whiteboardSpawner.js @@ -63,7 +63,7 @@ var colorIndicatorDimensions = { z: 0.02 }; scriptURL = Script.resolvePath("colorIndicatorEntityScript.js"); -var colorIndicatorPosition = Vec3.sum(center, {x: 0, y: whiteboardDimensions.y/2, z: 0}); +var colorIndicatorPosition = Vec3.sum(center, {x: 0, y: whiteboardDimensions.y/2 + colorIndicatorDimensions.y/2, z: 0}); var colorIndicatorBox = Entities.addEntity({ type: "Box", color: colors[0], @@ -73,6 +73,8 @@ var colorIndicatorBox = Entities.addEntity({ script: scriptURL }); +Entities.editEntity(whiteboard, {userData: JSON.stringify({currentColor: colors[i], colorIndicator: colorIndicatorBox})} ); + //COLOR BOXES var direction = Quat.getRight(rotation); var colorBoxPosition = Vec3.subtract(center, Vec3.multiply(direction, whiteboardDimensions.x / 2)); @@ -82,7 +84,7 @@ var colorSquareDimensions = { y: 0.1, z: 0.05 }; -colorBoxPosition.y += whiteboardDimensions.y / 2 + colorIndicatorDimensions.y/2 + colorSquareDimensions.y / 2 - 0.01; +colorBoxPosition.y += whiteboardDimensions.y / 2 + colorIndicatorDimensions.y + colorSquareDimensions.y / 2; var spaceBetweenColorBoxes = Vec3.multiply(direction, colorSquareDimensions.x * 2); var scriptURL = Script.resolvePath("colorSelectorEntityScript.js"); for (var i = 0; i < colors.length; i++) { @@ -117,7 +119,7 @@ var blackBox = Entities.addEntity({ userData: JSON.stringify({ whiteboard: whiteboard }) -}) +}); var eraseBoxDimensions = { @@ -159,6 +161,7 @@ function cleanup() { Entities.deleteEntity(whiteboard); Entities.deleteEntity(eraseAllText); Entities.deleteEntity(blackBox); + Entities.deleteEntity(colorIndicatorBox); colorBoxes.forEach(function(colorBox) { Entities.deleteEntity(colorBox); }); From 5082ac458316b6d0d2b548886459e35015db9605 Mon Sep 17 00:00:00 2001 From: ericrius1 Date: Wed, 14 Oct 2015 16:46:23 -0700 Subject: [PATCH 36/41] Added color status bar --- .../whiteboard/colorIndicatorEntityScript.js | 9 ++--- .../whiteboard/whiteboardEntityScript.js | 2 ++ .../painting/whiteboard/whiteboardSpawner.js | 36 ++++++++++++++----- 3 files changed, 35 insertions(+), 12 deletions(-) diff --git a/examples/painting/whiteboard/colorIndicatorEntityScript.js b/examples/painting/whiteboard/colorIndicatorEntityScript.js index 97deb0bc67..326e9ab9c3 100644 --- a/examples/painting/whiteboard/colorIndicatorEntityScript.js +++ b/examples/painting/whiteboard/colorIndicatorEntityScript.js @@ -21,20 +21,21 @@ ColorIndicator.prototype = { changeColor: function() { - var newColor = Entities.getEntityProperties(this.whiteboard, "userData").currentColor; - Entities.editEntity(this.EntityID, { + var userData = JSON.parse(Entities.getEntityProperties(this.whiteboard, "userData").userData); + var newColor = userData.currentColor; + Entities.editEntity(this.entityID, { color: newColor }); }, preload: function(entityID) { this.entityID = entityID; - var props = Entities.getEntityProperties(this.entityID, "userData"); + var props = Entities.getEntityProperties(this.entityID, ["position", "userData"]); this.position = props.position; this.whiteboard = JSON.parse(props.userData).whiteboard; }, - }; + }; // entity scripts always need to return a newly constructed object of our type return new ColorIndicator(); diff --git a/examples/painting/whiteboard/whiteboardEntityScript.js b/examples/painting/whiteboard/whiteboardEntityScript.js index f376c4f61c..9ed5d21065 100644 --- a/examples/painting/whiteboard/whiteboardEntityScript.js +++ b/examples/painting/whiteboard/whiteboardEntityScript.js @@ -189,6 +189,8 @@ Overlays.editOverlay(this.laserPointer, { color: this.strokeColor }); + + Entities.callEntityMethod(this.colorIndicator, "changeColor"); }, eraseBoard: function() { diff --git a/examples/painting/whiteboard/whiteboardSpawner.js b/examples/painting/whiteboard/whiteboardSpawner.js index 2624fba9b2..66be92466d 100644 --- a/examples/painting/whiteboard/whiteboardSpawner.js +++ b/examples/painting/whiteboard/whiteboardSpawner.js @@ -63,17 +63,29 @@ var colorIndicatorDimensions = { z: 0.02 }; scriptURL = Script.resolvePath("colorIndicatorEntityScript.js"); -var colorIndicatorPosition = Vec3.sum(center, {x: 0, y: whiteboardDimensions.y/2 + colorIndicatorDimensions.y/2, z: 0}); +var colorIndicatorPosition = Vec3.sum(center, { + x: 0, + y: whiteboardDimensions.y / 2 + colorIndicatorDimensions.y / 2, + z: 0 +}); var colorIndicatorBox = Entities.addEntity({ type: "Box", color: colors[0], rotation: rotation, position: colorIndicatorPosition, dimensions: colorIndicatorDimensions, - script: scriptURL + script: scriptURL, + userData: JSON.stringify({ + whiteboard: whiteboard + }) }); -Entities.editEntity(whiteboard, {userData: JSON.stringify({currentColor: colors[i], colorIndicator: colorIndicatorBox})} ); +Entities.editEntity(whiteboard, { + userData: JSON.stringify({ + currentColor: colors[0], + colorIndicator: colorIndicatorBox + }) +}); //COLOR BOXES var direction = Quat.getRight(rotation); @@ -84,7 +96,7 @@ var colorSquareDimensions = { y: 0.1, z: 0.05 }; -colorBoxPosition.y += whiteboardDimensions.y / 2 + colorIndicatorDimensions.y + colorSquareDimensions.y / 2; +colorBoxPosition.y += whiteboardDimensions.y / 2 + colorIndicatorDimensions.y + colorSquareDimensions.y / 2; var spaceBetweenColorBoxes = Vec3.multiply(direction, colorSquareDimensions.x * 2); var scriptURL = Script.resolvePath("colorSelectorEntityScript.js"); for (var i = 0; i < colors.length; i++) { @@ -106,18 +118,26 @@ for (var i = 0; i < colors.length; i++) { // BLACK BOX -var blackBoxDimensions = {x: .2, y: .2, z: 0.05}; -colorBoxPosition = Vec3.subtract(center, Vec3.multiply(direction, whiteboardDimensions.x / 2 + blackBoxDimensions.x/2 - 0.01)); +var blackBoxDimensions = { + x: .2, + y: .2, + z: 0.05 +}; +colorBoxPosition = Vec3.subtract(center, Vec3.multiply(direction, whiteboardDimensions.x / 2 + blackBoxDimensions.x / 2 - 0.01)); colorBoxPosition.y += 0.3; var blackBox = Entities.addEntity({ type: 'Box', position: colorBoxPosition, dimensions: blackBoxDimensions, rotation: rotation, - color: {red: 0, green: 0, blue: 0}, + color: { + red: 0, + green: 0, + blue: 0 + }, script: scriptURL, userData: JSON.stringify({ - whiteboard: whiteboard + whiteboard: whiteboard }) }); From 87439a049e90ef3792f4bc3d9076458e9bbcf7ce Mon Sep 17 00:00:00 2001 From: ericrius1 Date: Wed, 14 Oct 2015 17:22:46 -0700 Subject: [PATCH 37/41] Made color indicator thinner --- examples/painting/whiteboard/whiteboardSpawner.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/painting/whiteboard/whiteboardSpawner.js b/examples/painting/whiteboard/whiteboardSpawner.js index 66be92466d..4219ee30bc 100644 --- a/examples/painting/whiteboard/whiteboardSpawner.js +++ b/examples/painting/whiteboard/whiteboardSpawner.js @@ -35,7 +35,7 @@ var colors = [ var whiteboardDimensions = { x: 2, y: 1.5, - z: 0.02 + z: 0.08 }; var whiteboard = Entities.addEntity({ type: "Model", @@ -59,7 +59,7 @@ var whiteboard = Entities.addEntity({ // COLOR INDICATOR BOX var colorIndicatorDimensions = { x: whiteboardDimensions.x, - y: 0.2, + y: 0.05, z: 0.02 }; scriptURL = Script.resolvePath("colorIndicatorEntityScript.js"); From 3b59bffb79ae88caa6e703e52cc6120132729379 Mon Sep 17 00:00:00 2001 From: ericrius1 Date: Thu, 15 Oct 2015 11:38:18 -0700 Subject: [PATCH 38/41] Deleting only strokes from the whiteboard where the erase button was clicked on --- .../whiteboard/whiteboardEntityScript.js | 23 ++++++++++++++----- .../painting/whiteboard/whiteboardSpawner.js | 2 +- libraries/octree/src/Octree.cpp | 2 +- 3 files changed, 19 insertions(+), 8 deletions(-) diff --git a/examples/painting/whiteboard/whiteboardEntityScript.js b/examples/painting/whiteboard/whiteboardEntityScript.js index 9ed5d21065..cff028c566 100644 --- a/examples/painting/whiteboard/whiteboardEntityScript.js +++ b/examples/painting/whiteboard/whiteboardEntityScript.js @@ -93,7 +93,7 @@ this.oldPosition = null; } } - } else if(this.intersection.properties.type !== "Unknown") { + } else if (this.intersection.properties.type !== "Unknown") { //Sometimes ray will pick against an invisible object with type unkown... so if type is unknown, ignore this.stopPainting(); } @@ -169,7 +169,10 @@ y: 50, z: 50 }, - lifetime: 200 + lifetime: 200, + userData: JSON.stringify({ + whiteboard: this.entityID + }) }); this.strokePoints = []; this.strokeNormals = []; @@ -194,10 +197,17 @@ }, eraseBoard: function() { - var entities = Entities.findEntities(this.position, 5); + var distance = Math.max(this.dimensions.x, this.dimensions.y); + var entities = Entities.findEntities(this.position, distance); entities.forEach(function(entity) { - var name = Entities.getEntityProperties(entity, "name").name; - if (name === "paintStroke") { + var props = Entities.getEntityProperties(entity, ["name, userData"]); + var name = props.name; + if(!props.userData) { + return; + } + var whiteboardID = JSON.parse(props.userData).whiteboard; + if (name === "paintStroke" && JSON.stringify(whiteboardID) === JSON.stringify(_this.entityID)) { + // This entity is a paintstroke and part of this whiteboard so delete it Entities.deleteEntity(entity); } }); @@ -205,9 +215,10 @@ preload: function(entityID) { this.entityID = entityID; - var props = Entities.getEntityProperties(this.entityID, ["position", "rotation", "userData"]); + var props = Entities.getEntityProperties(this.entityID, ["position", "rotation", "userData", "dimensions"]); this.position = props.position; this.rotation = props.rotation; + this.dimensions = props.dimensions; this.normal = Vec3.multiply(Quat.getFront(this.rotation), -1); this.painting = false; this.strokes = []; diff --git a/examples/painting/whiteboard/whiteboardSpawner.js b/examples/painting/whiteboard/whiteboardSpawner.js index 4219ee30bc..51e4dee87d 100644 --- a/examples/painting/whiteboard/whiteboardSpawner.js +++ b/examples/painting/whiteboard/whiteboardSpawner.js @@ -189,4 +189,4 @@ function cleanup() { // Uncomment this line to delete whiteboard and all associated entity on script close -Script.scriptEnding.connect(cleanup); \ No newline at end of file +// Script.scriptEnding.connect(cleanup); \ No newline at end of file diff --git a/libraries/octree/src/Octree.cpp b/libraries/octree/src/Octree.cpp index 6f6f5af303..3b6467401c 100644 --- a/libraries/octree/src/Octree.cpp +++ b/libraries/octree/src/Octree.cpp @@ -724,7 +724,7 @@ bool Octree::findRayIntersection(const glm::vec3& origin, const glm::vec3& direc OctreeElementPointer& element, float& distance, BoxFace& face, glm::vec3& surfaceNormal, const QVector& entityIdsToInclude, void** intersectedObject, Octree::lockType lockType, bool* accurateResult, bool precisionPicking) { - RayArgs args = { origin, direction, element, distance, face, surfaceNormal, intersectedObject, false, precisionPicking}; + RayArgs args = { origin, direction, element, distance, face, surfaceNormal, entityIdsToInclude, intersectedObject, false, precisionPicking}; distance = FLT_MAX; bool requireLock = lockType == Octree::Lock; From dc6875f5b582d648b35bd94f14dbf165d608e424 Mon Sep 17 00:00:00 2001 From: ericrius1 Date: Thu, 15 Oct 2015 11:50:23 -0700 Subject: [PATCH 39/41] Strokes moving forward to avoid zfighting and incorrect overlaps --- .../painting/whiteboard/whiteboardEntityScript.js | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/examples/painting/whiteboard/whiteboardEntityScript.js b/examples/painting/whiteboard/whiteboardEntityScript.js index cff028c566..b03ab8f86c 100644 --- a/examples/painting/whiteboard/whiteboardEntityScript.js +++ b/examples/painting/whiteboard/whiteboardEntityScript.js @@ -20,7 +20,7 @@ var _this; var RIGHT_HAND = 1; var LEFT_HAND = 0; - var MIN_POINT_DISTANCE = 0.02; + var MIN_POINT_DISTANCE = 0.01 ; var MAX_POINT_DISTANCE = 0.5; var MAX_POINTS_PER_LINE = 40; var MAX_DISTANCE = 5; @@ -119,8 +119,9 @@ var localPoint = Vec3.subtract(position, this.strokeBasePosition); - //Move stroke a bit forward along normal so it doesnt zfight with mesh its drawing on - localPoint = Vec3.sum(localPoint, Vec3.multiply(this.normal, 0.001 + Math.random() * 0.001)); //rand avoid z fighting + //Move stroke a bit forward along normal each point so it doesnt zfight with mesh its drawing on, or previous part of stroke(s) + localPoint = Vec3.sum(localPoint, Vec3.multiply(this.normal, this.forwardOffset)); + this.forwardOffset += 0.00001; var distance = Vec3.distance(localPoint, this.strokePoints[this.strokePoints.length - 1]); if (this.strokePoints.length > 0 && distance < MIN_POINT_DISTANCE) { //need a minimum distance to avoid binormal NANs @@ -157,7 +158,6 @@ newStroke: function(position) { - this.strokeBasePosition = position; this.currentStroke = Entities.addEntity({ position: position, @@ -231,12 +231,11 @@ solid: true, rotation: this.rotation }); + this.forwardOffset = 0.0005; }, unload: function() { - this.strokes.forEach(function(stroke) { - Entities.deleteEntity(stroke); - }); + Overlays.deleteOverlay(this.laserPointer); } From e8b6b32572afc075b9c21a44b15f4f19d3f6b6c4 Mon Sep 17 00:00:00 2001 From: ericrius1 Date: Thu, 15 Oct 2015 14:12:15 -0700 Subject: [PATCH 40/41] Remembering whiteboards last color between sessions --- .../whiteboard/colorIndicatorEntityScript.js | 2 +- .../whiteboard/colorSelectorEntityScript.js | 7 +++---- .../painting/whiteboard/whiteboardEntityScript.js | 11 +++++++---- examples/painting/whiteboard/whiteboardSpawner.js | 13 ++++++++----- 4 files changed, 19 insertions(+), 14 deletions(-) diff --git a/examples/painting/whiteboard/colorIndicatorEntityScript.js b/examples/painting/whiteboard/colorIndicatorEntityScript.js index 326e9ab9c3..27b8ca01a1 100644 --- a/examples/painting/whiteboard/colorIndicatorEntityScript.js +++ b/examples/painting/whiteboard/colorIndicatorEntityScript.js @@ -22,7 +22,7 @@ changeColor: function() { var userData = JSON.parse(Entities.getEntityProperties(this.whiteboard, "userData").userData); - var newColor = userData.currentColor; + var newColor = userData.color.currentColor; Entities.editEntity(this.entityID, { color: newColor }); diff --git a/examples/painting/whiteboard/colorSelectorEntityScript.js b/examples/painting/whiteboard/colorSelectorEntityScript.js index 8ad003035c..f1105604c7 100644 --- a/examples/painting/whiteboard/colorSelectorEntityScript.js +++ b/examples/painting/whiteboard/colorSelectorEntityScript.js @@ -12,7 +12,7 @@ /*global ColorSelector */ (function() { - + Script.include("../../libraries/utils.js"); var _this; ColorSelector = function() { _this = this; @@ -29,9 +29,7 @@ }, selectColor: function() { - Entities.editEntity(this.whiteboard, { - userData: JSON.stringify({currentColor: this.color}) - }); + setEntityCustomData(this.colorKey, this.whiteboard, {currentColor: this.color}); Entities.callEntityMethod(this.whiteboard, "changeColor"); }, @@ -40,6 +38,7 @@ var props = Entities.getEntityProperties(this.entityID, ["position, color, userData"]); this.position = props.position; this.color = props.color; + this.colorKey = "color"; this.whiteboard = JSON.parse(props.userData).whiteboard; }, diff --git a/examples/painting/whiteboard/whiteboardEntityScript.js b/examples/painting/whiteboard/whiteboardEntityScript.js index b03ab8f86c..f38073f389 100644 --- a/examples/painting/whiteboard/whiteboardEntityScript.js +++ b/examples/painting/whiteboard/whiteboardEntityScript.js @@ -188,11 +188,14 @@ }, changeColor: function() { - this.strokeColor = JSON.parse(Entities.getEntityProperties(this.entityID, ["userData"]).userData).currentColor; + var userData = JSON.parse(Entities.getEntityProperties(this.entityID, ["userData"]).userData); + this.strokeColor = userData.color.currentColor; + this.colorIndicator = userData.colorIndicator; Overlays.editOverlay(this.laserPointer, { color: this.strokeColor }); + Entities.callEntityMethod(this.colorIndicator, "changeColor"); }, @@ -223,20 +226,20 @@ this.painting = false; this.strokes = []; this.whitelist = [this.entityID]; - var userData = JSON.parse(props.userData); - this.strokeColor = userData.currentColor; - this.colorIndicator = userData.colorIndicator; this.laserPointer = Overlays.addOverlay("circle3d", { color: this.strokeColor, solid: true, rotation: this.rotation }); this.forwardOffset = 0.0005; + + this.changeColor(); }, unload: function() { Overlays.deleteOverlay(this.laserPointer); + // this.eraseBoard(); } }; diff --git a/examples/painting/whiteboard/whiteboardSpawner.js b/examples/painting/whiteboard/whiteboardSpawner.js index 51e4dee87d..13588d24a8 100644 --- a/examples/painting/whiteboard/whiteboardSpawner.js +++ b/examples/painting/whiteboard/whiteboardSpawner.js @@ -49,10 +49,7 @@ var whiteboard = Entities.addEntity({ red: 255, green: 255, blue: 255 - }, - userData: JSON.stringify({ - currentColor: colors[0] - }) + } }); @@ -70,6 +67,7 @@ var colorIndicatorPosition = Vec3.sum(center, { }); var colorIndicatorBox = Entities.addEntity({ type: "Box", + name: "Color Indicator", color: colors[0], rotation: rotation, position: colorIndicatorPosition, @@ -82,7 +80,9 @@ var colorIndicatorBox = Entities.addEntity({ Entities.editEntity(whiteboard, { userData: JSON.stringify({ - currentColor: colors[0], + color: { + currentColor: colors[0], + }, colorIndicator: colorIndicatorBox }) }); @@ -102,6 +102,7 @@ var scriptURL = Script.resolvePath("colorSelectorEntityScript.js"); for (var i = 0; i < colors.length; i++) { var colorBox = Entities.addEntity({ type: "Box", + name: "Color Selector", position: colorBoxPosition, dimensions: colorSquareDimensions, rotation: rotation, @@ -127,6 +128,7 @@ colorBoxPosition = Vec3.subtract(center, Vec3.multiply(direction, whiteboardDime colorBoxPosition.y += 0.3; var blackBox = Entities.addEntity({ type: 'Box', + name: "Black Color", position: colorBoxPosition, dimensions: blackBoxDimensions, rotation: rotation, @@ -155,6 +157,7 @@ scriptURL = Script.resolvePath("eraseBoardEntityScript.js"); var eraseAllText = Entities.addEntity({ type: "Text", position: eraseBoxPosition, + name: "Eraser", script: scriptURL, rotation: rotation, dimensions: eraseBoxDimensions, From 97fe0170cbc5a20aa6d89dd83176082cbbe3e67d Mon Sep 17 00:00:00 2001 From: ericrius1 Date: Thu, 15 Oct 2015 17:09:41 -0700 Subject: [PATCH 41/41] glowing box for black color --- examples/painting/whiteboard/blackInk.fs | 23 +++++++++++++++++++ .../painting/whiteboard/whiteboardSpawner.js | 18 ++++++++++----- 2 files changed, 35 insertions(+), 6 deletions(-) create mode 100644 examples/painting/whiteboard/blackInk.fs diff --git a/examples/painting/whiteboard/blackInk.fs b/examples/painting/whiteboard/blackInk.fs new file mode 100644 index 0000000000..1e77db285c --- /dev/null +++ b/examples/painting/whiteboard/blackInk.fs @@ -0,0 +1,23 @@ +vec2 iResolution = iWorldScale.xy; +vec2 iMouse = vec2(0); + +const float PI = 3.14159265; + +float time = iGlobalTime; +vec2 center = vec2(0.5, 0.5); +void mainImage( out vec4 fragColor, in vec2 fragCoord ) { + vec2 position = (fragCoord.xy/iResolution.xy) + 0.5; + float dist = pow(distance(position.xy, center), 3.); + dist = dist / 1.0 + sin(time * 10)/100.0; + vec3 color = vec3(dist, 0.0, dist); + fragColor = vec4(color, 1.0); +} + +vec4 getProceduralColor() { + vec4 result; + vec2 position = _position.xy; + + mainImage(result, position * iWorldScale.xy); + + return result; +} \ No newline at end of file diff --git a/examples/painting/whiteboard/whiteboardSpawner.js b/examples/painting/whiteboard/whiteboardSpawner.js index 13588d24a8..cbc26da670 100644 --- a/examples/painting/whiteboard/whiteboardSpawner.js +++ b/examples/painting/whiteboard/whiteboardSpawner.js @@ -81,7 +81,7 @@ var colorIndicatorBox = Entities.addEntity({ Entities.editEntity(whiteboard, { userData: JSON.stringify({ color: { - currentColor: colors[0], + currentColor: colors[0] }, colorIndicator: colorIndicatorBox }) @@ -120,12 +120,14 @@ for (var i = 0; i < colors.length; i++) { // BLACK BOX var blackBoxDimensions = { - x: .2, - y: .2, - z: 0.05 + x: 0.3, + y: 0.3, + z: 0.01 }; + colorBoxPosition = Vec3.subtract(center, Vec3.multiply(direction, whiteboardDimensions.x / 2 + blackBoxDimensions.x / 2 - 0.01)); colorBoxPosition.y += 0.3; +var fragShaderURL = Script.resolvePath('blackInk.fs?v1' + Math.random()); var blackBox = Entities.addEntity({ type: 'Box', name: "Black Color", @@ -139,7 +141,11 @@ var blackBox = Entities.addEntity({ }, script: scriptURL, userData: JSON.stringify({ - whiteboard: whiteboard + whiteboard: whiteboard, + version: 2, + ProceduralEntity: { + shaderUrl: fragShaderURL + } }) }); @@ -192,4 +198,4 @@ function cleanup() { // Uncomment this line to delete whiteboard and all associated entity on script close -// Script.scriptEnding.connect(cleanup); \ No newline at end of file +Script.scriptEnding.connect(cleanup); \ No newline at end of file