Why Bodies Explode When Overlapping in Matter.js
When physics bodies in Matter.js spawn on top of each other, they often shoot apart violently in an effect commonly described as an explosion. This article explains the mechanics behind this behavior, detailing how the physics engine resolves deep overlaps via penetration correction and instantaneous impulses, along with practical methods developers can use to prevent it.
The Physics of Overlap Resolution
Matter.js is a rigid-body physics engine designed under the assumption that solid bodies cannot occupy the same space. When two objects overlap upon instantiation, the engine detects this intersection using the Separating Axis Theorem (SAT) and identifies it as a severe collision error known as penetration.
To maintain physical realism, the engine must separate the overlapping bodies. It does this by calculating a minimum translation vector (MTV) based on the penetration depth—the distance required to push the bodies apart so their surfaces only touch.
Massive Restorative Impulses
In a typical physical simulation, collisions occur at the boundary edges with low initial penetration depths. The engine applies small corrective forces or velocity changes over multiple engine updates (ticks) to bounce or push the bodies apart.
When bodies spawn directly inside one another:
- Extreme Penetration Depth: The overlap distance is at or near the maximum possible size of the bodies.
- Instant Positional Correction: Matter.js attempts to resolve this deep overlap immediately or over very few frames to enforce the non-penetration constraint.
- High Velocity Injection: The engine translates this deep penetration into a massive restorative impulse. Because kinetic energy and velocity scale directly with the magnitude of the corrective impulse, the bodies are instantly launched away from each other at extreme velocities, appearing as an explosion.
Compounding Factors
- Multiple Overlapping Bodies: Spawning three or more bodies in the same space multiplies the collision pairs exponentially. The solver attempts to resolve constraints simultaneously, causing corrective forces to chain together and amplify the outward velocities even further.
- Mass and Density: Lighter bodies receiving impulse from heavier intersecting bodies will absorb an even higher acceleration according to Newton’s second law (\(F = ma\)).
- Restitution (Bounciness): A high restitution value preserves the energy generated during the collision resolution, sending bodies flying across the canvas rather than coming to a rapid halt.
How to Prevent Bodies from Exploding
To stop overlapping bodies from violently repelling each other, you can implement one of several techniques depending on your use case:
- Pre-Spawn Validation: Check the coordinates before
adding a body to the engine. Use Matter.js query methods, such as
Matter.Query.region()orMatter.Query.collides(), to ensure a target area is clear before spawning an object. - Use Sensors on Spawn: Set
body.isSensor = trueupon creation. This disables physical collision responses while still allowing collision detection. Once the body moves out of an overlapping state, setisSensor = falseto enable solid physics. - Collision Filtering: Utilize
body.collisionFiltergroups or category masks to prevent overlapping bodies from recognizing each other until they are placed in safe, non-intersecting positions. - Gradual Scaling: Spawn bodies at a scale close to
zero (
Matter.Body.scale(body, 0.01, 0.01)) and smoothly scale them up to their target size across multiple frames, allowing surrounding bodies to move out of the way naturally.