dimforge / rapier

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

Performance Problem when using a lot of intersecting colliders #288

Open Bytekeeper opened 2 years ago

Bytekeeper commented 2 years ago

Even if no collision or solver interaction is configured, intersecting colliders massively reduce performance:

use rapier2d::prelude::*;

#[test]
fn timeout() {
    let mut rigid_body_set = RigidBodySet::new();
    let mut collider_set = ColliderSet::new();

    /* Create the ground. */

    for _ in 0..1000 {
        let rigid_body = RigidBodyBuilder::new_dynamic()
            .translation(vector![0.0, 10.0])
            .build();
        let collider = ColliderBuilder::ball(0.5)
            .restitution(0.7)
            .collision_groups(InteractionGroups::none())
            .solver_groups(InteractionGroups::none())
            .build();
        let ball_body_handle = rigid_body_set.insert(rigid_body);
        collider_set.insert_with_parent(collider, ball_body_handle, &mut rigid_body_set);
    }

    /* Create other structures necessary for the simulation. */
    let gravity = vector![0.0, -9.81];
    let integration_parameters = IntegrationParameters::default();
    let mut physics_pipeline = PhysicsPipeline::new();
    let mut island_manager = IslandManager::new();
    let mut broad_phase = BroadPhase::new();
    let mut narrow_phase = NarrowPhase::new();
    // DEMO uses non-existing ImpulseJointSet
    let mut joint_set = JointSet::new();
    let mut ccd_solver = CCDSolver::new();
    let physics_hooks = ();
    let event_handler = ();

    /* Run the game loop, stepping the simulation once per frame. */
    for _ in 0..200 {
        physics_pipeline.step(
            &gravity,
            &integration_parameters,
            &mut island_manager,
            &mut broad_phase,
            &mut narrow_phase,
            &mut rigid_body_set,
            &mut collider_set,
            &mut joint_set,
            &mut ccd_solver,
            &physics_hooks,
            &event_handler,
        );
    }
}

This test times out. If you prevent intersection (spawn at different locations), the test takes a short amount of time.

Background: I tried to simulate a large number of bullets, that should not interact with each other. Yet bounce of walls and some other things, but hit the player.

grufkork commented 1 year ago

Having the same problem trying to simulate many independent rigidbodies for a Galton board. Have you found a solution? I would expect it is due to the bounding box checks not being able to exclude collisions.

Edit: Looking into this, I would like a way to modify the broad-phase pass. As I understand, the broad-phase does not consider collision layers, and with a couple thousand colliders stacked on each other that results in an enourmous number of potential contacts. Each of these are then filtered. I'm checking the BroadPhase struct, but can't find much to modify there.