import type { Bounds, Vec3 } from './types'; /** * Where a player should stand when they enter an imported Scene. * * Deriving the spawn from the bounding box alone cannot work: the box's minimum * Y is the lowest point anywhere on the sheet (a shoreline, a basement, the * underside of a bridge), and its centre in X/Z is a corner for any source * whose local origin sits at one edge. Both mistakes put the player in open air * with nothing under them, which is indistinguishable from a broken collision * mesh. * * So probe the real geometry instead: drop a ray straight down at a candidate * point, take the highest surface it hits, and require standing headroom above * it so the spawn is never inside a building or under a canopy. */ export type SpawnProbeResult = { position: Vec3; /** Surface height the ray actually hit, before clearance was added. */ groundY: number; /** How many candidates were rejected before this one, for the receipt. */ rejectedCandidates: number; }; export type ProbeTriangle = readonly [Vec3, Vec3, Vec3]; /** * Highest surface at (x, z), or null when the downward ray misses the geometry * entirely — which is the signal that this candidate is over open air. */ export declare function columnAt(triangles: readonly ProbeTriangle[], x: number, z: number): { groundY: number; surfaces: number; } | null; /** * Barycentric height of a triangle at (x, z), or null when (x, z) falls outside * its vertical projection or the triangle is edge-on (zero projected area). */ export declare function triangleHeightAt(triangle: ProbeTriangle, x: number, z: number): number | null; /** * Walks candidate points outward from the centre of the sheet in a square * spiral, returning the first that has real ground under it. Falls back to the * top of the bounds only when the geometry is missed everywhere, which is an * honest "I could not find ground" rather than a fabricated standing position. */ export declare function probeSpawn(input: { triangles: readonly ProbeTriangle[]; bounds: Bounds; clearanceHeightM: number; /** Candidate grid resolution across the sheet. */ samples?: number; }): SpawnProbeResult; /** * True when the ground within `radius` of (x, z) stays within * OPEN_GROUND_TOLERANCE_M of the candidate's own height in every direction. A * tree canopy, a rooftop edge and a wall all fail this; a street passes. */ export declare function isFlatNeighbourhood(triangles: readonly ProbeTriangle[], x: number, z: number, groundY: number, radius: number): boolean;