@threenative/physics API

Every public function and class in @threenative/physics. Thin Rapier physics bindings for ThreeNative games.

On this page

Generated from the engine's capability manifest: 8 functions and 11 classes. Each entry is the exported signature, what it is for, and a working example. Start with the package overview.

Area3D

class · import { Area3D } from "@threenative/physics"

Detect overlaps without turning the body into a moving collider.

ts
class Area3D

Deprecated

  • Constructor option world is deprecated; pass an IPhysicsContext as physics instead. Area3D itself is not deprecated.

Use it to

  • detect when an enemy enters a trigger area
  • react to a player entering a zone

Example

ts
const goal = new Area3D({ physics: ctx.physics, shape: CollisionShape3D.sphere(1.2), position: { x: 0, y: 0.5, z: -8 } });

Good to know

  • add the area to the physics context before stepping the world

Also found by

  • pick up item

attachSnowPhysics

function · import { attachSnowPhysics } from "@threenative/physics"

Drive a SnowField from real solved contacts. The binding creates the snow surface collider from the field's own canonical samples and keeps it in step with them, so a body lands on the surface a query would report. Each fixed step it reads the solver's persistent contacts — not collision start/stop events, which carry no point or load — deforms the snow only where a contact is supported and loaded downward, then republishes the surface before the next step. Airborne bodies, side contacts and unrelated colliders never deform anything. A dropped sphere settles on the surface it made; a pushed one rotates and carves a connected track without its transform being copied anywhere. Footprints come from the body's own collision shape and orientation unless the game supplies one. Contact load is impulse / deltaTime * loadScale: a solver impulse over a step, which estimates a contact force and is not measured. observe().loadProvenance says so.

ts
function attachSnowPhysics(options: ISnowPhysicsOptions): ISnowPhysicsBinding

Needs

  • @threenative/core/world SnowField as the surface it deforms

Use it to

  • leave footprints and tracks where physical bodies actually touch snow
  • let a dropped or pushed sphere carve and settle into deformable snow
  • make a crate, capsule or ball compress the surface it rests on

Example

ts
const snowPhysics = attachSnowPhysics({ physics: ctx.physics, snow, bodies: [ball] });
afterPhysics(ctx, (dt) => snowPhysics.step(dt));

Good to know

  • register rapier() before attaching, and call step once per fixed step after the physics step
  • the backend must expose persistent solved contacts and in-place shape refresh; one that does not fails at attach
  • verified on browser WebGPU and the native Linux desktop host; Android and iOS share the native seam but have not run it
  • automatic profiles cover sphere, box and capsule; any other shape needs an explicit footprint

Options

  • loadScale, supportNormal, colliderTolerance, deposition, wind, collisionLayer and collisionMask name the binding's own behaviour

boxFootprint

function · import { boxFootprint } from "@threenative/physics"

A rectangular contact: the face a box rests on, in the contact's own frame. Coverage is full across the face and fades just outside it; the bank rises beyond that.

ts
function boxFootprint(halfWidth: number, halfDepth: number): ISnowFootprint

Use it to

  • let a crate, platform or plank press a rectangular pit into snow
  • imprint a box's own footprint rather than a circle around it

Example

ts
const footprint = boxFootprint(0.4, 0.25);

Good to know

  • halfWidth and halfDepth are metres; rotation comes from the contact, not the footprint

buildStaticColliders

function · import { buildStaticColliders } from "@threenative/physics"

Build fixed trimesh bodies from the meshes a game authored in a scene root.

ts
function buildStaticColliders( context: IStaticColliderContext, root: Object3D, filter?: StaticColliderFilter, ): readonly RigidBody3D[]

Use it to

  • make the level I built stop the player
  • turn a cathedral or map scene into static collision

Example

ts
const colliders = buildStaticColliders(ctx, level, { predicate: (object) => object.name.startsWith("wall") });

Good to know

  • supply the game-owned predicate for decorative meshes; the helper throws when it selects nothing
  • generated bodies use trimesh geometry and world-space instance transforms

Buoyancy3D

class · import { Buoyancy3D } from "@threenative/physics"

Float a rigid body on a game-owned height source with fixed-step force ordering.

ts
class Buoyancy3D

Use it to

  • float a boat on waves
  • keep a hull above a moving water surface

Example

ts
new Buoyancy3D({ body, surface: field, hullPoints, density: 1_000, drag: 4 });

Good to know

  • supply hull points, density, drag, and the height source

Options

  • buoyancy disables force application while submergedFraction remains measured

capsuleFootprint

function · import { capsuleFootprint } from "@threenative/physics"

A stadium contact: a rectangle of half-length halfHeight and half-width radius, capped by two half-discs of radius. The shape a capsule lies on, so a knocked-over body sinks along a line instead of at a point. Coverage is full across the body's own width and fades just outside it, so the body's edge never rests on a half-pressed rim; the bank rises beyond that.

ts
function capsuleFootprint(halfHeight: number, radius: number): ISnowFootprint

Use it to

  • let a fallen capsule, limb or barrel leave a linear imprint in snow
  • give a capsule a shape-appropriate snow contact instead of a sphere's dot

Example

ts
const footprint = capsuleFootprint(0.5, 0.2);

Good to know

  • radius and halfHeight are metres and never grow with load

CharacterBody3D

class · import { CharacterBody3D } from "@threenative/physics"

Move a character body with collision-aware sliding.

ts
class CharacterBody3D

Deprecated

  • Constructor option world is deprecated; pass an IPhysicsContext as physics instead. CharacterBody3D itself is not deprecated.

Use it to

  • move an enemy or player through a level
  • keep a character from walking through walls

Example

ts
const body = new CharacterBody3D({ object: hero, physics: ctx.physics, shape: CollisionShape3D.capsule(0.5, 0.35) });

Good to know

  • use moveAndSlide inside the physics update

Also found by

  • raised platform gap hazard restart
  • enemy targets cooldown reload win condition
  • platformer double jump
  • first person
  • run jump coins goal

CollisionShape3D

class · import { CollisionShape3D } from "@threenative/physics"

Give a physics body a Three.js collision shape.

ts
class CollisionShape3D

Use it to

  • add a capsule or box collider to a character
  • configure the shape used by a rigid body

Example

ts
const shape = CollisionShape3D.capsule(0.5, 0.35);

Good to know

  • create shapes through the owning physics context

Also found by

  • passes through body
  • arena walls pickups

interactionGroups

function · import { interactionGroups } from "@threenative/physics"

Encode collision layers and masks for Rapier groups.

ts
function interactionGroups(layer: number, mask: number): number

Use it to

  • make an enemy collide with the world but not pickups
  • configure which physics layers interact

Example

ts
const groups = interactionGroups(1, 3);

Joint3D

class · import { Joint3D } from "@threenative/physics"

Connect two physics bodies with a Godot-style joint.

ts
class Joint3D

Deprecated

  • Constructor option world is deprecated; pass an IPhysicsContext as physics instead. Joint3D itself is not deprecated.

Use it to

  • constrain a rigid body to another body
  • build a hinge or pin mechanism
  • swing a pendulum, wrecking ball, or hinged door on a joint

Example

ts
const hinge = Joint3D.hinge({ physics: ctx.physics, bodyA: beam, bodyB: bob, anchorA: { x: 0, y: 0, z: 0 }, anchorB: { x: 0, y: 2.4, z: 0 }, axis: { x: 1, y: 0, z: 0 } });

Good to know

  • both bodies must belong to the same physics context

PhysicsDirectSpaceState3D

class · import { PhysicsDirectSpaceState3D } from "@threenative/physics"

Query the physics world without creating a body.

ts
class PhysicsDirectSpaceState3D

Use it to

  • raycast for visibility or aiming
  • find bodies inside a shape or point query

Example

ts
const space = new PhysicsDirectSpaceState3D(context);

Good to know

  • query results are bounded by the configured result limit

Also found by

  • hitscan camera

rapier

function · import { rapier } from "@threenative/physics"

Install the Rapier physics plugin and simulation backend.

ts
function rapier(options: IPhysicsOptions =

Use it to

  • add physics to a portable game
  • provide the context used by character and rigid bodies

Example

ts
const game = defineGame({ plugins: [rapier()] });

Good to know

  • place rapier() before recast() in the plugin list

RigidBody3D

class · import { RigidBody3D } from "@threenative/physics"

Simulate a dynamic or static rigid body.

ts
class RigidBody3D

Deprecated

  • Constructor option world is deprecated; pass an IPhysicsContext as physics instead. RigidBody3D itself is not deprecated.

Use it to

  • give a crate or prop physical motion
  • create a body that collides with a character
  • fire physical cannonballs that collide with ships or scenery
  • fire a cannonball projectile with cannon smoke particles
  • a bullet passes through a wall

Example

ts
const crate = new RigidBody3D({ object, physics: ctx.physics, shape: CollisionShape3D.box(1, 1, 1), mass: 8 });

Good to know

  • register rapier() in the game plugin list before using bodies

Options

  • continuousCollision: false opts one body out while body.continuousCollision still reports the effective setting

softBodyCollision

function · import { softBodyCollision } from "@threenative/physics"

Feed existing rigid-body boxes into SoftBody3D without inventing a second collider API.

ts
function softBodyCollision(...bodies: readonly RigidBody3D[]): ISoftBodyCollision

Use it to

  • stop a cloth flag, cape, or curtain at an existing physics wall
  • collide SoftBody3D with fixed box bodies

Example

ts
const cloth = new SoftBody3D(mesh, { ...options, collision: softBodyCollision(wall) });

Good to know

  • every body must use CollisionShape3D.box and retain its Three.js object transform
  • rotated boxes become conservative cloth-local axis-aligned bounds

VehicleBody3D

class · import { VehicleBody3D } from "@threenative/physics"

Drive a car on ray-cast suspension instead of faking speed and heading.

ts
class VehicleBody3D extends RigidBody3D

Use it to

  • drive a car, truck or bike around a track
  • make a vehicle roll over kerbs, brake into a corner or stop at a wall

Example

ts
const car = new VehicleBody3D({ object: chassis, physics: ctx.physics, shape: CollisionShape3D.box(1.6, 0.5, 3.6), mass: 900, wheels: [{ position: { x: 0.8, y: -0.15, z: -1.2 }, wheelRadius: 0.34, suspensionRestLength: 0.3, suspensionStiffness: 100, dampingCompression: 2.3, dampingRelaxation: 4.4, wheelFrictionSlip: 10.5, maxSuspensionTravel: 0.3, useAsSteering: true, useAsTraction: false }] });

Good to know

  • write engineForce, brake and steering every physics update; a car with no input does not move
  • suspensionStiffness is a frequency squared, not newtons per metre; 100 is a road car and 20 bottoms out

Options

  • a wheel ray never hits the chassis it hangs from, and it honours the chassis collision mask
  • continuousCollision is on for the chassis, so a fast car cannot tunnel through a wall

Also found by

  • racing car racing kart drift vehicle go-kart
  • suspension wheel traction tyre grip
  • accelerator pedal handbrake steering wheel
  • rescue respawn flip back on track

class · import { NavigationAgent3D } from "@threenative/physics/navigation"

Move an agent along a baked navmesh toward a target.

ts
class NavigationAgent3D

Use it to

  • enemy walks around a wall
  • enemy patrols a level and chases the player
  • enemy walks around a patrol path and chases the player when it sees them
  • enemy patrols and chases while avoiding obstacles
  • enemy chases the player with line of sight and obstacle avoidance
  • NPC walks to a destination
  • move crew around a ship deck

Example

ts
import { NavigationAgent3D } from "@threenative/physics/navigation";
import { Vector3 } from "three";
const agent = new NavigationAgent3D({ navigation, object });
agent.setTargetPosition(player.position);
const reusableTarget = new Vector3();
const next = agent.getNextPathPosition(reusableTarget);

Good to know

  • import NavigationAgent3D from exactly @threenative/physics/navigation; @threenative/physics is not a valid import for this symbol; use this capability instead of hand-written A*; requires recast() after rapier(), plus a baked NavigationRegion3D

Also found by

  • close engagement range

class · import { NavigationObstacle3D } from "@threenative/physics/navigation"

Add a non-moving crowd obstacle to a navmesh.

ts
class NavigationObstacle3D

Use it to

  • keep navigation agents away from a blocking prop
  • make a stationary character affect crowd avoidance

Example

ts
const obstacle = new NavigationObstacle3D({ navigation, object });

Good to know

  • create it after recast() and dispose it with the scene

class · import { NavigationRegion3D } from "@threenative/physics/navigation"

Bake walkable Three.js geometry into a navigation region.

ts
class NavigationRegion3D

Use it to

  • let enemies walk around level geometry
  • create the baked navmesh required by NavigationAgent3D

Example

ts
const region = new NavigationRegion3D({ navigation, meshes: [floor] });

Good to know

  • bake before creating agents or obstacles

recast

function · import { recast } from "@threenative/physics/navigation"

Install navmesh pathfinding and crowd avoidance.

ts
function recast(): NavigationPlugin

Use it to

  • enemy walks around a wall
  • NPC patrols a level and chases a player

Example

ts
const game = defineGame({ plugins: [rapier(), recast()] });

Good to know

  • requires rapier() earlier in the plugins array
View source on GitHub ↗