@cesium/engine 2.1.0 → 2.2.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 (193) hide show
  1. package/Build/Workers/{AxisAlignedBoundingBox-a6f9f0e5.js → AxisAlignedBoundingBox-379015ef.js} +1 -1
  2. package/Build/Workers/{BoundingRectangle-b0a68595.js → BoundingRectangle-57f2b24f.js} +1 -1
  3. package/Build/Workers/{BoxGeometry-baedd794.js → BoxGeometry-ecabfc78.js} +1 -1
  4. package/Build/Workers/{Color-f85df1be.js → Color-14d1a36d.js} +1 -1
  5. package/Build/Workers/{CoplanarPolygonGeometryLibrary-30516950.js → CoplanarPolygonGeometryLibrary-048c3c14.js} +1 -1
  6. package/Build/Workers/{CorridorGeometryLibrary-5d5d3b3a.js → CorridorGeometryLibrary-520c8619.js} +1 -1
  7. package/Build/Workers/{CylinderGeometry-d899ae26.js → CylinderGeometry-119068b8.js} +1 -1
  8. package/Build/Workers/{EllipseGeometry-a49f8449.js → EllipseGeometry-2dfc3523.js} +1 -1
  9. package/Build/Workers/{EllipseGeometryLibrary-cba7edde.js → EllipseGeometryLibrary-0a1e0170.js} +1 -1
  10. package/Build/Workers/{EllipseOutlineGeometry-8095c8cb.js → EllipseOutlineGeometry-c5251669.js} +1 -1
  11. package/Build/Workers/{EllipsoidGeometry-ed93f571.js → EllipsoidGeometry-d10a5221.js} +1 -1
  12. package/Build/Workers/{EllipsoidOutlineGeometry-e4854854.js → EllipsoidOutlineGeometry-7039a0ae.js} +1 -1
  13. package/Build/Workers/{EllipsoidTangentPlane-7ae1aa9a.js → EllipsoidTangentPlane-857186be.js} +1 -1
  14. package/Build/Workers/{FrustumGeometry-b62db3e3.js → FrustumGeometry-400fa1b7.js} +2 -2
  15. package/Build/Workers/{GeometryAttribute-780af4fa.js → GeometryAttribute-7a2de5c6.js} +1 -1
  16. package/Build/Workers/{GeometryPipeline-36b61c99.js → GeometryPipeline-916636fa.js} +1 -1
  17. package/Build/Workers/{IntersectionTests-e889fcf0.js → IntersectionTests-b4d02d4d.js} +1 -1
  18. package/Build/Workers/{OrientedBoundingBox-43478ac8.js → OrientedBoundingBox-96fe1752.js} +5 -3
  19. package/Build/Workers/{PolygonGeometryLibrary-38a98276.js → PolygonGeometryLibrary-931f1ec6.js} +1 -1
  20. package/Build/Workers/{PolygonPipeline-d31ff61c.js → PolygonPipeline-32fc92cc.js} +1 -1
  21. package/Build/Workers/{PolylinePipeline-30e4cec9.js → PolylinePipeline-6d5c63e5.js} +1 -1
  22. package/Build/Workers/{PolylineVolumeGeometryLibrary-90551d26.js → PolylineVolumeGeometryLibrary-f068c1fb.js} +1 -1
  23. package/Build/Workers/{PrimitivePipeline-558d9cb0.js → PrimitivePipeline-879f996a.js} +1 -1
  24. package/Build/Workers/{RectangleGeometryLibrary-815c68df.js → RectangleGeometryLibrary-2d6f36f3.js} +1 -1
  25. package/Build/Workers/{TerrainEncoding-341ead52.js → TerrainEncoding-82882059.js} +1 -1
  26. package/Build/Workers/{Transforms-9e9df299.js → Transforms-9052372a.js} +6 -5
  27. package/Build/Workers/{WallGeometryLibrary-ccf90976.js → WallGeometryLibrary-db7a64fb.js} +1 -1
  28. package/Build/Workers/cesiumWorkerBootstrapper.js +1 -1
  29. package/Build/Workers/combineGeometry.js +1 -1
  30. package/Build/Workers/createBoxGeometry.js +1 -1
  31. package/Build/Workers/createBoxOutlineGeometry.js +1 -1
  32. package/Build/Workers/createCircleGeometry.js +1 -1
  33. package/Build/Workers/createCircleOutlineGeometry.js +1 -1
  34. package/Build/Workers/createCoplanarPolygonGeometry.js +1 -1
  35. package/Build/Workers/createCoplanarPolygonOutlineGeometry.js +1 -1
  36. package/Build/Workers/createCorridorGeometry.js +1 -1
  37. package/Build/Workers/createCorridorOutlineGeometry.js +1 -1
  38. package/Build/Workers/createCylinderGeometry.js +1 -1
  39. package/Build/Workers/createCylinderOutlineGeometry.js +1 -1
  40. package/Build/Workers/createEllipseGeometry.js +1 -1
  41. package/Build/Workers/createEllipseOutlineGeometry.js +1 -1
  42. package/Build/Workers/createEllipsoidGeometry.js +1 -1
  43. package/Build/Workers/createEllipsoidOutlineGeometry.js +1 -1
  44. package/Build/Workers/createFrustumGeometry.js +1 -1
  45. package/Build/Workers/createFrustumOutlineGeometry.js +1 -1
  46. package/Build/Workers/createGeometry.js +1 -1
  47. package/Build/Workers/createGroundPolylineGeometry.js +1 -1
  48. package/Build/Workers/createPlaneGeometry.js +1 -1
  49. package/Build/Workers/createPlaneOutlineGeometry.js +1 -1
  50. package/Build/Workers/createPolygonGeometry.js +1 -1
  51. package/Build/Workers/createPolygonOutlineGeometry.js +1 -1
  52. package/Build/Workers/createPolylineGeometry.js +1 -1
  53. package/Build/Workers/createPolylineVolumeGeometry.js +1 -1
  54. package/Build/Workers/createPolylineVolumeOutlineGeometry.js +1 -1
  55. package/Build/Workers/createRectangleGeometry.js +1 -1
  56. package/Build/Workers/createRectangleOutlineGeometry.js +1 -1
  57. package/Build/Workers/createSimplePolylineGeometry.js +1 -1
  58. package/Build/Workers/createSphereGeometry.js +1 -1
  59. package/Build/Workers/createSphereOutlineGeometry.js +1 -1
  60. package/Build/Workers/createVectorTileGeometries.js +1 -1
  61. package/Build/Workers/createVectorTilePolygons.js +1 -1
  62. package/Build/Workers/createVerticesFromGoogleEarthEnterpriseBuffer.js +1 -1
  63. package/Build/Workers/createVerticesFromHeightmap.js +1 -1
  64. package/Build/Workers/createVerticesFromQuantizedTerrainMesh.js +10 -15
  65. package/Build/Workers/createWallGeometry.js +1 -1
  66. package/Build/Workers/createWallOutlineGeometry.js +1 -1
  67. package/Build/Workers/package.js +1 -1
  68. package/Build/Workers/transferTypedArrayTest.js +1 -1
  69. package/Build/Workers/upsampleQuantizedTerrainMesh.js +1 -1
  70. package/Source/Core/ArcGISTiledElevationTerrainProvider.js +291 -191
  71. package/Source/Core/CesiumTerrainProvider.js +571 -434
  72. package/Source/Core/CustomHeightmapTerrainProvider.js +12 -0
  73. package/Source/Core/EllipsoidTerrainProvider.js +17 -10
  74. package/Source/Core/FrustumGeometry.js +1 -1
  75. package/Source/Core/GoogleEarthEnterpriseMetadata.js +86 -34
  76. package/Source/Core/GoogleEarthEnterpriseTerrainProvider.js +119 -82
  77. package/Source/Core/Ion.js +1 -1
  78. package/Source/Core/IonResource.js +14 -3
  79. package/Source/Core/OrientedBoundingBox.js +4 -2
  80. package/Source/Core/RequestScheduler.js +1 -1
  81. package/Source/Core/Resource.js +2 -2
  82. package/Source/Core/TerrainProvider.js +9 -14
  83. package/Source/Core/TileProviderError.js +8 -8
  84. package/Source/Core/VRTheWorldTerrainProvider.js +193 -124
  85. package/Source/Core/buildModuleUrl.js +4 -3
  86. package/Source/Core/createWorldTerrain.js +20 -2
  87. package/Source/Core/createWorldTerrainAsync.js +48 -0
  88. package/Source/Core/sampleTerrain.js +9 -10
  89. package/Source/Core/sampleTerrainMostDetailed.js +66 -72
  90. package/Source/DataSources/Cesium3DTilesetVisualizer.js +37 -26
  91. package/Source/DataSources/Entity.js +6 -1
  92. package/Source/DataSources/ModelVisualizer.js +99 -31
  93. package/Source/DataSources/PolygonGraphics.js +1 -1
  94. package/Source/Scene/ArcGisMapServerImageryProvider.js +552 -376
  95. package/Source/Scene/BingMapsImageryProvider.js +511 -305
  96. package/Source/Scene/BufferLoader.js +29 -34
  97. package/Source/Scene/Cesium3DTile.js +388 -251
  98. package/Source/Scene/Cesium3DTileBatchTable.js +2 -2
  99. package/Source/Scene/Cesium3DTileContent.js +16 -0
  100. package/Source/Scene/Cesium3DTileContentFactory.js +4 -4
  101. package/Source/Scene/Cesium3DTilePass.js +8 -11
  102. package/Source/Scene/Cesium3DTileStyleEngine.js +1 -1
  103. package/Source/Scene/Cesium3DTilesVoxelProvider.js +225 -117
  104. package/Source/Scene/Cesium3DTileset.js +755 -481
  105. package/Source/Scene/Cesium3DTilesetBaseTraversal.js +301 -0
  106. package/Source/Scene/Cesium3DTilesetMostDetailedTraversal.js +33 -46
  107. package/Source/Scene/Cesium3DTilesetSkipTraversal.js +421 -0
  108. package/Source/Scene/Cesium3DTilesetTraversal.js +219 -671
  109. package/Source/Scene/ClassificationPrimitive.js +7 -0
  110. package/Source/Scene/Composite3DTileContent.js +69 -26
  111. package/Source/Scene/CreditDisplay.js +20 -4
  112. package/Source/Scene/DepthPlane.js +1 -1
  113. package/Source/Scene/Empty3DTileContent.js +31 -1
  114. package/Source/Scene/Geometry3DTileContent.js +47 -7
  115. package/Source/Scene/Globe.js +5 -1
  116. package/Source/Scene/GlobeSurfaceTile.js +2 -1
  117. package/Source/Scene/GlobeSurfaceTileProvider.js +50 -27
  118. package/Source/Scene/GltfBufferViewLoader.js +47 -91
  119. package/Source/Scene/GltfDracoLoader.js +110 -112
  120. package/Source/Scene/GltfImageLoader.js +71 -78
  121. package/Source/Scene/GltfIndexBufferLoader.js +108 -121
  122. package/Source/Scene/GltfJsonLoader.js +75 -74
  123. package/Source/Scene/GltfLoader.js +392 -280
  124. package/Source/Scene/GltfStructuralMetadataLoader.js +109 -110
  125. package/Source/Scene/GltfTextureLoader.js +97 -96
  126. package/Source/Scene/GltfVertexBufferLoader.js +128 -133
  127. package/Source/Scene/GoogleEarthEnterpriseImageryProvider.js +353 -225
  128. package/Source/Scene/GoogleEarthEnterpriseMapsProvider.js +491 -331
  129. package/Source/Scene/GridImageryProvider.js +267 -104
  130. package/Source/Scene/GroundPolylinePrimitive.js +12 -1
  131. package/Source/Scene/GroundPrimitive.js +8 -1
  132. package/Source/Scene/I3SDataProvider.js +214 -113
  133. package/Source/Scene/I3SFeature.js +7 -6
  134. package/Source/Scene/I3SLayer.js +26 -37
  135. package/Source/Scene/I3SNode.js +59 -66
  136. package/Source/Scene/Imagery.js +6 -1
  137. package/Source/Scene/ImageryLayer.js +299 -48
  138. package/Source/Scene/ImageryLayerCollection.js +26 -0
  139. package/Source/Scene/ImageryProvider.js +129 -111
  140. package/Source/Scene/Implicit3DTileContent.js +72 -23
  141. package/Source/Scene/ImplicitSubtree.js +66 -45
  142. package/Source/Scene/IonImageryProvider.js +471 -264
  143. package/Source/Scene/MapboxImageryProvider.js +272 -112
  144. package/Source/Scene/MapboxStyleImageryProvider.js +270 -111
  145. package/Source/Scene/MetadataSchemaLoader.js +26 -36
  146. package/Source/Scene/Model/B3dmLoader.js +42 -46
  147. package/Source/Scene/Model/GeoJsonLoader.js +8 -32
  148. package/Source/Scene/Model/I3dmLoader.js +48 -74
  149. package/Source/Scene/Model/Model.js +470 -132
  150. package/Source/Scene/Model/Model3DTileContent.js +83 -31
  151. package/Source/Scene/Model/ModelAnimationCollection.js +3 -3
  152. package/Source/Scene/Model/ModelDrawCommand.js +15 -26
  153. package/Source/Scene/Model/ModelUtility.js +16 -16
  154. package/Source/Scene/Model/PntsLoader.js +27 -32
  155. package/Source/Scene/Multiple3DTileContent.js +134 -115
  156. package/Source/Scene/PointCloud.js +11 -19
  157. package/Source/Scene/Primitive.js +20 -0
  158. package/Source/Scene/QuadtreePrimitive.js +2 -0
  159. package/Source/Scene/QuadtreeTileProvider.js +4 -8
  160. package/Source/Scene/ResourceCache.js +47 -105
  161. package/Source/Scene/ResourceCacheStatistics.js +24 -58
  162. package/Source/Scene/ResourceLoader.js +5 -17
  163. package/Source/Scene/ResourceLoaderState.js +12 -4
  164. package/Source/Scene/Scene.js +65 -0
  165. package/Source/Scene/ScreenSpaceCameraController.js +1 -1
  166. package/Source/Scene/SingleTileImageryProvider.js +382 -209
  167. package/Source/Scene/Terrain.js +196 -0
  168. package/Source/Scene/TileCoordinatesImageryProvider.js +267 -104
  169. package/Source/Scene/TileMapServiceImageryProvider.js +177 -85
  170. package/Source/Scene/Tileset3DTileContent.js +47 -5
  171. package/Source/Scene/TimeDynamicPointCloud.js +15 -2
  172. package/Source/Scene/UrlTemplateImageryProvider.js +343 -215
  173. package/Source/Scene/Vector3DTileClampedPolylines.js +96 -84
  174. package/Source/Scene/Vector3DTileContent.js +47 -22
  175. package/Source/Scene/Vector3DTileGeometry.js +57 -52
  176. package/Source/Scene/Vector3DTilePoints.js +72 -68
  177. package/Source/Scene/Vector3DTilePolygons.js +118 -117
  178. package/Source/Scene/Vector3DTilePolylines.js +86 -82
  179. package/Source/Scene/Vector3DTilePrimitive.js +0 -1
  180. package/Source/Scene/VoxelContent.js +61 -63
  181. package/Source/Scene/VoxelPrimitive.js +39 -91
  182. package/Source/Scene/VoxelProvider.js +2 -2
  183. package/Source/Scene/WebMapServiceImageryProvider.js +272 -111
  184. package/Source/Scene/WebMapTileServiceImageryProvider.js +270 -107
  185. package/Source/Scene/computeFlyToLocationForRectangle.js +33 -37
  186. package/Source/Scene/createOsmBuildings.js +6 -0
  187. package/Source/Scene/createOsmBuildingsAsync.js +82 -0
  188. package/Source/Scene/createWorldImagery.js +14 -5
  189. package/Source/Scene/createWorldImageryAsync.js +39 -0
  190. package/Source/Widget/CesiumWidget.js +55 -27
  191. package/index.d.ts +2158 -1395
  192. package/index.js +58 -51
  193. package/package.json +1 -1
@@ -0,0 +1,421 @@
1
+ import defined from "../Core/defined.js";
2
+ import ManagedArray from "../Core/ManagedArray.js";
3
+ import Cesium3DTileRefine from "./Cesium3DTileRefine.js";
4
+ import Cesium3DTilesetTraversal from "./Cesium3DTilesetTraversal.js";
5
+
6
+ /**
7
+ * Depth-first traversal that traverses all visible tiles and marks tiles for selection.
8
+ * Allows for skipping levels of the tree and rendering children and parent tiles simultaneously.
9
+ *
10
+ * @alias Cesium3DTilesetSkipTraversal
11
+ * @constructor
12
+ *
13
+ * @private
14
+ */
15
+ function Cesium3DTilesetSkipTraversal() {}
16
+
17
+ const traversal = {
18
+ stack: new ManagedArray(),
19
+ stackMaximumLength: 0,
20
+ };
21
+
22
+ const descendantTraversal = {
23
+ stack: new ManagedArray(),
24
+ stackMaximumLength: 0,
25
+ };
26
+
27
+ const selectionTraversal = {
28
+ stack: new ManagedArray(),
29
+ stackMaximumLength: 0,
30
+ ancestorStack: new ManagedArray(),
31
+ ancestorStackMaximumLength: 0,
32
+ };
33
+
34
+ const descendantSelectionDepth = 2;
35
+
36
+ /**
37
+ * Traverses a {@link Cesium3DTileset} to determine which tiles to load and render.
38
+ *
39
+ * @private
40
+ * @param {Cesium3DTileset} tileset
41
+ * @param {FrameState} frameState
42
+ */
43
+ Cesium3DTilesetSkipTraversal.selectTiles = function (tileset, frameState) {
44
+ tileset._requestedTiles.length = 0;
45
+
46
+ if (tileset.debugFreezeFrame) {
47
+ return;
48
+ }
49
+
50
+ tileset._selectedTiles.length = 0;
51
+ tileset._selectedTilesToStyle.length = 0;
52
+ tileset._emptyTiles.length = 0;
53
+ tileset.hasMixedContent = false;
54
+
55
+ const root = tileset.root;
56
+ Cesium3DTilesetTraversal.updateTile(root, frameState);
57
+
58
+ if (!root.isVisible) {
59
+ return;
60
+ }
61
+
62
+ if (
63
+ root.getScreenSpaceError(frameState, true) <=
64
+ tileset._maximumScreenSpaceError
65
+ ) {
66
+ return;
67
+ }
68
+
69
+ executeTraversal(root, frameState);
70
+ traverseAndSelect(root, frameState);
71
+
72
+ traversal.stack.trim(traversal.stackMaximumLength);
73
+ descendantTraversal.stack.trim(descendantTraversal.stackMaximumLength);
74
+ selectionTraversal.stack.trim(selectionTraversal.stackMaximumLength);
75
+ selectionTraversal.ancestorStack.trim(
76
+ selectionTraversal.ancestorStackMaximumLength
77
+ );
78
+
79
+ // Update the priority for any requests found during traversal
80
+ // Update after traversal so that min and max values can be used to normalize priority values
81
+ const requestedTiles = tileset._requestedTiles;
82
+ for (let i = 0; i < requestedTiles.length; ++i) {
83
+ requestedTiles[i].updatePriority();
84
+ }
85
+ };
86
+
87
+ /**
88
+ * Mark descendant tiles for rendering, and update as needed
89
+ *
90
+ * @private
91
+ * @param {Cesium3DTile} root
92
+ * @param {FrameState} frameState
93
+ */
94
+ function selectDescendants(root, frameState) {
95
+ const { updateTile, touchTile, selectTile } = Cesium3DTilesetTraversal;
96
+ const stack = descendantTraversal.stack;
97
+ stack.push(root);
98
+ while (stack.length > 0) {
99
+ descendantTraversal.stackMaximumLength = Math.max(
100
+ descendantTraversal.stackMaximumLength,
101
+ stack.length
102
+ );
103
+ const tile = stack.pop();
104
+ const children = tile.children;
105
+ for (let i = 0; i < children.length; ++i) {
106
+ const child = children[i];
107
+ if (child.isVisible) {
108
+ if (child.contentAvailable) {
109
+ updateTile(child, frameState);
110
+ touchTile(child, frameState);
111
+ selectTile(child, frameState);
112
+ } else if (child._depth - root._depth < descendantSelectionDepth) {
113
+ // Continue traversing, but not too far
114
+ stack.push(child);
115
+ }
116
+ }
117
+ }
118
+ }
119
+ }
120
+
121
+ /**
122
+ * Mark a tile as selected if it has content available.
123
+ * If its content is not available, and we are skipping levels of detail,
124
+ * select an ancestor or descendant tile instead
125
+ *
126
+ * @private
127
+ * @param {Cesium3DTile} tile
128
+ * @param {FrameState} frameState
129
+ */
130
+ function selectDesiredTile(tile, frameState) {
131
+ // If this tile is not loaded attempt to select its ancestor instead
132
+ const loadedTile = tile.contentAvailable
133
+ ? tile
134
+ : tile._ancestorWithContentAvailable;
135
+ if (defined(loadedTile)) {
136
+ // Tiles will actually be selected in traverseAndSelect
137
+ loadedTile._shouldSelect = true;
138
+ } else {
139
+ // If no ancestors are ready traverse down and select tiles to minimize empty regions.
140
+ // This happens often for immediatelyLoadDesiredLevelOfDetail where parent tiles are not necessarily loaded before zooming out.
141
+ selectDescendants(tile, frameState);
142
+ }
143
+ }
144
+
145
+ /**
146
+ * Update links to the ancestor tiles that have content
147
+ *
148
+ * @private
149
+ * @param {Cesium3DTile} tile
150
+ * @param {FrameState} frameState
151
+ */
152
+ function updateTileAncestorContentLinks(tile, frameState) {
153
+ tile._ancestorWithContent = undefined;
154
+ tile._ancestorWithContentAvailable = undefined;
155
+
156
+ const { parent } = tile;
157
+ if (!defined(parent)) {
158
+ return;
159
+ }
160
+ const parentHasContent =
161
+ !parent.hasUnloadedRenderableContent ||
162
+ parent._requestedFrame === frameState.frameNumber;
163
+
164
+ // ancestorWithContent is an ancestor that has content or has the potential to have
165
+ // content. Used in conjunction with tileset.skipLevels to know when to skip a tile.
166
+ tile._ancestorWithContent = parentHasContent
167
+ ? parent
168
+ : parent._ancestorWithContent;
169
+
170
+ // ancestorWithContentAvailable is an ancestor that is rendered if a desired tile is not loaded
171
+ tile._ancestorWithContentAvailable = parent.contentAvailable
172
+ ? parent
173
+ : parent._ancestorWithContentAvailable;
174
+ }
175
+
176
+ /**
177
+ * Determine if a tile has reached the limit of level of detail skipping.
178
+ * If so, it should _not_ be skipped: it should be loaded and rendered
179
+ *
180
+ * @private
181
+ * @param {Cesium3DTileset} tileset
182
+ * @param {Cesium3DTile} tile
183
+ * @returns {boolean} true if this tile should not be skipped
184
+ */
185
+ function reachedSkippingThreshold(tileset, tile) {
186
+ const ancestor = tile._ancestorWithContent;
187
+ return (
188
+ !tileset.immediatelyLoadDesiredLevelOfDetail &&
189
+ (tile._priorityProgressiveResolutionScreenSpaceErrorLeaf ||
190
+ (defined(ancestor) &&
191
+ tile._screenSpaceError <
192
+ ancestor._screenSpaceError / tileset.skipScreenSpaceErrorFactor &&
193
+ tile._depth > ancestor._depth + tileset.skipLevels))
194
+ );
195
+ }
196
+
197
+ /**
198
+ * @private
199
+ * @param {Cesium3DTile} tile
200
+ * @param {ManagedArray} stack
201
+ * @param {FrameState} frameState
202
+ * @returns {boolean}
203
+ */
204
+ function updateAndPushChildren(tile, stack, frameState) {
205
+ const { tileset, children } = tile;
206
+ const { updateTile, loadTile, touchTile } = Cesium3DTilesetTraversal;
207
+
208
+ for (let i = 0; i < children.length; ++i) {
209
+ updateTile(children[i], frameState);
210
+ }
211
+
212
+ // Sort by distance to take advantage of early Z and reduce artifacts
213
+ children.sort(Cesium3DTilesetTraversal.sortChildrenByDistanceToCamera);
214
+
215
+ let anyChildrenVisible = false;
216
+
217
+ for (let i = 0; i < children.length; ++i) {
218
+ const child = children[i];
219
+ if (child.isVisible) {
220
+ stack.push(child);
221
+ anyChildrenVisible = true;
222
+ } else if (tileset.loadSiblings) {
223
+ loadTile(child, frameState);
224
+ touchTile(child, frameState);
225
+ }
226
+ }
227
+
228
+ return anyChildrenVisible;
229
+ }
230
+
231
+ /**
232
+ * Determine if a tile is part of the base traversal.
233
+ * If not, this tile could be considered for level of detail skipping
234
+ *
235
+ * @private
236
+ * @param {Cesium3DTile} tile
237
+ * @param {number} baseScreenSpaceError
238
+ * @returns {boolean}
239
+ */
240
+ function inBaseTraversal(tile, baseScreenSpaceError) {
241
+ const { tileset } = tile;
242
+ if (tileset.immediatelyLoadDesiredLevelOfDetail) {
243
+ return false;
244
+ }
245
+ if (!defined(tile._ancestorWithContent)) {
246
+ // Include root or near-root tiles in the base traversal so there is something to select up to
247
+ return true;
248
+ }
249
+ if (tile._screenSpaceError === 0.0) {
250
+ // If a leaf, use parent's SSE
251
+ return tile.parent._screenSpaceError > baseScreenSpaceError;
252
+ }
253
+ return tile._screenSpaceError > baseScreenSpaceError;
254
+ }
255
+
256
+ /**
257
+ * Depth-first traversal that traverses all visible tiles and marks tiles for selection.
258
+ * Tiles that have a greater screen space error than the base screen space error are part of the base traversal,
259
+ * all other tiles are part of the skip traversal. The skip traversal allows for skipping levels of the tree
260
+ * and rendering children and parent tiles simultaneously.
261
+ *
262
+ * @private
263
+ * @param {Cesium3DTile} root
264
+ * @param {FrameState} frameState
265
+ */
266
+ function executeTraversal(root, frameState) {
267
+ const { tileset } = root;
268
+ const baseScreenSpaceError = tileset.immediatelyLoadDesiredLevelOfDetail
269
+ ? Number.MAX_VALUE
270
+ : Math.max(tileset.baseScreenSpaceError, tileset.maximumScreenSpaceError);
271
+ const {
272
+ canTraverse,
273
+ loadTile,
274
+ visitTile,
275
+ touchTile,
276
+ } = Cesium3DTilesetTraversal;
277
+ const stack = traversal.stack;
278
+ stack.push(root);
279
+
280
+ while (stack.length > 0) {
281
+ traversal.stackMaximumLength = Math.max(
282
+ traversal.stackMaximumLength,
283
+ stack.length
284
+ );
285
+
286
+ const tile = stack.pop();
287
+
288
+ updateTileAncestorContentLinks(tile, frameState);
289
+ const parent = tile.parent;
290
+ const parentRefines = !defined(parent) || parent._refines;
291
+
292
+ tile._refines = canTraverse(tile)
293
+ ? updateAndPushChildren(tile, stack, frameState) && parentRefines
294
+ : false;
295
+
296
+ const stoppedRefining = !tile._refines && parentRefines;
297
+
298
+ if (!tile.hasRenderableContent) {
299
+ // Add empty tile just to show its debug bounding volume
300
+ // If the tile has tileset content load the external tileset
301
+ // If the tile cannot refine further select its nearest loaded ancestor
302
+ tileset._emptyTiles.push(tile);
303
+ loadTile(tile, frameState);
304
+ if (stoppedRefining) {
305
+ selectDesiredTile(tile, frameState);
306
+ }
307
+ } else if (tile.refine === Cesium3DTileRefine.ADD) {
308
+ // Additive tiles are always loaded and selected
309
+ selectDesiredTile(tile, frameState);
310
+ loadTile(tile, frameState);
311
+ } else if (tile.refine === Cesium3DTileRefine.REPLACE) {
312
+ if (inBaseTraversal(tile, baseScreenSpaceError)) {
313
+ // Always load tiles in the base traversal
314
+ // Select tiles that can't refine further
315
+ loadTile(tile, frameState);
316
+ if (stoppedRefining) {
317
+ selectDesiredTile(tile, frameState);
318
+ }
319
+ } else if (stoppedRefining) {
320
+ // In skip traversal, load and select tiles that can't refine further
321
+ selectDesiredTile(tile, frameState);
322
+ loadTile(tile, frameState);
323
+ } else if (reachedSkippingThreshold(tileset, tile)) {
324
+ // In skip traversal, load tiles that aren't skipped
325
+ loadTile(tile, frameState);
326
+ }
327
+ }
328
+
329
+ visitTile(tile, frameState);
330
+ touchTile(tile, frameState);
331
+ }
332
+ }
333
+
334
+ /**
335
+ * Traverse the tree and check if their selected frame is the current frame. If so, add it to a selection queue.
336
+ * This is a preorder traversal so children tiles are selected before ancestor tiles.
337
+ *
338
+ * The reason for the preorder traversal is so that tiles can easily be marked with their
339
+ * selection depth. A tile's _selectionDepth is its depth in the tree where all non-selected tiles are removed.
340
+ * This property is important for use in the stencil test because we want to render deeper tiles on top of their
341
+ * ancestors. If a tileset is very deep, the depth is unlikely to fit into the stencil buffer.
342
+ *
343
+ * We want to select children before their ancestors because there is no guarantee on the relationship between
344
+ * the children's z-depth and the ancestor's z-depth. We cannot rely on Z because we want the child to appear on top
345
+ * of ancestor regardless of true depth. The stencil tests used require children to be drawn first.
346
+ *
347
+ * NOTE: 3D Tiles uses 3 bits from the stencil buffer meaning this will not work when there is a chain of
348
+ * selected tiles that is deeper than 7. This is not very likely.
349
+ *
350
+ * @private
351
+ * @param {Cesium3DTile} root
352
+ * @param {FrameState} frameState
353
+ */
354
+ function traverseAndSelect(root, frameState) {
355
+ const { selectTile, canTraverse } = Cesium3DTilesetTraversal;
356
+ const { stack, ancestorStack } = selectionTraversal;
357
+ let lastAncestor;
358
+
359
+ stack.push(root);
360
+
361
+ while (stack.length > 0 || ancestorStack.length > 0) {
362
+ selectionTraversal.stackMaximumLength = Math.max(
363
+ selectionTraversal.stackMaximumLength,
364
+ stack.length
365
+ );
366
+ selectionTraversal.ancestorStackMaximumLength = Math.max(
367
+ selectionTraversal.ancestorStackMaximumLength,
368
+ ancestorStack.length
369
+ );
370
+
371
+ if (ancestorStack.length > 0) {
372
+ const waitingTile = ancestorStack.peek();
373
+ if (waitingTile._stackLength === stack.length) {
374
+ ancestorStack.pop();
375
+ if (waitingTile !== lastAncestor) {
376
+ waitingTile._finalResolution = false;
377
+ }
378
+ selectTile(waitingTile, frameState);
379
+ continue;
380
+ }
381
+ }
382
+
383
+ const tile = stack.pop();
384
+ if (!defined(tile)) {
385
+ // stack is empty but ancestorStack isn't
386
+ continue;
387
+ }
388
+
389
+ const traverse = canTraverse(tile);
390
+
391
+ if (tile._shouldSelect) {
392
+ if (tile.refine === Cesium3DTileRefine.ADD) {
393
+ selectTile(tile, frameState);
394
+ } else {
395
+ tile._selectionDepth = ancestorStack.length;
396
+ if (tile._selectionDepth > 0) {
397
+ tile.tileset.hasMixedContent = true;
398
+ }
399
+ lastAncestor = tile;
400
+ if (!traverse) {
401
+ selectTile(tile, frameState);
402
+ continue;
403
+ }
404
+ ancestorStack.push(tile);
405
+ tile._stackLength = stack.length;
406
+ }
407
+ }
408
+
409
+ if (traverse) {
410
+ const children = tile.children;
411
+ for (let i = 0; i < children.length; ++i) {
412
+ const child = children[i];
413
+ if (child.isVisible) {
414
+ stack.push(child);
415
+ }
416
+ }
417
+ }
418
+ }
419
+ }
420
+
421
+ export default Cesium3DTilesetSkipTraversal;