@loaders.gl/tiles 5.0.0-alpha.1 → 5.0.0-alpha.2
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/dist/dist.dev.js +2396 -274
- package/dist/dist.min.js +1 -1
- package/dist/index.cjs +2763 -337
- package/dist/index.cjs.map +3 -4
- package/dist/index.d.ts +7 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -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.map +1 -1
- package/dist/point-cloud/point-cloud-tileset.js +3 -0
- package/dist/point-cloud/point-cloud-tileset.js.map +1 -1
- 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 +35 -29
- package/dist/raster-set.d.ts.map +1 -1
- package/dist/raster-set.js +7 -1
- package/dist/raster-set.js.map +1 -1
- package/dist/tileset-3d/common/tile-3d.d.ts +98 -3
- package/dist/tileset-3d/common/tile-3d.d.ts.map +1 -1
- package/dist/tileset-3d/common/tile-3d.js +229 -15
- package/dist/tileset-3d/common/tile-3d.js.map +1 -1
- package/dist/tileset-3d/common/tileset-3d.d.ts +143 -3
- package/dist/tileset-3d/common/tileset-3d.d.ts.map +1 -1
- package/dist/tileset-3d/common/tileset-3d.js +257 -16
- 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-source.d.ts +18 -0
- 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 +13 -0
- package/dist/tileset-3d/common/tileset-traverser.d.ts.map +1 -1
- package/dist/tileset-3d/common/tileset-traverser.js +28 -1
- package/dist/tileset-3d/common/tileset-traverser.js.map +1 -1
- package/dist/tileset-3d/format-3d-tiles/implicit-tiling.d.ts +111 -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 +340 -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 +92 -3
- 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 +211 -13
- 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 +36 -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 +66 -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-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 +3 -0
- 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.map +1 -1
- package/dist/tileset-3d/helpers/bounding-volume.js +1 -0
- package/dist/tileset-3d/helpers/bounding-volume.js.map +1 -1
- package/dist/tileset-3d/helpers/frame-state.d.ts +59 -1
- package/dist/tileset-3d/helpers/frame-state.d.ts.map +1 -1
- package/dist/tileset-3d/helpers/frame-state.js +84 -9
- package/dist/tileset-3d/helpers/frame-state.js.map +1 -1
- 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 +2 -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 +5 -5
- package/src/index.ts +19 -0
- package/src/point-cloud/point-cloud-tile.ts +4 -0
- package/src/point-cloud/point-cloud-tileset.ts +4 -0
- package/src/point-cloud/types.ts +4 -0
- package/src/raster-set.ts +81 -43
- package/src/tileset-3d/common/tile-3d.ts +285 -21
- package/src/tileset-3d/common/tileset-3d.ts +368 -17
- package/src/tileset-3d/common/tileset-cache.ts +15 -7
- package/src/tileset-3d/common/tileset-source.ts +21 -0
- package/src/tileset-3d/common/tileset-traverser.ts +29 -1
- package/src/tileset-3d/format-3d-tiles/implicit-tiling.ts +534 -0
- package/src/tileset-3d/format-3d-tiles/tiles-3d-source.ts +266 -13
- package/src/tileset-3d/format-3d-tiles/tileset-3d-traverser.ts +77 -0
- package/src/tileset-3d/format-i3s/i3s-pending-tiles-register.ts +4 -0
- package/src/tileset-3d/format-i3s/i3s-tile-manager.ts +4 -0
- package/src/tileset-3d/format-i3s/i3s-tileset-traverser.ts +4 -0
- package/src/tileset-3d/helpers/3d-tiles-options.ts +4 -0
- package/src/tileset-3d/helpers/bounding-volume.ts +2 -0
- package/src/tileset-3d/helpers/frame-state.ts +139 -11
- 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 +6 -0
- package/src/utils/doubly-linked-list.ts +2 -0
- package/src/utils/managed-array.ts +2 -0
|
@@ -12,7 +12,7 @@ import {CullingVolume} from '@math.gl/culling';
|
|
|
12
12
|
import type {Tileset3D} from './tileset-3d';
|
|
13
13
|
import type {DoublyLinkedListNode} from '../../utils/doubly-linked-list-node';
|
|
14
14
|
import {LOD_METRIC_TYPE, TILE_REFINEMENT, TILE_CONTENT_STATE, TILESET_TYPE} from '../../constants';
|
|
15
|
-
import type {TileContentLoadResult} from './tileset-source';
|
|
15
|
+
import type {TileChildrenLoadResult, TileContentLoadResult} from './tileset-source';
|
|
16
16
|
|
|
17
17
|
import {FrameState} from '../helpers/frame-state';
|
|
18
18
|
import {
|
|
@@ -23,6 +23,13 @@ import {
|
|
|
23
23
|
import {getTiles3DScreenSpaceError} from '../helpers/tiles-3d-lod';
|
|
24
24
|
import {getProjectedRadius} from '../helpers/i3s-lod';
|
|
25
25
|
import {TilesetTraverser} from './tileset-traverser';
|
|
26
|
+
import {
|
|
27
|
+
calculateFoveatedFactor,
|
|
28
|
+
calculateTileRequestPriority,
|
|
29
|
+
isFoveatedRequestDelayActive,
|
|
30
|
+
isFoveatedRequestDeferred,
|
|
31
|
+
isProgressiveResolutionPriority
|
|
32
|
+
} from '../helpers/tiles-3d-request-priority';
|
|
26
33
|
|
|
27
34
|
const scratchVector = new Vector3();
|
|
28
35
|
|
|
@@ -44,6 +51,9 @@ export type Tile3DProps = {
|
|
|
44
51
|
extendedId: string;
|
|
45
52
|
};
|
|
46
53
|
|
|
54
|
+
/** Lifecycle of a source-managed lazy child-header group. */
|
|
55
|
+
export type TileChildrenState = 'unloaded' | 'loading' | 'ready' | 'failed';
|
|
56
|
+
|
|
47
57
|
/**
|
|
48
58
|
* A Tile3DHeader represents a tile as Tileset3D. When a tile is first created, its content is not loaded;
|
|
49
59
|
* the content is loaded on-demand when needed based on the view.
|
|
@@ -86,6 +96,8 @@ export class Tile3D {
|
|
|
86
96
|
|
|
87
97
|
/** The tile's children - an array of Tile3D objects. */
|
|
88
98
|
children: Tile3D[] = [];
|
|
99
|
+
/** Current lifecycle state for a lazy implicit subtree rooted at this tile. */
|
|
100
|
+
childrenState: TileChildrenState = 'ready';
|
|
89
101
|
depth: number = 0;
|
|
90
102
|
viewportIds: any[] = [];
|
|
91
103
|
transform = new Matrix4();
|
|
@@ -111,11 +123,22 @@ export class Tile3D {
|
|
|
111
123
|
private _expireDate: any = null;
|
|
112
124
|
private _expiredContent: any = null;
|
|
113
125
|
|
|
126
|
+
/** In-flight source request shared by repeated traversal frames. */
|
|
127
|
+
private _childrenPromise: Promise<TileChildrenLoadResult> | null = null;
|
|
128
|
+
|
|
114
129
|
private _boundingBox?: CartographicBounds = undefined;
|
|
115
130
|
|
|
116
131
|
/** updated every frame for tree traversal and rendering optimizations: */
|
|
117
132
|
public _distanceToCamera: number = 0;
|
|
118
133
|
_screenSpaceError: number = 0;
|
|
134
|
+
/** SSE calculated at the reduced viewport height used to prioritize coarse coverage. */
|
|
135
|
+
_screenSpaceErrorProgressiveResolution: number = 0;
|
|
136
|
+
/** Whether this tile should be promoted into the progressive-resolution request pass. */
|
|
137
|
+
_priorityProgressiveResolution: boolean = false;
|
|
138
|
+
/** Angular distance from the camera view axis used to prioritize center tiles. */
|
|
139
|
+
_foveatedFactor: number = 0;
|
|
140
|
+
/** Whether this peripheral request is currently inside the camera-motion deferral window. */
|
|
141
|
+
priorityDeferred: boolean = false;
|
|
119
142
|
private _visibilityPlaneMask: any;
|
|
120
143
|
private _visible: boolean | undefined = undefined;
|
|
121
144
|
|
|
@@ -176,6 +199,7 @@ export class Tile3D {
|
|
|
176
199
|
this.refine = this._getRefine(header.refine);
|
|
177
200
|
this.type = header.type;
|
|
178
201
|
this.contentUrl = header.contentUrl;
|
|
202
|
+
this.childrenState = header.implicitSubtree ? 'unloaded' : 'ready';
|
|
179
203
|
|
|
180
204
|
this._initializeLodMetric(header);
|
|
181
205
|
this._initializeTransforms(header);
|
|
@@ -214,7 +238,24 @@ export class Tile3D {
|
|
|
214
238
|
|
|
215
239
|
/** Returns true if tile has children */
|
|
216
240
|
get hasChildren() {
|
|
217
|
-
return
|
|
241
|
+
return (
|
|
242
|
+
this.children.length > 0 ||
|
|
243
|
+
(this.header.children && this.header.children.length > 0) ||
|
|
244
|
+
Boolean(this.header.implicitSubtree && this.childrenState !== 'ready')
|
|
245
|
+
);
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
/** Returns whether traversal may request an unresolved lazy child-header group. */
|
|
249
|
+
get hasUnloadedChildren(): boolean {
|
|
250
|
+
return Boolean(
|
|
251
|
+
this.header.implicitSubtree &&
|
|
252
|
+
(this.childrenState === 'unloaded' || this.childrenState === 'failed')
|
|
253
|
+
);
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
/** Returns whether a lazy child-header request is currently in flight. */
|
|
257
|
+
get childrenLoading(): boolean {
|
|
258
|
+
return this.childrenState === 'loading';
|
|
218
259
|
}
|
|
219
260
|
|
|
220
261
|
/**
|
|
@@ -287,13 +328,28 @@ export class Tile3D {
|
|
|
287
328
|
return this._boundingBox;
|
|
288
329
|
}
|
|
289
330
|
|
|
290
|
-
/**
|
|
291
|
-
|
|
331
|
+
/**
|
|
332
|
+
* Gets the tile's screen-space error for normal refinement or a reduced-height priority pass.
|
|
333
|
+
*
|
|
334
|
+
* I3S already supplies a screen-oriented LOD metric and intentionally ignores the optional 3D
|
|
335
|
+
* Tiles progressive-resolution height fraction.
|
|
336
|
+
*
|
|
337
|
+
* @param frameState - Current camera and viewport measurements.
|
|
338
|
+
* @param useParentLodMetric - Whether to substitute the parent LOD metric.
|
|
339
|
+
* @param viewportHeightFraction - Fraction of viewport height represented by the priority pass.
|
|
340
|
+
* @returns Screen-space LOD error for the current tileset format.
|
|
341
|
+
*/
|
|
342
|
+
getScreenSpaceError(frameState, useParentLodMetric, viewportHeightFraction = 1) {
|
|
292
343
|
switch (this.tileset.type) {
|
|
293
344
|
case TILESET_TYPE.I3S:
|
|
294
345
|
return getProjectedRadius(this, frameState);
|
|
295
346
|
case TILESET_TYPE.TILES3D:
|
|
296
|
-
return getTiles3DScreenSpaceError(
|
|
347
|
+
return getTiles3DScreenSpaceError(
|
|
348
|
+
this,
|
|
349
|
+
frameState,
|
|
350
|
+
useParentLodMetric,
|
|
351
|
+
viewportHeightFraction
|
|
352
|
+
);
|
|
297
353
|
default:
|
|
298
354
|
// eslint-disable-next-line
|
|
299
355
|
throw new Error('Unsupported tileset type');
|
|
@@ -315,12 +371,36 @@ export class Tile3D {
|
|
|
315
371
|
return this.content.gpuMemoryUsageInBytes || this.content.byteLength || 0;
|
|
316
372
|
}
|
|
317
373
|
|
|
318
|
-
|
|
319
|
-
*
|
|
320
|
-
*
|
|
374
|
+
/**
|
|
375
|
+
* Returns scheduler priority for render-content requests.
|
|
376
|
+
*
|
|
377
|
+
* @returns Numeric priority, or a negative value when the queued request should be cancelled.
|
|
378
|
+
*/
|
|
379
|
+
_getPriority(): number {
|
|
380
|
+
return this._calculateRequestPriority(false);
|
|
381
|
+
}
|
|
382
|
+
|
|
383
|
+
/**
|
|
384
|
+
* Returns scheduler priority for lazy child-header requests.
|
|
385
|
+
*
|
|
386
|
+
* Contentless implicit placeholders intentionally retain `UNLOADED` content state, so metadata
|
|
387
|
+
* scheduling skips only that render-content cancellation check and preserves every visibility,
|
|
388
|
+
* recency, progressive, foveated, and motion-deferral rule.
|
|
389
|
+
*
|
|
390
|
+
* @returns Numeric priority, or a negative value when the queued request should be cancelled.
|
|
391
|
+
*/
|
|
392
|
+
private _getChildrenPriority(): number {
|
|
393
|
+
return this._calculateRequestPriority(true);
|
|
394
|
+
}
|
|
395
|
+
|
|
396
|
+
/**
|
|
397
|
+
* Calculates the common scheduler priority for content or hierarchy metadata.
|
|
398
|
+
*
|
|
399
|
+
* @param allowUnloadedContent - Whether an empty placeholder may request child metadata.
|
|
400
|
+
* @returns Numeric priority, or a negative value when the queued request should be cancelled.
|
|
321
401
|
*/
|
|
322
402
|
// eslint-disable-next-line complexity
|
|
323
|
-
|
|
403
|
+
private _calculateRequestPriority(allowUnloadedContent: boolean): number {
|
|
324
404
|
const traverser = this.tileset._traverser;
|
|
325
405
|
const {skipLevelOfDetail} = traverser.options;
|
|
326
406
|
|
|
@@ -340,7 +420,13 @@ export class Tile3D {
|
|
|
340
420
|
if (this.tileset._frameNumber - this._touchedFrame >= 1) {
|
|
341
421
|
return -1;
|
|
342
422
|
}
|
|
343
|
-
|
|
423
|
+
// RequestScheduler re-evaluates this callback before a queued request receives a slot. A
|
|
424
|
+
// negative priority cancels work that became deferred after it was queued; the scheduled
|
|
425
|
+
// follow-up traversal submits it again after the motion delay expires.
|
|
426
|
+
if (this.priorityDeferred) {
|
|
427
|
+
return -1;
|
|
428
|
+
}
|
|
429
|
+
if (!allowUnloadedContent && this.contentState === TILE_CONTENT_STATE.UNLOADED) {
|
|
344
430
|
return -1;
|
|
345
431
|
}
|
|
346
432
|
|
|
@@ -354,8 +440,15 @@ export class Tile3D {
|
|
|
354
440
|
|
|
355
441
|
const rootScreenSpaceError = traverser.root ? traverser.root._screenSpaceError : 0.0;
|
|
356
442
|
|
|
357
|
-
// Map higher SSE to lower values (e.g. root tile is highest priority)
|
|
358
|
-
|
|
443
|
+
// Map higher SSE to lower values (e.g. root tile is highest priority), then combine the
|
|
444
|
+
// existing order with independent progressive and foveated priority bands.
|
|
445
|
+
const reverseScreenSpaceError = Math.max(rootScreenSpaceError - screenSpaceError, 0);
|
|
446
|
+
return calculateTileRequestPriority({
|
|
447
|
+
priorityProgressiveResolution: this._priorityProgressiveResolution,
|
|
448
|
+
foveatedFactor: this._foveatedFactor,
|
|
449
|
+
reverseScreenSpaceError,
|
|
450
|
+
rootScreenSpaceError
|
|
451
|
+
});
|
|
359
452
|
}
|
|
360
453
|
|
|
361
454
|
/**
|
|
@@ -410,6 +503,96 @@ export class Tile3D {
|
|
|
410
503
|
}
|
|
411
504
|
}
|
|
412
505
|
|
|
506
|
+
/**
|
|
507
|
+
* Requests and installs this tile's lazy child-header group through its source.
|
|
508
|
+
*
|
|
509
|
+
* The same request scheduler and SSE/foveated priority value used for render content are reused
|
|
510
|
+
* for subtree metadata. Repeated traversal frames share one promise, and scheduler cancellation
|
|
511
|
+
* restores the unloaded state so a later frame can retry.
|
|
512
|
+
*
|
|
513
|
+
* @param frameState - View state that made the subtree eligible for refinement.
|
|
514
|
+
* @returns Source load result, or an unloaded result if scheduling was cancelled.
|
|
515
|
+
*/
|
|
516
|
+
async loadChildren(frameState: FrameState): Promise<TileChildrenLoadResult> {
|
|
517
|
+
if (!this.header.implicitSubtree || this.childrenState === 'ready') {
|
|
518
|
+
return {loaded: false, tileCount: 0, childSubtreeCount: 0};
|
|
519
|
+
}
|
|
520
|
+
if (this._childrenPromise) {
|
|
521
|
+
return await this._childrenPromise;
|
|
522
|
+
}
|
|
523
|
+
if (!this.tileset.source.loadTileChildren) {
|
|
524
|
+
throw new Error('Tileset source does not support lazy tile children');
|
|
525
|
+
}
|
|
526
|
+
|
|
527
|
+
this.childrenState = 'loading';
|
|
528
|
+
this._childrenPromise = this._loadChildrenWithScheduler(frameState);
|
|
529
|
+
try {
|
|
530
|
+
return await this._childrenPromise;
|
|
531
|
+
} finally {
|
|
532
|
+
this._childrenPromise = null;
|
|
533
|
+
}
|
|
534
|
+
}
|
|
535
|
+
|
|
536
|
+
/**
|
|
537
|
+
* Runs one lazy child-header load after obtaining a scheduler token.
|
|
538
|
+
*
|
|
539
|
+
* @param frameState - View state forwarded to the source implementation.
|
|
540
|
+
* @returns Source load result.
|
|
541
|
+
*/
|
|
542
|
+
private async _loadChildrenWithScheduler(
|
|
543
|
+
frameState: FrameState
|
|
544
|
+
): Promise<TileChildrenLoadResult> {
|
|
545
|
+
const requestToken = await this.tileset._requestScheduler.scheduleRequest(
|
|
546
|
+
`${this.id}:implicit-subtree`,
|
|
547
|
+
this._getChildrenPriority.bind(this)
|
|
548
|
+
);
|
|
549
|
+
if (!requestToken) {
|
|
550
|
+
this.childrenState = 'unloaded';
|
|
551
|
+
return {loaded: false, tileCount: 0, childSubtreeCount: 0};
|
|
552
|
+
}
|
|
553
|
+
|
|
554
|
+
try {
|
|
555
|
+
const loadResult = await this.tileset.source.loadTileChildren!(this, frameState);
|
|
556
|
+
this.childrenState = loadResult.loaded ? 'ready' : 'unloaded';
|
|
557
|
+
return loadResult;
|
|
558
|
+
} catch (error) {
|
|
559
|
+
this.childrenState = 'failed';
|
|
560
|
+
throw error;
|
|
561
|
+
} finally {
|
|
562
|
+
requestToken.done();
|
|
563
|
+
}
|
|
564
|
+
}
|
|
565
|
+
|
|
566
|
+
/**
|
|
567
|
+
* Replaces a contentless implicit placeholder with its materialized subtree-root header.
|
|
568
|
+
*
|
|
569
|
+
* Transform state is intentionally preserved: the placeholder already owns the composed
|
|
570
|
+
* transform, and reapplying the root transform here would double-transform bounds and geometric
|
|
571
|
+
* error. Content and raw geometric error are reinitialized from the newly available header.
|
|
572
|
+
*
|
|
573
|
+
* @param materializedHeader - Available root header produced from one subtree resource.
|
|
574
|
+
*/
|
|
575
|
+
applyImplicitSubtreeHeader(materializedHeader: Record<string, any>): void {
|
|
576
|
+
const existingTransform = this.header.transform;
|
|
577
|
+
const existingTransformMatrix = this.header.transformMatrix;
|
|
578
|
+
this.header = {
|
|
579
|
+
...this.header,
|
|
580
|
+
...materializedHeader,
|
|
581
|
+
transform: existingTransform,
|
|
582
|
+
transformMatrix: existingTransformMatrix,
|
|
583
|
+
implicitSubtree: undefined
|
|
584
|
+
};
|
|
585
|
+
this.refine = this._getRefine(materializedHeader.refine);
|
|
586
|
+
this.type = materializedHeader.type;
|
|
587
|
+
this.contentUrl = materializedHeader.contentUrl;
|
|
588
|
+
this._initializeLodMetric(materializedHeader);
|
|
589
|
+
this._updateLodMetricScale();
|
|
590
|
+
this._initializeBoundingVolumes(this.header);
|
|
591
|
+
// Use the merged header so inherited viewer-request-volume metadata remains available when a
|
|
592
|
+
// materialized implicit tile has no render content of its own.
|
|
593
|
+
this._initializeContent(this.header);
|
|
594
|
+
}
|
|
595
|
+
|
|
413
596
|
// Unloads the tile's content.
|
|
414
597
|
unloadContent() {
|
|
415
598
|
if (this.content && this.content.destroy) {
|
|
@@ -450,6 +633,7 @@ export class Tile3D {
|
|
|
450
633
|
|
|
451
634
|
this._distanceToCamera = this.distanceToTile(frameState);
|
|
452
635
|
this._screenSpaceError = this.getScreenSpaceError(frameState, false);
|
|
636
|
+
this._updateRequestPriorityMetrics(frameState);
|
|
453
637
|
this._visibilityPlaneMask = this.visibility(frameState, parentVisibilityPlaneMask); // Use parent's plane mask to speed up visibility test
|
|
454
638
|
this._visible = this._visibilityPlaneMask !== CullingVolume.MASK_OUTSIDE;
|
|
455
639
|
this._inRequestVolume = this.insideViewerRequestVolume(frameState);
|
|
@@ -458,6 +642,71 @@ export class Tile3D {
|
|
|
458
642
|
this.viewportIds = viewportIds;
|
|
459
643
|
}
|
|
460
644
|
|
|
645
|
+
/**
|
|
646
|
+
* Updates progressive-resolution and foveated request metrics for a 3D Tiles traversal frame.
|
|
647
|
+
*
|
|
648
|
+
* I3S retains its format-specific screen-threshold ordering and is explicitly isolated from
|
|
649
|
+
* geometric-error scheduling. Orthographic viewports still receive progressive coverage, but
|
|
650
|
+
* angular foveation is disabled because an orthographic frustum has no perspective field of view.
|
|
651
|
+
*
|
|
652
|
+
* @param frameState - Current camera and viewport measurements.
|
|
653
|
+
*/
|
|
654
|
+
_updateRequestPriorityMetrics(frameState: FrameState): void {
|
|
655
|
+
if (this.tileset.type !== TILESET_TYPE.TILES3D) {
|
|
656
|
+
this._screenSpaceErrorProgressiveResolution = this._screenSpaceError;
|
|
657
|
+
this._priorityProgressiveResolution = false;
|
|
658
|
+
this._foveatedFactor = 0;
|
|
659
|
+
this.priorityDeferred = false;
|
|
660
|
+
return;
|
|
661
|
+
}
|
|
662
|
+
|
|
663
|
+
const options = this.tileset.options;
|
|
664
|
+
const progressiveResolutionHeightFraction = options.progressiveResolutionHeightFraction;
|
|
665
|
+
this._screenSpaceErrorProgressiveResolution = this.getScreenSpaceError(
|
|
666
|
+
frameState,
|
|
667
|
+
false,
|
|
668
|
+
progressiveResolutionHeightFraction
|
|
669
|
+
);
|
|
670
|
+
this._priorityProgressiveResolution = isProgressiveResolutionPriority(
|
|
671
|
+
this._screenSpaceErrorProgressiveResolution,
|
|
672
|
+
this.parent?._screenSpaceErrorProgressiveResolution,
|
|
673
|
+
this.tileset.memoryAdjustedScreenSpaceError,
|
|
674
|
+
progressiveResolutionHeightFraction
|
|
675
|
+
);
|
|
676
|
+
|
|
677
|
+
if (
|
|
678
|
+
!options.foveatedScreenSpaceError ||
|
|
679
|
+
frameState.viewport?.orthographic ||
|
|
680
|
+
!frameState.camera?.position ||
|
|
681
|
+
!frameState.camera?.direction
|
|
682
|
+
) {
|
|
683
|
+
this._foveatedFactor = 0;
|
|
684
|
+
this.priorityDeferred = false;
|
|
685
|
+
return;
|
|
686
|
+
}
|
|
687
|
+
|
|
688
|
+
this._foveatedFactor = calculateFoveatedFactor(this.boundingVolume, frameState.camera);
|
|
689
|
+
const deferralEligible = isFoveatedRequestDeferred({
|
|
690
|
+
refinement: this.refine,
|
|
691
|
+
skipLevelOfDetail: this.tileset._traverser.options.skipLevelOfDetail,
|
|
692
|
+
foveatedScreenSpaceError: options.foveatedScreenSpaceError,
|
|
693
|
+
foveatedConeSize: options.foveatedConeSize,
|
|
694
|
+
minimumScreenSpaceErrorRelaxation: options.foveatedMinimumScreenSpaceErrorRelaxation,
|
|
695
|
+
interpolationCallback: options.foveatedInterpolationCallback,
|
|
696
|
+
foveatedFactor: this._foveatedFactor,
|
|
697
|
+
verticalFieldOfView: frameState.camera.verticalFieldOfView,
|
|
698
|
+
screenSpaceError: this._screenSpaceError,
|
|
699
|
+
parentScreenSpaceError: this.parent?._screenSpaceError,
|
|
700
|
+
maximumScreenSpaceError: this.tileset.memoryAdjustedScreenSpaceError,
|
|
701
|
+
priorityProgressiveResolution: this._priorityProgressiveResolution
|
|
702
|
+
});
|
|
703
|
+
this.priorityDeferred = isFoveatedRequestDelayActive(
|
|
704
|
+
deferralEligible,
|
|
705
|
+
frameState.camera.timeSinceMovement,
|
|
706
|
+
options.foveatedTimeDelay
|
|
707
|
+
);
|
|
708
|
+
}
|
|
709
|
+
|
|
461
710
|
// Determines whether the tile's bounding volume intersects the culling volume.
|
|
462
711
|
// @param {FrameState} frameState The frame state.
|
|
463
712
|
// @param {Number} parentVisibilityPlaneMask The parent's plane mask to speed up the visibility check.
|
|
@@ -679,6 +928,10 @@ export class Tile3D {
|
|
|
679
928
|
this._distanceToCamera = 0;
|
|
680
929
|
this._centerZDepth = 0;
|
|
681
930
|
this._screenSpaceError = 0;
|
|
931
|
+
this._screenSpaceErrorProgressiveResolution = 0;
|
|
932
|
+
this._priorityProgressiveResolution = false;
|
|
933
|
+
this._foveatedFactor = 0;
|
|
934
|
+
this.priorityDeferred = false;
|
|
682
935
|
this._visibilityPlaneMask = CullingVolume.MASK_INDETERMINATE;
|
|
683
936
|
this._visible = undefined;
|
|
684
937
|
this._inRequestVolume = false;
|
|
@@ -700,8 +953,15 @@ export class Tile3D {
|
|
|
700
953
|
return refine || (this.parent && this.parent.refine) || TILE_REFINEMENT.REPLACE;
|
|
701
954
|
}
|
|
702
955
|
|
|
703
|
-
|
|
704
|
-
|
|
956
|
+
/**
|
|
957
|
+
* Returns whether loaded content is an external tileset.
|
|
958
|
+
*
|
|
959
|
+
* Parsed shape is authoritative because valid external resources may be extensionless, signed,
|
|
960
|
+
* or use a misleading filename. This method is called only after source loading has populated
|
|
961
|
+
* `content`.
|
|
962
|
+
*/
|
|
963
|
+
_isTileset(): boolean {
|
|
964
|
+
return this.content?.shape === 'tileset3d';
|
|
705
965
|
}
|
|
706
966
|
|
|
707
967
|
_onContentLoaded() {
|
|
@@ -731,6 +991,17 @@ export class Tile3D {
|
|
|
731
991
|
this.boundingVolume
|
|
732
992
|
);
|
|
733
993
|
|
|
994
|
+
// Viewer request volumes constrain traversal, not just render content. A contentless implicit
|
|
995
|
+
// connector can still own an inherited request volume, so initialize it before the
|
|
996
|
+
// content-specific early return below.
|
|
997
|
+
if (header.viewerRequestVolume) {
|
|
998
|
+
this._viewerRequestVolume = createBoundingVolume(
|
|
999
|
+
header.viewerRequestVolume,
|
|
1000
|
+
this.computedTransform,
|
|
1001
|
+
this._viewerRequestVolume
|
|
1002
|
+
);
|
|
1003
|
+
}
|
|
1004
|
+
|
|
734
1005
|
const content = header.content;
|
|
735
1006
|
if (!content) {
|
|
736
1007
|
return;
|
|
@@ -749,13 +1020,6 @@ export class Tile3D {
|
|
|
749
1020
|
this._contentBoundingVolume
|
|
750
1021
|
);
|
|
751
1022
|
}
|
|
752
|
-
if (header.viewerRequestVolume) {
|
|
753
|
-
this._viewerRequestVolume = createBoundingVolume(
|
|
754
|
-
header.viewerRequestVolume,
|
|
755
|
-
this.computedTransform,
|
|
756
|
-
this._viewerRequestVolume
|
|
757
|
-
);
|
|
758
|
-
}
|
|
759
1023
|
}
|
|
760
1024
|
|
|
761
1025
|
/**
|