/** * Raycasting utilities extracted from Scene. * * Pure math — takes positions/indices/rays and returns intersection results. * No dependency on Scene internal state. */ import type { Vec3, PickClipState } from './types.js'; export interface BoundingBox { min: Vec3; max: Vec3; } /** True when `clip` actually clips anything (a section plane or an enabled box). */ export declare function clipIsActive(clip?: PickClipState | null): boolean; /** * Is world point (x,y,z) clipped away (invisible) by the section plane or crop * box? Mirrors the renderer's fragment discard EXACTLY so a CPU pick can't select * geometry the GPU cropped/sectioned off. Section: discard where * (dot(p,n) - distance) * side > 0; box: discard outside the AABB. */ export declare function pointClipped(clip: PickClipState | null | undefined, x: number, y: number, z: number): boolean; /** * Is the whole AABB clipped away: every corner cut by the section plane, or no * overlap with the crop box? Used to skip fully-hidden entities/boxes before the * triangle test (perf) and to clip the bounding-box-only raycast (released geom). * Conservative: only skips when NOTHING of the box could be visible. */ export declare function boxFullyClipped(clip: PickClipState | null | undefined, box: BoundingBox): boolean; /** * Ray-box intersection test (slab method). * Handles zero ray direction components (axis-aligned rays) safely. */ export declare function rayIntersectsBox(rayOrigin: Vec3, rayDirInv: Vec3, // 1/rayDir for efficiency rayDirSign: [number, number, number], box: BoundingBox): boolean; /** * Ray-box intersection returning entry distance (tNear). * Returns null if no intersection, otherwise the distance along the ray * to the entry point (clamped to 0 if the ray originates inside the box). * Handles zero ray direction components (axis-aligned rays) safely. */ export declare function rayBoxDistance(rayOrigin: Vec3, rayDirInv: Vec3, rayDirSign: [number, number, number], box: BoundingBox): number | null; /** * Entry distance into the VISIBLE part of `box` under the section plane / crop * box, or null if the box is wholly clipped along the ray. Unlike a plain box * entry, this clips the crop box exactly (AABB intersection) and the section * plane as a half-space, so the released-geometry bbox raycast can't return a box * whose only ray overlap is in the cropped/sectioned-away region. */ export declare function clippedBoxEntryDistance(rayOrigin: Vec3, rayDir: Vec3, rayDirInv: Vec3, rayDirSign: [number, number, number], box: BoundingBox, clip: PickClipState | null | undefined): number | null; /** * Möller–Trumbore ray-triangle intersection. * Returns distance to intersection or null if no hit. */ export declare function rayTriangleIntersect(rayOrigin: Vec3, rayDir: Vec3, v0: Vec3, v1: Vec3, v2: Vec3): number | null; /** Result of a CPU raycast hit. */ export interface RaycastHit { expressId: number; distance: number; modelIndex?: number; } /** * Precompute inverse direction and sign arrays for a ray direction. * Shared by both the boolean and distance box tests. */ export declare function prepareRayDirInv(rayDir: Vec3): { rayDirInv: Vec3; rayDirSign: [number, number, number]; }; /** * CPU raycast against bounding-box-only data (post geometry release). * Returns the closest hit by bounding-box entry distance. */ export declare function raycastBoundingBoxes(rayOrigin: Vec3, rayDir: Vec3, rayDirInv: Vec3, rayDirSign: [number, number, number], boundingBoxes: Map, hiddenIds?: Set, isolatedIds?: Set | null, clip?: PickClipState | null): RaycastHit | null; /** * CPU raycast against triangle mesh data with a bounding-box pre-filter. * * @param rayOrigin - Ray origin in world space * @param rayDir - Normalised ray direction * @param meshDataMap - Map expressId -> MeshData[] (positions, normals, indices, entityIds) * @param getEntityBoundingBox - Function to obtain/cache a bounding box per entity * @param hiddenIds - Optional set of hidden expressIds to skip * @param isolatedIds - Optional set; when non-null only these expressIds are tested */ export declare function raycastTriangles(rayOrigin: Vec3, rayDir: Vec3, rayDirInv: Vec3, rayDirSign: [number, number, number], meshDataMap: Map, getEntityBoundingBox: (expressId: number) => BoundingBox | null, hiddenIds?: Set, isolatedIds?: Set | null, clip?: PickClipState | null): RaycastHit | null; //# sourceMappingURL=scene-raycaster.d.ts.map