Module avian3d::dynamics::ccd

source ·
Expand description

Contains components and functionality for Continuous Collision Detection.

§What Is CCD?

Physics simulation is typically done in a discrete manner. At the beginning of each physics frame, the simulation checks for collisions, and if none are found for a given rigid body, it is free to move according to its velocity and the size of the timestep.

This generally works well for large or slowly moving objects, but fast and small objects can pass through thin geometry such as walls and triangle meshes. This phenomenon is often called tunneling.

Discrete

Continuous Collision Detection (CCD) aims to prevent tunneling. Currently, two approaches are supported: Speculative Collision and Swept CCD. Speculative collision is enabled by default, but swept CCD is opt-in with the SweptCcd component. The two approaches can also be used together.

§Speculative Collision

Speculative collision is a form of Continuous Collision Detection where contacts are predicted before they happen. The contacts are only solved if the entities are expected to come into contact within the next frame.

To determine whether two bodies may come into contact, their AABBs are expanded based on their velocities. Additionally, a speculative margin is used to determine the maximum distance at which a collision pair can generate speculative contacts.

Collision AABB Speculative Margin Unconstrained Constrained SpeculativeContact

The current “effective” speculative margin for a body is determined by its velocity clamped by the specified maximum bound. By default, the maximum bound is infinite, but it can be configured for all entities using the NarrowPhaseConfig resource, and for individual entities using the SpeculativeMargin component.

use avian3d::prelude::*;
use bevy::prelude::*;

fn setup(mut commands: Commands) {
    // Spawn a rigid body with a maximum bound for the speculative margin.
    commands.spawn((
        RigidBody::Dynamic,
        Collider::capsule(0.5, 2.0),
        SpeculativeMargin(2.0),
    ));
}

Speculative collisions are an efficient and generally robust approach to Continuous Collision Detection. They are enabled for all bodies by default, provided that the default naximum speculative margin is greater than zero.

However, speculative collisions aren’t entirely without issues, and there are some cases where large speculative margins can cause undesired behavior.

§Caveats of Speculative Collision

Speculative contacts are approximations. They typically have good enough accuracy, but when bodies are moving past each other at high speeds, the prediction can sometimes fail and lead to ghost collisions. This happens because contact surfaces are treated like infinite planes from the point of view of the solver. Ghost collisions typically manifest as objects bumping into seemingly invisible walls.

Collision AABB Speculative Margin Unconstrained Constrained Ghost Collision Plane

Ghost collisions can be mitigated by using a smaller SpeculativeMargin or a higher Physics timestep rate.

Another caveat of speculative collisions is that they can still occasionally miss contacts, especially for thin objects spinning at very high speeds. This is typically quite rare however, and speculative collision should work fine for the majority of cases.

For an approach that is more expensive but doesn’t suffer from ghost collisions or missed collisions, consider using swept CCD, which is described in the following section.

§Swept CCD

Note: Swept CCD currently only supports the built-in Collider.

Swept CCD is a form of Continuous Collision Detection that sweeps potentially colliding objects from their previous positions to their current positions, and if a collision is found, moves the bodies back to the time of impact. This way, the normal collision algorithms will be able to detect and handle the collision during the next frame.

There are two variants of swept CCD: Linear and NonLinear. The difference between the two is that Linear only considers translational motion, so bodies can still pass through objects that are spinning at high speeds, while NonLinear also considers rotational motion, but is more expensive.

Linear / NonLinear Linear NonLinear

To enable swept CCD for a rigid body, simply add the SweptCcd component and make sure that the CcdPlugin is enabled. The plugin is included in the PhysicsPlugins plugin group.

use avian3d::prelude::*;
use bevy::prelude::*;

fn setup(mut commands: Commands) {
    // Spawn a rigid body with swept CCD enabled.
    // `SweepMode::NonLinear` is used by default.
    commands.spawn((
        RigidBody::Dynamic,
        Collider::capsule(0.5, 2.0),
        SweptCcd::default(),
    ));
}

See the documentation of the component for more details and configuration options.

Swept CCD is more expensive than Speculative Collision, but it doesn’t have the same issues with ghost collisions or missed collisions. It is primarily intended as a safety net when it is crucial that a body never tunnels through geometry. Swept CCD should only be used when necessary, as it also has its own set of problems.

§Caveats of Swept CCD

The Linear and NonLinear approaches can lead to time loss or time stealing, where bodies appear to momentarily move slower when Swept CCD is active. This happens because they are essentially moved backwards in time to avoid missing the collision.

Swept CCD might also not account for chain reactions properly, so if a fast-moving body bumps into another body, making it a fast-moving body that potentially bumps into even more bodies, the collisions might not propagate accurately. However, speculative contacts do detect secondary collisions quite well, so using the two together can help mitigate the issue.

Time loss and chain reactions could also be better accounted for with a substepped time-of-impact solver, but that would be much more expensive and complex, so it is not yet supported.

§Other Ways to Avoid Tunneling

CCD is one way to prevent objects from tunneling through each other, but it should only be used when necessary. There are several other approaches worth considering to help avoid the issue.

The most obvious way is to simply avoid small or thin geometry such as triangle meshes, and to make colliders for objects like walls slightly thicker than necessary. This is of course typically not possible everywhere, but it is good to keep in mind when authoring levels.

Triangle mesh colliders are especially prone to tunneling for dynamic rigid bodies. For shapes that are intended to be solid from the inside, it is recommended to use convex decomposition instead.

If you must use triangle mesh colliders and are having stability issues, consider giving them a small amount of extra thickness using the CollisionMargin component. This helps prevent objects from passing through the surface while also reducing numerical errors and improving performance.

Finally, making the physics timestep smaller can also help. However, this comes at the cost of worse performance for the entire simulation.

Structs§

Enums§