Managing collisions

During each simulation step, Jolt Physics performs collision detection in 2 phases: broadphase and narrowphase.

  1. Broadphase enumerates pairs of objects in close proximity, based on overlaps between their axis-aligned bounding boxes (AABBs).

  2. Narrowphase uses detailed collision shapes to test each pair found during broadphase, resulting in a list of manifolds where the shapes intersect.

Each manifold is composed of up to 64 contact points. Jolt’s rigid-body dynamics uses manifolds and contact points to implement contact response, including friction and restitution.

Jolt JNI provides mechanisms to:

  • customize which collisions are handled and which are ignored

  • perform custom actions when a contact point is created or destroyed

  • query the broadphase detector to find bodies in a particular region

  • query the narrowphase detector to find bodies in a particular region

Collision groups

We’ve seen how layers can be used to prevent static bodies from colliding with one another. For finer control over which bodies are allowed to collide, you can configure collision groups and filters.

A collision group consists of:

  • a group ID,

  • a subgroup ID, and

  • an optional group filter, which takes 2 collision groups and decides whether collisions are allowed.

Every body has a collision group. By default, bodies are created with invalid IDs and no filter.

Two bodies are allowed to collide only if:

  • neither body has a filter,

  • the first body’s filter says the bodies can collide, or

  • if the first body has no filter and the 2nd body’s filter says they can collide.

The typical use case is a chain of bodies, all of which are allowed to collide except those adjacent in the chain.

GroupFilterTable filter = new GroupFilterTable(chainLength);
for (int subGroupId = 0; subGroupId < chainLength - 1; ++subGroupId)
        filter.disableCollision(subGroupId, subGroupId + 1);

Contact listener

During simulation, contact points can be tracked by means of a listener object:

physicsSystem.setContactListener(contactListener);

A sensor is a body without contact response, created solely to report contacts with nearby bodies. In order to work, a sensor must be added to a physics system.

HelloSensor is a Sport-Jolt app that illustrates how a contact listener and a sensor could be used to detect the first moving body entering a spherical zone.

Things notice while running the app:

  1. The character includes a body with capsule shape.

  2. Press Right arrow to walk the character toward the sensor.

  3. Immediately after the character’s body comes in contact with the sensor, the app removes the sensor from the system, producing the effect of popping a bubble.

There is, of course, no reason a sensor has to be visible.

A contact listener can also be used to customize collision handling, by overloading its onContactValidate() method. This isn’t the most efficient way to filter collisions; in most cases it would be better to use layers or collision groups.

Broadphase queries

If you simply want to find bodies in a particular region, creating sensors and tracking contact points is unnecessarily complicated.

Instead, you can directly query the system’s broadphase data to enumerate bodies whose bounding boxes intersect with:

  • a non-moving point,

  • a point moving along a straight line,

  • a non-moving axis-aligned box,

  • an axis-aligned box moving along a straight line,

  • a non-moving sphere, or

  • a non-moving box with arbitrary orientation.

In general, a body’s bounding box is larger than its collision shape, so broadphase queries are not very precise. They are efficient, however, and their precision is adequate for many purposes.

Broadphase queries are usually performed between simulation steps. The system’s BroadPhaseQuery interface is used, along with an appropriate collector object, like so:

BroadPhaseQuery query = physicsSystem.getBroadPhaseQuery();
AllHitCollideShapeBodyCollector collector
        = new AllHitCollideShapeBodyCollector();
query.collideAaBox(aaBox, collector);

Filters can be specified to limit query results to specific layers.

HelloBroadphase is a Sport-Jolt app that illustrates how broadphase queries can be used to detect characters entering/leaving a box-shaped zone.

Things notice while running the app:

  1. The ghost zone is shown in yellow.

  2. To clarify what’s going on, the character’s bounding box is outlined in white.

  3. Press Right arrow to walk the character toward the ghost.

  4. As soon as the character’s box overlaps the ghost, the ghost turns red, indicating an intrusion, even though their collision shapes haven’t intersected yet.

  5. Press Space bar to jump.

  6. The character can jump high enough to leave the ghost zone, at which time the ghost will momentarily turn yellow again.

Narrowphase queries

For more precise detections, you can query a system’s narrowphase data between simulation steps.

Narrowphase queries can enumerate bodies whose shapes intersect with:

  • a non-moving point,

  • a point moving along a straight line,

  • a non-moving axis-aligned box,

  • a non-moving shape, or

  • a shape moving along a straight line.

Like broadphase queries, narrowphase queries are best performed between simulation steps. The system’s NarrowPhaseQuery interface is used, along with an appropriate collector object, like so:

NarrowPhaseQuery query = physicsSystem.getNarrowPhaseQuery();
Vec3Arg scale = Vec3.sOne();
CollideShapeSettings settings = new CollideShapeSettings();
AllHitCollideShapeCollector collector = new AllHitCollideShapeCollector();
query.collideShape(shape, scale, transform, settings, base, collector);

HelloNarrowphase is a Sport-Jolt app that illustrates how narrowphase queries can be used to detect characters entering/leaving an octahedral zone.

Things notice while running the app:

  1. Press Right arrow to walk the character toward the ghost zone.

  2. As soon as the character’s shape intersects with the ghost’s shape, the ghost turns red, indicating an intrusion.

  3. Press Space bar to jump.

  4. The character can jump high enough to leave the ghost zone, at which time the ghost will momentarily turn yellow again.

Summary

  • Collision groups offer fine control over which bodies are allowed to collide.

  • To track individual contacts in real time, use a contact listener.

  • To search a region for bodies, use a broadphase query or a narrowphase query.

  • Narrowphase queries are more precise, but also more expensive.