Result of one PickStrategy.pick call. Plain immutable struct — unlike the renderer's transient PickResult, the picker returns a fresh object per call that callers can keep, serialise, etc.

Field semantics:

  • hit is true when either a surface ray hit or a snap landed (or both). It is the single source of truth for "did anything come back".
  • worldPos, objectId, meshId prefer the snap-landed site when snap is set, otherwise come from the surface ray. Callers reading result.worldPos get the most accurate point available without having to branch on snap.
  • snap is the raw snap info, kept separate so callers who need to distinguish "snapped to a vertex" from "hit a surface" (e.g. for UX feedback) can do so.

Fields that don't apply to the chosen backend are null (BVH picks set worldNormal: null for example — the BVH primitive doesn't compute normals). The strategyUsed field tells you which backend ran, so this isn't ambiguous.

interface PickResult {
    _stateEpoch: number;
    canvasPos: Vec2;
    hit: boolean;
    localPos: Vec3;
    meshId: string;
    objectId: string;
    rayDir: Vec3;
    rayOrigin: Vec3;
    snap: PickSnap;
    strategyUsed: PickStrategyId;
    triangleIndex: number;
    uv: Vec2;
    view: View;
    worldNormal: Vec3;
    worldPos: Vec3;
}

Properties

_stateEpoch: number

Internal state epoch from the strategy that produced this result. Used by future memoising decorators to invalidate cached results on strategy state changes (renderer attach, context loss, etc.). Callers SHOULD NOT rely on this for application logic.

canvasPos: Vec2

Echo of PickParams.canvasPos when a canvas pick was used.

hit: boolean

True iff the surface ray hit or a snap landed.

localPos: Vec3

GPU-only. Local-space hit point on the picked mesh. null from BVH.

meshId: string

ID of the picked mesh, when the backend exposes one.

objectId: string

ID of the picked SceneObject. From snap when snap is set and the renderer resolved an object id for it; otherwise from the surface ray.

rayDir: Vec3

World-space ray direction used for the test. Always populated.

rayOrigin: Vec3

World-space ray origin used for the test. Always populated.

snap: PickSnap

Snap landing. null when snap wasn't requested, GPU was unavailable, or the snap radius found nothing.

strategyUsed: PickStrategyId

Which backend produced this result.

triangleIndex: number

BVH-only. Index of the hit triangle (offset into geometry indices ÷ 3). -1 when n/a (GPU branch, or ray miss).

uv: Vec2

GPU-only. UV at the surface hit. null when not requested or not available.

view: View

The view this pick was scoped to.

worldNormal: Vec3

GPU-only. World-space normal at the surface hit. null from BVH.

worldPos: Vec3

Best-available world-space hit point. Snap-landed point when snap is set, otherwise the surface-ray hit. null when neither was found.