فهرست منبع

Merge pull request #4477 from sebavan/master

Nightly
sebavan 7 سال پیش
والد
کامیت
69aad3b73a

تفاوت فایلی نمایش داده نمی شود زیرا این فایل بسیار بزرگ است
+ 0 - 41659
Playground/babylon.d.txt


تفاوت فایلی نمایش داده نمی شود زیرا این فایل بسیار بزرگ است
+ 9723 - 9723
dist/preview release/babylon.d.ts


تفاوت فایلی نمایش داده نمی شود زیرا این فایل بسیار بزرگ است
+ 5 - 5
dist/preview release/inspector/babylon.inspector.bundle.js


تفاوت فایلی نمایش داده نمی شود زیرا این فایل بسیار بزرگ است
+ 5 - 5
dist/preview release/viewer/babylon.viewer.js


+ 187 - 243
dist/preview release/viewer/babylon.viewer.max.js

@@ -105412,6 +105412,15 @@ var BABYLON;
             /** @hidden */
             this._normalizeAnimationGroupsToBeginAtZero = true;
             /**
+             * Defines if the loader logging is enabled.
+             */
+            this.loggingEnabled = false;
+            /**
+             * Observable raised when the loader logs a message.
+             */
+            this.onLogObservable = new BABYLON.Observable();
+            this._logIndentLevel = 0;
+            /**
              * Function called before loading a url referenced by the asset.
              */
             this.preprocessUrlAsync = function (url) { return Promise.resolve(url); };
@@ -105473,6 +105482,23 @@ var BABYLON;
             enumerable: true,
             configurable: true
         });
+        /** @hidden */
+        GLTFFileLoader.prototype._log = function (message) {
+            if (this.loggingEnabled) {
+                var spaces = GLTFFileLoader._logSpaces.substr(0, this._logIndentLevel * 2);
+                this.onLogObservable.notifyObservers("" + spaces + message);
+                BABYLON.Tools.Log("" + spaces + message);
+            }
+        };
+        /** @hidden */
+        GLTFFileLoader.prototype._logOpen = function (message) {
+            this._log(message);
+            this._logIndentLevel++;
+        };
+        /** @hidden */
+        GLTFFileLoader.prototype._logClose = function () {
+            --this._logIndentLevel;
+        };
         Object.defineProperty(GLTFFileLoader.prototype, "onMeshLoaded", {
             /**
              * Callback raised when the loader creates a mesh after parsing the glTF properties of the mesh.
@@ -105594,6 +105620,12 @@ var BABYLON;
                 this._loader.dispose();
                 this._loader = null;
             }
+            this._clear();
+            this.onDisposeObservable.notifyObservers(undefined);
+            this.onDisposeObservable.clear();
+        };
+        /** @hidden */
+        GLTFFileLoader.prototype._clear = function () {
             this.preprocessUrlAsync = function (url) { return Promise.resolve(url); };
             this.onMeshLoadedObservable.clear();
             this.onTextureLoadedObservable.clear();
@@ -105601,8 +105633,6 @@ var BABYLON;
             this.onCameraLoadedObservable.clear();
             this.onCompleteObservable.clear();
             this.onExtensionLoadedObservable.clear();
-            this.onDisposeObservable.notifyObservers(this);
-            this.onDisposeObservable.clear();
         };
         /**
          * Imports one or more meshes from the loaded glTF data and adds them to the scene
@@ -105679,9 +105709,16 @@ var BABYLON;
         GLTFFileLoader.prototype._parse = function (data) {
             var parsedData;
             if (data instanceof ArrayBuffer) {
-                parsedData = GLTFFileLoader._parseBinary(data);
+                if (this.loggingEnabled) {
+                    this._log("Parsing binary");
+                }
+                parsedData = this._parseBinary(data);
             }
             else {
+                if (this.loggingEnabled) {
+                    this._log("Parsing JSON");
+                    this._log("JSON length: " + data.length);
+                }
                 parsedData = {
                     json: JSON.parse(data),
                     bin: null
@@ -105692,9 +105729,16 @@ var BABYLON;
             return parsedData;
         };
         GLTFFileLoader.prototype._getLoader = function (loaderData) {
-            var _this = this;
-            var loaderVersion = { major: 2, minor: 0 };
             var asset = loaderData.json.asset || {};
+            if (this.loggingEnabled) {
+                this._log("Asset version: " + asset.version);
+                if (asset.minVersion) {
+                    this._log("Asset minimum version: " + asset.minVersion);
+                }
+                if (asset.generator) {
+                    this._log("Asset generator: " + asset.generator);
+                }
+            }
             var version = GLTFFileLoader._parseVersion(asset.version);
             if (!version) {
                 throw new Error("Invalid version: " + asset.version);
@@ -105704,7 +105748,7 @@ var BABYLON;
                 if (!minVersion) {
                     throw new Error("Invalid minimum version: " + asset.minVersion);
                 }
-                if (GLTFFileLoader._compareVersion(minVersion, loaderVersion) > 0) {
+                if (GLTFFileLoader._compareVersion(minVersion, { major: 2, minor: 0 }) > 0) {
                     throw new Error("Incompatible minimum version: " + asset.minVersion);
                 }
             }
@@ -105716,48 +105760,31 @@ var BABYLON;
             if (!createLoader) {
                 throw new Error("Unsupported version: " + asset.version);
             }
-            var loader = createLoader();
-            loader.coordinateSystemMode = this.coordinateSystemMode;
-            loader.animationStartMode = this.animationStartMode;
-            loader.compileMaterials = this.compileMaterials;
-            loader.useClipPlane = this.useClipPlane;
-            loader.compileShadowGenerators = this.compileShadowGenerators;
-            loader.transparencyAsCoverage = this.transparencyAsCoverage;
-            loader._normalizeAnimationGroupsToBeginAtZero = this._normalizeAnimationGroupsToBeginAtZero;
-            loader.preprocessUrlAsync = this.preprocessUrlAsync;
-            loader.onMeshLoadedObservable.add(function (mesh) { return _this.onMeshLoadedObservable.notifyObservers(mesh); });
-            loader.onTextureLoadedObservable.add(function (texture) { return _this.onTextureLoadedObservable.notifyObservers(texture); });
-            loader.onMaterialLoadedObservable.add(function (material) { return _this.onMaterialLoadedObservable.notifyObservers(material); });
-            loader.onCameraLoadedObservable.add(function (camera) { return _this.onCameraLoadedObservable.notifyObservers(camera); });
-            loader.onExtensionLoadedObservable.add(function (extension) { return _this.onExtensionLoadedObservable.notifyObservers(extension); });
-            loader.onCompleteObservable.add(function () {
-                _this.onMeshLoadedObservable.clear();
-                _this.onTextureLoadedObservable.clear();
-                _this.onMaterialLoadedObservable.clear();
-                _this.onCameraLoadedObservable.clear();
-                _this.onExtensionLoadedObservable.clear();
-                _this.onCompleteObservable.notifyObservers(_this);
-                _this.onCompleteObservable.clear();
-            });
-            return loader;
+            return createLoader(this);
         };
-        GLTFFileLoader._parseBinary = function (data) {
+        GLTFFileLoader.prototype._parseBinary = function (data) {
             var Binary = {
                 Magic: 0x46546C67
             };
+            if (this.loggingEnabled) {
+                this._log("Binary length: " + data.byteLength);
+            }
             var binaryReader = new BinaryReader(data);
             var magic = binaryReader.readUint32();
             if (magic !== Binary.Magic) {
                 throw new Error("Unexpected magic: " + magic);
             }
             var version = binaryReader.readUint32();
+            if (this.loggingEnabled) {
+                this._log("Binary version: " + version);
+            }
             switch (version) {
-                case 1: return GLTFFileLoader._parseV1(binaryReader);
-                case 2: return GLTFFileLoader._parseV2(binaryReader);
+                case 1: return this._parseV1(binaryReader);
+                case 2: return this._parseV2(binaryReader);
             }
             throw new Error("Unsupported version: " + version);
         };
-        GLTFFileLoader._parseV1 = function (binaryReader) {
+        GLTFFileLoader.prototype._parseV1 = function (binaryReader) {
             var ContentFormat = {
                 JSON: 0
             };
@@ -105784,7 +105811,7 @@ var BABYLON;
                 bin: body
             };
         };
-        GLTFFileLoader._parseV2 = function (binaryReader) {
+        GLTFFileLoader.prototype._parseV2 = function (binaryReader) {
             var ChunkFormat = {
                 JSON: 0x4E4F534A,
                 BIN: 0x004E4942
@@ -105875,6 +105902,7 @@ var BABYLON;
          * @hidden
          */
         GLTFFileLoader.HomogeneousCoordinates = false;
+        GLTFFileLoader._logSpaces = "                                ";
         return GLTFFileLoader;
     }());
     BABYLON.GLTFFileLoader = GLTFFileLoader;
@@ -107298,22 +107326,6 @@ var BABYLON;
         */
         var GLTFLoader = /** @class */ (function () {
             function GLTFLoader() {
-                // #region Stubs for IGLTFLoader interface
-                this.coordinateSystemMode = BABYLON.GLTFLoaderCoordinateSystemMode.AUTO;
-                this.animationStartMode = BABYLON.GLTFLoaderAnimationStartMode.FIRST;
-                this.compileMaterials = false;
-                this.useClipPlane = false;
-                this.compileShadowGenerators = false;
-                this.transparencyAsCoverage = false;
-                this._normalizeAnimationGroupsToBeginAtZero = true;
-                this.preprocessUrlAsync = function (url) { return Promise.resolve(url); };
-                this.onMeshLoadedObservable = new BABYLON.Observable();
-                this.onTextureLoadedObservable = new BABYLON.Observable();
-                this.onMaterialLoadedObservable = new BABYLON.Observable();
-                this.onCameraLoadedObservable = new BABYLON.Observable();
-                this.onCompleteObservable = new BABYLON.Observable();
-                this.onDisposeObservable = new BABYLON.Observable();
-                this.onExtensionLoadedObservable = new BABYLON.Observable();
                 this.state = null;
             }
             GLTFLoader.RegisterExtension = function (extension) {
@@ -107323,8 +107335,9 @@ var BABYLON;
                 }
                 GLTFLoader.Extensions[extension.name] = extension;
             };
-            GLTFLoader.prototype.dispose = function () { };
-            // #endregion
+            GLTFLoader.prototype.dispose = function () {
+                // do nothing
+            };
             GLTFLoader.prototype._importMeshAsync = function (meshesNames, scene, data, rootUrl, onSuccess, onProgress, onError) {
                 var _this = this;
                 scene.useRightHandedSystem = true;
@@ -108135,14 +108148,10 @@ var BABYLON;
             };
             return _ArrayItem;
         }());
-        /**
-         * Loader for loading a glTF 2.0 asset
-         */
+        /** @hidden */
         var GLTFLoader = /** @class */ (function () {
-            function GLTFLoader() {
-                /** @hidden */
+            function GLTFLoader(parent) {
                 this._completePromises = new Array();
-                /** @hidden */
                 this._onReadyObservable = new BABYLON.Observable();
                 this._disposed = false;
                 this._state = null;
@@ -108150,71 +108159,8 @@ var BABYLON;
                 this._defaultSampler = {};
                 this._defaultBabylonMaterials = {};
                 this._requests = new Array();
-                /**
-                 * Mode that determines the coordinate system to use.
-                 */
-                this.coordinateSystemMode = BABYLON.GLTFLoaderCoordinateSystemMode.AUTO;
-                /**
-                 * Mode that determines what animations will start.
-                 */
-                this.animationStartMode = BABYLON.GLTFLoaderAnimationStartMode.FIRST;
-                /**
-                 * Defines if the loader should compile materials.
-                 */
-                this.compileMaterials = false;
-                /**
-                 * Defines if the loader should also compile materials with clip planes.
-                 */
-                this.useClipPlane = false;
-                /**
-                 * Defines if the loader should compile shadow generators.
-                 */
-                this.compileShadowGenerators = false;
-                /**
-                 * Defines if the Alpha blended materials are only applied as coverage.
-                 * If false, (default) The luminance of each pixel will reduce its opacity to simulate the behaviour of most physical materials.
-                 * If true, no extra effects are applied to transparent pixels.
-                 */
-                this.transparencyAsCoverage = false;
-                /** @hidden */
-                this._normalizeAnimationGroupsToBeginAtZero = true;
-                /**
-                 * Function called before loading a url referenced by the asset.
-                 */
-                this.preprocessUrlAsync = function (url) { return Promise.resolve(url); };
-                /**
-                 * Observable raised when the loader creates a mesh after parsing the glTF properties of the mesh.
-                 */
-                this.onMeshLoadedObservable = new BABYLON.Observable();
-                /**
-                 * Observable raised when the loader creates a texture after parsing the glTF properties of the texture.
-                 */
-                this.onTextureLoadedObservable = new BABYLON.Observable();
-                /**
-                 * Observable raised when the loader creates a material after parsing the glTF properties of the material.
-                 */
-                this.onMaterialLoadedObservable = new BABYLON.Observable();
-                /**
-                 * Observable raised when the loader creates a camera after parsing the glTF properties of the camera.
-                 */
-                this.onCameraLoadedObservable = new BABYLON.Observable();
-                /**
-                 * Observable raised when the asset is completely loaded, immediately before the loader is disposed.
-                 * For assets with LODs, raised when all of the LODs are complete.
-                 * For assets without LODs, raised when the model is complete, immediately after the loader resolves the returned promise.
-                 */
-                this.onCompleteObservable = new BABYLON.Observable();
-                /**
-                 * Observable raised after the loader is disposed.
-                 */
-                this.onDisposeObservable = new BABYLON.Observable();
-                /**
-                 * Observable raised after a loader extension is created.
-                 * Set additional options for a loader extension in this event.
-                 */
-                this.onExtensionLoadedObservable = new BABYLON.Observable();
+                this._parent = parent;
             }
-            /** @hidden */
             GLTFLoader._Register = function (name, factory) {
                 if (GLTFLoader._ExtensionFactories[name]) {
                     BABYLON.Tools.Error("Extension with the name '" + name + "' already exists");
@@ -108234,27 +108180,28 @@ var BABYLON;
                 enumerable: true,
                 configurable: true
             });
-            /**
-             * Disposes the loader, releases resources during load, and cancels any outstanding requests.
-             */
             GLTFLoader.prototype.dispose = function () {
                 if (this._disposed) {
                     return;
                 }
                 this._disposed = true;
-                this.onDisposeObservable.notifyObservers(this);
-                this.onDisposeObservable.clear();
-                this._clear();
+                for (var _i = 0, _a = this._requests; _i < _a.length; _i++) {
+                    var request = _a[_i];
+                    request.abort();
+                }
+                this._requests.length = 0;
+                delete this._gltf;
+                delete this._babylonScene;
+                this._completePromises.length = 0;
+                this._onReadyObservable.clear();
+                for (var name_1 in this._extensions) {
+                    this._extensions[name_1].dispose();
+                }
+                this._extensions = {};
+                delete this._rootBabylonMesh;
+                delete this._progressCallback;
+                this._parent._clear();
             };
-            /**
-             * Imports one or more meshes from the loaded glTF data and adds them to the scene
-             * @param meshesNames a string or array of strings of the mesh names that should be loaded from the file
-             * @param scene the scene the meshes should be added to
-             * @param data the glTF data to load
-             * @param rootUrl root url to load from
-             * @param onProgress event that fires when loading progress has occured
-             * @returns a promise containg the loaded meshes, particles, skeletons and animations
-             */
             GLTFLoader.prototype.importMeshAsync = function (meshesNames, scene, data, rootUrl, onProgress) {
                 var _this = this;
                 return Promise.resolve().then(function () {
@@ -108292,14 +108239,6 @@ var BABYLON;
                     });
                 });
             };
-            /**
-             * Imports all objects from the loaded glTF data and adds them to the scene
-             * @param scene the scene the objects should be added to
-             * @param data the glTF data to load
-             * @param rootUrl root url to load from
-             * @param onProgress event that fires when loading progress has occured
-             * @returns a promise which completes when objects have been loaded to the scene
-             */
             GLTFLoader.prototype.loadAsync = function (scene, data, rootUrl, onProgress) {
                 var _this = this;
                 return Promise.resolve().then(function () {
@@ -108314,6 +108253,7 @@ var BABYLON;
                 var _this = this;
                 return Promise.resolve().then(function () {
                     _this._state = BABYLON.GLTFLoaderState.LOADING;
+                    _this._parent._log("Loading");
                     _this._loadExtensions();
                     _this._checkExtensions();
                     var promises = new Array();
@@ -108324,14 +108264,15 @@ var BABYLON;
                         var scene = GLTFLoader._GetProperty("#/scene", _this._gltf.scenes, _this._gltf.scene || 0);
                         promises.push(_this._loadSceneAsync("#/scenes/" + scene._index, scene));
                     }
-                    if (_this.compileMaterials) {
+                    if (_this._parent.compileMaterials) {
                         promises.push(_this._compileMaterialsAsync());
                     }
-                    if (_this.compileShadowGenerators) {
+                    if (_this._parent.compileShadowGenerators) {
                         promises.push(_this._compileShadowGeneratorsAsync());
                     }
                     var resultPromise = Promise.all(promises).then(function () {
                         _this._state = BABYLON.GLTFLoaderState.READY;
+                        _this._parent._log("Ready");
                         _this._onReadyObservable.notifyObservers(_this);
                         _this._startAnimations();
                     });
@@ -108343,12 +108284,13 @@ var BABYLON;
                             if (!_this._disposed) {
                                 Promise.all(_this._completePromises).then(function () {
                                     _this._state = BABYLON.GLTFLoaderState.COMPLETE;
-                                    _this.onCompleteObservable.notifyObservers(_this);
-                                    _this.onCompleteObservable.clear();
-                                    _this._clear();
+                                    _this._parent._log("Complete");
+                                    _this._parent.onCompleteObservable.notifyObservers(undefined);
+                                    _this._parent.onCompleteObservable.clear();
+                                    _this.dispose();
                                 }).catch(function (error) {
                                     BABYLON.Tools.Error("glTF Loader: " + error.message);
-                                    _this._clear();
+                                    _this.dispose();
                                 });
                             }
                         });
@@ -108357,7 +108299,7 @@ var BABYLON;
                 }).catch(function (error) {
                     if (!_this._disposed) {
                         BABYLON.Tools.Error("glTF Loader: " + error.message);
-                        _this._clear();
+                        _this.dispose();
                         throw error;
                     }
                 });
@@ -108414,20 +108356,20 @@ var BABYLON;
             };
             GLTFLoader.prototype._loadExtensions = function () {
                 for (var _i = 0, _a = GLTFLoader._ExtensionNames; _i < _a.length; _i++) {
-                    var name_1 = _a[_i];
-                    var extension = GLTFLoader._ExtensionFactories[name_1](this);
-                    this._extensions[name_1] = extension;
-                    this.onExtensionLoadedObservable.notifyObservers(extension);
+                    var name_2 = _a[_i];
+                    var extension = GLTFLoader._ExtensionFactories[name_2](this);
+                    this._extensions[name_2] = extension;
+                    this._parent.onExtensionLoadedObservable.notifyObservers(extension);
                 }
-                this.onExtensionLoadedObservable.clear();
+                this._parent.onExtensionLoadedObservable.clear();
             };
             GLTFLoader.prototype._checkExtensions = function () {
                 if (this._gltf.extensionsRequired) {
                     for (var _i = 0, _a = this._gltf.extensionsRequired; _i < _a.length; _i++) {
-                        var name_2 = _a[_i];
-                        var extension = this._extensions[name_2];
+                        var name_3 = _a[_i];
+                        var extension = this._extensions[name_3];
                         if (!extension || !extension.enabled) {
-                            throw new Error("Require extension " + name_2 + " is not available");
+                            throw new Error("Require extension " + name_3 + " is not available");
                         }
                     }
                 }
@@ -108436,7 +108378,7 @@ var BABYLON;
                 this._rootBabylonMesh = new BABYLON.Mesh("__root__", this._babylonScene);
                 this._rootBabylonMesh.setEnabled(false);
                 var rootNode = { _babylonMesh: this._rootBabylonMesh };
-                switch (this.coordinateSystemMode) {
+                switch (this._parent.coordinateSystemMode) {
                     case BABYLON.GLTFLoaderCoordinateSystemMode.AUTO: {
                         if (!this._babylonScene.useRightHandedSystem) {
                             rootNode.rotation = [0, 1, 0, 0];
@@ -108450,10 +108392,10 @@ var BABYLON;
                         break;
                     }
                     default: {
-                        throw new Error("Invalid coordinate system mode (" + this.coordinateSystemMode + ")");
+                        throw new Error("Invalid coordinate system mode (" + this._parent.coordinateSystemMode + ")");
                     }
                 }
-                this.onMeshLoadedObservable.notifyObservers(this._rootBabylonMesh);
+                this._parent.onMeshLoadedObservable.notifyObservers(this._rootBabylonMesh);
                 return rootNode;
             };
             GLTFLoader.prototype._loadNodesAsync = function (nodes) {
@@ -108465,19 +108407,22 @@ var BABYLON;
                 promises.push(this._loadAnimationsAsync());
                 return Promise.all(promises).then(function () { });
             };
-            /** @hidden */
             GLTFLoader.prototype._loadSceneAsync = function (context, scene) {
                 var promise = GLTF2.GLTFLoaderExtension._LoadSceneAsync(this, context, scene);
                 if (promise) {
                     return promise;
                 }
                 var promises = new Array();
-                for (var _i = 0, _a = scene.nodes; _i < _a.length; _i++) {
-                    var index = _a[_i];
-                    var node = GLTFLoader._GetProperty(context + "/nodes/" + index, this._gltf.nodes, index);
-                    promises.push(this._loadNodeAsync("#/nodes/" + node._index, node));
+                this._parent._logOpen(context + " " + (scene.name || ""));
+                if (scene.nodes) {
+                    for (var _i = 0, _a = scene.nodes; _i < _a.length; _i++) {
+                        var index = _a[_i];
+                        var node = GLTFLoader._GetProperty(context + "/nodes/" + index, this._gltf.nodes, index);
+                        promises.push(this._loadNodeAsync("#/nodes/" + node._index, node));
+                    }
                 }
                 promises.push(this._loadAnimationsAsync());
+                this._parent._logClose();
                 return Promise.all(promises).then(function () { });
             };
             GLTFLoader.prototype._forEachPrimitive = function (node, callback) {
@@ -108539,7 +108484,7 @@ var BABYLON;
                 return animationGroups;
             };
             GLTFLoader.prototype._startAnimations = function () {
-                switch (this.animationStartMode) {
+                switch (this._parent.animationStartMode) {
                     case BABYLON.GLTFLoaderAnimationStartMode.NONE: {
                         // do nothing
                         break;
@@ -108560,12 +108505,11 @@ var BABYLON;
                         break;
                     }
                     default: {
-                        BABYLON.Tools.Error("Invalid animation start mode (" + this.animationStartMode + ")");
+                        BABYLON.Tools.Error("Invalid animation start mode (" + this._parent.animationStartMode + ")");
                         return;
                     }
                 }
             };
-            /** @hidden */
             GLTFLoader.prototype._loadNodeAsync = function (context, node) {
                 var promise = GLTF2.GLTFLoaderExtension._LoadNodeAsync(this, context, node);
                 if (promise) {
@@ -108575,6 +108519,7 @@ var BABYLON;
                     throw new Error(context + ": Invalid recursive node hierarchy");
                 }
                 var promises = new Array();
+                this._parent._logOpen(context + " " + (node.name || ""));
                 var babylonMesh = new BABYLON.Mesh(node.name || "node" + node._index, this._babylonScene, node._parent ? node._parent._babylonMesh : null);
                 node._babylonMesh = babylonMesh;
                 GLTFLoader._LoadTransform(node, babylonMesh);
@@ -108593,12 +108538,14 @@ var BABYLON;
                         promises.push(this._loadNodeAsync("#/nodes/" + index, childNode));
                     }
                 }
-                this.onMeshLoadedObservable.notifyObservers(babylonMesh);
+                this._parent.onMeshLoadedObservable.notifyObservers(babylonMesh);
+                this._parent._logClose();
                 return Promise.all(promises).then(function () { });
             };
             GLTFLoader.prototype._loadMeshAsync = function (context, node, mesh, babylonMesh) {
                 var _this = this;
                 var promises = new Array();
+                this._parent._logOpen(context + " " + (mesh.name || ""));
                 var primitives = mesh.primitives;
                 if (!primitives || primitives.length === 0) {
                     throw new Error(context + ": Primitives are missing");
@@ -108615,13 +108562,14 @@ var BABYLON;
                         var primitiveBabylonMesh = new BABYLON.Mesh((mesh.name || babylonMesh.name) + "_" + primitive._index, this._babylonScene, babylonMesh);
                         node._primitiveBabylonMeshes.push(primitiveBabylonMesh);
                         promises.push(this._loadPrimitiveAsync(context + "/primitives/" + primitive._index, node, mesh, primitive, primitiveBabylonMesh));
-                        this.onMeshLoadedObservable.notifyObservers(babylonMesh);
+                        this._parent.onMeshLoadedObservable.notifyObservers(babylonMesh);
                     }
                 }
                 if (node.skin != undefined) {
                     var skin = GLTFLoader._GetProperty(context + "/skin", this._gltf.skins, node.skin);
                     promises.push(this._loadSkinAsync("#/skins/" + skin._index, node, mesh, skin));
                 }
+                this._parent._logClose();
                 return Promise.all(promises).then(function () {
                     _this._forEachPrimitive(node, function (babylonMesh) {
                         babylonMesh._refreshBoundingInfo(true);
@@ -108631,6 +108579,7 @@ var BABYLON;
             GLTFLoader.prototype._loadPrimitiveAsync = function (context, node, mesh, primitive, babylonMesh) {
                 var _this = this;
                 var promises = new Array();
+                this._parent._logOpen("" + context);
                 this._createMorphTargets(context, node, mesh, primitive, babylonMesh);
                 promises.push(this._loadVertexDataAsync(context, primitive, babylonMesh).then(function (babylonGeometry) {
                     return _this._loadMorphTargetsAsync(context, primitive, babylonMesh, babylonGeometry).then(function () {
@@ -108647,6 +108596,7 @@ var BABYLON;
                         babylonMesh.material = babylonMaterial;
                     }));
                 }
+                this._parent._logClose();
                 return Promise.all(promises).then(function () { });
             };
             GLTFLoader.prototype._loadVertexDataAsync = function (context, primitive, babylonMesh) {
@@ -108905,7 +108855,7 @@ var BABYLON;
                         throw new Error(context + ": Invalid camera type (" + camera.type + ")");
                     }
                 }
-                this.onCameraLoadedObservable.notifyObservers(babylonCamera);
+                this._parent.onCameraLoadedObservable.notifyObservers(babylonCamera);
             };
             GLTFLoader.prototype._loadAnimationsAsync = function () {
                 var animations = this._gltf.animations;
@@ -108931,7 +108881,7 @@ var BABYLON;
                     promises.push(this._loadAnimationChannelAsync(context + "/channels/" + channel._index, context, animation, channel, babylonAnimationGroup));
                 }
                 return Promise.all(promises).then(function () {
-                    babylonAnimationGroup.normalize(_this._normalizeAnimationGroupsToBeginAtZero ? 0 : null);
+                    babylonAnimationGroup.normalize(_this._parent._normalizeAnimationGroupsToBeginAtZero ? 0 : null);
                 });
             };
             GLTFLoader.prototype._loadAnimationChannelAsync = function (context, animationContext, animation, channel, babylonAnimationGroup) {
@@ -109125,7 +109075,6 @@ var BABYLON;
                 buffer._data = this._loadUriAsync(context, buffer.uri);
                 return buffer._data;
             };
-            /** @hidden */
             GLTFLoader.prototype._loadBufferViewAsync = function (context, bufferView) {
                 if (bufferView._data) {
                     return bufferView._data;
@@ -109204,7 +109153,6 @@ var BABYLON;
                 }
                 return accessor._data;
             };
-            /** @hidden */
             GLTFLoader.prototype._loadVertexBufferViewAsync = function (context, bufferView, kind) {
                 var _this = this;
                 if (bufferView._babylonBuffer) {
@@ -109241,7 +109189,7 @@ var BABYLON;
                     babylonMaterial.transparencyMode = BABYLON.PBRMaterial.PBRMATERIAL_OPAQUE;
                     babylonMaterial.metallic = 1;
                     babylonMaterial.roughness = 1;
-                    this.onMaterialLoadedObservable.notifyObservers(babylonMaterial);
+                    this._parent.onMaterialLoadedObservable.notifyObservers(babylonMaterial);
                 }
                 return babylonMaterial;
             };
@@ -109278,7 +109226,6 @@ var BABYLON;
                 this._loadMaterialAlphaProperties(context, material, babylonMaterial);
                 return Promise.all(promises).then(function () { });
             };
-            /** @hidden */
             GLTFLoader.prototype._loadMaterialAsync = function (context, material, mesh, babylonMesh, babylonDrawMode, assign) {
                 var promise = GLTF2.GLTFLoaderExtension._LoadMaterialAsync(this, context, material, mesh, babylonMesh, babylonDrawMode, assign);
                 if (promise) {
@@ -109288,33 +109235,33 @@ var BABYLON;
                 var babylonData = material._babylonData[babylonDrawMode];
                 if (!babylonData) {
                     var promises = new Array();
-                    var name_3 = material.name || "material_" + material._index;
-                    var babylonMaterial = this._createMaterial(name_3, babylonDrawMode);
+                    this._parent._logOpen(context + " " + (material.name || ""));
+                    var name_4 = material.name || "material_" + material._index;
+                    var babylonMaterial = this._createMaterial(name_4, babylonDrawMode);
                     promises.push(this._loadMaterialBasePropertiesAsync(context, material, babylonMaterial));
                     promises.push(this._loadMaterialMetallicRoughnessPropertiesAsync(context, material, babylonMaterial));
-                    this.onMaterialLoadedObservable.notifyObservers(babylonMaterial);
+                    this._parent.onMaterialLoadedObservable.notifyObservers(babylonMaterial);
                     babylonData = {
                         material: babylonMaterial,
                         meshes: [],
                         loaded: Promise.all(promises).then(function () { })
                     };
                     material._babylonData[babylonDrawMode] = babylonData;
+                    this._parent._logClose();
                 }
                 babylonData.meshes.push(babylonMesh);
                 assign(babylonData.material);
                 return babylonData.loaded;
             };
-            /** @hidden */
             GLTFLoader.prototype._createMaterial = function (name, drawMode) {
                 var babylonMaterial = new BABYLON.PBRMaterial(name, this._babylonScene);
                 babylonMaterial.sideOrientation = this._babylonScene.useRightHandedSystem ? BABYLON.Material.CounterClockWiseSideOrientation : BABYLON.Material.ClockWiseSideOrientation;
                 babylonMaterial.fillMode = drawMode;
                 babylonMaterial.enableSpecularAntiAliasing = true;
-                babylonMaterial.useRadianceOverAlpha = !this.transparencyAsCoverage;
-                babylonMaterial.useSpecularOverAlpha = !this.transparencyAsCoverage;
+                babylonMaterial.useRadianceOverAlpha = !this._parent.transparencyAsCoverage;
+                babylonMaterial.useSpecularOverAlpha = !this._parent.transparencyAsCoverage;
                 return babylonMaterial;
             };
-            /** @hidden */
             GLTFLoader.prototype._loadMaterialBasePropertiesAsync = function (context, material, babylonMaterial) {
                 var promises = new Array();
                 babylonMaterial.emissiveColor = material.emissiveFactor ? BABYLON.Color3.FromArray(material.emissiveFactor) : new BABYLON.Color3(0, 0, 0);
@@ -109348,7 +109295,6 @@ var BABYLON;
                 }
                 return Promise.all(promises).then(function () { });
             };
-            /** @hidden */
             GLTFLoader.prototype._loadMaterialAlphaProperties = function (context, material, babylonMaterial) {
                 var alphaMode = material.alphaMode || "OPAQUE" /* OPAQUE */;
                 switch (alphaMode) {
@@ -109377,16 +109323,17 @@ var BABYLON;
                     }
                 }
             };
-            /** @hidden */
             GLTFLoader.prototype._loadTextureAsync = function (context, textureInfo, assign) {
                 var _this = this;
                 var promise = GLTF2.GLTFLoaderExtension._LoadTextureAsync(this, context, textureInfo, assign);
                 if (promise) {
                     return promise;
                 }
+                this._parent._logOpen("" + context);
                 var texture = GLTFLoader._GetProperty(context + "/index", this._gltf.textures, textureInfo.index);
                 context = "#/textures/" + textureInfo.index;
                 var promises = new Array();
+                this._parent._logOpen(context + " " + (texture.name || ""));
                 var sampler = (texture.sampler == undefined ? this._defaultSampler : GLTFLoader._GetProperty(context + "/sampler", this._gltf.samplers, texture.sampler));
                 var samplerData = this._loadSampler("#/samplers/" + sampler._index, sampler);
                 var deferred = new BABYLON.Deferred();
@@ -109410,7 +109357,9 @@ var BABYLON;
                     babylonTexture.updateURL(dataUrl, blob);
                 }));
                 assign(babylonTexture);
-                this.onTextureLoadedObservable.notifyObservers(babylonTexture);
+                this._parent.onTextureLoadedObservable.notifyObservers(babylonTexture);
+                this._parent._logClose();
+                this._parent._logClose();
                 return Promise.all(promises).then(function () { });
             };
             GLTFLoader.prototype._loadSampler = function (context, sampler) {
@@ -109426,23 +109375,23 @@ var BABYLON;
                 return sampler._data;
             };
             GLTFLoader.prototype._loadImageAsync = function (context, image) {
-                if (image._blob) {
-                    return image._blob;
-                }
-                var promise;
-                if (image.uri) {
-                    promise = this._loadUriAsync(context, image.uri);
-                }
-                else {
-                    var bufferView = GLTFLoader._GetProperty(context + "/bufferView", this._gltf.bufferViews, image.bufferView);
-                    promise = this._loadBufferViewAsync("#/bufferViews/" + bufferView._index, bufferView);
+                if (!image._blob) {
+                    this._parent._logOpen(context + " " + (image.name || ""));
+                    var promise = void 0;
+                    if (image.uri) {
+                        promise = this._loadUriAsync(context, image.uri);
+                    }
+                    else {
+                        var bufferView = GLTFLoader._GetProperty(context + "/bufferView", this._gltf.bufferViews, image.bufferView);
+                        promise = this._loadBufferViewAsync("#/bufferViews/" + bufferView._index, bufferView);
+                    }
+                    image._blob = promise.then(function (data) {
+                        return new Blob([data], { type: image.mimeType });
+                    });
+                    this._parent._logClose();
                 }
-                image._blob = promise.then(function (data) {
-                    return new Blob([data], { type: image.mimeType });
-                });
                 return image._blob;
             };
-            /** @hidden */
             GLTFLoader.prototype._loadUriAsync = function (context, uri) {
                 var _this = this;
                 var promise = GLTF2.GLTFLoaderExtension._LoadUriAsync(this, context, uri);
@@ -109453,27 +109402,34 @@ var BABYLON;
                     throw new Error(context + ": Uri '" + uri + "' is invalid");
                 }
                 if (BABYLON.Tools.IsBase64(uri)) {
-                    return Promise.resolve(new Uint8Array(BABYLON.Tools.DecodeBase64(uri)));
+                    var data = new Uint8Array(BABYLON.Tools.DecodeBase64(uri));
+                    this._parent._log("Decoded " + uri.substr(0, 64) + "... (" + data.length + " bytes)");
+                    return Promise.resolve(data);
                 }
-                return this.preprocessUrlAsync(this._rootUrl + uri).then(function (url) {
+                this._parent._log("Loading " + uri);
+                return this._parent.preprocessUrlAsync(this._rootUrl + uri).then(function (url) {
                     return new Promise(function (resolve, reject) {
                         if (!_this._disposed) {
-                            var request_1 = BABYLON.Tools.LoadFile(url, function (data) {
+                            var request_1 = BABYLON.Tools.LoadFile(url, function (fileData) {
                                 if (!_this._disposed) {
-                                    resolve(new Uint8Array(data));
+                                    var data = new Uint8Array(fileData);
+                                    _this._parent._log("Loaded " + uri + " (" + data.length + " bytes)");
+                                    resolve(data);
                                 }
                             }, function (event) {
                                 if (!_this._disposed) {
-                                    try {
-                                        if (request_1 && _this._state === BABYLON.GLTFLoaderState.LOADING) {
-                                            request_1._lengthComputable = event.lengthComputable;
-                                            request_1._loaded = event.loaded;
-                                            request_1._total = event.total;
+                                    if (request_1) {
+                                        request_1._lengthComputable = event.lengthComputable;
+                                        request_1._loaded = event.loaded;
+                                        request_1._total = event.total;
+                                    }
+                                    if (_this._state === BABYLON.GLTFLoaderState.LOADING) {
+                                        try {
                                             _this._onProgress();
                                         }
-                                    }
-                                    catch (e) {
-                                        reject(e);
+                                        catch (e) {
+                                            reject(e);
+                                        }
                                     }
                                 }
                             }, _this._babylonScene.database, true, function (request, exception) {
@@ -109504,7 +109460,6 @@ var BABYLON;
                 }
                 this._progressCallback(new BABYLON.SceneLoaderProgressEvent(lengthComputable, loaded, lengthComputable ? total : 0));
             };
-            /** @hidden */
             GLTFLoader._GetProperty = function (context, array, index) {
                 if (!array || index == undefined || !array[index]) {
                     throw new Error(context + ": Failed to find index (" + index + ")");
@@ -109619,7 +109574,7 @@ var BABYLON;
                                     babylonMesh.computeWorldMatrix(true);
                                     var babylonMaterial = babylonData.material;
                                     promises.push(babylonMaterial.forceCompilationAsync(babylonMesh));
-                                    if (this.useClipPlane) {
+                                    if (this._parent.useClipPlane) {
                                         promises.push(babylonMaterial.forceCompilationAsync(babylonMesh, { clipPlane: true }));
                                     }
                                 }
@@ -109641,28 +109596,6 @@ var BABYLON;
                 }
                 return Promise.all(promises).then(function () { });
             };
-            GLTFLoader.prototype._clear = function () {
-                for (var _i = 0, _a = this._requests; _i < _a.length; _i++) {
-                    var request = _a[_i];
-                    request.abort();
-                }
-                this._requests.length = 0;
-                delete this._gltf;
-                delete this._babylonScene;
-                this._completePromises.length = 0;
-                this._onReadyObservable.clear();
-                for (var name_4 in this._extensions) {
-                    this._extensions[name_4].dispose();
-                }
-                this._extensions = {};
-                delete this._rootBabylonMesh;
-                delete this._progressCallback;
-                this.onMeshLoadedObservable.clear();
-                this.onTextureLoadedObservable.clear();
-                this.onMaterialLoadedObservable.clear();
-                this.onCameraLoadedObservable.clear();
-            };
-            /** @hidden */
             GLTFLoader.prototype._applyExtensions = function (actionAsync) {
                 for (var _i = 0, _a = GLTFLoader._ExtensionNames; _i < _a.length; _i++) {
                     var name_5 = _a[_i];
@@ -109681,7 +109614,7 @@ var BABYLON;
             return GLTFLoader;
         }());
         GLTF2.GLTFLoader = GLTFLoader;
-        BABYLON.GLTFFileLoader._CreateGLTFLoaderV2 = function () { return new GLTFLoader(); };
+        BABYLON.GLTFFileLoader._CreateGLTFLoaderV2 = function (parent) { return new GLTFLoader(parent); };
     })(GLTF2 = BABYLON.GLTF2 || (BABYLON.GLTF2 = {}));
 })(BABYLON || (BABYLON = {}));
 
@@ -109883,6 +109816,7 @@ var BABYLON;
                     _this._loader._onReadyObservable.addOnce(function () {
                         var _loop_1 = function (indexLOD) {
                             Promise.all(_this._loadNodePromises[indexLOD]).then(function () {
+                                _this._loader._parent._log("Loaded node LOD " + indexLOD);
                                 _this.onNodeLODsLoadedObservable.notifyObservers(indexLOD);
                             });
                         };
@@ -109891,6 +109825,7 @@ var BABYLON;
                         }
                         var _loop_2 = function (indexLOD) {
                             Promise.all(_this._loadMaterialPromises[indexLOD]).then(function () {
+                                _this._loader._parent._log("Loaded material LOD " + indexLOD);
                                 _this.onMaterialLODsLoadedObservable.notifyObservers(indexLOD);
                             });
                         };
@@ -109914,6 +109849,7 @@ var BABYLON;
                     return this._loadExtensionAsync(context, node, function (extensionContext, extension) {
                         var firstPromise;
                         var nodeLODs = _this._getLODs(extensionContext, node, _this._loader._gltf.nodes, extension.ids);
+                        _this._loader._parent._logOpen("" + extensionContext);
                         var _loop_3 = function (indexLOD) {
                             var nodeLOD = nodeLODs[indexLOD];
                             if (indexLOD !== 0) {
@@ -109951,6 +109887,7 @@ var BABYLON;
                         for (var indexLOD = 0; indexLOD < nodeLODs.length; indexLOD++) {
                             _loop_3(indexLOD);
                         }
+                        _this._loader._parent._logClose();
                         return firstPromise;
                     });
                 };
@@ -109963,6 +109900,7 @@ var BABYLON;
                     return this._loadExtensionAsync(context, material, function (extensionContext, extension) {
                         var firstPromise;
                         var materialLODs = _this._getLODs(extensionContext, material, _this._loader._gltf.materials, extension.ids);
+                        _this._loader._parent._logOpen("" + extensionContext);
                         var _loop_4 = function (indexLOD) {
                             var materialLOD = materialLODs[indexLOD];
                             if (indexLOD !== 0) {
@@ -110002,11 +109940,17 @@ var BABYLON;
                         for (var indexLOD = 0; indexLOD < materialLODs.length; indexLOD++) {
                             _loop_4(indexLOD);
                         }
+                        _this._loader._parent._logClose();
                         return firstPromise;
                     });
                 };
                 MSFT_lod.prototype._loadUriAsync = function (context, uri) {
                     var _this = this;
+                    if (this._loadingMaterialLOD || this._loadingNodeLOD) {
+                        if (this._loader._parent.loggingEnabled) {
+                            this._loader._parent._log("deferred");
+                        }
+                    }
                     // Defer the loading of uris if loading a material or node LOD.
                     if (this._loadingMaterialLOD) {
                         var index = this._loadingMaterialLOD._index;
@@ -110258,7 +110202,7 @@ var BABYLON;
                             var babylonMaterial = _this._loader._createMaterial(name_1, babylonDrawMode);
                             promises.push(_this._loader._loadMaterialBasePropertiesAsync(context, material, babylonMaterial));
                             promises.push(_this._loadSpecularGlossinessPropertiesAsync(extensionContext, material, extension, babylonMaterial));
-                            _this._loader.onMaterialLoadedObservable.notifyObservers(babylonMaterial);
+                            _this._loader._parent.onMaterialLoadedObservable.notifyObservers(babylonMaterial);
                             babylonData = {
                                 material: babylonMaterial,
                                 meshes: [],
@@ -110336,7 +110280,7 @@ var BABYLON;
                             var babylonMaterial = _this._loader._createMaterial(name_1, babylonDrawMode);
                             babylonMaterial.unlit = true;
                             var promise = _this._loadUnlitPropertiesAsync(context, material, babylonMaterial);
-                            _this._loader.onMaterialLoadedObservable.notifyObservers(babylonMaterial);
+                            _this._loader._parent.onMaterialLoadedObservable.notifyObservers(babylonMaterial);
                             babylonData = {
                                 material: babylonMaterial,
                                 meshes: [],