gkjohnson / three-mesh-bvh

A BVH implementation to speed up raycasting and enable spatial queries against three.js meshes.
https://gkjohnson.github.io/three-mesh-bvh/example/bundle/raycast.html
MIT License
2.39k stars 247 forks source link

Raycast.ray is not applied to the matrixWorld #297

Closed abbazabacto closed 2 years ago

abbazabacto commented 2 years ago

The raycast is not applied against the (inverse) matrixWorld of the Mesh. When the Mesh is inside a scaled/rotated group the intersection is incorrect due to this missing calculation.

See how threejs does do this in the Mesh raycast:

inverseMatrix.getInverse( matrixWorld );
ray.copy( raycaster.ray ).applyMatrix4( inverseMatrix );

https://github.com/mrdoob/three.js/blob/0aa87c999fe61e216c1133fba7a95772b503eddf/src/objects/Mesh.js#L217-L218

Updating the MeshBVH raycast with similar logic should solve this issue. The following code requires in scope of file var inverseMatrix = new Matrix();

raycast( mesh, raycaster, ray, intersects ) {
   const geometry = this.geometry;
   const localIntersects = intersects ? [] : null;
+   
+   inverseMatrix.getInverse(mesh.matrixWorld);
+   ray.copy(raycaster.ray).applyMatrix4(inverseMatrix);
+   
   for ( const root of this._roots ) {

https://github.com/gkjohnson/three-mesh-bvh/blob/master/src/MeshBVH.js#L315-L318

I could assist on opening a PR with the suggested solution (at a later moment).

abbazabacto commented 2 years ago

Sorry, this is my mistake I switched to a custom raycasting logic, the accelerated raycast has this logic in place: https://github.com/gkjohnson/three-mesh-bvh/blob/2ac3c87cf2759accdc9cfe04e2ae9098ecb5d10d/src/index.js#L18-L19

It is is even mentioned in the README: https://github.com/gkjohnson/three-mesh-bvh#querying-the-bvh-directly

gkjohnson commented 2 years ago

Glad the docs helped work it out for you! The MeshBVH class assumes any shape, ray, etc has been transformed into the local space of the BVH so the user can handle any conversions between arbitrary frames and so a mesh isn't needed. The mesh argument will be going away in the v0.5.0 release because it's actually longer needed after some changes in the v0.4.x releases.