API

Class WebXRTrackedBody

Represents a tracked body during a WebXR session.

This class manages the bridge between the WebXR body pose data and the Babylon.js scene graph. It creates a set of TransformNodes — one per body joint — whose transforms are updated every frame from the XR runtime. When a rigged body mesh is attached, its skeleton bones are linked to these transform nodes, causing the mesh to follow the user's body automatically.

Coordinate-system handling:

  • WebXR delivers poses in a right-handed system.
  • By default, Babylon.js uses a left-handed system.
  • The class converts the data in-place (negating the Z components of every 4 × 4 joint matrix) before decomposing into Babylon transforms.
  • If the mesh was authored in a right-handed tool (the common case for glTF), the bone transforms are un-flipped so the skeleton interprets them correctly.

Implements

Index
  • Construct a new tracked body instance.

    Parameters

    • scene: Scene

      The Babylon.js scene.

    • OptionalbodyMesh: AbstractMesh

      Optional rigged body mesh to attach immediately.

    • OptionalrigMapping: XRBodyMeshRigMapping

      Optional mapping from WebXR joint names to skeleton bone names.

    • jointScaleFactor: number = 1.0

      Scale factor for local joint offsets (default 1.0).

    • preserveBindPoseBonePositions: boolean = false

      Whether mapped bones should keep bind-pose local translations.

    • useBoneOrientationOffsets: boolean = false

      Whether mapped bones should correct XR joint rotations using bind-space offsets.

    • OptionalaimChildOverrides: Partial<Record<WebXRBodyJoint, WebXRBodyJoint>>

      Per–XR-joint override for the aim child used with useBoneOrientationOffsets.

    • OptionaljointLocalRotationOffset: Quaternion

      Optional rotation re-basing each XR joint's local frame (e.g. Z-along-bone → Y-along-bone).

    Returns WebXRTrackedBody

autoCaptureBindOnFirstFrame: boolean = true

When true (default), the first tracked frame after the feature attaches is used as the "rest" pose for delta-from-bind retargeting. Set to false to require an explicit captureTrackedBind call.

jointLocalRotationOffset: Nullable<Quaternion> = null

Runtime-mutable rotation applied in each tracked joint's local frame to re-base XR joint axes (e.g., "+Z-along-bone" → "+Y-along-bone"). null = identity / disabled.

onBodyMeshSetObservable: Observable<WebXRTrackedBody> = ...

Fired when the body mesh is changed via setBodyMesh.

  • Capture the current tracked-joint desired-final rotations and positions as the "rest pose" for delta-from-bind retargeting.

    Delta-from-bind is the production retarget path: every subsequent frame is interpreted as a rotation delta from this snapshot, which makes retargeting invariant to the XR-joint axis convention and to any skeletal-proportion differences between the tracked user and the avatar.

    Call this after the user assumes a known rest pose (e.g. T-pose, A-pose, arms-at-sides). By default the feature auto-captures on the first tracked frame — disable via autoCaptureBindOnFirstFrame.

    Returns void

  • Replay a pre-captured joint matrix set through the retargeting pipeline as if it had just been delivered by an XR frame.

    Useful for headset-less testing: call with a snapshot captured via snapshotFrame (the jointMatricesRHS array, or jointMatricesLHS already flipped). The matrices are assumed to be RHS unless isAlreadyLhs=true, in which case the RHS→LHS flip step is skipped.

    Parameters

    • rawMatrices: number[] | Float32Array<ArrayBufferLike>

      Float32Array of BODY_JOINT_COUNT × 16 (= 1328) floats.

    • isAlreadyLhs: boolean = false

      Set to true if matrices are already LHS-converted.

    Returns void

  • Capture a snapshot of the current frame's raw XR joint matrices and skeleton metadata. Returns a JSON string that can be used offline to replay / debug bone-local computation without a headset.

    The snapshot includes:

    • jointMatricesRHS – 83 × 16 raw RHS matrices (before LHS conversion)
    • jointMatricesLHS – 83 × 16 LHS-converted matrices (after step 3)
    • meshWorldMatrix – 16 floats, the skeleton mesh's world matrix (if any)
    • jointHasBone – boolean[83], which joints are mapped to bones
    • jointParentJointIdx – number[83], mapped ancestor for each joint
    • useRightHandedSystem – scene handedness setting
    • jointNames – the 83 joint names in order

    Returns string

    A JSON string with the snapshot data.

  • Update joint transforms from the current XR frame.

    This method is called once per frame by the feature class. Internally it:

    1. Extracts all XRBodySpaces from the XRBody.
    2. Fills the transform-matrix buffer via fillPoses() (or per-joint fallback).
    3. Converts from WebXR right-handed to Babylon left-handed coordinates.
    4. Decomposes each matrix into the corresponding TransformNode.
    5. Parents the body mesh root to the XR camera so it tracks correctly.

    Parameters

    • xrFrame: XRFrame

      The current XRFrame.

    • referenceSpace: XRReferenceSpace

      The XRReferenceSpace to resolve poses against.

    • xrCameraParent: Nullable<Node>

      The parent node of the XR camera (used for parenting).

    Returns boolean

    true if valid tracking data was processed, false otherwise.