How does planck.js manage broad-phase collisions?

Planck.js efficiently manages internal broad-phase collision detection by utilizing a dynamic AABB (Axis-Aligned Bounding Box) tree structure to minimize the number of expensive narrow-phase shape checks. As a 2D rigid-body physics engine ported from Box2D, Planck.js isolates the spatial queries of a high volume of moving bodies into a lightweight proxy system. This architecture replaces computationally heavy \(O(N^2)\) brute-force pair comparisons with optimized, tree-traversal algorithms that quickly filter out shapes that are nowhere near each other.

The Role of the Dynamic Tree

At the core of the broad-phase management in Planck.js is the DynamicTree class. This internal structure organizes shapes based on their AABBs rather than their actual complex geometry (such as polygons or edge chains).

The Pair Management Pipeline

The broad-phase layer does not permanently track ongoing collisions; instead, its primary goal is to surface a list of potentially overlapping pairs for the narrow-phase solver. This is handled through a structured lifecycle during each physics time step:

  1. Proxy Movement: When a body moves significantly enough to breach its fattened bounding box, the internal MoveProxy method is executed. The proxy’s AABB is updated, and the node is re-inserted into the tree.
  2. Flagging for Review: Moved proxies are placed into an internal buffer of changed nodes.
  3. Querying the Tree: During the synchronizing phase, Planck.js iterates through this buffer. For every moved proxy, it performs an AABB query against the rest of the dynamic tree to find overlapping leaf nodes.
  4. Generating Collision Pairs: If the query detects overlapping bounding boxes between two distinct proxies, the broad-phase creates or updates a “collision pair” and hands it off to the contact manager.

Optimizing Ray Casts and Region Queries

Beyond basic pair generation, the internal broad-phase setup exposes fast spatial optimization hooks for developers. Because the DynamicTree structure maintains hierarchical bounding boxes, ray casting or region querying through the World class can bypass massive subsets of data. Instead of testing a line or region against every single object in the simulation, the algorithm skips entire branches of the tree if the ray or box does not intersect the parent node’s bounding envelope.