Skip to content

@aosengine/physics-jolt ​

Interfaces ​

BodyArgs ​

Everything needed to create one body. Mirrors the WIT add-body command, minus the entity handle, which the host module owns.

Properties ​

angularDamping? ​
ts
optional angularDamping?: number;

Angular velocity damping per second. Defaults to 0.05.

dims ​
ts
dims: readonly number[];

Shape dimensions, in metres: box half-extents [hx, hy, hz]; sphere [radius]; capsule and cylinder [radius, halfHeight]. Ignored for mesh and convex.

flags? ​
ts
optional flags?: BodyFlags;

Optional switches.

friction ​
ts
friction: number;

Coulomb friction, 0..1.

geometry? ​
ts
optional geometry?: Shape;

Prebuilt shape for mesh and convex bodies, from meshShapeFromGeometry or convexHullFromPoints. The world takes its own reference, so one shape can back many bodies.

id ​
ts
id: number;

Guest-minted handle. Must not already exist in this world.

kind ​
ts
kind: BodyKind;

Body class.

layer ​
ts
layer: number;

What this body is, as a bitset.

linearDamping? ​
ts
optional linearDamping?: number;

Linear velocity damping per second. Defaults to 0.05, Jolt's own default.

mask ​
ts
mask: number;

What this body collides with, as a bitset of other bodies' layers.

mass ​
ts
mass: number;

Kilograms. Ignored for static, kinematic and character bodies.

position ​
ts
position: Vec3;

World-space position of the body origin.

restitution ​
ts
restitution: number;

Bounciness, 0..1.

rotation ​
ts
rotation: Quat;

World-space orientation, xyzw.

shape ​
ts
shape: ShapeKind;

Shape family. mesh and convex additionally need BodyArgs.geometry.


BodyFlags ​

Per-body switches. Mirrors WIT body-flags.

Properties ​

ccd? ​
ts
optional ccd?: boolean;

Use continuous collision detection (linear cast).

lockRotation? ​
ts
optional lockRotation?: boolean;

Lock all rotation. The usual choice for a capsule.

noSleep? ​
ts
optional noSleep?: boolean;

Never let the solver put this body to sleep.

reportContacts? ​
ts
optional reportContacts?: boolean;

Emit this body's contacts from PhysicsWorld.drainContacts.

Off by default. A world of resting crates generates a manifold per touching pair per step whether or not anyone reads it, and turning those into records costs a wasm crossing each. Ask for contacts on the handful of bodies whose collisions the game reacts to — the player, projectiles, triggers — and the rest cost nothing at all.

reportStay? ​
ts
optional reportStay?: boolean;

Also emit the stay phase, once per step for as long as the pair touches.

Off by default, and only meaningful together with BodyFlags.reportContacts: begin and end are edges, so a game that tracks "am I touching this" needs no more than those two. stay is the expensive one — a box resting on the floor emits it sixty times a second forever — so it is separately opt-in, for the rare system that wants a live contact point (a grinding-sparks effect, a pressure plate that weighs what is on it).

sensor? ​
ts
optional sensor?: boolean;

Trigger volume: generates contacts but no collision response.


ContactRecord ​

One contact event. Instances are pooled by the world and by the caller's out array; copy anything you want to keep past the next drainContacts.

Properties ​

a ​
ts
a: number;

Guest body id of the first body.

b ​
ts
b: number;

Guest body id of the second body.

impulse ​
ts
impulse: number;

Estimated normal impulse, newton-seconds. Jolt does not hand the solved impulse to a contact listener, so this is reduced mass * closing speed measured before the solve: right in order of magnitude, good enough to scale an impact sound, not a physical measurement.

nx ​
ts
nx: number;

Contact normal pointing from a towards b, x. Zero for end.

ny ​
ts
ny: number;

Contact normal, y.

nz ​
ts
nz: number;

Contact normal, z.

phase ​
ts
phase: ContactPhase;

Whether the contact started, continued or ended.

px ​
ts
px: number;

World-space contact point, x. Zero for end.

py ​
ts
py: number;

World-space contact point, y. Zero for end.

pz ​
ts
pz: number;

World-space contact point, z. Zero for end.


ConvexHullOptions ​

Options for convexHullFromPoints.

Properties ​

hullTolerance? ​
ts
optional hullTolerance?: number;

Distance, in metres, below which the hull builder merges coplanar faces.

maxConvexRadius? ​
ts
optional maxConvexRadius?: number;

Maximum convex radius used to round the hull off.


LayerOptions ​

Tuning for the object-layer slot table.

Properties ​

maxObjectLayers? ​
ts
optional maxObjectLayers?: number;

How many distinct Jolt object layers the world may hand out. Half of them back static bodies and half back moving bodies, so the default of 64 allows 32 distinct (layer, mask) pairs on each side.


LoadJoltOptions ​

Options for loadJolt.

Extended by ​

Properties ​

wasmUrl? ​
ts
optional wasmUrl?: string;

Where jolt-physics.wasm.wasm is served from.

Omit it and the loader asks the host for jolt-physics/jolt-physics.wasm.wasm via import.meta.resolve, which is correct under node and under any bundler that keeps an import map. In a plain browser build, pass the URL your bundler minted for the asset:

ts
import wasmUrl from 'jolt-physics/jolt-physics.wasm.wasm?url';

MeshShapeOptions ​

Options shared by the geometry shape builders.

Properties ​

maxTrianglesPerLeaf? ​
ts
optional maxTrianglesPerLeaf?: number;

Triangles per BVH leaf. Higher builds faster and uses less memory, lower queries faster. Jolt's own default is 8.


PhysicsOptions ​

Options for physics.

Extends ​

Properties ​

gravity? ​
ts
optional gravity?: Vec3;

Gravity in metres per second squared. Defaults to [0, -9.81, 0].

Inherited from ​

PhysicsWorldOptions.gravity

layers? ​
ts
optional layers?: LayerOptions;

Object-layer slot tuning. See LayerOptions.

Inherited from ​

PhysicsWorldOptions.layers

maxBodies? ​
ts
optional maxBodies?: number;

Hard ceiling on simultaneous bodies. Defaults to 4096.

Inherited from ​

PhysicsWorldOptions.maxBodies

maxBodyPairs? ​
ts
optional maxBodyPairs?: number;

Maximum body pairs the broad phase tracks. Defaults to maxBodies * 2.

Inherited from ​

PhysicsWorldOptions.maxBodyPairs

maxContactConstraints? ​
ts
optional maxContactConstraints?: number;

Maximum contact constraints per step. Defaults to maxBodies.

Inherited from ​

PhysicsWorldOptions.maxContactConstraints

maxContactsPerStep? ​
ts
optional maxContactsPerStep?: number;

Contact records the world keeps for one step. Defaults to 256.

The pool is allocated up front and never grows, because growing it would allocate inside Jolt's own Step(). A step that produces more reportable contacts than this drops the surplus and warns once — raise the ceiling if the game really does want that many in a single step.

Inherited from ​

PhysicsWorldOptions.maxContactsPerStep

substeps? ​
ts
optional substeps?: number;

Collision steps per fixed step. One is right for a 60 Hz simulation; raise it only if fast bodies tunnel and flags.ccd was not enough.

wasmUrl? ​
ts
optional wasmUrl?: string;

Where jolt-physics.wasm.wasm is served from.

Omit it and the loader asks the host for jolt-physics/jolt-physics.wasm.wasm via import.meta.resolve, which is correct under node and under any bundler that keeps an import map. In a plain browser build, pass the URL your bundler minted for the asset:

ts
import wasmUrl from 'jolt-physics/jolt-physics.wasm.wasm?url';
Inherited from ​

LoadJoltOptions.wasmUrl


PhysicsService ​

The physics service, published by the engine under the id physics.

It is the PhysicsWorld plus the debug view, so engine.get('physics').raycast(...) works directly.

Extends ​

Properties ​

bodyCount ​
ts
readonly bodyCount: number;

Number of bodies currently in the world.

Inherited from ​

PhysicsWorld.bodyCount

movingBodyCount ​
ts
readonly movingBodyCount: number;

Rows PhysicsWorld.readBodies would write: the non-static, enabled bodies. Size the destination from this and readBodies never has to be called twice.

Inherited from ​

PhysicsWorld.movingBodyCount

revision ​
ts
readonly revision: number;

Bumped whenever the set of bodies changes: add, remove or enable/disable. Debug views rebuild their geometry when this moves and not otherwise.

Inherited from ​

PhysicsWorld.revision

Methods ​

addBody() ​
ts
addBody(args): void;

Create a body. See BodyArgs.

Parameters ​
ParameterType
argsBodyArgs
Returns ​

void

Inherited from ​

PhysicsWorld.addBody

applyImpulse() ​
ts
applyImpulse(
   id, 
   impulse, 
   point?
): void;

Apply an impulse, at the centre of mass unless point says otherwise.

Parameters ​
ParameterType
idnumber
impulseVec3
point?Vec3
Returns ​

void

Inherited from ​

PhysicsWorld.applyImpulse

bodyIds() ​
ts
bodyIds(): readonly number[];

Snapshot of the live body ids, cheap and non-allocating to iterate.

Returns ​

readonly number[]

Inherited from ​

PhysicsWorld.bodyIds

debugWireframe() ​
ts
debugWireframe(scene): void;

Attach or detach a wireframe debug view.

Pass a scene to attach, null to detach and free the geometry. The line buffer is rebuilt only when the set of bodies changes; the per-frame cost is a transform of the cached corners in update, with no allocation.

Parameters ​
ParameterTypeDescription
sceneScene<Object3DEventMap> | nullThe scene to draw into, or null to remove the view.
Returns ​

void

dispose() ​
ts
dispose(): void;

Free every Jolt object this world owns.

Returns ​

void

Inherited from ​

PhysicsWorld.dispose

drainContacts() ​
ts
drainContacts(out): number;

Move queued contacts into out.

Parameters ​
ParameterType
outContactRecord[]
Returns ​

number

Inherited from ​

PhysicsWorld.drainContacts

groundState() ​
ts
groundState(id): GroundState;

What a character body is standing on, as of the last step.

Parameters ​
ParameterType
idnumber
Returns ​

GroundState

Inherited from ​

PhysicsWorld.groundState

moveCharacter() ​
ts
moveCharacter(id, desiredVelocity): void;

Set the desired world-space velocity of a character body for the next step.

Parameters ​
ParameterType
idnumber
desiredVelocityVec3
Returns ​

void

Inherited from ​

PhysicsWorld.moveCharacter

overlapSphere() ​
ts
overlapSphere(
   center, 
   radius, 
   mask
): number[];

Guest body ids overlapping a sphere, nearest first.

Parameters ​
ParameterType
centerVec3
radiusnumber
masknumber
Returns ​

number[]

Inherited from ​

PhysicsWorld.overlapSphere

overlapSphereInto() ​
ts
overlapSphereInto(
   center, 
   radius, 
   mask, 
   out
): number;

Zero-allocation form of PhysicsWorld.overlapSphere.

Parameters ​
ParameterType
centerVec3
radiusnumber
masknumber
outUint32Array
Returns ​

number

Inherited from ​

PhysicsWorld.overlapSphereInto

raycast() ​
ts
raycast(
   origin, 
   direction, 
   maxDistance, 
   mask
): RayHit | null;

Closest hit along a ray, or null. The returned object is reused.

Parameters ​
ParameterType
originVec3
directionVec3
maxDistancenumber
masknumber
Returns ​

RayHit | null

Inherited from ​

PhysicsWorld.raycast

raycastBatch() ​
ts
raycastBatch(
   rays, 
   mask, 
   out
): number;

Many rays, one call.

Parameters ​
ParameterType
raysFloat32Array
masknumber
outFloat32Array
Returns ​

number

Inherited from ​

PhysicsWorld.raycastBatch

readBodies() ​
ts
readBodies(out): number;

Write stride-15 body rows into out. See PhysicsWorld.readBodies.

Parameters ​
ParameterType
outFloat32Array
Returns ​

number

Inherited from ​

PhysicsWorld.readBodies

readBodyBounds() ​
ts
readBodyBounds(
   id, 
   out, 
   offset
): boolean;

Local-space bounds and world transform of a body, for debug drawing.

Parameters ​
ParameterType
idnumber
outFloat32Array
offsetnumber
Returns ​

boolean

Inherited from ​

PhysicsWorld.readBodyBounds

readBodyPose() ​
ts
readBodyPose(
   id, 
   out, 
   offset
): boolean;

World transform of a body alone, when its bounds are already known.

Parameters ​
ParameterType
idnumber
outFloat32Array
offsetnumber
Returns ​

boolean

Inherited from ​

PhysicsWorld.readBodyPose

removeBody() ​
ts
removeBody(id): void;

Destroy a body and release its shape reference. Unknown ids are ignored.

Parameters ​
ParameterType
idnumber
Returns ​

void

Inherited from ​

PhysicsWorld.removeBody

setEnabled() ​
ts
setEnabled(id, enabled): void;

Take a body out of the simulation without destroying it, or put it back.

Parameters ​
ParameterType
idnumber
enabledboolean
Returns ​

void

Inherited from ​

PhysicsWorld.setEnabled

setTransform() ​
ts
setTransform(
   id, 
   position, 
   rotation, 
   teleport?
): void;

Teleport a body. Velocities are left alone unless teleport says otherwise.

Parameters ​
ParameterTypeDescription
idnumberGuest body handle.
positionVec3New world-space position.
rotationQuatNew world-space orientation, xyzw.
teleport?booleanTrue for a hard cut: the body's linear and angular velocities are zeroed too, and a character forgets the velocity it was asked for. False (the default) moves the body and lets it keep moving.
Returns ​

void

Inherited from ​

PhysicsWorld.setTransform

setVelocity() ​
ts
setVelocity(
   id, 
   linear, 
   angular
): void;

Set linear and angular velocity.

Parameters ​
ParameterType
idnumber
linearVec3
angularVec3
Returns ​

void

Inherited from ​

PhysicsWorld.setVelocity

step() ​
ts
step(dt, substeps?): number;

Advance the simulation.

Parameters ​
ParameterType
dtnumber
substeps?number
Returns ​

number

Inherited from ​

PhysicsWorld.step


PhysicsSteppedEvent ​

What physics:stepped carries.

The object is reused, so a listener must read it and not retain it — the event fires inside fixedUpdate and allocating one of these per step is the thing the whole phase is about.

Example ​

ts
import type { PhysicsSteppedEvent } from '@aosengine/physics-jolt';

let rows = 0;
engine.events.on('physics:stepped', (e: PhysicsSteppedEvent) => {
  rows = e.movingBodyCount; // read it now; the object is rewritten next step
});

Properties ​

contacts ​
ts
contacts: number;

Contact events this step queued for drainContacts.

dt ​
ts
dt: number;

Length of the step that just ran, in seconds.

movingBodyCount ​
ts
movingBodyCount: number;

Rows the next PhysicsService.readBodies will fill.


PhysicsWorld ​

A live Jolt simulation. Everything the engine's physics command stream and synchronous query imports need, and nothing else.

Extended by ​

Properties ​

bodyCount ​
ts
readonly bodyCount: number;

Number of bodies currently in the world.

movingBodyCount ​
ts
readonly movingBodyCount: number;

Rows PhysicsWorld.readBodies would write: the non-static, enabled bodies. Size the destination from this and readBodies never has to be called twice.

revision ​
ts
readonly revision: number;

Bumped whenever the set of bodies changes: add, remove or enable/disable. Debug views rebuild their geometry when this moves and not otherwise.

Methods ​

addBody() ​
ts
addBody(args): void;

Create a body. See BodyArgs.

Parameters ​
ParameterType
argsBodyArgs
Returns ​

void

applyImpulse() ​
ts
applyImpulse(
   id, 
   impulse, 
   point?
): void;

Apply an impulse, at the centre of mass unless point says otherwise.

Parameters ​
ParameterType
idnumber
impulseVec3
point?Vec3
Returns ​

void

bodyIds() ​
ts
bodyIds(): readonly number[];

Snapshot of the live body ids, cheap and non-allocating to iterate.

Returns ​

readonly number[]

dispose() ​
ts
dispose(): void;

Free every Jolt object this world owns.

Returns ​

void

drainContacts() ​
ts
drainContacts(out): number;

Move queued contacts into out.

Parameters ​
ParameterType
outContactRecord[]
Returns ​

number

groundState() ​
ts
groundState(id): GroundState;

What a character body is standing on, as of the last step.

Parameters ​
ParameterType
idnumber
Returns ​

GroundState

moveCharacter() ​
ts
moveCharacter(id, desiredVelocity): void;

Set the desired world-space velocity of a character body for the next step.

Parameters ​
ParameterType
idnumber
desiredVelocityVec3
Returns ​

void

overlapSphere() ​
ts
overlapSphere(
   center, 
   radius, 
   mask
): number[];

Guest body ids overlapping a sphere, nearest first.

Parameters ​
ParameterType
centerVec3
radiusnumber
masknumber
Returns ​

number[]

overlapSphereInto() ​
ts
overlapSphereInto(
   center, 
   radius, 
   mask, 
   out
): number;

Zero-allocation form of PhysicsWorld.overlapSphere.

Parameters ​
ParameterType
centerVec3
radiusnumber
masknumber
outUint32Array
Returns ​

number

raycast() ​
ts
raycast(
   origin, 
   direction, 
   maxDistance, 
   mask
): RayHit | null;

Closest hit along a ray, or null. The returned object is reused.

Parameters ​
ParameterType
originVec3
directionVec3
maxDistancenumber
masknumber
Returns ​

RayHit | null

raycastBatch() ​
ts
raycastBatch(
   rays, 
   mask, 
   out
): number;

Many rays, one call.

Parameters ​
ParameterType
raysFloat32Array
masknumber
outFloat32Array
Returns ​

number

readBodies() ​
ts
readBodies(out): number;

Write stride-15 body rows into out. See PhysicsWorld.readBodies.

Parameters ​
ParameterType
outFloat32Array
Returns ​

number

readBodyBounds() ​
ts
readBodyBounds(
   id, 
   out, 
   offset
): boolean;

Local-space bounds and world transform of a body, for debug drawing.

Parameters ​
ParameterType
idnumber
outFloat32Array
offsetnumber
Returns ​

boolean

readBodyPose() ​
ts
readBodyPose(
   id, 
   out, 
   offset
): boolean;

World transform of a body alone, when its bounds are already known.

Parameters ​
ParameterType
idnumber
outFloat32Array
offsetnumber
Returns ​

boolean

removeBody() ​
ts
removeBody(id): void;

Destroy a body and release its shape reference. Unknown ids are ignored.

Parameters ​
ParameterType
idnumber
Returns ​

void

setEnabled() ​
ts
setEnabled(id, enabled): void;

Take a body out of the simulation without destroying it, or put it back.

Parameters ​
ParameterType
idnumber
enabledboolean
Returns ​

void

setTransform() ​
ts
setTransform(
   id, 
   position, 
   rotation, 
   teleport?
): void;

Teleport a body. Velocities are left alone unless teleport says otherwise.

Parameters ​
ParameterTypeDescription
idnumberGuest body handle.
positionVec3New world-space position.
rotationQuatNew world-space orientation, xyzw.
teleport?booleanTrue for a hard cut: the body's linear and angular velocities are zeroed too, and a character forgets the velocity it was asked for. False (the default) moves the body and lets it keep moving.
Returns ​

void

setVelocity() ​
ts
setVelocity(
   id, 
   linear, 
   angular
): void;

Set linear and angular velocity.

Parameters ​
ParameterType
idnumber
linearVec3
angularVec3
Returns ​

void

step() ​
ts
step(dt, substeps?): number;

Advance the simulation.

Parameters ​
ParameterType
dtnumber
substeps?number
Returns ​

number


PhysicsWorldOptions ​

Options for createPhysicsWorld.

Extended by ​

Properties ​

gravity? ​
ts
optional gravity?: Vec3;

Gravity in metres per second squared. Defaults to [0, -9.81, 0].

layers? ​
ts
optional layers?: LayerOptions;

Object-layer slot tuning. See LayerOptions.

maxBodies? ​
ts
optional maxBodies?: number;

Hard ceiling on simultaneous bodies. Defaults to 4096.

maxBodyPairs? ​
ts
optional maxBodyPairs?: number;

Maximum body pairs the broad phase tracks. Defaults to maxBodies * 2.

maxContactConstraints? ​
ts
optional maxContactConstraints?: number;

Maximum contact constraints per step. Defaults to maxBodies.

maxContactsPerStep? ​
ts
optional maxContactsPerStep?: number;

Contact records the world keeps for one step. Defaults to 256.

The pool is allocated up front and never grows, because growing it would allocate inside Jolt's own Step(). A step that produces more reportable contacts than this drops the surplus and warns once — raise the ceiling if the game really does want that many in a single step.


RayHit ​

One raycast result. The instance returned by raycast is reused.

Properties ​

body ​
ts
body: number;

Guest body id that was hit.

distance ​
ts
distance: number;

Distance from the ray origin, metres.

nx ​
ts
nx: number;

Surface normal at the hit, x.

ny ​
ts
ny: number;

Surface normal, y.

nz ​
ts
nz: number;

Surface normal, z.

px ​
ts
px: number;

Hit point, x.

py ​
ts
py: number;

Hit point, y.

pz ​
ts
pz: number;

Hit point, z.

Type Aliases ​

BodyKind ​

ts
type BodyKind = "static" | "dynamic" | "kinematic" | "character";

Body class. Mirrors WIT body-kind, except that WIT spells static as fixed because static is a WIT keyword.


ContactPhase ​

ts
type ContactPhase = "begin" | "stay" | "end";

Which side of a contact this record describes. Mirrors WIT contact-phase.


GroundState ​

ts
type GroundState = "on-ground" | "on-steep-ground" | "not-supported" | "in-air";

What a character controller is standing on.


JoltInstance ​

ts
type JoltInstance<K> = JoltModule[K] extends (...args) => infer R ? R : never;

Instance type of a Jolt class, e.g. JoltInstance<'Vec3'>.

Type Parameters ​

Type Parameter
K extends keyof JoltModule

JoltModule ​

ts
type JoltModule = Awaited<ReturnType<typeof initJolt>>;

The initialised Jolt wasm module: every Jolt class, enum constant and helper (destroy, wrapPointer, ...) hangs off this object.

It mirrors the Jolt C++ API one to one, so the C++ reference is the documentation.


JoltShape ​

ts
type JoltShape = JoltInstance<"Shape">;

A reference-counted Jolt collision shape.


Quat ​

ts
type Quat = readonly [number, number, number, number];

A unit quaternion in xyzw order, matching three.js and Jolt.


ShapeKind ​

ts
type ShapeKind = "box" | "sphere" | "capsule" | "cylinder" | "mesh" | "convex";

Collision shape family. Mirrors WIT shape-kind.


Vec3 ​

ts
type Vec3 = readonly [number, number, number];

A position or direction, in metres.

Variables ​

BODY_STRIDE ​

ts
const BODY_STRIDE: 15 = 15;

Floats per row in the buffer PhysicsWorld.readBodies fills.


PACKAGE ​

ts
const PACKAGE: "@aosengine/physics-jolt";

Package identity marker for @aosengine/physics-jolt.

Example ​

ts
import { PACKAGE } from '@aosengine/physics-jolt';

console.log(PACKAGE); // '@aosengine/physics-jolt'

RAY_HIT_STRIDE ​

ts
const RAY_HIT_STRIDE: 9 = 9;

Floats per row of the output buffer PhysicsWorld.raycastBatch fills.


RAY_STRIDE ​

ts
const RAY_STRIDE: 7 = 7;

Floats per row of the input buffer PhysicsWorld.raycastBatch reads.

Functions ​

convexHullFromPoints() ​

ts
function convexHullFromPoints(
   jolt, 
   points, 
   options?
): Shape;

Wrap a point cloud in its convex hull.

Unlike a mesh shape a convex hull can back a dynamic body, so this is the right shape for props lifted out of a splat scene: feed it the point cloud of the region you want solid and Jolt builds the tightest convex volume around it.

The returned shape carries one reference owned by you; see meshShapeFromGeometry.

Parameters ​

ParameterTypeDescription
jolttypeof JoltThe initialised Jolt module.
pointsFloat32ArrayPoint positions, stride 3 (x, y, z), in metres.
optionsConvexHullOptionsHull build tuning.

Returns ​

Shape

A shape with a reference count of one.

Throws ​

When there are fewer than four points or Jolt cannot build a hull.

Example ​

ts
import { convexHullFromPoints, loadJolt } from '@aosengine/physics-jolt';

const jolt = await loadJolt();
const cube = new Float32Array([
  -1, -1, -1, 1, -1, -1, -1, 1, -1, 1, 1, -1,
  -1, -1, 1, 1, -1, 1, -1, 1, 1, 1, 1, 1,
]);
const hull = convexHullFromPoints(jolt, cube);
hull.Release();

createContactRecord() ​

ts
function createContactRecord(): ContactRecord;

Allocate one pooled ContactRecord.

Returns ​

ContactRecord

A zeroed record.

Example ​

ts
import { createContactRecord, type ContactRecord } from '@aosengine/physics-jolt';

const pool: ContactRecord[] = [createContactRecord(), createContactRecord()];

createPhysicsWorld() ​

ts
function createPhysicsWorld(jolt, options?): PhysicsWorld;

Create a Jolt simulation.

Parameters ​

ParameterTypeDescription
jolttypeof JoltThe module from loadJolt.
optionsPhysicsWorldOptionsGravity, capacity and layer tuning.

Returns ​

PhysicsWorld

A live world. Call PhysicsWorld.dispose when done.

Example ​

ts
import { createPhysicsWorld, loadJolt } from '@aosengine/physics-jolt';

const world = createPhysicsWorld(await loadJolt(), { gravity: [0, -9.81, 0] });
world.addBody({
  id: 1,
  shape: 'box',
  dims: [10, 0.5, 10],
  position: [0, -0.5, 0],
  rotation: [0, 0, 0, 1],
  mass: 0,
  kind: 'static',
  layer: 0b10,
  mask: 0xffff,
  friction: 0.6,
  restitution: 0,
});
world.step(1 / 60);
world.dispose();

isJoltLoaded() ​

ts
function isJoltLoaded(): boolean;

Whether loadJolt has been called in this process.

Returns ​

boolean

True once the singleton exists, in flight or resolved.

Example ​

ts
import { isJoltLoaded, loadJolt } from '@aosengine/physics-jolt';

if (!isJoltLoaded()) await loadJolt();

loadJolt() ​

ts
function loadJolt(options?): Promise<typeof Jolt>;

Instantiate the Jolt wasm module, once per page.

The module is a process-wide singleton: every call returns the same promise, so registering two physics worlds costs one wasm instantiation. Passing a different wasmUrl after the singleton exists is a bug and throws rather than silently loading a second copy of the engine.

Parameters ​

ParameterTypeDescription
optionsLoadJoltOptionsWhere to fetch the wasm binary from.

Returns ​

Promise<typeof Jolt>

The initialised Jolt module.

Throws ​

When called again with a different wasmUrl.

Example ​

ts
import { loadJolt } from '@aosengine/physics-jolt';

const jolt = await loadJolt();
const up = new jolt.Vec3(0, 1, 0);
jolt.destroy(up); // Jolt never frees anything for you.

meshShapeFromGeometry() ​

ts
function meshShapeFromGeometry(
   jolt, 
   positions, 
   indices, 
   options?
): Shape;

Turn indexed triangle geometry into a Jolt MeshShape.

A MeshShape is a triangle soup with a BVH over it: it can only back a static body, which is exactly what splat-environment colliders and baked level geometry are. Building one is expensive (it constructs a tree), so build it once at load time and share it across every body that needs it.

The returned shape carries one reference owned by you. addBody takes its own reference, so the shape survives bodies being removed; call shape.Release() when the geometry itself is gone.

Parameters ​

ParameterTypeDescription
jolttypeof JoltThe initialised Jolt module.
positionsFloat32ArrayVertex positions, stride 3 (x, y, z), in metres.
indicesUint32ArrayTriangle indices, three per triangle, into positions.
optionsMeshShapeOptionsBuild tuning.

Returns ​

Shape

A shape with a reference count of one.

Throws ​

When the arrays are malformed or Jolt rejects the mesh.

Example ​

ts
import { loadJolt, meshShapeFromGeometry } from '@aosengine/physics-jolt';

const jolt = await loadJolt();
const positions = new Float32Array([0, 0, 0, 1, 0, 0, 0, 0, 1]);
const indices = new Uint32Array([0, 1, 2]);
const shape = meshShapeFromGeometry(jolt, positions, indices);
shape.Release();

physics() ​

ts
function physics(options?): EngineModule;

The Jolt physics EngineModule.

Registered in the engine's module list, it loads the Jolt wasm module in init, publishes the world as the physics service, and steps the simulation once per fixed step — never in update, because reading body state there gives you an interpolated pose, not a simulated one.

Parameters ​

ParameterTypeDescription
optionsPhysicsOptionsGravity, capacity, layer tuning and the wasm location.

Returns ​

EngineModule

A module to hand to createEngine({ modules: [...] }).

Example ​

ts
import { createEngine } from '@aosengine/core';
import { physics } from '@aosengine/physics-jolt';

const engine = await createEngine({
  canvas,
  manifest,
  modules: [physics({ gravity: [0, -9.81, 0] })],
});
const hit = engine.get('physics').raycast([0, 2, 0], [0, -1, 0], 10, 0xffff);