dimforge / rapier

2D and 3D physics engines focused on performance.
https://rapier.rs
Apache License 2.0
3.8k stars 236 forks source link

Collision group filtering during BroadPhase #530

Closed grufkork closed 3 months ago

grufkork commented 9 months ago

Hello, just picked up Rapier2D yesterday for a physics simulation of a plinko/Galton board, where I want to record the paths of thousands, if not millions, of balls dropping through. Performance so far is good, except when trying to run many balls through at the same time by setting collision filtering so the balls do not collide with each other. As far as I know, the collision group filtering only happens after the broad phase, which means stacking a thousand collider on top of each other probably causes something like 1000^2 potential contacts to register per frame. I would expect being able to filter contacts at the broad phase pass to increase performance massively.

I tried collison layers, custom physics hooks and active collision types, which all appear to process after the broad phase.

I have currently solved the problem by spacing out the instancing of rigidbodies over time and running more simulation steps instead. I have not yet measured the overhead of each simulation step, so the performance loss might actually not be too great. I do then however not have much use of the parallel feature - though I expect I could just spawn several threads.

On a sidenote: doing a rough estimation, the total number of potential intercollisions might be lower by simulating a lesser number of rigidbodies at a time. Simulating 1000 balls for 100 frames means (1000^2*100) total potential collisions, while simulating 100 balls for 1000 frames is (100^2*1000), which is actually fewer. This is not counting the static geometry, but that should be a fixed number per ball. Since each collider pair still has to be considered, the filtering method would need to be faster than the overhead of running more simulation steps. (Unless potential collision groups can be flexibly precomputed)

Is there a quick hack/check I could add to the broad phase system to facilitate this? I don't need any of the intersection checks.

Thank you!

grufkork commented 9 months ago

Doing a bit of testing, I do actually get better performance when spacing out the instancing. For 10k balls, spacing them out by 20 frames causes it to run in half the time than if I instance one every frame. The number of steps is thus 20x higher, but still runs faster. Performance also suffers if any balls get stuck, so further performance gains can be made by removing any sleeping rigidbodies. Upping to 40-50 frames spacing increases running times again. Having a nicer way to handle simulations of this kind would be great.

sebcrozet commented 3 months ago

Adding support for groups as part of the existing broad-phase implementation would be a bit challenging (because of the need to handle cases where the groups change, resulting in a non-incremental overlap check in the broad-phase), defining your own, custom, broad-phase will be possible with #606.