Inputs for PickStrategy.pick.

Exactly one of canvasPos, ray, or matrix must be supplied — they all describe the same thing (a world-space ray) at three different levels of pre-processing.

Snap fields (snapToVertex, snapToEdge, snapRadius) are GPU-only enrichments. When requested but unavailable (no renderer attached, WebGL context lost, or snap finds no vertex/edge in radius), the picker silently falls back to a non-snap result — the snap field on PickResult simply stays null and strategyUsed tells you what actually ran.

Snap is fundamentally a screen-space query: it can land on a vertex or edge that is not under the cursor's surface ray. So a snap-only hit (cursor in empty space, vertex 3 px away ⇒ snapped) is a valid result even when no surface ray hit anything.

interface PickParams {
    canvasPos?: Vec2;
    filter?: (objectId: string) => boolean;
    matrix?: Mat4;
    pickInvisible?: boolean;
    pickSurfaceNormal?: boolean;
    ray?: { dir: Vec3; origin: Vec3 };
    snapRadius?: number;
    snapToEdge?: boolean;
    snapToVertex?: boolean;
    tMax?: number;
    tMin?: number;
    view: View;
}

Properties

canvasPos?: Vec2

Canvas-pixel cursor position relative to view.htmlElement. Mutually exclusive with ray and matrix.

filter?: (objectId: string) => boolean

Optional pre-filter on candidate object IDs. BVH-only — the GPU path uses the renderer's own visibility / pickability gates and cannot apply an arbitrary callback per pick.

If supplied alongside a snap request, the picker runs BVH (which honours the filter) and the snap fields stay empty. Set this only when filtering matters more than snap to you.

matrix?: Mat4

World-from-pick affine transform — see "../collision".SceneRaycastParams.matrix for the full convention. Mutually exclusive with canvasPos and ray. Same GPU-snap caveat as ray.

pickInvisible?: boolean

If true, include invisible objects in the candidate set. Default false — most callers want what the user can actually see.

pickSurfaceNormal?: boolean

If true and the underlying backend supports it, populate PickResult.worldNormal. GPU-only.

ray?: { dir: Vec3; origin: Vec3 }

Pre-built world-space ray. dir need not be normalised. Mutually exclusive with canvasPos and matrix.

GPU snap is canvas-only — supplying a ray pick auto-disables the snap branch and forces the BVH backend.

snapRadius?: number

Radius in canvas pixels for snap searches. Default 30. Ignored when neither snapToVertex nor snapToEdge is set.

snapToEdge?: boolean

If true, attempt to snap to the nearest edge within snapRadius pixels of canvasPos. GPU-only.

snapToVertex and snapToEdge may be combined — the picker reports whichever the renderer landed on, preferring vertex on ties.

snapToVertex?: boolean

If true, attempt to snap to the nearest vertex within snapRadius pixels of canvasPos. GPU-only.

tMax?: number

Maximum parametric distance along the ray. BVH-only. Default Infinity.

tMin?: number

Minimum parametric distance along the ray. BVH-only. Default 0.

view: View

Active view. Always required: the picker uses it to resolve canvas coordinates, scope visibility / pickability filters, and route GPU snap requests to the right rendered framebuffer.