Physics · function

combineMassProperties

Several shapes as one body: volumes added, centre of mass weighted, tensors moved and summed.

Explained in Your first game, Rigid bodies.

function combineMassProperties(parts: readonly ConvexShape[], density: number, out: MassProperties): MassProperties
import { combineMassProperties } from '@driftengine/physics';

Parameters

ParameterTypeDescription
partsreadonly ConvexShape[]
densitynumber
outMassProperties

In depth

What a compound body weighs, and it is the parallel axis theorem doing the work. Each part's tensor is about that part's own centre of mass; the body's is about the body's. Moving one costs m (|d|² δ - d ⊗ d) where d is the offset between the two centres, and skipping that term is not a small error — an L-beam released at rest would rotate, because its inertia would no longer match its shape.

Overlap is counted twice, and that is the decision rather than an oversight. A decomposition's hulls bulge slightly into each other, so the volumes here sum to a little more than the solid they stand for — measured at 27% against 16% occupied on a torus, and 5% against 2% on a cup. Removing it exactly means a boolean intersection of convex solids, which is a large body of code whose output corrects a number the caller invented when they chose a density. Decomposition.hullVolume reports the sum, so a caller who cares can divide it out.

The shapes are read twice: once for the centre and once for the tensor about it. That is a bake's cost paid at addBody, not a tick's.