/** * Strategy resolution for body rendering. * * Two top-level body kinds (`'planetary'` / `'star'`) share the same handle * shape but use structurally different mesh pipelines (`useStar` vs the * planetary scene assembler). Stars are a single strategy; planetary bodies * pick a {@link SurfaceLook} ('terrain' / 'bands' / 'metallic') that drives * palette generator + atmo defaults + shader family. * * Adding a new visual archetype on a planet = one entry in * {@link SURFACE_LOOK_STRATEGIES}. Adding a new top-level kind (`'blackhole'` * later) = a new pipeline branch in `useBody`. */ import type { BodyConfig } from '../../types/body.types'; import type { SurfaceLook } from '../../types/surface.types'; import type { BodyVariation } from './bodyVariation'; import type { TerrainLevel } from '../types/terrain.types'; import type { ParamMap } from '../../shaders/BodyMaterial'; import { type LibBodyType } from '../../shaders'; /** * Per-type variation ranges for the **sol-side** procedural effects * (cracks, lava, blend mode pick). Optional on {@link BodyTypeStrategy}: * only metallic bodies override the defaults — every other strategy * falls back to `DEFAULT_SOL_RANGES` defined in `bodyVariation.ts`. */ export interface SolVariationRanges { /** `[min, max]` linear range for the crack width multiplier. */ crackWidth: readonly [number, number]; /** `[min, max]` linear range for the crack scale multiplier. */ crackScale: readonly [number, number]; /** `[min, max]` linear range for the lava scale multiplier. */ lavaScale: readonly [number, number]; /** * Returns the crack blend mode index (matches `crackBlend` slider in * `BODY_PARAMS`). Driven by a per-type rule rather than a uniform range * because metallic bodies bias toward a binary Mix / Soft-Light pick. */ pickCrackBlend(rng: () => number): number; } /** * Data + builders for a single {@link BodyType}. * * Fields are deliberately flat data when possible — `flatSurface`, * `atmoLayerMode`, `metallicSheen` are read-only constants the consumer * lifts straight off the strategy, no function call. The two builders * (`buildPalette`, `buildShaderParams`) wrap the per-type logic that's * too large for a flat record. */ export interface BodyTypeStrategy { /** Human-readable name — used for logs / panels, not for dispatch. */ readonly displayName: string; /** * Shader family used by the procedural material — selects which fragment * shader runs (`rocky.frag`, `gas.frag`, `metallic.frag`, `star.frag`). * Decoupled from the public {@link BodyType} so the shader catalogue can * keep its current names while the public taxonomy moves to * `'planetary' | 'star'` + {@link SurfaceLook}. */ readonly shaderType: LibBodyType; /** * `true` when the smooth-sphere display should be flat (no vertex * displacement) — currently only stars, whose granulation is a shader * effect rather than terrain relief. */ readonly flatSurface: boolean; /** * `true` when the smooth display sphere plays the role of the * atmosphere itself (gas-giant case) instead of being an inert sol * backdrop. Drives four downstream behaviours: * - the smooth sphere stretches to `config.radius` (atmospheric silhouette) * - it stays visible as a backdrop dome in the playable surface view * - its `Side` flips to `BackSide` in surface view (inner curvature read) * - default vertex paint is skipped (caller paints atmo-flavoured colours) */ readonly displayMeshIsAtmosphere: boolean; /** * Per-type sol-side variation ranges. Omitted by every strategy that * matches the lib's defaults — only metallic bodies override. */ readonly solVariationRanges?: SolVariationRanges; /** * Default atmosphere opacity for the `'shader'` view, in `[0, 1]`. The * config can override via `BodyConfig.atmosphereOpacity`. Gas giants land * at `1` (opaque envelope, smooth sphere can be skipped); rocky bodies * use a translucent halo (~`0.45`); metallic and stars default to `0` * (no atmo halo on shader view). */ readonly defaultAtmosphereOpacity: number; /** Whether this body type can ever carry a decorative ring system. */ readonly canHaveRings: boolean; /** * Metallic sheen coefficient passed to the legacy hex shader. `1.0` for * metallic bodies, `0.0` otherwise. Lifted into the strategy so the * shader override receives a single numeric input. */ readonly metallicSheen: number; /** * Returns the tile-reference radius used to derive the hexasphere * subdivision count. Stars use {@link STAR_TILE_REF} keyed by spectral * class (so tile counts stay stable across O/B/A/F/G/K/M); planets * use their own visual radius. */ tileRefRadius(config: BodyConfig): number; /** * Builds the terrain palette at the given band count. Each strategy * is responsible for densification + re-mapping to the integer band * model used downstream — the function returns the final palette * (length === count, threshold `i+1` per band, `Infinity` on the * last band, height = `i × layout.unit` or `0` when `flatSurface`). */ buildPalette(config: BodyConfig, count: number, coreRadiusRatio: number): TerrainLevel[]; /** * Builds the shader uniform map for this body's procedural material. * Combines the type's default param block with caller-supplied * physics + variation. Receives the deterministic seed so each * strategy can stamp it on its own field naming. */ buildShaderParams(config: BodyConfig, seed: number, variation?: BodyVariation): ParamMap; } /** * Strategy table for planetary surface looks. Adding a new visual archetype * (`'crystalline'`, `'oceanic'`, …) collapses to one entry here plus a new * discriminant in {@link SurfaceLook}. */ export declare const SURFACE_LOOK_STRATEGIES: Readonly>; /** * Resolves the strategy for a body. Stars use a fixed strategy (their * pipeline is structurally different); planetary bodies pick a * {@link SurfaceLook}, defaulting to `'terrain'` when the config omits it. */ export declare function strategyFor(config: BodyConfig): BodyTypeStrategy; //# sourceMappingURL=bodyTypeStrategy.d.ts.map