From 0d8b789e3e95ff74953adf4850f04030ae1d1a1b Mon Sep 17 00:00:00 2001 From: lindsay Date: Fri, 6 Dec 2024 16:10:37 +0100 Subject: [PATCH] [FIX] Add missing types for MarqueePicker and ObjectsKdTree3 --- types/extras/MarqueePicker/MarqueePicker.d.ts | 200 ++++++++++++++++++ .../MarqueePickerMouseControl.d.ts | 48 +++++ types/extras/MarqueePicker/index.d.ts | 2 + types/extras/collision/ObjectsKdTree3.d.ts | 43 ++++ types/extras/collision/index.d.ts | 1 + types/extras/index.d.ts | 2 + 6 files changed, 296 insertions(+) create mode 100644 types/extras/MarqueePicker/MarqueePicker.d.ts create mode 100644 types/extras/MarqueePicker/MarqueePickerMouseControl.d.ts create mode 100644 types/extras/MarqueePicker/index.d.ts create mode 100644 types/extras/collision/ObjectsKdTree3.d.ts create mode 100644 types/extras/collision/index.d.ts diff --git a/types/extras/MarqueePicker/MarqueePicker.d.ts b/types/extras/MarqueePicker/MarqueePicker.d.ts new file mode 100644 index 0000000000..a1fe9b50ae --- /dev/null +++ b/types/extras/MarqueePicker/MarqueePicker.d.ts @@ -0,0 +1,200 @@ +import {Viewer, Component} from "../../viewer"; +import {ObjectsKdTree3} from "../collision"; + +/** + * Picks a {@link Viewer}'s {@link Entity}s with a canvas-space 2D marquee box. + * + * [](https://xeokit.github.io/xeokit-sdk/examples/picking/#marqueePick_select) + * + * * [[Example 1: Select Objects with Marquee](https://xeokit.github.io/xeokit-sdk/examples/picking/#marqueePick_select)] + * * [[Example 2: View-Fit Objects with Marquee](https://xeokit.github.io/xeokit-sdk/examples/picking/#marqueePick_viewFit)] + * + * # Usage + * + * In the example below, we + * + * 1. Create a {@link Viewer}, arrange the {@link Camera} + * 2. Use an {@link XKTLoaderPlugin} to load a BIM model, + * 3. Create a {@link ObjectsKdTree3} to automatically index the `Viewer's` {@link Entity}s for fast spatial lookup, + * 4. Create a `MarqueePicker` to pick {@link Entity}s in the {@link Viewer}, using the {@link ObjectsKdTree3} to accelerate picking + * 5. Create a {@link MarqueePickerMouseControl} to perform the marquee-picking with the `MarqueePicker`, using mouse input to draw the marquee box on the `Viewer's` canvas. + * + * When the {@link MarqueePickerMouseControl} is active: + * + * * Long-click, drag and release on the canvas to define a marque box that picks {@link Entity}s. + * * Drag left-to-right to pick {@link Entity}s that intersect the box. + * * Drag right-to-left to pick {@link Entity}s that are fully inside the box. + * * On release, the `MarqueePicker` will fire a "picked" event with IDs of the picked {@link Entity}s, if any. + * * Handling that event, we mark the {@link Entity}s as selected. + * * Hold down CTRL to multi-pick. + * + * ````javascript + * import { + * Viewer, + * XKTLoaderPlugin, + * ObjectsKdTree3, + * MarqueePicker, + * MarqueePickerMouseControl + * } from "xeokit-sdk.es.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: "../../assets/models/xkt/v8/ifc/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 {@link ObjectsKdTree3} can be shared with any other components that want to use it to spatially search for {@link Entity}s. + * * The {@link 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*. + */ +export class MarqueePicker extends Component { + + /** + * Pick mode that picks {@link Entity}s that intersect the marquee box. + * + * @type {number} + */ + static PICK_MODE_INTERSECTS: number; + + /** + * Pick mode that picks {@link Entity}s that are completely inside the marquee box. + * + * @type {number} + */ + static PICK_MODE_INSIDE: number; + + /** + * Creates a MarqueePicker. + * + * @param {*} cfg Configuration + * @param {Viewer} cfg.viewer The Viewer to pick Entities from. + * @param {ObjectsKdTree3} cfg.objectsKdTree3 A k-d tree that indexes the Entities in the Viewer for fast spatial lookup. + */ + constructor(cfg: { + viewer: Viewer; + objectsKdTree3: ObjectsKdTree3; + }); + + /** + * Sets the canvas-space position of the first marquee box corner. + * + * @param corner1 + */ + setMarqueeCorner1(corner1: number[]): void; + + /** + * Sets the canvas-space position of the second marquee box corner. + * + * @param corner2 + */ + setMarqueeCorner2(corner2: number[]):void; + + /** + * Sets both canvas-space corner positions of the marquee box. + * + * @param corner1 + * @param corner2 + */ + setMarquee(corner1: number[], corner2: number[]):void; + + /** + * Sets if the marquee box is visible. + * + * @param {boolean} visible True if the marquee box is to be visible, else false. + */ + setMarqueeVisible(visible:boolean):void; + + /** + * Gets if the marquee box is visible. + * + * @returns {boolean} True if the marquee box is visible, else false. + */ + getMarqueeVisible() :boolean; + + /** + * Sets the pick mode. + * + * Supported pick modes are: + * + * * MarqueePicker.PICK_MODE_INSIDE - picks {@link Entity}s that are completely inside the marquee box. + * * MarqueePicker.PICK_MODE_INTERSECTS - picks {@link Entity}s that intersect the marquee box. + * + * @param {number} pickMode The pick mode. + */ + setPickMode(pickMode: number) :void; + + /** + * Gets the pick mode. + * + * Supported pick modes are: + * + * * MarqueePicker.PICK_MODE_INSIDE - picks {@link Entity}s that are completely inside the marquee box. + * * MarqueePicker.PICK_MODE_INTERSECTS - picks {@link Entity}s that intersect the marquee box. + * + * @returns {number} The pick mode. + */ + getPickMode() :number; + + /** + * Fires a "clear" event on this MarqueePicker. + */ + clear() :void; + + /** + * Attempts to pick {@link Entity}s, using the current MarquePicker settings. + * + * Fires a "picked" event with the IDs of the {@link Entity}s that were picked, if any. + * + * @returns {string[]} IDs of the {@link Entity}s that were picked, if any + */ + pick():string[]; + + + /** + * Destroys this MarqueePicker. + * + * Does not destroy the {@link Viewer} or the {@link ObjectsKdTree3} provided to the constructor of this MarqueePicker. + */ + destroy():void; +} + + + diff --git a/types/extras/MarqueePicker/MarqueePickerMouseControl.d.ts b/types/extras/MarqueePicker/MarqueePickerMouseControl.d.ts new file mode 100644 index 0000000000..968ba558f2 --- /dev/null +++ b/types/extras/MarqueePicker/MarqueePickerMouseControl.d.ts @@ -0,0 +1,48 @@ +import {Component} from "../../viewer"; +import {MarqueePicker} from "./MarqueePicker"; + +/** + * Controls a {@link MarqueePicker} with mouse input. + * + * See {@link MarqueePicker} for usage example. + * + * When the MarqueePickerMouseControl is active: + * + * * Long-click, drag and release on the canvas to define a marque box that picks {@link Entity}s. + * * 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 picked Entities , if any. + */ + + +export class MarqueePickerMouseControl extends Component { + + /** + * Creates a new MarqueePickerMouseControl. + * + * @param {*} cfg Configuration + * @param {MarqueePicker} cfg.marqueePicker The MarqueePicker to control. + */ + constructor(cfg: { + marqueePicker: MarqueePicker; + }); + + /** + * Activates or deactivates this MarqueePickerMouseControl. + * + * @param {boolean} active Whether or not to activate. + */ + setActive(active: boolean): void; + + /** + * Gets if this MarqueePickerMouseControl is active. + * + * @returns {boolean} + */ + getActive(): boolean; + + /** + * + */ + destroy(): void; +} diff --git a/types/extras/MarqueePicker/index.d.ts b/types/extras/MarqueePicker/index.d.ts new file mode 100644 index 0000000000..3d2ad608a8 --- /dev/null +++ b/types/extras/MarqueePicker/index.d.ts @@ -0,0 +1,2 @@ +export * from "./MarqueePicker"; +export * from "./MarqueePickerMouseControl"; \ No newline at end of file diff --git a/types/extras/collision/ObjectsKdTree3.d.ts b/types/extras/collision/ObjectsKdTree3.d.ts new file mode 100644 index 0000000000..128bd249d7 --- /dev/null +++ b/types/extras/collision/ObjectsKdTree3.d.ts @@ -0,0 +1,43 @@ +import {Viewer} from "../../viewer"; + +/** + * Automatically indexes a {@link Viewer}'s {@link Entity}s in a 3D k-d tree + * to support fast collision detection with 3D World-space axis-aligned boundaries (AABBs) and frustums. + * + * See {@link MarqueePicker} for usage example. + * + * An ObjectsKdTree3 is configured with a Viewer, and will then automatically + * keep itself populated with k-d nodes that contain the Viewer's Entitys. + * + * We can then traverse the k-d nodes, starting at {@link ObjectsKdTree3#root}, to find + * the contained Entities. + */ +export class ObjectsKdTree3 { + + /** + * Creates an ObjectsKdTree3. + * + * @param {*} cfg Configuration + * @param {Viewer} cfg.viewer The Viewer that provides the {@link Entity}s in this ObjectsKdTree3. + * @param {number} [cfg.maxTreeDepth=15] Optional maximum depth for the k-d tree. + */ + constructor(cfg: { + viewer: Viewer; + maxTreeDepth?: number; + }); + + /** + * Gets the root ObjectsKdTree3 node. + * + * Each time this accessor is accessed, it will lazy-rebuild the ObjectsKdTree3 + * if {@link Entity}s have been created or removed in the {@link Viewer} since the last time it was accessed. + */ + get root(): any; + + /** + * Destroys this ObjectsKdTree3. + * + * Does not destroy the {@link Viewer} given to the constructor of the ObjectsKdTree3. + */ + destroy(): void +} diff --git a/types/extras/collision/index.d.ts b/types/extras/collision/index.d.ts new file mode 100644 index 0000000000..9d21faa567 --- /dev/null +++ b/types/extras/collision/index.d.ts @@ -0,0 +1 @@ +export * from "./ObjectsKdTree3"; \ No newline at end of file diff --git a/types/extras/index.d.ts b/types/extras/index.d.ts index 67ff4aa96e..3c9a0affa0 100644 --- a/types/extras/index.d.ts +++ b/types/extras/index.d.ts @@ -1,2 +1,4 @@ export * from "./ContextMenu"; export * from "./PointerLens"; +export * from "./MarqueePicker"; +export * from "./collision"