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

dynamic position on a BVH geometry #330

Closed RenaudRohlinger closed 2 years ago

RenaudRohlinger commented 2 years ago

Hello @gkjohnson and thank you very much for this amazing library, I'm using it on almost all of my projects ^^!

Recently I stepped into a small issue and I would love to hear your advice.

I am trying to translate my MeshBVH geometry (like a platformer game) and it seems like the translation is not being applied. If I try to update the geometry by applying its mesh's matrix I got some strange behavior with the collision too. What would be a good way to make that box move and keep the collision dynamic?

Here is a small demo to illustrate my issue (line 306 of the codesandbox): https://codesandbox.io/s/fervent-fermi-ugz82?file=/src/index.js:8185-8195

Thank you very much! image

gkjohnson commented 2 years ago

Hi @RenaudRohlinger! Glad to hear you're getting some good use out of it. Please share at some point if you can -- I always like seeing the use cases and projects people put together.

Regarding your issue - the BVH class isn't aware of world transformations at all and expects all shapes being used for spatial queries to be transformed into the local coordinate frame of the BVH / geometry before calling the function. This allows for more flexibility in that the same BVH can be used for multiple meshes that share geometry, performance is better because triangles do not have to be individually transformed into world space, and it allows the BVH to be used without a mesh or object 3d entirely. The transformation into the local coordinate frame happens inside the acceleratedRaycast override function so results align with the built in three.js raycast behavior.

You can see in the collectTriangles example that the sphere is transformed into the local frame of the mesh before shapecast is called for this reason:

https://github.com/gkjohnson/three-mesh-bvh/blob/4f1ceeeaeb9c0a06ae2018ae1b11596af4793cf4/example/collectTriangles.js#L219-L224

Do note that after some changes in one of the 0.4.x releases the "mesh" argument is no longer required for any of the query functions. Originally it was used in order to get the geometry for the BVH but that is now referenced directly in the MeshBVH class itself. In the upcoming v0.5.0 release the function signatures for the query functions will change so the mesh argument is no longer required and a warning will be logged. All results from these functions will be provided in the local frame, as well, so you'll need to explicitly transform the results into world space if that's what you need.

Hopefully that answers your question! Please feel free to recommend documentation updates to make this more clear if you can.

RenaudRohlinger commented 2 years ago

@gkjohnson Ah! I understand! Thank you very much for the explanations. My example is now working https://ugz82.csb.app/ ^^ I am having fun making a physic engine for my company, and all the collisions detection is using three-mesh-bvh. Your examples helped me a lot to understand how physics engines work thanks a lot for that.

That was the first try: https://twitter.com/onirenaud/status/1439569141585702926

Since then I have implemented restitution, acceleration, and mass (still a lot of work to test). Thanks to you I also now have moving platforms. The next steps are rigid bodies and maybe one day soft bodies who knows ^^

gkjohnson commented 2 years ago

Great! Glad I could help.

I am having fun making a physic engine for my company, and all the collisions detection is using three-mesh-bvh. Your examples helped me a lot to understand how physics engines work thanks a lot for that.

That was the first try: https://twitter.com/onirenaud/status/1439569141585702926

Really looking forward to seeing where this goes. Is the video in that tweet made using three-mesh-bvh? Or the new version you're working on is?

The next steps are rigid bodies and maybe one day soft bodies who knows ^^

The refit() function should be useful for something like soft bodies. You can adjust vertices and then refit will expand / shrink any bounds to fit them again so queries will be correct. It's not an optimal bounds but should be good enough until you can regenerate it in a worker after it's deformed a lot. Technically I think that should work for doing intersection detection with SkinnedMeshes, as well, but I haven't tried that. I wonder how performant that would actually be in JS 🤔