@loaders.gl/tiles 4.0.4 → 4.1.0-alpha.10

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.
Files changed (44) hide show
  1. package/dist/constants.d.ts +1 -1
  2. package/dist/constants.d.ts.map +1 -1
  3. package/dist/constants.js.map +1 -1
  4. package/dist/dist.dev.js +29 -10
  5. package/dist/index.cjs +39 -10
  6. package/dist/index.d.ts.map +1 -1
  7. package/dist/index.js.map +1 -1
  8. package/dist/tileset/format-3d-tiles/tileset-3d-traverser.d.ts.map +1 -1
  9. package/dist/tileset/format-3d-tiles/tileset-3d-traverser.js.map +1 -1
  10. package/dist/tileset/helpers/i3s-lod.d.ts.map +1 -1
  11. package/dist/tileset/helpers/i3s-lod.js.map +1 -1
  12. package/dist/tileset/helpers/tiles-3d-lod.d.ts.map +1 -1
  13. package/dist/tileset/helpers/tiles-3d-lod.js.map +1 -1
  14. package/dist/tileset/helpers/transform-utils.d.ts.map +1 -1
  15. package/dist/tileset/helpers/transform-utils.js.map +1 -1
  16. package/dist/tileset/helpers/zoom.d.ts.map +1 -1
  17. package/dist/tileset/helpers/zoom.js.map +1 -1
  18. package/dist/tileset/tile-3d.d.ts.map +1 -1
  19. package/dist/tileset/tile-3d.js.map +1 -1
  20. package/dist/tileset/tileset-3d.d.ts +15 -0
  21. package/dist/tileset/tileset-3d.d.ts.map +1 -1
  22. package/dist/tileset/tileset-3d.js +21 -0
  23. package/dist/tileset/tileset-3d.js.map +1 -1
  24. package/dist/tileset/tileset-cache.d.ts.map +1 -1
  25. package/dist/tileset/tileset-cache.js.map +1 -1
  26. package/dist/tileset/tileset-traverser.d.ts +0 -1
  27. package/dist/tileset/tileset-traverser.d.ts.map +1 -1
  28. package/dist/tileset/tileset-traverser.js +8 -10
  29. package/dist/tileset/tileset-traverser.js.map +1 -1
  30. package/dist/utils/doubly-linked-list-node.d.ts.map +1 -1
  31. package/dist/utils/doubly-linked-list-node.js.map +1 -1
  32. package/package.json +6 -6
  33. package/src/constants.ts +2 -1
  34. package/src/index.ts +2 -1
  35. package/src/tileset/format-3d-tiles/tileset-3d-traverser.ts +2 -1
  36. package/src/tileset/helpers/i3s-lod.ts +2 -1
  37. package/src/tileset/helpers/tiles-3d-lod.ts +2 -1
  38. package/src/tileset/helpers/transform-utils.ts +2 -1
  39. package/src/tileset/helpers/zoom.ts +2 -1
  40. package/src/tileset/tile-3d.ts +2 -1
  41. package/src/tileset/tileset-3d.ts +46 -2
  42. package/src/tileset/tileset-cache.ts +2 -1
  43. package/src/tileset/tileset-traverser.ts +15 -19
  44. package/src/utils/doubly-linked-list-node.ts +2 -1
@@ -1,4 +1,5 @@
1
- // loaders.gl, MIT license
1
+ // loaders.gl
2
+ // SPDX-License-Identifier: MIT
2
3
  // Copyright (c) vis.gl contributors
3
4
 
4
5
  // This file is derived from the Cesium code base under Apache 2 license
@@ -1,4 +1,5 @@
1
- // loaders.gl, MIT license
1
+ // loaders.gl
2
+ // SPDX-License-Identifier: MIT
2
3
  // Copyright (c) vis.gl contributors
3
4
 
4
5
  import {Ellipsoid} from '@math.gl/geospatial';
@@ -1,4 +1,5 @@
1
- // loaders.gl, MIT license
1
+ // loaders.gl
2
+ // SPDX-License-Identifier: MIT
2
3
  // Copyright (c) vis.gl contributors
3
4
 
4
5
  import {Vector3} from '@math.gl/core';
@@ -1,4 +1,5 @@
1
- // loaders.gl, MIT license
1
+ // loaders.gl
2
+ // SPDX-License-Identifier: MIT
2
3
  // Copyright (c) vis.gl contributors
3
4
 
4
5
  // This file is derived from the Cesium code base under Apache 2 license
@@ -1,4 +1,4 @@
1
- // loaders.gl, MIT license
1
+ // SPDX-License-Identifier: MIT
2
2
  // Copyright (c) vis.gl contributors
3
3
 
4
4
  // This file is derived from the Cesium code base under Apache 2 license
@@ -52,6 +52,7 @@ export type Tileset3DProps = {
52
52
  loadTiles?: boolean;
53
53
  basePath?: string;
54
54
  maximumMemoryUsage?: number;
55
+ memoryCacheOverflow?: number;
55
56
  maximumTilesSelected?: number;
56
57
  debounceTime?: number;
57
58
 
@@ -65,6 +66,7 @@ export type Tileset3DProps = {
65
66
 
66
67
  // Traversal
67
68
  maximumScreenSpaceError?: number;
69
+ memoryAdjustedScreenSpaceError?: boolean;
68
70
  viewportTraversersMap?: any;
69
71
  updateTransforms?: boolean;
70
72
  viewDistanceScale?: number;
@@ -86,7 +88,10 @@ type Props = {
86
88
  throttleRequests: boolean;
87
89
  /** Number of simultaneous requsts, if throttleRequests is true */
88
90
  maxRequests: number;
91
+ /* Maximum amount of GPU memory (in MB) that may be used to cache tiles. */
89
92
  maximumMemoryUsage: number;
93
+ /* The maximum additional memory (in MB) to allow for cache headroom before adjusting the screen spacer error */
94
+ memoryCacheOverflow: number;
90
95
  /** Maximum number limit of tiles selected for show. 0 means no limit */
91
96
  maximumTilesSelected: number;
92
97
  /** Delay time before the tileset traversal. It prevents traversal requests spam.*/
@@ -101,6 +106,8 @@ type Props = {
101
106
  onTraversalComplete: (selectedTiles: Tile3D[]) => Tile3D[];
102
107
  /** The maximum screen space error used to drive level of detail refinement. */
103
108
  maximumScreenSpaceError: number;
109
+ /** Whether to adjust the maximum screen space error to comply with the maximum memory limitation */
110
+ memoryAdjustedScreenSpaceError: boolean;
104
111
  viewportTraversersMap: Record<string, any> | null;
105
112
  attributions: string[];
106
113
  loadTiles: boolean;
@@ -121,7 +128,9 @@ const DEFAULT_PROPS: Props = {
121
128
  modelMatrix: new Matrix4(),
122
129
  throttleRequests: true,
123
130
  maxRequests: 64,
131
+ /** Default memory values optimized for viewing mesh-based 3D Tiles on both mobile and desktop devices */
124
132
  maximumMemoryUsage: 32,
133
+ memoryCacheOverflow: 1,
125
134
  maximumTilesSelected: 0,
126
135
  debounceTime: 0,
127
136
  onTileLoad: () => {},
@@ -131,6 +140,7 @@ const DEFAULT_PROPS: Props = {
131
140
  contentLoader: undefined,
132
141
  viewDistanceScale: 1.0,
133
142
  maximumScreenSpaceError: 8,
143
+ memoryAdjustedScreenSpaceError: false,
134
144
  loadTiles: true,
135
145
  updateTransforms: true,
136
146
  viewportTraversersMap: null,
@@ -151,6 +161,7 @@ const TILES_UNLOADED = 'Tiles Unloaded';
151
161
  const TILES_LOAD_FAILED = 'Failed Tile Loads';
152
162
  const POINTS_COUNT = 'Points/Vertices';
153
163
  const TILES_GPU_MEMORY = 'Tile Memory Use';
164
+ const MAXIMUM_SSE = 'Maximum Screen Space Error';
154
165
 
155
166
  /**
156
167
  * The Tileset loading and rendering flow is as below,
@@ -238,6 +249,17 @@ export class Tileset3D {
238
249
  /** The total amount of GPU memory in bytes used by the tileset. */
239
250
  gpuMemoryUsageInBytes: number = 0;
240
251
 
252
+ /**
253
+ * If loading the level of detail required by maximumScreenSpaceError
254
+ * results in the memory usage exceeding maximumMemoryUsage (GPU), level of detail refinement
255
+ * will instead use this (larger) adjusted screen space error to achieve the
256
+ * best possible visual quality within the available memory.
257
+ */
258
+ memoryAdjustedScreenSpaceError: number = 0.0;
259
+
260
+ private _cacheBytes: number = 0;
261
+ private _cacheOverflowBytes: number = 0;
262
+
241
263
  /** Update tracker. increase in each update cycle. */
242
264
  _frameNumber: number = 0;
243
265
  private _queryParams: Record<string, string> = {};
@@ -300,6 +322,10 @@ export class Tileset3D {
300
322
  maxRequests: this.options.maxRequests
301
323
  });
302
324
 
325
+ this.memoryAdjustedScreenSpaceError = this.options.maximumScreenSpaceError;
326
+ this._cacheBytes = this.options.maximumMemoryUsage * 1024 * 1024;
327
+ this._cacheOverflowBytes = this.options.memoryCacheOverflow * 1024 * 1024;
328
+
303
329
  // METRICS
304
330
  // The total amount of GPU memory in bytes used by the tileset.
305
331
  this.stats = new Stats({id: this.url});
@@ -406,6 +432,16 @@ export class Tileset3D {
406
432
  return this.updatePromise;
407
433
  }
408
434
 
435
+ adjustScreenSpaceError(): void {
436
+ if (this.gpuMemoryUsageInBytes < this._cacheBytes) {
437
+ this.memoryAdjustedScreenSpaceError = Math.max(
438
+ this.memoryAdjustedScreenSpaceError / 1.02,
439
+ this.options.maximumScreenSpaceError
440
+ );
441
+ } else if (this.gpuMemoryUsageInBytes > this._cacheBytes + this._cacheOverflowBytes) {
442
+ this.memoryAdjustedScreenSpaceError *= 1.02;
443
+ }
444
+ }
409
445
  /**
410
446
  * Update visible tiles relying on a list of viewports
411
447
  * @param viewports viewports
@@ -570,6 +606,7 @@ export class Tileset3D {
570
606
  this.stats.get(TILES_IN_VIEW).count = this.selectedTiles.length;
571
607
  this.stats.get(TILES_RENDERABLE).count = tilesRenderable;
572
608
  this.stats.get(POINTS_COUNT).count = pointsRenderable;
609
+ this.stats.get(MAXIMUM_SSE).count = this.memoryAdjustedScreenSpaceError;
573
610
  }
574
611
 
575
612
  async _initializeTileSet(tilesetJson: TilesetJSON): Promise<void> {
@@ -667,6 +704,7 @@ export class Tileset3D {
667
704
  this.stats.get(TILES_LOAD_FAILED);
668
705
  this.stats.get(POINTS_COUNT);
669
706
  this.stats.get(TILES_GPU_MEMORY, 'memory');
707
+ this.stats.get(MAXIMUM_SSE);
670
708
  }
671
709
 
672
710
  // Installs the main tileset JSON file or a tileset JSON file referenced from a tile.
@@ -835,9 +873,15 @@ export class Tileset3D {
835
873
  this.stats.get(TILES_LOADED).incrementCount();
836
874
  this.stats.get(TILES_IN_MEMORY).incrementCount();
837
875
 
838
- // Good enough? Just use the raw binary ArrayBuffer's byte length.
876
+ // TODO: Calculate GPU memory usage statistics for a tile.
839
877
  this.gpuMemoryUsageInBytes += tile.gpuMemoryUsageInBytes || 0;
878
+
840
879
  this.stats.get(TILES_GPU_MEMORY).count = this.gpuMemoryUsageInBytes;
880
+
881
+ // Adjust SSE based on cache limits
882
+ if (this.options.memoryAdjustedScreenSpaceError) {
883
+ this.adjustScreenSpaceError();
884
+ }
841
885
  }
842
886
 
843
887
  _unloadTile(tile) {
@@ -1,4 +1,5 @@
1
- // loaders.gl, MIT license
1
+ // loaders.gl
2
+ // SPDX-License-Identifier: MIT
2
3
  // Copyright (c) vis.gl contributors
3
4
 
4
5
  // This file is derived from the Cesium code base under Apache 2 license
@@ -1,4 +1,5 @@
1
- // loaders.gl, MIT license
1
+ // loaders.gl
2
+ // SPDX-License-Identifier: MIT
2
3
  // Copyright (c) vis.gl contributors
3
4
 
4
5
  import type {Tile3D} from './tile-3d';
@@ -10,7 +11,6 @@ export type TilesetTraverserProps = {
10
11
  loadSiblings?: boolean;
11
12
  skipLevelOfDetail?: boolean;
12
13
  updateTransforms?: boolean;
13
- maximumScreenSpaceError?: number;
14
14
  onTraversalEnd?: (frameState) => any;
15
15
  viewportTraversersMap?: Record<string, any>;
16
16
  basePath?: string;
@@ -19,7 +19,6 @@ export type TilesetTraverserProps = {
19
19
  export const DEFAULT_PROPS: Required<TilesetTraverserProps> = {
20
20
  loadSiblings: false,
21
21
  skipLevelOfDetail: false,
22
- maximumScreenSpaceError: 2,
23
22
  updateTransforms: true,
24
23
  onTraversalEnd: () => {},
25
24
  viewportTraversersMap: {},
@@ -294,7 +293,7 @@ export class TilesetTraverser {
294
293
  screenSpaceError = tile.getScreenSpaceError(frameState, true);
295
294
  }
296
295
 
297
- return screenSpaceError > this.options.maximumScreenSpaceError;
296
+ return screenSpaceError > tile.tileset.memoryAdjustedScreenSpaceError;
298
297
  }
299
298
 
300
299
  updateTileVisibility(tile: Tile3D, frameState: FrameState): void {
@@ -334,38 +333,35 @@ export class TilesetTraverser {
334
333
  executeEmptyTraversal(root: Tile3D, frameState: FrameState): boolean {
335
334
  let allDescendantsLoaded = true;
336
335
  const stack = this._emptyTraversalStack;
337
-
338
336
  stack.push(root);
339
337
 
340
- while (stack.length > 0 && allDescendantsLoaded) {
338
+ while (stack.length > 0) {
341
339
  const tile = stack.pop();
342
340
 
341
+ const traverse = !tile.hasRenderContent && this.canTraverse(tile, frameState, false, false);
342
+ const emptyLeaf = !tile.hasRenderContent && tile.children.length === 0;
343
+
344
+ // Traversal stops but the tile does not have content yet
345
+ // There will be holes if the parent tries to refine to its children, so don't refine
346
+ // One exception: a parent may refine even if one of its descendants is an empty leaf
347
+ if (!traverse && !tile.contentAvailable && !emptyLeaf) {
348
+ allDescendantsLoaded = false;
349
+ }
350
+
343
351
  this.updateTile(tile, frameState);
344
352
 
345
353
  if (!tile.isVisibleAndInRequestVolume) {
346
- // Load tiles that aren't visible since they are still needed for the parent to refine
347
354
  this.loadTile(tile, frameState);
355
+ this.touchTile(tile, frameState);
348
356
  }
349
357
 
350
- this.touchTile(tile, frameState);
351
-
352
- // Only traverse if the tile is empty - traversal stop at descendants with content
353
- const traverse = !tile.hasRenderContent && this.canTraverse(tile, frameState, false, true);
354
-
355
358
  if (traverse) {
356
359
  const children = tile.children;
357
360
  for (const child of children) {
358
- // eslint-disable-next-line max-depth
359
- if (stack.find(child)) {
360
- stack.delete(child);
361
- }
362
361
  stack.push(child);
363
362
  }
364
- } else if (!tile.contentAvailable && !tile.hasEmptyContent) {
365
- allDescendantsLoaded = false;
366
363
  }
367
364
  }
368
-
369
365
  return allDescendantsLoaded;
370
366
  }
371
367
  }
@@ -1,4 +1,5 @@
1
- // loaders.gl, MIT license
1
+ // loaders.gl
2
+ // SPDX-License-Identifier: MIT
2
3
  // Copyright (c) vis.gl contributors
3
4
 
4
5
  // This file is derived from the Cesium code base under Apache 2 license