/**
 * Partitions this frame's awake dynamic bodies + touched non-sensor contacts
 * into connected components ("islands") via union-find. The solver iterates
 * each island independently (so impulses converge inside an island without
 * waiting for global passes) and the sleep test will eventually use island
 * granularity for atomic whole-island sleep.
 *
 * Static and Kinematic bodies are not merged into islands — they act as
 * constraint anchors. A 1000-block stack on a static floor is therefore one
 * island of 1000 dynamic bodies, not 1001 — the floor anchors the island but
 * does not enlarge it. Multiple separate piles all resting on the same static
 * floor remain *separate* islands so each can sleep/wake independently.
 *
 * Sensor contacts are skipped entirely: they don't transmit constraint
 * forces, so two bodies linked only by a sensor pair are not in the same
 * structural island.
 *
 * Determinism contract:
 *  - Union-find uses union-by-min-index + path halving, so the canonical
 *    root of any component is the smallest body index of any of its members.
 *  - Islands are emitted sorted ascending by root index.
 *  - Bodies within an island are emitted sorted ascending by body index.
 *  - Contacts within an island are emitted sorted ascending by manifold slot id.
 *
 * Output layout is CSR-like — `body_offsets[i]..body_offsets[i+1]` indexes
 * into `body_data` for island `i`, similarly for contacts.
 *
 * @author Alex Goldring
 * @copyright Company Named Limited (c) 2026
 */
export class IslandBuilder {
    /**
     * @param {RigidBody} rb
     * @param {Array} collider_list collider list for the body (or undefined)
     * @returns {boolean}
     * @private
     */
    private static __body_is_sensor;
    /**
     * Union-find parent table, indexed by body index (NOT packed id).
     * Sized to `storage.high_water_mark` at `build` time; reallocated by
     * doubling when the body pool grows past current capacity.
     * @type {Uint32Array}
     */
    parent: Uint32Array;
    /**
     * Per-body island id. `island_of_body[idx] === -1` means the body
     * is not in any island this frame (static, kinematic, or unallocated).
     * @type {Int32Array}
     */
    island_of_body: Int32Array;
    /**
     * Number of islands this frame.
     * @type {number}
     */
    island_count: number;
    /**
     * CSR offsets into `body_data`. Length is `island_count + 1`. Bodies
     * for island `i` live in `body_data[body_offsets[i]..body_offsets[i+1])`.
     * @type {Uint32Array}
     */
    body_offsets: Uint32Array;
    /**
     * Flattened body indices, grouped by island, sorted ascending within
     * each island.
     * @type {Uint32Array}
     */
    body_data: Uint32Array;
    /**
     * Total number of body entries across all islands (= sum of island sizes).
     * @type {number}
     */
    body_total: number;
    /**
     * CSR offsets into `contact_data`. Length is `island_count + 1`.
     * Manifold slot ids for island `i` live in
     * `contact_data[contact_offsets[i]..contact_offsets[i+1])`.
     * @type {Uint32Array}
     */
    contact_offsets: Uint32Array;
    /**
     * Flattened manifold slot ids, grouped by island, sorted ascending
     * within each island.
     * @type {Uint32Array}
     */
    contact_data: Uint32Array;
    /**
     * Total number of contact entries across all islands.
     * @type {number}
     */
    contact_total: number;
    /**
     * Scratch: root body index → island id, or -1 if unassigned.
     * Sized in lockstep with `parent`.
     * @private
     * @type {Int32Array}
     */
    private __root_to_island;
    /**
     * Scratch: list of distinct root indices observed this frame, used
     * to sort them ascending before assigning island ids.
     * @private
     * @type {Uint32Array}
     */
    private __scratch_roots;
    /**
     * Scratch write-cursors, one per island.
     * @private
     * @type {Uint32Array}
     */
    private __cursors;
    /**
     * (Re)build islands from `manifolds`' currently-touched non-sensor slots
     * and the bodies in `storage`'s awake list.
     *
     * @param {BodyStorage} storage
     * @param {ManifoldStore} manifolds
     * @param {RigidBody[]} bodies sparse, indexed by body index
     * @param {Array[]} body_collider_lists sparse, indexed by body index
     * @param {Joint[]} joints live joints (sparse). Jointed dynamic-dynamic
     *   bodies are unioned into the same island so a chain / ragdoll sleeps
     *   and wakes as a unit. Callers with no joints pass an empty array.
     */
    build(storage: BodyStorage, manifolds: ManifoldStore, bodies: RigidBody[], body_collider_lists: any[][], joints: Joint[]): void;
    /**
     * Fill `body_offsets` + `body_data` with awake dynamic bodies grouped
     * by island, sorted ascending within each island.
     * @private
     */
    private __build_body_csr;
    /**
     * Fill `contact_offsets` + `contact_data` with touched non-sensor manifold
     * slot ids grouped by island. A contact belongs to its dynamic
     * participant's island (if both sides are dynamic they share an island
     * by construction). Static-vs-static contacts are skipped.
     * @private
     */
    private __build_contact_csr;
    /**
     * Resolve which island a manifold slot belongs to.
     *
     * Returns `-1` if the manifold is not touched this frame, is a sensor
     * pair, or both bodies are non-dynamic (static-static, which the solver
     * wouldn't act on anyway).
     *
     * @private
     */
    private __island_of_slot;
    /**
     * @private
     * @param {number} n
     */
    private __ensure_body_capacity;
    /**
     * @private
     * @param {number} n
     */
    private __ensure_island_count_capacity;
    /**
     * @private
     * @param {number} n
     */
    private __ensure_body_data_capacity;
    /**
     * @private
     * @param {number} n
     */
    private __ensure_contact_data_capacity;
}
//# sourceMappingURL=IslandBuilder.d.ts.map