@cesium/engine 14.0.0 → 15.0.0

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 (156) hide show
  1. package/Build/Workers/{chunk-EWDGNOJE.js → chunk-25TOENEE.js} +7 -7
  2. package/Build/Workers/{chunk-OMXHEJTK.js → chunk-2AVIUB5H.js} +2 -2
  3. package/Build/Workers/{chunk-LJBJM6VI.js → chunk-3JZGPJMZ.js} +6 -6
  4. package/Build/Workers/{chunk-DT5NFR5C.js → chunk-3LHBH4TC.js} +7 -7
  5. package/Build/Workers/{chunk-3QLSKXKF.js → chunk-3LZF23RY.js} +6 -6
  6. package/Build/Workers/{chunk-ED6GLQTK.js → chunk-5S2B46UQ.js} +1 -1
  7. package/Build/Workers/{chunk-B4GSRXE3.js → chunk-67ONR44K.js} +6 -6
  8. package/Build/Workers/{chunk-LOZ4NKY3.js → chunk-6EDBC234.js} +11 -11
  9. package/Build/Workers/{chunk-7ZB2RVIQ.js → chunk-6EV4VOET.js} +10 -10
  10. package/Build/Workers/{chunk-KHWLAQVA.js → chunk-7ITUZTFH.js} +1 -1
  11. package/Build/Workers/{chunk-JHBPC4LK.js → chunk-ARVZCY6X.js} +7 -7
  12. package/Build/Workers/{chunk-FFBJDW4A.js → chunk-B2UQN3DH.js} +6 -6
  13. package/Build/Workers/{chunk-VCNOFQYH.js → chunk-B2Y4ZS6X.js} +9 -9
  14. package/Build/Workers/{chunk-Q4ZVWJXX.js → chunk-BD2TPFGC.js} +5 -5
  15. package/Build/Workers/{chunk-K4AH3TDT.js → chunk-CHX2K5AC.js} +10 -10
  16. package/Build/Workers/{chunk-3LYROPON.js → chunk-CJGVEABL.js} +13 -13
  17. package/Build/Workers/{chunk-KSYBJA4M.js → chunk-DYJHEP3B.js} +5 -5
  18. package/Build/Workers/{chunk-CI2HEJFC.js → chunk-E3H7AVMK.js} +13 -13
  19. package/Build/Workers/{chunk-F4CUH4MR.js → chunk-EZNAJPP5.js} +4 -4
  20. package/Build/Workers/{chunk-YJX7X577.js → chunk-F7ZI463G.js} +15 -15
  21. package/Build/Workers/{chunk-HEZHXDYB.js → chunk-FMZ5CX6V.js} +1 -1
  22. package/Build/Workers/{chunk-G3BVMPWG.js → chunk-FRAWHNSR.js} +2 -2
  23. package/Build/Workers/{chunk-J7IH4EYI.js → chunk-GGV2XJHE.js} +7 -7
  24. package/Build/Workers/{chunk-5KWRW7YL.js → chunk-GK4QU6QI.js} +2 -2
  25. package/Build/Workers/{chunk-77XPS7ZA.js → chunk-HYPB7FAV.js} +10 -10
  26. package/Build/Workers/{chunk-MVM4JV5U.js → chunk-I4HO2ED2.js} +9 -9
  27. package/Build/Workers/{chunk-FX4R4MTH.js → chunk-IGINOLDX.js} +6 -6
  28. package/Build/Workers/{chunk-PWF4EY5P.js → chunk-ISQSYLZY.js} +4 -4
  29. package/Build/Workers/{chunk-7UHKH6M3.js → chunk-JZAMRL5I.js} +6 -6
  30. package/Build/Workers/{chunk-HUFQVUMY.js → chunk-K5G2WELR.js} +7 -7
  31. package/Build/Workers/{chunk-5S5OOA6U.js → chunk-L5SO4Y5V.js} +1 -1
  32. package/Build/Workers/{chunk-LNSWJ43X.js → chunk-LCMJQVIF.js} +11 -11
  33. package/Build/Workers/{chunk-WVNLSTOF.js → chunk-MWJW37I7.js} +2 -2
  34. package/Build/Workers/{chunk-ZGFIT57T.js → chunk-NAGMYRDW.js} +27 -20
  35. package/Build/Workers/{chunk-SDIDRZDG.js → chunk-OYO6TKMU.js} +7 -7
  36. package/Build/Workers/{chunk-HKHQ3EDR.js → chunk-PUTA3AE2.js} +4 -4
  37. package/Build/Workers/{chunk-JPDKYBLF.js → chunk-Q5BHMNKU.js} +13 -13
  38. package/Build/Workers/{chunk-XK4OP6VA.js → chunk-QTEX3Y4V.js} +17 -17
  39. package/Build/Workers/{chunk-TVL3F7IU.js → chunk-QZKN2RXM.js} +1 -1
  40. package/Build/Workers/{chunk-Z3QWTHI7.js → chunk-RO2Z3LCR.js} +14 -14
  41. package/Build/Workers/{chunk-N2XAJBC6.js → chunk-RRN6LRDX.js} +12 -12
  42. package/Build/Workers/{chunk-FYGLNDKG.js → chunk-SLIA3GQP.js} +7 -7
  43. package/Build/Workers/{chunk-7EO56M5R.js → chunk-TFCOEX3W.js} +2 -2
  44. package/Build/Workers/{chunk-KM6MITPF.js → chunk-TU6ZXHVU.js} +5 -5
  45. package/Build/Workers/{chunk-LS3KVHYY.js → chunk-VJ2PDF64.js} +6 -6
  46. package/Build/Workers/{chunk-D7ZBZPHV.js → chunk-VMVPONIV.js} +5 -5
  47. package/Build/Workers/{chunk-3PIZQT3I.js → chunk-WPXU45PH.js} +4 -4
  48. package/Build/Workers/{chunk-WEHZP4SE.js → chunk-XDHM4G3P.js} +7 -7
  49. package/Build/Workers/{chunk-TY4DKOWR.js → chunk-XED3RXKO.js} +2 -2
  50. package/Build/Workers/{chunk-ZMNLEL6W.js → chunk-YNYCGTQH.js} +5 -5
  51. package/Build/Workers/{chunk-4CHMVQTQ.js → chunk-Z4SI54EB.js} +4 -4
  52. package/Build/Workers/{chunk-3JBEPBPL.js → chunk-ZVDLC3T4.js} +13 -13
  53. package/Build/Workers/combineGeometry.js +22 -22
  54. package/Build/Workers/createBoxGeometry.js +16 -16
  55. package/Build/Workers/createBoxOutlineGeometry.js +14 -14
  56. package/Build/Workers/createCircleGeometry.js +24 -24
  57. package/Build/Workers/createCircleOutlineGeometry.js +17 -17
  58. package/Build/Workers/createCoplanarPolygonGeometry.js +31 -31
  59. package/Build/Workers/createCoplanarPolygonOutlineGeometry.js +29 -29
  60. package/Build/Workers/createCorridorGeometry.js +27 -27
  61. package/Build/Workers/createCorridorOutlineGeometry.js +26 -26
  62. package/Build/Workers/createCylinderGeometry.js +18 -18
  63. package/Build/Workers/createCylinderOutlineGeometry.js +16 -16
  64. package/Build/Workers/createEllipseGeometry.js +24 -24
  65. package/Build/Workers/createEllipseOutlineGeometry.js +17 -17
  66. package/Build/Workers/createEllipsoidGeometry.js +17 -17
  67. package/Build/Workers/createEllipsoidOutlineGeometry.js +16 -16
  68. package/Build/Workers/createFrustumGeometry.js +16 -16
  69. package/Build/Workers/createFrustumOutlineGeometry.js +16 -16
  70. package/Build/Workers/createGeometry.js +22 -22
  71. package/Build/Workers/createGroundPolylineGeometry.js +20 -20
  72. package/Build/Workers/createPlaneGeometry.js +14 -14
  73. package/Build/Workers/createPlaneOutlineGeometry.js +13 -13
  74. package/Build/Workers/createPolygonGeometry.js +30 -30
  75. package/Build/Workers/createPolygonOutlineGeometry.js +28 -28
  76. package/Build/Workers/createPolylineGeometry.js +23 -23
  77. package/Build/Workers/createPolylineVolumeGeometry.js +29 -29
  78. package/Build/Workers/createPolylineVolumeOutlineGeometry.js +25 -25
  79. package/Build/Workers/createRectangleGeometry.js +25 -25
  80. package/Build/Workers/createRectangleOutlineGeometry.js +18 -18
  81. package/Build/Workers/createSimplePolylineGeometry.js +21 -21
  82. package/Build/Workers/createSphereGeometry.js +17 -17
  83. package/Build/Workers/createSphereOutlineGeometry.js +16 -16
  84. package/Build/Workers/createTaskProcessorWorker.js +3 -3
  85. package/Build/Workers/createVectorTileClampedPolylines.js +13 -13
  86. package/Build/Workers/createVectorTileGeometries.js +22 -22
  87. package/Build/Workers/createVectorTilePoints.js +12 -12
  88. package/Build/Workers/createVectorTilePolygons.js +20 -20
  89. package/Build/Workers/createVectorTilePolylines.js +13 -13
  90. package/Build/Workers/createVerticesFromGoogleEarthEnterpriseBuffer.js +20 -20
  91. package/Build/Workers/createVerticesFromHeightmap.js +20 -20
  92. package/Build/Workers/createVerticesFromQuantizedTerrainMesh.js +17 -17
  93. package/Build/Workers/createWallGeometry.js +22 -22
  94. package/Build/Workers/createWallOutlineGeometry.js +21 -21
  95. package/Build/Workers/decodeDraco.js +11 -11
  96. package/Build/Workers/decodeGoogleEarthEnterprisePacket.js +5 -5
  97. package/Build/Workers/decodeI3S.js +10 -10
  98. package/Build/Workers/transcodeKTX2.js +50 -43
  99. package/Build/Workers/transferTypedArrayTest.js +1 -1
  100. package/Build/Workers/upsampleQuantizedTerrainMesh.js +20 -20
  101. package/Source/Core/EllipsoidRhumbLine.js +1 -1
  102. package/Source/Core/Ion.js +1 -1
  103. package/Source/Core/PolygonGeometryLibrary.js +26 -4
  104. package/Source/Core/TexturePacker.js +166 -0
  105. package/Source/DataSources/BillboardVisualizer.js +3 -3
  106. package/Source/DataSources/EntityCluster.js +44 -19
  107. package/Source/Renderer/Context.js +0 -4
  108. package/Source/Renderer/Texture.js +6 -5
  109. package/Source/Renderer/TextureAtlas.js +802 -0
  110. package/Source/Scene/ArcGisMapService.js +1 -1
  111. package/Source/Scene/Billboard.js +86 -141
  112. package/Source/Scene/BillboardCollection.js +132 -202
  113. package/Source/Scene/BillboardLoadState.js +44 -0
  114. package/Source/Scene/BillboardTexture.js +348 -0
  115. package/Source/Scene/Camera.js +2 -2
  116. package/Source/Scene/Cesium3DTilesVoxelProvider.js +380 -126
  117. package/Source/Scene/Cesium3DTilesetStatistics.js +0 -1
  118. package/Source/Scene/Expression.js +1 -0
  119. package/Source/Scene/GltfLoader.js +5 -7
  120. package/Source/Scene/ImplicitSubtree.js +2 -0
  121. package/Source/Scene/KeyframeNode.js +16 -2
  122. package/Source/Scene/LabelCollection.js +212 -182
  123. package/Source/Scene/Megatexture.js +145 -81
  124. package/Source/Scene/Model/CustomShader.js +0 -2
  125. package/Source/Scene/Model/Model.js +1 -1
  126. package/Source/Scene/Model/ModelUtility.js +5 -1
  127. package/Source/Scene/Scene.js +39 -15
  128. package/Source/Scene/ScreenSpaceCameraController.js +0 -8
  129. package/Source/Scene/SpatialNode.js +4 -11
  130. package/Source/Scene/Vector3DTilePoints.js +2 -5
  131. package/Source/Scene/VoxelBoxShape.js +12 -5
  132. package/Source/Scene/VoxelCell.js +6 -5
  133. package/Source/Scene/VoxelContent.js +171 -107
  134. package/Source/Scene/VoxelCylinderShape.js +65 -58
  135. package/Source/Scene/VoxelEllipsoidShape.js +15 -5
  136. package/Source/Scene/VoxelMetadataOrder.js +12 -0
  137. package/Source/Scene/VoxelPrimitive.js +122 -54
  138. package/Source/Scene/VoxelProvider.js +34 -29
  139. package/Source/Scene/VoxelRenderResources.js +30 -7
  140. package/Source/Scene/VoxelShape.js +10 -3
  141. package/Source/Scene/VoxelTraversal.js +264 -180
  142. package/Source/Scene/processVoxelProperties.js +3 -0
  143. package/Source/Shaders/GlobeFS.glsl +10 -1
  144. package/Source/Shaders/GlobeFS.js +10 -1
  145. package/Source/Shaders/Voxels/Megatexture.glsl +4 -16
  146. package/Source/Shaders/Voxels/Megatexture.js +4 -16
  147. package/Source/Shaders/Voxels/Octree.glsl +44 -7
  148. package/Source/Shaders/Voxels/Octree.js +44 -7
  149. package/Source/Shaders/Voxels/VoxelFS.glsl +9 -15
  150. package/Source/Shaders/Voxels/VoxelFS.js +9 -15
  151. package/Source/Shaders/Voxels/convertUvToCylinder.glsl +15 -15
  152. package/Source/Shaders/Voxels/convertUvToCylinder.js +15 -15
  153. package/index.d.ts +176 -79
  154. package/index.js +413 -409
  155. package/package.json +2 -2
  156. package/Source/Scene/TextureAtlas.js +0 -558
@@ -1,6 +1,8 @@
1
1
  import Cartesian2 from "../Core/Cartesian2.js";
2
+ import Cartesian3 from "../Core/Cartesian3.js";
2
3
  import CesiumMath from "../Core/Math.js";
3
4
  import CullingVolume from "../Core/CullingVolume.js";
5
+ import defaultValue from "../Core/defaultValue.js";
4
6
  import defined from "../Core/defined.js";
5
7
  import destroyObject from "../Core/destroyObject.js";
6
8
  import DoubleEndedPriorityQueue from "../Core/DoubleEndedPriorityQueue.js";
@@ -15,6 +17,7 @@ import SpatialNode from "./SpatialNode.js";
15
17
  import Texture from "../Renderer/Texture.js";
16
18
  import TextureMagnificationFilter from "../Renderer/TextureMagnificationFilter.js";
17
19
  import TextureMinificationFilter from "../Renderer/TextureMinificationFilter.js";
20
+ import VoxelMetadataOrder from "./VoxelMetadataOrder.js";
18
21
 
19
22
  /**
20
23
  * Handles tileset traversal, tile requests, and GPU resources. Intended to be
@@ -23,32 +26,59 @@ import TextureMinificationFilter from "../Renderer/TextureMinificationFilter.js"
23
26
  * @alias VoxelTraversal
24
27
  * @constructor
25
28
  *
26
- * @param {VoxelPrimitive} primitive
27
- * @param {Context} context
28
- * @param {Cartesian3} dimensions
29
- * @param {MetadataType[]} types
30
- * @param {MetadataComponentType[]} componentTypes
31
- * @param {number} keyframeCount
32
- * @param {number} [maximumTextureMemoryByteLength]
29
+ * @param {VoxelPrimitive} primitive The voxel primitive for which this traversal will be used.
30
+ * @param {Context} context The context in which to create GPU resources.
31
+ * @param {number} keyframeCount The number of keyframes in the tileset.
32
+ * @param {number} [maximumTextureMemoryByteLength] The maximum amount of memory to use for textures.
33
33
  *
34
34
  * @private
35
35
  */
36
36
  function VoxelTraversal(
37
37
  primitive,
38
38
  context,
39
- dimensions,
40
- types,
41
- componentTypes,
42
39
  keyframeCount,
43
40
  maximumTextureMemoryByteLength,
44
41
  ) {
42
+ const { provider, dimensions, paddingBefore, paddingAfter } = primitive;
43
+ const { types, componentTypes, metadataOrder } = provider;
44
+
45
+ const inputDimensions = Cartesian3.add(
46
+ dimensions,
47
+ paddingBefore,
48
+ new Cartesian3(),
49
+ );
50
+ Cartesian3.add(inputDimensions, paddingAfter, inputDimensions);
51
+
52
+ if (metadataOrder === VoxelMetadataOrder.GLTF) {
53
+ const inputDimensionsY = inputDimensions.y;
54
+ inputDimensions.y = inputDimensions.z;
55
+ inputDimensions.z = inputDimensionsY;
56
+ }
57
+
58
+ if (
59
+ !defined(maximumTextureMemoryByteLength) &&
60
+ defined(provider.maximumTileCount)
61
+ ) {
62
+ maximumTextureMemoryByteLength = getApproximateTextureMemoryByteLength(
63
+ provider.maximumTileCount,
64
+ inputDimensions,
65
+ types,
66
+ componentTypes,
67
+ );
68
+ }
69
+
45
70
  /**
46
- * TODO: maybe this shouldn't be stored or passed into update function?
47
71
  * @type {VoxelPrimitive}
48
72
  * @private
49
73
  */
50
74
  this._primitive = primitive;
51
75
 
76
+ /**
77
+ * @type {number}
78
+ * @private
79
+ */
80
+ this.textureMemoryByteLength = 0;
81
+
52
82
  /**
53
83
  * @type {Megatexture[]}
54
84
  * @readonly
@@ -63,11 +93,14 @@ function VoxelTraversal(
63
93
 
64
94
  this.megatextures[i] = new Megatexture(
65
95
  context,
66
- dimensions,
96
+ inputDimensions,
67
97
  componentCount,
68
98
  componentType,
69
99
  maximumTextureMemoryByteLength,
70
100
  );
101
+
102
+ this.textureMemoryByteLength +=
103
+ this.megatextures[i].textureMemoryByteLength;
71
104
  }
72
105
 
73
106
  const maximumTileCount = this.megatextures[0].maximumTileCount;
@@ -84,6 +117,15 @@ function VoxelTraversal(
84
117
  */
85
118
  this._debugPrint = false;
86
119
 
120
+ /**
121
+ * @type {boolean}
122
+ * @private
123
+ */
124
+ this._calculateStatistics = defaultValue(
125
+ this._primitive._calculateStatistics,
126
+ false,
127
+ );
128
+
87
129
  /**
88
130
  * @type {number}
89
131
  * @private
@@ -113,6 +155,12 @@ function VoxelTraversal(
113
155
  */
114
156
  this._highPriorityKeyframeNodes = new Array(maximumTileCount);
115
157
 
158
+ /**
159
+ * @type {number}
160
+ * @private
161
+ */
162
+ this._highPriorityKeyframeNodeCount = 0;
163
+
116
164
  /**
117
165
  * @type {KeyframeNode[]}
118
166
  * @private
@@ -318,15 +366,18 @@ VoxelTraversal.prototype.update = function (
318
366
 
319
367
  this._frameNumber = frameState.frameNumber;
320
368
  const timestamp0 = getTimestamp();
321
- loadAndUnload(this, frameState);
369
+ selectKeyframeNodes(this, frameState);
370
+ updateKeyframeNodes(this, frameState);
322
371
  const timestamp1 = getTimestamp();
323
372
  generateOctree(this, sampleCount, levelBlendFactor);
324
373
  const timestamp2 = getTimestamp();
374
+
325
375
  const checkEventListeners =
326
376
  primitive.loadProgress.numberOfListeners > 0 ||
327
377
  primitive.allTilesLoaded.numberOfListeners > 0 ||
328
378
  primitive.initialTilesLoaded.numberOfListeners > 0;
329
- if (this._debugPrint || checkEventListeners) {
379
+
380
+ if (this._debugPrint || this._calculateStatistics || checkEventListeners) {
330
381
  const loadAndUnloadTimeMs = timestamp1 - timestamp0;
331
382
  const generateOctreeTimeMs = timestamp2 - timestamp1;
332
383
  const totalTimeMs = timestamp2 - timestamp0;
@@ -384,6 +435,7 @@ VoxelTraversal.prototype.destroy = function () {
384
435
  for (let i = 0; i < megatextureLength; i++) {
385
436
  megatextures[i] = megatextures[i] && megatextures[i].destroy();
386
437
  }
438
+ this.textureMemoryByteLength = 0;
387
439
 
388
440
  this.internalNodeTexture =
389
441
  this.internalNodeTexture && this.internalNodeTexture.destroy();
@@ -427,7 +479,8 @@ function requestData(that, keyframeNode) {
427
479
  return;
428
480
  }
429
481
 
430
- const provider = that._primitive._provider;
482
+ const primitive = that._primitive;
483
+ const provider = primitive.provider;
431
484
  const { keyframe, spatialNode } = keyframeNode;
432
485
  if (
433
486
  defined(provider.availableLevels) &&
@@ -436,66 +489,34 @@ function requestData(that, keyframeNode) {
436
489
  return;
437
490
  }
438
491
 
439
- const requestOptions = {
440
- tileLevel: spatialNode.level,
441
- tileX: spatialNode.x,
442
- tileY: spatialNode.y,
443
- tileZ: spatialNode.z,
444
- keyframe: keyframe,
445
- };
446
-
447
492
  function postRequestSuccess(result) {
448
493
  that._simultaneousRequestCount--;
449
- const length = provider.types.length;
450
-
451
- if (!defined(result)) {
452
- keyframeNode.state = KeyframeNode.LoadState.UNAVAILABLE;
453
- } else if (result === KeyframeNode.LoadState.FAILED) {
454
- keyframeNode.state = KeyframeNode.LoadState.FAILED;
455
- } else if (!Array.isArray(result) || result.length !== length) {
456
- // TODO should this throw runtime error?
457
- keyframeNode.state = KeyframeNode.LoadState.FAILED;
458
- } else {
459
- const megatextures = that.megatextures;
460
- for (let i = 0; i < length; i++) {
461
- const { voxelCountPerTile, channelCount } = megatextures[i];
462
- const { x, y, z } = voxelCountPerTile;
463
- const tileVoxelCount = x * y * z;
464
-
465
- const data = result[i];
466
- const expectedLength = tileVoxelCount * channelCount;
467
- if (data.length === expectedLength) {
468
- keyframeNode.metadata[i] = data;
469
- // State is received only when all metadata requests have been received
470
- keyframeNode.state = KeyframeNode.LoadState.RECEIVED;
471
- that._primitive.tileLoad.raiseEvent();
472
- } else {
473
- keyframeNode.state = KeyframeNode.LoadState.FAILED;
474
- break;
475
- }
476
- }
477
- }
478
- if (keyframeNode.state === KeyframeNode.LoadState.FAILED) {
479
- that._primitive.tileFailed.raiseEvent();
480
- }
494
+ keyframeNode.content = result;
495
+ keyframeNode.state = defined(result)
496
+ ? KeyframeNode.LoadState.PROCESSING
497
+ : KeyframeNode.LoadState.UNAVAILABLE;
481
498
  }
482
499
 
483
- function postRequestFailure() {
500
+ function postRequestFailure(error) {
484
501
  that._simultaneousRequestCount--;
485
502
  keyframeNode.state = KeyframeNode.LoadState.FAILED;
486
503
  that._primitive.tileFailed.raiseEvent();
487
504
  }
488
505
 
489
- const promise = provider.requestData(requestOptions);
490
-
491
- if (defined(promise)) {
492
- that._simultaneousRequestCount++;
493
- keyframeNode.state = KeyframeNode.LoadState.RECEIVING;
494
- promise.then(postRequestSuccess).catch(postRequestFailure);
495
- } else {
496
- keyframeNode.state = KeyframeNode.LoadState.FAILED;
497
- that._primitive.tileFailed.raiseEvent();
506
+ const requestParameters = {
507
+ tileLevel: spatialNode.level,
508
+ tileX: spatialNode.x,
509
+ tileY: spatialNode.y,
510
+ tileZ: spatialNode.z,
511
+ keyframe: keyframe,
512
+ };
513
+ const promise = provider.requestData(requestParameters);
514
+ if (!defined(promise)) {
515
+ return;
498
516
  }
517
+ that._simultaneousRequestCount++;
518
+ keyframeNode.state = KeyframeNode.LoadState.RECEIVING;
519
+ promise.then(postRequestSuccess).catch(postRequestFailure);
499
520
  }
500
521
 
501
522
  /**
@@ -511,105 +532,23 @@ function mapInfiniteRangeToZeroOne(x) {
511
532
  }
512
533
 
513
534
  /**
514
- * @function
515
- *
516
535
  * @param {VoxelTraversal} that
517
536
  * @param {FrameState} frameState
518
537
  *
519
538
  * @private
520
539
  */
521
- function loadAndUnload(that, frameState) {
540
+ function selectKeyframeNodes(that, frameState) {
522
541
  const frameNumber = that._frameNumber;
523
- const primitive = that._primitive;
524
- const shape = primitive._shape;
525
- const targetScreenSpaceError = primitive.screenSpaceError;
526
542
  const priorityQueue = that._priorityQueue;
527
- const keyframeCount = that._keyframeCount;
528
-
529
- const previousKeyframe = CesiumMath.clamp(
530
- Math.floor(that._keyframeLocation),
531
- 0,
532
- keyframeCount - 2,
533
- );
534
- const nextKeyframe = previousKeyframe + 1;
535
-
536
- const { camera, context, pixelRatio } = frameState;
537
- const { positionWC, frustum } = camera;
538
- const screenHeight = context.drawingBufferHeight / pixelRatio;
539
- const screenSpaceErrorMultiplier = screenHeight / frustum.sseDenominator;
540
-
541
- /**
542
- * @ignore
543
- * @param {SpatialNode} spatialNode
544
- * @param {number} visibilityPlaneMask
545
- */
546
- function addToQueueRecursive(spatialNode, visibilityPlaneMask) {
547
- spatialNode.computeScreenSpaceError(positionWC, screenSpaceErrorMultiplier);
548
-
549
- visibilityPlaneMask = spatialNode.visibility(
550
- frameState,
551
- visibilityPlaneMask,
552
- );
553
- if (visibilityPlaneMask === CullingVolume.MASK_OUTSIDE) {
554
- return;
555
- }
556
- spatialNode.visitedFrameNumber = frameNumber;
557
-
558
- // Create keyframe nodes at the playhead.
559
- // If they already exist, nothing will be created.
560
- if (keyframeCount === 1) {
561
- spatialNode.createKeyframeNode(0);
562
- } else if (spatialNode.keyframeNodes.length !== keyframeCount) {
563
- for (let k = 0; k < keyframeCount; k++) {
564
- spatialNode.createKeyframeNode(k);
565
- }
566
- }
567
- const { screenSpaceError, keyframeNodes } = spatialNode;
568
- const ssePriority = mapInfiniteRangeToZeroOne(screenSpaceError);
569
-
570
- let hasLoadedKeyframe = false;
571
- for (let i = 0; i < keyframeNodes.length; i++) {
572
- const keyframeNode = keyframeNodes[i];
573
-
574
- keyframeNode.priority =
575
- 10.0 * ssePriority +
576
- keyframePriority(
577
- previousKeyframe,
578
- keyframeNode.keyframe,
579
- nextKeyframe,
580
- that,
581
- );
582
-
583
- if (
584
- keyframeNode.state !== KeyframeNode.LoadState.UNAVAILABLE &&
585
- keyframeNode.state !== KeyframeNode.LoadState.FAILED &&
586
- keyframeNode.priority !== -Number.MAX_VALUE
587
- ) {
588
- priorityQueue.insert(keyframeNode);
589
- }
590
- if (keyframeNode.state === KeyframeNode.LoadState.LOADED) {
591
- hasLoadedKeyframe = true;
592
- }
593
- }
594
-
595
- if (screenSpaceError < targetScreenSpaceError || !hasLoadedKeyframe) {
596
- // Free up memory
597
- spatialNode.children = undefined;
598
- return;
599
- }
600
-
601
- if (!defined(spatialNode.children)) {
602
- spatialNode.constructChildNodes(shape);
603
- }
604
- for (let childIndex = 0; childIndex < 8; childIndex++) {
605
- const child = spatialNode.children[childIndex];
606
- addToQueueRecursive(child, visibilityPlaneMask);
607
- }
608
- }
609
543
 
610
544
  // Add all the nodes to the queue, to sort them by priority.
611
545
  priorityQueue.reset();
612
- addToQueueRecursive(that.rootNode, CullingVolume.MASK_INDETERMINATE);
546
+ addToQueueRecursive(
547
+ that.rootNode,
548
+ CullingVolume.MASK_INDETERMINATE,
549
+ that,
550
+ frameState,
551
+ );
613
552
 
614
553
  // Move the nodes from the queue to array of high priority nodes.
615
554
  const highPriorityKeyframeNodes = that._highPriorityKeyframeNodes;
@@ -622,23 +561,29 @@ function loadAndUnload(that, frameState) {
622
561
  highPriorityKeyframeNode;
623
562
  highPriorityKeyframeNodeCount++;
624
563
  }
564
+ that._highPriorityKeyframeNodeCount = highPriorityKeyframeNodeCount;
565
+ }
566
+
567
+ /**
568
+ * @param {VoxelTraversal} that
569
+ * @param {FrameState} frameState
570
+ *
571
+ * @private
572
+ */
573
+ function updateKeyframeNodes(that, frameState) {
574
+ const megatexture = that.megatextures[0];
575
+ const keyframeNodesInMegatextureCount = megatexture.occupiedCount;
625
576
 
626
577
  // Sort the list of keyframe nodes in the megatexture by priority, so
627
578
  // we can remove the lowest priority nodes if we need space.
628
579
  const keyframeNodesInMegatexture = that._keyframeNodesInMegatexture;
629
- // TODO: some of the megatexture state should be stored once, not duplicate for each megatexture
630
- const megatexture = that.megatextures[0];
631
- const keyframeNodesInMegatextureCount = megatexture.occupiedCount;
632
580
  keyframeNodesInMegatexture.length = keyframeNodesInMegatextureCount;
633
- keyframeNodesInMegatexture.sort(function (a, b) {
634
- if (a.highPriorityFrameNumber === b.highPriorityFrameNumber) {
635
- return b.priority - a.priority;
636
- }
637
- return b.highPriorityFrameNumber - a.highPriorityFrameNumber;
638
- });
581
+ keyframeNodesInMegatexture.sort(keyframeNodeSort);
639
582
 
640
583
  // Add the high priority nodes to the megatexture,
641
584
  // removing existing lower-priority nodes if necessary.
585
+ const highPriorityKeyframeNodes = that._highPriorityKeyframeNodes;
586
+ const highPriorityKeyframeNodeCount = that._highPriorityKeyframeNodeCount;
642
587
  let destroyedCount = 0;
643
588
  let addedCount = 0;
644
589
 
@@ -647,7 +592,7 @@ function loadAndUnload(that, frameState) {
647
592
  highPriorityKeyframeNodeIndex < highPriorityKeyframeNodeCount;
648
593
  highPriorityKeyframeNodeIndex++
649
594
  ) {
650
- highPriorityKeyframeNode =
595
+ const highPriorityKeyframeNode =
651
596
  highPriorityKeyframeNodes[highPriorityKeyframeNodeIndex];
652
597
 
653
598
  if (
@@ -661,7 +606,18 @@ function loadAndUnload(that, frameState) {
661
606
  if (highPriorityKeyframeNode.state === KeyframeNode.LoadState.UNLOADED) {
662
607
  requestData(that, highPriorityKeyframeNode);
663
608
  }
664
- if (highPriorityKeyframeNode.state === KeyframeNode.LoadState.RECEIVED) {
609
+ if (highPriorityKeyframeNode.state === KeyframeNode.LoadState.PROCESSING) {
610
+ const { content } = highPriorityKeyframeNode;
611
+ content.update(that._primitive, frameState);
612
+ if (!content.ready) {
613
+ continue;
614
+ }
615
+ if (!validateMetadata(content.metadata, that)) {
616
+ highPriorityKeyframeNode.content = undefined;
617
+ highPriorityKeyframeNode.state = KeyframeNode.LoadState.FAILED;
618
+ that._primitive.tileFailed.raiseEvent();
619
+ continue;
620
+ }
665
621
  let addNodeIndex = 0;
666
622
  if (megatexture.isFull()) {
667
623
  // If the megatexture is full, try removing a discardable node with the lowest priority.
@@ -682,11 +638,140 @@ function loadAndUnload(that, frameState) {
682
638
  highPriorityKeyframeNode,
683
639
  that.megatextures,
684
640
  );
641
+ highPriorityKeyframeNode.state = KeyframeNode.LoadState.LOADED;
685
642
  keyframeNodesInMegatexture[addNodeIndex] = highPriorityKeyframeNode;
643
+ that._primitive.tileLoad.raiseEvent();
686
644
  }
687
645
  }
688
646
  }
689
647
 
648
+ function keyframeNodeSort(a, b) {
649
+ if (a.highPriorityFrameNumber === b.highPriorityFrameNumber) {
650
+ return b.priority - a.priority;
651
+ }
652
+ return b.highPriorityFrameNumber - a.highPriorityFrameNumber;
653
+ }
654
+
655
+ /**
656
+ * Check if an array of metadata is of the expected type and size
657
+ *
658
+ * @param {TypedArray[]} metadata The metadata to validate
659
+ * @param {VoxelTraversal} traversal The traversal to validate against
660
+ * @returns {boolean} <code>true</code> if the metadata is valid, <code>false</code> otherwise
661
+ *
662
+ * @private
663
+ */
664
+ function validateMetadata(metadata, traversal) {
665
+ const length = traversal._primitive.provider.types.length;
666
+ if (!Array.isArray(metadata) || metadata.length !== length) {
667
+ return false;
668
+ }
669
+ const { megatextures } = traversal;
670
+ for (let i = 0; i < length; i++) {
671
+ const { voxelCountPerTile, channelCount } = megatextures[i];
672
+ const { x, y, z } = voxelCountPerTile;
673
+ const tileVoxelCount = x * y * z;
674
+
675
+ const data = metadata[i];
676
+ const expectedLength = tileVoxelCount * channelCount;
677
+ if (data.length !== expectedLength) {
678
+ return false;
679
+ }
680
+ }
681
+ return true;
682
+ }
683
+
684
+ /**
685
+ * @param {SpatialNode} spatialNode
686
+ * @param {number} visibilityPlaneMask
687
+ * @param {VoxelTraversal} that
688
+ * @param {FrameState} frameState
689
+ *
690
+ * @private
691
+ */
692
+ function addToQueueRecursive(
693
+ spatialNode,
694
+ visibilityPlaneMask,
695
+ that,
696
+ frameState,
697
+ ) {
698
+ const { camera, context, pixelRatio, frameNumber } = frameState;
699
+ const { positionWC, frustum } = camera;
700
+ const screenHeight = context.drawingBufferHeight / pixelRatio;
701
+ const screenSpaceErrorMultiplier = screenHeight / frustum.sseDenominator;
702
+
703
+ spatialNode.computeScreenSpaceError(positionWC, screenSpaceErrorMultiplier);
704
+
705
+ visibilityPlaneMask = spatialNode.visibility(frameState, visibilityPlaneMask);
706
+ if (visibilityPlaneMask === CullingVolume.MASK_OUTSIDE) {
707
+ return;
708
+ }
709
+ spatialNode.visitedFrameNumber = frameNumber;
710
+
711
+ const primitive = that._primitive;
712
+ const shape = primitive._shape;
713
+ const targetScreenSpaceError = primitive.screenSpaceError;
714
+ const priorityQueue = that._priorityQueue;
715
+ const keyframeCount = that._keyframeCount;
716
+ const previousKeyframe = CesiumMath.clamp(
717
+ Math.floor(that._keyframeLocation),
718
+ 0,
719
+ keyframeCount - 2,
720
+ );
721
+ const nextKeyframe = previousKeyframe + 1;
722
+
723
+ // Create keyframe nodes at the playhead.
724
+ // If they already exist, nothing will be created.
725
+ if (keyframeCount === 1) {
726
+ spatialNode.createKeyframeNode(0);
727
+ } else if (spatialNode.keyframeNodes.length !== keyframeCount) {
728
+ for (let k = 0; k < keyframeCount; k++) {
729
+ spatialNode.createKeyframeNode(k);
730
+ }
731
+ }
732
+ const { screenSpaceError, keyframeNodes } = spatialNode;
733
+ const ssePriority = mapInfiniteRangeToZeroOne(screenSpaceError);
734
+
735
+ let hasLoadedKeyframe = false;
736
+ for (let i = 0; i < keyframeNodes.length; i++) {
737
+ const keyframeNode = keyframeNodes[i];
738
+
739
+ keyframeNode.priority =
740
+ 10.0 * ssePriority +
741
+ keyframePriority(
742
+ previousKeyframe,
743
+ keyframeNode.keyframe,
744
+ nextKeyframe,
745
+ that,
746
+ );
747
+
748
+ if (
749
+ keyframeNode.state !== KeyframeNode.LoadState.UNAVAILABLE &&
750
+ keyframeNode.state !== KeyframeNode.LoadState.FAILED &&
751
+ keyframeNode.priority !== -Number.MAX_VALUE
752
+ ) {
753
+ priorityQueue.insert(keyframeNode);
754
+ }
755
+ if (keyframeNode.state === KeyframeNode.LoadState.LOADED) {
756
+ hasLoadedKeyframe = true;
757
+ }
758
+ }
759
+
760
+ if (screenSpaceError < targetScreenSpaceError || !hasLoadedKeyframe) {
761
+ // Free up memory
762
+ spatialNode.children = undefined;
763
+ return;
764
+ }
765
+
766
+ if (!defined(spatialNode.children)) {
767
+ spatialNode.constructChildNodes(shape);
768
+ }
769
+ for (let childIndex = 0; childIndex < 8; childIndex++) {
770
+ const child = spatialNode.children[childIndex];
771
+ addToQueueRecursive(child, visibilityPlaneMask, that, frameState);
772
+ }
773
+ }
774
+
690
775
  /**
691
776
  * Compute a priority for a keyframe node.
692
777
  *
@@ -748,16 +833,12 @@ function postPassesUpdate(
748
833
  loadStateIndex < loadStateCount;
749
834
  loadStateIndex++
750
835
  ) {
751
- const keyframeArray = new Array(keyframeCount);
836
+ const keyframeArray = new Array(keyframeCount).fill(0);
752
837
  loadStatesByKeyframe[loadStateIndex] = keyframeArray;
753
- for (let i = 0; i < keyframeCount; i++) {
754
- keyframeArray[i] = 0;
755
- }
756
838
  loadStateByCount[loadStateIndex] = 0;
757
839
  }
758
840
 
759
841
  /**
760
- * @ignore
761
842
  * @param {SpatialNode} node
762
843
  */
763
844
  function traverseRecursive(node) {
@@ -784,16 +865,20 @@ function postPassesUpdate(
784
865
  }
785
866
  traverseRecursive(rootNode);
786
867
 
868
+ that._primitive.statistics.numberOfTilesWithContentReady =
869
+ loadStateByCount[KeyframeNode.LoadState.LOADED];
870
+ that._primitive.statistics.visited = nodeCountTotal;
871
+
787
872
  const numberOfPendingRequests =
788
873
  loadStateByCount[KeyframeNode.LoadState.RECEIVING];
789
874
  const numberOfTilesProcessing =
790
- loadStateByCount[KeyframeNode.LoadState.RECEIVED];
875
+ loadStateByCount[KeyframeNode.LoadState.PROCESSING];
791
876
 
792
877
  const progressChanged =
793
878
  numberOfPendingRequests !==
794
- that._primitive._statistics.numberOfPendingRequests ||
879
+ that._primitive.statistics.numberOfPendingRequests ||
795
880
  numberOfTilesProcessing !==
796
- that._primitive._statistics.numberOfTilesProcessing;
881
+ that._primitive.statistics.numberOfTilesProcessing;
797
882
 
798
883
  if (progressChanged) {
799
884
  frameState.afterRender.push(function () {
@@ -806,8 +891,8 @@ function postPassesUpdate(
806
891
  });
807
892
  }
808
893
 
809
- that._primitive._statistics.numberOfPendingRequests = numberOfPendingRequests;
810
- that._primitive._statistics.numberOfTilesProcessing = numberOfTilesProcessing;
894
+ that._primitive.statistics.numberOfPendingRequests = numberOfPendingRequests;
895
+ that._primitive.statistics.numberOfTilesProcessing = numberOfTilesProcessing;
811
896
 
812
897
  const tilesLoaded =
813
898
  numberOfPendingRequests === 0 && numberOfTilesProcessing === 0;
@@ -839,7 +924,7 @@ function postPassesUpdate(
839
924
  const loadStateStatistics =
840
925
  `UNLOADED: ${loadStateByCount[KeyframeNode.LoadState.UNLOADED]} | ` +
841
926
  `RECEIVING: ${loadStateByCount[KeyframeNode.LoadState.RECEIVING]} | ` +
842
- `RECEIVED: ${loadStateByCount[KeyframeNode.LoadState.RECEIVED]} | ` +
927
+ `PROCESSING: ${loadStateByCount[KeyframeNode.LoadState.PROCESSING]} | ` +
843
928
  `LOADED: ${loadStateByCount[KeyframeNode.LoadState.LOADED]} | ` +
844
929
  `FAILED: ${loadStateByCount[KeyframeNode.LoadState.FAILED]} | ` +
845
930
  `UNAVAILABLE: ${loadStateByCount[KeyframeNode.LoadState.UNAVAILABLE]} | ` +
@@ -900,7 +985,6 @@ const GpuOctreeFlag = {
900
985
  * @function
901
986
  *
902
987
  * @param {VoxelTraversal} that
903
- * @param {FrameState} frameState
904
988
  * @param {number} sampleCount
905
989
  * @param {number} levelBlendFactor
906
990
  * @private
@@ -917,7 +1001,6 @@ function generateOctree(that, sampleCount, levelBlendFactor) {
917
1001
  const leafNodeOctreeData = [];
918
1002
 
919
1003
  /**
920
- * @ignore
921
1004
  * @param {SpatialNode} node
922
1005
  * @param {number} childOctreeIndex
923
1006
  * @param {number} childEntryIndex
@@ -1154,8 +1237,9 @@ function copyToLeafNodeTexture(data, texelsPerTile, tilesPerRow, texture) {
1154
1237
  * @param {Cartesian3} dimensions
1155
1238
  * @param {MetadataType[]} types
1156
1239
  * @param {MetadataComponentType[]} componentTypes
1240
+ * @private
1157
1241
  */
1158
- VoxelTraversal.getApproximateTextureMemoryByteLength = function (
1242
+ function getApproximateTextureMemoryByteLength(
1159
1243
  tileCount,
1160
1244
  dimensions,
1161
1245
  types,
@@ -1179,6 +1263,6 @@ VoxelTraversal.getApproximateTextureMemoryByteLength = function (
1179
1263
  }
1180
1264
 
1181
1265
  return textureMemoryByteLength;
1182
- };
1266
+ }
1183
1267
 
1184
1268
  export default VoxelTraversal;
@@ -310,6 +310,9 @@ function processVoxelProperties(renderResources, primitive) {
310
310
  const glslField = getGlslField(type, j);
311
311
  const minimumValue = minimumValues[i][j];
312
312
  const maximumValue = maximumValues[i][j];
313
+ if (!defined(minimumValue) || !defined(maximumValue)) {
314
+ continue;
315
+ }
313
316
  shaderBuilder.addFunctionLines(functionId, [
314
317
  `${statisticsFieldName}.${name}.min${glslField} = ${getGlslNumberAsFloat(
315
318
  minimumValue,
@@ -285,7 +285,16 @@ vec3 computeEllipsoidPosition()
285
285
  vec2 xy = gl_FragCoord.xy / czm_viewport.zw * 2.0 - vec2(1.0);
286
286
  xy *= czm_viewport.zw * mpp * 0.5;
287
287
 
288
- vec3 direction = normalize(vec3(xy, -czm_currentFrustum.x));
288
+ vec3 direction;
289
+ if (czm_orthographicIn3D == 1.0)
290
+ {
291
+ direction = vec3(0.0, 0.0, -1.0);
292
+ }
293
+ else
294
+ {
295
+ direction = normalize(vec3(xy, -czm_currentFrustum.x));
296
+ }
297
+
289
298
  czm_ray ray = czm_ray(vec3(0.0), direction);
290
299
 
291
300
  vec3 ellipsoid_center = czm_view[3].xyz;