import type { Vec3 } from '../math/vec3.js'; export interface CollisionPlane { normal: Vec3; dist: number; type: number; signbits: number; } export interface CollisionBrushSide { plane: CollisionPlane; surfaceFlags: number; } export interface CollisionBrush { contents: number; sides: CollisionBrushSide[]; checkcount?: number; } export interface CollisionLeaf { contents: number; cluster: number; area: number; firstLeafBrush: number; numLeafBrushes: number; } export interface CollisionNode { plane: CollisionPlane; children: [number, number]; } export interface CollisionBmodel { mins: Vec3; maxs: Vec3; origin: Vec3; headnode: number; } export interface CollisionModel { planes: CollisionPlane[]; nodes: CollisionNode[]; leaves: CollisionLeaf[]; brushes: CollisionBrush[]; leafBrushes: number[]; bmodels: CollisionBmodel[]; visibility?: CollisionVisibility; } export interface CollisionVisibilityCluster { pvs: Uint8Array; phs: Uint8Array; } export interface CollisionVisibility { numClusters: number; clusters: readonly CollisionVisibilityCluster[]; } export interface CollisionLumpData { planes: Array<{ normal: Vec3; dist: number; type: number; }>; nodes: Array<{ planenum: number; children: [number, number]; }>; leaves: Array<{ contents: number; cluster: number; area: number; firstLeafBrush: number; numLeafBrushes: number; }>; brushes: Array<{ firstSide: number; numSides: number; contents: number; }>; brushSides: Array<{ planenum: number; surfaceFlags: number; }>; leafBrushes: number[]; bmodels: Array<{ mins: Vec3; maxs: Vec3; origin: Vec3; headnode: number; }>; visibility?: CollisionVisibility; } export interface TraceResult { fraction: number; plane: CollisionPlane | null; contents: number; surfaceFlags: number; startsolid: boolean; allsolid: boolean; } export interface CollisionTraceResult { fraction: number; endpos: Vec3; plane: CollisionPlane | null; planeNormal?: Vec3; contents?: number; surfaceFlags?: number; startsolid: boolean; allsolid: boolean; } export declare enum PlaneSide { FRONT = 1, BACK = 2, CROSS = 3 } export interface TraceDebugInfo { nodesTraversed: number; leafsReached: number; brushesTested: number; } export declare let traceDebugInfo: TraceDebugInfo | null; export declare function enableTraceDebug(): void; export declare function disableTraceDebug(): void; export declare const DIST_EPSILON = 0.03125; export declare function buildCollisionModel(lumps: CollisionLumpData): CollisionModel; export declare function computePlaneSignBits(normal: Vec3): number; export declare function planeDistanceToPoint(plane: CollisionPlane, point: Vec3): number; export declare function pointOnPlaneSide(plane: CollisionPlane, point: Vec3, epsilon?: number): PlaneSide.FRONT | PlaneSide.BACK | PlaneSide.CROSS; export declare function boxOnPlaneSide(mins: Vec3, maxs: Vec3, plane: CollisionPlane, epsilon?: number): PlaneSide; export declare function pointInsideBrush(point: Vec3, brush: CollisionBrush, epsilon?: number): boolean; export interface BoxBrushTestResult { startsolid: boolean; allsolid: boolean; contents: number; } export declare function testBoxInBrush(origin: Vec3, mins: Vec3, maxs: Vec3, brush: CollisionBrush): BoxBrushTestResult; export interface ClipBoxParams { start: Vec3; end: Vec3; mins: Vec3; maxs: Vec3; brush: CollisionBrush; trace: TraceResult; } /** * Clips a movement box against a brush using the Liang-Barsky algorithm. * * This function determines if and where the swept box (from start to end) intersects the brush. * It works by clipping the movement line segment against the infinite planes defined by the brush sides. * * Algorithm Overview (Liang-Barsky): * The movement is treated as a parameterized line P(t) = Start + t * (End - Start), for t in [0, 1]. * We maintain an interval [enterfrac, leavefrac] (initially [-1, 1]) representing the portion of the * line that is potentially inside the brush. * For each plane: * 1. We determine the distance of Start (d1) and End (d2) from the plane. * - For box traces, planes are expanded by the box extents, effectively treating the box as a point. * 2. If both points are in front (outside), the line is outside the brush. * 3. If the line crosses the plane: * - If entering (d1 > d2), we update `enterfrac` (max of entry times). * - If leaving (d1 < d2), we update `leavefrac` (min of exit times). * 4. If at any point enterfrac > leavefrac, the line misses the brush. * * @see CM_ClipBoxToBrush in qcommon/cm_trace.c:145-220 * * @param params ClipBoxParams containing start/end vectors, box mins/maxs, target brush, and trace result to update. */ export declare function clipBoxToBrush({ start, end, mins, maxs, brush, trace }: ClipBoxParams): void; export declare function createDefaultTrace(): TraceResult; export interface CollisionTraceParams { readonly model: CollisionModel; readonly start: Vec3; readonly end: Vec3; readonly mins?: Vec3; readonly maxs?: Vec3; readonly headnode?: number; readonly contentMask?: number; } export declare function traceBox(params: CollisionTraceParams): CollisionTraceResult; export declare function pointContents(point: Vec3, model: CollisionModel, headnode?: number): number; export declare function pointContentsMany(points: readonly Vec3[], model: CollisionModel, headnode?: number): number[]; export declare function boxContents(origin: Vec3, mins: Vec3, maxs: Vec3, model: CollisionModel, headnode?: number): number; export declare function inPVS(p1: Vec3, p2: Vec3, model: CollisionModel, headnode?: number): boolean; export declare function inPHS(p1: Vec3, p2: Vec3, model: CollisionModel, headnode?: number): boolean; export interface CollisionEntityLink { readonly id: number; readonly origin: Vec3; readonly mins: Vec3; readonly maxs: Vec3; readonly contents: number; readonly surfaceFlags?: number; } export interface CollisionEntityTraceParams extends CollisionTraceParams { readonly passId?: number; } export interface CollisionEntityTraceResult extends CollisionTraceResult { readonly entityId: number | null; } export declare class CollisionEntityIndex { private readonly entities; private readonly entityNodes; private readonly rootNode; link(entity: CollisionEntityLink): void; unlink(entityId: number): void; trace(params: CollisionEntityTraceParams): CollisionEntityTraceResult; gatherTriggerTouches(origin: Vec3, mins: Vec3, maxs: Vec3, mask?: number): number[]; } //# sourceMappingURL=collision.d.ts.map