Skip to content

Commit

Permalink
Merge pull request #1758 from xeokit/XCD-216
Browse files Browse the repository at this point in the history
[FIX] Add missing types for MarqueePicker and ObjectsKdTree3
  • Loading branch information
xeolabs authored Dec 6, 2024
2 parents 0783b9b + 0d8b789 commit 63061bb
Show file tree
Hide file tree
Showing 6 changed files with 296 additions and 0 deletions.
200 changes: 200 additions & 0 deletions types/extras/MarqueePicker/MarqueePicker.d.ts
Original file line number Diff line number Diff line change
@@ -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.
*
* [<img src="https://xeokit.github.io/xeokit-sdk/assets/images/MarqueeSelect.gif">](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;
}



48 changes: 48 additions & 0 deletions types/extras/MarqueePicker/MarqueePickerMouseControl.d.ts
Original file line number Diff line number Diff line change
@@ -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;
}
2 changes: 2 additions & 0 deletions types/extras/MarqueePicker/index.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export * from "./MarqueePicker";
export * from "./MarqueePickerMouseControl";
43 changes: 43 additions & 0 deletions types/extras/collision/ObjectsKdTree3.d.ts
Original file line number Diff line number Diff line change
@@ -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
}
1 change: 1 addition & 0 deletions types/extras/collision/index.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from "./ObjectsKdTree3";
2 changes: 2 additions & 0 deletions types/extras/index.d.ts
Original file line number Diff line number Diff line change
@@ -1,2 +1,4 @@
export * from "./ContextMenu";
export * from "./PointerLens";
export * from "./MarqueePicker";
export * from "./collision"

0 comments on commit 63061bb

Please sign in to comment.