import type { GeneratedBuilding } from "./buildings.js"; import type { EnvironmentWorldFeature } from "./features.js"; import type { Aabb } from "./geometry.js"; import type { WallSegment } from "./walls.js"; /** One solid box in world space: the collision half of generated or authored world geometry. */ export interface WorldSolid { center: readonly [number, number, number]; halfExtents: readonly [number, number, number]; /** Yaw about `center`, radians, in the engine's `rotationY` convention. Default `0`. */ rotationY?: number; } /** Serializable contents of a {@link WorldSolids}: every layer's solids by layer id. */ export interface WorldSolidsState { layers: Record; } /** Caller-owned work counters, reset by each world-solid ray candidate query. */ export interface WorldSolidRayWork { /** Hash-grid cell lookups, including empty cells. */ cells: number; /** Indexed entry visits, including duplicates removed before bounds tests. */ entries: number; /** Cached AABB ray tests after deduplication. */ bounds: number; } /** * Static collision for world geometry that is not a scene object: generated buildings, studio * volumes like `city`, wall runs. Solids live in named layers so a feature can replace or drop its * own set without touching the rest. `solidObstaclesNear` (player and NPC movement), * `syncWorldColliders` (physics backends) and `populateNavGridFromSolids` all read this one store. */ export interface WorldSolids { /** Replace a layer's solids; an empty list removes the layer. */ set(layer: string, solids: readonly WorldSolid[]): void; remove(layer: string): void; /** Run several `set`/`remove` calls as one change: one index rebuild, one notification. */ batch(apply: () => void): void; /** Solids in one layer, empty when absent. */ layer(layer: string): readonly WorldSolid[]; layers(): readonly string[]; /** Every solid whose world AABB overlaps `min`..`max`. Bounded by a uniform XZ hash grid. */ inBox(min: readonly [number, number, number], max: readonly [number, number, number]): WorldSolid[]; /** Optional accelerated ray candidates; finite coordinates/direction and nonnegative finite distance, normalized internally. */ inRay?(origin: readonly [number, number, number], direction: readonly [number, number, number], maxDistance: number, work?: WorldSolidRayWork): WorldSolid[]; /** Every solid in every layer. */ all(): WorldSolid[]; count(): number; /** Bumps on every change; cheap cache key for consumers. */ version(): number; subscribe(listener: () => void): () => void; snapshot(): WorldSolidsState; restore(state: WorldSolidsState): void; } /** * Yaw-expanded world AABB of an oriented solid box. * @capability world-solid-bounds world AABB and nav footprint of a world solid */ export declare function worldSolidBounds(solid: WorldSolid): { min: [number, number, number]; max: [number, number, number]; }; /** * XZ footprint of a solid's world AABB, for 2D consumers such as nav grids. * @capability world-solid-bounds world AABB and nav footprint of a world solid */ export declare function worldSolidFootprint(solid: WorldSolid): Aabb; /** * A store of static world solids in named layers. * @capability world-solids collision for generated and authored world geometry (buildings, city lots, walls) */ export declare function createWorldSolids(options?: { cellSize?: number; }): WorldSolids; /** * One solid per generated building: its `bounds` footprint turned by `rotationY` about `center`, * from the ground under its center up through its floors. `groundHeight` defaults to flat `0`. * @capability world-solids-from-data derive collision boxes from generated buildings and wall runs */ export declare function buildingSolids(buildings: readonly GeneratedBuilding[], groundHeight?: (x: number, z: number) => number): WorldSolid[]; /** * Solids for every `structures` descriptor on an environment feature, skipping any marked `solid: false`. * @capability world-solids-from-data derive collision boxes from generated buildings and wall runs */ export declare function structureSolids(world: EnvironmentWorldFeature, groundHeight?: (x: number, z: number) => number): WorldSolid[]; /** Wall height, thickness and base for {@link wallSolids}. */ export interface WallSolidOptions { height: number; thickness: number; /** Ground height under a point; the wall stands on it at each segment's midpoint. Default flat `0`. */ groundHeight?: (x: number, z: number) => number; } /** * One oriented solid per wall segment (see `wallSegments` in `world/walls`). * @capability world-solids-from-data derive collision boxes from generated buildings and wall runs */ export declare function wallSolids(segments: readonly WallSegment[], options: WallSolidOptions): WorldSolid[];