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
// 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
_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
readonlycamera:PerspectiveCamera
Defined in: packages/core/src/ecs/system.ts:63
Inherited from
cleanupFuncs
readonlycleanupFuncs: () =>void[]
Defined in: packages/core/src/ecs/system.ts:66
Returns
void
Inherited from
config
config:
SystemConfigSignals<S>
Defined in: packages/core/src/ecs/system.ts:49
Inherited from
createEntity()
createEntity: () =>
Entity
Defined in: packages/core/src/ecs/system.ts:81
Returns
Entity
Inherited from
globals
globals:
Record<string,any>
Defined in: packages/core/src/ecs/system.ts:54
Inherited from
input
readonlyinput:InputManager
Defined in: packages/core/src/ecs/system.ts:61
Inherited from
isPaused
isPaused:
boolean
Defined in: packages/core/src/ecs/system.ts:48
Inherited from
player
readonlyplayer:XROrigin
Defined in: packages/core/src/ecs/system.ts:58
Inherited from
playerEntity
readonlyplayerEntity:Entity
Defined in: packages/core/src/ecs/system.ts:59
Inherited from
playerHeadEntity
readonlyplayerHeadEntity:Entity
Defined in: packages/core/src/ecs/system.ts:60
Inherited from
priority
priority:
number
Defined in: packages/core/src/ecs/system.ts:53
Inherited from
queries
queries:
Record<keyofQ,Query>
Defined in: packages/core/src/ecs/system.ts:50
Inherited from
queryManager
queryManager:
QueryManager
Defined in: packages/core/src/ecs/system.ts:52
Inherited from
renderer
readonlyrenderer:WebGLRenderer
Defined in: packages/core/src/ecs/system.ts:64
Inherited from
scene
readonlyscene:Scene
Defined in: packages/core/src/ecs/system.ts:62
Inherited from
visibilityState
readonlyvisibilityState:Signal<VisibilityState>
Defined in: packages/core/src/ecs/system.ts:65
Inherited from
world
world:
World
Defined in: packages/core/src/ecs/system.ts:51
Inherited from
xrFrame
xrFrame:
XRFrame
Defined in: packages/core/src/ecs/system.ts:56
Inherited from
xrManager
xrManager:
WebXRManager
Defined in: packages/core/src/ecs/system.ts:55
Inherited from
Methods
init()
init():
Promise<void>
Defined in: packages/core/src/physics/physics-system.ts:190
Returns
Promise<void>
Overrides
play()
play():
void
Defined in: packages/core/src/ecs/system.ts:79
Returns
void
Inherited from
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
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
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
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