Skip to content

Tooltips and selection

Pointer reporting in 3D ​

scenes/pointer-reporting-in-3d
plot.showMesh(plot.uploadMesh(extractIsosurface(field(48, 10, radial), 9)), [0.3, 0.6, 0.85]);
plot.frameScene();
// Off unless asked for: answering needs a copy of the frame's pickable
// geometry kept every frame.
plot.setScenePicking(true);
return {
  pointer(x, y) {
    const hit = plot.pickSceneNow(x, y);
    return hit ? `surface at (${hit.position.map(fixed).join(", ")})` : "nothing under the pointer";
  },
};

Calls

6 in the code above, in the order it makes them

plot.showMesh(handle: MeshHandle, colour: Colour | Hex): void

Draw the surface handle names.

plot.uploadMesh(mesh: Mesh): MeshHandle

Upload a surface and return a handle naming it.

extractIsosurface(field: Field, isovalue: number): Surface

The surface through isovalue in a scalar field, as triangles.

Nothing is uploaded and nothing is drawn. The drawn path -- Plot.uploadField and Plot.showIsosurface -- triangulates in a compute shader every frame and keeps nothing, which is what makes a dragged isovalue cost a frame rather than an upload, and also why it cannot answer a question about the surface itself. This is the path for those: an area, an intersection, a file to export.

An isovalue the field never reaches gives a surface of no triangles rather than an error, so a slider swept past the end of the range makes the surface disappear rather than fail.

plot.frameScene(): void

Point the camera at the middle of everything uploaded, far enough back to see it.

Call after uploading. A scene measured in grid cells or in millimetres is nowhere near where a camera starts, and without this the first thing a caller sees is an empty canvas.

plot.setScenePicking(on: boolean): void

Keep what a scene pick needs, from the next frame on.

Off by default: answering a pick later means keeping a copy of the frame's pickable geometry every frame, which is a cost every page would pay for something most do not use. Call it once at setup.

plot.pickSceneNow(x: number, y: number, detail?: boolean): ScenePick | null

What scene item is under a pixel, answered now.

The immediate answer and the narrow one: a CPU ray-cast, so it needs setScenePicking on and a frame drawn since, and it reaches uploaded surfaces rather than every kind of scene item. pickScene is the general one and the one to reach for; this is for the case where the answer is needed inside the same call and the scene is surfaces.