Documentation
    Preparing search index...

    Interface HeightFieldShape

    A height field, "3d" only (§24) — a regular grid of heights along local Y.

    rows and columns are sample counts, not subdivisions, because a caller counts the numbers they have. heights.length is therefore rows * columns, and the adapter hands the solver rows - 1 / columns - 1 (Rapier's heightfield(nrows, ncols, …) takes subdivisions and wants (nrows + 1) * (ncols + 1) heights — verified 2026-08-08 by reading nrows/ncols/heights.length back off a built collider).

    heights is column-major: the sample at grid position (row, column) is heights[row + column * rows]. Which world axis each index walks was measured, again against Rapier 0.19.3, by building a 2×2 field with heights [0, 1, 2, 3] and scale = (2, 1, 2) and raycasting down at its four corners:

    Corner Height read Grid position
    x = −1, z = −1 0 (0, 0)
    x = −1, z = +1 1 (1, 0)
    x = +1, z = −1 2 (0, 1)
    x = +1, z = +1 3 (1, 1)

    So row walks local Z and column walks local X, which is the opposite of the guess a "rows are horizontal" reading produces. The field is centred on the collider origin and spans scale.x in X and scale.z in Z, with every height multiplied by scale.y.

    Composite: refused as a §30 query shape (see the module header).

    interface HeightFieldShape {
        columns: number;
        heights: readonly number[];
        rows: number;
        scale: Vector3;
        type: "height-field";
    }
    Index
    columns: number

    Number of height samples along local X. An integer ≥ 2.

    heights: readonly number[]

    rows * columns finite heights in column-major order: the sample at (row, column) is heights[row + column * rows].

    rows: number

    Number of height samples along local Z. An integer ≥ 2.

    scale: Vector3

    The field's extent in local X and Z, and the multiplier applied to every height along local Y. All three components must be > 0.

    type: "height-field"