What Is a Compound Body in Matter.js?
This article explains the concept of compound bodies in Matter.js, a 2D physics engine for the web. You will learn what compound bodies are, why they are essential for creating complex physical shapes, how Matter.js calculates their physical properties like mass and center of gravity, and how to implement them in your projects.
In Matter.js, a basic rigid body is typically restricted to simple convex shapes such as circles, rectangles, or regular polygons. A compound body is a single rigid physical body composed of two or more individual parts (sub-bodies). By combining these simple shapes into a unified entity, you can create complex, multi-part, or concave geometries—such as an "L" shaped bracket, a hollow container, or a vehicle frame—that behave as a single, unbreakable physical object.
Why Use Compound Bodies?
Physics engines struggle with concave polygons because collision detection algorithms (like the Separating Axis Theorem) require shapes to be convex. To simulate a concave object or an intricate structure, you decompose it into multiple overlapping or adjacent convex pieces.
While you could connect multiple bodies using stiff constraints (springs), doing so introduces computational overhead and can lead to physics instability or "spongy" behavior. A compound body solves this by permanently welding the parts together at the engine level, treating them mathematically as one rigid object with zero flexibility between parts.
How Compound Bodies Work Internally
When you create a compound body, Matter.js organizes the shapes in a parent-child relationship:
- The Parts Array: The compound body holds a
partsarray. The first element (parts[0]) is the parent body itself, while the subsequent elements are the child parts. - Center of Mass: Matter.js automatically recalculates the overall center of mass based on the positions, areas, and densities of all individual parts. The parent body's position is then aligned with this computed center of mass.
- Mass and Inertia: The total mass, area, and rotational inertia (moment of inertia) of the compound body are computed as the sum of its individual parts.
- Collision Handling: The engine tests collisions against each individual part's geometry. However, when a collision occurs, the resulting forces, friction, and restitution are applied to the parent body as a whole.
How to Create a Compound Body
To create a compound body, instantiate your individual parts using
standard shape creation methods, and then pass them inside an options
object to Body.create().
// Define individual convex parts
const partA = Bodies.rectangle(100, 200, 50, 50);
const partB = Bodies.rectangle(140, 200, 50, 50);
// Combine them into a single compound body
const compoundBody = Body.create({
parts: [partA, partB]
});
// Add the compound body to the world
Composite.add(engine.world, compoundBody);You can also update an existing body into a compound body at runtime
using the Body.setParts() method.
Key Considerations
When defining the initial positions of the parts, place them in world coordinates where they should sit relative to each other. Matter.js automatically normalizes their offsets relative to the newly calculated center of mass. If you need to apply physical forces, velocities, or torques, apply them to the parent compound body rather than the individual sub-parts to ensure correct physical simulation.