David Catuhe 8 年之前
父节点
当前提交
256b9cc67c
共有 50 个文件被更改,包括 14570 次插入14037 次删除
  1. 3783 3783
      dist/preview release/babylon.d.ts
  2. 33 33
      dist/preview release/babylon.js
  3. 4 4
      dist/preview release/babylon.max.js
  4. 3783 3783
      dist/preview release/babylon.module.d.ts
  5. 34 34
      dist/preview release/babylon.worker.js
  6. 2823 2809
      dist/preview release/customConfigurations/minimalViewer/babylon.d.ts
  7. 19 19
      dist/preview release/customConfigurations/minimalViewer/babylon.js
  8. 147 5
      dist/preview release/customConfigurations/minimalViewer/babylon.max.js
  9. 2823 2809
      dist/preview release/customConfigurations/minimalViewer/babylon.module.d.ts
  10. 1 1
      dist/preview release/gui/babylon.gui.min.js
  11. 263 263
      dist/preview release/inspector/babylon.inspector.bundle.js
  12. 3 3
      dist/preview release/inspector/babylon.inspector.min.js
  13. 2 2
      dist/preview release/loaders/babylon.glTF1FileLoader.min.js
  14. 42 30
      dist/preview release/loaders/babylon.glTF2FileLoader.d.ts
  15. 319 200
      dist/preview release/loaders/babylon.glTF2FileLoader.js
  16. 1 5
      dist/preview release/loaders/babylon.glTF2FileLoader.min.js
  17. 42 30
      dist/preview release/loaders/babylon.glTFFileLoader.d.ts
  18. 319 200
      dist/preview release/loaders/babylon.glTFFileLoader.js
  19. 2 7
      dist/preview release/loaders/babylon.glTFFileLoader.min.js
  20. 1 5
      dist/preview release/loaders/babylon.objFileLoader.min.js
  21. 1 0
      dist/preview release/materialsLibrary/babylon.cellMaterial.d.ts
  22. 7 0
      dist/preview release/materialsLibrary/babylon.cellMaterial.js
  23. 1 1
      dist/preview release/materialsLibrary/babylon.cellMaterial.min.js
  24. 1 1
      dist/preview release/materialsLibrary/babylon.customMaterial.min.js
  25. 1 0
      dist/preview release/materialsLibrary/babylon.fireMaterial.d.ts
  26. 13 0
      dist/preview release/materialsLibrary/babylon.fireMaterial.js
  27. 1 1
      dist/preview release/materialsLibrary/babylon.fireMaterial.min.js
  28. 1 0
      dist/preview release/materialsLibrary/babylon.furMaterial.d.ts
  29. 10 0
      dist/preview release/materialsLibrary/babylon.furMaterial.js
  30. 1 1
      dist/preview release/materialsLibrary/babylon.furMaterial.min.js
  31. 1 0
      dist/preview release/materialsLibrary/babylon.lavaMaterial.d.ts
  32. 7 0
      dist/preview release/materialsLibrary/babylon.lavaMaterial.js
  33. 1 1
      dist/preview release/materialsLibrary/babylon.lavaMaterial.min.js
  34. 1 0
      dist/preview release/materialsLibrary/babylon.normalMaterial.d.ts
  35. 7 0
      dist/preview release/materialsLibrary/babylon.normalMaterial.js
  36. 1 1
      dist/preview release/materialsLibrary/babylon.normalMaterial.min.js
  37. 1 0
      dist/preview release/materialsLibrary/babylon.simpleMaterial.d.ts
  38. 7 0
      dist/preview release/materialsLibrary/babylon.simpleMaterial.js
  39. 1 1
      dist/preview release/materialsLibrary/babylon.simpleMaterial.min.js
  40. 1 0
      dist/preview release/materialsLibrary/babylon.terrainMaterial.d.ts
  41. 25 0
      dist/preview release/materialsLibrary/babylon.terrainMaterial.js
  42. 1 1
      dist/preview release/materialsLibrary/babylon.terrainMaterial.min.js
  43. 1 0
      dist/preview release/materialsLibrary/babylon.triPlanarMaterial.d.ts
  44. 22 0
      dist/preview release/materialsLibrary/babylon.triPlanarMaterial.js
  45. 1 1
      dist/preview release/materialsLibrary/babylon.triPlanarMaterial.min.js
  46. 1 0
      dist/preview release/materialsLibrary/babylon.waterMaterial.d.ts
  47. 7 0
      dist/preview release/materialsLibrary/babylon.waterMaterial.js
  48. 1 1
      dist/preview release/materialsLibrary/babylon.waterMaterial.min.js
  49. 1 1
      dist/preview release/postProcessesLibrary/babylon.asciiArtPostProcess.min.js
  50. 1 1
      dist/preview release/postProcessesLibrary/babylon.digitalRainPostProcess.min.js

文件差异内容过多而无法显示
+ 3783 - 3783
dist/preview release/babylon.d.ts


文件差异内容过多而无法显示
+ 33 - 33
dist/preview release/babylon.js


+ 4 - 4
dist/preview release/babylon.max.js

@@ -39235,7 +39235,7 @@ var BABYLON;
                 if (this.mesh._worldMatrix.decompose(this._scale, this._quaternion, this._translation)) {
                 if (this.mesh._worldMatrix.decompose(this._scale, this._quaternion, this._translation)) {
                     this._quaternionToRotationMatrix();
                     this._quaternionToRotationMatrix();
                     this._rotMatrix.invertToRef(this._invertMatrix);
                     this._rotMatrix.invertToRef(this._invertMatrix);
-                    this._camera._currentTarget.subtractToRef(this._camera.globalPosition, this._camDir);
+                    this._camera.getDirectionToRef(this._axisZ, this._camDir);
                     BABYLON.Vector3.TransformNormalToRef(this._camDir, this._invertMatrix, this._cam_axisZ);
                     BABYLON.Vector3.TransformNormalToRef(this._camDir, this._invertMatrix, this._cam_axisZ);
                     this._cam_axisZ.normalize();
                     this._cam_axisZ.normalize();
                     // same for camera up vector extracted from the cam view matrix
                     // same for camera up vector extracted from the cam view matrix
@@ -39368,9 +39368,9 @@ var BABYLON;
                         idx = index + pt * 3;
                         idx = index + pt * 3;
                         colidx = colorIndex + pt * 4;
                         colidx = colorIndex + pt * 4;
                         uvidx = uvIndex + pt * 2;
                         uvidx = uvIndex + pt * 2;
-                        this._positions32[idx] = this._camera.position.x;
-                        this._positions32[idx + 1] = this._camera.position.y;
-                        this._positions32[idx + 2] = this._camera.position.z;
+                        this._positions32[idx] = this._camera.globalPosition.x;
+                        this._positions32[idx + 1] = this._camera.globalPosition.y;
+                        this._positions32[idx + 2] = this._camera.globalPosition.z;
                         this._normals32[idx] = 0.0;
                         this._normals32[idx] = 0.0;
                         this._normals32[idx + 1] = 0.0;
                         this._normals32[idx + 1] = 0.0;
                         this._normals32[idx + 2] = 0.0;
                         this._normals32[idx + 2] = 0.0;

文件差异内容过多而无法显示
+ 3783 - 3783
dist/preview release/babylon.module.d.ts


文件差异内容过多而无法显示
+ 34 - 34
dist/preview release/babylon.worker.js


文件差异内容过多而无法显示
+ 2823 - 2809
dist/preview release/customConfigurations/minimalViewer/babylon.d.ts


文件差异内容过多而无法显示
+ 19 - 19
dist/preview release/customConfigurations/minimalViewer/babylon.js


+ 147 - 5
dist/preview release/customConfigurations/minimalViewer/babylon.max.js

@@ -19039,6 +19039,31 @@ var BABYLON;
             BABYLON.Animation.AppendSerializedAnimations(this, serializationObject);
             BABYLON.Animation.AppendSerializedAnimations(this, serializationObject);
             return serializationObject;
             return serializationObject;
         };
         };
+        BaseTexture.WhenAllReady = function (textures, onLoad) {
+            var numReady = 0;
+            var _loop_1 = function () {
+                texture = textures[i];
+                if (texture.isReady()) {
+                    if (++numReady === textures.length) {
+                        onLoad();
+                    }
+                }
+                else {
+                    observable = texture.onLoadObservable;
+                    var callback_1 = function () {
+                        observable.removeCallback(callback_1);
+                        if (++numReady === textures.length) {
+                            onLoad();
+                        }
+                    };
+                    observable.add(callback_1);
+                }
+            };
+            var texture, observable;
+            for (var i = 0; i < textures.length; i++) {
+                _loop_1();
+            }
+        };
         return BaseTexture;
         return BaseTexture;
     }());
     }());
     BaseTexture.DEFAULT_ANISOTROPIC_FILTERING_LEVEL = 4;
     BaseTexture.DEFAULT_ANISOTROPIC_FILTERING_LEVEL = 4;
@@ -19117,8 +19142,8 @@ var BABYLON;
             _this._format = format;
             _this._format = format;
             scene = _this.getScene();
             scene = _this.getScene();
             var load = function () {
             var load = function () {
-                if (_this._onLoadObservarble && _this._onLoadObservarble.hasObservers()) {
-                    _this.onLoadObservable.notifyObservers(true);
+                if (_this._onLoadObservable && _this._onLoadObservable.hasObservers()) {
+                    _this.onLoadObservable.notifyObservers(_this);
                 }
                 }
                 if (onLoad) {
                 if (onLoad) {
                     onLoad();
                     onLoad();
@@ -19306,10 +19331,10 @@ var BABYLON;
         };
         };
         Object.defineProperty(Texture.prototype, "onLoadObservable", {
         Object.defineProperty(Texture.prototype, "onLoadObservable", {
             get: function () {
             get: function () {
-                if (!this._onLoadObservarble) {
-                    this._onLoadObservarble = new BABYLON.Observable();
+                if (!this._onLoadObservable) {
+                    this._onLoadObservable = new BABYLON.Observable();
                 }
                 }
-                return this._onLoadObservarble;
+                return this._onLoadObservable;
             },
             },
             enumerable: true,
             enumerable: true,
             configurable: true
             configurable: true
@@ -24095,6 +24120,9 @@ var BABYLON;
                 engine.setDepthWrite(this._cachedDepthWriteState);
                 engine.setDepthWrite(this._cachedDepthWriteState);
             }
             }
         };
         };
+        Material.prototype.getActiveTextures = function () {
+            return [];
+        };
         Material.prototype.clone = function (name) {
         Material.prototype.clone = function (name) {
             return null;
             return null;
         };
         };
@@ -34542,6 +34570,10 @@ var BABYLON;
             }
             }
             return this.subMaterials[index];
             return this.subMaterials[index];
         };
         };
+        MultiMaterial.prototype.getActiveTextures = function () {
+            return (_a = _super.prototype.getActiveTextures.call(this)).concat.apply(_a, this.subMaterials.map(function (subMaterial) { return subMaterial.getActiveTextures(); }));
+            var _a;
+        };
         // Methods
         // Methods
         MultiMaterial.prototype.getClassName = function () {
         MultiMaterial.prototype.getClassName = function () {
             return "MultiMaterial";
             return "MultiMaterial";
@@ -36154,6 +36186,43 @@ var BABYLON;
         PBRMaterial.prototype.getClassName = function () {
         PBRMaterial.prototype.getClassName = function () {
             return "PBRMaterial";
             return "PBRMaterial";
         };
         };
+        PBRMaterial.prototype.getActiveTextures = function () {
+            var activeTextures = _super.prototype.getActiveTextures.call(this);
+            if (this._albedoTexture) {
+                activeTextures.push(this._albedoTexture);
+            }
+            if (this._ambientTexture) {
+                activeTextures.push(this._ambientTexture);
+            }
+            if (this._opacityTexture) {
+                activeTextures.push(this._opacityTexture);
+            }
+            if (this._reflectionTexture) {
+                activeTextures.push(this._reflectionTexture);
+            }
+            if (this._emissiveTexture) {
+                activeTextures.push(this._emissiveTexture);
+            }
+            if (this._reflectionTexture) {
+                activeTextures.push(this._reflectionTexture);
+            }
+            if (this._metallicTexture) {
+                activeTextures.push(this._metallicTexture);
+            }
+            if (this._microSurfaceTexture) {
+                activeTextures.push(this._microSurfaceTexture);
+            }
+            if (this._bumpTexture) {
+                activeTextures.push(this._bumpTexture);
+            }
+            if (this._lightmapTexture) {
+                activeTextures.push(this._lightmapTexture);
+            }
+            if (this._refractionTexture) {
+                activeTextures.push(this._refractionTexture);
+            }
+            return activeTextures;
+        };
         PBRMaterial.prototype.clone = function (name) {
         PBRMaterial.prototype.clone = function (name) {
             var _this = this;
             var _this = this;
             return BABYLON.SerializationHelper.Clone(function () { return new PBRMaterial(name, _this.getScene()); }, this);
             return BABYLON.SerializationHelper.Clone(function () { return new PBRMaterial(name, _this.getScene()); }, this);
@@ -36437,6 +36506,19 @@ var BABYLON;
             return "PBRMetallicRoughnessMaterial";
             return "PBRMetallicRoughnessMaterial";
         };
         };
         /**
         /**
+         * Return the active textures of the material.
+         */
+        PBRMetallicRoughnessMaterial.prototype.getActiveTextures = function () {
+            var activeTextures = _super.prototype.getActiveTextures.call(this);
+            if (this.baseTexture) {
+                activeTextures.push(this.baseTexture);
+            }
+            if (this.metallicRoughnessTexture) {
+                activeTextures.push(this.metallicRoughnessTexture);
+            }
+            return activeTextures;
+        };
+        /**
          * Serialize the material to a parsable JSON object.
          * Serialize the material to a parsable JSON object.
          */
          */
         PBRMetallicRoughnessMaterial.prototype.serialize = function () {
         PBRMetallicRoughnessMaterial.prototype.serialize = function () {
@@ -36511,6 +36593,19 @@ var BABYLON;
             return "PBRSpecularGlossinessMaterial";
             return "PBRSpecularGlossinessMaterial";
         };
         };
         /**
         /**
+         * Return the active textures of the material.
+         */
+        PBRSpecularGlossinessMaterial.prototype.getActiveTextures = function () {
+            var activeTextures = _super.prototype.getActiveTextures.call(this);
+            if (this.diffuseTexture) {
+                activeTextures.push(this.diffuseTexture);
+            }
+            if (this.specularGlossinessTexture) {
+                activeTextures.push(this.specularGlossinessTexture);
+            }
+            return activeTextures;
+        };
+        /**
          * Serialize the material to a parsable JSON object.
          * Serialize the material to a parsable JSON object.
          */
          */
         PBRSpecularGlossinessMaterial.prototype.serialize = function () {
         PBRSpecularGlossinessMaterial.prototype.serialize = function () {
@@ -36834,6 +36929,19 @@ var BABYLON;
             }
             }
             this._afterBind(mesh);
             this._afterBind(mesh);
         };
         };
+        ShaderMaterial.prototype.getActiveTextures = function () {
+            var activeTextures = _super.prototype.getActiveTextures.call(this);
+            for (var name in this._textures) {
+                activeTextures.push(this._textures[name]);
+            }
+            for (var name in this._textureArrays) {
+                var array = this._textureArrays[name];
+                for (var index = 0; index < array.length; index++) {
+                    activeTextures.push(array[index]);
+                }
+            }
+            return activeTextures;
+        };
         ShaderMaterial.prototype.clone = function (name) {
         ShaderMaterial.prototype.clone = function (name) {
             var newShaderMaterial = new ShaderMaterial(name, this.getScene(), this._shaderPath, this._options);
             var newShaderMaterial = new ShaderMaterial(name, this.getScene(), this._shaderPath, this._options);
             return newShaderMaterial;
             return newShaderMaterial;
@@ -41629,6 +41737,40 @@ var BABYLON;
             }
             }
             return results;
             return results;
         };
         };
+        StandardMaterial.prototype.getActiveTextures = function () {
+            var activeTextures = _super.prototype.getActiveTextures.call(this);
+            if (this._diffuseTexture) {
+                activeTextures.push(this._diffuseTexture);
+            }
+            if (this._ambientTexture) {
+                activeTextures.push(this._ambientTexture);
+            }
+            if (this._opacityTexture) {
+                activeTextures.push(this._opacityTexture);
+            }
+            if (this._reflectionTexture) {
+                activeTextures.push(this._reflectionTexture);
+            }
+            if (this._emissiveTexture) {
+                activeTextures.push(this._emissiveTexture);
+            }
+            if (this._specularTexture) {
+                activeTextures.push(this._specularTexture);
+            }
+            if (this._bumpTexture) {
+                activeTextures.push(this._bumpTexture);
+            }
+            if (this._lightmapTexture) {
+                activeTextures.push(this._lightmapTexture);
+            }
+            if (this._refractionTexture) {
+                activeTextures.push(this._refractionTexture);
+            }
+            if (this._cameraColorGradingTexture) {
+                activeTextures.push(this._cameraColorGradingTexture);
+            }
+            return activeTextures;
+        };
         StandardMaterial.prototype.dispose = function (forceDisposeEffect, forceDisposeTextures) {
         StandardMaterial.prototype.dispose = function (forceDisposeEffect, forceDisposeTextures) {
             if (forceDisposeTextures) {
             if (forceDisposeTextures) {
                 if (this._diffuseTexture) {
                 if (this._diffuseTexture) {

文件差异内容过多而无法显示
+ 2823 - 2809
dist/preview release/customConfigurations/minimalViewer/babylon.module.d.ts


文件差异内容过多而无法显示
+ 1 - 1
dist/preview release/gui/babylon.gui.min.js


文件差异内容过多而无法显示
+ 263 - 263
dist/preview release/inspector/babylon.inspector.bundle.js


文件差异内容过多而无法显示
+ 3 - 3
dist/preview release/inspector/babylon.inspector.min.js


文件差异内容过多而无法显示
+ 2 - 2
dist/preview release/loaders/babylon.glTF1FileLoader.min.js


+ 42 - 30
dist/preview release/loaders/babylon.glTF2FileLoader.d.ts

@@ -120,15 +120,11 @@ declare module BABYLON.GLTF2 {
         samplers: IGLTFAnimationSampler[];
         samplers: IGLTFAnimationSampler[];
         targets?: any[];
         targets?: any[];
     }
     }
-    interface IGLTFAssetProfile extends IGLTFProperty {
-        api?: string;
-        version?: string;
-    }
     interface IGLTFAsset extends IGLTFChildRootProperty {
     interface IGLTFAsset extends IGLTFChildRootProperty {
         copyright?: string;
         copyright?: string;
         generator?: string;
         generator?: string;
-        profile?: IGLTFAssetProfile;
         version: string;
         version: string;
+        minVersion?: string;
     }
     }
     interface IGLTFBuffer extends IGLTFChildRootProperty {
     interface IGLTFBuffer extends IGLTFChildRootProperty {
         uri?: string;
         uri?: string;
@@ -186,6 +182,7 @@ declare module BABYLON.GLTF2 {
         alphaMode?: string;
         alphaMode?: string;
         alphaCutoff: number;
         alphaCutoff: number;
         doubleSided?: boolean;
         doubleSided?: boolean;
+        index?: number;
         babylonMaterial?: PBRMaterial;
         babylonMaterial?: PBRMaterial;
     }
     }
     interface IGLTFMeshPrimitive extends IGLTFProperty {
     interface IGLTFMeshPrimitive extends IGLTFProperty {
@@ -214,6 +211,7 @@ declare module BABYLON.GLTF2 {
         translation?: number[];
         translation?: number[];
         weights?: number[];
         weights?: number[];
         index?: number;
         index?: number;
+        parent?: IGLTFNode;
         babylonMesh?: Mesh;
         babylonMesh?: Mesh;
         babylonSkinToBones?: {
         babylonSkinToBones?: {
             [skin: number]: Bone;
             [skin: number]: Bone;
@@ -272,24 +270,26 @@ declare module BABYLON.GLTF2 {
 declare module BABYLON.GLTF2 {
 declare module BABYLON.GLTF2 {
     class GLTFLoader implements IGLTFLoader {
     class GLTFLoader implements IGLTFLoader {
         private _gltf;
         private _gltf;
-        private _pendingCount;
-        private _onLoaded;
         private _errors;
         private _errors;
         private _babylonScene;
         private _babylonScene;
         private _rootUrl;
         private _rootUrl;
         private _defaultMaterial;
         private _defaultMaterial;
+        private _onSuccess;
+        private _onError;
+        private _renderReady;
+        private _renderPendingCount;
+        private _loaderPendingCount;
         static Extensions: {
         static Extensions: {
             [name: string]: GLTFLoaderExtension;
             [name: string]: GLTFLoaderExtension;
         };
         };
         static RegisterExtension(extension: GLTFLoaderExtension): void;
         static RegisterExtension(extension: GLTFLoaderExtension): void;
-        static LoadMaterial(index: number): IGLTFMaterial;
-        static LoadCoreMaterial(index: number): Material;
-        static LoadCommonMaterialProperties(material: IGLTFMaterial): void;
-        static LoadAlphaProperties(material: IGLTFMaterial): void;
-        static LoadTexture(textureInfo: IGLTFTextureInfo): Texture;
+        readonly gltf: IGLTF;
+        readonly babylonScene: Scene;
         importMeshAsync(meshesNames: any, scene: Scene, data: IGLTFLoaderData, rootUrl: string, onSuccess: (meshes: AbstractMesh[], particleSystems: ParticleSystem[], skeletons: Skeleton[]) => void, onError: () => void): void;
         importMeshAsync(meshesNames: any, scene: Scene, data: IGLTFLoaderData, rootUrl: string, onSuccess: (meshes: AbstractMesh[], particleSystems: ParticleSystem[], skeletons: Skeleton[]) => void, onError: () => void): void;
         loadAsync(scene: Scene, data: IGLTFLoaderData, rootUrl: string, onSuccess: () => void, onError: () => void): void;
         loadAsync(scene: Scene, data: IGLTFLoaderData, rootUrl: string, onSuccess: () => void, onError: () => void): void;
         private _loadAsync(nodeNames, scene, data, rootUrl, onSuccess, onError);
         private _loadAsync(nodeNames, scene, data, rootUrl, onSuccess, onError);
+        private _onRenderReady();
+        private _onLoaderComplete();
         private _loadData(data);
         private _loadData(data);
         private _showMeshes();
         private _showMeshes();
         private _startAnimations();
         private _startAnimations();
@@ -298,27 +298,30 @@ declare module BABYLON.GLTF2 {
         private _loadSkin(node);
         private _loadSkin(node);
         private _updateBone(node, parentNode, skin, inverseBindMatrixData);
         private _updateBone(node, parentNode, skin, inverseBindMatrixData);
         private _createBone(node, skin);
         private _createBone(node, skin);
-        private _loadMesh(node, parentNode);
+        private _loadMesh(node);
         private _loadMeshData(node, mesh, babylonMesh);
         private _loadMeshData(node, mesh, babylonMesh);
         private _loadVertexDataAsync(primitive, onSuccess);
         private _loadVertexDataAsync(primitive, onSuccess);
         private _createMorphTargets(node, mesh, primitive, babylonMesh);
         private _createMorphTargets(node, mesh, primitive, babylonMesh);
         private _loadMorphTargetsData(mesh, primitive, vertexData, babylonMesh);
         private _loadMorphTargetsData(mesh, primitive, vertexData, babylonMesh);
         private _loadTransform(node, babylonMesh);
         private _loadTransform(node, babylonMesh);
-        private _traverseScene(nodeNames, scene, action);
-        private _traverseNode(nodeNames, index, action, parentNode?);
+        private _traverseNodes(indices, action, parentNode?);
+        private _traverseNode(index, action, parentNode?);
         private _loadAnimations();
         private _loadAnimations();
         private _loadAnimationChannel(animation, animationIndex, channelIndex);
         private _loadAnimationChannel(animation, animationIndex, channelIndex);
         private _loadBufferAsync(index, onSuccess);
         private _loadBufferAsync(index, onSuccess);
         private _loadBufferViewAsync(bufferView, byteOffset, byteLength, componentType, onSuccess);
         private _loadBufferViewAsync(bufferView, byteOffset, byteLength, componentType, onSuccess);
         private _loadAccessorAsync(accessor, onSuccess);
         private _loadAccessorAsync(accessor, onSuccess);
-        private _addPendingData(data);
-        private _removePendingData(data);
+        addPendingData(data: any): void;
+        removePendingData(data: any): void;
+        addLoaderPendingData(data: any): void;
+        removeLoaderPendingData(data: any): void;
         private _getDefaultMaterial();
         private _getDefaultMaterial();
-        private _loadMaterial(index);
-        private _loadCoreMaterial(index);
-        private _loadCommonMaterialProperties(material);
-        private _loadAlphaProperties(material);
-        private _loadTexture(textureInfo);
+        private _loadMaterialMetallicRoughnessProperties(material);
+        loadMaterial(index: number, assign: (material: Material) => void): void;
+        createPbrMaterial(material: IGLTFMaterial): void;
+        loadMaterialBaseProperties(material: IGLTFMaterial): void;
+        loadMaterialAlphaProperties(material: IGLTFMaterial): void;
+        loadTexture(textureInfo: IGLTFTextureInfo): Texture;
     }
     }
 }
 }
 
 
@@ -364,19 +367,28 @@ declare module BABYLON.GLTF2 {
 
 
 declare module BABYLON.GLTF2 {
 declare module BABYLON.GLTF2 {
     abstract class GLTFLoaderExtension {
     abstract class GLTFLoaderExtension {
-        private _name;
         enabled: boolean;
         enabled: boolean;
-        constructor(name: string);
+        readonly abstract name: string;
+        protected loadMaterial(loader: GLTFLoader, material: IGLTFMaterial, assign: (material: Material) => void): boolean;
+        static _Extensions: GLTFLoaderExtension[];
+        static LoadMaterial(loader: GLTFLoader, material: IGLTFMaterial, assign: (material: Material) => void): boolean;
+        private static _ApplyExtensions(action);
+    }
+}
+
+
+declare module BABYLON.GLTF2.Extensions {
+    class MSFTLOD extends GLTFLoaderExtension {
         readonly name: string;
         readonly name: string;
-        protected loadMaterial(index: number): Material;
-        static LoadMaterial(index: number): Material;
+        protected loadMaterial(loader: GLTFLoader, material: IGLTFMaterial, assign: (material: Material) => void): boolean;
+        private loadMaterialLOD(loader, material, materialLODs, lod, assign);
     }
     }
 }
 }
 
 
 
 
-declare module BABYLON.GLTF2 {
-    class GLTFMaterialsPbrSpecularGlossinessExtension extends GLTFLoaderExtension {
-        constructor();
-        protected loadMaterial(index: number): Material;
+declare module BABYLON.GLTF2.Extensions {
+    class KHRMaterialsPbrSpecularGlossiness extends GLTFLoaderExtension {
+        readonly name: string;
+        protected loadMaterial(loader: GLTFLoader, material: IGLTFMaterial, assign: (material: Material) => void): boolean;
     }
     }
 }
 }

+ 319 - 200
dist/preview release/loaders/babylon.glTF2FileLoader.js

@@ -295,23 +295,24 @@ var BABYLON;
                     BABYLON.Tools.Error("Extension with the same name '" + extension.name + "' already exists");
                     BABYLON.Tools.Error("Extension with the same name '" + extension.name + "' already exists");
                     return;
                     return;
                 }
                 }
-                this.Extensions[extension.name] = extension;
-            };
-            GLTFLoader.LoadMaterial = function (index) {
-                return BABYLON.GLTFFileLoader.GLTFLoaderV2._loadMaterial(index);
-            };
-            GLTFLoader.LoadCoreMaterial = function (index) {
-                return BABYLON.GLTFFileLoader.GLTFLoaderV2._loadCoreMaterial(index);
-            };
-            GLTFLoader.LoadCommonMaterialProperties = function (material) {
-                return BABYLON.GLTFFileLoader.GLTFLoaderV2._loadCommonMaterialProperties(material);
-            };
-            GLTFLoader.LoadAlphaProperties = function (material) {
-                return BABYLON.GLTFFileLoader.GLTFLoaderV2._loadAlphaProperties(material);
-            };
-            GLTFLoader.LoadTexture = function (textureInfo) {
-                return BABYLON.GLTFFileLoader.GLTFLoaderV2._loadTexture(textureInfo);
+                GLTFLoader.Extensions[extension.name] = extension;
+                // Keep the order of registration so that extensions registered first are called first.
+                GLTF2.GLTFLoaderExtension._Extensions.push(extension);
             };
             };
+            Object.defineProperty(GLTFLoader.prototype, "gltf", {
+                get: function () {
+                    return this._gltf;
+                },
+                enumerable: true,
+                configurable: true
+            });
+            Object.defineProperty(GLTFLoader.prototype, "babylonScene", {
+                get: function () {
+                    return this._babylonScene;
+                },
+                enumerable: true,
+                configurable: true
+            });
             GLTFLoader.prototype.importMeshAsync = function (meshesNames, scene, data, rootUrl, onSuccess, onError) {
             GLTFLoader.prototype.importMeshAsync = function (meshesNames, scene, data, rootUrl, onSuccess, onError) {
                 var _this = this;
                 var _this = this;
                 this._loadAsync(meshesNames, scene, data, rootUrl, function () {
                 this._loadAsync(meshesNames, scene, data, rootUrl, function () {
@@ -340,28 +341,34 @@ var BABYLON;
                 this._loadAsync(null, scene, data, rootUrl, onSuccess, onError);
                 this._loadAsync(null, scene, data, rootUrl, onSuccess, onError);
             };
             };
             GLTFLoader.prototype._loadAsync = function (nodeNames, scene, data, rootUrl, onSuccess, onError) {
             GLTFLoader.prototype._loadAsync = function (nodeNames, scene, data, rootUrl, onSuccess, onError) {
-                var _this = this;
                 scene.useRightHandedSystem = true;
                 scene.useRightHandedSystem = true;
                 this._clear();
                 this._clear();
                 this._loadData(data);
                 this._loadData(data);
                 this._babylonScene = scene;
                 this._babylonScene = scene;
                 this._rootUrl = rootUrl;
                 this._rootUrl = rootUrl;
-                this._onLoaded = function () {
-                    _this._showMeshes();
-                    _this._startAnimations();
-                    if (_this._errors.length === 0) {
-                        onSuccess();
-                    }
-                    else {
-                        _this._errors.forEach(function (error) { return BABYLON.Tools.Error(error); });
-                        onError();
-                    }
-                    _this._clear();
-                };
-                this._addPendingData(this);
+                this._onSuccess = onSuccess;
+                this._onError = onError;
+                this.addPendingData(this);
                 this._loadScene(nodeNames);
                 this._loadScene(nodeNames);
                 this._loadAnimations();
                 this._loadAnimations();
-                this._removePendingData(this);
+                this.removePendingData(this);
+            };
+            GLTFLoader.prototype._onRenderReady = function () {
+                this._showMeshes();
+                this._startAnimations();
+                if (this._errors.length === 0) {
+                    this._onSuccess();
+                }
+                else {
+                    this._errors.forEach(function (error) { return BABYLON.Tools.Error(error); });
+                    this._errors = [];
+                    this._onError();
+                }
+            };
+            GLTFLoader.prototype._onLoaderComplete = function () {
+                this._errors.forEach(function (error) { return BABYLON.Tools.Error(error); });
+                this._errors = [];
+                this._clear();
             };
             };
             GLTFLoader.prototype._loadData = function (data) {
             GLTFLoader.prototype._loadData = function (data) {
                 this._gltf = data.json;
                 this._gltf = data.json;
@@ -404,13 +411,6 @@ var BABYLON;
                 }
                 }
             };
             };
             GLTFLoader.prototype._clear = function () {
             GLTFLoader.prototype._clear = function () {
-                this._gltf = undefined;
-                this._pendingCount = 0;
-                this._onLoaded = undefined;
-                this._errors = [];
-                this._babylonScene = undefined;
-                this._rootUrl = undefined;
-                this._defaultMaterial = undefined;
                 // Revoke object urls created during load
                 // Revoke object urls created during load
                 if (this._gltf && this._gltf.textures) {
                 if (this._gltf && this._gltf.textures) {
                     for (var i = 0; i < this._gltf.textures.length; i++) {
                     for (var i = 0; i < this._gltf.textures.length; i++) {
@@ -420,14 +420,42 @@ var BABYLON;
                         }
                         }
                     }
                     }
                 }
                 }
+                this._gltf = undefined;
+                this._errors = [];
+                this._babylonScene = undefined;
+                this._rootUrl = undefined;
+                this._defaultMaterial = undefined;
+                this._onSuccess = undefined;
+                this._onError = undefined;
+                this._renderReady = false;
+                this._renderPendingCount = 0;
+                this._loaderPendingCount = 0;
             };
             };
             GLTFLoader.prototype._loadScene = function (nodeNames) {
             GLTFLoader.prototype._loadScene = function (nodeNames) {
                 var _this = this;
                 var _this = this;
-                nodeNames = (nodeNames === "") ? null : nodeNames;
-                nodeNames = (nodeNames instanceof Array) ? nodeNames : [nodeNames];
                 var scene = this._gltf.scenes[this._gltf.scene || 0];
                 var scene = this._gltf.scenes[this._gltf.scene || 0];
-                this._traverseScene(nodeNames, scene, function (node) { return _this._loadSkin(node); });
-                this._traverseScene(nodeNames, scene, function (node, parentNode) { return _this._loadMesh(node, parentNode); });
+                var nodeIndices = scene.nodes;
+                this._traverseNodes(nodeIndices, function (node, index, parentNode) {
+                    node.index = index;
+                    node.parent = parentNode;
+                    return true;
+                });
+                if (nodeNames) {
+                    if (!(nodeNames instanceof Array)) {
+                        nodeNames = [nodeNames];
+                    }
+                    var filteredNodeIndices = new Array();
+                    this._traverseNodes(nodeIndices, function (node) {
+                        if (nodeNames.indexOf(node.name) === -1) {
+                            return true;
+                        }
+                        filteredNodeIndices.push(node.index);
+                        return false;
+                    });
+                    nodeIndices = filteredNodeIndices;
+                }
+                this._traverseNodes(nodeIndices, function (node) { return _this._loadSkin(node); });
+                this._traverseNodes(nodeIndices, function (node) { return _this._loadMesh(node); });
             };
             };
             GLTFLoader.prototype._loadSkin = function (node) {
             GLTFLoader.prototype._loadSkin = function (node) {
                 var _this = this;
                 var _this = this;
@@ -449,7 +477,7 @@ var BABYLON;
                     }
                     }
                     var accessor = this._gltf.accessors[skin.inverseBindMatrices];
                     var accessor = this._gltf.accessors[skin.inverseBindMatrices];
                     this._loadAccessorAsync(accessor, function (data) {
                     this._loadAccessorAsync(accessor, function (data) {
-                        _this._traverseNode(null, skin.skeleton, function (node, parent) { return _this._updateBone(node, parent, skin, data); });
+                        _this._traverseNode(skin.skeleton, function (node, index, parent) { return _this._updateBone(node, parent, skin, data); });
                     });
                     });
                 }
                 }
                 return true;
                 return true;
@@ -478,7 +506,7 @@ var BABYLON;
                 node.babylonAnimationTargets.push(babylonBone);
                 node.babylonAnimationTargets.push(babylonBone);
                 return babylonBone;
                 return babylonBone;
             };
             };
-            GLTFLoader.prototype._loadMesh = function (node, parentNode) {
+            GLTFLoader.prototype._loadMesh = function (node) {
                 var babylonMesh = new BABYLON.Mesh(node.name || "mesh" + node.index, this._babylonScene);
                 var babylonMesh = new BABYLON.Mesh(node.name || "mesh" + node.index, this._babylonScene);
                 babylonMesh.isVisible = false;
                 babylonMesh.isVisible = false;
                 this._loadTransform(node, babylonMesh);
                 this._loadTransform(node, babylonMesh);
@@ -486,7 +514,7 @@ var BABYLON;
                     var mesh = this._gltf.meshes[node.mesh];
                     var mesh = this._gltf.meshes[node.mesh];
                     this._loadMeshData(node, mesh, babylonMesh);
                     this._loadMeshData(node, mesh, babylonMesh);
                 }
                 }
-                babylonMesh.parent = parentNode ? parentNode.babylonMesh : null;
+                babylonMesh.parent = node.parent ? node.parent.babylonMesh : null;
                 node.babylonMesh = babylonMesh;
                 node.babylonMesh = babylonMesh;
                 node.babylonAnimationTargets = node.babylonAnimationTargets || [];
                 node.babylonAnimationTargets = node.babylonAnimationTargets || [];
                 node.babylonAnimationTargets.push(node.babylonMesh);
                 node.babylonAnimationTargets.push(node.babylonMesh);
@@ -502,17 +530,16 @@ var BABYLON;
             GLTFLoader.prototype._loadMeshData = function (node, mesh, babylonMesh) {
             GLTFLoader.prototype._loadMeshData = function (node, mesh, babylonMesh) {
                 var _this = this;
                 var _this = this;
                 babylonMesh.name = mesh.name || babylonMesh.name;
                 babylonMesh.name = mesh.name || babylonMesh.name;
-                babylonMesh.subMeshes = [];
-                var multiMaterial = new BABYLON.MultiMaterial(babylonMesh.name, this._babylonScene);
-                babylonMesh.material = multiMaterial;
+                var babylonMultiMaterial = new BABYLON.MultiMaterial(babylonMesh.name, this._babylonScene);
+                babylonMesh.material = babylonMultiMaterial;
                 var geometry = new BABYLON.Geometry(babylonMesh.name, this._babylonScene, null, false, babylonMesh);
                 var geometry = new BABYLON.Geometry(babylonMesh.name, this._babylonScene, null, false, babylonMesh);
                 var vertexData = new BABYLON.VertexData();
                 var vertexData = new BABYLON.VertexData();
                 vertexData.positions = [];
                 vertexData.positions = [];
                 vertexData.indices = [];
                 vertexData.indices = [];
                 var subMeshInfos = [];
                 var subMeshInfos = [];
-                var primitivesLoaded = 0;
-                var numPrimitives = mesh.primitives.length;
-                var _loop_1 = function () {
+                var loadedPrimitives = 0;
+                var totalPrimitives = mesh.primitives.length;
+                var _loop_1 = function (i) {
                     var primitive = mesh.primitives[i];
                     var primitive = mesh.primitives[i];
                     if (primitive.mode && primitive.mode !== GLTF2.EMeshPrimitiveMode.TRIANGLES) {
                     if (primitive.mode && primitive.mode !== GLTF2.EMeshPrimitiveMode.TRIANGLES) {
                         // TODO: handle other primitive modes
                         // TODO: handle other primitive modes
@@ -522,28 +549,40 @@ var BABYLON;
                     this_1._loadVertexDataAsync(primitive, function (subVertexData) {
                     this_1._loadVertexDataAsync(primitive, function (subVertexData) {
                         _this._loadMorphTargetsData(mesh, primitive, subVertexData, babylonMesh);
                         _this._loadMorphTargetsData(mesh, primitive, subVertexData, babylonMesh);
                         subMeshInfos.push({
                         subMeshInfos.push({
-                            materialIndex: multiMaterial.subMaterials.length,
+                            materialIndex: i,
                             verticesStart: vertexData.positions.length,
                             verticesStart: vertexData.positions.length,
                             verticesCount: subVertexData.positions.length,
                             verticesCount: subVertexData.positions.length,
                             indicesStart: vertexData.indices.length,
                             indicesStart: vertexData.indices.length,
                             indicesCount: subVertexData.indices.length
                             indicesCount: subVertexData.indices.length
                         });
                         });
-                        var subMaterial = primitive.material === undefined ? _this._getDefaultMaterial() : GLTF2.GLTFLoaderExtension.LoadMaterial(primitive.material);
-                        multiMaterial.subMaterials.push(subMaterial);
                         vertexData.merge(subVertexData);
                         vertexData.merge(subVertexData);
-                        if (++primitivesLoaded === numPrimitives) {
+                        if (primitive.material === undefined) {
+                            babylonMultiMaterial.subMaterials[i] = _this._getDefaultMaterial();
+                        }
+                        else {
+                            _this.loadMaterial(primitive.material, function (babylonSubMaterial) {
+                                if (_this._renderReady) {
+                                    babylonSubMaterial.forceCompilation(babylonMesh, function (babylonSubMaterial) {
+                                        babylonMultiMaterial.subMaterials[i] = babylonSubMaterial;
+                                    });
+                                }
+                                else {
+                                    babylonMultiMaterial.subMaterials[i] = babylonSubMaterial;
+                                }
+                            });
+                        }
+                        if (++loadedPrimitives === totalPrimitives) {
                             geometry.setAllVerticesData(vertexData, false);
                             geometry.setAllVerticesData(vertexData, false);
-                            // Sub meshes must be created after setting vertex data because of mesh._createGlobalSubMesh.
-                            for (var i = 0; i < subMeshInfos.length; i++) {
-                                var info = subMeshInfos[i];
-                                new BABYLON.SubMesh(info.materialIndex, info.verticesStart, info.verticesCount, info.indicesStart, info.indicesCount, babylonMesh);
-                            }
+                            // TODO: optimize this so that sub meshes can be created without being overwritten after setting vertex data.
+                            // Sub meshes must be cleared and created after setting vertex data because of mesh._createGlobalSubMesh.
+                            babylonMesh.subMeshes = [];
+                            subMeshInfos.forEach(function (info) { return new BABYLON.SubMesh(info.materialIndex, info.verticesStart, info.verticesCount, info.indicesStart, info.indicesCount, babylonMesh); });
                         }
                         }
                     });
                     });
                 };
                 };
                 var this_1 = this;
                 var this_1 = this;
-                for (var i = 0; i < numPrimitives; i++) {
-                    _loop_1();
+                for (var i = 0; i < totalPrimitives; i++) {
+                    _loop_1(i);
                 }
                 }
             };
             };
             GLTFLoader.prototype._loadVertexDataAsync = function (primitive, onSuccess) {
             GLTFLoader.prototype._loadVertexDataAsync = function (primitive, onSuccess) {
@@ -555,7 +594,7 @@ var BABYLON;
                 }
                 }
                 var vertexData = new BABYLON.VertexData();
                 var vertexData = new BABYLON.VertexData();
                 var loadedAttributes = 0;
                 var loadedAttributes = 0;
-                var numAttributes = Object.keys(attributes).length;
+                var totalAttributes = Object.keys(attributes).length;
                 var _loop_2 = function (semantic) {
                 var _loop_2 = function (semantic) {
                     accessor = this_2._gltf.accessors[attributes[semantic]];
                     accessor = this_2._gltf.accessors[attributes[semantic]];
                     this_2._loadAccessorAsync(accessor, function (data) {
                     this_2._loadAccessorAsync(accessor, function (data) {
@@ -588,7 +627,7 @@ var BABYLON;
                                 BABYLON.Tools.Warn("Ignoring unrecognized semantic '" + semantic + "'");
                                 BABYLON.Tools.Warn("Ignoring unrecognized semantic '" + semantic + "'");
                                 break;
                                 break;
                         }
                         }
-                        if (++loadedAttributes === numAttributes) {
+                        if (++loadedAttributes === totalAttributes) {
                             var indicesAccessor = _this._gltf.accessors[primitive.indices];
                             var indicesAccessor = _this._gltf.accessors[primitive.indices];
                             if (indicesAccessor) {
                             if (indicesAccessor) {
                                 _this._loadAccessorAsync(indicesAccessor, function (data) {
                                 _this._loadAccessorAsync(indicesAccessor, function (data) {
@@ -695,34 +734,21 @@ var BABYLON;
                 babylonMesh.rotationQuaternion = rotation;
                 babylonMesh.rotationQuaternion = rotation;
                 babylonMesh.scaling = scaling;
                 babylonMesh.scaling = scaling;
             };
             };
-            GLTFLoader.prototype._traverseScene = function (nodeNames, scene, action) {
-                var nodes = scene.nodes;
-                if (nodes) {
-                    for (var i = 0; i < nodes.length; i++) {
-                        this._traverseNode(nodeNames, nodes[i], action);
-                    }
+            GLTFLoader.prototype._traverseNodes = function (indices, action, parentNode) {
+                if (parentNode === void 0) { parentNode = null; }
+                for (var i = 0; i < indices.length; i++) {
+                    this._traverseNode(indices[i], action, parentNode);
                 }
                 }
             };
             };
-            GLTFLoader.prototype._traverseNode = function (nodeNames, index, action, parentNode) {
+            GLTFLoader.prototype._traverseNode = function (index, action, parentNode) {
                 if (parentNode === void 0) { parentNode = null; }
                 if (parentNode === void 0) { parentNode = null; }
                 var node = this._gltf.nodes[index];
                 var node = this._gltf.nodes[index];
-                if (nodeNames) {
-                    if (nodeNames.indexOf(node.name)) {
-                        // load all children
-                        nodeNames = null;
-                    }
-                    else {
-                        // skip this node tree
-                        return;
-                    }
-                }
-                node.index = index;
-                if (!action(node, parentNode)) {
+                if (!action(node, index, parentNode)) {
                     return;
                     return;
                 }
                 }
                 if (node.children) {
                 if (node.children) {
                     for (var i = 0; i < node.children.length; i++) {
                     for (var i = 0; i < node.children.length; i++) {
-                        this._traverseNode(nodeNames, node.children[i], action, node);
+                        this._traverseNode(node.children[i], action, node);
                     }
                     }
                 }
                 }
             };
             };
@@ -851,11 +877,11 @@ var BABYLON;
             GLTFLoader.prototype._loadBufferAsync = function (index, onSuccess) {
             GLTFLoader.prototype._loadBufferAsync = function (index, onSuccess) {
                 var _this = this;
                 var _this = this;
                 var buffer = this._gltf.buffers[index];
                 var buffer = this._gltf.buffers[index];
-                this._addPendingData(buffer);
+                this.addPendingData(buffer);
                 if (buffer.loadedData) {
                 if (buffer.loadedData) {
                     setTimeout(function () {
                     setTimeout(function () {
                         onSuccess(buffer.loadedData);
                         onSuccess(buffer.loadedData);
-                        _this._removePendingData(buffer);
+                        _this.removePendingData(buffer);
                     });
                     });
                 }
                 }
                 else if (GLTF2.GLTFUtils.IsBase64(buffer.uri)) {
                 else if (GLTF2.GLTFUtils.IsBase64(buffer.uri)) {
@@ -863,20 +889,20 @@ var BABYLON;
                     buffer.loadedData = new Uint8Array(data);
                     buffer.loadedData = new Uint8Array(data);
                     setTimeout(function () {
                     setTimeout(function () {
                         onSuccess(buffer.loadedData);
                         onSuccess(buffer.loadedData);
-                        _this._removePendingData(buffer);
+                        _this.removePendingData(buffer);
                     });
                     });
                 }
                 }
                 else if (buffer.loadedObservable) {
                 else if (buffer.loadedObservable) {
                     buffer.loadedObservable.add(function (buffer) {
                     buffer.loadedObservable.add(function (buffer) {
                         onSuccess(buffer.loadedData);
                         onSuccess(buffer.loadedData);
-                        _this._removePendingData(buffer);
+                        _this.removePendingData(buffer);
                     });
                     });
                 }
                 }
                 else {
                 else {
                     buffer.loadedObservable = new BABYLON.Observable();
                     buffer.loadedObservable = new BABYLON.Observable();
                     buffer.loadedObservable.add(function (buffer) {
                     buffer.loadedObservable.add(function (buffer) {
                         onSuccess(buffer.loadedData);
                         onSuccess(buffer.loadedData);
-                        _this._removePendingData(buffer);
+                        _this.removePendingData(buffer);
                     });
                     });
                     BABYLON.Tools.LoadFile(this._rootUrl + buffer.uri, function (data) {
                     BABYLON.Tools.LoadFile(this._rootUrl + buffer.uri, function (data) {
                         buffer.loadedData = new Uint8Array(data);
                         buffer.loadedData = new Uint8Array(data);
@@ -884,7 +910,7 @@ var BABYLON;
                         buffer.loadedObservable = null;
                         buffer.loadedObservable = null;
                     }, null, null, true, function (request) {
                     }, null, null, true, function (request) {
                         _this._errors.push("Failed to load file '" + buffer.uri + "': " + request.statusText + "(" + request.status + ")");
                         _this._errors.push("Failed to load file '" + buffer.uri + "': " + request.statusText + "(" + request.status + ")");
-                        _this._removePendingData(buffer);
+                        _this.removePendingData(buffer);
                     });
                     });
                 }
                 }
             };
             };
@@ -931,12 +957,27 @@ var BABYLON;
                 var byteLength = accessor.count * GLTF2.GLTFUtils.GetByteStrideFromType(accessor);
                 var byteLength = accessor.count * GLTF2.GLTFUtils.GetByteStrideFromType(accessor);
                 this._loadBufferViewAsync(bufferView, byteOffset, byteLength, accessor.componentType, onSuccess);
                 this._loadBufferViewAsync(bufferView, byteOffset, byteLength, accessor.componentType, onSuccess);
             };
             };
-            GLTFLoader.prototype._addPendingData = function (data) {
-                this._pendingCount++;
+            GLTFLoader.prototype.addPendingData = function (data) {
+                if (!this._renderReady) {
+                    this._renderPendingCount++;
+                }
+                this.addLoaderPendingData(data);
+            };
+            GLTFLoader.prototype.removePendingData = function (data) {
+                if (!this._renderReady) {
+                    if (--this._renderPendingCount === 0) {
+                        this._renderReady = true;
+                        this._onRenderReady();
+                    }
+                }
+                this.removeLoaderPendingData(data);
+            };
+            GLTFLoader.prototype.addLoaderPendingData = function (data) {
+                this._loaderPendingCount++;
             };
             };
-            GLTFLoader.prototype._removePendingData = function (data) {
-                if (--this._pendingCount === 0) {
-                    this._onLoaded();
+            GLTFLoader.prototype.removeLoaderPendingData = function (data) {
+                if (--this._loaderPendingCount === 0) {
+                    this._onLoaderComplete();
                 }
                 }
             };
             };
             GLTFLoader.prototype._getDefaultMaterial = function () {
             GLTFLoader.prototype._getDefaultMaterial = function () {
@@ -953,46 +994,49 @@ var BABYLON;
                 }
                 }
                 return this._defaultMaterial;
                 return this._defaultMaterial;
             };
             };
-            GLTFLoader.prototype._loadMaterial = function (index) {
-                var materials = this._gltf.materials;
-                var material = materials ? materials[index] : null;
-                if (!material) {
-                    BABYLON.Tools.Warn("Material index (" + index + ") does not exist");
-                    return null;
-                }
-                material.babylonMaterial = new BABYLON.PBRMaterial(material.name || "mat" + index, this._babylonScene);
-                material.babylonMaterial.sideOrientation = BABYLON.Material.CounterClockWiseSideOrientation;
-                material.babylonMaterial.useScalarInLinearSpace = true;
-                return material;
-            };
-            GLTFLoader.prototype._loadCoreMaterial = function (index) {
-                var material = this._loadMaterial(index);
-                if (!material) {
-                    return null;
-                }
-                this._loadCommonMaterialProperties(material);
+            GLTFLoader.prototype._loadMaterialMetallicRoughnessProperties = function (material) {
                 // Ensure metallic workflow
                 // Ensure metallic workflow
                 material.babylonMaterial.metallic = 1;
                 material.babylonMaterial.metallic = 1;
                 material.babylonMaterial.roughness = 1;
                 material.babylonMaterial.roughness = 1;
                 var properties = material.pbrMetallicRoughness;
                 var properties = material.pbrMetallicRoughness;
-                if (properties) {
-                    material.babylonMaterial.albedoColor = properties.baseColorFactor ? BABYLON.Color3.FromArray(properties.baseColorFactor) : new BABYLON.Color3(1, 1, 1);
-                    material.babylonMaterial.metallic = properties.metallicFactor === undefined ? 1 : properties.metallicFactor;
-                    material.babylonMaterial.roughness = properties.roughnessFactor === undefined ? 1 : properties.roughnessFactor;
-                    if (properties.baseColorTexture) {
-                        material.babylonMaterial.albedoTexture = this._loadTexture(properties.baseColorTexture);
-                        this._loadAlphaProperties(material);
-                    }
-                    if (properties.metallicRoughnessTexture) {
-                        material.babylonMaterial.metallicTexture = this._loadTexture(properties.metallicRoughnessTexture);
-                        material.babylonMaterial.useMetallnessFromMetallicTextureBlue = true;
-                        material.babylonMaterial.useRoughnessFromMetallicTextureGreen = true;
-                        material.babylonMaterial.useRoughnessFromMetallicTextureAlpha = false;
-                    }
+                if (!properties) {
+                    return;
+                }
+                material.babylonMaterial.albedoColor = properties.baseColorFactor ? BABYLON.Color3.FromArray(properties.baseColorFactor) : new BABYLON.Color3(1, 1, 1);
+                material.babylonMaterial.metallic = properties.metallicFactor === undefined ? 1 : properties.metallicFactor;
+                material.babylonMaterial.roughness = properties.roughnessFactor === undefined ? 1 : properties.roughnessFactor;
+                if (properties.baseColorTexture) {
+                    material.babylonMaterial.albedoTexture = this.loadTexture(properties.baseColorTexture);
+                    this.loadMaterialAlphaProperties(material);
+                }
+                if (properties.metallicRoughnessTexture) {
+                    material.babylonMaterial.metallicTexture = this.loadTexture(properties.metallicRoughnessTexture);
+                    material.babylonMaterial.useMetallnessFromMetallicTextureBlue = true;
+                    material.babylonMaterial.useRoughnessFromMetallicTextureGreen = true;
+                    material.babylonMaterial.useRoughnessFromMetallicTextureAlpha = false;
+                }
+            };
+            GLTFLoader.prototype.loadMaterial = function (index, assign) {
+                var material = this._gltf.materials[index];
+                material.index = index;
+                if (material.babylonMaterial) {
+                    assign(material.babylonMaterial);
+                    return;
+                }
+                if (GLTF2.GLTFLoaderExtension.LoadMaterial(this, material, assign)) {
+                    return;
                 }
                 }
-                return material.babylonMaterial;
+                this.createPbrMaterial(material);
+                this.loadMaterialBaseProperties(material);
+                this._loadMaterialMetallicRoughnessProperties(material);
+                assign(material.babylonMaterial);
+            };
+            GLTFLoader.prototype.createPbrMaterial = function (material) {
+                material.babylonMaterial = new BABYLON.PBRMaterial(material.name || "mat" + material.index, this._babylonScene);
+                material.babylonMaterial.sideOrientation = BABYLON.Material.CounterClockWiseSideOrientation;
+                material.babylonMaterial.useScalarInLinearSpace = true;
             };
             };
-            GLTFLoader.prototype._loadCommonMaterialProperties = function (material) {
+            GLTFLoader.prototype.loadMaterialBaseProperties = function (material) {
                 material.babylonMaterial.useEmissiveAsIllumination = (material.emissiveFactor || material.emissiveTexture) ? true : false;
                 material.babylonMaterial.useEmissiveAsIllumination = (material.emissiveFactor || material.emissiveTexture) ? true : false;
                 material.babylonMaterial.emissiveColor = material.emissiveFactor ? BABYLON.Color3.FromArray(material.emissiveFactor) : new BABYLON.Color3(0, 0, 0);
                 material.babylonMaterial.emissiveColor = material.emissiveFactor ? BABYLON.Color3.FromArray(material.emissiveFactor) : new BABYLON.Color3(0, 0, 0);
                 if (material.doubleSided) {
                 if (material.doubleSided) {
@@ -1000,23 +1044,23 @@ var BABYLON;
                     material.babylonMaterial.twoSidedLighting = true;
                     material.babylonMaterial.twoSidedLighting = true;
                 }
                 }
                 if (material.normalTexture) {
                 if (material.normalTexture) {
-                    material.babylonMaterial.bumpTexture = this._loadTexture(material.normalTexture);
+                    material.babylonMaterial.bumpTexture = this.loadTexture(material.normalTexture);
                     if (material.normalTexture.scale !== undefined) {
                     if (material.normalTexture.scale !== undefined) {
                         material.babylonMaterial.bumpTexture.level = material.normalTexture.scale;
                         material.babylonMaterial.bumpTexture.level = material.normalTexture.scale;
                     }
                     }
                 }
                 }
                 if (material.occlusionTexture) {
                 if (material.occlusionTexture) {
-                    material.babylonMaterial.ambientTexture = this._loadTexture(material.occlusionTexture);
+                    material.babylonMaterial.ambientTexture = this.loadTexture(material.occlusionTexture);
                     material.babylonMaterial.useAmbientInGrayScale = true;
                     material.babylonMaterial.useAmbientInGrayScale = true;
                     if (material.occlusionTexture.strength !== undefined) {
                     if (material.occlusionTexture.strength !== undefined) {
                         material.babylonMaterial.ambientTextureStrength = material.occlusionTexture.strength;
                         material.babylonMaterial.ambientTextureStrength = material.occlusionTexture.strength;
                     }
                     }
                 }
                 }
                 if (material.emissiveTexture) {
                 if (material.emissiveTexture) {
-                    material.babylonMaterial.emissiveTexture = this._loadTexture(material.emissiveTexture);
+                    material.babylonMaterial.emissiveTexture = this.loadTexture(material.emissiveTexture);
                 }
                 }
             };
             };
-            GLTFLoader.prototype._loadAlphaProperties = function (material) {
+            GLTFLoader.prototype.loadMaterialAlphaProperties = function (material) {
                 var alphaMode = material.alphaMode || "OPAQUE";
                 var alphaMode = material.alphaMode || "OPAQUE";
                 switch (alphaMode) {
                 switch (alphaMode) {
                     case "OPAQUE":
                     case "OPAQUE":
@@ -1025,18 +1069,17 @@ var BABYLON;
                     case "MASK":
                     case "MASK":
                         material.babylonMaterial.albedoTexture.hasAlpha = true;
                         material.babylonMaterial.albedoTexture.hasAlpha = true;
                         material.babylonMaterial.useAlphaFromAlbedoTexture = false;
                         material.babylonMaterial.useAlphaFromAlbedoTexture = false;
-                        material.babylonMaterial.alphaMode = BABYLON.Engine.ALPHA_DISABLE;
                         break;
                         break;
                     case "BLEND":
                     case "BLEND":
                         material.babylonMaterial.albedoTexture.hasAlpha = true;
                         material.babylonMaterial.albedoTexture.hasAlpha = true;
                         material.babylonMaterial.useAlphaFromAlbedoTexture = true;
                         material.babylonMaterial.useAlphaFromAlbedoTexture = true;
-                        material.babylonMaterial.alphaMode = BABYLON.Engine.ALPHA_COMBINE;
                         break;
                         break;
                     default:
                     default:
-                        BABYLON.Tools.Error("Invalid alpha mode '" + material.alphaMode + "'");
+                        BABYLON.Tools.Warn("Invalid alpha mode '" + material.alphaMode + "'");
+                        break;
                 }
                 }
             };
             };
-            GLTFLoader.prototype._loadTexture = function (textureInfo) {
+            GLTFLoader.prototype.loadTexture = function (textureInfo) {
                 var _this = this;
                 var _this = this;
                 var texture = this._gltf.textures[textureInfo.index];
                 var texture = this._gltf.textures[textureInfo.index];
                 var texCoord = textureInfo.texCoord || 0;
                 var texCoord = textureInfo.texCoord || 0;
@@ -1079,12 +1122,12 @@ var BABYLON;
                 var sampler = (texture.sampler === undefined ? {} : this._gltf.samplers[texture.sampler]);
                 var sampler = (texture.sampler === undefined ? {} : this._gltf.samplers[texture.sampler]);
                 var noMipMaps = (sampler.minFilter === GLTF2.ETextureMinFilter.NEAREST || sampler.minFilter === GLTF2.ETextureMinFilter.LINEAR);
                 var noMipMaps = (sampler.minFilter === GLTF2.ETextureMinFilter.NEAREST || sampler.minFilter === GLTF2.ETextureMinFilter.LINEAR);
                 var samplingMode = GLTF2.GLTFUtils.GetTextureFilterMode(sampler.minFilter);
                 var samplingMode = GLTF2.GLTFUtils.GetTextureFilterMode(sampler.minFilter);
-                this._addPendingData(texture);
+                this.addPendingData(texture);
                 var babylonTexture = new BABYLON.Texture(url, this._babylonScene, noMipMaps, false, samplingMode, function () {
                 var babylonTexture = new BABYLON.Texture(url, this._babylonScene, noMipMaps, false, samplingMode, function () {
-                    _this._removePendingData(texture);
+                    _this.removePendingData(texture);
                 }, function () {
                 }, function () {
                     _this._errors.push("Failed to load texture '" + source.uri + "'");
                     _this._errors.push("Failed to load texture '" + source.uri + "'");
-                    _this._removePendingData(texture);
+                    _this.removePendingData(texture);
                 });
                 });
                 babylonTexture.coordinatesIndex = texCoord;
                 babylonTexture.coordinatesIndex = texCoord;
                 babylonTexture.wrapU = GLTF2.GLTFUtils.GetWrapMode(sampler.wrapS);
                 babylonTexture.wrapU = GLTF2.GLTFUtils.GetWrapMode(sampler.wrapS);
@@ -1205,42 +1248,39 @@ var BABYLON;
     var GLTF2;
     var GLTF2;
     (function (GLTF2) {
     (function (GLTF2) {
         var GLTFLoaderExtension = (function () {
         var GLTFLoaderExtension = (function () {
-            function GLTFLoaderExtension(name) {
+            function GLTFLoaderExtension() {
                 this.enabled = true;
                 this.enabled = true;
-                this._name = name;
             }
             }
-            Object.defineProperty(GLTFLoaderExtension.prototype, "name", {
-                get: function () {
-                    return this._name;
-                },
-                enumerable: true,
-                configurable: true
-            });
-            GLTFLoaderExtension.prototype.loadMaterial = function (index) { return null; };
-            // ---------
-            // Utilities
-            // ---------
-            GLTFLoaderExtension.LoadMaterial = function (index) {
-                for (var extensionName in GLTF2.GLTFLoader.Extensions) {
-                    var extension = GLTF2.GLTFLoader.Extensions[extensionName];
-                    if (extension.enabled) {
-                        var babylonMaterial = extension.loadMaterial(index);
-                        if (babylonMaterial) {
-                            return babylonMaterial;
-                        }
+            GLTFLoaderExtension.prototype.loadMaterial = function (loader, material, assign) { return false; };
+            GLTFLoaderExtension.LoadMaterial = function (loader, material, assign) {
+                return this._ApplyExtensions(function (extension) { return extension.loadMaterial(loader, material, assign); });
+            };
+            GLTFLoaderExtension._ApplyExtensions = function (action) {
+                var extensions = GLTFLoaderExtension._Extensions;
+                if (!extensions) {
+                    return;
+                }
+                for (var i = 0; i < extensions.length; i++) {
+                    var extension = extensions[i];
+                    if (extension.enabled && action(extension)) {
+                        return true;
                     }
                     }
                 }
                 }
-                return GLTF2.GLTFLoader.LoadCoreMaterial(index);
+                return false;
             };
             };
             return GLTFLoaderExtension;
             return GLTFLoaderExtension;
         }());
         }());
+        //
+        // Utilities
+        //
+        GLTFLoaderExtension._Extensions = [];
         GLTF2.GLTFLoaderExtension = GLTFLoaderExtension;
         GLTF2.GLTFLoaderExtension = GLTFLoaderExtension;
     })(GLTF2 = BABYLON.GLTF2 || (BABYLON.GLTF2 = {}));
     })(GLTF2 = BABYLON.GLTF2 || (BABYLON.GLTF2 = {}));
 })(BABYLON || (BABYLON = {}));
 })(BABYLON || (BABYLON = {}));
 
 
 //# sourceMappingURL=babylon.glTFLoaderExtension.js.map
 //# sourceMappingURL=babylon.glTFLoaderExtension.js.map
 
 
-/// <reference path="../../../../dist/preview release/babylon.d.ts"/>
+/// <reference path="../../../../../dist/preview release/babylon.d.ts"/>
 var __extends = (this && this.__extends) || (function () {
 var __extends = (this && this.__extends) || (function () {
     var extendStatics = Object.setPrototypeOf ||
     var extendStatics = Object.setPrototypeOf ||
         ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
         ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
@@ -1255,43 +1295,122 @@ var BABYLON;
 (function (BABYLON) {
 (function (BABYLON) {
     var GLTF2;
     var GLTF2;
     (function (GLTF2) {
     (function (GLTF2) {
-        var GLTFMaterialsPbrSpecularGlossinessExtension = (function (_super) {
-            __extends(GLTFMaterialsPbrSpecularGlossinessExtension, _super);
-            function GLTFMaterialsPbrSpecularGlossinessExtension() {
-                return _super.call(this, "KHR_materials_pbrSpecularGlossiness") || this;
-            }
-            GLTFMaterialsPbrSpecularGlossinessExtension.prototype.loadMaterial = function (index) {
-                var material = GLTF2.GLTFLoader.LoadMaterial(index);
-                if (!material || !material.extensions)
-                    return null;
-                var properties = material.extensions[this.name];
-                if (!properties)
-                    return null;
-                GLTF2.GLTFLoader.LoadCommonMaterialProperties(material);
-                //
-                // Load Factors
-                //
-                material.babylonMaterial.albedoColor = properties.diffuseFactor ? BABYLON.Color3.FromArray(properties.diffuseFactor) : new BABYLON.Color3(1, 1, 1);
-                material.babylonMaterial.reflectivityColor = properties.specularFactor ? BABYLON.Color3.FromArray(properties.specularFactor) : new BABYLON.Color3(1, 1, 1);
-                material.babylonMaterial.microSurface = properties.glossinessFactor === undefined ? 1 : properties.glossinessFactor;
-                //
-                // Load Textures
-                //
-                if (properties.diffuseTexture) {
-                    material.babylonMaterial.albedoTexture = GLTF2.GLTFLoader.LoadTexture(properties.diffuseTexture);
-                    GLTF2.GLTFLoader.LoadAlphaProperties(material);
-                }
-                if (properties.specularGlossinessTexture) {
-                    material.babylonMaterial.reflectivityTexture = GLTF2.GLTFLoader.LoadTexture(properties.specularGlossinessTexture);
-                    material.babylonMaterial.useMicroSurfaceFromReflectivityMapAlpha = true;
-                }
-                return material.babylonMaterial;
-            };
-            return GLTFMaterialsPbrSpecularGlossinessExtension;
-        }(GLTF2.GLTFLoaderExtension));
-        GLTF2.GLTFMaterialsPbrSpecularGlossinessExtension = GLTFMaterialsPbrSpecularGlossinessExtension;
-        GLTF2.GLTFLoader.RegisterExtension(new GLTFMaterialsPbrSpecularGlossinessExtension());
+        var Extensions;
+        (function (Extensions) {
+            var MSFTLOD = (function (_super) {
+                __extends(MSFTLOD, _super);
+                function MSFTLOD() {
+                    return _super !== null && _super.apply(this, arguments) || this;
+                }
+                Object.defineProperty(MSFTLOD.prototype, "name", {
+                    get: function () {
+                        return "MSFT_lod";
+                    },
+                    enumerable: true,
+                    configurable: true
+                });
+                MSFTLOD.prototype.loadMaterial = function (loader, material, assign) {
+                    if (!material.extensions) {
+                        return false;
+                    }
+                    var properties = material.extensions[this.name];
+                    if (!properties) {
+                        return false;
+                    }
+                    // Clear out the extension so that it won't get loaded again.
+                    material.extensions[this.name] = undefined;
+                    // Tell the loader not to clear its state until the highest LOD is loaded.
+                    loader.addLoaderPendingData(material);
+                    // Start with the lowest quality LOD.
+                    var materialLODs = [material.index].concat(properties.ids);
+                    this.loadMaterialLOD(loader, material, materialLODs, materialLODs.length - 1, assign);
+                    return true;
+                };
+                MSFTLOD.prototype.loadMaterialLOD = function (loader, material, materialLODs, lod, assign) {
+                    var _this = this;
+                    loader.loadMaterial(materialLODs[lod], function (babylonMaterial) {
+                        babylonMaterial.name += ".LOD" + lod;
+                        assign(babylonMaterial);
+                        // Loading is complete if this is the highest quality LOD.
+                        if (lod === 0) {
+                            loader.removeLoaderPendingData(material);
+                            return;
+                        }
+                        // Load the next LOD when all of the textures are loaded.
+                        BABYLON.BaseTexture.WhenAllReady(babylonMaterial.getActiveTextures(), function () {
+                            _this.loadMaterialLOD(loader, material, materialLODs, lod - 1, assign);
+                        });
+                    });
+                };
+                return MSFTLOD;
+            }(GLTF2.GLTFLoaderExtension));
+            Extensions.MSFTLOD = MSFTLOD;
+            GLTF2.GLTFLoader.RegisterExtension(new MSFTLOD());
+        })(Extensions = GLTF2.Extensions || (GLTF2.Extensions = {}));
+    })(GLTF2 = BABYLON.GLTF2 || (BABYLON.GLTF2 = {}));
+})(BABYLON || (BABYLON = {}));
+
+//# sourceMappingURL=MSFT_lod.js.map
+
+/// <reference path="../../../../../dist/preview release/babylon.d.ts"/>
+var __extends = (this && this.__extends) || (function () {
+    var extendStatics = Object.setPrototypeOf ||
+        ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
+        function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
+    return function (d, b) {
+        extendStatics(d, b);
+        function __() { this.constructor = d; }
+        d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
+    };
+})();
+var BABYLON;
+(function (BABYLON) {
+    var GLTF2;
+    (function (GLTF2) {
+        var Extensions;
+        (function (Extensions) {
+            var KHRMaterialsPbrSpecularGlossiness = (function (_super) {
+                __extends(KHRMaterialsPbrSpecularGlossiness, _super);
+                function KHRMaterialsPbrSpecularGlossiness() {
+                    return _super !== null && _super.apply(this, arguments) || this;
+                }
+                Object.defineProperty(KHRMaterialsPbrSpecularGlossiness.prototype, "name", {
+                    get: function () {
+                        return "KHR_materials_pbrSpecularGlossiness";
+                    },
+                    enumerable: true,
+                    configurable: true
+                });
+                KHRMaterialsPbrSpecularGlossiness.prototype.loadMaterial = function (loader, material, assign) {
+                    if (!material.extensions) {
+                        return false;
+                    }
+                    var properties = material.extensions[this.name];
+                    if (!properties) {
+                        return false;
+                    }
+                    loader.createPbrMaterial(material);
+                    loader.loadMaterialBaseProperties(material);
+                    material.babylonMaterial.albedoColor = properties.diffuseFactor ? BABYLON.Color3.FromArray(properties.diffuseFactor) : new BABYLON.Color3(1, 1, 1);
+                    material.babylonMaterial.reflectivityColor = properties.specularFactor ? BABYLON.Color3.FromArray(properties.specularFactor) : new BABYLON.Color3(1, 1, 1);
+                    material.babylonMaterial.microSurface = properties.glossinessFactor === undefined ? 1 : properties.glossinessFactor;
+                    if (properties.diffuseTexture) {
+                        material.babylonMaterial.albedoTexture = loader.loadTexture(properties.diffuseTexture);
+                        loader.loadMaterialAlphaProperties(material);
+                    }
+                    if (properties.specularGlossinessTexture) {
+                        material.babylonMaterial.reflectivityTexture = loader.loadTexture(properties.specularGlossinessTexture);
+                        material.babylonMaterial.useMicroSurfaceFromReflectivityMapAlpha = true;
+                    }
+                    assign(material.babylonMaterial);
+                    return true;
+                };
+                return KHRMaterialsPbrSpecularGlossiness;
+            }(GLTF2.GLTFLoaderExtension));
+            Extensions.KHRMaterialsPbrSpecularGlossiness = KHRMaterialsPbrSpecularGlossiness;
+            GLTF2.GLTFLoader.RegisterExtension(new KHRMaterialsPbrSpecularGlossiness());
+        })(Extensions = GLTF2.Extensions || (GLTF2.Extensions = {}));
     })(GLTF2 = BABYLON.GLTF2 || (BABYLON.GLTF2 = {}));
     })(GLTF2 = BABYLON.GLTF2 || (BABYLON.GLTF2 = {}));
 })(BABYLON || (BABYLON = {}));
 })(BABYLON || (BABYLON = {}));
 
 
-//# sourceMappingURL=babylon.glTFMaterialsPbrSpecularGlossinessExtension.js.map
+//# sourceMappingURL=KHR_materials_pbrSpecularGlossiness.js.map

文件差异内容过多而无法显示
+ 1 - 5
dist/preview release/loaders/babylon.glTF2FileLoader.min.js


+ 42 - 30
dist/preview release/loaders/babylon.glTFFileLoader.d.ts

@@ -615,15 +615,11 @@ declare module BABYLON.GLTF2 {
         samplers: IGLTFAnimationSampler[];
         samplers: IGLTFAnimationSampler[];
         targets?: any[];
         targets?: any[];
     }
     }
-    interface IGLTFAssetProfile extends IGLTFProperty {
-        api?: string;
-        version?: string;
-    }
     interface IGLTFAsset extends IGLTFChildRootProperty {
     interface IGLTFAsset extends IGLTFChildRootProperty {
         copyright?: string;
         copyright?: string;
         generator?: string;
         generator?: string;
-        profile?: IGLTFAssetProfile;
         version: string;
         version: string;
+        minVersion?: string;
     }
     }
     interface IGLTFBuffer extends IGLTFChildRootProperty {
     interface IGLTFBuffer extends IGLTFChildRootProperty {
         uri?: string;
         uri?: string;
@@ -681,6 +677,7 @@ declare module BABYLON.GLTF2 {
         alphaMode?: string;
         alphaMode?: string;
         alphaCutoff: number;
         alphaCutoff: number;
         doubleSided?: boolean;
         doubleSided?: boolean;
+        index?: number;
         babylonMaterial?: PBRMaterial;
         babylonMaterial?: PBRMaterial;
     }
     }
     interface IGLTFMeshPrimitive extends IGLTFProperty {
     interface IGLTFMeshPrimitive extends IGLTFProperty {
@@ -709,6 +706,7 @@ declare module BABYLON.GLTF2 {
         translation?: number[];
         translation?: number[];
         weights?: number[];
         weights?: number[];
         index?: number;
         index?: number;
+        parent?: IGLTFNode;
         babylonMesh?: Mesh;
         babylonMesh?: Mesh;
         babylonSkinToBones?: {
         babylonSkinToBones?: {
             [skin: number]: Bone;
             [skin: number]: Bone;
@@ -767,24 +765,26 @@ declare module BABYLON.GLTF2 {
 declare module BABYLON.GLTF2 {
 declare module BABYLON.GLTF2 {
     class GLTFLoader implements IGLTFLoader {
     class GLTFLoader implements IGLTFLoader {
         private _gltf;
         private _gltf;
-        private _pendingCount;
-        private _onLoaded;
         private _errors;
         private _errors;
         private _babylonScene;
         private _babylonScene;
         private _rootUrl;
         private _rootUrl;
         private _defaultMaterial;
         private _defaultMaterial;
+        private _onSuccess;
+        private _onError;
+        private _renderReady;
+        private _renderPendingCount;
+        private _loaderPendingCount;
         static Extensions: {
         static Extensions: {
             [name: string]: GLTFLoaderExtension;
             [name: string]: GLTFLoaderExtension;
         };
         };
         static RegisterExtension(extension: GLTFLoaderExtension): void;
         static RegisterExtension(extension: GLTFLoaderExtension): void;
-        static LoadMaterial(index: number): IGLTFMaterial;
-        static LoadCoreMaterial(index: number): Material;
-        static LoadCommonMaterialProperties(material: IGLTFMaterial): void;
-        static LoadAlphaProperties(material: IGLTFMaterial): void;
-        static LoadTexture(textureInfo: IGLTFTextureInfo): Texture;
+        readonly gltf: IGLTF;
+        readonly babylonScene: Scene;
         importMeshAsync(meshesNames: any, scene: Scene, data: IGLTFLoaderData, rootUrl: string, onSuccess: (meshes: AbstractMesh[], particleSystems: ParticleSystem[], skeletons: Skeleton[]) => void, onError: () => void): void;
         importMeshAsync(meshesNames: any, scene: Scene, data: IGLTFLoaderData, rootUrl: string, onSuccess: (meshes: AbstractMesh[], particleSystems: ParticleSystem[], skeletons: Skeleton[]) => void, onError: () => void): void;
         loadAsync(scene: Scene, data: IGLTFLoaderData, rootUrl: string, onSuccess: () => void, onError: () => void): void;
         loadAsync(scene: Scene, data: IGLTFLoaderData, rootUrl: string, onSuccess: () => void, onError: () => void): void;
         private _loadAsync(nodeNames, scene, data, rootUrl, onSuccess, onError);
         private _loadAsync(nodeNames, scene, data, rootUrl, onSuccess, onError);
+        private _onRenderReady();
+        private _onLoaderComplete();
         private _loadData(data);
         private _loadData(data);
         private _showMeshes();
         private _showMeshes();
         private _startAnimations();
         private _startAnimations();
@@ -793,27 +793,30 @@ declare module BABYLON.GLTF2 {
         private _loadSkin(node);
         private _loadSkin(node);
         private _updateBone(node, parentNode, skin, inverseBindMatrixData);
         private _updateBone(node, parentNode, skin, inverseBindMatrixData);
         private _createBone(node, skin);
         private _createBone(node, skin);
-        private _loadMesh(node, parentNode);
+        private _loadMesh(node);
         private _loadMeshData(node, mesh, babylonMesh);
         private _loadMeshData(node, mesh, babylonMesh);
         private _loadVertexDataAsync(primitive, onSuccess);
         private _loadVertexDataAsync(primitive, onSuccess);
         private _createMorphTargets(node, mesh, primitive, babylonMesh);
         private _createMorphTargets(node, mesh, primitive, babylonMesh);
         private _loadMorphTargetsData(mesh, primitive, vertexData, babylonMesh);
         private _loadMorphTargetsData(mesh, primitive, vertexData, babylonMesh);
         private _loadTransform(node, babylonMesh);
         private _loadTransform(node, babylonMesh);
-        private _traverseScene(nodeNames, scene, action);
-        private _traverseNode(nodeNames, index, action, parentNode?);
+        private _traverseNodes(indices, action, parentNode?);
+        private _traverseNode(index, action, parentNode?);
         private _loadAnimations();
         private _loadAnimations();
         private _loadAnimationChannel(animation, animationIndex, channelIndex);
         private _loadAnimationChannel(animation, animationIndex, channelIndex);
         private _loadBufferAsync(index, onSuccess);
         private _loadBufferAsync(index, onSuccess);
         private _loadBufferViewAsync(bufferView, byteOffset, byteLength, componentType, onSuccess);
         private _loadBufferViewAsync(bufferView, byteOffset, byteLength, componentType, onSuccess);
         private _loadAccessorAsync(accessor, onSuccess);
         private _loadAccessorAsync(accessor, onSuccess);
-        private _addPendingData(data);
-        private _removePendingData(data);
+        addPendingData(data: any): void;
+        removePendingData(data: any): void;
+        addLoaderPendingData(data: any): void;
+        removeLoaderPendingData(data: any): void;
         private _getDefaultMaterial();
         private _getDefaultMaterial();
-        private _loadMaterial(index);
-        private _loadCoreMaterial(index);
-        private _loadCommonMaterialProperties(material);
-        private _loadAlphaProperties(material);
-        private _loadTexture(textureInfo);
+        private _loadMaterialMetallicRoughnessProperties(material);
+        loadMaterial(index: number, assign: (material: Material) => void): void;
+        createPbrMaterial(material: IGLTFMaterial): void;
+        loadMaterialBaseProperties(material: IGLTFMaterial): void;
+        loadMaterialAlphaProperties(material: IGLTFMaterial): void;
+        loadTexture(textureInfo: IGLTFTextureInfo): Texture;
     }
     }
 }
 }
 
 
@@ -859,19 +862,28 @@ declare module BABYLON.GLTF2 {
 
 
 declare module BABYLON.GLTF2 {
 declare module BABYLON.GLTF2 {
     abstract class GLTFLoaderExtension {
     abstract class GLTFLoaderExtension {
-        private _name;
         enabled: boolean;
         enabled: boolean;
-        constructor(name: string);
+        readonly abstract name: string;
+        protected loadMaterial(loader: GLTFLoader, material: IGLTFMaterial, assign: (material: Material) => void): boolean;
+        static _Extensions: GLTFLoaderExtension[];
+        static LoadMaterial(loader: GLTFLoader, material: IGLTFMaterial, assign: (material: Material) => void): boolean;
+        private static _ApplyExtensions(action);
+    }
+}
+
+
+declare module BABYLON.GLTF2.Extensions {
+    class MSFTLOD extends GLTFLoaderExtension {
         readonly name: string;
         readonly name: string;
-        protected loadMaterial(index: number): Material;
-        static LoadMaterial(index: number): Material;
+        protected loadMaterial(loader: GLTFLoader, material: IGLTFMaterial, assign: (material: Material) => void): boolean;
+        private loadMaterialLOD(loader, material, materialLODs, lod, assign);
     }
     }
 }
 }
 
 
 
 
-declare module BABYLON.GLTF2 {
-    class GLTFMaterialsPbrSpecularGlossinessExtension extends GLTFLoaderExtension {
-        constructor();
-        protected loadMaterial(index: number): Material;
+declare module BABYLON.GLTF2.Extensions {
+    class KHRMaterialsPbrSpecularGlossiness extends GLTFLoaderExtension {
+        readonly name: string;
+        protected loadMaterial(loader: GLTFLoader, material: IGLTFMaterial, assign: (material: Material) => void): boolean;
     }
     }
 }
 }

+ 319 - 200
dist/preview release/loaders/babylon.glTFFileLoader.js

@@ -2448,23 +2448,24 @@ var BABYLON;
                     BABYLON.Tools.Error("Extension with the same name '" + extension.name + "' already exists");
                     BABYLON.Tools.Error("Extension with the same name '" + extension.name + "' already exists");
                     return;
                     return;
                 }
                 }
-                this.Extensions[extension.name] = extension;
-            };
-            GLTFLoader.LoadMaterial = function (index) {
-                return BABYLON.GLTFFileLoader.GLTFLoaderV2._loadMaterial(index);
-            };
-            GLTFLoader.LoadCoreMaterial = function (index) {
-                return BABYLON.GLTFFileLoader.GLTFLoaderV2._loadCoreMaterial(index);
-            };
-            GLTFLoader.LoadCommonMaterialProperties = function (material) {
-                return BABYLON.GLTFFileLoader.GLTFLoaderV2._loadCommonMaterialProperties(material);
-            };
-            GLTFLoader.LoadAlphaProperties = function (material) {
-                return BABYLON.GLTFFileLoader.GLTFLoaderV2._loadAlphaProperties(material);
-            };
-            GLTFLoader.LoadTexture = function (textureInfo) {
-                return BABYLON.GLTFFileLoader.GLTFLoaderV2._loadTexture(textureInfo);
+                GLTFLoader.Extensions[extension.name] = extension;
+                // Keep the order of registration so that extensions registered first are called first.
+                GLTF2.GLTFLoaderExtension._Extensions.push(extension);
             };
             };
+            Object.defineProperty(GLTFLoader.prototype, "gltf", {
+                get: function () {
+                    return this._gltf;
+                },
+                enumerable: true,
+                configurable: true
+            });
+            Object.defineProperty(GLTFLoader.prototype, "babylonScene", {
+                get: function () {
+                    return this._babylonScene;
+                },
+                enumerable: true,
+                configurable: true
+            });
             GLTFLoader.prototype.importMeshAsync = function (meshesNames, scene, data, rootUrl, onSuccess, onError) {
             GLTFLoader.prototype.importMeshAsync = function (meshesNames, scene, data, rootUrl, onSuccess, onError) {
                 var _this = this;
                 var _this = this;
                 this._loadAsync(meshesNames, scene, data, rootUrl, function () {
                 this._loadAsync(meshesNames, scene, data, rootUrl, function () {
@@ -2493,28 +2494,34 @@ var BABYLON;
                 this._loadAsync(null, scene, data, rootUrl, onSuccess, onError);
                 this._loadAsync(null, scene, data, rootUrl, onSuccess, onError);
             };
             };
             GLTFLoader.prototype._loadAsync = function (nodeNames, scene, data, rootUrl, onSuccess, onError) {
             GLTFLoader.prototype._loadAsync = function (nodeNames, scene, data, rootUrl, onSuccess, onError) {
-                var _this = this;
                 scene.useRightHandedSystem = true;
                 scene.useRightHandedSystem = true;
                 this._clear();
                 this._clear();
                 this._loadData(data);
                 this._loadData(data);
                 this._babylonScene = scene;
                 this._babylonScene = scene;
                 this._rootUrl = rootUrl;
                 this._rootUrl = rootUrl;
-                this._onLoaded = function () {
-                    _this._showMeshes();
-                    _this._startAnimations();
-                    if (_this._errors.length === 0) {
-                        onSuccess();
-                    }
-                    else {
-                        _this._errors.forEach(function (error) { return BABYLON.Tools.Error(error); });
-                        onError();
-                    }
-                    _this._clear();
-                };
-                this._addPendingData(this);
+                this._onSuccess = onSuccess;
+                this._onError = onError;
+                this.addPendingData(this);
                 this._loadScene(nodeNames);
                 this._loadScene(nodeNames);
                 this._loadAnimations();
                 this._loadAnimations();
-                this._removePendingData(this);
+                this.removePendingData(this);
+            };
+            GLTFLoader.prototype._onRenderReady = function () {
+                this._showMeshes();
+                this._startAnimations();
+                if (this._errors.length === 0) {
+                    this._onSuccess();
+                }
+                else {
+                    this._errors.forEach(function (error) { return BABYLON.Tools.Error(error); });
+                    this._errors = [];
+                    this._onError();
+                }
+            };
+            GLTFLoader.prototype._onLoaderComplete = function () {
+                this._errors.forEach(function (error) { return BABYLON.Tools.Error(error); });
+                this._errors = [];
+                this._clear();
             };
             };
             GLTFLoader.prototype._loadData = function (data) {
             GLTFLoader.prototype._loadData = function (data) {
                 this._gltf = data.json;
                 this._gltf = data.json;
@@ -2557,13 +2564,6 @@ var BABYLON;
                 }
                 }
             };
             };
             GLTFLoader.prototype._clear = function () {
             GLTFLoader.prototype._clear = function () {
-                this._gltf = undefined;
-                this._pendingCount = 0;
-                this._onLoaded = undefined;
-                this._errors = [];
-                this._babylonScene = undefined;
-                this._rootUrl = undefined;
-                this._defaultMaterial = undefined;
                 // Revoke object urls created during load
                 // Revoke object urls created during load
                 if (this._gltf && this._gltf.textures) {
                 if (this._gltf && this._gltf.textures) {
                     for (var i = 0; i < this._gltf.textures.length; i++) {
                     for (var i = 0; i < this._gltf.textures.length; i++) {
@@ -2573,14 +2573,42 @@ var BABYLON;
                         }
                         }
                     }
                     }
                 }
                 }
+                this._gltf = undefined;
+                this._errors = [];
+                this._babylonScene = undefined;
+                this._rootUrl = undefined;
+                this._defaultMaterial = undefined;
+                this._onSuccess = undefined;
+                this._onError = undefined;
+                this._renderReady = false;
+                this._renderPendingCount = 0;
+                this._loaderPendingCount = 0;
             };
             };
             GLTFLoader.prototype._loadScene = function (nodeNames) {
             GLTFLoader.prototype._loadScene = function (nodeNames) {
                 var _this = this;
                 var _this = this;
-                nodeNames = (nodeNames === "") ? null : nodeNames;
-                nodeNames = (nodeNames instanceof Array) ? nodeNames : [nodeNames];
                 var scene = this._gltf.scenes[this._gltf.scene || 0];
                 var scene = this._gltf.scenes[this._gltf.scene || 0];
-                this._traverseScene(nodeNames, scene, function (node) { return _this._loadSkin(node); });
-                this._traverseScene(nodeNames, scene, function (node, parentNode) { return _this._loadMesh(node, parentNode); });
+                var nodeIndices = scene.nodes;
+                this._traverseNodes(nodeIndices, function (node, index, parentNode) {
+                    node.index = index;
+                    node.parent = parentNode;
+                    return true;
+                });
+                if (nodeNames) {
+                    if (!(nodeNames instanceof Array)) {
+                        nodeNames = [nodeNames];
+                    }
+                    var filteredNodeIndices = new Array();
+                    this._traverseNodes(nodeIndices, function (node) {
+                        if (nodeNames.indexOf(node.name) === -1) {
+                            return true;
+                        }
+                        filteredNodeIndices.push(node.index);
+                        return false;
+                    });
+                    nodeIndices = filteredNodeIndices;
+                }
+                this._traverseNodes(nodeIndices, function (node) { return _this._loadSkin(node); });
+                this._traverseNodes(nodeIndices, function (node) { return _this._loadMesh(node); });
             };
             };
             GLTFLoader.prototype._loadSkin = function (node) {
             GLTFLoader.prototype._loadSkin = function (node) {
                 var _this = this;
                 var _this = this;
@@ -2602,7 +2630,7 @@ var BABYLON;
                     }
                     }
                     var accessor = this._gltf.accessors[skin.inverseBindMatrices];
                     var accessor = this._gltf.accessors[skin.inverseBindMatrices];
                     this._loadAccessorAsync(accessor, function (data) {
                     this._loadAccessorAsync(accessor, function (data) {
-                        _this._traverseNode(null, skin.skeleton, function (node, parent) { return _this._updateBone(node, parent, skin, data); });
+                        _this._traverseNode(skin.skeleton, function (node, index, parent) { return _this._updateBone(node, parent, skin, data); });
                     });
                     });
                 }
                 }
                 return true;
                 return true;
@@ -2631,7 +2659,7 @@ var BABYLON;
                 node.babylonAnimationTargets.push(babylonBone);
                 node.babylonAnimationTargets.push(babylonBone);
                 return babylonBone;
                 return babylonBone;
             };
             };
-            GLTFLoader.prototype._loadMesh = function (node, parentNode) {
+            GLTFLoader.prototype._loadMesh = function (node) {
                 var babylonMesh = new BABYLON.Mesh(node.name || "mesh" + node.index, this._babylonScene);
                 var babylonMesh = new BABYLON.Mesh(node.name || "mesh" + node.index, this._babylonScene);
                 babylonMesh.isVisible = false;
                 babylonMesh.isVisible = false;
                 this._loadTransform(node, babylonMesh);
                 this._loadTransform(node, babylonMesh);
@@ -2639,7 +2667,7 @@ var BABYLON;
                     var mesh = this._gltf.meshes[node.mesh];
                     var mesh = this._gltf.meshes[node.mesh];
                     this._loadMeshData(node, mesh, babylonMesh);
                     this._loadMeshData(node, mesh, babylonMesh);
                 }
                 }
-                babylonMesh.parent = parentNode ? parentNode.babylonMesh : null;
+                babylonMesh.parent = node.parent ? node.parent.babylonMesh : null;
                 node.babylonMesh = babylonMesh;
                 node.babylonMesh = babylonMesh;
                 node.babylonAnimationTargets = node.babylonAnimationTargets || [];
                 node.babylonAnimationTargets = node.babylonAnimationTargets || [];
                 node.babylonAnimationTargets.push(node.babylonMesh);
                 node.babylonAnimationTargets.push(node.babylonMesh);
@@ -2655,17 +2683,16 @@ var BABYLON;
             GLTFLoader.prototype._loadMeshData = function (node, mesh, babylonMesh) {
             GLTFLoader.prototype._loadMeshData = function (node, mesh, babylonMesh) {
                 var _this = this;
                 var _this = this;
                 babylonMesh.name = mesh.name || babylonMesh.name;
                 babylonMesh.name = mesh.name || babylonMesh.name;
-                babylonMesh.subMeshes = [];
-                var multiMaterial = new BABYLON.MultiMaterial(babylonMesh.name, this._babylonScene);
-                babylonMesh.material = multiMaterial;
+                var babylonMultiMaterial = new BABYLON.MultiMaterial(babylonMesh.name, this._babylonScene);
+                babylonMesh.material = babylonMultiMaterial;
                 var geometry = new BABYLON.Geometry(babylonMesh.name, this._babylonScene, null, false, babylonMesh);
                 var geometry = new BABYLON.Geometry(babylonMesh.name, this._babylonScene, null, false, babylonMesh);
                 var vertexData = new BABYLON.VertexData();
                 var vertexData = new BABYLON.VertexData();
                 vertexData.positions = [];
                 vertexData.positions = [];
                 vertexData.indices = [];
                 vertexData.indices = [];
                 var subMeshInfos = [];
                 var subMeshInfos = [];
-                var primitivesLoaded = 0;
-                var numPrimitives = mesh.primitives.length;
-                var _loop_1 = function () {
+                var loadedPrimitives = 0;
+                var totalPrimitives = mesh.primitives.length;
+                var _loop_1 = function (i) {
                     var primitive = mesh.primitives[i];
                     var primitive = mesh.primitives[i];
                     if (primitive.mode && primitive.mode !== GLTF2.EMeshPrimitiveMode.TRIANGLES) {
                     if (primitive.mode && primitive.mode !== GLTF2.EMeshPrimitiveMode.TRIANGLES) {
                         // TODO: handle other primitive modes
                         // TODO: handle other primitive modes
@@ -2675,28 +2702,40 @@ var BABYLON;
                     this_1._loadVertexDataAsync(primitive, function (subVertexData) {
                     this_1._loadVertexDataAsync(primitive, function (subVertexData) {
                         _this._loadMorphTargetsData(mesh, primitive, subVertexData, babylonMesh);
                         _this._loadMorphTargetsData(mesh, primitive, subVertexData, babylonMesh);
                         subMeshInfos.push({
                         subMeshInfos.push({
-                            materialIndex: multiMaterial.subMaterials.length,
+                            materialIndex: i,
                             verticesStart: vertexData.positions.length,
                             verticesStart: vertexData.positions.length,
                             verticesCount: subVertexData.positions.length,
                             verticesCount: subVertexData.positions.length,
                             indicesStart: vertexData.indices.length,
                             indicesStart: vertexData.indices.length,
                             indicesCount: subVertexData.indices.length
                             indicesCount: subVertexData.indices.length
                         });
                         });
-                        var subMaterial = primitive.material === undefined ? _this._getDefaultMaterial() : GLTF2.GLTFLoaderExtension.LoadMaterial(primitive.material);
-                        multiMaterial.subMaterials.push(subMaterial);
                         vertexData.merge(subVertexData);
                         vertexData.merge(subVertexData);
-                        if (++primitivesLoaded === numPrimitives) {
+                        if (primitive.material === undefined) {
+                            babylonMultiMaterial.subMaterials[i] = _this._getDefaultMaterial();
+                        }
+                        else {
+                            _this.loadMaterial(primitive.material, function (babylonSubMaterial) {
+                                if (_this._renderReady) {
+                                    babylonSubMaterial.forceCompilation(babylonMesh, function (babylonSubMaterial) {
+                                        babylonMultiMaterial.subMaterials[i] = babylonSubMaterial;
+                                    });
+                                }
+                                else {
+                                    babylonMultiMaterial.subMaterials[i] = babylonSubMaterial;
+                                }
+                            });
+                        }
+                        if (++loadedPrimitives === totalPrimitives) {
                             geometry.setAllVerticesData(vertexData, false);
                             geometry.setAllVerticesData(vertexData, false);
-                            // Sub meshes must be created after setting vertex data because of mesh._createGlobalSubMesh.
-                            for (var i = 0; i < subMeshInfos.length; i++) {
-                                var info = subMeshInfos[i];
-                                new BABYLON.SubMesh(info.materialIndex, info.verticesStart, info.verticesCount, info.indicesStart, info.indicesCount, babylonMesh);
-                            }
+                            // TODO: optimize this so that sub meshes can be created without being overwritten after setting vertex data.
+                            // Sub meshes must be cleared and created after setting vertex data because of mesh._createGlobalSubMesh.
+                            babylonMesh.subMeshes = [];
+                            subMeshInfos.forEach(function (info) { return new BABYLON.SubMesh(info.materialIndex, info.verticesStart, info.verticesCount, info.indicesStart, info.indicesCount, babylonMesh); });
                         }
                         }
                     });
                     });
                 };
                 };
                 var this_1 = this;
                 var this_1 = this;
-                for (var i = 0; i < numPrimitives; i++) {
-                    _loop_1();
+                for (var i = 0; i < totalPrimitives; i++) {
+                    _loop_1(i);
                 }
                 }
             };
             };
             GLTFLoader.prototype._loadVertexDataAsync = function (primitive, onSuccess) {
             GLTFLoader.prototype._loadVertexDataAsync = function (primitive, onSuccess) {
@@ -2708,7 +2747,7 @@ var BABYLON;
                 }
                 }
                 var vertexData = new BABYLON.VertexData();
                 var vertexData = new BABYLON.VertexData();
                 var loadedAttributes = 0;
                 var loadedAttributes = 0;
-                var numAttributes = Object.keys(attributes).length;
+                var totalAttributes = Object.keys(attributes).length;
                 var _loop_2 = function (semantic) {
                 var _loop_2 = function (semantic) {
                     accessor = this_2._gltf.accessors[attributes[semantic]];
                     accessor = this_2._gltf.accessors[attributes[semantic]];
                     this_2._loadAccessorAsync(accessor, function (data) {
                     this_2._loadAccessorAsync(accessor, function (data) {
@@ -2741,7 +2780,7 @@ var BABYLON;
                                 BABYLON.Tools.Warn("Ignoring unrecognized semantic '" + semantic + "'");
                                 BABYLON.Tools.Warn("Ignoring unrecognized semantic '" + semantic + "'");
                                 break;
                                 break;
                         }
                         }
-                        if (++loadedAttributes === numAttributes) {
+                        if (++loadedAttributes === totalAttributes) {
                             var indicesAccessor = _this._gltf.accessors[primitive.indices];
                             var indicesAccessor = _this._gltf.accessors[primitive.indices];
                             if (indicesAccessor) {
                             if (indicesAccessor) {
                                 _this._loadAccessorAsync(indicesAccessor, function (data) {
                                 _this._loadAccessorAsync(indicesAccessor, function (data) {
@@ -2848,34 +2887,21 @@ var BABYLON;
                 babylonMesh.rotationQuaternion = rotation;
                 babylonMesh.rotationQuaternion = rotation;
                 babylonMesh.scaling = scaling;
                 babylonMesh.scaling = scaling;
             };
             };
-            GLTFLoader.prototype._traverseScene = function (nodeNames, scene, action) {
-                var nodes = scene.nodes;
-                if (nodes) {
-                    for (var i = 0; i < nodes.length; i++) {
-                        this._traverseNode(nodeNames, nodes[i], action);
-                    }
+            GLTFLoader.prototype._traverseNodes = function (indices, action, parentNode) {
+                if (parentNode === void 0) { parentNode = null; }
+                for (var i = 0; i < indices.length; i++) {
+                    this._traverseNode(indices[i], action, parentNode);
                 }
                 }
             };
             };
-            GLTFLoader.prototype._traverseNode = function (nodeNames, index, action, parentNode) {
+            GLTFLoader.prototype._traverseNode = function (index, action, parentNode) {
                 if (parentNode === void 0) { parentNode = null; }
                 if (parentNode === void 0) { parentNode = null; }
                 var node = this._gltf.nodes[index];
                 var node = this._gltf.nodes[index];
-                if (nodeNames) {
-                    if (nodeNames.indexOf(node.name)) {
-                        // load all children
-                        nodeNames = null;
-                    }
-                    else {
-                        // skip this node tree
-                        return;
-                    }
-                }
-                node.index = index;
-                if (!action(node, parentNode)) {
+                if (!action(node, index, parentNode)) {
                     return;
                     return;
                 }
                 }
                 if (node.children) {
                 if (node.children) {
                     for (var i = 0; i < node.children.length; i++) {
                     for (var i = 0; i < node.children.length; i++) {
-                        this._traverseNode(nodeNames, node.children[i], action, node);
+                        this._traverseNode(node.children[i], action, node);
                     }
                     }
                 }
                 }
             };
             };
@@ -3004,11 +3030,11 @@ var BABYLON;
             GLTFLoader.prototype._loadBufferAsync = function (index, onSuccess) {
             GLTFLoader.prototype._loadBufferAsync = function (index, onSuccess) {
                 var _this = this;
                 var _this = this;
                 var buffer = this._gltf.buffers[index];
                 var buffer = this._gltf.buffers[index];
-                this._addPendingData(buffer);
+                this.addPendingData(buffer);
                 if (buffer.loadedData) {
                 if (buffer.loadedData) {
                     setTimeout(function () {
                     setTimeout(function () {
                         onSuccess(buffer.loadedData);
                         onSuccess(buffer.loadedData);
-                        _this._removePendingData(buffer);
+                        _this.removePendingData(buffer);
                     });
                     });
                 }
                 }
                 else if (GLTF2.GLTFUtils.IsBase64(buffer.uri)) {
                 else if (GLTF2.GLTFUtils.IsBase64(buffer.uri)) {
@@ -3016,20 +3042,20 @@ var BABYLON;
                     buffer.loadedData = new Uint8Array(data);
                     buffer.loadedData = new Uint8Array(data);
                     setTimeout(function () {
                     setTimeout(function () {
                         onSuccess(buffer.loadedData);
                         onSuccess(buffer.loadedData);
-                        _this._removePendingData(buffer);
+                        _this.removePendingData(buffer);
                     });
                     });
                 }
                 }
                 else if (buffer.loadedObservable) {
                 else if (buffer.loadedObservable) {
                     buffer.loadedObservable.add(function (buffer) {
                     buffer.loadedObservable.add(function (buffer) {
                         onSuccess(buffer.loadedData);
                         onSuccess(buffer.loadedData);
-                        _this._removePendingData(buffer);
+                        _this.removePendingData(buffer);
                     });
                     });
                 }
                 }
                 else {
                 else {
                     buffer.loadedObservable = new BABYLON.Observable();
                     buffer.loadedObservable = new BABYLON.Observable();
                     buffer.loadedObservable.add(function (buffer) {
                     buffer.loadedObservable.add(function (buffer) {
                         onSuccess(buffer.loadedData);
                         onSuccess(buffer.loadedData);
-                        _this._removePendingData(buffer);
+                        _this.removePendingData(buffer);
                     });
                     });
                     BABYLON.Tools.LoadFile(this._rootUrl + buffer.uri, function (data) {
                     BABYLON.Tools.LoadFile(this._rootUrl + buffer.uri, function (data) {
                         buffer.loadedData = new Uint8Array(data);
                         buffer.loadedData = new Uint8Array(data);
@@ -3037,7 +3063,7 @@ var BABYLON;
                         buffer.loadedObservable = null;
                         buffer.loadedObservable = null;
                     }, null, null, true, function (request) {
                     }, null, null, true, function (request) {
                         _this._errors.push("Failed to load file '" + buffer.uri + "': " + request.statusText + "(" + request.status + ")");
                         _this._errors.push("Failed to load file '" + buffer.uri + "': " + request.statusText + "(" + request.status + ")");
-                        _this._removePendingData(buffer);
+                        _this.removePendingData(buffer);
                     });
                     });
                 }
                 }
             };
             };
@@ -3084,12 +3110,27 @@ var BABYLON;
                 var byteLength = accessor.count * GLTF2.GLTFUtils.GetByteStrideFromType(accessor);
                 var byteLength = accessor.count * GLTF2.GLTFUtils.GetByteStrideFromType(accessor);
                 this._loadBufferViewAsync(bufferView, byteOffset, byteLength, accessor.componentType, onSuccess);
                 this._loadBufferViewAsync(bufferView, byteOffset, byteLength, accessor.componentType, onSuccess);
             };
             };
-            GLTFLoader.prototype._addPendingData = function (data) {
-                this._pendingCount++;
+            GLTFLoader.prototype.addPendingData = function (data) {
+                if (!this._renderReady) {
+                    this._renderPendingCount++;
+                }
+                this.addLoaderPendingData(data);
+            };
+            GLTFLoader.prototype.removePendingData = function (data) {
+                if (!this._renderReady) {
+                    if (--this._renderPendingCount === 0) {
+                        this._renderReady = true;
+                        this._onRenderReady();
+                    }
+                }
+                this.removeLoaderPendingData(data);
+            };
+            GLTFLoader.prototype.addLoaderPendingData = function (data) {
+                this._loaderPendingCount++;
             };
             };
-            GLTFLoader.prototype._removePendingData = function (data) {
-                if (--this._pendingCount === 0) {
-                    this._onLoaded();
+            GLTFLoader.prototype.removeLoaderPendingData = function (data) {
+                if (--this._loaderPendingCount === 0) {
+                    this._onLoaderComplete();
                 }
                 }
             };
             };
             GLTFLoader.prototype._getDefaultMaterial = function () {
             GLTFLoader.prototype._getDefaultMaterial = function () {
@@ -3106,46 +3147,49 @@ var BABYLON;
                 }
                 }
                 return this._defaultMaterial;
                 return this._defaultMaterial;
             };
             };
-            GLTFLoader.prototype._loadMaterial = function (index) {
-                var materials = this._gltf.materials;
-                var material = materials ? materials[index] : null;
-                if (!material) {
-                    BABYLON.Tools.Warn("Material index (" + index + ") does not exist");
-                    return null;
-                }
-                material.babylonMaterial = new BABYLON.PBRMaterial(material.name || "mat" + index, this._babylonScene);
-                material.babylonMaterial.sideOrientation = BABYLON.Material.CounterClockWiseSideOrientation;
-                material.babylonMaterial.useScalarInLinearSpace = true;
-                return material;
-            };
-            GLTFLoader.prototype._loadCoreMaterial = function (index) {
-                var material = this._loadMaterial(index);
-                if (!material) {
-                    return null;
-                }
-                this._loadCommonMaterialProperties(material);
+            GLTFLoader.prototype._loadMaterialMetallicRoughnessProperties = function (material) {
                 // Ensure metallic workflow
                 // Ensure metallic workflow
                 material.babylonMaterial.metallic = 1;
                 material.babylonMaterial.metallic = 1;
                 material.babylonMaterial.roughness = 1;
                 material.babylonMaterial.roughness = 1;
                 var properties = material.pbrMetallicRoughness;
                 var properties = material.pbrMetallicRoughness;
-                if (properties) {
-                    material.babylonMaterial.albedoColor = properties.baseColorFactor ? BABYLON.Color3.FromArray(properties.baseColorFactor) : new BABYLON.Color3(1, 1, 1);
-                    material.babylonMaterial.metallic = properties.metallicFactor === undefined ? 1 : properties.metallicFactor;
-                    material.babylonMaterial.roughness = properties.roughnessFactor === undefined ? 1 : properties.roughnessFactor;
-                    if (properties.baseColorTexture) {
-                        material.babylonMaterial.albedoTexture = this._loadTexture(properties.baseColorTexture);
-                        this._loadAlphaProperties(material);
-                    }
-                    if (properties.metallicRoughnessTexture) {
-                        material.babylonMaterial.metallicTexture = this._loadTexture(properties.metallicRoughnessTexture);
-                        material.babylonMaterial.useMetallnessFromMetallicTextureBlue = true;
-                        material.babylonMaterial.useRoughnessFromMetallicTextureGreen = true;
-                        material.babylonMaterial.useRoughnessFromMetallicTextureAlpha = false;
-                    }
+                if (!properties) {
+                    return;
                 }
                 }
-                return material.babylonMaterial;
+                material.babylonMaterial.albedoColor = properties.baseColorFactor ? BABYLON.Color3.FromArray(properties.baseColorFactor) : new BABYLON.Color3(1, 1, 1);
+                material.babylonMaterial.metallic = properties.metallicFactor === undefined ? 1 : properties.metallicFactor;
+                material.babylonMaterial.roughness = properties.roughnessFactor === undefined ? 1 : properties.roughnessFactor;
+                if (properties.baseColorTexture) {
+                    material.babylonMaterial.albedoTexture = this.loadTexture(properties.baseColorTexture);
+                    this.loadMaterialAlphaProperties(material);
+                }
+                if (properties.metallicRoughnessTexture) {
+                    material.babylonMaterial.metallicTexture = this.loadTexture(properties.metallicRoughnessTexture);
+                    material.babylonMaterial.useMetallnessFromMetallicTextureBlue = true;
+                    material.babylonMaterial.useRoughnessFromMetallicTextureGreen = true;
+                    material.babylonMaterial.useRoughnessFromMetallicTextureAlpha = false;
+                }
+            };
+            GLTFLoader.prototype.loadMaterial = function (index, assign) {
+                var material = this._gltf.materials[index];
+                material.index = index;
+                if (material.babylonMaterial) {
+                    assign(material.babylonMaterial);
+                    return;
+                }
+                if (GLTF2.GLTFLoaderExtension.LoadMaterial(this, material, assign)) {
+                    return;
+                }
+                this.createPbrMaterial(material);
+                this.loadMaterialBaseProperties(material);
+                this._loadMaterialMetallicRoughnessProperties(material);
+                assign(material.babylonMaterial);
+            };
+            GLTFLoader.prototype.createPbrMaterial = function (material) {
+                material.babylonMaterial = new BABYLON.PBRMaterial(material.name || "mat" + material.index, this._babylonScene);
+                material.babylonMaterial.sideOrientation = BABYLON.Material.CounterClockWiseSideOrientation;
+                material.babylonMaterial.useScalarInLinearSpace = true;
             };
             };
-            GLTFLoader.prototype._loadCommonMaterialProperties = function (material) {
+            GLTFLoader.prototype.loadMaterialBaseProperties = function (material) {
                 material.babylonMaterial.useEmissiveAsIllumination = (material.emissiveFactor || material.emissiveTexture) ? true : false;
                 material.babylonMaterial.useEmissiveAsIllumination = (material.emissiveFactor || material.emissiveTexture) ? true : false;
                 material.babylonMaterial.emissiveColor = material.emissiveFactor ? BABYLON.Color3.FromArray(material.emissiveFactor) : new BABYLON.Color3(0, 0, 0);
                 material.babylonMaterial.emissiveColor = material.emissiveFactor ? BABYLON.Color3.FromArray(material.emissiveFactor) : new BABYLON.Color3(0, 0, 0);
                 if (material.doubleSided) {
                 if (material.doubleSided) {
@@ -3153,23 +3197,23 @@ var BABYLON;
                     material.babylonMaterial.twoSidedLighting = true;
                     material.babylonMaterial.twoSidedLighting = true;
                 }
                 }
                 if (material.normalTexture) {
                 if (material.normalTexture) {
-                    material.babylonMaterial.bumpTexture = this._loadTexture(material.normalTexture);
+                    material.babylonMaterial.bumpTexture = this.loadTexture(material.normalTexture);
                     if (material.normalTexture.scale !== undefined) {
                     if (material.normalTexture.scale !== undefined) {
                         material.babylonMaterial.bumpTexture.level = material.normalTexture.scale;
                         material.babylonMaterial.bumpTexture.level = material.normalTexture.scale;
                     }
                     }
                 }
                 }
                 if (material.occlusionTexture) {
                 if (material.occlusionTexture) {
-                    material.babylonMaterial.ambientTexture = this._loadTexture(material.occlusionTexture);
+                    material.babylonMaterial.ambientTexture = this.loadTexture(material.occlusionTexture);
                     material.babylonMaterial.useAmbientInGrayScale = true;
                     material.babylonMaterial.useAmbientInGrayScale = true;
                     if (material.occlusionTexture.strength !== undefined) {
                     if (material.occlusionTexture.strength !== undefined) {
                         material.babylonMaterial.ambientTextureStrength = material.occlusionTexture.strength;
                         material.babylonMaterial.ambientTextureStrength = material.occlusionTexture.strength;
                     }
                     }
                 }
                 }
                 if (material.emissiveTexture) {
                 if (material.emissiveTexture) {
-                    material.babylonMaterial.emissiveTexture = this._loadTexture(material.emissiveTexture);
+                    material.babylonMaterial.emissiveTexture = this.loadTexture(material.emissiveTexture);
                 }
                 }
             };
             };
-            GLTFLoader.prototype._loadAlphaProperties = function (material) {
+            GLTFLoader.prototype.loadMaterialAlphaProperties = function (material) {
                 var alphaMode = material.alphaMode || "OPAQUE";
                 var alphaMode = material.alphaMode || "OPAQUE";
                 switch (alphaMode) {
                 switch (alphaMode) {
                     case "OPAQUE":
                     case "OPAQUE":
@@ -3178,18 +3222,17 @@ var BABYLON;
                     case "MASK":
                     case "MASK":
                         material.babylonMaterial.albedoTexture.hasAlpha = true;
                         material.babylonMaterial.albedoTexture.hasAlpha = true;
                         material.babylonMaterial.useAlphaFromAlbedoTexture = false;
                         material.babylonMaterial.useAlphaFromAlbedoTexture = false;
-                        material.babylonMaterial.alphaMode = BABYLON.Engine.ALPHA_DISABLE;
                         break;
                         break;
                     case "BLEND":
                     case "BLEND":
                         material.babylonMaterial.albedoTexture.hasAlpha = true;
                         material.babylonMaterial.albedoTexture.hasAlpha = true;
                         material.babylonMaterial.useAlphaFromAlbedoTexture = true;
                         material.babylonMaterial.useAlphaFromAlbedoTexture = true;
-                        material.babylonMaterial.alphaMode = BABYLON.Engine.ALPHA_COMBINE;
                         break;
                         break;
                     default:
                     default:
-                        BABYLON.Tools.Error("Invalid alpha mode '" + material.alphaMode + "'");
+                        BABYLON.Tools.Warn("Invalid alpha mode '" + material.alphaMode + "'");
+                        break;
                 }
                 }
             };
             };
-            GLTFLoader.prototype._loadTexture = function (textureInfo) {
+            GLTFLoader.prototype.loadTexture = function (textureInfo) {
                 var _this = this;
                 var _this = this;
                 var texture = this._gltf.textures[textureInfo.index];
                 var texture = this._gltf.textures[textureInfo.index];
                 var texCoord = textureInfo.texCoord || 0;
                 var texCoord = textureInfo.texCoord || 0;
@@ -3232,12 +3275,12 @@ var BABYLON;
                 var sampler = (texture.sampler === undefined ? {} : this._gltf.samplers[texture.sampler]);
                 var sampler = (texture.sampler === undefined ? {} : this._gltf.samplers[texture.sampler]);
                 var noMipMaps = (sampler.minFilter === GLTF2.ETextureMinFilter.NEAREST || sampler.minFilter === GLTF2.ETextureMinFilter.LINEAR);
                 var noMipMaps = (sampler.minFilter === GLTF2.ETextureMinFilter.NEAREST || sampler.minFilter === GLTF2.ETextureMinFilter.LINEAR);
                 var samplingMode = GLTF2.GLTFUtils.GetTextureFilterMode(sampler.minFilter);
                 var samplingMode = GLTF2.GLTFUtils.GetTextureFilterMode(sampler.minFilter);
-                this._addPendingData(texture);
+                this.addPendingData(texture);
                 var babylonTexture = new BABYLON.Texture(url, this._babylonScene, noMipMaps, false, samplingMode, function () {
                 var babylonTexture = new BABYLON.Texture(url, this._babylonScene, noMipMaps, false, samplingMode, function () {
-                    _this._removePendingData(texture);
+                    _this.removePendingData(texture);
                 }, function () {
                 }, function () {
                     _this._errors.push("Failed to load texture '" + source.uri + "'");
                     _this._errors.push("Failed to load texture '" + source.uri + "'");
-                    _this._removePendingData(texture);
+                    _this.removePendingData(texture);
                 });
                 });
                 babylonTexture.coordinatesIndex = texCoord;
                 babylonTexture.coordinatesIndex = texCoord;
                 babylonTexture.wrapU = GLTF2.GLTFUtils.GetWrapMode(sampler.wrapS);
                 babylonTexture.wrapU = GLTF2.GLTFUtils.GetWrapMode(sampler.wrapS);
@@ -3358,42 +3401,39 @@ var BABYLON;
     var GLTF2;
     var GLTF2;
     (function (GLTF2) {
     (function (GLTF2) {
         var GLTFLoaderExtension = (function () {
         var GLTFLoaderExtension = (function () {
-            function GLTFLoaderExtension(name) {
+            function GLTFLoaderExtension() {
                 this.enabled = true;
                 this.enabled = true;
-                this._name = name;
             }
             }
-            Object.defineProperty(GLTFLoaderExtension.prototype, "name", {
-                get: function () {
-                    return this._name;
-                },
-                enumerable: true,
-                configurable: true
-            });
-            GLTFLoaderExtension.prototype.loadMaterial = function (index) { return null; };
-            // ---------
-            // Utilities
-            // ---------
-            GLTFLoaderExtension.LoadMaterial = function (index) {
-                for (var extensionName in GLTF2.GLTFLoader.Extensions) {
-                    var extension = GLTF2.GLTFLoader.Extensions[extensionName];
-                    if (extension.enabled) {
-                        var babylonMaterial = extension.loadMaterial(index);
-                        if (babylonMaterial) {
-                            return babylonMaterial;
-                        }
+            GLTFLoaderExtension.prototype.loadMaterial = function (loader, material, assign) { return false; };
+            GLTFLoaderExtension.LoadMaterial = function (loader, material, assign) {
+                return this._ApplyExtensions(function (extension) { return extension.loadMaterial(loader, material, assign); });
+            };
+            GLTFLoaderExtension._ApplyExtensions = function (action) {
+                var extensions = GLTFLoaderExtension._Extensions;
+                if (!extensions) {
+                    return;
+                }
+                for (var i = 0; i < extensions.length; i++) {
+                    var extension = extensions[i];
+                    if (extension.enabled && action(extension)) {
+                        return true;
                     }
                     }
                 }
                 }
-                return GLTF2.GLTFLoader.LoadCoreMaterial(index);
+                return false;
             };
             };
             return GLTFLoaderExtension;
             return GLTFLoaderExtension;
         }());
         }());
+        //
+        // Utilities
+        //
+        GLTFLoaderExtension._Extensions = [];
         GLTF2.GLTFLoaderExtension = GLTFLoaderExtension;
         GLTF2.GLTFLoaderExtension = GLTFLoaderExtension;
     })(GLTF2 = BABYLON.GLTF2 || (BABYLON.GLTF2 = {}));
     })(GLTF2 = BABYLON.GLTF2 || (BABYLON.GLTF2 = {}));
 })(BABYLON || (BABYLON = {}));
 })(BABYLON || (BABYLON = {}));
 
 
 //# sourceMappingURL=babylon.glTFLoaderExtension.js.map
 //# sourceMappingURL=babylon.glTFLoaderExtension.js.map
 
 
-/// <reference path="../../../../dist/preview release/babylon.d.ts"/>
+/// <reference path="../../../../../dist/preview release/babylon.d.ts"/>
 var __extends = (this && this.__extends) || (function () {
 var __extends = (this && this.__extends) || (function () {
     var extendStatics = Object.setPrototypeOf ||
     var extendStatics = Object.setPrototypeOf ||
         ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
         ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
@@ -3408,43 +3448,122 @@ var BABYLON;
 (function (BABYLON) {
 (function (BABYLON) {
     var GLTF2;
     var GLTF2;
     (function (GLTF2) {
     (function (GLTF2) {
-        var GLTFMaterialsPbrSpecularGlossinessExtension = (function (_super) {
-            __extends(GLTFMaterialsPbrSpecularGlossinessExtension, _super);
-            function GLTFMaterialsPbrSpecularGlossinessExtension() {
-                return _super.call(this, "KHR_materials_pbrSpecularGlossiness") || this;
-            }
-            GLTFMaterialsPbrSpecularGlossinessExtension.prototype.loadMaterial = function (index) {
-                var material = GLTF2.GLTFLoader.LoadMaterial(index);
-                if (!material || !material.extensions)
-                    return null;
-                var properties = material.extensions[this.name];
-                if (!properties)
-                    return null;
-                GLTF2.GLTFLoader.LoadCommonMaterialProperties(material);
-                //
-                // Load Factors
-                //
-                material.babylonMaterial.albedoColor = properties.diffuseFactor ? BABYLON.Color3.FromArray(properties.diffuseFactor) : new BABYLON.Color3(1, 1, 1);
-                material.babylonMaterial.reflectivityColor = properties.specularFactor ? BABYLON.Color3.FromArray(properties.specularFactor) : new BABYLON.Color3(1, 1, 1);
-                material.babylonMaterial.microSurface = properties.glossinessFactor === undefined ? 1 : properties.glossinessFactor;
-                //
-                // Load Textures
-                //
-                if (properties.diffuseTexture) {
-                    material.babylonMaterial.albedoTexture = GLTF2.GLTFLoader.LoadTexture(properties.diffuseTexture);
-                    GLTF2.GLTFLoader.LoadAlphaProperties(material);
-                }
-                if (properties.specularGlossinessTexture) {
-                    material.babylonMaterial.reflectivityTexture = GLTF2.GLTFLoader.LoadTexture(properties.specularGlossinessTexture);
-                    material.babylonMaterial.useMicroSurfaceFromReflectivityMapAlpha = true;
-                }
-                return material.babylonMaterial;
-            };
-            return GLTFMaterialsPbrSpecularGlossinessExtension;
-        }(GLTF2.GLTFLoaderExtension));
-        GLTF2.GLTFMaterialsPbrSpecularGlossinessExtension = GLTFMaterialsPbrSpecularGlossinessExtension;
-        GLTF2.GLTFLoader.RegisterExtension(new GLTFMaterialsPbrSpecularGlossinessExtension());
+        var Extensions;
+        (function (Extensions) {
+            var MSFTLOD = (function (_super) {
+                __extends(MSFTLOD, _super);
+                function MSFTLOD() {
+                    return _super !== null && _super.apply(this, arguments) || this;
+                }
+                Object.defineProperty(MSFTLOD.prototype, "name", {
+                    get: function () {
+                        return "MSFT_lod";
+                    },
+                    enumerable: true,
+                    configurable: true
+                });
+                MSFTLOD.prototype.loadMaterial = function (loader, material, assign) {
+                    if (!material.extensions) {
+                        return false;
+                    }
+                    var properties = material.extensions[this.name];
+                    if (!properties) {
+                        return false;
+                    }
+                    // Clear out the extension so that it won't get loaded again.
+                    material.extensions[this.name] = undefined;
+                    // Tell the loader not to clear its state until the highest LOD is loaded.
+                    loader.addLoaderPendingData(material);
+                    // Start with the lowest quality LOD.
+                    var materialLODs = [material.index].concat(properties.ids);
+                    this.loadMaterialLOD(loader, material, materialLODs, materialLODs.length - 1, assign);
+                    return true;
+                };
+                MSFTLOD.prototype.loadMaterialLOD = function (loader, material, materialLODs, lod, assign) {
+                    var _this = this;
+                    loader.loadMaterial(materialLODs[lod], function (babylonMaterial) {
+                        babylonMaterial.name += ".LOD" + lod;
+                        assign(babylonMaterial);
+                        // Loading is complete if this is the highest quality LOD.
+                        if (lod === 0) {
+                            loader.removeLoaderPendingData(material);
+                            return;
+                        }
+                        // Load the next LOD when all of the textures are loaded.
+                        BABYLON.BaseTexture.WhenAllReady(babylonMaterial.getActiveTextures(), function () {
+                            _this.loadMaterialLOD(loader, material, materialLODs, lod - 1, assign);
+                        });
+                    });
+                };
+                return MSFTLOD;
+            }(GLTF2.GLTFLoaderExtension));
+            Extensions.MSFTLOD = MSFTLOD;
+            GLTF2.GLTFLoader.RegisterExtension(new MSFTLOD());
+        })(Extensions = GLTF2.Extensions || (GLTF2.Extensions = {}));
+    })(GLTF2 = BABYLON.GLTF2 || (BABYLON.GLTF2 = {}));
+})(BABYLON || (BABYLON = {}));
+
+//# sourceMappingURL=MSFT_lod.js.map
+
+/// <reference path="../../../../../dist/preview release/babylon.d.ts"/>
+var __extends = (this && this.__extends) || (function () {
+    var extendStatics = Object.setPrototypeOf ||
+        ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
+        function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
+    return function (d, b) {
+        extendStatics(d, b);
+        function __() { this.constructor = d; }
+        d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
+    };
+})();
+var BABYLON;
+(function (BABYLON) {
+    var GLTF2;
+    (function (GLTF2) {
+        var Extensions;
+        (function (Extensions) {
+            var KHRMaterialsPbrSpecularGlossiness = (function (_super) {
+                __extends(KHRMaterialsPbrSpecularGlossiness, _super);
+                function KHRMaterialsPbrSpecularGlossiness() {
+                    return _super !== null && _super.apply(this, arguments) || this;
+                }
+                Object.defineProperty(KHRMaterialsPbrSpecularGlossiness.prototype, "name", {
+                    get: function () {
+                        return "KHR_materials_pbrSpecularGlossiness";
+                    },
+                    enumerable: true,
+                    configurable: true
+                });
+                KHRMaterialsPbrSpecularGlossiness.prototype.loadMaterial = function (loader, material, assign) {
+                    if (!material.extensions) {
+                        return false;
+                    }
+                    var properties = material.extensions[this.name];
+                    if (!properties) {
+                        return false;
+                    }
+                    loader.createPbrMaterial(material);
+                    loader.loadMaterialBaseProperties(material);
+                    material.babylonMaterial.albedoColor = properties.diffuseFactor ? BABYLON.Color3.FromArray(properties.diffuseFactor) : new BABYLON.Color3(1, 1, 1);
+                    material.babylonMaterial.reflectivityColor = properties.specularFactor ? BABYLON.Color3.FromArray(properties.specularFactor) : new BABYLON.Color3(1, 1, 1);
+                    material.babylonMaterial.microSurface = properties.glossinessFactor === undefined ? 1 : properties.glossinessFactor;
+                    if (properties.diffuseTexture) {
+                        material.babylonMaterial.albedoTexture = loader.loadTexture(properties.diffuseTexture);
+                        loader.loadMaterialAlphaProperties(material);
+                    }
+                    if (properties.specularGlossinessTexture) {
+                        material.babylonMaterial.reflectivityTexture = loader.loadTexture(properties.specularGlossinessTexture);
+                        material.babylonMaterial.useMicroSurfaceFromReflectivityMapAlpha = true;
+                    }
+                    assign(material.babylonMaterial);
+                    return true;
+                };
+                return KHRMaterialsPbrSpecularGlossiness;
+            }(GLTF2.GLTFLoaderExtension));
+            Extensions.KHRMaterialsPbrSpecularGlossiness = KHRMaterialsPbrSpecularGlossiness;
+            GLTF2.GLTFLoader.RegisterExtension(new KHRMaterialsPbrSpecularGlossiness());
+        })(Extensions = GLTF2.Extensions || (GLTF2.Extensions = {}));
     })(GLTF2 = BABYLON.GLTF2 || (BABYLON.GLTF2 = {}));
     })(GLTF2 = BABYLON.GLTF2 || (BABYLON.GLTF2 = {}));
 })(BABYLON || (BABYLON = {}));
 })(BABYLON || (BABYLON = {}));
 
 
-//# sourceMappingURL=babylon.glTFMaterialsPbrSpecularGlossinessExtension.js.map
+//# sourceMappingURL=KHR_materials_pbrSpecularGlossiness.js.map

文件差异内容过多而无法显示
+ 2 - 7
dist/preview release/loaders/babylon.glTFFileLoader.min.js


文件差异内容过多而无法显示
+ 1 - 5
dist/preview release/loaders/babylon.objFileLoader.min.js


+ 1 - 0
dist/preview release/materialsLibrary/babylon.cellMaterial.d.ts

@@ -20,6 +20,7 @@ declare module BABYLON {
         isReadyForSubMesh(mesh: AbstractMesh, subMesh: SubMesh, useInstances?: boolean): boolean;
         isReadyForSubMesh(mesh: AbstractMesh, subMesh: SubMesh, useInstances?: boolean): boolean;
         bindForSubMesh(world: Matrix, mesh: Mesh, subMesh: SubMesh): void;
         bindForSubMesh(world: Matrix, mesh: Mesh, subMesh: SubMesh): void;
         getAnimatables(): IAnimatable[];
         getAnimatables(): IAnimatable[];
+        getActiveTextures(): BaseTexture[];
         dispose(forceDisposeEffect?: boolean): void;
         dispose(forceDisposeEffect?: boolean): void;
         clone(name: string): CellMaterial;
         clone(name: string): CellMaterial;
         serialize(): any;
         serialize(): any;

+ 7 - 0
dist/preview release/materialsLibrary/babylon.cellMaterial.js

@@ -220,6 +220,13 @@ var BABYLON;
             }
             }
             return results;
             return results;
         };
         };
+        CellMaterial.prototype.getActiveTextures = function () {
+            var activeTextures = _super.prototype.getActiveTextures.call(this);
+            if (this._diffuseTexture) {
+                activeTextures.push(this._diffuseTexture);
+            }
+            return activeTextures;
+        };
         CellMaterial.prototype.dispose = function (forceDisposeEffect) {
         CellMaterial.prototype.dispose = function (forceDisposeEffect) {
             if (this._diffuseTexture) {
             if (this._diffuseTexture) {
                 this._diffuseTexture.dispose();
                 this._diffuseTexture.dispose();

文件差异内容过多而无法显示
+ 1 - 1
dist/preview release/materialsLibrary/babylon.cellMaterial.min.js


文件差异内容过多而无法显示
+ 1 - 1
dist/preview release/materialsLibrary/babylon.customMaterial.min.js


+ 1 - 0
dist/preview release/materialsLibrary/babylon.fireMaterial.d.ts

@@ -19,6 +19,7 @@ declare module BABYLON {
         isReadyForSubMesh(mesh: AbstractMesh, subMesh: SubMesh, useInstances?: boolean): boolean;
         isReadyForSubMesh(mesh: AbstractMesh, subMesh: SubMesh, useInstances?: boolean): boolean;
         bindForSubMesh(world: Matrix, mesh: Mesh, subMesh: SubMesh): void;
         bindForSubMesh(world: Matrix, mesh: Mesh, subMesh: SubMesh): void;
         getAnimatables(): IAnimatable[];
         getAnimatables(): IAnimatable[];
+        getActiveTextures(): BaseTexture[];
         dispose(forceDisposeEffect?: boolean): void;
         dispose(forceDisposeEffect?: boolean): void;
         clone(name: string): FireMaterial;
         clone(name: string): FireMaterial;
         serialize(): any;
         serialize(): any;

+ 13 - 0
dist/preview release/materialsLibrary/babylon.fireMaterial.js

@@ -209,6 +209,19 @@ var BABYLON;
             }
             }
             return results;
             return results;
         };
         };
+        FireMaterial.prototype.getActiveTextures = function () {
+            var activeTextures = _super.prototype.getActiveTextures.call(this);
+            if (this._diffuseTexture) {
+                activeTextures.push(this._diffuseTexture);
+            }
+            if (this._distortionTexture) {
+                activeTextures.push(this._distortionTexture);
+            }
+            if (this._opacityTexture) {
+                activeTextures.push(this._opacityTexture);
+            }
+            return activeTextures;
+        };
         FireMaterial.prototype.dispose = function (forceDisposeEffect) {
         FireMaterial.prototype.dispose = function (forceDisposeEffect) {
             if (this._diffuseTexture) {
             if (this._diffuseTexture) {
                 this._diffuseTexture.dispose();
                 this._diffuseTexture.dispose();

文件差异内容过多而无法显示
+ 1 - 1
dist/preview release/materialsLibrary/babylon.fireMaterial.min.js


+ 1 - 0
dist/preview release/materialsLibrary/babylon.furMaterial.d.ts

@@ -33,6 +33,7 @@ declare module BABYLON {
         isReadyForSubMesh(mesh: AbstractMesh, subMesh: SubMesh, useInstances?: boolean): boolean;
         isReadyForSubMesh(mesh: AbstractMesh, subMesh: SubMesh, useInstances?: boolean): boolean;
         bindForSubMesh(world: Matrix, mesh: Mesh, subMesh: SubMesh): void;
         bindForSubMesh(world: Matrix, mesh: Mesh, subMesh: SubMesh): void;
         getAnimatables(): IAnimatable[];
         getAnimatables(): IAnimatable[];
+        getActiveTextures(): BaseTexture[];
         dispose(forceDisposeEffect?: boolean): void;
         dispose(forceDisposeEffect?: boolean): void;
         clone(name: string): FurMaterial;
         clone(name: string): FurMaterial;
         serialize(): any;
         serialize(): any;

+ 10 - 0
dist/preview release/materialsLibrary/babylon.furMaterial.js

@@ -285,6 +285,16 @@ var BABYLON;
             }
             }
             return results;
             return results;
         };
         };
+        FurMaterial.prototype.getActiveTextures = function () {
+            var activeTextures = _super.prototype.getActiveTextures.call(this);
+            if (this._diffuseTexture) {
+                activeTextures.push(this._diffuseTexture);
+            }
+            if (this._heightTexture) {
+                activeTextures.push(this._heightTexture);
+            }
+            return activeTextures;
+        };
         FurMaterial.prototype.dispose = function (forceDisposeEffect) {
         FurMaterial.prototype.dispose = function (forceDisposeEffect) {
             if (this.diffuseTexture) {
             if (this.diffuseTexture) {
                 this.diffuseTexture.dispose();
                 this.diffuseTexture.dispose();

文件差异内容过多而无法显示
+ 1 - 1
dist/preview release/materialsLibrary/babylon.furMaterial.min.js


+ 1 - 0
dist/preview release/materialsLibrary/babylon.lavaMaterial.d.ts

@@ -25,6 +25,7 @@ declare module BABYLON {
         isReadyForSubMesh(mesh: AbstractMesh, subMesh: SubMesh, useInstances?: boolean): boolean;
         isReadyForSubMesh(mesh: AbstractMesh, subMesh: SubMesh, useInstances?: boolean): boolean;
         bindForSubMesh(world: Matrix, mesh: Mesh, subMesh: SubMesh): void;
         bindForSubMesh(world: Matrix, mesh: Mesh, subMesh: SubMesh): void;
         getAnimatables(): IAnimatable[];
         getAnimatables(): IAnimatable[];
+        getActiveTextures(): BaseTexture[];
         dispose(forceDisposeEffect?: boolean): void;
         dispose(forceDisposeEffect?: boolean): void;
         clone(name: string): LavaMaterial;
         clone(name: string): LavaMaterial;
         serialize(): any;
         serialize(): any;

+ 7 - 0
dist/preview release/materialsLibrary/babylon.lavaMaterial.js

@@ -271,6 +271,13 @@ var BABYLON;
             }
             }
             return results;
             return results;
         };
         };
+        LavaMaterial.prototype.getActiveTextures = function () {
+            var activeTextures = _super.prototype.getActiveTextures.call(this);
+            if (this._diffuseTexture) {
+                activeTextures.push(this._diffuseTexture);
+            }
+            return activeTextures;
+        };
         LavaMaterial.prototype.dispose = function (forceDisposeEffect) {
         LavaMaterial.prototype.dispose = function (forceDisposeEffect) {
             if (this.diffuseTexture) {
             if (this.diffuseTexture) {
                 this.diffuseTexture.dispose();
                 this.diffuseTexture.dispose();

文件差异内容过多而无法显示
+ 1 - 1
dist/preview release/materialsLibrary/babylon.lavaMaterial.min.js


+ 1 - 0
dist/preview release/materialsLibrary/babylon.normalMaterial.d.ts

@@ -18,6 +18,7 @@ declare module BABYLON {
         isReadyForSubMesh(mesh: AbstractMesh, subMesh: SubMesh, useInstances?: boolean): boolean;
         isReadyForSubMesh(mesh: AbstractMesh, subMesh: SubMesh, useInstances?: boolean): boolean;
         bindForSubMesh(world: Matrix, mesh: Mesh, subMesh: SubMesh): void;
         bindForSubMesh(world: Matrix, mesh: Mesh, subMesh: SubMesh): void;
         getAnimatables(): IAnimatable[];
         getAnimatables(): IAnimatable[];
+        getActiveTextures(): BaseTexture[];
         dispose(forceDisposeEffect?: boolean): void;
         dispose(forceDisposeEffect?: boolean): void;
         clone(name: string): NormalMaterial;
         clone(name: string): NormalMaterial;
         serialize(): any;
         serialize(): any;

+ 7 - 0
dist/preview release/materialsLibrary/babylon.normalMaterial.js

@@ -247,6 +247,13 @@ var BABYLON;
             }
             }
             return results;
             return results;
         };
         };
+        NormalMaterial.prototype.getActiveTextures = function () {
+            var activeTextures = _super.prototype.getActiveTextures.call(this);
+            if (this._diffuseTexture) {
+                activeTextures.push(this._diffuseTexture);
+            }
+            return activeTextures;
+        };
         NormalMaterial.prototype.dispose = function (forceDisposeEffect) {
         NormalMaterial.prototype.dispose = function (forceDisposeEffect) {
             if (this.diffuseTexture) {
             if (this.diffuseTexture) {
                 this.diffuseTexture.dispose();
                 this.diffuseTexture.dispose();

文件差异内容过多而无法显示
+ 1 - 1
dist/preview release/materialsLibrary/babylon.normalMaterial.min.js


+ 1 - 0
dist/preview release/materialsLibrary/babylon.simpleMaterial.d.ts

@@ -18,6 +18,7 @@ declare module BABYLON {
         isReadyForSubMesh(mesh: AbstractMesh, subMesh: SubMesh, useInstances?: boolean): boolean;
         isReadyForSubMesh(mesh: AbstractMesh, subMesh: SubMesh, useInstances?: boolean): boolean;
         bindForSubMesh(world: Matrix, mesh: Mesh, subMesh: SubMesh): void;
         bindForSubMesh(world: Matrix, mesh: Mesh, subMesh: SubMesh): void;
         getAnimatables(): IAnimatable[];
         getAnimatables(): IAnimatable[];
+        getActiveTextures(): BaseTexture[];
         dispose(forceDisposeEffect?: boolean): void;
         dispose(forceDisposeEffect?: boolean): void;
         clone(name: string): SimpleMaterial;
         clone(name: string): SimpleMaterial;
         serialize(): any;
         serialize(): any;

+ 7 - 0
dist/preview release/materialsLibrary/babylon.simpleMaterial.js

@@ -214,6 +214,13 @@ var BABYLON;
             }
             }
             return results;
             return results;
         };
         };
+        SimpleMaterial.prototype.getActiveTextures = function () {
+            var activeTextures = _super.prototype.getActiveTextures.call(this);
+            if (this._diffuseTexture) {
+                activeTextures.push(this._diffuseTexture);
+            }
+            return activeTextures;
+        };
         SimpleMaterial.prototype.dispose = function (forceDisposeEffect) {
         SimpleMaterial.prototype.dispose = function (forceDisposeEffect) {
             if (this._diffuseTexture) {
             if (this._diffuseTexture) {
                 this._diffuseTexture.dispose();
                 this._diffuseTexture.dispose();

文件差异内容过多而无法显示
+ 1 - 1
dist/preview release/materialsLibrary/babylon.simpleMaterial.min.js


+ 1 - 0
dist/preview release/materialsLibrary/babylon.terrainMaterial.d.ts

@@ -31,6 +31,7 @@ declare module BABYLON {
         isReadyForSubMesh(mesh: AbstractMesh, subMesh: SubMesh, useInstances?: boolean): boolean;
         isReadyForSubMesh(mesh: AbstractMesh, subMesh: SubMesh, useInstances?: boolean): boolean;
         bindForSubMesh(world: Matrix, mesh: Mesh, subMesh: SubMesh): void;
         bindForSubMesh(world: Matrix, mesh: Mesh, subMesh: SubMesh): void;
         getAnimatables(): IAnimatable[];
         getAnimatables(): IAnimatable[];
+        getActiveTextures(): BaseTexture[];
         dispose(forceDisposeEffect?: boolean): void;
         dispose(forceDisposeEffect?: boolean): void;
         clone(name: string): TerrainMaterial;
         clone(name: string): TerrainMaterial;
         serialize(): any;
         serialize(): any;

+ 25 - 0
dist/preview release/materialsLibrary/babylon.terrainMaterial.js

@@ -250,6 +250,31 @@ var BABYLON;
             }
             }
             return results;
             return results;
         };
         };
+        TerrainMaterial.prototype.getActiveTextures = function () {
+            var activeTextures = _super.prototype.getActiveTextures.call(this);
+            if (this._mixTexture) {
+                activeTextures.push(this._mixTexture);
+            }
+            if (this._diffuseTexture1) {
+                activeTextures.push(this._diffuseTexture1);
+            }
+            if (this._diffuseTexture2) {
+                activeTextures.push(this._diffuseTexture2);
+            }
+            if (this._diffuseTexture3) {
+                activeTextures.push(this._diffuseTexture3);
+            }
+            if (this._bumpTexture1) {
+                activeTextures.push(this._bumpTexture1);
+            }
+            if (this._bumpTexture2) {
+                activeTextures.push(this._bumpTexture2);
+            }
+            if (this._bumpTexture3) {
+                activeTextures.push(this._bumpTexture3);
+            }
+            return activeTextures;
+        };
         TerrainMaterial.prototype.dispose = function (forceDisposeEffect) {
         TerrainMaterial.prototype.dispose = function (forceDisposeEffect) {
             if (this.mixTexture) {
             if (this.mixTexture) {
                 this.mixTexture.dispose();
                 this.mixTexture.dispose();

文件差异内容过多而无法显示
+ 1 - 1
dist/preview release/materialsLibrary/babylon.terrainMaterial.min.js


+ 1 - 0
dist/preview release/materialsLibrary/babylon.triPlanarMaterial.d.ts

@@ -31,6 +31,7 @@ declare module BABYLON {
         isReadyForSubMesh(mesh: AbstractMesh, subMesh: SubMesh, useInstances?: boolean): boolean;
         isReadyForSubMesh(mesh: AbstractMesh, subMesh: SubMesh, useInstances?: boolean): boolean;
         bindForSubMesh(world: Matrix, mesh: Mesh, subMesh: SubMesh): void;
         bindForSubMesh(world: Matrix, mesh: Mesh, subMesh: SubMesh): void;
         getAnimatables(): IAnimatable[];
         getAnimatables(): IAnimatable[];
+        getActiveTextures(): BaseTexture[];
         dispose(forceDisposeEffect?: boolean): void;
         dispose(forceDisposeEffect?: boolean): void;
         clone(name: string): TriPlanarMaterial;
         clone(name: string): TriPlanarMaterial;
         serialize(): any;
         serialize(): any;

+ 22 - 0
dist/preview release/materialsLibrary/babylon.triPlanarMaterial.js

@@ -251,6 +251,28 @@ var BABYLON;
             }
             }
             return results;
             return results;
         };
         };
+        TriPlanarMaterial.prototype.getActiveTextures = function () {
+            var activeTextures = _super.prototype.getActiveTextures.call(this);
+            if (this._diffuseTextureX) {
+                activeTextures.push(this._diffuseTextureX);
+            }
+            if (this._diffuseTextureY) {
+                activeTextures.push(this._diffuseTextureY);
+            }
+            if (this._diffuseTextureZ) {
+                activeTextures.push(this._diffuseTextureZ);
+            }
+            if (this._normalTextureX) {
+                activeTextures.push(this._normalTextureX);
+            }
+            if (this._normalTextureY) {
+                activeTextures.push(this._normalTextureY);
+            }
+            if (this._normalTextureZ) {
+                activeTextures.push(this._normalTextureZ);
+            }
+            return activeTextures;
+        };
         TriPlanarMaterial.prototype.dispose = function (forceDisposeEffect) {
         TriPlanarMaterial.prototype.dispose = function (forceDisposeEffect) {
             if (this.mixTexture) {
             if (this.mixTexture) {
                 this.mixTexture.dispose();
                 this.mixTexture.dispose();

文件差异内容过多而无法显示
+ 1 - 1
dist/preview release/materialsLibrary/babylon.triPlanarMaterial.min.js


+ 1 - 0
dist/preview release/materialsLibrary/babylon.waterMaterial.d.ts

@@ -92,6 +92,7 @@ declare module BABYLON {
         bindForSubMesh(world: Matrix, mesh: Mesh, subMesh: SubMesh): void;
         bindForSubMesh(world: Matrix, mesh: Mesh, subMesh: SubMesh): void;
         private _createRenderTargets(scene, renderTargetSize);
         private _createRenderTargets(scene, renderTargetSize);
         getAnimatables(): IAnimatable[];
         getAnimatables(): IAnimatable[];
+        getActiveTextures(): BaseTexture[];
         dispose(forceDisposeEffect?: boolean): void;
         dispose(forceDisposeEffect?: boolean): void;
         clone(name: string): WaterMaterial;
         clone(name: string): WaterMaterial;
         serialize(): any;
         serialize(): any;

+ 7 - 0
dist/preview release/materialsLibrary/babylon.waterMaterial.js

@@ -444,6 +444,13 @@ var BABYLON;
             }
             }
             return results;
             return results;
         };
         };
+        WaterMaterial.prototype.getActiveTextures = function () {
+            var activeTextures = _super.prototype.getActiveTextures.call(this);
+            if (this._bumpTexture) {
+                activeTextures.push(this._bumpTexture);
+            }
+            return activeTextures;
+        };
         WaterMaterial.prototype.dispose = function (forceDisposeEffect) {
         WaterMaterial.prototype.dispose = function (forceDisposeEffect) {
             if (this.bumpTexture) {
             if (this.bumpTexture) {
                 this.bumpTexture.dispose();
                 this.bumpTexture.dispose();

文件差异内容过多而无法显示
+ 1 - 1
dist/preview release/materialsLibrary/babylon.waterMaterial.min.js


文件差异内容过多而无法显示
+ 1 - 1
dist/preview release/postProcessesLibrary/babylon.asciiArtPostProcess.min.js


文件差异内容过多而无法显示
+ 1 - 1
dist/preview release/postProcessesLibrary/babylon.digitalRainPostProcess.min.js