| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760 |
- import Cartesian3 from "../Core/Cartesian3.js";
- import Cesium3DTilesetMetadata from "./Cesium3DTilesetMetadata.js";
- import Check from "../Core/Check.js";
- import Frozen from "../Core/Frozen.js";
- import defined from "../Core/defined.js";
- import Ellipsoid from "../Core/Ellipsoid.js";
- import hasExtension from "./hasExtension.js";
- import ImplicitSubtree from "./ImplicitSubtree.js";
- import ImplicitSubtreeCache from "./ImplicitSubtreeCache.js";
- import ImplicitTileCoordinates from "./ImplicitTileCoordinates.js";
- import ImplicitTileset from "./ImplicitTileset.js";
- import Matrix3 from "../Core/Matrix3.js";
- import Matrix4 from "../Core/Matrix4.js";
- import MetadataSemantic from "./MetadataSemantic.js";
- import MetadataType from "./MetadataType.js";
- import OrientedBoundingBox from "../Core/OrientedBoundingBox.js";
- import preprocess3DTileContent from "./preprocess3DTileContent.js";
- import Resource from "../Core/Resource.js";
- import ResourceCache from "./ResourceCache.js";
- import RuntimeError from "../Core/RuntimeError.js";
- import VoxelContent from "./VoxelContent.js";
- import VoxelMetadataOrder from "./VoxelMetadataOrder.js";
- import VoxelShapeType from "./VoxelShapeType.js";
- import CesiumMath from "../Core/Math.js";
- import Quaternion from "../Core/Quaternion.js";
-
- /**
- * @typedef {object} Cesium3DTilesVoxelProvider.ConstructorOptions
- *
- * Initialization options for the Cesium3DTilesVoxelProvider constructor
- *
- * @property {string} className The class in the tileset schema describing voxel metadata.
- * @property {string[]} names The metadata names.
- * @property {MetadataType[]} types The metadata types.
- * @property {MetadataComponentType[]} componentTypes The metadata component types.
- * @property {VoxelShapeType} shape The {@link VoxelShapeType}.
- * @property {Cartesian3} dimensions The number of voxels per dimension of a tile. This is the same for all tiles in the dataset.
- * @property {Cartesian3} [paddingBefore=Cartesian3.ZERO] The number of padding voxels before the tile. This improves rendering quality when sampling the edge of a tile, but it increases memory usage.
- * @property {Cartesian3} [paddingAfter=Cartesian3.ZERO] The number of padding voxels after the tile. This improves rendering quality when sampling the edge of a tile, but it increases memory usage.
- * @property {Matrix4} [globalTransform=Matrix4.IDENTITY] A transform from local space to global space.
- * @property {Matrix4} [shapeTransform=Matrix4.IDENTITY] A transform from shape space to local space.
- * @property {Cartesian3} [minBounds] The minimum bounds.
- * @property {Cartesian3} [maxBounds] The maximum bounds.
- * @property {number[][]} [minimumValues] The metadata minimum values.
- * @property {number[][]} [maximumValues] The metadata maximum values.
- * @property {number} [maximumTileCount] The maximum number of tiles that exist for this provider. This value is used as a hint to the voxel renderer to allocate an appropriate amount of GPU memory. If this value is not known it can be undefined.
- */
-
- /**
- * A {@link VoxelProvider} that fetches voxel data from a 3D Tiles tileset.
- * <p>
- * Implements the {@link VoxelProvider} interface.
- * </p>
- * <div class="notice">
- * This object is normally not instantiated directly, use {@link Cesium3DTilesVoxelProvider.fromUrl}.
- * </div>
- *
- * @alias Cesium3DTilesVoxelProvider
- * @constructor
- * @augments VoxelProvider
- *
- * @param {Cesium3DTilesVoxelProvider.ConstructorOptions} options An object describing initialization options
- *
- * @see Cesium3DTilesVoxelProvider.fromUrl
- * @see VoxelProvider
- * @see VoxelPrimitive
- * @see VoxelShapeType
- *
- * @experimental This feature is not final and is subject to change without Cesium's standard deprecation policy.
- */
- function Cesium3DTilesVoxelProvider(options) {
- options = options ?? Frozen.EMPTY_OBJECT;
-
- const {
- className,
- names,
- types,
- componentTypes,
- shape,
- dimensions,
- paddingBefore = Cartesian3.ZERO.clone(),
- paddingAfter = Cartesian3.ZERO.clone(),
- globalTransform = Matrix4.IDENTITY.clone(),
- shapeTransform = Matrix4.IDENTITY.clone(),
- minBounds,
- maxBounds,
- minimumValues,
- maximumValues,
- maximumTileCount,
- } = options;
-
- //>>includeStart('debug', pragmas.debug);
- Check.typeOf.string("className", className);
- Check.typeOf.object("names", names);
- Check.typeOf.object("types", types);
- Check.typeOf.object("componentTypes", componentTypes);
- Check.typeOf.string("shape", shape);
- Check.typeOf.object("dimensions", dimensions);
- //>>includeEnd('debug');
-
- this._shapeTransform = shapeTransform;
- this._globalTransform = globalTransform;
- this._shape = shape;
- this._minBounds = minBounds;
- this._maxBounds = maxBounds;
- this._dimensions = dimensions;
- this._paddingBefore = paddingBefore;
- this._paddingAfter = paddingAfter;
- this._className = className;
- this._names = names;
- this._types = types;
- this._componentTypes = componentTypes;
- this._metadataOrder =
- shape === VoxelShapeType.ELLIPSOID
- ? VoxelMetadataOrder.Z_UP
- : VoxelMetadataOrder.Y_UP;
- this._minimumValues = minimumValues;
- this._maximumValues = maximumValues;
- this._maximumTileCount = maximumTileCount;
- this._availableLevels = undefined;
- this._implicitTileset = undefined;
- this._subtreeCache = new ImplicitSubtreeCache();
- }
-
- Object.defineProperties(Cesium3DTilesVoxelProvider.prototype, {
- /**
- * A transform from local space to global space.
- *
- * @memberof Cesium3DTilesVoxelProvider.prototype
- * @type {Matrix4}
- * @default Matrix4.IDENTITY
- * @readonly
- */
- globalTransform: {
- get: function () {
- return this._globalTransform;
- },
- },
-
- /**
- * A transform from shape space to local space.
- *
- * @memberof Cesium3DTilesVoxelProvider.prototype
- * @type {Matrix4}
- * @default Matrix4.IDENTITY
- * @readonly
- */
- shapeTransform: {
- get: function () {
- return this._shapeTransform;
- },
- },
-
- /**
- * Gets the {@link VoxelShapeType}
- *
- * @memberof Cesium3DTilesVoxelProvider.prototype
- * @type {VoxelShapeType}
- * @readonly
- */
- shape: {
- get: function () {
- return this._shape;
- },
- },
-
- /**
- * Gets the minimum bounds.
- * If undefined, the shape's default minimum bounds will be used instead.
- *
- * @memberof Cesium3DTilesVoxelProvider.prototype
- * @type {Cartesian3|undefined}
- * @readonly
- */
- minBounds: {
- get: function () {
- return this._minBounds;
- },
- },
-
- /**
- * Gets the maximum bounds.
- * If undefined, the shape's default maximum bounds will be used instead.
- *
- * @memberof Cesium3DTilesVoxelProvider.prototype
- * @type {Cartesian3|undefined}
- * @readonly
- */
- maxBounds: {
- get: function () {
- return this._maxBounds;
- },
- },
-
- /**
- * Gets the number of voxels per dimension of a tile. This is the same for all tiles in the dataset.
- *
- * @memberof Cesium3DTilesVoxelProvider.prototype
- * @type {Cartesian3}
- * @readonly
- */
- dimensions: {
- get: function () {
- return this._dimensions;
- },
- },
-
- /**
- * Gets the number of padding voxels before the tile. This improves rendering quality when sampling the edge of a tile, but it increases memory usage.
- *
- * @memberof Cesium3DTilesVoxelProvider.prototype
- * @type {Cartesian3}
- * @default Cartesian3.ZERO
- * @readonly
- */
- paddingBefore: {
- get: function () {
- return this._paddingBefore;
- },
- },
-
- /**
- * Gets the number of padding voxels after the tile. This improves rendering quality when sampling the edge of a tile, but it increases memory usage.
- *
- * @memberof Cesium3DTilesVoxelProvider.prototype
- * @type {Cartesian3}
- * @default Cartesian3.ZERO
- * @readonly
- */
- paddingAfter: {
- get: function () {
- return this._paddingAfter;
- },
- },
-
- /**
- * The metadata class for this tileset.
- *
- * @memberof Cesium3DTilesVoxelProvider.prototype
- * @type {string}
- * @readonly
- */
- className: {
- get: function () {
- return this._className;
- },
- },
-
- /**
- * Gets the metadata names.
- *
- * @memberof Cesium3DTilesVoxelProvider.prototype
- * @type {string[]}
- * @readonly
- */
- names: {
- get: function () {
- return this._names;
- },
- },
-
- /**
- * Gets the metadata types.
- *
- * @memberof Cesium3DTilesVoxelProvider.prototype
- * @type {MetadataType[]}
- * @readonly
- */
- types: {
- get: function () {
- return this._types;
- },
- },
-
- /**
- * Gets the metadata component types.
- *
- * @memberof Cesium3DTilesVoxelProvider.prototype
- * @type {MetadataComponentType[]}
- * @readonly
- */
- componentTypes: {
- get: function () {
- return this._componentTypes;
- },
- },
-
- /**
- * Gets the ordering of the metadata in the buffers.
- *
- * @memberof Cesium3DTilesVoxelProvider.prototype
- * @type {VoxelMetadataOrder}
- * @readonly
- * @private
- */
- metadataOrder: {
- get: function () {
- return this._metadataOrder;
- },
- },
-
- /**
- * Gets the metadata minimum values.
- *
- * @memberof Cesium3DTilesVoxelProvider.prototype
- * @type {number[][]|undefined}
- * @readonly
- */
- minimumValues: {
- get: function () {
- return this._minimumValues;
- },
- },
-
- /**
- * Gets the metadata maximum values.
- *
- * @memberof Cesium3DTilesVoxelProvider.prototype
- * @type {number[][]|undefined}
- * @readonly
- */
- maximumValues: {
- get: function () {
- return this._maximumValues;
- },
- },
-
- /**
- * The maximum number of tiles that exist for this provider.
- * This value is used as a hint to the voxel renderer to allocate an appropriate amount of GPU memory.
- * If this value is not known it can be undefined.
- *
- * @memberof Cesium3DTilesVoxelProvider.prototype
- * @type {number|undefined}
- * @readonly
- */
- maximumTileCount: {
- get: function () {
- return this._maximumTileCount;
- },
- },
-
- /**
- * The number of levels of detail containing available tiles in the tileset.
- *
- * @memberof Cesium3DTilesVoxelProvider.prototype
- * @type {number|undefined}
- * @readonly
- */
- availableLevels: {
- get: function () {
- return this._availableLevels;
- },
- },
- });
-
- /**
- * Creates a {@link Cesium3DTilesVoxelProvider} that fetches voxel data from a 3D Tiles tileset.
- *
- * @param {Resource|string} url The URL to a tileset JSON file
- * @returns {Promise<Cesium3DTilesVoxelProvider>} The created provider
- *
- * @exception {RuntimeException} Root must have content
- * @exception {RuntimeException} Root tile content must have 3DTILES_content_voxels extension
- * @exception {RuntimeException} Root tile must have implicit tiling
- * @exception {RuntimeException} Tileset must have a metadata schema
- * @exception {RuntimeException} Only box, region and 3DTILES_bounding_volume_cylinder are supported in Cesium3DTilesVoxelProvider
- *
- * @example
- * try {
- * const voxelProvider = await Cesium3DTilesVoxelProvider.fromUrl(
- * "http://localhost:8002/tilesets/voxel/tileset.json"
- * );
- * const voxelPrimitive = new VoxelPrimitive({
- * provider: voxelProvider,
- * customShader: customShader,
- * });
- * scene.primitives.add(voxelPrimitive);
- * } catch (error) {
- * console.error(`Error creating voxel primitive: ${error}`);
- * }
- *
- * @see {@link VoxelPrimitive}
- */
- Cesium3DTilesVoxelProvider.fromUrl = async function (url) {
- //>>includeStart('debug', pragmas.debug);
- Check.defined("url", url);
- //>>includeEnd('debug');
-
- const resource = Resource.createIfNeeded(url);
- const tilesetJson = await resource.fetchJson();
-
- validate(tilesetJson);
-
- const schemaLoader = getMetadataSchemaLoader(tilesetJson, resource);
- await schemaLoader.load();
-
- const { root } = tilesetJson;
-
- const metadataJson = hasExtension(tilesetJson, "3DTILES_metadata")
- ? tilesetJson.extensions["3DTILES_metadata"]
- : tilesetJson;
-
- const tilesetMetadata = new Cesium3DTilesetMetadata({
- metadataJson: metadataJson,
- schema: schemaLoader.schema,
- });
-
- const voxel = root.content.extensions["3DTILES_content_voxels"];
- const className = voxel.class;
-
- const providerOptions = getAttributeInfo(tilesetMetadata, className);
- Object.assign(providerOptions, getShape(root));
- if (defined(root.transform)) {
- providerOptions.globalTransform = Matrix4.unpack(root.transform);
- } else {
- providerOptions.globalTransform = Matrix4.clone(Matrix4.IDENTITY);
- }
-
- providerOptions.dimensions = Cartesian3.unpack(voxel.dimensions);
- providerOptions.maximumTileCount = getTileCount(tilesetMetadata);
-
- if (defined(voxel.padding)) {
- providerOptions.paddingBefore = Cartesian3.unpack(voxel.padding.before);
- providerOptions.paddingAfter = Cartesian3.unpack(voxel.padding.after);
- }
-
- const provider = new Cesium3DTilesVoxelProvider(providerOptions);
-
- const implicitTileset = new ImplicitTileset(
- resource,
- root,
- schemaLoader.schema,
- );
- provider._implicitTileset = implicitTileset;
- provider._availableLevels = implicitTileset.availableLevels;
-
- ResourceCache.unload(schemaLoader);
-
- return provider;
- };
-
- function getTileCount(metadata) {
- if (!defined(metadata.tileset)) {
- return undefined;
- }
-
- return metadata.tileset.getPropertyBySemantic(
- MetadataSemantic.TILESET_TILE_COUNT,
- );
- }
-
- function validate(tileset) {
- const root = tileset.root;
-
- if (!defined(root.content)) {
- throw new RuntimeError("Root must have content");
- }
-
- if (!hasExtension(root.content, "3DTILES_content_voxels")) {
- throw new RuntimeError(
- "Root tile content must have 3DTILES_content_voxels extension",
- );
- }
-
- if (
- !hasExtension(root, "3DTILES_implicit_tiling") &&
- !defined(root.implicitTiling)
- ) {
- throw new RuntimeError("Root tile must have implicit tiling");
- }
-
- if (
- !defined(tileset.schema) &&
- !defined(tileset.schemaUri) &&
- !hasExtension(tileset, "3DTILES_metadata")
- ) {
- throw new RuntimeError("Tileset must have a metadata schema");
- }
- }
-
- function getShape(tile) {
- const boundingVolume = tile.boundingVolume;
-
- if (defined(boundingVolume.box)) {
- return getBoxShape(boundingVolume.box);
- } else if (defined(boundingVolume.region)) {
- return getEllipsoidShape(boundingVolume.region);
- } else if (hasExtension(boundingVolume, "3DTILES_bounding_volume_cylinder")) {
- return getCylinderShape(
- boundingVolume.extensions["3DTILES_bounding_volume_cylinder"],
- );
- }
-
- throw new RuntimeError(
- "Only box, region and 3DTILES_bounding_volume_cylinder are supported in Cesium3DTilesVoxelProvider",
- );
- }
-
- function getEllipsoidShape(region) {
- const west = region[0];
- const south = region[1];
- const east = region[2];
- const north = region[3];
- const minHeight = region[4];
- const maxHeight = region[5];
-
- const shapeTransform = Matrix4.fromScale(Ellipsoid.WGS84.radii);
-
- const minBounds = new Cartesian3(west, south, minHeight);
- const maxBounds = new Cartesian3(east, north, maxHeight);
-
- return {
- shape: VoxelShapeType.ELLIPSOID,
- minBounds: minBounds,
- maxBounds: maxBounds,
- shapeTransform: shapeTransform,
- };
- }
-
- const scratchScale = new Cartesian3();
- const scratchRotation = new Matrix3();
-
- function getBoxShape(box) {
- const obb = OrientedBoundingBox.unpack(box);
- const scale = Matrix3.getScale(obb.halfAxes, scratchScale);
- const rotation = Matrix3.getRotation(obb.halfAxes, scratchRotation);
-
- return {
- shape: VoxelShapeType.BOX,
- minBounds: Cartesian3.negate(scale, new Cartesian3()),
- maxBounds: Cartesian3.clone(scale),
- shapeTransform: Matrix4.fromRotationTranslation(rotation, obb.center),
- };
- }
-
- function getCylinderShape(cylinder) {
- const {
- minRadius,
- maxRadius,
- height,
- minAngle = -CesiumMath.PI,
- maxAngle = CesiumMath.PI,
- translation = [0, 0, 0],
- rotation = [0, 0, 0, 1],
- } = cylinder;
-
- //>>includeStart('debug', pragmas.debug);
- Check.typeOf.number("minRadius", minRadius);
- Check.typeOf.number("maxRadius", maxRadius);
- Check.typeOf.number("height", height);
- Check.typeOf.number("minAngle", minAngle);
- Check.typeOf.number("maxAngle", maxAngle);
- Check.typeOf.object("translation", translation);
- Check.typeOf.object("rotation", rotation);
- //>>includeEnd('debug');
-
- const minHeight = -0.5 * height + translation[2];
- const maxHeight = 0.5 * height + translation[2];
-
- const shapeTransform = Matrix4.fromTranslationQuaternionRotationScale(
- Cartesian3.unpack(translation),
- Quaternion.unpack(rotation),
- Cartesian3.ONE,
- );
-
- return {
- shape: VoxelShapeType.CYLINDER,
- minBounds: Cartesian3.fromElements(minRadius, minAngle, minHeight),
- maxBounds: Cartesian3.fromElements(maxRadius, maxAngle, maxHeight),
- shapeTransform: shapeTransform,
- };
- }
-
- function getMetadataSchemaLoader(tilesetJson, resource) {
- const { schemaUri, schema } = tilesetJson;
- if (!defined(schemaUri)) {
- return ResourceCache.getSchemaLoader({ schema });
- }
- return ResourceCache.getSchemaLoader({
- resource: resource.getDerivedResource({
- url: schemaUri,
- }),
- });
- }
-
- function getAttributeInfo(metadata, className) {
- const { schema, statistics } = metadata;
- const classStatistics = statistics?.classes[className];
- const properties = schema.classes[className].properties;
-
- const propertyInfo = Object.entries(properties).map(([id, property]) => {
- const { type, componentType } = property;
- const min = classStatistics?.properties[id].min;
- const max = classStatistics?.properties[id].max;
- const componentCount = MetadataType.getComponentCount(type);
- const minValue = copyArray(min, componentCount);
- const maxValue = copyArray(max, componentCount);
-
- return { id, type, componentType, minValue, maxValue };
- });
-
- const names = propertyInfo.map((info) => info.id);
- const types = propertyInfo.map((info) => info.type);
- const componentTypes = propertyInfo.map((info) => info.componentType);
-
- const minimumValues = propertyInfo.map((info) => info.minValue);
- const maximumValues = propertyInfo.map((info) => info.maxValue);
- const hasMinimumValues = minimumValues.some(defined);
-
- return {
- className,
- names,
- types,
- componentTypes,
- minimumValues: hasMinimumValues ? minimumValues : undefined,
- maximumValues: hasMinimumValues ? maximumValues : undefined,
- };
- }
-
- function copyArray(values, length) {
- // Copy input values into a new array of a specified length.
- // If the input is not an array, its value will be copied into the first element
- // of the returned array. If the input is an array shorter than the returned
- // array, the extra elements in the returned array will be undefined. If the
- // input is undefined, the return will be undefined.
- if (!defined(values)) {
- return;
- }
- const valuesArray = Array.isArray(values) ? values : [values];
- return Array.from({ length }, (v, i) => valuesArray[i]);
- }
-
- /**
- * Get the subtree at a given subtree coordinate
- * @param {VoxelProvider} provider The voxel provider
- * @param {ImplicitTileCoordinates} subtreeCoord The coordinate at which to retrieve the subtree
- * @returns {Promise<ImplicitSubtree>} The subtree at the given coordinate
- * @private
- */
- async function getSubtree(provider, subtreeCoord) {
- const implicitTileset = provider._implicitTileset;
- const subtreeCache = provider._subtreeCache;
-
- // First load the subtree to check if the tile is available.
- // If the subtree has been requested previously it might still be in the cache
- let subtree = subtreeCache.find(subtreeCoord);
- if (defined(subtree)) {
- return subtree;
- }
-
- const subtreeRelative = implicitTileset.subtreeUriTemplate.getDerivedResource(
- {
- templateValues: subtreeCoord.getTemplateValues(),
- },
- );
- const subtreeResource = implicitTileset.baseResource.getDerivedResource({
- url: subtreeRelative.url,
- });
-
- const arrayBuffer = await subtreeResource.fetchArrayBuffer();
- // Check one more time if the subtree is in the cache.
- // This could happen if there are two in-flight tile requests from the same
- // subtree and one finishes before the other.
- subtree = subtreeCache.find(subtreeCoord);
- if (defined(subtree)) {
- return subtree;
- }
-
- const preprocessed = preprocess3DTileContent(arrayBuffer);
- subtree = await ImplicitSubtree.fromSubtreeJson(
- subtreeResource,
- preprocessed.jsonPayload,
- preprocessed.binaryPayload,
- implicitTileset,
- subtreeCoord,
- );
- subtreeCache.addSubtree(subtree);
- return subtree;
- }
-
- /**
- * Requests the data for a given tile.
- *
- * @param {object} [options] Object with the following properties:
- * @param {number} [options.tileLevel=0] The tile's level.
- * @param {number} [options.tileX=0] The tile's X coordinate.
- * @param {number} [options.tileY=0] The tile's Y coordinate.
- * @param {number} [options.tileZ=0] The tile's Z coordinate.
- * @privateparam {number} [options.keyframe=0] The requested keyframe.
- * @returns {Promise<VoxelContent>|undefined} A promise resolving to a VoxelContent containing the data for the tile, or undefined if the request could not be scheduled this frame.
- */
- Cesium3DTilesVoxelProvider.prototype.requestData = async function (options) {
- options = options ?? Frozen.EMPTY_OBJECT;
- const {
- tileLevel = 0,
- tileX = 0,
- tileY = 0,
- tileZ = 0,
- keyframe = 0,
- } = options;
-
- if (keyframe !== 0) {
- return Promise.reject(
- `3D Tiles currently doesn't support time-dynamic data.`,
- );
- }
-
- // 1. Load the subtree that the tile belongs to (possibly from the subtree cache)
- // 2. Load the voxel content if available
-
- // Can't use a scratch variable here because the object is used inside the promise chain.
- const implicitTileset = this._implicitTileset;
- const tileCoordinates = new ImplicitTileCoordinates({
- subdivisionScheme: implicitTileset.subdivisionScheme,
- subtreeLevels: implicitTileset.subtreeLevels,
- level: tileLevel,
- x: tileX,
- y: tileY,
- z: tileZ,
- });
-
- // Find the coordinates of the parent subtree containing tileCoordinates
- // If tileCoordinates is a subtree child, use that subtree
- // If tileCoordinates is a subtree root, use its parent subtree
- const isSubtreeRoot =
- tileCoordinates.isSubtreeRoot() && tileCoordinates.level > 0;
-
- const subtreeCoord = isSubtreeRoot
- ? tileCoordinates.getParentSubtreeCoordinates()
- : tileCoordinates.getSubtreeCoordinates();
-
- const that = this;
-
- const subtree = await getSubtree(that, subtreeCoord);
- // NOTE: these two subtree methods are ONLY used by voxels!
- const isAvailable = isSubtreeRoot
- ? subtree.childSubtreeIsAvailableAtCoordinates
- : subtree.tileIsAvailableAtCoordinates;
-
- const available = isAvailable.call(subtree, tileCoordinates);
-
- if (!available) {
- return Promise.reject(
- `Tile is not available at level ${tileLevel}, x ${tileX}, y ${tileY}, z ${tileZ}.`,
- );
- }
-
- const { contentUriTemplates, baseResource } = implicitTileset;
- const gltfRelative = contentUriTemplates[0].getDerivedResource({
- templateValues: tileCoordinates.getTemplateValues(),
- });
- const gltfResource = baseResource.getDerivedResource({
- url: gltfRelative.url,
- });
-
- return VoxelContent.fromGltf(gltfResource);
- };
-
- export default Cesium3DTilesVoxelProvider;
|