/** * Hex liquid cap — flat hex tiles laid at the waterline over every * submerged tile when the body's surface liquid is in the `liquid` state. * * Each tile contributes only its **top fan** (no walls): water is a * surface, not a column, so there is nothing meaningful to draw between * the waterline and the underlying mineral floor. Skipping the walls * also avoids the visual clutter that ice-style stacked prisms produce * when rendered translucent — neighbour walls would otherwise show * through as a thicket of vertical slabs. The mineral floor stays * visible through the translucent surface, giving the underwater * relief read for free. * * No mining API on purpose — water cannot be destroyed, so the handle * exposes only `setTopElevation` (sea-level slider), `setOpacity`, * `setVisible`, `tick` (advances the wave animation) and `dispose`. * * Substance-agnostic: the caller resolves the liquid identity (h2o, * ch4, …) and pushes a single tint via {@link LiquidShellConfig.color}. */ import * as THREE from 'three'; import type { Tile } from '../../geometry/hexasphere.types'; import type { TerrainLevel } from '../types/terrain.types'; import type { GraphicsUniforms } from '../hex/hexGraphicsUniforms'; /** Inputs for {@link buildLiquidShell}. */ export interface LiquidShellConfig { /** Tiles eligible for the cap — typically every tile below the waterline. */ tiles: readonly Tile[]; /** Per-tile underlying mineral elevation in band space (wall start). */ baseElevation: ReadonlyMap; /** Uniform top elevation in band space — the waterline. */ topElevation: number; /** Palette feeding the band → world-height conversion (must match the sol mesh). */ palette: TerrainLevel[]; /** World-space surface radius of the body (= `BodyConfig.radius`). */ bodyRadius: number; /** World-space radius of the inner core sphere. */ coreRadius: number; /** Resolved liquid tint (caller-owned chemistry). */ color: THREE.ColorRepresentation; /** Initial alpha in `[0, 1]` — defaults to 0.78 (translucent water). */ opacity?: number; /** * Per-body graphics-uniform bag — wires the wave / specular / opacity * uniforms into the shader and lets `setOpacity` push slider changes * without rebuilding the material. */ graphicsUniforms: GraphicsUniforms; } /** Handle returned by {@link buildLiquidShell}. */ export interface LiquidShellHandle { /** Root group — attach under the body's group. */ group: THREE.Group; /** The merged liquid mesh — single draw call, single material. */ mesh: THREE.Mesh; /** `faceToTileId[i]` returns the tile id of the i-th triangle. */ faceToTileId: readonly number[]; /** * Re-elevates every prism to a new uniform top band (band space) so * the cap surface tracks a moving sea level. Submerged tiles whose * base is already at or above the new top end up collapsed. */ setTopElevation: (newTopBand: number) => void; /** * Re-bases the wall start of one or more tiles in band space. Used * when the underlying sol cap moves (digging, scripted lift) so the * liquid hex follows: a tile dug below the current waterline gains * a liquid cap, a tile lifted above it loses it (collapses). * Re-uses the last `setTopElevation` request as the clamp ceiling * so the cap top stays on the current sea level after the mutation. * Unknown tile ids are silently skipped. */ setBaseElevation: (updates: ReadonlyMap) => void; /** Toggles mesh visibility. */ setVisible: (on: boolean) => void; /** Updates the alpha in `[0, 1]`. Syncs the per-body shader uniform. */ setOpacity: (alpha: number) => void; /** * Live-patches the liquid tint without rebuilding the material. The * caller resolves the substance (h2o, ch4, …) and passes the resolved * color in any `THREE.ColorRepresentation` form (hex string, hex int, * `THREE.Color`). The shader's per-fragment colour shifts (foam, depth * darken) keep working unchanged — they read the diffuse base after * this update. */ setColor: (color: THREE.ColorRepresentation) => void; /** Advances the wave animation clock. */ tick: (elapsed: number) => void; /** Releases GPU resources. */ dispose: () => void; } /** * Builds the merged hex liquid cap and returns a non-mineable handle. * * Tiles missing from `baseElevation`, or whose base sits at or above * `topElevation`, are silently skipped. Empty input produces a hidden * placeholder mesh so callers can unconditionally hold the handle. */ export declare function buildLiquidShell(config: LiquidShellConfig): LiquidShellHandle; //# sourceMappingURL=buildLiquidShell.d.ts.map