@cesium/engine 12.0.0 → 13.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 (152) hide show
  1. package/Build/Workers/{chunk-2RHMHHJH.js → chunk-22NU5WU5.js} +2 -2
  2. package/Build/Workers/{chunk-3OM5QZSI.js → chunk-2IIE2UZ3.js} +2 -2
  3. package/Build/Workers/{chunk-WQCX7U65.js → chunk-2OD54CUD.js} +7 -7
  4. package/Build/Workers/{chunk-IT6AWHFV.js → chunk-2TSF7N76.js} +2 -2
  5. package/Build/Workers/{chunk-AL7BHP36.js → chunk-3VHIUS7I.js} +6 -6
  6. package/Build/Workers/{chunk-MSY2AAW2.js → chunk-3ZMTG4X5.js} +4 -4
  7. package/Build/Workers/{chunk-GZG526CC.js → chunk-4HS475MU.js} +14 -14
  8. package/Build/Workers/{chunk-4IQPX22D.js → chunk-4IM6WQEI.js} +6 -6
  9. package/Build/Workers/{chunk-7DSVCRFD.js → chunk-6HWW6KNV.js} +6 -6
  10. package/Build/Workers/{chunk-GUW6BS72.js → chunk-6ZOS2ACR.js} +7 -7
  11. package/Build/Workers/{chunk-7OISMGQF.js → chunk-BFNZUP2C.js} +7 -41
  12. package/Build/Workers/{chunk-WW5RTJ72.js → chunk-BLTSMJIP.js} +1 -1
  13. package/Build/Workers/{chunk-ES6Q5HWK.js → chunk-BZMHXDKV.js} +13 -13
  14. package/Build/Workers/{chunk-5YKJKOFE.js → chunk-CQDSGG3R.js} +7 -7
  15. package/Build/Workers/{chunk-ZZNBFQL5.js → chunk-CUMDCSMT.js} +11 -11
  16. package/Build/Workers/{chunk-BQNTN4CC.js → chunk-D3VPMNUR.js} +13 -13
  17. package/Build/Workers/{chunk-4ESQ3DN2.js → chunk-DIAH2ZTB.js} +9 -9
  18. package/Build/Workers/{chunk-VQZNBD3T.js → chunk-EXDSJZ7J.js} +4 -4
  19. package/Build/Workers/{chunk-T6FZFMTF.js → chunk-FANORJU6.js} +2 -2
  20. package/Build/Workers/{chunk-US3L7FXC.js → chunk-FLPIQK2R.js} +6 -6
  21. package/Build/Workers/{chunk-J64XIF5C.js → chunk-GBXJIWAZ.js} +34 -8
  22. package/Build/Workers/{chunk-TQK4D4AR.js → chunk-GJZQSAES.js} +7 -7
  23. package/Build/Workers/{chunk-X67KKHI7.js → chunk-GNG3V432.js} +4 -4
  24. package/Build/Workers/{chunk-B4AZL6Q4.js → chunk-H4Y7ADFL.js} +5 -5
  25. package/Build/Workers/{chunk-SXJ37VUC.js → chunk-H7BML7HH.js} +6 -6
  26. package/Build/Workers/{chunk-5FSKL7US.js → chunk-HMMPNR4Z.js} +12 -12
  27. package/Build/Workers/{chunk-ARTM66DL.js → chunk-JISDBAYP.js} +5 -5
  28. package/Build/Workers/{chunk-6DYMJ57Z.js → chunk-KCCTLUKK.js} +10 -10
  29. package/Build/Workers/{chunk-X7VRF25X.js → chunk-KKVKSTWC.js} +5 -5
  30. package/Build/Workers/{chunk-JGGZ3H4W.js → chunk-KRCUHV7P.js} +1 -1
  31. package/Build/Workers/{chunk-AOCENJVH.js → chunk-MMILY4S7.js} +11 -11
  32. package/Build/Workers/{chunk-GYHHNFW5.js → chunk-MSKD73KW.js} +10 -10
  33. package/Build/Workers/{chunk-C4IAULHW.js → chunk-NVFEDMX4.js} +15 -15
  34. package/Build/Workers/{chunk-YANQEHO5.js → chunk-OUIF26MQ.js} +6 -6
  35. package/Build/Workers/{chunk-GKBICLGC.js → chunk-OZZD3VY4.js} +17 -17
  36. package/Build/Workers/{chunk-56LALJCU.js → chunk-PD2MCNV7.js} +2 -2
  37. package/Build/Workers/{chunk-62YGXNGC.js → chunk-PMNQULFU.js} +7 -7
  38. package/Build/Workers/{chunk-3OHDXGFC.js → chunk-Q4MTXEB7.js} +6 -6
  39. package/Build/Workers/{chunk-4XPGN5Y7.js → chunk-RC5N5SJL.js} +7 -7
  40. package/Build/Workers/{chunk-IL6SMMDD.js → chunk-RGZWZ4PP.js} +4 -4
  41. package/Build/Workers/{chunk-GMGUR5GM.js → chunk-RIQGQMS4.js} +4 -4
  42. package/Build/Workers/{chunk-VUCVRDLD.js → chunk-RR4M3ZGF.js} +7 -7
  43. package/Build/Workers/{chunk-3UJV3W4Y.js → chunk-S4SCKDK4.js} +1 -1
  44. package/Build/Workers/{chunk-VGT4ONMC.js → chunk-T5H7YWC7.js} +17 -17
  45. package/Build/Workers/{chunk-QXBRZZQS.js → chunk-W2DVQETH.js} +10 -10
  46. package/Build/Workers/{chunk-HYUTWUXN.js → chunk-W2E67GLE.js} +13 -13
  47. package/Build/Workers/{chunk-3X2LXRHU.js → chunk-WXJY6NDI.js} +13 -13
  48. package/Build/Workers/{chunk-W2Q2F7JS.js → chunk-XQP37R5E.js} +5 -5
  49. package/Build/Workers/{chunk-VJVTWBXB.js → chunk-YBDL7YPF.js} +1 -1
  50. package/Build/Workers/{chunk-HILBDZUP.js → chunk-YDEZMDB7.js} +2 -2
  51. package/Build/Workers/{chunk-JRULXFCC.js → chunk-Z7OYBX6P.js} +5 -5
  52. package/Build/Workers/{chunk-2B5H7KIN.js → chunk-ZIWULRRD.js} +1 -1
  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 +31 -32
  78. package/Build/Workers/createPolylineVolumeOutlineGeometry.js +25 -25
  79. package/Build/Workers/createRectangleGeometry.js +25 -25
  80. package/Build/Workers/createRectangleOutlineGeometry.js +18 -18
  81. package/Build/Workers/createSimplePolylineGeometry.js +21 -21
  82. package/Build/Workers/createSphereGeometry.js +17 -17
  83. package/Build/Workers/createSphereOutlineGeometry.js +16 -16
  84. package/Build/Workers/createTaskProcessorWorker.js +3 -3
  85. package/Build/Workers/createVectorTileClampedPolylines.js +13 -13
  86. package/Build/Workers/createVectorTileGeometries.js +22 -22
  87. package/Build/Workers/createVectorTilePoints.js +12 -12
  88. package/Build/Workers/createVectorTilePolygons.js +20 -20
  89. package/Build/Workers/createVectorTilePolylines.js +13 -13
  90. package/Build/Workers/createVerticesFromGoogleEarthEnterpriseBuffer.js +20 -20
  91. package/Build/Workers/createVerticesFromHeightmap.js +20 -20
  92. package/Build/Workers/createVerticesFromQuantizedTerrainMesh.js +17 -17
  93. package/Build/Workers/createWallGeometry.js +22 -22
  94. package/Build/Workers/createWallOutlineGeometry.js +21 -21
  95. package/Build/Workers/decodeDraco.js +11 -11
  96. package/Build/Workers/decodeGoogleEarthEnterprisePacket.js +5 -5
  97. package/Build/Workers/decodeI3S.js +10 -10
  98. package/Build/Workers/transcodeKTX2.js +7 -7
  99. package/Build/Workers/transferTypedArrayTest.js +1 -1
  100. package/Build/Workers/upsampleQuantizedTerrainMesh.js +20 -20
  101. package/Source/Core/BingMapsGeocoderService.js +2 -0
  102. package/Source/Core/GoogleGeocoderService.js +110 -0
  103. package/Source/Core/ITwinPlatform.js +359 -0
  104. package/Source/Core/Ion.js +1 -1
  105. package/Source/Core/IonGeocodeProviderType.js +33 -0
  106. package/Source/Core/IonGeocoderService.js +72 -0
  107. package/Source/Core/Rectangle.js +0 -20
  108. package/Source/Core/TrackingReferenceFrame.js +45 -0
  109. package/Source/DataSources/Entity.js +15 -1
  110. package/Source/DataSources/EntityView.js +55 -4
  111. package/Source/DataSources/SampledProperty.js +24 -0
  112. package/Source/Renderer/ContextLimits.js +1 -1
  113. package/Source/Renderer/Texture.js +104 -92
  114. package/Source/Scene/ArcGisMapService.js +1 -1
  115. package/Source/Scene/Cesium3DTilesetStatistics.js +109 -42
  116. package/Source/Scene/DerivedCommand.js +109 -16
  117. package/Source/Scene/DynamicEnvironmentMapManager.js +130 -8
  118. package/Source/Scene/GltfTextureLoader.js +16 -1
  119. package/Source/Scene/ITwinData.js +138 -0
  120. package/Source/Scene/Label.js +17 -3
  121. package/Source/Scene/MetadataClassProperty.js +26 -0
  122. package/Source/Scene/MetadataPicking.js +108 -17
  123. package/Source/Scene/MetadataType.js +20 -0
  124. package/Source/Scene/Model/Extensions/Gpm/GltfMeshPrimitiveGpmLoader.js +6 -11
  125. package/Source/Scene/Model/Model3DTileContent.js +23 -1
  126. package/Source/Scene/Model/ModelStatistics.js +33 -5
  127. package/Source/Scene/Model/PointCloudStylingPipelineStage.js +2 -1
  128. package/Source/Scene/PickedMetadataInfo.js +21 -3
  129. package/Source/Scene/Picking.js +7 -1
  130. package/Source/Scene/PostProcessStage.js +14 -17
  131. package/Source/Scene/PostProcessStageCollection.js +4 -16
  132. package/Source/Scene/PostProcessStageLibrary.js +13 -51
  133. package/Source/Scene/PropertyAttributeProperty.js +15 -3
  134. package/Source/Scene/PropertyTextureProperty.js +12 -0
  135. package/Source/Scene/Scene.js +17 -2
  136. package/Source/Scene/SkyBox.js +23 -4
  137. package/Source/Scene/UrlTemplateImageryProvider.js +5 -5
  138. package/Source/Scene/createGooglePhotorealistic3DTileset.js +55 -16
  139. package/Source/Scene/getMetadataProperty.js +48 -0
  140. package/Source/Shaders/Builtin/Functions/reverseLogDepth.glsl +1 -1
  141. package/Source/Shaders/Builtin/Functions/reverseLogDepth.js +1 -1
  142. package/Source/Shaders/ConvolveSpecularMapFS.glsl +1 -1
  143. package/Source/Shaders/ConvolveSpecularMapFS.js +1 -1
  144. package/Source/Shaders/Model/ModelFS.glsl +7 -0
  145. package/Source/Shaders/Model/ModelFS.js +7 -0
  146. package/Source/Shaders/Model/ModelVS.glsl +9 -1
  147. package/Source/Shaders/Model/ModelVS.js +9 -1
  148. package/Source/Shaders/PostProcessStages/AmbientOcclusionGenerate.glsl +66 -37
  149. package/Source/Shaders/PostProcessStages/AmbientOcclusionGenerate.js +66 -37
  150. package/index.d.ts +286 -40
  151. package/index.js +59 -53
  152. package/package.json +1 -1
@@ -1,3 +1,4 @@
1
+ import { MetadataComponentType } from "@cesium/engine";
1
2
  import defined from "../Core/defined.js";
2
3
  import DrawCommand from "../Renderer/DrawCommand.js";
3
4
  import RenderState from "../Renderer/RenderState.js";
@@ -416,6 +417,98 @@ function getGlslType(classProperty) {
416
417
  return `ivec${componentCount}`;
417
418
  }
418
419
 
420
+ /**
421
+ * Returns a shader statement that applies the inverse of the
422
+ * value transform to the given value, based on the given offset
423
+ * and scale.
424
+ *
425
+ * @param {string} input The input value
426
+ * @param {string} offset The offset
427
+ * @param {string} scale The scale
428
+ * @returns {string} The statement
429
+ */
430
+ function unapplyValueTransform(input, offset, scale) {
431
+ return `((${input} - float(${offset})) / float(${scale}))`;
432
+ }
433
+
434
+ /**
435
+ * Returns a shader statement that applies the inverse of the
436
+ * normalization, based on the given component type
437
+ *
438
+ * @param {string} input The input value
439
+ * @param {string} componentType The component type
440
+ * @returns {string} The statement
441
+ */
442
+ function unnormalize(input, componentType) {
443
+ const max = MetadataComponentType.getMaximum(componentType);
444
+ return `(${input}) / float(${max})`;
445
+ }
446
+
447
+ /**
448
+ * Creates a shader statement that returns the value of the specified
449
+ * property, normalized to the range [0, 1].
450
+ *
451
+ * @param {MetadataClassProperty} classProperty The class property
452
+ * @param {object} metadataProperty The metadata property, either
453
+ * a `PropertyTextureProperty` or a `PropertyAttributeProperty`
454
+ * @returns {string} The string
455
+ */
456
+ function getSourceValueStringScalar(classProperty, metadataProperty) {
457
+ let result = `float(value)`;
458
+
459
+ // The 'hasValueTransform' indicates whether the property
460
+ // (or its class property) did define an 'offset' or 'scale'.
461
+ // Even when they had not been defined in the JSON, they are
462
+ // defined in the object, with default values.
463
+ if (metadataProperty.hasValueTransform) {
464
+ const offset = metadataProperty.offset;
465
+ const scale = metadataProperty.scale;
466
+ result = unapplyValueTransform(result, offset, scale);
467
+ }
468
+ if (!classProperty.normalized) {
469
+ result = unnormalize(result, classProperty.componentType);
470
+ }
471
+ return result;
472
+ }
473
+
474
+ /**
475
+ * Creates a shader statement that returns the value of the specified
476
+ * component of the given property, normalized to the range [0, 1].
477
+ *
478
+ * @param {MetadataClassProperty} classProperty The class property
479
+ * @param {object} metadataProperty The metadata property, either
480
+ * a `PropertyTextureProperty` or a `PropertyAttributeProperty`
481
+ * @param {string} componentName The name, in ["x", "y", "z", "w"]
482
+ * @returns {string} The string
483
+ */
484
+ function getSourceValueStringComponent(
485
+ classProperty,
486
+ metadataProperty,
487
+ componentName,
488
+ ) {
489
+ const valueString = `value.${componentName}`;
490
+ let result = `float(${valueString})`;
491
+
492
+ // The 'hasValueTransform' indicates whether the property
493
+ // (or its class property) did define an 'offset' or 'scale'.
494
+ // Even when they had not been defined in the JSON, they are
495
+ // defined in the object, with default values
496
+ // Note that in the 'PropertyTextureProperty' and the
497
+ // 'PropertyAttributeProperty', these values are
498
+ // stored as "object types" (like 'Cartesian2'), whereas
499
+ // in the 'MetadataClassProperty', they are stored as
500
+ // "array types", e.g. a `[number, number]`
501
+ if (metadataProperty.hasValueTransform) {
502
+ const offset = metadataProperty.offset[componentName];
503
+ const scale = metadataProperty.scale[componentName];
504
+ result = unapplyValueTransform(result, offset, scale);
505
+ }
506
+ if (!classProperty.normalized) {
507
+ result = unnormalize(result, classProperty.componentType);
508
+ }
509
+ return result;
510
+ }
511
+
419
512
  /**
420
513
  * Creates a new `ShaderProgram` from the given input that renders metadata
421
514
  * values into the frame buffer, according to the given picked metadata info.
@@ -452,34 +545,34 @@ function getPickMetadataShaderProgram(
452
545
  return shader;
453
546
  }
454
547
 
548
+ const metadataProperty = pickedMetadataInfo.metadataProperty;
455
549
  const classProperty = pickedMetadataInfo.classProperty;
456
550
  const glslType = getGlslType(classProperty);
457
551
 
458
552
  // Define the components that will go into the output `metadataValues`.
553
+ // This will be the 'color' that is written into the frame buffer,
554
+ // meaning that the values should be in [0.0, 1.0], and will become
555
+ // values in [0, 255] in the frame buffer.
459
556
  // By default, all of them are 0.0.
460
557
  const sourceValueStrings = ["0.0", "0.0", "0.0", "0.0"];
461
558
  const componentCount = getComponentCount(classProperty);
462
559
  if (componentCount === 1) {
463
- // When the property is a scalar, store its value directly
464
- // in `metadataValues.x`
465
- sourceValueStrings[0] = `float(value)`;
560
+ // When the property is a scalar, store the source value
561
+ // string directly in `metadataValues.x`
562
+ sourceValueStrings[0] = getSourceValueStringScalar(
563
+ classProperty,
564
+ metadataProperty,
565
+ );
466
566
  } else {
467
567
  // When the property is an array, store the array elements
468
568
  // in `metadataValues.x/y/z/w`
469
- const components = ["x", "y", "z", "w"];
470
- for (let i = 0; i < componentCount; i++) {
471
- const component = components[i];
472
- const valueString = `value.${component}`;
473
- sourceValueStrings[i] = `float(${valueString})`;
474
- }
475
- }
476
-
477
- // Make sure that the `metadataValues` components are all in
478
- // the range [0, 1] (which will result in RGBA components
479
- // in [0, 255] during rendering)
480
- if (!classProperty.normalized) {
569
+ const componentNames = ["x", "y", "z", "w"];
481
570
  for (let i = 0; i < componentCount; i++) {
482
- sourceValueStrings[i] += " / 255.0";
571
+ sourceValueStrings[i] = getSourceValueStringComponent(
572
+ classProperty,
573
+ metadataProperty,
574
+ componentNames[i],
575
+ );
483
576
  }
484
577
  }
485
578
 
@@ -12,6 +12,7 @@ import PixelFormat from "../Core/PixelFormat.js";
12
12
  import SceneMode from "./SceneMode.js";
13
13
  import Transforms from "../Core/Transforms.js";
14
14
  import ComputeCommand from "../Renderer/ComputeCommand.js";
15
+ import ContextLimits from "../Renderer/ContextLimits.js";
15
16
  import CubeMap from "../Renderer/CubeMap.js";
16
17
  import Framebuffer from "../Renderer/Framebuffer.js";
17
18
  import Texture from "../Renderer/Texture.js";
@@ -79,7 +80,11 @@ function DynamicEnvironmentMapManager(options) {
79
80
 
80
81
  options = defaultValue(options, defaultValue.EMPTY_OBJECT);
81
82
 
82
- const mipmapLevels = defaultValue(options.mipmapLevels, 10);
83
+ const mipmapLevels = Math.min(
84
+ defaultValue(options.mipmapLevels, 10),
85
+ Math.log2(ContextLimits.maximumCubeMapSize),
86
+ );
87
+
83
88
  this._mipmapLevels = mipmapLevels;
84
89
  this._radianceMapComputeCommands = new Array(6);
85
90
  this._convolutionComputeCommands = new Array((mipmapLevels - 1) * 6);
@@ -95,7 +100,8 @@ function DynamicEnvironmentMapManager(options) {
95
100
  this._radianceCubeMap = undefined;
96
101
  this._irradianceMapTexture = undefined;
97
102
 
98
- this._sphericalHarmonicCoefficients = new Array(9);
103
+ this._sphericalHarmonicCoefficients =
104
+ DynamicEnvironmentMapManager.DEFAULT_SPHERICAL_HARMONIC_COEFFICIENTS.slice();
99
105
 
100
106
  this._lastTime = new JulianDate();
101
107
  const width = Math.pow(2, mipmapLevels - 1);
@@ -294,6 +300,63 @@ Object.defineProperties(DynamicEnvironmentMapManager.prototype, {
294
300
  },
295
301
  });
296
302
 
303
+ // Internally manage a queue of commands across all instances to prevent too many commands from being added in a single frame and using too much memory at once.
304
+ DynamicEnvironmentMapManager._maximumComputeCommandCount = 8; // This value is updated once a context is created.
305
+ DynamicEnvironmentMapManager._activeComputeCommandCount = 0;
306
+ DynamicEnvironmentMapManager._nextFrameCommandQueue = [];
307
+ /**
308
+ * Add a command to the queue. If possible, it will be added to the list of commands for the next frame. Otherwise, it will be added to a backlog
309
+ * and attempted next frame.
310
+ * @private
311
+ * @param {ComputeCommand} command The created command
312
+ * @param {FrameState} frameState The current frame state
313
+ */
314
+ DynamicEnvironmentMapManager._queueCommand = (command, frameState) => {
315
+ if (
316
+ DynamicEnvironmentMapManager._activeComputeCommandCount >=
317
+ DynamicEnvironmentMapManager._maximumComputeCommandCount
318
+ ) {
319
+ // Command will instead be scheduled next frame
320
+ DynamicEnvironmentMapManager._nextFrameCommandQueue.push(command);
321
+ return;
322
+ }
323
+
324
+ frameState.commandList.push(command);
325
+ DynamicEnvironmentMapManager._activeComputeCommandCount++;
326
+ };
327
+ /**
328
+ * If there are any backlogged commands, queue up as many as possible for the next frame.
329
+ * @private
330
+ * @param {FrameState} frameState The current frame state
331
+ */
332
+ DynamicEnvironmentMapManager._updateCommandQueue = (frameState) => {
333
+ DynamicEnvironmentMapManager._maximumComputeCommandCount = Math.log2(
334
+ ContextLimits.maximumCubeMapSize,
335
+ ); // Scale relative to GPU resources available
336
+
337
+ if (
338
+ DynamicEnvironmentMapManager._nextFrameCommandQueue.length > 0 &&
339
+ DynamicEnvironmentMapManager._activeComputeCommandCount <
340
+ DynamicEnvironmentMapManager._maximumComputeCommandCount
341
+ ) {
342
+ let command = DynamicEnvironmentMapManager._nextFrameCommandQueue.shift();
343
+ while (
344
+ defined(command) &&
345
+ DynamicEnvironmentMapManager._activeComputeCommandCount <
346
+ DynamicEnvironmentMapManager._maximumComputeCommandCount
347
+ ) {
348
+ if (command.canceled) {
349
+ command = DynamicEnvironmentMapManager._nextFrameCommandQueue.shift();
350
+ continue;
351
+ }
352
+
353
+ frameState.commandList.push(command);
354
+ DynamicEnvironmentMapManager._activeComputeCommandCount++;
355
+ command = DynamicEnvironmentMapManager._nextFrameCommandQueue.shift();
356
+ }
357
+ }
358
+ };
359
+
297
360
  /**
298
361
  * Sets the owner for the input DynamicEnvironmentMapManager if there wasn't another owner.
299
362
  * Destroys the owner's previous DynamicEnvironmentMapManager if setting is successful.
@@ -333,15 +396,25 @@ DynamicEnvironmentMapManager.setOwner = function (
333
396
  DynamicEnvironmentMapManager.prototype.reset = function () {
334
397
  let length = this._radianceMapComputeCommands.length;
335
398
  for (let i = 0; i < length; ++i) {
399
+ if (defined(this._radianceMapComputeCommands[i])) {
400
+ this._radianceMapComputeCommands[i].canceled = true;
401
+ DynamicEnvironmentMapManager._activeComputeCommandCount--;
402
+ }
336
403
  this._radianceMapComputeCommands[i] = undefined;
337
404
  }
338
405
 
339
406
  length = this._convolutionComputeCommands.length;
340
407
  for (let i = 0; i < length; ++i) {
408
+ if (defined(this._convolutionComputeCommands[i])) {
409
+ this._convolutionComputeCommands[i].canceled = true;
410
+ DynamicEnvironmentMapManager._activeComputeCommandCount--;
411
+ }
341
412
  this._convolutionComputeCommands[i] = undefined;
342
413
  }
343
414
 
344
415
  if (defined(this._irradianceComputeCommand)) {
416
+ this._irradianceComputeCommand.canceled = true;
417
+ DynamicEnvironmentMapManager._activeComputeCommandCount--;
345
418
  this._irradianceComputeCommand = undefined;
346
419
  }
347
420
 
@@ -519,14 +592,17 @@ function updateRadianceMap(manager, frameState) {
519
592
  framebuffer._unBind();
520
593
  framebuffer.destroy();
521
594
 
595
+ DynamicEnvironmentMapManager._activeComputeCommandCount--;
596
+
522
597
  if (!commands.some(defined)) {
523
598
  manager._convolutionsCommandsDirty = true;
524
599
  manager._shouldRegenerateShaders = true;
525
600
  }
526
601
  },
527
602
  });
528
- frameState.commandList.push(command);
603
+
529
604
  manager._radianceMapComputeCommands[i] = command;
605
+ DynamicEnvironmentMapManager._queueCommand(command, frameState);
530
606
  i++;
531
607
  }
532
608
  manager._radianceCommandsDirty = false;
@@ -553,7 +629,7 @@ function updateSpecularMaps(manager, frameState) {
553
629
  const getPostExecute = (index, texture, face, level) => () => {
554
630
  // Copy output texture to corresponding face and mipmap level
555
631
  const commands = manager._convolutionComputeCommands;
556
- if (!defined(commands[index])) {
632
+ if (!defined(commands[index]) || commands[index].canceled) {
557
633
  // This command was cancelled
558
634
  return;
559
635
  }
@@ -561,6 +637,7 @@ function updateSpecularMaps(manager, frameState) {
561
637
 
562
638
  radianceCubeMap.copyFace(frameState, texture, face, level);
563
639
  facesCopied++;
640
+ DynamicEnvironmentMapManager._activeComputeCommandCount--;
564
641
 
565
642
  // All faces and levels have been copied
566
643
  if (facesCopied === manager._specularMapTextures.length) {
@@ -610,7 +687,7 @@ function updateSpecularMaps(manager, frameState) {
610
687
  owner: manager,
611
688
  uniformMap: {
612
689
  u_roughness: () => level / (mipmapLevels - 1),
613
- u_radianceTexture: () => radianceCubeMap,
690
+ u_radianceTexture: () => radianceCubeMap ?? context.defaultTexture,
614
691
  u_faceDirection: () => {
615
692
  return CubeMap.getDirection(face, scratchCartesian);
616
693
  },
@@ -618,7 +695,7 @@ function updateSpecularMaps(manager, frameState) {
618
695
  postExecute: getPostExecute(index, texture, face, level),
619
696
  });
620
697
  manager._convolutionComputeCommands[index] = command;
621
- frameState.commandList.push(command);
698
+ DynamicEnvironmentMapManager._queueCommand(command, frameState);
622
699
  ++index;
623
700
  }
624
701
 
@@ -663,7 +740,7 @@ function updateIrradianceResources(manager, frameState) {
663
740
  fragmentShaderSource: fs,
664
741
  outputTexture: texture,
665
742
  uniformMap: {
666
- u_radianceMap: () => manager._radianceCubeMap,
743
+ u_radianceMap: () => manager._radianceCubeMap ?? context.defaultTexture,
667
744
  },
668
745
  postExecute: () => {
669
746
  if (!defined(manager._irradianceComputeCommand)) {
@@ -673,10 +750,12 @@ function updateIrradianceResources(manager, frameState) {
673
750
  manager._irradianceTextureDirty = false;
674
751
  manager._irradianceComputeCommand = undefined;
675
752
  manager._sphericalHarmonicCoefficientsDirty = true;
753
+
754
+ DynamicEnvironmentMapManager._activeComputeCommandCount--;
676
755
  },
677
756
  });
678
757
  manager._irradianceComputeCommand = command;
679
- frameState.commandList.push(command);
758
+ DynamicEnvironmentMapManager._queueCommand(command, frameState);
680
759
  manager._irradianceTextureDirty = true;
681
760
  }
682
761
 
@@ -727,8 +806,13 @@ function updateSphericalHarmonicCoefficients(manager, frameState) {
727
806
  */
728
807
  DynamicEnvironmentMapManager.prototype.update = function (frameState) {
729
808
  const mode = frameState.mode;
809
+ const isSupported =
810
+ // A FrameState type works here because the function only references the context parameter.
811
+ // @ts-ignore
812
+ DynamicEnvironmentMapManager.isDynamicUpdateSupported(frameState);
730
813
 
731
814
  if (
815
+ !isSupported ||
732
816
  !this.enabled ||
733
817
  !this.shouldUpdate ||
734
818
  !defined(this._position) ||
@@ -738,6 +822,8 @@ DynamicEnvironmentMapManager.prototype.update = function (frameState) {
738
822
  return;
739
823
  }
740
824
 
825
+ DynamicEnvironmentMapManager._updateCommandQueue(frameState);
826
+
741
827
  const dynamicLighting = frameState.atmosphere.dynamicLighting;
742
828
  const regenerateEnvironmentMap =
743
829
  atmosphereNeedsUpdate(this, frameState) ||
@@ -841,12 +927,48 @@ DynamicEnvironmentMapManager.prototype.destroy = function () {
841
927
  return destroyObject(this);
842
928
  };
843
929
 
930
+ /**
931
+ * Returns <code>true</code> if dynamic updates are supported in the current WebGL rendering context.
932
+ * Dynamic updates requires the EXT_color_buffer_float or EXT_color_buffer_half_float extension.
933
+ *
934
+ * @param {Scene} scene The object containing the rendering context
935
+ * @returns {boolean} true if supported
936
+ */
937
+ DynamicEnvironmentMapManager.isDynamicUpdateSupported = function (scene) {
938
+ const context = scene.context;
939
+ return context.halfFloatingPointTexture || context.colorBufferFloat;
940
+ };
941
+
844
942
  /**
845
943
  * Average hue of ground color on earth, a warm green-gray.
846
944
  * @type {Color}
945
+ * @readonly
847
946
  */
848
947
  DynamicEnvironmentMapManager.AVERAGE_EARTH_GROUND_COLOR = Object.freeze(
849
948
  Color.fromCssColorString("#717145"),
850
949
  );
851
950
 
951
+ /**
952
+ * The default third order spherical harmonic coefficients used for the diffuse color of image-based lighting, a white ambient light with low intensity.
953
+ * <p>
954
+ * There are nine <code>Cartesian3</code> coefficients.
955
+ * The order of the coefficients is: L<sub>0,0</sub>, L<sub>1,-1</sub>, L<sub>1,0</sub>, L<sub>1,1</sub>, L<sub>2,-2</sub>, L<sub>2,-1</sub>, L<sub>2,0</sub>, L<sub>2,1</sub>, L<sub>2,2</sub>
956
+ * </p>
957
+ * @readonly
958
+ * @type {Cartesian3[]}
959
+ * @see {@link https://graphics.stanford.edu/papers/envmap/envmap.pdf|An Efficient Representation for Irradiance Environment Maps}
960
+ */
961
+ DynamicEnvironmentMapManager.DEFAULT_SPHERICAL_HARMONIC_COEFFICIENTS =
962
+ Object.freeze([
963
+ Object.freeze(new Cartesian3(0.35449, 0.35449, 0.35449)),
964
+ Cartesian3.ZERO,
965
+ Cartesian3.ZERO,
966
+ Cartesian3.ZERO,
967
+ Cartesian3.ZERO,
968
+ Cartesian3.ZERO,
969
+ Cartesian3.ZERO,
970
+ Cartesian3.ZERO,
971
+ Cartesian3.ZERO,
972
+ ]);
973
+
852
974
  export default DynamicEnvironmentMapManager;
@@ -170,6 +170,7 @@ GltfTextureLoader.prototype.load = async function () {
170
170
  function CreateTextureJob() {
171
171
  this.gltf = undefined;
172
172
  this.textureInfo = undefined;
173
+ this.textureId = undefined;
173
174
  this.image = undefined;
174
175
  this.context = undefined;
175
176
  this.texture = undefined;
@@ -178,12 +179,14 @@ function CreateTextureJob() {
178
179
  CreateTextureJob.prototype.set = function (
179
180
  gltf,
180
181
  textureInfo,
182
+ textureId,
181
183
  image,
182
184
  mipLevels,
183
185
  context,
184
186
  ) {
185
187
  this.gltf = gltf;
186
188
  this.textureInfo = textureInfo;
189
+ this.textureId = textureId;
187
190
  this.image = image;
188
191
  this.mipLevels = mipLevels;
189
192
  this.context = context;
@@ -193,13 +196,21 @@ CreateTextureJob.prototype.execute = function () {
193
196
  this.texture = createTexture(
194
197
  this.gltf,
195
198
  this.textureInfo,
199
+ this.textureId,
196
200
  this.image,
197
201
  this.mipLevels,
198
202
  this.context,
199
203
  );
200
204
  };
201
205
 
202
- function createTexture(gltf, textureInfo, image, mipLevels, context) {
206
+ function createTexture(
207
+ gltf,
208
+ textureInfo,
209
+ textureId,
210
+ image,
211
+ mipLevels,
212
+ context,
213
+ ) {
203
214
  // internalFormat is only defined for CompressedTextureBuffer
204
215
  const internalFormat = image.internalFormat;
205
216
 
@@ -261,6 +272,7 @@ function createTexture(gltf, textureInfo, image, mipLevels, context) {
261
272
  }
262
273
 
263
274
  texture = Texture.create({
275
+ id: textureId,
264
276
  context: context,
265
277
  source: {
266
278
  arrayBufferView: image.bufferView, // Only defined for CompressedTextureBuffer
@@ -276,6 +288,7 @@ function createTexture(gltf, textureInfo, image, mipLevels, context) {
276
288
  image = resizeImageToNextPowerOfTwo(image);
277
289
  }
278
290
  texture = Texture.create({
291
+ id: textureId,
279
292
  context: context,
280
293
  source: image,
281
294
  sampler: sampler,
@@ -332,6 +345,7 @@ GltfTextureLoader.prototype.process = function (frameState) {
332
345
  textureJob.set(
333
346
  this._gltf,
334
347
  this._textureInfo,
348
+ this._cacheKey,
335
349
  this._image,
336
350
  this._mipLevels,
337
351
  frameState.context,
@@ -346,6 +360,7 @@ GltfTextureLoader.prototype.process = function (frameState) {
346
360
  texture = createTexture(
347
361
  this._gltf,
348
362
  this._textureInfo,
363
+ this._cacheKey,
349
364
  this._image,
350
365
  this._mipLevels,
351
366
  frameState.context,
@@ -0,0 +1,138 @@
1
+ import Cesium3DTileset from "./Cesium3DTileset.js";
2
+ import defined from "../Core/defined.js";
3
+ import Resource from "../Core/Resource.js";
4
+ import ITwinPlatform from "../Core/ITwinPlatform.js";
5
+ import RuntimeError from "../Core/RuntimeError.js";
6
+ import Check from "../Core/Check.js";
7
+
8
+ /**
9
+ * Methods for loading iTwin platform data into CesiumJS
10
+ *
11
+ * @experimental This feature is not final and is subject to change without Cesium's standard deprecation policy.
12
+ *
13
+ * @see ITwinPlatform
14
+ * @namespace ITwinData
15
+ */
16
+ const ITwinData = {};
17
+
18
+ /**
19
+ * Create a {@link Cesium3DTileset} for the given iModel id using iTwin's Mesh Export API.
20
+ *
21
+ * If there is not a completed export available for the given iModel id, the returned promise will resolve to <code>undefined</code>.
22
+ * We recommend waiting 10-20 seconds and trying to load the tileset again.
23
+ * If all exports are Invalid this will throw an error.
24
+ *
25
+ * @example
26
+ * const tileset = await Cesium.ITwinData.createTilesetFromIModelId(iModelId);
27
+ * if (Cesium.defined(tileset)) {
28
+ * viewer.scene.primitives.add(tileset);
29
+ * }
30
+ *
31
+ * @experimental This feature is not final and is subject to change without Cesium's standard deprecation policy.
32
+ *
33
+ * @param {string} iModelId The id of the iModel to load
34
+ * @param {Cesium3DTileset.ConstructorOptions} [options] Object containing options to pass to the internally created {@link Cesium3DTileset}.
35
+ * @returns {Promise<Cesium3DTileset | undefined>} A promise that will resolve to the created 3D tileset or <code>undefined</code> if there is no completed export for the given iModel id
36
+ *
37
+ * @throws {RuntimeError} If all exports for the given iModel are Invalid
38
+ * @throws {RuntimeError} If the iTwin API request is not successful
39
+ */
40
+ ITwinData.createTilesetFromIModelId = async function (iModelId, options) {
41
+ const { exports } = await ITwinPlatform.getExports(iModelId);
42
+
43
+ if (
44
+ exports.length > 0 &&
45
+ exports.every((exportObj) => {
46
+ return exportObj.status === ITwinPlatform.ExportStatus.Invalid;
47
+ })
48
+ ) {
49
+ throw new RuntimeError(
50
+ `All exports for this iModel are Invalid: ${iModelId}`,
51
+ );
52
+ }
53
+
54
+ const completeExport = exports.find((exportObj) => {
55
+ return exportObj.status === ITwinPlatform.ExportStatus.Complete;
56
+ });
57
+
58
+ if (!defined(completeExport)) {
59
+ return;
60
+ }
61
+
62
+ // Convert the link to the tileset url while preserving the search paramaters
63
+ // This link is only valid 1 hour
64
+ const baseUrl = new URL(completeExport._links.mesh.href);
65
+ baseUrl.pathname = `${baseUrl.pathname}/tileset.json`;
66
+ const tilesetUrl = baseUrl.toString();
67
+
68
+ const resource = new Resource({
69
+ url: tilesetUrl,
70
+ });
71
+
72
+ return Cesium3DTileset.fromUrl(resource, options);
73
+ };
74
+
75
+ /**
76
+ * Create a tileset for the specified reality data id. This function only works
77
+ * with 3D Tiles meshes and point clouds.
78
+ *
79
+ * If the <code>type</code> or <code>rootDocument</code> are not provided this function
80
+ * will first request the full metadata for the specified reality data to fill these values.
81
+ *
82
+ * @experimental This feature is not final and is subject to change without Cesium's standard deprecation policy.
83
+ *
84
+ * @param {string} iTwinId The id of the iTwin to load data from
85
+ * @param {string} realityDataId The id of the reality data to load
86
+ * @param {ITwinPlatform.RealityDataType} [type] The type of this reality data
87
+ * @param {string} [rootDocument] The path of the root document for this reality data
88
+ * @returns {Promise<Cesium3DTileset>}
89
+ */
90
+ ITwinData.createTilesetForRealityDataId = async function (
91
+ iTwinId,
92
+ realityDataId,
93
+ type,
94
+ rootDocument,
95
+ ) {
96
+ //>>includeStart('debug', pragmas.debug);
97
+ Check.typeOf.string("iTwinId", iTwinId);
98
+ Check.typeOf.string("realityDataId", realityDataId);
99
+ if (defined(type)) {
100
+ Check.typeOf.string("type", type);
101
+ }
102
+ if (defined(rootDocument)) {
103
+ Check.typeOf.string("rootDocument", rootDocument);
104
+ }
105
+ //>>includeEnd('debug')
106
+
107
+ if (!defined(type) || !defined(rootDocument)) {
108
+ const metadata = await ITwinPlatform.getRealityDataMetadata(
109
+ iTwinId,
110
+ realityDataId,
111
+ );
112
+ rootDocument = metadata.rootDocument;
113
+ type = metadata.type;
114
+ }
115
+
116
+ const supportedRealityDataTypes = [
117
+ ITwinPlatform.RealityDataType.Cesium3DTiles,
118
+ ITwinPlatform.RealityDataType.PNTS,
119
+ ITwinPlatform.RealityDataType.RealityMesh3DTiles,
120
+ ITwinPlatform.RealityDataType.Terrain3DTiles,
121
+ ];
122
+
123
+ if (!supportedRealityDataTypes.includes(type)) {
124
+ throw new RuntimeError(`Reality data type is not a mesh type: ${type}`);
125
+ }
126
+
127
+ const tilesetAccessUrl = await ITwinPlatform.getRealityDataURL(
128
+ iTwinId,
129
+ realityDataId,
130
+ rootDocument,
131
+ );
132
+
133
+ return Cesium3DTileset.fromUrl(tilesetAccessUrl, {
134
+ maximumScreenSpaceError: 4,
135
+ });
136
+ };
137
+
138
+ export default ITwinData;
@@ -400,8 +400,7 @@ Object.defineProperties(Label.prototype, {
400
400
  if (this._text !== value) {
401
401
  this._text = value;
402
402
 
403
- // Strip soft-hyphen (auto-wrap) characters from input string
404
- const renderedValue = value.replace(/\u00ad/g, "");
403
+ const renderedValue = Label.filterUnsupportedCharacters(value);
405
404
  this._renderedText = Label.enableRightToLeftDetection
406
405
  ? reverseRtl(renderedValue)
407
406
  : renderedValue;
@@ -1346,6 +1345,21 @@ Label.getScreenSpaceBoundingBox = function (
1346
1345
  return result;
1347
1346
  };
1348
1347
 
1348
+ /**
1349
+ * Removes control characters and soft hyphon (auto-wrap) characters, which will cause an error when rendering a glyph. This does not remove tabs, carriage returns, or newlines.
1350
+ * @private
1351
+ * @param {string} text The original label text
1352
+ * @returns {string} The renderable filtered text
1353
+ */
1354
+ Label.filterUnsupportedCharacters = function (text) {
1355
+ const problematicCharactersRegex = new RegExp(
1356
+ // eslint-disable-next-line no-control-regex
1357
+ /[\u0000-\u0008\u000E-\u001F\u00ad\u202a-\u206f\u200b-\u200f]/,
1358
+ "g",
1359
+ );
1360
+ return text.replace(problematicCharactersRegex, "");
1361
+ };
1362
+
1349
1363
  /**
1350
1364
  * Determines if this label equals another label. Labels are equal if all their properties
1351
1365
  * are equal. Labels in different collections can be equal.
@@ -1502,7 +1516,7 @@ function reverseBrackets(bracket) {
1502
1516
  }
1503
1517
  }
1504
1518
 
1505
- //To add another language, simply add its Unicode block range(s) to the below regex.
1519
+ // To add another language, add its Unicode block range(s) to the below regex.
1506
1520
  const hebrew = "\u05D0-\u05EA";
1507
1521
  const arabic = "\u0600-\u06FF\u0750-\u077F\u08A0-\u08FF";
1508
1522
  const rtlChars = new RegExp(`[${hebrew}${arabic}]`);