/** * Sol interactive mesh — orchestrator. * * Each tile becomes a single hex prism spanning `[coreRadius, coreRadius + * solHeight]`, with `solHeight ∈ [0, shellThickness]` driven by the palette. * The atmosphere is **not** part of this mesh anymore — it lives on a * dedicated board mesh (`buildAtmoBoardMesh`) built from its own hexasphere. * * This file is the **assembly point**. The heavy lifting is delegated: * - {@link buildLayeredMergedGeometry} — geometry merge + per-tile ranges. * - {@link buildLayeredMaterials} — sol material. * - {@link buildLayeredTileVisuals} — sea anchor / palette / per-tile RGB cache. * - {@link buildLayeredColorBuffer} — vertex-color attribute + tile writes. * - {@link buildLayeredHoverRing} — hover + pin ring renderer. * - {@link buildLiquidShell} — stacked hex liquid cap on submerged tiles. * * The orchestrator owns the state machine (current hover/pin id, sea-level * band) and routes calls into the right collaborator; the public * {@link LayeredInteractiveMesh} surface is preserved so existing * orchestration and overlay consumers keep working with minor adjustments * (the per-layer overlay dispatch collapses to a single primitive, since * the mesh is now sol-only). */ import * as THREE from 'three'; import type { BodySimulation } from '../../sim/BodySimulation'; import type { TerrainLevel } from '../types/terrain.types'; import type { BodyVariation } from '../body/bodyVariation'; import { type HoverConfig } from '../../config/render'; import type { HoverChannel } from '../state/hoverState'; import type { GraphicsUniforms } from '../hex/hexGraphicsUniforms'; import type { InteractiveMesh } from '../body/buildInteractiveMesh'; import type { InteractiveLayer } from '../types/bodyHandle.types'; import { resolveSolHeight } from './layeredShellMetrics'; import type { RaycastState } from '../body/interactiveController'; export { resolveSolHeight }; export type { InteractiveLayer }; /** * Sol interactive mesh interface — `InteractiveMesh` plus the mutation * primitives that only make sense on the sol layer (height mutation, * sea-level repaint, layered overlay). */ export interface LayeredInteractiveMesh extends InteractiveMesh { /** * Sol band thickness (`solOuterRadius - coreRadius`). Lets callers scale * runtime heights into world units. */ totalThickness: number; /** * Mutates the sol height of the given tiles in place. Rewrites position, * normal and `aSolHeight` attributes for each affected tile — vertex * counts stay stable thanks to always-emitted walls in * {@link buildLayeredPrismGeometry}. * * Silently skips unknown tile ids. Heights are clamped to * `[0, maxTerrainHeight]`. */ updateTileSolHeight: (updates: Map) => void; /** * World-space position at the top of the sol cap for a tile. Returns * `null` for unknown ids. Consumers use it to anchor labels, projectors * or resource markers on the sol board. */ getTilePosition: (tileId: number) => THREE.Vector3 | null; /** * Stamps per-tile RGB into the sol vertex buffer. Same effect as * {@link InteractiveMesh.writeTileColor} called in a loop, but flips the * dirty flag once at the end. */ applyTileOverlay: (colors: Map) => void; /** * Sets the world-space radius of the liquid surface sphere. Use with * {@link LayeredInteractiveMesh.totalThickness} to express runtime * heights: e.g. `setSeaLevel(coreRadius + userHeight)`. A value `≤ 0` * hides the liquid mesh. * * No-op when the body has no liquid configured (dry rocky, metallic, …). */ setSeaLevel: (worldRadius: number) => void; /** * Current sea level world radius. Returns `-1` on dry / frozen bodies * (no liquid surface). Used by the upstream hover cursor as the cap * radius for the liquid layer. */ getSeaLevelRadius: () => number; /** Toggles the liquid surface visibility. No-op on dry bodies. */ setLiquidVisible: (on: boolean) => void; /** Sets the liquid surface alpha in `[0, 1]`. No-op on dry bodies. */ setLiquidOpacity: (alpha: number) => void; /** * Live-patches the liquid surface tint. No-op on dry / frozen bodies. * Substance-agnostic — the caller resolves the chemistry (h2o, ch4, …) * and passes the resolved colour through. */ setLiquidColor: (color: THREE.ColorRepresentation) => void; /** Toggles the entire sol mesh visibility (sol + liquid). */ setVisible: (on: boolean) => void; /** * Forces the sol material to render with flat (light-independent) * shading when enabled. Used by the playable views (`'surface'`, * `'atmosphere'`) so star-driven shadows don't hide tiles on the * night side of the body. PBR channels (roughness, metalness, future * per-tile biome attributes) stay intact — only the directional * contribution of scene lights is bypassed. */ setFlatLighting: (enabled: boolean) => void; /** * Resolves the raycast target for the sol mesh — the mesh itself, with * its accelerated BVH. The mesh may be hidden by the view switcher; * the controller copies the body's `matrixWorld` onto it before each * query so raycasting still works while it sits invisible. */ getRaycastState: () => RaycastState; /** * Resolves the raycast target for the liquid shell, when the body * carries one. Returns `null` on dry bodies / frozen bodies (no liquid * shell built). The mesh is the merged liquid cap; `faceToTileId` * maps a triangle index back to the tile it covers, letting callers * tell which water hex the user is hovering. */ getLiquidRaycastState: () => { mesh: THREE.Mesh; faceToTileId: readonly number[]; } | null; } /** Required dependencies + optional tuning for {@link buildLayeredInteractiveMesh}. */ export interface LayeredInteractiveMeshOptions { /** Per-body hover publication channel — forwarded to upstream cursor consumers. */ hoverChannel: HoverChannel; /** Per-body graphics uniform bag — wired into the liquid shell shader. */ graphicsUniforms: GraphicsUniforms; /** Optional hover overlay visual tuning. Falls back to {@link DEFAULT_HOVER}. */ hoverCfg?: HoverConfig; } /** * Builds the sol interactive mesh for a rocky / metallic / gaseous body. * * @param sim - Pre-computed simulation (tiles, states, palette bridge). * @param levels - Palette driving vertex colours and per-tile sol heights. * @param variation - Deterministic visual variation for the sol shader. * @param options - Per-body channels + optional tuning. */ export declare function buildLayeredInteractiveMesh(sim: BodySimulation, levels: TerrainLevel[], variation: BodyVariation, options: LayeredInteractiveMeshOptions): LayeredInteractiveMesh; //# sourceMappingURL=buildLayeredInteractiveMesh.d.ts.map