Skip to main content

Simulation structures

This page describes all the data structures needed for stepping the simulation as illustrated by the basic simulation example.

Gravity

Gravity is represented as a vector. It affects every dynamic rigid-body taking part of the simulation. The gravity can be altered at each timestep (by passing a different vector to PhysicsPipeline::step). Learn more about per-rigid-body gravity modification in the dedicated section.

Integration parameters

The IntegrationParameters controls various aspects of the physics simulation, including the timestep length, number of solver iterations, number of CCD substeps, etc. The default integration parameters are set to achieve a good balance between performance and accuracy for games. They can be changed to make the simulation more accurate at the expanse of a bit of performance. Learn more about each integration parameter in the API docs.

Island manager

The IslandManager is responsible for tracking the set of dynamic rigid-bodies that are still moving and these that are no longer moving (and can ignored by subsequent timesteps to avoid useless computations). The island manager is automatically updated by PhysicsPipeline::step and can be queried to retrieve the list of all the rigid-bodies modified by the physics engine during the last timestep. This can be useful to update the rendering of only the rigid-bodies that moved:

// Iter on each dynamic rigid-bodies that moved.
for rigid_body_handle in island_manager.active_dynamic_bodies() {
let rigid_body = &rigid_body_set[*rigid_body_handle];
println!(
"Rigid body {:?} has a new position: {}",
rigid_body_handle,
rigid_body.position()
);
}

Learn more about sleeping rigid-bodies in the dedicated section.

Physics pipeline

The PhysicsPipeline is responsible for tying everything together in order to run the physics simulation. It will take care of updating every data-structures mentioned in this page (except the other pipelines), running the collision-detection, running the force computation and integration, and running CCD resolution.

PhysicsPipeline::step executes one timestep. Its usage is illustrated in the basic simulation example.

Collision pipeline

The CollisionPipeline is similar to the PhysicsPipeline except that it will only run collision-detection. It won't perform any dynamics (force computation, integration, CCD, etc.) It is generally used instead of the PhysicsPipeline when one only needs collision-detection.

info

Running both the CollisionPipeline and the PhysicsPipeline is useless because the PhysicsPipeline already does collision-detection.

Query pipeline

The QueryPipeline is responsible for efficiently running scene queries, e.g., ray-casting, shape-casting (sweep tests), intersection tests, on all the colliders of the scene.

Before it is used, the QueryPipeline needs to be updated in order to take the new colliders' positions into account. The QueryPipeline can be used alone, but it is very common to use the QueryPipeline alongside the CollisionPipeline or PhysicsPipeline:

// Game loop.
loop {
// You can pass the query pipeline as parameter to the physics pipeline,
// This enables optimizations such as update the query pipeline incrementally rather
// than triggering a more expensive full rebuild.
physics_pipeline.step(..., Some(&mut query_pipeline), ...);

// - If you have passed the query pipeline in the physics pipeline `step()` function:
// Now we can read the results of the physics simulation,
// and we can do advanced scene queries on the colliders.
// Game loop.
loop {
physics_pipeline.step(..., None, ...);
// - If you have NOT passed the query pipeline in the physics pipeline `step()` function,
// OR if you have made some changes to your simulation data since that `step()` call:
// You'll need to update your query pipeline.
query_pipeline.update(...);
// Now we can read the results of the physics simulation,
// and we can do advanced scene queries on the colliders.
}

Learn more about scene queries with the QueryPipeline in the dedicated page.

Rigid-body set

The RigidBodySet contains all the rigid-bodies that needs to be simulated. This set is represented as a generational-arena, i.e., a vector where each element is indexed using a handle that combines an u32 index and an u32 generation number. This ensures that every rigid-body is given a unique handle. Learn more about rigid-bodies in the dedicated page.

Collider set

The ColliderSet contains all the colliders that needs to be simulated. This set is represented as a generational-arena, i.e., a vector where each element is indexed using a handle that combines an u32 index and an u32 generation number. This ensures that every collider is given a unique handle. Learn more about colliders in the dedicated page.

Joint set

The ImpulseJointSet contains all the impulse-based joints that needs to be simulated. This set is represented as a generational-arena, i.e., a vector where each element is indexed using a handle that combines an u32 index and an u32 generation number. This ensures that every joint is given a unique handle. Learn more about joints in the dedicated page.

CCD solver

The CCD solver is responsible for the resolution of Continuous-Collision-Detection. By itself, this structure doesn't expose any useful feature. So it should simply be passed to the PhysicsPipeline::step method. Learn more about CCD in the dedicated section.

Physics hooks

The physics hooks are trait-objects implementing the PhysicsHooks trait. They can be used to apply arbitrary rules to ignore collision detection between some pairs of colliders. They can also be used to modify the contacts processed by the constraints solver for computing forces. Learn more about physics hooks in the dedicated section.

Event handler

The event handlers are trait-objects implementing the EventHandler trait. They can be used to get notified when two non-sensor colliders start/stop having contacts, and when one sensor collider and one other collider start/stop intersecting. Learn more about collision events in the dedicated section.