import { BlockMaskBuffer } from './block-mask-buffer';
import { BlockMaskMap } from './block-mask-map';
declare const SOLID_LO: number;
declare const SOLID_HI: number;
declare const BLOCK_EMPTY = 0;
declare const BLOCK_SOLID = 1;
declare const BLOCK_MIXED = 2;
declare const FACE_MASKS_LO: number[];
declare const FACE_MASKS_HI: number[];
declare const BLOCKS_PER_WORD: number;
declare const TYPE_MASK: number;
declare const SOLID_WORD: number;
declare const EVEN_BITS: number;
/**
 * Read the 2-bit block type directly from a packed `types` Uint32Array.
 * Module-level so V8 can inline it into hot loops without method dispatch.
 * Equivalent to `grid.getBlockType(blockIdx)` when `types === grid.types`.
 *
 * @param types - Packed types array (16 blocks per word).
 * @param blockIdx - Linear block index.
 * @returns Block type: `BLOCK_EMPTY`, `BLOCK_SOLID`, or `BLOCK_MIXED`.
 */
declare const readBlockType: (types: Uint32Array, blockIdx: number) => number;
/**
 * Write the 2-bit block type directly into a packed `types` Uint32Array.
 * Module-level so V8 can inline it into hot loops without method dispatch.
 * Caller is responsible for keeping the grid's `masks` consistent (only
 * `MIXED` blocks should have a mask entry).
 *
 * @param types - Packed types array (16 blocks per word).
 * @param blockIdx - Linear block index.
 * @param value - Block type to set.
 */
declare const writeBlockType: (types: Uint32Array, blockIdx: number, value: number) => void;
declare class SparseVoxelGrid {
    readonly nx: number;
    readonly ny: number;
    readonly nz: number;
    readonly nbx: number;
    readonly nby: number;
    readonly nbz: number;
    readonly bStride: number;
    /**
     * Packed block types: 2 bits per block, 16 blocks per Uint32 word.
     * Length = ceil(totalBlocks / 16).
     */
    types: Uint32Array;
    /** Voxel masks for MIXED blocks, keyed on global block index. */
    masks: BlockMaskMap;
    constructor(nx: number, ny: number, nz: number);
    /**
     * Read the 2-bit block type at the given block index.
     *
     * @param blockIdx - Linear block index (`bx + by*nbx + bz*bStride`).
     * @returns Block type: `BLOCK_EMPTY`, `BLOCK_SOLID`, or `BLOCK_MIXED`.
     */
    getBlockType(blockIdx: number): number;
    /**
     * Write the 2-bit block type at the given block index. Caller is
     * responsible for keeping `masks` consistent (only `MIXED` blocks
     * should have a mask entry; `EMPTY`/`SOLID` should not).
     *
     * @param blockIdx - Linear block index.
     * @param value - Block type to set.
     */
    setBlockType(blockIdx: number, value: number): void;
    getVoxel(ix: number, iy: number, iz: number): number;
    setVoxel(ix: number, iy: number, iz: number): void;
    orBlock(blockIdx: number, lo: number, hi: number): void;
    clear(): void;
    clone(): SparseVoxelGrid;
    static fromBuffer(acc: BlockMaskBuffer, nx: number, ny: number, nz: number): SparseVoxelGrid;
    toBuffer(cropMinBx: number, cropMinBy: number, cropMinBz: number, cropMaxBx: number, cropMaxBy: number, cropMaxBz: number, defaultSolid?: boolean): BlockMaskBuffer;
    toBufferInverted(cropMinBx: number, cropMinBy: number, cropMinBz: number, cropMaxBx: number, cropMaxBy: number, cropMaxBz: number): BlockMaskBuffer;
    /**
     * Get the bounding box of occupied blocks.
     *
     * @returns Block coordinate bounds, or null if no blocks are occupied.
     */
    getOccupiedBlockBounds(): {
        minBx: number;
        minBy: number;
        minBz: number;
        maxBx: number;
        maxBy: number;
        maxBz: number;
    } | null;
    /**
     * Get the bounding box of navigable (non-fully-solid) blocks. A block is
     * navigable if it is EMPTY or MIXED (i.e. contains at least one empty
     * voxel). Useful when the runtime treats out-of-grid as solid, so fully
     * solid blocks beyond the navigable region can be cropped away.
     *
     * @returns Block coordinate bounds, or null if every block is solid.
     */
    getNavigableBlockBounds(): {
        minBx: number;
        minBy: number;
        minBz: number;
        maxBx: number;
        maxBy: number;
        maxBz: number;
    } | null;
    /**
     * Find the nearest free (unblocked) voxel to a seed position using
     * expanding cube shells.
     *
     * @param blocked - Grid to search for free cells in.
     * @param seedIx - Seed voxel X coordinate.
     * @param seedIy - Seed voxel Y coordinate.
     * @param seedIz - Seed voxel Z coordinate.
     * @param maxRadius - Maximum search radius in voxels.
     * @returns Coordinates of the nearest free voxel, or null.
     */
    static findNearestFreeCell(blocked: SparseVoxelGrid, seedIx: number, seedIy: number, seedIz: number, maxRadius: number): {
        ix: number;
        iy: number;
        iz: number;
    } | null;
}
export { BLOCK_EMPTY, BLOCK_MIXED, BLOCK_SOLID, BLOCKS_PER_WORD, EVEN_BITS, FACE_MASKS_HI, FACE_MASKS_LO, SOLID_HI, SOLID_LO, SOLID_WORD, SparseVoxelGrid, TYPE_MASK, readBlockType, writeBlockType };
