/** * GPU-based object picking */ import { WebGPUDevice } from './device.js'; import type { Mesh, PickResult, PickClipState } from './types.js'; import type { InstancedTemplateGPU } from './scene.js'; import { type PointPickNode } from './point-picker.js'; /** Point-pick sizing parameters forwarded to the GPU pipeline. */ export interface PointPickSizing { sizeMode: 0 | 1 | 2; worldRadius: number; pointSizePx: number; /** Extra pixels added to the splat radius for click tolerance. Default 2. */ clickTolerancePx?: number; } export declare class Picker { private device; private webgpuDevice; private pipeline; private instancedPickPipeline; private instancedPickBindGroup; private depthTexture; private colorTexture; private uniformBuffer; private expressIdBuffer; private bindGroup; private maxMeshes; private destroyed; private pointPicker; private readonly uniformScratch; private readonly clipFlags; constructor(device: WebGPUDevice, width?: number, height?: number); /** * Pick object at screen coordinates. * * When `pointNodes` is non-empty the picker draws point splats into * the same r32uint target as the meshes (sharing the depth buffer so * occlusion is correct). Point hits set bit 31 of the readback value; * the decoder distinguishes mesh vs point from that flag. * * Returns `PickResult` with `{expressId, modelIndex}` for both kinds. * For point hits, expressId is the federated globalId of the asset * (already correct for hover/selection plumbing — no remapping needed). */ pick(x: number, y: number, width: number, height: number, meshes: Mesh[], viewProj: Float32Array, pointNodes?: ReadonlyArray, pointSizing?: PointPickSizing, instancedTemplates?: readonly InstancedTemplateGPU[], clip?: PickClipState | null): Promise; updateUniforms(viewProj: Float32Array, clip?: PickClipState | null): void; /** * Pack viewProj + the last render's section plane / crop box into the shared * pick uniform and upload it. Layout + flag bits live in {@link packPickUniforms}. */ private writePickUniforms; /** * Rectangle pick: render the pick pass once, then read back every * texel inside `[x0, y0]..[x1, y1]` and dedupe the hit set. Returns * a `Set` for both meshes and point clouds. * * Used by the Shift+drag rectangle-selection UI; not meant for * sustained use because the readback grows with rect area. A 800×600 * rect = 480k pixels = ~2 MB transfer, fine for one-shot but we'd * want a GPU-side dedupe for sustained marquee selection. */ pickRect(x0: number, y0: number, x1: number, y1: number, width: number, height: number, meshes: Mesh[], viewProj: Float32Array, pointNodes?: ReadonlyArray, pointSizing?: PointPickSizing, instancedTemplates?: readonly InstancedTemplateGPU[], clip?: PickClipState | null): Promise>; /** * Render the picker pass into `colorTexture` + `depthTexture` and * return the still-open command encoder so the caller can append a * `copyTextureToBuffer` for either a single texel (`pick`) or a * whole rect (`pickRect`) before submitting. */ private renderPickPass; /** * Resize expressId buffer to accommodate more meshes */ private resizeExpressIdBuffer; /** * Destroy all GPU resources held by this picker. * After calling this method the picker is no longer usable. * Safe to call multiple times. */ destroy(): void; } //# sourceMappingURL=picker.d.ts.map