From 48af8df08e781611256398b29319acfb51f4dfcc Mon Sep 17 00:00:00 2001 From: Jaakko Manninen Date: Sat, 28 Jan 2017 12:00:07 +0200 Subject: [PATCH 1/3] Allow passing custom scene hierarchy to intersect When switching between multiple scenes, add/remove can be very costly. Also change the intersect handling to handle nested meshes. --- src/ray-input.js | 4 ++-- src/ray-renderer.js | 25 +++++++++++++++++++------ 2 files changed, 21 insertions(+), 8 deletions(-) diff --git a/src/ray-input.js b/src/ray-input.js index 34a22d3..58e018a 100644 --- a/src/ray-input.js +++ b/src/ray-input.js @@ -57,7 +57,7 @@ export default class RayInput extends EventEmitter { delete this.handlers[object.id] } - update() { + update(meshes) { let lookAt = new THREE.Vector3(0, 0, -1); lookAt.applyQuaternion(this.camera.quaternion); @@ -166,7 +166,7 @@ export default class RayInput extends EventEmitter { default: console.error('Unknown interaction mode.'); } - this.renderer.update(); + this.renderer.update(meshes); this.controller.update(); } diff --git a/src/ray-renderer.js b/src/ray-renderer.js index 7322d64..53196e1 100644 --- a/src/ray-renderer.js +++ b/src/ray-renderer.js @@ -94,15 +94,28 @@ export default class RayRenderer extends EventEmitter { } } - update() { + update(meshes) { // Do the raycasting and issue various events as needed. + let intersects = this.raycaster.intersectObjects(meshes, true); + let intersectedMesh; + + for (var i=0; i < intersects.length; i++) { + let obj = intersects[i].object; + + // traverse the hierarchy backwards, to find a clickable mesh via a child + while (obj && !this.meshes[obj.id]) { + obj = obj.parent; + } + + if (obj) { + intersectedMesh = obj.id; + break; + } + } + for (let id in this.meshes) { let mesh = this.meshes[id]; - let intersects = this.raycaster.intersectObject(mesh, true); - if (intersects.length > 1) { - console.warn('Unexpected: multiple meshes intersected.'); - } - let isIntersected = (intersects.length > 0); + let isIntersected = (intersectedMesh === id); let isSelected = this.selected[id]; // If it's newly selected, send rayover. From 9b2c6a381706ff2d1237f5f2058b0f99df0fe4e1 Mon Sep 17 00:00:00 2001 From: Jaakko Manninen Date: Sun, 29 Jan 2017 16:02:16 +0200 Subject: [PATCH 2/3] Check equality on mesh.id --- src/ray-renderer.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ray-renderer.js b/src/ray-renderer.js index 53196e1..885363f 100644 --- a/src/ray-renderer.js +++ b/src/ray-renderer.js @@ -115,7 +115,7 @@ export default class RayRenderer extends EventEmitter { for (let id in this.meshes) { let mesh = this.meshes[id]; - let isIntersected = (intersectedMesh === id); + let isIntersected = (intersectedMesh === mesh.id); let isSelected = this.selected[id]; // If it's newly selected, send rayover. From 6157ff69fee68bb97ba6be2deaf0fded4643d9a7 Mon Sep 17 00:00:00 2001 From: Jaakko Manninen Date: Sun, 29 Jan 2017 16:43:11 +0200 Subject: [PATCH 3/3] Remember the current meshes for the raydown re-raycast --- src/ray-input.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/ray-input.js b/src/ray-input.js index 58e018a..212b2f2 100644 --- a/src/ray-input.js +++ b/src/ray-input.js @@ -61,6 +61,8 @@ export default class RayInput extends EventEmitter { let lookAt = new THREE.Vector3(0, 0, -1); lookAt.applyQuaternion(this.camera.quaternion); + this.currentMeshes = meshes; + let mode = this.controller.getInteractionMode(); switch (mode) { case InteractionModes.MOUSE: @@ -196,7 +198,7 @@ export default class RayInput extends EventEmitter { //console.log('onRayDown_'); // Force the renderer to raycast. - this.renderer.update(); + this.renderer.update(this.currentMeshes); let mesh = this.renderer.getSelectedMesh(); this.emit('raydown', mesh);