Maul2D API reference

Generated from the public headers, which are the source of truth: 291 functions across 8 headers.

base.h

The base of the Maul2D API: the library version, the export and attribute macros, the result codes every fallible function returns, the allocator, and hashing.

m2Version m2GetVersion(void);

Returns the version of the library that was linked, which may differ from the M2_VERSION macros a program was compiled with.

Returns: The library version.

Thread safety. Safe from any thread.

const char* m2GetResultName(m2Result result);

Returns the name of a result code, for diagnostics.

Parameters:

Returns: A static, NUL-terminated string such as "m2_errorCapacity".

Thread safety. Safe from any thread.

const char* m2GetSimdBackend(void);

Returns the SIMD backend the library was compiled for: "avx2", "neon" or "scalar". Every backend produces the same bits; this only reports which kernels the binary carries.

Returns: A static, NUL-terminated string.

Thread safety. Safe from any thread.

bool m2IsCpuBackendSupported(void);

Returns whether the CPU running the call supports the compiled backend. An "avx2" binary needs AVX2 and FMA3 with the wide registers enabled by the operating system; "neon" and "scalar" run on every CPU of their architecture. m2CreateWorld refuses a CPU without the backend with m2_errorUnsupported, so a program can call this first to choose another path, or build with -DMAUL2D_SIMD=scalar.

Returns: Whether the CPU can run this library.

Thread safety. Safe from any thread.

uint64_t m2Hash64(uint64_t seed, const void* data, int64_t byteCount);

The 64-bit hash every determinism check is built on: eight bytes a round, xored in, multiplied by an odd constant and folded, the leftover bytes one at a time (FNV-1a). Its constants are frozen.

Parameters:

Returns: The new running hash.

Thread safety. Safe from any thread.

body.h

Rigid bodies: creation and destruction, motion, forces and impulses, mass, sleep, and state readback.

m2BodyDef m2DefaultBodyDef(void);

Returns a body def: a static, enabled body at the origin with identity rotation, gravity scale 1, sleep allowed, everything else zero.

Returns: The default def.

Thread safety. Safe from any thread.

M2_NODISCARD M2_API m2Result m2CreateBody(m2World* world, const m2BodyDef* def, m2BodyId* bodyOut);

Creates a body. Journaled.

Parameters:

Returns: m2_success; m2_errorInvalid for a null argument, a def not from m2DefaultBodyDef, a NaN or a field outside its domain, and m2_errorLimit for a field past its published bound, each of which counts one misuse; m2_errorCapacity when the body pool is full; m2_errorBusy from host code the world is running.

Thread safety. Safe from any thread; a world is used by one thread at a time.

M2_NODISCARD M2_API m2Result m2DestroyBody(m2World* world, m2BodyId bodyId);

Destroys a body with its shapes, chains and joints; their contacts end and touching sleepers wake. The slot is reused in FIFO order under a new generation, and retires rather than let the generation wrap. Journaled.

Parameters:

Returns: m2_success; m2_errorInvalid for a null world; m2_errorStale when the body is already gone; m2_errorBusy from host code the world is running.

Thread safety. Safe from any thread; a world is used by one thread at a time.

bool m2Body_IsValid(const m2World* world, m2BodyId bodyId);

Tells whether a body id names a live body. Counts no misuse.

Parameters:

Returns: True for a live body.

Thread safety. Safe from any thread; a world is used by one thread at a time, or by several readers at once.

m2Transform m2Body_GetTransform(const m2World* world, m2BodyId bodyId);

Reads a body's pose.

Parameters:

Returns: The pose; the identity at the origin for a stale id.

Thread safety. Safe from any thread; a world is used by one thread at a time, or by several readers at once.

m2Pos2 m2Body_GetPosition(const m2World* world, m2BodyId bodyId);

Reads a body's origin in world space.

Parameters:

Returns: The position; the origin for a stale id.

Thread safety. Safe from any thread; a world is used by one thread at a time, or by several readers at once.

m2Rot m2Body_GetRotation(const m2World* world, m2BodyId bodyId);

Reads a body's rotation.

Parameters:

Returns: The rotation; the identity for a stale id.

Thread safety. Safe from any thread; a world is used by one thread at a time, or by several readers at once.

m2Vec2 m2Body_GetLinearVelocity(const m2World* world, m2BodyId bodyId);

Reads the velocity of a body's center of mass.

Parameters:

Returns: The velocity, m/s; zero for a stale id.

Thread safety. Safe from any thread; a world is used by one thread at a time, or by several readers at once.

float m2Body_GetAngularVelocity(const m2World* world, m2BodyId bodyId);

Reads a body's angular velocity.

Parameters:

Returns: The angular velocity, radians/s; 0 for a stale id.

Thread safety. Safe from any thread; a world is used by one thread at a time, or by several readers at once.

uint64_t m2Body_GetUserData(const m2World* world, m2BodyId bodyId);

Reads a body's game data.

Parameters:

Returns: The value; 0 for a stale id.

Thread safety. Safe from any thread; a world is used by one thread at a time, or by several readers at once.

bool m2Body_IsAwake(const m2World* world, m2BodyId bodyId);

Tells whether a body is awake. Setters and new contacts wake a body; waking spreads through its island at the next step.

Parameters:

Returns: True when awake, and always for a static or kinematic body; false for a stale id.

Thread safety. Safe from any thread; a world is used by one thread at a time, or by several readers at once.

void m2Body_SetAwake(m2World* world, m2BodyId bodyId, bool awake);

Wakes a body, or puts it to sleep at once with its velocities zeroed. Only an enabled dynamic body sleeps; for any other body the call changes nothing. A stale id counts one misuse. Journaled.

Parameters:

Thread safety. Safe from any thread; a world is used by one thread at a time.

void m2Body_EnableBullet(m2World* world, m2BodyId bodyId, bool flag);

Makes a body a bullet, which sweeps continuously against the shapes of non-bullets, or a plain body again. A stale id counts one misuse. Journaled.

Parameters:

Thread safety. Safe from any thread; a world is used by one thread at a time.

void m2Body_SetUserData(m2World* world, m2BodyId bodyId, uint64_t userData);

Sets a body's opaque game data, kept through snapshots and journals. A stale id counts one misuse. Journaled.

Parameters:

Thread safety. Safe from any thread; a world is used by one thread at a time.

void m2Body_SetDominance(m2World* world, m2BodyId bodyId, int8_t dominance);

Sets a body's contact dominance. In a pair, the higher side acts as unmovable toward the lower one, and statics outrank everything. Joints are unaffected. A stale id counts one misuse. Journaled.

Parameters:

Thread safety. Safe from any thread; a world is used by one thread at a time.

int8_t m2Body_GetDominance(const m2World* world, m2BodyId bodyId);

Reads a body's contact dominance.

Parameters:

Returns: The dominance; 0 for a stale id.

Thread safety. Safe from any thread; a world is used by one thread at a time, or by several readers at once.

M2_NODISCARD M2_API m2Result m2Body_SetTargetTransform(m2World* world, m2BodyId bodyId, m2Pos2 position, m2Rot rotation, float dt);

Sets the velocities that carry a body to a target pose in one step of the given length: the way to drive a kinematic body. It goes through the journaled velocity setters, so a replay repeats it. A refused call changes nothing.

Parameters:

Returns: m2_success; m2_errorInvalid for a null world, a static body, a position that is not finite, a rotation that is not unit length or a dt of 0 or below; m2_errorStale for a stale id; m2_errorLimit for a dt outside M2_MIN_STEP to M2_STEP_LIMIT, and for a pose too far from the body to reach within M2_SPEED_LIMIT, which counts no misuse, since where the body is is the world's state; m2_errorBusy from host code the world is running.

Thread safety. Safe from any thread; a world is used by one thread at a time.

m2BodyType m2Body_GetType(const m2World* world, m2BodyId bodyId);

Reads a body's type.

Parameters:

Returns: The type; m2_staticBody for a stale id.

Thread safety. Safe from any thread; a world is used by one thread at a time, or by several readers at once.

void m2Body_SetMassData(m2World* world, m2BodyId bodyId, m2MassData massData);

Overrides the mass a dynamic body's shapes give it. The override lasts until a shape change, a fixed-rotation change or m2Body_ApplyMassFromShapes recomputes the mass. The body wakes. A stale id, a body that is not dynamic, a mass outside M2_MIN_MASS to M2_MASS_LIMIT, a center beyond M2_LOCAL_LIMIT, or a central inertia that is neither 0 nor within M2_MIN_INERTIA to M2_INERTIA_LIMIT, changes nothing and counts one misuse. Every override this accepts survives a snapshot. A central inertia of 0 leaves the body unable to turn. Mass computed from shapes is clamped into the same ranges. Journaled.

Parameters:

Thread safety. Safe from any thread; a world is used by one thread at a time.

m2MassData m2Body_GetMassData(const m2World* world, m2BodyId bodyId);

Reads a body's mass properties.

Parameters:

Returns: The mass, centroid and inertia about the centroid; zeroed for a stale id.

Thread safety. Safe from any thread; a world is used by one thread at a time, or by several readers at once.

void m2Body_ApplyMassFromShapes(m2World* world, m2BodyId bodyId);

Recomputes a body's mass from its shapes, dropping an override. A dynamic body wakes. A stale id counts one misuse. Journaled.

Parameters:

Thread safety. Safe from any thread; a world is used by one thread at a time.

void m2Body_Enable(m2World* world, m2BodyId bodyId, bool flag);

Takes a body out of the simulation without destroying it, or puts it back where it was. A disabled body's shapes leave the broadphase (contacts end, riders wake), its joints stay attached but inert, and queries stop seeing it. Setting the state a body already has changes nothing and records nothing. A stale id counts one misuse. Journaled.

Parameters:

Thread safety. Safe from any thread; a world is used by one thread at a time.

bool m2Body_IsEnabled(const m2World* world, m2BodyId bodyId);

Tells whether a body takes part in the simulation.

Parameters:

Returns: True when enabled; false for a stale id.

Thread safety. Safe from any thread; a world is used by one thread at a time, or by several readers at once.

m2Vec2 m2Body_GetLocalCenter(const m2World* world, m2BodyId bodyId);

Reads a body's center of mass in its own frame.

Parameters:

Returns: The body-local center; zero for a stale id.

Thread safety. Safe from any thread; a world is used by one thread at a time, or by several readers at once.

bool m2Body_IsBulletEnabled(const m2World* world, m2BodyId bodyId);

Tells whether a body is a bullet.

Parameters:

Returns: True for a bullet; false for a stale id.

Thread safety. Safe from any thread; a world is used by one thread at a time, or by several readers at once.

float m2Body_GetGravityScale(const m2World* world, m2BodyId bodyId);

Reads a body's gravity scale.

Parameters:

Returns: The scale; 0 for a stale id.

Thread safety. Safe from any thread; a world is used by one thread at a time, or by several readers at once.

int32_t m2World_GetBodies(const m2World* world, m2BodyId* idsOut, int32_t capacity);

Lists the world's bodies in ascending slot order.

Parameters:

Returns: The number of bodies, which may exceed capacity.

Thread safety. Safe from any thread; a world is used by one thread at a time, or by several readers at once.

m2Pos2 m2Body_GetWorldPoint(const m2World* world, m2BodyId bodyId, m2Vec2 localPoint);

Maps a point from a body's frame to world space.

Parameters:

Returns: The world point; the origin for a stale id.

Thread safety. Safe from any thread; a world is used by one thread at a time, or by several readers at once.

m2Vec2 m2Body_GetLocalPoint(const m2World* world, m2BodyId bodyId, m2Pos2 worldPoint);

Maps a world point to a body's frame.

Parameters:

Returns: The point in the body's frame; zero for a stale id.

Thread safety. Safe from any thread; a world is used by one thread at a time, or by several readers at once.

m2Vec2 m2Body_GetWorldVector(const m2World* world, m2BodyId bodyId, m2Vec2 localVector);

Rotates a vector from a body's frame to the world frame.

Parameters:

Returns: The world vector; zero for a stale id.

Thread safety. Safe from any thread; a world is used by one thread at a time, or by several readers at once.

m2Vec2 m2Body_GetLocalVector(const m2World* world, m2BodyId bodyId, m2Vec2 worldVector);

Rotates a world vector into a body's frame.

Parameters:

Returns: The vector in the body's frame; zero for a stale id.

Thread safety. Safe from any thread; a world is used by one thread at a time, or by several readers at once.

m2Vec2 m2Body_GetWorldPointVelocity(const m2World* world, m2BodyId bodyId, m2Pos2 worldPoint);

Reads the world velocity of the body point at a world position.

Parameters:

Returns: Its velocity; zero for a stale id.

Thread safety. Safe from any thread; a world is used by one thread at a time, or by several readers at once.

m2Vec2 m2Body_GetLocalPointVelocity(const m2World* world, m2BodyId bodyId, m2Vec2 localPoint);

Reads the world velocity of the body point at a body-local position.

Parameters:

Returns: Its velocity; zero for a stale id.

Thread safety. Safe from any thread; a world is used by one thread at a time, or by several readers at once.

m2Pos2 m2Body_GetWorldCenterOfMass(const m2World* world, m2BodyId bodyId);

Reads a body's center of mass in world space.

Parameters:

Returns: The world center; the origin for a stale id.

Thread safety. Safe from any thread; a world is used by one thread at a time, or by several readers at once.

float m2Body_GetMass(const m2World* world, m2BodyId bodyId);

Reads a body's mass: m2MassData.mass.

Parameters:

Returns: The mass, kg; 0 for a body that is not dynamic or a stale id.

Thread safety. Safe from any thread; a world is used by one thread at a time, or by several readers at once.

float m2Body_GetCentralInertia(const m2World* world, m2BodyId bodyId);

Reads a body's rotational inertia about its center of mass: m2MassData.centralInertia.

Parameters:

Returns: The inertia, kg m^2; 0 for a stale id.

Thread safety. Safe from any thread; a world is used by one thread at a time, or by several readers at once.

m2WorldAabb m2Body_ComputeAabb(const m2World* world, m2BodyId bodyId);

Computes the tight box around every shape of a body, without the broadphase margins.

Parameters:

Returns: The box; a point at the body origin for a body without shapes; zeroed for a stale id.

Thread safety. Safe from any thread; a world is used by one thread at a time, or by several readers at once.

void m2Body_SetLinearVelocity(m2World* world, m2BodyId bodyId, m2Vec2 velocity);

Sets the velocity of a body's center of mass and wakes it. A stale id, a static body or a velocity beyond M2_SPEED_LIMIT on either axis changes nothing and counts one misuse: a static body never moves. Journaled.

Parameters:

Thread safety. Safe from any thread; a world is used by one thread at a time.

void m2Body_SetAngularVelocity(m2World* world, m2BodyId bodyId, float velocity);

Sets a body's angular velocity and wakes it, as m2Body_SetLinearVelocity does.

Parameters:

Thread safety. Safe from any thread; a world is used by one thread at a time.

void m2Body_SetTransform(m2World* world, m2BodyId bodyId, m2Pos2 position, m2Rot rotation);

Teleports a body: position and rotation snap, velocities stay, the broadphase refreshes at once, and the body and everything it touched wake. A teleport is not a sweep: nothing keeps it from tunneling. A stale id, a non-finite position or a rotation that is not unit length changes nothing and counts one misuse. Journaled.

Parameters:

Thread safety. Safe from any thread; a world is used by one thread at a time.

void m2Body_SetType(m2World* world, m2BodyId bodyId, m2BodyType type);

Changes a body's type in place. Becoming static zeroes the velocities; becoming dynamic recomputes the mass from the shapes. The body and everything it touches wake, its shapes move to the tree of the new type, and pairs that no longer apply end with end events. A stale id or an unknown type counts one misuse. Journaled.

Parameters:

Thread safety. Safe from any thread; a world is used by one thread at a time.

void m2Body_ApplyLinearImpulseAtPoint(m2World* world, m2BodyId bodyId, m2Vec2 impulse, m2Pos2 worldPoint);

Applies an impulse at a world point, changing the velocity at once; the lever arm is measured from the center of mass, each axis clamped to M2_REACH_LIMIT. The body wakes, and its velocity saturates at M2_SPEED_LIMIT per axis. A stale id, a body that is not dynamic, a non-finite point or an impulse beyond M2_IMPULSE_LIMIT on either axis changes nothing and counts one misuse. Journaled.

Parameters:

Thread safety. Safe from any thread; a world is used by one thread at a time.

void m2Body_ApplyLinearImpulse(m2World* world, m2BodyId bodyId, m2Vec2 impulse);

Applies an impulse at the center of mass, as m2Body_ApplyLinearImpulseAtPoint does.

Parameters:

Thread safety. Safe from any thread; a world is used by one thread at a time.

void m2Body_ApplyForceAtPoint(m2World* world, m2BodyId bodyId, m2Vec2 force, m2Pos2 worldPoint);

Adds a force at a world point for the next step. Forces accumulate across calls, saturating at M2_FORCE_LIMIT per axis (and torque), act during the step and clear when it ends. The lever arm is clamped as m2Body_ApplyLinearImpulseAtPoint clamps it. The body wakes. A stale id, a body that is not dynamic, a non-finite point or a force beyond M2_FORCE_LIMIT on either axis changes nothing and counts one misuse. Journaled.

Parameters:

Thread safety. Safe from any thread; a world is used by one thread at a time.

void m2Body_ApplyForce(m2World* world, m2BodyId bodyId, m2Vec2 force);

Adds a force at the center of mass for the next step, as m2Body_ApplyForceAtPoint does.

Parameters:

Thread safety. Safe from any thread; a world is used by one thread at a time.

void m2Body_ApplyTorque(m2World* world, m2BodyId bodyId, float torque);

Adds a torque for the next step, as m2Body_ApplyForceAtPoint does.

Parameters:

Thread safety. Safe from any thread; a world is used by one thread at a time.

void m2Body_SetLinearDamping(m2World* world, m2BodyId bodyId, float damping);

Sets a body's linear damping. A stale id or a value outside 0 to M2_RATE_LIMIT changes nothing and counts one misuse. Journaled.

Parameters:

Thread safety. Safe from any thread; a world is used by one thread at a time.

float m2Body_GetLinearDamping(const m2World* world, m2BodyId bodyId);

Reads a body's linear damping.

Parameters:

Returns: The damping; 0 for a stale id.

Thread safety. Safe from any thread; a world is used by one thread at a time, or by several readers at once.

void m2Body_SetAngularDamping(m2World* world, m2BodyId bodyId, float damping);

Sets a body's angular damping, as m2Body_SetLinearDamping does.

Parameters:

Thread safety. Safe from any thread; a world is used by one thread at a time.

float m2Body_GetAngularDamping(const m2World* world, m2BodyId bodyId);

Reads a body's angular damping.

Parameters:

Returns: The damping; 0 for a stale id.

Thread safety. Safe from any thread; a world is used by one thread at a time, or by several readers at once.

void m2Body_SetGravityScale(m2World* world, m2BodyId bodyId, float scale);

Sets how strongly gravity pulls a body. A stale id or a scale beyond M2_GRAVITY_SCALE_LIMIT changes nothing and counts one misuse. Journaled.

Parameters:

Thread safety. Safe from any thread; a world is used by one thread at a time.

void m2Body_SetMotionLocks(m2World* world, m2BodyId bodyId, m2MotionLocks locks);

Sets a body's motion locks. Locking an axis zeroes its velocity, and changing angularZ recomputes the inertia. The body wakes. A stale id counts one misuse. Journaled.

Parameters:

Thread safety. Safe from any thread; a world is used by one thread at a time.

m2MotionLocks m2Body_GetMotionLocks(const m2World* world, m2BodyId bodyId);

Reads a body's motion locks.

Parameters:

Returns: The locks; all false for a stale id.

Thread safety. Safe from any thread; a world is used by one thread at a time, or by several readers at once.

void m2Body_EnableSleep(m2World* world, m2BodyId bodyId, bool flag);

Allows or forbids a body to sleep; forbidding wakes it. A stale id counts one misuse. Journaled.

Parameters:

Thread safety. Safe from any thread; a world is used by one thread at a time.

bool m2Body_IsSleepEnabled(const m2World* world, m2BodyId bodyId);

Tells whether a body may sleep.

Parameters:

Returns: True when it may; false for a stale id.

Thread safety. Safe from any thread; a world is used by one thread at a time, or by several readers at once.

void m2Body_SetSleepThreshold(m2World* world, m2BodyId bodyId, float threshold);

Sets the speed below which a body counts as resting. A body rests while its speed is below the threshold t and its spin below 0.12 rad/s times t / 0.05; resting for half a second with the rest of its island, it falls asleep. 0 gives the default, 0.05 m/s and so 0.12 rad/s. A kinematic body below its threshold does not wake what it touches. The change applies from the next step: a sleeping body stays asleep. A stale id, or a threshold outside 0 to M2_SPEED_LIMIT, changes nothing and counts one misuse. Journaled.

Parameters:

Thread safety. Safe from any thread; a world is used by one thread at a time.

float m2Body_GetSleepThreshold(const m2World* world, m2BodyId bodyId);

Reads the speed below which a body counts as resting.

Parameters:

Returns: The threshold, m/s: 0.05 for a body given the default; 0 for a stale id.

Thread safety. Safe from any thread; a world is used by one thread at a time, or by several readers at once.

void m2Body_ApplyAngularImpulse(m2World* world, m2BodyId bodyId, float impulse);

Applies an angular impulse, changing the angular velocity at once. The body wakes, and its spin saturates at M2_SPEED_LIMIT. A stale id, a body that is not dynamic or an impulse beyond M2_IMPULSE_LIMIT changes nothing and counts one misuse. Journaled.

Parameters:

Thread safety. Safe from any thread; a world is used by one thread at a time.

core_math.h

Deterministic 2D math: vectors, rotations, transforms and the engine's own trigonometry. Positions are 64-bit, everything local is 32-bit, and every operation is plain IEEE arithmetic so the bits agree on every platform.

m2Rot m2MakeRot(float radians);

Builds a rotation from an angle without calling the C library, so the bits agree everywhere. Accurate to about 4e-7.

Parameters:

Returns: A unit rotation.

Thread safety. Safe from any thread.

float m2Atan2(float y, float x);

The engine's atan2, accurate to about 3e-7, with the same bits everywhere.

Parameters:

Returns: The angle in [-pi, pi]; 0 for (0, 0) instead of NaN.

Thread safety. Safe from any thread.

m2Rot m2NormalizeRot(m2Rot q);

Renormalizes a rotation. Every composition of rotations renormalizes at once: bounded drift is part of the determinism contract.

Parameters:

Returns: The unit rotation in q's direction, for any finite nonzero q however long or short; the identity when q is zero or not finite, never NaN.

Thread safety. Safe from any thread.

m2Rot m2MulRot(m2Rot q, m2Rot r);

Composes two rotations, q followed by r, and renormalizes.

Parameters:

Returns: The unit rotation of both.

Thread safety. Safe from any thread.

bool m2IsNormalizedRot(m2Rot q);

Tells whether a rotation is unit length within the engine's tolerance.

Parameters:

Returns: True when q is unit length.

Thread safety. Safe from any thread.

events.h

Event streams: contact begin and end, sensor overlaps and joint breaks, collected during a step and read after it.

m2ContactEvents m2World_GetContactEvents(const m2World* world);

Returns the contact events of the last step. Events are polled, never called back. After a rollback, the steps simulated again emit their events again; a host that must see each once keys them by step and shape ids.

Parameters:

Returns: Arrays the world owns, in canonical order, valid until the next m2World_Step or m2World_Restore of this world; a restore clears them. Empty for a null world.

Thread safety. Safe from any thread; a world is used by one thread at a time, or by several readers at once.

m2SensorEvents m2World_GetSensorEvents(const m2World* world);

Returns the sensor events of the last step. A destroyed or filtered overlap always emits its end.

Parameters:

Returns: Arrays the world owns, in canonical order, valid until the next m2World_Step or m2World_Restore of this world. Empty for a null world.

Thread safety. Safe from any thread; a world is used by one thread at a time, or by several readers at once.

m2JointEvents m2World_GetJointEvents(const m2World* world);

Returns the joints that broke during the last step.

Parameters:

Returns: An array the world owns, in ascending joint order, valid until the next m2World_Step or m2World_Restore of this world. Empty for a null world.

Thread safety. Safe from any thread; a world is used by one thread at a time, or by several readers at once.

int32_t m2Shape_GetSensorOverlaps(const m2World* world, m2ShapeId sensorShapeId, m2ShapeId* overlapsOut, int32_t capacity);

Lists the shapes inside a sensor now, in canonical pair order.

Parameters:

Returns: The number of shapes inside, which may exceed capacity.

Thread safety. Safe from any thread; a world is used by one thread at a time, or by several readers at once.

int32_t m2World_GetContactData(const m2World* world, m2ContactData* dataOut, int32_t capacity);

Lists the solid contacts touching now, in canonical pair order. Sensor overlaps are not contacts and are left out.

Parameters:

Returns: The number of touching contacts, which may exceed capacity.

Thread safety. Safe from any thread; a world is used by one thread at a time, or by several readers at once.

joint.h

Joints: the eleven joint types, their defs, motors, limits, springs, runtime tuning and breaking. Every joint call on a stale id changes nothing, returns zero and counts one misuse. A call made for one joint type (a motor joint's offsets, a distance joint's length) does the same on a joint of another type. Motors and limits belong to the revolute, prismatic and wheel joints; m2Joint_SetMaxMotorEffort also sets a motor joint's torque budget, as m2MotorJoint_SetMaxTorque does. Every setter is journaled, and one that changes how a joint pulls wakes the bodies it moves.

m2DistanceJointDef m2DefaultDistanceJointDef(void);

Returns a distance joint def: zero anchors, the length taken at creation, no range, the stiff default, no collision between the bodies.

Returns: The default def; set both bodies.

Thread safety. Safe from any thread.

m2RevoluteJointDef m2DefaultRevoluteJointDef(void);

Returns a revolute joint def: zero anchors, no spring, motor or limit.

Returns: The default def; set both bodies.

Thread safety. Safe from any thread.

m2PrismaticJointDef m2DefaultPrismaticJointDef(void);

Returns a prismatic joint def: zero anchors, the x axis, no motor or limit.

Returns: The default def; set both bodies.

Thread safety. Safe from any thread.

m2WeldJointDef m2DefaultWeldJointDef(void);

Returns a weld joint def: zero anchors, both rows rigid.

Returns: The default def; set both bodies.

Thread safety. Safe from any thread.

m2WheelJointDef m2DefaultWheelJointDef(void);

Returns a wheel joint def: zero anchors, the y axis, a 2 Hz suspension at damping ratio 0.7, no motor or limit.

Returns: The default def; set both bodies.

Thread safety. Safe from any thread.

m2FilterJointDef m2DefaultFilterJointDef(void);

Returns a filter joint def.

Returns: The default def; set both bodies.

Thread safety. Safe from any thread.

m2GearJointDef m2DefaultGearJointDef(void);

Returns a gear joint def with ratio 1.

Returns: The default def; set both bodies.

Thread safety. Safe from any thread.

m2PulleyJointDef m2DefaultPulleyJointDef(void);

Returns a pulley joint def with ratio 1 and every anchor at the origin.

Returns: The default def; set both bodies and both ground anchors.

Thread safety. Safe from any thread.

m2RatchetJointDef m2DefaultRatchetJointDef(void);

Returns a ratchet joint def with a 0.5 radian tooth.

Returns: The default def; set both bodies.

Thread safety. Safe from any thread.

m2MotorJointDef m2DefaultMotorJointDef(void);

Returns a motor joint def: zero offsets, a 1 N force and 1 N m torque budget, correction factor 0.3, the hard servo.

Returns: The default def; set both bodies.

Thread safety. Safe from any thread.

m2MouseJointDef m2DefaultMouseJointDef(void);

Returns a mouse joint def: a 4 Hz spring at damping ratio 1 with a 35 N budget, the target at the origin.

Returns: The default def; set both bodies and the target.

Thread safety. Safe from any thread.

M2_NODISCARD M2_API m2Result m2CreateDistanceJoint(m2World* world, const m2DistanceJointDef* def, m2JointId* jointOut);

Creates a distance joint. A joint joins its bodies' sleep island, so they sleep and wake together, and both wake now. Destroying either body destroys the joint. Journaled. Every joint def's local anchors, axis and linear offset lie within M2_LOCAL_LIMIT.

Parameters:

Returns: m2_success; m2_errorStale when either body is stale; m2_errorInvalid for a bad def, the same body twice or a null argument; m2_errorLimit for a value of the def past its published bound; m2_errorCapacity when the joint pool is full; m2_errorBusy from host code the world is running.

Thread safety. Safe from any thread; a world is used by one thread at a time.

M2_NODISCARD M2_API m2Result m2CreateRevoluteJoint(m2World* world, const m2RevoluteJointDef* def, m2JointId* jointOut);

Creates a revolute joint, as m2CreateDistanceJoint does.

Parameters:

Returns: As m2CreateDistanceJoint.

Thread safety. Safe from any thread; a world is used by one thread at a time.

M2_NODISCARD M2_API m2Result m2CreatePrismaticJoint(m2World* world, const m2PrismaticJointDef* def, m2JointId* jointOut);

Creates a prismatic joint, as m2CreateDistanceJoint does.

Parameters:

Returns: As m2CreateDistanceJoint.

Thread safety. Safe from any thread; a world is used by one thread at a time.

M2_NODISCARD M2_API m2Result m2CreateWeldJoint(m2World* world, const m2WeldJointDef* def, m2JointId* jointOut);

Creates a weld joint, as m2CreateDistanceJoint does.

Parameters:

Returns: As m2CreateDistanceJoint.

Thread safety. Safe from any thread; a world is used by one thread at a time.

M2_NODISCARD M2_API m2Result m2CreateWheelJoint(m2World* world, const m2WheelJointDef* def, m2JointId* jointOut);

Creates a wheel joint, as m2CreateDistanceJoint does.

Parameters:

Returns: As m2CreateDistanceJoint.

Thread safety. Safe from any thread; a world is used by one thread at a time.

M2_NODISCARD M2_API m2Result m2CreateFilterJoint(m2World* world, const m2FilterJointDef* def, m2JointId* jointOut);

Creates a filter joint, as m2CreateDistanceJoint does. Destroying it switches collision back on, with the usual events.

Parameters:

Returns: As m2CreateDistanceJoint.

Thread safety. Safe from any thread; a world is used by one thread at a time.

M2_NODISCARD M2_API m2Result m2CreateGearJoint(m2World* world, const m2GearJointDef* def, m2JointId* jointOut);

Creates a gear joint, as m2CreateDistanceJoint does.

Parameters:

Returns: As m2CreateDistanceJoint.

Thread safety. Safe from any thread; a world is used by one thread at a time.

M2_NODISCARD M2_API m2Result m2CreatePulleyJoint(m2World* world, const m2PulleyJointDef* def, m2JointId* jointOut);

Creates a pulley joint, as m2CreateDistanceJoint does.

Parameters:

Returns: As m2CreateDistanceJoint.

Thread safety. Safe from any thread; a world is used by one thread at a time.

M2_NODISCARD M2_API m2Result m2CreateRatchetJoint(m2World* world, const m2RatchetJointDef* def, m2JointId* jointOut);

Creates a ratchet joint, as m2CreateDistanceJoint does.

Parameters:

Returns: As m2CreateDistanceJoint.

Thread safety. Safe from any thread; a world is used by one thread at a time.

M2_NODISCARD M2_API m2Result m2CreateMotorJoint(m2World* world, const m2MotorJointDef* def, m2JointId* jointOut);

Creates a motor joint, as m2CreateDistanceJoint does.

Parameters:

Returns: As m2CreateDistanceJoint.

Thread safety. Safe from any thread; a world is used by one thread at a time.

M2_NODISCARD M2_API m2Result m2CreateMouseJoint(m2World* world, const m2MouseJointDef* def, m2JointId* jointOut);

Creates a mouse joint, as m2CreateDistanceJoint does. The grab point, body B's anchor, is where the target lies in B's frame at creation, so it lies within M2_LOCAL_LIMIT like any other anchor.

Parameters:

Returns: As m2CreateDistanceJoint, and m2_errorLimit for a target past M2_LOCAL_LIMIT from B in B's frame, which counts no misuse, since where B is is the world's state.

Thread safety. Safe from any thread; a world is used by one thread at a time.

M2_NODISCARD M2_API m2Result m2DestroyJoint(m2World* world, m2JointId jointId);

Destroys a joint and wakes its bodies. Journaled.

Parameters:

Returns: m2_success; m2_errorInvalid for a null world; m2_errorStale when it is already gone; m2_errorBusy from host code the world is running.

Thread safety. Safe from any thread; a world is used by one thread at a time.

void m2Joint_SetMotorSpeed(m2World* world, m2JointId jointId, float speed);

Sets a motor's speed: rad/s on revolute and wheel joints, m/s on a prismatic joint. A speed beyond M2_SPEED_LIMIT or another joint type counts one misuse.

Parameters:

Thread safety. Safe from any thread; a world is used by one thread at a time.

void m2Joint_SetMaxMotorEffort(m2World* world, m2JointId jointId, float maxEffort);

Sets a motor's budget: a torque on revolute and wheel joints and on a motor joint, a force on a prismatic joint. A budget outside 0 to M2_FORCE_LIMIT or another joint type counts one misuse.

Parameters:

Thread safety. Safe from any thread; a world is used by one thread at a time.

void m2Joint_EnableMotor(m2World* world, m2JointId jointId, bool enable);

Turns a motor on or off. Another joint type counts one misuse.

Parameters:

Thread safety. Safe from any thread; a world is used by one thread at a time.

void m2Joint_EnableLimit(m2World* world, m2JointId jointId, bool enable);

Turns the limits on or off. Another joint type counts one misuse.

Parameters:

Thread safety. Safe from any thread; a world is used by one thread at a time.

void m2Joint_SetLimits(m2World* world, m2JointId jointId, float lower, float upper);

Sets the limits: angles in radians on a revolute joint, travel in meters on prismatic and wheel joints, both from the creation pose. An inverted range, an angle beyond M2_ANGLE_LIMIT, a travel beyond M2_REACH_LIMIT or another joint type changes nothing, on either bound, and counts one misuse.

Parameters:

Thread safety. Safe from any thread; a world is used by one thread at a time.

void m2Joint_SetBreakLimits(m2World* world, m2JointId jointId, float maxForce, float maxTorque);

Sets the loads past which a joint breaks during a step. A broken joint is destroyed and reported by m2World_GetJointEvents. A negative or NaN threshold changes nothing and counts one misuse.

Parameters:

Thread safety. Safe from any thread; a world is used by one thread at a time.

void m2Joint_SetConstraintHertz(m2World* world, m2JointId jointId, float hertz);

Sets the softness of the rows that hold a joint together: a revolute joint's pin, a prismatic joint's slide, the tie of a gear, pulley or ratchet joint. Another joint type, or a value out of its range, counts one misuse. Journaled.

Parameters:

Thread safety. Safe from any thread; a world is used by one thread at a time.

void m2Joint_SetConstraintDampingRatio(m2World* world, m2JointId jointId, float dampingRatio);

Sets the damping ratio of the rows m2Joint_SetConstraintHertz softens. Another joint type, or a value out of its range, counts one misuse. Journaled.

Parameters:

Thread safety. Safe from any thread; a world is used by one thread at a time.

void m2Joint_SetSpringHertz(m2World* world, m2JointId jointId, float hertz);

Sets a joint's spring frequency: a distance joint's spring, a wheel's suspension, a revolute joint's angular spring, a motor joint's drive, a mouse joint's drag. A distance, wheel or revolute spring acts only while it is enabled (m2Joint_EnableSpring). Another joint type, or a value out of its range, counts one misuse. Journaled.

Parameters:

Thread safety. Safe from any thread; a world is used by one thread at a time.

void m2Joint_SetSpringDampingRatio(m2World* world, m2JointId jointId, float dampingRatio);

Sets the damping ratio of the spring m2Joint_SetSpringHertz tunes. Another joint type, or a value out of its range, counts one misuse. Journaled.

Parameters:

Thread safety. Safe from any thread; a world is used by one thread at a time.

void m2WeldJoint_SetLinearSpringHertz(m2World* world, m2JointId jointId, float hertz);

Softens a weld joint's linear rows into a spring. Another joint type, or a value out of its range, counts one misuse. Journaled.

Parameters:

Thread safety. Safe from any thread; a world is used by one thread at a time.

void m2WeldJoint_SetLinearSpringDampingRatio(m2World* world, m2JointId jointId, float dampingRatio);

Sets the damping ratio of a weld joint's linear spring. Another joint type, or a value out of its range, counts one misuse. Journaled.

Parameters:

Thread safety. Safe from any thread; a world is used by one thread at a time.

void m2WeldJoint_SetAngularSpringHertz(m2World* world, m2JointId jointId, float hertz);

Softens a weld joint's angular row into a spring. Another joint type, or a value out of its range, counts one misuse. Journaled.

Parameters:

Thread safety. Safe from any thread; a world is used by one thread at a time.

void m2WeldJoint_SetAngularSpringDampingRatio(m2World* world, m2JointId jointId, float dampingRatio);

Sets the damping ratio of a weld joint's angular spring. Another joint type, or a value out of its range, counts one misuse. Journaled.

Parameters:

Thread safety. Safe from any thread; a world is used by one thread at a time.

void m2DistanceJoint_SetLength(m2World* world, m2JointId jointId, float length);

Sets a distance joint's rest length and drops its stored impulses. Another joint type, or a length that is not positive or is beyond M2_REACH_LIMIT, counts one misuse.

Parameters:

Thread safety. Safe from any thread; a world is used by one thread at a time.

void m2DistanceJoint_SetLengthRange(m2World* world, m2JointId jointId, float minLength, float maxLength);

Sets a distance joint's hard length range. Each bound is raised to the linear slop (0.005 m) and the two are put in order. Another joint type or a bound beyond M2_REACH_LIMIT counts one misuse. Read the range with m2DistanceJoint_GetLengthRange.

Parameters:

Thread safety. Safe from any thread; a world is used by one thread at a time.

float m2DistanceJoint_GetLength(const m2World* world, m2JointId jointId);

Reads a distance joint's rest length.

Parameters:

Returns: The length, meters; 0 for another joint type or a stale id.

Thread safety. Safe from any thread; a world is used by one thread at a time, or by several readers at once.

void m2DistanceJoint_GetLengthRange(const m2World* world, m2JointId jointId, float* minLengthOut, float* maxLengthOut);

Reads the length range m2DistanceJoint_SetLengthRange sets.

Parameters:

Thread safety. Safe from any thread; a world is used by one thread at a time, or by several readers at once.

float m2Joint_GetReactionForce(const m2World* world, m2JointId jointId);

Reads the force a joint carried on the last step: its stored impulses over that step's substep length. The break pass compares the same number with the break limits, bit for bit, so a threshold tuned against this reading behaves exactly as read.

Parameters:

Returns: The force, N; 0 before the first step and for a stale id.

Thread safety. Safe from any thread; a world is used by one thread at a time, or by several readers at once.

float m2Joint_GetReactionTorque(const m2World* world, m2JointId jointId);

Reads the torque a joint carried on the last step, as m2Joint_GetReactionForce does.

Parameters:

Returns: The torque, N m; 0 before the first step and for a stale id.

Thread safety. Safe from any thread; a world is used by one thread at a time, or by several readers at once.

bool m2Joint_IsValid(const m2World* world, m2JointId jointId);

Tells whether a joint id names a live joint. Counts no misuse.

Parameters:

Returns: True for a live joint.

Thread safety. Safe from any thread; a world is used by one thread at a time, or by several readers at once.

m2JointType m2Joint_GetType(const m2World* world, m2JointId jointId);

Reads a joint's type.

Parameters:

Returns: The type; m2_distanceJoint for a stale id.

Thread safety. Safe from any thread; a world is used by one thread at a time, or by several readers at once.

m2Vec2 m2Joint_GetLocalAnchorA(const m2World* world, m2JointId jointId);

Reads a joint's anchor on body A, in A's frame.

Parameters:

Returns: The anchor; zero for a stale id.

Thread safety. Safe from any thread; a world is used by one thread at a time, or by several readers at once.

m2Vec2 m2Joint_GetLocalAnchorB(const m2World* world, m2JointId jointId);

Reads a joint's anchor on body B, in B's frame.

Parameters:

Returns: The anchor; zero for a stale id.

Thread safety. Safe from any thread; a world is used by one thread at a time, or by several readers at once.

m2Vec2 m2Joint_GetLocalAxisA(const m2World* world, m2JointId jointId);

Reads the axis of a prismatic or wheel joint, in body A's frame.

Parameters:

Returns: The unit axis; zero for another joint type or a stale id, which count one misuse.

Thread safety. Safe from any thread; a world is used by one thread at a time, or by several readers at once.

float m2Joint_GetConstraintHertz(const m2World* world, m2JointId jointId);

Reads the frequency m2Joint_SetConstraintHertz sets.

Parameters:

Returns: The frequency; 0 for another joint type or a stale id, which count one misuse.

Thread safety. Safe from any thread; a world is used by one thread at a time, or by several readers at once.

float m2Joint_GetConstraintDampingRatio(const m2World* world, m2JointId jointId);

Reads the damping ratio m2Joint_SetConstraintDampingRatio sets.

Parameters:

Returns: The ratio; 0 for another joint type or a stale id, which count one misuse.

Thread safety. Safe from any thread; a world is used by one thread at a time, or by several readers at once.

float m2Joint_GetSpringHertz(const m2World* world, m2JointId jointId);

Reads the frequency m2Joint_SetSpringHertz sets.

Parameters:

Returns: The frequency; 0 for another joint type or a stale id, which count one misuse.

Thread safety. Safe from any thread; a world is used by one thread at a time, or by several readers at once.

float m2Joint_GetSpringDampingRatio(const m2World* world, m2JointId jointId);

Reads the damping ratio m2Joint_SetSpringDampingRatio sets.

Parameters:

Returns: The ratio; 0 for another joint type or a stale id, which count one misuse.

Thread safety. Safe from any thread; a world is used by one thread at a time, or by several readers at once.

float m2WeldJoint_GetLinearSpringHertz(const m2World* world, m2JointId jointId);

Reads a weld joint's linear spring frequency.

Parameters:

Returns: The frequency; 0 for another joint type or a stale id, which count one misuse.

Thread safety. Safe from any thread; a world is used by one thread at a time, or by several readers at once.

float m2WeldJoint_GetLinearSpringDampingRatio(const m2World* world, m2JointId jointId);

Reads a weld joint's linear spring damping ratio.

Parameters:

Returns: The ratio; 0 for another joint type or a stale id, which count one misuse.

Thread safety. Safe from any thread; a world is used by one thread at a time, or by several readers at once.

float m2WeldJoint_GetAngularSpringHertz(const m2World* world, m2JointId jointId);

Reads a weld joint's angular spring frequency.

Parameters:

Returns: The frequency; 0 for another joint type or a stale id, which count one misuse.

Thread safety. Safe from any thread; a world is used by one thread at a time, or by several readers at once.

float m2WeldJoint_GetAngularSpringDampingRatio(const m2World* world, m2JointId jointId);

Reads a weld joint's angular spring damping ratio.

Parameters:

Returns: The ratio; 0 for another joint type or a stale id, which count one misuse.

Thread safety. Safe from any thread; a world is used by one thread at a time, or by several readers at once.

float m2Joint_GetMotorSpeed(const m2World* world, m2JointId jointId);

Reads a motor's target speed.

Parameters:

Returns: The speed; 0 for another joint type or a stale id.

Thread safety. Safe from any thread; a world is used by one thread at a time, or by several readers at once.

float m2Joint_GetMaxMotorEffort(const m2World* world, m2JointId jointId);

Reads a motor's budget.

Parameters:

Returns: The torque or force; 0 for another joint type or a stale id.

Thread safety. Safe from any thread; a world is used by one thread at a time, or by several readers at once.

bool m2Joint_IsMotorEnabled(const m2World* world, m2JointId jointId);

Tells whether a motor drives.

Parameters:

Returns: True when on; false for another joint type or a stale id.

Thread safety. Safe from any thread; a world is used by one thread at a time, or by several readers at once.

bool m2Joint_IsLimitEnabled(const m2World* world, m2JointId jointId);

Tells whether the limits hold.

Parameters:

Returns: True when on; false for another joint type or a stale id.

Thread safety. Safe from any thread; a world is used by one thread at a time, or by several readers at once.

void m2Joint_EnableSpring(m2World* world, m2JointId jointId, bool enable);

Turns a joint's spring on or off: a distance joint's, which makes a rod a spring (or, at spring hertz 0, a slack rope or a strut), a wheel's suspension, or a revolute joint's angular spring. A wheel's or revolute joint's spring row drops its accumulated impulse; a distance joint's rod and spring share the rest row, which keeps it. Another joint type counts one misuse. Journaled.

Parameters:

Thread safety. Safe from any thread; a world is used by one thread at a time.

bool m2Joint_IsSpringEnabled(const m2World* world, m2JointId jointId);

Tells whether a distance, wheel or revolute joint's spring is on.

Parameters:

Returns: True when its spring is on; false for another joint type or a stale id, which count one misuse.

Thread safety. Safe from any thread; a world is used by one thread at a time, or by several readers at once.

void m2Joint_GetLimits(const m2World* world, m2JointId jointId, float* lowerOut, float* upperOut);

Reads the limits m2Joint_SetLimits sets.

Parameters:

Thread safety. Safe from any thread; a world is used by one thread at a time, or by several readers at once.

void m2Joint_GetBreakLimits(const m2World* world, m2JointId jointId, float* maxForceOut, float* maxTorqueOut);

Reads the break limits m2Joint_SetBreakLimits sets.

Parameters:

Thread safety. Safe from any thread; a world is used by one thread at a time, or by several readers at once.

m2BodyId m2Joint_GetBodyA(const m2World* world, m2JointId jointId);

Reads a joint's body A.

Parameters:

Returns: The body; the null id for a stale id.

Thread safety. Safe from any thread; a world is used by one thread at a time, or by several readers at once.

m2BodyId m2Joint_GetBodyB(const m2World* world, m2JointId jointId);

Reads a joint's body B.

Parameters:

Returns: The body; the null id for a stale id.

Thread safety. Safe from any thread; a world is used by one thread at a time, or by several readers at once.

void m2Joint_EnableConnectedCollision(m2World* world, m2JointId jointId, bool enable);

Lets a joint's two bodies collide with each other, or keeps them apart, as the def's enableConnectedCollision does at creation. Both bodies wake and their pairs are found again on the next step. A filter joint, which exists to keep its bodies apart, or a stale id counts one misuse. Journaled.

Parameters:

Thread safety. Safe from any thread; a world is used by one thread at a time.

bool m2Joint_IsConnectedCollisionEnabled(const m2World* world, m2JointId jointId);

Tells whether a joint's two bodies collide with each other.

Parameters:

Returns: True when they collide; false for a stale id.

Thread safety. Safe from any thread; a world is used by one thread at a time, or by several readers at once.

uint64_t m2Joint_GetUserData(const m2World* world, m2JointId jointId);

Reads a joint's game data.

Parameters:

Returns: The value; 0 for a stale id.

Thread safety. Safe from any thread; a world is used by one thread at a time, or by several readers at once.

void m2Joint_SetUserData(m2World* world, m2JointId jointId, uint64_t userData);

Sets a joint's opaque game data, kept through snapshots and journals.

Parameters:

Thread safety. Safe from any thread; a world is used by one thread at a time.

float m2Joint_GetLinearSeparation(const m2World* world, m2JointId jointId);

Measures how far a joint is now from what it holds: the anchor gap of point constraints, a distance joint's length error, a slider's gap off its axis. Bodies more than M2_REACH_LIMIT apart along an axis are taken as that far apart, as the solver takes them.

Parameters:

Returns: The distance, meters; 0 for a stale id.

Thread safety. Safe from any thread; a world is used by one thread at a time, or by several readers at once.

float m2Joint_GetAngularSeparation(const m2World* world, m2JointId jointId);

Measures a joint's angle error now, unwound, where it holds an angle.

Parameters:

Returns: The error, radians; 0 where no angle is held and for a stale id.

Thread safety. Safe from any thread; a world is used by one thread at a time, or by several readers at once.

void m2MotorJoint_SetOffsets(m2World* world, m2JointId jointId, m2Vec2 linearOffset, float angularOffset);

Moves a motor joint's target, as a moving platform does every frame. The budgets are set with m2MotorJoint_SetMaxForce and m2MotorJoint_SetMaxTorque. Another joint type, an angular offset beyond M2_ANGLE_LIMIT or a linear offset beyond M2_LOCAL_LIMIT counts one misuse.

Parameters:

Thread safety. Safe from any thread; a world is used by one thread at a time.

void m2MotorJoint_SetMaxForce(m2World* world, m2JointId jointId, float maxForce);

Sets a motor joint's force budget, the most force its point rows apply to hold B at its offset. Another joint type, or a budget outside 0 to M2_FORCE_LIMIT, counts one misuse.

Parameters:

Thread safety. Safe from any thread; a world is used by one thread at a time.

void m2MotorJoint_SetMaxTorque(m2World* world, m2JointId jointId, float maxTorque);

Sets a motor joint's torque budget, the most torque its angle row applies to hold B at its angular offset; the same budget m2Joint_SetMaxMotorEffort sets. Another joint type, or a budget outside 0 to M2_FORCE_LIMIT, counts one misuse.

Parameters:

Thread safety. Safe from any thread; a world is used by one thread at a time.

m2Vec2 m2MotorJoint_GetLinearOffset(const m2World* world, m2JointId jointId);

Reads a motor joint's linear offset.

Parameters:

Returns: The offset; zero for another joint type or a stale id.

Thread safety. Safe from any thread; a world is used by one thread at a time, or by several readers at once.

float m2MotorJoint_GetAngularOffset(const m2World* world, m2JointId jointId);

Reads a motor joint's angular offset.

Parameters:

Returns: The offset, radians; 0 for another joint type or a stale id.

Thread safety. Safe from any thread; a world is used by one thread at a time, or by several readers at once.

float m2MotorJoint_GetMaxForce(const m2World* world, m2JointId jointId);

Reads a motor joint's force budget.

Parameters:

Returns: The force, N; 0 for another joint type or a stale id.

Thread safety. Safe from any thread; a world is used by one thread at a time, or by several readers at once.

float m2MotorJoint_GetMaxTorque(const m2World* world, m2JointId jointId);

Reads a motor joint's torque budget.

Parameters:

Returns: The torque, N m; 0 for another joint type or a stale id.

Thread safety. Safe from any thread; a world is used by one thread at a time, or by several readers at once.

float m2MotorJoint_GetCorrectionFactor(const m2World* world, m2JointId jointId);

Reads a motor joint's correction factor.

Parameters:

Returns: The factor; 0 for another joint type or a stale id.

Thread safety. Safe from any thread; a world is used by one thread at a time, or by several readers at once.

void m2GearJoint_SetRatio(m2World* world, m2JointId jointId, float ratio);

Sets a gear joint's ratio. Another joint type, or a ratio whose magnitude is outside M2_MIN_RATIO to M2_RATIO_LIMIT, counts one misuse.

Parameters:

Thread safety. Safe from any thread; a world is used by one thread at a time.

float m2GearJoint_GetRatio(const m2World* world, m2JointId jointId);

Reads a gear joint's ratio.

Parameters:

Returns: The ratio; 0 for another joint type or a stale id.

Thread safety. Safe from any thread; a world is used by one thread at a time, or by several readers at once.

void m2PulleyJoint_SetRatio(m2World* world, m2JointId jointId, float ratio);

Sets a pulley joint's ratio. The rope total is measured again from the current pose, so the machine does not snap, and the stored impulse is dropped. Another joint type, or a ratio outside M2_MIN_RATIO to M2_RATIO_LIMIT, counts one misuse.

Parameters:

Thread safety. Safe from any thread; a world is used by one thread at a time.

float m2PulleyJoint_GetRatio(const m2World* world, m2JointId jointId);

Reads a pulley joint's ratio.

Parameters:

Returns: The ratio; 0 for another joint type or a stale id.

Thread safety. Safe from any thread; a world is used by one thread at a time, or by several readers at once.

float m2PulleyJoint_GetLengthA(const m2World* world, m2JointId jointId);

Measures the A side of a pulley's rope now.

Parameters:

Returns: The length, meters; 0 for another joint type or a stale id.

Thread safety. Safe from any thread; a world is used by one thread at a time, or by several readers at once.

float m2PulleyJoint_GetLengthB(const m2World* world, m2JointId jointId);

Measures the B side of a pulley's rope now.

Parameters:

Returns: The length, meters; 0 for another joint type or a stale id.

Thread safety. Safe from any thread; a world is used by one thread at a time, or by several readers at once.

m2Pos2 m2PulleyJoint_GetGroundAnchorA(const m2World* world, m2JointId jointId);

Reads the world point a pulley's A rope hangs from.

Parameters:

Returns: The point; the origin for another joint type or a stale id.

Thread safety. Safe from any thread; a world is used by one thread at a time, or by several readers at once.

m2Pos2 m2PulleyJoint_GetGroundAnchorB(const m2World* world, m2JointId jointId);

Reads the world point a pulley's B rope hangs from.

Parameters:

Returns: The point; the origin for another joint type or a stale id.

Thread safety. Safe from any thread; a world is used by one thread at a time, or by several readers at once.

float m2RatchetJoint_GetToothAngle(const m2World* world, m2JointId jointId);

Reads a ratchet's tooth angle.

Parameters:

Returns: The angle, radians, signed by the free direction; 0 for another joint type or a stale id.

Thread safety. Safe from any thread; a world is used by one thread at a time, or by several readers at once.

float m2RatchetJoint_GetPhase(const m2World* world, m2JointId jointId);

Reads a ratchet's tooth phase.

Parameters:

Returns: The phase, radians; 0 for another joint type or a stale id.

Thread safety. Safe from any thread; a world is used by one thread at a time, or by several readers at once.

void m2MouseJoint_SetTarget(m2World* world, m2JointId jointId, m2Pos2 target);

Moves a mouse joint's target. Another joint type or a non-finite target counts one misuse.

Parameters:

Thread safety. Safe from any thread; a world is used by one thread at a time.

m2Pos2 m2MouseJoint_GetTarget(const m2World* world, m2JointId jointId);

Reads a mouse joint's target.

Parameters:

Returns: The target; the origin for another joint type or a stale id.

Thread safety. Safe from any thread; a world is used by one thread at a time, or by several readers at once.

float m2MouseJoint_GetMaxForce(const m2World* world, m2JointId jointId);

Reads a mouse joint's force budget.

Parameters:

Returns: The force, N; 0 for another joint type or a stale id.

Thread safety. Safe from any thread; a world is used by one thread at a time, or by several readers at once.

int32_t m2World_GetJoints(const m2World* world, m2JointId* idsOut, int32_t capacity);

Lists the world's joints in ascending slot order.

Parameters:

Returns: The number of joints, which may exceed capacity.

Thread safety. Safe from any thread; a world is used by one thread at a time, or by several readers at once.

int32_t m2Body_GetJoints(const m2World* world, m2BodyId bodyId, m2JointId* idsOut, int32_t capacity);

Lists the joints attached to a body, in ascending slot order.

Parameters:

Returns: The number of joints, which may exceed capacity; 0 for a stale id.

Thread safety. Safe from any thread; a world is used by one thread at a time, or by several readers at once.

particle.h

Particle fluids: a fixed-capacity particle system that lives inside the world when its def asks for one. Particles are stored in stable slots with generation-checked ids and are never reordered, so snapshots, the journal and rollback cover them like everything else. A particle can die on its own, when its lifetime runs out, and no event reports it. A program may therefore hold a dead particle id, and a stale particle id counts no misuse in any call: a getter returns zero, a setter changes nothing, m2DestroyParticle returns m2_errorStale.

m2ParticleDef m2DefaultParticleDef(void);

A particle def with its defaults: a water particle at rest at the origin.

Returns: The def.

Thread safety. Safe from any thread.

M2_NODISCARD M2_API m2Result m2CreateParticle(m2World* world, const m2ParticleDef* def, m2ParticleId* particleOut);

Creates one particle. A full pool is also counted in m2Counters.particleCreatesRefused; pace emitters off m2World_GetParticleCount. Journaled.

Parameters:

Returns: m2_success; m2_errorInvalid when the world, def or particleOut is null, def was not initialized by m2DefaultParticleDef, a value of it is NaN or not finite where it has no bound, or its flags hold a bit no m2_*Particle flag has; m2_errorLimit for a velocity past M2_SPEED_LIMIT; m2_errorCapacity when the pool is full, a pool of 0 included, which counts no misuse; m2_errorBusy from host code the world is running.

Thread safety. Safe from any thread; a world is used by one thread at a time.

M2_NODISCARD M2_API m2Result m2DestroyParticle(m2World* world, m2ParticleId particleId);

Destroys one particle, with its springs and triads. Its slot is reused in FIFO order under a new generation, and retires rather than let the generation wrap. Journaled.

Parameters:

Returns: m2_success; m2_errorInvalid for a null world; m2_errorStale when it is already gone, which counts no misuse; m2_errorBusy from host code the world is running.

Thread safety. Safe from any thread; a world is used by one thread at a time.

bool m2Particle_IsValid(const m2World* world, m2ParticleId particleId);

Tells whether a particle id names a live particle. A particle can expire during any step.

Parameters:

Returns: True for a live particle.

Thread safety. Safe from any thread; a world is used by one thread at a time, or by several readers at once.

m2Pos2 m2Particle_GetPosition(const m2World* world, m2ParticleId particleId);

Reads a particle's position.

Parameters:

Returns: The position; the origin for a stale id.

Thread safety. Safe from any thread; a world is used by one thread at a time, or by several readers at once.

m2ParticleFlags m2Particle_GetFlags(const m2World* world, m2ParticleId particleId);

Reads a particle's behavior flags.

Parameters:

Returns: The m2_*Particle flags it was created with; 0 for a stale id.

Thread safety. Safe from any thread; a world is used by one thread at a time, or by several readers at once.

void m2Particle_SetLifetime(m2World* world, m2ParticleId particleId, float seconds);

Gives a particle a lifetime. It counts down by each step's length, and the particle is destroyed at the end of the step it reaches zero, in ascending slot order. The countdown is world state, so it replays and rolls back by itself. A negative or non-finite value counts one misuse. Journaled.

Parameters:

Thread safety. Safe from any thread; a world is used by one thread at a time.

float m2Particle_GetLifetime(const m2World* world, m2ParticleId particleId);

Reads a particle's remaining lifetime.

Parameters:

Returns: The seconds left; 0 for an immortal particle or a stale id.

Thread safety. Safe from any thread; a world is used by one thread at a time, or by several readers at once.

void m2Particle_SetUserData(m2World* world, m2ParticleId particleId, uint64_t userData);

Sets a particle's opaque game data, kept through snapshots and journals. Journaled.

Parameters:

Thread safety. Safe from any thread; a world is used by one thread at a time.

uint64_t m2Particle_GetUserData(const m2World* world, m2ParticleId particleId);

Reads a particle's game data.

Parameters:

Returns: The value; 0 for a stale id.

Thread safety. Safe from any thread; a world is used by one thread at a time, or by several readers at once.

m2Vec2 m2Particle_GetVelocity(const m2World* world, m2ParticleId particleId);

Reads a particle's velocity.

Parameters:

Returns: The velocity, m/s; zero for a stale id.

Thread safety. Safe from any thread; a world is used by one thread at a time, or by several readers at once.

void m2Particle_SetVelocity(m2World* world, m2ParticleId particleId, m2Vec2 velocity);

Sets a particle's velocity. A velocity beyond M2_SPEED_LIMIT on either axis counts one misuse. Journaled.

Parameters:

Thread safety. Safe from any thread; a world is used by one thread at a time.

int32_t m2World_GetParticleCount(const m2World* world);

Counts the live particles.

Parameters:

Returns: The count; 0 for a null world.

Thread safety. Safe from any thread; a world is used by one thread at a time, or by several readers at once.

M2_NODISCARD M2_API m2Result m2CreateParticlesInPolygon(m2World* world, const m2ParticleDef* def, const m2Polygon* polygon, int32_t* countOut);

Fills a convex polygon with particles on the rest stride (0.75 diameters), row by row from the bottom, left to right. A full pool ends the fill early: the particles created so far stay, and the fill returns m2_errorCapacity with their count, which may be 0. With the spring or elastic flag the batch becomes a body: springs keep their spawn lengths and triads their spawn shape. Journaled as one operation, a fill cut short included.

Parameters:

Returns: m2_success; m2_errorCapacity when the pool ran out before the polygon was full, a pool of 0 included, which counts no misuse and counts once in m2Counters.particleCreatesRefused; m2_errorInvalid when an argument is null, def was not initialized by m2DefaultParticleDef, a value of it is NaN, its flags hold a bit no m2_*Particle flag has, or the polygon is not one a shape would take; m2_errorLimit for a velocity or a polygon past its published bound, or a polygon wider than M2_MAX_FILL_COLUMNS strides; m2_errorBusy from host code the world is running.

Thread safety. Safe from any thread; a world is used by one thread at a time.

int32_t m2World_OverlapParticlesAabb(const m2World* world, m2WorldAabb box, m2ParticleId* idsOut, int32_t capacity);

Lists the live particles whose centers lie inside a box, in ascending slot order. A circular region is one distance check away on the caller's side.

Parameters:

Returns: The number of particles inside, which may exceed capacity; 0 for a non-finite or inverted box, which counts one misuse.

Thread safety. Safe from any thread; a world is used by one thread at a time, or by several readers at once.

int32_t m2World_GetParticles(const m2World* world, m2ParticleId* idsOut, int32_t capacity);

Lists the live particles in ascending slot order.

Parameters:

Returns: The number of particles, which may exceed capacity.

Thread safety. Safe from any thread; a world is used by one thread at a time, or by several readers at once.

shape.h

Shapes: geometry, materials, collision filters, chains, convex hulls, outline decomposition and the query functions.

m2ChainDef m2DefaultChainDef(void);

Returns a chain def with the default material and filter.

Returns: The default def, with no points.

Thread safety. Safe from any thread.

M2_NODISCARD M2_API m2Result m2CreateChain(m2World* world, m2BodyId bodyId, const m2ChainDef* def, m2ChainId* chainOut);

Creates a chain's segment shapes on a body. A shape pool that runs out midway leaves a shorter chain: its segments and its id stay, the create returns m2_errorCapacity, and m2Chain_GetSegmentCount tells how many it has. The id names the whole chain; destroying the body retires it too. Journaled as one operation, a chain cut short included.

Parameters:

Returns: m2_success; m2_errorCapacity, counting no misuse, when the shape pool ran out before the last segment (chainOut names the shorter chain) or the chain or shape pool has no room at all (chainOut is the null id); m2_errorStale for a stale body; m2_errorInvalid for a null world, a bad def or a null chainOut; m2_errorLimit for a point or value past its published bound; m2_errorBusy from host code the world is running.

Thread safety. Safe from any thread; a world is used by one thread at a time.

M2_NODISCARD M2_API m2Result m2DestroyChain(m2World* world, m2ChainId chainId);

Destroys a chain and every segment of it at once: their contacts end and whatever rested on them wakes. Journaled.

Parameters:

Returns: m2_success; m2_errorInvalid for a null world; m2_errorStale when the chain is already gone; m2_errorBusy from host code the world is running.

Thread safety. Safe from any thread; a world is used by one thread at a time.

bool m2Chain_IsValid(const m2World* world, m2ChainId chainId);

Tells whether a chain id names a live chain. Counts no misuse.

Parameters:

Returns: True for a live chain.

Thread safety. Safe from any thread; a world is used by one thread at a time, or by several readers at once.

int32_t m2Chain_GetSegmentCount(const m2World* world, m2ChainId chainId);

Counts the segments a chain has, which is fewer than its def asked for when the shape pool ran out.

Parameters:

Returns: The number of segments; 0 for a stale id.

Thread safety. Safe from any thread; a world is used by one thread at a time, or by several readers at once.

bool m2Chain_IsLoop(const m2World* world, m2ChainId chainId);

Tells whether a chain is a closed loop, as its def's isLoop said.

Parameters:

Returns: True for a loop; false for an open chain or a stale id.

Thread safety. Safe from any thread; a world is used by one thread at a time, or by several readers at once.

m2ShapeDef m2DefaultShapeDef(void);

Returns a shape def: density 1, friction 0.6, no bounce, category 1, mask all, not a sensor.

Returns: The default def.

Thread safety. Safe from any thread.

M2_NODISCARD M2_API m2Result m2MakePolygon(const m2Vec2* points, int32_t count, float radius, m2Polygon* polygonOut);

Builds a polygon from convex, counter-clockwise points, with thresholds relative to its size.

Parameters:

Returns: m2_success; m2_errorLimit for more than M2_MAX_POLYGON_VERTICES points, or a point or radius past M2_LOCAL_LIMIT; m2_errorInvalid when the points do not make a valid polygon or an argument is null.

Thread safety. Safe from any thread.

M2_NODISCARD M2_API m2Result m2ComputeHull(const m2Vec2* points, int32_t count, float radius, m2Polygon* polygonOut);

Builds the convex hull of a loose point cloud: near points are welded, collinear ones merged, the rest wrapped in a deterministic order. The way from a sprite's points to a collision shape. A merged point lies within 0.01 m of the edge that replaces it, so a curve that needs more vertices to stay that close is m2_errorLimit.

Parameters:

Returns: m2_success; m2_errorLimit for more than M2_MAX_HULL_POINTS points, a point or the radius past M2_LOCAL_LIMIT, or a hull of more than M2_MAX_POLYGON_VERTICES vertices; m2_errorInvalid when no hull remains (too few points, all welded together, all collinear) or an argument is null.

Thread safety. Safe from any thread.

M2_NODISCARD M2_API m2Result m2DecomposeOutline(const m2Vec2* points, int32_t count, m2Polygon* piecesOut, int32_t capacity, int32_t* countOut);

Splits a simple counter-clockwise outline, without holes, into convex pieces of at most 8 vertices: the way from a sprite outline to the shapes of a destructible body. Pieces of near-zero area are dropped by validation; a clean outline loses nothing, and one that would lose every piece is refused.

Parameters:

Returns: m2_success; m2_errorLimit for more than M2_MAX_OUTLINE_POINTS points or a point past M2_LOCAL_LIMIT; m2_errorInvalid for too few points, clockwise winding, an outline too thin for any piece to pass validation, an outline that is not simple (an edge crossing another, a vertex within 0.005 m of an edge it does not end, a repeated vertex, an edge folding back over its neighbor), a negative capacity, a null piecesOut with a positive capacity or another null argument. It takes no world, so a refusal counts nothing.

Thread safety. Safe from any thread.

M2_NODISCARD M2_API m2Result m2Body_Shatter(m2World* world, m2BodyId bodyId, const m2Polygon* pieces, int32_t pieceCount, m2BodyId* bodiesOut, int32_t capacity, int32_t* countOut);

Breaks a dynamic body into one new dynamic body per piece, all at the parent's pose. Each takes the parent's velocity at its own center of mass and the parent's spin, and the material and filter of the parent's first shape. The parent is destroyed like any body: its joints go with it and touching sleepers wake. All or nothing: when the pools cannot seat every piece, nothing changes. Journaled as one operation.

Parameters:

Returns: m2_success; m2_errorStale for a stale body; m2_errorInvalid for a body that is not dynamic, an invalid piece or piece count, a null world or a bad output argument; m2_errorLimit for more than M2_MAX_SHATTER_PIECES pieces or a piece past its bounds, as m2MakePolygon gives them; m2_errorCapacity when the body or shape pool cannot seat every piece, which counts no misuse; m2_errorBusy from host code the world is running.

Thread safety. Safe from any thread; a world is used by one thread at a time.

m2Polygon m2MakeBox(float halfWidth, float halfHeight);

Builds a box centered on the body origin.

Parameters:

Returns: The box; a polygon with count 0 when the extents are not positive and finite, which every create refuses.

Thread safety. Safe from any thread.

M2_NODISCARD M2_API m2Result m2CreateCircleShape(m2World* world, m2BodyId bodyId, const m2ShapeDef* def, const m2Circle* circle, m2ShapeId* shapeOut);

Attaches a circle to a body. A dynamic body recomputes its mass from all its shapes. Nothing is left half made on failure. Journaled.

Parameters:

Returns: m2_success; m2_errorStale for a stale body; m2_errorInvalid for a bad def or geometry or a null argument; m2_errorLimit for a value or coordinate past its published bound; m2_errorCapacity when the shape pool is full; m2_errorBusy from host code the world is running.

Thread safety. Safe from any thread; a world is used by one thread at a time.

M2_NODISCARD M2_API m2Result m2CreateCapsuleShape(m2World* world, m2BodyId bodyId, const m2ShapeDef* def, const m2Capsule* capsule, m2ShapeId* shapeOut);

Attaches a capsule to a body, as m2CreateCircleShape does.

Parameters:

Returns: As m2CreateCircleShape.

Thread safety. Safe from any thread; a world is used by one thread at a time.

M2_NODISCARD M2_API m2Result m2CreatePolygonShape(m2World* world, m2BodyId bodyId, const m2ShapeDef* def, const m2Polygon* polygon, m2ShapeId* shapeOut);

Attaches a polygon to a body, as m2CreateCircleShape does.

Parameters:

Returns: As m2CreateCircleShape.

Thread safety. Safe from any thread; a world is used by one thread at a time.

M2_NODISCARD M2_API m2Result m2CreateSegmentShape(m2World* world, m2BodyId bodyId, const m2ShapeDef* def, const m2Segment* segment, m2ShapeId* shapeOut);

Attaches a two-sided segment to a body, as m2CreateCircleShape does.

Parameters:

Returns: As m2CreateCircleShape.

Thread safety. Safe from any thread; a world is used by one thread at a time.

bool m2Shape_IsValid(const m2World* world, m2ShapeId shapeId);

Tells whether a shape id names a live shape. Counts no misuse.

Parameters:

Returns: True for a live shape.

Thread safety. Safe from any thread; a world is used by one thread at a time, or by several readers at once.

M2_NODISCARD M2_API m2Result m2DestroyShape(m2World* world, m2ShapeId shapeId);

Destroys one shape: its touching contacts end (their end events arrive with the next step's), its pairs go, and its body's mass and center of mass are recomputed. Journaled.

Parameters:

Returns: m2_success; m2_errorInvalid for a null world; m2_errorStale when the shape is already gone; m2_errorBusy from host code the world is running.

Thread safety. Safe from any thread; a world is used by one thread at a time.

void m2Shape_SetFriction(m2World* world, m2ShapeId shapeId, float friction);

Sets a shape's friction. It applies the next time its contacts are prepared. A stale id or an invalid value changes nothing and counts one misuse. Journaled.

Parameters:

Thread safety. Safe from any thread; a world is used by one thread at a time.

void m2Shape_SetRestitution(m2World* world, m2ShapeId shapeId, float restitution);

Sets a shape's restitution, as m2Shape_SetFriction does.

Parameters:

Thread safety. Safe from any thread; a world is used by one thread at a time.

void m2Shape_SetTangentSpeed(m2World* world, m2ShapeId shapeId, float speed);

Sets a shape's conveyor speed along the contact tangent. A pair slides at the sum of both shapes' speeds; positive drives a rider toward +x on an upward-facing floor. Riders wake. A stale id or a speed beyond M2_SPEED_LIMIT changes nothing and counts one misuse. Journaled.

Parameters:

Thread safety. Safe from any thread; a world is used by one thread at a time.

float m2Shape_GetTangentSpeed(const m2World* world, m2ShapeId shapeId);

Reads a shape's conveyor speed.

Parameters:

Returns: The surface speed; 0 for a stale id.

Thread safety. Safe from any thread; a world is used by one thread at a time, or by several readers at once.

void m2Shape_SetFilter(m2World* world, m2ShapeId shapeId, uint64_t categoryBits, uint64_t maskBits, int32_t groupIndex);

Sets a shape's collision filter. Its pairs are rebuilt at once, the ended ones with end events, and whatever touched it wakes. A stale id changes nothing and counts one misuse. Journaled.

Parameters:

Thread safety. Safe from any thread; a world is used by one thread at a time.

float m2Shape_GetFriction(const m2World* world, m2ShapeId shapeId);

Reads a shape's friction.

Parameters:

Returns: The friction; 0 for a stale id.

Thread safety. Safe from any thread; a world is used by one thread at a time, or by several readers at once.

float m2Shape_GetRestitution(const m2World* world, m2ShapeId shapeId);

Reads a shape's restitution.

Parameters:

Returns: The restitution; 0 for a stale id.

Thread safety. Safe from any thread; a world is used by one thread at a time, or by several readers at once.

m2ShapeType m2Shape_GetType(const m2World* world, m2ShapeId shapeId);

Reads a shape's geometry type.

Parameters:

Returns: The type; m2_circleShape for a stale id.

Thread safety. Safe from any thread; a world is used by one thread at a time, or by several readers at once.

bool m2Shape_IsSensor(const m2World* world, m2ShapeId shapeId);

Tells whether a shape is a sensor.

Parameters:

Returns: True for a sensor; false for a stale id.

Thread safety. Safe from any thread; a world is used by one thread at a time, or by several readers at once.

void m2Shape_GetFilter(const m2World* world, m2ShapeId shapeId, uint64_t* categoryBitsOut, uint64_t* maskBitsOut, int32_t* groupIndexOut);

Reads a shape's collision filter.

Parameters:

Thread safety. Safe from any thread; a world is used by one thread at a time, or by several readers at once.

m2Circle m2CircleShape_GetCircle(const m2World* world, m2ShapeId shapeId);

Reads a circle shape's geometry, the exact stored bits in the body's frame.

Parameters:

Returns: The circle; zeroed on a refusal.

Thread safety. Safe from any thread; a world is used by one thread at a time, or by several readers at once.

m2Capsule m2CapsuleShape_GetCapsule(const m2World* world, m2ShapeId shapeId);

Reads a capsule shape's geometry, as m2CircleShape_GetCircle does.

Parameters:

Returns: The capsule; zeroed on a refusal.

Thread safety. Safe from any thread; a world is used by one thread at a time, or by several readers at once.

m2Polygon m2PolygonShape_GetPolygon(const m2World* world, m2ShapeId shapeId);

Reads a polygon shape's geometry, as m2CircleShape_GetCircle does.

Parameters:

Returns: The polygon; zeroed on a refusal.

Thread safety. Safe from any thread; a world is used by one thread at a time, or by several readers at once.

m2Segment m2SegmentShape_GetSegment(const m2World* world, m2ShapeId shapeId);

Reads a segment shape's geometry, as m2CircleShape_GetCircle does.

Parameters:

Returns: The segment; zeroed on a refusal.

Thread safety. Safe from any thread; a world is used by one thread at a time, or by several readers at once.

m2ChainSegment m2ChainSegmentShape_GetChainSegment(const m2World* world, m2ShapeId shapeId);

Reads a chain link's geometry and ghosts, as m2CircleShape_GetCircle does.

Parameters:

Returns: The link; zeroed on a refusal.

Thread safety. Safe from any thread; a world is used by one thread at a time, or by several readers at once.

float m2Shape_GetDensity(const m2World* world, m2ShapeId shapeId);

Reads a shape's density.

Parameters:

Returns: The density; 0 for a stale id.

Thread safety. Safe from any thread; a world is used by one thread at a time, or by several readers at once.

void m2Shape_SetCircle(m2World* world, m2ShapeId shapeId, const m2Circle* circle);

Replaces a shape's geometry with a circle, changing its type if it has another. The body's mass recomputes, touching partners wake, and the broadphase refreshes. A stale id, invalid geometry or a chain link changes nothing and counts one misuse. Journaled.

Parameters:

Thread safety. Safe from any thread; a world is used by one thread at a time.

void m2Shape_SetCapsule(m2World* world, m2ShapeId shapeId, const m2Capsule* capsule);

Replaces a shape's geometry with a capsule, as m2Shape_SetCircle does.

Parameters:

Thread safety. Safe from any thread; a world is used by one thread at a time.

void m2Shape_SetPolygon(m2World* world, m2ShapeId shapeId, const m2Polygon* polygon);

Replaces a shape's geometry with a polygon, as m2Shape_SetCircle does.

Parameters:

Thread safety. Safe from any thread; a world is used by one thread at a time.

void m2Shape_SetSegment(m2World* world, m2ShapeId shapeId, const m2Segment* segment);

Replaces a shape's geometry with a segment, as m2Shape_SetCircle does.

Parameters:

Thread safety. Safe from any thread; a world is used by one thread at a time.

int32_t m2Body_GetShapes(const m2World* world, m2BodyId bodyId, m2ShapeId* idsOut, int32_t capacity);

Lists a body's shapes in ascending slot order.

Parameters:

Returns: The number of shapes, which may exceed capacity; 0 for a stale id.

Thread safety. Safe from any thread; a world is used by one thread at a time, or by several readers at once.

int32_t m2World_GetChains(const m2World* world, m2ChainId* idsOut, int32_t capacity);

Lists the world's chains in ascending slot order.

Parameters:

Returns: The number of chains, which may exceed capacity.

Thread safety. Safe from any thread; a world is used by one thread at a time, or by several readers at once.

int32_t m2Chain_GetShapes(const m2World* world, m2ChainId chainId, m2ShapeId* idsOut, int32_t capacity);

Lists a chain's links in ascending slot order.

Parameters:

Returns: The number of links, which may exceed capacity; 0 for a stale id.

Thread safety. Safe from any thread; a world is used by one thread at a time, or by several readers at once.

void m2Chain_SetFriction(m2World* world, m2ChainId chainId, float friction);

Sets the friction of every link of a chain, as one journaled operation. It applies the next time the contacts are prepared. A stale id or an invalid value changes nothing and counts one misuse.

Parameters:

Thread safety. Safe from any thread; a world is used by one thread at a time.

void m2Chain_SetRestitution(m2World* world, m2ChainId chainId, float restitution);

Sets the restitution of every link of a chain, as m2Chain_SetFriction does.

Parameters:

Thread safety. Safe from any thread; a world is used by one thread at a time.

float m2Chain_GetFriction(const m2World* world, m2ChainId chainId);

Reads a chain's friction: the chain's own material, as its def or m2Chain_SetFriction last set it, not any link's. m2Shape_SetFriction on one link changes that link alone and leaves this value as it is.

Parameters:

Returns: The friction; 0 for a stale id.

Thread safety. Safe from any thread; a world is used by one thread at a time, or by several readers at once.

float m2Chain_GetRestitution(const m2World* world, m2ChainId chainId);

Reads a chain's restitution: the chain's own material, as its def or m2Chain_SetRestitution last set it, not any link's. m2Shape_SetRestitution on one link changes that link alone and leaves this value as it is.

Parameters:

Returns: The restitution; 0 for a stale id.

Thread safety. Safe from any thread; a world is used by one thread at a time, or by several readers at once.

m2BodyId m2Shape_GetBody(const m2World* world, m2ShapeId shapeId);

Reads the body a shape is attached to.

Parameters:

Returns: The body; the null id for a stale id.

Thread safety. Safe from any thread; a world is used by one thread at a time, or by several readers at once.

m2ChainId m2Shape_GetParentChain(const m2World* world, m2ShapeId shapeId);

Reads the chain a link belongs to.

Parameters:

Returns: The chain; the null id for a shape outside any chain or a stale id.

Thread safety. Safe from any thread; a world is used by one thread at a time, or by several readers at once.

m2WorldAabb m2Shape_GetAabb(const m2World* world, m2ShapeId shapeId);

Computes a shape's tight world-space box, without the broadphase margin.

Parameters:

Returns: The box; zeroed for a stale id.

Thread safety. Safe from any thread; a world is used by one thread at a time, or by several readers at once.

bool m2Shape_TestPoint(const m2World* world, m2ShapeId shapeId, m2Pos2 point);

Tells whether a world point is inside a shape. A point within the engine's slop skin of the surface counts as inside, as overlaps do.

Parameters:

Returns: True when the point is inside; false for a stale id.

Thread safety. Safe from any thread; a world is used by one thread at a time, or by several readers at once.

m2Pos2 m2Shape_GetClosestPoint(const m2World* world, m2ShapeId shapeId, m2Pos2 point);

Finds the point of a shape's surface nearest a world point, radius included. A point inside the shape, or within its radius, is its own nearest point and comes back as it is.

Parameters:

Returns: The nearest surface point, or the point itself when it is inside; the origin for a stale id.

Thread safety. Safe from any thread; a world is used by one thread at a time, or by several readers at once.

void m2Shape_SetDensity(m2World* world, m2ShapeId shapeId, float density);

Sets a shape's density; a dynamic body recomputes its mass. A stale id or a density outside 0 to M2_DENSITY_LIMIT changes nothing and counts one misuse. Journaled.

Parameters:

Thread safety. Safe from any thread; a world is used by one thread at a time.

void m2Shape_SetUserData(m2World* world, m2ShapeId shapeId, uint64_t userData);

Sets a shape's opaque game data, kept through snapshots and journals. A stale id changes nothing and counts one misuse. Journaled.

Parameters:

Thread safety. Safe from any thread; a world is used by one thread at a time.

uint64_t m2Shape_GetUserData(const m2World* world, m2ShapeId shapeId);

Reads a shape's game data.

Parameters:

Returns: The value; 0 for a stale id.

Thread safety. Safe from any thread; a world is used by one thread at a time, or by several readers at once.

m2QueryFilter m2DefaultQueryFilter(void);

Returns the default query filter, category 1 and mask all, which sees every shape whose mask includes category 1.

Returns: The default filter.

Thread safety. Safe from any thread.

bool m2World_CastRayClosest(const m2World* world, m2Pos2 origin, m2Vec2 translation, m2QueryFilter filter, m2CastHit* hitOut);

Casts a ray and returns its closest hit. A chain link is hit only from its solid side.

Parameters:

Returns: True on a hit; false on a miss, and for a non-finite argument or a null hitOut, which count one misuse.

Thread safety. Safe from any thread; a world is used by one thread at a time, or by several readers at once.

bool m2Shape_CastRay(const m2World* world, m2ShapeId shapeId, m2Pos2 origin, m2Vec2 translation, m2CastHit* hitOut);

Casts a ray against one shape, with the conventions of m2World_CastRayClosest.

Parameters:

Returns: True on a hit; false on a miss, and for a stale id, a non-finite argument or a null hitOut, which count one misuse.

Thread safety. Safe from any thread; a world is used by one thread at a time, or by several readers at once.

int32_t m2World_CastRayAll(const m2World* world, m2Pos2 origin, m2Vec2 translation, m2QueryFilter filter, m2CastHit* hitsOut, int32_t capacity);

Casts a ray and lists every hit in ascending fraction, ties to the lower shape index. When there are more hits than capacity, the closest are kept.

Parameters:

Returns: The number of hits, which may exceed capacity; 0 for a non-finite argument, which counts one misuse.

Thread safety. Safe from any thread; a world is used by one thread at a time, or by several readers at once.

int32_t m2World_CastCircleAll(const m2World* world, const m2Circle* circle, m2Transform origin, m2Vec2 translation, m2QueryFilter filter, m2CastHit* hitsOut, int32_t capacity);

Sweeps a circle and lists every hit, as m2World_CastRayAll does.

Parameters:

Returns: The number of hits, which may exceed capacity; 0 for an invalid argument, which counts one misuse.

Thread safety. Safe from any thread; a world is used by one thread at a time, or by several readers at once.

int32_t m2World_CastCapsuleAll(const m2World* world, const m2Capsule* capsule, m2Transform origin, m2Vec2 translation, m2QueryFilter filter, m2CastHit* hitsOut, int32_t capacity);

Sweeps a capsule and lists every hit, as m2World_CastRayAll does.

Parameters:

Returns: The number of hits, which may exceed capacity; 0 for an invalid argument, which counts one misuse.

Thread safety. Safe from any thread; a world is used by one thread at a time, or by several readers at once.

int32_t m2World_CastPolygonAll(const m2World* world, const m2Polygon* polygon, m2Transform origin, m2Vec2 translation, m2QueryFilter filter, m2CastHit* hitsOut, int32_t capacity);

Sweeps a polygon and lists every hit, as m2World_CastRayAll does.

Parameters:

Returns: The number of hits, which may exceed capacity; 0 for an invalid argument, which counts one misuse.

Thread safety. Safe from any thread; a world is used by one thread at a time, or by several readers at once.

int32_t m2World_CollideMover(const m2World* world, const m2Capsule* mover, m2Transform origin, m2QueryFilter filter, m2MoverPlane* planesOut, int32_t capacity);

Gathers the planes touching a posed capsule, one per nearby shape, in ascending shape order; an array too short for them all holds the planes of the lowest shape slots. A collar of four linear slops lets a controller see a wall before it reaches it. A chain link counts only from its solid side. Use m2World_CastCapsuleClosest for the sweep.

Parameters:

Returns: The number of planes, which may exceed capacity; 0 for an invalid argument, which counts one misuse.

Thread safety. Safe from any thread; a world is used by one thread at a time, or by several readers at once.

m2MoverMove m2SolveMover(m2Vec2 wish, const m2MoverPlane* planes, int32_t count);

Turns a wished translation into the closest one no plane blocks, and reports which planes it rests on.

Parameters:

Returns: The translation to apply and the planes that stopped part of the wish.

Thread safety. Safe from any thread.

m2Vec2 m2ClipMoverVelocity(m2Vec2 velocity, const m2MoverPlane* planes, int32_t count, uint32_t pressed);

Removes the part of a velocity that points into the planes a move rests on.

Parameters:

Returns: The clipped velocity.

Thread safety. Safe from any thread.

bool m2World_CastCircleClosest(const m2World* world, const m2Circle* circle, m2Transform origin, m2Vec2 translation, m2QueryFilter filter, m2CastHit* hitOut);

Sweeps a circle and returns its closest hit, ties to the lower shape index. A sweep that starts on a chain link's ghost side passes through it. An initial overlap reports fraction 0 and a zero normal, as rays do.

Parameters:

Returns: True on a hit; false on a miss, and for an invalid argument or a null hitOut, which count one misuse.

Thread safety. Safe from any thread; a world is used by one thread at a time, or by several readers at once.

bool m2World_CastCapsuleClosest(const m2World* world, const m2Capsule* capsule, m2Transform origin, m2Vec2 translation, m2QueryFilter filter, m2CastHit* hitOut);

Sweeps a capsule and returns its closest hit, as m2World_CastCircleClosest does. A character controller's sweep.

Parameters:

Returns: True on a hit; false on a miss, and for an invalid argument or a null hitOut, which count one misuse.

Thread safety. Safe from any thread; a world is used by one thread at a time, or by several readers at once.

bool m2World_CastPolygonClosest(const m2World* world, const m2Polygon* polygon, m2Transform origin, m2Vec2 translation, m2QueryFilter filter, m2CastHit* hitOut);

Sweeps a polygon and returns its closest hit, as m2World_CastCircleClosest does.

Parameters:

Returns: True on a hit; false on a miss, and for an invalid argument or a null hitOut, which count one misuse.

Thread safety. Safe from any thread; a world is used by one thread at a time, or by several readers at once.

int32_t m2World_OverlapCircle(const m2World* world, const m2Circle* circle, m2Transform origin, m2QueryFilter filter, m2ShapeId* idsOut, int32_t capacity);

Lists the live shapes touching a posed circle, in ascending slot order. Touching within the engine's slop skin counts. A chain link counts only from its solid side.

Parameters:

Returns: The number of shapes, which may exceed capacity; 0 for an invalid argument, which counts one misuse.

Thread safety. Safe from any thread; a world is used by one thread at a time, or by several readers at once.

int32_t m2World_OverlapCapsule(const m2World* world, const m2Capsule* capsule, m2Transform origin, m2QueryFilter filter, m2ShapeId* idsOut, int32_t capacity);

Lists the live shapes touching a posed capsule, as m2World_OverlapCircle does.

Parameters:

Returns: The number of shapes, which may exceed capacity; 0 for an invalid argument, which counts one misuse.

Thread safety. Safe from any thread; a world is used by one thread at a time, or by several readers at once.

int32_t m2World_OverlapPolygon(const m2World* world, const m2Polygon* polygon, m2Transform origin, m2QueryFilter filter, m2ShapeId* idsOut, int32_t capacity);

Lists the live shapes touching a posed polygon, as m2World_OverlapCircle does.

Parameters:

Returns: The number of shapes, which may exceed capacity; 0 for an invalid argument, which counts one misuse.

Thread safety. Safe from any thread; a world is used by one thread at a time, or by several readers at once.

int32_t m2World_OverlapAabb(const m2World* world, m2WorldAabb box, m2QueryFilter filter, m2ShapeId* idsOut, int32_t capacity);

Lists the live shapes whose tight box overlaps a world box, in ascending slot order.

Parameters:

Returns: The number of shapes, which may exceed capacity; 0 for a non-finite or inverted box, which counts one misuse.

Thread safety. Safe from any thread; a world is used by one thread at a time, or by several readers at once.

world.h

The world: creation, stepping, tuning, snapshots, the command journal, counters and diagnostics.

m2WorldDef m2DefaultWorldDefValues(void);

THREADS. Readers (queries, getters, diagnostics, drawing) take a const world and may run at the same time as each other, never with m2World_Step or another writer. Writers (creates and destroys, setters, impulses, the step) need the world to themselves. Separate worlds share nothing. The host code a world runs (the task hooks, the debug draw callbacks, the allocator) must not change that world: its writers refuse with m2_errorBusy, or count one misuse where they return void. Readers stay open to it.

FLOATING POINT. A call that computes runs in the library's own floating-point setting, whatever the calling thread's is: it rounds to nearest, keeps subnormals and masks every exception, and gives the thread back its rounding mode and flush-to-zero and denormals-are-zero bits as they were. A host may run its threads in any setting and still gets the same bits. The host code a world runs (the task hooks, the debug draw callbacks, the allocator) runs in the thread's own setting, and a range job sets the library's on whatever thread the host runs it.

IDS. An id names an object of the world that issued it: a 1-based slot and a generation. A correct program never uses an id after destroying its object, so a stale id counts one misuse: a getter returns the zeroed value, a setter changes nothing, and a call that returns a status returns m2_errorStale. Particles are the exception: the world ends a particle on its own when its lifetime runs out, so a program may hold a dead particle id, and a stale particle id counts nothing. The validity queries (m2Body_IsValid and the others) count nothing either. An id carries no world: one passed to another world names whatever that world holds in the same slot and generation, and the library cannot tell. A slot takes a new generation each time it is reused, and after 2^32 objects it retires instead of starting over, so no id ever names two objects. A pool of capacity n therefore makes n * 2^32 objects over a world's life, snapshots included; then its creates return m2_errorCapacity.

MISUSE. m2Counters.misuseCount counts the bugs of the calling code: an argument a correct program never passes, a stale id, a writer called from host code the world is running. Untrusted input is not misuse: a snapshot or journal tape that fails its checks, and a value one of a tape's ops refuses while it replays, return m2_errorInvalid and count nothing, so bytes from outside cannot inflate the counter. Host code a replay runs (a task hook, the allocator) is the calling code's: what it gets wrong counts, replay or not. A full pool counts nothing either. Returns the library's default world def with the version left zero. Call m2DefaultWorldDef instead, which stamps the version of the program's headers.

Returns: The library's defaults: gravity (0, -10), 1024 bodies, 2048 shapes, 256 joints, sleeping on, no particles or volumes.

Thread safety. Safe from any thread.

static inline m2WorldDef m2DefaultWorldDef(void);

Returns a world def with the library's defaults, a valid cookie and the ABI version of the headers the program is built with. It is built in the program, so m2CreateWorld can refuse a def made for another minor version's binary interface.

Returns: The default def.

Thread safety. Safe from any thread.

M2_NODISCARD M2_API m2Result m2CreateWorld(const m2WorldDef* def, m2World** worldOut);

Creates a world. Every byte the world keeps is allocated here, from the def's allocator, and pools never grow; afterwards only a journal replay takes scratch memory from it, and gives it back.

Parameters:

Returns: m2_success, or the first failed check in this order: m2_errorInvalid for a null argument; m2_errorUnsupported when this CPU cannot run the library's SIMD backend; m2_errorInvalid for a bad cookie; m2_errorVersion for a def built for another binary interface; m2_errorInvalid for the rest of the def (a capacity below 1, an allocator with one function set, a NaN, a value outside its field's domain); m2_errorLimit for a value past a published bound (a gravity past M2_ACCEL_LIMIT, a particle radius below M2_MIN_PARTICLE_RADIUS, a particle parameter past its bound); m2_errorCapacity, before anything is allocated, when the world's snapshot size does not fit a size_t (only on a 32-bit target), and when the allocator refuses or a size does not fit.

Thread safety. Safe from any thread.

void m2DestroyWorld(m2World* world);

Destroys a world and everything in it, and returns its memory to its allocator. Ids into it become meaningless. The world empties before its first free: the allocator's free hook may read it back and finds every id stale and every list empty, and every writer it calls is refused as busy. This call is a writer too: host code the world runs (a task hook, a debug draw callback, the allocator) that calls it counts one misuse, and the world stays.

Parameters:

Thread safety. Safe from any thread; a world is used by one thread at a time.

bool m2World_Validate(const m2World* world);

Walks the whole world and checks its invariants: every live position, velocity and particle finite, every body rotation of unit length, every joint and jelly net attached to live objects, the counts consistent, the pairs in key order. It costs a full walk, so call it from debug paths; building with -DMAUL2D_VALIDATE=ON asserts it after every step.

Parameters:

Returns: True when the world is sound; false at the first broken invariant and for a null world. It never stops the program.

Thread safety. Safe from any thread; a world is used by one thread at a time, or by several readers at once.

void m2World_SetGravity(m2World* world, m2Vec2 gravity);

Sets the gravity and wakes every sleeping dynamic body: a stack must not float in a world that turned upside down. A gravity beyond M2_ACCEL_LIMIT on either axis counts one misuse. Journaled.

Parameters:

Thread safety. Safe from any thread; a world is used by one thread at a time.

m2Vec2 m2World_GetGravity(const m2World* world);

Reads the gravity.

Parameters:

Returns: The acceleration; zero for a null world.

Thread safety. Safe from any thread; a world is used by one thread at a time, or by several readers at once.

void m2World_SetWind(m2World* world, m2Vec2 velocity, float linearDrag);

Sets the global wind. Each step every awake dynamic body feels -linearDrag * shapeArea * (bodyVelocity - windVelocity), added like gravity, so larger bodies catch more wind and everything drifts toward the wind's speed. Unlike gravity it wakes no sleeper, since wind is meant to gust. Regional wind is a water volume of density 0. A velocity beyond M2_SPEED_LIMIT on either axis or a drag outside 0 to M2_RATE_LIMIT counts one misuse. Journaled.

Parameters:

Thread safety. Safe from any thread; a world is used by one thread at a time.

void m2World_GetWind(const m2World* world, m2Vec2* velocityOut, float* linearDragOut);

Reads the global wind.

Parameters:

Thread safety. Safe from any thread; a world is used by one thread at a time, or by several readers at once.

m2ExplosionDef m2DefaultExplosionDef(void);

Returns an explosion def: radius 1, falloff 0.5, impulse 1, every category.

Returns: The default def; set the position.

Thread safety. Safe from any thread.

void m2World_Explode(m2World* world, const m2ExplosionDef* def);

Sets off an explosion. Each body's velocity saturates at M2_SPEED_LIMIT per axis. A bad def counts one misuse. Journaled as one operation.

Parameters:

Thread safety. Safe from any thread; a world is used by one thread at a time.

void m2World_EnableSleep(m2World* world, bool flag);

Allows or forbids sleep in the whole world. Forbidding wakes every sleeping dynamic body. Journaled.

Parameters:

Thread safety. Safe from any thread; a world is used by one thread at a time.

bool m2World_IsSleepEnabled(const m2World* world);

Tells whether the world allows sleep.

Parameters:

Returns: True when allowed; false for a null world.

Thread safety. Safe from any thread; a world is used by one thread at a time, or by several readers at once.

void m2World_Draw(const m2World* world, const m2DebugDraw* draw);

Draws the world through the callbacks. The callbacks are host code the world runs: they may read the world, never change it.

Parameters:

Thread safety. Safe from any thread; a world is used by one thread at a time, or by several readers at once.

double m2World_GetKineticEnergy(const m2World* world);

Sums the kinetic energy of the awake dynamic bodies, in f64 and in body order, so two worlds given the same calls report the same bits. Sleeping bodies add nothing.

Parameters:

Returns: The energy, joules; 0 for a null world.

Thread safety. Safe from any thread; a world is used by one thread at a time, or by several readers at once.

m2Profile m2World_GetProfile(const m2World* world);

Reads the times of the last step.

Parameters:

Returns: The times; zeroed for a null world.

Thread safety. Safe from any thread; a world is used by one thread at a time, or by several readers at once.

m2Counters m2World_GetCounters(const m2World* world);

Reads the counters.

Parameters:

Returns: The counters; zeroed for a null world.

Thread safety. Safe from any thread; a world is used by one thread at a time, or by several readers at once.

M2_NODISCARD M2_API m2Result m2World_Step(m2World* world, float dt, int32_t substepCount);

Advances the simulation. Identical worlds given identical calls reach identical bits on every supported platform. Feed the same dt every step: 1/60 with 4 substeps is the tuned default. A refused step changes nothing, and every refusal but a null world's counts one misuse. Journaled.

Parameters:

Returns: m2_success; m2_errorInvalid for a null world, a dt that is NaN or 0 or below, or a substep count below 1; m2_errorLimit for a dt outside M2_MIN_STEP to M2_STEP_LIMIT or a substep count above M2_MAX_SUBSTEPS; m2_errorBusy from host code the world is running.

Thread safety. Safe from any thread; a world is used by one thread at a time.

uint64_t m2World_GetStepCount(const m2World* world);

Counts the steps taken since creation; a restore brings back the snapshot's count.

Parameters:

Returns: The count; 0 for a null world.

Thread safety. Safe from any thread; a world is used by one thread at a time, or by several readers at once.

int64_t m2World_GetSnapshotSize(const m2World* world);

Returns the size of this world's snapshot. It is fixed for the world's life and fits a size_t.

Parameters:

Returns: The size in bytes; 0 for a null world.

Thread safety. Safe from any thread; a world is used by one thread at a time, or by several readers at once.

M2_NODISCARD M2_API m2Result m2World_Snapshot(const m2World* world, void* bufferOut, int64_t capacity, int64_t* bytesOut);

Writes the whole simulation state into caller memory. A failed snapshot zeroes the buffer, so it never holds what looks like part of a snapshot: a host that keeps a ring of snapshot buffers sizes them with m2World_GetSnapshotSize first, or snapshots into a spare buffer and swaps it in on success.

Parameters:

Returns: m2_success; m2_errorInvalid for a null argument or a negative capacity; m2_errorCapacity when capacity is below m2World_GetSnapshotSize.

Thread safety. Safe from any thread; a world is used by one thread at a time, or by several readers at once.

M2_NODISCARD M2_API m2Result m2World_Restore(m2World* world, const void* buffer, int64_t size);

Restores a snapshot of a world with the same shape: the same capacities and the same particle radius in its def. Everything, bodies, id pools and the step count included, returns to the snapshot's instant, bit for bit, and the event streams clear. End events a destroy or a disable queued for the next step are state: the snapshot carries them, and the next step delivers them. Only the minor version that wrote a snapshot reads it (M2_ABI_VERSION). The buffer is checked before any byte lands: a header from another minor version, build or world shape, an index or count out of range, flags that are not flags and non-finite state are refused, and the world stays as it was. The checks make every index safe; they do not rebuild every structural invariant (tree shape, list links), so restore only snapshots this library wrote. A restore while recording is recorded.

Parameters:

Returns: m2_success; m2_errorVersion for a snapshot another minor version or build wrote, and m2_errorFormat for other bytes that fail the checks, a world of another shape included, neither of which counts misuse; m2_errorInvalid for a null buffer, which counts one; m2_errorBusy from host code the world is running.

Thread safety. Safe from any thread; a world is used by one thread at a time.

uint64_t m2World_Hash(const m2World* world);

Hashes every piece of state the step reads and a call can change: the world's gravity, wind, sleeping switch and step count; every live body, shape, chain, joint, particle and water volume, each field keyed by its slot (pose, velocities, forces, mass data, damping, gravity scale, locks, dominance, sleep and enable state; geometry, materials, filter and sensor flag; joint anchors, lengths, ranges, motor, spring and break settings, targets and impulses; particle and volume settings); the contact pairs, their touching flags and manifolds; each shape's fat box and moved flag in the broadphase, from which the next pairs are found; the particle springs and triads; and each id pool's free order and generations, which decide where the next object lands and the id it gets. Two worlds with the same hash step on to the same bits. Not hashed: user data, events, and the broadphase tree's shape, which decides only the order a query meets the boxes in. The value changes between library versions. Present in every build: it is how a divergence is found.

Parameters:

Returns: The hash; 0 for a null world.

Thread safety. Safe from any thread; a world is used by one thread at a time, or by several readers at once.

m2MemoryUsage m2World_GetMemoryUsage(const m2World* world);

Reports a world's memory footprint. It is fixed for the world's life: pools never grow, step scratch lives in them, and a journal's buffer is the host's.

Parameters:

Returns: The footprint; zeroed for a null world.

Thread safety. Safe from any thread; a world is used by one thread at a time, or by several readers at once.

m2WorldHashParts m2World_GetHashParts(const m2World* world);

Hashes each part of the world. Compare two runs part by part each step: the step where a part first differs names the moment, and the part names the subsystem. The values are diagnostics: they change between library versions, and m2World_Hash is not built from them.

Parameters:

Returns: The hashes; zeroed for a null world.

Thread safety. Safe from any thread; a world is used by one thread at a time, or by several readers at once.

m2WaterVolumeDef m2DefaultWaterVolumeDef(void);

Returns a water volume def: density 2, linear drag 1, angular drag 0.5, no flow, and a box of one point at the origin, which m2CreateWaterVolume refuses until the bounds are set.

Returns: The default def; set the bounds and the surface.

Thread safety. Safe from any thread.

M2_NODISCARD M2_API m2Result m2CreateWaterVolume(m2World* world, const m2WaterVolumeDef* def, m2WaterVolumeId* volumeOut);

Creates a water volume. Journaled.

Parameters:

Returns: m2_success; m2_errorInvalid for a bad def, a box with no area among them (upper at or below lower on either axis, which can never hold a body), or a null argument; m2_errorLimit for a value past its published bound; m2_errorCapacity when the volume pool is full, a pool of 0 included, which counts no misuse; m2_errorBusy from host code the world is running.

Thread safety. Safe from any thread; a world is used by one thread at a time.

M2_NODISCARD M2_API m2Result m2DestroyWaterVolume(m2World* world, m2WaterVolumeId volumeId);

Destroys a water volume. Journaled.

Parameters:

Returns: m2_success; m2_errorInvalid for a null world; m2_errorStale when it is already gone; m2_errorBusy from host code the world is running.

Thread safety. Safe from any thread; a world is used by one thread at a time.

bool m2WaterVolume_IsValid(const m2World* world, m2WaterVolumeId volumeId);

Tells whether a volume id names a live volume. Counts no misuse.

Parameters:

Returns: True for a live volume.

Thread safety. Safe from any thread; a world is used by one thread at a time, or by several readers at once.

void m2WaterVolume_SetSurface(m2World* world, m2WaterVolumeId volumeId, double surface);

Moves a volume's waterline: a rising tide, a draining tank. A stale id or a non-finite surface counts one misuse. Journaled.

Parameters:

Thread safety. Safe from any thread; a world is used by one thread at a time.

double m2WaterVolume_GetSurface(const m2World* world, m2WaterVolumeId volumeId);

Reads a volume's waterline.

Parameters:

Returns: The waterline; 0 for a stale id.

Thread safety. Safe from any thread; a world is used by one thread at a time, or by several readers at once.

uint64_t m2WaterVolume_GetUserData(const m2World* world, m2WaterVolumeId volumeId);

Reads a volume's game data.

Parameters:

Returns: The value; 0 for a stale id.

Thread safety. Safe from any thread; a world is used by one thread at a time, or by several readers at once.

void m2WaterVolume_SetUserData(m2World* world, m2WaterVolumeId volumeId, uint64_t userData);

Sets a volume's opaque game data, kept through snapshots and journals.

Parameters:

Thread safety. Safe from any thread; a world is used by one thread at a time.

int64_t m2World_GetJournalBaseSize(const m2World* world);

Returns a journal tape's fixed cost: its header and the snapshot it embeds. Size a tape as this plus room for the operations.

Parameters:

Returns: The size in bytes; 0 for a null world.

Thread safety. Safe from any thread; a world is used by one thread at a time, or by several readers at once.

M2_NODISCARD M2_API m2Result m2World_StartJournal(m2World* world, void* buffer, int64_t capacity);

Starts recording a journal into caller memory: a snapshot first, then every call that changes the world, the steps and the restores included, with floats as their exact bits. The buffer must stay valid until m2World_StopJournal.

Parameters:

Returns: m2_success; m2_errorInvalid for a null buffer, a negative capacity or one a size_t cannot hold; m2_errorCapacity when capacity is below m2World_GetJournalBaseSize; m2_errorState when the world is already recording; m2_errorBusy from host code the world is running.

Thread safety. Safe from any thread; a world is used by one thread at a time.

M2_NODISCARD M2_API m2Result m2World_StopJournal(m2World* world, int64_t* bytesOut);

Stops recording. Operations that did not fit make the tape unusable: it is never cut short silently.

Parameters:

Returns: m2_success; m2_errorInvalid for a null world or bytesOut; m2_errorCapacity when the operations overflowed the buffer; m2_errorState when the world was not recording; m2_errorBusy from host code the world is running.

Thread safety. Safe from any thread; a world is used by one thread at a time.

M2_NODISCARD M2_API m2Result m2World_ReplayJournal(m2World* world, const void* data, int64_t size);

Replays a tape: restores the snapshot it embeds and applies its operations through the same calls that recorded them. It is atomic: a tape that is malformed or truncated, that carries a value one of its calls refuses (a void call included), or that recreates an object under another id than the recording saw, is refused and the world stays as it was, its event streams and counters included; only misuse by host code the replay ran stays counted. Only the minor version that wrote a tape replays it (M2_ABI_VERSION); a tape from another minor version, build or world shape is refused too.

Parameters:

Returns: m2_success; m2_errorVersion for a tape, or its embedded snapshot, another minor version or build wrote, and m2_errorFormat for another tape that fails its checks (a record the world refuses included), neither of which counts misuse; m2_errorInvalid for a null data pointer or a size a size_t cannot hold, which counts one; m2_errorState while the world is recording; m2_errorBusy from host code the world is running; m2_errorCapacity when the allocator cannot give the replay its scratch memory.

Thread safety. Safe from any thread; a world is used by one thread at a time.