@loaders.gl/tiles 5.0.0-alpha.1 → 5.0.0-alpha.11
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +14 -3
- package/README.md +26 -0
- package/dist/dist.dev.js +20341 -5081
- package/dist/dist.min.js +3 -1
- package/dist/index.cjs +7904 -2071
- package/dist/index.cjs.map +3 -4
- package/dist/index.d.ts +25 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +11 -0
- package/dist/index.js.map +1 -1
- package/dist/point-cloud/point-cloud-tile.d.ts.map +1 -1
- package/dist/point-cloud/point-cloud-tile.js +3 -0
- package/dist/point-cloud/point-cloud-tile.js.map +1 -1
- package/dist/point-cloud/point-cloud-tileset.d.ts +4 -0
- package/dist/point-cloud/point-cloud-tileset.d.ts.map +1 -1
- package/dist/point-cloud/point-cloud-tileset.js +54 -12
- package/dist/point-cloud/point-cloud-tileset.js.map +1 -1
- package/dist/point-cloud/types.d.ts +17 -0
- package/dist/point-cloud/types.d.ts.map +1 -1
- package/dist/point-cloud/types.js +3 -0
- package/dist/point-cloud/types.js.map +1 -1
- package/dist/raster-set.d.ts +48 -31
- package/dist/raster-set.d.ts.map +1 -1
- package/dist/raster-set.js +104 -24
- package/dist/raster-set.js.map +1 -1
- package/dist/spatial/format-spatial-reference.d.ts +68 -0
- package/dist/spatial/format-spatial-reference.d.ts.map +1 -0
- package/dist/spatial/format-spatial-reference.js +291 -0
- package/dist/spatial/format-spatial-reference.js.map +1 -0
- package/dist/spatial/get-spatial-coordinate-frame.d.ts +20 -0
- package/dist/spatial/get-spatial-coordinate-frame.d.ts.map +1 -0
- package/dist/spatial/get-spatial-coordinate-frame.js +139 -0
- package/dist/spatial/get-spatial-coordinate-frame.js.map +1 -0
- package/dist/spatial/i3s-elevation.d.ts +20 -0
- package/dist/spatial/i3s-elevation.d.ts.map +1 -0
- package/dist/spatial/i3s-elevation.js +90 -0
- package/dist/spatial/i3s-elevation.js.map +1 -0
- package/dist/spatial/i3s-spatial-transformer.d.ts +205 -0
- package/dist/spatial/i3s-spatial-transformer.d.ts.map +1 -0
- package/dist/spatial/i3s-spatial-transformer.js +731 -0
- package/dist/spatial/i3s-spatial-transformer.js.map +1 -0
- package/dist/spatial/normalize-crs-identifier.d.ts +15 -0
- package/dist/spatial/normalize-crs-identifier.d.ts.map +1 -0
- package/dist/spatial/normalize-crs-identifier.js +22 -0
- package/dist/spatial/normalize-crs-identifier.js.map +1 -0
- package/dist/spatial/spatial-coordinate-transformer.d.ts +52 -0
- package/dist/spatial/spatial-coordinate-transformer.d.ts.map +1 -0
- package/dist/spatial/spatial-coordinate-transformer.js +295 -0
- package/dist/spatial/spatial-coordinate-transformer.js.map +1 -0
- package/dist/spatial/spatial-resource-registry.d.ts +47 -0
- package/dist/spatial/spatial-resource-registry.d.ts.map +1 -0
- package/dist/spatial/spatial-resource-registry.js +76 -0
- package/dist/spatial/spatial-resource-registry.js.map +1 -0
- package/dist/spatial/spatial-types.d.ts +190 -0
- package/dist/spatial/spatial-types.d.ts.map +1 -0
- package/dist/spatial/spatial-types.js +192 -0
- package/dist/spatial/spatial-types.js.map +1 -0
- package/dist/spatial/tiles-3d-spatial-transformer.d.ts +32 -0
- package/dist/spatial/tiles-3d-spatial-transformer.d.ts.map +1 -0
- package/dist/spatial/tiles-3d-spatial-transformer.js +163 -0
- package/dist/spatial/tiles-3d-spatial-transformer.js.map +1 -0
- package/dist/tileset-2d/adapter.d.ts +2 -3
- package/dist/tileset-2d/adapter.d.ts.map +1 -1
- package/dist/tileset-2d/tileset-2d.d.ts +2 -3
- package/dist/tileset-2d/tileset-2d.d.ts.map +1 -1
- package/dist/tileset-2d/tileset-2d.js.map +1 -1
- package/dist/tileset-3d/common/indexed-archive-tileset-source.d.ts +3 -3
- package/dist/tileset-3d/common/indexed-archive-tileset-source.d.ts.map +1 -1
- package/dist/tileset-3d/common/indexed-archive-tileset-source.js +9 -4
- package/dist/tileset-3d/common/indexed-archive-tileset-source.js.map +1 -1
- package/dist/tileset-3d/common/tile-3d-contracts.d.ts +63 -0
- package/dist/tileset-3d/common/tile-3d-contracts.d.ts.map +1 -0
- package/dist/tileset-3d/common/tile-3d-contracts.js +51 -0
- package/dist/tileset-3d/common/tile-3d-contracts.js.map +1 -0
- package/dist/tileset-3d/common/tile-3d.d.ts +176 -5
- package/dist/tileset-3d/common/tile-3d.d.ts.map +1 -1
- package/dist/tileset-3d/common/tile-3d.js +523 -89
- package/dist/tileset-3d/common/tile-3d.js.map +1 -1
- package/dist/tileset-3d/common/tileset-3d.d.ts +199 -9
- package/dist/tileset-3d/common/tileset-3d.d.ts.map +1 -1
- package/dist/tileset-3d/common/tileset-3d.js +345 -32
- package/dist/tileset-3d/common/tileset-3d.js.map +1 -1
- package/dist/tileset-3d/common/tileset-cache.d.ts +11 -1
- package/dist/tileset-3d/common/tileset-cache.d.ts.map +1 -1
- package/dist/tileset-3d/common/tileset-cache.js +11 -3
- package/dist/tileset-3d/common/tileset-cache.js.map +1 -1
- package/dist/tileset-3d/common/tileset-content-traversal.d.ts +37 -0
- package/dist/tileset-3d/common/tileset-content-traversal.d.ts.map +1 -0
- package/dist/tileset-3d/common/tileset-content-traversal.js +80 -0
- package/dist/tileset-3d/common/tileset-content-traversal.js.map +1 -0
- package/dist/tileset-3d/common/tileset-observability.d.ts +60 -0
- package/dist/tileset-3d/common/tileset-observability.d.ts.map +1 -0
- package/dist/tileset-3d/common/tileset-observability.js +39 -0
- package/dist/tileset-3d/common/tileset-observability.js.map +1 -0
- package/dist/tileset-3d/common/tileset-source.d.ts +51 -9
- package/dist/tileset-3d/common/tileset-source.d.ts.map +1 -1
- package/dist/tileset-3d/common/tileset-source.js.map +1 -1
- package/dist/tileset-3d/common/tileset-traverser.d.ts +33 -1
- package/dist/tileset-3d/common/tileset-traverser.d.ts.map +1 -1
- package/dist/tileset-3d/common/tileset-traverser.js +61 -14
- package/dist/tileset-3d/common/tileset-traverser.js.map +1 -1
- package/dist/tileset-3d/format-3d-tiles/implicit-tiling.d.ts +182 -0
- package/dist/tileset-3d/format-3d-tiles/implicit-tiling.d.ts.map +1 -0
- package/dist/tileset-3d/format-3d-tiles/implicit-tiling.js +681 -0
- package/dist/tileset-3d/format-3d-tiles/implicit-tiling.js.map +1 -0
- package/dist/tileset-3d/format-3d-tiles/tiles-3d-source.d.ts +127 -6
- package/dist/tileset-3d/format-3d-tiles/tiles-3d-source.d.ts.map +1 -1
- package/dist/tileset-3d/format-3d-tiles/tiles-3d-source.js +485 -27
- package/dist/tileset-3d/format-3d-tiles/tiles-3d-source.js.map +1 -1
- package/dist/tileset-3d/format-3d-tiles/tileset-3d-traverser.d.ts +104 -0
- package/dist/tileset-3d/format-3d-tiles/tileset-3d-traverser.d.ts.map +1 -1
- package/dist/tileset-3d/format-3d-tiles/tileset-3d-traverser.js +286 -0
- package/dist/tileset-3d/format-3d-tiles/tileset-3d-traverser.js.map +1 -1
- package/dist/tileset-3d/format-i3s/i3s-pending-tiles-register.d.ts.map +1 -1
- package/dist/tileset-3d/format-i3s/i3s-pending-tiles-register.js +3 -0
- package/dist/tileset-3d/format-i3s/i3s-pending-tiles-register.js.map +1 -1
- package/dist/tileset-3d/format-i3s/i3s-source.d.ts +23 -6
- package/dist/tileset-3d/format-i3s/i3s-source.d.ts.map +1 -1
- package/dist/tileset-3d/format-i3s/i3s-source.js +176 -25
- package/dist/tileset-3d/format-i3s/i3s-source.js.map +1 -1
- package/dist/tileset-3d/format-i3s/i3s-tile-manager.d.ts.map +1 -1
- package/dist/tileset-3d/format-i3s/i3s-tile-manager.js +3 -0
- package/dist/tileset-3d/format-i3s/i3s-tile-manager.js.map +1 -1
- package/dist/tileset-3d/format-i3s/i3s-tileset-traverser.d.ts.map +1 -1
- package/dist/tileset-3d/format-i3s/i3s-tileset-traverser.js +4 -1
- package/dist/tileset-3d/format-i3s/i3s-tileset-traverser.js.map +1 -1
- package/dist/tileset-3d/helpers/3d-tiles-options.d.ts.map +1 -1
- package/dist/tileset-3d/helpers/3d-tiles-options.js +3 -0
- package/dist/tileset-3d/helpers/3d-tiles-options.js.map +1 -1
- package/dist/tileset-3d/helpers/bounding-volume.d.ts +7 -3
- package/dist/tileset-3d/helpers/bounding-volume.d.ts.map +1 -1
- package/dist/tileset-3d/helpers/bounding-volume.js +20 -91
- package/dist/tileset-3d/helpers/bounding-volume.js.map +1 -1
- package/dist/tileset-3d/helpers/frame-state.d.ts +67 -2
- package/dist/tileset-3d/helpers/frame-state.d.ts.map +1 -1
- package/dist/tileset-3d/helpers/frame-state.js +92 -10
- package/dist/tileset-3d/helpers/frame-state.js.map +1 -1
- package/dist/tileset-3d/helpers/i3s-lod.d.ts.map +1 -1
- package/dist/tileset-3d/helpers/i3s-lod.js +20 -8
- package/dist/tileset-3d/helpers/i3s-lod.js.map +1 -1
- package/dist/tileset-3d/helpers/s2-bounding-volume.d.ts +17 -0
- package/dist/tileset-3d/helpers/s2-bounding-volume.d.ts.map +1 -0
- package/dist/tileset-3d/helpers/s2-bounding-volume.js +20 -0
- package/dist/tileset-3d/helpers/s2-bounding-volume.js.map +1 -0
- package/dist/tileset-3d/helpers/tiles-3d-lod.d.ts +61 -9
- package/dist/tileset-3d/helpers/tiles-3d-lod.d.ts.map +1 -1
- package/dist/tileset-3d/helpers/tiles-3d-lod.js +198 -93
- package/dist/tileset-3d/helpers/tiles-3d-lod.js.map +1 -1
- package/dist/tileset-3d/helpers/tiles-3d-request-priority.d.ts +134 -0
- package/dist/tileset-3d/helpers/tiles-3d-request-priority.d.ts.map +1 -0
- package/dist/tileset-3d/helpers/tiles-3d-request-priority.js +179 -0
- package/dist/tileset-3d/helpers/tiles-3d-request-priority.js.map +1 -0
- package/dist/types.d.ts +7 -0
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +3 -0
- package/dist/types.js.map +1 -1
- package/dist/utils/doubly-linked-list.d.ts.map +1 -1
- package/dist/utils/doubly-linked-list.js +1 -0
- package/dist/utils/doubly-linked-list.js.map +1 -1
- package/dist/utils/managed-array.d.ts.map +1 -1
- package/dist/utils/managed-array.js +1 -0
- package/dist/utils/managed-array.js.map +1 -1
- package/package.json +12 -10
- package/src/index.ts +79 -1
- package/src/point-cloud/point-cloud-tile.ts +4 -0
- package/src/point-cloud/point-cloud-tileset.ts +70 -12
- package/src/point-cloud/types.ts +21 -0
- package/src/raster-set.ts +197 -67
- package/src/spatial/format-spatial-reference.ts +385 -0
- package/src/spatial/get-spatial-coordinate-frame.ts +169 -0
- package/src/spatial/i3s-elevation.ts +96 -0
- package/src/spatial/i3s-spatial-transformer.ts +1021 -0
- package/src/spatial/normalize-crs-identifier.ts +26 -0
- package/src/spatial/spatial-coordinate-transformer.ts +377 -0
- package/src/spatial/spatial-resource-registry.ts +90 -0
- package/src/spatial/spatial-types.ts +422 -0
- package/src/spatial/tiles-3d-spatial-transformer.ts +194 -0
- package/src/tileset-2d/adapter.ts +2 -3
- package/src/tileset-2d/tileset-2d.ts +2 -3
- package/src/tileset-3d/common/indexed-archive-tileset-source.ts +13 -13
- package/src/tileset-3d/common/tile-3d-contracts.ts +115 -0
- package/src/tileset-3d/common/tile-3d.ts +629 -98
- package/src/tileset-3d/common/tileset-3d.ts +512 -40
- package/src/tileset-3d/common/tileset-cache.ts +15 -7
- package/src/tileset-3d/common/tileset-content-traversal.ts +114 -0
- package/src/tileset-3d/common/tileset-observability.ts +100 -0
- package/src/tileset-3d/common/tileset-source.ts +63 -13
- package/src/tileset-3d/common/tileset-traverser.ts +73 -15
- package/src/tileset-3d/format-3d-tiles/implicit-tiling.ts +1059 -0
- package/src/tileset-3d/format-3d-tiles/tiles-3d-source.ts +674 -28
- package/src/tileset-3d/format-3d-tiles/tileset-3d-traverser.ts +328 -0
- package/src/tileset-3d/format-i3s/i3s-pending-tiles-register.ts +4 -0
- package/src/tileset-3d/format-i3s/i3s-source.ts +220 -29
- package/src/tileset-3d/format-i3s/i3s-tile-manager.ts +4 -0
- package/src/tileset-3d/format-i3s/i3s-tileset-traverser.ts +6 -1
- package/src/tileset-3d/helpers/3d-tiles-options.ts +4 -0
- package/src/tileset-3d/helpers/bounding-volume.ts +31 -114
- package/src/tileset-3d/helpers/frame-state.ts +152 -13
- package/src/tileset-3d/helpers/i3s-lod.ts +22 -8
- package/src/tileset-3d/helpers/s2-bounding-volume.ts +35 -0
- package/src/tileset-3d/helpers/tiles-3d-lod.ts +291 -112
- package/src/tileset-3d/helpers/tiles-3d-request-priority.ts +301 -0
- package/src/types.ts +11 -0
- package/src/utils/doubly-linked-list.ts +2 -0
- package/src/utils/managed-array.ts +2 -0
|
@@ -8,16 +8,63 @@ import { Stats } from '@probe.gl/stats';
|
|
|
8
8
|
import { RequestScheduler } from '@loaders.gl/loader-utils';
|
|
9
9
|
import { TilesetCache } from "./tileset-cache.js";
|
|
10
10
|
import { calculateTransformProps } from "../helpers/transform-utils.js";
|
|
11
|
-
import { getFrameState, limitSelectedTiles } from "../helpers/frame-state.js";
|
|
11
|
+
import { getFrameState, limitSelectedTiles, updateCameraMotionState } from "../helpers/frame-state.js";
|
|
12
|
+
import { calculateDynamicScreenSpaceErrorDensity, updateRootTransformForDynamicScreenSpaceError } from "../helpers/tiles-3d-lod.js";
|
|
13
|
+
import { interpolateLinearly } from "../helpers/tiles-3d-request-priority.js";
|
|
14
|
+
import { TILESET_TYPE } from "../../constants.js";
|
|
15
|
+
import { applyTilesetSpatialOptions, createTilesetSpatialReference } from "../../spatial/spatial-types.js";
|
|
12
16
|
import { isTileset3DSource } from "./tileset-source.js";
|
|
17
|
+
const BYTES_PER_MEBIBYTE = 1024 * 1024;
|
|
18
|
+
const DEFAULT_CACHE_BYTES = 512 * BYTES_PER_MEBIBYTE;
|
|
19
|
+
const DEFAULT_MAXIMUM_CACHE_OVERFLOW_BYTES = 512 * BYTES_PER_MEBIBYTE;
|
|
20
|
+
const DEFAULT_I3S_CACHE_BYTES = 32 * BYTES_PER_MEBIBYTE;
|
|
21
|
+
const DEFAULT_I3S_MAXIMUM_CACHE_OVERFLOW_BYTES = BYTES_PER_MEBIBYTE;
|
|
22
|
+
/**
|
|
23
|
+
* Validates a byte-based tile-cache budget.
|
|
24
|
+
*
|
|
25
|
+
* Fractions are accepted because JavaScript memory estimates are numbers, but negative, infinite,
|
|
26
|
+
* and `NaN` values cannot define a stable cache threshold.
|
|
27
|
+
*
|
|
28
|
+
* @param value - Proposed cache budget in bytes.
|
|
29
|
+
* @param optionName - Public option name used in an actionable error message.
|
|
30
|
+
* @returns The validated byte budget.
|
|
31
|
+
*/
|
|
32
|
+
function validateCacheByteLength(value, optionName) {
|
|
33
|
+
if (!Number.isFinite(value) || value < 0) {
|
|
34
|
+
throw new Error(`${optionName} must be a finite number greater than or equal to 0`);
|
|
35
|
+
}
|
|
36
|
+
return value;
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Resolves the base cache target from the byte-native option or its fallback.
|
|
40
|
+
*
|
|
41
|
+
* @param options - Options that may contain a byte-native cache value.
|
|
42
|
+
* @param fallbackCacheBytes - Existing or default cache target in bytes.
|
|
43
|
+
* @returns The resolved and validated cache target in bytes.
|
|
44
|
+
*/
|
|
45
|
+
function resolveCacheBytes(options, fallbackCacheBytes) {
|
|
46
|
+
const cacheBytes = options.cacheBytes ?? fallbackCacheBytes;
|
|
47
|
+
return validateCacheByteLength(cacheBytes, 'cacheBytes');
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Resolves cache overflow headroom from the byte-native option or its fallback.
|
|
51
|
+
*
|
|
52
|
+
* @param options - Options that may contain a byte-native overflow value.
|
|
53
|
+
* @param fallbackOverflowBytes - Existing or default overflow headroom in bytes.
|
|
54
|
+
* @returns The resolved and validated overflow headroom in bytes.
|
|
55
|
+
*/
|
|
56
|
+
function resolveMaximumCacheOverflowBytes(options, fallbackOverflowBytes) {
|
|
57
|
+
const maximumCacheOverflowBytes = options.maximumCacheOverflowBytes ?? fallbackOverflowBytes;
|
|
58
|
+
return validateCacheByteLength(maximumCacheOverflowBytes, 'maximumCacheOverflowBytes');
|
|
59
|
+
}
|
|
13
60
|
const DEFAULT_PROPS = {
|
|
14
61
|
description: '',
|
|
15
62
|
ellipsoid: Ellipsoid.WGS84,
|
|
16
63
|
modelMatrix: new Matrix4(),
|
|
17
64
|
throttleRequests: true,
|
|
18
65
|
maxRequests: 64,
|
|
19
|
-
|
|
20
|
-
|
|
66
|
+
cacheBytes: DEFAULT_CACHE_BYTES,
|
|
67
|
+
maximumCacheOverflowBytes: DEFAULT_MAXIMUM_CACHE_OVERFLOW_BYTES,
|
|
21
68
|
maximumTilesSelected: 0,
|
|
22
69
|
debounceTime: 0,
|
|
23
70
|
onTileLoad: () => { },
|
|
@@ -29,15 +76,31 @@ const DEFAULT_PROPS = {
|
|
|
29
76
|
onUpdate: () => { },
|
|
30
77
|
contentLoader: undefined,
|
|
31
78
|
viewDistanceScale: 1.0,
|
|
79
|
+
progressiveResolutionHeightFraction: 0.3,
|
|
80
|
+
foveatedScreenSpaceError: true,
|
|
81
|
+
foveatedConeSize: 0.1,
|
|
82
|
+
foveatedMinimumScreenSpaceErrorRelaxation: 0,
|
|
83
|
+
foveatedInterpolationCallback: interpolateLinearly,
|
|
84
|
+
foveatedTimeDelay: 0.2,
|
|
32
85
|
maximumScreenSpaceError: 8,
|
|
33
|
-
|
|
86
|
+
skipLevelOfDetail: false,
|
|
87
|
+
baseScreenSpaceError: 1024,
|
|
88
|
+
skipScreenSpaceErrorFactor: 16,
|
|
89
|
+
skipLevels: 1,
|
|
90
|
+
immediatelyLoadDesiredLevelOfDetail: false,
|
|
91
|
+
dynamicScreenSpaceError: true,
|
|
92
|
+
dynamicScreenSpaceErrorDensity: 2.0e-4,
|
|
93
|
+
dynamicScreenSpaceErrorFactor: 24,
|
|
94
|
+
dynamicScreenSpaceErrorHeightFalloff: 0.25,
|
|
95
|
+
memoryAdjustedScreenSpaceError: true,
|
|
34
96
|
loadTiles: true,
|
|
35
97
|
updateTransforms: true,
|
|
36
98
|
viewportTraversersMap: null,
|
|
37
99
|
loadOptions: { fetch: {} },
|
|
38
100
|
attributions: [],
|
|
39
101
|
basePath: '',
|
|
40
|
-
i3s: {}
|
|
102
|
+
i3s: {},
|
|
103
|
+
spatial: {}
|
|
41
104
|
};
|
|
42
105
|
const TILES_TOTAL = 'Tiles In Tileset(s)';
|
|
43
106
|
const TILES_IN_MEMORY = 'Tiles In Memory';
|
|
@@ -73,6 +136,18 @@ export class Tileset3D {
|
|
|
73
136
|
root = null;
|
|
74
137
|
roots = {};
|
|
75
138
|
asset = {};
|
|
139
|
+
/** Inline metadata schema declared by the source tileset, when present. */
|
|
140
|
+
schema = null;
|
|
141
|
+
/** External metadata schema URI declared by the source tileset, when present. */
|
|
142
|
+
schemaUri = null;
|
|
143
|
+
/** Metadata groups declared by the source tileset, in source order. */
|
|
144
|
+
groups = [];
|
|
145
|
+
/** Tileset-wide metadata entity, preserved without property-table decoding. */
|
|
146
|
+
metadata = null;
|
|
147
|
+
/** Tileset statistics metadata, preserved for application-level inspection. */
|
|
148
|
+
statistics = null;
|
|
149
|
+
/** Normalized source and target coordinate reference system metadata. */
|
|
150
|
+
spatialReference = createTilesetSpatialReference({});
|
|
76
151
|
description = '';
|
|
77
152
|
properties;
|
|
78
153
|
extras = null;
|
|
@@ -84,12 +159,14 @@ export class Tileset3D {
|
|
|
84
159
|
cartesianCenter = null;
|
|
85
160
|
zoom = 1;
|
|
86
161
|
boundingVolume = null;
|
|
87
|
-
|
|
88
|
-
|
|
162
|
+
/** Effective dynamic SSE density calculated for the most recently traversed viewport. */
|
|
163
|
+
dynamicScreenSpaceErrorComputedDensity = 0;
|
|
164
|
+
/** Estimated bytes currently retained by loaded tile content. */
|
|
89
165
|
gpuMemoryUsageInBytes = 0;
|
|
166
|
+
/** Active SSE threshold after optional cache-pressure adjustment, in logical/CSS pixels. */
|
|
90
167
|
memoryAdjustedScreenSpaceError = 0.0;
|
|
91
|
-
_cacheBytes =
|
|
92
|
-
|
|
168
|
+
_cacheBytes = DEFAULT_CACHE_BYTES;
|
|
169
|
+
_maximumCacheOverflowBytes = DEFAULT_MAXIMUM_CACHE_OVERFLOW_BYTES;
|
|
93
170
|
_frameNumber = 0;
|
|
94
171
|
_tiles = {};
|
|
95
172
|
_pendingCount = 0;
|
|
@@ -100,9 +177,14 @@ export class Tileset3D {
|
|
|
100
177
|
_requestedTiles = [];
|
|
101
178
|
_emptyTiles = [];
|
|
102
179
|
frameStateData = {};
|
|
180
|
+
/** Last camera pose retained independently for each viewport. */
|
|
181
|
+
_cameraMotionStates = {};
|
|
182
|
+
/** Pending traversal that releases requests after camera motion settles. */
|
|
183
|
+
_deferredTraversalTimeout = null;
|
|
103
184
|
_traverser;
|
|
104
185
|
_cache = new TilesetCache();
|
|
105
186
|
_requestScheduler;
|
|
187
|
+
/** Drawn fallback instances retained independently for each viewport tree. */
|
|
106
188
|
_heldTiles = new Set();
|
|
107
189
|
updatePromise = null;
|
|
108
190
|
tilesetInitializationPromise;
|
|
@@ -112,11 +194,28 @@ export class Tileset3D {
|
|
|
112
194
|
* @param options Traversal and runtime options.
|
|
113
195
|
*/
|
|
114
196
|
constructor(source, options) {
|
|
115
|
-
this.options = { ...DEFAULT_PROPS, ...options };
|
|
116
|
-
this.loadOptions = this.options.loadOptions || {};
|
|
117
197
|
if (!isTileset3DSource(source)) {
|
|
118
198
|
throw new Error('Tileset3D requires a Tileset3DSource instance');
|
|
119
199
|
}
|
|
200
|
+
const suppliedOptions = options || {};
|
|
201
|
+
const usesTiles3DCacheDefaults = source.type === TILESET_TYPE.TILES3D;
|
|
202
|
+
const defaultCacheBytes = usesTiles3DCacheDefaults
|
|
203
|
+
? DEFAULT_PROPS.cacheBytes
|
|
204
|
+
: DEFAULT_I3S_CACHE_BYTES;
|
|
205
|
+
const defaultMaximumCacheOverflowBytes = usesTiles3DCacheDefaults
|
|
206
|
+
? DEFAULT_PROPS.maximumCacheOverflowBytes
|
|
207
|
+
: DEFAULT_I3S_MAXIMUM_CACHE_OVERFLOW_BYTES;
|
|
208
|
+
const cacheBytes = resolveCacheBytes(suppliedOptions, defaultCacheBytes);
|
|
209
|
+
const maximumCacheOverflowBytes = resolveMaximumCacheOverflowBytes(suppliedOptions, defaultMaximumCacheOverflowBytes);
|
|
210
|
+
this.options = {
|
|
211
|
+
...DEFAULT_PROPS,
|
|
212
|
+
...suppliedOptions,
|
|
213
|
+
cacheBytes,
|
|
214
|
+
maximumCacheOverflowBytes,
|
|
215
|
+
skipLevelOfDetail: suppliedOptions.skipLevelOfDetail ?? source.type === TILESET_TYPE.TILES3D,
|
|
216
|
+
memoryAdjustedScreenSpaceError: suppliedOptions.memoryAdjustedScreenSpaceError ?? usesTiles3DCacheDefaults
|
|
217
|
+
};
|
|
218
|
+
this.loadOptions = this.options.loadOptions || {};
|
|
120
219
|
this.source = source;
|
|
121
220
|
this.tileset = null;
|
|
122
221
|
this.loader = this.source.loader;
|
|
@@ -135,13 +234,19 @@ export class Tileset3D {
|
|
|
135
234
|
maxRequests: this.options.maxRequests
|
|
136
235
|
});
|
|
137
236
|
this.memoryAdjustedScreenSpaceError = this.options.maximumScreenSpaceError;
|
|
138
|
-
this._cacheBytes =
|
|
139
|
-
this.
|
|
237
|
+
this._cacheBytes = cacheBytes;
|
|
238
|
+
this._maximumCacheOverflowBytes = maximumCacheOverflowBytes;
|
|
239
|
+
const metadata = this._getSourceMetadata();
|
|
240
|
+
if (metadata) {
|
|
241
|
+
this.spatialReference = applyTilesetSpatialOptions(metadata.spatialReference, this.options.spatial);
|
|
242
|
+
}
|
|
140
243
|
this.stats = new Stats({ id: this.url });
|
|
141
244
|
this._initializeStats();
|
|
142
245
|
this.tilesetInitializationPromise = this._initializeTileSet();
|
|
143
246
|
}
|
|
144
247
|
destroy() {
|
|
248
|
+
this._clearDeferredTraversal();
|
|
249
|
+
this.source.destroy?.();
|
|
145
250
|
this._destroy();
|
|
146
251
|
}
|
|
147
252
|
isLoaded() {
|
|
@@ -153,13 +258,74 @@ export class Tileset3D {
|
|
|
153
258
|
get frameNumber() {
|
|
154
259
|
return this._frameNumber;
|
|
155
260
|
}
|
|
261
|
+
/**
|
|
262
|
+
* Returns the tiles requested during the most recent completed traversal.
|
|
263
|
+
*
|
|
264
|
+
* A defensive copy makes request ordering deterministic for diagnostics and prevents callers
|
|
265
|
+
* from mutating the scheduler's working set.
|
|
266
|
+
*/
|
|
267
|
+
get requestedTiles() {
|
|
268
|
+
return this._requestedTiles.slice();
|
|
269
|
+
}
|
|
270
|
+
/**
|
|
271
|
+
* Returns empty tiles considered during the most recent completed traversal.
|
|
272
|
+
*
|
|
273
|
+
* Empty tiles can still be useful hierarchy placeholders, but their IDs are included in
|
|
274
|
+
* observability snapshots so applications can distinguish traversal work from render content.
|
|
275
|
+
*/
|
|
276
|
+
get emptyTiles() {
|
|
277
|
+
return this._emptyTiles.slice();
|
|
278
|
+
}
|
|
279
|
+
/**
|
|
280
|
+
* Gets or sets the soft target, in bytes, for cached tile content not needed this frame.
|
|
281
|
+
*
|
|
282
|
+
* Current-frame tiles remain protected even when their estimated memory exceeds this target.
|
|
283
|
+
* Reducing the value makes unused least-recently-used tiles eligible for eviction on the next
|
|
284
|
+
* traversal.
|
|
285
|
+
* @default 536870912 for 3D Tiles; 33554432 for I3S
|
|
286
|
+
*/
|
|
287
|
+
get cacheBytes() {
|
|
288
|
+
return this._cacheBytes;
|
|
289
|
+
}
|
|
290
|
+
set cacheBytes(value) {
|
|
291
|
+
this._cacheBytes = validateCacheByteLength(value, 'cacheBytes');
|
|
292
|
+
this.options.cacheBytes = this._cacheBytes;
|
|
293
|
+
}
|
|
294
|
+
/**
|
|
295
|
+
* Gets or sets the additional current-frame headroom, in bytes, before memory-adjusted SSE rises.
|
|
296
|
+
*
|
|
297
|
+
* The pressure ceiling is `cacheBytes + maximumCacheOverflowBytes`. This value does not change
|
|
298
|
+
* the base target used to evict tiles that were not touched in the current frame.
|
|
299
|
+
* @default 536870912 for 3D Tiles; 1048576 for I3S
|
|
300
|
+
*/
|
|
301
|
+
get maximumCacheOverflowBytes() {
|
|
302
|
+
return this._maximumCacheOverflowBytes;
|
|
303
|
+
}
|
|
304
|
+
set maximumCacheOverflowBytes(value) {
|
|
305
|
+
this._maximumCacheOverflowBytes = validateCacheByteLength(value, 'maximumCacheOverflowBytes');
|
|
306
|
+
this.options.maximumCacheOverflowBytes = this._maximumCacheOverflowBytes;
|
|
307
|
+
}
|
|
156
308
|
get queryParams() {
|
|
157
309
|
const rootUrl = this.source.getTileUrl(this.url);
|
|
158
310
|
const queryIndex = rootUrl.indexOf('?');
|
|
159
311
|
return queryIndex >= 0 ? rootUrl.slice(queryIndex + 1) : '';
|
|
160
312
|
}
|
|
313
|
+
/**
|
|
314
|
+
* Updates traversal and runtime options while retaining unspecified byte budgets.
|
|
315
|
+
*
|
|
316
|
+
* @param props - Partial runtime options to apply.
|
|
317
|
+
*/
|
|
161
318
|
setProps(props) {
|
|
162
|
-
|
|
319
|
+
const cacheBytes = resolveCacheBytes(props, this.cacheBytes);
|
|
320
|
+
const maximumCacheOverflowBytes = resolveMaximumCacheOverflowBytes(props, this.maximumCacheOverflowBytes);
|
|
321
|
+
this.options = {
|
|
322
|
+
...this.options,
|
|
323
|
+
...props,
|
|
324
|
+
cacheBytes,
|
|
325
|
+
maximumCacheOverflowBytes
|
|
326
|
+
};
|
|
327
|
+
this._cacheBytes = cacheBytes;
|
|
328
|
+
this._maximumCacheOverflowBytes = maximumCacheOverflowBytes;
|
|
163
329
|
}
|
|
164
330
|
getTileUrl(tilePath) {
|
|
165
331
|
return this.source.getTileUrl(tilePath);
|
|
@@ -198,11 +364,18 @@ export class Tileset3D {
|
|
|
198
364
|
}
|
|
199
365
|
return this.updatePromise;
|
|
200
366
|
}
|
|
367
|
+
/**
|
|
368
|
+
* Moves the active LOD threshold toward the configured SSE or away from cache pressure.
|
|
369
|
+
*
|
|
370
|
+
* Usage below {@link Tileset3D.cacheBytes} restores quality in two-percent steps. Usage above
|
|
371
|
+
* `cacheBytes + maximumCacheOverflowBytes` reduces refinement in two-percent steps. Values in
|
|
372
|
+
* the overflow window leave the threshold unchanged, preventing rapid load/evict oscillation.
|
|
373
|
+
*/
|
|
201
374
|
adjustScreenSpaceError() {
|
|
202
|
-
if (this.gpuMemoryUsageInBytes < this.
|
|
375
|
+
if (this.gpuMemoryUsageInBytes < this.cacheBytes) {
|
|
203
376
|
this.memoryAdjustedScreenSpaceError = Math.max(this.memoryAdjustedScreenSpaceError / 1.02, this.options.maximumScreenSpaceError);
|
|
204
377
|
}
|
|
205
|
-
else if (this.gpuMemoryUsageInBytes > this.
|
|
378
|
+
else if (this.gpuMemoryUsageInBytes > this.cacheBytes + this.maximumCacheOverflowBytes) {
|
|
206
379
|
this.memoryAdjustedScreenSpaceError *= 1.02;
|
|
207
380
|
}
|
|
208
381
|
}
|
|
@@ -214,9 +387,19 @@ export class Tileset3D {
|
|
|
214
387
|
return;
|
|
215
388
|
}
|
|
216
389
|
const preparedViewports = viewports instanceof Array ? viewports : [viewports];
|
|
390
|
+
const activeViewportIds = new Set(preparedViewports.map(viewport => viewport.id));
|
|
391
|
+
// A viewport may be removed between frames. Discard its completed state before aggregating
|
|
392
|
+
// requested and selected tiles so observability reflects only the current traversal inputs.
|
|
393
|
+
for (const frameStateId of Object.keys(this.frameStateData)) {
|
|
394
|
+
if (!activeViewportIds.has(frameStateId)) {
|
|
395
|
+
delete this.frameStateData[frameStateId];
|
|
396
|
+
}
|
|
397
|
+
}
|
|
217
398
|
this._cache.reset();
|
|
218
399
|
this._frameNumber++;
|
|
219
400
|
this.traverseCounter = preparedViewports.length;
|
|
401
|
+
const currentTime = Date.now();
|
|
402
|
+
let minimumDeferredTraversalDelay = Number.POSITIVE_INFINITY;
|
|
220
403
|
const viewportsToTraverse = [];
|
|
221
404
|
for (const viewport of preparedViewports) {
|
|
222
405
|
const id = viewport.id;
|
|
@@ -236,7 +419,57 @@ export class Tileset3D {
|
|
|
236
419
|
continue;
|
|
237
420
|
}
|
|
238
421
|
const frameState = getFrameState(viewport, this._frameNumber);
|
|
239
|
-
this.
|
|
422
|
+
const root = this.roots[id];
|
|
423
|
+
const cameraMotionUpdate = updateCameraMotionState(this._cameraMotionStates[id], frameState.camera.position, frameState.camera.direction, currentTime);
|
|
424
|
+
this._cameraMotionStates[id] = cameraMotionUpdate.state;
|
|
425
|
+
frameState.camera.timeSinceMovement = cameraMotionUpdate.timeSinceMovement;
|
|
426
|
+
// Dynamic SSE reads the root's inverse computed transform before traversal updates tile
|
|
427
|
+
// visibility. Refresh it from the current tileset model matrix here so animated local
|
|
428
|
+
// box/sphere tilesets never calculate their height falloff one transform behind the frame.
|
|
429
|
+
updateRootTransformForDynamicScreenSpaceError(root, this.modelMatrix);
|
|
430
|
+
frameState.dynamicScreenSpaceErrorDensity =
|
|
431
|
+
this.type === TILESET_TYPE.TILES3D &&
|
|
432
|
+
this.options.dynamicScreenSpaceError &&
|
|
433
|
+
!frameState.viewport.orthographic
|
|
434
|
+
? calculateDynamicScreenSpaceErrorDensity(root, frameState, this.options)
|
|
435
|
+
: 0;
|
|
436
|
+
// Keep the legacy diagnostic field, but traversal reads the per-viewport frame value above.
|
|
437
|
+
this.dynamicScreenSpaceErrorComputedDensity = frameState.dynamicScreenSpaceErrorDensity;
|
|
438
|
+
this._traverser.traverse(root, frameState, this.options);
|
|
439
|
+
if (Object.keys(this._traverser.deferredTiles).length > 0) {
|
|
440
|
+
minimumDeferredTraversalDelay = Math.min(minimumDeferredTraversalDelay, Math.max(this.options.foveatedTimeDelay - cameraMotionUpdate.timeSinceMovement, 0));
|
|
441
|
+
}
|
|
442
|
+
}
|
|
443
|
+
if (Number.isFinite(minimumDeferredTraversalDelay)) {
|
|
444
|
+
this._scheduleDeferredTraversal(minimumDeferredTraversalDelay);
|
|
445
|
+
}
|
|
446
|
+
else {
|
|
447
|
+
this._clearDeferredTraversal();
|
|
448
|
+
}
|
|
449
|
+
}
|
|
450
|
+
/**
|
|
451
|
+
* Schedules one follow-up traversal when the moving-camera deferral window expires.
|
|
452
|
+
*
|
|
453
|
+
* Replacing an existing timer ensures continuing camera movement pushes the retry window forward
|
|
454
|
+
* instead of creating a queue of redundant traversals.
|
|
455
|
+
*
|
|
456
|
+
* @param delayInSeconds - Remaining stationary delay before deferred requests become eligible.
|
|
457
|
+
*/
|
|
458
|
+
_scheduleDeferredTraversal(delayInSeconds) {
|
|
459
|
+
this._clearDeferredTraversal();
|
|
460
|
+
this._deferredTraversalTimeout = setTimeout(() => {
|
|
461
|
+
this._deferredTraversalTimeout = null;
|
|
462
|
+
this.selectTiles().catch((error) => {
|
|
463
|
+
const traversalError = error instanceof Error ? error : new Error(String(error));
|
|
464
|
+
this._onTilesetError(traversalError);
|
|
465
|
+
});
|
|
466
|
+
}, Math.max(delayInSeconds * 1000, 0));
|
|
467
|
+
}
|
|
468
|
+
/** Clears a pending moving-camera follow-up traversal. */
|
|
469
|
+
_clearDeferredTraversal() {
|
|
470
|
+
if (this._deferredTraversalTimeout !== null) {
|
|
471
|
+
clearTimeout(this._deferredTraversalTimeout);
|
|
472
|
+
this._deferredTraversalTimeout = null;
|
|
240
473
|
}
|
|
241
474
|
}
|
|
242
475
|
_needTraverse(viewportId) {
|
|
@@ -278,29 +511,47 @@ export class Tileset3D {
|
|
|
278
511
|
this._emptyTiles = this._emptyTiles.concat(frameStateDataValue._emptyTiles);
|
|
279
512
|
}
|
|
280
513
|
this.selectedTiles = this.options.onTraversalComplete(this.selectedTiles);
|
|
281
|
-
const
|
|
514
|
+
const selectedTiles = new Set(this.selectedTiles);
|
|
282
515
|
const hasUndrawnTiles = this.selectedTiles.some(tile => !tile.tileDrawn);
|
|
283
516
|
let heldBackCount = 0;
|
|
284
517
|
if (hasUndrawnTiles) {
|
|
285
|
-
|
|
286
|
-
|
|
518
|
+
const activeRoots = new Set(Object.keys(this.frameStateData).map(viewportId => this.roots[viewportId]));
|
|
519
|
+
const descendantReadiness = new Map();
|
|
520
|
+
for (const tile of this.selectedTiles) {
|
|
521
|
+
for (let ancestor = tile.parent; ancestor; ancestor = ancestor.parent) {
|
|
522
|
+
descendantReadiness.set(ancestor, (descendantReadiness.get(ancestor) ?? true) && tile.tileDrawn);
|
|
523
|
+
}
|
|
524
|
+
}
|
|
525
|
+
// Drawing can finish between traversals. Promote only previously selected
|
|
526
|
+
// geometry that actually drew; pending tiles cannot provide visible fallback.
|
|
527
|
+
for (const tile of previousSelectedTiles) {
|
|
528
|
+
if (tile.tileDrawn)
|
|
529
|
+
this._heldTiles.add(tile);
|
|
287
530
|
}
|
|
288
|
-
for (const
|
|
289
|
-
|
|
531
|
+
for (const tile of this._heldTiles) {
|
|
532
|
+
let root = tile;
|
|
533
|
+
while (root.parent)
|
|
534
|
+
root = root.parent;
|
|
535
|
+
// Removed viewport trees cannot contribute fallback to the remaining views.
|
|
536
|
+
if (!activeRoots.has(root)) {
|
|
537
|
+
this._heldTiles.delete(tile);
|
|
290
538
|
continue;
|
|
291
|
-
|
|
292
|
-
if (tile
|
|
539
|
+
}
|
|
540
|
+
if (selectedTiles.has(tile))
|
|
541
|
+
continue;
|
|
542
|
+
if (tile.contentAvailable &&
|
|
543
|
+
!this._hasDrawnReplacement(tile, selectedTiles, descendantReadiness)) {
|
|
293
544
|
tile._selectedFrame = this._frameNumber;
|
|
294
545
|
this.selectedTiles.push(tile);
|
|
295
546
|
heldBackCount++;
|
|
296
547
|
}
|
|
297
548
|
else {
|
|
298
|
-
this._heldTiles.delete(
|
|
549
|
+
this._heldTiles.delete(tile);
|
|
299
550
|
}
|
|
300
551
|
}
|
|
301
552
|
}
|
|
302
553
|
else {
|
|
303
|
-
this._heldTiles =
|
|
554
|
+
this._heldTiles = selectedTiles;
|
|
304
555
|
}
|
|
305
556
|
if (heldBackCount > 0) {
|
|
306
557
|
setTimeout(() => {
|
|
@@ -317,6 +568,19 @@ export class Tileset3D {
|
|
|
317
568
|
this.options.onUpdate();
|
|
318
569
|
}
|
|
319
570
|
}
|
|
571
|
+
/**
|
|
572
|
+
* Releases fallback geometry once its own selected replacement has drawn.
|
|
573
|
+
* Unrelated pending branches must not delay this region's handoff. When no related
|
|
574
|
+
* replacement is selected, retain the fallback until the complete selection has drawn.
|
|
575
|
+
*/
|
|
576
|
+
_hasDrawnReplacement(tile, selectedTiles, descendantReadiness) {
|
|
577
|
+
for (let ancestor = tile.parent; ancestor; ancestor = ancestor.parent) {
|
|
578
|
+
if (selectedTiles.has(ancestor)) {
|
|
579
|
+
return ancestor.tileDrawn;
|
|
580
|
+
}
|
|
581
|
+
}
|
|
582
|
+
return descendantReadiness.get(tile) === true;
|
|
583
|
+
}
|
|
320
584
|
_tilesChanged(oldSelectedTiles, selectedTiles) {
|
|
321
585
|
if (oldSelectedTiles.length !== selectedTiles.length) {
|
|
322
586
|
return true;
|
|
@@ -337,6 +601,9 @@ export class Tileset3D {
|
|
|
337
601
|
}
|
|
338
602
|
_unloadTiles() {
|
|
339
603
|
this._cache.unloadTiles(this, (tileset, tile) => tileset._unloadTile(tile));
|
|
604
|
+
if (this.options.memoryAdjustedScreenSpaceError) {
|
|
605
|
+
this.adjustScreenSpaceError();
|
|
606
|
+
}
|
|
340
607
|
}
|
|
341
608
|
_updateStats() {
|
|
342
609
|
let tilesRenderable = 0;
|
|
@@ -344,11 +611,14 @@ export class Tileset3D {
|
|
|
344
611
|
for (const tile of this.selectedTiles) {
|
|
345
612
|
if (tile.contentAvailable && tile.content) {
|
|
346
613
|
tilesRenderable++;
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
614
|
+
const contents = tile.contents.length ? tile.contents : [tile.content];
|
|
615
|
+
for (const content of contents) {
|
|
616
|
+
if (content.pointCount) {
|
|
617
|
+
pointsRenderable += content.pointCount;
|
|
618
|
+
}
|
|
619
|
+
else {
|
|
620
|
+
pointsRenderable += content.vertexCount || 0;
|
|
621
|
+
}
|
|
352
622
|
}
|
|
353
623
|
}
|
|
354
624
|
}
|
|
@@ -365,13 +635,15 @@ export class Tileset3D {
|
|
|
365
635
|
this._syncSourceState(initialMetadata);
|
|
366
636
|
}
|
|
367
637
|
if (initialMetadata?.tileset?.root &&
|
|
368
|
-
typeof initialMetadata.tileset.root.then !== 'function'
|
|
638
|
+
typeof initialMetadata.tileset.root.then !== 'function' &&
|
|
639
|
+
(!this.source.prepareTileset || this.spatialReference?.status === 'native')) {
|
|
369
640
|
this.root = this._initializeTileHeaders(initialMetadata.tileset, null);
|
|
370
641
|
this._applyViewState();
|
|
371
642
|
}
|
|
372
643
|
await initializePromise;
|
|
373
644
|
const metadata = this.source.getMetadata();
|
|
374
645
|
this._syncSourceState(metadata);
|
|
646
|
+
await this.source.prepareTileset?.(this);
|
|
375
647
|
if (!this.root) {
|
|
376
648
|
this.root = this._initializeTileHeaders(metadata.tileset, null);
|
|
377
649
|
}
|
|
@@ -425,6 +697,29 @@ export class Tileset3D {
|
|
|
425
697
|
this._onTileLoad(tile, loadResult);
|
|
426
698
|
}
|
|
427
699
|
}
|
|
700
|
+
/**
|
|
701
|
+
* Loads a source-managed lazy child-header group and reports failures through tile callbacks.
|
|
702
|
+
*
|
|
703
|
+
* Subtree metadata shares the normal loading counters but is not reported as render content and
|
|
704
|
+
* is not added to the GPU cache. Traversal is notified separately after the promise settles.
|
|
705
|
+
*
|
|
706
|
+
* @param tile - Runtime tile that owns the lazy subtree reference.
|
|
707
|
+
* @param frameState - View state that made the subtree eligible for refinement.
|
|
708
|
+
*/
|
|
709
|
+
async _loadTileChildren(tile, frameState) {
|
|
710
|
+
try {
|
|
711
|
+
this._onStartTileLoading();
|
|
712
|
+
await tile.loadChildren(frameState);
|
|
713
|
+
}
|
|
714
|
+
catch (error) {
|
|
715
|
+
const tileError = error instanceof Error ? error : new Error('subtree load failed');
|
|
716
|
+
this._onSourceError(tileError, tile);
|
|
717
|
+
this._onTileLoadError(tile, tileError);
|
|
718
|
+
}
|
|
719
|
+
finally {
|
|
720
|
+
this._onEndTileLoading();
|
|
721
|
+
}
|
|
722
|
+
}
|
|
428
723
|
_onTileLoadError(tile, error) {
|
|
429
724
|
this.stats.get(TILES_LOAD_FAILED).incrementCount();
|
|
430
725
|
const message = error.message || error.toString();
|
|
@@ -527,6 +822,14 @@ export class Tileset3D {
|
|
|
527
822
|
this.refine = metadata.refine;
|
|
528
823
|
this.contentFormats = this.source.contentFormats;
|
|
529
824
|
this.asset = this.source.asset || this.asset;
|
|
825
|
+
const tileset = metadata.tileset;
|
|
826
|
+
this.schema = tileset.schema || null;
|
|
827
|
+
this.schemaUri = tileset.schemaUri || null;
|
|
828
|
+
this.groups = tileset.groups || [];
|
|
829
|
+
this.metadata = tileset.metadata || null;
|
|
830
|
+
this.statistics = tileset.statistics ?? null;
|
|
831
|
+
const spatialReference = applyTilesetSpatialOptions(metadata.spatialReference, this.options.spatial);
|
|
832
|
+
this.spatialReference = preserveTransformedSpatialReference(this.spatialReference, spatialReference);
|
|
530
833
|
this.properties = this.source.properties ?? this.properties;
|
|
531
834
|
this.extras = this.source.extras ?? this.extras;
|
|
532
835
|
if (this.options.attributions?.length) {
|
|
@@ -563,4 +866,14 @@ export class Tileset3D {
|
|
|
563
866
|
}
|
|
564
867
|
}
|
|
565
868
|
}
|
|
869
|
+
/** Preserve a completed runtime operation when asynchronous source metadata describes the same request. */
|
|
870
|
+
function preserveTransformedSpatialReference(current, next) {
|
|
871
|
+
return current?.status === 'transformed' &&
|
|
872
|
+
current.sourceCrs === next.sourceCrs &&
|
|
873
|
+
current.targetCrs === next.targetCrs &&
|
|
874
|
+
current.targetHeightReference === next.targetHeightReference &&
|
|
875
|
+
current.outputCoordinates === next.outputCoordinates
|
|
876
|
+
? current
|
|
877
|
+
: next;
|
|
878
|
+
}
|
|
566
879
|
//# sourceMappingURL=tileset-3d.js.map
|