/** * Build the hit-test grid's AABB set from the resident WASM transform store, * instead of recomputing every world AABB in JavaScript. * * Why this exists: the WASM hit grid's *kernel* is 65-170x faster than the JS * depth-first walk, but the integrated path was measured **slower** for an * ordinary hover — 11.2ms versus 39us at 100k entities. All of that went to the * JS gather in front of it: walk the tree, `getWorldTransform()`, `getBounds()`, * transform four corners per entity, push into arrays, copy into WASM views. The * kernel win was real and the gather ate it. * * When the transform backend is active, those world AABBs already exist inside * WASM memory: `compose_*` filled the world matrices and `compute_aabbs` reduced * them to `aminx/aminy/amaxx/amaxy`. So the gather can become a copy between two * views of the *same* linear memory (possible only because all backends now share * one instance) plus the index remap below. * * The remap is the whole subtlety. Two different index spaces are in play: * * - The **transform store** re-indexes entities into depth-ordered, contiguous * sibling runs, because that is what the SIMD composer needs. * - The **hit grid** requires strict **pre-order** indices, because its * `idx > best` tie-break is only equivalent to `findHitRecursively`'s * topmost-hit priority under that numbering. * * Those orders differ, so this walks the tree in pre-order exactly as * {@link gatherHitAABBs} does — preserving the priority invariant — and for each * entity reads its AABB from `entity._storeSlot`. Nothing about which entity wins * a hit changes; only where the four numbers come from. */ import type { Entity } from '../tree/Entity'; import type { HitGatherResult } from './hit-store'; /** The resident world-AABB views of the transform backend. */ export interface ResidentAabbs { aminx: Float64Array; aminy: Float64Array; amaxx: Float64Array; amaxy: Float64Array; } /** * Pre-order walk collecting AABBs out of the transform store. * * Returns `null` when the store cannot answer for some entity — an unassigned or * out-of-range `_storeSlot`, which happens legitimately when the tree changed * after the last store rebuild. The caller then falls back to the JS gather * rather than indexing a stale slot, because a wrong AABB would mean a wrong * entity under the cursor, and a slower correct answer beats a fast wrong one. * * `slotEntity` here is the *hit* grid's pre-order mapping, unrelated to the * transform store's slots despite the shared name in the result type. */ export declare function gatherHitAABBsFromStore(root: Entity, aabbs: ResidentAabbs, storeSlotEntity: readonly Entity[], out: HitGatherResult): HitGatherResult | null; /** A reusable result buffer, so the fused path allocates nothing per query. */ export declare function createHitGatherBuffer(): HitGatherResult;