SDK Components for Picking Objects with a Marquee Box
· 2 min read
Introduction
In xeokit-sdk v2.4.2, we have added components that enable interactive picking of a Viewer's
Entities
using a 2D box drawn on the canvas with mouse input.
New Components
ObjectsKdTree3
- Automatically indexes aViewer
'sEntities
in a 3D k-d tree to support fast collision detection with 3D World-space axis-aligned boundaries (AABBs) and frustums.MarqueePicker
- Picks aViewer
'sEntities
with a canvas-space 2D marquee box.MarqueePickerMouseControl
- Controls aMarqueePicker
with mouse input.
Usage
In the example below, we:
- Create a
Viewer
, arrange theCamera
- Use an
XKTLoaderPlugin
to load BIM model, - Create a
ObjectsKdTree3
to automatically index theViewer's
Entities
for fast spatial lookup, - Create a
MarqueePicker
to pickEntities
in theViewer
, using theObjectsKdTree3
to accelerate picking - Create a
MarqueePickerMouseControl
to perform the marquee-picking with theMarqueePicker
, using mouse input to draw the marquee box on theViewer's
canvas.
When the MarqueePickerMouseControl
is active:
- Long-click, drag and release on the canvas to define a marque box that picks
Entities
. - Drag left-to-right to pick
Entities
that intersect the box. - Drag right-to-left to pick
Entities
that are fully inside the box. - On release, the
MarqueePicker
will fire a "picked" event with IDs of the pickedEntities
, if any. - Handling that event, we mark the
Entities
as selected.
import { Viewer, XKTLoaderPlugin, ObjectsKdTree3, MarqueePicker, MarqueePickerMouseControl } from "https://cdn.jsdelivr.net/npm/@xeokit/xeokit-sdk/dist/xeokit-sdk.es.min.js";
// 1
const viewer = new Viewer({
canvasId: "myCanvas",
});
viewer.scene.camera.eye = [14.9, 14.3, 5.4];
viewer.scene.camera.look = [6.5, 8.3, -4.1];
viewer.scene.camera.up = [-0.28, 0.9, -0.3];
// 2
const xktLoader = new XKTLoaderPlugin(viewer);
const sceneModel = xktLoader.load({
id: "myModel",
src: "HolterTower.ifc.xkt",
});
// 3
const objectsKdTree3 = new ObjectsKdTree3({ viewer });
// 4
const marqueePicker = new MarqueePicker({ viewer, objectsKdTree3 });
// 5
const marqueePickerMouseControl = new MarqueePickerMouseControl({
marqueePicker,
});
marqueePicker.on("clear", () => {
viewer.scene.setObjectsSelected(viewer.scene.selectedObjectIds, false);
});
marqueePicker.on("picked", (objectIds) => {
viewer.scene.setObjectsSelected(objectIds, true);
});
marqueePickerMouseControl.setActive(true);
Design Notes
- The
ObjectsKdTree3
can be shared with any other components that want to use it to spatially search forEntities
. - The
MarqueePickerMouseControl
can be replaced with other types of controllers (i.e. touch), or used alongside them. - The
MarqueePicker
has no input handlers of its own, and provides an API through which to programmatically control marquee picking. By firing the "picked" events,MarqueePicker
implements the Blackboard Pattern.