Skip to content

Documentation / scene / JointDynamicsSystemController

Class: JointDynamicsSystemController

Defined in: libs/scene/src/animation/joint_dynamics/controller.ts:195

High-level controller for joint dynamics simulation.

This class manages the physics simulation for a hierarchy of bones, including constraints, colliders, and grabbers. It provides an API for initializing the system with bone data and transforms, stepping the simulation each frame, and modifying colliders and grabbers at runtime. The controller handles the internal state and logic for blending between animation and physics, applying forces, and enforcing constraints.

Constructors

Constructor

new JointDynamicsSystemController(config): JointDynamicsSystemController

Defined in: libs/scene/src/animation/joint_dynamics/controller.ts:241

Parameters

config

ControllerConfig

Returns

JointDynamicsSystemController

Accessors

pointCount

Get Signature

get pointCount(): number

Defined in: libs/scene/src/animation/joint_dynamics/controller.ts:827

Gets the total number of physics points.

Returns

number


blendRatio

Get Signature

get blendRatio(): number

Defined in: libs/scene/src/animation/joint_dynamics/controller.ts:871

The blend ratio for the physics simulation

Returns

number

Set Signature

set blendRatio(value): void

Defined in: libs/scene/src/animation/joint_dynamics/controller.ts:875

Parameters
value

number

Returns

void


colliderCount

Get Signature

get colliderCount(): number

Defined in: libs/scene/src/animation/joint_dynamics/controller.ts:1141

Gets the number of runtime colliders.

Returns

number


flatPlaneCount

Get Signature

get flatPlaneCount(): number

Defined in: libs/scene/src/animation/joint_dynamics/controller.ts:1146

Gets the number of runtime flat planes.

Returns

number


grabberCount

Get Signature

get grabberCount(): number

Defined in: libs/scene/src/animation/joint_dynamics/controller.ts:1151

Gets the number of runtime grabbers.

Returns

number

Methods

initialize()

initialize(rootTransform, rootPoints, pointTransforms, colliders, grabbers, flatPlanes): void

Defined in: libs/scene/src/animation/joint_dynamics/controller.ts:254

Initializes the physics system.

Parameters

rootTransform

TransformAccess

Root bone transform used to detect root motion.

rootPoints

BoneNode[]

Root nodes of the bone hierarchy. Multiple roots are allowed.

pointTransforms

TransformAccess[]

Transform array for all physics points. Order must match BoneNode.index.

colliders

object[]

Collider array (spheres/capsules).

grabbers

object[]

Grabber array used for interactions such as mouse dragging.

flatPlanes

object[]

Plane limiters such as the floor to prevent penetration.

Returns

void


step()

step(deltaTime): void

Defined in: libs/scene/src/animation/joint_dynamics/controller.ts:382

Advances the simulation by one frame. Internal flow: read current transforms, run Verlet integration and constraint solving, then write the result back to the transforms.

Parameters

deltaTime

number

Frame delta time in seconds. Internally subdivided by subSteps.

Returns

void


getResults()

getResults(): object[]

Defined in: libs/scene/src/animation/joint_dynamics/controller.ts:506

Returns the simulated results for all points as world-space positions and rotations. Usually this does not need to be called manually because step() already writes the output back to the transforms.

Returns

object[]


getConfig()

getConfig(): ControllerConfig

Defined in: libs/scene/src/animation/joint_dynamics/controller.ts:526

Returns a detached snapshot of the current runtime configuration.

Returns

ControllerConfig


getColliderSnapshots()

getColliderSnapshots(): JointDynamicsColliderSnapshot[]

Defined in: libs/scene/src/animation/joint_dynamics/controller.ts:533

Returns detached collider snapshots for persistence.

Returns

JointDynamicsColliderSnapshot[]


getFlatPlaneSnapshots()

getFlatPlaneSnapshots(): JointDynamicsFlatPlaneSnapshot[]

Defined in: libs/scene/src/animation/joint_dynamics/controller.ts:544

Returns detached flat-plane snapshots for persistence.

Returns

JointDynamicsFlatPlaneSnapshot[]


getGrabberSnapshots()

getGrabberSnapshots(): JointDynamicsGrabberSnapshot[]

Defined in: libs/scene/src/animation/joint_dynamics/controller.ts:555

Returns detached grabber snapshots for persistence.

Returns

JointDynamicsGrabberSnapshot[]


setConfig()

setConfig(config): void

Defined in: libs/scene/src/animation/joint_dynamics/controller.ts:571

Replaces the runtime configuration.

If the controller is already initialized, cached per-point parameters and generated constraints are refreshed immediately so editor-driven changes take effect in the next step.

Parameters

config

ControllerConfig

Complete controller configuration to apply.

Returns

void


updateConfig()

updateConfig(config): void

Defined in: libs/scene/src/animation/joint_dynamics/controller.ts:587

Applies a partial runtime configuration update.

This is intended for editor workflows that tweak one or more simulation parameters live. The controller updates only the affected caches: global step parameters are applied directly, per-point curve/gravity changes rebuild cached point coefficients, and constraint option changes rebuild the generated constraints.

Parameters

config

Partial configuration update.

gravity?

Vector3

Global gravity vector

windForce?

Vector3

Global wind force vector applied to all dynamic points

relaxation?

number

Number of constraint relaxation iterations per substep. Higher = more stable but slower

subSteps?

number

Number of simulation substeps per frame. Higher = more stable at cost of performance

rootSlideLimit?

number

Max system-local root slide distance retained after root motion. Excess is applied to physics state. -1 = unlimited

rootRotateLimit?

number

Max root bone rotation angle (degrees) per substep. Excess is distributed. -1 = unlimited

constraintShrinkLimit?

number

Upper limit for horizontal/shear constraint shrink power. Prevents over-compression

blendRatio?

number

Global blend ratio between physics and animation [0-1]. 0 = full physics, 1 = full animation

stabilizationFrameRate?

number

Target frame rate for stabilization (currently unused, reserved)

isFakeWave?

boolean

Enable sinusoidal fake wave effect on leaf bones

fakeWaveSpeed?

number

Fake wave global speed (accumulates over time)

fakeWavePower?

number

Fake wave global amplitude multiplier

enableSurfaceCollision?

boolean

Enable triangle-based surface collision (cloth vs colliders)

enableBroadPhase?

boolean

Enable broad-phase pruning before precise collider tests

preserveTwist?

boolean

Preserve each joint's initial local twist (axial roll) after physics simulation

angleLimitConfig?

{ angleLimit?: number; limitFromRoot?: boolean; }

Post-simulation angle limiting between parent-child bones

angleLimitConfig.angleLimit?

number

Max angle in degrees between parent and child bone. Negative = disabled

angleLimitConfig.limitFromRoot?

boolean

If true, measure angle from original transform orientation instead of simulated parent

curves?

{ massScale?: InterpolatorScalar; gravityScale?: InterpolatorScalar; windForceScale?: InterpolatorScalar; resistance?: InterpolatorScalar; hardness?: InterpolatorScalar; friction?: InterpolatorScalar; pointRadius?: InterpolatorScalar; sliderJointLength?: InterpolatorScalar; allShrinkScale?: InterpolatorScalar; allStretchScale?: InterpolatorScalar; structuralShrinkVertical?: InterpolatorScalar; structuralStretchVertical?: InterpolatorScalar; structuralShrinkHorizontal?: InterpolatorScalar; structuralStretchHorizontal?: InterpolatorScalar; shearShrink?: InterpolatorScalar; shearStretch?: InterpolatorScalar; bendingShrinkVertical?: InterpolatorScalar; bendingStretchVertical?: InterpolatorScalar; bendingShrinkHorizontal?: InterpolatorScalar; bendingStretchHorizontal?: InterpolatorScalar; fakeWavePower?: InterpolatorScalar; fakeWaveFreq?: InterpolatorScalar; }

Depth-based physics parameter curves

curves.massScale?

InterpolatorScalar

Scales point mass by depth

curves.gravityScale?

InterpolatorScalar

Scales gravity strength by depth

curves.windForceScale?

InterpolatorScalar

Scales wind force effect by depth (also multiplied by depth rate)

curves.resistance?

InterpolatorScalar

Velocity damping [0-1]. Higher = less damping. Controls how much velocity is preserved

curves.hardness?

InterpolatorScalar

Restore-to-animation stiffness [0-1]. Higher = bone stays closer to animated pose

curves.friction?

InterpolatorScalar

Friction multiplier by depth. Scales collision friction accumulation

curves.pointRadius?

InterpolatorScalar

Collision radius by depth, mapped from VRM SpringBone hitRadius when available

curves.sliderJointLength?

InterpolatorScalar

Extra slack length for horizontal/shear constraints (allows stretching)

curves.allShrinkScale?

InterpolatorScalar

Global shrink stiffness multiplier (applied to all constraint types)

curves.allStretchScale?

InterpolatorScalar

Global stretch stiffness multiplier (applied to all constraint types)

curves.structuralShrinkVertical?

InterpolatorScalar

Structural vertical constraint shrink stiffness by depth

curves.structuralStretchVertical?

InterpolatorScalar

Structural vertical constraint stretch stiffness by depth

curves.structuralShrinkHorizontal?

InterpolatorScalar

Structural horizontal constraint shrink stiffness by depth

curves.structuralStretchHorizontal?

InterpolatorScalar

Structural horizontal constraint stretch stiffness by depth

curves.shearShrink?

InterpolatorScalar

Shear constraint shrink stiffness by depth

curves.shearStretch?

InterpolatorScalar

Shear constraint stretch stiffness by depth

curves.bendingShrinkVertical?

InterpolatorScalar

Bending vertical constraint shrink stiffness by depth

curves.bendingStretchVertical?

InterpolatorScalar

Bending vertical constraint stretch stiffness by depth

curves.bendingShrinkHorizontal?

InterpolatorScalar

Bending horizontal constraint shrink stiffness by depth

curves.bendingStretchHorizontal?

InterpolatorScalar

Bending horizontal constraint stretch stiffness by depth

curves.fakeWavePower?

InterpolatorScalar

Fake wave amplitude by depth (sinusoidal pseudo-wind on leaf bones)

curves.fakeWaveFreq?

InterpolatorScalar

Fake wave frequency offset by depth

constraintOptions?

{ structuralVertical?: boolean; structuralHorizontal?: boolean; shear?: boolean; bendingVertical?: boolean; bendingHorizontal?: boolean; isLoop?: boolean; collideStructuralVertical?: boolean; collideStructuralHorizontal?: boolean; collideShear?: boolean; enableSurfaceCollision?: boolean; }

Which constraint types to generate and their collision flags

constraintOptions.structuralVertical?

boolean

Generate parent→child vertical constraints

constraintOptions.structuralHorizontal?

boolean

Generate same-depth horizontal constraints across chains

constraintOptions.shear?

boolean

Generate diagonal cross-bracing constraints

constraintOptions.bendingVertical?

boolean

Generate skip-one vertical bending constraints

constraintOptions.bendingHorizontal?

boolean

Generate skip-one horizontal bending constraints

constraintOptions.isLoop?

boolean

Connect last root point back to first (for cylindrical topology like skirts)

constraintOptions.collideStructuralVertical?

boolean

Enable per-constraint collision detection on structural vertical pairs

constraintOptions.collideStructuralHorizontal?

boolean

Enable per-constraint collision detection on structural horizontal pairs

constraintOptions.collideShear?

boolean

Enable per-constraint collision detection on shear pairs

constraintOptions.enableSurfaceCollision?

boolean

Enable surface/triangle collision (overrides per-type collision flags)

Returns

void


warp()

warp(): void

Defined in: libs/scene/src/animation/joint_dynamics/controller.ts:725

Resets all physics state after teleportation.

Returns

void

Deprecated

Use JointDynamicsSystemController.reset. This method is kept as a compatibility alias.


reset()

reset(): void

Defined in: libs/scene/src/animation/joint_dynamics/controller.ts:735

Resets all physics state. Simulated points, transform history, root-motion history, grab state and wave phase are snapped back to the current scene transforms. Runtime configuration and fixed/released point weights are preserved.

Returns

void


releasePoint()

releasePoint(index): void

Defined in: libs/scene/src/animation/joint_dynamics/controller.ts:791

Releases a fixed point so it becomes dynamic, for example when cloth is detached. The point state is reset to avoid a sudden impulse.

Parameters

index

number

Point index.

Returns

void


fixPoint()

fixPoint(index): void

Defined in: libs/scene/src/animation/joint_dynamics/controller.ts:807

Fixes a dynamic point back to the animation pose, for example when an item is reattached. The point grab state is cleared.

Parameters

index

number

Point index.

Returns

void


isPointFixed()

isPointFixed(index): boolean

Defined in: libs/scene/src/animation/joint_dynamics/controller.ts:819

Returns whether a point is fixed to animation (weight = 0).

Parameters

index

number

Point index.

Returns

boolean


fadeIn()

fadeIn(seconds): void

Defined in: libs/scene/src/animation/joint_dynamics/controller.ts:836

Fades physics in by blending from animation pose to simulation. blendRatio moves from 1 (animation only) to 0 (physics only).

Parameters

seconds

number

Transition duration in seconds.

Returns

void


fadeOut()

fadeOut(seconds): void

Defined in: libs/scene/src/animation/joint_dynamics/controller.ts:847

Fades physics out by blending from simulation back to animation pose. blendRatio moves from 0 (physics only) to 1 (animation only).

Parameters

seconds

number

Transition duration in seconds.

Returns

void


setWindForce()

setWindForce(wind): void

Defined in: libs/scene/src/animation/joint_dynamics/controller.ts:858

Sets the global wind force vector. The final wind contribution is still scaled per point by windForceScale and mass.

Parameters

wind

Vector3

Wind vector in world space.

Returns

void


setBroadPhaseEnabled()

setBroadPhaseEnabled(enabled): void

Defined in: libs/scene/src/animation/joint_dynamics/controller.ts:866

Enable/disable broad-phase pruning for runtime performance comparison

Parameters

enabled

boolean

true to enable broad-phase, false to disable.

Returns

void


setPaused()

setPaused(paused): void

Defined in: libs/scene/src/animation/joint_dynamics/controller.ts:885

Pauses or resumes the physics simulation. While paused, the system still follows root motion but skips force integration and constraint solving.

Parameters

paused

boolean

true to pause, false to resume.

Returns

void


setColliderEnabledAt()

setColliderEnabledAt(index, enabled): boolean

Defined in: libs/scene/src/animation/joint_dynamics/controller.ts:899

Enable or disable a collider by current array index. Transform state is still read from the collider's TransformAccess each frame. Prefer setColliderEnabled(handle, enabled) for runtime-owned colliders.

Parameters

index

number

Collider index in the current array. Note that this may change when colliders are added or removed.

enabled

boolean

true to enable the collider, false to disable it.

Returns

boolean

true if the index is valid and the collider was updated, false if the index is out of range.


setColliderEnabled()

setColliderEnabled(handle, enabled): boolean

Defined in: libs/scene/src/animation/joint_dynamics/controller.ts:914

Enable or disable a runtime collider by stable handle.

Parameters

handle

JointDynamicsColliderHandle

Stable handle for the collider to enable or disable.

enabled

boolean

true to enable the collider, false to disable it.

Returns

boolean

true if the handle is still valid.


addCollider()

addCollider(r, transform): JointDynamicsColliderHandle

Defined in: libs/scene/src/animation/joint_dynamics/controller.ts:928

Add a collider at runtime.

Parameters

r

ColliderR

Read-only collider data such as shape and size.

transform

TransformAccess

TransformAccess that provides the collider's position and rotation each frame.

Returns

JointDynamicsColliderHandle

A stable handle that remains valid until this collider is removed.


removeCollider()

removeCollider(handle): boolean

Defined in: libs/scene/src/animation/joint_dynamics/controller.ts:943

Remove a collider by stable handle.

Parameters

handle

JointDynamicsColliderHandle

Stable handle for the collider to remove.

Returns

boolean

true if the collider existed and was removed.


removeColliderAt()

removeColliderAt(index): boolean

Defined in: libs/scene/src/animation/joint_dynamics/controller.ts:956

Remove a collider by current array index.

Parameters

index

number

Collider index in the current array. Note that this may change when colliders are added or removed. Prefer removeCollider(handle) for runtime-owned colliders.

Returns

boolean


setFlatPlaneEnabledAt()

setFlatPlaneEnabledAt(index, enabled): boolean

Defined in: libs/scene/src/animation/joint_dynamics/controller.ts:974

Enable or disable a flat plane by current array index.

Parameters

index

number

Flat plane index in the current array. Note that this may change when flat planes are added or removed.

enabled

boolean

true to enable the flat plane, false to disable it.

Returns

boolean

true if the index is valid and the flat plane was updated, false if the index is out of range.


setFlatPlaneEnabled()

setFlatPlaneEnabled(handle, enabled): boolean

Defined in: libs/scene/src/animation/joint_dynamics/controller.ts:989

Enable or disable a runtime flat plane by stable handle.

Parameters

handle

JointDynamicsFlatPlaneHandle

Stable handle for the flat plane to enable or disable.

enabled

boolean

true to enable the flat plane, false to disable it.

Returns

boolean

true if the handle is still valid.


addFlatPlane()

addFlatPlane(up, position): JointDynamicsFlatPlaneHandle

Defined in: libs/scene/src/animation/joint_dynamics/controller.ts:1003

Add a flat plane at runtime.

Parameters

up

Vector3

Up direction of the plane. The normal is computed as Vector3.normalize(up).

position

Vector3

A point on the plane. The distance is computed as -Vector3.dot(normal, position).

Returns

JointDynamicsFlatPlaneHandle

A stable handle that remains valid until this flat plane is removed.


removeFlatPlane()

removeFlatPlane(handle): boolean

Defined in: libs/scene/src/animation/joint_dynamics/controller.ts:1022

Remove a flat plane by stable handle.

Parameters

handle

JointDynamicsFlatPlaneHandle

Stable handle for the flat plane to remove.

Returns

boolean

true if the flat plane existed and was removed.


removeFlatPlaneAt()

removeFlatPlaneAt(index): boolean

Defined in: libs/scene/src/animation/joint_dynamics/controller.ts:1035

Remove a flat plane by current array index.

Parameters

index

number

Flat plane index in the current array. Note that this may change when flat planes are added or removed.

Returns

boolean

true if the index was valid and the flat plane was removed, false if the index was out of range.


setGrabberEnabledAt()

setGrabberEnabledAt(index, enabled): boolean

Defined in: libs/scene/src/animation/joint_dynamics/controller.ts:1056

Enable or disable a grabber by current array index. Transform state is still read from the grabber's TransformAccess each frame. Prefer setGrabberEnabled(handle, enabled) for runtime-owned grabbers.

Parameters

index

number

Grabber index in the current array. Note that this may change when grabbers are added or removed.

enabled

boolean

true to enable the grabber, false to disable it.

Returns

boolean

true if the index is valid and the grabber was updated, false if the index is out of range.


setGrabberEnabled()

setGrabberEnabled(handle, enabled): boolean

Defined in: libs/scene/src/animation/joint_dynamics/controller.ts:1073

Enable or disable a runtime grabber by stable handle.

Parameters

handle

JointDynamicsGrabberHandle

Stable handle for the grabber to enable or disable.

enabled

boolean

true to enable the grabber, false to disable it.

Returns

boolean

true if the handle is still valid.


addGrabber()

addGrabber(r, transform, enabled?): JointDynamicsGrabberHandle

Defined in: libs/scene/src/animation/joint_dynamics/controller.ts:1088

Add a grabber at runtime.

Parameters

r

GrabberR

Read-only grabber data such as interaction radius.

transform

TransformAccess

TransformAccess that provides the grabber's position each frame.

enabled?

boolean = false

Whether the grabber starts enabled. The grabber can still be moved by its transform while disabled, but it won't affect any points until enabled.

Returns

JointDynamicsGrabberHandle

A stable handle that remains valid until this grabber is removed.


removeGrabber()

removeGrabber(handle): boolean

Defined in: libs/scene/src/animation/joint_dynamics/controller.ts:1106

Remove a grabber by stable handle.

Parameters

handle

JointDynamicsGrabberHandle

Stable handle for the grabber to remove.

Returns

boolean

true if the grabber existed and was removed.


removeGrabberAt()

removeGrabberAt(index): boolean

Defined in: libs/scene/src/animation/joint_dynamics/controller.ts:1121

Remove a grabber by current array index. Prefer removeGrabber(handle) for runtime-owned grabbers.

Parameters

index

number

Grabber index in the current array. Note that this may change when grabbers are added or removed.

Returns

boolean

true if the index was valid and the grabber was removed, false if the index was out of range.

Released under the MIT License.