three-mesh-bvh
three-mesh-bvh copied to clipboard
raycastFirst does not stop on first hit
Describe the bug
The performance feature raycastFirst does not stop on first hit and gives intersections.length > 1.
To Reproduce
Init raycaster as documented and set firstHitOnly to true. Raycast will give more than one intersection.
Code
init as documented
THREE.BufferGeometry.prototype.computeBoundsTree = computeBoundsTree THREE.BufferGeometry.prototype.disposeBoundsTree = disposeBoundsTree THREE.Mesh.prototype.raycast = acceleratedRaycast
const raycaster = new THREE.Raycaster() raycaster.firstHitOnly = true
const intersects = raycaster.intersectObjects(objects)
intersects.length > 1 // true
Expected behavior
acceleratedRaycast with firstHitOnly = true should give length <= 1
Screenshots
If applicable, add screenshots to help explain your problem (drag and drop the image).
Platform:
- Device: Desktop
- OS: MacOS
- Browser: Chrome
- Three.js version: 144
- Library version: v0.5.16
Perhaps the documentation could be updated but setting raycaster.firstHitOnly
only affects the behavior at the individual Mesh level - ie when performing a raycast into a mesh it will early out once the closest hit is found as an optimization. The raycaster.raycast function will still return multiple intersections if multiple meshes are intersected with even if it just returns at most one intersection per mesh. This is as designed.
raycaster.firstHitOnly can deliver more than two intersections for raycaster.intersectObjects([mesh1, mesh2]) as a result if the material.side is DoubleSide. Is this also as designed?
Could there be a benefit to provide a firstHitOnly which gets the first hit from the first mesh and than sets the far parameter for the next mesh/iteration?
raycaster.firstHitOnly can deliver more than two intersections for raycaster.intersectObjects([mesh1, mesh2]) as a result if the material.side is DoubleSide. Is this also as designed?
This doesn't sound right. Can you provide a demonstration of the issue?
Could there be a benefit to provide a firstHitOnly which gets the first hit from the first mesh and than sets the far parameter for the next mesh/iteration?
This would be a better role for a scene-level spatial index. Something like #388 or an octree implementation would be a better general approach for this. In your app you could also collect all the meshes that you anticipate intersecting, sort them by distance along the ray, and then perform per-mesh intersections until you know you've found the closest one so you can early out.
Going to close this - it's possible to write a better raycaster that would work for three.js without a BVH by presorting the geometry but I think that's outside the scope of this project for the moment.