import type { Vec3 } from "../world/geometry.js"; import { type NavMeshData, type NavMeshLink, type NavMeshPath, type NavMeshQueryOptions } from "./navMesh.js"; /** What an authored off-mesh connection crosses; the runtime prices it by kind unless the author sets a cost. */ export type NavLinkKind = "door" | "ladder" | "jump" | "link"; /** * A connection the scene author places between two spots — a door through a wall, a ladder to a * deck, a jump across a gap. Authored as world points, not polygon ids, so it survives a re-bake: * {@link NavRuntime.applyMesh} resolves each end onto the nearest walkable polygon. */ export interface AuthoredNavLink { /** Stable authored id; reported by `unresolvedLinks()` when an end no longer touches the mesh. */ id: string; /** Traversal kind; prices the link when `cost` is absent. Default `"link"`. */ kind?: NavLinkKind; /** World point the agent leaves from. */ from: Vec3; /** World point the agent arrives at. */ to: Vec3; /** Path cost in world units; overrides the kind's price. Non-finite or negative falls back to the kind. */ cost?: number; } /** An XZ box naming the authored area a scene edit touched, so routing state elsewhere is left alone. */ export interface NavRegion { min: readonly [number, number]; max: readonly [number, number]; } /** How one {@link NavRuntime.applyMesh} exchange changed the mesh. */ export interface NavRebuildStats { /** Polygons in the new bake that have no predecessor. */ added: number; /** Older polygons the new bake no longer contains. */ removed: number; /** Older polygons the new bake still contains, matched by geometry — their routes stay valid. */ kept: number; /** Old polygon index → its index in the new mesh, or `-1` when that polygon is gone. */ remap: Int32Array; } /** Serializable tuning and authored links of a {@link NavRuntime}; the baked geometry is replaced by `applyMesh`. */ export interface NavRuntimeSnapshot { areaCosts: Record; maxNodes: number; links: AuthoredNavLink[]; linkCosts: Partial>; linkSnapRadius: number; } /** Runtime seam over a baked {@link NavMeshData}: route, price areas, resolve authored links, rebuild in place. */ export interface NavRuntime { /** The mesh currently routed on — a bake plus the resolved links. */ readonly mesh: NavMeshData; /** Cheapest polygon corridor between two points, funnel-smoothed by the mesh query. */ plan(from: Vec3, to: Vec3): NavMeshPath | null; findPolygon(point: Vec3): number | null; closestPoint(point: Vec3): Vec3 | null; /** True when the straight segment stays on walkable, unblocked polygons. */ raycast(from: Vec3, to: Vec3): boolean; /** * Exchange the bake for a newer one. The new geometry is authoritative; polygons that survive the * re-bake keep their identity through `remap`, so routing state over them stays valid and only the * routes crossing changed polygons need re-planning. */ applyMesh(next: NavMeshData): NavRebuildStats; /** Resolved links the router is using. */ links(): readonly NavMeshLink[]; /** Authored ids whose ends no longer reach the mesh. */ unresolvedLinks(): readonly string[]; /** How many times the mesh was exchanged. */ rebuilds(): number; retune(patch: NavRuntimeOptions): void; snapshot(): NavRuntimeSnapshot; restore(next: NavRuntimeSnapshot): void; /** Drop the devtools probe registered by `devtoolsName`. Safe to call twice. */ dispose(): void; } /** Options for {@link createNavRuntime}. */ export interface NavRuntimeOptions extends NavMeshQueryOptions { /** Authored off-mesh connections resolved onto the current mesh. */ links?: readonly AuthoredNavLink[]; /** Price per link kind, in path-cost units; defaults `door` 0.5, `jump` 1.5, `ladder` 4, `link` 0. */ linkCosts?: Partial>; /** How far an authored link end may sit from the mesh before the link is reported unresolved. Default 2. */ linkSnapRadius?: number; /** Register a devtools probe under this name so the perf overlay shows mesh and routing counters. */ devtoolsName?: string; } /** A bake stored on an editor scene document, structurally compatible with `EditorBake`. */ export interface SceneBake { kind: string; id: string; data: unknown; } /** * Read the named navigation bake an editor wrote onto a scene document. Returns `null` when the * document holds no such bake yet, and throws when the stored bake is not a valid nav mesh — a * corrupt bake should fail at load, not as agents walking through walls. * * @capability navmesh-from-scene read the editor's baked nav mesh off a scene document */ export declare function navMeshFromBake(bakes: readonly SceneBake[] | undefined, id?: string): NavMeshData | null; /** * Route agents over the nav mesh an editor baked. Wraps {@link createNavMeshQuery}, resolves authored * off-mesh links (doors, ladders, jumps) onto the current surface, and exchanges the mesh one scene * region at a time so untouched polygons keep their ids and the agents routing over them keep their paths. * * @capability nav-runtime route agents on an editor-baked nav mesh with authored links and re-bakes that keep polygon identity */ export declare function createNavRuntime(options: NavRuntimeOptions & { mesh: NavMeshData; }): NavRuntime;