UNPKG

@itwin/core-frontend

Version:
289 lines • 14.4 kB
/*--------------------------------------------------------------------------------------------- * 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 { assert, BeTimePoint } from "@itwin/core-bentley"; import { Range3d } from "@itwin/core-geometry"; import { PlanarClipMaskPriority } from "@itwin/core-common"; import { TileDrawArgs, TileTreeLoadStatus, tileTreeReferenceFromRenderGraphic, } from "./internal"; /** Describes the type of graphics produced by a [[TileTreeReference]]. * @public * @extensions */ export var TileGraphicType; (function (TileGraphicType) { /** Rendered behind all other geometry without depth. */ TileGraphicType[TileGraphicType["BackgroundMap"] = 0] = "BackgroundMap"; /** Rendered with normal scene graphics. */ TileGraphicType[TileGraphicType["Scene"] = 1] = "Scene"; /** Rendered in front of all other geometry. */ TileGraphicType[TileGraphicType["Overlay"] = 2] = "Overlay"; })(TileGraphicType || (TileGraphicType = {})); /** A reference to a [[TileTree]] suitable for drawing within a [[Viewport]]. The reference does not *own* its tile tree - it merely refers to it by * way of the tree's [[TileTreeOwner]]. * The specific [[TileTree]] referenced by this object may change based on the current state of the Viewport in which it is drawn - for example, * as a result of changing the RenderMode, or animation settings, or classification settings, etc. * A reference to a TileTree is typically associated with a [[ViewState]], a [[DisplayStyleState]], or a [[Viewport]]. * Multiple TileTreeReferences can refer to the same TileTree with different parameters and logic - for example, the same background map tiles can be displayed in two viewports with * differing levels of transparency. * @see [[TiledGraphicsProvider]] to supply custom [[TileTreeReference]]s to be drawn within a [[Viewport]]. * @public * @extensions */ export class TileTreeReference /* implements RenderMemory.Consumer */ { /** If set to true, tile geometry will be reprojected using the tile's reprojection transform when geometry is collected from the referenced TileTree. * @internal */ reprojectGeometry; /** Force a new tree owner / tile tree to be created for the current tile tree reference * @internal */ resetTreeOwner() { } /** Disclose *all* TileTrees use by this reference. This may include things like map tiles used for draping on terrain. * Override this and call super if you have such auxiliary trees. * @note Any tree *NOT* disclosed becomes a candidate for *purging* (being unloaded from memory along with all of its tiles and graphics). */ discloseTileTrees(trees) { const tree = this.treeOwner.tileTree; if (undefined !== tree) trees.add(tree); } /** Adds this reference's graphics to the scene. By default this invokes [[draw]]. */ addToScene(context) { const args = this.createDrawArgs(context); if (undefined !== args) this.draw(args); } /** Adds this reference's graphics to the scene. By default this invokes [[TileTree.draw]] on the referenced TileTree, if it is loaded. */ draw(args) { args.tree.draw(args); } /** Return a tooltip describing the hit, or `undefined` if no tooltip can be supplied. * If you override this method, make sure to check that `hit` represents an entity belonging to your tile tree, e.g., by checking `hit.modelId` and `hit.sourceId`. * If you *don't* override this method, override [[canSupplyToolTip]] to return false. * Callers who want to obtain a tooltip should prefer [[getToolTipPromise]]. */ async getToolTip(_hit) { return undefined; } /** Return whether this TileTreeReference can supply a tooltip describing the entity represented by the specified hit. * [[getToolTipPromise]] calls [[getToolTip]] if and only if `canSupplyToolTip` returns `true`. * If your tile tree never supplies tooltips, override this to return `false`. */ canSupplyToolTip(_hit) { return true; } /** Obtain a tooltip describing the specified `hit`, or `undefined` if this tile tree reference cannot supply a tooltip for the hit. */ getToolTipPromise(hit) { return this.canSupplyToolTip(hit) ? this.getToolTip(hit).catch(() => undefined) : undefined; } /** Optionally return a MapLayerFeatureInfo object describing the hit.]. * @alpha */ async getMapFeatureInfo(_hit, _options) { return undefined; } /** Optionally add any decorations specific to this reference. For example, map tile trees may add a logo image and/or copyright attributions. * @note This is currently only invoked for background maps and TiledGraphicsProviders - others have no decorations, but if they did implement this it would not be called. */ decorate(_context) { } /** Unions this reference's range with the supplied range to help compute a volume in world space for fitting a viewport to its contents. * Override this function if a reference's range should not be included in the fit range, or a range different from its tile tree's range should be used. */ unionFitRange(union) { const contentRange = this.computeWorldContentRange(); if (!contentRange.isNull) union.extendRange(contentRange); } /** Record graphics memory consumed by this tile tree reference. */ collectStatistics(stats) { const tree = this.treeOwner.tileTree; if (undefined !== tree) tree.collectStatistics(stats); } /** Return true if the tile tree is fully loaded and ready to draw. * The default implementation returns true if the tile tree loading process completed (whether it resulted in success or failure). * @note Do *not* override this property - override [[_isLoadingComplete]] instead.. * @public */ get isLoadingComplete() { switch (this.treeOwner.loadStatus) { case TileTreeLoadStatus.NotLoaded: case TileTreeLoadStatus.Loading: return false; case TileTreeLoadStatus.NotFound: return true; // we tried, and failed, to load. case TileTreeLoadStatus.Loaded: return this._isLoadingComplete; } } /** Override if additional asynchronous loading is required after the tile tree is successfully loaded, to indicate when that loading has completed. * @public */ get _isLoadingComplete() { return true; } /** Create context for drawing the tile tree, if it is ready for drawing. * TileTreeReferences can override individual portions of the context, e.g. apply their own transform. * Returns undefined if, e.g., the tile tree is not yet loaded. */ createDrawArgs(context) { const tree = this.treeOwner.load(); if (undefined === tree) return undefined; return new TileDrawArgs({ context, tree, now: BeTimePoint.now(), location: this.computeTransform(tree), viewFlagOverrides: this.getViewFlagOverrides(tree), clipVolume: this.getClipVolume(tree), parentsAndChildrenExclusive: tree.parentsAndChildrenExclusive, symbologyOverrides: this.getSymbologyOverrides(tree), appearanceProvider: this.getAppearanceProvider(tree), hiddenLineSettings: this.getHiddenLineSettings(tree), animationTransformNodeId: this.getAnimationTransformNodeId(tree), groupNodeId: this.getGroupNodeId(tree), transformFromIModel: this.getTransformFromIModel(), }); } /** @beta */ getTransformFromIModel() { return undefined; } /** @internal */ getAnimationTransformNodeId(_tree) { return undefined; } /** @internal */ getGroupNodeId(_tree) { return undefined; } /** Supply transform from this tile tree reference's location to iModel coordinate space. * @returns undefined if the TileTree is not yet loaded. */ getLocation() { const tree = this.treeOwner.load(); return undefined !== tree ? this.computeTransform(tree) : undefined; } /** Compute a transform from this tile tree reference's coordinate space to the [[IModelConnection]]'s coordinate space. */ computeTransform(tree) { return tree.iModelTransform.clone(); } /** Compute the range of this tile tree's contents in world coordinates. * @returns The content range in world coodinates, or a null range if the tile tree is not loaded or has a null content range. */ computeWorldContentRange() { const range = new Range3d(); const tree = this.treeOwner.tileTree; if (undefined !== tree && !tree.rootTile.contentRange.isNull) this.computeTransform(tree).multiplyRange(tree.rootTile.contentRange, range); return range; } /** Return the clip volume applied to this reference's tile tree, if any. */ getClipVolume(tree) { return tree.clipVolume; } /** Supply overrides that should be applied to the [[ViewState]]'s [ViewFlags]($common) when drawing this tile tree reference. */ getViewFlagOverrides(tree) { return tree.viewFlagOverrides; } /** Return overrides that *replace* any defined for the view. */ getSymbologyOverrides(_tree) { return undefined; } /** Return a provider that can supplement the view's symbology overrides. */ getAppearanceProvider(_tree) { return undefined; } /** Return hidden line settings to replace those defined for the view. */ getHiddenLineSettings(_tree) { return undefined; } /* Extend range to include transformed range of this tile tree. * @internal */ accumulateTransformedRange(range, matrix, frustumPlanes) { const tree = this.treeOwner.tileTree; if (undefined === tree) return; const location = this.computeTransform(tree); tree.accumulateTransformedRange(range, matrix, location, frustumPlanes); } /** @internal */ getTerrainHeight(_terrainHeights) { } /** Return whether the geometry exposed by this tile tree reference should cast shadows on other geometry. */ get castsShadows() { return true; } /** Return whether this reference has global coverage. Mapping data is global and some non-primary models such as the OSM building layer have global coverage */ get isGlobal() { return false; } /** The [PlanarClipMaskPriority]($common) of this tile tree used to determine which tile trees contribute to a clip mask when * using [PlanarClipMaskMode.Priority]($common). * @beta */ get planarClipMaskPriority() { return PlanarClipMaskPriority.DesignModel; } /** @deprecated in 5.0 - will not be removed until after 2026-06-13. Use [addAttributions] instead. */ addLogoCards(_cards, _vp) { } /** Add attribution logo cards for the tile tree source logo cards to the viewport's logo div. * @beta */ async addAttributions(cards, vp) { // eslint-disable-next-line @typescript-eslint/no-deprecated return Promise.resolve(this.addLogoCards(cards, vp)); } /** Create a tile tree reference equivalent to this one that also supplies an implementation of [[GeometryTileTreeReference.collectTileGeometry]]. * Return `undefined` if geometry collection is not supported. * @see [[createGeometryTreeReference]]. */ _createGeometryTreeReference(_options) { return undefined; } /** If defined, supplies the implementation of [[GeometryTileTreeReference.collectTileGeometry]]. */ collectTileGeometry; /** A function that can be assigned to [[collectTileGeometry]] to enable geometry collection for references to tile trees that support geometry collection. */ _collectTileGeometry(collector) { const tree = this.treeOwner.load(); switch (this.treeOwner.loadStatus) { case TileTreeLoadStatus.Loaded: assert(undefined !== tree); tree.collectTileGeometry(collector); break; case TileTreeLoadStatus.Loading: collector.markLoading(); break; } } /** Obtain a tile tree reference equivalent to this one that also supplies an implementation of [[GeometryTileTreeReference.collectTileGeometry]], or * undefined if geometry collection is not supported. * Currently, only terrain and reality model tiles support geometry collection. * @note Do not override this method - override [[_createGeometryTreeReference]] instead. */ createGeometryTreeReference(options) { if (this.collectTileGeometry) { // Unclear why compiler doesn't detect that `this` satisfies the GeometryTileTreeReference interface...it must be looking only at the types, not this particular instance. const ref = this; ref.reprojectGeometry = options?.reprojectGeometry; return ref; } return this._createGeometryTreeReference(options); } /** Create a [[TileTreeReference]] that displays a pre-defined [[RenderGraphic]]. * The reference can be used to add dynamic content to a [[Viewport]]'s scene as a [[TiledGraphicsProvider]], as in the following example: * ```ts * [[include:TileTreeReference_createFromRenderGraphic]] *``` * Or, it can be used as a [[DynamicSpatialClassifier]] to contextualize a reality model, like so: * ```ts * [[include:TileTreeReference_DynamicClassifier]] * ``` * It can also be used to mask out portions of the background map or terrain via [PlanarClipMaskSettings]($common), as shown below: * ```ts * [[include:TileTreeReference_DynamicClipMask]] * ``` * @beta */ static createFromRenderGraphic(args) { return tileTreeReferenceFromRenderGraphic(args); } } //# sourceMappingURL=TileTreeReference.js.map