@itwin/core-frontend
Version:
iTwin.js frontend components
175 lines • 8.09 kB
JavaScript
/*---------------------------------------------------------------------------------------------
* Copyright (c) Bentley Systems, Incorporated. All rights reserved.
* See LICENSE.md in the project root for license terms and full copyright notice.
*--------------------------------------------------------------------------------------------*/
/** @packageDocumentation
* @module Tiles
*/
import { BeTimePoint, dispose } from "@itwin/core-bentley";
import { calculateEcefToDbTransformAtLocation } from "../BackgroundMapGeometry";
import { IModelApp } from "../IModelApp";
/** Describes the current state of a [[TileTree]]. TileTrees are loaded asynchronously and may be unloaded after a period of disuse.
* @see [[TileTreeOwner]].
* @public
* @extensions
*/
export var TileTreeLoadStatus;
(function (TileTreeLoadStatus) {
/** No attempt to load the tile tree has yet been made. */
TileTreeLoadStatus[TileTreeLoadStatus["NotLoaded"] = 0] = "NotLoaded";
/** The tile tree is in the process of being loaded. */
TileTreeLoadStatus[TileTreeLoadStatus["Loading"] = 1] = "Loading";
/** The tile tree has been successfully loaded. */
TileTreeLoadStatus[TileTreeLoadStatus["Loaded"] = 2] = "Loaded";
/** An attempt to load the tile tree failed. */
TileTreeLoadStatus[TileTreeLoadStatus["NotFound"] = 3] = "NotFound";
})(TileTreeLoadStatus || (TileTreeLoadStatus = {}));
/** A hierarchical level-of-detail tree of [3d Tiles](https://github.com/CesiumGS/3d-tiles) to be rendered in a [[Viewport]].
* Tile trees originate from a variety of sources:
* - Each [[GeometricModelState]] can supply its graphics as a tile tree;
* - A [[DisplayStyleState]]'s map settings or reality models;
* - [ViewAttachment]($backend)s in a [[SheetModelState]];
* - [[TiledGraphicsProvider]]s associated with a viewport.
*
* The same TileTree can be displayed in any number of viewports using multiple [[TileTreeReference]]s.
* A TileTree's lifetime is managed by a [[TileTreeOwner]].
*
* @note Some methods carry a warning that they should **not** be overridden by subclasses; typically a protected method exists that can be
* overridden instead to customize the behavior. For example, [[selectTiles]] should not be overridden; instead, override the[[_selectTiles]] method
* that it calls.
* @public
* @extensions
*/
export class TileTree {
_isDisposed = false;
/** @internal */
_lastSelected = BeTimePoint.now();
/** @internal */
_clipVolume;
iModel;
/** Transform from this tile tree's coordinate space to the iModel's coordinate space. */
iModelTransform;
/** Uniquely identifies this tree among all other tile trees associated with the iModel. */
id;
/** A 64-bit identifier for this tile tree, unique within the context of its [[IModelConnection]].
* For a tile tree associated with a [[GeometricModelState]], this is the Id of the model. Other types of tile trees
* typically use a transient Id obtained from [[IModelConnection.transientIds]].
*/
modelId;
/** The length of time after which tiles belonging to this tree are considered elegible for disposal if they are no longer in use. */
expirationTime;
/** @internal */
get loadPriority() { return this._loadPriority; }
_loadPriority;
/** Optional tight bounding box around the entire contents of all of this tree's tiles. */
contentRange;
/** True if this tile tree has no bounds - e.g., a tile tree representing a globe is unbounded. */
get isContentUnbounded() {
return false;
}
/** True if this tile tree contains 2d graphics. */
get is2d() { return !this.is3d; }
/** @internal */
get isPointCloud() { return false; }
/** @internal */
get clipVolume() { return this._clipVolume; }
/** The volume of space occupied by this tile tree. */
get range() { return this.rootTile.range; }
/** The most recent time at which tiles [[selectTiles]] was called. */
get lastSelectedTime() { return this._lastSelected; }
/** True if a tile and its child tiles should not be drawn simultaneously.
* Default: true.
*/
get parentsAndChildrenExclusive() { return true; }
/** @internal */
get layerHandler() { return undefined; }
/** Constructor */
constructor(params) {
this._lastSelected = BeTimePoint.now();
this.iModel = params.iModel;
this.iModelTransform = params.location;
this._clipVolume = params.clipVolume;
this.modelId = params.modelId;
this.id = params.id;
this.contentRange = params.contentRange;
const admin = IModelApp.tileAdmin;
this._loadPriority = params.priority;
this.expirationTime = params.expirationTime ?? admin.tileExpirationTime;
}
/** Selects tiles of appropriate resolution for some purpose like drawing to the screen, producing a shadow map, etc.
* @note Do **not** override this method. Implement [[_selectTiles]].
*/
selectTiles(args) {
this._lastSelected = BeTimePoint.now();
const tiles = this._selectTiles(args);
IModelApp.tileAdmin.addTilesForUser(args.context.viewport, tiles, args.readyTiles, args.touchedTiles);
args.processSelectedTiles(tiles);
return tiles;
}
/** True if [[dispose]] has been called on this tile tree. */
get isDisposed() { return this._isDisposed; }
/** Dispose of this tree and any resources owned by it. This is typically invoked by a [[TileTreeOwner]]. */
[Symbol.dispose]() {
if (this.isDisposed)
return;
this._isDisposed = true;
dispose(this.rootTile);
}
/** @deprecated in 5.0 - will not be removed until after 2026-06-13. Use [Symbol.dispose] instead. */
dispose() {
this[Symbol.dispose]();
}
/** @internal */
collectStatistics(stats) {
this.rootTile.collectStatistics(stats);
}
/** Returns the number of [[Tile]]s currently in memory belonging to this tree, primarily for debugging. */
countTiles() {
return 1 + this.rootTile.countDescendants();
}
/** @internal */
accumulateTransformedRange(range, matrix, location, frustumPlanes) {
this.rootTile.extendRangeForContent(range, matrix, location, frustumPlanes);
}
/**
* Return the transform from the tile tree's coordinate space to [ECEF](https://en.wikipedia.org/wiki/ECEF) (Earth Centered Earth Fixed) coordinates.
* If a geographic coordinate system is present then this transform will be calculated at the tile tree center.
* @beta
*/
async getEcefTransform() {
if (!this.iModel.ecefLocation)
return undefined;
let dbToEcef;
const range = this.contentRange ? this.contentRange : this.range;
const center = range.localXYZToWorld(.5, .5, .5);
if (center) {
this.iModelTransform.multiplyPoint3d(center, center);
const ecefToDb = await calculateEcefToDbTransformAtLocation(center, this.iModel);
dbToEcef = ecefToDb?.inverse();
}
if (!dbToEcef)
dbToEcef = this.iModel.ecefLocation.getTransform();
return dbToEcef.multiplyTransformTransform(this.iModelTransform);
}
/** Populate [[TileGeometryCollector.polyfaces]] with geometry obtained from this tile tree's tiles satisfying the collector's criteria.
* The base implementation does nothing.
* @see [[TileTreeReference.createGeometryTreeReference]] to attempt to create a TileTree that can collect geometry.
* @beta
*/
collectTileGeometry(_collector) {
}
/**
* Invoked when a schedule script is edited.
* Override to handle updates for affected elements or timelines.
*
* @internal
*/
async onScheduleEditingChanged(_changes) { }
/**
* Invoked when a schedule script is committed during editing.
* Override in specific tile tree types to handle the change.
* @internal
*/
onScheduleEditingCommitted() { }
}
//# sourceMappingURL=TileTree.js.map