import type { EntityPosition } from "./entityStore.js"; /** * Compact, serializable triangle collision mesh measured at asset reindex — the renderer-free source * of mesh-accurate hitboxes. Positions are welded onto a 16-bit grid spanning `min`..`max` (model * space) and stored base64-encoded, so an opted-in catalog asset ships its collision triangles inside * the generated index without the runtime ever touching the rendered scene graph. */ export interface CollisionMeshData { /** Model-space bounds of the encoded vertices — the quantization frame. */ min: readonly [number, number, number]; max: readonly [number, number, number]; /** Welded vertex count; `positions` holds exactly `vertexCount * 3` u16 values. */ vertexCount: number; /** Triangle count; `indices` holds exactly `triangleCount * 3` values. */ triangleCount: number; /** Base64 little-endian u16 xyz triples, each axis normalized 0..65535 across `min`..`max`. */ positions: string; /** Base64 little-endian triangle vertex indices — u16, or u32 when `vertexCount` exceeds 65536. */ indices: string; /** * Optional compact model-space solid decomposition from {@link voxelizeToBoxes} — a deterministic set * of AABBs approximating the model's filled volume so movement obstruction can slide a capsule against * the real pillars/lintel of a concave opening (walk THROUGH an arch) instead of one outer box. Absent * for models whose voxelization is empty, keeping box-less assets byte-identical. */ boxes?: readonly { min: readonly [number, number, number]; max: readonly [number, number, number]; }[]; } /** Raw triangle soup for {@link encodeCollisionMesh}: model-space xyz triples plus triangle indices. */ export interface CollisionMeshSource { positions: ArrayLike; indices: ArrayLike; } /** * Decoded, BVH-indexed triangles ready for per-ray queries — build once per asset via * {@link prepareCollisionMesh}. Treat the fields as opaque; they exist so the raycast hot path can * run allocation-free over flat arrays. */ export interface PreparedCollisionMesh { /** Dequantized model-space vertex xyz triples. */ readonly positions: Float32Array; /** Triangle vertex indices, 3 per triangle. */ readonly indices: Uint32Array; /** Per-node AABBs, 6 floats (minXYZ, maxXYZ) per node. */ readonly nodeBounds: Float32Array; /** Leaf: first slot in `triOrder`. Internal: right-child node index (left child is `node + 1`). */ readonly nodeStart: Int32Array; /** Leaf: triangle count (> 0). Internal: 0. */ readonly nodeCount: Int32Array; /** Triangle indices grouped by leaf ranges. */ readonly triOrder: Uint32Array; } /** Nearest triangle impact from {@link raycastCollisionMesh}: world distance along the ray and the world-space geometric normal facing the ray. */ export interface CollisionMeshHit { distance: number; normal: EntityPosition; } /** * Quantize a triangle soup onto the 16-bit grid, weld coincident vertices, and drop triangles that * collapse — the reindex-time compressor producing {@link CollisionMeshData}. Returns `null` when no * finite, non-degenerate triangle survives. */ export declare function encodeCollisionMesh(source: CollisionMeshSource): CollisionMeshData | null; /** * Decompose a triangle soup into a compact, deterministic set of model-space AABBs approximating its * solid volume — the movement-obstruction counterpart to the raycast BVH. Rasterizes triangles onto a * `cellSize` voxel grid, fills each vertical column between its lowest and highest occupied voxel (so a * solid becomes solid and a concave opening — an archway — keeps its central gap empty while its pillars * and lintel fill in), then greedy-merges occupied voxels into AABBs in a fixed z→y→x order. Pure and * allocation-tolerant (runs once per asset at reindex). Caps the output at `maxBoxes`, folding any * remainder into one enclosing AABB so obstruction stays conservative. Returns `[]` for degenerate input. * @internal */ export declare function voxelizeToBoxes(source: CollisionMeshSource, cellSize?: number, maxBoxes?: number): { min: [number, number, number]; max: [number, number, number]; }[]; /** * Build a prepared BVH mesh straight from a runtime triangle soup (float positions + indices) — * the renderer-fed counterpart to {@link prepareCollisionMesh}, feeding * `ctx.scene.entity.reportCollisionMesh` / `ctx.scene.object.reportCollisionMesh` without a * quantize/encode round-trip. Copies and sanitizes the input: triangles referencing out-of-range, * non-finite, or repeated vertices are dropped. Returns `null` when no triangle survives. */ export declare function prepareCollisionMeshSource(source: CollisionMeshSource): PreparedCollisionMesh | null; /** * Decode a stored collision mesh and index it with a BVH. Memoized per data object, so the shell and * a headless host preparing the same catalog entry share one build. Returns `null` (also memoized) * when the payload is malformed. */ export declare function prepareCollisionMesh(data: CollisionMeshData): PreparedCollisionMesh | null; /** * Nearest triangle hit for a world-space ray against a prepared mesh placed like its rendered model: * model space scaled uniformly by `scale`, translated by entity-local `translate`, yaw-rotated by * `rotationY`, and moved to `position` — the same composition {@link "scene/colliders".ModelBodySource} * fitting applies to the AABB. Allocation-free until the returned hit. `distance` is world distance * along `direction` (callers pass `direction` normalized); `normal` is the world-space geometric * triangle normal facing the ray. */ export declare function raycastCollisionMesh(mesh: PreparedCollisionMesh, origin: EntityPosition, direction: EntityPosition, maxDistance: number, position: EntityPosition, rotationY: number, scale: number, translate: EntityPosition): CollisionMeshHit | null;