@cesium/engine 13.1.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 (183) hide show
  1. package/Build/Workers/{chunk-APCS5YJI.js → chunk-25TOENEE.js} +7 -7
  2. package/Build/Workers/{chunk-FNCXBBCF.js → chunk-2AVIUB5H.js} +2 -2
  3. package/Build/Workers/{chunk-OZTFRHA2.js → chunk-3JZGPJMZ.js} +6 -6
  4. package/Build/Workers/{chunk-5JY4LYO3.js → chunk-3LHBH4TC.js} +7 -7
  5. package/Build/Workers/{chunk-MGABCOOH.js → chunk-3LZF23RY.js} +6 -6
  6. package/Build/Workers/{chunk-AXYZUG4N.js → chunk-5S2B46UQ.js} +1 -1
  7. package/Build/Workers/{chunk-2SRHVCFD.js → chunk-67ONR44K.js} +6 -6
  8. package/Build/Workers/{chunk-PBJQFLKS.js → chunk-6EDBC234.js} +11 -11
  9. package/Build/Workers/{chunk-GSLKQJM2.js → chunk-6EV4VOET.js} +10 -10
  10. package/Build/Workers/{chunk-OGRXNUR2.js → chunk-7ITUZTFH.js} +1 -1
  11. package/Build/Workers/{chunk-IP7F2MVW.js → chunk-ARVZCY6X.js} +7 -7
  12. package/Build/Workers/{chunk-EYZFEJX3.js → chunk-B2UQN3DH.js} +6 -6
  13. package/Build/Workers/{chunk-WE4KF4AM.js → chunk-B2Y4ZS6X.js} +9 -9
  14. package/Build/Workers/{chunk-DWIKWWEE.js → chunk-BD2TPFGC.js} +5 -5
  15. package/Build/Workers/{chunk-5ICYLS6B.js → chunk-CHX2K5AC.js} +10 -10
  16. package/Build/Workers/{chunk-NQDKNE7V.js → chunk-CJGVEABL.js} +13 -13
  17. package/Build/Workers/{chunk-B34JXFHF.js → chunk-DYJHEP3B.js} +5 -5
  18. package/Build/Workers/{chunk-J7BMSSY7.js → chunk-E3H7AVMK.js} +13 -13
  19. package/Build/Workers/{chunk-TOHDFUJM.js → chunk-EZNAJPP5.js} +4 -4
  20. package/Build/Workers/{chunk-K62EHZFT.js → chunk-F7ZI463G.js} +15 -15
  21. package/Build/Workers/{chunk-EJ5DT5BP.js → chunk-FMZ5CX6V.js} +1 -1
  22. package/Build/Workers/{chunk-OARMSJUU.js → chunk-FRAWHNSR.js} +2 -2
  23. package/Build/Workers/{chunk-S3UM4OKP.js → chunk-GGV2XJHE.js} +7 -7
  24. package/Build/Workers/{chunk-SAKQO5NX.js → chunk-GK4QU6QI.js} +2 -2
  25. package/Build/Workers/{chunk-LFUFGHL3.js → chunk-HYPB7FAV.js} +10 -10
  26. package/Build/Workers/{chunk-3SCCWLZS.js → chunk-I4HO2ED2.js} +9 -9
  27. package/Build/Workers/{chunk-K6SQV4IS.js → chunk-IGINOLDX.js} +6 -6
  28. package/Build/Workers/{chunk-IXNXKVOB.js → chunk-ISQSYLZY.js} +4 -4
  29. package/Build/Workers/{chunk-PM76TX2X.js → chunk-JZAMRL5I.js} +6 -6
  30. package/Build/Workers/{chunk-CBE4HRBH.js → chunk-K5G2WELR.js} +7 -7
  31. package/Build/Workers/{chunk-EHGQQA7C.js → chunk-L5SO4Y5V.js} +1 -1
  32. package/Build/Workers/{chunk-M2AA2ARJ.js → chunk-LCMJQVIF.js} +11 -11
  33. package/Build/Workers/{chunk-HI73PIPQ.js → chunk-MWJW37I7.js} +2 -2
  34. package/Build/Workers/{chunk-WAJNX74N.js → chunk-NAGMYRDW.js} +27 -20
  35. package/Build/Workers/{chunk-WUIDEXAN.js → chunk-OYO6TKMU.js} +7 -7
  36. package/Build/Workers/{chunk-YVGU235V.js → chunk-PUTA3AE2.js} +4 -4
  37. package/Build/Workers/{chunk-ZWSWJYJP.js → chunk-Q5BHMNKU.js} +13 -13
  38. package/Build/Workers/{chunk-LQT2ZK7D.js → chunk-QTEX3Y4V.js} +17 -17
  39. package/Build/Workers/{chunk-UBAHTE4Q.js → chunk-QZKN2RXM.js} +1 -1
  40. package/Build/Workers/{chunk-T34EOLFR.js → chunk-RO2Z3LCR.js} +14 -14
  41. package/Build/Workers/{chunk-PTFIVVLX.js → chunk-RRN6LRDX.js} +12 -12
  42. package/Build/Workers/{chunk-B6IJY6AN.js → chunk-SLIA3GQP.js} +7 -7
  43. package/Build/Workers/{chunk-GIOZHX7U.js → chunk-TFCOEX3W.js} +2 -2
  44. package/Build/Workers/{chunk-KRVALCCI.js → chunk-TU6ZXHVU.js} +5 -5
  45. package/Build/Workers/{chunk-54I6VSRP.js → chunk-VJ2PDF64.js} +6 -6
  46. package/Build/Workers/{chunk-BMFWWTD7.js → chunk-VMVPONIV.js} +5 -5
  47. package/Build/Workers/{chunk-CNPP6TQ2.js → chunk-WPXU45PH.js} +4 -4
  48. package/Build/Workers/{chunk-2ONAV62A.js → chunk-XDHM4G3P.js} +7 -7
  49. package/Build/Workers/{chunk-KO232FLP.js → chunk-XED3RXKO.js} +2 -2
  50. package/Build/Workers/{chunk-5I3LPAS7.js → chunk-YNYCGTQH.js} +5 -5
  51. package/Build/Workers/{chunk-THDHWSEJ.js → chunk-Z4SI54EB.js} +4 -4
  52. package/Build/Workers/{chunk-R2KGFZBA.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 +15 -14
  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/Color.js +3 -3
  102. package/Source/Core/Credit.js +3 -3
  103. package/Source/Core/DistanceDisplayCondition.js +3 -3
  104. package/Source/Core/EllipsoidRhumbLine.js +1 -1
  105. package/Source/Core/Ion.js +1 -1
  106. package/Source/Core/OrientedBoundingBox.js +2 -2
  107. package/Source/Core/PolygonGeometryLibrary.js +26 -4
  108. package/Source/Core/Spherical.js +3 -3
  109. package/Source/Core/TexturePacker.js +166 -0
  110. package/Source/Core/writeTextToCanvas.js +0 -1
  111. package/Source/DataSources/BillboardVisualizer.js +3 -3
  112. package/Source/DataSources/BoundingSphereState.js +3 -3
  113. package/Source/DataSources/DataSourceClock.js +1 -1
  114. package/Source/DataSources/DataSourceDisplay.js +5 -2
  115. package/Source/DataSources/EntityCluster.js +44 -19
  116. package/Source/Renderer/AutomaticUniforms.js +2 -2
  117. package/Source/Renderer/Context.js +0 -4
  118. package/Source/Renderer/Texture.js +6 -5
  119. package/Source/Renderer/TextureAtlas.js +802 -0
  120. package/Source/Scene/ArcGisMapService.js +1 -1
  121. package/Source/Scene/Billboard.js +87 -142
  122. package/Source/Scene/BillboardCollection.js +132 -202
  123. package/Source/Scene/BillboardLoadState.js +44 -0
  124. package/Source/Scene/BillboardTexture.js +348 -0
  125. package/Source/Scene/Camera.js +2 -2
  126. package/Source/Scene/Cesium3DTile.js +56 -28
  127. package/Source/Scene/Cesium3DTilesVoxelProvider.js +403 -132
  128. package/Source/Scene/Cesium3DTilesetStatistics.js +0 -1
  129. package/Source/Scene/ClippingPolygon.js +2 -2
  130. package/Source/Scene/Expression.js +1 -0
  131. package/Source/Scene/GltfDracoLoader.js +45 -0
  132. package/Source/Scene/GltfIndexBufferLoader.js +5 -0
  133. package/Source/Scene/GltfLoader.js +22 -9
  134. package/Source/Scene/GltfVertexBufferLoader.js +13 -0
  135. package/Source/Scene/ITwinData.js +47 -1
  136. package/Source/Scene/ImageryLayer.js +1 -1
  137. package/Source/Scene/ImplicitSubtree.js +2 -0
  138. package/Source/Scene/KeyframeNode.js +16 -2
  139. package/Source/Scene/Label.js +1 -1
  140. package/Source/Scene/LabelCollection.js +212 -193
  141. package/Source/Scene/Megatexture.js +145 -81
  142. package/Source/Scene/Model/CustomShader.js +0 -2
  143. package/Source/Scene/Model/Model.js +1 -1
  144. package/Source/Scene/Model/ModelUtility.js +5 -1
  145. package/Source/Scene/Multiple3DTileContent.js +21 -8
  146. package/Source/Scene/PointPrimitive.js +1 -1
  147. package/Source/Scene/ResourceCache.js +17 -1
  148. package/Source/Scene/Scene.js +39 -15
  149. package/Source/Scene/ScreenSpaceCameraController.js +0 -8
  150. package/Source/Scene/SpatialNode.js +4 -11
  151. package/Source/Scene/Vector3DTilePoints.js +2 -5
  152. package/Source/Scene/VoxelBoxShape.js +12 -5
  153. package/Source/Scene/VoxelCell.js +6 -5
  154. package/Source/Scene/VoxelContent.js +171 -107
  155. package/Source/Scene/VoxelCylinderShape.js +65 -58
  156. package/Source/Scene/VoxelEllipsoidShape.js +15 -5
  157. package/Source/Scene/VoxelMetadataOrder.js +12 -0
  158. package/Source/Scene/VoxelPrimitive.js +245 -53
  159. package/Source/Scene/VoxelProvider.js +44 -29
  160. package/Source/Scene/VoxelRenderResources.js +30 -7
  161. package/Source/Scene/VoxelShape.js +10 -3
  162. package/Source/Scene/VoxelTraversal.js +326 -166
  163. package/Source/Scene/WebMapTileServiceImageryProvider.js +2 -2
  164. package/Source/Scene/createGooglePhotorealistic3DTileset.js +5 -8
  165. package/Source/Scene/processVoxelProperties.js +3 -0
  166. package/Source/Shaders/GlobeFS.glsl +10 -1
  167. package/Source/Shaders/GlobeFS.js +10 -1
  168. package/Source/Shaders/PolylineCommon.glsl +1 -1
  169. package/Source/Shaders/PolylineCommon.js +1 -1
  170. package/Source/Shaders/Voxels/Megatexture.glsl +4 -16
  171. package/Source/Shaders/Voxels/Megatexture.js +4 -16
  172. package/Source/Shaders/Voxels/Octree.glsl +44 -7
  173. package/Source/Shaders/Voxels/Octree.js +44 -7
  174. package/Source/Shaders/Voxels/VoxelFS.glsl +9 -15
  175. package/Source/Shaders/Voxels/VoxelFS.js +9 -15
  176. package/Source/Shaders/Voxels/convertUvToCylinder.glsl +15 -15
  177. package/Source/Shaders/Voxels/convertUvToCylinder.js +15 -15
  178. package/Source/Widget/CesiumWidget.js +16 -10
  179. package/Source/Workers/decodeDraco.js +4 -4
  180. package/index.d.ts +321 -110
  181. package/index.js +209 -205
  182. package/package.json +2 -2
  183. package/Source/Scene/TextureAtlas.js +0 -558
@@ -21,11 +21,11 @@ import TextureWrap from "../Renderer/TextureWrap.js";
21
21
  * @alias Megatexture
22
22
  * @constructor
23
23
  *
24
- * @param {Context} context
25
- * @param {Cartesian3} dimensions
26
- * @param {number} channelCount
27
- * @param {MetadataComponentType} componentType
28
- * @param {number} [textureMemoryByteLength]
24
+ * @param {Context} context The context in which to create GPU resources.
25
+ * @param {Cartesian3} dimensions The number of voxels in each dimension of the tile.
26
+ * @param {number} channelCount The number of channels in the metadata.
27
+ * @param {MetadataComponentType} componentType The component type of the metadata.
28
+ * @param {number} [availableTextureMemoryBytes=134217728] An upper limit on the texture memory size in bytes.
29
29
  *
30
30
  * @private
31
31
  */
@@ -34,59 +34,35 @@ function Megatexture(
34
34
  dimensions,
35
35
  channelCount,
36
36
  componentType,
37
- textureMemoryByteLength,
37
+ availableTextureMemoryBytes,
38
38
  ) {
39
+ const maximumTextureMemoryByteLength = 512 * 1024 * 1024;
40
+ availableTextureMemoryBytes = Math.min(
41
+ defaultValue(availableTextureMemoryBytes, 128 * 1024 * 1024),
42
+ maximumTextureMemoryByteLength,
43
+ );
44
+
39
45
  // TODO there are a lot of texture packing rules, see https://github.com/CesiumGS/cesium/issues/9572
40
46
  // Unsigned short textures not allowed in webgl 1, so treat as float
41
47
  if (componentType === MetadataComponentType.UNSIGNED_SHORT) {
42
48
  componentType = MetadataComponentType.FLOAT32;
43
49
  }
44
50
 
45
- const supportsFloatingPointTexture = context.floatingPointTexture;
46
51
  if (
47
52
  componentType === MetadataComponentType.FLOAT32 &&
48
- !supportsFloatingPointTexture
53
+ !context.floatingPointTexture
49
54
  ) {
50
55
  throw new RuntimeError("Floating point texture not supported");
51
56
  }
52
57
 
53
- // TODO support more
54
- let pixelType;
55
- if (
56
- componentType === MetadataComponentType.FLOAT32 ||
57
- componentType === MetadataComponentType.FLOAT64
58
- ) {
59
- pixelType = PixelDatatype.FLOAT;
60
- } else if (componentType === MetadataComponentType.UINT8) {
61
- pixelType = PixelDatatype.UNSIGNED_BYTE;
62
- }
63
-
64
- let pixelFormat;
65
- if (channelCount === 1) {
66
- pixelFormat = context.webgl2 ? PixelFormat.RED : PixelFormat.LUMINANCE;
67
- } else if (channelCount === 2) {
68
- pixelFormat = context.webgl2 ? PixelFormat.RG : PixelFormat.LUMINANCE_ALPHA;
69
- } else if (channelCount === 3) {
70
- pixelFormat = PixelFormat.RGB;
71
- } else if (channelCount === 4) {
72
- pixelFormat = PixelFormat.RGBA;
73
- }
74
-
75
- const maximumTextureMemoryByteLength = 512 * 1024 * 1024;
76
- const defaultTextureMemoryByteLength = 128 * 1024 * 1024;
77
- textureMemoryByteLength = Math.min(
78
- defaultValue(textureMemoryByteLength, defaultTextureMemoryByteLength),
79
- maximumTextureMemoryByteLength,
80
- );
81
- const maximumTextureDimensionContext = ContextLimits.maximumTextureSize;
58
+ const pixelDataType = getPixelDataType(componentType);
59
+ const pixelFormat = getPixelFormat(channelCount, context.webgl2);
82
60
  const componentTypeByteLength =
83
61
  MetadataComponentType.getSizeInBytes(componentType);
84
- const texelCount = Math.floor(
85
- textureMemoryByteLength / (channelCount * componentTypeByteLength),
86
- );
87
- const textureDimension = Math.min(
88
- maximumTextureDimensionContext,
89
- CesiumMath.previousPowerOfTwo(Math.floor(Math.sqrt(texelCount))),
62
+ const textureDimension = getTextureDimension(
63
+ availableTextureMemoryBytes,
64
+ channelCount,
65
+ componentTypeByteLength,
90
66
  );
91
67
 
92
68
  const sliceCountPerRegionX = Math.ceil(Math.sqrt(dimensions.x));
@@ -116,6 +92,13 @@ function Megatexture(
116
92
  */
117
93
  this.componentType = componentType;
118
94
 
95
+ /**
96
+ * @type {number}
97
+ * @readonly
98
+ */
99
+ this.textureMemoryByteLength =
100
+ componentTypeByteLength * channelCount * textureDimension ** 2;
101
+
119
102
  /**
120
103
  * @type {Cartesian3}
121
104
  * @readonly
@@ -190,7 +173,7 @@ function Megatexture(
190
173
  this.texture = new Texture({
191
174
  context: context,
192
175
  pixelFormat: pixelFormat,
193
- pixelDatatype: pixelType,
176
+ pixelDatatype: pixelDataType,
194
177
  flipY: false,
195
178
  width: textureDimension,
196
179
  height: textureDimension,
@@ -249,6 +232,73 @@ function Megatexture(
249
232
  this.occupiedCount = 0;
250
233
  }
251
234
 
235
+ /**
236
+ * Get the pixel data type to use in a megatexture.
237
+ * TODO support more
238
+ *
239
+ * @param {MetadataComponentType} componentType The component type of the metadata.
240
+ * @returns {PixelDatatype} The pixel datatype to use for a megatexture.
241
+ *
242
+ * @private
243
+ */
244
+ function getPixelDataType(componentType) {
245
+ if (
246
+ componentType === MetadataComponentType.FLOAT32 ||
247
+ componentType === MetadataComponentType.FLOAT64
248
+ ) {
249
+ return PixelDatatype.FLOAT;
250
+ } else if (componentType === MetadataComponentType.UINT8) {
251
+ return PixelDatatype.UNSIGNED_BYTE;
252
+ }
253
+ }
254
+
255
+ /**
256
+ * Get the pixel format to use for a megatexture.
257
+ *
258
+ * @param {number} channelCount The number of channels in the metadata. Must be 1 to 4.
259
+ * @param {boolean} webgl2 true if the context is using webgl2
260
+ * @returns {PixelFormat} The pixel format to use for a megatexture.
261
+ *
262
+ * @private
263
+ */
264
+ function getPixelFormat(channelCount, webgl2) {
265
+ if (channelCount === 1) {
266
+ return webgl2 ? PixelFormat.RED : PixelFormat.LUMINANCE;
267
+ } else if (channelCount === 2) {
268
+ return webgl2 ? PixelFormat.RG : PixelFormat.LUMINANCE_ALPHA;
269
+ } else if (channelCount === 3) {
270
+ return PixelFormat.RGB;
271
+ } else if (channelCount === 4) {
272
+ return PixelFormat.RGBA;
273
+ }
274
+ }
275
+
276
+ /**
277
+ * Compute the largest size of a square texture that will fit in the available memory.
278
+ *
279
+ * @param {number} availableTextureMemoryBytes An upper limit on the texture memory size.
280
+ * @param {number} channelCount The number of metadata channels per texel.
281
+ * @param {number} componentByteLength The byte length of each component of the metadata.
282
+ * @returns {number} The dimension of the square texture to use for the megatexture.
283
+ *
284
+ * @private
285
+ */
286
+ function getTextureDimension(
287
+ availableTextureMemoryBytes,
288
+ channelCount,
289
+ componentByteLength,
290
+ ) {
291
+ // Compute how many texels will fit in the available memory
292
+ const texelCount = Math.floor(
293
+ availableTextureMemoryBytes / (channelCount * componentByteLength),
294
+ );
295
+ // Return the largest power of two texture size that will fit in memory
296
+ return Math.min(
297
+ ContextLimits.maximumTextureSize,
298
+ CesiumMath.previousPowerOfTwo(Math.floor(Math.sqrt(texelCount))),
299
+ );
300
+ }
301
+
252
302
  /**
253
303
  * @alias MegatextureNode
254
304
  * @constructor
@@ -275,8 +325,9 @@ function MegatextureNode(index) {
275
325
  }
276
326
 
277
327
  /**
278
- * @param {Array} data
279
- * @returns {number}
328
+ * Add an array of tile metadata to the megatexture.
329
+ * @param {Array} data The data to be added.
330
+ * @returns {number} The index of the tile's location in the megatexture.
280
331
  */
281
332
  Megatexture.prototype.add = function (data) {
282
333
  if (this.isFull()) {
@@ -339,10 +390,10 @@ Megatexture.prototype.isFull = function () {
339
390
  };
340
391
 
341
392
  /**
342
- * @param {number} tileCount
343
- * @param {Cartesian3} dimensions
344
- * @param {number} channelCount number of channels in the metadata. Must be 1 to 4.
345
- * @param {MetadataComponentType} componentType
393
+ * @param {number} tileCount The total number of tiles in the tileset.
394
+ * @param {Cartesian3} dimensions The number of voxels in each dimension of the tile.
395
+ * @param {number} channelCount The number of channels in the metadata.
396
+ * @param {MetadataComponentType} componentType The type of one channel of the metadata.
346
397
  * @returns {number}
347
398
  */
348
399
  Megatexture.getApproximateTextureMemoryByteLength = function (
@@ -390,55 +441,52 @@ Megatexture.getApproximateTextureMemoryByteLength = function (
390
441
  };
391
442
 
392
443
  /**
393
- * @param {number} index
394
- * @param {Float32Array|Uint16Array|Uint8Array} data
444
+ * Write an array of tile metadata to the megatexture.
445
+ * @param {number} index The index of the tile's location in the megatexture.
446
+ * @param {Float32Array|Uint16Array|Uint8Array} data The data to be written.
395
447
  */
396
448
  Megatexture.prototype.writeDataToTexture = function (index, data) {
397
449
  // Unsigned short textures not allowed in webgl 1, so treat as float
398
450
  const tileData =
399
451
  data.constructor === Uint16Array ? new Float32Array(data) : data;
400
452
 
401
- const voxelDimensionsPerTile = this.voxelCountPerTile;
402
- const sliceDimensionsPerRegion = this.sliceCountPerRegion;
403
- const voxelDimensionsPerRegion = this.voxelCountPerRegion;
404
- const channelCount = this.channelCount;
405
-
406
- const tileVoxelData = this.tileVoxelDataTemp;
407
- for (let z = 0; z < voxelDimensionsPerTile.z; z++) {
408
- const sliceVoxelOffsetX =
409
- (z % sliceDimensionsPerRegion.x) * voxelDimensionsPerTile.x;
453
+ const {
454
+ tileVoxelDataTemp,
455
+ voxelCountPerTile,
456
+ sliceCountPerRegion,
457
+ voxelCountPerRegion,
458
+ channelCount,
459
+ regionCountPerMegatexture,
460
+ } = this;
461
+
462
+ for (let z = 0; z < voxelCountPerTile.z; z++) {
463
+ const sliceVoxelOffsetX = (z % sliceCountPerRegion.x) * voxelCountPerTile.x;
410
464
  const sliceVoxelOffsetY =
411
- Math.floor(z / sliceDimensionsPerRegion.x) * voxelDimensionsPerTile.y;
412
- for (let y = 0; y < voxelDimensionsPerTile.y; y++) {
413
- for (let x = 0; x < voxelDimensionsPerTile.x; x++) {
414
- const readIndex =
415
- z * voxelDimensionsPerTile.y * voxelDimensionsPerTile.x +
416
- y * voxelDimensionsPerTile.x +
417
- x;
418
- const writeIndex =
419
- (sliceVoxelOffsetY + y) * voxelDimensionsPerRegion.x +
420
- (sliceVoxelOffsetX + x);
465
+ Math.floor(z / sliceCountPerRegion.x) * voxelCountPerTile.y;
466
+ for (let y = 0; y < voxelCountPerTile.y; y++) {
467
+ const readOffset = getReadOffset(voxelCountPerTile, y, z);
468
+ const writeOffset =
469
+ (sliceVoxelOffsetY + y) * voxelCountPerRegion.x + sliceVoxelOffsetX;
470
+ for (let x = 0; x < voxelCountPerTile.x; x++) {
471
+ const readIndex = readOffset + x;
472
+ const writeIndex = writeOffset + x;
421
473
  for (let c = 0; c < channelCount; c++) {
422
- tileVoxelData[writeIndex * channelCount + c] =
474
+ tileVoxelDataTemp[writeIndex * channelCount + c] =
423
475
  tileData[readIndex * channelCount + c];
424
476
  }
425
477
  }
426
478
  }
427
479
  }
428
480
 
429
- const regionDimensionsPerMegatexture = this.regionCountPerMegatexture;
430
- const voxelWidth = voxelDimensionsPerRegion.x;
431
- const voxelHeight = voxelDimensionsPerRegion.y;
432
481
  const voxelOffsetX =
433
- (index % regionDimensionsPerMegatexture.x) * voxelDimensionsPerRegion.x;
482
+ (index % regionCountPerMegatexture.x) * voxelCountPerRegion.x;
434
483
  const voxelOffsetY =
435
- Math.floor(index / regionDimensionsPerMegatexture.x) *
436
- voxelDimensionsPerRegion.y;
484
+ Math.floor(index / regionCountPerMegatexture.x) * voxelCountPerRegion.y;
437
485
 
438
486
  const source = {
439
- arrayBufferView: tileVoxelData,
440
- width: voxelWidth,
441
- height: voxelHeight,
487
+ arrayBufferView: tileVoxelDataTemp,
488
+ width: voxelCountPerRegion.x,
489
+ height: voxelCountPerRegion.y,
442
490
  };
443
491
 
444
492
  const copyOptions = {
@@ -450,6 +498,22 @@ Megatexture.prototype.writeDataToTexture = function (index, data) {
450
498
  this.texture.copyFrom(copyOptions);
451
499
  };
452
500
 
501
+ /**
502
+ * Get the offset into the data array for a given row of contiguous voxel data.
503
+ *
504
+ * @param {Cartesian3} dimensions The number of voxels in each dimension of the tile.
505
+ * @param {number} y The y index of the voxel row
506
+ * @param {number} z The z index of the voxel row
507
+ * @returns {number} The offset into the data array
508
+ * @private
509
+ */
510
+ function getReadOffset(dimensions, y, z) {
511
+ const voxelsPerInputSlice = dimensions.y * dimensions.x;
512
+ const sliceIndex = z;
513
+ const rowIndex = y;
514
+ return sliceIndex * voxelsPerInputSlice + rowIndex * dimensions.x;
515
+ }
516
+
453
517
  /**
454
518
  * Returns true if this object was destroyed; otherwise, false.
455
519
  * <br /><br />
@@ -443,7 +443,6 @@ CustomShader.prototype.update = function (frameState) {
443
443
  * @returns {boolean} True if this object was destroyed; otherwise, false.
444
444
  *
445
445
  * @see CustomShader#destroy
446
- * @private
447
446
  */
448
447
  CustomShader.prototype.isDestroyed = function () {
449
448
  return false;
@@ -463,7 +462,6 @@ CustomShader.prototype.isDestroyed = function () {
463
462
  * customShader = customShader && customShader.destroy();
464
463
  *
465
464
  * @see CustomShader#isDestroyed
466
- * @private
467
465
  */
468
466
  CustomShader.prototype.destroy = function () {
469
467
  this._textureManager = this._textureManager && this._textureManager.destroy();
@@ -120,9 +120,9 @@ import pickModel from "./pickModel.js";
120
120
  * @alias Model
121
121
  * @internalConstructor
122
122
  *
123
+ * @privateParam {object} options Object with the following properties:
123
124
  * @privateParam {ResourceLoader} options.loader The loader used to load resources for this model.
124
125
  * @privateParam {ModelType} options.type Type of this model, to distinguish individual glTF files from 3D Tiles internally.
125
- * @privateParam {object} options Object with the following properties:
126
126
  * @privateParam {Resource} options.resource The Resource to the 3D model.
127
127
  * @privateParam {boolean} [options.show=true] Whether or not to render the model.
128
128
  * @privateParam {Matrix4} [options.modelMatrix=Matrix4.IDENTITY] The 4x4 transformation matrix that transforms the model from model to world coordinates.
@@ -346,15 +346,18 @@ ModelUtility.supportedExtensions = {
346
346
  CESIUM_primitive_outline: true,
347
347
  CESIUM_RTC: true,
348
348
  EXT_feature_metadata: true,
349
+ EXT_implicit_cylinder_region: true,
350
+ EXT_implicit_ellipsoid_region: true,
349
351
  EXT_instance_features: true,
350
352
  EXT_mesh_features: true,
351
353
  EXT_mesh_gpu_instancing: true,
352
354
  EXT_meshopt_compression: true,
355
+ EXT_primitive_voxels: true,
353
356
  EXT_structural_metadata: true,
354
357
  EXT_texture_webp: true,
355
358
  KHR_blend: true,
356
359
  KHR_draco_mesh_compression: true,
357
- KHR_techniques_webgl: true,
360
+ KHR_implicit_shapes: true,
358
361
  KHR_materials_common: true,
359
362
  KHR_materials_pbrSpecularGlossiness: true,
360
363
  KHR_materials_specular: true,
@@ -362,6 +365,7 @@ ModelUtility.supportedExtensions = {
362
365
  KHR_materials_clearcoat: true,
363
366
  KHR_materials_unlit: true,
364
367
  KHR_mesh_quantization: true,
368
+ KHR_techniques_webgl: true,
365
369
  KHR_texture_basisu: true,
366
370
  KHR_texture_transform: true,
367
371
  WEB3D_quantized_attributes: true,
@@ -6,7 +6,6 @@ import Request from "../Core/Request.js";
6
6
  import RequestScheduler from "../Core/RequestScheduler.js";
7
7
  import RequestState from "../Core/RequestState.js";
8
8
  import RequestType from "../Core/RequestType.js";
9
- import RuntimeError from "../Core/RuntimeError.js";
10
9
  import Cesium3DContentGroup from "./Cesium3DContentGroup.js";
11
10
  import Cesium3DTileContentType from "./Cesium3DTileContentType.js";
12
11
  import Cesium3DTileContentFactory from "./Cesium3DTileContentFactory.js";
@@ -52,6 +51,11 @@ function Multiple3DTileContent(tileset, tile, tilesetResource, contentsJson) {
52
51
  // used to help short-circuit computations after a tile was canceled.
53
52
  this._cancelCount = 0;
54
53
 
54
+ // The number of contents that turned out to be external tilesets
55
+ // in createInnerContent. When all contents are external tilesets,
56
+ // then tile.hasRenderableContent will become `false`
57
+ this._externalTilesetCount = 0;
58
+
55
59
  const contentCount = this._innerContentHeaders.length;
56
60
  this._arrayFetchPromises = new Array(contentCount);
57
61
  this._requests = new Array(contentCount);
@@ -505,6 +509,16 @@ async function createInnerContents(multipleContents) {
505
509
  const contents = await Promise.all(promises);
506
510
  multipleContents._contentsCreated = true;
507
511
  multipleContents._contents = contents.filter(defined);
512
+
513
+ // If each content is an external tileset, then the tile
514
+ // itself does not have any renderable content
515
+ if (
516
+ multipleContents._externalTilesetCount === multipleContents._contents.length
517
+ ) {
518
+ const tile = multipleContents._tile;
519
+ tile.hasRenderableContent = false;
520
+ }
521
+
508
522
  return contents;
509
523
  }
510
524
 
@@ -518,10 +532,13 @@ async function createInnerContent(multipleContents, arrayBuffer, index) {
518
532
  try {
519
533
  const preprocessed = preprocess3DTileContent(arrayBuffer);
520
534
 
535
+ const tileset = multipleContents._tileset;
536
+ const resource = multipleContents._innerContentResources[index];
537
+ const tile = multipleContents._tile;
538
+
521
539
  if (preprocessed.contentType === Cesium3DTileContentType.EXTERNAL_TILESET) {
522
- throw new RuntimeError(
523
- "External tilesets are disallowed inside multiple contents",
524
- );
540
+ multipleContents._externalTilesetCount++;
541
+ tile.hasTilesetContent = true;
525
542
  }
526
543
 
527
544
  multipleContents._disableSkipLevelOfDetail =
@@ -529,10 +546,6 @@ async function createInnerContent(multipleContents, arrayBuffer, index) {
529
546
  preprocessed.contentType === Cesium3DTileContentType.GEOMETRY ||
530
547
  preprocessed.contentType === Cesium3DTileContentType.VECTOR;
531
548
 
532
- const tileset = multipleContents._tileset;
533
- const resource = multipleContents._innerContentResources[index];
534
- const tile = multipleContents._tile;
535
-
536
549
  let content;
537
550
  const contentFactory = Cesium3DTileContentFactory[preprocessed.contentType];
538
551
  if (defined(preprocessed.binaryPayload)) {
@@ -665,7 +665,7 @@ PointPrimitive.getScreenSpaceBoundingBox = function (
665
665
  * Determines if this point equals another point. Points are equal if all their properties
666
666
  * are equal. Points in different collections can be equal.
667
667
  *
668
- * @param {PointPrimitive} other The point to compare for equality.
668
+ * @param {PointPrimitive} [other] The point to compare for equality.
669
669
  * @returns {boolean} <code>true</code> if the points are equal; otherwise, <code>false</code>.
670
670
  */
671
671
  PointPrimitive.prototype.equals = function (other) {
@@ -345,6 +345,7 @@ ResourceCache.getBufferViewLoader = function (options) {
345
345
  *
346
346
  * @param {object} options Object with the following properties:
347
347
  * @param {object} options.gltf The glTF JSON.
348
+ * @param {object} options.primitive The primitive containing the Draco extension.
348
349
  * @param {object} options.draco The Draco extension object.
349
350
  * @param {Resource} options.gltfResource The {@link Resource} containing the glTF.
350
351
  * @param {Resource} options.baseResource The {@link Resource} that paths in the glTF JSON are relative to.
@@ -354,10 +355,11 @@ ResourceCache.getBufferViewLoader = function (options) {
354
355
  */
355
356
  ResourceCache.getDracoLoader = function (options) {
356
357
  options = defaultValue(options, defaultValue.EMPTY_OBJECT);
357
- const { gltf, draco, gltfResource, baseResource } = options;
358
+ const { gltf, primitive, draco, gltfResource, baseResource } = options;
358
359
 
359
360
  //>>includeStart('debug', pragmas.debug);
360
361
  Check.typeOf.object("options.gltf", gltf);
362
+ Check.typeOf.object("options.primitive", primitive);
361
363
  Check.typeOf.object("options.draco", draco);
362
364
  Check.typeOf.object("options.gltfResource", gltfResource);
363
365
  Check.typeOf.object("options.baseResource", baseResource);
@@ -378,6 +380,7 @@ ResourceCache.getDracoLoader = function (options) {
378
380
  dracoLoader = new GltfDracoLoader({
379
381
  resourceCache: ResourceCache,
380
382
  gltf: gltf,
383
+ primitive: primitive,
381
384
  draco: draco,
382
385
  gltfResource: gltfResource,
383
386
  baseResource: baseResource,
@@ -396,6 +399,7 @@ ResourceCache.getDracoLoader = function (options) {
396
399
  * @param {Resource} options.baseResource The {@link Resource} that paths in the glTF JSON are relative to.
397
400
  * @param {FrameState} options.frameState The frame state.
398
401
  * @param {number} [options.bufferViewId] The bufferView ID corresponding to the vertex buffer.
402
+ * @param {object} [options.primitive] The primitive containing the Draco extension.
399
403
  * @param {object} [options.draco] The Draco extension object.
400
404
  * @param {string} [options.attributeSemantic] The attribute semantic, e.g. POSITION or NORMAL.
401
405
  * @param {number} [options.accessorId] The accessor ID.
@@ -418,6 +422,7 @@ ResourceCache.getVertexBufferLoader = function (options) {
418
422
  baseResource,
419
423
  frameState,
420
424
  bufferViewId,
425
+ primitive,
421
426
  draco,
422
427
  attributeSemantic,
423
428
  accessorId,
@@ -439,6 +444,7 @@ ResourceCache.getVertexBufferLoader = function (options) {
439
444
  }
440
445
 
441
446
  const hasBufferViewId = defined(bufferViewId);
447
+ const hasPrimitive = defined(primitive);
442
448
  const hasDraco = hasDracoCompression(draco, attributeSemantic);
443
449
  const hasAttributeSemantic = defined(attributeSemantic);
444
450
  const hasAccessorId = defined(accessorId);
@@ -461,6 +467,12 @@ ResourceCache.getVertexBufferLoader = function (options) {
461
467
  );
462
468
  }
463
469
 
470
+ if (hasDraco && !hasPrimitive) {
471
+ throw new DeveloperError(
472
+ "When options.draco is defined options.primitive must also be defined.",
473
+ );
474
+ }
475
+
464
476
  if (hasDraco) {
465
477
  Check.typeOf.object("options.draco", draco);
466
478
  Check.typeOf.string("options.attributeSemantic", attributeSemantic);
@@ -492,6 +504,7 @@ ResourceCache.getVertexBufferLoader = function (options) {
492
504
  gltfResource: gltfResource,
493
505
  baseResource: baseResource,
494
506
  bufferViewId: bufferViewId,
507
+ primitive: primitive,
495
508
  draco: draco,
496
509
  attributeSemantic: attributeSemantic,
497
510
  accessorId: accessorId,
@@ -522,6 +535,7 @@ function hasDracoCompression(draco, semantic) {
522
535
  * @param {Resource} options.gltfResource The {@link Resource} containing the glTF.
523
536
  * @param {Resource} options.baseResource The {@link Resource} that paths in the glTF JSON are relative to.
524
537
  * @param {FrameState} options.frameState The frame state.
538
+ * @param {object} [options.primitive] The primitive containing the Draco extension.
525
539
  * @param {object} [options.draco] The Draco extension object.
526
540
  * @param {boolean} [options.asynchronous=true] Determines if WebGL resource creation will be spread out over several frames or block until all WebGL resources are created.
527
541
  * @param {boolean} [options.loadBuffer=false] Load index buffer as a GPU index buffer.
@@ -537,6 +551,7 @@ ResourceCache.getIndexBufferLoader = function (options) {
537
551
  gltfResource,
538
552
  baseResource,
539
553
  frameState,
554
+ primitive,
540
555
  draco,
541
556
  asynchronous = true,
542
557
  loadBuffer = false,
@@ -578,6 +593,7 @@ ResourceCache.getIndexBufferLoader = function (options) {
578
593
  accessorId: accessorId,
579
594
  gltfResource: gltfResource,
580
595
  baseResource: baseResource,
596
+ primitive: primitive,
581
597
  draco: draco,
582
598
  cacheKey: cacheKey,
583
599
  asynchronous: asynchronous,
@@ -3805,6 +3805,38 @@ function getGlobeHeight(scene) {
3805
3805
  return scene.getHeight(cartographic);
3806
3806
  }
3807
3807
 
3808
+ function getMaxPrimitiveHeight(primitive, cartographic, scene) {
3809
+ let maxHeight = Number.NEGATIVE_INFINITY;
3810
+
3811
+ if (primitive instanceof PrimitiveCollection) {
3812
+ // If it's a PrimitiveCollection, iterate through its children
3813
+ const length = primitive.length;
3814
+ for (let i = 0; i < length; ++i) {
3815
+ const subPrimitive = primitive.get(i);
3816
+ const subHeight = getMaxPrimitiveHeight(
3817
+ subPrimitive,
3818
+ cartographic,
3819
+ scene,
3820
+ );
3821
+ if (defined(subHeight) && subHeight > maxHeight) {
3822
+ maxHeight = subHeight;
3823
+ }
3824
+ }
3825
+ } else if (
3826
+ primitive.isCesium3DTileset &&
3827
+ primitive.show &&
3828
+ primitive.enableCollision
3829
+ ) {
3830
+ // If it's an individual primitive, check its height
3831
+ const result = primitive.getHeight(cartographic, scene);
3832
+ if (defined(result) && result > maxHeight) {
3833
+ return result;
3834
+ }
3835
+ }
3836
+
3837
+ return maxHeight;
3838
+ }
3839
+
3808
3840
  /**
3809
3841
  * Gets the height of the loaded surface at the cartographic position.
3810
3842
  * @param {Cartographic} cartographic The cartographic position.
@@ -3831,21 +3863,13 @@ Scene.prototype.getHeight = function (cartographic, heightReference) {
3831
3863
  let maxHeight = Number.NEGATIVE_INFINITY;
3832
3864
 
3833
3865
  if (!ignore3dTiles) {
3834
- const length = this.primitives.length;
3835
- for (let i = 0; i < length; ++i) {
3836
- const primitive = this.primitives.get(i);
3837
- if (
3838
- !primitive.isCesium3DTileset ||
3839
- !primitive.show ||
3840
- !primitive.enableCollision
3841
- ) {
3842
- continue;
3843
- }
3844
-
3845
- const result = primitive.getHeight(cartographic, this);
3846
- if (defined(result) && result > maxHeight) {
3847
- maxHeight = result;
3848
- }
3866
+ const maxPrimitiveHeight = getMaxPrimitiveHeight(
3867
+ this.primitives,
3868
+ cartographic,
3869
+ this,
3870
+ );
3871
+ if (defined(maxPrimitiveHeight) && maxPrimitiveHeight > maxHeight) {
3872
+ maxHeight = maxPrimitiveHeight;
3849
3873
  }
3850
3874
  }
3851
3875
 
@@ -623,14 +623,6 @@ function handleZoom(
623
623
  orientation.pitch = camera.pitch;
624
624
  orientation.roll = camera.roll;
625
625
 
626
- if (camera.frustum instanceof OrthographicFrustum) {
627
- if (Math.abs(distance) > 0.0) {
628
- camera.zoomIn(distance);
629
- camera._adjustOrthographicFrustum(true);
630
- }
631
- return;
632
- }
633
-
634
626
  const sameStartPosition = defaultValue(
635
627
  movement.inertiaEnabled,
636
628
  Cartesian2.equals(startPosition, object._zoomMouseStart),
@@ -320,12 +320,7 @@ SpatialNode.prototype.destroyKeyframeNode = function (
320
320
  this.renderableKeyframeNodes.splice(renderableKeyframeNodeIndex, 1);
321
321
  }
322
322
 
323
- keyframeNode.spatialNode = undefined;
324
- keyframeNode.state = KeyframeNode.LoadState.UNLOADED;
325
- keyframeNode.metadata = {};
326
- keyframeNode.megatextureIndex = -1;
327
- keyframeNode.priority = -Number.MAX_VALUE;
328
- keyframeNode.highPriorityFrameNumber = -1;
323
+ keyframeNode.unload();
329
324
  };
330
325
 
331
326
  /**
@@ -337,20 +332,18 @@ SpatialNode.prototype.addKeyframeNodeToMegatextures = function (
337
332
  megatextures,
338
333
  ) {
339
334
  if (
340
- keyframeNode.state !== KeyframeNode.LoadState.RECEIVED ||
341
335
  keyframeNode.megatextureIndex !== -1 ||
342
- keyframeNode.metadata.length !== megatextures.length
336
+ keyframeNode.content.metadata.length !== megatextures.length
343
337
  ) {
344
338
  throw new DeveloperError("Keyframe node cannot be added to megatexture");
345
339
  }
346
340
 
341
+ const { metadata } = keyframeNode.content;
347
342
  for (let i = 0; i < megatextures.length; i++) {
348
343
  const megatexture = megatextures[i];
349
- keyframeNode.megatextureIndex = megatexture.add(keyframeNode.metadata[i]);
344
+ keyframeNode.megatextureIndex = megatexture.add(metadata[i]);
350
345
  }
351
346
 
352
- keyframeNode.state = KeyframeNode.LoadState.LOADED;
353
-
354
347
  const renderableKeyframeNodes = this.renderableKeyframeNodes;
355
348
  let renderableKeyframeNodeIndex = findKeyframeIndex(
356
349
  keyframeNode.keyframe,