Show Convex Hulls of Compound Parts in Matter.js
This article explains how to visualize the convex hulls of complex
compound bodies in Matter.js using the built-in
showConvexHulls render option. You will learn why convex
hulls are essential for collision detection in 2D physics simulations,
how compound parts interact within the engine, and how to properly
configure the Matter.Render module to visually debug these
collision boundaries.
Matter.js relies on the Separating Axis Theorem (SAT) for collision
detection, which strictly requires convex polygons. When dealing with
complex, concave, or multi-part shapes, Matter.js breaks these
geometries down into a set of smaller convex shapes assigned as children
(parts) of a single root body. Enabling showConvexHulls
draws the computed convex boundaries around these parts, allowing you to
verify that collision meshes accurately match your visual assets.
Enabling showConvexHulls in the Renderer
The showConvexHulls property is a boolean flag located
inside the options object of a Matter.Render
instance. By default, it is set to false. To turn it on,
set showConvexHulls: true when initializing the renderer,
or modify the render instance directly after creation.
// Creating the renderer with showConvexHulls enabled
const render = Matter.Render.create({
element: document.body,
engine: engine,
options: {
width: 800,
height: 600,
wireframes: false, // Set to false to see fills along with debug hulls
showConvexHulls: true
}
});
Matter.Render.run(render);If the renderer is already running, you can toggle it dynamically:
render.options.showConvexHulls = true;Creating Complex Compound Parts
Compound bodies are typically created in two ways: manually grouping
individual rigid bodies using Body.create(), or decomposing
a concave SVG path or vertex array using
Bodies.fromVertices().
1. Concave Vertex Decomposition
When using Bodies.fromVertices, Matter.js automatically
uses a decomposition algorithm (such as poly-decomp.js) to split concave
vertex paths into multiple convex parts.
// Ensure poly-decomp is loaded globally or passed to Matter
// e.g., Common.setDecomp(decomp);
const concavePath = [
{ x: 0, y: 0 },
{ x: 100, y: 0 },
{ x: 100, y: 100 },
{ x: 50, y: 50 },
{ x: 0, y: 100 }
];
const compoundBody = Matter.Bodies.fromVertices(400, 300, concavePath);
Matter.Composite.add(engine.world, compoundBody);With showConvexHulls: true, Matter.js renders an outline
around each convex polygon generated to satisfy the concave shape.
2. Manual Compound Body Assembly
You can also construct compound bodies manually by chaining parts together.
const partA = Matter.Bodies.rectangle(400, 200, 140, 20);
const partB = Matter.Bodies.rectangle(400, 260, 20, 100);
const partC = Matter.Bodies.circle(400, 320, 30);
// Combine parts into a single compound body
const compoundBody = Matter.Body.create({
parts: [partA, partB, partC]
});
Matter.Composite.add(engine.world, compoundBody);How the Visual Output Works
When showConvexHulls is enabled:
- Matter.js iterates through every body in the world and inspects its
partsarray. - For every part that has a valid
hullorverticesarray, the renderer draws the minimum bounding convex polygon using a semi-transparent stroke. - If a shape is concave and failed to decompose properly, the hull preview highlights discrepancies between the intended graphical shape and the actual colliding region.
Common Troubleshooting Tips
- Missing Poly-Decomp: If
Bodies.fromVerticesdoes not split your shape into convex parts, verify that thepoly-decomplibrary is imported and provided to Matter viaMatter.Common.setDecomp(decomp). - Wireframe Mode Interference: When
wireframes: trueis set, Matter.js displays a simplified outline of all bodies. For the clearest view of hulls versus body bodies, setwireframes: falseso the hulls overlay on top of colored bodies.