/** * Point cloud picker — sibling pipeline to `Picker` that draws splats * into the same r32uint object-id target so points and meshes occlude * each other correctly during a pick. * * Disambiguation: points emit `0x80000000 | (expressId & 0x7FFFFFFF)`, * meshes emit `meshIndex+1` (always under 100K). The reader checks bit * 31 to know which path produced the hit. * * Click tolerance: the picker pipeline inflates each splat by an extra * ~2 px over its on-screen size. This makes picking forgiving even for * sub-pixel splats (adaptive-world mode, dense scans) without changing * the rendered look. */ import type { WebGPUDevice } from './device.js'; export interface PointPickNode { expressId: number; modelIndex?: number; chunks: ReadonlyArray<{ vertexBuffer: GPUBuffer; pointCount: number; }>; } /** bit 30 marks a GPU-instanced occurrence; the express id is in the low 30 bits. * Checked AFTER the point marker (bit 31), so a point's express-id that happens * to set bit 30 still decodes as a point. The instanced picker shader writes * `INSTANCED_PICK_MARKER | (entityId & INSTANCED_PICK_MASK)`. */ export declare const INSTANCED_PICK_MARKER = 1073741824; export declare const INSTANCED_PICK_MASK = 1073741823; /** Decode a r32uint sample from the picker target. */ export interface DecodedPickSample { /** Mesh index (1-based) when bits 30-31 clear and value > 0; 0 = no hit. */ meshIndexPlusOne: number; /** Federated expressId when bit 31 is set; 0 otherwise. */ pointExpressId: number; /** Express id when bit 30 is set (GPU-instanced occurrence); 0 otherwise. */ instanceExpressId: number; /** Convenience: which discipline produced the hit. */ kind: 'mesh' | 'point' | 'instanced' | 'none'; } export declare function decodePickSample(value: number): DecodedPickSample; export declare class PointPicker { private device; private pipeline; private bindGroupLayout; private uniformBuffer; private bindGroup; private uniformScratch; private uniformU32; private destroyed; constructor(device: WebGPUDevice); /** * Draw point pick splats into the (already-open) render pass. The * caller is responsible for clearing the color + depth attachments * and ending the pass. */ drawIntoPass(pass: GPURenderPassEncoder, nodes: ReadonlyArray, viewProj: Float32Array, viewport: { width: number; height: number; }, sizing: { sizeMode: 0 | 1 | 2; worldRadius: number; pointSizePx: number; clickTolerancePx: number; }, section?: { normal: [number, number, number]; distance: number; flipped: boolean; } | null): void; private writeUniforms; destroy(): void; } //# sourceMappingURL=point-picker.d.ts.map