From f8a515de64fd51ca2297c969145aa3a68ba6a709 Mon Sep 17 00:00:00 2001 From: Brad Hefta-Gaub Date: Wed, 23 Dec 2015 14:46:18 -0800 Subject: [PATCH 01/16] add a test script for HMD.getHUDLookAtPositionXX() --- .../controllers/getHUDLookAtPositionTest.js | 54 +++++++++++++++++++ 1 file changed, 54 insertions(+) create mode 100644 examples/controllers/getHUDLookAtPositionTest.js diff --git a/examples/controllers/getHUDLookAtPositionTest.js b/examples/controllers/getHUDLookAtPositionTest.js new file mode 100644 index 0000000000..348b6757b8 --- /dev/null +++ b/examples/controllers/getHUDLookAtPositionTest.js @@ -0,0 +1,54 @@ +// +// getHUDLookAtPositionTest.js +// examples/controllers +// +// Created by Brad Hefta-Gaub on 2015/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 +// + + +// This script demonstrates the testing of the HMD.getHUDLookAtPosition--() functions. +// If these functions are working correctly, we'd expect to see a 3D cube and a 2D square +// follow around the center of the HMD view. + +var cubePosition = { x: 0, y: 0, z: 0 }; +var cubeSize = 0.03; +var cube = Overlays.addOverlay("cube", { + position: cubePosition, + size: cubeSize, + color: { red: 255, green: 0, blue: 0}, + alpha: 1, + solid: false + }); + +var square = Overlays.addOverlay("text", { + x: 0, + y: 0, + width: 20, + height: 20, + color: { red: 255, green: 255, blue: 0}, + backgroundColor: { red: 255, green: 255, blue: 0}, + alpha: 1 + }); + + +Script.update.connect(function(deltaTime) { + if (!HMD.active) { + return; + } + var lookAt3D = HMD.getHUDLookAtPosition3D(); + Overlays.editOverlay(cube, { position: lookAt3D }); + + var lookAt2D = HMD.getHUDLookAtPosition2D(); + Overlays.editOverlay(square, { x: lookAt2D.x, y: lookAt2D.y }); +}); + +Script.scriptEnding.connect(function(){ + Overlays.deleteOverlay(cube); + Overlays.deleteOverlay(square); +}); + + From b4988b0998b0f5c40962cbd5fa4817294ee13cb4 Mon Sep 17 00:00:00 2001 From: ericrius1 Date: Wed, 23 Dec 2015 15:09:10 -0800 Subject: [PATCH 02/16] Taking individual avatar hand size into consideration for grabbing objects --- examples/controllers/handControllerGrab.js | 9 ++- examples/libraries/utils.js | 27 +++++++ unpublishedScripts/hiddenEntityReset.js | 67 +-------------- unpublishedScripts/masterReset.js | 94 +++++----------------- 4 files changed, 54 insertions(+), 143 deletions(-) diff --git a/examples/controllers/handControllerGrab.js b/examples/controllers/handControllerGrab.js index 9e7623b483..7afb687f6d 100644 --- a/examples/controllers/handControllerGrab.js +++ b/examples/controllers/handControllerGrab.js @@ -226,6 +226,9 @@ function getSpatialOffsetPosition(hand, spatialKey) { position = spatialKey.relativePosition; } + // add the relative hand center offset + var handSizeRatio = calculateHandSizeRatio(); + position = Vec3.multiply(position, handSizeRatio); return position; } @@ -1159,12 +1162,14 @@ function MyController(hand) { if (this.state != STATE_NEAR_GRABBING && grabbableData.spatialKey) { // if an object is "equipped" and has a spatialKey, use it. this.ignoreIK = grabbableData.spatialKey.ignoreIK ? grabbableData.spatialKey.ignoreIK : false; - if (grabbableData.spatialKey.relativePosition) { + if (grabbableData.spatialKey.relativePosition || grabbableData.spatialKey.rightRelativePosition + || grabbableData.spatialKey.leftRelativePosition) { this.offsetPosition = getSpatialOffsetPosition(this.hand, grabbableData.spatialKey); } else { this.offsetPosition = Vec3.multiplyQbyV(Quat.inverse(Quat.multiply(handRotation, this.offsetRotation)), offset); } - if (grabbableData.spatialKey.relativeRotation) { + if (grabbableData.spatialKey.relativeRotation || grabbableData.spatialKey.rightRelativeRotation + || grabbableData.spatialKey.leftRelativeRotation) { this.offsetRotation = getSpatialOffsetRotation(this.hand, grabbableData.spatialKey); } else { this.offsetRotation = Quat.multiply(Quat.inverse(handRotation), objectRotation); diff --git a/examples/libraries/utils.js b/examples/libraries/utils.js index 5d14bfb7dd..37dccd5ac8 100644 --- a/examples/libraries/utils.js +++ b/examples/libraries/utils.js @@ -271,3 +271,30 @@ hexToRgb = function(hex) { } : null; } +calculateHandSizeRatio = function() { + // Get the ratio of the current avatar's hand to Owen's hand + + // var standardCenterHandPoint = 0.11288; + var standardCenterHandPoint = 0.11288; + var jointNames = MyAvatar.getJointNames(); + //get distance from handJoint up to leftHandIndex3 as a proxy for center of hand + var wristToFingertipDistance = 0;; + for (var i = 0; i < jointNames.length; i++) { + var jointName = jointNames[i]; + print(jointName) + if (jointName.indexOf("LeftHandIndex") !== -1) { + // translations are relative to parent joint, so simply add them together + // joints face down the y-axis + var translation = MyAvatar.getDefaultJointTranslation(i).y; + wristToFingertipDistance += translation; + } + } + // Right now units are in cm, so convert to meters + wristToFingertipDistance /= 100; + + var centerHandPoint = wristToFingertipDistance/2; + + // Compare against standard hand (Owen) + var handSizeRatio = centerHandPoint/standardCenterHandPoint; + return handSizeRatio; +} diff --git a/unpublishedScripts/hiddenEntityReset.js b/unpublishedScripts/hiddenEntityReset.js index 94d815796b..e8783bbbcb 100644 --- a/unpublishedScripts/hiddenEntityReset.js +++ b/unpublishedScripts/hiddenEntityReset.js @@ -169,7 +169,7 @@ } function createRaveStick(position) { - var modelURL = "https://s3.amazonaws.com/hifi-public/eric/models/rave/raveStick.fbx"; + var modelURL = "https://s3-us-west-1.amazonaws.com/hifi-content/eric/models/raveStick.fbx"; var stick = Entities.addEntity({ type: "Model", name: "raveStick", @@ -205,71 +205,6 @@ } }) }); - var rotation = Quat.fromPitchYawRollDegrees(0, 0, 0) - var forwardVec = Quat.getFront(Quat.multiply(rotation, Quat.fromPitchYawRollDegrees(-90, 0, 0))); - forwardVec = Vec3.normalize(forwardVec); - var forwardQuat = orientationOf(forwardVec); - position = Vec3.sum(position, Vec3.multiply(Quat.getFront(rotation), 0.1)); - position.z += 0.1; - position.x += -0.035; - var color = { - red: 0, - green: 200, - blue: 40 - }; - var props = { - type: "ParticleEffect", - position: position, - parentID: stick, - isEmitting: true, - name: "raveBeam", - colorStart: color, - colorSpread: { - red: 200, - green: 10, - blue: 10 - }, - color: { - red: 200, - green: 200, - blue: 255 - }, - colorFinish: color, - maxParticles: 100000, - lifespan: 1, - emitRate: 1000, - emitOrientation: forwardQuat, - emitSpeed: 0.2, - speedSpread: 0.0, - polarStart: 0, - polarFinish: 0.0, - azimuthStart: 0.1, - azimuthFinish: 0.01, - emitAcceleration: { - x: 0, - y: 0, - z: 0 - }, - accelerationSpread: { - x: 0.00, - y: 0.00, - z: 0.00 - }, - radiusStart: 0.03, - radiusFinish: 0.025, - alpha: 0.7, - alphaSpread:0.1, - alphaStart: 0.5, - alphaFinish: 0.5, - textures: "https://s3.amazonaws.com/hifi-public/eric/textures/particleSprites/beamParticle.png", - emitterShouldTrail: false, - userData: JSON.stringify({ - resetMe: { - resetMe: true - } - }) - } - var beam = Entities.addEntity(props); } diff --git a/unpublishedScripts/masterReset.js b/unpublishedScripts/masterReset.js index 9afbd0a68b..f3c38b2adf 100644 --- a/unpublishedScripts/masterReset.js +++ b/unpublishedScripts/masterReset.js @@ -148,7 +148,7 @@ MasterReset = function() { } function createRaveStick(position) { - var modelURL = "https://s3.amazonaws.com/hifi-public/eric/models/rave/raveStick.fbx"; + var modelURL = "https://s3-us-west-1.amazonaws.com/hifi-content/eric/models/raveStick.fbx"; var stick = Entities.addEntity({ type: "Model", name: "raveStick", @@ -173,10 +173,15 @@ MasterReset = function() { }, grabbableKey: { spatialKey: { - relativePosition: { - x: 0, + rightRelativePosition: { + x: 0.02, y: 0, - z: -0.1 + z: 0 + }, + leftRelativePosition: { + x: -0.02, + y: 0, + z: 0 }, relativeRotation: Quat.fromPitchYawRollDegrees(90, 90, 0) }, @@ -184,72 +189,6 @@ MasterReset = function() { } }) }); - var rotation = Quat.fromPitchYawRollDegrees(0, 0, 0) - var forwardVec = Quat.getFront(Quat.multiply(rotation, Quat.fromPitchYawRollDegrees(-90, 0, 0))); - forwardVec = Vec3.normalize(forwardVec); - var forwardQuat = orientationOf(forwardVec); - position = Vec3.sum(position, Vec3.multiply(Quat.getFront(rotation), 0.1)); - position.z += 0.1; - position.x += -0.035; - var color = { - red: 0, - green: 200, - blue: 40 - }; - var props = { - type: "ParticleEffect", - position: position, - parentID: stick, - isEmitting: true, - name: "raveBeam", - colorStart: color, - colorSpread: { - red: 200, - green: 10, - blue: 10 - }, - color: { - red: 200, - green: 200, - blue: 255 - }, - colorFinish: color, - maxParticles: 100000, - lifespan: 1, - emitRate: 1000, - emitOrientation: forwardQuat, - emitSpeed: 0.2, - speedSpread: 0.0, - polarStart: 0, - polarFinish: 0.0, - azimuthStart: 0.1, - azimuthFinish: 0.01, - emitAcceleration: { - x: 0, - y: 0, - z: 0 - }, - accelerationSpread: { - x: 0.00, - y: 0.00, - z: 0.00 - }, - radiusStart: 0.03, - radiusFinish: 0.025, - alpha: 0.7, - alphaSpread: 0.1, - alphaStart: 0.5, - alphaFinish: 0.5, - textures: "https://s3.amazonaws.com/hifi-public/eric/textures/particleSprites/beamParticle.png", - emitterShouldTrail: false, - userData: JSON.stringify({ - resetMe: { - resetMe: true - } - }) - } - var beam = Entities.addEntity(props); - } function createGun(position) { @@ -283,10 +222,15 @@ MasterReset = function() { userData: JSON.stringify({ grabbableKey: { spatialKey: { - relativePosition: { - x: 0, + rightRelativePosition: { + x: 0.02, y: 0, - z: -0.1 + z: -0.03 + }, + leftRelativePosition: { + x: -0.02, + y: 0, + z: -0.03 }, relativeRotation: Quat.fromPitchYawRollDegrees(100, 90, 0) }, @@ -1136,9 +1080,9 @@ MasterReset = function() { grabbableKey: { spatialKey: { relativePosition: { - x: -0.05, + x: 0, y: 0, - z: 0.0 + z: .06 }, relativeRotation: Quat.fromPitchYawRollDegrees(0,-90, -90) }, From 24796c1a1eb46cce988752634bd40ba62cf28bdd Mon Sep 17 00:00:00 2001 From: ericrius1 Date: Thu, 24 Dec 2015 10:14:36 -0800 Subject: [PATCH 03/16] updated ravestick spawner relative position --- examples/flowArts/raveStick/raveStick.js | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/examples/flowArts/raveStick/raveStick.js b/examples/flowArts/raveStick/raveStick.js index c51e8b5d89..5fb019bf97 100644 --- a/examples/flowArts/raveStick/raveStick.js +++ b/examples/flowArts/raveStick/raveStick.js @@ -40,13 +40,18 @@ RaveStick = function(spawnPosition) { userData: JSON.stringify({ grabbableKey: { spatialKey: { - relativePosition: { - x: 0, - y: 0, - z: -0.1 + rightRelativePosition: { + x: 0.02, + y: 0, + z: 0 + }, + leftRelativePosition: { + x: -0.02, + y: 0, + z: 0 + }, + relativeRotation: Quat.fromPitchYawRollDegrees(90, 90, 0) }, - relativeRotation: Quat.fromPitchYawRollDegrees(90, 90, 0) - }, invertSolidWhileHeld: true } }) From e8a6fd1f054e375b2e2316009c7991b3d55d24a5 Mon Sep 17 00:00:00 2001 From: ericrius1 Date: Thu, 24 Dec 2015 11:00:24 -0800 Subject: [PATCH 04/16] adding ray filters example/test --- .../painting/whiteboard/whiteboardSpawner.js | 4 +- examples/rayPickingFilterExample.js | 50 +++++++++++++++++++ 2 files changed, 52 insertions(+), 2 deletions(-) create mode 100644 examples/rayPickingFilterExample.js diff --git a/examples/painting/whiteboard/whiteboardSpawner.js b/examples/painting/whiteboard/whiteboardSpawner.js index f3005495ec..1d0f21c026 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?v1" + Math.random()); var modelURL = "https://s3.amazonaws.com/hifi-public/eric/models/whiteboard.fbx"; var colorIndicatorBorderModelURL = "https://s3.amazonaws.com/hifi-public/eric/models/colorIndicatorBorder.fbx"; @@ -247,4 +247,4 @@ function cleanup() { // Uncomment this line to delete whiteboard and all associated entity on script close -//Script.scriptEnding.connect(cleanup); +Script.scriptEnding.connect(cleanup); diff --git a/examples/rayPickingFilterExample.js b/examples/rayPickingFilterExample.js new file mode 100644 index 0000000000..f434d21ab9 --- /dev/null +++ b/examples/rayPickingFilterExample.js @@ -0,0 +1,50 @@ + var center = Vec3.sum(MyAvatar.position, Vec3.multiply(3, Quat.getFront(Camera.getOrientation()))); + + var whiteListBox = Entities.addEntity({ + type: "Box", + color: { + red: 10, + green: 200, + blue: 10 + }, + dimensions: { + x: .2, + y: .2, + z: .2 + }, + position: center + }); + + var blackListBox = Entities.addEntity({ + type: "Box", + color: { + red: 100, + green: 10, + blue: 10 + }, + dimensions: { + x: .2, + y: .2, + z: .2 + }, + position: Vec3.sum(center, {x: 0, y: .3, z: 0}) + }); + + + function castRay(event) { + var pickRay = Camera.computePickRay(event.x, event.y); + var pickResults = Entities.findRayIntersection(pickRay, true, [whiteListBox]); + + if(pickResults.intersects) { + print("INTERSECTION"); + } + + } + + function cleanup() { + Entities.deleteEntity(whiteListBox); + Entities.deleteEntity(blackListBox); + } + + Script.scriptEnding.connect(cleanup); + Controller.mousePressEvent.connect(castRay); \ No newline at end of file From 390dce461317e36d97e2214274f6044b3b0ff526 Mon Sep 17 00:00:00 2001 From: ericrius1 Date: Thu, 24 Dec 2015 11:48:40 -0800 Subject: [PATCH 05/16] Adding blacklist --- examples/rayPickingFilterExample.js | 2 +- .../src/EntityTreeRenderer.cpp | 5 +++-- .../entities-renderer/src/EntityTreeRenderer.h | 3 ++- .../entities/src/EntityScriptingInterface.cpp | 18 ++++++++++-------- .../entities/src/EntityScriptingInterface.h | 6 +++--- libraries/entities/src/EntityTree.cpp | 7 ++++--- libraries/entities/src/EntityTree.h | 1 + libraries/entities/src/EntityTreeElement.cpp | 8 ++++---- libraries/entities/src/EntityTreeElement.h | 4 +++- 9 files changed, 31 insertions(+), 23 deletions(-) diff --git a/examples/rayPickingFilterExample.js b/examples/rayPickingFilterExample.js index f434d21ab9..aa1950c013 100644 --- a/examples/rayPickingFilterExample.js +++ b/examples/rayPickingFilterExample.js @@ -33,7 +33,7 @@ function castRay(event) { var pickRay = Camera.computePickRay(event.x, event.y); - var pickResults = Entities.findRayIntersection(pickRay, true, [whiteListBox]); + var pickResults = Entities.findRayIntersection(pickRay, true, [], [blackListBox]); if(pickResults.intersects) { print("INTERSECTION"); diff --git a/libraries/entities-renderer/src/EntityTreeRenderer.cpp b/libraries/entities-renderer/src/EntityTreeRenderer.cpp index 996a8f3e1d..f517c49b00 100644 --- a/libraries/entities-renderer/src/EntityTreeRenderer.cpp +++ b/libraries/entities-renderer/src/EntityTreeRenderer.cpp @@ -487,7 +487,8 @@ void EntityTreeRenderer::deleteReleasedModels() { } RayToEntityIntersectionResult EntityTreeRenderer::findRayIntersectionWorker(const PickRay& ray, Octree::lockType lockType, - bool precisionPicking, const QVector& entityIdsToInclude) { + bool precisionPicking, const QVector& entityIdsToInclude, + const QVector& entityIdsToDiscard) { RayToEntityIntersectionResult result; if (_tree) { EntityTreePointer entityTree = std::static_pointer_cast(_tree); @@ -495,7 +496,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, entityIdsToInclude, + result.face, result.surfaceNormal, entityIdsToInclude, entityIdsToDiscard, (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 076fe26d6f..2c205336c0 100644 --- a/libraries/entities-renderer/src/EntityTreeRenderer.h +++ b/libraries/entities-renderer/src/EntityTreeRenderer.h @@ -130,7 +130,8 @@ private: QList _releasedModels; RayToEntityIntersectionResult findRayIntersectionWorker(const PickRay& ray, Octree::lockType lockType, - bool precisionPicking, const QVector& entityIdsToInclude = QVector()); + bool precisionPicking, const QVector& entityIdsToInclude = QVector(), + const QVector& entityIdsToDiscard = QVector()); EntityItemID _currentHoverOverEntityID; EntityItemID _currentClickingOnEntityID; diff --git a/libraries/entities/src/EntityScriptingInterface.cpp b/libraries/entities/src/EntityScriptingInterface.cpp index a0a6719521..0746c2a824 100644 --- a/libraries/entities/src/EntityScriptingInterface.cpp +++ b/libraries/entities/src/EntityScriptingInterface.cpp @@ -357,19 +357,21 @@ QVector EntityScriptingInterface::findEntitiesInBox(const glm::vec3& corn return result; } -RayToEntityIntersectionResult EntityScriptingInterface::findRayIntersection(const PickRay& ray, bool precisionPicking, const QScriptValue& entityIdsToInclude) { - QVector entities = qVectorEntityItemIDFromScriptValue(entityIdsToInclude); - return findRayIntersectionWorker(ray, Octree::TryLock, precisionPicking, entities); +RayToEntityIntersectionResult EntityScriptingInterface::findRayIntersection(const PickRay& ray, bool precisionPicking, const QScriptValue& entityIdsToInclude, const QScriptValue& entityIdsToDiscard) { + QVector entitiesToInclude = qVectorEntityItemIDFromScriptValue(entityIdsToInclude); + QVector entitiesToDiscard = qVectorEntityItemIDFromScriptValue(entityIdsToDiscard); + return findRayIntersectionWorker(ray, Octree::TryLock, precisionPicking, entitiesToInclude, entitiesToDiscard); } -RayToEntityIntersectionResult EntityScriptingInterface::findRayIntersectionBlocking(const PickRay& ray, bool precisionPicking, const QScriptValue& entityIdsToInclude) { - const QVector& entities = qVectorEntityItemIDFromScriptValue(entityIdsToInclude); - return findRayIntersectionWorker(ray, Octree::Lock, precisionPicking, entities); +RayToEntityIntersectionResult EntityScriptingInterface::findRayIntersectionBlocking(const PickRay& ray, bool precisionPicking, const QScriptValue& entityIdsToInclude, const QScriptValue& entityIdsToDiscard) { + const QVector& entitiesToInclude = qVectorEntityItemIDFromScriptValue(entityIdsToInclude); + const QVector entitiesToDiscard = qVectorEntityItemIDFromScriptValue(entityIdsToDiscard); + return findRayIntersectionWorker(ray, Octree::Lock, precisionPicking, entitiesToInclude, entitiesToDiscard); } RayToEntityIntersectionResult EntityScriptingInterface::findRayIntersectionWorker(const PickRay& ray, Octree::lockType lockType, - bool precisionPicking, const QVector& entityIdsToInclude) { + bool precisionPicking, const QVector& entityIdsToInclude, const QVector& entityIdsToDiscard) { RayToEntityIntersectionResult result; @@ -377,7 +379,7 @@ RayToEntityIntersectionResult EntityScriptingInterface::findRayIntersectionWorke OctreeElementPointer element; EntityItemPointer intersectedEntity = NULL; result.intersects = _entityTree->findRayIntersection(ray.origin, ray.direction, element, result.distance, result.face, - result.surfaceNormal, entityIdsToInclude, (void**)&intersectedEntity, lockType, &result.accurate, + result.surfaceNormal, entityIdsToInclude, entityIdsToDiscard, (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 f745b6b644..d08a1b7e36 100644 --- a/libraries/entities/src/EntityScriptingInterface.h +++ b/libraries/entities/src/EntityScriptingInterface.h @@ -112,11 +112,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 QScriptValue& entityIdsToInclude = QScriptValue()); + Q_INVOKABLE RayToEntityIntersectionResult findRayIntersection(const PickRay& ray, bool precisionPicking = false, const QScriptValue& entityIdsToInclude = QScriptValue(), const QScriptValue& entityIdsToDiscard = 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 QScriptValue& entityIdsToInclude = QScriptValue()); + Q_INVOKABLE RayToEntityIntersectionResult findRayIntersectionBlocking(const PickRay& ray, bool precisionPicking = false, const QScriptValue& entityIdsToInclude = QScriptValue(), const QScriptValue& entityIdsToDiscard = QScriptValue()); Q_INVOKABLE void setLightsArePickable(bool value); Q_INVOKABLE bool getLightsArePickable() const; @@ -189,7 +189,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, - bool precisionPicking, const QVector& entityIdsToInclude); + bool precisionPicking, const QVector& entityIdsToInclude, const QVector& entityIdsToDiscard); EntityTreePointer _entityTree; EntitiesScriptEngineProvider* _entitiesScriptEngine = nullptr; diff --git a/libraries/entities/src/EntityTree.cpp b/libraries/entities/src/EntityTree.cpp index ba6294f8a8..f0a03623c2 100644 --- a/libraries/entities/src/EntityTree.cpp +++ b/libraries/entities/src/EntityTree.cpp @@ -498,6 +498,7 @@ public: BoxFace& face; glm::vec3& surfaceNormal; const QVector& entityIdsToInclude; + const QVector& entityIdsToDiscard; void** intersectedObject; bool found; bool precisionPicking; @@ -510,7 +511,7 @@ bool findRayIntersectionOp(OctreeElementPointer element, void* extraData) { EntityTreeElementPointer entityTreeElementPointer = std::dynamic_pointer_cast(element); if (entityTreeElementPointer ->findRayIntersection(args->origin, args->direction, keepSearching, args->element, args->distance, args->face, args->surfaceNormal, args->entityIdsToInclude, - args->intersectedObject, args->precisionPicking)) { + args->entityIdsToDiscard, args->intersectedObject, args->precisionPicking)) { args->found = true; } return keepSearching; @@ -518,9 +519,9 @@ bool findRayIntersectionOp(OctreeElementPointer element, void* extraData) { bool EntityTree::findRayIntersection(const glm::vec3& origin, const glm::vec3& direction, OctreeElementPointer& element, float& distance, - BoxFace& face, glm::vec3& surfaceNormal, const QVector& entityIdsToInclude, void** intersectedObject, + BoxFace& face, glm::vec3& surfaceNormal, const QVector& entityIdsToInclude, const QVector& entityIdsToDiscard, 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, entityIdsToInclude, entityIdsToDiscard, intersectedObject, false, precisionPicking }; distance = FLT_MAX; bool requireLock = lockType == Octree::Lock; diff --git a/libraries/entities/src/EntityTree.h b/libraries/entities/src/EntityTree.h index 5e54e562a0..f68e2d59e9 100644 --- a/libraries/entities/src/EntityTree.h +++ b/libraries/entities/src/EntityTree.h @@ -84,6 +84,7 @@ public: virtual bool findRayIntersection(const glm::vec3& origin, const glm::vec3& direction, OctreeElementPointer& node, float& distance, BoxFace& face, glm::vec3& surfaceNormal, const QVector& entityIdsToInclude = QVector(), + const QVector& entityIdsToDiscard = QVector(), void** intersectedObject = NULL, Octree::lockType lockType = Octree::TryLock, bool* accurateResult = NULL, diff --git a/libraries/entities/src/EntityTreeElement.cpp b/libraries/entities/src/EntityTreeElement.cpp index ff2e97e8fe..17f967fc1f 100644 --- a/libraries/entities/src/EntityTreeElement.cpp +++ b/libraries/entities/src/EntityTreeElement.cpp @@ -475,8 +475,8 @@ bool EntityTreeElement::bestFitBounds(const glm::vec3& minPoint, const glm::vec3 bool EntityTreeElement::findRayIntersection(const glm::vec3& origin, const glm::vec3& direction, bool& keepSearching, OctreeElementPointer& element, float& distance, - BoxFace& face, glm::vec3& surfaceNormal, const QVector& entityIdsToInclude, - void** intersectedObject, bool precisionPicking) { + BoxFace& face, glm::vec3& surfaceNormal, const QVector& entityIdsToInclude, + const QVector& entityIdsToDiscard, void** intersectedObject, bool precisionPicking) { keepSearching = true; // assume that we will continue searching after this. @@ -501,7 +501,7 @@ bool EntityTreeElement::findRayIntersection(const glm::vec3& origin, const glm:: if (_cube.contains(origin) || distanceToElementCube < distance) { if (findDetailedRayIntersection(origin, direction, keepSearching, element, distanceToElementDetails, - face, localSurfaceNormal, entityIdsToInclude, intersectedObject, precisionPicking, distanceToElementCube)) { + face, localSurfaceNormal, entityIdsToInclude, entityIdsToDiscard, intersectedObject, precisionPicking, distanceToElementCube)) { if (distanceToElementDetails < distance) { distance = distanceToElementDetails; @@ -516,7 +516,7 @@ bool EntityTreeElement::findRayIntersection(const glm::vec3& origin, const glm:: bool EntityTreeElement::findDetailedRayIntersection(const glm::vec3& origin, const glm::vec3& direction, bool& keepSearching, OctreeElementPointer& element, float& distance, BoxFace& face, glm::vec3& surfaceNormal, - const QVector& entityIdsToInclude, void** intersectedObject, bool precisionPicking, float distanceToElementCube) { + const QVector& entityIdsToInclude, const QVector& entityIDsToDiscard, 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; diff --git a/libraries/entities/src/EntityTreeElement.h b/libraries/entities/src/EntityTreeElement.h index d8a182156d..aa05438bde 100644 --- a/libraries/entities/src/EntityTreeElement.h +++ b/libraries/entities/src/EntityTreeElement.h @@ -144,11 +144,13 @@ public: virtual bool canRayIntersect() const { return hasEntities(); } virtual bool findRayIntersection(const glm::vec3& origin, const glm::vec3& direction, bool& keepSearching, OctreeElementPointer& node, float& distance, - BoxFace& face, glm::vec3& surfaceNormal, const QVector& entityIdsToInclude, + BoxFace& face, glm::vec3& surfaceNormal, const QVector& entityIdsToInclude, + const QVector& entityIdsToDiscard, 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, const QVector& entityIdsToInclude, + const QVector& entityIdsToDiscard, void** intersectedObject, bool precisionPicking, float distanceToElementCube); virtual bool findSpherePenetration(const glm::vec3& center, float radius, glm::vec3& penetration, void** penetratedObject) const; From 8e7dfc07c0568616f06d66c0276337166cc03488 Mon Sep 17 00:00:00 2001 From: ericrius1 Date: Thu, 24 Dec 2015 11:59:47 -0800 Subject: [PATCH 06/16] Added logic to blacklist entities from raypicking --- examples/rayPickingFilterExample.js | 110 +++++++++++-------- libraries/entities/src/EntityTreeElement.cpp | 2 +- 2 files changed, 67 insertions(+), 45 deletions(-) diff --git a/examples/rayPickingFilterExample.js b/examples/rayPickingFilterExample.js index aa1950c013..a373840e72 100644 --- a/examples/rayPickingFilterExample.js +++ b/examples/rayPickingFilterExample.js @@ -1,50 +1,72 @@ - var center = Vec3.sum(MyAvatar.position, Vec3.multiply(3, Quat.getFront(Camera.getOrientation()))); - - var whiteListBox = Entities.addEntity({ - type: "Box", - color: { - red: 10, - green: 200, - blue: 10 - }, - dimensions: { - x: .2, - y: .2, - z: .2 - }, - position: center - }); - - var blackListBox = Entities.addEntity({ - type: "Box", - color: { - red: 100, - green: 10, - blue: 10 - }, - dimensions: { - x: .2, - y: .2, - z: .2 - }, - position: Vec3.sum(center, {x: 0, y: .3, z: 0}) - }); + // + // rayPickingFilterExample.js + // examples + // + // Created by Eric Levin on 12/24/2015 + // Copyright 2015 High Fidelity, Inc. + // + // This is an example script that demonstrates the use of filtering entities for ray picking + // + // Distributed under the Apache License, Version 2.0. + // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html + // - function castRay(event) { - var pickRay = Camera.computePickRay(event.x, event.y); - var pickResults = Entities.findRayIntersection(pickRay, true, [], [blackListBox]); + var center = Vec3.sum(MyAvatar.position, Vec3.multiply(3, Quat.getFront(Camera.getOrientation()))); - if(pickResults.intersects) { - print("INTERSECTION"); - } + var whiteListBox = Entities.addEntity({ + type: "Box", + color: { + red: 10, + green: 200, + blue: 10 + }, + dimensions: { + x: 0.2, + y: 0.2, + z: 0.2 + }, + position: center + }); - } + var blackListBox = Entities.addEntity({ + type: "Box", + color: { + red: 100, + green: 10, + blue: 10 + }, + dimensions: { + x: 0.2, + y: 0.2, + z: 0.2 + }, + position: Vec3.sum(center, { + x: 0, + y: 0.3, + z: 0 + }) + }); - function cleanup() { - Entities.deleteEntity(whiteListBox); - Entities.deleteEntity(blackListBox); - } - Script.scriptEnding.connect(cleanup); - Controller.mousePressEvent.connect(castRay); \ No newline at end of file + function castRay(event) { + var pickRay = Camera.computePickRay(event.x, event.y); + // In this example every entity will be pickable except the entities in the blacklist array + // the third arg is the whitelist array,a nd the fourth and final is the blacklist array + var pickResults = Entities.findRayIntersection(pickRay, true, [], [blackListBox]); + // With below example, only entities adde dto whitelist will be pickable + // var pickResults = Entities.findRayIntersection(pickRay, true, [whiteListBox], []); + + if (pickResults.intersects) { + print("INTERSECTION!"); + } + + } + + function cleanup() { + Entities.deleteEntity(whiteListBox); + Entities.deleteEntity(blackListBox); + } + + Script.scriptEnding.connect(cleanup); + Controller.mousePressEvent.connect(castRay); \ No newline at end of file diff --git a/libraries/entities/src/EntityTreeElement.cpp b/libraries/entities/src/EntityTreeElement.cpp index 17f967fc1f..8944c95cbc 100644 --- a/libraries/entities/src/EntityTreeElement.cpp +++ b/libraries/entities/src/EntityTreeElement.cpp @@ -522,7 +522,7 @@ bool EntityTreeElement::findDetailedRayIntersection(const glm::vec3& origin, con int entityNumber = 0; bool somethingIntersected = false; forEachEntity([&](EntityItemPointer entity) { - if (entityIdsToInclude.size() > 0 && !entityIdsToInclude.contains(entity->getID())) { + if ( (entityIdsToInclude.size() > 0 && !entityIdsToInclude.contains(entity->getID())) || (entityIDsToDiscard.size() > 0 && entityIDsToDiscard.contains(entity->getID())) ) { return; } From 340c066b5ccba6a40bfd11d02604b554cb8ace2f Mon Sep 17 00:00:00 2001 From: ericrius1 Date: Thu, 24 Dec 2015 12:04:36 -0800 Subject: [PATCH 07/16] reverted whiteboard changes --- 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 1d0f21c026..e55f54e312 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?v1" + Math.random()); +var scriptURL = Script.resolvePath("whiteboardEntityScript.js"; var modelURL = "https://s3.amazonaws.com/hifi-public/eric/models/whiteboard.fbx"; var colorIndicatorBorderModelURL = "https://s3.amazonaws.com/hifi-public/eric/models/colorIndicatorBorder.fbx"; @@ -247,4 +247,4 @@ function cleanup() { // Uncomment this line to delete whiteboard and all associated entity on script close -Script.scriptEnding.connect(cleanup); +// Script.scriptEnding.connect(cleanup); From 2e95ca7947d54f9f99e46c44398d0fcadaf5fedc Mon Sep 17 00:00:00 2001 From: ericrius1 Date: Thu, 24 Dec 2015 12:05:11 -0800 Subject: [PATCH 08/16] fixed syntax error --- 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 e55f54e312..f6c7aa77ca 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 modelURL = "https://s3.amazonaws.com/hifi-public/eric/models/whiteboard.fbx"; var colorIndicatorBorderModelURL = "https://s3.amazonaws.com/hifi-public/eric/models/colorIndicatorBorder.fbx"; From 542d8a4b6cb292bc1e5bdd40c8b69675345c665d Mon Sep 17 00:00:00 2001 From: ericrius1 Date: Thu, 24 Dec 2015 12:06:29 -0800 Subject: [PATCH 09/16] Fixed spelling mistakes --- examples/rayPickingFilterExample.js | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/examples/rayPickingFilterExample.js b/examples/rayPickingFilterExample.js index a373840e72..73d151847b 100644 --- a/examples/rayPickingFilterExample.js +++ b/examples/rayPickingFilterExample.js @@ -52,9 +52,10 @@ function castRay(event) { var pickRay = Camera.computePickRay(event.x, event.y); // In this example every entity will be pickable except the entities in the blacklist array - // the third arg is the whitelist array,a nd the fourth and final is the blacklist array + // the third argument is the whitelist array,and the fourth and final is the blacklist array var pickResults = Entities.findRayIntersection(pickRay, true, [], [blackListBox]); - // With below example, only entities adde dto whitelist will be pickable + + // With below example, only entities added to whitelist will be pickable // var pickResults = Entities.findRayIntersection(pickRay, true, [whiteListBox], []); if (pickResults.intersects) { From 28c53822b15291c99f7845e3e42af285e45019f1 Mon Sep 17 00:00:00 2001 From: "James B. Pollack" Date: Sun, 27 Dec 2015 12:37:33 -0800 Subject: [PATCH 10/16] add raypick blacklisting to hand grab script --- examples/controllers/handControllerGrab.js | 33 +++++++++++++++++++++- 1 file changed, 32 insertions(+), 1 deletion(-) diff --git a/examples/controllers/handControllerGrab.js b/examples/controllers/handControllerGrab.js index e0a7c55af8..aa416068f2 100644 --- a/examples/controllers/handControllerGrab.js +++ b/examples/controllers/handControllerGrab.js @@ -116,6 +116,11 @@ var DEFAULT_GRABBABLE_DATA = { invertSolidWhileHeld: false }; + +// sometimes we want to exclude objects from being picked +var USE_BLACKLIST = true; +var blacklist = []; + //we've created various ways of visualizing looking for and moving distant objects var USE_ENTITY_LINES_FOR_SEARCHING = false; var USE_OVERLAY_LINES_FOR_SEARCHING = false; @@ -771,7 +776,14 @@ function MyController(hand) { }) } - var intersection = Entities.findRayIntersection(pickRayBacked, true); + var intersection; + + if(USE_BLACKLIST===true){ + intersection = Entities.findRayIntersection(pickRay, true, [], blacklist); + } + else{ + intersection = Entities.findRayIntersection(pickRayBacked, true); + } if (intersection.intersects) { // the ray is intersecting something we can move. @@ -1626,6 +1638,7 @@ function update() { Messages.subscribe('Hifi-Hand-Disabler'); Messages.subscribe('Hifi-Hand-Grab'); +Messages.subscribe('Hifi-Hand-RayPick-Blacklist'); handleHandMessages = function(channel, message, sender) { if (sender === MyAvatar.sessionUUID) { @@ -1649,6 +1662,24 @@ handleHandMessages = function(channel, message, sender) { } catch (e) { } } + else if (channel === 'Hifi-Hand-RayPick-Blacklist') { + try { + var data = JSON.parse(message); + var action = data.action; + var id = data.id; + var index = blacklist.indexOf(id); + + if (action === 'add' && index ===-1) { + blacklist.push(id); + } + if (action === 'remove') { + if (index > -1) { + blacklist.splice(index, 1); + } + } + + } catch (e) {} + } } } From 546e908633f41206c032b114eaa3af179b5bc770 Mon Sep 17 00:00:00 2001 From: "James B. Pollack" Date: Sun, 27 Dec 2015 12:46:40 -0800 Subject: [PATCH 11/16] protect blacklisting to my id --- examples/controllers/handControllerGrab.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/controllers/handControllerGrab.js b/examples/controllers/handControllerGrab.js index aa416068f2..80fcaa3f6f 100644 --- a/examples/controllers/handControllerGrab.js +++ b/examples/controllers/handControllerGrab.js @@ -777,7 +777,7 @@ function MyController(hand) { } var intersection; - + if(USE_BLACKLIST===true){ intersection = Entities.findRayIntersection(pickRay, true, [], blacklist); } @@ -1662,7 +1662,7 @@ handleHandMessages = function(channel, message, sender) { } catch (e) { } } - else if (channel === 'Hifi-Hand-RayPick-Blacklist') { + else if (channel === 'Hifi-Hand-RayPick-Blacklist' && sender === MyAvatar.sessionUUID) { try { var data = JSON.parse(message); var action = data.action; From 0e30393c81b7ec1067d0fdfb5f483b68004326cd Mon Sep 17 00:00:00 2001 From: "James B. Pollack" Date: Sun, 27 Dec 2015 12:47:56 -0800 Subject: [PATCH 12/16] make sure theres something on the blacklist --- examples/controllers/handControllerGrab.js | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/examples/controllers/handControllerGrab.js b/examples/controllers/handControllerGrab.js index 80fcaa3f6f..deca0aa3ba 100644 --- a/examples/controllers/handControllerGrab.js +++ b/examples/controllers/handControllerGrab.js @@ -778,13 +778,12 @@ function MyController(hand) { var intersection; - if(USE_BLACKLIST===true){ - intersection = Entities.findRayIntersection(pickRay, true, [], blacklist); + if (USE_BLACKLIST === true && blacklist.length !== 0) { + intersection = Entities.findRayIntersection(pickRay, true, [], blacklist); + } else { + intersection = Entities.findRayIntersection(pickRayBacked, true); } - else{ - intersection = Entities.findRayIntersection(pickRayBacked, true); - } - + if (intersection.intersects) { // the ray is intersecting something we can move. var intersectionDistance = Vec3.distance(pickRay.origin, intersection.intersection); From c4d7b7b9bb2afc5abd5f084c45391ef51a372fca Mon Sep 17 00:00:00 2001 From: "James B. Pollack" Date: Mon, 28 Dec 2015 10:21:23 -0800 Subject: [PATCH 13/16] Update utils.js --- examples/libraries/utils.js | 1 - 1 file changed, 1 deletion(-) diff --git a/examples/libraries/utils.js b/examples/libraries/utils.js index 37dccd5ac8..115c1bcb65 100644 --- a/examples/libraries/utils.js +++ b/examples/libraries/utils.js @@ -274,7 +274,6 @@ hexToRgb = function(hex) { calculateHandSizeRatio = function() { // Get the ratio of the current avatar's hand to Owen's hand - // var standardCenterHandPoint = 0.11288; var standardCenterHandPoint = 0.11288; var jointNames = MyAvatar.getJointNames(); //get distance from handJoint up to leftHandIndex3 as a proxy for center of hand From 679070ff6e1b155fcb8388aa3c446515499e4d8f Mon Sep 17 00:00:00 2001 From: "James B. Pollack" Date: Mon, 28 Dec 2015 10:22:02 -0800 Subject: [PATCH 14/16] Update hiddenEntityReset.js --- unpublishedScripts/hiddenEntityReset.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/unpublishedScripts/hiddenEntityReset.js b/unpublishedScripts/hiddenEntityReset.js index e8783bbbcb..a53d6e721f 100644 --- a/unpublishedScripts/hiddenEntityReset.js +++ b/unpublishedScripts/hiddenEntityReset.js @@ -169,7 +169,7 @@ } function createRaveStick(position) { - var modelURL = "https://s3-us-west-1.amazonaws.com/hifi-content/eric/models/raveStick.fbx"; + var modelURL = "http://hifi-content.s3.amazonaws.com/eric/models/raveStick.fbx"; var stick = Entities.addEntity({ type: "Model", name: "raveStick", From 4f80753d7b0c9ec88f49cc3ea3034d5929967e9f Mon Sep 17 00:00:00 2001 From: "James B. Pollack" Date: Mon, 28 Dec 2015 10:22:34 -0800 Subject: [PATCH 15/16] Update masterReset.js --- unpublishedScripts/masterReset.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/unpublishedScripts/masterReset.js b/unpublishedScripts/masterReset.js index f3c38b2adf..b82c8340e4 100644 --- a/unpublishedScripts/masterReset.js +++ b/unpublishedScripts/masterReset.js @@ -148,7 +148,7 @@ MasterReset = function() { } function createRaveStick(position) { - var modelURL = "https://s3-us-west-1.amazonaws.com/hifi-content/eric/models/raveStick.fbx"; + var modelURL = "http://hifi-content.s3.amazonaws.com/eric/models/raveStick.fbx"; var stick = Entities.addEntity({ type: "Model", name: "raveStick", From 4b50a030e06aeffd105abd977511e4f1932edf30 Mon Sep 17 00:00:00 2001 From: "James B. Pollack" Date: Mon, 28 Dec 2015 10:23:08 -0800 Subject: [PATCH 16/16] Update masterReset.js --- unpublishedScripts/masterReset.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/unpublishedScripts/masterReset.js b/unpublishedScripts/masterReset.js index b82c8340e4..2d6d9a0d01 100644 --- a/unpublishedScripts/masterReset.js +++ b/unpublishedScripts/masterReset.js @@ -1082,7 +1082,7 @@ MasterReset = function() { relativePosition: { x: 0, y: 0, - z: .06 + z: 0.06 }, relativeRotation: Quat.fromPitchYawRollDegrees(0,-90, -90) },