@cesium/engine 7.0.0 → 9.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 (200) hide show
  1. package/Build/ThirdParty/Workers/z-worker-pako.js +1 -5
  2. package/Build/Workers/{chunk-7XEAYGZK.js → chunk-24YTYWNB.js} +10 -10
  3. package/Build/Workers/{chunk-IQBYFRVW.js → chunk-2632RVPI.js} +7 -7
  4. package/Build/Workers/chunk-2KACWKS4.js +501 -0
  5. package/Build/Workers/{chunk-QZAD5O7I.js → chunk-2XPLH3JY.js} +7 -7
  6. package/Build/Workers/{chunk-JY5YEZFA.js → chunk-2ZBL3MVO.js} +8 -8
  7. package/Build/Workers/{chunk-ZK5JOS3D.js → chunk-3NCVAGDA.js} +14 -14
  8. package/Build/Workers/{chunk-AR5DNBJ4.js → chunk-5R6VWLMH.js} +6 -6
  9. package/Build/Workers/{chunk-PTQQUQC3.js → chunk-5TIV3L26.js} +13 -13
  10. package/Build/Workers/{chunk-BZP4T2JJ.js → chunk-6WF3KIF5.js} +10 -10
  11. package/Build/Workers/{chunk-5WQ523AW.js → chunk-73FKKY52.js} +5 -5
  12. package/Build/Workers/{chunk-F6SE42BK.js → chunk-7COR472O.js} +15 -472
  13. package/Build/Workers/{chunk-72SANQJV.js → chunk-ADOVHYWO.js} +9 -5
  14. package/Build/Workers/{chunk-5YLJ77FF.js → chunk-BCU2LH5T.js} +12 -11
  15. package/Build/Workers/{chunk-4EBHOMFX.js → chunk-C3XBUYBO.js} +17 -17
  16. package/Build/Workers/{chunk-IX2JCCNM.js → chunk-C6OI26DR.js} +1 -1
  17. package/Build/Workers/{chunk-2HJWSU7B.js → chunk-CO35JNNE.js} +4 -4
  18. package/Build/Workers/{chunk-OVLG3FRS.js → chunk-DGDUKCJJ.js} +6 -6
  19. package/Build/Workers/{chunk-DTAIXKTO.js → chunk-DPUSFA7S.js} +6 -6
  20. package/Build/Workers/{chunk-R5X4OQT4.js → chunk-E6WXPSJS.js} +7 -7
  21. package/Build/Workers/{chunk-VK3EJHWI.js → chunk-EOXYZ34O.js} +2 -2
  22. package/Build/Workers/{chunk-RAEV7K66.js → chunk-EPKE7GE3.js} +5 -5
  23. package/Build/Workers/{chunk-GV56Q4LU.js → chunk-GFA4SMXV.js} +11 -11
  24. package/Build/Workers/{chunk-NKPBIX7F.js → chunk-GXUXEOE2.js} +1 -1
  25. package/Build/Workers/{chunk-NY3K4IM3.js → chunk-HBQPB6IH.js} +12 -12
  26. package/Build/Workers/{chunk-6HZQPRUS.js → chunk-I37B3MZ2.js} +1 -1
  27. package/Build/Workers/{chunk-VRGFV2UO.js → chunk-L4BW3RUA.js} +10 -10
  28. package/Build/Workers/{chunk-6VJVYK2V.js → chunk-LAQP3SCC.js} +2 -2
  29. package/Build/Workers/{chunk-PNBGBETF.js → chunk-LQJ5FFFR.js} +10 -10
  30. package/Build/Workers/{chunk-UAEW6HKG.js → chunk-M2AYBTNH.js} +13 -13
  31. package/Build/Workers/{chunk-YUCVWAY6.js → chunk-MWV7IZK4.js} +7 -7
  32. package/Build/Workers/{chunk-JXDC723O.js → chunk-N4KXMWQU.js} +2 -2
  33. package/Build/Workers/{chunk-XWXM2O2R.js → chunk-NP2GYYE5.js} +6 -6
  34. package/Build/Workers/{chunk-GEJTYLCO.js → chunk-NZWNZA6S.js} +5 -5
  35. package/Build/Workers/{chunk-LZGHD6NY.js → chunk-P2YAAMT2.js} +15 -15
  36. package/Build/Workers/{chunk-S6SKF6DT.js → chunk-P4XKB3QZ.js} +5 -5
  37. package/Build/Workers/{chunk-U2VCRRQW.js → chunk-PXB7T27O.js} +6 -6
  38. package/Build/Workers/{chunk-RV7ZYPFT.js → chunk-QCQUZGXI.js} +4 -4
  39. package/Build/Workers/{chunk-JJ4VBOQ3.js → chunk-QKBGRKKG.js} +4 -4
  40. package/Build/Workers/{chunk-ODW7WYM4.js → chunk-RMOEYCZW.js} +2 -2
  41. package/Build/Workers/{chunk-ZUA2UUNV.js → chunk-RSJXEO2A.js} +2 -2
  42. package/Build/Workers/{chunk-UDO6BFSF.js → chunk-RV7ZOSS6.js} +13 -13
  43. package/Build/Workers/{chunk-LZ7JIV3K.js → chunk-SE4PXOEA.js} +17 -17
  44. package/Build/Workers/{chunk-S4MAZ3SS.js → chunk-SS4ESNE3.js} +2 -2
  45. package/Build/Workers/{chunk-AIPU2VSX.js → chunk-TJBU6GML.js} +6 -6
  46. package/Build/Workers/{chunk-5M3U6ZMA.js → chunk-TZORKRNK.js} +1 -1
  47. package/Build/Workers/{chunk-MY3VNFGQ.js → chunk-VR5RBW52.js} +7 -7
  48. package/Build/Workers/{chunk-FP6GYBFX.js → chunk-WHUSTDIB.js} +10 -10
  49. package/Build/Workers/{chunk-5HDYHG3F.js → chunk-X2F6BEPY.js} +13 -13
  50. package/Build/Workers/{chunk-WZU2YLWG.js → chunk-X6XOMPWL.js} +3 -3
  51. package/Build/Workers/{chunk-UGK3FCDY.js → chunk-YDVSBWEO.js} +1 -1
  52. package/Build/Workers/{chunk-46UD5ABS.js → chunk-YV4H2Y7M.js} +4 -4
  53. package/Build/Workers/{chunk-WBQCVXR3.js → chunk-Z7FQLK6N.js} +4 -4
  54. package/Build/Workers/{chunk-L2ZN645J.js → chunk-ZNVSKMQ2.js} +6 -6
  55. package/Build/Workers/{chunk-JCNXK6EL.js → chunk-ZYPTP7GS.js} +11 -11
  56. package/Build/Workers/combineGeometry.js +24 -23
  57. package/Build/Workers/createBoxGeometry.js +18 -17
  58. package/Build/Workers/createBoxOutlineGeometry.js +16 -15
  59. package/Build/Workers/createCircleGeometry.js +26 -25
  60. package/Build/Workers/createCircleOutlineGeometry.js +19 -18
  61. package/Build/Workers/createCoplanarPolygonGeometry.js +33 -32
  62. package/Build/Workers/createCoplanarPolygonOutlineGeometry.js +31 -30
  63. package/Build/Workers/createCorridorGeometry.js +29 -28
  64. package/Build/Workers/createCorridorOutlineGeometry.js +28 -27
  65. package/Build/Workers/createCylinderGeometry.js +20 -19
  66. package/Build/Workers/createCylinderOutlineGeometry.js +18 -17
  67. package/Build/Workers/createEllipseGeometry.js +26 -25
  68. package/Build/Workers/createEllipseOutlineGeometry.js +19 -18
  69. package/Build/Workers/createEllipsoidGeometry.js +19 -18
  70. package/Build/Workers/createEllipsoidOutlineGeometry.js +18 -17
  71. package/Build/Workers/createFrustumGeometry.js +18 -17
  72. package/Build/Workers/createFrustumOutlineGeometry.js +18 -17
  73. package/Build/Workers/createGeometry.js +54 -33
  74. package/Build/Workers/createGroundPolylineGeometry.js +22 -21
  75. package/Build/Workers/createPlaneGeometry.js +16 -15
  76. package/Build/Workers/createPlaneOutlineGeometry.js +15 -14
  77. package/Build/Workers/createPolygonGeometry.js +33 -32
  78. package/Build/Workers/createPolygonOutlineGeometry.js +30 -29
  79. package/Build/Workers/createPolylineGeometry.js +25 -24
  80. package/Build/Workers/createPolylineVolumeGeometry.js +31 -30
  81. package/Build/Workers/createPolylineVolumeOutlineGeometry.js +27 -26
  82. package/Build/Workers/createRectangleGeometry.js +27 -26
  83. package/Build/Workers/createRectangleOutlineGeometry.js +20 -19
  84. package/Build/Workers/createSimplePolylineGeometry.js +23 -22
  85. package/Build/Workers/createSphereGeometry.js +19 -18
  86. package/Build/Workers/createSphereOutlineGeometry.js +18 -17
  87. package/Build/Workers/createTaskProcessorWorker.js +3 -3
  88. package/Build/Workers/createVectorTileClampedPolylines.js +14 -14
  89. package/Build/Workers/createVectorTileGeometries.js +24 -23
  90. package/Build/Workers/createVectorTilePoints.js +12 -12
  91. package/Build/Workers/createVectorTilePolygons.js +22 -21
  92. package/Build/Workers/createVectorTilePolylines.js +14 -14
  93. package/Build/Workers/createVerticesFromGoogleEarthEnterpriseBuffer.js +22 -21
  94. package/Build/Workers/createVerticesFromHeightmap.js +22 -21
  95. package/Build/Workers/createVerticesFromQuantizedTerrainMesh.js +19 -18
  96. package/Build/Workers/createWallGeometry.js +24 -23
  97. package/Build/Workers/createWallOutlineGeometry.js +23 -22
  98. package/Build/Workers/decodeDraco.js +11 -11
  99. package/Build/Workers/decodeGoogleEarthEnterprisePacket.js +5 -5
  100. package/Build/Workers/decodeI3S.js +601 -92
  101. package/Build/Workers/transcodeKTX2.js +7 -7
  102. package/Build/Workers/transferTypedArrayTest.js +1 -1
  103. package/Build/Workers/upsampleQuantizedTerrainMesh.js +22 -21
  104. package/Source/Core/Check.d.ts +127 -0
  105. package/Source/Core/Check.js +0 -1
  106. package/Source/Core/Ellipsoid.js +6 -0
  107. package/Source/Core/Geometry.js +1 -1
  108. package/Source/Core/IntersectionTests.js +6 -3
  109. package/Source/Core/Ion.js +1 -1
  110. package/Source/Core/PixelFormat.js +5 -0
  111. package/Source/Core/PolygonGeometry.js +1 -1
  112. package/Source/Core/Transforms.js +3 -0
  113. package/Source/Core/VerticalExaggeration.js +2 -1
  114. package/Source/Core/srgbToLinear.js +32 -0
  115. package/Source/DataSources/CzmlDataSource.js +51 -23
  116. package/Source/DataSources/DataSourceDisplay.js +27 -0
  117. package/Source/DataSources/Entity.js +20 -2
  118. package/Source/DataSources/GeometryUpdaterSet.js +114 -0
  119. package/Source/DataSources/GeometryVisualizer.js +19 -83
  120. package/Source/Renderer/Context.js +10 -0
  121. package/Source/Renderer/ContextLimits.js +2 -0
  122. package/Source/Renderer/demodernizeShader.js +4 -1
  123. package/Source/Scene/ArcGisMapService.js +1 -1
  124. package/Source/Scene/Axis.js +12 -7
  125. package/Source/Scene/Billboard.js +32 -0
  126. package/Source/Scene/BillboardCollection.js +1 -1
  127. package/Source/Scene/BingMapsImageryProvider.js +4 -0
  128. package/Source/Scene/Camera.js +46 -4
  129. package/Source/Scene/Cesium3DTilesVoxelProvider.js +2 -9
  130. package/Source/Scene/Cesium3DTileset.js +10 -7
  131. package/Source/Scene/Cesium3DTilesetBaseTraversal.js +2 -4
  132. package/Source/Scene/FrameState.js +5 -0
  133. package/Source/Scene/Globe.js +0 -67
  134. package/Source/Scene/GlobeTranslucencyState.js +1 -1
  135. package/Source/Scene/GltfPipeline/updateVersion.js +69 -68
  136. package/Source/Scene/I3SDataProvider.js +270 -53
  137. package/Source/Scene/I3SDecoder.js +8 -1
  138. package/Source/Scene/I3SFeature.js +2 -5
  139. package/Source/Scene/I3SField.js +136 -31
  140. package/Source/Scene/I3SGeometry.js +70 -2
  141. package/Source/Scene/I3SLayer.js +55 -10
  142. package/Source/Scene/I3SNode.js +175 -18
  143. package/Source/Scene/I3SStatistics.js +94 -0
  144. package/Source/Scene/I3SSublayer.js +176 -0
  145. package/Source/Scene/I3SSymbology.js +337 -0
  146. package/Source/Scene/KeyframeNode.js +1 -1
  147. package/Source/Scene/Label.js +33 -0
  148. package/Source/Scene/LabelCollection.js +2 -1
  149. package/Source/Scene/Model/pickModel.js +25 -7
  150. package/Source/Scene/PickFramebuffer.js +37 -2
  151. package/Source/Scene/Picking.js +113 -39
  152. package/Source/Scene/Primitive.js +6 -5
  153. package/Source/Scene/Scene.js +126 -42
  154. package/Source/Scene/ScreenSpaceCameraController.js +21 -7
  155. package/Source/Scene/SensorVolumePortionToDisplay.js +69 -0
  156. package/Source/Scene/SpatialNode.js +12 -19
  157. package/Source/Scene/StructuralMetadata.js +1 -1
  158. package/Source/Scene/VoxelBoxShape.js +67 -6
  159. package/Source/Scene/VoxelCell.js +273 -0
  160. package/Source/Scene/VoxelCylinderShape.js +117 -163
  161. package/Source/Scene/VoxelEllipsoidShape.js +255 -304
  162. package/Source/Scene/VoxelPrimitive.js +109 -15
  163. package/Source/Scene/VoxelRenderResources.js +12 -3
  164. package/Source/Scene/VoxelShape.js +7 -4
  165. package/Source/Scene/VoxelTraversal.js +76 -54
  166. package/Source/Scene/buildVoxelDrawCommands.js +23 -0
  167. package/Source/Scene/createGooglePhotorealistic3DTileset.js +1 -0
  168. package/Source/Scene/processVoxelProperties.js +3 -0
  169. package/Source/Shaders/Voxels/IntersectBox.glsl +21 -47
  170. package/Source/Shaders/Voxels/IntersectBox.js +21 -47
  171. package/Source/Shaders/Voxels/IntersectClippingPlanes.glsl +1 -1
  172. package/Source/Shaders/Voxels/IntersectClippingPlanes.js +1 -1
  173. package/Source/Shaders/Voxels/IntersectCylinder.glsl +76 -203
  174. package/Source/Shaders/Voxels/IntersectCylinder.js +76 -203
  175. package/Source/Shaders/Voxels/IntersectEllipsoid.glsl +220 -229
  176. package/Source/Shaders/Voxels/IntersectEllipsoid.js +220 -229
  177. package/Source/Shaders/Voxels/IntersectLongitude.glsl +102 -0
  178. package/Source/Shaders/Voxels/IntersectLongitude.js +104 -0
  179. package/Source/Shaders/Voxels/IntersectionUtils.glsl +33 -11
  180. package/Source/Shaders/Voxels/IntersectionUtils.js +33 -11
  181. package/Source/Shaders/Voxels/Megatexture.glsl +1 -2
  182. package/Source/Shaders/Voxels/Megatexture.js +1 -2
  183. package/Source/Shaders/Voxels/Octree.glsl +14 -9
  184. package/Source/Shaders/Voxels/Octree.js +14 -9
  185. package/Source/Shaders/Voxels/VoxelFS.glsl +128 -40
  186. package/Source/Shaders/Voxels/VoxelFS.js +128 -40
  187. package/Source/Shaders/Voxels/VoxelUtils.glsl +31 -0
  188. package/Source/Shaders/Voxels/VoxelUtils.js +33 -0
  189. package/Source/Shaders/Voxels/convertUvToBox.glsl +24 -3
  190. package/Source/Shaders/Voxels/convertUvToBox.js +24 -4
  191. package/Source/Shaders/Voxels/convertUvToCylinder.glsl +64 -40
  192. package/Source/Shaders/Voxels/convertUvToCylinder.js +64 -40
  193. package/Source/Shaders/Voxels/convertUvToEllipsoid.glsl +100 -91
  194. package/Source/Shaders/Voxels/convertUvToEllipsoid.js +100 -91
  195. package/Source/ThirdParty/Workers/z-worker-pako.js +1 -1
  196. package/Source/Workers/createGeometry.js +40 -11
  197. package/Source/Workers/decodeI3S.js +720 -94
  198. package/index.d.ts +542 -40
  199. package/index.js +75 -66
  200. package/package.json +2 -2
@@ -22,6 +22,9 @@ import PolylineCollection from "./PolylineCollection.js";
22
22
  import VoxelShapeType from "./VoxelShapeType.js";
23
23
  import VoxelTraversal from "./VoxelTraversal.js";
24
24
  import CustomShader from "./Model/CustomShader.js";
25
+ import Cartographic from "../Core/Cartographic.js";
26
+ import Ellipsoid from "../Core/Ellipsoid.js";
27
+ import VerticalExaggeration from "../Core/VerticalExaggeration.js";
25
28
 
26
29
  /**
27
30
  * A primitive that renders voxel data from a {@link VoxelProvider}.
@@ -231,6 +234,14 @@ function VoxelPrimitive(options) {
231
234
  defaultValue(options.modelMatrix, Matrix4.IDENTITY)
232
235
  );
233
236
 
237
+ /**
238
+ * Model matrix with vertical exaggeration applied. Only used for BOX shape type.
239
+ *
240
+ * @type {Matrix4}
241
+ * @private
242
+ */
243
+ this._exaggeratedModelMatrix = Matrix4.clone(this._modelMatrix);
244
+
234
245
  /**
235
246
  * The primitive's model matrix multiplied by the provider's model matrix.
236
247
  * This member is not known until the provider is ready.
@@ -320,18 +331,12 @@ function VoxelPrimitive(options) {
320
331
  */
321
332
  this._transformNormalLocalToWorld = new Matrix3();
322
333
 
323
- /**
324
- * @type {number}
325
- * @private
326
- */
327
- this._stepSizeUv = 1.0;
328
-
329
334
  // Rendering
330
335
  /**
331
336
  * @type {boolean}
332
337
  * @private
333
338
  */
334
- this._jitter = true;
339
+ this._jitter = false;
335
340
 
336
341
  /**
337
342
  * @type {boolean}
@@ -469,12 +474,25 @@ function initialize(primitive, provider) {
469
474
  primitive.minClippingBounds = VoxelShapeType.getMinBounds(shapeType);
470
475
  primitive.maxClippingBounds = VoxelShapeType.getMaxBounds(shapeType);
471
476
 
477
+ // Initialize the exaggerated versions of bounds and model matrix
478
+ primitive._exaggeratedMinBounds = Cartesian3.clone(
479
+ primitive._minBounds,
480
+ primitive._exaggeratedMinBounds
481
+ );
482
+ primitive._exaggeratedMaxBounds = Cartesian3.clone(
483
+ primitive._maxBounds,
484
+ primitive._exaggeratedMaxBounds
485
+ );
486
+ primitive._exaggeratedModelMatrix = Matrix4.clone(
487
+ primitive._modelMatrix,
488
+ primitive._exaggeratedModelMatrix
489
+ );
490
+
472
491
  checkTransformAndBounds(primitive, provider);
473
492
 
474
493
  // Create the shape object, and update it so it is valid for VoxelTraversal
475
494
  const ShapeConstructor = VoxelShapeType.getShapeConstructor(shapeType);
476
495
  primitive._shape = new ShapeConstructor();
477
- updateVerticalExaggeration(primitive);
478
496
  primitive._shapeVisible = updateShapeAndTransforms(
479
497
  primitive,
480
498
  primitive._shape,
@@ -531,7 +549,7 @@ Object.defineProperties(VoxelPrimitive.prototype, {
531
549
  */
532
550
  orientedBoundingBox: {
533
551
  get: function () {
534
- return this.shape.orientedBoundingBox;
552
+ return this._shape.orientedBoundingBox;
535
553
  },
536
554
  },
537
555
 
@@ -1132,21 +1150,28 @@ VoxelPrimitive.prototype.update = function (frameState) {
1132
1150
  cameraPositionWorld,
1133
1151
  uniforms.cameraPositionUv
1134
1152
  );
1135
- uniforms.stepSize = this._stepSizeUv * this._stepSizeMultiplier;
1153
+ uniforms.stepSize = this._stepSizeMultiplier;
1136
1154
 
1137
1155
  // Render the primitive
1138
1156
  const command = frameState.passes.pick
1139
1157
  ? this._drawCommandPick
1158
+ : frameState.passes.pickVoxel
1159
+ ? this._drawCommandPickVoxel
1140
1160
  : this._drawCommand;
1141
1161
  command.boundingVolume = shape.boundingSphere;
1142
1162
  frameState.commandList.push(command);
1143
1163
  };
1144
1164
 
1165
+ const scratchExaggerationScale = new Cartesian3();
1166
+ const scratchExaggerationCenter = new Cartesian3();
1167
+ const scratchCartographicCenter = new Cartographic();
1168
+ const scratchExaggerationTranslation = new Cartesian3();
1169
+
1145
1170
  /**
1146
1171
  * Update the exaggerated bounds of a primitive to account for vertical exaggeration
1147
1172
  * Currently only applies to Ellipsoid shape type
1148
1173
  * @param {VoxelPrimitive} primitive
1149
- * @param {FrameState} [frameState]
1174
+ * @param {FrameState} frameState
1150
1175
  * @private
1151
1176
  */
1152
1177
  function updateVerticalExaggeration(primitive, frameState) {
@@ -1158,16 +1183,87 @@ function updateVerticalExaggeration(primitive, frameState) {
1158
1183
  primitive._maxBounds,
1159
1184
  primitive._exaggeratedMaxBounds
1160
1185
  );
1161
- if (defined(frameState) && primitive.shape === VoxelShapeType.ELLIPSOID) {
1186
+
1187
+ if (primitive.shape === VoxelShapeType.ELLIPSOID) {
1188
+ // Apply the exaggeration by stretching the height bounds
1162
1189
  const relativeHeight = frameState.verticalExaggerationRelativeHeight;
1163
1190
  const exaggeration = frameState.verticalExaggeration;
1164
1191
  primitive._exaggeratedMinBounds.z =
1165
1192
  (primitive._minBounds.z - relativeHeight) * exaggeration + relativeHeight;
1166
1193
  primitive._exaggeratedMaxBounds.z =
1167
1194
  (primitive._maxBounds.z - relativeHeight) * exaggeration + relativeHeight;
1195
+ } else if (primitive.shape === VoxelShapeType.BOX) {
1196
+ // Apply the exaggeration via the model matrix
1197
+ const exaggerationScale = Cartesian3.fromElements(
1198
+ 1.0,
1199
+ 1.0,
1200
+ frameState.verticalExaggeration,
1201
+ scratchExaggerationScale
1202
+ );
1203
+ primitive._exaggeratedModelMatrix = Matrix4.multiplyByScale(
1204
+ primitive._modelMatrix,
1205
+ exaggerationScale,
1206
+ primitive._exaggeratedModelMatrix
1207
+ );
1208
+ primitive._exaggeratedModelMatrix = Matrix4.multiplyByTranslation(
1209
+ primitive._exaggeratedModelMatrix,
1210
+ computeBoxExaggerationTranslation(primitive, frameState),
1211
+ primitive._exaggeratedModelMatrix
1212
+ );
1168
1213
  }
1169
1214
  }
1170
1215
 
1216
+ function computeBoxExaggerationTranslation(primitive, frameState) {
1217
+ // Compute translation based on box center, relative height, and exaggeration
1218
+ const {
1219
+ shapeTransform = Matrix4.IDENTITY,
1220
+ globalTransform = Matrix4.IDENTITY,
1221
+ } = primitive._provider;
1222
+
1223
+ // Find the Cartesian position of the center of the OBB
1224
+ const initialCenter = Matrix4.getTranslation(
1225
+ shapeTransform,
1226
+ scratchExaggerationCenter
1227
+ );
1228
+ const intermediateCenter = Matrix4.multiplyByPoint(
1229
+ primitive._modelMatrix,
1230
+ initialCenter,
1231
+ scratchExaggerationCenter
1232
+ );
1233
+ const transformedCenter = Matrix4.multiplyByPoint(
1234
+ globalTransform,
1235
+ intermediateCenter,
1236
+ scratchExaggerationCenter
1237
+ );
1238
+
1239
+ // Find the cartographic height
1240
+ const ellipsoid = Ellipsoid.WGS84;
1241
+ const centerCartographic = ellipsoid.cartesianToCartographic(
1242
+ transformedCenter,
1243
+ scratchCartographicCenter
1244
+ );
1245
+
1246
+ let centerHeight = 0.0;
1247
+ if (defined(centerCartographic)) {
1248
+ centerHeight = centerCartographic.height;
1249
+ }
1250
+
1251
+ // Find the shift that will put the center in the right position relative
1252
+ // to relativeHeight, after it is scaled by verticalExaggeration
1253
+ const exaggeratedHeight = VerticalExaggeration.getHeight(
1254
+ centerHeight,
1255
+ frameState.verticalExaggeration,
1256
+ frameState.verticalExaggerationRelativeHeight
1257
+ );
1258
+
1259
+ return Cartesian3.fromElements(
1260
+ 0.0,
1261
+ 0.0,
1262
+ (exaggeratedHeight - centerHeight) / frameState.verticalExaggeration,
1263
+ scratchExaggerationTranslation
1264
+ );
1265
+ }
1266
+
1171
1267
  /**
1172
1268
  * Initialize primitive properties that are derived from the voxel provider
1173
1269
  * @param {VoxelPrimitive} primitive
@@ -1252,7 +1348,7 @@ function checkTransformAndBounds(primitive, provider) {
1252
1348
  // Compound model matrix = global transform * model matrix * shape transform
1253
1349
  Matrix4.multiplyTransformation(
1254
1350
  globalTransform,
1255
- primitive._modelMatrix,
1351
+ primitive._exaggeratedModelMatrix,
1256
1352
  primitive._compoundModelMatrix
1257
1353
  );
1258
1354
  Matrix4.multiplyTransformation(
@@ -1343,8 +1439,6 @@ function updateShapeAndTransforms(primitive, shape, provider) {
1343
1439
  );
1344
1440
 
1345
1441
  // Set member variables when the shape is dirty
1346
- const dimensions = provider.dimensions;
1347
- primitive._stepSizeUv = shape.computeApproximateStepSize(dimensions);
1348
1442
  primitive._transformPositionWorldToUv = Matrix4.multiplyTransformation(
1349
1443
  transformPositionLocalToUv,
1350
1444
  transformPositionWorldToLocal,
@@ -3,11 +3,13 @@ import combine from "../Core/combine.js";
3
3
  import defined from "../Core/defined.js";
4
4
  import ShaderBuilder from "../Renderer/ShaderBuilder.js";
5
5
  import ShaderDestination from "../Renderer/ShaderDestination.js";
6
+ import VoxelUtils from "../Shaders/Voxels/VoxelUtils.js";
6
7
  import VoxelFS from "../Shaders/Voxels/VoxelFS.js";
7
8
  import VoxelVS from "../Shaders/Voxels/VoxelVS.js";
8
9
  import IntersectionUtils from "../Shaders/Voxels/IntersectionUtils.js";
9
10
  import IntersectDepth from "../Shaders/Voxels/IntersectDepth.js";
10
11
  import IntersectClippingPlanes from "../Shaders/Voxels/IntersectClippingPlanes.js";
12
+ import IntersectLongitude from "../Shaders/Voxels/IntersectLongitude.js";
11
13
  import IntersectBox from "../Shaders/Voxels/IntersectBox.js";
12
14
  import IntersectCylinder from "../Shaders/Voxels/IntersectCylinder.js";
13
15
  import IntersectEllipsoid from "../Shaders/Voxels/IntersectEllipsoid.js";
@@ -88,6 +90,7 @@ function VoxelRenderResources(primitive) {
88
90
  customShader.fragmentShaderText,
89
91
  "#line 0",
90
92
  Octree,
93
+ VoxelUtils,
91
94
  IntersectionUtils,
92
95
  Megatexture,
93
96
  ]);
@@ -123,7 +126,6 @@ function VoxelRenderResources(primitive) {
123
126
 
124
127
  const shapeType = primitive._provider.shape;
125
128
  if (shapeType === "BOX") {
126
- shaderBuilder.addDefine("SHAPE_BOX", undefined, ShaderDestination.FRAGMENT);
127
129
  shaderBuilder.addFragmentLines([
128
130
  convertUvToBox,
129
131
  IntersectBox,
@@ -131,15 +133,22 @@ function VoxelRenderResources(primitive) {
131
133
  ]);
132
134
  } else if (shapeType === "CYLINDER") {
133
135
  shaderBuilder.addFragmentLines([
136
+ convertUvToCylinder,
137
+ IntersectLongitude,
134
138
  IntersectCylinder,
135
139
  Intersection,
136
- convertUvToCylinder,
137
140
  ]);
138
141
  } else if (shapeType === "ELLIPSOID") {
142
+ shaderBuilder.addDefine(
143
+ "SHAPE_ELLIPSOID",
144
+ undefined,
145
+ ShaderDestination.FRAGMENT
146
+ );
139
147
  shaderBuilder.addFragmentLines([
148
+ convertUvToEllipsoid,
149
+ IntersectLongitude,
140
150
  IntersectEllipsoid,
141
151
  Intersection,
142
- convertUvToEllipsoid,
143
152
  ]);
144
153
  }
145
154
 
@@ -118,13 +118,16 @@ VoxelShape.prototype.computeOrientedBoundingBoxForTile =
118
118
  DeveloperError.throwInstantiationError;
119
119
 
120
120
  /**
121
- * Computes an approximate step size for raymarching the root tile of a voxel grid.
121
+ * Computes an oriented bounding box for a specified sample within a specified tile.
122
122
  * The update function must be called before calling this function.
123
123
  *
124
- * @param {Cartesian3} voxelDimensions The voxel grid dimensions for a tile.
125
- * @returns {number} The step size.
124
+ * @param {SpatialNode} spatialNode The spatial node containing the sample
125
+ * @param {Cartesian3} tileDimensions The size of the tile in number of samples, before padding
126
+ * @param {Cartesian3} tileUv The sample coordinate within the tile
127
+ * @param {OrientedBoundingBox} result The oriented bounding box that will be set to enclose the specified sample
128
+ * @returns {OrientedBoundingBox} The oriented bounding box.
126
129
  */
127
- VoxelShape.prototype.computeApproximateStepSize =
130
+ VoxelShape.prototype.computeOrientedBoundingBoxForSample =
128
131
  DeveloperError.throwInstantiationError;
129
132
 
130
133
  /**
@@ -49,16 +49,14 @@ function VoxelTraversal(
49
49
  */
50
50
  this._primitive = primitive;
51
51
 
52
- const length = types.length;
53
-
54
52
  /**
55
53
  * @type {Megatexture[]}
56
54
  * @readonly
57
55
  */
58
- this.megatextures = new Array(length);
56
+ this.megatextures = new Array(types.length);
59
57
 
60
58
  // TODO make sure to split the maximumTextureMemoryByteLength across all the megatextures
61
- for (let i = 0; i < length; i++) {
59
+ for (let i = 0; i < types.length; i++) {
62
60
  const type = types[i];
63
61
  const componentCount = MetadataType.getComponentCount(type);
64
62
  const componentType = componentTypes[i];
@@ -218,6 +216,18 @@ function VoxelTraversal(
218
216
  this.leafNodeTexelSizeUv = new Cartesian2();
219
217
  }
220
218
 
219
+ /**
220
+ * Finds a keyframe node in the traversal
221
+ *
222
+ * @param {number} megatextureIndex
223
+ * @returns {KeyframeNode}
224
+ */
225
+ VoxelTraversal.prototype.findKeyframeNode = function (megatextureIndex) {
226
+ return this._keyframeNodesInMegatexture.find(function (keyframeNode) {
227
+ return keyframeNode.megatextureIndex === megatextureIndex;
228
+ });
229
+ };
230
+
221
231
  function binaryTreeWeightingRecursive(arr, start, end, depth) {
222
232
  if (start > end) {
223
233
  return;
@@ -382,10 +392,7 @@ VoxelTraversal.prototype.destroy = function () {
382
392
  * @private
383
393
  */
384
394
  function recomputeBoundingVolumesRecursive(that, node) {
385
- const primitive = that._primitive;
386
- const shape = primitive._shape;
387
- const dimensions = primitive._provider.dimensions;
388
- node.computeBoundingVolumes(shape, dimensions);
395
+ node.computeBoundingVolumes(that._primitive._shape);
389
396
  if (defined(node.children)) {
390
397
  for (let i = 0; i < 8; i++) {
391
398
  const child = node.children[i];
@@ -410,12 +417,11 @@ function requestData(that, keyframeNode) {
410
417
  return;
411
418
  }
412
419
 
413
- const primitive = that._primitive;
414
- const provider = primitive._provider;
420
+ const provider = that._primitive._provider;
415
421
 
416
422
  function postRequestSuccess(result) {
417
423
  that._simultaneousRequestCount--;
418
- const length = primitive._provider.types.length;
424
+ const length = provider.types.length;
419
425
 
420
426
  if (!defined(result)) {
421
427
  keyframeNode.state = KeyframeNode.LoadState.UNAVAILABLE;
@@ -434,7 +440,7 @@ function requestData(that, keyframeNode) {
434
440
  const data = result[i];
435
441
  const expectedLength = tileVoxelCount * channelCount;
436
442
  if (data.length === expectedLength) {
437
- keyframeNode.metadatas[i] = data;
443
+ keyframeNode.metadata[i] = data;
438
444
  // State is received only when all metadata requests have been received
439
445
  keyframeNode.state = KeyframeNode.LoadState.RECEIVED;
440
446
  } else {
@@ -492,42 +498,22 @@ function loadAndUnload(that, frameState) {
492
498
  const frameNumber = that._frameNumber;
493
499
  const primitive = that._primitive;
494
500
  const shape = primitive._shape;
495
- const { dimensions } = primitive;
496
501
  const targetScreenSpaceError = primitive.screenSpaceError;
497
502
  const priorityQueue = that._priorityQueue;
498
- const keyframeLocation = that._keyframeLocation;
499
503
  const keyframeCount = that._keyframeCount;
500
- const rootNode = that.rootNode;
504
+
505
+ const previousKeyframe = CesiumMath.clamp(
506
+ Math.floor(that._keyframeLocation),
507
+ 0,
508
+ keyframeCount - 2
509
+ );
510
+ const nextKeyframe = previousKeyframe + 1;
501
511
 
502
512
  const { camera, context, pixelRatio } = frameState;
503
513
  const { positionWC, frustum } = camera;
504
514
  const screenHeight = context.drawingBufferHeight / pixelRatio;
505
515
  const screenSpaceErrorMultiplier = screenHeight / frustum.sseDenominator;
506
516
 
507
- function keyframePriority(previousKeyframe, keyframe, nextKeyframe) {
508
- const keyframeDifference = Math.min(
509
- Math.abs(keyframe - previousKeyframe),
510
- Math.abs(keyframe - nextKeyframe)
511
- );
512
- const maxKeyframeDifference = Math.max(
513
- previousKeyframe,
514
- keyframeCount - nextKeyframe - 1,
515
- 1
516
- );
517
- const keyframeFactor = Math.pow(
518
- 1.0 - keyframeDifference / maxKeyframeDifference,
519
- 4.0
520
- );
521
- const binaryTreeFactor = Math.exp(
522
- -that._binaryTreeKeyframeWeighting[keyframe]
523
- );
524
- return CesiumMath.lerp(
525
- binaryTreeFactor,
526
- keyframeFactor,
527
- 0.15 + 0.85 * keyframeFactor
528
- );
529
- }
530
-
531
517
  /**
532
518
  * @ignore
533
519
  * @param {SpatialNode} spatialNode
@@ -545,13 +531,6 @@ function loadAndUnload(that, frameState) {
545
531
  }
546
532
  spatialNode.visitedFrameNumber = frameNumber;
547
533
 
548
- const previousKeyframe = CesiumMath.clamp(
549
- Math.floor(keyframeLocation),
550
- 0,
551
- keyframeCount - 2
552
- );
553
- const nextKeyframe = previousKeyframe + 1;
554
-
555
534
  // Create keyframe nodes at the playhead.
556
535
  // If they already exist, nothing will be created.
557
536
  if (keyframeCount === 1) {
@@ -561,16 +540,21 @@ function loadAndUnload(that, frameState) {
561
540
  spatialNode.createKeyframeNode(k);
562
541
  }
563
542
  }
564
- const ssePriority = mapInfiniteRangeToZeroOne(spatialNode.screenSpaceError);
543
+ const { screenSpaceError, keyframeNodes } = spatialNode;
544
+ const ssePriority = mapInfiniteRangeToZeroOne(screenSpaceError);
565
545
 
566
546
  let hasLoadedKeyframe = false;
567
- const keyframeNodes = spatialNode.keyframeNodes;
568
547
  for (let i = 0; i < keyframeNodes.length; i++) {
569
548
  const keyframeNode = keyframeNodes[i];
570
549
 
571
550
  keyframeNode.priority =
572
551
  10.0 * ssePriority +
573
- keyframePriority(previousKeyframe, keyframeNode.keyframe, nextKeyframe);
552
+ keyframePriority(
553
+ previousKeyframe,
554
+ keyframeNode.keyframe,
555
+ nextKeyframe,
556
+ that
557
+ );
574
558
 
575
559
  if (
576
560
  keyframeNode.state !== KeyframeNode.LoadState.UNAVAILABLE &&
@@ -584,16 +568,14 @@ function loadAndUnload(that, frameState) {
584
568
  }
585
569
  }
586
570
 
587
- const meetsScreenSpaceError =
588
- spatialNode.screenSpaceError < targetScreenSpaceError;
589
- if (meetsScreenSpaceError || !hasLoadedKeyframe) {
571
+ if (screenSpaceError < targetScreenSpaceError || !hasLoadedKeyframe) {
590
572
  // Free up memory
591
573
  spatialNode.children = undefined;
592
574
  return;
593
575
  }
594
576
 
595
577
  if (!defined(spatialNode.children)) {
596
- spatialNode.constructChildNodes(shape, dimensions);
578
+ spatialNode.constructChildNodes(shape);
597
579
  }
598
580
  for (let childIndex = 0; childIndex < 8; childIndex++) {
599
581
  const child = spatialNode.children[childIndex];
@@ -601,9 +583,11 @@ function loadAndUnload(that, frameState) {
601
583
  }
602
584
  }
603
585
 
586
+ // Add all the nodes to the queue, to sort them by priority.
604
587
  priorityQueue.reset();
605
- addToQueueRecursive(rootNode, CullingVolume.MASK_INDETERMINATE);
588
+ addToQueueRecursive(that.rootNode, CullingVolume.MASK_INDETERMINATE);
606
589
 
590
+ // Move the nodes from the queue to array of high priority nodes.
607
591
  const highPriorityKeyframeNodes = that._highPriorityKeyframeNodes;
608
592
  let highPriorityKeyframeNodeCount = 0;
609
593
  let highPriorityKeyframeNode;
@@ -616,6 +600,8 @@ function loadAndUnload(that, frameState) {
616
600
  highPriorityKeyframeNodeCount++;
617
601
  }
618
602
 
603
+ // Sort the list of keyframe nodes in the megatexture by priority, so
604
+ // we can remove the lowest priority nodes if we need space.
619
605
  const keyframeNodesInMegatexture = that._keyframeNodesInMegatexture;
620
606
  // TODO: some of the megatexture state should be stored once, not duplicate for each megatexture
621
607
  const megatexture = that.megatextures[0];
@@ -628,6 +614,8 @@ function loadAndUnload(that, frameState) {
628
614
  return b.highPriorityFrameNumber - a.highPriorityFrameNumber;
629
615
  });
630
616
 
617
+ // Add the high priority nodes to the megatexture,
618
+ // removing existing lower-priority nodes if necessary.
631
619
  let destroyedCount = 0;
632
620
  let addedCount = 0;
633
621
 
@@ -675,6 +663,40 @@ function loadAndUnload(that, frameState) {
675
663
  }
676
664
  }
677
665
 
666
+ /**
667
+ * Compute a priority for a keyframe node.
668
+ *
669
+ * @private
670
+ * @param {number} previousKeyframe
671
+ * @param {number} keyframe
672
+ * @param {number} nextKeyframe
673
+ * @param {VoxelTraversal} traversal
674
+ * @returns {number} The computed priority
675
+ */
676
+ function keyframePriority(previousKeyframe, keyframe, nextKeyframe, traversal) {
677
+ const keyframeDifference = Math.min(
678
+ Math.abs(keyframe - previousKeyframe),
679
+ Math.abs(keyframe - nextKeyframe)
680
+ );
681
+ const maxKeyframeDifference = Math.max(
682
+ previousKeyframe,
683
+ traversal._keyframeCount - nextKeyframe - 1,
684
+ 1
685
+ );
686
+ const keyframeFactor = Math.pow(
687
+ 1.0 - keyframeDifference / maxKeyframeDifference,
688
+ 4.0
689
+ );
690
+ const binaryTreeFactor = Math.exp(
691
+ -traversal._binaryTreeKeyframeWeighting[keyframe]
692
+ );
693
+ return CesiumMath.lerp(
694
+ binaryTreeFactor,
695
+ keyframeFactor,
696
+ 0.15 + 0.85 * keyframeFactor
697
+ );
698
+ }
699
+
678
700
  /**
679
701
  * @function
680
702
  *
@@ -58,8 +58,17 @@ function buildVoxelDrawCommands(primitive, context) {
58
58
  // Compile shaders
59
59
  const shaderBuilderPick = shaderBuilder.clone();
60
60
  shaderBuilderPick.addDefine("PICKING", undefined, ShaderDestination.FRAGMENT);
61
+ const shaderBuilderPickVoxel = shaderBuilder.clone();
62
+ shaderBuilderPickVoxel.addDefine(
63
+ "PICKING_VOXEL",
64
+ undefined,
65
+ ShaderDestination.FRAGMENT
66
+ );
61
67
  const shaderProgram = shaderBuilder.buildShaderProgram(context);
62
68
  const shaderProgramPick = shaderBuilderPick.buildShaderProgram(context);
69
+ const shaderProgramPickVoxel = shaderBuilderPickVoxel.buildShaderProgram(
70
+ context
71
+ );
63
72
  const renderState = RenderState.fromCache({
64
73
  cull: {
65
74
  enabled: true,
@@ -98,6 +107,14 @@ function buildVoxelDrawCommands(primitive, context) {
98
107
  drawCommandPick.shaderProgram = shaderProgramPick;
99
108
  drawCommandPick.pickOnly = true;
100
109
 
110
+ // Create the pick voxels draw command
111
+ const drawCommandPickVoxel = DrawCommand.shallowClone(
112
+ drawCommand,
113
+ new DrawCommand()
114
+ );
115
+ drawCommandPickVoxel.shaderProgram = shaderProgramPickVoxel;
116
+ drawCommandPickVoxel.pickOnly = true;
117
+
101
118
  // Delete the old shader programs
102
119
  if (defined(primitive._drawCommand)) {
103
120
  const command = primitive._drawCommand;
@@ -109,9 +126,15 @@ function buildVoxelDrawCommands(primitive, context) {
109
126
  command.shaderProgram =
110
127
  command.shaderProgram && command.shaderProgram.destroy();
111
128
  }
129
+ if (defined(primitive._drawCommandPickVoxel)) {
130
+ const command = primitive._drawCommandPickVoxel;
131
+ command.shaderProgram =
132
+ command.shaderProgram && command.shaderProgram.destroy();
133
+ }
112
134
 
113
135
  primitive._drawCommand = drawCommand;
114
136
  primitive._drawCommandPick = drawCommandPick;
137
+ primitive._drawCommandPickVoxel = drawCommandPickVoxel;
115
138
  }
116
139
 
117
140
  export default buildVoxelDrawCommands;
@@ -46,6 +46,7 @@ async function createGooglePhotorealistic3DTileset(key, options) {
46
46
  options.maximumCacheOverflowBytes,
47
47
  1024 * 1024 * 1024
48
48
  );
49
+ options.enableCollision = defaultValue(options.enableCollision, true);
49
50
 
50
51
  key = defaultValue(key, GoogleMaps.defaultApiKey);
51
52
  if (!defined(key)) {
@@ -153,6 +153,9 @@ function processVoxelProperties(renderResources, primitive) {
153
153
  shaderBuilder.addStructField(voxelStructId, "vec3", "viewDirWorld");
154
154
  shaderBuilder.addStructField(voxelStructId, "vec3", "surfaceNormal");
155
155
  shaderBuilder.addStructField(voxelStructId, "float", "travelDistance");
156
+ shaderBuilder.addStructField(voxelStructId, "int", "stepCount");
157
+ shaderBuilder.addStructField(voxelStructId, "int", "tileIndex");
158
+ shaderBuilder.addStructField(voxelStructId, "int", "sampleIndex");
156
159
 
157
160
  // FragmentInput struct
158
161
  const fragmentInputStructId = "FragmentInput";