Joints

A joint connects two bodies. It joins their sleep island, wakes both when it is created or tuned, and goes when either body is destroyed. Its two bodies do not collide with each other unless the def's enableConnectedCollision is set, which is what ragdolls expect.

The core joints

Motors and limits belong to the revolute, prismatic and wheel joints. m2Joint_SetMotorSpeed, m2Joint_SetMaxMotorEffort, m2Joint_EnableMotor, m2Joint_EnableLimit and m2Joint_SetLimits tune them at run time; on another type they change nothing and count one misuse. A motor's budget, maxMotorEffort in the def, is a torque on revolute and wheel joints and a force on prismatic joints. Angles are measured from the pose at creation.

The utility joints

Tuning and reading back

Every parameter of a def can be read back and most can be set at run time; each change is journaled. A joint's stiffness comes in two words. A spring (springHertz, springDampingRatio) pulls toward a rest pose: the distance spring, the wheel suspension, the revolute spring, the motor joint's drive and the mouse joint's drag, tuned by m2Joint_SetSpringHertz and m2Joint_SetSpringDampingRatio, with a weld's two springs under m2WeldJoint_. A constraint softness (constraintHertz, constraintDampingRatio) loosens the rows that hold a revolute, prismatic, gear, pulley or ratchet joint together, through m2Joint_SetConstraintHertz and m2Joint_SetConstraintDampingRatio; 0 hertz is the stiff default. m2Joint_EnableSpring turns the distance, wheel or revolute spring on and off, and m2Joint_EnableConnectedCollision lets a joint's bodies collide or keeps them apart. A call made for one type, such as m2DistanceJoint_SetLength on a weld, changes nothing and counts one misuse.

m2Joint_GetLinearSeparation and m2Joint_GetAngularSeparation say how far a joint is from what it holds right now, which shows a rig being pulled apart. A joint takes bodies more than M2_REACH_LIMIT (1e9 m) apart along an axis as that far apart: world positions are 64-bit and unbounded, but the solver works in 32-bit floats, and the clamp keeps it finite when a teleport sends one body to the far end of the world.

Breaking

m2Joint_SetBreakLimits sets the force and torque past which a joint breaks during a step. A broken joint is destroyed and reported in m2World_GetJointEvents with the load that broke it; two worlds given the same calls break the same joints on the same step.

m2Joint_GetReactionForce and m2Joint_GetReactionTorque report the load a joint carried on the last step. They are the numbers the break check compares, bit for bit, so a threshold tuned against a reading behaves exactly as read.