Skip to content

Class: PhysicsSystem

Defined in: packages/core/src/physics/physics-system.ts:136

Manages physics simulation using the Havok physics engine.

Remarks

  • Initializes Havok physics engine and creates a physics world with gravity.
  • Supports automatic physics shapes creation based on entity geometry when PhysicsShapeType.Auto is used.
  • Supports multiple collision shapes: Sphere, Box, Cylinder, ConvexHull, and TriMesh.
  • Synchronizes physics body transforms with Three.js Object3D positions and rotations using PhysicsBody.
  • Handles physics manipulations like applying forces and setting velocities in PhysicsManipulation.
  • Automatically cleans up physics resources when entities are removed.

Example

ts
// Add to your world to enable physics
world.addSystem(PhysicsSystem)

// Create a dynamic box that falls due to gravity
const box = world.createTransformEntity(boxMesh)
box.addComponent(PhysicsShape, {
  shape: PhysicsShapeType.Box,
  dimensions: [1, 1, 1]
})
box.addComponent(PhysicsBody, { state: PhysicsState.Dynamic })

See

Extends

  • System<{ gravity: { default: [number, number, number]; type: Vec3; }; }, { angularDampingOverrides: { required: (Component<{ _angularVelocity: { default: [number, number, number]; type: Vec3; }; _engineAngularDamping: { default: number; type: Float32; }; _engineBody: { default: number; type: Float64; }; _engineGravityFactor: { default: number; type: Float32; }; _engineLinearDamping: { default: number; type: Float32; }; _engineOffset: { default: number; type: Float64; }; _linearVelocity: { default: [number, number, number]; type: Vec3; }; angularDamping: { default: number; type: Float32; }; centerOfMass: { default: [number, number, number]; type: Vec3; }; gravityFactor: { default: number; type: Float32; }; linearDamping: { default: number; type: Float32; }; state: { default: "DYNAMIC"; enum: { Dynamic: "DYNAMIC"; Kinematic: "KINEMATIC"; Static: "STATIC"; }; type: Enum; }; }> | Component<{ _engineShape: { default: number; type: Float64; }; density: { default: number; type: Float32; }; dimensions: { default: [number, number, number]; type: Vec3; }; friction: { default: number; type: Float32; }; restitution: { default: number; type: Float32; }; shape: { default: "Auto"; enum: { Auto: "Auto"; Box: "Box"; Capsules: "Capsules"; ConvexHull: "ConvexHull"; Cylinder: "Cylinder"; Sphere: "Sphere"; TriMesh: "TriMesh"; }; type: Enum; }; }>)[]; where: ValuePredicate[]; }; gravityOverrides: { required: (Component<{ _angularVelocity: { default: [number, number, number]; type: Vec3; }; _engineAngularDamping: { default: number; type: Float32; }; _engineBody: { default: number; type: Float64; }; _engineGravityFactor: { default: number; type: Float32; }; _engineLinearDamping: { default: number; type: Float32; }; _engineOffset: { default: number; type: Float64; }; _linearVelocity: { default: [number, number, number]; type: Vec3; }; angularDamping: { default: number; type: Float32; }; centerOfMass: { default: [number, number, number]; type: Vec3; }; gravityFactor: { default: number; type: Float32; }; linearDamping: { default: number; type: Float32; }; state: { default: "DYNAMIC"; enum: { Dynamic: "DYNAMIC"; Kinematic: "KINEMATIC"; Static: "STATIC"; }; type: Enum; }; }> | Component<{ _engineShape: { default: number; type: Float64; }; density: { default: number; type: Float32; }; dimensions: { default: [number, number, number]; type: Vec3; }; friction: { default: number; type: Float32; }; restitution: { default: number; type: Float32; }; shape: { default: "Auto"; enum: { Auto: "Auto"; Box: "Box"; Capsules: "Capsules"; ConvexHull: "ConvexHull"; Cylinder: "Cylinder"; Sphere: "Sphere"; TriMesh: "TriMesh"; }; type: Enum; }; }>)[]; where: ValuePredicate[]; }; linearDampingOverrides: { required: (Component<{ _angularVelocity: { default: [number, number, number]; type: Vec3; }; _engineAngularDamping: { default: number; type: Float32; }; _engineBody: { default: number; type: Float64; }; _engineGravityFactor: { default: number; type: Float32; }; _engineLinearDamping: { default: number; type: Float32; }; _engineOffset: { default: number; type: Float64; }; _linearVelocity: { default: [number, number, number]; type: Vec3; }; angularDamping: { default: number; type: Float32; }; centerOfMass: { default: [number, number, number]; type: Vec3; }; gravityFactor: { default: number; type: Float32; }; linearDamping: { default: number; type: Float32; }; state: { default: "DYNAMIC"; enum: { Dynamic: "DYNAMIC"; Kinematic: "KINEMATIC"; Static: "STATIC"; }; type: Enum; }; }> | Component<{ _engineShape: { default: number; type: Float64; }; density: { default: number; type: Float32; }; dimensions: { default: [number, number, number]; type: Vec3; }; friction: { default: number; type: Float32; }; restitution: { default: number; type: Float32; }; shape: { default: "Auto"; enum: { Auto: "Auto"; Box: "Box"; Capsules: "Capsules"; ConvexHull: "ConvexHull"; Cylinder: "Cylinder"; Sphere: "Sphere"; TriMesh: "TriMesh"; }; type: Enum; }; }>)[]; where: ValuePredicate[]; }; manipluatedEntities: { required: (Component<{ _angularVelocity: { default: [number, number, number]; type: Vec3; }; _engineAngularDamping: { default: number; type: Float32; }; _engineBody: { default: number; type: Float64; }; _engineGravityFactor: { default: number; type: Float32; }; _engineLinearDamping: { default: number; type: Float32; }; _engineOffset: { default: number; type: Float64; }; _linearVelocity: { default: [number, number, number]; type: Vec3; }; angularDamping: { default: number; type: Float32; }; centerOfMass: { default: [number, number, number]; type: Vec3; }; gravityFactor: { default: number; type: Float32; }; linearDamping: { default: number; type: Float32; }; state: { default: "DYNAMIC"; enum: { Dynamic: "DYNAMIC"; Kinematic: "KINEMATIC"; Static: "STATIC"; }; type: Enum; }; }> | Component<{ angularVelocity: { default: [number, number, number]; type: Vec3; }; force: { default: [number, number, number]; type: Vec3; }; linearVelocity: { default: [number, number, number]; type: Vec3; }; }>)[]; where: ValuePredicate[]; }; physicsEntities: { required: (Component<{ _angularVelocity: { default: [number, number, number]; type: Vec3; }; _engineAngularDamping: { default: number; type: Float32; }; _engineBody: { default: number; type: Float64; }; _engineGravityFactor: { default: number; type: Float32; }; _engineLinearDamping: { default: number; type: Float32; }; _engineOffset: { default: number; type: Float64; }; _linearVelocity: { default: [number, number, number]; type: Vec3; }; angularDamping: { default: number; type: Float32; }; centerOfMass: { default: [number, number, number]; type: Vec3; }; gravityFactor: { default: number; type: Float32; }; linearDamping: { default: number; type: Float32; }; state: { default: "DYNAMIC"; enum: { Dynamic: "DYNAMIC"; Kinematic: "KINEMATIC"; Static: "STATIC"; }; type: Enum; }; }> | Component<{ _engineShape: { default: number; type: Float64; }; density: { default: number; type: Float32; }; dimensions: { default: [number, number, number]; type: Vec3; }; friction: { default: number; type: Float32; }; restitution: { default: number; type: Float32; }; shape: { default: "Auto"; enum: { Auto: "Auto"; Box: "Box"; Capsules: "Capsules"; ConvexHull: "ConvexHull"; Cylinder: "Cylinder"; Sphere: "Sphere"; TriMesh: "TriMesh"; }; type: Enum; }; }>)[]; }; }, this>

Constructors

Constructor

new PhysicsSystem(_w, _qm, _p): PhysicsSystem

Defined in: node_modules/.pnpm/elics@3.4.2/node_modules/elics/lib/system.d.ts:76

Parameters

_w

World

_qm

QueryManager

_p

number

Returns

PhysicsSystem

Inherited from

createSystem( { physicsEntities: { required: [PhysicsBody, PhysicsShape], }, manipluatedEntities: { required: [PhysicsBody, PhysicsManipulation], where: [ne(PhysicsBody, '_engineBody', 0)], }, // Bodies whose gravityFactor / linearDamping / angularDamping differ from // the defaults. The value predicate keeps each set limited to overridden // bodies, so the common case (default values) is never visited by the // per-frame reactive sync below, and the queries re-fire whenever the field // is `setValue`-d. gravityOverrides: { required: [PhysicsBody, PhysicsShape], where: [ne(PhysicsBody, 'gravityFactor', DEFAULT_GRAVITY_FACTOR)], }, linearDampingOverrides: { required: [PhysicsBody, PhysicsShape], where: [ne(PhysicsBody, 'linearDamping', DEFAULT_LINEAR_DAMPING)], }, angularDampingOverrides: { required: [PhysicsBody, PhysicsShape], where: [ne(PhysicsBody, 'angularDamping', DEFAULT_ANGULAR_DAMPING)], }, }, { gravity: { type: Types.Vec3, default: [0, -9.81, 0] }, }, ).constructor

Properties

camera

readonly camera: PerspectiveCamera

Defined in: packages/core/src/ecs/system.ts:63

Inherited from

System.camera


cleanupFuncs

readonly cleanupFuncs: () => void[]

Defined in: packages/core/src/ecs/system.ts:66

Returns

void

Inherited from

System.cleanupFuncs


config

config: SystemConfigSignals<S>

Defined in: packages/core/src/ecs/system.ts:49

Inherited from

System.config


createEntity()

createEntity: () => Entity

Defined in: packages/core/src/ecs/system.ts:81

Returns

Entity

Inherited from

System.createEntity


globals

globals: Record<string, any>

Defined in: packages/core/src/ecs/system.ts:54

Inherited from

System.globals


input

readonly input: InputManager

Defined in: packages/core/src/ecs/system.ts:61

Inherited from

System.input


isPaused

isPaused: boolean

Defined in: packages/core/src/ecs/system.ts:48

Inherited from

System.isPaused


player

readonly player: XROrigin

Defined in: packages/core/src/ecs/system.ts:58

Inherited from

System.player


playerEntity

readonly playerEntity: Entity

Defined in: packages/core/src/ecs/system.ts:59

Inherited from

System.playerEntity


playerHeadEntity

readonly playerHeadEntity: Entity

Defined in: packages/core/src/ecs/system.ts:60

Inherited from

System.playerHeadEntity


priority

priority: number

Defined in: packages/core/src/ecs/system.ts:53

Inherited from

System.priority


queries

queries: Record<keyof Q, Query>

Defined in: packages/core/src/ecs/system.ts:50

Inherited from

System.queries


queryManager

queryManager: QueryManager

Defined in: packages/core/src/ecs/system.ts:52

Inherited from

System.queryManager


renderer

readonly renderer: WebGLRenderer

Defined in: packages/core/src/ecs/system.ts:64

Inherited from

System.renderer


scene

readonly scene: Scene

Defined in: packages/core/src/ecs/system.ts:62

Inherited from

System.scene


visibilityState

readonly visibilityState: Signal<VisibilityState>

Defined in: packages/core/src/ecs/system.ts:65

Inherited from

System.visibilityState


world

world: World

Defined in: packages/core/src/ecs/system.ts:51

Inherited from

System.world


xrFrame

xrFrame: XRFrame

Defined in: packages/core/src/ecs/system.ts:56

Inherited from

System.xrFrame


xrManager

xrManager: WebXRManager

Defined in: packages/core/src/ecs/system.ts:55

Inherited from

System.xrManager

Methods

init()

init(): Promise<void>

Defined in: packages/core/src/physics/physics-system.ts:190

Returns

Promise<void>

Overrides

System.init


play()

play(): void

Defined in: packages/core/src/ecs/system.ts:79

Returns

void

Inherited from

System.play


setBodyTransform()

setBodyTransform(entity, pose, options): void

Defined in: packages/core/src/physics/physics-system.ts:235

Teleport an existing Havok body to pose.

Parameters

entity

Entity

pose

PhysicsBodyTransformPose

options

PhysicsBodyTransformOptions = {}

Returns

void

Remarks

No-ops until the entity has a live PhysicsBody. The pose is pushed directly to Havok and mirrored onto entity.object3D immediately so callers do not need to wait for the next physics tick before reading the reset transform. Linear and angular velocity are cleared by default, which is the expected behavior for reset/home-position flows.

Example

ts
const physics = world.getSystem(PhysicsSystem);
physics.setBodyTransform(prop, {
  position: homePosition,
  quaternion: homeQuaternion,
});

stop()

stop(): void

Defined in: packages/core/src/ecs/system.ts:80

Returns

void

Inherited from

System.stop


update()

update(delta): void

Defined in: packages/core/src/physics/physics-system.ts:312

Per-frame tick. Both arguments are in seconds (Three.js Clock convention), not milliseconds.

Parameters

delta

number

Seconds since the previous frame.

Returns

void

Overrides

System.update

Privacy | Terms