Concave 2D colliders
· 3 min read
A table can be one dynamic body again. collider2d takes a
convex_decomposition kind: it cuts the polygon into convex pieces, then
grows each piece through the seams it shares.
Cut a table into a top and two legs and you leave seams. A beam pushed into one is three collision pairs that disagree, and it stays put. Erin Catto's Stuck Inside overlaps the pieces by hand. This does it for you: each piece carries its two edges at a seam on into the neighbour and keeps what they enclose.
overlap is the dial, 0.9 by default. At 0 you get the plain cut; at 1 a
piece grows flush with whatever stopped it.

What it costs and what it buys
- A piece keeps a seam only while it stays convex. Without that rule, a piece with several seams on a spiky outline grows a few percent of its area past the polygon. A sampling test over 25 shapes guards it.
overlapscales depth, not count, so pieces pile up. A drawn outline stacks two or three pieces on a point, and a 240-point star stacks 80.- The cost, one box tested against that star, per placement:
| kind | ns |
|---|---|
| trimesh | 118 |
| convex_decomposition, overlap 0 | 187 |
| convex_decomposition, overlap 0.9 | 367 |
- What it buys, a beam started inside the table, after four seconds:
| kind | result |
|---|---|
| trimesh, polyline, overlap 0 | still inside |
| convex_hull | out, with the gap under the table filled in |
| overlap 0.9 | out |
- A trimesh is the cheaper static collider when bodies only touch it from outside. This kind is for dynamic bodies, and for static ones a body can end up inside.
Also
- Mass comes from the ungrown pieces, so a table weighs what its area says.
- A solids-mode Godot
CollisionPolygon2Dimports as this kind. geometry2d.convex_decompositionhands the pieces to a script.- 3D keeps VHACD. Its hulls share no faces, so there is nothing to grow across. Overlapping hulls are authored by hand there, as several colliders on one body.
