/**
 * Arbitrary triangle-mesh collider.
 *
 * The shape carries two synchronized representations:
 *   - flat (`positions`, `indices`) surface — used by GJK's support
 *     function and the per-triangle distance queries;
 *   - a {@link TetrahedralMesh} of the *interior* (built from the surface
 *     by `compute_tetrahedral_mesh_from_surface`) plus a {@link BVH}
 *     keyed by tet AABB — used by `contains_point` and any future
 *     volume-aware query.
 *
 * The tet decomposition gives us convex primitives. Two consequences:
 *   1. `contains_point` is a point-in-AABB BVH query followed by a
 *      per-tet `orient3d` test. Critically this works for **disconnected
 *      meshes** (two cubes welded into one buffer; a torus and a sphere
 *      handed to the same shape). A walking query started from one
 *      component can't reach the others — that was the previous
 *      implementation's silent bug.
 *   2. Per-point queries are O(log N_tets) on average — the BVH's
 *      traversal short-circuits cleanly when the query point is far
 *      from the mesh.
 *
 * Construct via {@link shape_mesh_from_geometry} rather than `new
 * MeshShape3D()` directly — the factory compacts the tet mesh, builds
 * the BVH, and caches the bbox / volume / surface area.
 *
 * Narrowphase routing:
 *   - GJK + EPA for the general case, using {@link support}.
 *   - The support function currently returns the deepest tet-mesh
 *     vertex, which gives GJK the *convex hull* of the mesh — not the
 *     true non-convex surface. For convex authored geometry that's
 *     fine; for highly concave shapes (a torus's hole, an L-bracket,
 *     two disconnected components) the convex-hull approximation
 *     overstates the collision volume. The accurate fix is a per-tet
 *     GJK loop in the narrowphase, which would consume `tet_mesh` and
 *     `tet_positions` directly — see PLAN.md's mesh-vs-convex
 *     closed-form item.
 *
 * @author Alex Goldring
 * @copyright Company Named Limited (c) 2026
 */
export class MeshShape3D extends AbstractShape3D {
    /**
     * Surface vertex positions, flat `(x, y, z)` per vertex. Authored
     * by the factory; mutate at your own risk (the cached bbox /
     * volume / surface area / BVH will go stale).
     * @type {Float32Array}
     */
    positions: Float32Array;
    /**
     * Surface triangle indices, three uint32 per face referring to
     * {@link positions}. Same mutate-at-your-own-risk caveat.
     * @type {Uint32Array}
     */
    indices: Uint32Array;
    /**
     * Tetrahedral decomposition of the interior. The factory
     * compacts the mesh before storing (low-index slots that the
     * carve pass freed get refilled), so iteration via
     * `tet_id in [0, tet_mesh.count)` is safe — no need for
     * `forEach` or `exists` filtering on the hot path.
     * @type {TetrahedralMesh}
     */
    tet_mesh: TetrahedralMesh;
    /**
     * Flat positions array for {@link tet_mesh}. Includes the
     * surface vertices and any hole-closing centroids added during
     * tetrahedralisation. For closed airtight meshes this equals
     * {@link positions} element-wise; for meshes with boundary holes
     * (rare in authored content, common in mis-exported assets) the
     * trailing slots carry the closure centroids.
     * @type {Float32Array}
     */
    tet_positions: Float32Array;
    /**
     * BVH over the tet mesh, keyed by tet index. Built by the
     * factory after compacting the tet mesh, so leaf user_data
     * values are valid tet indices that can be passed straight to
     * `tet_mesh.getVertexIndex`.
     * @type {BVH}
     */
    tet_bvh: BVH;
    /**
     * Cached axis-aligned bounding box, layout `[minX, minY, minZ,
     * maxX, maxY, maxZ]`.
     * @private
     * @type {Float64Array}
     */
    private __bbox;
    /**
     * Cached total volume in the shape's local frame, computed from
     * the tetrahedral decomposition at construction.
     * @private
     * @type {number}
     */
    private __volume;
    /**
     * Cached total surface area, sum of triangle areas.
     * @private
     * @type {number}
     */
    private __surface_area;
    compute_bounding_box(result: any): void;
    /**
     * Refresh the cached bounding box, volume, and surface area from the
     * current `positions` / `indices` / `tet_mesh`. Called by
     * {@link shape_mesh_from_geometry} at construction; call again after
     * mutating the underlying data.
     */
    recompute_cached(): void;
    /**
     * Support function: returns the deepest tet-mesh vertex along the
     * supplied direction. This gives GJK the **convex hull** of the
     * mesh — fine for convex authored geometry, an overestimate for
     * concave shapes (a torus's hole or two disconnected components
     * read as one filled blob through this function).
     *
     * Iterates `tet_positions` rather than the original surface
     * `positions` so any hole-closing centroid that the
     * tetrahedralisation added shows up. For airtight closed meshes the
     * two arrays match element-wise.
     *
     * Future work: an accurate non-convex `support` would have to be
     * per-tet (each tet is convex; the shape is the union). The
     * narrowphase would then iterate tets via the BVH. See PLAN.md.
     *
     * @param {number[]|Float32Array} result
     * @param {number} result_offset
     * @param {number} direction_x
     * @param {number} direction_y
     * @param {number} direction_z
     */
    support(result: number[] | Float32Array, result_offset: number, direction_x: number, direction_y: number, direction_z: number): void;
    /**
     * Inside test via the tet mesh. Queries the tet BVH for the leaves
     * whose AABB contains the point, then runs an `orient3d`-based
     * point-in-tet test on each candidate. Returns `true` on the first
     * hit.
     *
     * Crucially this works for **disconnected meshes** — a single
     * `MeshShape3D` holding two cubes welded into one buffer, or a
     * torus with a separate sphere, will correctly classify points
     * inside either component. The previous implementation walked tet
     * neighbours starting from a single seed, which trapped the query
     * in the seed's connected component and produced silent false
     * negatives in the other components.
     *
     * @param {number[]|Float32Array} point
     * @returns {boolean}
     */
    contains_point(point: number[] | Float32Array): boolean;
    /**
     * Closest world-space point on the surface to `reference`. Linear
     * scan over triangles using the barycentric closest-point helper.
     * For mesh sizes where this becomes a bottleneck, a triangle BVH
     * would be the next acceleration (sibling to {@link tet_bvh} but
     * keyed on surface triangles).
     *
     * @param {number[]|Float32Array} result
     * @param {number[]|Float32Array} reference
     */
    nearest_point_on_surface(result: number[] | Float32Array, reference: number[] | Float32Array): void;
    /**
     * Signed distance to the surface: positive outside the mesh,
     * negative inside. Linear scan over triangles for nearest unsigned
     * distance, then the BVH-backed {@link contains_point} flips the
     * sign for interior points.
     *
     * @param {number[]|Float32Array} point
     * @returns {number}
     */
    signed_distance_at_point(point: number[] | Float32Array): number;
    /**
     * Reject-sample inside the bounding box until a point lands in the
     * mesh volume. For convex or near-convex shapes this terminates in
     * 1–3 attempts; for thin or pinched shapes the worst-case cost can
     * be high. Falls back to the bbox centre after 256 misses.
     *
     * @param {number[]|Float32Array} result
     * @param {number} result_offset
     * @param {function():number} random
     */
    sample_random_point_in_volume(result: number[] | Float32Array, result_offset: number, random: () => number): void;
    /**
     * Numerical-gradient SDF gradient.
     *
     * @param {number[]|Float32Array} result
     * @param {number[]|Float32Array} point
     * @returns {number}
     */
    signed_distance_gradient_at_point(result: number[] | Float32Array, point: number[] | Float32Array): number;
    /**
     * Topology equality: same vertex count, same triangle count, and
     * positions / indices match element-by-element.
     *
     * @param {MeshShape3D} other
     * @returns {boolean}
     */
    equals(other: MeshShape3D): boolean;
    /**
     * Fast type-check marker.
     * @readonly
     * @type {boolean}
     */
    readonly isMeshShape3D: boolean;
}
import { AbstractShape3D } from "./AbstractShape3D.js";
import { TetrahedralMesh } from "../tetrahedra/TetrahedralMesh.js";
import { BVH } from "../../../bvh2/bvh3/BVH.js";
//# sourceMappingURL=MeshShape3D.d.ts.map