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:242

Parameters ​

config ​

ControllerConfig

Returns ​

JointDynamicsSystemController

Accessors ​

pointCount ​

Get Signature ​

get pointCount(): number

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

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:859

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:863

Parameters ​
value ​

number

Returns ​

void


colliderCount ​

Get Signature ​

get colliderCount(): number

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

Gets the number of runtime colliders.

Returns ​

number


flatPlaneCount ​

Get Signature ​

get flatPlaneCount(): number

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

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:1139

Gets the number of runtime grabbers.

Returns ​

number

Methods ​

initialize() ​

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

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

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.

pointInputTransforms ​

TransformAccess[]

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:375

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:494

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:514

Returns a detached snapshot of the current runtime configuration.

Returns ​

ControllerConfig


getColliderSnapshots() ​

getColliderSnapshots(): JointDynamicsColliderSnapshot[]

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

Returns detached collider snapshots for persistence.

Returns ​

JointDynamicsColliderSnapshot[]


getFlatPlaneSnapshots() ​

getFlatPlaneSnapshots(): JointDynamicsFlatPlaneSnapshot[]

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

Returns detached flat-plane snapshots for persistence.

Returns ​

JointDynamicsFlatPlaneSnapshot[]


getGrabberSnapshots() ​

getGrabberSnapshots(): JointDynamicsGrabberSnapshot[]

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

Returns detached grabber snapshots for persistence.

Returns ​

JointDynamicsGrabberSnapshot[]


setConfig() ​

setConfig(config): void

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

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:575

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:713

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:723

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:779

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:795

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:807

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:824

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:835

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:846

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:854

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:873

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:887

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:902

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:916

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:931

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:944

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:962

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:977

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:991

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:1010

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:1023

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:1044

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:1061

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:1076

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:1094

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:1109

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.