@cesium/engine 2.1.0 → 2.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (193) hide show
  1. package/Build/Workers/{AxisAlignedBoundingBox-a6f9f0e5.js → AxisAlignedBoundingBox-379015ef.js} +1 -1
  2. package/Build/Workers/{BoundingRectangle-b0a68595.js → BoundingRectangle-57f2b24f.js} +1 -1
  3. package/Build/Workers/{BoxGeometry-baedd794.js → BoxGeometry-ecabfc78.js} +1 -1
  4. package/Build/Workers/{Color-f85df1be.js → Color-14d1a36d.js} +1 -1
  5. package/Build/Workers/{CoplanarPolygonGeometryLibrary-30516950.js → CoplanarPolygonGeometryLibrary-048c3c14.js} +1 -1
  6. package/Build/Workers/{CorridorGeometryLibrary-5d5d3b3a.js → CorridorGeometryLibrary-520c8619.js} +1 -1
  7. package/Build/Workers/{CylinderGeometry-d899ae26.js → CylinderGeometry-119068b8.js} +1 -1
  8. package/Build/Workers/{EllipseGeometry-a49f8449.js → EllipseGeometry-2dfc3523.js} +1 -1
  9. package/Build/Workers/{EllipseGeometryLibrary-cba7edde.js → EllipseGeometryLibrary-0a1e0170.js} +1 -1
  10. package/Build/Workers/{EllipseOutlineGeometry-8095c8cb.js → EllipseOutlineGeometry-c5251669.js} +1 -1
  11. package/Build/Workers/{EllipsoidGeometry-ed93f571.js → EllipsoidGeometry-d10a5221.js} +1 -1
  12. package/Build/Workers/{EllipsoidOutlineGeometry-e4854854.js → EllipsoidOutlineGeometry-7039a0ae.js} +1 -1
  13. package/Build/Workers/{EllipsoidTangentPlane-7ae1aa9a.js → EllipsoidTangentPlane-857186be.js} +1 -1
  14. package/Build/Workers/{FrustumGeometry-b62db3e3.js → FrustumGeometry-400fa1b7.js} +2 -2
  15. package/Build/Workers/{GeometryAttribute-780af4fa.js → GeometryAttribute-7a2de5c6.js} +1 -1
  16. package/Build/Workers/{GeometryPipeline-36b61c99.js → GeometryPipeline-916636fa.js} +1 -1
  17. package/Build/Workers/{IntersectionTests-e889fcf0.js → IntersectionTests-b4d02d4d.js} +1 -1
  18. package/Build/Workers/{OrientedBoundingBox-43478ac8.js → OrientedBoundingBox-96fe1752.js} +5 -3
  19. package/Build/Workers/{PolygonGeometryLibrary-38a98276.js → PolygonGeometryLibrary-931f1ec6.js} +1 -1
  20. package/Build/Workers/{PolygonPipeline-d31ff61c.js → PolygonPipeline-32fc92cc.js} +1 -1
  21. package/Build/Workers/{PolylinePipeline-30e4cec9.js → PolylinePipeline-6d5c63e5.js} +1 -1
  22. package/Build/Workers/{PolylineVolumeGeometryLibrary-90551d26.js → PolylineVolumeGeometryLibrary-f068c1fb.js} +1 -1
  23. package/Build/Workers/{PrimitivePipeline-558d9cb0.js → PrimitivePipeline-879f996a.js} +1 -1
  24. package/Build/Workers/{RectangleGeometryLibrary-815c68df.js → RectangleGeometryLibrary-2d6f36f3.js} +1 -1
  25. package/Build/Workers/{TerrainEncoding-341ead52.js → TerrainEncoding-82882059.js} +1 -1
  26. package/Build/Workers/{Transforms-9e9df299.js → Transforms-9052372a.js} +6 -5
  27. package/Build/Workers/{WallGeometryLibrary-ccf90976.js → WallGeometryLibrary-db7a64fb.js} +1 -1
  28. package/Build/Workers/cesiumWorkerBootstrapper.js +1 -1
  29. package/Build/Workers/combineGeometry.js +1 -1
  30. package/Build/Workers/createBoxGeometry.js +1 -1
  31. package/Build/Workers/createBoxOutlineGeometry.js +1 -1
  32. package/Build/Workers/createCircleGeometry.js +1 -1
  33. package/Build/Workers/createCircleOutlineGeometry.js +1 -1
  34. package/Build/Workers/createCoplanarPolygonGeometry.js +1 -1
  35. package/Build/Workers/createCoplanarPolygonOutlineGeometry.js +1 -1
  36. package/Build/Workers/createCorridorGeometry.js +1 -1
  37. package/Build/Workers/createCorridorOutlineGeometry.js +1 -1
  38. package/Build/Workers/createCylinderGeometry.js +1 -1
  39. package/Build/Workers/createCylinderOutlineGeometry.js +1 -1
  40. package/Build/Workers/createEllipseGeometry.js +1 -1
  41. package/Build/Workers/createEllipseOutlineGeometry.js +1 -1
  42. package/Build/Workers/createEllipsoidGeometry.js +1 -1
  43. package/Build/Workers/createEllipsoidOutlineGeometry.js +1 -1
  44. package/Build/Workers/createFrustumGeometry.js +1 -1
  45. package/Build/Workers/createFrustumOutlineGeometry.js +1 -1
  46. package/Build/Workers/createGeometry.js +1 -1
  47. package/Build/Workers/createGroundPolylineGeometry.js +1 -1
  48. package/Build/Workers/createPlaneGeometry.js +1 -1
  49. package/Build/Workers/createPlaneOutlineGeometry.js +1 -1
  50. package/Build/Workers/createPolygonGeometry.js +1 -1
  51. package/Build/Workers/createPolygonOutlineGeometry.js +1 -1
  52. package/Build/Workers/createPolylineGeometry.js +1 -1
  53. package/Build/Workers/createPolylineVolumeGeometry.js +1 -1
  54. package/Build/Workers/createPolylineVolumeOutlineGeometry.js +1 -1
  55. package/Build/Workers/createRectangleGeometry.js +1 -1
  56. package/Build/Workers/createRectangleOutlineGeometry.js +1 -1
  57. package/Build/Workers/createSimplePolylineGeometry.js +1 -1
  58. package/Build/Workers/createSphereGeometry.js +1 -1
  59. package/Build/Workers/createSphereOutlineGeometry.js +1 -1
  60. package/Build/Workers/createVectorTileGeometries.js +1 -1
  61. package/Build/Workers/createVectorTilePolygons.js +1 -1
  62. package/Build/Workers/createVerticesFromGoogleEarthEnterpriseBuffer.js +1 -1
  63. package/Build/Workers/createVerticesFromHeightmap.js +1 -1
  64. package/Build/Workers/createVerticesFromQuantizedTerrainMesh.js +10 -15
  65. package/Build/Workers/createWallGeometry.js +1 -1
  66. package/Build/Workers/createWallOutlineGeometry.js +1 -1
  67. package/Build/Workers/package.js +1 -1
  68. package/Build/Workers/transferTypedArrayTest.js +1 -1
  69. package/Build/Workers/upsampleQuantizedTerrainMesh.js +1 -1
  70. package/Source/Core/ArcGISTiledElevationTerrainProvider.js +291 -191
  71. package/Source/Core/CesiumTerrainProvider.js +571 -434
  72. package/Source/Core/CustomHeightmapTerrainProvider.js +12 -0
  73. package/Source/Core/EllipsoidTerrainProvider.js +17 -10
  74. package/Source/Core/FrustumGeometry.js +1 -1
  75. package/Source/Core/GoogleEarthEnterpriseMetadata.js +86 -34
  76. package/Source/Core/GoogleEarthEnterpriseTerrainProvider.js +119 -82
  77. package/Source/Core/Ion.js +1 -1
  78. package/Source/Core/IonResource.js +14 -3
  79. package/Source/Core/OrientedBoundingBox.js +4 -2
  80. package/Source/Core/RequestScheduler.js +1 -1
  81. package/Source/Core/Resource.js +2 -2
  82. package/Source/Core/TerrainProvider.js +9 -14
  83. package/Source/Core/TileProviderError.js +8 -8
  84. package/Source/Core/VRTheWorldTerrainProvider.js +193 -124
  85. package/Source/Core/buildModuleUrl.js +4 -3
  86. package/Source/Core/createWorldTerrain.js +20 -2
  87. package/Source/Core/createWorldTerrainAsync.js +48 -0
  88. package/Source/Core/sampleTerrain.js +9 -10
  89. package/Source/Core/sampleTerrainMostDetailed.js +66 -72
  90. package/Source/DataSources/Cesium3DTilesetVisualizer.js +37 -26
  91. package/Source/DataSources/Entity.js +6 -1
  92. package/Source/DataSources/ModelVisualizer.js +99 -31
  93. package/Source/DataSources/PolygonGraphics.js +1 -1
  94. package/Source/Scene/ArcGisMapServerImageryProvider.js +552 -376
  95. package/Source/Scene/BingMapsImageryProvider.js +511 -305
  96. package/Source/Scene/BufferLoader.js +29 -34
  97. package/Source/Scene/Cesium3DTile.js +388 -251
  98. package/Source/Scene/Cesium3DTileBatchTable.js +2 -2
  99. package/Source/Scene/Cesium3DTileContent.js +16 -0
  100. package/Source/Scene/Cesium3DTileContentFactory.js +4 -4
  101. package/Source/Scene/Cesium3DTilePass.js +8 -11
  102. package/Source/Scene/Cesium3DTileStyleEngine.js +1 -1
  103. package/Source/Scene/Cesium3DTilesVoxelProvider.js +225 -117
  104. package/Source/Scene/Cesium3DTileset.js +755 -481
  105. package/Source/Scene/Cesium3DTilesetBaseTraversal.js +301 -0
  106. package/Source/Scene/Cesium3DTilesetMostDetailedTraversal.js +33 -46
  107. package/Source/Scene/Cesium3DTilesetSkipTraversal.js +421 -0
  108. package/Source/Scene/Cesium3DTilesetTraversal.js +219 -671
  109. package/Source/Scene/ClassificationPrimitive.js +7 -0
  110. package/Source/Scene/Composite3DTileContent.js +69 -26
  111. package/Source/Scene/CreditDisplay.js +20 -4
  112. package/Source/Scene/DepthPlane.js +1 -1
  113. package/Source/Scene/Empty3DTileContent.js +31 -1
  114. package/Source/Scene/Geometry3DTileContent.js +47 -7
  115. package/Source/Scene/Globe.js +5 -1
  116. package/Source/Scene/GlobeSurfaceTile.js +2 -1
  117. package/Source/Scene/GlobeSurfaceTileProvider.js +50 -27
  118. package/Source/Scene/GltfBufferViewLoader.js +47 -91
  119. package/Source/Scene/GltfDracoLoader.js +110 -112
  120. package/Source/Scene/GltfImageLoader.js +71 -78
  121. package/Source/Scene/GltfIndexBufferLoader.js +108 -121
  122. package/Source/Scene/GltfJsonLoader.js +75 -74
  123. package/Source/Scene/GltfLoader.js +392 -280
  124. package/Source/Scene/GltfStructuralMetadataLoader.js +109 -110
  125. package/Source/Scene/GltfTextureLoader.js +97 -96
  126. package/Source/Scene/GltfVertexBufferLoader.js +128 -133
  127. package/Source/Scene/GoogleEarthEnterpriseImageryProvider.js +353 -225
  128. package/Source/Scene/GoogleEarthEnterpriseMapsProvider.js +491 -331
  129. package/Source/Scene/GridImageryProvider.js +267 -104
  130. package/Source/Scene/GroundPolylinePrimitive.js +12 -1
  131. package/Source/Scene/GroundPrimitive.js +8 -1
  132. package/Source/Scene/I3SDataProvider.js +214 -113
  133. package/Source/Scene/I3SFeature.js +7 -6
  134. package/Source/Scene/I3SLayer.js +26 -37
  135. package/Source/Scene/I3SNode.js +59 -66
  136. package/Source/Scene/Imagery.js +6 -1
  137. package/Source/Scene/ImageryLayer.js +299 -48
  138. package/Source/Scene/ImageryLayerCollection.js +26 -0
  139. package/Source/Scene/ImageryProvider.js +129 -111
  140. package/Source/Scene/Implicit3DTileContent.js +72 -23
  141. package/Source/Scene/ImplicitSubtree.js +66 -45
  142. package/Source/Scene/IonImageryProvider.js +471 -264
  143. package/Source/Scene/MapboxImageryProvider.js +272 -112
  144. package/Source/Scene/MapboxStyleImageryProvider.js +270 -111
  145. package/Source/Scene/MetadataSchemaLoader.js +26 -36
  146. package/Source/Scene/Model/B3dmLoader.js +42 -46
  147. package/Source/Scene/Model/GeoJsonLoader.js +8 -32
  148. package/Source/Scene/Model/I3dmLoader.js +48 -74
  149. package/Source/Scene/Model/Model.js +470 -132
  150. package/Source/Scene/Model/Model3DTileContent.js +83 -31
  151. package/Source/Scene/Model/ModelAnimationCollection.js +3 -3
  152. package/Source/Scene/Model/ModelDrawCommand.js +15 -26
  153. package/Source/Scene/Model/ModelUtility.js +16 -16
  154. package/Source/Scene/Model/PntsLoader.js +27 -32
  155. package/Source/Scene/Multiple3DTileContent.js +134 -115
  156. package/Source/Scene/PointCloud.js +11 -19
  157. package/Source/Scene/Primitive.js +20 -0
  158. package/Source/Scene/QuadtreePrimitive.js +2 -0
  159. package/Source/Scene/QuadtreeTileProvider.js +4 -8
  160. package/Source/Scene/ResourceCache.js +47 -105
  161. package/Source/Scene/ResourceCacheStatistics.js +24 -58
  162. package/Source/Scene/ResourceLoader.js +5 -17
  163. package/Source/Scene/ResourceLoaderState.js +12 -4
  164. package/Source/Scene/Scene.js +65 -0
  165. package/Source/Scene/ScreenSpaceCameraController.js +1 -1
  166. package/Source/Scene/SingleTileImageryProvider.js +382 -209
  167. package/Source/Scene/Terrain.js +196 -0
  168. package/Source/Scene/TileCoordinatesImageryProvider.js +267 -104
  169. package/Source/Scene/TileMapServiceImageryProvider.js +177 -85
  170. package/Source/Scene/Tileset3DTileContent.js +47 -5
  171. package/Source/Scene/TimeDynamicPointCloud.js +15 -2
  172. package/Source/Scene/UrlTemplateImageryProvider.js +343 -215
  173. package/Source/Scene/Vector3DTileClampedPolylines.js +96 -84
  174. package/Source/Scene/Vector3DTileContent.js +47 -22
  175. package/Source/Scene/Vector3DTileGeometry.js +57 -52
  176. package/Source/Scene/Vector3DTilePoints.js +72 -68
  177. package/Source/Scene/Vector3DTilePolygons.js +118 -117
  178. package/Source/Scene/Vector3DTilePolylines.js +86 -82
  179. package/Source/Scene/Vector3DTilePrimitive.js +0 -1
  180. package/Source/Scene/VoxelContent.js +61 -63
  181. package/Source/Scene/VoxelPrimitive.js +39 -91
  182. package/Source/Scene/VoxelProvider.js +2 -2
  183. package/Source/Scene/WebMapServiceImageryProvider.js +272 -111
  184. package/Source/Scene/WebMapTileServiceImageryProvider.js +270 -107
  185. package/Source/Scene/computeFlyToLocationForRectangle.js +33 -37
  186. package/Source/Scene/createOsmBuildings.js +6 -0
  187. package/Source/Scene/createOsmBuildingsAsync.js +82 -0
  188. package/Source/Scene/createWorldImagery.js +14 -5
  189. package/Source/Scene/createWorldImageryAsync.js +39 -0
  190. package/Source/Widget/CesiumWidget.js +55 -27
  191. package/index.d.ts +2158 -1395
  192. package/index.js +58 -51
  193. package/package.json +1 -1
@@ -6,9 +6,11 @@ import Credit from "../../Core/Credit.js";
6
6
  import Color from "../../Core/Color.js";
7
7
  import defined from "../../Core/defined.js";
8
8
  import defaultValue from "../../Core/defaultValue.js";
9
+ import deprecationWarning from "../../Core/deprecationWarning.js";
9
10
  import DeveloperError from "../../Core/DeveloperError.js";
10
11
  import destroyObject from "../../Core/destroyObject.js";
11
12
  import DistanceDisplayCondition from "../../Core/DistanceDisplayCondition.js";
13
+ import Event from "../../Core/Event.js";
12
14
  import Matrix3 from "../../Core/Matrix3.js";
13
15
  import Matrix4 from "../../Core/Matrix4.js";
14
16
  import Resource from "../../Core/Resource.js";
@@ -39,7 +41,7 @@ import StyleCommandsNeeded from "./StyleCommandsNeeded.js";
39
41
 
40
42
  /**
41
43
  * <div class="notice">
42
- * To construct a Model, call {@link Model.fromGltf}. Do not call the constructor directly.
44
+ * To construct a Model, call {@link Model.fromGltfAsync}. Do not call the constructor directly.
43
45
  * </div>
44
46
  * A 3D model based on glTF, the runtime asset format for WebGL, OpenGL ES, and OpenGL.
45
47
  * <p>
@@ -155,7 +157,7 @@ import StyleCommandsNeeded from "./StyleCommandsNeeded.js";
155
157
  * @privateParam {ClassificationType} [options.classificationType] Determines whether terrain, 3D Tiles or both will be classified by this model. This cannot be set after the model has loaded.
156
158
 
157
159
  *
158
- * @see Model.fromGltf
160
+ * @see Model.fromGltfAsync
159
161
  *
160
162
  * @demo {@link https://sandcastle.cesium.com/index.html?src=3D%20Models.html|Cesium Sandcastle Models Demo}
161
163
  */
@@ -455,9 +457,65 @@ function Model(options) {
455
457
  this._skipLevelOfDetail = false;
456
458
  this._ignoreCommands = defaultValue(options.ignoreCommands, false);
457
459
 
458
- this._completeLoad = function (model, frameState) {};
459
460
  this._texturesLoadedPromise = undefined;
460
- this._readyPromise = initialize(this);
461
+
462
+ this._completeLoad = undefined;
463
+ this._rejectLoad = undefined;
464
+ this._completeTexturesLoad = undefined;
465
+ this._rejectTexturesLoad = undefined;
466
+
467
+ // This is for backward compatibility. When readyPromise is removed, this block can be too
468
+ if (!defined(this._loader._promise)) {
469
+ this._readyPromise = new Promise((resolve, reject) => {
470
+ this._completeLoad = () => {
471
+ resolve(this);
472
+ return false;
473
+ };
474
+ this._rejectLoad = (error) => {
475
+ reject(error);
476
+ return false;
477
+ };
478
+ });
479
+
480
+ // Transcoded .pnts models do not have textures
481
+ if (this._loader instanceof PntsLoader) {
482
+ this._texturesLoadedPromise = Promise.resolve(this);
483
+ } else {
484
+ this._texturesLoadedPromise = new Promise((resolve, reject) => {
485
+ this._completeTexturesLoad = () => {
486
+ resolve(this);
487
+ return false;
488
+ };
489
+ this._rejectTexturesLoad = (error) => {
490
+ reject(error);
491
+ return false;
492
+ };
493
+ });
494
+ }
495
+
496
+ this._loader.load().catch((error) => {
497
+ // If the model is destroyed before the promise resolves, then
498
+ // the loader will have been destroyed as well. Return early.
499
+ if (
500
+ this.isDestroyed() ||
501
+ !defined(this._loader) ||
502
+ this._loader.isDestroyed()
503
+ ) {
504
+ return;
505
+ }
506
+
507
+ this._rejectLoad = this._rejectLoad(
508
+ ModelUtility.getError("model", this._resource, error)
509
+ );
510
+ });
511
+ } else {
512
+ this._readyPromise = Promise.resolve(this);
513
+ this._texturesLoadedPromise = Promise.resolve(this);
514
+ }
515
+
516
+ this._errorEvent = new Event();
517
+ this._readyEvent = new Event();
518
+ this._texturesReadyEvent = new Event();
461
519
 
462
520
  this._sceneGraph = undefined;
463
521
  this._nodesByName = {}; // Stores the nodes by their names in the glTF.
@@ -470,6 +528,15 @@ function Model(options) {
470
528
  this.pickObject = options.pickObject;
471
529
  }
472
530
 
531
+ function handleError(model, error) {
532
+ if (model._errorEvent.numberOfListeners > 0) {
533
+ model._errorEvent.raiseEvent(error);
534
+ return;
535
+ }
536
+
537
+ console.log(error);
538
+ }
539
+
473
540
  function createModelFeatureTables(model, structuralMetadata) {
474
541
  const featureTables = model._featureTables;
475
542
 
@@ -561,101 +628,10 @@ function isColorAlphaDirty(currentColor, previousColor) {
561
628
  );
562
629
  }
563
630
 
564
- function initialize(model) {
565
- const loader = model._loader;
566
- const resource = model._resource;
567
-
568
- loader.load();
569
-
570
- const loaderPromise = loader.promise.then(function (loader) {
571
- // If the model is destroyed before the promise resolves, then
572
- // the loader will have been destroyed as well. Return early.
573
- if (!defined(loader)) {
574
- return;
575
- }
576
-
577
- const components = loader.components;
578
- if (!defined(components)) {
579
- if (loader.isUnloaded()) {
580
- return;
581
- }
582
-
583
- throw new RuntimeError("Failed to load model.");
584
- }
585
-
586
- const structuralMetadata = components.structuralMetadata;
587
-
588
- if (
589
- defined(structuralMetadata) &&
590
- structuralMetadata.propertyTableCount > 0
591
- ) {
592
- createModelFeatureTables(model, structuralMetadata);
593
- }
594
-
595
- const sceneGraph = new ModelSceneGraph({
596
- model: model,
597
- modelComponents: components,
598
- });
599
-
600
- model._sceneGraph = sceneGraph;
601
- model._gltfCredits = sceneGraph.components.asset.credits;
602
-
603
- const resourceCredits = model._resource.credits;
604
- if (defined(resourceCredits)) {
605
- const length = resourceCredits.length;
606
- for (let i = 0; i < length; i++) {
607
- model._resourceCredits.push(resourceCredits[i]);
608
- }
609
- }
610
-
611
- model._resourcesLoaded = true;
612
- });
613
-
614
- // Transcoded .pnts models do not have textures
615
- const texturesLoadedPromise = defaultValue(
616
- loader.texturesLoadedPromise,
617
- Promise.resolve()
618
- );
619
- model._texturesLoadedPromise = texturesLoadedPromise
620
- .then(function () {
621
- // If the model was destroyed while loading textures, return.
622
- if (!defined(model) || model.isDestroyed()) {
623
- return;
624
- }
625
-
626
- model._texturesLoaded = true;
627
-
628
- // Re-run the pipeline so texture memory statistics are re-computed
629
- if (loader._incrementallyLoadTextures) {
630
- model.resetDrawCommands();
631
- }
632
- })
633
- .catch(ModelUtility.getFailedLoadFunction(model, "model", resource));
634
-
635
- const promise = new Promise(function (resolve, reject) {
636
- model._completeLoad = function (model, frameState) {
637
- // Set the model as ready after the first frame render since the user might set up events subscribed to
638
- // the post render event, and the model may not be ready for those past the first frame.
639
- frameState.afterRender.push(function () {
640
- model._ready = true;
641
- resolve(model);
642
- return true;
643
- });
644
- };
645
- });
646
-
647
- return loaderPromise
648
- .then(function () {
649
- return promise;
650
- })
651
- .catch(ModelUtility.getFailedLoadFunction(model, "model", resource));
652
- }
653
-
654
631
  Object.defineProperties(Model.prototype, {
655
632
  /**
656
633
  * When <code>true</code>, this model is ready to render, i.e., the external binary, image,
657
- * and shader files were downloaded and the WebGL resources were created. This is set to
658
- * <code>true</code> right before {@link Model#readyPromise} is resolved.
634
+ * and shader files were downloaded and the WebGL resources were created.
659
635
  *
660
636
  * @memberof Model.prototype
661
637
  *
@@ -670,6 +646,69 @@ Object.defineProperties(Model.prototype, {
670
646
  },
671
647
  },
672
648
 
649
+ /**
650
+ * Gets an event that is raised when the model encounters an asynchronous rendering error. By subscribing
651
+ * to the event, you will be notified of the error and can potentially recover from it. Event listeners
652
+ * are passed an instance of {@link ModelError}.
653
+ * @memberof Model.prototype
654
+ * @type {Event}
655
+ * @readonly
656
+ */
657
+ errorEvent: {
658
+ get: function () {
659
+ return this._errorEvent;
660
+ },
661
+ },
662
+
663
+ /**
664
+ * Gets an event that is raised when the model is loaded and ready for rendering, i.e. when the external resources
665
+ * have been downloaded and the WebGL resources are created. Event listeners
666
+ * are passed an instance of the {@link Model}.
667
+ *
668
+ * <p>
669
+ * If {@link Model.incrementallyLoadTextures} is true, this event will be raised before all textures are loaded and ready for rendering. Subscribe to {@link Model.texturesReadyEvent} to be notified when the textures are ready.
670
+ * </p>
671
+ *
672
+ * @memberof Model.prototype
673
+ * @type {Event}
674
+ * @readonly
675
+ */
676
+ readyEvent: {
677
+ get: function () {
678
+ return this._readyEvent;
679
+ },
680
+ },
681
+
682
+ /**
683
+ * Returns true if textures are loaded separately from the other glTF resources.
684
+ *
685
+ * @memberof GltfLoader.prototype
686
+ *
687
+ * @type {boolean}
688
+ * @readonly
689
+ * @private
690
+ */
691
+ incrementallyLoadTextures: {
692
+ get: function () {
693
+ return defaultValue(this._loader.incrementallyLoadTextures, false);
694
+ },
695
+ },
696
+
697
+ /**
698
+ * Gets an event that, if {@link Model.incrementallyLoadTextures} is true, is raised when the model textures are loaded and ready for rendering, i.e. when the external resources
699
+ * have been downloaded and the WebGL resources are created. Event listeners
700
+ * are passed an instance of the {@link Model}.
701
+ *
702
+ * @memberof Model.prototype
703
+ * @type {Event}
704
+ * @readonly
705
+ */
706
+ texturesReadyEvent: {
707
+ get: function () {
708
+ return this._texturesReadyEvent;
709
+ },
710
+ },
711
+
673
712
  /**
674
713
  * Gets the promise that will be resolved when this model is ready to render, i.e. when the external resources
675
714
  * have been downloaded and the WebGL resources are created.
@@ -681,9 +720,14 @@ Object.defineProperties(Model.prototype, {
681
720
  *
682
721
  * @type {Promise<Model>}
683
722
  * @readonly
723
+ * @deprecated
684
724
  */
685
725
  readyPromise: {
686
726
  get: function () {
727
+ deprecationWarning(
728
+ "Model.readyPromise",
729
+ "Model.readyPromise was deprecated in CesiumJS 1.104. It will be removed in 1.107. Use Model.fromGltfAsync and Model.readyEvent instead."
730
+ );
687
731
  return this._readyPromise;
688
732
  },
689
733
  },
@@ -697,11 +741,16 @@ Object.defineProperties(Model.prototype, {
697
741
  *
698
742
  * @type {Promise<void>}
699
743
  * @readonly
744
+ * @deprecated
700
745
  *
701
746
  * @private
702
747
  */
703
748
  texturesLoadedPromise: {
704
749
  get: function () {
750
+ deprecationWarning(
751
+ "Model.texturesLoadedPromise",
752
+ "Model.texturesLoadedPromise was deprecated in CesiumJS 1.104. It will be removed in 1.107. Use Model.fromGltfAsync and Model.texturesReadyEvent instead."
753
+ );
705
754
  return this._texturesLoadedPromise;
706
755
  },
707
756
  },
@@ -1155,7 +1204,7 @@ Object.defineProperties(Model.prototype, {
1155
1204
  //>>includeStart('debug', pragmas.debug);
1156
1205
  if (!this._ready) {
1157
1206
  throw new DeveloperError(
1158
- "The model is not loaded. Use Model.readyPromise or wait for Model.ready to be true."
1207
+ "The model is not loaded. Use Model.readyEvent or wait for Model.ready to be true."
1159
1208
  );
1160
1209
  }
1161
1210
  //>>includeEnd('debug');
@@ -1223,7 +1272,7 @@ Object.defineProperties(Model.prototype, {
1223
1272
  ) {
1224
1273
  oneTimeWarning(
1225
1274
  "model-debug-wireframe-ignored",
1226
- "enableDebugWireframe must be set to true in Model.fromGltf, otherwise debugWireframe will be ignored."
1275
+ "enableDebugWireframe must be set to true in Model.fromGltfAsync, otherwise debugWireframe will be ignored."
1227
1276
  );
1228
1277
  }
1229
1278
  },
@@ -1664,7 +1713,7 @@ Object.defineProperties(Model.prototype, {
1664
1713
  * @param {string} name The name of the node in the glTF.
1665
1714
  * @returns {ModelNode} The node, or <code>undefined</code> if no node with the <code>name</code> exists.
1666
1715
  *
1667
- * @exception {DeveloperError} The model is not loaded. Use Model.readyPromise or wait for Model.ready to be true.
1716
+ * @exception {DeveloperError} The model is not loaded. Use Model.readyEvent or wait for Model.ready to be true.
1668
1717
  *
1669
1718
  * @example
1670
1719
  * // Apply non-uniform scale to node "Hand"
@@ -1675,7 +1724,7 @@ Model.prototype.getNode = function (name) {
1675
1724
  //>>includeStart('debug', pragmas.debug);
1676
1725
  if (!this._ready) {
1677
1726
  throw new DeveloperError(
1678
- "The model is not loaded. Use Model.readyPromise or wait for Model.ready to be true."
1727
+ "The model is not loaded. Use Model.readyEvent or wait for Model.ready to be true."
1679
1728
  );
1680
1729
  }
1681
1730
  Check.typeOf.string("name", name);
@@ -1692,7 +1741,7 @@ Model.prototype.getNode = function (name) {
1692
1741
  * @param {string} articulationStageKey The name of the articulation, a space, and the name of the stage.
1693
1742
  * @param {number} value The numeric value of this stage of the articulation.
1694
1743
  *
1695
- * @exception {DeveloperError} The model is not loaded. Use Model.readyPromise or wait for Model.ready to be true.
1744
+ * @exception {DeveloperError} The model is not loaded. Use Model.readyEvent or wait for Model.ready to be true.
1696
1745
  *
1697
1746
  * @see Model#applyArticulations
1698
1747
  *
@@ -1705,7 +1754,7 @@ Model.prototype.setArticulationStage = function (articulationStageKey, value) {
1705
1754
  Check.typeOf.number("value", value);
1706
1755
  if (!this._ready) {
1707
1756
  throw new DeveloperError(
1708
- "The model is not loaded. Use Model.readyPromise or wait for Model.ready to be true."
1757
+ "The model is not loaded. Use Model.readyEvent or wait for Model.ready to be true."
1709
1758
  );
1710
1759
  }
1711
1760
  //>>includeEnd('debug');
@@ -1718,13 +1767,13 @@ Model.prototype.setArticulationStage = function (articulationStageKey, value) {
1718
1767
  * participates in any articulation. Note that this will overwrite any node
1719
1768
  * transformations on participating nodes.
1720
1769
  *
1721
- * @exception {DeveloperError} The model is not loaded. Use Model.readyPromise or wait for Model.ready to be true.
1770
+ * @exception {DeveloperError} The model is not loaded. Use Model.readyEvent or wait for Model.ready to be true.
1722
1771
  */
1723
1772
  Model.prototype.applyArticulations = function () {
1724
1773
  //>>includeStart('debug', pragmas.debug);
1725
1774
  if (!this._ready) {
1726
1775
  throw new DeveloperError(
1727
- "The model is not loaded. Use Model.readyPromise or wait for Model.ready to be true."
1776
+ "The model is not loaded. Use Model.readyEvent or wait for Model.ready to be true."
1728
1777
  );
1729
1778
  }
1730
1779
  //>>includeEnd('debug');
@@ -1764,10 +1813,40 @@ const scratchClippingPlanesMatrix = new Matrix4();
1764
1813
  * @exception {RuntimeError} Failed to load external reference.
1765
1814
  */
1766
1815
  Model.prototype.update = function (frameState) {
1767
- // Keep processing the model every frame until the main resources
1768
- // (buffer views) and textures (which may be loaded asynchronously)
1769
- // are processed.
1770
- processLoader(this, frameState);
1816
+ let finishedProcessing = false;
1817
+ try {
1818
+ // Keep processing the model every frame until the main resources
1819
+ // (buffer views) and textures (which may be loaded asynchronously)
1820
+ // are processed.
1821
+ finishedProcessing = processLoader(this, frameState);
1822
+ } catch (error) {
1823
+ if (!this._loader.incrementallyLoadTextures) {
1824
+ const runtimeError = ModelUtility.getError(
1825
+ "model",
1826
+ this._resource,
1827
+ error
1828
+ );
1829
+ handleError(this, runtimeError);
1830
+
1831
+ this._rejectLoad = this._rejectLoad && this._rejectLoad(runtimeError);
1832
+ this._rejectTexturesLoad =
1833
+ this._rejectTexturesLoad && this._rejectTexturesLoad(runtimeError);
1834
+ } else if (error.name === "TextureError") {
1835
+ handleError(this, error);
1836
+
1837
+ this._rejectTexturesLoad =
1838
+ this._rejectTexturesLoad && this._rejectTexturesLoad(error);
1839
+ } else {
1840
+ const runtimeError = ModelUtility.getError(
1841
+ "model",
1842
+ this._resource,
1843
+ error
1844
+ );
1845
+ handleError(this, runtimeError);
1846
+
1847
+ this._rejectLoad = this._rejectLoad && this._rejectLoad(runtimeError);
1848
+ }
1849
+ }
1771
1850
 
1772
1851
  // A custom shader may have to load texture uniforms.
1773
1852
  updateCustomShader(this, frameState);
@@ -1776,6 +1855,41 @@ Model.prototype.update = function (frameState) {
1776
1855
  // for specular maps.
1777
1856
  updateImageBasedLighting(this, frameState);
1778
1857
 
1858
+ if (!this._resourcesLoaded && finishedProcessing) {
1859
+ this._resourcesLoaded = true;
1860
+
1861
+ const components = this._loader.components;
1862
+ if (!defined(components)) {
1863
+ if (this._loader.isUnloaded()) {
1864
+ return;
1865
+ }
1866
+
1867
+ const error = ModelUtility.getError(
1868
+ "model",
1869
+ this._resource,
1870
+ new RuntimeError("Failed to load model.")
1871
+ );
1872
+ handleError(error);
1873
+ this._rejectLoad = this._rejectLoad && this._rejectLoad(error);
1874
+ }
1875
+
1876
+ const structuralMetadata = components.structuralMetadata;
1877
+ if (
1878
+ defined(structuralMetadata) &&
1879
+ structuralMetadata.propertyTableCount > 0
1880
+ ) {
1881
+ createModelFeatureTables(this, structuralMetadata);
1882
+ }
1883
+
1884
+ const sceneGraph = new ModelSceneGraph({
1885
+ model: this,
1886
+ modelComponents: components,
1887
+ });
1888
+
1889
+ this._sceneGraph = sceneGraph;
1890
+ this._gltfCredits = sceneGraph.components.asset.credits;
1891
+ }
1892
+
1779
1893
  // Short-circuit if the model resources aren't ready or the scene
1780
1894
  // is currently morphing.
1781
1895
  if (!this._resourcesLoaded || frameState.mode === SceneMode.MORPHING) {
@@ -1806,14 +1920,40 @@ Model.prototype.update = function (frameState) {
1806
1920
  // This check occurs after the bounding sphere has been updated so that
1807
1921
  // zooming to the bounding sphere can account for any modifications
1808
1922
  // from the clamp-to-ground setting.
1809
- const model = this;
1810
- if (!model._ready) {
1811
- model._completeLoad(model, frameState);
1923
+ if (!this._ready) {
1924
+ // Set the model as ready after the first frame render since the user might set up events subscribed to
1925
+ // the post render event, and the model may not be ready for those past the first frame.
1926
+ frameState.afterRender.push(() => {
1927
+ this._ready = true;
1928
+ this._readyEvent.raiseEvent(this);
1929
+ // This is here for backwards compatibility and can be removed when readyPromise is removed.
1930
+ this._completeLoad = this._completeLoad && this._completeLoad();
1931
+ if (!this._loader.incrementallyLoadTextures) {
1932
+ this._texturesLoaded = true;
1933
+ this._texturesReadyEvent.raiseEvent(this);
1934
+ this._completeTexturesLoad =
1935
+ this._completeTexturesLoad && this._completeTexturesLoad();
1936
+ }
1937
+ });
1812
1938
 
1813
1939
  // Don't render until the next frame after the ready promise is resolved
1814
1940
  return;
1815
1941
  }
1816
1942
 
1943
+ if (
1944
+ this._loader.incrementallyLoadTextures &&
1945
+ !this._texturesLoaded &&
1946
+ this._loader.texturesLoaded
1947
+ ) {
1948
+ // Re-run the pipeline so texture memory statistics are re-computed
1949
+ this.resetDrawCommands();
1950
+
1951
+ this._texturesLoaded = true;
1952
+ this._texturesReadyEvent.raiseEvent(this);
1953
+ this._completeTexturesLoad =
1954
+ this._completeTexturesLoad && this._completeTexturesLoad();
1955
+ }
1956
+
1817
1957
  updatePickIds(this);
1818
1958
 
1819
1959
  // Update the scene graph and draw commands for any changes in model's properties
@@ -1825,8 +1965,12 @@ Model.prototype.update = function (frameState) {
1825
1965
 
1826
1966
  function processLoader(model, frameState) {
1827
1967
  if (!model._resourcesLoaded || !model._texturesLoaded) {
1828
- model._loader.process(frameState);
1968
+ // Ensures frames continue to render in requestRender mode while resources are processing
1969
+ frameState.afterRender.push(() => true);
1970
+ return model._loader.process(frameState);
1829
1971
  }
1972
+
1973
+ return true;
1830
1974
  }
1831
1975
 
1832
1976
  function updateCustomShader(model, frameState) {
@@ -2430,10 +2574,6 @@ Model.prototype.hasSilhouette = function (frameState) {
2430
2574
  );
2431
2575
  };
2432
2576
 
2433
- function supportsSkipLevelOfDetail(frameState) {
2434
- return frameState.context.stencilBuffer;
2435
- }
2436
-
2437
2577
  /**
2438
2578
  * Gets whether or not the model is part of a tileset that uses the
2439
2579
  * skipLevelOfDetail optimization. This accounts for whether skipLevelOfDetail
@@ -2444,13 +2584,13 @@ function supportsSkipLevelOfDetail(frameState) {
2444
2584
  * @private
2445
2585
  */
2446
2586
  Model.prototype.hasSkipLevelOfDetail = function (frameState) {
2447
- const is3DTiles = ModelType.is3DTiles(this.type);
2448
- if (!is3DTiles) {
2587
+ if (!ModelType.is3DTiles(this.type)) {
2449
2588
  return false;
2450
2589
  }
2451
2590
 
2591
+ const supportsSkipLevelOfDetail = frameState.context.stencilBuffer;
2452
2592
  const tileset = this._content.tileset;
2453
- return supportsSkipLevelOfDetail(frameState) && tileset.skipLevelOfDetail;
2593
+ return supportsSkipLevelOfDetail && tileset.isSkippingLevelOfDetail;
2454
2594
  };
2455
2595
 
2456
2596
  /**
@@ -2635,6 +2775,11 @@ Model.prototype.destroyModelResources = function () {
2635
2775
  * @returns {Model} The newly created model.
2636
2776
  */
2637
2777
  Model.fromGltf = function (options) {
2778
+ deprecationWarning(
2779
+ "Model.fromGltf",
2780
+ "Model.fromGltf was deprecated in CesiumJS 1.104. It will be removed in 1.107. Use Model.fromGltfAsync instead."
2781
+ );
2782
+
2638
2783
  options = defaultValue(options, defaultValue.EMPTY_OBJECT);
2639
2784
 
2640
2785
  //>>includeStart('debug', pragmas.debug);
@@ -2688,10 +2833,183 @@ Model.fromGltf = function (options) {
2688
2833
  return model;
2689
2834
  };
2690
2835
 
2836
+ /**
2837
+ * <p>
2838
+ * Asynchronously creates a model from a glTF asset. This function returns a promise that resolves when the model is ready to render, i.e., when the external binary, image,
2839
+ * and shader files are downloaded and the WebGL resources are created.
2840
+ * </p>
2841
+ * <p>
2842
+ * The model can be a traditional glTF asset with a .gltf extension or a Binary glTF using the .glb extension.
2843
+ *
2844
+ * @param {Object} options Object with the following properties:
2845
+ * @param {String|Resource} options.url The url to the .gltf or .glb file.
2846
+ * @param {String|Resource} [options.basePath=''] The base path that paths in the glTF JSON are relative to.
2847
+ * @param {Boolean} [options.show=true] Whether or not to render the model.
2848
+ * @param {Matrix4} [options.modelMatrix=Matrix4.IDENTITY] The 4x4 transformation matrix that transforms the model from model to world coordinates.
2849
+ * @param {Number} [options.scale=1.0] A uniform scale applied to this model.
2850
+ * @param {Number} [options.minimumPixelSize=0.0] The approximate minimum pixel size of the model regardless of zoom.
2851
+ * @param {Number} [options.maximumScale] The maximum scale size of a model. An upper limit for minimumPixelSize.
2852
+ * @param {Object} [options.id] A user-defined object to return when the model is picked with {@link Scene#pick}.
2853
+ * @param {Boolean} [options.allowPicking=true] When <code>true</code>, each primitive is pickable with {@link Scene#pick}.
2854
+ * @param {Boolean} [options.incrementallyLoadTextures=true] Determine if textures may continue to stream in after the model is loaded.
2855
+ * @param {Boolean} [options.asynchronous=true] Determines if model WebGL resource creation will be spread out over several frames or block until completion once all glTF files are loaded.
2856
+ * @param {Boolean} [options.clampAnimations=true] Determines if the model's animations should hold a pose over frames where no keyframes are specified.
2857
+ * @param {ShadowMode} [options.shadows=ShadowMode.ENABLED] Determines whether the model casts or receives shadows from light sources.
2858
+ * @param {Boolean} [options.releaseGltfJson=false] When true, the glTF JSON is released once the glTF is loaded. This is is especially useful for cases like 3D Tiles, where each .gltf model is unique and caching the glTF JSON is not effective.
2859
+ * @param {Boolean} [options.debugShowBoundingVolume=false] For debugging only. Draws the bounding sphere for each draw command in the model.
2860
+ * @param {Boolean} [options.enableDebugWireframe=false] For debugging only. This must be set to true for debugWireframe to work in WebGL1. This cannot be set after the model has loaded.
2861
+ * @param {Boolean} [options.debugWireframe=false] For debugging only. Draws the model in wireframe. Will only work for WebGL1 if enableDebugWireframe is set to true.
2862
+ * @param {Boolean} [options.cull=true] Whether or not to cull the model using frustum/horizon culling. If the model is part of a 3D Tiles tileset, this property will always be false, since the 3D Tiles culling system is used.
2863
+ * @param {Boolean} [options.opaquePass=Pass.OPAQUE] The pass to use in the {@link DrawCommand} for the opaque portions of the model.
2864
+ * @param {Axis} [options.upAxis=Axis.Y] The up-axis of the glTF model.
2865
+ * @param {Axis} [options.forwardAxis=Axis.Z] The forward-axis of the glTF model.
2866
+ * @param {CustomShader} [options.customShader] A custom shader. This will add user-defined GLSL code to the vertex and fragment shaders. Using custom shaders with a {@link Cesium3DTileStyle} may lead to undefined behavior.
2867
+ * @param {Cesium3DTileContent} [options.content] The tile content this model belongs to. This property will be undefined if model is not loaded as part of a tileset.
2868
+ * @param {HeightReference} [options.heightReference=HeightReference.NONE] Determines how the model is drawn relative to terrain.
2869
+ * @param {Scene} [options.scene] Must be passed in for models that use the height reference property.
2870
+ * @param {DistanceDisplayCondition} [options.distanceDisplayCondition] The condition specifying at what distance from the camera that this model will be displayed.
2871
+ * @param {Color} [options.color] A color that blends with the model's rendered color.
2872
+ * @param {ColorBlendMode} [options.colorBlendMode=ColorBlendMode.HIGHLIGHT] Defines how the color blends with the model.
2873
+ * @param {Number} [options.colorBlendAmount=0.5] Value used to determine the color strength when the <code>colorBlendMode</code> is <code>MIX</code>. A value of 0.0 results in the model's rendered color while a value of 1.0 results in a solid color, with any value in-between resulting in a mix of the two.
2874
+ * @param {Color} [options.silhouetteColor=Color.RED] The silhouette color. If more than 256 models have silhouettes enabled, there is a small chance that overlapping models will have minor artifacts.
2875
+ * @param {Number} [options.silhouetteSize=0.0] The size of the silhouette in pixels.
2876
+ * @param {Boolean} [options.enableShowOutline=true] Whether to enable outlines for models using the {@link https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Vendor/CESIUM_primitive_outline|CESIUM_primitive_outline} extension. This can be set false to avoid post-processing geometry at load time. When false, the showOutlines and outlineColor options are ignored.
2877
+ * @param {Boolean} [options.showOutline=true] Whether to display the outline for models using the {@link https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Vendor/CESIUM_primitive_outline|CESIUM_primitive_outline} extension. When true, outlines are displayed. When false, outlines are not displayed.
2878
+ * @param {Color} [options.outlineColor=Color.BLACK] The color to use when rendering outlines.
2879
+ * @param {ClippingPlaneCollection} [options.clippingPlanes] The {@link ClippingPlaneCollection} used to selectively disable rendering the model.
2880
+ * @param {Cartesian3} [options.lightColor] The light color when shading the model. When <code>undefined</code> the scene's light color is used instead.
2881
+ * @param {ImageBasedLighting} [options.imageBasedLighting] The properties for managing image-based lighting on this model.
2882
+ * @param {Boolean} [options.backFaceCulling=true] Whether to cull back-facing geometry. When true, back face culling is determined by the material's doubleSided property; when false, back face culling is disabled. Back faces are not culled if the model's color is translucent.
2883
+ * @param {Credit|String} [options.credit] A credit for the data source, which is displayed on the canvas.
2884
+ * @param {Boolean} [options.showCreditsOnScreen=false] Whether to display the credits of this model on screen.
2885
+ * @param {SplitDirection} [options.splitDirection=SplitDirection.NONE] The {@link SplitDirection} split to apply to this model.
2886
+ * @param {Boolean} [options.projectTo2D=false] Whether to accurately project the model's positions in 2D. If this is true, the model will be projected accurately to 2D, but it will use more memory to do so. If this is false, the model will use less memory and will still render in 2D / CV mode, but its positions may be inaccurate. This disables minimumPixelSize and prevents future modification to the model matrix. This also cannot be set after the model has loaded.
2887
+ * @param {String|Number} [options.featureIdLabel="featureId_0"] Label of the feature ID set to use for picking and styling. For EXT_mesh_features, this is the feature ID's label property, or "featureId_N" (where N is the index in the featureIds array) when not specified. EXT_feature_metadata did not have a label field, so such feature ID sets are always labeled "featureId_N" where N is the index in the list of all feature Ids, where feature ID attributes are listed before feature ID textures. If featureIdLabel is an integer N, it is converted to the string "featureId_N" automatically. If both per-primitive and per-instance feature IDs are present, the instance feature IDs take priority.
2888
+ * @param {String|Number} [options.instanceFeatureIdLabel="instanceFeatureId_0"] Label of the instance feature ID set used for picking and styling. If instanceFeatureIdLabel is set to an integer N, it is converted to the string "instanceFeatureId_N" automatically. If both per-primitive and per-instance feature IDs are present, the instance feature IDs take priority.
2889
+ * @param {Object} [options.pointCloudShading] Options for constructing a {@link PointCloudShading} object to control point attenuation and lighting.
2890
+ * @param {ClassificationType} [options.classificationType] Determines whether terrain, 3D Tiles or both will be classified by this model. This cannot be set after the model has loaded.
2891
+ *
2892
+ * @returns {Promise<Model>} A promise that resolves to the created model when it is ready to render.
2893
+ *
2894
+ * @exception {RuntimeError} The model failed to load.
2895
+ *
2896
+ * @example
2897
+ * // Load a model and add it to the scene
2898
+ * try {
2899
+ * const model = await Cesium.Model.fromGltfAsync({
2900
+ * url: "../../SampleData/models/CesiumMan/Cesium_Man.glb"
2901
+ * });
2902
+ * viewer.scene.primitives.add(model);
2903
+ * } catch (error) {
2904
+ * console.log(`Failed to load model. ${error}`);
2905
+ * }
2906
+ *
2907
+ * @example
2908
+ * // Position a model with modelMatrix and display it with a minimum size of 128 pixels
2909
+ * const position = Cesium.Cartesian3.fromDegrees(
2910
+ * -123.0744619,
2911
+ * 44.0503706,
2912
+ * 5000.0
2913
+ * );
2914
+ * const headingPositionRoll = new Cesium.HeadingPitchRoll();
2915
+ * const fixedFrameTransform = Cesium.Transforms.localFrameToFixedFrameGenerator(
2916
+ * "north",
2917
+ * "west"
2918
+ * );
2919
+ * try {
2920
+ * const model = await Cesium.Model.fromGltfAsync({
2921
+ * url: "../../SampleData/models/CesiumAir/Cesium_Air.glb",
2922
+ * modelMatrix: Cesium.Transforms.headingPitchRollToFixedFrame(
2923
+ * position,
2924
+ * headingPositionRoll,
2925
+ * Cesium.Ellipsoid.WGS84,
2926
+ * fixedFrameTransform
2927
+ * ),
2928
+ * minimumPixelSize: 128,
2929
+ * });
2930
+ * viewer.scene.primitives.add(model);
2931
+ * } catch (error) {
2932
+ * console.log(`Failed to load model. ${error}`);
2933
+ * }
2934
+ */
2935
+ Model.fromGltfAsync = async function (options) {
2936
+ options = defaultValue(options, defaultValue.EMPTY_OBJECT);
2937
+
2938
+ //>>includeStart('debug', pragmas.debug);
2939
+ if (!defined(options.url) && !defined(options.gltf)) {
2940
+ throw new DeveloperError("options.url is required.");
2941
+ }
2942
+ //>>includeEnd('debug');
2943
+
2944
+ // options.gltf is used internally for 3D Tiles. It can be a Resource, a URL
2945
+ // to a glTF/glb file, a binary glTF buffer, or a JSON object containing the
2946
+ // glTF contents.
2947
+ const gltf = defaultValue(options.url, options.gltf);
2948
+
2949
+ const loaderOptions = {
2950
+ releaseGltfJson: options.releaseGltfJson,
2951
+ asynchronous: options.asynchronous,
2952
+ incrementallyLoadTextures: options.incrementallyLoadTextures,
2953
+ upAxis: options.upAxis,
2954
+ forwardAxis: options.forwardAxis,
2955
+ loadAttributesFor2D: options.projectTo2D,
2956
+ loadIndicesForWireframe: options.enableDebugWireframe,
2957
+ loadPrimitiveOutline: options.enableShowOutline,
2958
+ loadForClassification: defined(options.classificationType),
2959
+ };
2960
+
2961
+ const basePath = defaultValue(options.basePath, "");
2962
+ const baseResource = Resource.createIfNeeded(basePath);
2963
+
2964
+ if (defined(gltf.asset)) {
2965
+ loaderOptions.gltfJson = gltf;
2966
+ loaderOptions.baseResource = baseResource;
2967
+ loaderOptions.gltfResource = baseResource;
2968
+ } else if (gltf instanceof Uint8Array) {
2969
+ loaderOptions.typedArray = gltf;
2970
+ loaderOptions.baseResource = baseResource;
2971
+ loaderOptions.gltfResource = baseResource;
2972
+ } else {
2973
+ loaderOptions.gltfResource = Resource.createIfNeeded(gltf);
2974
+ }
2975
+
2976
+ const loader = new GltfLoader(loaderOptions);
2977
+
2978
+ const is3DTiles = defined(options.content);
2979
+ const type = is3DTiles ? ModelType.TILE_GLTF : ModelType.GLTF;
2980
+
2981
+ const resource = loaderOptions.gltfResource;
2982
+
2983
+ const modelOptions = makeModelOptions(loader, type, options);
2984
+ modelOptions.resource = resource;
2985
+
2986
+ try {
2987
+ // This load the gltf JSON and ensures the gltf is valid
2988
+ // Further resource loading is handled synchronously in loader.process(), and requires
2989
+ // hooking into model's update() as the frameState is needed
2990
+ await loader.load();
2991
+
2992
+ const model = new Model(modelOptions);
2993
+
2994
+ const resourceCredits = model._resource.credits;
2995
+ if (defined(resourceCredits)) {
2996
+ const length = resourceCredits.length;
2997
+ for (let i = 0; i < length; i++) {
2998
+ model._resourceCredits.push(resourceCredits[i]);
2999
+ }
3000
+ }
3001
+
3002
+ return model;
3003
+ } catch (error) {
3004
+ loader.destroy();
3005
+ throw ModelUtility.getError("model", resource, error);
3006
+ }
3007
+ };
3008
+
2691
3009
  /*
2692
3010
  * @private
2693
3011
  */
2694
- Model.fromB3dm = function (options) {
3012
+ Model.fromB3dm = async function (options) {
2695
3013
  const loaderOptions = {
2696
3014
  b3dmResource: options.resource,
2697
3015
  arrayBuffer: options.arrayBuffer,
@@ -2709,15 +3027,22 @@ Model.fromB3dm = function (options) {
2709
3027
 
2710
3028
  const loader = new B3dmLoader(loaderOptions);
2711
3029
 
2712
- const modelOptions = makeModelOptions(loader, ModelType.TILE_B3DM, options);
2713
- const model = new Model(modelOptions);
2714
- return model;
3030
+ try {
3031
+ await loader.load();
3032
+
3033
+ const modelOptions = makeModelOptions(loader, ModelType.TILE_B3DM, options);
3034
+ const model = new Model(modelOptions);
3035
+ return model;
3036
+ } catch (error) {
3037
+ loader.destroy();
3038
+ throw error;
3039
+ }
2715
3040
  };
2716
3041
 
2717
3042
  /**
2718
3043
  * @private
2719
3044
  */
2720
- Model.fromPnts = function (options) {
3045
+ Model.fromPnts = async function (options) {
2721
3046
  const loaderOptions = {
2722
3047
  arrayBuffer: options.arrayBuffer,
2723
3048
  byteOffset: options.byteOffset,
@@ -2725,15 +3050,21 @@ Model.fromPnts = function (options) {
2725
3050
  };
2726
3051
  const loader = new PntsLoader(loaderOptions);
2727
3052
 
2728
- const modelOptions = makeModelOptions(loader, ModelType.TILE_PNTS, options);
2729
- const model = new Model(modelOptions);
2730
- return model;
3053
+ try {
3054
+ await loader.load();
3055
+ const modelOptions = makeModelOptions(loader, ModelType.TILE_PNTS, options);
3056
+ const model = new Model(modelOptions);
3057
+ return model;
3058
+ } catch (error) {
3059
+ loader.destroy();
3060
+ throw error;
3061
+ }
2731
3062
  };
2732
3063
 
2733
3064
  /*
2734
3065
  * @private
2735
3066
  */
2736
- Model.fromI3dm = function (options) {
3067
+ Model.fromI3dm = async function (options) {
2737
3068
  const loaderOptions = {
2738
3069
  i3dmResource: options.resource,
2739
3070
  arrayBuffer: options.arrayBuffer,
@@ -2749,15 +3080,22 @@ Model.fromI3dm = function (options) {
2749
3080
  };
2750
3081
  const loader = new I3dmLoader(loaderOptions);
2751
3082
 
2752
- const modelOptions = makeModelOptions(loader, ModelType.TILE_I3DM, options);
2753
- const model = new Model(modelOptions);
2754
- return model;
3083
+ try {
3084
+ await loader.load();
3085
+
3086
+ const modelOptions = makeModelOptions(loader, ModelType.TILE_I3DM, options);
3087
+ const model = new Model(modelOptions);
3088
+ return model;
3089
+ } catch (error) {
3090
+ loader.destroy();
3091
+ throw error;
3092
+ }
2755
3093
  };
2756
3094
 
2757
3095
  /*
2758
3096
  * @private
2759
3097
  */
2760
- Model.fromGeoJson = function (options) {
3098
+ Model.fromGeoJson = async function (options) {
2761
3099
  const loaderOptions = {
2762
3100
  geoJson: options.geoJson,
2763
3101
  };