DanielChappuis / reactphysics3d

Open source C++ physics engine library in 3D
http://www.reactphysics3d.com
zlib License
1.5k stars 218 forks source link

Creating collision shapes in a thread #186

Open Zylann opened 3 years ago

Zylann commented 3 years ago

I'm getting started with ReactPhysics3D as an experiment, and I would like to know if it allows (or will allow) to create collision shapes from a separate thread, without blocking the simulation?

Here is my use case: I am making a voxel engine in Godot Engine, and one expensive task consists in creating static mesh colliders from the isosurface chunks (made with Transvoxel). In Godot, 3D physics cannot be used outside of the main thread, it wasn't implemented. This is a problem for me because it tremendously limits the amount of updates I can do per frame. The slow part is when the BVH is computed by Bullet: https://github.com/Zylann/godot_voxel/issues/124

I see ReactPhysics3D does the same, but it seems that it would also not be safe due to the use of PhysicsCommon.


Note, unrelated to this issue but related to my use case: I was thinking that maybe a specialized collider deriving the surface from voxels directly might be more efficient than an arbitrary mesh collider, similarly to what heightmaps do in 2D. I have no experience in making physics engines, but is it possible to do that in ReactPhysics3D?

DanielChappuis commented 3 years ago

I see ReactPhysics3D does the same, but it seems that it would also not be safe due to the use of PhysicsCommon.

Yes ReactPhysics3D does the same. Currently, multi-threading in not supported with the library. In order to be able to create collision shapes in a different thread, we would need to make the PhysicsCommon class thread-safe and particularly the part that is responsible for memory allocations.

Note, unrelated to this issue but related to my use case: I was thinking that maybe a specialized collider deriving the surface from voxels directly might be more efficient than an arbitrary mesh collider, similarly to what heightmaps do in 2D. I have no experience in making physics engines, but is it possible to do that in ReactPhysics3D?

Sorry but it is currently not really possible to create a custom collider.

Zylann commented 3 years ago

Yes ReactPhysics3D does the same. Currently, multi-threading in not supported with the library. In order to be able to create collision shapes in a different thread, we would need to make the PhysicsCommon class thread-safe and particularly the part that is responsible for memory allocations.

Is it planned for something like this to be possible in the future?

Sorry but it is currently not really possible to create a custom collider.

Ah, too bad. I've had this bottleneck for a while now and I'm running out of options to make voxel collisions faster.

DanielChappuis commented 3 years ago

Is it planned for something like this to be possible in the future?

I think I would need to work on this when implementing multi-threading. This is not planned in v0.9.0 and I am not sure yet whether it will be part of v1.0.0 or v1.1.0.

Ah, too bad. I've had this bottleneck for a while now and I'm running out of options to make voxel collisions faster.

I am not very familiar with voxels engines. What is the most common way to perform collision detection in voxels scenes ? Creating a static mesh that corresponds to the voxels geometry of using multiple box collision shapes for instance ? In the second case, the broad-phase could speed up the collision detection, however ghost collisions might occur with internal edges between two neighboring voxels.

Zylann commented 3 years ago

I am not very familiar with voxels engines. What is the most common way to perform collision detection in voxels scenes ? Creating a static mesh that corresponds to the voxels geometry of using multiple box collision shapes for instance ? In the second case, the broad-phase could speed up the collision detection, however ghost collisions might occur with internal edges between two neighboring voxels.

I'm dealing with isosurfaces, so voxels that look like this: image

They really aren't just cubes. Internally they are stored as a signed distance field (SDF), in chunks of 16x16x16 cells. So if you take a slice of the chunk data from that cave, you'd see this: image

Each chunk is polygonized using the Transvoxel algorithm (derived from marching cubes), which is able to tell, for any cell, which triangles it has or not. The result is a mesh which in turn I'm feeding to the physics engine, but computing the BVH for this on the main thread slows everything down. I already limit the area in which they generate, but that's not enough, and players can edit nearby ground in realtime.

So I was thinking, maybe, similarly to the approach heightmaps take, the SDF grid could be used to obtain the triangles on the fly when collision processing is needed in a particular area. In the kind of game scenarios involved, it sounds faster than pre-emptively building and relying on a concave mesh + BVH which cannot take advantage of the particular way triangles are structured (from a grid). This is only an idea though, I'm myself still discovering how to do things, so I don't know if there is actually a common way to do this fast. Mesh colliders are the easiest so I assume most people use that, but they are really slow to create (I don't know yet if they would also be slower to collide with). Maybe even a triangle lookup grid could be faster and lighter than a BVH?

Found a link about the subject from Roblox: https://blog.roblox.com/2018/01/voxel-terrain-physics/

DanielChappuis commented 3 years ago

Thanks a lot for sharing this. The article from Roblox looks very interesting.

It seems to be quite a custom technique for voxel-terrain collision detection. I do not plan to work on this in the near future because I have many other things that I think should be prioritize instead but if many people are asking for this it would be quite interesting to add it into the library.

Chevifier commented 1 year ago

Just came across this issue as well I was thinking, not sure if its possible but since im procedurally generating the vertices for the mesh instances could I do some algorithm to just check for collisions locally around the viewer with just the vertex data from the mesh. Im guessing there would be plenty of limitations to doing that. Im not sure if it would even be possible.