/**
 * Write the heightmap's triangles that may overlap the given body-local
 * query AABB into `output`, starting at float-index `offset`.
 *
 * Each triangle occupies {@link TRIANGLE_FLOAT_STRIDE} consecutive floats:
 *   [+0..+2]  vA.xyz   (body-local frame)
 *   [+3..+5]  vB.xyz
 *   [+6..+8]  vC.xyz
 *   [+9]      feature_id   (stable across frames; warm-start key)
 *
 * ## Tessellation
 *
 * Each sampler cell is split into `N × N` sub-cells, where `N =
 * shape.tessellation` (a non-negative integer, validated at construction).
 * The sub-cell corners are sampled with the same Catmull-Rom filter the
 * surface uses everywhere else, so finer `N` makes the faceted collision
 * surface converge toward the smooth surface the renderer draws (which
 * samples the identical cubic, just at its own `size × resolution` density).
 * `N = 1` emits exactly one quad per sampler cell — the legacy behaviour;
 * `N = 0` emits nothing. Cost is O(N²) per cell, so the caller owns the
 * fidelity/cost trade-off.
 *
 * The collision grid therefore has `seg_u = (W − 1)·N` segments along u and
 * `seg_v = (H − 1)·N` along v. The feature_id encodes
 * `(sub_y · seg_u + sub_x) · 2 + tri_idx`, where (sub_x, sub_y) is the
 * sub-cell and tri_idx ∈ {0, 1}: a unique, frame-stable key per sub-cell
 * triangle (`seg_u · seg_v · 2` stays well under 2^53 for any realistic
 * sampler × N). Two triangles per sub-cell, lower-left-diagonal split
 * (matches the existing {@link build_height_field_geometry} winding).
 *
 * The query AABB is filtered against the footprint *and* against the
 * cell grid; triangles outside the query AABB along the height axis are
 * NOT filtered out — that test is left to the per-triangle narrowphase
 * (where the precise GJK distance is computed anyway). This keeps the
 * enumerator branch-free over the height field and aligned with what
 * Bullet's btHeightfieldTerrainShape does.
 *
 * The caller is responsible for ensuring
 *   `output.length - offset >= sub_cells_in_query * 2 * TRIANGLE_FLOAT_STRIDE`
 * — sizing the scratch buffer for the *worst-case* query AABB is the
 * right pattern. The broadphase already bounded the AABB to one body's
 * world envelope, so the sampler-cell count is bounded by the footprint
 * resolution; note the sub-cell count (and thus the buffer requirement)
 * scales by N² with {@link HeightMapShape3D#tessellation}. Writes past the
 * end of `output` are silently dropped by the typed array, so an
 * undersized buffer degrades to a missed contact on a far cell (recovered
 * next broadphase), never a crash.
 *
 * @param {Float64Array} output
 * @param {number} offset float-index into output
 * @param {HeightMapShape3D} shape
 * @param {number} aabb_min_x  query AABB in shape's body-local frame
 * @param {number} aabb_min_y
 * @param {number} aabb_min_z
 * @param {number} aabb_max_x
 * @param {number} aabb_max_y
 * @param {number} aabb_max_z
 * @returns {number} number of triangles written
 */
export function heightmap_enumerate_triangles(output: Float64Array, offset: number, shape: HeightMapShape3D, aabb_min_x: number, aabb_min_y: number, aabb_min_z: number, aabb_max_x: number, aabb_max_y: number, aabb_max_z: number): number;
//# sourceMappingURL=heightmap_enumerate_triangles.d.ts.map