/**
 * ECS component representing a fluid volume — one {@link FluidField} plus its placement
 * in world space.
 *
 * Behaviour (stepping the simulation, dispatching effectors, re-anchoring on Transform
 * motion) lives on {@link FluidSystem}, not here. This component is pure data.
 *
 * World ↔ grid mapping is uniform and axis-aligned: cell `(0,0,0)`'s center sits at
 * {@link origin}, and cells are spaced {@link cell_size} world-units apart along each
 * axis. For non-uniform or oriented volumes, use multiple components.
 *
 * **Static placement**: leave the entity without a `Transform`. Set {@link origin}
 * directly and the system never touches it.
 *
 * **Moving placement**: pair the entity with a `Transform`. The system re-anchors the
 * grid on every fixedUpdate to `quantize(transform.position, cell_size) + offset`, and
 * when the quantization changes shifts the field by the integer cell delta (carrying
 * fluid data along with the grid so the fluid appears to stay put in world space) and
 * patches the newly exposed edges with a Neumann zero-gradient extrapolation. {@link
 * origin} becomes system-managed in this case.
 *
 * NOTE on layout: sibling physics ECS code lives under `engine/ecs/*` (see
 * `engine/ecs/ik/InverseKinematicsSystem.js`). This component is placed inside the
 * fluid package because edits to the ECS folder were out-of-scope when it was first
 * written. Moving it under `engine/ecs/fluid/` later is a pure relocation.
 */
export class FluidComponent {
    /**
     * @type {FluidField}
     */
    field: FluidField;
    /**
     * World position of grid cell `(0,0,0)`'s center. For static placement (no
     * `Transform` on the entity) the user sets this directly. For moving placement
     * (with `Transform`) {@link FluidSystem} owns it — every fixedUpdate it computes
     * the desired origin from the transform and either snaps on first sync or shifts
     * the field by the integer cell delta.
     * @type {[number, number, number]}
     */
    origin: [number, number, number];
    /**
     * World-space offset added to the quantized `Transform.position` when computing
     * the grid centre. Use to place the grid asymmetrically relative to the entity —
     * e.g. `[-2, 0, 0]` puts the centre 2 world units behind the entity.
     *
     * Only consulted when a `Transform` is present (otherwise `origin` is fully
     * user-controlled).
     * @type {[number, number, number]}
     */
    offset: [number, number, number];
    /**
     * Uniform world-space spacing between adjacent cell centers.
     * @type {number}
     */
    cell_size: number;
    /**
     * Half-cell extra margin (in cells) the Transform must cross before the field
     * re-quantizes to the next cell. Without it, a Transform jittering right on the
     * boundary between two cells would re-shift every frame, repeatedly clearing the
     * solid mask and patching velocity edges — visible as flicker in the fluid and
     * thrashing in any solid-voxelizer downstream of the shift.
     *
     * Mechanism: the system keeps the current quantized cell `q` and only re-quantizes
     * when `|transform.position / cell_size - q| > 0.5 + hysteresis`. Crossing the
     * threshold snaps to the new nearest cell — not the threshold position — so motion
     * past the deadband still produces a single discrete shift.
     *
     * Range `[0, 0.5)`. `0` disables (snap on any boundary crossing). Default `0.1`
     * gives a ~10%-of-a-cell deadband on each side, killing jitter while staying
     * imperceptible at typical cell sizes.
     *
     * Only consulted when a `Transform` is present.
     * @type {number}
     */
    hysteresis: number;
    /**
     * If false, {@link FluidSystem} skips this volume's step. Use to pause fluid for
     * culled or off-screen volumes.
     * @type {boolean}
     */
    enabled: boolean;
    /**
     * Set by {@link FluidSystem} on the first reanchor — distinguishes "snap origin
     * to the desired position without shifting" (first sync) from "shift the field
     * by the integer cell delta" (subsequent syncs). User code should not touch this.
     * @type {boolean}
     */
    anchored: boolean;
    /**
     * Convert a world-space point to fractional grid coordinates.
     * @param {Float32Array|number[]} out  length-3 destination
     * @param {number} wx
     * @param {number} wy
     * @param {number} wz
     * @return {Float32Array|number[]} `out`, for chaining.
     */
    worldToGrid(out: Float32Array | number[], wx: number, wy: number, wz: number): Float32Array | number[];
    /**
     * Convert fractional grid coordinates to a world-space point.
     * @param {Float32Array|number[]} out  length-3 destination
     * @param {number} gx
     * @param {number} gy
     * @param {number} gz
     * @return {Float32Array|number[]} `out`, for chaining.
     */
    gridToWorld(out: Float32Array | number[], gx: number, gy: number, gz: number): Float32Array | number[];
    /**
     * Sample velocity at a world-space point. The velocity values stored in the field
     * are in "grid cells per second"; this method does NOT rescale them, on the
     * assumption that callers (vegetation sway, dust drift) interpret the field as a
     * direction × magnitude wind and want consistent strength regardless of the
     * underlying cell size.
     *
     * If you need world-units-per-second velocity, multiply the result by `cell_size`.
     *
     * @param {Float32Array|number[]} out  length-3 destination
     * @param {number} wx
     * @param {number} wy
     * @param {number} wz
     * @return {Float32Array|number[]} `out`, for chaining.
     */
    sampleVelocityAtWorld(out: Float32Array | number[], wx: number, wy: number, wz: number): Float32Array | number[];
    /**
     * Sample a passive scalar at a world-space point.
     * @param {string} name
     * @param {number} wx
     * @param {number} wy
     * @param {number} wz
     * @return {number}
     */
    sampleScalarAtWorld(name: string, wx: number, wy: number, wz: number): number;
    /**
     * @param {FluidComponent} other
     * @return {boolean}
     */
    equals(other: FluidComponent): boolean;
    /**
     * @return {number}
     */
    hash(): number;
    /**
     * Write the field's world-space axis-aligned bounding box into `out`. Used by
     * {@link FluidSystem} as a broad-phase target when filtering effectors. The box
     * spans cell `(0, 0, 0)` (centred at `origin`) to cell `(res_x-1, res_y-1, res_z-1)`
     * plus a `cell_size` margin on the far side, so a point exactly on the field's
     * boundary cells lies inside the AABB.
     *
     * @param {AABB3} out
     */
    getBoundingBox(out: AABB3): void;
    isFluidComponent: boolean;
}
import { FluidField } from "../FluidField.js";
//# sourceMappingURL=FluidComponent.d.ts.map