David Catuhe 7 years ago
parent
commit
1f23374bd6
24 changed files with 36029 additions and 35420 deletions
  1. 16796 16770
      Playground/babylon.d.txt
  2. 16717 16691
      dist/preview release/babylon.d.ts
  3. 44 44
      dist/preview release/babylon.js
  4. 167 61
      dist/preview release/babylon.max.js
  5. 44 44
      dist/preview release/babylon.worker.js
  6. 909 883
      dist/preview release/customConfigurations/minimalGLTFViewer/babylon.d.ts
  7. 47 47
      dist/preview release/customConfigurations/minimalGLTFViewer/babylon.js
  8. 286 166
      dist/preview release/customConfigurations/minimalGLTFViewer/babylon.max.js
  9. 286 166
      dist/preview release/customConfigurations/minimalGLTFViewer/es6.js
  10. 167 61
      dist/preview release/es6.js
  11. 20 13
      dist/preview release/loaders/babylon.glTF1FileLoader.d.ts
  12. 16 10
      dist/preview release/loaders/babylon.glTF1FileLoader.js
  13. 2 2
      dist/preview release/loaders/babylon.glTF1FileLoader.min.js
  14. 33 23
      dist/preview release/loaders/babylon.glTF2FileLoader.d.ts
  15. 122 110
      dist/preview release/loaders/babylon.glTF2FileLoader.js
  16. 2 2
      dist/preview release/loaders/babylon.glTF2FileLoader.min.js
  17. 34 24
      dist/preview release/loaders/babylon.glTFFileLoader.d.ts
  18. 123 111
      dist/preview release/loaders/babylon.glTFFileLoader.js
  19. 3 3
      dist/preview release/loaders/babylon.glTFFileLoader.min.js
  20. 123 111
      dist/preview release/loaders/babylonjs.loaders.js
  21. 3 3
      dist/preview release/loaders/babylonjs.loaders.min.js
  22. 34 24
      dist/preview release/loaders/babylonjs.loaders.module.d.ts
  23. 2 2
      dist/preview release/typedocValidationBaseline.json
  24. 49 49
      dist/preview release/viewer/babylon.viewer.js

File diff suppressed because it is too large
+ 16796 - 16770
Playground/babylon.d.txt


File diff suppressed because it is too large
+ 16717 - 16691
dist/preview release/babylon.d.ts


File diff suppressed because it is too large
+ 44 - 44
dist/preview release/babylon.js


File diff suppressed because it is too large
+ 167 - 61
dist/preview release/babylon.max.js


File diff suppressed because it is too large
+ 44 - 44
dist/preview release/babylon.worker.js


File diff suppressed because it is too large
+ 909 - 883
dist/preview release/customConfigurations/minimalGLTFViewer/babylon.d.ts


File diff suppressed because it is too large
+ 47 - 47
dist/preview release/customConfigurations/minimalGLTFViewer/babylon.js


File diff suppressed because it is too large
+ 286 - 166
dist/preview release/customConfigurations/minimalGLTFViewer/babylon.max.js


File diff suppressed because it is too large
+ 286 - 166
dist/preview release/customConfigurations/minimalGLTFViewer/es6.js


File diff suppressed because it is too large
+ 167 - 61
dist/preview release/es6.js


+ 20 - 13
dist/preview release/loaders/babylon.glTF1FileLoader.d.ts

@@ -28,30 +28,34 @@ declare module BABYLON {
         json: Object;
         json: Object;
         bin: Nullable<ArrayBufferView>;
         bin: Nullable<ArrayBufferView>;
     }
     }
+    interface IGLTFLoaderExtension {
+        /**
+         * The name of this extension.
+         */
+        readonly name: string;
+        /**
+         * Whether this extension is enabled.
+         */
+        enabled: boolean;
+    }
     enum GLTFLoaderState {
     enum GLTFLoaderState {
         Loading = 0,
         Loading = 0,
         Ready = 1,
         Ready = 1,
         Complete = 2,
         Complete = 2,
     }
     }
-    interface IGLTFLoaderExtension {
-        enabled: boolean;
-    }
-    interface IGLTFLoaderExtensions {
-        [name: string]: IGLTFLoaderExtension;
-    }
     interface IGLTFLoader extends IDisposable {
     interface IGLTFLoader extends IDisposable {
         coordinateSystemMode: GLTFLoaderCoordinateSystemMode;
         coordinateSystemMode: GLTFLoaderCoordinateSystemMode;
         animationStartMode: GLTFLoaderAnimationStartMode;
         animationStartMode: GLTFLoaderAnimationStartMode;
         compileMaterials: boolean;
         compileMaterials: boolean;
         useClipPlane: boolean;
         useClipPlane: boolean;
         compileShadowGenerators: boolean;
         compileShadowGenerators: boolean;
-        onDisposeObservable: Observable<IGLTFLoader>;
         onMeshLoadedObservable: Observable<AbstractMesh>;
         onMeshLoadedObservable: Observable<AbstractMesh>;
         onTextureLoadedObservable: Observable<BaseTexture>;
         onTextureLoadedObservable: Observable<BaseTexture>;
         onMaterialLoadedObservable: Observable<Material>;
         onMaterialLoadedObservable: Observable<Material>;
         onCompleteObservable: Observable<IGLTFLoader>;
         onCompleteObservable: Observable<IGLTFLoader>;
+        onDisposeObservable: Observable<IGLTFLoader>;
+        onExtensionLoadedObservable: Observable<IGLTFLoaderExtension>;
         state: Nullable<GLTFLoaderState>;
         state: Nullable<GLTFLoaderState>;
-        extensions: Nullable<IGLTFLoaderExtensions>;
         importMeshAsync: (meshesNames: any, scene: Scene, data: IGLTFLoaderData, rootUrl: string, onProgress?: (event: SceneLoaderProgressEvent) => void) => Promise<{
         importMeshAsync: (meshesNames: any, scene: Scene, data: IGLTFLoaderData, rootUrl: string, onProgress?: (event: SceneLoaderProgressEvent) => void) => Promise<{
             meshes: AbstractMesh[];
             meshes: AbstractMesh[];
             particleSystems: ParticleSystem[];
             particleSystems: ParticleSystem[];
@@ -125,13 +129,16 @@ declare module BABYLON {
         private _onDisposeObserver;
         private _onDisposeObserver;
         onDispose: () => void;
         onDispose: () => void;
         /**
         /**
-         * The loader state or null if not active.
+         * Raised after a loader extension is created.
+         * Set additional options for a loader extension in this event.
          */
          */
-        readonly loaderState: Nullable<GLTFLoaderState>;
+        readonly onExtensionLoadedObservable: Observable<IGLTFLoaderExtension>;
+        private _onExtensionLoadedObserver;
+        onExtensionLoaded: (extension: IGLTFLoaderExtension) => void;
         /**
         /**
-         * The loader extensions or null if not active.
+         * The loader state or null if not active.
          */
          */
-        readonly loaderExtensions: Nullable<IGLTFLoaderExtensions>;
+        readonly loaderState: Nullable<GLTFLoaderState>;
         private _loader;
         private _loader;
         name: string;
         name: string;
         extensions: ISceneLoaderPluginExtensions;
         extensions: ISceneLoaderPluginExtensions;
@@ -563,8 +570,8 @@ declare module BABYLON.GLTF1 {
         onTextureLoadedObservable: Observable<BaseTexture>;
         onTextureLoadedObservable: Observable<BaseTexture>;
         onMaterialLoadedObservable: Observable<Material>;
         onMaterialLoadedObservable: Observable<Material>;
         onCompleteObservable: Observable<IGLTFLoader>;
         onCompleteObservable: Observable<IGLTFLoader>;
+        onExtensionLoadedObservable: Observable<IGLTFLoaderExtension>;
         state: Nullable<GLTFLoaderState>;
         state: Nullable<GLTFLoaderState>;
-        extensions: Nullable<IGLTFLoaderExtensions>;
         dispose(): void;
         dispose(): void;
         private _importMeshAsync(meshesNames, scene, data, rootUrl, onSuccess, onProgress, onError);
         private _importMeshAsync(meshesNames, scene, data, rootUrl, onSuccess, onProgress, onError);
         importMeshAsync(meshesNames: any, scene: Scene, data: IGLTFLoaderData, rootUrl: string, onProgress: (event: SceneLoaderProgressEvent) => void): Promise<{
         importMeshAsync(meshesNames: any, scene: Scene, data: IGLTFLoaderData, rootUrl: string, onProgress: (event: SceneLoaderProgressEvent) => void): Promise<{

+ 16 - 10
dist/preview release/loaders/babylon.glTF1FileLoader.js

@@ -86,6 +86,11 @@ var BABYLON;
             * Raised when the loader is disposed.
             * Raised when the loader is disposed.
             */
             */
             this.onDisposeObservable = new BABYLON.Observable();
             this.onDisposeObservable = new BABYLON.Observable();
+            /**
+             * Raised after a loader extension is created.
+             * Set additional options for a loader extension in this event.
+             */
+            this.onExtensionLoadedObservable = new BABYLON.Observable();
             // #endregion
             // #endregion
             this._loader = null;
             this._loader = null;
             this.name = "gltf";
             this.name = "gltf";
@@ -154,22 +159,22 @@ var BABYLON;
             enumerable: true,
             enumerable: true,
             configurable: true
             configurable: true
         });
         });
-        Object.defineProperty(GLTFFileLoader.prototype, "loaderState", {
-            /**
-             * The loader state or null if not active.
-             */
-            get: function () {
-                return this._loader ? this._loader.state : null;
+        Object.defineProperty(GLTFFileLoader.prototype, "onExtensionLoaded", {
+            set: function (callback) {
+                if (this._onExtensionLoadedObserver) {
+                    this.onExtensionLoadedObservable.remove(this._onExtensionLoadedObserver);
+                }
+                this._onExtensionLoadedObserver = this.onExtensionLoadedObservable.add(callback);
             },
             },
             enumerable: true,
             enumerable: true,
             configurable: true
             configurable: true
         });
         });
-        Object.defineProperty(GLTFFileLoader.prototype, "loaderExtensions", {
+        Object.defineProperty(GLTFFileLoader.prototype, "loaderState", {
             /**
             /**
-             * The loader extensions or null if not active.
+             * The loader state or null if not active.
              */
              */
             get: function () {
             get: function () {
-                return this._loader ? this._loader.extensions : null;
+                return this._loader ? this._loader.state : null;
             },
             },
             enumerable: true,
             enumerable: true,
             configurable: true
             configurable: true
@@ -276,6 +281,7 @@ var BABYLON;
             loader.onTextureLoadedObservable.add(function (texture) { return _this.onTextureLoadedObservable.notifyObservers(texture); });
             loader.onTextureLoadedObservable.add(function (texture) { return _this.onTextureLoadedObservable.notifyObservers(texture); });
             loader.onMaterialLoadedObservable.add(function (material) { return _this.onMaterialLoadedObservable.notifyObservers(material); });
             loader.onMaterialLoadedObservable.add(function (material) { return _this.onMaterialLoadedObservable.notifyObservers(material); });
             loader.onCompleteObservable.add(function () { return _this.onCompleteObservable.notifyObservers(_this); });
             loader.onCompleteObservable.add(function () { return _this.onCompleteObservable.notifyObservers(_this); });
+            loader.onExtensionLoadedObservable.add(function (extension) { return _this.onExtensionLoadedObservable.notifyObservers(extension); });
             return loader;
             return loader;
         };
         };
         GLTFFileLoader._parseBinary = function (data) {
         GLTFFileLoader._parseBinary = function (data) {
@@ -1827,8 +1833,8 @@ var BABYLON;
                 this.onTextureLoadedObservable = new BABYLON.Observable();
                 this.onTextureLoadedObservable = new BABYLON.Observable();
                 this.onMaterialLoadedObservable = new BABYLON.Observable();
                 this.onMaterialLoadedObservable = new BABYLON.Observable();
                 this.onCompleteObservable = new BABYLON.Observable();
                 this.onCompleteObservable = new BABYLON.Observable();
+                this.onExtensionLoadedObservable = new BABYLON.Observable();
                 this.state = null;
                 this.state = null;
-                this.extensions = null;
             }
             }
             GLTFLoader.RegisterExtension = function (extension) {
             GLTFLoader.RegisterExtension = function (extension) {
                 if (GLTFLoader.Extensions[extension.name]) {
                 if (GLTFLoader.Extensions[extension.name]) {

File diff suppressed because it is too large
+ 2 - 2
dist/preview release/loaders/babylon.glTF1FileLoader.min.js


+ 33 - 23
dist/preview release/loaders/babylon.glTF2FileLoader.d.ts

@@ -28,30 +28,34 @@ declare module BABYLON {
         json: Object;
         json: Object;
         bin: Nullable<ArrayBufferView>;
         bin: Nullable<ArrayBufferView>;
     }
     }
+    interface IGLTFLoaderExtension {
+        /**
+         * The name of this extension.
+         */
+        readonly name: string;
+        /**
+         * Whether this extension is enabled.
+         */
+        enabled: boolean;
+    }
     enum GLTFLoaderState {
     enum GLTFLoaderState {
         Loading = 0,
         Loading = 0,
         Ready = 1,
         Ready = 1,
         Complete = 2,
         Complete = 2,
     }
     }
-    interface IGLTFLoaderExtension {
-        enabled: boolean;
-    }
-    interface IGLTFLoaderExtensions {
-        [name: string]: IGLTFLoaderExtension;
-    }
     interface IGLTFLoader extends IDisposable {
     interface IGLTFLoader extends IDisposable {
         coordinateSystemMode: GLTFLoaderCoordinateSystemMode;
         coordinateSystemMode: GLTFLoaderCoordinateSystemMode;
         animationStartMode: GLTFLoaderAnimationStartMode;
         animationStartMode: GLTFLoaderAnimationStartMode;
         compileMaterials: boolean;
         compileMaterials: boolean;
         useClipPlane: boolean;
         useClipPlane: boolean;
         compileShadowGenerators: boolean;
         compileShadowGenerators: boolean;
-        onDisposeObservable: Observable<IGLTFLoader>;
         onMeshLoadedObservable: Observable<AbstractMesh>;
         onMeshLoadedObservable: Observable<AbstractMesh>;
         onTextureLoadedObservable: Observable<BaseTexture>;
         onTextureLoadedObservable: Observable<BaseTexture>;
         onMaterialLoadedObservable: Observable<Material>;
         onMaterialLoadedObservable: Observable<Material>;
         onCompleteObservable: Observable<IGLTFLoader>;
         onCompleteObservable: Observable<IGLTFLoader>;
+        onDisposeObservable: Observable<IGLTFLoader>;
+        onExtensionLoadedObservable: Observable<IGLTFLoaderExtension>;
         state: Nullable<GLTFLoaderState>;
         state: Nullable<GLTFLoaderState>;
-        extensions: Nullable<IGLTFLoaderExtensions>;
         importMeshAsync: (meshesNames: any, scene: Scene, data: IGLTFLoaderData, rootUrl: string, onProgress?: (event: SceneLoaderProgressEvent) => void) => Promise<{
         importMeshAsync: (meshesNames: any, scene: Scene, data: IGLTFLoaderData, rootUrl: string, onProgress?: (event: SceneLoaderProgressEvent) => void) => Promise<{
             meshes: AbstractMesh[];
             meshes: AbstractMesh[];
             particleSystems: ParticleSystem[];
             particleSystems: ParticleSystem[];
@@ -125,13 +129,16 @@ declare module BABYLON {
         private _onDisposeObserver;
         private _onDisposeObserver;
         onDispose: () => void;
         onDispose: () => void;
         /**
         /**
-         * The loader state or null if not active.
+         * Raised after a loader extension is created.
+         * Set additional options for a loader extension in this event.
          */
          */
-        readonly loaderState: Nullable<GLTFLoaderState>;
+        readonly onExtensionLoadedObservable: Observable<IGLTFLoaderExtension>;
+        private _onExtensionLoadedObserver;
+        onExtensionLoaded: (extension: IGLTFLoaderExtension) => void;
         /**
         /**
-         * The loader extensions or null if not active.
+         * The loader state or null if not active.
          */
          */
-        readonly loaderExtensions: Nullable<IGLTFLoaderExtensions>;
+        readonly loaderState: Nullable<GLTFLoaderState>;
         private _loader;
         private _loader;
         name: string;
         name: string;
         extensions: ISceneLoaderPluginExtensions;
         extensions: ISceneLoaderPluginExtensions;
@@ -283,10 +290,9 @@ declare module BABYLON.GLTF2 {
         readonly onMeshLoadedObservable: Observable<AbstractMesh>;
         readonly onMeshLoadedObservable: Observable<AbstractMesh>;
         readonly onTextureLoadedObservable: Observable<BaseTexture>;
         readonly onTextureLoadedObservable: Observable<BaseTexture>;
         readonly onMaterialLoadedObservable: Observable<Material>;
         readonly onMaterialLoadedObservable: Observable<Material>;
+        readonly onExtensionLoadedObservable: Observable<IGLTFLoaderExtension>;
         readonly onCompleteObservable: Observable<IGLTFLoader>;
         readonly onCompleteObservable: Observable<IGLTFLoader>;
         readonly state: Nullable<GLTFLoaderState>;
         readonly state: Nullable<GLTFLoaderState>;
-        readonly extensions: IGLTFLoaderExtensions;
-        constructor();
         dispose(): void;
         dispose(): void;
         importMeshAsync(meshesNames: any, scene: Scene, data: IGLTFLoaderData, rootUrl: string, onProgress?: (event: SceneLoaderProgressEvent) => void): Promise<{
         importMeshAsync(meshesNames: any, scene: Scene, data: IGLTFLoaderData, rootUrl: string, onProgress?: (event: SceneLoaderProgressEvent) => void): Promise<{
             meshes: AbstractMesh[];
             meshes: AbstractMesh[];
@@ -353,11 +359,11 @@ declare module BABYLON.GLTF2 {
 
 
 
 
 declare module BABYLON.GLTF2 {
 declare module BABYLON.GLTF2 {
-    abstract class GLTFLoaderExtension {
+    abstract class GLTFLoaderExtension implements IGLTFLoaderExtension {
         enabled: boolean;
         enabled: boolean;
         protected _loader: GLTFLoader;
         protected _loader: GLTFLoader;
         constructor(loader: GLTFLoader);
         constructor(loader: GLTFLoader);
-        protected readonly abstract _name: string;
+        readonly abstract name: string;
         /** Override this method to modify the default behavior for loading scenes. */
         /** Override this method to modify the default behavior for loading scenes. */
         protected _loadSceneAsync(context: string, node: ILoaderScene): Nullable<Promise<void>>;
         protected _loadSceneAsync(context: string, node: ILoaderScene): Nullable<Promise<void>>;
         /** Override this method to modify the default behavior for loading nodes. */
         /** Override this method to modify the default behavior for loading nodes. */
@@ -381,26 +387,30 @@ declare module BABYLON.GLTF2 {
 
 
 
 
 declare module BABYLON.GLTF2.Extensions {
 declare module BABYLON.GLTF2.Extensions {
-    class MSFTLOD extends GLTFLoaderExtension {
+    class MSFT_lod extends GLTFLoaderExtension {
+        readonly name: string;
+        /**
+         * Maximum number of LODs to load, starting from the lowest LOD.
+         */
+        maxLODsToLoad: number;
         private _loadingNodeLOD;
         private _loadingNodeLOD;
         private _loadNodeSignals;
         private _loadNodeSignals;
         private _loadingMaterialLOD;
         private _loadingMaterialLOD;
         private _loadMaterialSignals;
         private _loadMaterialSignals;
-        protected readonly _name: string;
         protected _loadNodeAsync(context: string, node: ILoaderNode): Nullable<Promise<void>>;
         protected _loadNodeAsync(context: string, node: ILoaderNode): Nullable<Promise<void>>;
         protected _loadMaterialAsync(context: string, material: ILoaderMaterial, babylonMesh: Mesh): Nullable<Promise<void>>;
         protected _loadMaterialAsync(context: string, material: ILoaderMaterial, babylonMesh: Mesh): Nullable<Promise<void>>;
         protected _loadUriAsync(context: string, uri: string): Nullable<Promise<ArrayBufferView>>;
         protected _loadUriAsync(context: string, uri: string): Nullable<Promise<ArrayBufferView>>;
         /**
         /**
          * Gets an array of LOD properties from lowest to highest.
          * Gets an array of LOD properties from lowest to highest.
          */
          */
-        private static _GetLODs<T>(context, property, array, ids);
+        private _getLODs<T>(context, property, array, ids);
     }
     }
 }
 }
 
 
 
 
 declare module BABYLON.GLTF2.Extensions {
 declare module BABYLON.GLTF2.Extensions {
-    class KHRMaterialsPbrSpecularGlossiness extends GLTFLoaderExtension {
-        protected readonly _name: string;
+    class KHR_materials_pbrSpecularGlossiness extends GLTFLoaderExtension {
+        readonly name: string;
         protected _loadMaterialAsync(context: string, material: ILoaderMaterial, babylonMesh: Mesh): Nullable<Promise<void>>;
         protected _loadMaterialAsync(context: string, material: ILoaderMaterial, babylonMesh: Mesh): Nullable<Promise<void>>;
         private _loadSpecularGlossinessPropertiesAsync(loader, context, material, properties);
         private _loadSpecularGlossinessPropertiesAsync(loader, context, material, properties);
     }
     }
@@ -408,8 +418,8 @@ declare module BABYLON.GLTF2.Extensions {
 
 
 
 
 declare module BABYLON.GLTF2.Extensions {
 declare module BABYLON.GLTF2.Extensions {
-    class KHRLights extends GLTFLoaderExtension {
-        protected readonly _name: string;
+    class KHR_lights extends GLTFLoaderExtension {
+        readonly name: string;
         protected _loadSceneAsync(context: string, scene: ILoaderScene): Nullable<Promise<void>>;
         protected _loadSceneAsync(context: string, scene: ILoaderScene): Nullable<Promise<void>>;
         protected _loadNodeAsync(context: string, node: ILoaderNode): Nullable<Promise<void>>;
         protected _loadNodeAsync(context: string, node: ILoaderNode): Nullable<Promise<void>>;
         private readonly _lights;
         private readonly _lights;

+ 122 - 110
dist/preview release/loaders/babylon.glTF2FileLoader.js

@@ -86,6 +86,11 @@ var BABYLON;
             * Raised when the loader is disposed.
             * Raised when the loader is disposed.
             */
             */
             this.onDisposeObservable = new BABYLON.Observable();
             this.onDisposeObservable = new BABYLON.Observable();
+            /**
+             * Raised after a loader extension is created.
+             * Set additional options for a loader extension in this event.
+             */
+            this.onExtensionLoadedObservable = new BABYLON.Observable();
             // #endregion
             // #endregion
             this._loader = null;
             this._loader = null;
             this.name = "gltf";
             this.name = "gltf";
@@ -154,22 +159,22 @@ var BABYLON;
             enumerable: true,
             enumerable: true,
             configurable: true
             configurable: true
         });
         });
-        Object.defineProperty(GLTFFileLoader.prototype, "loaderState", {
-            /**
-             * The loader state or null if not active.
-             */
-            get: function () {
-                return this._loader ? this._loader.state : null;
+        Object.defineProperty(GLTFFileLoader.prototype, "onExtensionLoaded", {
+            set: function (callback) {
+                if (this._onExtensionLoadedObserver) {
+                    this.onExtensionLoadedObservable.remove(this._onExtensionLoadedObserver);
+                }
+                this._onExtensionLoadedObserver = this.onExtensionLoadedObservable.add(callback);
             },
             },
             enumerable: true,
             enumerable: true,
             configurable: true
             configurable: true
         });
         });
-        Object.defineProperty(GLTFFileLoader.prototype, "loaderExtensions", {
+        Object.defineProperty(GLTFFileLoader.prototype, "loaderState", {
             /**
             /**
-             * The loader extensions or null if not active.
+             * The loader state or null if not active.
              */
              */
             get: function () {
             get: function () {
-                return this._loader ? this._loader.extensions : null;
+                return this._loader ? this._loader.state : null;
             },
             },
             enumerable: true,
             enumerable: true,
             configurable: true
             configurable: true
@@ -276,6 +281,7 @@ var BABYLON;
             loader.onTextureLoadedObservable.add(function (texture) { return _this.onTextureLoadedObservable.notifyObservers(texture); });
             loader.onTextureLoadedObservable.add(function (texture) { return _this.onTextureLoadedObservable.notifyObservers(texture); });
             loader.onMaterialLoadedObservable.add(function (material) { return _this.onMaterialLoadedObservable.notifyObservers(material); });
             loader.onMaterialLoadedObservable.add(function (material) { return _this.onMaterialLoadedObservable.notifyObservers(material); });
             loader.onCompleteObservable.add(function () { return _this.onCompleteObservable.notifyObservers(_this); });
             loader.onCompleteObservable.add(function () { return _this.onCompleteObservable.notifyObservers(_this); });
+            loader.onExtensionLoadedObservable.add(function (extension) { return _this.onExtensionLoadedObservable.notifyObservers(extension); });
             return loader;
             return loader;
         };
         };
         GLTFFileLoader._parseBinary = function (data) {
         GLTFFileLoader._parseBinary = function (data) {
@@ -488,12 +494,8 @@ var BABYLON;
                 this.onMeshLoadedObservable = new BABYLON.Observable();
                 this.onMeshLoadedObservable = new BABYLON.Observable();
                 this.onTextureLoadedObservable = new BABYLON.Observable();
                 this.onTextureLoadedObservable = new BABYLON.Observable();
                 this.onMaterialLoadedObservable = new BABYLON.Observable();
                 this.onMaterialLoadedObservable = new BABYLON.Observable();
+                this.onExtensionLoadedObservable = new BABYLON.Observable();
                 this.onCompleteObservable = new BABYLON.Observable();
                 this.onCompleteObservable = new BABYLON.Observable();
-                for (var _i = 0, _a = GLTFLoader._Names; _i < _a.length; _i++) {
-                    var name_1 = _a[_i];
-                    var extension = GLTFLoader._Factories[name_1](this);
-                    this._extensions[name_1] = extension;
-                }
             }
             }
             GLTFLoader._Register = function (name, factory) {
             GLTFLoader._Register = function (name, factory) {
                 if (GLTFLoader._Factories[name]) {
                 if (GLTFLoader._Factories[name]) {
@@ -511,13 +513,6 @@ var BABYLON;
                 enumerable: true,
                 enumerable: true,
                 configurable: true
                 configurable: true
             });
             });
-            Object.defineProperty(GLTFLoader.prototype, "extensions", {
-                get: function () {
-                    return this.extensions;
-                },
-                enumerable: true,
-                configurable: true
-            });
             GLTFLoader.prototype.dispose = function () {
             GLTFLoader.prototype.dispose = function () {
                 if (this._disposed) {
                 if (this._disposed) {
                     return;
                     return;
@@ -565,6 +560,12 @@ var BABYLON;
             GLTFLoader.prototype._loadAsync = function (nodes, scene, data, rootUrl, onProgress) {
             GLTFLoader.prototype._loadAsync = function (nodes, scene, data, rootUrl, onProgress) {
                 var _this = this;
                 var _this = this;
                 return Promise.resolve().then(function () {
                 return Promise.resolve().then(function () {
+                    for (var _i = 0, _a = GLTFLoader._Names; _i < _a.length; _i++) {
+                        var name_1 = _a[_i];
+                        var extension = GLTFLoader._Factories[name_1](_this);
+                        _this._extensions[name_1] = extension;
+                        _this.onExtensionLoadedObservable.notifyObservers(extension);
+                    }
                     _this._babylonScene = scene;
                     _this._babylonScene = scene;
                     _this._rootUrl = rootUrl;
                     _this._rootUrl = rootUrl;
                     _this._progressCallback = onProgress;
                     _this._progressCallback = onProgress;
@@ -588,20 +589,22 @@ var BABYLON;
                         _this._state = BABYLON.GLTFLoaderState.Ready;
                         _this._state = BABYLON.GLTFLoaderState.Ready;
                         _this._startAnimations();
                         _this._startAnimations();
                         BABYLON.Tools.SetImmediate(function () {
                         BABYLON.Tools.SetImmediate(function () {
-                            Promise.all(_this._completePromises).then(function () {
-                                _this._releaseResources();
-                                _this._state = BABYLON.GLTFLoaderState.Complete;
-                                _this.onCompleteObservable.notifyObservers(_this);
-                            }).catch(function (error) {
-                                BABYLON.Tools.Error("glTF Loader: " + error.message);
-                                _this.dispose();
-                            });
+                            if (!_this._disposed) {
+                                Promise.all(_this._completePromises).then(function () {
+                                    _this._releaseResources();
+                                    _this._state = BABYLON.GLTFLoaderState.Complete;
+                                    _this.onCompleteObservable.notifyObservers(_this);
+                                }).catch(function (error) {
+                                    BABYLON.Tools.Error("glTF Loader: " + error.message);
+                                    _this.dispose();
+                                });
+                            }
                         });
                         });
-                    }).catch(function (error) {
-                        BABYLON.Tools.Error("glTF Loader: " + error.message);
-                        _this.dispose();
-                        throw error;
                     });
                     });
+                }).catch(function (error) {
+                    BABYLON.Tools.Error("glTF Loader: " + error.message);
+                    _this.dispose();
+                    throw error;
                 });
                 });
             };
             };
             GLTFLoader.prototype._loadData = function (data) {
             GLTFLoader.prototype._loadData = function (data) {
@@ -1542,6 +1545,7 @@ var BABYLON;
                 }
                 }
             };
             };
             GLTFLoader.prototype._loadTextureAsync = function (context, textureInfo, assign) {
             GLTFLoader.prototype._loadTextureAsync = function (context, textureInfo, assign) {
+                var _this = this;
                 var texture = GLTFLoader._GetProperty(context + "/index", this._gltf.textures, textureInfo.index);
                 var texture = GLTFLoader._GetProperty(context + "/index", this._gltf.textures, textureInfo.index);
                 context = "#/textures/" + textureInfo.index;
                 context = "#/textures/" + textureInfo.index;
                 var promises = new Array();
                 var promises = new Array();
@@ -1549,9 +1553,13 @@ var BABYLON;
                 var samplerData = this._loadSampler("#/samplers/" + sampler._index, sampler);
                 var samplerData = this._loadSampler("#/samplers/" + sampler._index, sampler);
                 var deferred = new BABYLON.Deferred();
                 var deferred = new BABYLON.Deferred();
                 var babylonTexture = new BABYLON.Texture(null, this._babylonScene, samplerData.noMipMaps, false, samplerData.samplingMode, function () {
                 var babylonTexture = new BABYLON.Texture(null, this._babylonScene, samplerData.noMipMaps, false, samplerData.samplingMode, function () {
-                    deferred.resolve();
+                    if (!_this._disposed) {
+                        deferred.resolve();
+                    }
                 }, function (message, exception) {
                 }, function (message, exception) {
-                    deferred.reject(new Error(context + ": " + (exception && exception.message) ? exception.message : message || "Failed to load texture"));
+                    if (!_this._disposed) {
+                        deferred.reject(new Error(context + ": " + (exception && exception.message) ? exception.message : message || "Failed to load texture"));
+                    }
                 });
                 });
                 promises.push(deferred.promise);
                 promises.push(deferred.promise);
                 babylonTexture.name = texture.name || "texture" + texture._index;
                 babylonTexture.name = texture.name || "texture" + texture._index;
@@ -1609,21 +1617,27 @@ var BABYLON;
                 }
                 }
                 return new Promise(function (resolve, reject) {
                 return new Promise(function (resolve, reject) {
                     var request = BABYLON.Tools.LoadFile(_this._rootUrl + uri, function (data) {
                     var request = BABYLON.Tools.LoadFile(_this._rootUrl + uri, function (data) {
-                        resolve(new Uint8Array(data));
+                        if (!_this._disposed) {
+                            resolve(new Uint8Array(data));
+                        }
                     }, function (event) {
                     }, function (event) {
-                        try {
-                            if (request && _this._state === BABYLON.GLTFLoaderState.Loading) {
-                                request._lengthComputable = event.lengthComputable;
-                                request._loaded = event.loaded;
-                                request._total = event.total;
-                                _this._onProgress();
+                        if (!_this._disposed) {
+                            try {
+                                if (request && _this._state === BABYLON.GLTFLoaderState.Loading) {
+                                    request._lengthComputable = event.lengthComputable;
+                                    request._loaded = event.loaded;
+                                    request._total = event.total;
+                                    _this._onProgress();
+                                }
+                            }
+                            catch (e) {
+                                reject(e);
                             }
                             }
-                        }
-                        catch (e) {
-                            reject(e);
                         }
                         }
                     }, _this._babylonScene.database, true, function (request, exception) {
                     }, _this._babylonScene.database, true, function (request, exception) {
-                        reject(new BABYLON.LoadFileError(context + ": Failed to load '" + uri + "'" + (request ? ": " + request.status + " " + request.statusText : ""), request));
+                        if (!_this._disposed) {
+                            reject(new BABYLON.LoadFileError(context + ": Failed to load '" + uri + "'" + (request ? ": " + request.status + " " + request.statusText : ""), request));
+                        }
                     });
                     });
                     _this._requests.push(request);
                     _this._requests.push(request);
                 });
                 });
@@ -1816,15 +1830,15 @@ var BABYLON;
                     return null;
                     return null;
                 }
                 }
                 var extensions = property.extensions;
                 var extensions = property.extensions;
-                var extension = extensions[this._name];
+                var extension = extensions[this.name];
                 if (!extension) {
                 if (!extension) {
                     return null;
                     return null;
                 }
                 }
                 // Clear out the extension before executing the action to avoid recursing into the same property.
                 // Clear out the extension before executing the action to avoid recursing into the same property.
-                delete extensions[this._name];
-                return actionAsync(context + "extensions/" + this._name, extension).then(function () {
+                delete extensions[this.name];
+                return actionAsync(context + "/extensions/" + this.name, extension).then(function () {
                     // Restore the extension after completing the action.
                     // Restore the extension after completing the action.
-                    extensions[_this._name] = extension;
+                    extensions[_this.name] = extension;
                 });
                 });
             };
             };
             /** Helper method called by the loader to allow extensions to override loading scenes. */
             /** Helper method called by the loader to allow extensions to override loading scenes. */
@@ -1870,28 +1884,26 @@ var BABYLON;
         (function (Extensions) {
         (function (Extensions) {
             // https://github.com/sbtron/glTF/tree/MSFT_lod/extensions/Vendor/MSFT_lod
             // https://github.com/sbtron/glTF/tree/MSFT_lod/extensions/Vendor/MSFT_lod
             var NAME = "MSFT_lod";
             var NAME = "MSFT_lod";
-            var MSFTLOD = /** @class */ (function (_super) {
-                __extends(MSFTLOD, _super);
-                function MSFTLOD() {
+            var MSFT_lod = /** @class */ (function (_super) {
+                __extends(MSFT_lod, _super);
+                function MSFT_lod() {
                     var _this = _super !== null && _super.apply(this, arguments) || this;
                     var _this = _super !== null && _super.apply(this, arguments) || this;
+                    _this.name = NAME;
+                    /**
+                     * Maximum number of LODs to load, starting from the lowest LOD.
+                     */
+                    _this.maxLODsToLoad = Number.MAX_VALUE;
                     _this._loadingNodeLOD = null;
                     _this._loadingNodeLOD = null;
                     _this._loadNodeSignals = {};
                     _this._loadNodeSignals = {};
                     _this._loadingMaterialLOD = null;
                     _this._loadingMaterialLOD = null;
                     _this._loadMaterialSignals = {};
                     _this._loadMaterialSignals = {};
                     return _this;
                     return _this;
                 }
                 }
-                Object.defineProperty(MSFTLOD.prototype, "_name", {
-                    get: function () {
-                        return NAME;
-                    },
-                    enumerable: true,
-                    configurable: true
-                });
-                MSFTLOD.prototype._loadNodeAsync = function (context, node) {
+                MSFT_lod.prototype._loadNodeAsync = function (context, node) {
                     var _this = this;
                     var _this = this;
                     return this._loadExtensionAsync(context, node, function (context, extension) {
                     return this._loadExtensionAsync(context, node, function (context, extension) {
                         var firstPromise;
                         var firstPromise;
-                        var nodeLODs = MSFTLOD._GetLODs(context, node, _this._loader._gltf.nodes, extension.ids);
+                        var nodeLODs = _this._getLODs(context, node, _this._loader._gltf.nodes, extension.ids);
                         var _loop_1 = function (indexLOD) {
                         var _loop_1 = function (indexLOD) {
                             var nodeLOD = nodeLODs[indexLOD];
                             var nodeLOD = nodeLODs[indexLOD];
                             if (indexLOD !== 0) {
                             if (indexLOD !== 0) {
@@ -1923,11 +1935,15 @@ var BABYLON;
                         return firstPromise;
                         return firstPromise;
                     });
                     });
                 };
                 };
-                MSFTLOD.prototype._loadMaterialAsync = function (context, material, babylonMesh) {
+                MSFT_lod.prototype._loadMaterialAsync = function (context, material, babylonMesh) {
                     var _this = this;
                     var _this = this;
+                    // Don't load material LODs if already loading a node LOD.
+                    if (this._loadingNodeLOD) {
+                        return null;
+                    }
                     return this._loadExtensionAsync(context, material, function (context, extension) {
                     return this._loadExtensionAsync(context, material, function (context, extension) {
                         var firstPromise;
                         var firstPromise;
-                        var materialLODs = MSFTLOD._GetLODs(context, material, _this._loader._gltf.materials, extension.ids);
+                        var materialLODs = _this._getLODs(context, material, _this._loader._gltf.materials, extension.ids);
                         var _loop_2 = function (indexLOD) {
                         var _loop_2 = function (indexLOD) {
                             var materialLOD = materialLODs[indexLOD];
                             var materialLOD = materialLODs[indexLOD];
                             if (indexLOD !== 0) {
                             if (indexLOD !== 0) {
@@ -1955,7 +1971,7 @@ var BABYLON;
                         return firstPromise;
                         return firstPromise;
                     });
                     });
                 };
                 };
-                MSFTLOD.prototype._loadUriAsync = function (context, uri) {
+                MSFT_lod.prototype._loadUriAsync = function (context, uri) {
                     var _this = this;
                     var _this = this;
                     // Defer the loading of uris if loading a material or node LOD.
                     // Defer the loading of uris if loading a material or node LOD.
                     if (this._loadingMaterialLOD) {
                     if (this._loadingMaterialLOD) {
@@ -1975,18 +1991,24 @@ var BABYLON;
                 /**
                 /**
                  * Gets an array of LOD properties from lowest to highest.
                  * Gets an array of LOD properties from lowest to highest.
                  */
                  */
-                MSFTLOD._GetLODs = function (context, property, array, ids) {
-                    var properties = [property];
-                    for (var _i = 0, ids_1 = ids; _i < ids_1.length; _i++) {
-                        var id = ids_1[_i];
-                        properties.push(GLTF2.GLTFLoader._GetProperty(context + "/ids/" + id, array, id));
+                MSFT_lod.prototype._getLODs = function (context, property, array, ids) {
+                    if (this.maxLODsToLoad <= 0) {
+                        throw new Error("maxLODsToLoad must be greater than zero");
+                    }
+                    var properties = new Array();
+                    for (var i = ids.length - 1; i >= 0; i--) {
+                        properties.push(GLTF2.GLTFLoader._GetProperty(context + "/ids/" + ids[i], array, ids[i]));
+                        if (properties.length === this.maxLODsToLoad) {
+                            return properties;
+                        }
                     }
                     }
-                    return properties.reverse();
+                    properties.push(property);
+                    return properties;
                 };
                 };
-                return MSFTLOD;
+                return MSFT_lod;
             }(GLTF2.GLTFLoaderExtension));
             }(GLTF2.GLTFLoaderExtension));
-            Extensions.MSFTLOD = MSFTLOD;
-            GLTF2.GLTFLoader._Register(NAME, function (loader) { return new MSFTLOD(loader); });
+            Extensions.MSFT_lod = MSFT_lod;
+            GLTF2.GLTFLoader._Register(NAME, function (loader) { return new MSFT_lod(loader); });
         })(Extensions = GLTF2.Extensions || (GLTF2.Extensions = {}));
         })(Extensions = GLTF2.Extensions || (GLTF2.Extensions = {}));
     })(GLTF2 = BABYLON.GLTF2 || (BABYLON.GLTF2 = {}));
     })(GLTF2 = BABYLON.GLTF2 || (BABYLON.GLTF2 = {}));
 })(BABYLON || (BABYLON = {}));
 })(BABYLON || (BABYLON = {}));
@@ -2012,19 +2034,14 @@ var BABYLON;
         (function (Extensions) {
         (function (Extensions) {
             // https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Khronos/KHR_materials_pbrSpecularGlossiness
             // https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Khronos/KHR_materials_pbrSpecularGlossiness
             var NAME = "KHR_materials_pbrSpecularGlossiness";
             var NAME = "KHR_materials_pbrSpecularGlossiness";
-            var KHRMaterialsPbrSpecularGlossiness = /** @class */ (function (_super) {
-                __extends(KHRMaterialsPbrSpecularGlossiness, _super);
-                function KHRMaterialsPbrSpecularGlossiness() {
-                    return _super !== null && _super.apply(this, arguments) || this;
+            var KHR_materials_pbrSpecularGlossiness = /** @class */ (function (_super) {
+                __extends(KHR_materials_pbrSpecularGlossiness, _super);
+                function KHR_materials_pbrSpecularGlossiness() {
+                    var _this = _super !== null && _super.apply(this, arguments) || this;
+                    _this.name = NAME;
+                    return _this;
                 }
                 }
-                Object.defineProperty(KHRMaterialsPbrSpecularGlossiness.prototype, "_name", {
-                    get: function () {
-                        return NAME;
-                    },
-                    enumerable: true,
-                    configurable: true
-                });
-                KHRMaterialsPbrSpecularGlossiness.prototype._loadMaterialAsync = function (context, material, babylonMesh) {
+                KHR_materials_pbrSpecularGlossiness.prototype._loadMaterialAsync = function (context, material, babylonMesh) {
                     var _this = this;
                     var _this = this;
                     return this._loadExtensionAsync(context, material, function (context, extension) {
                     return this._loadExtensionAsync(context, material, function (context, extension) {
                         material._babylonMeshes = material._babylonMeshes || [];
                         material._babylonMeshes = material._babylonMeshes || [];
@@ -2043,7 +2060,7 @@ var BABYLON;
                         return (material._loaded = Promise.all(promises).then(function () { }));
                         return (material._loaded = Promise.all(promises).then(function () { }));
                     });
                     });
                 };
                 };
-                KHRMaterialsPbrSpecularGlossiness.prototype._loadSpecularGlossinessPropertiesAsync = function (loader, context, material, properties) {
+                KHR_materials_pbrSpecularGlossiness.prototype._loadSpecularGlossinessPropertiesAsync = function (loader, context, material, properties) {
                     var promises = new Array();
                     var promises = new Array();
                     var babylonMaterial = material._babylonMaterial;
                     var babylonMaterial = material._babylonMaterial;
                     if (properties.diffuseFactor) {
                     if (properties.diffuseFactor) {
@@ -2070,10 +2087,10 @@ var BABYLON;
                     loader._loadMaterialAlphaProperties(context, material);
                     loader._loadMaterialAlphaProperties(context, material);
                     return Promise.all(promises).then(function () { });
                     return Promise.all(promises).then(function () { });
                 };
                 };
-                return KHRMaterialsPbrSpecularGlossiness;
+                return KHR_materials_pbrSpecularGlossiness;
             }(GLTF2.GLTFLoaderExtension));
             }(GLTF2.GLTFLoaderExtension));
-            Extensions.KHRMaterialsPbrSpecularGlossiness = KHRMaterialsPbrSpecularGlossiness;
-            GLTF2.GLTFLoader._Register(NAME, function (loader) { return new KHRMaterialsPbrSpecularGlossiness(loader); });
+            Extensions.KHR_materials_pbrSpecularGlossiness = KHR_materials_pbrSpecularGlossiness;
+            GLTF2.GLTFLoader._Register(NAME, function (loader) { return new KHR_materials_pbrSpecularGlossiness(loader); });
         })(Extensions = GLTF2.Extensions || (GLTF2.Extensions = {}));
         })(Extensions = GLTF2.Extensions || (GLTF2.Extensions = {}));
     })(GLTF2 = BABYLON.GLTF2 || (BABYLON.GLTF2 = {}));
     })(GLTF2 = BABYLON.GLTF2 || (BABYLON.GLTF2 = {}));
 })(BABYLON || (BABYLON = {}));
 })(BABYLON || (BABYLON = {}));
@@ -2106,19 +2123,14 @@ var BABYLON;
                 LightType["POINT"] = "point";
                 LightType["POINT"] = "point";
                 LightType["SPOT"] = "spot";
                 LightType["SPOT"] = "spot";
             })(LightType || (LightType = {}));
             })(LightType || (LightType = {}));
-            var KHRLights = /** @class */ (function (_super) {
-                __extends(KHRLights, _super);
-                function KHRLights() {
-                    return _super !== null && _super.apply(this, arguments) || this;
+            var KHR_lights = /** @class */ (function (_super) {
+                __extends(KHR_lights, _super);
+                function KHR_lights() {
+                    var _this = _super !== null && _super.apply(this, arguments) || this;
+                    _this.name = NAME;
+                    return _this;
                 }
                 }
-                Object.defineProperty(KHRLights.prototype, "_name", {
-                    get: function () {
-                        return NAME;
-                    },
-                    enumerable: true,
-                    configurable: true
-                });
-                KHRLights.prototype._loadSceneAsync = function (context, scene) {
+                KHR_lights.prototype._loadSceneAsync = function (context, scene) {
                     var _this = this;
                     var _this = this;
                     return this._loadExtensionAsync(context, scene, function (context, extension) {
                     return this._loadExtensionAsync(context, scene, function (context, extension) {
                         var promise = _this._loader._loadSceneAsync(context, scene);
                         var promise = _this._loader._loadSceneAsync(context, scene);
@@ -2130,7 +2142,7 @@ var BABYLON;
                         return promise;
                         return promise;
                     });
                     });
                 };
                 };
-                KHRLights.prototype._loadNodeAsync = function (context, node) {
+                KHR_lights.prototype._loadNodeAsync = function (context, node) {
                     var _this = this;
                     var _this = this;
                     return this._loadExtensionAsync(context, node, function (context, extension) {
                     return this._loadExtensionAsync(context, node, function (context, extension) {
                         var promise = _this._loader._loadNodeAsync(context, node);
                         var promise = _this._loader._loadNodeAsync(context, node);
@@ -2167,22 +2179,22 @@ var BABYLON;
                         return promise;
                         return promise;
                     });
                     });
                 };
                 };
-                Object.defineProperty(KHRLights.prototype, "_lights", {
+                Object.defineProperty(KHR_lights.prototype, "_lights", {
                     get: function () {
                     get: function () {
                         var extensions = this._loader._gltf.extensions;
                         var extensions = this._loader._gltf.extensions;
-                        if (!extensions || !extensions[this._name]) {
-                            throw new Error("#/extensions: " + this._name + " not found");
+                        if (!extensions || !extensions[this.name]) {
+                            throw new Error("#/extensions: " + this.name + " not found");
                         }
                         }
-                        var extension = extensions[this._name];
+                        var extension = extensions[this.name];
                         return extension.lights;
                         return extension.lights;
                     },
                     },
                     enumerable: true,
                     enumerable: true,
                     configurable: true
                     configurable: true
                 });
                 });
-                return KHRLights;
+                return KHR_lights;
             }(GLTF2.GLTFLoaderExtension));
             }(GLTF2.GLTFLoaderExtension));
-            Extensions.KHRLights = KHRLights;
-            GLTF2.GLTFLoader._Register(NAME, function (loader) { return new KHRLights(loader); });
+            Extensions.KHR_lights = KHR_lights;
+            GLTF2.GLTFLoader._Register(NAME, function (loader) { return new KHR_lights(loader); });
         })(Extensions = GLTF2.Extensions || (GLTF2.Extensions = {}));
         })(Extensions = GLTF2.Extensions || (GLTF2.Extensions = {}));
     })(GLTF2 = BABYLON.GLTF2 || (BABYLON.GLTF2 = {}));
     })(GLTF2 = BABYLON.GLTF2 || (BABYLON.GLTF2 = {}));
 })(BABYLON || (BABYLON = {}));
 })(BABYLON || (BABYLON = {}));

File diff suppressed because it is too large
+ 2 - 2
dist/preview release/loaders/babylon.glTF2FileLoader.min.js


+ 34 - 24
dist/preview release/loaders/babylon.glTFFileLoader.d.ts

@@ -28,30 +28,34 @@ declare module BABYLON {
         json: Object;
         json: Object;
         bin: Nullable<ArrayBufferView>;
         bin: Nullable<ArrayBufferView>;
     }
     }
+    interface IGLTFLoaderExtension {
+        /**
+         * The name of this extension.
+         */
+        readonly name: string;
+        /**
+         * Whether this extension is enabled.
+         */
+        enabled: boolean;
+    }
     enum GLTFLoaderState {
     enum GLTFLoaderState {
         Loading = 0,
         Loading = 0,
         Ready = 1,
         Ready = 1,
         Complete = 2,
         Complete = 2,
     }
     }
-    interface IGLTFLoaderExtension {
-        enabled: boolean;
-    }
-    interface IGLTFLoaderExtensions {
-        [name: string]: IGLTFLoaderExtension;
-    }
     interface IGLTFLoader extends IDisposable {
     interface IGLTFLoader extends IDisposable {
         coordinateSystemMode: GLTFLoaderCoordinateSystemMode;
         coordinateSystemMode: GLTFLoaderCoordinateSystemMode;
         animationStartMode: GLTFLoaderAnimationStartMode;
         animationStartMode: GLTFLoaderAnimationStartMode;
         compileMaterials: boolean;
         compileMaterials: boolean;
         useClipPlane: boolean;
         useClipPlane: boolean;
         compileShadowGenerators: boolean;
         compileShadowGenerators: boolean;
-        onDisposeObservable: Observable<IGLTFLoader>;
         onMeshLoadedObservable: Observable<AbstractMesh>;
         onMeshLoadedObservable: Observable<AbstractMesh>;
         onTextureLoadedObservable: Observable<BaseTexture>;
         onTextureLoadedObservable: Observable<BaseTexture>;
         onMaterialLoadedObservable: Observable<Material>;
         onMaterialLoadedObservable: Observable<Material>;
         onCompleteObservable: Observable<IGLTFLoader>;
         onCompleteObservable: Observable<IGLTFLoader>;
+        onDisposeObservable: Observable<IGLTFLoader>;
+        onExtensionLoadedObservable: Observable<IGLTFLoaderExtension>;
         state: Nullable<GLTFLoaderState>;
         state: Nullable<GLTFLoaderState>;
-        extensions: Nullable<IGLTFLoaderExtensions>;
         importMeshAsync: (meshesNames: any, scene: Scene, data: IGLTFLoaderData, rootUrl: string, onProgress?: (event: SceneLoaderProgressEvent) => void) => Promise<{
         importMeshAsync: (meshesNames: any, scene: Scene, data: IGLTFLoaderData, rootUrl: string, onProgress?: (event: SceneLoaderProgressEvent) => void) => Promise<{
             meshes: AbstractMesh[];
             meshes: AbstractMesh[];
             particleSystems: ParticleSystem[];
             particleSystems: ParticleSystem[];
@@ -125,13 +129,16 @@ declare module BABYLON {
         private _onDisposeObserver;
         private _onDisposeObserver;
         onDispose: () => void;
         onDispose: () => void;
         /**
         /**
-         * The loader state or null if not active.
+         * Raised after a loader extension is created.
+         * Set additional options for a loader extension in this event.
          */
          */
-        readonly loaderState: Nullable<GLTFLoaderState>;
+        readonly onExtensionLoadedObservable: Observable<IGLTFLoaderExtension>;
+        private _onExtensionLoadedObserver;
+        onExtensionLoaded: (extension: IGLTFLoaderExtension) => void;
         /**
         /**
-         * The loader extensions or null if not active.
+         * The loader state or null if not active.
          */
          */
-        readonly loaderExtensions: Nullable<IGLTFLoaderExtensions>;
+        readonly loaderState: Nullable<GLTFLoaderState>;
         private _loader;
         private _loader;
         name: string;
         name: string;
         extensions: ISceneLoaderPluginExtensions;
         extensions: ISceneLoaderPluginExtensions;
@@ -563,8 +570,8 @@ declare module BABYLON.GLTF1 {
         onTextureLoadedObservable: Observable<BaseTexture>;
         onTextureLoadedObservable: Observable<BaseTexture>;
         onMaterialLoadedObservable: Observable<Material>;
         onMaterialLoadedObservable: Observable<Material>;
         onCompleteObservable: Observable<IGLTFLoader>;
         onCompleteObservable: Observable<IGLTFLoader>;
+        onExtensionLoadedObservable: Observable<IGLTFLoaderExtension>;
         state: Nullable<GLTFLoaderState>;
         state: Nullable<GLTFLoaderState>;
-        extensions: Nullable<IGLTFLoaderExtensions>;
         dispose(): void;
         dispose(): void;
         private _importMeshAsync(meshesNames, scene, data, rootUrl, onSuccess, onProgress, onError);
         private _importMeshAsync(meshesNames, scene, data, rootUrl, onSuccess, onProgress, onError);
         importMeshAsync(meshesNames: any, scene: Scene, data: IGLTFLoaderData, rootUrl: string, onProgress: (event: SceneLoaderProgressEvent) => void): Promise<{
         importMeshAsync(meshesNames: any, scene: Scene, data: IGLTFLoaderData, rootUrl: string, onProgress: (event: SceneLoaderProgressEvent) => void): Promise<{
@@ -838,10 +845,9 @@ declare module BABYLON.GLTF2 {
         readonly onMeshLoadedObservable: Observable<AbstractMesh>;
         readonly onMeshLoadedObservable: Observable<AbstractMesh>;
         readonly onTextureLoadedObservable: Observable<BaseTexture>;
         readonly onTextureLoadedObservable: Observable<BaseTexture>;
         readonly onMaterialLoadedObservable: Observable<Material>;
         readonly onMaterialLoadedObservable: Observable<Material>;
+        readonly onExtensionLoadedObservable: Observable<IGLTFLoaderExtension>;
         readonly onCompleteObservable: Observable<IGLTFLoader>;
         readonly onCompleteObservable: Observable<IGLTFLoader>;
         readonly state: Nullable<GLTFLoaderState>;
         readonly state: Nullable<GLTFLoaderState>;
-        readonly extensions: IGLTFLoaderExtensions;
-        constructor();
         dispose(): void;
         dispose(): void;
         importMeshAsync(meshesNames: any, scene: Scene, data: IGLTFLoaderData, rootUrl: string, onProgress?: (event: SceneLoaderProgressEvent) => void): Promise<{
         importMeshAsync(meshesNames: any, scene: Scene, data: IGLTFLoaderData, rootUrl: string, onProgress?: (event: SceneLoaderProgressEvent) => void): Promise<{
             meshes: AbstractMesh[];
             meshes: AbstractMesh[];
@@ -908,11 +914,11 @@ declare module BABYLON.GLTF2 {
 
 
 
 
 declare module BABYLON.GLTF2 {
 declare module BABYLON.GLTF2 {
-    abstract class GLTFLoaderExtension {
+    abstract class GLTFLoaderExtension implements IGLTFLoaderExtension {
         enabled: boolean;
         enabled: boolean;
         protected _loader: GLTFLoader;
         protected _loader: GLTFLoader;
         constructor(loader: GLTFLoader);
         constructor(loader: GLTFLoader);
-        protected readonly abstract _name: string;
+        readonly abstract name: string;
         /** Override this method to modify the default behavior for loading scenes. */
         /** Override this method to modify the default behavior for loading scenes. */
         protected _loadSceneAsync(context: string, node: ILoaderScene): Nullable<Promise<void>>;
         protected _loadSceneAsync(context: string, node: ILoaderScene): Nullable<Promise<void>>;
         /** Override this method to modify the default behavior for loading nodes. */
         /** Override this method to modify the default behavior for loading nodes. */
@@ -936,26 +942,30 @@ declare module BABYLON.GLTF2 {
 
 
 
 
 declare module BABYLON.GLTF2.Extensions {
 declare module BABYLON.GLTF2.Extensions {
-    class MSFTLOD extends GLTFLoaderExtension {
+    class MSFT_lod extends GLTFLoaderExtension {
+        readonly name: string;
+        /**
+         * Maximum number of LODs to load, starting from the lowest LOD.
+         */
+        maxLODsToLoad: number;
         private _loadingNodeLOD;
         private _loadingNodeLOD;
         private _loadNodeSignals;
         private _loadNodeSignals;
         private _loadingMaterialLOD;
         private _loadingMaterialLOD;
         private _loadMaterialSignals;
         private _loadMaterialSignals;
-        protected readonly _name: string;
         protected _loadNodeAsync(context: string, node: ILoaderNode): Nullable<Promise<void>>;
         protected _loadNodeAsync(context: string, node: ILoaderNode): Nullable<Promise<void>>;
         protected _loadMaterialAsync(context: string, material: ILoaderMaterial, babylonMesh: Mesh): Nullable<Promise<void>>;
         protected _loadMaterialAsync(context: string, material: ILoaderMaterial, babylonMesh: Mesh): Nullable<Promise<void>>;
         protected _loadUriAsync(context: string, uri: string): Nullable<Promise<ArrayBufferView>>;
         protected _loadUriAsync(context: string, uri: string): Nullable<Promise<ArrayBufferView>>;
         /**
         /**
          * Gets an array of LOD properties from lowest to highest.
          * Gets an array of LOD properties from lowest to highest.
          */
          */
-        private static _GetLODs<T>(context, property, array, ids);
+        private _getLODs<T>(context, property, array, ids);
     }
     }
 }
 }
 
 
 
 
 declare module BABYLON.GLTF2.Extensions {
 declare module BABYLON.GLTF2.Extensions {
-    class KHRMaterialsPbrSpecularGlossiness extends GLTFLoaderExtension {
-        protected readonly _name: string;
+    class KHR_materials_pbrSpecularGlossiness extends GLTFLoaderExtension {
+        readonly name: string;
         protected _loadMaterialAsync(context: string, material: ILoaderMaterial, babylonMesh: Mesh): Nullable<Promise<void>>;
         protected _loadMaterialAsync(context: string, material: ILoaderMaterial, babylonMesh: Mesh): Nullable<Promise<void>>;
         private _loadSpecularGlossinessPropertiesAsync(loader, context, material, properties);
         private _loadSpecularGlossinessPropertiesAsync(loader, context, material, properties);
     }
     }
@@ -963,8 +973,8 @@ declare module BABYLON.GLTF2.Extensions {
 
 
 
 
 declare module BABYLON.GLTF2.Extensions {
 declare module BABYLON.GLTF2.Extensions {
-    class KHRLights extends GLTFLoaderExtension {
-        protected readonly _name: string;
+    class KHR_lights extends GLTFLoaderExtension {
+        readonly name: string;
         protected _loadSceneAsync(context: string, scene: ILoaderScene): Nullable<Promise<void>>;
         protected _loadSceneAsync(context: string, scene: ILoaderScene): Nullable<Promise<void>>;
         protected _loadNodeAsync(context: string, node: ILoaderNode): Nullable<Promise<void>>;
         protected _loadNodeAsync(context: string, node: ILoaderNode): Nullable<Promise<void>>;
         private readonly _lights;
         private readonly _lights;

+ 123 - 111
dist/preview release/loaders/babylon.glTFFileLoader.js

@@ -86,6 +86,11 @@ var BABYLON;
             * Raised when the loader is disposed.
             * Raised when the loader is disposed.
             */
             */
             this.onDisposeObservable = new BABYLON.Observable();
             this.onDisposeObservable = new BABYLON.Observable();
+            /**
+             * Raised after a loader extension is created.
+             * Set additional options for a loader extension in this event.
+             */
+            this.onExtensionLoadedObservable = new BABYLON.Observable();
             // #endregion
             // #endregion
             this._loader = null;
             this._loader = null;
             this.name = "gltf";
             this.name = "gltf";
@@ -154,22 +159,22 @@ var BABYLON;
             enumerable: true,
             enumerable: true,
             configurable: true
             configurable: true
         });
         });
-        Object.defineProperty(GLTFFileLoader.prototype, "loaderState", {
-            /**
-             * The loader state or null if not active.
-             */
-            get: function () {
-                return this._loader ? this._loader.state : null;
+        Object.defineProperty(GLTFFileLoader.prototype, "onExtensionLoaded", {
+            set: function (callback) {
+                if (this._onExtensionLoadedObserver) {
+                    this.onExtensionLoadedObservable.remove(this._onExtensionLoadedObserver);
+                }
+                this._onExtensionLoadedObserver = this.onExtensionLoadedObservable.add(callback);
             },
             },
             enumerable: true,
             enumerable: true,
             configurable: true
             configurable: true
         });
         });
-        Object.defineProperty(GLTFFileLoader.prototype, "loaderExtensions", {
+        Object.defineProperty(GLTFFileLoader.prototype, "loaderState", {
             /**
             /**
-             * The loader extensions or null if not active.
+             * The loader state or null if not active.
              */
              */
             get: function () {
             get: function () {
-                return this._loader ? this._loader.extensions : null;
+                return this._loader ? this._loader.state : null;
             },
             },
             enumerable: true,
             enumerable: true,
             configurable: true
             configurable: true
@@ -276,6 +281,7 @@ var BABYLON;
             loader.onTextureLoadedObservable.add(function (texture) { return _this.onTextureLoadedObservable.notifyObservers(texture); });
             loader.onTextureLoadedObservable.add(function (texture) { return _this.onTextureLoadedObservable.notifyObservers(texture); });
             loader.onMaterialLoadedObservable.add(function (material) { return _this.onMaterialLoadedObservable.notifyObservers(material); });
             loader.onMaterialLoadedObservable.add(function (material) { return _this.onMaterialLoadedObservable.notifyObservers(material); });
             loader.onCompleteObservable.add(function () { return _this.onCompleteObservable.notifyObservers(_this); });
             loader.onCompleteObservable.add(function () { return _this.onCompleteObservable.notifyObservers(_this); });
+            loader.onExtensionLoadedObservable.add(function (extension) { return _this.onExtensionLoadedObservable.notifyObservers(extension); });
             return loader;
             return loader;
         };
         };
         GLTFFileLoader._parseBinary = function (data) {
         GLTFFileLoader._parseBinary = function (data) {
@@ -1827,8 +1833,8 @@ var BABYLON;
                 this.onTextureLoadedObservable = new BABYLON.Observable();
                 this.onTextureLoadedObservable = new BABYLON.Observable();
                 this.onMaterialLoadedObservable = new BABYLON.Observable();
                 this.onMaterialLoadedObservable = new BABYLON.Observable();
                 this.onCompleteObservable = new BABYLON.Observable();
                 this.onCompleteObservable = new BABYLON.Observable();
+                this.onExtensionLoadedObservable = new BABYLON.Observable();
                 this.state = null;
                 this.state = null;
-                this.extensions = null;
             }
             }
             GLTFLoader.RegisterExtension = function (extension) {
             GLTFLoader.RegisterExtension = function (extension) {
                 if (GLTFLoader.Extensions[extension.name]) {
                 if (GLTFLoader.Extensions[extension.name]) {
@@ -2664,12 +2670,8 @@ var BABYLON;
                 this.onMeshLoadedObservable = new BABYLON.Observable();
                 this.onMeshLoadedObservable = new BABYLON.Observable();
                 this.onTextureLoadedObservable = new BABYLON.Observable();
                 this.onTextureLoadedObservable = new BABYLON.Observable();
                 this.onMaterialLoadedObservable = new BABYLON.Observable();
                 this.onMaterialLoadedObservable = new BABYLON.Observable();
+                this.onExtensionLoadedObservable = new BABYLON.Observable();
                 this.onCompleteObservable = new BABYLON.Observable();
                 this.onCompleteObservable = new BABYLON.Observable();
-                for (var _i = 0, _a = GLTFLoader._Names; _i < _a.length; _i++) {
-                    var name_1 = _a[_i];
-                    var extension = GLTFLoader._Factories[name_1](this);
-                    this._extensions[name_1] = extension;
-                }
             }
             }
             GLTFLoader._Register = function (name, factory) {
             GLTFLoader._Register = function (name, factory) {
                 if (GLTFLoader._Factories[name]) {
                 if (GLTFLoader._Factories[name]) {
@@ -2687,13 +2689,6 @@ var BABYLON;
                 enumerable: true,
                 enumerable: true,
                 configurable: true
                 configurable: true
             });
             });
-            Object.defineProperty(GLTFLoader.prototype, "extensions", {
-                get: function () {
-                    return this.extensions;
-                },
-                enumerable: true,
-                configurable: true
-            });
             GLTFLoader.prototype.dispose = function () {
             GLTFLoader.prototype.dispose = function () {
                 if (this._disposed) {
                 if (this._disposed) {
                     return;
                     return;
@@ -2741,6 +2736,12 @@ var BABYLON;
             GLTFLoader.prototype._loadAsync = function (nodes, scene, data, rootUrl, onProgress) {
             GLTFLoader.prototype._loadAsync = function (nodes, scene, data, rootUrl, onProgress) {
                 var _this = this;
                 var _this = this;
                 return Promise.resolve().then(function () {
                 return Promise.resolve().then(function () {
+                    for (var _i = 0, _a = GLTFLoader._Names; _i < _a.length; _i++) {
+                        var name_1 = _a[_i];
+                        var extension = GLTFLoader._Factories[name_1](_this);
+                        _this._extensions[name_1] = extension;
+                        _this.onExtensionLoadedObservable.notifyObservers(extension);
+                    }
                     _this._babylonScene = scene;
                     _this._babylonScene = scene;
                     _this._rootUrl = rootUrl;
                     _this._rootUrl = rootUrl;
                     _this._progressCallback = onProgress;
                     _this._progressCallback = onProgress;
@@ -2764,20 +2765,22 @@ var BABYLON;
                         _this._state = BABYLON.GLTFLoaderState.Ready;
                         _this._state = BABYLON.GLTFLoaderState.Ready;
                         _this._startAnimations();
                         _this._startAnimations();
                         BABYLON.Tools.SetImmediate(function () {
                         BABYLON.Tools.SetImmediate(function () {
-                            Promise.all(_this._completePromises).then(function () {
-                                _this._releaseResources();
-                                _this._state = BABYLON.GLTFLoaderState.Complete;
-                                _this.onCompleteObservable.notifyObservers(_this);
-                            }).catch(function (error) {
-                                BABYLON.Tools.Error("glTF Loader: " + error.message);
-                                _this.dispose();
-                            });
+                            if (!_this._disposed) {
+                                Promise.all(_this._completePromises).then(function () {
+                                    _this._releaseResources();
+                                    _this._state = BABYLON.GLTFLoaderState.Complete;
+                                    _this.onCompleteObservable.notifyObservers(_this);
+                                }).catch(function (error) {
+                                    BABYLON.Tools.Error("glTF Loader: " + error.message);
+                                    _this.dispose();
+                                });
+                            }
                         });
                         });
-                    }).catch(function (error) {
-                        BABYLON.Tools.Error("glTF Loader: " + error.message);
-                        _this.dispose();
-                        throw error;
                     });
                     });
+                }).catch(function (error) {
+                    BABYLON.Tools.Error("glTF Loader: " + error.message);
+                    _this.dispose();
+                    throw error;
                 });
                 });
             };
             };
             GLTFLoader.prototype._loadData = function (data) {
             GLTFLoader.prototype._loadData = function (data) {
@@ -3718,6 +3721,7 @@ var BABYLON;
                 }
                 }
             };
             };
             GLTFLoader.prototype._loadTextureAsync = function (context, textureInfo, assign) {
             GLTFLoader.prototype._loadTextureAsync = function (context, textureInfo, assign) {
+                var _this = this;
                 var texture = GLTFLoader._GetProperty(context + "/index", this._gltf.textures, textureInfo.index);
                 var texture = GLTFLoader._GetProperty(context + "/index", this._gltf.textures, textureInfo.index);
                 context = "#/textures/" + textureInfo.index;
                 context = "#/textures/" + textureInfo.index;
                 var promises = new Array();
                 var promises = new Array();
@@ -3725,9 +3729,13 @@ var BABYLON;
                 var samplerData = this._loadSampler("#/samplers/" + sampler._index, sampler);
                 var samplerData = this._loadSampler("#/samplers/" + sampler._index, sampler);
                 var deferred = new BABYLON.Deferred();
                 var deferred = new BABYLON.Deferred();
                 var babylonTexture = new BABYLON.Texture(null, this._babylonScene, samplerData.noMipMaps, false, samplerData.samplingMode, function () {
                 var babylonTexture = new BABYLON.Texture(null, this._babylonScene, samplerData.noMipMaps, false, samplerData.samplingMode, function () {
-                    deferred.resolve();
+                    if (!_this._disposed) {
+                        deferred.resolve();
+                    }
                 }, function (message, exception) {
                 }, function (message, exception) {
-                    deferred.reject(new Error(context + ": " + (exception && exception.message) ? exception.message : message || "Failed to load texture"));
+                    if (!_this._disposed) {
+                        deferred.reject(new Error(context + ": " + (exception && exception.message) ? exception.message : message || "Failed to load texture"));
+                    }
                 });
                 });
                 promises.push(deferred.promise);
                 promises.push(deferred.promise);
                 babylonTexture.name = texture.name || "texture" + texture._index;
                 babylonTexture.name = texture.name || "texture" + texture._index;
@@ -3785,21 +3793,27 @@ var BABYLON;
                 }
                 }
                 return new Promise(function (resolve, reject) {
                 return new Promise(function (resolve, reject) {
                     var request = BABYLON.Tools.LoadFile(_this._rootUrl + uri, function (data) {
                     var request = BABYLON.Tools.LoadFile(_this._rootUrl + uri, function (data) {
-                        resolve(new Uint8Array(data));
+                        if (!_this._disposed) {
+                            resolve(new Uint8Array(data));
+                        }
                     }, function (event) {
                     }, function (event) {
-                        try {
-                            if (request && _this._state === BABYLON.GLTFLoaderState.Loading) {
-                                request._lengthComputable = event.lengthComputable;
-                                request._loaded = event.loaded;
-                                request._total = event.total;
-                                _this._onProgress();
+                        if (!_this._disposed) {
+                            try {
+                                if (request && _this._state === BABYLON.GLTFLoaderState.Loading) {
+                                    request._lengthComputable = event.lengthComputable;
+                                    request._loaded = event.loaded;
+                                    request._total = event.total;
+                                    _this._onProgress();
+                                }
+                            }
+                            catch (e) {
+                                reject(e);
                             }
                             }
-                        }
-                        catch (e) {
-                            reject(e);
                         }
                         }
                     }, _this._babylonScene.database, true, function (request, exception) {
                     }, _this._babylonScene.database, true, function (request, exception) {
-                        reject(new BABYLON.LoadFileError(context + ": Failed to load '" + uri + "'" + (request ? ": " + request.status + " " + request.statusText : ""), request));
+                        if (!_this._disposed) {
+                            reject(new BABYLON.LoadFileError(context + ": Failed to load '" + uri + "'" + (request ? ": " + request.status + " " + request.statusText : ""), request));
+                        }
                     });
                     });
                     _this._requests.push(request);
                     _this._requests.push(request);
                 });
                 });
@@ -3992,15 +4006,15 @@ var BABYLON;
                     return null;
                     return null;
                 }
                 }
                 var extensions = property.extensions;
                 var extensions = property.extensions;
-                var extension = extensions[this._name];
+                var extension = extensions[this.name];
                 if (!extension) {
                 if (!extension) {
                     return null;
                     return null;
                 }
                 }
                 // Clear out the extension before executing the action to avoid recursing into the same property.
                 // Clear out the extension before executing the action to avoid recursing into the same property.
-                delete extensions[this._name];
-                return actionAsync(context + "extensions/" + this._name, extension).then(function () {
+                delete extensions[this.name];
+                return actionAsync(context + "/extensions/" + this.name, extension).then(function () {
                     // Restore the extension after completing the action.
                     // Restore the extension after completing the action.
-                    extensions[_this._name] = extension;
+                    extensions[_this.name] = extension;
                 });
                 });
             };
             };
             /** Helper method called by the loader to allow extensions to override loading scenes. */
             /** Helper method called by the loader to allow extensions to override loading scenes. */
@@ -4046,28 +4060,26 @@ var BABYLON;
         (function (Extensions) {
         (function (Extensions) {
             // https://github.com/sbtron/glTF/tree/MSFT_lod/extensions/Vendor/MSFT_lod
             // https://github.com/sbtron/glTF/tree/MSFT_lod/extensions/Vendor/MSFT_lod
             var NAME = "MSFT_lod";
             var NAME = "MSFT_lod";
-            var MSFTLOD = /** @class */ (function (_super) {
-                __extends(MSFTLOD, _super);
-                function MSFTLOD() {
+            var MSFT_lod = /** @class */ (function (_super) {
+                __extends(MSFT_lod, _super);
+                function MSFT_lod() {
                     var _this = _super !== null && _super.apply(this, arguments) || this;
                     var _this = _super !== null && _super.apply(this, arguments) || this;
+                    _this.name = NAME;
+                    /**
+                     * Maximum number of LODs to load, starting from the lowest LOD.
+                     */
+                    _this.maxLODsToLoad = Number.MAX_VALUE;
                     _this._loadingNodeLOD = null;
                     _this._loadingNodeLOD = null;
                     _this._loadNodeSignals = {};
                     _this._loadNodeSignals = {};
                     _this._loadingMaterialLOD = null;
                     _this._loadingMaterialLOD = null;
                     _this._loadMaterialSignals = {};
                     _this._loadMaterialSignals = {};
                     return _this;
                     return _this;
                 }
                 }
-                Object.defineProperty(MSFTLOD.prototype, "_name", {
-                    get: function () {
-                        return NAME;
-                    },
-                    enumerable: true,
-                    configurable: true
-                });
-                MSFTLOD.prototype._loadNodeAsync = function (context, node) {
+                MSFT_lod.prototype._loadNodeAsync = function (context, node) {
                     var _this = this;
                     var _this = this;
                     return this._loadExtensionAsync(context, node, function (context, extension) {
                     return this._loadExtensionAsync(context, node, function (context, extension) {
                         var firstPromise;
                         var firstPromise;
-                        var nodeLODs = MSFTLOD._GetLODs(context, node, _this._loader._gltf.nodes, extension.ids);
+                        var nodeLODs = _this._getLODs(context, node, _this._loader._gltf.nodes, extension.ids);
                         var _loop_1 = function (indexLOD) {
                         var _loop_1 = function (indexLOD) {
                             var nodeLOD = nodeLODs[indexLOD];
                             var nodeLOD = nodeLODs[indexLOD];
                             if (indexLOD !== 0) {
                             if (indexLOD !== 0) {
@@ -4099,11 +4111,15 @@ var BABYLON;
                         return firstPromise;
                         return firstPromise;
                     });
                     });
                 };
                 };
-                MSFTLOD.prototype._loadMaterialAsync = function (context, material, babylonMesh) {
+                MSFT_lod.prototype._loadMaterialAsync = function (context, material, babylonMesh) {
                     var _this = this;
                     var _this = this;
+                    // Don't load material LODs if already loading a node LOD.
+                    if (this._loadingNodeLOD) {
+                        return null;
+                    }
                     return this._loadExtensionAsync(context, material, function (context, extension) {
                     return this._loadExtensionAsync(context, material, function (context, extension) {
                         var firstPromise;
                         var firstPromise;
-                        var materialLODs = MSFTLOD._GetLODs(context, material, _this._loader._gltf.materials, extension.ids);
+                        var materialLODs = _this._getLODs(context, material, _this._loader._gltf.materials, extension.ids);
                         var _loop_2 = function (indexLOD) {
                         var _loop_2 = function (indexLOD) {
                             var materialLOD = materialLODs[indexLOD];
                             var materialLOD = materialLODs[indexLOD];
                             if (indexLOD !== 0) {
                             if (indexLOD !== 0) {
@@ -4131,7 +4147,7 @@ var BABYLON;
                         return firstPromise;
                         return firstPromise;
                     });
                     });
                 };
                 };
-                MSFTLOD.prototype._loadUriAsync = function (context, uri) {
+                MSFT_lod.prototype._loadUriAsync = function (context, uri) {
                     var _this = this;
                     var _this = this;
                     // Defer the loading of uris if loading a material or node LOD.
                     // Defer the loading of uris if loading a material or node LOD.
                     if (this._loadingMaterialLOD) {
                     if (this._loadingMaterialLOD) {
@@ -4151,18 +4167,24 @@ var BABYLON;
                 /**
                 /**
                  * Gets an array of LOD properties from lowest to highest.
                  * Gets an array of LOD properties from lowest to highest.
                  */
                  */
-                MSFTLOD._GetLODs = function (context, property, array, ids) {
-                    var properties = [property];
-                    for (var _i = 0, ids_1 = ids; _i < ids_1.length; _i++) {
-                        var id = ids_1[_i];
-                        properties.push(GLTF2.GLTFLoader._GetProperty(context + "/ids/" + id, array, id));
+                MSFT_lod.prototype._getLODs = function (context, property, array, ids) {
+                    if (this.maxLODsToLoad <= 0) {
+                        throw new Error("maxLODsToLoad must be greater than zero");
+                    }
+                    var properties = new Array();
+                    for (var i = ids.length - 1; i >= 0; i--) {
+                        properties.push(GLTF2.GLTFLoader._GetProperty(context + "/ids/" + ids[i], array, ids[i]));
+                        if (properties.length === this.maxLODsToLoad) {
+                            return properties;
+                        }
                     }
                     }
-                    return properties.reverse();
+                    properties.push(property);
+                    return properties;
                 };
                 };
-                return MSFTLOD;
+                return MSFT_lod;
             }(GLTF2.GLTFLoaderExtension));
             }(GLTF2.GLTFLoaderExtension));
-            Extensions.MSFTLOD = MSFTLOD;
-            GLTF2.GLTFLoader._Register(NAME, function (loader) { return new MSFTLOD(loader); });
+            Extensions.MSFT_lod = MSFT_lod;
+            GLTF2.GLTFLoader._Register(NAME, function (loader) { return new MSFT_lod(loader); });
         })(Extensions = GLTF2.Extensions || (GLTF2.Extensions = {}));
         })(Extensions = GLTF2.Extensions || (GLTF2.Extensions = {}));
     })(GLTF2 = BABYLON.GLTF2 || (BABYLON.GLTF2 = {}));
     })(GLTF2 = BABYLON.GLTF2 || (BABYLON.GLTF2 = {}));
 })(BABYLON || (BABYLON = {}));
 })(BABYLON || (BABYLON = {}));
@@ -4188,19 +4210,14 @@ var BABYLON;
         (function (Extensions) {
         (function (Extensions) {
             // https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Khronos/KHR_materials_pbrSpecularGlossiness
             // https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Khronos/KHR_materials_pbrSpecularGlossiness
             var NAME = "KHR_materials_pbrSpecularGlossiness";
             var NAME = "KHR_materials_pbrSpecularGlossiness";
-            var KHRMaterialsPbrSpecularGlossiness = /** @class */ (function (_super) {
-                __extends(KHRMaterialsPbrSpecularGlossiness, _super);
-                function KHRMaterialsPbrSpecularGlossiness() {
-                    return _super !== null && _super.apply(this, arguments) || this;
+            var KHR_materials_pbrSpecularGlossiness = /** @class */ (function (_super) {
+                __extends(KHR_materials_pbrSpecularGlossiness, _super);
+                function KHR_materials_pbrSpecularGlossiness() {
+                    var _this = _super !== null && _super.apply(this, arguments) || this;
+                    _this.name = NAME;
+                    return _this;
                 }
                 }
-                Object.defineProperty(KHRMaterialsPbrSpecularGlossiness.prototype, "_name", {
-                    get: function () {
-                        return NAME;
-                    },
-                    enumerable: true,
-                    configurable: true
-                });
-                KHRMaterialsPbrSpecularGlossiness.prototype._loadMaterialAsync = function (context, material, babylonMesh) {
+                KHR_materials_pbrSpecularGlossiness.prototype._loadMaterialAsync = function (context, material, babylonMesh) {
                     var _this = this;
                     var _this = this;
                     return this._loadExtensionAsync(context, material, function (context, extension) {
                     return this._loadExtensionAsync(context, material, function (context, extension) {
                         material._babylonMeshes = material._babylonMeshes || [];
                         material._babylonMeshes = material._babylonMeshes || [];
@@ -4219,7 +4236,7 @@ var BABYLON;
                         return (material._loaded = Promise.all(promises).then(function () { }));
                         return (material._loaded = Promise.all(promises).then(function () { }));
                     });
                     });
                 };
                 };
-                KHRMaterialsPbrSpecularGlossiness.prototype._loadSpecularGlossinessPropertiesAsync = function (loader, context, material, properties) {
+                KHR_materials_pbrSpecularGlossiness.prototype._loadSpecularGlossinessPropertiesAsync = function (loader, context, material, properties) {
                     var promises = new Array();
                     var promises = new Array();
                     var babylonMaterial = material._babylonMaterial;
                     var babylonMaterial = material._babylonMaterial;
                     if (properties.diffuseFactor) {
                     if (properties.diffuseFactor) {
@@ -4246,10 +4263,10 @@ var BABYLON;
                     loader._loadMaterialAlphaProperties(context, material);
                     loader._loadMaterialAlphaProperties(context, material);
                     return Promise.all(promises).then(function () { });
                     return Promise.all(promises).then(function () { });
                 };
                 };
-                return KHRMaterialsPbrSpecularGlossiness;
+                return KHR_materials_pbrSpecularGlossiness;
             }(GLTF2.GLTFLoaderExtension));
             }(GLTF2.GLTFLoaderExtension));
-            Extensions.KHRMaterialsPbrSpecularGlossiness = KHRMaterialsPbrSpecularGlossiness;
-            GLTF2.GLTFLoader._Register(NAME, function (loader) { return new KHRMaterialsPbrSpecularGlossiness(loader); });
+            Extensions.KHR_materials_pbrSpecularGlossiness = KHR_materials_pbrSpecularGlossiness;
+            GLTF2.GLTFLoader._Register(NAME, function (loader) { return new KHR_materials_pbrSpecularGlossiness(loader); });
         })(Extensions = GLTF2.Extensions || (GLTF2.Extensions = {}));
         })(Extensions = GLTF2.Extensions || (GLTF2.Extensions = {}));
     })(GLTF2 = BABYLON.GLTF2 || (BABYLON.GLTF2 = {}));
     })(GLTF2 = BABYLON.GLTF2 || (BABYLON.GLTF2 = {}));
 })(BABYLON || (BABYLON = {}));
 })(BABYLON || (BABYLON = {}));
@@ -4282,19 +4299,14 @@ var BABYLON;
                 LightType["POINT"] = "point";
                 LightType["POINT"] = "point";
                 LightType["SPOT"] = "spot";
                 LightType["SPOT"] = "spot";
             })(LightType || (LightType = {}));
             })(LightType || (LightType = {}));
-            var KHRLights = /** @class */ (function (_super) {
-                __extends(KHRLights, _super);
-                function KHRLights() {
-                    return _super !== null && _super.apply(this, arguments) || this;
+            var KHR_lights = /** @class */ (function (_super) {
+                __extends(KHR_lights, _super);
+                function KHR_lights() {
+                    var _this = _super !== null && _super.apply(this, arguments) || this;
+                    _this.name = NAME;
+                    return _this;
                 }
                 }
-                Object.defineProperty(KHRLights.prototype, "_name", {
-                    get: function () {
-                        return NAME;
-                    },
-                    enumerable: true,
-                    configurable: true
-                });
-                KHRLights.prototype._loadSceneAsync = function (context, scene) {
+                KHR_lights.prototype._loadSceneAsync = function (context, scene) {
                     var _this = this;
                     var _this = this;
                     return this._loadExtensionAsync(context, scene, function (context, extension) {
                     return this._loadExtensionAsync(context, scene, function (context, extension) {
                         var promise = _this._loader._loadSceneAsync(context, scene);
                         var promise = _this._loader._loadSceneAsync(context, scene);
@@ -4306,7 +4318,7 @@ var BABYLON;
                         return promise;
                         return promise;
                     });
                     });
                 };
                 };
-                KHRLights.prototype._loadNodeAsync = function (context, node) {
+                KHR_lights.prototype._loadNodeAsync = function (context, node) {
                     var _this = this;
                     var _this = this;
                     return this._loadExtensionAsync(context, node, function (context, extension) {
                     return this._loadExtensionAsync(context, node, function (context, extension) {
                         var promise = _this._loader._loadNodeAsync(context, node);
                         var promise = _this._loader._loadNodeAsync(context, node);
@@ -4343,22 +4355,22 @@ var BABYLON;
                         return promise;
                         return promise;
                     });
                     });
                 };
                 };
-                Object.defineProperty(KHRLights.prototype, "_lights", {
+                Object.defineProperty(KHR_lights.prototype, "_lights", {
                     get: function () {
                     get: function () {
                         var extensions = this._loader._gltf.extensions;
                         var extensions = this._loader._gltf.extensions;
-                        if (!extensions || !extensions[this._name]) {
-                            throw new Error("#/extensions: " + this._name + " not found");
+                        if (!extensions || !extensions[this.name]) {
+                            throw new Error("#/extensions: " + this.name + " not found");
                         }
                         }
-                        var extension = extensions[this._name];
+                        var extension = extensions[this.name];
                         return extension.lights;
                         return extension.lights;
                     },
                     },
                     enumerable: true,
                     enumerable: true,
                     configurable: true
                     configurable: true
                 });
                 });
-                return KHRLights;
+                return KHR_lights;
             }(GLTF2.GLTFLoaderExtension));
             }(GLTF2.GLTFLoaderExtension));
-            Extensions.KHRLights = KHRLights;
-            GLTF2.GLTFLoader._Register(NAME, function (loader) { return new KHRLights(loader); });
+            Extensions.KHR_lights = KHR_lights;
+            GLTF2.GLTFLoader._Register(NAME, function (loader) { return new KHR_lights(loader); });
         })(Extensions = GLTF2.Extensions || (GLTF2.Extensions = {}));
         })(Extensions = GLTF2.Extensions || (GLTF2.Extensions = {}));
     })(GLTF2 = BABYLON.GLTF2 || (BABYLON.GLTF2 = {}));
     })(GLTF2 = BABYLON.GLTF2 || (BABYLON.GLTF2 = {}));
 })(BABYLON || (BABYLON = {}));
 })(BABYLON || (BABYLON = {}));

File diff suppressed because it is too large
+ 3 - 3
dist/preview release/loaders/babylon.glTFFileLoader.min.js


+ 123 - 111
dist/preview release/loaders/babylonjs.loaders.js

@@ -1072,6 +1072,11 @@ var BABYLON;
             * Raised when the loader is disposed.
             * Raised when the loader is disposed.
             */
             */
             this.onDisposeObservable = new BABYLON.Observable();
             this.onDisposeObservable = new BABYLON.Observable();
+            /**
+             * Raised after a loader extension is created.
+             * Set additional options for a loader extension in this event.
+             */
+            this.onExtensionLoadedObservable = new BABYLON.Observable();
             // #endregion
             // #endregion
             this._loader = null;
             this._loader = null;
             this.name = "gltf";
             this.name = "gltf";
@@ -1140,22 +1145,22 @@ var BABYLON;
             enumerable: true,
             enumerable: true,
             configurable: true
             configurable: true
         });
         });
-        Object.defineProperty(GLTFFileLoader.prototype, "loaderState", {
-            /**
-             * The loader state or null if not active.
-             */
-            get: function () {
-                return this._loader ? this._loader.state : null;
+        Object.defineProperty(GLTFFileLoader.prototype, "onExtensionLoaded", {
+            set: function (callback) {
+                if (this._onExtensionLoadedObserver) {
+                    this.onExtensionLoadedObservable.remove(this._onExtensionLoadedObserver);
+                }
+                this._onExtensionLoadedObserver = this.onExtensionLoadedObservable.add(callback);
             },
             },
             enumerable: true,
             enumerable: true,
             configurable: true
             configurable: true
         });
         });
-        Object.defineProperty(GLTFFileLoader.prototype, "loaderExtensions", {
+        Object.defineProperty(GLTFFileLoader.prototype, "loaderState", {
             /**
             /**
-             * The loader extensions or null if not active.
+             * The loader state or null if not active.
              */
              */
             get: function () {
             get: function () {
-                return this._loader ? this._loader.extensions : null;
+                return this._loader ? this._loader.state : null;
             },
             },
             enumerable: true,
             enumerable: true,
             configurable: true
             configurable: true
@@ -1262,6 +1267,7 @@ var BABYLON;
             loader.onTextureLoadedObservable.add(function (texture) { return _this.onTextureLoadedObservable.notifyObservers(texture); });
             loader.onTextureLoadedObservable.add(function (texture) { return _this.onTextureLoadedObservable.notifyObservers(texture); });
             loader.onMaterialLoadedObservable.add(function (material) { return _this.onMaterialLoadedObservable.notifyObservers(material); });
             loader.onMaterialLoadedObservable.add(function (material) { return _this.onMaterialLoadedObservable.notifyObservers(material); });
             loader.onCompleteObservable.add(function () { return _this.onCompleteObservable.notifyObservers(_this); });
             loader.onCompleteObservable.add(function () { return _this.onCompleteObservable.notifyObservers(_this); });
+            loader.onExtensionLoadedObservable.add(function (extension) { return _this.onExtensionLoadedObservable.notifyObservers(extension); });
             return loader;
             return loader;
         };
         };
         GLTFFileLoader._parseBinary = function (data) {
         GLTFFileLoader._parseBinary = function (data) {
@@ -2813,8 +2819,8 @@ var BABYLON;
                 this.onTextureLoadedObservable = new BABYLON.Observable();
                 this.onTextureLoadedObservable = new BABYLON.Observable();
                 this.onMaterialLoadedObservable = new BABYLON.Observable();
                 this.onMaterialLoadedObservable = new BABYLON.Observable();
                 this.onCompleteObservable = new BABYLON.Observable();
                 this.onCompleteObservable = new BABYLON.Observable();
+                this.onExtensionLoadedObservable = new BABYLON.Observable();
                 this.state = null;
                 this.state = null;
-                this.extensions = null;
             }
             }
             GLTFLoader.RegisterExtension = function (extension) {
             GLTFLoader.RegisterExtension = function (extension) {
                 if (GLTFLoader.Extensions[extension.name]) {
                 if (GLTFLoader.Extensions[extension.name]) {
@@ -3632,12 +3638,8 @@ var BABYLON;
                 this.onMeshLoadedObservable = new BABYLON.Observable();
                 this.onMeshLoadedObservable = new BABYLON.Observable();
                 this.onTextureLoadedObservable = new BABYLON.Observable();
                 this.onTextureLoadedObservable = new BABYLON.Observable();
                 this.onMaterialLoadedObservable = new BABYLON.Observable();
                 this.onMaterialLoadedObservable = new BABYLON.Observable();
+                this.onExtensionLoadedObservable = new BABYLON.Observable();
                 this.onCompleteObservable = new BABYLON.Observable();
                 this.onCompleteObservable = new BABYLON.Observable();
-                for (var _i = 0, _a = GLTFLoader._Names; _i < _a.length; _i++) {
-                    var name_1 = _a[_i];
-                    var extension = GLTFLoader._Factories[name_1](this);
-                    this._extensions[name_1] = extension;
-                }
             }
             }
             GLTFLoader._Register = function (name, factory) {
             GLTFLoader._Register = function (name, factory) {
                 if (GLTFLoader._Factories[name]) {
                 if (GLTFLoader._Factories[name]) {
@@ -3655,13 +3657,6 @@ var BABYLON;
                 enumerable: true,
                 enumerable: true,
                 configurable: true
                 configurable: true
             });
             });
-            Object.defineProperty(GLTFLoader.prototype, "extensions", {
-                get: function () {
-                    return this.extensions;
-                },
-                enumerable: true,
-                configurable: true
-            });
             GLTFLoader.prototype.dispose = function () {
             GLTFLoader.prototype.dispose = function () {
                 if (this._disposed) {
                 if (this._disposed) {
                     return;
                     return;
@@ -3709,6 +3704,12 @@ var BABYLON;
             GLTFLoader.prototype._loadAsync = function (nodes, scene, data, rootUrl, onProgress) {
             GLTFLoader.prototype._loadAsync = function (nodes, scene, data, rootUrl, onProgress) {
                 var _this = this;
                 var _this = this;
                 return Promise.resolve().then(function () {
                 return Promise.resolve().then(function () {
+                    for (var _i = 0, _a = GLTFLoader._Names; _i < _a.length; _i++) {
+                        var name_1 = _a[_i];
+                        var extension = GLTFLoader._Factories[name_1](_this);
+                        _this._extensions[name_1] = extension;
+                        _this.onExtensionLoadedObservable.notifyObservers(extension);
+                    }
                     _this._babylonScene = scene;
                     _this._babylonScene = scene;
                     _this._rootUrl = rootUrl;
                     _this._rootUrl = rootUrl;
                     _this._progressCallback = onProgress;
                     _this._progressCallback = onProgress;
@@ -3732,20 +3733,22 @@ var BABYLON;
                         _this._state = BABYLON.GLTFLoaderState.Ready;
                         _this._state = BABYLON.GLTFLoaderState.Ready;
                         _this._startAnimations();
                         _this._startAnimations();
                         BABYLON.Tools.SetImmediate(function () {
                         BABYLON.Tools.SetImmediate(function () {
-                            Promise.all(_this._completePromises).then(function () {
-                                _this._releaseResources();
-                                _this._state = BABYLON.GLTFLoaderState.Complete;
-                                _this.onCompleteObservable.notifyObservers(_this);
-                            }).catch(function (error) {
-                                BABYLON.Tools.Error("glTF Loader: " + error.message);
-                                _this.dispose();
-                            });
+                            if (!_this._disposed) {
+                                Promise.all(_this._completePromises).then(function () {
+                                    _this._releaseResources();
+                                    _this._state = BABYLON.GLTFLoaderState.Complete;
+                                    _this.onCompleteObservable.notifyObservers(_this);
+                                }).catch(function (error) {
+                                    BABYLON.Tools.Error("glTF Loader: " + error.message);
+                                    _this.dispose();
+                                });
+                            }
                         });
                         });
-                    }).catch(function (error) {
-                        BABYLON.Tools.Error("glTF Loader: " + error.message);
-                        _this.dispose();
-                        throw error;
                     });
                     });
+                }).catch(function (error) {
+                    BABYLON.Tools.Error("glTF Loader: " + error.message);
+                    _this.dispose();
+                    throw error;
                 });
                 });
             };
             };
             GLTFLoader.prototype._loadData = function (data) {
             GLTFLoader.prototype._loadData = function (data) {
@@ -4686,6 +4689,7 @@ var BABYLON;
                 }
                 }
             };
             };
             GLTFLoader.prototype._loadTextureAsync = function (context, textureInfo, assign) {
             GLTFLoader.prototype._loadTextureAsync = function (context, textureInfo, assign) {
+                var _this = this;
                 var texture = GLTFLoader._GetProperty(context + "/index", this._gltf.textures, textureInfo.index);
                 var texture = GLTFLoader._GetProperty(context + "/index", this._gltf.textures, textureInfo.index);
                 context = "#/textures/" + textureInfo.index;
                 context = "#/textures/" + textureInfo.index;
                 var promises = new Array();
                 var promises = new Array();
@@ -4693,9 +4697,13 @@ var BABYLON;
                 var samplerData = this._loadSampler("#/samplers/" + sampler._index, sampler);
                 var samplerData = this._loadSampler("#/samplers/" + sampler._index, sampler);
                 var deferred = new BABYLON.Deferred();
                 var deferred = new BABYLON.Deferred();
                 var babylonTexture = new BABYLON.Texture(null, this._babylonScene, samplerData.noMipMaps, false, samplerData.samplingMode, function () {
                 var babylonTexture = new BABYLON.Texture(null, this._babylonScene, samplerData.noMipMaps, false, samplerData.samplingMode, function () {
-                    deferred.resolve();
+                    if (!_this._disposed) {
+                        deferred.resolve();
+                    }
                 }, function (message, exception) {
                 }, function (message, exception) {
-                    deferred.reject(new Error(context + ": " + (exception && exception.message) ? exception.message : message || "Failed to load texture"));
+                    if (!_this._disposed) {
+                        deferred.reject(new Error(context + ": " + (exception && exception.message) ? exception.message : message || "Failed to load texture"));
+                    }
                 });
                 });
                 promises.push(deferred.promise);
                 promises.push(deferred.promise);
                 babylonTexture.name = texture.name || "texture" + texture._index;
                 babylonTexture.name = texture.name || "texture" + texture._index;
@@ -4753,21 +4761,27 @@ var BABYLON;
                 }
                 }
                 return new Promise(function (resolve, reject) {
                 return new Promise(function (resolve, reject) {
                     var request = BABYLON.Tools.LoadFile(_this._rootUrl + uri, function (data) {
                     var request = BABYLON.Tools.LoadFile(_this._rootUrl + uri, function (data) {
-                        resolve(new Uint8Array(data));
+                        if (!_this._disposed) {
+                            resolve(new Uint8Array(data));
+                        }
                     }, function (event) {
                     }, function (event) {
-                        try {
-                            if (request && _this._state === BABYLON.GLTFLoaderState.Loading) {
-                                request._lengthComputable = event.lengthComputable;
-                                request._loaded = event.loaded;
-                                request._total = event.total;
-                                _this._onProgress();
+                        if (!_this._disposed) {
+                            try {
+                                if (request && _this._state === BABYLON.GLTFLoaderState.Loading) {
+                                    request._lengthComputable = event.lengthComputable;
+                                    request._loaded = event.loaded;
+                                    request._total = event.total;
+                                    _this._onProgress();
+                                }
+                            }
+                            catch (e) {
+                                reject(e);
                             }
                             }
-                        }
-                        catch (e) {
-                            reject(e);
                         }
                         }
                     }, _this._babylonScene.database, true, function (request, exception) {
                     }, _this._babylonScene.database, true, function (request, exception) {
-                        reject(new BABYLON.LoadFileError(context + ": Failed to load '" + uri + "'" + (request ? ": " + request.status + " " + request.statusText : ""), request));
+                        if (!_this._disposed) {
+                            reject(new BABYLON.LoadFileError(context + ": Failed to load '" + uri + "'" + (request ? ": " + request.status + " " + request.statusText : ""), request));
+                        }
                     });
                     });
                     _this._requests.push(request);
                     _this._requests.push(request);
                 });
                 });
@@ -4960,15 +4974,15 @@ var BABYLON;
                     return null;
                     return null;
                 }
                 }
                 var extensions = property.extensions;
                 var extensions = property.extensions;
-                var extension = extensions[this._name];
+                var extension = extensions[this.name];
                 if (!extension) {
                 if (!extension) {
                     return null;
                     return null;
                 }
                 }
                 // Clear out the extension before executing the action to avoid recursing into the same property.
                 // Clear out the extension before executing the action to avoid recursing into the same property.
-                delete extensions[this._name];
-                return actionAsync(context + "extensions/" + this._name, extension).then(function () {
+                delete extensions[this.name];
+                return actionAsync(context + "/extensions/" + this.name, extension).then(function () {
                     // Restore the extension after completing the action.
                     // Restore the extension after completing the action.
-                    extensions[_this._name] = extension;
+                    extensions[_this.name] = extension;
                 });
                 });
             };
             };
             /** Helper method called by the loader to allow extensions to override loading scenes. */
             /** Helper method called by the loader to allow extensions to override loading scenes. */
@@ -5005,28 +5019,26 @@ var BABYLON;
         (function (Extensions) {
         (function (Extensions) {
             // https://github.com/sbtron/glTF/tree/MSFT_lod/extensions/Vendor/MSFT_lod
             // https://github.com/sbtron/glTF/tree/MSFT_lod/extensions/Vendor/MSFT_lod
             var NAME = "MSFT_lod";
             var NAME = "MSFT_lod";
-            var MSFTLOD = /** @class */ (function (_super) {
-                __extends(MSFTLOD, _super);
-                function MSFTLOD() {
+            var MSFT_lod = /** @class */ (function (_super) {
+                __extends(MSFT_lod, _super);
+                function MSFT_lod() {
                     var _this = _super !== null && _super.apply(this, arguments) || this;
                     var _this = _super !== null && _super.apply(this, arguments) || this;
+                    _this.name = NAME;
+                    /**
+                     * Maximum number of LODs to load, starting from the lowest LOD.
+                     */
+                    _this.maxLODsToLoad = Number.MAX_VALUE;
                     _this._loadingNodeLOD = null;
                     _this._loadingNodeLOD = null;
                     _this._loadNodeSignals = {};
                     _this._loadNodeSignals = {};
                     _this._loadingMaterialLOD = null;
                     _this._loadingMaterialLOD = null;
                     _this._loadMaterialSignals = {};
                     _this._loadMaterialSignals = {};
                     return _this;
                     return _this;
                 }
                 }
-                Object.defineProperty(MSFTLOD.prototype, "_name", {
-                    get: function () {
-                        return NAME;
-                    },
-                    enumerable: true,
-                    configurable: true
-                });
-                MSFTLOD.prototype._loadNodeAsync = function (context, node) {
+                MSFT_lod.prototype._loadNodeAsync = function (context, node) {
                     var _this = this;
                     var _this = this;
                     return this._loadExtensionAsync(context, node, function (context, extension) {
                     return this._loadExtensionAsync(context, node, function (context, extension) {
                         var firstPromise;
                         var firstPromise;
-                        var nodeLODs = MSFTLOD._GetLODs(context, node, _this._loader._gltf.nodes, extension.ids);
+                        var nodeLODs = _this._getLODs(context, node, _this._loader._gltf.nodes, extension.ids);
                         var _loop_1 = function (indexLOD) {
                         var _loop_1 = function (indexLOD) {
                             var nodeLOD = nodeLODs[indexLOD];
                             var nodeLOD = nodeLODs[indexLOD];
                             if (indexLOD !== 0) {
                             if (indexLOD !== 0) {
@@ -5058,11 +5070,15 @@ var BABYLON;
                         return firstPromise;
                         return firstPromise;
                     });
                     });
                 };
                 };
-                MSFTLOD.prototype._loadMaterialAsync = function (context, material, babylonMesh) {
+                MSFT_lod.prototype._loadMaterialAsync = function (context, material, babylonMesh) {
                     var _this = this;
                     var _this = this;
+                    // Don't load material LODs if already loading a node LOD.
+                    if (this._loadingNodeLOD) {
+                        return null;
+                    }
                     return this._loadExtensionAsync(context, material, function (context, extension) {
                     return this._loadExtensionAsync(context, material, function (context, extension) {
                         var firstPromise;
                         var firstPromise;
-                        var materialLODs = MSFTLOD._GetLODs(context, material, _this._loader._gltf.materials, extension.ids);
+                        var materialLODs = _this._getLODs(context, material, _this._loader._gltf.materials, extension.ids);
                         var _loop_2 = function (indexLOD) {
                         var _loop_2 = function (indexLOD) {
                             var materialLOD = materialLODs[indexLOD];
                             var materialLOD = materialLODs[indexLOD];
                             if (indexLOD !== 0) {
                             if (indexLOD !== 0) {
@@ -5090,7 +5106,7 @@ var BABYLON;
                         return firstPromise;
                         return firstPromise;
                     });
                     });
                 };
                 };
-                MSFTLOD.prototype._loadUriAsync = function (context, uri) {
+                MSFT_lod.prototype._loadUriAsync = function (context, uri) {
                     var _this = this;
                     var _this = this;
                     // Defer the loading of uris if loading a material or node LOD.
                     // Defer the loading of uris if loading a material or node LOD.
                     if (this._loadingMaterialLOD) {
                     if (this._loadingMaterialLOD) {
@@ -5110,18 +5126,24 @@ var BABYLON;
                 /**
                 /**
                  * Gets an array of LOD properties from lowest to highest.
                  * Gets an array of LOD properties from lowest to highest.
                  */
                  */
-                MSFTLOD._GetLODs = function (context, property, array, ids) {
-                    var properties = [property];
-                    for (var _i = 0, ids_1 = ids; _i < ids_1.length; _i++) {
-                        var id = ids_1[_i];
-                        properties.push(GLTF2.GLTFLoader._GetProperty(context + "/ids/" + id, array, id));
+                MSFT_lod.prototype._getLODs = function (context, property, array, ids) {
+                    if (this.maxLODsToLoad <= 0) {
+                        throw new Error("maxLODsToLoad must be greater than zero");
+                    }
+                    var properties = new Array();
+                    for (var i = ids.length - 1; i >= 0; i--) {
+                        properties.push(GLTF2.GLTFLoader._GetProperty(context + "/ids/" + ids[i], array, ids[i]));
+                        if (properties.length === this.maxLODsToLoad) {
+                            return properties;
+                        }
                     }
                     }
-                    return properties.reverse();
+                    properties.push(property);
+                    return properties;
                 };
                 };
-                return MSFTLOD;
+                return MSFT_lod;
             }(GLTF2.GLTFLoaderExtension));
             }(GLTF2.GLTFLoaderExtension));
-            Extensions.MSFTLOD = MSFTLOD;
-            GLTF2.GLTFLoader._Register(NAME, function (loader) { return new MSFTLOD(loader); });
+            Extensions.MSFT_lod = MSFT_lod;
+            GLTF2.GLTFLoader._Register(NAME, function (loader) { return new MSFT_lod(loader); });
         })(Extensions = GLTF2.Extensions || (GLTF2.Extensions = {}));
         })(Extensions = GLTF2.Extensions || (GLTF2.Extensions = {}));
     })(GLTF2 = BABYLON.GLTF2 || (BABYLON.GLTF2 = {}));
     })(GLTF2 = BABYLON.GLTF2 || (BABYLON.GLTF2 = {}));
 })(BABYLON || (BABYLON = {}));
 })(BABYLON || (BABYLON = {}));
@@ -5138,19 +5160,14 @@ var BABYLON;
         (function (Extensions) {
         (function (Extensions) {
             // https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Khronos/KHR_materials_pbrSpecularGlossiness
             // https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Khronos/KHR_materials_pbrSpecularGlossiness
             var NAME = "KHR_materials_pbrSpecularGlossiness";
             var NAME = "KHR_materials_pbrSpecularGlossiness";
-            var KHRMaterialsPbrSpecularGlossiness = /** @class */ (function (_super) {
-                __extends(KHRMaterialsPbrSpecularGlossiness, _super);
-                function KHRMaterialsPbrSpecularGlossiness() {
-                    return _super !== null && _super.apply(this, arguments) || this;
+            var KHR_materials_pbrSpecularGlossiness = /** @class */ (function (_super) {
+                __extends(KHR_materials_pbrSpecularGlossiness, _super);
+                function KHR_materials_pbrSpecularGlossiness() {
+                    var _this = _super !== null && _super.apply(this, arguments) || this;
+                    _this.name = NAME;
+                    return _this;
                 }
                 }
-                Object.defineProperty(KHRMaterialsPbrSpecularGlossiness.prototype, "_name", {
-                    get: function () {
-                        return NAME;
-                    },
-                    enumerable: true,
-                    configurable: true
-                });
-                KHRMaterialsPbrSpecularGlossiness.prototype._loadMaterialAsync = function (context, material, babylonMesh) {
+                KHR_materials_pbrSpecularGlossiness.prototype._loadMaterialAsync = function (context, material, babylonMesh) {
                     var _this = this;
                     var _this = this;
                     return this._loadExtensionAsync(context, material, function (context, extension) {
                     return this._loadExtensionAsync(context, material, function (context, extension) {
                         material._babylonMeshes = material._babylonMeshes || [];
                         material._babylonMeshes = material._babylonMeshes || [];
@@ -5169,7 +5186,7 @@ var BABYLON;
                         return (material._loaded = Promise.all(promises).then(function () { }));
                         return (material._loaded = Promise.all(promises).then(function () { }));
                     });
                     });
                 };
                 };
-                KHRMaterialsPbrSpecularGlossiness.prototype._loadSpecularGlossinessPropertiesAsync = function (loader, context, material, properties) {
+                KHR_materials_pbrSpecularGlossiness.prototype._loadSpecularGlossinessPropertiesAsync = function (loader, context, material, properties) {
                     var promises = new Array();
                     var promises = new Array();
                     var babylonMaterial = material._babylonMaterial;
                     var babylonMaterial = material._babylonMaterial;
                     if (properties.diffuseFactor) {
                     if (properties.diffuseFactor) {
@@ -5196,10 +5213,10 @@ var BABYLON;
                     loader._loadMaterialAlphaProperties(context, material);
                     loader._loadMaterialAlphaProperties(context, material);
                     return Promise.all(promises).then(function () { });
                     return Promise.all(promises).then(function () { });
                 };
                 };
-                return KHRMaterialsPbrSpecularGlossiness;
+                return KHR_materials_pbrSpecularGlossiness;
             }(GLTF2.GLTFLoaderExtension));
             }(GLTF2.GLTFLoaderExtension));
-            Extensions.KHRMaterialsPbrSpecularGlossiness = KHRMaterialsPbrSpecularGlossiness;
-            GLTF2.GLTFLoader._Register(NAME, function (loader) { return new KHRMaterialsPbrSpecularGlossiness(loader); });
+            Extensions.KHR_materials_pbrSpecularGlossiness = KHR_materials_pbrSpecularGlossiness;
+            GLTF2.GLTFLoader._Register(NAME, function (loader) { return new KHR_materials_pbrSpecularGlossiness(loader); });
         })(Extensions = GLTF2.Extensions || (GLTF2.Extensions = {}));
         })(Extensions = GLTF2.Extensions || (GLTF2.Extensions = {}));
     })(GLTF2 = BABYLON.GLTF2 || (BABYLON.GLTF2 = {}));
     })(GLTF2 = BABYLON.GLTF2 || (BABYLON.GLTF2 = {}));
 })(BABYLON || (BABYLON = {}));
 })(BABYLON || (BABYLON = {}));
@@ -5223,19 +5240,14 @@ var BABYLON;
                 LightType["POINT"] = "point";
                 LightType["POINT"] = "point";
                 LightType["SPOT"] = "spot";
                 LightType["SPOT"] = "spot";
             })(LightType || (LightType = {}));
             })(LightType || (LightType = {}));
-            var KHRLights = /** @class */ (function (_super) {
-                __extends(KHRLights, _super);
-                function KHRLights() {
-                    return _super !== null && _super.apply(this, arguments) || this;
+            var KHR_lights = /** @class */ (function (_super) {
+                __extends(KHR_lights, _super);
+                function KHR_lights() {
+                    var _this = _super !== null && _super.apply(this, arguments) || this;
+                    _this.name = NAME;
+                    return _this;
                 }
                 }
-                Object.defineProperty(KHRLights.prototype, "_name", {
-                    get: function () {
-                        return NAME;
-                    },
-                    enumerable: true,
-                    configurable: true
-                });
-                KHRLights.prototype._loadSceneAsync = function (context, scene) {
+                KHR_lights.prototype._loadSceneAsync = function (context, scene) {
                     var _this = this;
                     var _this = this;
                     return this._loadExtensionAsync(context, scene, function (context, extension) {
                     return this._loadExtensionAsync(context, scene, function (context, extension) {
                         var promise = _this._loader._loadSceneAsync(context, scene);
                         var promise = _this._loader._loadSceneAsync(context, scene);
@@ -5247,7 +5259,7 @@ var BABYLON;
                         return promise;
                         return promise;
                     });
                     });
                 };
                 };
-                KHRLights.prototype._loadNodeAsync = function (context, node) {
+                KHR_lights.prototype._loadNodeAsync = function (context, node) {
                     var _this = this;
                     var _this = this;
                     return this._loadExtensionAsync(context, node, function (context, extension) {
                     return this._loadExtensionAsync(context, node, function (context, extension) {
                         var promise = _this._loader._loadNodeAsync(context, node);
                         var promise = _this._loader._loadNodeAsync(context, node);
@@ -5284,22 +5296,22 @@ var BABYLON;
                         return promise;
                         return promise;
                     });
                     });
                 };
                 };
-                Object.defineProperty(KHRLights.prototype, "_lights", {
+                Object.defineProperty(KHR_lights.prototype, "_lights", {
                     get: function () {
                     get: function () {
                         var extensions = this._loader._gltf.extensions;
                         var extensions = this._loader._gltf.extensions;
-                        if (!extensions || !extensions[this._name]) {
-                            throw new Error("#/extensions: " + this._name + " not found");
+                        if (!extensions || !extensions[this.name]) {
+                            throw new Error("#/extensions: " + this.name + " not found");
                         }
                         }
-                        var extension = extensions[this._name];
+                        var extension = extensions[this.name];
                         return extension.lights;
                         return extension.lights;
                     },
                     },
                     enumerable: true,
                     enumerable: true,
                     configurable: true
                     configurable: true
                 });
                 });
-                return KHRLights;
+                return KHR_lights;
             }(GLTF2.GLTFLoaderExtension));
             }(GLTF2.GLTFLoaderExtension));
-            Extensions.KHRLights = KHRLights;
-            GLTF2.GLTFLoader._Register(NAME, function (loader) { return new KHRLights(loader); });
+            Extensions.KHR_lights = KHR_lights;
+            GLTF2.GLTFLoader._Register(NAME, function (loader) { return new KHR_lights(loader); });
         })(Extensions = GLTF2.Extensions || (GLTF2.Extensions = {}));
         })(Extensions = GLTF2.Extensions || (GLTF2.Extensions = {}));
     })(GLTF2 = BABYLON.GLTF2 || (BABYLON.GLTF2 = {}));
     })(GLTF2 = BABYLON.GLTF2 || (BABYLON.GLTF2 = {}));
 })(BABYLON || (BABYLON = {}));
 })(BABYLON || (BABYLON = {}));

File diff suppressed because it is too large
+ 3 - 3
dist/preview release/loaders/babylonjs.loaders.min.js


+ 34 - 24
dist/preview release/loaders/babylonjs.loaders.module.d.ts

@@ -129,30 +129,34 @@ declare module BABYLON {
         json: Object;
         json: Object;
         bin: Nullable<ArrayBufferView>;
         bin: Nullable<ArrayBufferView>;
     }
     }
+    interface IGLTFLoaderExtension {
+        /**
+         * The name of this extension.
+         */
+        readonly name: string;
+        /**
+         * Whether this extension is enabled.
+         */
+        enabled: boolean;
+    }
     enum GLTFLoaderState {
     enum GLTFLoaderState {
         Loading = 0,
         Loading = 0,
         Ready = 1,
         Ready = 1,
         Complete = 2,
         Complete = 2,
     }
     }
-    interface IGLTFLoaderExtension {
-        enabled: boolean;
-    }
-    interface IGLTFLoaderExtensions {
-        [name: string]: IGLTFLoaderExtension;
-    }
     interface IGLTFLoader extends IDisposable {
     interface IGLTFLoader extends IDisposable {
         coordinateSystemMode: GLTFLoaderCoordinateSystemMode;
         coordinateSystemMode: GLTFLoaderCoordinateSystemMode;
         animationStartMode: GLTFLoaderAnimationStartMode;
         animationStartMode: GLTFLoaderAnimationStartMode;
         compileMaterials: boolean;
         compileMaterials: boolean;
         useClipPlane: boolean;
         useClipPlane: boolean;
         compileShadowGenerators: boolean;
         compileShadowGenerators: boolean;
-        onDisposeObservable: Observable<IGLTFLoader>;
         onMeshLoadedObservable: Observable<AbstractMesh>;
         onMeshLoadedObservable: Observable<AbstractMesh>;
         onTextureLoadedObservable: Observable<BaseTexture>;
         onTextureLoadedObservable: Observable<BaseTexture>;
         onMaterialLoadedObservable: Observable<Material>;
         onMaterialLoadedObservable: Observable<Material>;
         onCompleteObservable: Observable<IGLTFLoader>;
         onCompleteObservable: Observable<IGLTFLoader>;
+        onDisposeObservable: Observable<IGLTFLoader>;
+        onExtensionLoadedObservable: Observable<IGLTFLoaderExtension>;
         state: Nullable<GLTFLoaderState>;
         state: Nullable<GLTFLoaderState>;
-        extensions: Nullable<IGLTFLoaderExtensions>;
         importMeshAsync: (meshesNames: any, scene: Scene, data: IGLTFLoaderData, rootUrl: string, onProgress?: (event: SceneLoaderProgressEvent) => void) => Promise<{
         importMeshAsync: (meshesNames: any, scene: Scene, data: IGLTFLoaderData, rootUrl: string, onProgress?: (event: SceneLoaderProgressEvent) => void) => Promise<{
             meshes: AbstractMesh[];
             meshes: AbstractMesh[];
             particleSystems: ParticleSystem[];
             particleSystems: ParticleSystem[];
@@ -226,13 +230,16 @@ declare module BABYLON {
         private _onDisposeObserver;
         private _onDisposeObserver;
         onDispose: () => void;
         onDispose: () => void;
         /**
         /**
-         * The loader state or null if not active.
+         * Raised after a loader extension is created.
+         * Set additional options for a loader extension in this event.
          */
          */
-        readonly loaderState: Nullable<GLTFLoaderState>;
+        readonly onExtensionLoadedObservable: Observable<IGLTFLoaderExtension>;
+        private _onExtensionLoadedObserver;
+        onExtensionLoaded: (extension: IGLTFLoaderExtension) => void;
         /**
         /**
-         * The loader extensions or null if not active.
+         * The loader state or null if not active.
          */
          */
-        readonly loaderExtensions: Nullable<IGLTFLoaderExtensions>;
+        readonly loaderState: Nullable<GLTFLoaderState>;
         private _loader;
         private _loader;
         name: string;
         name: string;
         extensions: ISceneLoaderPluginExtensions;
         extensions: ISceneLoaderPluginExtensions;
@@ -664,8 +671,8 @@ declare module BABYLON.GLTF1 {
         onTextureLoadedObservable: Observable<BaseTexture>;
         onTextureLoadedObservable: Observable<BaseTexture>;
         onMaterialLoadedObservable: Observable<Material>;
         onMaterialLoadedObservable: Observable<Material>;
         onCompleteObservable: Observable<IGLTFLoader>;
         onCompleteObservable: Observable<IGLTFLoader>;
+        onExtensionLoadedObservable: Observable<IGLTFLoaderExtension>;
         state: Nullable<GLTFLoaderState>;
         state: Nullable<GLTFLoaderState>;
-        extensions: Nullable<IGLTFLoaderExtensions>;
         dispose(): void;
         dispose(): void;
         private _importMeshAsync(meshesNames, scene, data, rootUrl, onSuccess, onProgress, onError);
         private _importMeshAsync(meshesNames, scene, data, rootUrl, onSuccess, onProgress, onError);
         importMeshAsync(meshesNames: any, scene: Scene, data: IGLTFLoaderData, rootUrl: string, onProgress: (event: SceneLoaderProgressEvent) => void): Promise<{
         importMeshAsync(meshesNames: any, scene: Scene, data: IGLTFLoaderData, rootUrl: string, onProgress: (event: SceneLoaderProgressEvent) => void): Promise<{
@@ -939,10 +946,9 @@ declare module BABYLON.GLTF2 {
         readonly onMeshLoadedObservable: Observable<AbstractMesh>;
         readonly onMeshLoadedObservable: Observable<AbstractMesh>;
         readonly onTextureLoadedObservable: Observable<BaseTexture>;
         readonly onTextureLoadedObservable: Observable<BaseTexture>;
         readonly onMaterialLoadedObservable: Observable<Material>;
         readonly onMaterialLoadedObservable: Observable<Material>;
+        readonly onExtensionLoadedObservable: Observable<IGLTFLoaderExtension>;
         readonly onCompleteObservable: Observable<IGLTFLoader>;
         readonly onCompleteObservable: Observable<IGLTFLoader>;
         readonly state: Nullable<GLTFLoaderState>;
         readonly state: Nullable<GLTFLoaderState>;
-        readonly extensions: IGLTFLoaderExtensions;
-        constructor();
         dispose(): void;
         dispose(): void;
         importMeshAsync(meshesNames: any, scene: Scene, data: IGLTFLoaderData, rootUrl: string, onProgress?: (event: SceneLoaderProgressEvent) => void): Promise<{
         importMeshAsync(meshesNames: any, scene: Scene, data: IGLTFLoaderData, rootUrl: string, onProgress?: (event: SceneLoaderProgressEvent) => void): Promise<{
             meshes: AbstractMesh[];
             meshes: AbstractMesh[];
@@ -1009,11 +1015,11 @@ declare module BABYLON.GLTF2 {
 
 
 
 
 declare module BABYLON.GLTF2 {
 declare module BABYLON.GLTF2 {
-    abstract class GLTFLoaderExtension {
+    abstract class GLTFLoaderExtension implements IGLTFLoaderExtension {
         enabled: boolean;
         enabled: boolean;
         protected _loader: GLTFLoader;
         protected _loader: GLTFLoader;
         constructor(loader: GLTFLoader);
         constructor(loader: GLTFLoader);
-        protected readonly abstract _name: string;
+        readonly abstract name: string;
         /** Override this method to modify the default behavior for loading scenes. */
         /** Override this method to modify the default behavior for loading scenes. */
         protected _loadSceneAsync(context: string, node: ILoaderScene): Nullable<Promise<void>>;
         protected _loadSceneAsync(context: string, node: ILoaderScene): Nullable<Promise<void>>;
         /** Override this method to modify the default behavior for loading nodes. */
         /** Override this method to modify the default behavior for loading nodes. */
@@ -1037,26 +1043,30 @@ declare module BABYLON.GLTF2 {
 
 
 
 
 declare module BABYLON.GLTF2.Extensions {
 declare module BABYLON.GLTF2.Extensions {
-    class MSFTLOD extends GLTFLoaderExtension {
+    class MSFT_lod extends GLTFLoaderExtension {
+        readonly name: string;
+        /**
+         * Maximum number of LODs to load, starting from the lowest LOD.
+         */
+        maxLODsToLoad: number;
         private _loadingNodeLOD;
         private _loadingNodeLOD;
         private _loadNodeSignals;
         private _loadNodeSignals;
         private _loadingMaterialLOD;
         private _loadingMaterialLOD;
         private _loadMaterialSignals;
         private _loadMaterialSignals;
-        protected readonly _name: string;
         protected _loadNodeAsync(context: string, node: ILoaderNode): Nullable<Promise<void>>;
         protected _loadNodeAsync(context: string, node: ILoaderNode): Nullable<Promise<void>>;
         protected _loadMaterialAsync(context: string, material: ILoaderMaterial, babylonMesh: Mesh): Nullable<Promise<void>>;
         protected _loadMaterialAsync(context: string, material: ILoaderMaterial, babylonMesh: Mesh): Nullable<Promise<void>>;
         protected _loadUriAsync(context: string, uri: string): Nullable<Promise<ArrayBufferView>>;
         protected _loadUriAsync(context: string, uri: string): Nullable<Promise<ArrayBufferView>>;
         /**
         /**
          * Gets an array of LOD properties from lowest to highest.
          * Gets an array of LOD properties from lowest to highest.
          */
          */
-        private static _GetLODs<T>(context, property, array, ids);
+        private _getLODs<T>(context, property, array, ids);
     }
     }
 }
 }
 
 
 
 
 declare module BABYLON.GLTF2.Extensions {
 declare module BABYLON.GLTF2.Extensions {
-    class KHRMaterialsPbrSpecularGlossiness extends GLTFLoaderExtension {
-        protected readonly _name: string;
+    class KHR_materials_pbrSpecularGlossiness extends GLTFLoaderExtension {
+        readonly name: string;
         protected _loadMaterialAsync(context: string, material: ILoaderMaterial, babylonMesh: Mesh): Nullable<Promise<void>>;
         protected _loadMaterialAsync(context: string, material: ILoaderMaterial, babylonMesh: Mesh): Nullable<Promise<void>>;
         private _loadSpecularGlossinessPropertiesAsync(loader, context, material, properties);
         private _loadSpecularGlossinessPropertiesAsync(loader, context, material, properties);
     }
     }
@@ -1064,8 +1074,8 @@ declare module BABYLON.GLTF2.Extensions {
 
 
 
 
 declare module BABYLON.GLTF2.Extensions {
 declare module BABYLON.GLTF2.Extensions {
-    class KHRLights extends GLTFLoaderExtension {
-        protected readonly _name: string;
+    class KHR_lights extends GLTFLoaderExtension {
+        readonly name: string;
         protected _loadSceneAsync(context: string, scene: ILoaderScene): Nullable<Promise<void>>;
         protected _loadSceneAsync(context: string, scene: ILoaderScene): Nullable<Promise<void>>;
         protected _loadNodeAsync(context: string, node: ILoaderNode): Nullable<Promise<void>>;
         protected _loadNodeAsync(context: string, node: ILoaderNode): Nullable<Promise<void>>;
         private readonly _lights;
         private readonly _lights;

+ 2 - 2
dist/preview release/typedocValidationBaseline.json

@@ -1,7 +1,7 @@
 {
 {
-  "errors": 7933,
+  "errors": 7349,
   "babylon.typedoc.json": {
   "babylon.typedoc.json": {
-    "errors": 7933,
+    "errors": 7349,
     "AnimationKeyInterpolation": {
     "AnimationKeyInterpolation": {
       "Enumeration": {
       "Enumeration": {
         "Comments": {
         "Comments": {

File diff suppressed because it is too large
+ 49 - 49
dist/preview release/viewer/babylon.viewer.js