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 {
    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

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

World-space normal at the surface hit, when requested and supported.

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.