Matter.js Broad-Phase Collision Detection Explained

In Matter.js, collision handling operates on a multi-stage pipeline designed to maintain high performance by eliminating non-colliding objects before running expensive geometry calculations. The Matter.Detector.collisions method serves as the core coordinator for this broad-phase stage, scanning registered bodies to produce a list of active collision candidates. This article explains how Matter.Detector.collisions identifies these candidates through part flattening, spatial boundary evaluations, collision filtering rules, and state optimizations.

Compound Part Extraction

Matter.js represents both simple and complex objects as bodies composed of one or more parts. When Matter.Detector.collisions begins its evaluation, it does not compare composite bodies as single monolithic entities. Instead, it accesses the flattened array of leaf parts for each body. The top-level parent body is ignored in geometric testing if it contains subordinate parts, ensuring that collision detection resolves at the primitive convex polygon or circle level.

Fast State Rejection

Before running any spatial or geometric math, the detector skips pairs that cannot produce active physical responses:

Collision Filtering (Masks and Categories)

Candidates that pass state checks are evaluated using bitwise collision filters via body.collisionFilter. Each part contains group, category, and mask properties.

  1. Collision Groups: If both parts share the same non-zero group value, positive values force an automatic collision candidate match, while negative values force an immediate rejection.
  2. Category and Mask Bitmasks: If the group values do not match or are zero, the detector performs a bitwise AND comparison:
    (filterA.mask & filterB.category) !== 0 && (filterB.mask & filterA.category) !== 0
    If either side of the bitwise comparison evaluates to zero, the pair is discarded.

Axis-Aligned Bounding Box (AABB) Overlaps

For all pairs that satisfy the logical and state criteria, the detector performs spatial checks using Axis-Aligned Bounding Boxes (part.bounds). Every part's bounding box is dynamically updated during engine updates to encompass its current position, rotation, and vertices.

The detector checks for overlap along the X and Y axes using simple min-max comparisons via Bounds.overlaps(boundsA, boundsB):

If the bounding boxes do not overlap on both axes, the parts cannot possibly intersect, and the pair is rejected with minimal computational cost.

Passing Candidates to the Narrow Phase

When a pair of parts satisfies the hierarchy, sleep, bitmask, and AABB criteria, Matter.Detector.collisions marks them as an active collision candidate pair. The detector then forwards this candidate pair to the narrow phase—typically handled by Matter.SAT.collides (Separating Axis Theorem)—to determine true vertex-level intersection, contact points, penetration depth, and normal vectors.