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.
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.
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.
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.
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§
- A plugin for Continuous Collision Detection.
- The maximum distance at which speculative contacts are generated for this entity. A value greater than zero helps prevent missing contacts for moderately fast-moving and thin objects.
- A component that enables sweep-based Continuous Collision Detection (CCD) for a
RigidBody
. This helps prevent missed collisions for small and fast-moving objects. - A system set for Continuous Collision Detection systems.
Enums§
- The algorithm used for Swept Continuous Collision Detection.