import type { NavPoint } from "./navGrid.js"; export type Waypoint = readonly [number, number, number]; export interface PathFollowConfig { waypoints: readonly Waypoint[]; /** World units per second. */ speed: number; /** Wrap back to the first waypoint after the last (never `done`). Default false. */ loop?: boolean; } export interface PathFollowState { position: Waypoint; /** Index of the waypoint the mover is currently travelling toward. */ target: number; /** Yaw (radians) of the current travel direction, matching engine `rotationY`. */ heading: number; done: boolean; /** Total world-distance covered so far — drives progress/leak logic in tower defense. */ distanceTravelled: number; } export interface HeightSampler { sampleHeight(x: number, z: number): number; } export declare function pathFromNav(points: readonly NavPoint[], elevation?: number | HeightSampler, offset?: number): Waypoint[]; /** * Semantic seek target for {@link pathFollowSeek} — the caller-facing progress vocabulary a * stateful path behavior restores from, so a follower can start at a distributed phase or resume * a serialized route without knowing waypoint internals. `direction` (forward heading) falls out of * the resulting {@link PathFollowState.heading}, so it is an output rather than a seek input. */ export type PathProgress = /** Fraction `0..1` of total path length (looping paths wrap; clamped otherwise). */ { readonly kind: "normalized"; readonly value: number; } /** World-distance travelled from the first waypoint (looping paths wrap; clamped otherwise). */ | { readonly kind: "distance"; readonly value: number; } /** Segment `index` (0-based) plus `fraction` `0..1` along that segment. */ | { readonly kind: "segment"; readonly index: number; readonly fraction: number; }; /** Read-only progress readout for inspection/debug tooling, produced by {@link pathFollowProgress}. */ export interface PathFollowProgress { /** Cumulative world-distance travelled (matches {@link PathFollowState.distanceTravelled}). */ distance: number; /** Fraction `0..1` of total path length at the current position. */ normalized: number; /** 0-based index of the segment the mover is currently on. */ segment: number; /** Fraction `0..1` along the current segment. */ fraction: number; } /** * Total world-distance of a path — sum of every segment, including the wrap segment back to the * first waypoint when `loop` is set. Zero for a degenerate (0- or 1-waypoint) path. * * @capability path-length total polyline distance for progress math and seeding */ export declare function pathLength(config: PathFollowConfig): number; /** * Place a follower at a semantic {@link PathProgress} without simulating from the start — the seek * adapter behavior lifecycles use to seed distributed phases and restore serialized routes. Pure; * returns a fresh {@link PathFollowState} whose `heading` gives travel direction. Looping paths wrap * the distance; non-looping paths clamp to `[0, pathLength]` and report `done` at the end. * * @capability path-follow-seek jump a path-follower to normalized/distance/segment progress */ export declare function pathFollowSeek(config: PathFollowConfig, target: PathProgress): PathFollowState; /** * Read a follower's current progress in every semantic form — the inverse of {@link pathFollowSeek}, * for editor/debug inspection and progress HUDs. Pure and allocation-light. * * @capability path-follow-progress read normalized/distance/segment progress from follow state */ export declare function pathFollowProgress(config: PathFollowConfig, state: PathFollowState): PathFollowProgress; export declare function createPathFollow(config: PathFollowConfig): PathFollowState; /** * Advance a path-follower by `speed * dt` along its authored polyline. Pure — returns * the next state. Crosses multiple waypoints in one step, loops when configured, and * reports `done` at the end of a non-looping path. No navmesh required (#52); feed it a * navmesh route via `pathFromNav` for click-to-move (#51). */ export declare function advancePathFollow(config: PathFollowConfig, state: PathFollowState, dt: number): PathFollowState;