From ccd18c13bb9fcd2ecc30b2a87a0cf8ed449aa69e Mon Sep 17 00:00:00 2001 From: Val Erastov Date: Mon, 18 Feb 2019 23:41:57 -0800 Subject: [PATCH] being able to pick objects based on a custom ray --- modules/scene/sceneSetup.js | 10 ++ .../cad/scene/controls/pickControlPlugin.js | 138 ++++++++++-------- web/app/cad/scene/viewer.js | 4 + 3 files changed, 89 insertions(+), 63 deletions(-) diff --git a/modules/scene/sceneSetup.js b/modules/scene/sceneSetup.js index d21436d4..13bea336 100644 --- a/modules/scene/sceneSetup.js +++ b/modules/scene/sceneSetup.js @@ -177,6 +177,16 @@ export default class SceneSetUp { return raycaster.intersectObjects( objects, true ); } + customRaycast(from3, to3, objects) { + let raycaster = new THREE.Raycaster(); + let from = new THREE.Vector3().fromArray(from3); + let to = new THREE.Vector3().fromArray(to3); + let dir = to.sub(from); + let dist = dir.length(); + raycaster.set(from, dir.normalize()); + return raycaster.intersectObjects(objects, true ).filter(h => h.distance <= dist); + } + modelToScreen(pos) { let width = this.container.clientWidth, height = this.container.clientHeight; let widthHalf = width / 2, heightHalf = height / 2; diff --git a/web/app/cad/scene/controls/pickControlPlugin.js b/web/app/cad/scene/controls/pickControlPlugin.js index 8f7b1f68..41a43758 100644 --- a/web/app/cad/scene/controls/pickControlPlugin.js +++ b/web/app/cad/scene/controls/pickControlPlugin.js @@ -21,6 +21,8 @@ const DEFAULT_SELECTION_MODE = Object.freeze({ datum: true }); +export const ALL_EXCLUDING_SOLID_KINDS = PICK_KIND.FACE | PICK_KIND.SKETCH | PICK_KIND.EDGE | PICK_KIND.DATUM_AXIS | PICK_KIND.LOOP; + export function activate(context) { const {services, streams} = context; @@ -96,11 +98,17 @@ export function activate(context) { const deselectAll = () => services.marker.clear(); function handlePick(event) { - raycastObjects(event, PICK_KIND.FACE | PICK_KIND.SKETCH | PICK_KIND.EDGE | PICK_KIND.DATUM_AXIS | PICK_KIND.LOOP, pickHandler); + let pickResults = services.viewer.raycast(event, services.cadScene.workGroup.children); + traversePickResults(event, pickResults, ALL_EXCLUDING_SOLID_KINDS, pickHandler); } - function pick(obj) { - pickHandler(obj, null); + function pickFromRay(from3, to3, kind, event = null) { + let pickResults = services.viewer.customRaycast(from3, to3, services.cadScene.workGroup.children); + return traversePickResults(event, pickResults, kind, pickHandler); + } + + function pick(obj, event = null) { + pickHandler(obj, event); } function dispatchSelection(entityType, selectee, event) { @@ -119,84 +127,88 @@ export function activate(context) { } function handleSolidPick(e) { - raycastObjects(e, PICK_KIND.FACE, (sketchFace) => { + let pickResults = services.viewer.raycast(e, services.cadScene.workGroup.children); + traversePickResults(e, pickResults, PICK_KIND.FACE, (sketchFace) => { streams.selection.solid.next([sketchFace.solid]); services.viewer.render(); return false; }); } + + services.pickControl = { + setPickHandler, deselectAll, pick, pickFromRay + }; +} - function raycastObjects(event, kind, visitor) { - let pickResults = services.viewer.raycast(event, services.cadScene.workGroup.children); - const pickers = [ - (pickResult) => { - if (mask.is(kind, PICK_KIND.SKETCH)) { - let sketchObjectV = getAttribute(pickResult.object, SKETCH_OBJECT); - if (sketchObjectV) { - return !visitor(sketchObjectV.model, event, pickResult); - } +export function traversePickResults(event, pickResults, kind, visitor) { + const pickers = [ + (pickResult) => { + if (mask.is(kind, PICK_KIND.SKETCH)) { + let sketchObjectV = getAttribute(pickResult.object, SKETCH_OBJECT); + if (sketchObjectV) { + return !visitor(sketchObjectV.model, event, pickResult); } - return false; - }, - (pickResult) => { - if (mask.is(kind, PICK_KIND.EDGE)) { - let edgeV = getAttribute(pickResult.object, EDGE); - if (edgeV) { - return !visitor(edgeV.model, event, pickResult); - } + } + return false; + }, + (pickResult) => { + if (mask.is(kind, PICK_KIND.EDGE)) { + let edgeV = getAttribute(pickResult.object, EDGE); + if (edgeV) { + return !visitor(edgeV.model, event, pickResult); } - return false; - }, - (pickResult) => { - if (mask.is(kind, PICK_KIND.LOOP) && !!pickResult.face) { - let faceV = getAttribute(pickResult.face, LOOP); - if (faceV) { - return !visitor(faceV.model, event, pickResult); - } + } + return false; + }, + (pickResult) => { + if (mask.is(kind, PICK_KIND.LOOP) && !!pickResult.face) { + let faceV = getAttribute(pickResult.face, LOOP); + if (faceV) { + return !visitor(faceV.model, event, pickResult); } - return false; - }, - (pickResult) => { - if (mask.is(kind, PICK_KIND.FACE) && !!pickResult.face) { - let faceV = getAttribute(pickResult.face, FACE); - if (faceV) { - return !visitor(faceV.model, event, pickResult); - } + } + return false; + }, + (pickResult) => { + if (mask.is(kind, PICK_KIND.FACE) && !!pickResult.face) { + let faceV = getAttribute(pickResult.face, FACE); + if (faceV) { + return !visitor(faceV.model, event, pickResult); } - return false; - }, - (pickResult) => { - if (mask.is(kind, PICK_KIND.DATUM_AXIS)) { - let datumAxisV = getAttribute(pickResult.object, DATUM_AXIS); - if (datumAxisV) { - return !visitor(datumAxisV.model, event, pickResult); - } - } - return false; - }, - ]; - for (let i = 0; i < pickResults.length; i++) { - const pickResult = pickResults[i]; - for (let picker of pickers) { - if (pickResult.object && pickResult.object.passRayCast && pickResult.object.passRayCast(pickResults)) { - // continue; - } - if (picker(pickResult)) { - return; + } + return false; + }, + (pickResult) => { + if (mask.is(kind, PICK_KIND.DATUM_AXIS)) { + let datumAxisV = getAttribute(pickResult.object, DATUM_AXIS); + if (datumAxisV) { + return !visitor(datumAxisV.model, event, pickResult); } } + return false; + }, + ]; + for (let i = 0; i < pickResults.length; i++) { + const pickResult = pickResults[i]; + for (let picker of pickers) { + if (pickResult.object && pickResult.object.passRayCast && pickResult.object.passRayCast(pickResults)) { + // continue; + } + if (picker(pickResult)) { + return; + } } } - services.pickControl = { - setPickHandler, deselectAll, pick - }; } + function printPickInfo(model, rayCastData) { console.log("PICKED MODEL:"); console.dir(model); console.log("PICK RAYCAST INFO:"); - console.dir(rayCastData); - let pt = rayCastData.point; - console.log('POINT: ' + pt.x + ', ' + pt.y + ',' + pt.z); + if (rayCastData) { + console.dir(rayCastData); + let pt = rayCastData.point; + console.log('POINT: ' + pt.x + ', ' + pt.y + ',' + pt.z); + } } \ No newline at end of file diff --git a/web/app/cad/scene/viewer.js b/web/app/cad/scene/viewer.js index ac10e3b4..efdda499 100644 --- a/web/app/cad/scene/viewer.js +++ b/web/app/cad/scene/viewer.js @@ -36,6 +36,10 @@ export default class Viewer { return this.sceneSetup.raycast(event, objects); } + customRaycast(from3, to3, objects) { + return this.sceneSetup.customRaycast(from3, to3, objects); + } + setCameraMode(mode) { if (this.getCameraMode() === mode) { return;