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.5k stars 261 forks source link

Cannot shapecast against objects that have been quantized with gltf-transform #448

Closed dmliao closed 2 years ago

dmliao commented 2 years ago

Describe the bug

Hi there. I'm currently building an app with three-mesh-bvh for the collision layer that uses gltf-transform to compress GLTFs before serving them in the app. However, if I attempt to quantize the mesh, the shapecasts I use for collisions stop operating in three-mesh-bvh.

This appears to be related to discussion in #367, in which people noted that normalized attributes are used in gltf-transform, which apparently don't work with raycasts in three.js. I'm submitting this issue to formally note that this is now a problem that is surfacing in a real-world case.

If there are other places I should be going to try to address this issue, I'm happy to do so.

To Reproduce

Steps to reproduce the behavior:

  1. Create a quantized version of a model using gltf-transform
  2. Create a new bounds tree on that mesh once loaded in three.js
  3. Attempt to shapecast against that mesh
  4. Note that the shapecast never seems to register.

Live example

I've created a codesandbox that is mostly a copy of the characterMovement demo from within three-mesh-bvh that demonstrates this behavior: https://codesandbox.io/s/crazy-fermat-fkyplu?file=/src/index.js

You can change the included platform to the non-quantized version, which will work.

(I had to modify the models because the original example merged geometry, which also broke with the quantized meshes. However, that is irrelevant to my use case, so I replaced them.)

Expected behavior

All loaded GLTFs should be able to run three-mesh-bvh's shapecast properly (and other operations)

Platform:

gkjohnson commented 2 years ago

@dmliao https://github.com/mrdoob/three.js/pull/22874 has been merged and will be available next release. However this project relies on accessing the buffer arrays directly. Would you like to help make the changes required to support this?

I think the first thing I'd like to understand is the performance ramifications of switching from raw array access to the BufferAttribute getters to see what kind of impact that will have on the projects build and run time perf.

dmliao commented 2 years ago

Yes, I'd gladly help with that. I was actually in the process of going through three-mesh-bvh so I could test using the getters in anticipation of that three.js change; however, I haven't really done much thinking on performance yet.

Though -- upon closer inspection of the source, it looks like most of the attribute accesses are indeed with the getters, or by using Vertex3.fromBufferAttribute(...), which uses the getters under the hood. The only direct array reference I've found so far in the code is in MeshBVH.js's refit function...though that's a pretty important function for the library. I can work on updating that to use setters, and see how it performs?