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

Possible bug in 0.5.0 #353

Closed obsius closed 2 years ago

obsius commented 2 years ago

Hi, and thanks again for this library. I see there are a few changes to the newest version, so maybe there is something I need to change in my usage, otherwise I think there is a bug.

Below are two short clips of raycasting into a terrain. The first example is v0.4.3, and the behavior is as expected. A hit is detected as indicated by the arrows (ignore the variable vertical angles, that is something done after raycasting, the raycasts are always done directly horizontal), and the second is v0.5.0:

0.4.3 0 4 3

0.5.0 0 5 0

In the second (0.5.0) you can see the arrows pass through the wall in some spots.

Let me know your thoughts and if you want me to isolate this down to the failure cases.

Thanks!

gkjohnson commented 2 years ago

Hey @obsius! It does look like a bug -- I tried to be careful in my refactoring of the API but it is possible I missed something. And it seems there's a gap in the tests, as well. I haven't seen any failures either in tests or the examples recently myself, though.

Rather than guess at what settings or functions might need to be adjusted it would be easiest if you could provide a version of the mesh that I could use to test as well as information about a ray, material settings (mostly sideness), and BVH construction options and I'll try to have this fixed in the next release!

Thanks again for being diligent on bug reports to new versions!

obsius commented 2 years ago

@gkjohnson Hey Garrett, I haven't forgotten about this, well, I had, but now I remember. I've grabbed your latest version 0.5.2, and have tested a few files out and haven't seen any issues, but I cannot find the data that caused this issue. Did you change anything that might have fixed this? Otherwise, I'll need to do some digging to find this data set again.

gkjohnson commented 2 years ago

@obsius

Hey! I was actually about to ping you about it 😁 I was thinking about making a few more changes but I don't want to obscure this issue -- it would be good to know where it came from.

I cannot find the data that caused this issue. Did you change anything that might have fixed this? Otherwise, I'll need to do some digging to find this data set again.

I don't think anything should have changed that would impact this. Most of the recent changes have been related to shader raycast capabilities. To be safe maybe test on v0.5.0? Even if it is not an issue anymore somehow it would be good to verify.

Thanks again for your help!

obsius commented 2 years ago

@gkjohnson Found the data set. I've put it all in one source file, both data and logic, so it should just need proper require or import statements at the top, and then rename any references to those deps in the code if they are different.

The results are:

On 0.4.3: raycasting with BVH and without produces identical intersects On 0.5.2: raycasting with BVH and without produces different intersects (the near intersects are missing)

Visually, this looks like:

image

Source file (make sure linewrap is off in your editor): test.js.txt

obsius commented 2 years ago

@gkjohnson I had to edit that source file to make it decoupled from some of the stuff I have in my project, and I forgot to include some setup stuff:

    THREE.BufferGeometry.prototype.computeBoundsTree = BVH.computeBoundsTree;
    THREE.BufferGeometry.prototype.disposeBoundsTree = BVH.disposeBoundsTree;
    THREE.Mesh.prototype.raycast = BVH.acceleratedRaycast;

Let me know if you have any issues, probably will be something else like this that I may have missed.

gkjohnson commented 2 years ago

@obsius Thanks for the repro case! It seems this line in your example that incorrectly passes a object rather than a material that is the issue:

let mesh = new THREE.Mesh(geometry, {
    side: THREE.DoubleSide
});

A material is expected so changing the line to this fixes the issue:

let mesh = new THREE.Mesh(geometry, new THREE.MeshBasicMaterial({
    side: THREE.DoubleSide
}));

Let me know if that works for you!

obsius commented 2 years ago

@gkjohnson Ah, perfect, that is spot on. Thanks for the quick debug. I'll close this out.

gkjohnson commented 2 years ago

Great! Glad it worked. Thanks again!