Expand description
Components and functionality for Continuous Collision Detection (CCD).
§What Is CCD?
Physics simulation is typically done in a discrete manner. At the beginning of each timestep, 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 and deep overlap.
Currently, two approaches are supported: swept CCD and
speculative collision. Swept CCD is performed for fast-moving
dynamic bodies by default, and can be configured using the SweptCcd component,
while speculative collision is fully opt-in via the SpeculativeCcd component.
§Swept CCD
Note: Swept CCD currently only supports the built-in Collider.
Swept CCD is a form of Continuous Collision Detection that sweeps fast-moving dynamic bodies from their previous positions to their current positions, and if a collision is found along the path, moves the body back to the time of impact. This way, discrete collision algorithms will be able to detect and handle the collision during the next timestep.
There are two variants of swept CCD: SweepMode::Linear and SweepMode::NonLinear.
The difference is that Linear only considers translational motion,
so fast-spinning bodies can still pass through objects, while NonLinear
also considers rotational motion, but is more expensive.
Sweeps are performed automatically for every fast dynamic body, against both static and kinematic bodies. A body is considered “fast” if its motion during a timestep is large relative to its minimum thickness. This way, we only pay the cost of CCD for bodies that have a risk of tunneling or deep overlap.
The behavior of swept CCD can be customized using the SweptCcd component.
This includes configuring which types of bodies sweeps are performed against,
tuning the threshold for what is considered a “fast” body, and changing
the sweep mode:
use avian3d::prelude::*;
use bevy::prelude::*;
fn setup(mut commands: Commands) {
commands.spawn((
RigidBody::Dynamic,
Collider::capsule(0.5, 2.0),
// These are the default settings
SweptCcd {
filter: CcdFilter::DEFAULT,
mode: SweepMode::NonLinear,
threshold: 0.5,
}
));
}See the documentation of the SweptCcd component for more details
and configuration options.
This approach to CCD is heavily inspired by Box2D by Erin Catto.
§Caveats of Swept CCD
Swept CCD can lead to time loss or time stealing, where bodies appear to momentarily slow down or freeze when colliding at high speeds. This happens because they are essentially moved backwards in time to avoid missing the collision. Time loss could be better accounted for with a substepped time-of-impact solver, but it would be much more expensive and complex, so it is not supported yet.
Additionally, if two fast-moving bodies are approaching each other, but are not already in the path of each other’s sweeps (ex: projectiles coming from different directions), they can miss each other. This can be solved by also enabling speculative collision in order to expand their AABBs based on velocity and predict contacts before they happen.
§Speculative Collision
Speculative collision is a form of Continuous Collision Detection
where contacts are predicted before they happen. It is only performed
for bodies that have the SpeculativeCcd component.
To determine whether two bodies may come into contact within the next timestep,
speculative collision expands their ColliderAabbs based on their velocities.
Additionally, a speculative margin is used to determine the maximum distance
at which two shapes can generate speculative contacts.
By default, Avian keeps AABBs tight, and only predicts contacts up to a small,
fixed contact_tolerance, which aims to improve stability and avoid jitter
for resting bodies. By adding the SpeculativeCcd component, you can increase
the maximum speculative distance and opt in to velocity-based AABB expansion,
enabling speculative contact behavior.
Speculative collisions can be very efficient for highly dynamic scenes, but a large speculative margin can also lead to excessive collision tests and false positives, which are described below.
§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 contact solver. Ghost collisions typically manifest as objects bumping into seemingly invisible walls or seams.
Another caveat of speculative collision is that it can still occasionally miss contacts, especially for fast-spinning objects, as speculative contacts do not properly account for rotational motion.
Speculative collisions can also absorb some energy in contacts, causing even perfectly elastic objects to lose kinetic energy over several bounces.
These caveats together with the performance impact of velocity-expanded AABBs
are why Avian does not predict contacts beyond the small contact_tolerance
by default. Still, speculative contacts can be a good option for some scenes,
which is what the opt-in SpeculativeCcd component is for.
§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 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§
- CcdFilter
- A bitmask determining which
RigidBodytypes aSweptCcdbody is swept against during Continuous Collision Detection (CCD). - CcdPlugin
- A plugin for Continuous Collision Detection (CCD).
- Speculative
Ccd - A component that enables speculative collision
and velocity-expanded AABBs for a
RigidBody, allowing it to predict and react to contacts before they happen. - Swept
Ccd - A component that configures swept Continuous Collision Detection (CCD)
for a dynamic
RigidBody.
Enums§
- Sweep
Mode - The algorithm used for sweeps during Continuous Collision Detection (CCD).