فهرست منبع

Added multiple then support for promises polyfill

David Catuhe 7 سال پیش
والد
کامیت
6e63fe1f1c

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


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


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


+ 191 - 131
dist/preview release/babylon.max.js

@@ -153,28 +153,31 @@ var __extends = (this && this.__extends) || (function () {
             else {
                 fragmentSource = baseName.fragment || baseName;
             }
-            this._loadVertexShader(vertexSource, function (vertexCode) {
-                _this._processIncludes(vertexCode, function (vertexCodeWithIncludes) {
-                    _this._processShaderConversion(vertexCodeWithIncludes, false, function (migratedVertexCode) {
-                        _this._loadFragmentShader(fragmentSource, function (fragmentCode) {
-                            _this._processIncludes(fragmentCode, function (fragmentCodeWithIncludes) {
-                                _this._processShaderConversion(fragmentCodeWithIncludes, true, function (migratedFragmentCode) {
-                                    if (baseName) {
-                                        var vertex = baseName.vertexElement || baseName.vertex || baseName;
-                                        var fragment = baseName.fragmentElement || baseName.fragment || baseName;
-                                        _this._vertexSourceCode = "#define SHADER_NAME vertex:" + vertex + "\n" + migratedVertexCode;
-                                        _this._fragmentSourceCode = "#define SHADER_NAME fragment:" + fragment + "\n" + migratedFragmentCode;
-                                    }
-                                    else {
-                                        _this._vertexSourceCode = migratedVertexCode;
-                                        _this._fragmentSourceCode = migratedFragmentCode;
-                                    }
-                                    _this._prepareEffect();
-                                });
-                            });
-                        });
-                    });
-                });
+            var finalVertexCode;
+            this._loadVertexShaderAsync(vertexSource)
+                .then(function (vertexCode) {
+                return _this._processIncludesAsync(vertexCode);
+            })
+                .then(function (vertexCodeWithIncludes) {
+                finalVertexCode = _this._processShaderConversion(vertexCodeWithIncludes, false);
+                return _this._loadFragmentShaderAsync(fragmentSource);
+            })
+                .then(function (fragmentCode) {
+                return _this._processIncludesAsync(fragmentCode);
+            })
+                .then(function (fragmentCodeWithIncludes) {
+                var migratedFragmentCode = _this._processShaderConversion(fragmentCodeWithIncludes, true);
+                if (baseName) {
+                    var vertex = baseName.vertexElement || baseName.vertex || baseName;
+                    var fragment = baseName.fragmentElement || baseName.fragment || baseName;
+                    _this._vertexSourceCode = "#define SHADER_NAME vertex:" + vertex + "\n" + finalVertexCode;
+                    _this._fragmentSourceCode = "#define SHADER_NAME fragment:" + fragment + "\n" + migratedFragmentCode;
+                }
+                else {
+                    _this._vertexSourceCode = finalVertexCode;
+                    _this._fragmentSourceCode = migratedFragmentCode;
+                }
+                _this._prepareEffect();
             });
         }
         Object.defineProperty(Effect.prototype, "key", {
@@ -229,25 +232,23 @@ var __extends = (this && this.__extends) || (function () {
                 func(effect);
             });
         };
-        Effect.prototype._loadVertexShader = function (vertex, callback) {
+        /** @ignore */
+        Effect.prototype._loadVertexShaderAsync = function (vertex) {
             if (BABYLON.Tools.IsWindowObjectExist()) {
                 // DOM element ?
                 if (vertex instanceof HTMLElement) {
                     var vertexCode = BABYLON.Tools.GetDOMTextContent(vertex);
-                    callback(vertexCode);
-                    return;
+                    return Promise.resolve(vertexCode);
                 }
             }
             // Base64 encoded ?
             if (vertex.substr(0, 7) === "base64:") {
                 var vertexBinary = window.atob(vertex.substr(7));
-                callback(vertexBinary);
-                return;
+                return Promise.resolve(vertexBinary);
             }
             // Is in local store ?
             if (Effect.ShadersStore[vertex + "VertexShader"]) {
-                callback(Effect.ShadersStore[vertex + "VertexShader"]);
-                return;
+                return Promise.resolve(Effect.ShadersStore[vertex + "VertexShader"]);
             }
             var vertexShaderUrl;
             if (vertex[0] === "." || vertex[0] === "/" || vertex.indexOf("http") > -1) {
@@ -257,31 +258,28 @@ var __extends = (this && this.__extends) || (function () {
                 vertexShaderUrl = BABYLON.Engine.ShadersRepository + vertex;
             }
             // Vertex shader
-            this._engine._loadFile(vertexShaderUrl + ".vertex.fx", callback);
+            return this._engine._loadFileAsync(vertexShaderUrl + ".vertex.fx");
         };
-        Effect.prototype._loadFragmentShader = function (fragment, callback) {
+        /** @ignore */
+        Effect.prototype._loadFragmentShaderAsync = function (fragment) {
             if (BABYLON.Tools.IsWindowObjectExist()) {
                 // DOM element ?
                 if (fragment instanceof HTMLElement) {
                     var fragmentCode = BABYLON.Tools.GetDOMTextContent(fragment);
-                    callback(fragmentCode);
-                    return;
+                    return Promise.resolve(fragmentCode);
                 }
             }
             // Base64 encoded ?
             if (fragment.substr(0, 7) === "base64:") {
                 var fragmentBinary = window.atob(fragment.substr(7));
-                callback(fragmentBinary);
-                return;
+                return Promise.resolve(fragmentBinary);
             }
             // Is in local store ?
             if (Effect.ShadersStore[fragment + "PixelShader"]) {
-                callback(Effect.ShadersStore[fragment + "PixelShader"]);
-                return;
+                return Promise.resolve(Effect.ShadersStore[fragment + "PixelShader"]);
             }
             if (Effect.ShadersStore[fragment + "FragmentShader"]) {
-                callback(Effect.ShadersStore[fragment + "FragmentShader"]);
-                return;
+                return Promise.resolve(Effect.ShadersStore[fragment + "FragmentShader"]);
             }
             var fragmentShaderUrl;
             if (fragment[0] === "." || fragment[0] === "/" || fragment.indexOf("http") > -1) {
@@ -291,7 +289,7 @@ var __extends = (this && this.__extends) || (function () {
                 fragmentShaderUrl = BABYLON.Engine.ShadersRepository + fragment;
             }
             // Fragment shader
-            this._engine._loadFile(fragmentShaderUrl + ".fragment.fx", callback);
+            return this._engine._loadFileAsync(fragmentShaderUrl + ".fragment.fx");
         };
         Effect.prototype._dumpShadersSource = function (vertexCode, fragmentCode, defines) {
             // Rebuild shaders source code
@@ -320,16 +318,14 @@ var __extends = (this && this.__extends) || (function () {
             }
         };
         ;
-        Effect.prototype._processShaderConversion = function (sourceCode, isFragment, callback) {
+        Effect.prototype._processShaderConversion = function (sourceCode, isFragment) {
             var preparedSourceCode = this._processPrecision(sourceCode);
             if (this._engine.webGLVersion == 1) {
-                callback(preparedSourceCode);
-                return;
+                return preparedSourceCode;
             }
             // Already converted
             if (preparedSourceCode.indexOf("#version 3") !== -1) {
-                callback(preparedSourceCode.replace("#version 300 es", ""));
-                return;
+                return preparedSourceCode.replace("#version 300 es", "");
             }
             var hasDrawBuffersExtension = preparedSourceCode.search(/#extension.+GL_EXT_draw_buffers.+require/) !== -1;
             // Remove extensions 
@@ -353,80 +349,86 @@ var __extends = (this && this.__extends) || (function () {
                 result = result.replace(/gl_FragData/g, "glFragData");
                 result = result.replace(/void\s+?main\s*\(/g, (hasDrawBuffersExtension ? "" : "out vec4 glFragColor;\n") + "void main(");
             }
-            callback(result);
+            return result;
         };
-        Effect.prototype._processIncludes = function (sourceCode, callback) {
+        Effect.prototype._processIncludesAsync = function (sourceCode) {
             var _this = this;
-            var regex = /#include<(.+)>(\((.*)\))*(\[(.*)\])*/g;
-            var match = regex.exec(sourceCode);
-            var returnValue = new String(sourceCode);
-            while (match != null) {
-                var includeFile = match[1];
-                // Uniform declaration
-                if (includeFile.indexOf("__decl__") !== -1) {
-                    includeFile = includeFile.replace(/__decl__/, "");
-                    if (this._engine.supportsUniformBuffers) {
-                        includeFile = includeFile.replace(/Vertex/, "Ubo");
-                        includeFile = includeFile.replace(/Fragment/, "Ubo");
-                    }
-                    includeFile = includeFile + "Declaration";
-                }
-                if (Effect.IncludesShadersStore[includeFile]) {
-                    // Substitution
-                    var includeContent = Effect.IncludesShadersStore[includeFile];
-                    if (match[2]) {
-                        var splits = match[3].split(",");
-                        for (var index = 0; index < splits.length; index += 2) {
-                            var source = new RegExp(splits[index], "g");
-                            var dest = splits[index + 1];
-                            includeContent = includeContent.replace(source, dest);
+            return new Promise(function (resolve, reject) {
+                var regex = /#include<(.+)>(\((.*)\))*(\[(.*)\])*/g;
+                var match = regex.exec(sourceCode);
+                var returnValue = sourceCode;
+                while (match != null) {
+                    var includeFile = match[1];
+                    // Uniform declaration
+                    if (includeFile.indexOf("__decl__") !== -1) {
+                        includeFile = includeFile.replace(/__decl__/, "");
+                        if (_this._engine.supportsUniformBuffers) {
+                            includeFile = includeFile.replace(/Vertex/, "Ubo");
+                            includeFile = includeFile.replace(/Fragment/, "Ubo");
                         }
-                    }
-                    if (match[4]) {
-                        var indexString = match[5];
-                        if (indexString.indexOf("..") !== -1) {
-                            var indexSplits = indexString.split("..");
-                            var minIndex = parseInt(indexSplits[0]);
-                            var maxIndex = parseInt(indexSplits[1]);
-                            var sourceIncludeContent = includeContent.slice(0);
-                            includeContent = "";
-                            if (isNaN(maxIndex)) {
-                                maxIndex = this._indexParameters[indexSplits[1]];
+                        includeFile = includeFile + "Declaration";
+                    }
+                    if (Effect.IncludesShadersStore[includeFile]) {
+                        // Substitution
+                        var includeContent = Effect.IncludesShadersStore[includeFile];
+                        if (match[2]) {
+                            var splits = match[3].split(",");
+                            for (var index = 0; index < splits.length; index += 2) {
+                                var source = new RegExp(splits[index], "g");
+                                var dest = splits[index + 1];
+                                includeContent = includeContent.replace(source, dest);
                             }
-                            for (var i = minIndex; i < maxIndex; i++) {
-                                if (!this._engine.supportsUniformBuffers) {
+                        }
+                        if (match[4]) {
+                            var indexString = match[5];
+                            if (indexString.indexOf("..") !== -1) {
+                                var indexSplits = indexString.split("..");
+                                var minIndex = parseInt(indexSplits[0]);
+                                var maxIndex = parseInt(indexSplits[1]);
+                                var sourceIncludeContent = includeContent.slice(0);
+                                includeContent = "";
+                                if (isNaN(maxIndex)) {
+                                    maxIndex = _this._indexParameters[indexSplits[1]];
+                                }
+                                for (var i = minIndex; i < maxIndex; i++) {
+                                    if (!_this._engine.supportsUniformBuffers) {
+                                        // Ubo replacement
+                                        sourceIncludeContent = sourceIncludeContent.replace(/light\{X\}.(\w*)/g, function (str, p1) {
+                                            return p1 + "{X}";
+                                        });
+                                    }
+                                    includeContent += sourceIncludeContent.replace(/\{X\}/g, i.toString()) + "\n";
+                                }
+                            }
+                            else {
+                                if (!_this._engine.supportsUniformBuffers) {
                                     // Ubo replacement
-                                    sourceIncludeContent = sourceIncludeContent.replace(/light\{X\}.(\w*)/g, function (str, p1) {
+                                    includeContent = includeContent.replace(/light\{X\}.(\w*)/g, function (str, p1) {
                                         return p1 + "{X}";
                                     });
                                 }
-                                includeContent += sourceIncludeContent.replace(/\{X\}/g, i.toString()) + "\n";
+                                includeContent = includeContent.replace(/\{X\}/g, indexString);
                             }
                         }
-                        else {
-                            if (!this._engine.supportsUniformBuffers) {
-                                // Ubo replacement
-                                includeContent = includeContent.replace(/light\{X\}.(\w*)/g, function (str, p1) {
-                                    return p1 + "{X}";
-                                });
-                            }
-                            includeContent = includeContent.replace(/\{X\}/g, indexString);
-                        }
+                        // Replace
+                        returnValue = returnValue.replace(match[0], includeContent);
                     }
-                    // Replace
-                    returnValue = returnValue.replace(match[0], includeContent);
-                }
-                else {
-                    var includeShaderUrl = BABYLON.Engine.ShadersRepository + "ShadersInclude/" + includeFile + ".fx";
-                    this._engine._loadFile(includeShaderUrl, function (fileContent) {
-                        Effect.IncludesShadersStore[includeFile] = fileContent;
-                        _this._processIncludes(returnValue, callback);
-                    });
-                    return;
+                    else {
+                        var includeShaderUrl = BABYLON.Engine.ShadersRepository + "ShadersInclude/" + includeFile + ".fx";
+                        _this._engine._loadFileAsync(includeShaderUrl)
+                            .then(function (fileContent) {
+                            Effect.IncludesShadersStore[includeFile] = fileContent;
+                            return _this._processIncludesAsync(returnValue);
+                        })
+                            .then(function (returnValue) {
+                            resolve(returnValue);
+                        });
+                        return;
+                    }
+                    match = regex.exec(sourceCode);
                 }
-                match = regex.exec(sourceCode);
-            }
-            callback(returnValue);
+                resolve(returnValue);
+            });
         };
         Effect.prototype._processPrecision = function (source) {
             if (source.indexOf("precision highp float") === -1) {
@@ -8292,6 +8294,7 @@ var BABYLON;
         function InternalPromise(resolver) {
             var _this = this;
             this._state = PromiseStates.Pending;
+            this._children = new Array();
             this._rejectWasConsumed = false;
             if (!resolver) {
                 return;
@@ -8314,23 +8317,35 @@ var BABYLON;
             enumerable: true,
             configurable: true
         });
-        InternalPromise.prototype.isFulfilled = function () {
-            return this._state === PromiseStates.Fulfilled;
-        };
-        InternalPromise.prototype.isRejected = function () {
-            return this._state === PromiseStates.Rejected;
-        };
-        InternalPromise.prototype.isPending = function () {
-            return this._state === PromiseStates.Pending;
-        };
+        Object.defineProperty(InternalPromise.prototype, "isFulfilled", {
+            get: function () {
+                return this._state === PromiseStates.Fulfilled;
+            },
+            enumerable: true,
+            configurable: true
+        });
+        Object.defineProperty(InternalPromise.prototype, "isRejected", {
+            get: function () {
+                return this._state === PromiseStates.Rejected;
+            },
+            enumerable: true,
+            configurable: true
+        });
+        Object.defineProperty(InternalPromise.prototype, "isPending", {
+            get: function () {
+                return this._state === PromiseStates.Pending;
+            },
+            enumerable: true,
+            configurable: true
+        });
         InternalPromise.prototype.value = function () {
-            if (!this.isFulfilled()) {
+            if (!this.isFulfilled) {
                 throw new Error("Promise is not fulfilled");
             }
             return this._result;
         };
         InternalPromise.prototype.reason = function () {
-            if (!this.isRejected()) {
+            if (!this.isRejected) {
                 throw new Error("Promise is not rejected");
             }
             return this._reason;
@@ -8343,14 +8358,14 @@ var BABYLON;
             newPromise._onFulfilled = onFulfilled;
             newPromise._onRejected = onRejected;
             // Composition
-            this._child = newPromise;
+            this._children.push(newPromise);
             if (this._state !== PromiseStates.Pending) {
                 if (this._state === PromiseStates.Fulfilled || this._rejectWasConsumed) {
                     var returnedValue = newPromise._resolve(this._result);
                     if (returnedValue !== undefined && returnedValue !== null) {
                         if (returnedValue._state !== undefined) {
                             var returnedPromise = returnedValue;
-                            newPromise._child = returnedPromise;
+                            newPromise._children.push(returnedPromise);
                             newPromise = returnedPromise;
                         }
                         else {
@@ -8364,18 +8379,41 @@ var BABYLON;
             }
             return newPromise;
         };
+        InternalPromise.prototype._moveChildren = function (children) {
+            this._children = children.splice(0, children.length);
+            if (this.isFulfilled) {
+                for (var _i = 0, _a = this._children; _i < _a.length; _i++) {
+                    var child = _a[_i];
+                    child._resolve(this._result);
+                }
+            }
+            else if (this.isRejected) {
+                for (var _b = 0, _c = this._children; _b < _c.length; _b++) {
+                    var child = _c[_b];
+                    child._reject(this._reason);
+                }
+            }
+        };
         InternalPromise.prototype._resolve = function (value) {
             try {
                 this._state = PromiseStates.Fulfilled;
                 this._result = value;
-                var returnedPromise = null;
+                var returnedValue = null;
                 if (this._onFulfilled) {
-                    returnedPromise = this._onFulfilled(value);
+                    returnedValue = this._onFulfilled(value);
                 }
-                if (this._child) {
-                    this._child._resolve(value);
+                if (returnedValue !== undefined && returnedValue !== null) {
+                    if (returnedValue._state !== undefined) {
+                        // Transmit children
+                        var returnedPromise = returnedValue;
+                        returnedPromise._moveChildren(this._children);
+                    }
                 }
-                return returnedPromise;
+                for (var _i = 0, _a = this._children; _i < _a.length; _i++) {
+                    var child = _a[_i];
+                    child._resolve(value);
+                }
+                return returnedValue;
             }
             catch (e) {
                 this._reject(e.message);
@@ -8389,12 +8427,13 @@ var BABYLON;
                 this._onRejected(reason);
                 this._rejectWasConsumed = true;
             }
-            if (this._child) {
+            for (var _i = 0, _a = this._children; _i < _a.length; _i++) {
+                var child = _a[_i];
                 if (this._rejectWasConsumed) {
-                    this._child._resolve(null);
+                    child._resolve(null);
                 }
                 else {
-                    this._child._reject(reason);
+                    child._reject(reason);
                 }
             }
         };
@@ -9846,7 +9885,7 @@ var BABYLON;
         });
         Object.defineProperty(Engine, "Version", {
             get: function () {
-                return "3.2.0-alpha5";
+                return "3.2.0-alpha6";
             },
             enumerable: true,
             configurable: true
@@ -13809,6 +13848,17 @@ var BABYLON;
             });
             return request;
         };
+        /** @ignore */
+        Engine.prototype._loadFileAsync = function (url, database, useArrayBuffer) {
+            var _this = this;
+            return new Promise(function (resolve, reject) {
+                _this._loadFile(url, function (data) {
+                    resolve(data);
+                }, undefined, database, useArrayBuffer, function (request, exception) {
+                    reject(exception);
+                });
+            });
+        };
         Engine.prototype._partialLoadFile = function (url, index, loadedFiles, scene, onfinish, onErrorCallBack) {
             if (onErrorCallBack === void 0) { onErrorCallBack = null; }
             var onload = function (data) {
@@ -23547,6 +23597,17 @@ var BABYLON;
             });
             return request;
         };
+        /** @ignore */
+        Scene.prototype._loadFileAsync = function (url, useDatabase, useArrayBuffer) {
+            var _this = this;
+            return new Promise(function (resolve, reject) {
+                _this._loadFile(url, function (data) {
+                    resolve(data);
+                }, undefined, useDatabase, useArrayBuffer, function (request, exception) {
+                    reject(exception);
+                });
+            });
+        };
         // Statics
         Scene._FOGMODE_NONE = 0;
         Scene._FOGMODE_EXP = 1;
@@ -55035,9 +55096,8 @@ var BABYLON;
                     _this._generateMipMaps = false;
                 }
                 _this._texture = _this._engine.createDynamicTexture(_this.video.videoWidth, _this.video.videoHeight, _this._generateMipMaps, _this._samplingMode);
-                _this._texture.width;
-                _this._updateInternalTexture();
                 _this._texture.isReady = true;
+                _this._updateInternalTexture();
             };
             _this.reset = function () {
                 if (_this._texture == null) {

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


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


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


+ 192 - 132
dist/preview release/customConfigurations/minimalGLTFViewer/babylon.max.js

@@ -153,28 +153,31 @@ var __extends = (this && this.__extends) || (function () {
             else {
                 fragmentSource = baseName.fragment || baseName;
             }
-            this._loadVertexShader(vertexSource, function (vertexCode) {
-                _this._processIncludes(vertexCode, function (vertexCodeWithIncludes) {
-                    _this._processShaderConversion(vertexCodeWithIncludes, false, function (migratedVertexCode) {
-                        _this._loadFragmentShader(fragmentSource, function (fragmentCode) {
-                            _this._processIncludes(fragmentCode, function (fragmentCodeWithIncludes) {
-                                _this._processShaderConversion(fragmentCodeWithIncludes, true, function (migratedFragmentCode) {
-                                    if (baseName) {
-                                        var vertex = baseName.vertexElement || baseName.vertex || baseName;
-                                        var fragment = baseName.fragmentElement || baseName.fragment || baseName;
-                                        _this._vertexSourceCode = "#define SHADER_NAME vertex:" + vertex + "\n" + migratedVertexCode;
-                                        _this._fragmentSourceCode = "#define SHADER_NAME fragment:" + fragment + "\n" + migratedFragmentCode;
-                                    }
-                                    else {
-                                        _this._vertexSourceCode = migratedVertexCode;
-                                        _this._fragmentSourceCode = migratedFragmentCode;
-                                    }
-                                    _this._prepareEffect();
-                                });
-                            });
-                        });
-                    });
-                });
+            var finalVertexCode;
+            this._loadVertexShaderAsync(vertexSource)
+                .then(function (vertexCode) {
+                return _this._processIncludesAsync(vertexCode);
+            })
+                .then(function (vertexCodeWithIncludes) {
+                finalVertexCode = _this._processShaderConversion(vertexCodeWithIncludes, false);
+                return _this._loadFragmentShaderAsync(fragmentSource);
+            })
+                .then(function (fragmentCode) {
+                return _this._processIncludesAsync(fragmentCode);
+            })
+                .then(function (fragmentCodeWithIncludes) {
+                var migratedFragmentCode = _this._processShaderConversion(fragmentCodeWithIncludes, true);
+                if (baseName) {
+                    var vertex = baseName.vertexElement || baseName.vertex || baseName;
+                    var fragment = baseName.fragmentElement || baseName.fragment || baseName;
+                    _this._vertexSourceCode = "#define SHADER_NAME vertex:" + vertex + "\n" + finalVertexCode;
+                    _this._fragmentSourceCode = "#define SHADER_NAME fragment:" + fragment + "\n" + migratedFragmentCode;
+                }
+                else {
+                    _this._vertexSourceCode = finalVertexCode;
+                    _this._fragmentSourceCode = migratedFragmentCode;
+                }
+                _this._prepareEffect();
             });
         }
         Object.defineProperty(Effect.prototype, "key", {
@@ -229,25 +232,23 @@ var __extends = (this && this.__extends) || (function () {
                 func(effect);
             });
         };
-        Effect.prototype._loadVertexShader = function (vertex, callback) {
+        /** @ignore */
+        Effect.prototype._loadVertexShaderAsync = function (vertex) {
             if (BABYLON.Tools.IsWindowObjectExist()) {
                 // DOM element ?
                 if (vertex instanceof HTMLElement) {
                     var vertexCode = BABYLON.Tools.GetDOMTextContent(vertex);
-                    callback(vertexCode);
-                    return;
+                    return Promise.resolve(vertexCode);
                 }
             }
             // Base64 encoded ?
             if (vertex.substr(0, 7) === "base64:") {
                 var vertexBinary = window.atob(vertex.substr(7));
-                callback(vertexBinary);
-                return;
+                return Promise.resolve(vertexBinary);
             }
             // Is in local store ?
             if (Effect.ShadersStore[vertex + "VertexShader"]) {
-                callback(Effect.ShadersStore[vertex + "VertexShader"]);
-                return;
+                return Promise.resolve(Effect.ShadersStore[vertex + "VertexShader"]);
             }
             var vertexShaderUrl;
             if (vertex[0] === "." || vertex[0] === "/" || vertex.indexOf("http") > -1) {
@@ -257,31 +258,28 @@ var __extends = (this && this.__extends) || (function () {
                 vertexShaderUrl = BABYLON.Engine.ShadersRepository + vertex;
             }
             // Vertex shader
-            this._engine._loadFile(vertexShaderUrl + ".vertex.fx", callback);
+            return this._engine._loadFileAsync(vertexShaderUrl + ".vertex.fx");
         };
-        Effect.prototype._loadFragmentShader = function (fragment, callback) {
+        /** @ignore */
+        Effect.prototype._loadFragmentShaderAsync = function (fragment) {
             if (BABYLON.Tools.IsWindowObjectExist()) {
                 // DOM element ?
                 if (fragment instanceof HTMLElement) {
                     var fragmentCode = BABYLON.Tools.GetDOMTextContent(fragment);
-                    callback(fragmentCode);
-                    return;
+                    return Promise.resolve(fragmentCode);
                 }
             }
             // Base64 encoded ?
             if (fragment.substr(0, 7) === "base64:") {
                 var fragmentBinary = window.atob(fragment.substr(7));
-                callback(fragmentBinary);
-                return;
+                return Promise.resolve(fragmentBinary);
             }
             // Is in local store ?
             if (Effect.ShadersStore[fragment + "PixelShader"]) {
-                callback(Effect.ShadersStore[fragment + "PixelShader"]);
-                return;
+                return Promise.resolve(Effect.ShadersStore[fragment + "PixelShader"]);
             }
             if (Effect.ShadersStore[fragment + "FragmentShader"]) {
-                callback(Effect.ShadersStore[fragment + "FragmentShader"]);
-                return;
+                return Promise.resolve(Effect.ShadersStore[fragment + "FragmentShader"]);
             }
             var fragmentShaderUrl;
             if (fragment[0] === "." || fragment[0] === "/" || fragment.indexOf("http") > -1) {
@@ -291,7 +289,7 @@ var __extends = (this && this.__extends) || (function () {
                 fragmentShaderUrl = BABYLON.Engine.ShadersRepository + fragment;
             }
             // Fragment shader
-            this._engine._loadFile(fragmentShaderUrl + ".fragment.fx", callback);
+            return this._engine._loadFileAsync(fragmentShaderUrl + ".fragment.fx");
         };
         Effect.prototype._dumpShadersSource = function (vertexCode, fragmentCode, defines) {
             // Rebuild shaders source code
@@ -320,16 +318,14 @@ var __extends = (this && this.__extends) || (function () {
             }
         };
         ;
-        Effect.prototype._processShaderConversion = function (sourceCode, isFragment, callback) {
+        Effect.prototype._processShaderConversion = function (sourceCode, isFragment) {
             var preparedSourceCode = this._processPrecision(sourceCode);
             if (this._engine.webGLVersion == 1) {
-                callback(preparedSourceCode);
-                return;
+                return preparedSourceCode;
             }
             // Already converted
             if (preparedSourceCode.indexOf("#version 3") !== -1) {
-                callback(preparedSourceCode.replace("#version 300 es", ""));
-                return;
+                return preparedSourceCode.replace("#version 300 es", "");
             }
             var hasDrawBuffersExtension = preparedSourceCode.search(/#extension.+GL_EXT_draw_buffers.+require/) !== -1;
             // Remove extensions 
@@ -353,80 +349,86 @@ var __extends = (this && this.__extends) || (function () {
                 result = result.replace(/gl_FragData/g, "glFragData");
                 result = result.replace(/void\s+?main\s*\(/g, (hasDrawBuffersExtension ? "" : "out vec4 glFragColor;\n") + "void main(");
             }
-            callback(result);
+            return result;
         };
-        Effect.prototype._processIncludes = function (sourceCode, callback) {
+        Effect.prototype._processIncludesAsync = function (sourceCode) {
             var _this = this;
-            var regex = /#include<(.+)>(\((.*)\))*(\[(.*)\])*/g;
-            var match = regex.exec(sourceCode);
-            var returnValue = new String(sourceCode);
-            while (match != null) {
-                var includeFile = match[1];
-                // Uniform declaration
-                if (includeFile.indexOf("__decl__") !== -1) {
-                    includeFile = includeFile.replace(/__decl__/, "");
-                    if (this._engine.supportsUniformBuffers) {
-                        includeFile = includeFile.replace(/Vertex/, "Ubo");
-                        includeFile = includeFile.replace(/Fragment/, "Ubo");
-                    }
-                    includeFile = includeFile + "Declaration";
-                }
-                if (Effect.IncludesShadersStore[includeFile]) {
-                    // Substitution
-                    var includeContent = Effect.IncludesShadersStore[includeFile];
-                    if (match[2]) {
-                        var splits = match[3].split(",");
-                        for (var index = 0; index < splits.length; index += 2) {
-                            var source = new RegExp(splits[index], "g");
-                            var dest = splits[index + 1];
-                            includeContent = includeContent.replace(source, dest);
-                        }
-                    }
-                    if (match[4]) {
-                        var indexString = match[5];
-                        if (indexString.indexOf("..") !== -1) {
-                            var indexSplits = indexString.split("..");
-                            var minIndex = parseInt(indexSplits[0]);
-                            var maxIndex = parseInt(indexSplits[1]);
-                            var sourceIncludeContent = includeContent.slice(0);
-                            includeContent = "";
-                            if (isNaN(maxIndex)) {
-                                maxIndex = this._indexParameters[indexSplits[1]];
+            return new Promise(function (resolve, reject) {
+                var regex = /#include<(.+)>(\((.*)\))*(\[(.*)\])*/g;
+                var match = regex.exec(sourceCode);
+                var returnValue = sourceCode;
+                while (match != null) {
+                    var includeFile = match[1];
+                    // Uniform declaration
+                    if (includeFile.indexOf("__decl__") !== -1) {
+                        includeFile = includeFile.replace(/__decl__/, "");
+                        if (_this._engine.supportsUniformBuffers) {
+                            includeFile = includeFile.replace(/Vertex/, "Ubo");
+                            includeFile = includeFile.replace(/Fragment/, "Ubo");
+                        }
+                        includeFile = includeFile + "Declaration";
+                    }
+                    if (Effect.IncludesShadersStore[includeFile]) {
+                        // Substitution
+                        var includeContent = Effect.IncludesShadersStore[includeFile];
+                        if (match[2]) {
+                            var splits = match[3].split(",");
+                            for (var index = 0; index < splits.length; index += 2) {
+                                var source = new RegExp(splits[index], "g");
+                                var dest = splits[index + 1];
+                                includeContent = includeContent.replace(source, dest);
                             }
-                            for (var i = minIndex; i < maxIndex; i++) {
-                                if (!this._engine.supportsUniformBuffers) {
+                        }
+                        if (match[4]) {
+                            var indexString = match[5];
+                            if (indexString.indexOf("..") !== -1) {
+                                var indexSplits = indexString.split("..");
+                                var minIndex = parseInt(indexSplits[0]);
+                                var maxIndex = parseInt(indexSplits[1]);
+                                var sourceIncludeContent = includeContent.slice(0);
+                                includeContent = "";
+                                if (isNaN(maxIndex)) {
+                                    maxIndex = _this._indexParameters[indexSplits[1]];
+                                }
+                                for (var i = minIndex; i < maxIndex; i++) {
+                                    if (!_this._engine.supportsUniformBuffers) {
+                                        // Ubo replacement
+                                        sourceIncludeContent = sourceIncludeContent.replace(/light\{X\}.(\w*)/g, function (str, p1) {
+                                            return p1 + "{X}";
+                                        });
+                                    }
+                                    includeContent += sourceIncludeContent.replace(/\{X\}/g, i.toString()) + "\n";
+                                }
+                            }
+                            else {
+                                if (!_this._engine.supportsUniformBuffers) {
                                     // Ubo replacement
-                                    sourceIncludeContent = sourceIncludeContent.replace(/light\{X\}.(\w*)/g, function (str, p1) {
+                                    includeContent = includeContent.replace(/light\{X\}.(\w*)/g, function (str, p1) {
                                         return p1 + "{X}";
                                     });
                                 }
-                                includeContent += sourceIncludeContent.replace(/\{X\}/g, i.toString()) + "\n";
+                                includeContent = includeContent.replace(/\{X\}/g, indexString);
                             }
                         }
-                        else {
-                            if (!this._engine.supportsUniformBuffers) {
-                                // Ubo replacement
-                                includeContent = includeContent.replace(/light\{X\}.(\w*)/g, function (str, p1) {
-                                    return p1 + "{X}";
-                                });
-                            }
-                            includeContent = includeContent.replace(/\{X\}/g, indexString);
-                        }
+                        // Replace
+                        returnValue = returnValue.replace(match[0], includeContent);
                     }
-                    // Replace
-                    returnValue = returnValue.replace(match[0], includeContent);
-                }
-                else {
-                    var includeShaderUrl = BABYLON.Engine.ShadersRepository + "ShadersInclude/" + includeFile + ".fx";
-                    this._engine._loadFile(includeShaderUrl, function (fileContent) {
-                        Effect.IncludesShadersStore[includeFile] = fileContent;
-                        _this._processIncludes(returnValue, callback);
-                    });
-                    return;
+                    else {
+                        var includeShaderUrl = BABYLON.Engine.ShadersRepository + "ShadersInclude/" + includeFile + ".fx";
+                        _this._engine._loadFileAsync(includeShaderUrl)
+                            .then(function (fileContent) {
+                            Effect.IncludesShadersStore[includeFile] = fileContent;
+                            return _this._processIncludesAsync(returnValue);
+                        })
+                            .then(function (returnValue) {
+                            resolve(returnValue);
+                        });
+                        return;
+                    }
+                    match = regex.exec(sourceCode);
                 }
-                match = regex.exec(sourceCode);
-            }
-            callback(returnValue);
+                resolve(returnValue);
+            });
         };
         Effect.prototype._processPrecision = function (source) {
             if (source.indexOf("precision highp float") === -1) {
@@ -8292,6 +8294,7 @@ var BABYLON;
         function InternalPromise(resolver) {
             var _this = this;
             this._state = PromiseStates.Pending;
+            this._children = new Array();
             this._rejectWasConsumed = false;
             if (!resolver) {
                 return;
@@ -8314,23 +8317,35 @@ var BABYLON;
             enumerable: true,
             configurable: true
         });
-        InternalPromise.prototype.isFulfilled = function () {
-            return this._state === PromiseStates.Fulfilled;
-        };
-        InternalPromise.prototype.isRejected = function () {
-            return this._state === PromiseStates.Rejected;
-        };
-        InternalPromise.prototype.isPending = function () {
-            return this._state === PromiseStates.Pending;
-        };
+        Object.defineProperty(InternalPromise.prototype, "isFulfilled", {
+            get: function () {
+                return this._state === PromiseStates.Fulfilled;
+            },
+            enumerable: true,
+            configurable: true
+        });
+        Object.defineProperty(InternalPromise.prototype, "isRejected", {
+            get: function () {
+                return this._state === PromiseStates.Rejected;
+            },
+            enumerable: true,
+            configurable: true
+        });
+        Object.defineProperty(InternalPromise.prototype, "isPending", {
+            get: function () {
+                return this._state === PromiseStates.Pending;
+            },
+            enumerable: true,
+            configurable: true
+        });
         InternalPromise.prototype.value = function () {
-            if (!this.isFulfilled()) {
+            if (!this.isFulfilled) {
                 throw new Error("Promise is not fulfilled");
             }
             return this._result;
         };
         InternalPromise.prototype.reason = function () {
-            if (!this.isRejected()) {
+            if (!this.isRejected) {
                 throw new Error("Promise is not rejected");
             }
             return this._reason;
@@ -8343,14 +8358,14 @@ var BABYLON;
             newPromise._onFulfilled = onFulfilled;
             newPromise._onRejected = onRejected;
             // Composition
-            this._child = newPromise;
+            this._children.push(newPromise);
             if (this._state !== PromiseStates.Pending) {
                 if (this._state === PromiseStates.Fulfilled || this._rejectWasConsumed) {
                     var returnedValue = newPromise._resolve(this._result);
                     if (returnedValue !== undefined && returnedValue !== null) {
                         if (returnedValue._state !== undefined) {
                             var returnedPromise = returnedValue;
-                            newPromise._child = returnedPromise;
+                            newPromise._children.push(returnedPromise);
                             newPromise = returnedPromise;
                         }
                         else {
@@ -8364,18 +8379,41 @@ var BABYLON;
             }
             return newPromise;
         };
+        InternalPromise.prototype._moveChildren = function (children) {
+            this._children = children.splice(0, children.length);
+            if (this.isFulfilled) {
+                for (var _i = 0, _a = this._children; _i < _a.length; _i++) {
+                    var child = _a[_i];
+                    child._resolve(this._result);
+                }
+            }
+            else if (this.isRejected) {
+                for (var _b = 0, _c = this._children; _b < _c.length; _b++) {
+                    var child = _c[_b];
+                    child._reject(this._reason);
+                }
+            }
+        };
         InternalPromise.prototype._resolve = function (value) {
             try {
                 this._state = PromiseStates.Fulfilled;
                 this._result = value;
-                var returnedPromise = null;
+                var returnedValue = null;
                 if (this._onFulfilled) {
-                    returnedPromise = this._onFulfilled(value);
+                    returnedValue = this._onFulfilled(value);
                 }
-                if (this._child) {
-                    this._child._resolve(value);
+                if (returnedValue !== undefined && returnedValue !== null) {
+                    if (returnedValue._state !== undefined) {
+                        // Transmit children
+                        var returnedPromise = returnedValue;
+                        returnedPromise._moveChildren(this._children);
+                    }
                 }
-                return returnedPromise;
+                for (var _i = 0, _a = this._children; _i < _a.length; _i++) {
+                    var child = _a[_i];
+                    child._resolve(value);
+                }
+                return returnedValue;
             }
             catch (e) {
                 this._reject(e.message);
@@ -8389,12 +8427,13 @@ var BABYLON;
                 this._onRejected(reason);
                 this._rejectWasConsumed = true;
             }
-            if (this._child) {
+            for (var _i = 0, _a = this._children; _i < _a.length; _i++) {
+                var child = _a[_i];
                 if (this._rejectWasConsumed) {
-                    this._child._resolve(null);
+                    child._resolve(null);
                 }
                 else {
-                    this._child._reject(reason);
+                    child._reject(reason);
                 }
             }
         };
@@ -9846,7 +9885,7 @@ var BABYLON;
         });
         Object.defineProperty(Engine, "Version", {
             get: function () {
-                return "3.2.0-alpha5";
+                return "3.2.0-alpha6";
             },
             enumerable: true,
             configurable: true
@@ -13809,6 +13848,17 @@ var BABYLON;
             });
             return request;
         };
+        /** @ignore */
+        Engine.prototype._loadFileAsync = function (url, database, useArrayBuffer) {
+            var _this = this;
+            return new Promise(function (resolve, reject) {
+                _this._loadFile(url, function (data) {
+                    resolve(data);
+                }, undefined, database, useArrayBuffer, function (request, exception) {
+                    reject(exception);
+                });
+            });
+        };
         Engine.prototype._partialLoadFile = function (url, index, loadedFiles, scene, onfinish, onErrorCallBack) {
             if (onErrorCallBack === void 0) { onErrorCallBack = null; }
             var onload = function (data) {
@@ -23547,6 +23597,17 @@ var BABYLON;
             });
             return request;
         };
+        /** @ignore */
+        Scene.prototype._loadFileAsync = function (url, useDatabase, useArrayBuffer) {
+            var _this = this;
+            return new Promise(function (resolve, reject) {
+                _this._loadFile(url, function (data) {
+                    resolve(data);
+                }, undefined, useDatabase, useArrayBuffer, function (request, exception) {
+                    reject(exception);
+                });
+            });
+        };
         // Statics
         Scene._FOGMODE_NONE = 0;
         Scene._FOGMODE_EXP = 1;
@@ -54829,9 +54890,8 @@ var BABYLON;
                     _this._generateMipMaps = false;
                 }
                 _this._texture = _this._engine.createDynamicTexture(_this.video.videoWidth, _this.video.videoHeight, _this._generateMipMaps, _this._samplingMode);
-                _this._texture.width;
-                _this._updateInternalTexture();
                 _this._texture.isReady = true;
+                _this._updateInternalTexture();
             };
             _this.reset = function () {
                 if (_this._texture == null) {

+ 192 - 132
dist/preview release/customConfigurations/minimalGLTFViewer/es6.js

@@ -139,28 +139,31 @@ var BABYLON;
             else {
                 fragmentSource = baseName.fragment || baseName;
             }
-            this._loadVertexShader(vertexSource, function (vertexCode) {
-                _this._processIncludes(vertexCode, function (vertexCodeWithIncludes) {
-                    _this._processShaderConversion(vertexCodeWithIncludes, false, function (migratedVertexCode) {
-                        _this._loadFragmentShader(fragmentSource, function (fragmentCode) {
-                            _this._processIncludes(fragmentCode, function (fragmentCodeWithIncludes) {
-                                _this._processShaderConversion(fragmentCodeWithIncludes, true, function (migratedFragmentCode) {
-                                    if (baseName) {
-                                        var vertex = baseName.vertexElement || baseName.vertex || baseName;
-                                        var fragment = baseName.fragmentElement || baseName.fragment || baseName;
-                                        _this._vertexSourceCode = "#define SHADER_NAME vertex:" + vertex + "\n" + migratedVertexCode;
-                                        _this._fragmentSourceCode = "#define SHADER_NAME fragment:" + fragment + "\n" + migratedFragmentCode;
-                                    }
-                                    else {
-                                        _this._vertexSourceCode = migratedVertexCode;
-                                        _this._fragmentSourceCode = migratedFragmentCode;
-                                    }
-                                    _this._prepareEffect();
-                                });
-                            });
-                        });
-                    });
-                });
+            var finalVertexCode;
+            this._loadVertexShaderAsync(vertexSource)
+                .then(function (vertexCode) {
+                return _this._processIncludesAsync(vertexCode);
+            })
+                .then(function (vertexCodeWithIncludes) {
+                finalVertexCode = _this._processShaderConversion(vertexCodeWithIncludes, false);
+                return _this._loadFragmentShaderAsync(fragmentSource);
+            })
+                .then(function (fragmentCode) {
+                return _this._processIncludesAsync(fragmentCode);
+            })
+                .then(function (fragmentCodeWithIncludes) {
+                var migratedFragmentCode = _this._processShaderConversion(fragmentCodeWithIncludes, true);
+                if (baseName) {
+                    var vertex = baseName.vertexElement || baseName.vertex || baseName;
+                    var fragment = baseName.fragmentElement || baseName.fragment || baseName;
+                    _this._vertexSourceCode = "#define SHADER_NAME vertex:" + vertex + "\n" + finalVertexCode;
+                    _this._fragmentSourceCode = "#define SHADER_NAME fragment:" + fragment + "\n" + migratedFragmentCode;
+                }
+                else {
+                    _this._vertexSourceCode = finalVertexCode;
+                    _this._fragmentSourceCode = migratedFragmentCode;
+                }
+                _this._prepareEffect();
             });
         }
         Object.defineProperty(Effect.prototype, "key", {
@@ -215,25 +218,23 @@ var BABYLON;
                 func(effect);
             });
         };
-        Effect.prototype._loadVertexShader = function (vertex, callback) {
+        /** @ignore */
+        Effect.prototype._loadVertexShaderAsync = function (vertex) {
             if (BABYLON.Tools.IsWindowObjectExist()) {
                 // DOM element ?
                 if (vertex instanceof HTMLElement) {
                     var vertexCode = BABYLON.Tools.GetDOMTextContent(vertex);
-                    callback(vertexCode);
-                    return;
+                    return Promise.resolve(vertexCode);
                 }
             }
             // Base64 encoded ?
             if (vertex.substr(0, 7) === "base64:") {
                 var vertexBinary = window.atob(vertex.substr(7));
-                callback(vertexBinary);
-                return;
+                return Promise.resolve(vertexBinary);
             }
             // Is in local store ?
             if (Effect.ShadersStore[vertex + "VertexShader"]) {
-                callback(Effect.ShadersStore[vertex + "VertexShader"]);
-                return;
+                return Promise.resolve(Effect.ShadersStore[vertex + "VertexShader"]);
             }
             var vertexShaderUrl;
             if (vertex[0] === "." || vertex[0] === "/" || vertex.indexOf("http") > -1) {
@@ -243,31 +244,28 @@ var BABYLON;
                 vertexShaderUrl = BABYLON.Engine.ShadersRepository + vertex;
             }
             // Vertex shader
-            this._engine._loadFile(vertexShaderUrl + ".vertex.fx", callback);
+            return this._engine._loadFileAsync(vertexShaderUrl + ".vertex.fx");
         };
-        Effect.prototype._loadFragmentShader = function (fragment, callback) {
+        /** @ignore */
+        Effect.prototype._loadFragmentShaderAsync = function (fragment) {
             if (BABYLON.Tools.IsWindowObjectExist()) {
                 // DOM element ?
                 if (fragment instanceof HTMLElement) {
                     var fragmentCode = BABYLON.Tools.GetDOMTextContent(fragment);
-                    callback(fragmentCode);
-                    return;
+                    return Promise.resolve(fragmentCode);
                 }
             }
             // Base64 encoded ?
             if (fragment.substr(0, 7) === "base64:") {
                 var fragmentBinary = window.atob(fragment.substr(7));
-                callback(fragmentBinary);
-                return;
+                return Promise.resolve(fragmentBinary);
             }
             // Is in local store ?
             if (Effect.ShadersStore[fragment + "PixelShader"]) {
-                callback(Effect.ShadersStore[fragment + "PixelShader"]);
-                return;
+                return Promise.resolve(Effect.ShadersStore[fragment + "PixelShader"]);
             }
             if (Effect.ShadersStore[fragment + "FragmentShader"]) {
-                callback(Effect.ShadersStore[fragment + "FragmentShader"]);
-                return;
+                return Promise.resolve(Effect.ShadersStore[fragment + "FragmentShader"]);
             }
             var fragmentShaderUrl;
             if (fragment[0] === "." || fragment[0] === "/" || fragment.indexOf("http") > -1) {
@@ -277,7 +275,7 @@ var BABYLON;
                 fragmentShaderUrl = BABYLON.Engine.ShadersRepository + fragment;
             }
             // Fragment shader
-            this._engine._loadFile(fragmentShaderUrl + ".fragment.fx", callback);
+            return this._engine._loadFileAsync(fragmentShaderUrl + ".fragment.fx");
         };
         Effect.prototype._dumpShadersSource = function (vertexCode, fragmentCode, defines) {
             // Rebuild shaders source code
@@ -306,16 +304,14 @@ var BABYLON;
             }
         };
         ;
-        Effect.prototype._processShaderConversion = function (sourceCode, isFragment, callback) {
+        Effect.prototype._processShaderConversion = function (sourceCode, isFragment) {
             var preparedSourceCode = this._processPrecision(sourceCode);
             if (this._engine.webGLVersion == 1) {
-                callback(preparedSourceCode);
-                return;
+                return preparedSourceCode;
             }
             // Already converted
             if (preparedSourceCode.indexOf("#version 3") !== -1) {
-                callback(preparedSourceCode.replace("#version 300 es", ""));
-                return;
+                return preparedSourceCode.replace("#version 300 es", "");
             }
             var hasDrawBuffersExtension = preparedSourceCode.search(/#extension.+GL_EXT_draw_buffers.+require/) !== -1;
             // Remove extensions 
@@ -339,80 +335,86 @@ var BABYLON;
                 result = result.replace(/gl_FragData/g, "glFragData");
                 result = result.replace(/void\s+?main\s*\(/g, (hasDrawBuffersExtension ? "" : "out vec4 glFragColor;\n") + "void main(");
             }
-            callback(result);
+            return result;
         };
-        Effect.prototype._processIncludes = function (sourceCode, callback) {
+        Effect.prototype._processIncludesAsync = function (sourceCode) {
             var _this = this;
-            var regex = /#include<(.+)>(\((.*)\))*(\[(.*)\])*/g;
-            var match = regex.exec(sourceCode);
-            var returnValue = new String(sourceCode);
-            while (match != null) {
-                var includeFile = match[1];
-                // Uniform declaration
-                if (includeFile.indexOf("__decl__") !== -1) {
-                    includeFile = includeFile.replace(/__decl__/, "");
-                    if (this._engine.supportsUniformBuffers) {
-                        includeFile = includeFile.replace(/Vertex/, "Ubo");
-                        includeFile = includeFile.replace(/Fragment/, "Ubo");
-                    }
-                    includeFile = includeFile + "Declaration";
-                }
-                if (Effect.IncludesShadersStore[includeFile]) {
-                    // Substitution
-                    var includeContent = Effect.IncludesShadersStore[includeFile];
-                    if (match[2]) {
-                        var splits = match[3].split(",");
-                        for (var index = 0; index < splits.length; index += 2) {
-                            var source = new RegExp(splits[index], "g");
-                            var dest = splits[index + 1];
-                            includeContent = includeContent.replace(source, dest);
-                        }
-                    }
-                    if (match[4]) {
-                        var indexString = match[5];
-                        if (indexString.indexOf("..") !== -1) {
-                            var indexSplits = indexString.split("..");
-                            var minIndex = parseInt(indexSplits[0]);
-                            var maxIndex = parseInt(indexSplits[1]);
-                            var sourceIncludeContent = includeContent.slice(0);
-                            includeContent = "";
-                            if (isNaN(maxIndex)) {
-                                maxIndex = this._indexParameters[indexSplits[1]];
+            return new Promise(function (resolve, reject) {
+                var regex = /#include<(.+)>(\((.*)\))*(\[(.*)\])*/g;
+                var match = regex.exec(sourceCode);
+                var returnValue = sourceCode;
+                while (match != null) {
+                    var includeFile = match[1];
+                    // Uniform declaration
+                    if (includeFile.indexOf("__decl__") !== -1) {
+                        includeFile = includeFile.replace(/__decl__/, "");
+                        if (_this._engine.supportsUniformBuffers) {
+                            includeFile = includeFile.replace(/Vertex/, "Ubo");
+                            includeFile = includeFile.replace(/Fragment/, "Ubo");
+                        }
+                        includeFile = includeFile + "Declaration";
+                    }
+                    if (Effect.IncludesShadersStore[includeFile]) {
+                        // Substitution
+                        var includeContent = Effect.IncludesShadersStore[includeFile];
+                        if (match[2]) {
+                            var splits = match[3].split(",");
+                            for (var index = 0; index < splits.length; index += 2) {
+                                var source = new RegExp(splits[index], "g");
+                                var dest = splits[index + 1];
+                                includeContent = includeContent.replace(source, dest);
                             }
-                            for (var i = minIndex; i < maxIndex; i++) {
-                                if (!this._engine.supportsUniformBuffers) {
+                        }
+                        if (match[4]) {
+                            var indexString = match[5];
+                            if (indexString.indexOf("..") !== -1) {
+                                var indexSplits = indexString.split("..");
+                                var minIndex = parseInt(indexSplits[0]);
+                                var maxIndex = parseInt(indexSplits[1]);
+                                var sourceIncludeContent = includeContent.slice(0);
+                                includeContent = "";
+                                if (isNaN(maxIndex)) {
+                                    maxIndex = _this._indexParameters[indexSplits[1]];
+                                }
+                                for (var i = minIndex; i < maxIndex; i++) {
+                                    if (!_this._engine.supportsUniformBuffers) {
+                                        // Ubo replacement
+                                        sourceIncludeContent = sourceIncludeContent.replace(/light\{X\}.(\w*)/g, function (str, p1) {
+                                            return p1 + "{X}";
+                                        });
+                                    }
+                                    includeContent += sourceIncludeContent.replace(/\{X\}/g, i.toString()) + "\n";
+                                }
+                            }
+                            else {
+                                if (!_this._engine.supportsUniformBuffers) {
                                     // Ubo replacement
-                                    sourceIncludeContent = sourceIncludeContent.replace(/light\{X\}.(\w*)/g, function (str, p1) {
+                                    includeContent = includeContent.replace(/light\{X\}.(\w*)/g, function (str, p1) {
                                         return p1 + "{X}";
                                     });
                                 }
-                                includeContent += sourceIncludeContent.replace(/\{X\}/g, i.toString()) + "\n";
+                                includeContent = includeContent.replace(/\{X\}/g, indexString);
                             }
                         }
-                        else {
-                            if (!this._engine.supportsUniformBuffers) {
-                                // Ubo replacement
-                                includeContent = includeContent.replace(/light\{X\}.(\w*)/g, function (str, p1) {
-                                    return p1 + "{X}";
-                                });
-                            }
-                            includeContent = includeContent.replace(/\{X\}/g, indexString);
-                        }
+                        // Replace
+                        returnValue = returnValue.replace(match[0], includeContent);
                     }
-                    // Replace
-                    returnValue = returnValue.replace(match[0], includeContent);
-                }
-                else {
-                    var includeShaderUrl = BABYLON.Engine.ShadersRepository + "ShadersInclude/" + includeFile + ".fx";
-                    this._engine._loadFile(includeShaderUrl, function (fileContent) {
-                        Effect.IncludesShadersStore[includeFile] = fileContent;
-                        _this._processIncludes(returnValue, callback);
-                    });
-                    return;
+                    else {
+                        var includeShaderUrl = BABYLON.Engine.ShadersRepository + "ShadersInclude/" + includeFile + ".fx";
+                        _this._engine._loadFileAsync(includeShaderUrl)
+                            .then(function (fileContent) {
+                            Effect.IncludesShadersStore[includeFile] = fileContent;
+                            return _this._processIncludesAsync(returnValue);
+                        })
+                            .then(function (returnValue) {
+                            resolve(returnValue);
+                        });
+                        return;
+                    }
+                    match = regex.exec(sourceCode);
                 }
-                match = regex.exec(sourceCode);
-            }
-            callback(returnValue);
+                resolve(returnValue);
+            });
         };
         Effect.prototype._processPrecision = function (source) {
             if (source.indexOf("precision highp float") === -1) {
@@ -8278,6 +8280,7 @@ var BABYLON;
         function InternalPromise(resolver) {
             var _this = this;
             this._state = PromiseStates.Pending;
+            this._children = new Array();
             this._rejectWasConsumed = false;
             if (!resolver) {
                 return;
@@ -8300,23 +8303,35 @@ var BABYLON;
             enumerable: true,
             configurable: true
         });
-        InternalPromise.prototype.isFulfilled = function () {
-            return this._state === PromiseStates.Fulfilled;
-        };
-        InternalPromise.prototype.isRejected = function () {
-            return this._state === PromiseStates.Rejected;
-        };
-        InternalPromise.prototype.isPending = function () {
-            return this._state === PromiseStates.Pending;
-        };
+        Object.defineProperty(InternalPromise.prototype, "isFulfilled", {
+            get: function () {
+                return this._state === PromiseStates.Fulfilled;
+            },
+            enumerable: true,
+            configurable: true
+        });
+        Object.defineProperty(InternalPromise.prototype, "isRejected", {
+            get: function () {
+                return this._state === PromiseStates.Rejected;
+            },
+            enumerable: true,
+            configurable: true
+        });
+        Object.defineProperty(InternalPromise.prototype, "isPending", {
+            get: function () {
+                return this._state === PromiseStates.Pending;
+            },
+            enumerable: true,
+            configurable: true
+        });
         InternalPromise.prototype.value = function () {
-            if (!this.isFulfilled()) {
+            if (!this.isFulfilled) {
                 throw new Error("Promise is not fulfilled");
             }
             return this._result;
         };
         InternalPromise.prototype.reason = function () {
-            if (!this.isRejected()) {
+            if (!this.isRejected) {
                 throw new Error("Promise is not rejected");
             }
             return this._reason;
@@ -8329,14 +8344,14 @@ var BABYLON;
             newPromise._onFulfilled = onFulfilled;
             newPromise._onRejected = onRejected;
             // Composition
-            this._child = newPromise;
+            this._children.push(newPromise);
             if (this._state !== PromiseStates.Pending) {
                 if (this._state === PromiseStates.Fulfilled || this._rejectWasConsumed) {
                     var returnedValue = newPromise._resolve(this._result);
                     if (returnedValue !== undefined && returnedValue !== null) {
                         if (returnedValue._state !== undefined) {
                             var returnedPromise = returnedValue;
-                            newPromise._child = returnedPromise;
+                            newPromise._children.push(returnedPromise);
                             newPromise = returnedPromise;
                         }
                         else {
@@ -8350,18 +8365,41 @@ var BABYLON;
             }
             return newPromise;
         };
+        InternalPromise.prototype._moveChildren = function (children) {
+            this._children = children.splice(0, children.length);
+            if (this.isFulfilled) {
+                for (var _i = 0, _a = this._children; _i < _a.length; _i++) {
+                    var child = _a[_i];
+                    child._resolve(this._result);
+                }
+            }
+            else if (this.isRejected) {
+                for (var _b = 0, _c = this._children; _b < _c.length; _b++) {
+                    var child = _c[_b];
+                    child._reject(this._reason);
+                }
+            }
+        };
         InternalPromise.prototype._resolve = function (value) {
             try {
                 this._state = PromiseStates.Fulfilled;
                 this._result = value;
-                var returnedPromise = null;
+                var returnedValue = null;
                 if (this._onFulfilled) {
-                    returnedPromise = this._onFulfilled(value);
+                    returnedValue = this._onFulfilled(value);
                 }
-                if (this._child) {
-                    this._child._resolve(value);
+                if (returnedValue !== undefined && returnedValue !== null) {
+                    if (returnedValue._state !== undefined) {
+                        // Transmit children
+                        var returnedPromise = returnedValue;
+                        returnedPromise._moveChildren(this._children);
+                    }
                 }
-                return returnedPromise;
+                for (var _i = 0, _a = this._children; _i < _a.length; _i++) {
+                    var child = _a[_i];
+                    child._resolve(value);
+                }
+                return returnedValue;
             }
             catch (e) {
                 this._reject(e.message);
@@ -8375,12 +8413,13 @@ var BABYLON;
                 this._onRejected(reason);
                 this._rejectWasConsumed = true;
             }
-            if (this._child) {
+            for (var _i = 0, _a = this._children; _i < _a.length; _i++) {
+                var child = _a[_i];
                 if (this._rejectWasConsumed) {
-                    this._child._resolve(null);
+                    child._resolve(null);
                 }
                 else {
-                    this._child._reject(reason);
+                    child._reject(reason);
                 }
             }
         };
@@ -9832,7 +9871,7 @@ var BABYLON;
         });
         Object.defineProperty(Engine, "Version", {
             get: function () {
-                return "3.2.0-alpha5";
+                return "3.2.0-alpha6";
             },
             enumerable: true,
             configurable: true
@@ -13795,6 +13834,17 @@ var BABYLON;
             });
             return request;
         };
+        /** @ignore */
+        Engine.prototype._loadFileAsync = function (url, database, useArrayBuffer) {
+            var _this = this;
+            return new Promise(function (resolve, reject) {
+                _this._loadFile(url, function (data) {
+                    resolve(data);
+                }, undefined, database, useArrayBuffer, function (request, exception) {
+                    reject(exception);
+                });
+            });
+        };
         Engine.prototype._partialLoadFile = function (url, index, loadedFiles, scene, onfinish, onErrorCallBack) {
             if (onErrorCallBack === void 0) { onErrorCallBack = null; }
             var onload = function (data) {
@@ -23533,6 +23583,17 @@ var BABYLON;
             });
             return request;
         };
+        /** @ignore */
+        Scene.prototype._loadFileAsync = function (url, useDatabase, useArrayBuffer) {
+            var _this = this;
+            return new Promise(function (resolve, reject) {
+                _this._loadFile(url, function (data) {
+                    resolve(data);
+                }, undefined, useDatabase, useArrayBuffer, function (request, exception) {
+                    reject(exception);
+                });
+            });
+        };
         // Statics
         Scene._FOGMODE_NONE = 0;
         Scene._FOGMODE_EXP = 1;
@@ -54815,9 +54876,8 @@ var BABYLON;
                     _this._generateMipMaps = false;
                 }
                 _this._texture = _this._engine.createDynamicTexture(_this.video.videoWidth, _this.video.videoHeight, _this._generateMipMaps, _this._samplingMode);
-                _this._texture.width;
-                _this._updateInternalTexture();
                 _this._texture.isReady = true;
+                _this._updateInternalTexture();
             };
             _this.reset = function () {
                 if (_this._texture == null) {

+ 191 - 131
dist/preview release/es6.js

@@ -139,28 +139,31 @@ var BABYLON;
             else {
                 fragmentSource = baseName.fragment || baseName;
             }
-            this._loadVertexShader(vertexSource, function (vertexCode) {
-                _this._processIncludes(vertexCode, function (vertexCodeWithIncludes) {
-                    _this._processShaderConversion(vertexCodeWithIncludes, false, function (migratedVertexCode) {
-                        _this._loadFragmentShader(fragmentSource, function (fragmentCode) {
-                            _this._processIncludes(fragmentCode, function (fragmentCodeWithIncludes) {
-                                _this._processShaderConversion(fragmentCodeWithIncludes, true, function (migratedFragmentCode) {
-                                    if (baseName) {
-                                        var vertex = baseName.vertexElement || baseName.vertex || baseName;
-                                        var fragment = baseName.fragmentElement || baseName.fragment || baseName;
-                                        _this._vertexSourceCode = "#define SHADER_NAME vertex:" + vertex + "\n" + migratedVertexCode;
-                                        _this._fragmentSourceCode = "#define SHADER_NAME fragment:" + fragment + "\n" + migratedFragmentCode;
-                                    }
-                                    else {
-                                        _this._vertexSourceCode = migratedVertexCode;
-                                        _this._fragmentSourceCode = migratedFragmentCode;
-                                    }
-                                    _this._prepareEffect();
-                                });
-                            });
-                        });
-                    });
-                });
+            var finalVertexCode;
+            this._loadVertexShaderAsync(vertexSource)
+                .then(function (vertexCode) {
+                return _this._processIncludesAsync(vertexCode);
+            })
+                .then(function (vertexCodeWithIncludes) {
+                finalVertexCode = _this._processShaderConversion(vertexCodeWithIncludes, false);
+                return _this._loadFragmentShaderAsync(fragmentSource);
+            })
+                .then(function (fragmentCode) {
+                return _this._processIncludesAsync(fragmentCode);
+            })
+                .then(function (fragmentCodeWithIncludes) {
+                var migratedFragmentCode = _this._processShaderConversion(fragmentCodeWithIncludes, true);
+                if (baseName) {
+                    var vertex = baseName.vertexElement || baseName.vertex || baseName;
+                    var fragment = baseName.fragmentElement || baseName.fragment || baseName;
+                    _this._vertexSourceCode = "#define SHADER_NAME vertex:" + vertex + "\n" + finalVertexCode;
+                    _this._fragmentSourceCode = "#define SHADER_NAME fragment:" + fragment + "\n" + migratedFragmentCode;
+                }
+                else {
+                    _this._vertexSourceCode = finalVertexCode;
+                    _this._fragmentSourceCode = migratedFragmentCode;
+                }
+                _this._prepareEffect();
             });
         }
         Object.defineProperty(Effect.prototype, "key", {
@@ -215,25 +218,23 @@ var BABYLON;
                 func(effect);
             });
         };
-        Effect.prototype._loadVertexShader = function (vertex, callback) {
+        /** @ignore */
+        Effect.prototype._loadVertexShaderAsync = function (vertex) {
             if (BABYLON.Tools.IsWindowObjectExist()) {
                 // DOM element ?
                 if (vertex instanceof HTMLElement) {
                     var vertexCode = BABYLON.Tools.GetDOMTextContent(vertex);
-                    callback(vertexCode);
-                    return;
+                    return Promise.resolve(vertexCode);
                 }
             }
             // Base64 encoded ?
             if (vertex.substr(0, 7) === "base64:") {
                 var vertexBinary = window.atob(vertex.substr(7));
-                callback(vertexBinary);
-                return;
+                return Promise.resolve(vertexBinary);
             }
             // Is in local store ?
             if (Effect.ShadersStore[vertex + "VertexShader"]) {
-                callback(Effect.ShadersStore[vertex + "VertexShader"]);
-                return;
+                return Promise.resolve(Effect.ShadersStore[vertex + "VertexShader"]);
             }
             var vertexShaderUrl;
             if (vertex[0] === "." || vertex[0] === "/" || vertex.indexOf("http") > -1) {
@@ -243,31 +244,28 @@ var BABYLON;
                 vertexShaderUrl = BABYLON.Engine.ShadersRepository + vertex;
             }
             // Vertex shader
-            this._engine._loadFile(vertexShaderUrl + ".vertex.fx", callback);
+            return this._engine._loadFileAsync(vertexShaderUrl + ".vertex.fx");
         };
-        Effect.prototype._loadFragmentShader = function (fragment, callback) {
+        /** @ignore */
+        Effect.prototype._loadFragmentShaderAsync = function (fragment) {
             if (BABYLON.Tools.IsWindowObjectExist()) {
                 // DOM element ?
                 if (fragment instanceof HTMLElement) {
                     var fragmentCode = BABYLON.Tools.GetDOMTextContent(fragment);
-                    callback(fragmentCode);
-                    return;
+                    return Promise.resolve(fragmentCode);
                 }
             }
             // Base64 encoded ?
             if (fragment.substr(0, 7) === "base64:") {
                 var fragmentBinary = window.atob(fragment.substr(7));
-                callback(fragmentBinary);
-                return;
+                return Promise.resolve(fragmentBinary);
             }
             // Is in local store ?
             if (Effect.ShadersStore[fragment + "PixelShader"]) {
-                callback(Effect.ShadersStore[fragment + "PixelShader"]);
-                return;
+                return Promise.resolve(Effect.ShadersStore[fragment + "PixelShader"]);
             }
             if (Effect.ShadersStore[fragment + "FragmentShader"]) {
-                callback(Effect.ShadersStore[fragment + "FragmentShader"]);
-                return;
+                return Promise.resolve(Effect.ShadersStore[fragment + "FragmentShader"]);
             }
             var fragmentShaderUrl;
             if (fragment[0] === "." || fragment[0] === "/" || fragment.indexOf("http") > -1) {
@@ -277,7 +275,7 @@ var BABYLON;
                 fragmentShaderUrl = BABYLON.Engine.ShadersRepository + fragment;
             }
             // Fragment shader
-            this._engine._loadFile(fragmentShaderUrl + ".fragment.fx", callback);
+            return this._engine._loadFileAsync(fragmentShaderUrl + ".fragment.fx");
         };
         Effect.prototype._dumpShadersSource = function (vertexCode, fragmentCode, defines) {
             // Rebuild shaders source code
@@ -306,16 +304,14 @@ var BABYLON;
             }
         };
         ;
-        Effect.prototype._processShaderConversion = function (sourceCode, isFragment, callback) {
+        Effect.prototype._processShaderConversion = function (sourceCode, isFragment) {
             var preparedSourceCode = this._processPrecision(sourceCode);
             if (this._engine.webGLVersion == 1) {
-                callback(preparedSourceCode);
-                return;
+                return preparedSourceCode;
             }
             // Already converted
             if (preparedSourceCode.indexOf("#version 3") !== -1) {
-                callback(preparedSourceCode.replace("#version 300 es", ""));
-                return;
+                return preparedSourceCode.replace("#version 300 es", "");
             }
             var hasDrawBuffersExtension = preparedSourceCode.search(/#extension.+GL_EXT_draw_buffers.+require/) !== -1;
             // Remove extensions 
@@ -339,80 +335,86 @@ var BABYLON;
                 result = result.replace(/gl_FragData/g, "glFragData");
                 result = result.replace(/void\s+?main\s*\(/g, (hasDrawBuffersExtension ? "" : "out vec4 glFragColor;\n") + "void main(");
             }
-            callback(result);
+            return result;
         };
-        Effect.prototype._processIncludes = function (sourceCode, callback) {
+        Effect.prototype._processIncludesAsync = function (sourceCode) {
             var _this = this;
-            var regex = /#include<(.+)>(\((.*)\))*(\[(.*)\])*/g;
-            var match = regex.exec(sourceCode);
-            var returnValue = new String(sourceCode);
-            while (match != null) {
-                var includeFile = match[1];
-                // Uniform declaration
-                if (includeFile.indexOf("__decl__") !== -1) {
-                    includeFile = includeFile.replace(/__decl__/, "");
-                    if (this._engine.supportsUniformBuffers) {
-                        includeFile = includeFile.replace(/Vertex/, "Ubo");
-                        includeFile = includeFile.replace(/Fragment/, "Ubo");
-                    }
-                    includeFile = includeFile + "Declaration";
-                }
-                if (Effect.IncludesShadersStore[includeFile]) {
-                    // Substitution
-                    var includeContent = Effect.IncludesShadersStore[includeFile];
-                    if (match[2]) {
-                        var splits = match[3].split(",");
-                        for (var index = 0; index < splits.length; index += 2) {
-                            var source = new RegExp(splits[index], "g");
-                            var dest = splits[index + 1];
-                            includeContent = includeContent.replace(source, dest);
+            return new Promise(function (resolve, reject) {
+                var regex = /#include<(.+)>(\((.*)\))*(\[(.*)\])*/g;
+                var match = regex.exec(sourceCode);
+                var returnValue = sourceCode;
+                while (match != null) {
+                    var includeFile = match[1];
+                    // Uniform declaration
+                    if (includeFile.indexOf("__decl__") !== -1) {
+                        includeFile = includeFile.replace(/__decl__/, "");
+                        if (_this._engine.supportsUniformBuffers) {
+                            includeFile = includeFile.replace(/Vertex/, "Ubo");
+                            includeFile = includeFile.replace(/Fragment/, "Ubo");
                         }
-                    }
-                    if (match[4]) {
-                        var indexString = match[5];
-                        if (indexString.indexOf("..") !== -1) {
-                            var indexSplits = indexString.split("..");
-                            var minIndex = parseInt(indexSplits[0]);
-                            var maxIndex = parseInt(indexSplits[1]);
-                            var sourceIncludeContent = includeContent.slice(0);
-                            includeContent = "";
-                            if (isNaN(maxIndex)) {
-                                maxIndex = this._indexParameters[indexSplits[1]];
+                        includeFile = includeFile + "Declaration";
+                    }
+                    if (Effect.IncludesShadersStore[includeFile]) {
+                        // Substitution
+                        var includeContent = Effect.IncludesShadersStore[includeFile];
+                        if (match[2]) {
+                            var splits = match[3].split(",");
+                            for (var index = 0; index < splits.length; index += 2) {
+                                var source = new RegExp(splits[index], "g");
+                                var dest = splits[index + 1];
+                                includeContent = includeContent.replace(source, dest);
                             }
-                            for (var i = minIndex; i < maxIndex; i++) {
-                                if (!this._engine.supportsUniformBuffers) {
+                        }
+                        if (match[4]) {
+                            var indexString = match[5];
+                            if (indexString.indexOf("..") !== -1) {
+                                var indexSplits = indexString.split("..");
+                                var minIndex = parseInt(indexSplits[0]);
+                                var maxIndex = parseInt(indexSplits[1]);
+                                var sourceIncludeContent = includeContent.slice(0);
+                                includeContent = "";
+                                if (isNaN(maxIndex)) {
+                                    maxIndex = _this._indexParameters[indexSplits[1]];
+                                }
+                                for (var i = minIndex; i < maxIndex; i++) {
+                                    if (!_this._engine.supportsUniformBuffers) {
+                                        // Ubo replacement
+                                        sourceIncludeContent = sourceIncludeContent.replace(/light\{X\}.(\w*)/g, function (str, p1) {
+                                            return p1 + "{X}";
+                                        });
+                                    }
+                                    includeContent += sourceIncludeContent.replace(/\{X\}/g, i.toString()) + "\n";
+                                }
+                            }
+                            else {
+                                if (!_this._engine.supportsUniformBuffers) {
                                     // Ubo replacement
-                                    sourceIncludeContent = sourceIncludeContent.replace(/light\{X\}.(\w*)/g, function (str, p1) {
+                                    includeContent = includeContent.replace(/light\{X\}.(\w*)/g, function (str, p1) {
                                         return p1 + "{X}";
                                     });
                                 }
-                                includeContent += sourceIncludeContent.replace(/\{X\}/g, i.toString()) + "\n";
+                                includeContent = includeContent.replace(/\{X\}/g, indexString);
                             }
                         }
-                        else {
-                            if (!this._engine.supportsUniformBuffers) {
-                                // Ubo replacement
-                                includeContent = includeContent.replace(/light\{X\}.(\w*)/g, function (str, p1) {
-                                    return p1 + "{X}";
-                                });
-                            }
-                            includeContent = includeContent.replace(/\{X\}/g, indexString);
-                        }
+                        // Replace
+                        returnValue = returnValue.replace(match[0], includeContent);
                     }
-                    // Replace
-                    returnValue = returnValue.replace(match[0], includeContent);
-                }
-                else {
-                    var includeShaderUrl = BABYLON.Engine.ShadersRepository + "ShadersInclude/" + includeFile + ".fx";
-                    this._engine._loadFile(includeShaderUrl, function (fileContent) {
-                        Effect.IncludesShadersStore[includeFile] = fileContent;
-                        _this._processIncludes(returnValue, callback);
-                    });
-                    return;
+                    else {
+                        var includeShaderUrl = BABYLON.Engine.ShadersRepository + "ShadersInclude/" + includeFile + ".fx";
+                        _this._engine._loadFileAsync(includeShaderUrl)
+                            .then(function (fileContent) {
+                            Effect.IncludesShadersStore[includeFile] = fileContent;
+                            return _this._processIncludesAsync(returnValue);
+                        })
+                            .then(function (returnValue) {
+                            resolve(returnValue);
+                        });
+                        return;
+                    }
+                    match = regex.exec(sourceCode);
                 }
-                match = regex.exec(sourceCode);
-            }
-            callback(returnValue);
+                resolve(returnValue);
+            });
         };
         Effect.prototype._processPrecision = function (source) {
             if (source.indexOf("precision highp float") === -1) {
@@ -8278,6 +8280,7 @@ var BABYLON;
         function InternalPromise(resolver) {
             var _this = this;
             this._state = PromiseStates.Pending;
+            this._children = new Array();
             this._rejectWasConsumed = false;
             if (!resolver) {
                 return;
@@ -8300,23 +8303,35 @@ var BABYLON;
             enumerable: true,
             configurable: true
         });
-        InternalPromise.prototype.isFulfilled = function () {
-            return this._state === PromiseStates.Fulfilled;
-        };
-        InternalPromise.prototype.isRejected = function () {
-            return this._state === PromiseStates.Rejected;
-        };
-        InternalPromise.prototype.isPending = function () {
-            return this._state === PromiseStates.Pending;
-        };
+        Object.defineProperty(InternalPromise.prototype, "isFulfilled", {
+            get: function () {
+                return this._state === PromiseStates.Fulfilled;
+            },
+            enumerable: true,
+            configurable: true
+        });
+        Object.defineProperty(InternalPromise.prototype, "isRejected", {
+            get: function () {
+                return this._state === PromiseStates.Rejected;
+            },
+            enumerable: true,
+            configurable: true
+        });
+        Object.defineProperty(InternalPromise.prototype, "isPending", {
+            get: function () {
+                return this._state === PromiseStates.Pending;
+            },
+            enumerable: true,
+            configurable: true
+        });
         InternalPromise.prototype.value = function () {
-            if (!this.isFulfilled()) {
+            if (!this.isFulfilled) {
                 throw new Error("Promise is not fulfilled");
             }
             return this._result;
         };
         InternalPromise.prototype.reason = function () {
-            if (!this.isRejected()) {
+            if (!this.isRejected) {
                 throw new Error("Promise is not rejected");
             }
             return this._reason;
@@ -8329,14 +8344,14 @@ var BABYLON;
             newPromise._onFulfilled = onFulfilled;
             newPromise._onRejected = onRejected;
             // Composition
-            this._child = newPromise;
+            this._children.push(newPromise);
             if (this._state !== PromiseStates.Pending) {
                 if (this._state === PromiseStates.Fulfilled || this._rejectWasConsumed) {
                     var returnedValue = newPromise._resolve(this._result);
                     if (returnedValue !== undefined && returnedValue !== null) {
                         if (returnedValue._state !== undefined) {
                             var returnedPromise = returnedValue;
-                            newPromise._child = returnedPromise;
+                            newPromise._children.push(returnedPromise);
                             newPromise = returnedPromise;
                         }
                         else {
@@ -8350,18 +8365,41 @@ var BABYLON;
             }
             return newPromise;
         };
+        InternalPromise.prototype._moveChildren = function (children) {
+            this._children = children.splice(0, children.length);
+            if (this.isFulfilled) {
+                for (var _i = 0, _a = this._children; _i < _a.length; _i++) {
+                    var child = _a[_i];
+                    child._resolve(this._result);
+                }
+            }
+            else if (this.isRejected) {
+                for (var _b = 0, _c = this._children; _b < _c.length; _b++) {
+                    var child = _c[_b];
+                    child._reject(this._reason);
+                }
+            }
+        };
         InternalPromise.prototype._resolve = function (value) {
             try {
                 this._state = PromiseStates.Fulfilled;
                 this._result = value;
-                var returnedPromise = null;
+                var returnedValue = null;
                 if (this._onFulfilled) {
-                    returnedPromise = this._onFulfilled(value);
+                    returnedValue = this._onFulfilled(value);
                 }
-                if (this._child) {
-                    this._child._resolve(value);
+                if (returnedValue !== undefined && returnedValue !== null) {
+                    if (returnedValue._state !== undefined) {
+                        // Transmit children
+                        var returnedPromise = returnedValue;
+                        returnedPromise._moveChildren(this._children);
+                    }
                 }
-                return returnedPromise;
+                for (var _i = 0, _a = this._children; _i < _a.length; _i++) {
+                    var child = _a[_i];
+                    child._resolve(value);
+                }
+                return returnedValue;
             }
             catch (e) {
                 this._reject(e.message);
@@ -8375,12 +8413,13 @@ var BABYLON;
                 this._onRejected(reason);
                 this._rejectWasConsumed = true;
             }
-            if (this._child) {
+            for (var _i = 0, _a = this._children; _i < _a.length; _i++) {
+                var child = _a[_i];
                 if (this._rejectWasConsumed) {
-                    this._child._resolve(null);
+                    child._resolve(null);
                 }
                 else {
-                    this._child._reject(reason);
+                    child._reject(reason);
                 }
             }
         };
@@ -9832,7 +9871,7 @@ var BABYLON;
         });
         Object.defineProperty(Engine, "Version", {
             get: function () {
-                return "3.2.0-alpha5";
+                return "3.2.0-alpha6";
             },
             enumerable: true,
             configurable: true
@@ -13795,6 +13834,17 @@ var BABYLON;
             });
             return request;
         };
+        /** @ignore */
+        Engine.prototype._loadFileAsync = function (url, database, useArrayBuffer) {
+            var _this = this;
+            return new Promise(function (resolve, reject) {
+                _this._loadFile(url, function (data) {
+                    resolve(data);
+                }, undefined, database, useArrayBuffer, function (request, exception) {
+                    reject(exception);
+                });
+            });
+        };
         Engine.prototype._partialLoadFile = function (url, index, loadedFiles, scene, onfinish, onErrorCallBack) {
             if (onErrorCallBack === void 0) { onErrorCallBack = null; }
             var onload = function (data) {
@@ -23533,6 +23583,17 @@ var BABYLON;
             });
             return request;
         };
+        /** @ignore */
+        Scene.prototype._loadFileAsync = function (url, useDatabase, useArrayBuffer) {
+            var _this = this;
+            return new Promise(function (resolve, reject) {
+                _this._loadFile(url, function (data) {
+                    resolve(data);
+                }, undefined, useDatabase, useArrayBuffer, function (request, exception) {
+                    reject(exception);
+                });
+            });
+        };
         // Statics
         Scene._FOGMODE_NONE = 0;
         Scene._FOGMODE_EXP = 1;
@@ -55021,9 +55082,8 @@ var BABYLON;
                     _this._generateMipMaps = false;
                 }
                 _this._texture = _this._engine.createDynamicTexture(_this.video.videoWidth, _this.video.videoHeight, _this._generateMipMaps, _this._samplingMode);
-                _this._texture.width;
-                _this._updateInternalTexture();
                 _this._texture.isReady = true;
+                _this._updateInternalTexture();
             };
             _this.reset = function () {
                 if (_this._texture == null) {

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

@@ -1,7 +1,7 @@
 {
-  "errors": 8794,
+  "errors": 8788,
   "babylon.typedoc.json": {
-    "errors": 8794,
+    "errors": 8788,
     "AnimationKeyInterpolation": {
       "Enumeration": {
         "Comments": {
@@ -10641,40 +10641,6 @@
             }
           }
         },
-        "_loadFragmentShader": {
-          "Comments": {
-            "MissingText": true
-          },
-          "Parameter": {
-            "fragment": {
-              "Comments": {
-                "MissingText": true
-              }
-            },
-            "callback": {
-              "Comments": {
-                "MissingText": true
-              }
-            }
-          }
-        },
-        "_loadVertexShader": {
-          "Comments": {
-            "MissingText": true
-          },
-          "Parameter": {
-            "vertex": {
-              "Comments": {
-                "MissingText": true
-              }
-            },
-            "callback": {
-              "Comments": {
-                "MissingText": true
-              }
-            }
-          }
-        },
         "_prepareEffect": {
           "Comments": {
             "MissingText": true

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


+ 1 - 0
src/Engine/babylon.engine.ts

@@ -5754,6 +5754,7 @@
             return request;
         }
 
+        /** @ignore */
         public _loadFileAsync(url: string, database?: Database, useArrayBuffer?: boolean): Promise<string | ArrayBuffer> {
             return new Promise((resolve, reject) => {
                 this._loadFile(url, (data) => {

+ 15 - 15
src/Materials/babylon.effect.ts

@@ -184,24 +184,20 @@
             }
 
             let finalVertexCode: string;
+
             this._loadVertexShaderAsync(vertexSource)
             .then((vertexCode) => {
                 return this._processIncludesAsync(vertexCode);
             })
             .then((vertexCodeWithIncludes) => {
-                return this._processShaderConversion(vertexCodeWithIncludes, false);
-            })
-            .then((migratedVertexCode) => {
-                finalVertexCode = migratedVertexCode;
+                finalVertexCode = this._processShaderConversion(vertexCodeWithIncludes, false);
                 return this._loadFragmentShaderAsync(fragmentSource);
             })
             .then((fragmentCode) => {
                 return this._processIncludesAsync(fragmentCode);
             })
             .then((fragmentCodeWithIncludes) => {
-                return this._processShaderConversion(fragmentCodeWithIncludes, true);
-            })
-            .then((migratedFragmentCode) => {
+                let migratedFragmentCode = this._processShaderConversion(fragmentCodeWithIncludes, true);
                 if (baseName) {
                     var vertex = baseName.vertexElement || baseName.vertex || baseName;
                     var fragment = baseName.fragmentElement || baseName.fragment || baseName;
@@ -279,6 +275,7 @@
             });
         }
 
+        /** @ignore */
         public _loadVertexShaderAsync(vertex: any): Promise<any> {
             if (Tools.IsWindowObjectExist()) {
                 // DOM element ?
@@ -311,6 +308,7 @@
             return this._engine._loadFileAsync(vertexShaderUrl + ".vertex.fx");
         }
 
+        /** @ignore */
         public _loadFragmentShaderAsync(fragment: any): Promise<any>  {
             if (Tools.IsWindowObjectExist()) {
                 // DOM element ?
@@ -422,7 +420,7 @@
                 var regex = /#include<(.+)>(\((.*)\))*(\[(.*)\])*/g;
                 var match = regex.exec(sourceCode);
 
-                var returnValue = new String(sourceCode);
+                var returnValue = sourceCode;
 
                 while (match != null) {
                     var includeFile = match[1];
@@ -490,13 +488,15 @@
                     } else {
                         var includeShaderUrl = Engine.ShadersRepository + "ShadersInclude/" + includeFile + ".fx";
 
-                        return this._engine._loadFileAsync(includeShaderUrl)
-                                .then((fileContent) => {
-                                    Effect.IncludesShadersStore[includeFile] = fileContent as string;
-                                    this._processIncludesAsync(<string>returnValue).then((value) => {
-                                        resolve(value)
-                                    });
-                                });
+                        this._engine._loadFileAsync(includeShaderUrl)
+                            .then((fileContent) => {
+                                Effect.IncludesShadersStore[includeFile] = fileContent as string;
+                                return this._processIncludesAsync(returnValue);
+                            })
+                            .then((returnValue) => {
+                                resolve(returnValue);
+                            });
+                        return;
                     }
 
                     match = regex.exec(sourceCode);

+ 39 - 16
src/Tools/babylon.promise.ts

@@ -17,7 +17,7 @@ module BABYLON {
         private _state = PromiseStates.Pending;
         private _result?: Nullable<T>;
         private _reason: any;
-        private _child: InternalPromise<T>;
+        private _children = new Array<InternalPromise<T>>();
         private _onFulfilled?: (fulfillment?: Nullable<T>) => Nullable<InternalPromise<T>> | T;
         private _onRejected?: (reason: any) => void;
         private _rejectWasConsumed = false;
@@ -26,27 +26,27 @@ module BABYLON {
             return this._state;
         }
 
-        public isFulfilled(): boolean {
+        public get isFulfilled(): boolean {
             return this._state === PromiseStates.Fulfilled;
         }            
 
-        public isRejected(): boolean {
+        public get isRejected(): boolean {
             return this._state === PromiseStates.Rejected;
         }
     
-        public isPending(): boolean {
+        public get isPending(): boolean {
             return this._state === PromiseStates.Pending;
         }
     
         public value(): Nullable<T> | undefined {
-            if (!this.isFulfilled()) {
+            if (!this.isFulfilled) {
                 throw new Error("Promise is not fulfilled");
             }
             return this._result;
         }     
         
         public reason(): any {
-            if (!this.isRejected()) {
+            if (!this.isRejected) {
                 throw new Error("Promise is not rejected");
             }
             return this._reason;
@@ -82,7 +82,7 @@ module BABYLON {
             newPromise._onRejected = onRejected;
 
             // Composition
-            this._child = newPromise;
+            this._children.push(newPromise);
 
             if (this._state !== PromiseStates.Pending) {
                 if (this._state === PromiseStates.Fulfilled || this._rejectWasConsumed) {
@@ -91,7 +91,7 @@ module BABYLON {
                     if (returnedValue !== undefined && returnedValue !== null) {
                         if ((<InternalPromise<T>>returnedValue)._state !== undefined) {
                             let returnedPromise = returnedValue as InternalPromise<T>;
-                            newPromise._child = returnedPromise;
+                            newPromise._children.push(returnedPromise);
                             newPromise = returnedPromise;
                         } else {
                             newPromise._result = (<T>returnedValue);
@@ -104,22 +104,45 @@ module BABYLON {
 
             return newPromise;
         }       
+
+        private _moveChildren(children: InternalPromise<T>[]): void {
+            this._children = children.splice(0, children.length);
+
+            if (this.isFulfilled) {
+                for (var child of this._children) {
+                    child._resolve(this._result);
+                } 
+            } else if (this.isRejected) {
+                for (var child of this._children) {
+                    child._reject(this._reason);
+                }                 
+            }
+        }
         
         private _resolve(value?: Nullable<T>): Nullable<InternalPromise<T>> | T {
             try {
                 this._state = PromiseStates.Fulfilled;
                 this._result = value;
-                let returnedPromise: Nullable<InternalPromise<T>> | T = null;
+                let returnedValue: Nullable<InternalPromise<T>> | T = null;
 
                 if (this._onFulfilled) {
-                    returnedPromise = this._onFulfilled(value);
+                    returnedValue = this._onFulfilled(value);
+                }
+
+                if (returnedValue !== undefined && returnedValue !== null) {
+                    if ((<InternalPromise<T>>returnedValue)._state !== undefined) {
+                        // Transmit children
+                        let returnedPromise = returnedValue as InternalPromise<T>;
+                        
+                        returnedPromise._moveChildren(this._children);
+                    }
                 }
 
-                if (this._child) {
-                    this._child._resolve(value);
+                for (var child of this._children) {
+                    child._resolve(value);
                 }                
 
-                return returnedPromise;
+                return returnedValue;
             } catch(e) {
                 this._reject((<Error>e).message);
             }
@@ -136,11 +159,11 @@ module BABYLON {
                 this._rejectWasConsumed = true;
             }
 
-            if (this._child) {
+            for (var child of this._children) {
                 if (this._rejectWasConsumed) {
-                    this._child._resolve(null);
+                    child._resolve(null);
                 } else {
-                    this._child._reject(reason);
+                    child._reject(reason);
                 }
             }                
         }

+ 1 - 0
src/babylon.scene.ts

@@ -4815,6 +4815,7 @@
             return request;
         }
 
+        /** @ignore */
         public _loadFileAsync(url: string, useDatabase?: boolean, useArrayBuffer?: boolean): Promise<string | ArrayBuffer> {
             return new Promise((resolve, reject) => {
                 this._loadFile(url, (data) => {

+ 29 - 2
tests/unit/babylon/promises/babylon.promises.tests.ts

@@ -147,7 +147,34 @@ describe('Babylon.Promise', () => {
             .then(number => { 
                 number.should.be.equal(3);
                 done();
-             })
+             });
         });
-    });      
+    });     
+    
+    describe('#Multiple children', () => {
+        it('should correctly handle multiple independant "then"', (done) => {
+            mocha.timeout(10000);
+            var promise1 = new Promise(function(resolve, reject) {
+                setTimeout(function() {
+                    resolve('Success!');
+                }, 500);
+            });
+            var sum = 0;
+            promise1.then(function(value) {
+                sum++;
+                console.log(sum);
+                if (sum === 2) {
+                    done();
+                }
+            });
+            
+            promise1.then(function(value) {
+                sum++;
+                console.log(sum);
+                if (sum === 2) {
+                    done();
+                }
+            });
+        });
+    });     
 });