Physics

Joints

Connecting bodies with the Joint constraint — ball-sockets, hinges, sliders, welds, and world anchors.

A Joint connects two bodies — or a body and the world — and removes degrees of freedom between them. One configurable constraint expresses the whole joint taxonomy: it has six independent degrees of freedom (3 linear, 3 angular), each of which can be locked, free, limited, sprung, or motorised. The named helpers below pick the right combination for you.

Anatomy

A joint holds an anchor frame on each body coincident according to its per-DOF rules:

  • entityA / entityB — the two bodies. Set entityB = JOINT_WORLD to anchor body A to a fixed point in the world instead of a second body.
  • localAnchorA / localAnchorB — the anchor point on each body, in that body’s local frame. When entityB === JOINT_WORLD, localAnchorB is a world coordinate.
  • localBasisA / localBasisB — the orientation of the joint’s reference frame on each body (unit quaternions, identity by default). The locked/free/limited axes are this frame’s axes — so for a hinge you orient the frame so its free axis is the hinge axis.

Register a joint with the PhysicsSystem once both bodies exist; remove it with unlink_joint:

import { Joint, JOINT_WORLD } from "@woosh/meep-engine/src/engine/physics/ecs/Joint.js";

const joint = new Joint();              // default: ball-socket
joint.entityA = linkA;
joint.entityB = linkB;
joint.localAnchorA.set(0, -0.3, 0);     // bottom of A
joint.localAnchorB.set(0,  0.3, 0);     // top of B
physics.link_joint(joint);

Joint types

Each helper configures the six DOFs and returns the joint, so you can chain. They’re the standard joints expressed as DOF patterns:

HelperDOFsUse for
asBallSocket() (default)3 linear locked, 3 angular freechains, ropes, pendulums
asHinge(axis)3 linear + 2 angular locked, 1 angular freedoors, wheels, elbows
asPrismatic(axis)2 linear + 3 angular locked, 1 linear freesliders, pistons, lifts
asWeld()all 6 lockedrigidly fuse two bodies
asConeTwist(twistLo, twistHi, swingY, swingZ?)3 linear locked, 3 angular limitedragdoll shoulders / hips

For hinges and sliders, orient localBasisA / localBasisB so the free frame axis is the one you want.

Anchoring to the world

entityB = JOINT_WORLD pins body A to a fixed world point. A pendulum is one ball-socket to the world:

const pivot = new Joint();
pivot.entityA = bob;
pivot.entityB = JOINT_WORLD;
pivot.localAnchorA.set(0, 1, 0);        // top of the bob, in its frame
pivot.localAnchorB.set(0, 5, 0);        // fixed world point to hang from
physics.link_joint(pivot);

Chains

Wire a column of bodies anchor-to-anchor — bottom of each link to the top of the next — and pin the first to the world, and you have a rope or chain. The solver runs extra iterations on joints (physics.jointIterations) so impulses propagate the length of the chain in a single tick. See the Jointed chains example, which hangs four of them and sweeps a kinematic log through.

Beyond locked DOFs

Locking and freeing DOFs covers the rigid joints above. The same Joint also gives each DOF a limit, spring, or motor — end-stops, suspension, powered hinges. Those live on the Constraints page.

Where to go next