Browse Source

3.2.0-alpha6 on npm

Raanan Weber 7 năm trước cách đây
mục cha
commit
08f35d09a9
29 tập tin đã thay đổi với 19806 bổ sung18106 xóa
  1. 3 3
      Tools/Publisher/index.js
  2. 10623 10343
      dist/preview release/babylon.d.ts
  3. 20 20
      dist/preview release/babylon.js
  4. 293 53
      dist/preview release/babylon.max.js
  5. 20 20
      dist/preview release/babylon.worker.js
  6. 7035 6755
      dist/preview release/customConfigurations/minimalGLTFViewer/babylon.d.ts
  7. 10 10
      dist/preview release/customConfigurations/minimalGLTFViewer/babylon.js
  8. 293 53
      dist/preview release/customConfigurations/minimalGLTFViewer/babylon.max.js
  9. 293 53
      dist/preview release/customConfigurations/minimalGLTFViewer/es6.js
  10. 293 53
      dist/preview release/es6.js
  11. 1 1
      dist/preview release/gui/package.json
  12. 2 2
      dist/preview release/inspector/babylon.inspector.bundle.js
  13. 1 1
      dist/preview release/inspector/package.json
  14. 1 1
      dist/preview release/loaders/babylon.objFileLoader.min.js
  15. 2 2
      dist/preview release/loaders/babylonjs.loaders.min.js
  16. 1 1
      dist/preview release/loaders/package.json
  17. 1 1
      dist/preview release/materialsLibrary/package.json
  18. 1 1
      dist/preview release/postProcessesLibrary/package.json
  19. 1 1
      dist/preview release/proceduralTexturesLibrary/package.json
  20. 57 49
      dist/preview release/serializers/babylon.glTF2Serializer.d.ts
  21. 381 299
      dist/preview release/serializers/babylon.glTF2Serializer.js
  22. 1 1
      dist/preview release/serializers/babylon.glTF2Serializer.min.js
  23. 381 299
      dist/preview release/serializers/babylonjs.serializers.js
  24. 1 1
      dist/preview release/serializers/babylonjs.serializers.min.js
  25. 57 49
      dist/preview release/serializers/babylonjs.serializers.module.d.ts
  26. 1 1
      dist/preview release/serializers/package.json
  27. 31 31
      dist/preview release/viewer/babylon.viewer.js
  28. 1 1
      dist/preview release/viewer/package.json
  29. 1 1
      package.json

+ 3 - 3
Tools/Publisher/index.js

@@ -55,6 +55,7 @@ function updateEngineVersion(newVersion) {
 
 function runGulp() {
     // run gulp typescript-all
+    console.log("Running gulp compilation");
     let exec = shelljs.exec("gulp typescript-all --gulpfile ../Gulp/gulpfile.js");
     if (exec.code) {
         console.log("error during compilation, aborting");
@@ -62,7 +63,7 @@ function runGulp() {
     }
 }
 
-function processPackages() {
+function processPackages(version) {
     packages.forEach((package) => {
         if (package.name === "core") {
             processCore(package, version);
@@ -82,7 +83,6 @@ function processPackages() {
 //check if logged in
 console.log("Using npm user:");
 let loginCheck = shelljs.exec('npm whoami');
-console.log("Not that I can check, but - did you run gulp typescript-all?");
 if (loginCheck.code === 0) {
     prompt.start();
 
@@ -90,7 +90,7 @@ if (loginCheck.code === 0) {
         let version = result.version;
         updateEngineVersion(version);
         runGulp();
-        processPackages();
+        processPackages(version);
 
         console.log("done, please tag git with " + version);
     });

Những thai đổi đã bị hủy bỏ vì nó quá lớn
+ 10623 - 10343
dist/preview release/babylon.d.ts


Những thai đổi đã bị hủy bỏ vì nó quá lớn
+ 20 - 20
dist/preview release/babylon.js


+ 293 - 53
dist/preview release/babylon.max.js

@@ -7102,10 +7102,21 @@ var BABYLON;
                 return path;
             return path.substring(index + 1);
         };
-        Tools.GetFolderPath = function (uri) {
+        /**
+         * Extracts the "folder" part of a path (everything before the filename).
+         * @param uri The URI to extract the info from
+         * @param returnUnchangedIfNoSlash Do not touch the URI if no slashes are present
+         * @returns The "folder" part of the path
+         */
+        Tools.GetFolderPath = function (uri, returnUnchangedIfNoSlash) {
+            if (returnUnchangedIfNoSlash === void 0) { returnUnchangedIfNoSlash = false; }
             var index = uri.lastIndexOf("/");
-            if (index < 0)
+            if (index < 0) {
+                if (returnUnchangedIfNoSlash) {
+                    return uri;
+                }
                 return "";
+            }
             return uri.substring(0, index + 1);
         };
         Tools.GetDOMTextContent = function (element) {
@@ -8647,19 +8658,20 @@ var BABYLON;
             return newPromise;
         };
         InternalPromise.prototype._moveChildren = function (children) {
-            this._children = children.splice(0, children.length);
+            (_a = this._children).push.apply(_a, children.splice(0, children.length));
             if (this.isFulfilled) {
-                for (var _i = 0, _a = this._children; _i < _a.length; _i++) {
-                    var child = _a[_i];
+                for (var _i = 0, _b = this._children; _i < _b.length; _i++) {
+                    var child = _b[_i];
                     child._resolve(this._result);
                 }
             }
             else if (this.isRejected) {
-                for (var _b = 0, _c = this._children; _b < _c.length; _b++) {
-                    var child = _c[_b];
+                for (var _c = 0, _d = this._children; _c < _d.length; _c++) {
+                    var child = _d[_c];
                     child._reject(this._reason);
                 }
             }
+            var _a;
         };
         InternalPromise.prototype._resolve = function (value) {
             try {
@@ -8731,8 +8743,13 @@ var BABYLON;
             var agregator = new FulFillmentAgregator();
             agregator.target = promises.length;
             agregator.rootPromise = newPromise;
-            for (var index = 0; index < promises.length; index++) {
-                InternalPromise._RegisterForFulfillment(promises[index], agregator, index);
+            if (promises.length) {
+                for (var index = 0; index < promises.length; index++) {
+                    InternalPromise._RegisterForFulfillment(promises[index], agregator, index);
+                }
+            }
+            else {
+                newPromise._resolve([]);
             }
             return newPromise;
         };
@@ -34653,7 +34670,15 @@ var BABYLON;
 
 var BABYLON;
 (function (BABYLON) {
+    /**
+     * PostProcessManager is used to manage one or more post processes or post process pipelines
+     * See https://doc.babylonjs.com/how_to/how_to_use_postprocesses
+     */
     var PostProcessManager = /** @class */ (function () {
+        /**
+         * Creates a new instance of @see PostProcess
+         * @param scene The scene that the post process is associated with.
+         */
         function PostProcessManager(scene) {
             this._vertexBuffers = {};
             this._scene = scene;
@@ -34682,6 +34707,9 @@ var BABYLON;
             indices.push(3);
             this._indexBuffer = this._scene.getEngine().createIndexBuffer(indices);
         };
+        /**
+         * Rebuilds the vertex buffers of the manager.
+         */
         PostProcessManager.prototype._rebuild = function () {
             var vb = this._vertexBuffers[BABYLON.VertexBuffer.PositionKind];
             if (!vb) {
@@ -34691,6 +34719,12 @@ var BABYLON;
             this._buildIndexBuffer();
         };
         // Methods
+        /**
+         * Prepares a frame to be run through a post process.
+         * @param sourceTexture The input texture to the post procesess. (default: null)
+         * @param postProcesses An array of post processes to be run. (default: null)
+         * @returns True if the post processes were able to be run.
+         */
         PostProcessManager.prototype._prepareFrame = function (sourceTexture, postProcesses) {
             if (sourceTexture === void 0) { sourceTexture = null; }
             if (postProcesses === void 0) { postProcesses = null; }
@@ -34705,6 +34739,12 @@ var BABYLON;
             postProcesses[0].activate(camera, sourceTexture, postProcesses !== null && postProcesses !== undefined);
             return true;
         };
+        /**
+         * Manually render a set of post processes to a texture.
+         * @param postProcesses An array of post processes to be run.
+         * @param targetTexture The target texture to render to.
+         * @param forceFullscreenViewport force gl.viewport to be full screen eg. 0,0,textureWidth,textureHeight
+         */
         PostProcessManager.prototype.directRender = function (postProcesses, targetTexture, forceFullscreenViewport) {
             if (targetTexture === void 0) { targetTexture = null; }
             if (forceFullscreenViewport === void 0) { forceFullscreenViewport = false; }
@@ -34737,6 +34777,14 @@ var BABYLON;
             engine.setDepthBuffer(true);
             engine.setDepthWrite(true);
         };
+        /**
+         * Finalize the result of the output of the postprocesses.
+         * @param doNotPresent If true the result will not be displayed to the screen.
+         * @param targetTexture The target texture to render to.
+         * @param faceIndex The index of the face to bind the target texture to.
+         * @param postProcesses The array of post processes to render.
+         * @param forceFullscreenViewport force gl.viewport to be full screen eg. 0,0,textureWidth,textureHeight (default: false)
+         */
         PostProcessManager.prototype._finalizeFrame = function (doNotPresent, targetTexture, faceIndex, postProcesses, forceFullscreenViewport) {
             if (forceFullscreenViewport === void 0) { forceFullscreenViewport = false; }
             var camera = this._scene.activeCamera;
@@ -34780,6 +34828,9 @@ var BABYLON;
             engine.setDepthWrite(true);
             engine.setAlphaMode(BABYLON.Engine.ALPHA_DISABLE);
         };
+        /**
+         * Disposes of the post process manager.
+         */
         PostProcessManager.prototype.dispose = function () {
             var buffer = this._vertexBuffers[BABYLON.VertexBuffer.PositionKind];
             if (buffer) {
@@ -56279,30 +56330,85 @@ var BABYLON;
 
 var BABYLON;
 (function (BABYLON) {
+    /**
+     * PostProcess can be used to apply a shader to a texture after it has been rendered
+     * See https://doc.babylonjs.com/how_to/how_to_use_postprocesses
+     */
     var PostProcess = /** @class */ (function () {
-        function PostProcess(name, fragmentUrl, parameters, samplers, options, camera, samplingMode, engine, reusable, defines, textureType, vertexUrl, indexParameters, blockCompilation) {
+        /**
+         * Creates a new instance of @see PostProcess
+         * @param name The name of the PostProcess.
+         * @param fragmentUrl The url of the fragment shader to be used.
+         * @param parameters Array of the names of uniform non-sampler2D variables that will be passed to the shader.
+         * @param samplers Array of the names of uniform sampler2D variables that will be passed to the shader.
+         * @param options The required width/height ratio to downsize to before computing the render pass. (Use 1.0 for full size)
+         * @param camera The camera to apply the render pass to.
+         * @param samplingMode The sampling mode to be used when computing the pass. (default: 0)
+         * @param engine The engine which the post process will be applied. (default: current engine)
+         * @param reusable If the post process can be reused on the same frame. (default: false)
+         * @param defines String of defines that will be set when running the fragment shader. (default: null)
+         * @param textureType Type of textures used when performing the post process. (default: 0)
+         * @param vertexUrl The url of the vertex shader to be used. (default: "postprocess")
+         * @param indexParameters The index parameters to be used for babylons include syntax "#include<kernelBlurVaryingDeclaration>[0..varyingCount]". (default: undefined) See usage in babylon.blurPostProcess.ts and kernelBlur.vertex.fx
+         * @param blockCompilation If the shader should be compiled imediatly. (default: false)
+         */
+        function PostProcess(/** Name of the PostProcess. */ name, fragmentUrl, parameters, samplers, options, camera, samplingMode, engine, reusable, defines, textureType, vertexUrl, indexParameters, blockCompilation) {
             if (samplingMode === void 0) { samplingMode = BABYLON.Texture.NEAREST_SAMPLINGMODE; }
             if (defines === void 0) { defines = null; }
             if (textureType === void 0) { textureType = BABYLON.Engine.TEXTURETYPE_UNSIGNED_INT; }
             if (vertexUrl === void 0) { vertexUrl = "postprocess"; }
             if (blockCompilation === void 0) { blockCompilation = false; }
             this.name = name;
+            /**
+            * Width of the texture to apply the post process on
+            */
             this.width = -1;
+            /**
+            * Height of the texture to apply the post process on
+            */
             this.height = -1;
+            /**
+            * If the buffer needs to be cleared before applying the post process. (default: true)
+            * Should be set to false if shader will overwrite all previous pixels.
+            */
             this.autoClear = true;
+            /**
+            * Type of alpha mode to use when performing the post process (default: Engine.ALPHA_DISABLE)
+            */
             this.alphaMode = BABYLON.Engine.ALPHA_DISABLE;
-            this.animations = new Array();
-            /*
-                Enable Pixel Perfect mode where texture is not scaled to be power of 2.
-                Can only be used on a single postprocess or on the last one of a chain.
+            /**
+            * Animations to be used for the post processing
             */
+            this.animations = new Array();
+            /**
+             * Enable Pixel Perfect mode where texture is not scaled to be power of 2.
+             * Can only be used on a single postprocess or on the last one of a chain. (default: false)
+             */
             this.enablePixelPerfectMode = false;
+            /**
+            * Scale mode for the post process (default: Engine.SCALEMODE_FLOOR)
+            */
             this.scaleMode = BABYLON.Engine.SCALEMODE_FLOOR;
+            /**
+            * Force textures to be a power of two (default: false)
+            */
             this.alwaysForcePOT = false;
+            /**
+            * Number of sample textures (default: 1)
+            */
             this.samples = 1;
+            /**
+            * Modify the scale of the post process to be the same as the viewport (default: false)
+            */
             this.adaptScaleToCurrentViewport = false;
             this._reusable = false;
+            /**
+            * Smart array of input and output textures for the post process.
+            */
             this._textures = new BABYLON.SmartArray(2);
+            /**
+            * The index in _textures that corresponds to the output texture.
+            */
             this._currentRenderTextureInd = 0;
             this._scaleRatio = new BABYLON.Vector2(1, 1);
             this._texelSize = BABYLON.Vector2.Zero();
@@ -56359,6 +56465,9 @@ var BABYLON;
             }
         }
         Object.defineProperty(PostProcess.prototype, "onActivate", {
+            /**
+            * A function that is added to the onActivateObservable
+            */
             set: function (callback) {
                 if (this._onActivateObserver) {
                     this.onActivateObservable.remove(this._onActivateObserver);
@@ -56371,6 +56480,9 @@ var BABYLON;
             configurable: true
         });
         Object.defineProperty(PostProcess.prototype, "onSizeChanged", {
+            /**
+            * A function that is added to the onSizeChangedObservable
+            */
             set: function (callback) {
                 if (this._onSizeChangedObserver) {
                     this.onSizeChangedObservable.remove(this._onSizeChangedObserver);
@@ -56381,6 +56493,9 @@ var BABYLON;
             configurable: true
         });
         Object.defineProperty(PostProcess.prototype, "onApply", {
+            /**
+            * A function that is added to the onApplyObservable
+            */
             set: function (callback) {
                 if (this._onApplyObserver) {
                     this.onApplyObservable.remove(this._onApplyObserver);
@@ -56391,6 +56506,9 @@ var BABYLON;
             configurable: true
         });
         Object.defineProperty(PostProcess.prototype, "onBeforeRender", {
+            /**
+            * A function that is added to the onBeforeRenderObservable
+            */
             set: function (callback) {
                 if (this._onBeforeRenderObserver) {
                     this.onBeforeRenderObservable.remove(this._onBeforeRenderObserver);
@@ -56401,6 +56519,9 @@ var BABYLON;
             configurable: true
         });
         Object.defineProperty(PostProcess.prototype, "onAfterRender", {
+            /**
+            * A function that is added to the onAfterRenderObservable
+            */
             set: function (callback) {
                 if (this._onAfterRenderObserver) {
                     this.onAfterRenderObservable.remove(this._onAfterRenderObserver);
@@ -56411,6 +56532,9 @@ var BABYLON;
             configurable: true
         });
         Object.defineProperty(PostProcess.prototype, "outputTexture", {
+            /**
+            * The resulting output of the post process.
+            */
             get: function () {
                 return this._textures.data[this._currentRenderTextureInd];
             },
@@ -56420,10 +56544,18 @@ var BABYLON;
             enumerable: true,
             configurable: true
         });
+        /**
+        * Gets the camera which post process is applied to.
+        * @returns The camera the post process is applied to.
+        */
         PostProcess.prototype.getCamera = function () {
             return this._camera;
         };
         Object.defineProperty(PostProcess.prototype, "texelSize", {
+            /**
+            * Gets the texel size of the postprocess.
+            * See https://en.wikipedia.org/wiki/Texel_(graphics)
+            */
             get: function () {
                 if (this._shareOutputWithPostProcess) {
                     return this._shareOutputWithPostProcess.texelSize;
@@ -56436,23 +56568,49 @@ var BABYLON;
             enumerable: true,
             configurable: true
         });
+        /**
+         * Gets the engine which this post process belongs to.
+         * @returns The engine the post process was enabled with.
+         */
         PostProcess.prototype.getEngine = function () {
             return this._engine;
         };
+        /**
+         * The effect that is created when initializing the post process.
+         * @returns The created effect corrisponding the the postprocess.
+         */
         PostProcess.prototype.getEffect = function () {
             return this._effect;
         };
+        /**
+         * To avoid multiple redundant textures for multiple post process, the output the output texture for this post process can be shared with another.
+         * @param postProcess The post process to share the output with.
+         * @returns This post process.
+         */
         PostProcess.prototype.shareOutputWith = function (postProcess) {
             this._disposeTextures();
             this._shareOutputWithPostProcess = postProcess;
             return this;
         };
+        /**
+         * Updates the effect with the current post process compile time values and recompiles the shader.
+         * @param defines Define statements that should be added at the beginning of the shader. (default: null)
+         * @param uniforms Set of uniform variables that will be passed to the shader. (default: null)
+         * @param samplers Set of Texture2D variables that will be passed to the shader. (default: null)
+         * @param indexParameters The index parameters to be used for babylons include syntax "#include<kernelBlurVaryingDeclaration>[0..varyingCount]". (default: undefined) See usage in babylon.blurPostProcess.ts and kernelBlur.vertex.fx
+         * @param onCompiled Called when the shader has been compiled.
+         * @param onError Called if there is an error when compiling a shader.
+         */
         PostProcess.prototype.updateEffect = function (defines, uniforms, samplers, indexParameters, onCompiled, onError) {
             if (defines === void 0) { defines = null; }
             if (uniforms === void 0) { uniforms = null; }
             if (samplers === void 0) { samplers = null; }
             this._effect = this._engine.createEffect({ vertex: this._vertexUrl, fragment: this._fragmentUrl }, ["position"], uniforms || this._parameters, samplers || this._samplers, defines !== null ? defines : "", undefined, onCompiled, onError, indexParameters || this._indexParameters);
         };
+        /**
+         * The post process is reusable if it can be used multiple times within one frame.
+         * @returns If the post process is reusable
+         */
         PostProcess.prototype.isReusable = function () {
             return this._reusable;
         };
@@ -56460,6 +56618,12 @@ var BABYLON;
         PostProcess.prototype.markTextureDirty = function () {
             this.width = -1;
         };
+        /**
+         * Activates the post process by intializing the textures to be used when executed. Notifies onActivateObservable.
+         * @param camera The camera that will be used in the post process. This camera will be used when calling onActivateObservable.
+         * @param sourceTexture The source texture to be inspected to get the width and height if not specified in the post process constructor. (default: null)
+         * @param forceDepthStencil If true, a depth and stencil buffer will be generated. (default: false)
+         */
         PostProcess.prototype.activate = function (camera, sourceTexture, forceDepthStencil) {
             var _this = this;
             if (sourceTexture === void 0) { sourceTexture = null; }
@@ -56547,6 +56711,9 @@ var BABYLON;
             }
         };
         Object.defineProperty(PostProcess.prototype, "isSupported", {
+            /**
+             * If the post process is supported.
+             */
             get: function () {
                 return this._effect.isSupported;
             },
@@ -56554,6 +56721,9 @@ var BABYLON;
             configurable: true
         });
         Object.defineProperty(PostProcess.prototype, "aspectRatio", {
+            /**
+             * The aspect ratio of the output texture.
+             */
             get: function () {
                 if (this._shareOutputWithPostProcess) {
                     return this._shareOutputWithPostProcess.aspectRatio;
@@ -56573,6 +56743,10 @@ var BABYLON;
         PostProcess.prototype.isReady = function () {
             return this._effect && this._effect.isReady();
         };
+        /**
+         * Binds all textures and uniforms to the shader, this will be run on every pass.
+         * @returns the effect corrisponding to this post process. Null if not compiled or not ready.
+         */
         PostProcess.prototype.apply = function () {
             // Check
             if (!this._effect || !this._effect.isReady())
@@ -56615,6 +56789,10 @@ var BABYLON;
             }
             this._textures.dispose();
         };
+        /**
+         * Disposes the post process.
+         * @param camera The camera to dispose the post process on.
+         */
         PostProcess.prototype.dispose = function (camera) {
             camera = camera || this._camera;
             this._disposeTextures();
@@ -58124,7 +58302,6 @@ var BABYLON;
         * @param onError a callback with the scene, a message, and possibly an exception when import fails
         */
         SceneLoader.ImportMesh = function (meshNames, rootUrl, sceneFilename, scene, onSuccess, onProgress, onError, pluginExtension) {
-            var _this = this;
             if (onSuccess === void 0) { onSuccess = null; }
             if (onProgress === void 0) { onProgress = null; }
             if (onError === void 0) { onError = null; }
@@ -58175,7 +58352,7 @@ var BABYLON;
                 }
                 if (sceneFilename === "") {
                     if (sceneFilename === "") {
-                        rootUrl = _this._StripFilenameFromRootUrl(rootUrl);
+                        rootUrl = BABYLON.Tools.GetFolderPath(rootUrl, true);
                     }
                 }
                 if (plugin.importMesh) {
@@ -58224,7 +58401,6 @@ var BABYLON;
         * @param onError a callback with the scene, a message, and possibly an exception when import fails
         */
         SceneLoader.Append = function (rootUrl, sceneFilename, scene, onSuccess, onProgress, onError, pluginExtension) {
-            var _this = this;
             if (onSuccess === void 0) { onSuccess = null; }
             if (onProgress === void 0) { onProgress = null; }
             if (onError === void 0) { onError = null; }
@@ -58274,7 +58450,7 @@ var BABYLON;
             };
             return SceneLoader._loadData(rootUrl, sceneFilename, scene, function (plugin, data, responseURL) {
                 if (sceneFilename === "") {
-                    rootUrl = _this._StripFilenameFromRootUrl(rootUrl);
+                    rootUrl = BABYLON.Tools.GetFolderPath(rootUrl, true);
                 }
                 if (plugin.load) {
                     var syncedPlugin = plugin;
@@ -58298,14 +58474,6 @@ var BABYLON;
                 }
             }, progressHandler, errorHandler, disposeHandler, pluginExtension);
         };
-        SceneLoader._StripFilenameFromRootUrl = function (rootUrl) {
-            // We need to strip the filename off from the rootUrl
-            var lastSlash = rootUrl.lastIndexOf("/");
-            if (lastSlash > -1) {
-                rootUrl = rootUrl.substr(0, lastSlash + 1);
-            }
-            return rootUrl;
-        };
         SceneLoader.LoadAssetContainer = function (rootUrl, sceneFilename, scene, onSuccess, onProgress, onError, pluginExtension) {
             if (onSuccess === void 0) { onSuccess = null; }
             if (onProgress === void 0) { onProgress = null; }
@@ -65138,83 +65306,83 @@ var BABYLON;
          */
         function DepthOfFieldEffect(scene, pipelineTextureType) {
             if (pipelineTextureType === void 0) { pipelineTextureType = 0; }
-            var _this = _super.call(this, scene.getEngine(), "depth of field", function () { return [_this.circleOfConfusion, _this.depthOfFieldPass, _this.depthOfFieldBlurY, _this.depthOfFieldBlurX, _this.depthOfFieldMerge]; }, true) || this;
+            var _this = _super.call(this, scene.getEngine(), "depth of field", function () { return [_this._circleOfConfusion, _this._depthOfFieldPass, _this._depthOfFieldBlurY, _this._depthOfFieldBlurX, _this._depthOfFieldMerge]; }, true) || this;
             // Enable and get current depth map
             var depthMap = scene.enableDepthRenderer().getDepthMap();
             // Circle of confusion value for each pixel is used to determine how much to blur that pixel
-            _this.circleOfConfusion = new BABYLON.CircleOfConfusionPostProcess("circleOfConfusion", scene, depthMap, 1, null, BABYLON.Texture.BILINEAR_SAMPLINGMODE, scene.getEngine(), false, pipelineTextureType);
+            _this._circleOfConfusion = new BABYLON.CircleOfConfusionPostProcess("circleOfConfusion", scene, depthMap, 1, null, BABYLON.Texture.BILINEAR_SAMPLINGMODE, scene.getEngine(), false, pipelineTextureType);
             // Capture circle of confusion texture
-            _this.depthOfFieldPass = new BABYLON.PassPostProcess("depthOfFieldPass", 1.0, null, BABYLON.Texture.BILINEAR_SAMPLINGMODE, scene.getEngine(), false, pipelineTextureType);
+            _this._depthOfFieldPass = new BABYLON.PassPostProcess("depthOfFieldPass", 1.0, null, BABYLON.Texture.BILINEAR_SAMPLINGMODE, scene.getEngine(), false, pipelineTextureType);
             // Blur the image but do not blur on sharp far to near distance changes to avoid bleeding artifacts 
             // See section 2.6.2 http://fileadmin.cs.lth.se/cs/education/edan35/lectures/12dof.pdf
-            _this.depthOfFieldBlurY = new BABYLON.DepthOfFieldBlurPostProcess("verticle blur", scene, new BABYLON.Vector2(0, 1.0), 15, 1.0, null, depthMap, _this.circleOfConfusion, BABYLON.Texture.BILINEAR_SAMPLINGMODE, scene.getEngine(), false, pipelineTextureType);
-            _this.depthOfFieldBlurX = new BABYLON.DepthOfFieldBlurPostProcess("horizontal blur", scene, new BABYLON.Vector2(1.0, 0), 15, 1.0, null, depthMap, null, BABYLON.Texture.BILINEAR_SAMPLINGMODE, scene.getEngine(), false, pipelineTextureType);
+            _this._depthOfFieldBlurY = new BABYLON.DepthOfFieldBlurPostProcess("verticle blur", scene, new BABYLON.Vector2(0, 1.0), 15, 1.0, null, depthMap, _this._circleOfConfusion, BABYLON.Texture.BILINEAR_SAMPLINGMODE, scene.getEngine(), false, pipelineTextureType);
+            _this._depthOfFieldBlurX = new BABYLON.DepthOfFieldBlurPostProcess("horizontal blur", scene, new BABYLON.Vector2(1.0, 0), 15, 1.0, null, depthMap, null, BABYLON.Texture.BILINEAR_SAMPLINGMODE, scene.getEngine(), false, pipelineTextureType);
             // Merge blurred images with original image based on circleOfConfusion
-            _this.depthOfFieldMerge = new BABYLON.DepthOfFieldMergePostProcess("depthOfFieldMerge", _this.circleOfConfusion, _this.depthOfFieldPass, 1, null, BABYLON.Texture.BILINEAR_SAMPLINGMODE, scene.getEngine(), false, pipelineTextureType);
+            _this._depthOfFieldMerge = new BABYLON.DepthOfFieldMergePostProcess("depthOfFieldMerge", _this._circleOfConfusion, _this._depthOfFieldPass, 1, null, BABYLON.Texture.BILINEAR_SAMPLINGMODE, scene.getEngine(), false, pipelineTextureType);
             return _this;
         }
         Object.defineProperty(DepthOfFieldEffect.prototype, "kernelSize", {
             get: function () {
-                return this.depthOfFieldBlurX.kernel;
+                return this._depthOfFieldBlurX.kernel;
             },
             /**
              * The size of the kernel to be used for the blur
              */
             set: function (value) {
-                this.depthOfFieldBlurX.kernel = value;
-                this.depthOfFieldBlurY.kernel = value;
+                this._depthOfFieldBlurX.kernel = value;
+                this._depthOfFieldBlurY.kernel = value;
             },
             enumerable: true,
             configurable: true
         });
         Object.defineProperty(DepthOfFieldEffect.prototype, "focalLength", {
             get: function () {
-                return this.circleOfConfusion.focalLength;
+                return this._circleOfConfusion.focalLength;
             },
             /**
              * The focal the length of the camera used in the effect
              */
             set: function (value) {
-                this.circleOfConfusion.focalLength = value;
+                this._circleOfConfusion.focalLength = value;
             },
             enumerable: true,
             configurable: true
         });
         Object.defineProperty(DepthOfFieldEffect.prototype, "fStop", {
             get: function () {
-                return this.circleOfConfusion.fStop;
+                return this._circleOfConfusion.fStop;
             },
             /**
              * F-Stop of the effect's camera. The diamater of the resulting aperture can be computed by lensSize/fStop. (default: 1.4)
              */
             set: function (value) {
-                this.circleOfConfusion.fStop = value;
+                this._circleOfConfusion.fStop = value;
             },
             enumerable: true,
             configurable: true
         });
         Object.defineProperty(DepthOfFieldEffect.prototype, "focusDistance", {
             get: function () {
-                return this.circleOfConfusion.focusDistance;
+                return this._circleOfConfusion.focusDistance;
             },
             /**
              * Distance away from the camera to focus on in scene units/1000 (eg. millimeter). (default: 2000)
              */
             set: function (value) {
-                this.circleOfConfusion.focusDistance = value;
+                this._circleOfConfusion.focusDistance = value;
             },
             enumerable: true,
             configurable: true
         });
         Object.defineProperty(DepthOfFieldEffect.prototype, "lensSize", {
             get: function () {
-                return this.circleOfConfusion.lensSize;
+                return this._circleOfConfusion.lensSize;
             },
             /**
              * Max lens size in scene units/1000 (eg. millimeter). Standard cameras are 50mm. (default: 50) The diamater of the resulting aperture can be computed by lensSize/fStop.
              */
             set: function (value) {
-                this.circleOfConfusion.lensSize = value;
+                this._circleOfConfusion.lensSize = value;
             },
             enumerable: true,
             configurable: true
@@ -65224,11 +65392,11 @@ var BABYLON;
          * @param camera The camera to dispose the effect on.
          */
         DepthOfFieldEffect.prototype.disposeEffects = function (camera) {
-            this.depthOfFieldPass.dispose(camera);
-            this.circleOfConfusion.dispose(camera);
-            this.depthOfFieldBlurX.dispose(camera);
-            this.depthOfFieldBlurY.dispose(camera);
-            this.depthOfFieldMerge.dispose(camera);
+            this._depthOfFieldPass.dispose(camera);
+            this._circleOfConfusion.dispose(camera);
+            this._depthOfFieldBlurX.dispose(camera);
+            this._depthOfFieldBlurY.dispose(camera);
+            this._depthOfFieldMerge.dispose(camera);
         };
         return DepthOfFieldEffect;
     }(BABYLON.PostProcessRenderEffect));
@@ -65245,6 +65413,10 @@ var BABYLON;
 
 var BABYLON;
 (function (BABYLON) {
+    /**
+     * The default rendering pipeline can be added to a scene to apply common post processing effects such as anti-aliasing or depth of field.
+     * See https://doc.babylonjs.com/how_to/using_default_rendering_pipeline
+     */
     var DefaultRenderingPipeline = /** @class */ (function (_super) {
         __extends(DefaultRenderingPipeline, _super);
         /**
@@ -65258,15 +65430,41 @@ var BABYLON;
         function DefaultRenderingPipeline(name, hdr, scene, cameras, automaticBuild) {
             if (automaticBuild === void 0) { automaticBuild = true; }
             var _this = _super.call(this, scene.getEngine(), name) || this;
+            /**
+             * ID of the pass post process used for bloom,
+             */
             _this.PassPostProcessId = "PassPostProcessEffect";
+            /**
+             * ID of the highlight post process used for bloom,
+             */
             _this.HighLightsPostProcessId = "HighLightsPostProcessEffect";
+            /**
+             * ID of the blurX post process used for bloom,
+             */
             _this.BlurXPostProcessId = "BlurXPostProcessEffect";
+            /**
+             * ID of the blurY post process used for bloom,
+             */
             _this.BlurYPostProcessId = "BlurYPostProcessEffect";
+            /**
+             * ID of the copy back post process used for bloom,
+             */
             _this.CopyBackPostProcessId = "CopyBackPostProcessEffect";
+            /**
+             * ID of the image processing post process;
+             */
             _this.ImageProcessingPostProcessId = "ImageProcessingPostProcessEffect";
+            /**
+             * ID of the Fast Approximate Anti-Aliasing post process;
+             */
             _this.FxaaPostProcessId = "FxaaPostProcessEffect";
+            /**
+             * ID of the final merge post process;
+             */
             _this.FinalMergePostProcessId = "FinalMergePostProcessEffect";
-            // IAnimatable
+            /**
+             * Animations which can be used to tweak settings over a period of time
+             */
             _this.animations = [];
             // Values       
             _this._bloomEnabled = false;
@@ -65310,6 +65508,9 @@ var BABYLON;
             get: function () {
                 return this._bloomWeight;
             },
+            /**
+             * The strength of the bloom.
+             */
             set: function (value) {
                 if (this._bloomWeight === value) {
                     return;
@@ -65326,6 +65527,9 @@ var BABYLON;
             get: function () {
                 return this._bloomScale;
             },
+            /**
+             * The scale of the bloom, lower value will provide better performance.
+             */
             set: function (value) {
                 if (this._bloomScale === value) {
                     return;
@@ -65340,6 +65544,9 @@ var BABYLON;
             get: function () {
                 return this._bloomEnabled;
             },
+            /**
+             * Enable or disable the bloom from the pipeline
+             */
             set: function (enabled) {
                 if (this._bloomEnabled === enabled) {
                     return;
@@ -65371,6 +65578,9 @@ var BABYLON;
             get: function () {
                 return this._fxaaEnabled;
             },
+            /**
+             * If the anti aliasing is enabled.
+             */
             set: function (enabled) {
                 if (this._fxaaEnabled === enabled) {
                     return;
@@ -65385,6 +65595,9 @@ var BABYLON;
             get: function () {
                 return this._imageProcessingEnabled;
             },
+            /**
+             * If image processing is enabled.
+             */
             set: function (enabled) {
                 if (this._imageProcessingEnabled === enabled) {
                     return;
@@ -65544,19 +65757,30 @@ var BABYLON;
             this.finalMerge = null;
             this.depthOfField = null;
         };
-        // Dispose
+        /**
+         * Dispose of the pipeline and stop all post processes
+         */
         DefaultRenderingPipeline.prototype.dispose = function () {
             this._disposePostProcesses();
             this._scene.postProcessRenderPipelineManager.detachCamerasFromRenderPipeline(this._name, this._cameras);
             _super.prototype.dispose.call(this);
         };
-        // Serialize rendering pipeline
+        /**
+         * Serialize the rendering pipeline (Used when exporting)
+         * @returns the serialized object
+         */
         DefaultRenderingPipeline.prototype.serialize = function () {
             var serializationObject = BABYLON.SerializationHelper.Serialize(this);
             serializationObject.customType = "DefaultRenderingPipeline";
             return serializationObject;
         };
-        // Parse serialized pipeline
+        /**
+         * Parse the serialized pipeline
+         * @param source Source pipeline.
+         * @param scene The scene to load the pipeline to.
+         * @param rootUrl The URL of the serialized pipeline.
+         * @returns An instantiated pipeline from the serialized object.
+         */
         DefaultRenderingPipeline.Parse = function (source, scene, rootUrl) {
             return BABYLON.SerializationHelper.Parse(function () { return new DefaultRenderingPipeline(source._name, source._name._hdr, scene); }, source, scene, rootUrl);
         };
@@ -66860,9 +67084,25 @@ var BABYLON;
 
 var BABYLON;
 (function (BABYLON) {
+    /**
+     * The Blur Post Process which blurs an image based on a kernel and direction.
+     * Can be used twice in x and y directions to perform a guassian blur in two passes.
+     */
     var BlurPostProcess = /** @class */ (function (_super) {
         __extends(BlurPostProcess, _super);
-        function BlurPostProcess(name, direction, kernel, options, camera, samplingMode, engine, reusable, textureType) {
+        /**
+         * Creates a new instance of @see BlurPostProcess
+         * @param name The name of the effect.
+         * @param direction The direction in which to blur the image.
+         * @param kernel The size of the kernel to be used when computing the blur. eg. Size of 3 will blur the center pixel by 2 pixels surrounding it.
+         * @param options The required width/height ratio to downsize to before computing the render pass. (Use 1.0 for full size)
+         * @param camera The camera to apply the render pass to.
+         * @param samplingMode The sampling mode to be used when computing the pass. (default: 0)
+         * @param engine The engine which the post process will be applied. (default: current engine)
+         * @param reusable If the post process can be reused on the same frame. (default: false)
+         * @param textureType Type of textures used when performing the post process. (default: 0)
+         */
+        function BlurPostProcess(name, /** The direction in which to blur the image. */ direction, kernel, options, camera, samplingMode, engine, reusable, textureType) {
             if (samplingMode === void 0) { samplingMode = BABYLON.Texture.BILINEAR_SAMPLINGMODE; }
             if (textureType === void 0) { textureType = BABYLON.Engine.TEXTURETYPE_UNSIGNED_INT; }
             var _this = _super.call(this, name, "kernelBlur", ["delta", "direction", "cameraMinMaxZ"], ["depthSampler"], options, camera, samplingMode, engine, reusable, null, textureType, "kernelBlur", { varyingCount: 0, depCount: 0 }, true) || this;

Những thai đổi đã bị hủy bỏ vì nó quá lớn
+ 20 - 20
dist/preview release/babylon.worker.js


Những thai đổi đã bị hủy bỏ vì nó quá lớn
+ 7035 - 6755
dist/preview release/customConfigurations/minimalGLTFViewer/babylon.d.ts


Những thai đổi đã bị hủy bỏ vì nó quá lớn
+ 10 - 10
dist/preview release/customConfigurations/minimalGLTFViewer/babylon.js


+ 293 - 53
dist/preview release/customConfigurations/minimalGLTFViewer/babylon.max.js

@@ -7102,10 +7102,21 @@ var BABYLON;
                 return path;
             return path.substring(index + 1);
         };
-        Tools.GetFolderPath = function (uri) {
+        /**
+         * Extracts the "folder" part of a path (everything before the filename).
+         * @param uri The URI to extract the info from
+         * @param returnUnchangedIfNoSlash Do not touch the URI if no slashes are present
+         * @returns The "folder" part of the path
+         */
+        Tools.GetFolderPath = function (uri, returnUnchangedIfNoSlash) {
+            if (returnUnchangedIfNoSlash === void 0) { returnUnchangedIfNoSlash = false; }
             var index = uri.lastIndexOf("/");
-            if (index < 0)
+            if (index < 0) {
+                if (returnUnchangedIfNoSlash) {
+                    return uri;
+                }
                 return "";
+            }
             return uri.substring(0, index + 1);
         };
         Tools.GetDOMTextContent = function (element) {
@@ -8647,19 +8658,20 @@ var BABYLON;
             return newPromise;
         };
         InternalPromise.prototype._moveChildren = function (children) {
-            this._children = children.splice(0, children.length);
+            (_a = this._children).push.apply(_a, children.splice(0, children.length));
             if (this.isFulfilled) {
-                for (var _i = 0, _a = this._children; _i < _a.length; _i++) {
-                    var child = _a[_i];
+                for (var _i = 0, _b = this._children; _i < _b.length; _i++) {
+                    var child = _b[_i];
                     child._resolve(this._result);
                 }
             }
             else if (this.isRejected) {
-                for (var _b = 0, _c = this._children; _b < _c.length; _b++) {
-                    var child = _c[_b];
+                for (var _c = 0, _d = this._children; _c < _d.length; _c++) {
+                    var child = _d[_c];
                     child._reject(this._reason);
                 }
             }
+            var _a;
         };
         InternalPromise.prototype._resolve = function (value) {
             try {
@@ -8731,8 +8743,13 @@ var BABYLON;
             var agregator = new FulFillmentAgregator();
             agregator.target = promises.length;
             agregator.rootPromise = newPromise;
-            for (var index = 0; index < promises.length; index++) {
-                InternalPromise._RegisterForFulfillment(promises[index], agregator, index);
+            if (promises.length) {
+                for (var index = 0; index < promises.length; index++) {
+                    InternalPromise._RegisterForFulfillment(promises[index], agregator, index);
+                }
+            }
+            else {
+                newPromise._resolve([]);
             }
             return newPromise;
         };
@@ -34653,7 +34670,15 @@ var BABYLON;
 
 var BABYLON;
 (function (BABYLON) {
+    /**
+     * PostProcessManager is used to manage one or more post processes or post process pipelines
+     * See https://doc.babylonjs.com/how_to/how_to_use_postprocesses
+     */
     var PostProcessManager = /** @class */ (function () {
+        /**
+         * Creates a new instance of @see PostProcess
+         * @param scene The scene that the post process is associated with.
+         */
         function PostProcessManager(scene) {
             this._vertexBuffers = {};
             this._scene = scene;
@@ -34682,6 +34707,9 @@ var BABYLON;
             indices.push(3);
             this._indexBuffer = this._scene.getEngine().createIndexBuffer(indices);
         };
+        /**
+         * Rebuilds the vertex buffers of the manager.
+         */
         PostProcessManager.prototype._rebuild = function () {
             var vb = this._vertexBuffers[BABYLON.VertexBuffer.PositionKind];
             if (!vb) {
@@ -34691,6 +34719,12 @@ var BABYLON;
             this._buildIndexBuffer();
         };
         // Methods
+        /**
+         * Prepares a frame to be run through a post process.
+         * @param sourceTexture The input texture to the post procesess. (default: null)
+         * @param postProcesses An array of post processes to be run. (default: null)
+         * @returns True if the post processes were able to be run.
+         */
         PostProcessManager.prototype._prepareFrame = function (sourceTexture, postProcesses) {
             if (sourceTexture === void 0) { sourceTexture = null; }
             if (postProcesses === void 0) { postProcesses = null; }
@@ -34705,6 +34739,12 @@ var BABYLON;
             postProcesses[0].activate(camera, sourceTexture, postProcesses !== null && postProcesses !== undefined);
             return true;
         };
+        /**
+         * Manually render a set of post processes to a texture.
+         * @param postProcesses An array of post processes to be run.
+         * @param targetTexture The target texture to render to.
+         * @param forceFullscreenViewport force gl.viewport to be full screen eg. 0,0,textureWidth,textureHeight
+         */
         PostProcessManager.prototype.directRender = function (postProcesses, targetTexture, forceFullscreenViewport) {
             if (targetTexture === void 0) { targetTexture = null; }
             if (forceFullscreenViewport === void 0) { forceFullscreenViewport = false; }
@@ -34737,6 +34777,14 @@ var BABYLON;
             engine.setDepthBuffer(true);
             engine.setDepthWrite(true);
         };
+        /**
+         * Finalize the result of the output of the postprocesses.
+         * @param doNotPresent If true the result will not be displayed to the screen.
+         * @param targetTexture The target texture to render to.
+         * @param faceIndex The index of the face to bind the target texture to.
+         * @param postProcesses The array of post processes to render.
+         * @param forceFullscreenViewport force gl.viewport to be full screen eg. 0,0,textureWidth,textureHeight (default: false)
+         */
         PostProcessManager.prototype._finalizeFrame = function (doNotPresent, targetTexture, faceIndex, postProcesses, forceFullscreenViewport) {
             if (forceFullscreenViewport === void 0) { forceFullscreenViewport = false; }
             var camera = this._scene.activeCamera;
@@ -34780,6 +34828,9 @@ var BABYLON;
             engine.setDepthWrite(true);
             engine.setAlphaMode(BABYLON.Engine.ALPHA_DISABLE);
         };
+        /**
+         * Disposes of the post process manager.
+         */
         PostProcessManager.prototype.dispose = function () {
             var buffer = this._vertexBuffers[BABYLON.VertexBuffer.PositionKind];
             if (buffer) {
@@ -56073,30 +56124,85 @@ var BABYLON;
 
 var BABYLON;
 (function (BABYLON) {
+    /**
+     * PostProcess can be used to apply a shader to a texture after it has been rendered
+     * See https://doc.babylonjs.com/how_to/how_to_use_postprocesses
+     */
     var PostProcess = /** @class */ (function () {
-        function PostProcess(name, fragmentUrl, parameters, samplers, options, camera, samplingMode, engine, reusable, defines, textureType, vertexUrl, indexParameters, blockCompilation) {
+        /**
+         * Creates a new instance of @see PostProcess
+         * @param name The name of the PostProcess.
+         * @param fragmentUrl The url of the fragment shader to be used.
+         * @param parameters Array of the names of uniform non-sampler2D variables that will be passed to the shader.
+         * @param samplers Array of the names of uniform sampler2D variables that will be passed to the shader.
+         * @param options The required width/height ratio to downsize to before computing the render pass. (Use 1.0 for full size)
+         * @param camera The camera to apply the render pass to.
+         * @param samplingMode The sampling mode to be used when computing the pass. (default: 0)
+         * @param engine The engine which the post process will be applied. (default: current engine)
+         * @param reusable If the post process can be reused on the same frame. (default: false)
+         * @param defines String of defines that will be set when running the fragment shader. (default: null)
+         * @param textureType Type of textures used when performing the post process. (default: 0)
+         * @param vertexUrl The url of the vertex shader to be used. (default: "postprocess")
+         * @param indexParameters The index parameters to be used for babylons include syntax "#include<kernelBlurVaryingDeclaration>[0..varyingCount]". (default: undefined) See usage in babylon.blurPostProcess.ts and kernelBlur.vertex.fx
+         * @param blockCompilation If the shader should be compiled imediatly. (default: false)
+         */
+        function PostProcess(/** Name of the PostProcess. */ name, fragmentUrl, parameters, samplers, options, camera, samplingMode, engine, reusable, defines, textureType, vertexUrl, indexParameters, blockCompilation) {
             if (samplingMode === void 0) { samplingMode = BABYLON.Texture.NEAREST_SAMPLINGMODE; }
             if (defines === void 0) { defines = null; }
             if (textureType === void 0) { textureType = BABYLON.Engine.TEXTURETYPE_UNSIGNED_INT; }
             if (vertexUrl === void 0) { vertexUrl = "postprocess"; }
             if (blockCompilation === void 0) { blockCompilation = false; }
             this.name = name;
+            /**
+            * Width of the texture to apply the post process on
+            */
             this.width = -1;
+            /**
+            * Height of the texture to apply the post process on
+            */
             this.height = -1;
+            /**
+            * If the buffer needs to be cleared before applying the post process. (default: true)
+            * Should be set to false if shader will overwrite all previous pixels.
+            */
             this.autoClear = true;
+            /**
+            * Type of alpha mode to use when performing the post process (default: Engine.ALPHA_DISABLE)
+            */
             this.alphaMode = BABYLON.Engine.ALPHA_DISABLE;
-            this.animations = new Array();
-            /*
-                Enable Pixel Perfect mode where texture is not scaled to be power of 2.
-                Can only be used on a single postprocess or on the last one of a chain.
+            /**
+            * Animations to be used for the post processing
             */
+            this.animations = new Array();
+            /**
+             * Enable Pixel Perfect mode where texture is not scaled to be power of 2.
+             * Can only be used on a single postprocess or on the last one of a chain. (default: false)
+             */
             this.enablePixelPerfectMode = false;
+            /**
+            * Scale mode for the post process (default: Engine.SCALEMODE_FLOOR)
+            */
             this.scaleMode = BABYLON.Engine.SCALEMODE_FLOOR;
+            /**
+            * Force textures to be a power of two (default: false)
+            */
             this.alwaysForcePOT = false;
+            /**
+            * Number of sample textures (default: 1)
+            */
             this.samples = 1;
+            /**
+            * Modify the scale of the post process to be the same as the viewport (default: false)
+            */
             this.adaptScaleToCurrentViewport = false;
             this._reusable = false;
+            /**
+            * Smart array of input and output textures for the post process.
+            */
             this._textures = new BABYLON.SmartArray(2);
+            /**
+            * The index in _textures that corresponds to the output texture.
+            */
             this._currentRenderTextureInd = 0;
             this._scaleRatio = new BABYLON.Vector2(1, 1);
             this._texelSize = BABYLON.Vector2.Zero();
@@ -56153,6 +56259,9 @@ var BABYLON;
             }
         }
         Object.defineProperty(PostProcess.prototype, "onActivate", {
+            /**
+            * A function that is added to the onActivateObservable
+            */
             set: function (callback) {
                 if (this._onActivateObserver) {
                     this.onActivateObservable.remove(this._onActivateObserver);
@@ -56165,6 +56274,9 @@ var BABYLON;
             configurable: true
         });
         Object.defineProperty(PostProcess.prototype, "onSizeChanged", {
+            /**
+            * A function that is added to the onSizeChangedObservable
+            */
             set: function (callback) {
                 if (this._onSizeChangedObserver) {
                     this.onSizeChangedObservable.remove(this._onSizeChangedObserver);
@@ -56175,6 +56287,9 @@ var BABYLON;
             configurable: true
         });
         Object.defineProperty(PostProcess.prototype, "onApply", {
+            /**
+            * A function that is added to the onApplyObservable
+            */
             set: function (callback) {
                 if (this._onApplyObserver) {
                     this.onApplyObservable.remove(this._onApplyObserver);
@@ -56185,6 +56300,9 @@ var BABYLON;
             configurable: true
         });
         Object.defineProperty(PostProcess.prototype, "onBeforeRender", {
+            /**
+            * A function that is added to the onBeforeRenderObservable
+            */
             set: function (callback) {
                 if (this._onBeforeRenderObserver) {
                     this.onBeforeRenderObservable.remove(this._onBeforeRenderObserver);
@@ -56195,6 +56313,9 @@ var BABYLON;
             configurable: true
         });
         Object.defineProperty(PostProcess.prototype, "onAfterRender", {
+            /**
+            * A function that is added to the onAfterRenderObservable
+            */
             set: function (callback) {
                 if (this._onAfterRenderObserver) {
                     this.onAfterRenderObservable.remove(this._onAfterRenderObserver);
@@ -56205,6 +56326,9 @@ var BABYLON;
             configurable: true
         });
         Object.defineProperty(PostProcess.prototype, "outputTexture", {
+            /**
+            * The resulting output of the post process.
+            */
             get: function () {
                 return this._textures.data[this._currentRenderTextureInd];
             },
@@ -56214,10 +56338,18 @@ var BABYLON;
             enumerable: true,
             configurable: true
         });
+        /**
+        * Gets the camera which post process is applied to.
+        * @returns The camera the post process is applied to.
+        */
         PostProcess.prototype.getCamera = function () {
             return this._camera;
         };
         Object.defineProperty(PostProcess.prototype, "texelSize", {
+            /**
+            * Gets the texel size of the postprocess.
+            * See https://en.wikipedia.org/wiki/Texel_(graphics)
+            */
             get: function () {
                 if (this._shareOutputWithPostProcess) {
                     return this._shareOutputWithPostProcess.texelSize;
@@ -56230,23 +56362,49 @@ var BABYLON;
             enumerable: true,
             configurable: true
         });
+        /**
+         * Gets the engine which this post process belongs to.
+         * @returns The engine the post process was enabled with.
+         */
         PostProcess.prototype.getEngine = function () {
             return this._engine;
         };
+        /**
+         * The effect that is created when initializing the post process.
+         * @returns The created effect corrisponding the the postprocess.
+         */
         PostProcess.prototype.getEffect = function () {
             return this._effect;
         };
+        /**
+         * To avoid multiple redundant textures for multiple post process, the output the output texture for this post process can be shared with another.
+         * @param postProcess The post process to share the output with.
+         * @returns This post process.
+         */
         PostProcess.prototype.shareOutputWith = function (postProcess) {
             this._disposeTextures();
             this._shareOutputWithPostProcess = postProcess;
             return this;
         };
+        /**
+         * Updates the effect with the current post process compile time values and recompiles the shader.
+         * @param defines Define statements that should be added at the beginning of the shader. (default: null)
+         * @param uniforms Set of uniform variables that will be passed to the shader. (default: null)
+         * @param samplers Set of Texture2D variables that will be passed to the shader. (default: null)
+         * @param indexParameters The index parameters to be used for babylons include syntax "#include<kernelBlurVaryingDeclaration>[0..varyingCount]". (default: undefined) See usage in babylon.blurPostProcess.ts and kernelBlur.vertex.fx
+         * @param onCompiled Called when the shader has been compiled.
+         * @param onError Called if there is an error when compiling a shader.
+         */
         PostProcess.prototype.updateEffect = function (defines, uniforms, samplers, indexParameters, onCompiled, onError) {
             if (defines === void 0) { defines = null; }
             if (uniforms === void 0) { uniforms = null; }
             if (samplers === void 0) { samplers = null; }
             this._effect = this._engine.createEffect({ vertex: this._vertexUrl, fragment: this._fragmentUrl }, ["position"], uniforms || this._parameters, samplers || this._samplers, defines !== null ? defines : "", undefined, onCompiled, onError, indexParameters || this._indexParameters);
         };
+        /**
+         * The post process is reusable if it can be used multiple times within one frame.
+         * @returns If the post process is reusable
+         */
         PostProcess.prototype.isReusable = function () {
             return this._reusable;
         };
@@ -56254,6 +56412,12 @@ var BABYLON;
         PostProcess.prototype.markTextureDirty = function () {
             this.width = -1;
         };
+        /**
+         * Activates the post process by intializing the textures to be used when executed. Notifies onActivateObservable.
+         * @param camera The camera that will be used in the post process. This camera will be used when calling onActivateObservable.
+         * @param sourceTexture The source texture to be inspected to get the width and height if not specified in the post process constructor. (default: null)
+         * @param forceDepthStencil If true, a depth and stencil buffer will be generated. (default: false)
+         */
         PostProcess.prototype.activate = function (camera, sourceTexture, forceDepthStencil) {
             var _this = this;
             if (sourceTexture === void 0) { sourceTexture = null; }
@@ -56341,6 +56505,9 @@ var BABYLON;
             }
         };
         Object.defineProperty(PostProcess.prototype, "isSupported", {
+            /**
+             * If the post process is supported.
+             */
             get: function () {
                 return this._effect.isSupported;
             },
@@ -56348,6 +56515,9 @@ var BABYLON;
             configurable: true
         });
         Object.defineProperty(PostProcess.prototype, "aspectRatio", {
+            /**
+             * The aspect ratio of the output texture.
+             */
             get: function () {
                 if (this._shareOutputWithPostProcess) {
                     return this._shareOutputWithPostProcess.aspectRatio;
@@ -56367,6 +56537,10 @@ var BABYLON;
         PostProcess.prototype.isReady = function () {
             return this._effect && this._effect.isReady();
         };
+        /**
+         * Binds all textures and uniforms to the shader, this will be run on every pass.
+         * @returns the effect corrisponding to this post process. Null if not compiled or not ready.
+         */
         PostProcess.prototype.apply = function () {
             // Check
             if (!this._effect || !this._effect.isReady())
@@ -56409,6 +56583,10 @@ var BABYLON;
             }
             this._textures.dispose();
         };
+        /**
+         * Disposes the post process.
+         * @param camera The camera to dispose the post process on.
+         */
         PostProcess.prototype.dispose = function (camera) {
             camera = camera || this._camera;
             this._disposeTextures();
@@ -57918,7 +58096,6 @@ var BABYLON;
         * @param onError a callback with the scene, a message, and possibly an exception when import fails
         */
         SceneLoader.ImportMesh = function (meshNames, rootUrl, sceneFilename, scene, onSuccess, onProgress, onError, pluginExtension) {
-            var _this = this;
             if (onSuccess === void 0) { onSuccess = null; }
             if (onProgress === void 0) { onProgress = null; }
             if (onError === void 0) { onError = null; }
@@ -57969,7 +58146,7 @@ var BABYLON;
                 }
                 if (sceneFilename === "") {
                     if (sceneFilename === "") {
-                        rootUrl = _this._StripFilenameFromRootUrl(rootUrl);
+                        rootUrl = BABYLON.Tools.GetFolderPath(rootUrl, true);
                     }
                 }
                 if (plugin.importMesh) {
@@ -58018,7 +58195,6 @@ var BABYLON;
         * @param onError a callback with the scene, a message, and possibly an exception when import fails
         */
         SceneLoader.Append = function (rootUrl, sceneFilename, scene, onSuccess, onProgress, onError, pluginExtension) {
-            var _this = this;
             if (onSuccess === void 0) { onSuccess = null; }
             if (onProgress === void 0) { onProgress = null; }
             if (onError === void 0) { onError = null; }
@@ -58068,7 +58244,7 @@ var BABYLON;
             };
             return SceneLoader._loadData(rootUrl, sceneFilename, scene, function (plugin, data, responseURL) {
                 if (sceneFilename === "") {
-                    rootUrl = _this._StripFilenameFromRootUrl(rootUrl);
+                    rootUrl = BABYLON.Tools.GetFolderPath(rootUrl, true);
                 }
                 if (plugin.load) {
                     var syncedPlugin = plugin;
@@ -58092,14 +58268,6 @@ var BABYLON;
                 }
             }, progressHandler, errorHandler, disposeHandler, pluginExtension);
         };
-        SceneLoader._StripFilenameFromRootUrl = function (rootUrl) {
-            // We need to strip the filename off from the rootUrl
-            var lastSlash = rootUrl.lastIndexOf("/");
-            if (lastSlash > -1) {
-                rootUrl = rootUrl.substr(0, lastSlash + 1);
-            }
-            return rootUrl;
-        };
         SceneLoader.LoadAssetContainer = function (rootUrl, sceneFilename, scene, onSuccess, onProgress, onError, pluginExtension) {
             if (onSuccess === void 0) { onSuccess = null; }
             if (onProgress === void 0) { onProgress = null; }
@@ -64932,83 +65100,83 @@ var BABYLON;
          */
         function DepthOfFieldEffect(scene, pipelineTextureType) {
             if (pipelineTextureType === void 0) { pipelineTextureType = 0; }
-            var _this = _super.call(this, scene.getEngine(), "depth of field", function () { return [_this.circleOfConfusion, _this.depthOfFieldPass, _this.depthOfFieldBlurY, _this.depthOfFieldBlurX, _this.depthOfFieldMerge]; }, true) || this;
+            var _this = _super.call(this, scene.getEngine(), "depth of field", function () { return [_this._circleOfConfusion, _this._depthOfFieldPass, _this._depthOfFieldBlurY, _this._depthOfFieldBlurX, _this._depthOfFieldMerge]; }, true) || this;
             // Enable and get current depth map
             var depthMap = scene.enableDepthRenderer().getDepthMap();
             // Circle of confusion value for each pixel is used to determine how much to blur that pixel
-            _this.circleOfConfusion = new BABYLON.CircleOfConfusionPostProcess("circleOfConfusion", scene, depthMap, 1, null, BABYLON.Texture.BILINEAR_SAMPLINGMODE, scene.getEngine(), false, pipelineTextureType);
+            _this._circleOfConfusion = new BABYLON.CircleOfConfusionPostProcess("circleOfConfusion", scene, depthMap, 1, null, BABYLON.Texture.BILINEAR_SAMPLINGMODE, scene.getEngine(), false, pipelineTextureType);
             // Capture circle of confusion texture
-            _this.depthOfFieldPass = new BABYLON.PassPostProcess("depthOfFieldPass", 1.0, null, BABYLON.Texture.BILINEAR_SAMPLINGMODE, scene.getEngine(), false, pipelineTextureType);
+            _this._depthOfFieldPass = new BABYLON.PassPostProcess("depthOfFieldPass", 1.0, null, BABYLON.Texture.BILINEAR_SAMPLINGMODE, scene.getEngine(), false, pipelineTextureType);
             // Blur the image but do not blur on sharp far to near distance changes to avoid bleeding artifacts 
             // See section 2.6.2 http://fileadmin.cs.lth.se/cs/education/edan35/lectures/12dof.pdf
-            _this.depthOfFieldBlurY = new BABYLON.DepthOfFieldBlurPostProcess("verticle blur", scene, new BABYLON.Vector2(0, 1.0), 15, 1.0, null, depthMap, _this.circleOfConfusion, BABYLON.Texture.BILINEAR_SAMPLINGMODE, scene.getEngine(), false, pipelineTextureType);
-            _this.depthOfFieldBlurX = new BABYLON.DepthOfFieldBlurPostProcess("horizontal blur", scene, new BABYLON.Vector2(1.0, 0), 15, 1.0, null, depthMap, null, BABYLON.Texture.BILINEAR_SAMPLINGMODE, scene.getEngine(), false, pipelineTextureType);
+            _this._depthOfFieldBlurY = new BABYLON.DepthOfFieldBlurPostProcess("verticle blur", scene, new BABYLON.Vector2(0, 1.0), 15, 1.0, null, depthMap, _this._circleOfConfusion, BABYLON.Texture.BILINEAR_SAMPLINGMODE, scene.getEngine(), false, pipelineTextureType);
+            _this._depthOfFieldBlurX = new BABYLON.DepthOfFieldBlurPostProcess("horizontal blur", scene, new BABYLON.Vector2(1.0, 0), 15, 1.0, null, depthMap, null, BABYLON.Texture.BILINEAR_SAMPLINGMODE, scene.getEngine(), false, pipelineTextureType);
             // Merge blurred images with original image based on circleOfConfusion
-            _this.depthOfFieldMerge = new BABYLON.DepthOfFieldMergePostProcess("depthOfFieldMerge", _this.circleOfConfusion, _this.depthOfFieldPass, 1, null, BABYLON.Texture.BILINEAR_SAMPLINGMODE, scene.getEngine(), false, pipelineTextureType);
+            _this._depthOfFieldMerge = new BABYLON.DepthOfFieldMergePostProcess("depthOfFieldMerge", _this._circleOfConfusion, _this._depthOfFieldPass, 1, null, BABYLON.Texture.BILINEAR_SAMPLINGMODE, scene.getEngine(), false, pipelineTextureType);
             return _this;
         }
         Object.defineProperty(DepthOfFieldEffect.prototype, "kernelSize", {
             get: function () {
-                return this.depthOfFieldBlurX.kernel;
+                return this._depthOfFieldBlurX.kernel;
             },
             /**
              * The size of the kernel to be used for the blur
              */
             set: function (value) {
-                this.depthOfFieldBlurX.kernel = value;
-                this.depthOfFieldBlurY.kernel = value;
+                this._depthOfFieldBlurX.kernel = value;
+                this._depthOfFieldBlurY.kernel = value;
             },
             enumerable: true,
             configurable: true
         });
         Object.defineProperty(DepthOfFieldEffect.prototype, "focalLength", {
             get: function () {
-                return this.circleOfConfusion.focalLength;
+                return this._circleOfConfusion.focalLength;
             },
             /**
              * The focal the length of the camera used in the effect
              */
             set: function (value) {
-                this.circleOfConfusion.focalLength = value;
+                this._circleOfConfusion.focalLength = value;
             },
             enumerable: true,
             configurable: true
         });
         Object.defineProperty(DepthOfFieldEffect.prototype, "fStop", {
             get: function () {
-                return this.circleOfConfusion.fStop;
+                return this._circleOfConfusion.fStop;
             },
             /**
              * F-Stop of the effect's camera. The diamater of the resulting aperture can be computed by lensSize/fStop. (default: 1.4)
              */
             set: function (value) {
-                this.circleOfConfusion.fStop = value;
+                this._circleOfConfusion.fStop = value;
             },
             enumerable: true,
             configurable: true
         });
         Object.defineProperty(DepthOfFieldEffect.prototype, "focusDistance", {
             get: function () {
-                return this.circleOfConfusion.focusDistance;
+                return this._circleOfConfusion.focusDistance;
             },
             /**
              * Distance away from the camera to focus on in scene units/1000 (eg. millimeter). (default: 2000)
              */
             set: function (value) {
-                this.circleOfConfusion.focusDistance = value;
+                this._circleOfConfusion.focusDistance = value;
             },
             enumerable: true,
             configurable: true
         });
         Object.defineProperty(DepthOfFieldEffect.prototype, "lensSize", {
             get: function () {
-                return this.circleOfConfusion.lensSize;
+                return this._circleOfConfusion.lensSize;
             },
             /**
              * Max lens size in scene units/1000 (eg. millimeter). Standard cameras are 50mm. (default: 50) The diamater of the resulting aperture can be computed by lensSize/fStop.
              */
             set: function (value) {
-                this.circleOfConfusion.lensSize = value;
+                this._circleOfConfusion.lensSize = value;
             },
             enumerable: true,
             configurable: true
@@ -65018,11 +65186,11 @@ var BABYLON;
          * @param camera The camera to dispose the effect on.
          */
         DepthOfFieldEffect.prototype.disposeEffects = function (camera) {
-            this.depthOfFieldPass.dispose(camera);
-            this.circleOfConfusion.dispose(camera);
-            this.depthOfFieldBlurX.dispose(camera);
-            this.depthOfFieldBlurY.dispose(camera);
-            this.depthOfFieldMerge.dispose(camera);
+            this._depthOfFieldPass.dispose(camera);
+            this._circleOfConfusion.dispose(camera);
+            this._depthOfFieldBlurX.dispose(camera);
+            this._depthOfFieldBlurY.dispose(camera);
+            this._depthOfFieldMerge.dispose(camera);
         };
         return DepthOfFieldEffect;
     }(BABYLON.PostProcessRenderEffect));
@@ -65039,6 +65207,10 @@ var BABYLON;
 
 var BABYLON;
 (function (BABYLON) {
+    /**
+     * The default rendering pipeline can be added to a scene to apply common post processing effects such as anti-aliasing or depth of field.
+     * See https://doc.babylonjs.com/how_to/using_default_rendering_pipeline
+     */
     var DefaultRenderingPipeline = /** @class */ (function (_super) {
         __extends(DefaultRenderingPipeline, _super);
         /**
@@ -65052,15 +65224,41 @@ var BABYLON;
         function DefaultRenderingPipeline(name, hdr, scene, cameras, automaticBuild) {
             if (automaticBuild === void 0) { automaticBuild = true; }
             var _this = _super.call(this, scene.getEngine(), name) || this;
+            /**
+             * ID of the pass post process used for bloom,
+             */
             _this.PassPostProcessId = "PassPostProcessEffect";
+            /**
+             * ID of the highlight post process used for bloom,
+             */
             _this.HighLightsPostProcessId = "HighLightsPostProcessEffect";
+            /**
+             * ID of the blurX post process used for bloom,
+             */
             _this.BlurXPostProcessId = "BlurXPostProcessEffect";
+            /**
+             * ID of the blurY post process used for bloom,
+             */
             _this.BlurYPostProcessId = "BlurYPostProcessEffect";
+            /**
+             * ID of the copy back post process used for bloom,
+             */
             _this.CopyBackPostProcessId = "CopyBackPostProcessEffect";
+            /**
+             * ID of the image processing post process;
+             */
             _this.ImageProcessingPostProcessId = "ImageProcessingPostProcessEffect";
+            /**
+             * ID of the Fast Approximate Anti-Aliasing post process;
+             */
             _this.FxaaPostProcessId = "FxaaPostProcessEffect";
+            /**
+             * ID of the final merge post process;
+             */
             _this.FinalMergePostProcessId = "FinalMergePostProcessEffect";
-            // IAnimatable
+            /**
+             * Animations which can be used to tweak settings over a period of time
+             */
             _this.animations = [];
             // Values       
             _this._bloomEnabled = false;
@@ -65104,6 +65302,9 @@ var BABYLON;
             get: function () {
                 return this._bloomWeight;
             },
+            /**
+             * The strength of the bloom.
+             */
             set: function (value) {
                 if (this._bloomWeight === value) {
                     return;
@@ -65120,6 +65321,9 @@ var BABYLON;
             get: function () {
                 return this._bloomScale;
             },
+            /**
+             * The scale of the bloom, lower value will provide better performance.
+             */
             set: function (value) {
                 if (this._bloomScale === value) {
                     return;
@@ -65134,6 +65338,9 @@ var BABYLON;
             get: function () {
                 return this._bloomEnabled;
             },
+            /**
+             * Enable or disable the bloom from the pipeline
+             */
             set: function (enabled) {
                 if (this._bloomEnabled === enabled) {
                     return;
@@ -65165,6 +65372,9 @@ var BABYLON;
             get: function () {
                 return this._fxaaEnabled;
             },
+            /**
+             * If the anti aliasing is enabled.
+             */
             set: function (enabled) {
                 if (this._fxaaEnabled === enabled) {
                     return;
@@ -65179,6 +65389,9 @@ var BABYLON;
             get: function () {
                 return this._imageProcessingEnabled;
             },
+            /**
+             * If image processing is enabled.
+             */
             set: function (enabled) {
                 if (this._imageProcessingEnabled === enabled) {
                     return;
@@ -65338,19 +65551,30 @@ var BABYLON;
             this.finalMerge = null;
             this.depthOfField = null;
         };
-        // Dispose
+        /**
+         * Dispose of the pipeline and stop all post processes
+         */
         DefaultRenderingPipeline.prototype.dispose = function () {
             this._disposePostProcesses();
             this._scene.postProcessRenderPipelineManager.detachCamerasFromRenderPipeline(this._name, this._cameras);
             _super.prototype.dispose.call(this);
         };
-        // Serialize rendering pipeline
+        /**
+         * Serialize the rendering pipeline (Used when exporting)
+         * @returns the serialized object
+         */
         DefaultRenderingPipeline.prototype.serialize = function () {
             var serializationObject = BABYLON.SerializationHelper.Serialize(this);
             serializationObject.customType = "DefaultRenderingPipeline";
             return serializationObject;
         };
-        // Parse serialized pipeline
+        /**
+         * Parse the serialized pipeline
+         * @param source Source pipeline.
+         * @param scene The scene to load the pipeline to.
+         * @param rootUrl The URL of the serialized pipeline.
+         * @returns An instantiated pipeline from the serialized object.
+         */
         DefaultRenderingPipeline.Parse = function (source, scene, rootUrl) {
             return BABYLON.SerializationHelper.Parse(function () { return new DefaultRenderingPipeline(source._name, source._name._hdr, scene); }, source, scene, rootUrl);
         };
@@ -66654,9 +66878,25 @@ var BABYLON;
 
 var BABYLON;
 (function (BABYLON) {
+    /**
+     * The Blur Post Process which blurs an image based on a kernel and direction.
+     * Can be used twice in x and y directions to perform a guassian blur in two passes.
+     */
     var BlurPostProcess = /** @class */ (function (_super) {
         __extends(BlurPostProcess, _super);
-        function BlurPostProcess(name, direction, kernel, options, camera, samplingMode, engine, reusable, textureType) {
+        /**
+         * Creates a new instance of @see BlurPostProcess
+         * @param name The name of the effect.
+         * @param direction The direction in which to blur the image.
+         * @param kernel The size of the kernel to be used when computing the blur. eg. Size of 3 will blur the center pixel by 2 pixels surrounding it.
+         * @param options The required width/height ratio to downsize to before computing the render pass. (Use 1.0 for full size)
+         * @param camera The camera to apply the render pass to.
+         * @param samplingMode The sampling mode to be used when computing the pass. (default: 0)
+         * @param engine The engine which the post process will be applied. (default: current engine)
+         * @param reusable If the post process can be reused on the same frame. (default: false)
+         * @param textureType Type of textures used when performing the post process. (default: 0)
+         */
+        function BlurPostProcess(name, /** The direction in which to blur the image. */ direction, kernel, options, camera, samplingMode, engine, reusable, textureType) {
             if (samplingMode === void 0) { samplingMode = BABYLON.Texture.BILINEAR_SAMPLINGMODE; }
             if (textureType === void 0) { textureType = BABYLON.Engine.TEXTURETYPE_UNSIGNED_INT; }
             var _this = _super.call(this, name, "kernelBlur", ["delta", "direction", "cameraMinMaxZ"], ["depthSampler"], options, camera, samplingMode, engine, reusable, null, textureType, "kernelBlur", { varyingCount: 0, depCount: 0 }, true) || this;

+ 293 - 53
dist/preview release/customConfigurations/minimalGLTFViewer/es6.js

@@ -7088,10 +7088,21 @@ var BABYLON;
                 return path;
             return path.substring(index + 1);
         };
-        Tools.GetFolderPath = function (uri) {
+        /**
+         * Extracts the "folder" part of a path (everything before the filename).
+         * @param uri The URI to extract the info from
+         * @param returnUnchangedIfNoSlash Do not touch the URI if no slashes are present
+         * @returns The "folder" part of the path
+         */
+        Tools.GetFolderPath = function (uri, returnUnchangedIfNoSlash) {
+            if (returnUnchangedIfNoSlash === void 0) { returnUnchangedIfNoSlash = false; }
             var index = uri.lastIndexOf("/");
-            if (index < 0)
+            if (index < 0) {
+                if (returnUnchangedIfNoSlash) {
+                    return uri;
+                }
                 return "";
+            }
             return uri.substring(0, index + 1);
         };
         Tools.GetDOMTextContent = function (element) {
@@ -8633,19 +8644,20 @@ var BABYLON;
             return newPromise;
         };
         InternalPromise.prototype._moveChildren = function (children) {
-            this._children = children.splice(0, children.length);
+            (_a = this._children).push.apply(_a, children.splice(0, children.length));
             if (this.isFulfilled) {
-                for (var _i = 0, _a = this._children; _i < _a.length; _i++) {
-                    var child = _a[_i];
+                for (var _i = 0, _b = this._children; _i < _b.length; _i++) {
+                    var child = _b[_i];
                     child._resolve(this._result);
                 }
             }
             else if (this.isRejected) {
-                for (var _b = 0, _c = this._children; _b < _c.length; _b++) {
-                    var child = _c[_b];
+                for (var _c = 0, _d = this._children; _c < _d.length; _c++) {
+                    var child = _d[_c];
                     child._reject(this._reason);
                 }
             }
+            var _a;
         };
         InternalPromise.prototype._resolve = function (value) {
             try {
@@ -8717,8 +8729,13 @@ var BABYLON;
             var agregator = new FulFillmentAgregator();
             agregator.target = promises.length;
             agregator.rootPromise = newPromise;
-            for (var index = 0; index < promises.length; index++) {
-                InternalPromise._RegisterForFulfillment(promises[index], agregator, index);
+            if (promises.length) {
+                for (var index = 0; index < promises.length; index++) {
+                    InternalPromise._RegisterForFulfillment(promises[index], agregator, index);
+                }
+            }
+            else {
+                newPromise._resolve([]);
             }
             return newPromise;
         };
@@ -34639,7 +34656,15 @@ var BABYLON;
 
 var BABYLON;
 (function (BABYLON) {
+    /**
+     * PostProcessManager is used to manage one or more post processes or post process pipelines
+     * See https://doc.babylonjs.com/how_to/how_to_use_postprocesses
+     */
     var PostProcessManager = /** @class */ (function () {
+        /**
+         * Creates a new instance of @see PostProcess
+         * @param scene The scene that the post process is associated with.
+         */
         function PostProcessManager(scene) {
             this._vertexBuffers = {};
             this._scene = scene;
@@ -34668,6 +34693,9 @@ var BABYLON;
             indices.push(3);
             this._indexBuffer = this._scene.getEngine().createIndexBuffer(indices);
         };
+        /**
+         * Rebuilds the vertex buffers of the manager.
+         */
         PostProcessManager.prototype._rebuild = function () {
             var vb = this._vertexBuffers[BABYLON.VertexBuffer.PositionKind];
             if (!vb) {
@@ -34677,6 +34705,12 @@ var BABYLON;
             this._buildIndexBuffer();
         };
         // Methods
+        /**
+         * Prepares a frame to be run through a post process.
+         * @param sourceTexture The input texture to the post procesess. (default: null)
+         * @param postProcesses An array of post processes to be run. (default: null)
+         * @returns True if the post processes were able to be run.
+         */
         PostProcessManager.prototype._prepareFrame = function (sourceTexture, postProcesses) {
             if (sourceTexture === void 0) { sourceTexture = null; }
             if (postProcesses === void 0) { postProcesses = null; }
@@ -34691,6 +34725,12 @@ var BABYLON;
             postProcesses[0].activate(camera, sourceTexture, postProcesses !== null && postProcesses !== undefined);
             return true;
         };
+        /**
+         * Manually render a set of post processes to a texture.
+         * @param postProcesses An array of post processes to be run.
+         * @param targetTexture The target texture to render to.
+         * @param forceFullscreenViewport force gl.viewport to be full screen eg. 0,0,textureWidth,textureHeight
+         */
         PostProcessManager.prototype.directRender = function (postProcesses, targetTexture, forceFullscreenViewport) {
             if (targetTexture === void 0) { targetTexture = null; }
             if (forceFullscreenViewport === void 0) { forceFullscreenViewport = false; }
@@ -34723,6 +34763,14 @@ var BABYLON;
             engine.setDepthBuffer(true);
             engine.setDepthWrite(true);
         };
+        /**
+         * Finalize the result of the output of the postprocesses.
+         * @param doNotPresent If true the result will not be displayed to the screen.
+         * @param targetTexture The target texture to render to.
+         * @param faceIndex The index of the face to bind the target texture to.
+         * @param postProcesses The array of post processes to render.
+         * @param forceFullscreenViewport force gl.viewport to be full screen eg. 0,0,textureWidth,textureHeight (default: false)
+         */
         PostProcessManager.prototype._finalizeFrame = function (doNotPresent, targetTexture, faceIndex, postProcesses, forceFullscreenViewport) {
             if (forceFullscreenViewport === void 0) { forceFullscreenViewport = false; }
             var camera = this._scene.activeCamera;
@@ -34766,6 +34814,9 @@ var BABYLON;
             engine.setDepthWrite(true);
             engine.setAlphaMode(BABYLON.Engine.ALPHA_DISABLE);
         };
+        /**
+         * Disposes of the post process manager.
+         */
         PostProcessManager.prototype.dispose = function () {
             var buffer = this._vertexBuffers[BABYLON.VertexBuffer.PositionKind];
             if (buffer) {
@@ -56059,30 +56110,85 @@ var BABYLON;
 
 var BABYLON;
 (function (BABYLON) {
+    /**
+     * PostProcess can be used to apply a shader to a texture after it has been rendered
+     * See https://doc.babylonjs.com/how_to/how_to_use_postprocesses
+     */
     var PostProcess = /** @class */ (function () {
-        function PostProcess(name, fragmentUrl, parameters, samplers, options, camera, samplingMode, engine, reusable, defines, textureType, vertexUrl, indexParameters, blockCompilation) {
+        /**
+         * Creates a new instance of @see PostProcess
+         * @param name The name of the PostProcess.
+         * @param fragmentUrl The url of the fragment shader to be used.
+         * @param parameters Array of the names of uniform non-sampler2D variables that will be passed to the shader.
+         * @param samplers Array of the names of uniform sampler2D variables that will be passed to the shader.
+         * @param options The required width/height ratio to downsize to before computing the render pass. (Use 1.0 for full size)
+         * @param camera The camera to apply the render pass to.
+         * @param samplingMode The sampling mode to be used when computing the pass. (default: 0)
+         * @param engine The engine which the post process will be applied. (default: current engine)
+         * @param reusable If the post process can be reused on the same frame. (default: false)
+         * @param defines String of defines that will be set when running the fragment shader. (default: null)
+         * @param textureType Type of textures used when performing the post process. (default: 0)
+         * @param vertexUrl The url of the vertex shader to be used. (default: "postprocess")
+         * @param indexParameters The index parameters to be used for babylons include syntax "#include<kernelBlurVaryingDeclaration>[0..varyingCount]". (default: undefined) See usage in babylon.blurPostProcess.ts and kernelBlur.vertex.fx
+         * @param blockCompilation If the shader should be compiled imediatly. (default: false)
+         */
+        function PostProcess(/** Name of the PostProcess. */ name, fragmentUrl, parameters, samplers, options, camera, samplingMode, engine, reusable, defines, textureType, vertexUrl, indexParameters, blockCompilation) {
             if (samplingMode === void 0) { samplingMode = BABYLON.Texture.NEAREST_SAMPLINGMODE; }
             if (defines === void 0) { defines = null; }
             if (textureType === void 0) { textureType = BABYLON.Engine.TEXTURETYPE_UNSIGNED_INT; }
             if (vertexUrl === void 0) { vertexUrl = "postprocess"; }
             if (blockCompilation === void 0) { blockCompilation = false; }
             this.name = name;
+            /**
+            * Width of the texture to apply the post process on
+            */
             this.width = -1;
+            /**
+            * Height of the texture to apply the post process on
+            */
             this.height = -1;
+            /**
+            * If the buffer needs to be cleared before applying the post process. (default: true)
+            * Should be set to false if shader will overwrite all previous pixels.
+            */
             this.autoClear = true;
+            /**
+            * Type of alpha mode to use when performing the post process (default: Engine.ALPHA_DISABLE)
+            */
             this.alphaMode = BABYLON.Engine.ALPHA_DISABLE;
-            this.animations = new Array();
-            /*
-                Enable Pixel Perfect mode where texture is not scaled to be power of 2.
-                Can only be used on a single postprocess or on the last one of a chain.
+            /**
+            * Animations to be used for the post processing
             */
+            this.animations = new Array();
+            /**
+             * Enable Pixel Perfect mode where texture is not scaled to be power of 2.
+             * Can only be used on a single postprocess or on the last one of a chain. (default: false)
+             */
             this.enablePixelPerfectMode = false;
+            /**
+            * Scale mode for the post process (default: Engine.SCALEMODE_FLOOR)
+            */
             this.scaleMode = BABYLON.Engine.SCALEMODE_FLOOR;
+            /**
+            * Force textures to be a power of two (default: false)
+            */
             this.alwaysForcePOT = false;
+            /**
+            * Number of sample textures (default: 1)
+            */
             this.samples = 1;
+            /**
+            * Modify the scale of the post process to be the same as the viewport (default: false)
+            */
             this.adaptScaleToCurrentViewport = false;
             this._reusable = false;
+            /**
+            * Smart array of input and output textures for the post process.
+            */
             this._textures = new BABYLON.SmartArray(2);
+            /**
+            * The index in _textures that corresponds to the output texture.
+            */
             this._currentRenderTextureInd = 0;
             this._scaleRatio = new BABYLON.Vector2(1, 1);
             this._texelSize = BABYLON.Vector2.Zero();
@@ -56139,6 +56245,9 @@ var BABYLON;
             }
         }
         Object.defineProperty(PostProcess.prototype, "onActivate", {
+            /**
+            * A function that is added to the onActivateObservable
+            */
             set: function (callback) {
                 if (this._onActivateObserver) {
                     this.onActivateObservable.remove(this._onActivateObserver);
@@ -56151,6 +56260,9 @@ var BABYLON;
             configurable: true
         });
         Object.defineProperty(PostProcess.prototype, "onSizeChanged", {
+            /**
+            * A function that is added to the onSizeChangedObservable
+            */
             set: function (callback) {
                 if (this._onSizeChangedObserver) {
                     this.onSizeChangedObservable.remove(this._onSizeChangedObserver);
@@ -56161,6 +56273,9 @@ var BABYLON;
             configurable: true
         });
         Object.defineProperty(PostProcess.prototype, "onApply", {
+            /**
+            * A function that is added to the onApplyObservable
+            */
             set: function (callback) {
                 if (this._onApplyObserver) {
                     this.onApplyObservable.remove(this._onApplyObserver);
@@ -56171,6 +56286,9 @@ var BABYLON;
             configurable: true
         });
         Object.defineProperty(PostProcess.prototype, "onBeforeRender", {
+            /**
+            * A function that is added to the onBeforeRenderObservable
+            */
             set: function (callback) {
                 if (this._onBeforeRenderObserver) {
                     this.onBeforeRenderObservable.remove(this._onBeforeRenderObserver);
@@ -56181,6 +56299,9 @@ var BABYLON;
             configurable: true
         });
         Object.defineProperty(PostProcess.prototype, "onAfterRender", {
+            /**
+            * A function that is added to the onAfterRenderObservable
+            */
             set: function (callback) {
                 if (this._onAfterRenderObserver) {
                     this.onAfterRenderObservable.remove(this._onAfterRenderObserver);
@@ -56191,6 +56312,9 @@ var BABYLON;
             configurable: true
         });
         Object.defineProperty(PostProcess.prototype, "outputTexture", {
+            /**
+            * The resulting output of the post process.
+            */
             get: function () {
                 return this._textures.data[this._currentRenderTextureInd];
             },
@@ -56200,10 +56324,18 @@ var BABYLON;
             enumerable: true,
             configurable: true
         });
+        /**
+        * Gets the camera which post process is applied to.
+        * @returns The camera the post process is applied to.
+        */
         PostProcess.prototype.getCamera = function () {
             return this._camera;
         };
         Object.defineProperty(PostProcess.prototype, "texelSize", {
+            /**
+            * Gets the texel size of the postprocess.
+            * See https://en.wikipedia.org/wiki/Texel_(graphics)
+            */
             get: function () {
                 if (this._shareOutputWithPostProcess) {
                     return this._shareOutputWithPostProcess.texelSize;
@@ -56216,23 +56348,49 @@ var BABYLON;
             enumerable: true,
             configurable: true
         });
+        /**
+         * Gets the engine which this post process belongs to.
+         * @returns The engine the post process was enabled with.
+         */
         PostProcess.prototype.getEngine = function () {
             return this._engine;
         };
+        /**
+         * The effect that is created when initializing the post process.
+         * @returns The created effect corrisponding the the postprocess.
+         */
         PostProcess.prototype.getEffect = function () {
             return this._effect;
         };
+        /**
+         * To avoid multiple redundant textures for multiple post process, the output the output texture for this post process can be shared with another.
+         * @param postProcess The post process to share the output with.
+         * @returns This post process.
+         */
         PostProcess.prototype.shareOutputWith = function (postProcess) {
             this._disposeTextures();
             this._shareOutputWithPostProcess = postProcess;
             return this;
         };
+        /**
+         * Updates the effect with the current post process compile time values and recompiles the shader.
+         * @param defines Define statements that should be added at the beginning of the shader. (default: null)
+         * @param uniforms Set of uniform variables that will be passed to the shader. (default: null)
+         * @param samplers Set of Texture2D variables that will be passed to the shader. (default: null)
+         * @param indexParameters The index parameters to be used for babylons include syntax "#include<kernelBlurVaryingDeclaration>[0..varyingCount]". (default: undefined) See usage in babylon.blurPostProcess.ts and kernelBlur.vertex.fx
+         * @param onCompiled Called when the shader has been compiled.
+         * @param onError Called if there is an error when compiling a shader.
+         */
         PostProcess.prototype.updateEffect = function (defines, uniforms, samplers, indexParameters, onCompiled, onError) {
             if (defines === void 0) { defines = null; }
             if (uniforms === void 0) { uniforms = null; }
             if (samplers === void 0) { samplers = null; }
             this._effect = this._engine.createEffect({ vertex: this._vertexUrl, fragment: this._fragmentUrl }, ["position"], uniforms || this._parameters, samplers || this._samplers, defines !== null ? defines : "", undefined, onCompiled, onError, indexParameters || this._indexParameters);
         };
+        /**
+         * The post process is reusable if it can be used multiple times within one frame.
+         * @returns If the post process is reusable
+         */
         PostProcess.prototype.isReusable = function () {
             return this._reusable;
         };
@@ -56240,6 +56398,12 @@ var BABYLON;
         PostProcess.prototype.markTextureDirty = function () {
             this.width = -1;
         };
+        /**
+         * Activates the post process by intializing the textures to be used when executed. Notifies onActivateObservable.
+         * @param camera The camera that will be used in the post process. This camera will be used when calling onActivateObservable.
+         * @param sourceTexture The source texture to be inspected to get the width and height if not specified in the post process constructor. (default: null)
+         * @param forceDepthStencil If true, a depth and stencil buffer will be generated. (default: false)
+         */
         PostProcess.prototype.activate = function (camera, sourceTexture, forceDepthStencil) {
             var _this = this;
             if (sourceTexture === void 0) { sourceTexture = null; }
@@ -56327,6 +56491,9 @@ var BABYLON;
             }
         };
         Object.defineProperty(PostProcess.prototype, "isSupported", {
+            /**
+             * If the post process is supported.
+             */
             get: function () {
                 return this._effect.isSupported;
             },
@@ -56334,6 +56501,9 @@ var BABYLON;
             configurable: true
         });
         Object.defineProperty(PostProcess.prototype, "aspectRatio", {
+            /**
+             * The aspect ratio of the output texture.
+             */
             get: function () {
                 if (this._shareOutputWithPostProcess) {
                     return this._shareOutputWithPostProcess.aspectRatio;
@@ -56353,6 +56523,10 @@ var BABYLON;
         PostProcess.prototype.isReady = function () {
             return this._effect && this._effect.isReady();
         };
+        /**
+         * Binds all textures and uniforms to the shader, this will be run on every pass.
+         * @returns the effect corrisponding to this post process. Null if not compiled or not ready.
+         */
         PostProcess.prototype.apply = function () {
             // Check
             if (!this._effect || !this._effect.isReady())
@@ -56395,6 +56569,10 @@ var BABYLON;
             }
             this._textures.dispose();
         };
+        /**
+         * Disposes the post process.
+         * @param camera The camera to dispose the post process on.
+         */
         PostProcess.prototype.dispose = function (camera) {
             camera = camera || this._camera;
             this._disposeTextures();
@@ -57904,7 +58082,6 @@ var BABYLON;
         * @param onError a callback with the scene, a message, and possibly an exception when import fails
         */
         SceneLoader.ImportMesh = function (meshNames, rootUrl, sceneFilename, scene, onSuccess, onProgress, onError, pluginExtension) {
-            var _this = this;
             if (onSuccess === void 0) { onSuccess = null; }
             if (onProgress === void 0) { onProgress = null; }
             if (onError === void 0) { onError = null; }
@@ -57955,7 +58132,7 @@ var BABYLON;
                 }
                 if (sceneFilename === "") {
                     if (sceneFilename === "") {
-                        rootUrl = _this._StripFilenameFromRootUrl(rootUrl);
+                        rootUrl = BABYLON.Tools.GetFolderPath(rootUrl, true);
                     }
                 }
                 if (plugin.importMesh) {
@@ -58004,7 +58181,6 @@ var BABYLON;
         * @param onError a callback with the scene, a message, and possibly an exception when import fails
         */
         SceneLoader.Append = function (rootUrl, sceneFilename, scene, onSuccess, onProgress, onError, pluginExtension) {
-            var _this = this;
             if (onSuccess === void 0) { onSuccess = null; }
             if (onProgress === void 0) { onProgress = null; }
             if (onError === void 0) { onError = null; }
@@ -58054,7 +58230,7 @@ var BABYLON;
             };
             return SceneLoader._loadData(rootUrl, sceneFilename, scene, function (plugin, data, responseURL) {
                 if (sceneFilename === "") {
-                    rootUrl = _this._StripFilenameFromRootUrl(rootUrl);
+                    rootUrl = BABYLON.Tools.GetFolderPath(rootUrl, true);
                 }
                 if (plugin.load) {
                     var syncedPlugin = plugin;
@@ -58078,14 +58254,6 @@ var BABYLON;
                 }
             }, progressHandler, errorHandler, disposeHandler, pluginExtension);
         };
-        SceneLoader._StripFilenameFromRootUrl = function (rootUrl) {
-            // We need to strip the filename off from the rootUrl
-            var lastSlash = rootUrl.lastIndexOf("/");
-            if (lastSlash > -1) {
-                rootUrl = rootUrl.substr(0, lastSlash + 1);
-            }
-            return rootUrl;
-        };
         SceneLoader.LoadAssetContainer = function (rootUrl, sceneFilename, scene, onSuccess, onProgress, onError, pluginExtension) {
             if (onSuccess === void 0) { onSuccess = null; }
             if (onProgress === void 0) { onProgress = null; }
@@ -64918,83 +65086,83 @@ var BABYLON;
          */
         function DepthOfFieldEffect(scene, pipelineTextureType) {
             if (pipelineTextureType === void 0) { pipelineTextureType = 0; }
-            var _this = _super.call(this, scene.getEngine(), "depth of field", function () { return [_this.circleOfConfusion, _this.depthOfFieldPass, _this.depthOfFieldBlurY, _this.depthOfFieldBlurX, _this.depthOfFieldMerge]; }, true) || this;
+            var _this = _super.call(this, scene.getEngine(), "depth of field", function () { return [_this._circleOfConfusion, _this._depthOfFieldPass, _this._depthOfFieldBlurY, _this._depthOfFieldBlurX, _this._depthOfFieldMerge]; }, true) || this;
             // Enable and get current depth map
             var depthMap = scene.enableDepthRenderer().getDepthMap();
             // Circle of confusion value for each pixel is used to determine how much to blur that pixel
-            _this.circleOfConfusion = new BABYLON.CircleOfConfusionPostProcess("circleOfConfusion", scene, depthMap, 1, null, BABYLON.Texture.BILINEAR_SAMPLINGMODE, scene.getEngine(), false, pipelineTextureType);
+            _this._circleOfConfusion = new BABYLON.CircleOfConfusionPostProcess("circleOfConfusion", scene, depthMap, 1, null, BABYLON.Texture.BILINEAR_SAMPLINGMODE, scene.getEngine(), false, pipelineTextureType);
             // Capture circle of confusion texture
-            _this.depthOfFieldPass = new BABYLON.PassPostProcess("depthOfFieldPass", 1.0, null, BABYLON.Texture.BILINEAR_SAMPLINGMODE, scene.getEngine(), false, pipelineTextureType);
+            _this._depthOfFieldPass = new BABYLON.PassPostProcess("depthOfFieldPass", 1.0, null, BABYLON.Texture.BILINEAR_SAMPLINGMODE, scene.getEngine(), false, pipelineTextureType);
             // Blur the image but do not blur on sharp far to near distance changes to avoid bleeding artifacts 
             // See section 2.6.2 http://fileadmin.cs.lth.se/cs/education/edan35/lectures/12dof.pdf
-            _this.depthOfFieldBlurY = new BABYLON.DepthOfFieldBlurPostProcess("verticle blur", scene, new BABYLON.Vector2(0, 1.0), 15, 1.0, null, depthMap, _this.circleOfConfusion, BABYLON.Texture.BILINEAR_SAMPLINGMODE, scene.getEngine(), false, pipelineTextureType);
-            _this.depthOfFieldBlurX = new BABYLON.DepthOfFieldBlurPostProcess("horizontal blur", scene, new BABYLON.Vector2(1.0, 0), 15, 1.0, null, depthMap, null, BABYLON.Texture.BILINEAR_SAMPLINGMODE, scene.getEngine(), false, pipelineTextureType);
+            _this._depthOfFieldBlurY = new BABYLON.DepthOfFieldBlurPostProcess("verticle blur", scene, new BABYLON.Vector2(0, 1.0), 15, 1.0, null, depthMap, _this._circleOfConfusion, BABYLON.Texture.BILINEAR_SAMPLINGMODE, scene.getEngine(), false, pipelineTextureType);
+            _this._depthOfFieldBlurX = new BABYLON.DepthOfFieldBlurPostProcess("horizontal blur", scene, new BABYLON.Vector2(1.0, 0), 15, 1.0, null, depthMap, null, BABYLON.Texture.BILINEAR_SAMPLINGMODE, scene.getEngine(), false, pipelineTextureType);
             // Merge blurred images with original image based on circleOfConfusion
-            _this.depthOfFieldMerge = new BABYLON.DepthOfFieldMergePostProcess("depthOfFieldMerge", _this.circleOfConfusion, _this.depthOfFieldPass, 1, null, BABYLON.Texture.BILINEAR_SAMPLINGMODE, scene.getEngine(), false, pipelineTextureType);
+            _this._depthOfFieldMerge = new BABYLON.DepthOfFieldMergePostProcess("depthOfFieldMerge", _this._circleOfConfusion, _this._depthOfFieldPass, 1, null, BABYLON.Texture.BILINEAR_SAMPLINGMODE, scene.getEngine(), false, pipelineTextureType);
             return _this;
         }
         Object.defineProperty(DepthOfFieldEffect.prototype, "kernelSize", {
             get: function () {
-                return this.depthOfFieldBlurX.kernel;
+                return this._depthOfFieldBlurX.kernel;
             },
             /**
              * The size of the kernel to be used for the blur
              */
             set: function (value) {
-                this.depthOfFieldBlurX.kernel = value;
-                this.depthOfFieldBlurY.kernel = value;
+                this._depthOfFieldBlurX.kernel = value;
+                this._depthOfFieldBlurY.kernel = value;
             },
             enumerable: true,
             configurable: true
         });
         Object.defineProperty(DepthOfFieldEffect.prototype, "focalLength", {
             get: function () {
-                return this.circleOfConfusion.focalLength;
+                return this._circleOfConfusion.focalLength;
             },
             /**
              * The focal the length of the camera used in the effect
              */
             set: function (value) {
-                this.circleOfConfusion.focalLength = value;
+                this._circleOfConfusion.focalLength = value;
             },
             enumerable: true,
             configurable: true
         });
         Object.defineProperty(DepthOfFieldEffect.prototype, "fStop", {
             get: function () {
-                return this.circleOfConfusion.fStop;
+                return this._circleOfConfusion.fStop;
             },
             /**
              * F-Stop of the effect's camera. The diamater of the resulting aperture can be computed by lensSize/fStop. (default: 1.4)
              */
             set: function (value) {
-                this.circleOfConfusion.fStop = value;
+                this._circleOfConfusion.fStop = value;
             },
             enumerable: true,
             configurable: true
         });
         Object.defineProperty(DepthOfFieldEffect.prototype, "focusDistance", {
             get: function () {
-                return this.circleOfConfusion.focusDistance;
+                return this._circleOfConfusion.focusDistance;
             },
             /**
              * Distance away from the camera to focus on in scene units/1000 (eg. millimeter). (default: 2000)
              */
             set: function (value) {
-                this.circleOfConfusion.focusDistance = value;
+                this._circleOfConfusion.focusDistance = value;
             },
             enumerable: true,
             configurable: true
         });
         Object.defineProperty(DepthOfFieldEffect.prototype, "lensSize", {
             get: function () {
-                return this.circleOfConfusion.lensSize;
+                return this._circleOfConfusion.lensSize;
             },
             /**
              * Max lens size in scene units/1000 (eg. millimeter). Standard cameras are 50mm. (default: 50) The diamater of the resulting aperture can be computed by lensSize/fStop.
              */
             set: function (value) {
-                this.circleOfConfusion.lensSize = value;
+                this._circleOfConfusion.lensSize = value;
             },
             enumerable: true,
             configurable: true
@@ -65004,11 +65172,11 @@ var BABYLON;
          * @param camera The camera to dispose the effect on.
          */
         DepthOfFieldEffect.prototype.disposeEffects = function (camera) {
-            this.depthOfFieldPass.dispose(camera);
-            this.circleOfConfusion.dispose(camera);
-            this.depthOfFieldBlurX.dispose(camera);
-            this.depthOfFieldBlurY.dispose(camera);
-            this.depthOfFieldMerge.dispose(camera);
+            this._depthOfFieldPass.dispose(camera);
+            this._circleOfConfusion.dispose(camera);
+            this._depthOfFieldBlurX.dispose(camera);
+            this._depthOfFieldBlurY.dispose(camera);
+            this._depthOfFieldMerge.dispose(camera);
         };
         return DepthOfFieldEffect;
     }(BABYLON.PostProcessRenderEffect));
@@ -65025,6 +65193,10 @@ var BABYLON;
 
 var BABYLON;
 (function (BABYLON) {
+    /**
+     * The default rendering pipeline can be added to a scene to apply common post processing effects such as anti-aliasing or depth of field.
+     * See https://doc.babylonjs.com/how_to/using_default_rendering_pipeline
+     */
     var DefaultRenderingPipeline = /** @class */ (function (_super) {
         __extends(DefaultRenderingPipeline, _super);
         /**
@@ -65038,15 +65210,41 @@ var BABYLON;
         function DefaultRenderingPipeline(name, hdr, scene, cameras, automaticBuild) {
             if (automaticBuild === void 0) { automaticBuild = true; }
             var _this = _super.call(this, scene.getEngine(), name) || this;
+            /**
+             * ID of the pass post process used for bloom,
+             */
             _this.PassPostProcessId = "PassPostProcessEffect";
+            /**
+             * ID of the highlight post process used for bloom,
+             */
             _this.HighLightsPostProcessId = "HighLightsPostProcessEffect";
+            /**
+             * ID of the blurX post process used for bloom,
+             */
             _this.BlurXPostProcessId = "BlurXPostProcessEffect";
+            /**
+             * ID of the blurY post process used for bloom,
+             */
             _this.BlurYPostProcessId = "BlurYPostProcessEffect";
+            /**
+             * ID of the copy back post process used for bloom,
+             */
             _this.CopyBackPostProcessId = "CopyBackPostProcessEffect";
+            /**
+             * ID of the image processing post process;
+             */
             _this.ImageProcessingPostProcessId = "ImageProcessingPostProcessEffect";
+            /**
+             * ID of the Fast Approximate Anti-Aliasing post process;
+             */
             _this.FxaaPostProcessId = "FxaaPostProcessEffect";
+            /**
+             * ID of the final merge post process;
+             */
             _this.FinalMergePostProcessId = "FinalMergePostProcessEffect";
-            // IAnimatable
+            /**
+             * Animations which can be used to tweak settings over a period of time
+             */
             _this.animations = [];
             // Values       
             _this._bloomEnabled = false;
@@ -65090,6 +65288,9 @@ var BABYLON;
             get: function () {
                 return this._bloomWeight;
             },
+            /**
+             * The strength of the bloom.
+             */
             set: function (value) {
                 if (this._bloomWeight === value) {
                     return;
@@ -65106,6 +65307,9 @@ var BABYLON;
             get: function () {
                 return this._bloomScale;
             },
+            /**
+             * The scale of the bloom, lower value will provide better performance.
+             */
             set: function (value) {
                 if (this._bloomScale === value) {
                     return;
@@ -65120,6 +65324,9 @@ var BABYLON;
             get: function () {
                 return this._bloomEnabled;
             },
+            /**
+             * Enable or disable the bloom from the pipeline
+             */
             set: function (enabled) {
                 if (this._bloomEnabled === enabled) {
                     return;
@@ -65151,6 +65358,9 @@ var BABYLON;
             get: function () {
                 return this._fxaaEnabled;
             },
+            /**
+             * If the anti aliasing is enabled.
+             */
             set: function (enabled) {
                 if (this._fxaaEnabled === enabled) {
                     return;
@@ -65165,6 +65375,9 @@ var BABYLON;
             get: function () {
                 return this._imageProcessingEnabled;
             },
+            /**
+             * If image processing is enabled.
+             */
             set: function (enabled) {
                 if (this._imageProcessingEnabled === enabled) {
                     return;
@@ -65324,19 +65537,30 @@ var BABYLON;
             this.finalMerge = null;
             this.depthOfField = null;
         };
-        // Dispose
+        /**
+         * Dispose of the pipeline and stop all post processes
+         */
         DefaultRenderingPipeline.prototype.dispose = function () {
             this._disposePostProcesses();
             this._scene.postProcessRenderPipelineManager.detachCamerasFromRenderPipeline(this._name, this._cameras);
             _super.prototype.dispose.call(this);
         };
-        // Serialize rendering pipeline
+        /**
+         * Serialize the rendering pipeline (Used when exporting)
+         * @returns the serialized object
+         */
         DefaultRenderingPipeline.prototype.serialize = function () {
             var serializationObject = BABYLON.SerializationHelper.Serialize(this);
             serializationObject.customType = "DefaultRenderingPipeline";
             return serializationObject;
         };
-        // Parse serialized pipeline
+        /**
+         * Parse the serialized pipeline
+         * @param source Source pipeline.
+         * @param scene The scene to load the pipeline to.
+         * @param rootUrl The URL of the serialized pipeline.
+         * @returns An instantiated pipeline from the serialized object.
+         */
         DefaultRenderingPipeline.Parse = function (source, scene, rootUrl) {
             return BABYLON.SerializationHelper.Parse(function () { return new DefaultRenderingPipeline(source._name, source._name._hdr, scene); }, source, scene, rootUrl);
         };
@@ -66640,9 +66864,25 @@ var BABYLON;
 
 var BABYLON;
 (function (BABYLON) {
+    /**
+     * The Blur Post Process which blurs an image based on a kernel and direction.
+     * Can be used twice in x and y directions to perform a guassian blur in two passes.
+     */
     var BlurPostProcess = /** @class */ (function (_super) {
         __extends(BlurPostProcess, _super);
-        function BlurPostProcess(name, direction, kernel, options, camera, samplingMode, engine, reusable, textureType) {
+        /**
+         * Creates a new instance of @see BlurPostProcess
+         * @param name The name of the effect.
+         * @param direction The direction in which to blur the image.
+         * @param kernel The size of the kernel to be used when computing the blur. eg. Size of 3 will blur the center pixel by 2 pixels surrounding it.
+         * @param options The required width/height ratio to downsize to before computing the render pass. (Use 1.0 for full size)
+         * @param camera The camera to apply the render pass to.
+         * @param samplingMode The sampling mode to be used when computing the pass. (default: 0)
+         * @param engine The engine which the post process will be applied. (default: current engine)
+         * @param reusable If the post process can be reused on the same frame. (default: false)
+         * @param textureType Type of textures used when performing the post process. (default: 0)
+         */
+        function BlurPostProcess(name, /** The direction in which to blur the image. */ direction, kernel, options, camera, samplingMode, engine, reusable, textureType) {
             if (samplingMode === void 0) { samplingMode = BABYLON.Texture.BILINEAR_SAMPLINGMODE; }
             if (textureType === void 0) { textureType = BABYLON.Engine.TEXTURETYPE_UNSIGNED_INT; }
             var _this = _super.call(this, name, "kernelBlur", ["delta", "direction", "cameraMinMaxZ"], ["depthSampler"], options, camera, samplingMode, engine, reusable, null, textureType, "kernelBlur", { varyingCount: 0, depCount: 0 }, true) || this;

+ 293 - 53
dist/preview release/es6.js

@@ -7088,10 +7088,21 @@ var BABYLON;
                 return path;
             return path.substring(index + 1);
         };
-        Tools.GetFolderPath = function (uri) {
+        /**
+         * Extracts the "folder" part of a path (everything before the filename).
+         * @param uri The URI to extract the info from
+         * @param returnUnchangedIfNoSlash Do not touch the URI if no slashes are present
+         * @returns The "folder" part of the path
+         */
+        Tools.GetFolderPath = function (uri, returnUnchangedIfNoSlash) {
+            if (returnUnchangedIfNoSlash === void 0) { returnUnchangedIfNoSlash = false; }
             var index = uri.lastIndexOf("/");
-            if (index < 0)
+            if (index < 0) {
+                if (returnUnchangedIfNoSlash) {
+                    return uri;
+                }
                 return "";
+            }
             return uri.substring(0, index + 1);
         };
         Tools.GetDOMTextContent = function (element) {
@@ -8633,19 +8644,20 @@ var BABYLON;
             return newPromise;
         };
         InternalPromise.prototype._moveChildren = function (children) {
-            this._children = children.splice(0, children.length);
+            (_a = this._children).push.apply(_a, children.splice(0, children.length));
             if (this.isFulfilled) {
-                for (var _i = 0, _a = this._children; _i < _a.length; _i++) {
-                    var child = _a[_i];
+                for (var _i = 0, _b = this._children; _i < _b.length; _i++) {
+                    var child = _b[_i];
                     child._resolve(this._result);
                 }
             }
             else if (this.isRejected) {
-                for (var _b = 0, _c = this._children; _b < _c.length; _b++) {
-                    var child = _c[_b];
+                for (var _c = 0, _d = this._children; _c < _d.length; _c++) {
+                    var child = _d[_c];
                     child._reject(this._reason);
                 }
             }
+            var _a;
         };
         InternalPromise.prototype._resolve = function (value) {
             try {
@@ -8717,8 +8729,13 @@ var BABYLON;
             var agregator = new FulFillmentAgregator();
             agregator.target = promises.length;
             agregator.rootPromise = newPromise;
-            for (var index = 0; index < promises.length; index++) {
-                InternalPromise._RegisterForFulfillment(promises[index], agregator, index);
+            if (promises.length) {
+                for (var index = 0; index < promises.length; index++) {
+                    InternalPromise._RegisterForFulfillment(promises[index], agregator, index);
+                }
+            }
+            else {
+                newPromise._resolve([]);
             }
             return newPromise;
         };
@@ -34639,7 +34656,15 @@ var BABYLON;
 
 var BABYLON;
 (function (BABYLON) {
+    /**
+     * PostProcessManager is used to manage one or more post processes or post process pipelines
+     * See https://doc.babylonjs.com/how_to/how_to_use_postprocesses
+     */
     var PostProcessManager = /** @class */ (function () {
+        /**
+         * Creates a new instance of @see PostProcess
+         * @param scene The scene that the post process is associated with.
+         */
         function PostProcessManager(scene) {
             this._vertexBuffers = {};
             this._scene = scene;
@@ -34668,6 +34693,9 @@ var BABYLON;
             indices.push(3);
             this._indexBuffer = this._scene.getEngine().createIndexBuffer(indices);
         };
+        /**
+         * Rebuilds the vertex buffers of the manager.
+         */
         PostProcessManager.prototype._rebuild = function () {
             var vb = this._vertexBuffers[BABYLON.VertexBuffer.PositionKind];
             if (!vb) {
@@ -34677,6 +34705,12 @@ var BABYLON;
             this._buildIndexBuffer();
         };
         // Methods
+        /**
+         * Prepares a frame to be run through a post process.
+         * @param sourceTexture The input texture to the post procesess. (default: null)
+         * @param postProcesses An array of post processes to be run. (default: null)
+         * @returns True if the post processes were able to be run.
+         */
         PostProcessManager.prototype._prepareFrame = function (sourceTexture, postProcesses) {
             if (sourceTexture === void 0) { sourceTexture = null; }
             if (postProcesses === void 0) { postProcesses = null; }
@@ -34691,6 +34725,12 @@ var BABYLON;
             postProcesses[0].activate(camera, sourceTexture, postProcesses !== null && postProcesses !== undefined);
             return true;
         };
+        /**
+         * Manually render a set of post processes to a texture.
+         * @param postProcesses An array of post processes to be run.
+         * @param targetTexture The target texture to render to.
+         * @param forceFullscreenViewport force gl.viewport to be full screen eg. 0,0,textureWidth,textureHeight
+         */
         PostProcessManager.prototype.directRender = function (postProcesses, targetTexture, forceFullscreenViewport) {
             if (targetTexture === void 0) { targetTexture = null; }
             if (forceFullscreenViewport === void 0) { forceFullscreenViewport = false; }
@@ -34723,6 +34763,14 @@ var BABYLON;
             engine.setDepthBuffer(true);
             engine.setDepthWrite(true);
         };
+        /**
+         * Finalize the result of the output of the postprocesses.
+         * @param doNotPresent If true the result will not be displayed to the screen.
+         * @param targetTexture The target texture to render to.
+         * @param faceIndex The index of the face to bind the target texture to.
+         * @param postProcesses The array of post processes to render.
+         * @param forceFullscreenViewport force gl.viewport to be full screen eg. 0,0,textureWidth,textureHeight (default: false)
+         */
         PostProcessManager.prototype._finalizeFrame = function (doNotPresent, targetTexture, faceIndex, postProcesses, forceFullscreenViewport) {
             if (forceFullscreenViewport === void 0) { forceFullscreenViewport = false; }
             var camera = this._scene.activeCamera;
@@ -34766,6 +34814,9 @@ var BABYLON;
             engine.setDepthWrite(true);
             engine.setAlphaMode(BABYLON.Engine.ALPHA_DISABLE);
         };
+        /**
+         * Disposes of the post process manager.
+         */
         PostProcessManager.prototype.dispose = function () {
             var buffer = this._vertexBuffers[BABYLON.VertexBuffer.PositionKind];
             if (buffer) {
@@ -56265,30 +56316,85 @@ var BABYLON;
 
 var BABYLON;
 (function (BABYLON) {
+    /**
+     * PostProcess can be used to apply a shader to a texture after it has been rendered
+     * See https://doc.babylonjs.com/how_to/how_to_use_postprocesses
+     */
     var PostProcess = /** @class */ (function () {
-        function PostProcess(name, fragmentUrl, parameters, samplers, options, camera, samplingMode, engine, reusable, defines, textureType, vertexUrl, indexParameters, blockCompilation) {
+        /**
+         * Creates a new instance of @see PostProcess
+         * @param name The name of the PostProcess.
+         * @param fragmentUrl The url of the fragment shader to be used.
+         * @param parameters Array of the names of uniform non-sampler2D variables that will be passed to the shader.
+         * @param samplers Array of the names of uniform sampler2D variables that will be passed to the shader.
+         * @param options The required width/height ratio to downsize to before computing the render pass. (Use 1.0 for full size)
+         * @param camera The camera to apply the render pass to.
+         * @param samplingMode The sampling mode to be used when computing the pass. (default: 0)
+         * @param engine The engine which the post process will be applied. (default: current engine)
+         * @param reusable If the post process can be reused on the same frame. (default: false)
+         * @param defines String of defines that will be set when running the fragment shader. (default: null)
+         * @param textureType Type of textures used when performing the post process. (default: 0)
+         * @param vertexUrl The url of the vertex shader to be used. (default: "postprocess")
+         * @param indexParameters The index parameters to be used for babylons include syntax "#include<kernelBlurVaryingDeclaration>[0..varyingCount]". (default: undefined) See usage in babylon.blurPostProcess.ts and kernelBlur.vertex.fx
+         * @param blockCompilation If the shader should be compiled imediatly. (default: false)
+         */
+        function PostProcess(/** Name of the PostProcess. */ name, fragmentUrl, parameters, samplers, options, camera, samplingMode, engine, reusable, defines, textureType, vertexUrl, indexParameters, blockCompilation) {
             if (samplingMode === void 0) { samplingMode = BABYLON.Texture.NEAREST_SAMPLINGMODE; }
             if (defines === void 0) { defines = null; }
             if (textureType === void 0) { textureType = BABYLON.Engine.TEXTURETYPE_UNSIGNED_INT; }
             if (vertexUrl === void 0) { vertexUrl = "postprocess"; }
             if (blockCompilation === void 0) { blockCompilation = false; }
             this.name = name;
+            /**
+            * Width of the texture to apply the post process on
+            */
             this.width = -1;
+            /**
+            * Height of the texture to apply the post process on
+            */
             this.height = -1;
+            /**
+            * If the buffer needs to be cleared before applying the post process. (default: true)
+            * Should be set to false if shader will overwrite all previous pixels.
+            */
             this.autoClear = true;
+            /**
+            * Type of alpha mode to use when performing the post process (default: Engine.ALPHA_DISABLE)
+            */
             this.alphaMode = BABYLON.Engine.ALPHA_DISABLE;
-            this.animations = new Array();
-            /*
-                Enable Pixel Perfect mode where texture is not scaled to be power of 2.
-                Can only be used on a single postprocess or on the last one of a chain.
+            /**
+            * Animations to be used for the post processing
             */
+            this.animations = new Array();
+            /**
+             * Enable Pixel Perfect mode where texture is not scaled to be power of 2.
+             * Can only be used on a single postprocess or on the last one of a chain. (default: false)
+             */
             this.enablePixelPerfectMode = false;
+            /**
+            * Scale mode for the post process (default: Engine.SCALEMODE_FLOOR)
+            */
             this.scaleMode = BABYLON.Engine.SCALEMODE_FLOOR;
+            /**
+            * Force textures to be a power of two (default: false)
+            */
             this.alwaysForcePOT = false;
+            /**
+            * Number of sample textures (default: 1)
+            */
             this.samples = 1;
+            /**
+            * Modify the scale of the post process to be the same as the viewport (default: false)
+            */
             this.adaptScaleToCurrentViewport = false;
             this._reusable = false;
+            /**
+            * Smart array of input and output textures for the post process.
+            */
             this._textures = new BABYLON.SmartArray(2);
+            /**
+            * The index in _textures that corresponds to the output texture.
+            */
             this._currentRenderTextureInd = 0;
             this._scaleRatio = new BABYLON.Vector2(1, 1);
             this._texelSize = BABYLON.Vector2.Zero();
@@ -56345,6 +56451,9 @@ var BABYLON;
             }
         }
         Object.defineProperty(PostProcess.prototype, "onActivate", {
+            /**
+            * A function that is added to the onActivateObservable
+            */
             set: function (callback) {
                 if (this._onActivateObserver) {
                     this.onActivateObservable.remove(this._onActivateObserver);
@@ -56357,6 +56466,9 @@ var BABYLON;
             configurable: true
         });
         Object.defineProperty(PostProcess.prototype, "onSizeChanged", {
+            /**
+            * A function that is added to the onSizeChangedObservable
+            */
             set: function (callback) {
                 if (this._onSizeChangedObserver) {
                     this.onSizeChangedObservable.remove(this._onSizeChangedObserver);
@@ -56367,6 +56479,9 @@ var BABYLON;
             configurable: true
         });
         Object.defineProperty(PostProcess.prototype, "onApply", {
+            /**
+            * A function that is added to the onApplyObservable
+            */
             set: function (callback) {
                 if (this._onApplyObserver) {
                     this.onApplyObservable.remove(this._onApplyObserver);
@@ -56377,6 +56492,9 @@ var BABYLON;
             configurable: true
         });
         Object.defineProperty(PostProcess.prototype, "onBeforeRender", {
+            /**
+            * A function that is added to the onBeforeRenderObservable
+            */
             set: function (callback) {
                 if (this._onBeforeRenderObserver) {
                     this.onBeforeRenderObservable.remove(this._onBeforeRenderObserver);
@@ -56387,6 +56505,9 @@ var BABYLON;
             configurable: true
         });
         Object.defineProperty(PostProcess.prototype, "onAfterRender", {
+            /**
+            * A function that is added to the onAfterRenderObservable
+            */
             set: function (callback) {
                 if (this._onAfterRenderObserver) {
                     this.onAfterRenderObservable.remove(this._onAfterRenderObserver);
@@ -56397,6 +56518,9 @@ var BABYLON;
             configurable: true
         });
         Object.defineProperty(PostProcess.prototype, "outputTexture", {
+            /**
+            * The resulting output of the post process.
+            */
             get: function () {
                 return this._textures.data[this._currentRenderTextureInd];
             },
@@ -56406,10 +56530,18 @@ var BABYLON;
             enumerable: true,
             configurable: true
         });
+        /**
+        * Gets the camera which post process is applied to.
+        * @returns The camera the post process is applied to.
+        */
         PostProcess.prototype.getCamera = function () {
             return this._camera;
         };
         Object.defineProperty(PostProcess.prototype, "texelSize", {
+            /**
+            * Gets the texel size of the postprocess.
+            * See https://en.wikipedia.org/wiki/Texel_(graphics)
+            */
             get: function () {
                 if (this._shareOutputWithPostProcess) {
                     return this._shareOutputWithPostProcess.texelSize;
@@ -56422,23 +56554,49 @@ var BABYLON;
             enumerable: true,
             configurable: true
         });
+        /**
+         * Gets the engine which this post process belongs to.
+         * @returns The engine the post process was enabled with.
+         */
         PostProcess.prototype.getEngine = function () {
             return this._engine;
         };
+        /**
+         * The effect that is created when initializing the post process.
+         * @returns The created effect corrisponding the the postprocess.
+         */
         PostProcess.prototype.getEffect = function () {
             return this._effect;
         };
+        /**
+         * To avoid multiple redundant textures for multiple post process, the output the output texture for this post process can be shared with another.
+         * @param postProcess The post process to share the output with.
+         * @returns This post process.
+         */
         PostProcess.prototype.shareOutputWith = function (postProcess) {
             this._disposeTextures();
             this._shareOutputWithPostProcess = postProcess;
             return this;
         };
+        /**
+         * Updates the effect with the current post process compile time values and recompiles the shader.
+         * @param defines Define statements that should be added at the beginning of the shader. (default: null)
+         * @param uniforms Set of uniform variables that will be passed to the shader. (default: null)
+         * @param samplers Set of Texture2D variables that will be passed to the shader. (default: null)
+         * @param indexParameters The index parameters to be used for babylons include syntax "#include<kernelBlurVaryingDeclaration>[0..varyingCount]". (default: undefined) See usage in babylon.blurPostProcess.ts and kernelBlur.vertex.fx
+         * @param onCompiled Called when the shader has been compiled.
+         * @param onError Called if there is an error when compiling a shader.
+         */
         PostProcess.prototype.updateEffect = function (defines, uniforms, samplers, indexParameters, onCompiled, onError) {
             if (defines === void 0) { defines = null; }
             if (uniforms === void 0) { uniforms = null; }
             if (samplers === void 0) { samplers = null; }
             this._effect = this._engine.createEffect({ vertex: this._vertexUrl, fragment: this._fragmentUrl }, ["position"], uniforms || this._parameters, samplers || this._samplers, defines !== null ? defines : "", undefined, onCompiled, onError, indexParameters || this._indexParameters);
         };
+        /**
+         * The post process is reusable if it can be used multiple times within one frame.
+         * @returns If the post process is reusable
+         */
         PostProcess.prototype.isReusable = function () {
             return this._reusable;
         };
@@ -56446,6 +56604,12 @@ var BABYLON;
         PostProcess.prototype.markTextureDirty = function () {
             this.width = -1;
         };
+        /**
+         * Activates the post process by intializing the textures to be used when executed. Notifies onActivateObservable.
+         * @param camera The camera that will be used in the post process. This camera will be used when calling onActivateObservable.
+         * @param sourceTexture The source texture to be inspected to get the width and height if not specified in the post process constructor. (default: null)
+         * @param forceDepthStencil If true, a depth and stencil buffer will be generated. (default: false)
+         */
         PostProcess.prototype.activate = function (camera, sourceTexture, forceDepthStencil) {
             var _this = this;
             if (sourceTexture === void 0) { sourceTexture = null; }
@@ -56533,6 +56697,9 @@ var BABYLON;
             }
         };
         Object.defineProperty(PostProcess.prototype, "isSupported", {
+            /**
+             * If the post process is supported.
+             */
             get: function () {
                 return this._effect.isSupported;
             },
@@ -56540,6 +56707,9 @@ var BABYLON;
             configurable: true
         });
         Object.defineProperty(PostProcess.prototype, "aspectRatio", {
+            /**
+             * The aspect ratio of the output texture.
+             */
             get: function () {
                 if (this._shareOutputWithPostProcess) {
                     return this._shareOutputWithPostProcess.aspectRatio;
@@ -56559,6 +56729,10 @@ var BABYLON;
         PostProcess.prototype.isReady = function () {
             return this._effect && this._effect.isReady();
         };
+        /**
+         * Binds all textures and uniforms to the shader, this will be run on every pass.
+         * @returns the effect corrisponding to this post process. Null if not compiled or not ready.
+         */
         PostProcess.prototype.apply = function () {
             // Check
             if (!this._effect || !this._effect.isReady())
@@ -56601,6 +56775,10 @@ var BABYLON;
             }
             this._textures.dispose();
         };
+        /**
+         * Disposes the post process.
+         * @param camera The camera to dispose the post process on.
+         */
         PostProcess.prototype.dispose = function (camera) {
             camera = camera || this._camera;
             this._disposeTextures();
@@ -58110,7 +58288,6 @@ var BABYLON;
         * @param onError a callback with the scene, a message, and possibly an exception when import fails
         */
         SceneLoader.ImportMesh = function (meshNames, rootUrl, sceneFilename, scene, onSuccess, onProgress, onError, pluginExtension) {
-            var _this = this;
             if (onSuccess === void 0) { onSuccess = null; }
             if (onProgress === void 0) { onProgress = null; }
             if (onError === void 0) { onError = null; }
@@ -58161,7 +58338,7 @@ var BABYLON;
                 }
                 if (sceneFilename === "") {
                     if (sceneFilename === "") {
-                        rootUrl = _this._StripFilenameFromRootUrl(rootUrl);
+                        rootUrl = BABYLON.Tools.GetFolderPath(rootUrl, true);
                     }
                 }
                 if (plugin.importMesh) {
@@ -58210,7 +58387,6 @@ var BABYLON;
         * @param onError a callback with the scene, a message, and possibly an exception when import fails
         */
         SceneLoader.Append = function (rootUrl, sceneFilename, scene, onSuccess, onProgress, onError, pluginExtension) {
-            var _this = this;
             if (onSuccess === void 0) { onSuccess = null; }
             if (onProgress === void 0) { onProgress = null; }
             if (onError === void 0) { onError = null; }
@@ -58260,7 +58436,7 @@ var BABYLON;
             };
             return SceneLoader._loadData(rootUrl, sceneFilename, scene, function (plugin, data, responseURL) {
                 if (sceneFilename === "") {
-                    rootUrl = _this._StripFilenameFromRootUrl(rootUrl);
+                    rootUrl = BABYLON.Tools.GetFolderPath(rootUrl, true);
                 }
                 if (plugin.load) {
                     var syncedPlugin = plugin;
@@ -58284,14 +58460,6 @@ var BABYLON;
                 }
             }, progressHandler, errorHandler, disposeHandler, pluginExtension);
         };
-        SceneLoader._StripFilenameFromRootUrl = function (rootUrl) {
-            // We need to strip the filename off from the rootUrl
-            var lastSlash = rootUrl.lastIndexOf("/");
-            if (lastSlash > -1) {
-                rootUrl = rootUrl.substr(0, lastSlash + 1);
-            }
-            return rootUrl;
-        };
         SceneLoader.LoadAssetContainer = function (rootUrl, sceneFilename, scene, onSuccess, onProgress, onError, pluginExtension) {
             if (onSuccess === void 0) { onSuccess = null; }
             if (onProgress === void 0) { onProgress = null; }
@@ -65124,83 +65292,83 @@ var BABYLON;
          */
         function DepthOfFieldEffect(scene, pipelineTextureType) {
             if (pipelineTextureType === void 0) { pipelineTextureType = 0; }
-            var _this = _super.call(this, scene.getEngine(), "depth of field", function () { return [_this.circleOfConfusion, _this.depthOfFieldPass, _this.depthOfFieldBlurY, _this.depthOfFieldBlurX, _this.depthOfFieldMerge]; }, true) || this;
+            var _this = _super.call(this, scene.getEngine(), "depth of field", function () { return [_this._circleOfConfusion, _this._depthOfFieldPass, _this._depthOfFieldBlurY, _this._depthOfFieldBlurX, _this._depthOfFieldMerge]; }, true) || this;
             // Enable and get current depth map
             var depthMap = scene.enableDepthRenderer().getDepthMap();
             // Circle of confusion value for each pixel is used to determine how much to blur that pixel
-            _this.circleOfConfusion = new BABYLON.CircleOfConfusionPostProcess("circleOfConfusion", scene, depthMap, 1, null, BABYLON.Texture.BILINEAR_SAMPLINGMODE, scene.getEngine(), false, pipelineTextureType);
+            _this._circleOfConfusion = new BABYLON.CircleOfConfusionPostProcess("circleOfConfusion", scene, depthMap, 1, null, BABYLON.Texture.BILINEAR_SAMPLINGMODE, scene.getEngine(), false, pipelineTextureType);
             // Capture circle of confusion texture
-            _this.depthOfFieldPass = new BABYLON.PassPostProcess("depthOfFieldPass", 1.0, null, BABYLON.Texture.BILINEAR_SAMPLINGMODE, scene.getEngine(), false, pipelineTextureType);
+            _this._depthOfFieldPass = new BABYLON.PassPostProcess("depthOfFieldPass", 1.0, null, BABYLON.Texture.BILINEAR_SAMPLINGMODE, scene.getEngine(), false, pipelineTextureType);
             // Blur the image but do not blur on sharp far to near distance changes to avoid bleeding artifacts 
             // See section 2.6.2 http://fileadmin.cs.lth.se/cs/education/edan35/lectures/12dof.pdf
-            _this.depthOfFieldBlurY = new BABYLON.DepthOfFieldBlurPostProcess("verticle blur", scene, new BABYLON.Vector2(0, 1.0), 15, 1.0, null, depthMap, _this.circleOfConfusion, BABYLON.Texture.BILINEAR_SAMPLINGMODE, scene.getEngine(), false, pipelineTextureType);
-            _this.depthOfFieldBlurX = new BABYLON.DepthOfFieldBlurPostProcess("horizontal blur", scene, new BABYLON.Vector2(1.0, 0), 15, 1.0, null, depthMap, null, BABYLON.Texture.BILINEAR_SAMPLINGMODE, scene.getEngine(), false, pipelineTextureType);
+            _this._depthOfFieldBlurY = new BABYLON.DepthOfFieldBlurPostProcess("verticle blur", scene, new BABYLON.Vector2(0, 1.0), 15, 1.0, null, depthMap, _this._circleOfConfusion, BABYLON.Texture.BILINEAR_SAMPLINGMODE, scene.getEngine(), false, pipelineTextureType);
+            _this._depthOfFieldBlurX = new BABYLON.DepthOfFieldBlurPostProcess("horizontal blur", scene, new BABYLON.Vector2(1.0, 0), 15, 1.0, null, depthMap, null, BABYLON.Texture.BILINEAR_SAMPLINGMODE, scene.getEngine(), false, pipelineTextureType);
             // Merge blurred images with original image based on circleOfConfusion
-            _this.depthOfFieldMerge = new BABYLON.DepthOfFieldMergePostProcess("depthOfFieldMerge", _this.circleOfConfusion, _this.depthOfFieldPass, 1, null, BABYLON.Texture.BILINEAR_SAMPLINGMODE, scene.getEngine(), false, pipelineTextureType);
+            _this._depthOfFieldMerge = new BABYLON.DepthOfFieldMergePostProcess("depthOfFieldMerge", _this._circleOfConfusion, _this._depthOfFieldPass, 1, null, BABYLON.Texture.BILINEAR_SAMPLINGMODE, scene.getEngine(), false, pipelineTextureType);
             return _this;
         }
         Object.defineProperty(DepthOfFieldEffect.prototype, "kernelSize", {
             get: function () {
-                return this.depthOfFieldBlurX.kernel;
+                return this._depthOfFieldBlurX.kernel;
             },
             /**
              * The size of the kernel to be used for the blur
              */
             set: function (value) {
-                this.depthOfFieldBlurX.kernel = value;
-                this.depthOfFieldBlurY.kernel = value;
+                this._depthOfFieldBlurX.kernel = value;
+                this._depthOfFieldBlurY.kernel = value;
             },
             enumerable: true,
             configurable: true
         });
         Object.defineProperty(DepthOfFieldEffect.prototype, "focalLength", {
             get: function () {
-                return this.circleOfConfusion.focalLength;
+                return this._circleOfConfusion.focalLength;
             },
             /**
              * The focal the length of the camera used in the effect
              */
             set: function (value) {
-                this.circleOfConfusion.focalLength = value;
+                this._circleOfConfusion.focalLength = value;
             },
             enumerable: true,
             configurable: true
         });
         Object.defineProperty(DepthOfFieldEffect.prototype, "fStop", {
             get: function () {
-                return this.circleOfConfusion.fStop;
+                return this._circleOfConfusion.fStop;
             },
             /**
              * F-Stop of the effect's camera. The diamater of the resulting aperture can be computed by lensSize/fStop. (default: 1.4)
              */
             set: function (value) {
-                this.circleOfConfusion.fStop = value;
+                this._circleOfConfusion.fStop = value;
             },
             enumerable: true,
             configurable: true
         });
         Object.defineProperty(DepthOfFieldEffect.prototype, "focusDistance", {
             get: function () {
-                return this.circleOfConfusion.focusDistance;
+                return this._circleOfConfusion.focusDistance;
             },
             /**
              * Distance away from the camera to focus on in scene units/1000 (eg. millimeter). (default: 2000)
              */
             set: function (value) {
-                this.circleOfConfusion.focusDistance = value;
+                this._circleOfConfusion.focusDistance = value;
             },
             enumerable: true,
             configurable: true
         });
         Object.defineProperty(DepthOfFieldEffect.prototype, "lensSize", {
             get: function () {
-                return this.circleOfConfusion.lensSize;
+                return this._circleOfConfusion.lensSize;
             },
             /**
              * Max lens size in scene units/1000 (eg. millimeter). Standard cameras are 50mm. (default: 50) The diamater of the resulting aperture can be computed by lensSize/fStop.
              */
             set: function (value) {
-                this.circleOfConfusion.lensSize = value;
+                this._circleOfConfusion.lensSize = value;
             },
             enumerable: true,
             configurable: true
@@ -65210,11 +65378,11 @@ var BABYLON;
          * @param camera The camera to dispose the effect on.
          */
         DepthOfFieldEffect.prototype.disposeEffects = function (camera) {
-            this.depthOfFieldPass.dispose(camera);
-            this.circleOfConfusion.dispose(camera);
-            this.depthOfFieldBlurX.dispose(camera);
-            this.depthOfFieldBlurY.dispose(camera);
-            this.depthOfFieldMerge.dispose(camera);
+            this._depthOfFieldPass.dispose(camera);
+            this._circleOfConfusion.dispose(camera);
+            this._depthOfFieldBlurX.dispose(camera);
+            this._depthOfFieldBlurY.dispose(camera);
+            this._depthOfFieldMerge.dispose(camera);
         };
         return DepthOfFieldEffect;
     }(BABYLON.PostProcessRenderEffect));
@@ -65231,6 +65399,10 @@ var BABYLON;
 
 var BABYLON;
 (function (BABYLON) {
+    /**
+     * The default rendering pipeline can be added to a scene to apply common post processing effects such as anti-aliasing or depth of field.
+     * See https://doc.babylonjs.com/how_to/using_default_rendering_pipeline
+     */
     var DefaultRenderingPipeline = /** @class */ (function (_super) {
         __extends(DefaultRenderingPipeline, _super);
         /**
@@ -65244,15 +65416,41 @@ var BABYLON;
         function DefaultRenderingPipeline(name, hdr, scene, cameras, automaticBuild) {
             if (automaticBuild === void 0) { automaticBuild = true; }
             var _this = _super.call(this, scene.getEngine(), name) || this;
+            /**
+             * ID of the pass post process used for bloom,
+             */
             _this.PassPostProcessId = "PassPostProcessEffect";
+            /**
+             * ID of the highlight post process used for bloom,
+             */
             _this.HighLightsPostProcessId = "HighLightsPostProcessEffect";
+            /**
+             * ID of the blurX post process used for bloom,
+             */
             _this.BlurXPostProcessId = "BlurXPostProcessEffect";
+            /**
+             * ID of the blurY post process used for bloom,
+             */
             _this.BlurYPostProcessId = "BlurYPostProcessEffect";
+            /**
+             * ID of the copy back post process used for bloom,
+             */
             _this.CopyBackPostProcessId = "CopyBackPostProcessEffect";
+            /**
+             * ID of the image processing post process;
+             */
             _this.ImageProcessingPostProcessId = "ImageProcessingPostProcessEffect";
+            /**
+             * ID of the Fast Approximate Anti-Aliasing post process;
+             */
             _this.FxaaPostProcessId = "FxaaPostProcessEffect";
+            /**
+             * ID of the final merge post process;
+             */
             _this.FinalMergePostProcessId = "FinalMergePostProcessEffect";
-            // IAnimatable
+            /**
+             * Animations which can be used to tweak settings over a period of time
+             */
             _this.animations = [];
             // Values       
             _this._bloomEnabled = false;
@@ -65296,6 +65494,9 @@ var BABYLON;
             get: function () {
                 return this._bloomWeight;
             },
+            /**
+             * The strength of the bloom.
+             */
             set: function (value) {
                 if (this._bloomWeight === value) {
                     return;
@@ -65312,6 +65513,9 @@ var BABYLON;
             get: function () {
                 return this._bloomScale;
             },
+            /**
+             * The scale of the bloom, lower value will provide better performance.
+             */
             set: function (value) {
                 if (this._bloomScale === value) {
                     return;
@@ -65326,6 +65530,9 @@ var BABYLON;
             get: function () {
                 return this._bloomEnabled;
             },
+            /**
+             * Enable or disable the bloom from the pipeline
+             */
             set: function (enabled) {
                 if (this._bloomEnabled === enabled) {
                     return;
@@ -65357,6 +65564,9 @@ var BABYLON;
             get: function () {
                 return this._fxaaEnabled;
             },
+            /**
+             * If the anti aliasing is enabled.
+             */
             set: function (enabled) {
                 if (this._fxaaEnabled === enabled) {
                     return;
@@ -65371,6 +65581,9 @@ var BABYLON;
             get: function () {
                 return this._imageProcessingEnabled;
             },
+            /**
+             * If image processing is enabled.
+             */
             set: function (enabled) {
                 if (this._imageProcessingEnabled === enabled) {
                     return;
@@ -65530,19 +65743,30 @@ var BABYLON;
             this.finalMerge = null;
             this.depthOfField = null;
         };
-        // Dispose
+        /**
+         * Dispose of the pipeline and stop all post processes
+         */
         DefaultRenderingPipeline.prototype.dispose = function () {
             this._disposePostProcesses();
             this._scene.postProcessRenderPipelineManager.detachCamerasFromRenderPipeline(this._name, this._cameras);
             _super.prototype.dispose.call(this);
         };
-        // Serialize rendering pipeline
+        /**
+         * Serialize the rendering pipeline (Used when exporting)
+         * @returns the serialized object
+         */
         DefaultRenderingPipeline.prototype.serialize = function () {
             var serializationObject = BABYLON.SerializationHelper.Serialize(this);
             serializationObject.customType = "DefaultRenderingPipeline";
             return serializationObject;
         };
-        // Parse serialized pipeline
+        /**
+         * Parse the serialized pipeline
+         * @param source Source pipeline.
+         * @param scene The scene to load the pipeline to.
+         * @param rootUrl The URL of the serialized pipeline.
+         * @returns An instantiated pipeline from the serialized object.
+         */
         DefaultRenderingPipeline.Parse = function (source, scene, rootUrl) {
             return BABYLON.SerializationHelper.Parse(function () { return new DefaultRenderingPipeline(source._name, source._name._hdr, scene); }, source, scene, rootUrl);
         };
@@ -66846,9 +67070,25 @@ var BABYLON;
 
 var BABYLON;
 (function (BABYLON) {
+    /**
+     * The Blur Post Process which blurs an image based on a kernel and direction.
+     * Can be used twice in x and y directions to perform a guassian blur in two passes.
+     */
     var BlurPostProcess = /** @class */ (function (_super) {
         __extends(BlurPostProcess, _super);
-        function BlurPostProcess(name, direction, kernel, options, camera, samplingMode, engine, reusable, textureType) {
+        /**
+         * Creates a new instance of @see BlurPostProcess
+         * @param name The name of the effect.
+         * @param direction The direction in which to blur the image.
+         * @param kernel The size of the kernel to be used when computing the blur. eg. Size of 3 will blur the center pixel by 2 pixels surrounding it.
+         * @param options The required width/height ratio to downsize to before computing the render pass. (Use 1.0 for full size)
+         * @param camera The camera to apply the render pass to.
+         * @param samplingMode The sampling mode to be used when computing the pass. (default: 0)
+         * @param engine The engine which the post process will be applied. (default: current engine)
+         * @param reusable If the post process can be reused on the same frame. (default: false)
+         * @param textureType Type of textures used when performing the post process. (default: 0)
+         */
+        function BlurPostProcess(name, /** The direction in which to blur the image. */ direction, kernel, options, camera, samplingMode, engine, reusable, textureType) {
             if (samplingMode === void 0) { samplingMode = BABYLON.Texture.BILINEAR_SAMPLINGMODE; }
             if (textureType === void 0) { textureType = BABYLON.Engine.TEXTURETYPE_UNSIGNED_INT; }
             var _this = _super.call(this, name, "kernelBlur", ["delta", "direction", "cameraMinMaxZ"], ["depthSampler"], options, camera, samplingMode, engine, reusable, null, textureType, "kernelBlur", { varyingCount: 0, depCount: 0 }, true) || this;

+ 1 - 1
dist/preview release/gui/package.json

@@ -4,7 +4,7 @@
     },
     "name": "babylonjs-gui",
     "description": "The Babylon.js GUI library is an extension you can use to generate interactive user interface. It is build on top of the DynamicTexture.",
-    "version": "3.2.0-alpha4",
+    "version": "3.2.0-alpha6",
     "repository": {
         "type": "git",
         "url": "https://github.com/BabylonJS/Babylon.js.git"

Những thai đổi đã bị hủy bỏ vì nó quá lớn
+ 2 - 2
dist/preview release/inspector/babylon.inspector.bundle.js


+ 1 - 1
dist/preview release/inspector/package.json

@@ -4,7 +4,7 @@
     },
     "name": "babylonjs-inspector",
     "description": "The Babylon.js inspector.",
-    "version": "3.2.0-alpha4",
+    "version": "3.2.0-alpha6",
     "repository": {
         "type": "git",
         "url": "https://github.com/BabylonJS/Babylon.js.git"

Những thai đổi đã bị hủy bỏ vì nó quá lớn
+ 1 - 1
dist/preview release/loaders/babylon.objFileLoader.min.js


Những thai đổi đã bị hủy bỏ vì nó quá lớn
+ 2 - 2
dist/preview release/loaders/babylonjs.loaders.min.js


+ 1 - 1
dist/preview release/loaders/package.json

@@ -4,7 +4,7 @@
     },
     "name": "babylonjs-loaders",
     "description": "The Babylon.js file loaders library is an extension you can use to load different 3D file types into a Babylon scene.",
-    "version": "3.2.0-alpha4",
+    "version": "3.2.0-alpha6",
     "repository": {
         "type": "git",
         "url": "https://github.com/BabylonJS/Babylon.js.git"

+ 1 - 1
dist/preview release/materialsLibrary/package.json

@@ -4,7 +4,7 @@
     },
     "name": "babylonjs-materials",
     "description": "The Babylon.js materials library is a collection of advanced materials to be used in a Babylon.js scene.",
-    "version": "3.2.0-alpha4",
+    "version": "3.2.0-alpha6",
     "repository": {
         "type": "git",
         "url": "https://github.com/BabylonJS/Babylon.js.git"

+ 1 - 1
dist/preview release/postProcessesLibrary/package.json

@@ -4,7 +4,7 @@
     },
     "name": "babylonjs-post-process",
     "description": "The Babylon.js materials library is a collection of advanced materials to be used in a Babylon.js scene.",
-    "version": "3.2.0-alpha4",
+    "version": "3.2.0-alpha6",
     "repository": {
         "type": "git",
         "url": "https://github.com/BabylonJS/Babylon.js.git"

+ 1 - 1
dist/preview release/proceduralTexturesLibrary/package.json

@@ -4,7 +4,7 @@
     },
     "name": "babylonjs-procedural-textures",
     "description": "The Babylon.js materials library is a collection of advanced materials to be used in a Babylon.js scene.",
-    "version": "3.2.0-alpha4",
+    "version": "3.2.0-alpha6",
     "repository": {
         "type": "git",
         "url": "https://github.com/BabylonJS/Babylon.js.git"

+ 57 - 49
dist/preview release/serializers/babylon.glTF2Serializer.d.ts

@@ -107,12 +107,14 @@ declare module BABYLON.GLTF2 {
         constructor(babylonScene: Scene, options?: IExporterOptions);
         /**
          * Creates a buffer view based on teh supplied arguments
-         * @param {number} bufferIndex - index value of the specified buffer
-         * @param {number} byteOffset - byte offset value
-         * @param {number} byteLength - byte length of the bufferView
+         * @param bufferIndex - index value of the specified buffer
+         * @param byteOffset - byte offset value
+         * @param byteLength - byte length of the bufferView
+         * @param byteStride - byte distance between conequential elements.
+         * @param name - name of the buffer view
          * @returns - bufferView for glTF
          */
-        private createBufferView(bufferIndex, byteOffset, byteLength, name?);
+        private createBufferView(bufferIndex, byteOffset, byteLength, byteStride?, name?);
         /**
          * Creates an accessor based on the supplied arguments
          * @param bufferviewIndex
@@ -124,43 +126,41 @@ declare module BABYLON.GLTF2 {
          * @param max
          * @returns - accessor for glTF
          */
-        private createAccessor(bufferviewIndex, name, type, componentType, count, min?, max?);
+        private createAccessor(bufferviewIndex, name, type, componentType, count, byteOffset?, min?, max?);
         /**
          * Calculates the minimum and maximum values of an array of floats, based on stride
-         * @param buff
-         * @param vertexStart
-         * @param vertexCount
-         * @param arrayOffset
-         * @param stride
-         * @returns - min number array and max number array
+         * @param buff - Data to check for min and max values.
+         * @param vertexStart - Start offset to calculate min and max values.
+         * @param vertexCount - Number of vertices to check for min and max values.
+         * @param stride - Offset between consecutive attributes.
+         * @param useRightHandedSystem - Indicates whether the data should be modified for a right or left handed coordinate system.
+         * @returns - min number array and max number array.
          */
-        private calculateMinMax(buff, vertexStart, vertexCount, arrayOffset, stride);
+        private calculateMinMax(buff, vertexStart, vertexCount, stride, useRightHandedSystem);
         /**
-         * Write mesh attribute data to buffer.
+         * Writes mesh attribute data to a data buffer.
          * Returns the bytelength of the data.
-         * @param vertexBufferType
-         * @param submesh
-         * @param meshAttributeArray
-         * @param strideSize
-         * @param byteOffset
-         * @param dataBuffer
-         * @param useRightHandedSystem
-         * @returns - byte length
+         * @param vertexBufferKind - Indicates what kind of vertex data is being passed in.
+         * @param meshAttributeArray - Array containing the attribute data.
+         * @param strideSize - Represents the offset between consecutive attributes
+         * @param byteOffset - The offset to start counting bytes from.
+         * @param dataBuffer - The buffer to write the binary data to.
+         * @param useRightHandedSystem - Indicates whether the data should be modified for a right or left handed coordinate system.
+         * @returns - Byte length of the attribute data.
          */
-        private writeAttributeData(vertexBufferType, submesh, meshAttributeArray, strideSize, byteOffset, dataBuffer, useRightHandedSystem);
+        private writeAttributeData(vertexBufferKind, meshAttributeArray, strideSize, vertexBufferOffset, byteOffset, dataBuffer, useRightHandedSystem);
         /**
          * Generates glTF json data
-         * @param glb
-         * @param glTFPrefix
-         * @param prettyPrint
+         * @param shouldUseGlb - Indicates whether the json should be written for a glb file.
+         * @param glTFPrefix - Text to use when prefixing a glTF file.
+         * @param prettyPrint - Indicates whether the json file should be pretty printed (true) or not (false).
          * @returns - json data as string
          */
-        private generateJSON(glb, glTFPrefix?, prettyPrint?);
+        private generateJSON(shouldUseGlb, glTFPrefix?, prettyPrint?);
         /**
          * Generates data for .gltf and .bin files based on the glTF prefix string
-         * @param glTFPrefix
-         * @returns - object with glTF json tex filename
-         * and binary file name as keys and their data as values
+         * @param glTFPrefix - Text to use when prefixing a glTF file.
+         * @returns - GLTFData with glTF file data.
          */
         _generateGLTF(glTFPrefix: string): _GLTFData;
         /**
@@ -169,7 +169,7 @@ declare module BABYLON.GLTF2 {
          */
         private generateBinary();
         /**
-         * Pads the number to a power of 4
+         * Pads the number to a multiple of 4
          * @param num - number to pad
          * @returns - padded number
          */
@@ -177,45 +177,53 @@ declare module BABYLON.GLTF2 {
         /**
          * Generates a glb file from the json and binary data.
          * Returns an object with the glb file name as the key and data as the value.
-         * @param jsonText
-         * @param binaryBuffer
          * @param glTFPrefix
          * @returns - object with glb filename as key and data as value
          */
         _generateGLB(glTFPrefix: string): _GLTFData;
         /**
          * Sets the TRS for each node
-         * @param node
-         * @param babylonMesh
-         * @param useRightHandedSystem
+         * @param node - glTF Node for storing the transformation data.
+         * @param babylonMesh - Babylon mesh used as the source for the transformation data.
+         * @param useRightHandedSystem - Indicates whether the data should be modified for a right or left handed coordinate system.
          */
         private setNodeTransformation(node, babylonMesh, useRightHandedSystem);
         /**
          *
-         * @param babylonTexture
-         * @return - glTF texture, or null if the texture format is not supported
+         * @param babylonTexture - Babylon texture to extract.
+         * @param mimeType - Mime Type of the babylonTexture.
+         * @return - glTF texture, or null if the texture format is not supported.
          */
         private exportTexture(babylonTexture, mimeType?);
         /**
+         * Creates a bufferview based on the vertices type for the Babylon mesh
+         * @param kind - Indicates the type of vertices data.
+         * @param babylonMesh - The Babylon mesh to get the vertices data from.
+         * @param byteOffset - The offset from the buffer to start indexing from.
+         * @param useRightHandedSystem - Indicates whether the data should be modified for a right or left handed coordinate system.
+         * @param dataBuffer - The buffer to write the bufferview data to.
+         * @returns bytelength of the bufferview data.
+         */
+        private createBufferViewKind(kind, babylonMesh, byteOffset, useRightHandedSystem, dataBuffer);
+        /**
          * Sets data for the primitive attributes of each submesh
-         * @param mesh
-         * @param babylonMesh
-         * @param byteOffset
-         * @param useRightHandedSystem
-         * @param dataBuffer
-         * @returns - bytelength of the primitive attributes plus the passed in byteOffset
+         * @param mesh - glTF Mesh object to store the primitive attribute information.
+         * @param babylonMesh - Babylon mesh to get the primitive attribute data from.
+         * @param byteOffset - The offset in bytes of the buffer data.
+         * @param useRightHandedSystem - Indicates whether the data should be modified for a right or left handed coordinate system.
+         * @param dataBuffer - Buffer to write the attribute data to.
+         * @returns - bytelength of the primitive attributes plus the passed in byteOffset.
          */
-        private setPrimitiveAttributes(mesh, babylonMesh, byteOffset, useRightHandedSystem, dataBuffer?);
+        private setPrimitiveAttributes(mesh, babylonMesh, byteOffset, useRightHandedSystem, dataBuffer);
         /**
          * Creates a glTF scene based on the array of meshes.
          * Returns the the total byte offset.
-         * @param gltf
-         * @param byteOffset
-         * @param buffer
-         * @param dataBuffer
+         * @param babylonScene - Babylon scene to get the mesh data from.
+         * @param byteOffset - Offset to start from in bytes.
+         * @param dataBuffer - Buffer to write geometry data to.
          * @returns bytelength + byteoffset
          */
-        private createScene(babylonScene, byteOffset, dataBuffer?);
+        private createScene(babylonScene, byteOffset, dataBuffer);
     }
 }
 

+ 381 - 299
dist/preview release/serializers/babylon.glTF2Serializer.js

@@ -78,22 +78,25 @@ var BABYLON;
                 this.nodes = new Array();
                 this.images = new Array();
                 this.materials = new Array();
+                this.textures = new Array();
                 this.imageData = {};
                 if (options !== undefined) {
                     this.options = options;
                 }
                 var totalByteLength = 0;
-                totalByteLength = this.createScene(this.babylonScene, totalByteLength);
+                totalByteLength = this.createScene(this.babylonScene, totalByteLength, null);
                 this.totalByteLength = totalByteLength;
             }
             /**
              * Creates a buffer view based on teh supplied arguments
-             * @param {number} bufferIndex - index value of the specified buffer
-             * @param {number} byteOffset - byte offset value
-             * @param {number} byteLength - byte length of the bufferView
+             * @param bufferIndex - index value of the specified buffer
+             * @param byteOffset - byte offset value
+             * @param byteLength - byte length of the bufferView
+             * @param byteStride - byte distance between conequential elements.
+             * @param name - name of the buffer view
              * @returns - bufferView for glTF
              */
-            _Exporter.prototype.createBufferView = function (bufferIndex, byteOffset, byteLength, name) {
+            _Exporter.prototype.createBufferView = function (bufferIndex, byteOffset, byteLength, byteStride, name) {
                 var bufferview = { buffer: bufferIndex, byteLength: byteLength };
                 if (byteOffset > 0) {
                     bufferview.byteOffset = byteOffset;
@@ -101,6 +104,9 @@ var BABYLON;
                 if (name) {
                     bufferview.name = name;
                 }
+                if (byteStride) {
+                    bufferview.byteStride = byteStride;
+                }
                 return bufferview;
             };
             /**
@@ -114,7 +120,7 @@ var BABYLON;
              * @param max
              * @returns - accessor for glTF
              */
-            _Exporter.prototype.createAccessor = function (bufferviewIndex, name, type, componentType, count, min, max) {
+            _Exporter.prototype.createAccessor = function (bufferviewIndex, name, type, componentType, count, byteOffset, min, max) {
                 var accessor = { name: name, bufferView: bufferviewIndex, componentType: componentType, count: count, type: type };
                 if (min) {
                     accessor.min = min;
@@ -122,30 +128,38 @@ var BABYLON;
                 if (max) {
                     accessor.max = max;
                 }
+                if (byteOffset) {
+                    accessor.byteOffset = byteOffset;
+                }
                 return accessor;
             };
             /**
              * Calculates the minimum and maximum values of an array of floats, based on stride
-             * @param buff
-             * @param vertexStart
-             * @param vertexCount
-             * @param arrayOffset
-             * @param stride
-             * @returns - min number array and max number array
+             * @param buff - Data to check for min and max values.
+             * @param vertexStart - Start offset to calculate min and max values.
+             * @param vertexCount - Number of vertices to check for min and max values.
+             * @param stride - Offset between consecutive attributes.
+             * @param useRightHandedSystem - Indicates whether the data should be modified for a right or left handed coordinate system.
+             * @returns - min number array and max number array.
              */
-            _Exporter.prototype.calculateMinMax = function (buff, vertexStart, vertexCount, arrayOffset, stride) {
+            _Exporter.prototype.calculateMinMax = function (buff, vertexStart, vertexCount, stride, useRightHandedSystem) {
                 var min = [Infinity, Infinity, Infinity];
                 var max = [-Infinity, -Infinity, -Infinity];
                 var end = vertexStart + vertexCount;
                 if (vertexCount > 0) {
                     for (var i = vertexStart; i < end; ++i) {
                         var index = stride * i;
+                        var scale = 1;
                         for (var j = 0; j < stride; ++j) {
-                            if (buff[index] < min[j]) {
-                                min[j] = buff[index];
+                            if (j === (stride - 1) && !useRightHandedSystem) {
+                                scale = -1;
                             }
-                            if (buff[index] > max[j]) {
-                                max[j] = buff[index];
+                            var num = scale * buff[index];
+                            if (num < min[j]) {
+                                min[j] = num;
+                            }
+                            if (num > max[j]) {
+                                max[j] = num;
                             }
                             ++index;
                         }
@@ -154,24 +168,24 @@ var BABYLON;
                 return { min: min, max: max };
             };
             /**
-             * Write mesh attribute data to buffer.
+             * Writes mesh attribute data to a data buffer.
              * Returns the bytelength of the data.
-             * @param vertexBufferType
-             * @param submesh
-             * @param meshAttributeArray
-             * @param strideSize
-             * @param byteOffset
-             * @param dataBuffer
-             * @param useRightHandedSystem
-             * @returns - byte length
+             * @param vertexBufferKind - Indicates what kind of vertex data is being passed in.
+             * @param meshAttributeArray - Array containing the attribute data.
+             * @param strideSize - Represents the offset between consecutive attributes
+             * @param byteOffset - The offset to start counting bytes from.
+             * @param dataBuffer - The buffer to write the binary data to.
+             * @param useRightHandedSystem - Indicates whether the data should be modified for a right or left handed coordinate system.
+             * @returns - Byte length of the attribute data.
              */
-            _Exporter.prototype.writeAttributeData = function (vertexBufferType, submesh, meshAttributeArray, strideSize, byteOffset, dataBuffer, useRightHandedSystem) {
+            _Exporter.prototype.writeAttributeData = function (vertexBufferKind, meshAttributeArray, strideSize, vertexBufferOffset, byteOffset, dataBuffer, useRightHandedSystem) {
                 var byteOff = byteOffset;
-                var end = submesh.verticesStart + submesh.verticesCount;
+                var start = 0;
+                var end = meshAttributeArray.length / strideSize;
                 var byteLength = 0;
-                switch (vertexBufferType) {
+                switch (vertexBufferKind) {
                     case BABYLON.VertexBuffer.PositionKind: {
-                        for (var k = submesh.verticesStart; k < end; ++k) {
+                        for (var k = start; k < end; ++k) {
                             var index = k * strideSize;
                             dataBuffer.setFloat32(byteOff, meshAttributeArray[index], true);
                             byteOff += 4;
@@ -185,11 +199,11 @@ var BABYLON;
                             }
                             byteOff += 4;
                         }
-                        byteLength = submesh.verticesCount * 12;
+                        byteLength = meshAttributeArray.length * 4;
                         break;
                     }
                     case BABYLON.VertexBuffer.NormalKind: {
-                        for (var k = submesh.verticesStart; k < end; ++k) {
+                        for (var k = start; k < end; ++k) {
                             var index = k * strideSize;
                             dataBuffer.setFloat32(byteOff, meshAttributeArray[index], true);
                             byteOff += 4;
@@ -203,11 +217,11 @@ var BABYLON;
                             }
                             byteOff += 4;
                         }
-                        byteLength = submesh.verticesCount * 12;
+                        byteLength = meshAttributeArray.length * 4;
                         break;
                     }
                     case BABYLON.VertexBuffer.TangentKind: {
-                        for (var k = submesh.indexStart; k < end; ++k) {
+                        for (var k = start; k < end; ++k) {
                             var index = k * strideSize;
                             dataBuffer.setFloat32(byteOff, meshAttributeArray[index], true);
                             byteOff += 4;
@@ -223,11 +237,11 @@ var BABYLON;
                             dataBuffer.setFloat32(byteOff, meshAttributeArray[index + 3], true);
                             byteOff += 4;
                         }
-                        byteLength = submesh.verticesCount * 16;
+                        byteLength = meshAttributeArray.length * 4;
                         break;
                     }
                     case BABYLON.VertexBuffer.ColorKind: {
-                        for (var k = submesh.verticesStart; k < end; ++k) {
+                        for (var k = start; k < end; ++k) {
                             var index = k * strideSize;
                             dataBuffer.setFloat32(byteOff, meshAttributeArray[index], true);
                             byteOff += 4;
@@ -238,45 +252,45 @@ var BABYLON;
                             dataBuffer.setFloat32(byteOff, meshAttributeArray[index + 3], true);
                             byteOff += 4;
                         }
-                        byteLength = submesh.verticesCount * 16;
+                        byteLength = meshAttributeArray.length * 4;
                         break;
                     }
                     case BABYLON.VertexBuffer.UVKind: {
-                        for (var k = submesh.verticesStart; k < end; ++k) {
+                        for (var k = start; k < end; ++k) {
                             var index = k * strideSize;
                             dataBuffer.setFloat32(byteOff, meshAttributeArray[index], true);
                             byteOff += 4;
                             dataBuffer.setFloat32(byteOff, meshAttributeArray[index + 1], true);
                             byteOff += 4;
                         }
-                        byteLength = submesh.verticesCount * 8;
+                        byteLength = meshAttributeArray.length * 4;
                         break;
                     }
                     case BABYLON.VertexBuffer.UV2Kind: {
-                        for (var k = submesh.verticesStart; k < end; ++k) {
+                        for (var k = start; k < end; ++k) {
                             var index = k * strideSize;
                             dataBuffer.setFloat32(byteOff, meshAttributeArray[index], true);
                             byteOff += 4;
                             dataBuffer.setFloat32(byteOff, meshAttributeArray[index + 1], true);
                             byteOff += 4;
                         }
-                        byteLength = submesh.verticesCount * 8;
+                        byteLength = meshAttributeArray.length * 4;
                         break;
                     }
                     default: {
-                        throw new Error("Unsupported vertex buffer type: " + vertexBufferType);
+                        throw new Error("Unsupported vertex buffer type: " + vertexBufferKind);
                     }
                 }
                 return byteLength;
             };
             /**
              * Generates glTF json data
-             * @param glb
-             * @param glTFPrefix
-             * @param prettyPrint
+             * @param shouldUseGlb - Indicates whether the json should be written for a glb file.
+             * @param glTFPrefix - Text to use when prefixing a glTF file.
+             * @param prettyPrint - Indicates whether the json file should be pretty printed (true) or not (false).
              * @returns - json data as string
              */
-            _Exporter.prototype.generateJSON = function (glb, glTFPrefix, prettyPrint) {
+            _Exporter.prototype.generateJSON = function (shouldUseGlb, glTFPrefix, prettyPrint) {
                 var buffer = { byteLength: this.totalByteLength };
                 var glTF = {
                     asset: this.asset
@@ -307,7 +321,7 @@ var BABYLON;
                     glTF.textures = this.textures;
                 }
                 if (this.images && this.images.length !== 0) {
-                    if (!glb) {
+                    if (!shouldUseGlb) {
                         glTF.images = this.images;
                     }
                     else {
@@ -320,7 +334,7 @@ var BABYLON;
                             if (image.uri !== undefined) {
                                 var imageData = this.imageData[image.uri];
                                 var imageName = image.uri.split('.')[0] + " image";
-                                var bufferView = this.createBufferView(0, byteOffset, imageData.data.length, imageName);
+                                var bufferView = this.createBufferView(0, byteOffset, imageData.data.length, undefined, imageName);
                                 byteOffset += imageData.data.buffer.byteLength;
                                 this.bufferViews.push(bufferView);
                                 image.bufferView = this.bufferViews.length - 1;
@@ -333,7 +347,7 @@ var BABYLON;
                         buffer.byteLength = byteOffset;
                     }
                 }
-                if (!glb) {
+                if (!shouldUseGlb) {
                     buffer.uri = glTFPrefix + ".bin";
                 }
                 var jsonText = prettyPrint ? JSON.stringify(glTF, null, 2) : JSON.stringify(glTF);
@@ -341,9 +355,8 @@ var BABYLON;
             };
             /**
              * Generates data for .gltf and .bin files based on the glTF prefix string
-             * @param glTFPrefix
-             * @returns - object with glTF json tex filename
-             * and binary file name as keys and their data as values
+             * @param glTFPrefix - Text to use when prefixing a glTF file.
+             * @returns - GLTFData with glTF file data.
              */
             _Exporter.prototype._generateGLTF = function (glTFPrefix) {
                 var jsonText = this.generateJSON(false, glTFPrefix, true);
@@ -373,7 +386,7 @@ var BABYLON;
                 return binaryBuffer;
             };
             /**
-             * Pads the number to a power of 4
+             * Pads the number to a multiple of 4
              * @param num - number to pad
              * @returns - padded number
              */
@@ -385,8 +398,6 @@ var BABYLON;
             /**
              * Generates a glb file from the json and binary data.
              * Returns an object with the glb file name as the key and data as the value.
-             * @param jsonText
-             * @param binaryBuffer
              * @param glTFPrefix
              * @returns - object with glb filename as key and data as value
              */
@@ -403,7 +414,8 @@ var BABYLON;
                 }
                 var jsonPadding = this._getPadding(jsonLength);
                 var binPadding = this._getPadding(binaryBuffer.byteLength);
-                var byteLength = headerLength + (2 * chunkLengthPrefix) + jsonLength + jsonPadding + binaryBuffer.byteLength + binPadding + imageByteLength;
+                var imagePadding = this._getPadding(imageByteLength);
+                var byteLength = headerLength + (2 * chunkLengthPrefix) + jsonLength + jsonPadding + binaryBuffer.byteLength + binPadding + imageByteLength + imagePadding;
                 //header
                 var headerBuffer = new ArrayBuffer(headerLength);
                 var headerBufferView = new DataView(headerBuffer);
@@ -428,7 +440,7 @@ var BABYLON;
                 //binary chunk
                 var binaryChunkBuffer = new ArrayBuffer(chunkLengthPrefix);
                 var binaryChunkBufferView = new DataView(binaryChunkBuffer);
-                binaryChunkBufferView.setUint32(0, binaryBuffer.byteLength + imageByteLength, true);
+                binaryChunkBufferView.setUint32(0, binaryBuffer.byteLength + imageByteLength + imagePadding, true);
                 binaryChunkBufferView.setUint32(4, 0x004E4942, true);
                 // binary padding
                 var binPaddingBuffer = new ArrayBuffer(binPadding);
@@ -436,12 +448,18 @@ var BABYLON;
                 for (var i = 0; i < binPadding; ++i) {
                     binPaddingView[i] = 0;
                 }
+                var imagePaddingBuffer = new ArrayBuffer(imagePadding);
+                var imagePaddingView = new Uint8Array(imagePaddingBuffer);
+                for (var i = 0; i < imagePadding; ++i) {
+                    imagePaddingView[i] = 0;
+                }
                 var glbData = [headerBuffer, jsonChunkBuffer, binaryChunkBuffer, binaryBuffer];
                 // binary data
                 for (var key in this.imageData) {
                     glbData.push(this.imageData[key].data.buffer);
                 }
                 glbData.push(binPaddingBuffer);
+                glbData.push(imagePaddingBuffer);
                 var glbFile = new Blob(glbData, { type: 'application/octet-stream' });
                 var container = new BABYLON._GLTFData();
                 container.glTFFiles[glbFileName] = glbFile;
@@ -449,9 +467,9 @@ var BABYLON;
             };
             /**
              * Sets the TRS for each node
-             * @param node
-             * @param babylonMesh
-             * @param useRightHandedSystem
+             * @param node - glTF Node for storing the transformation data.
+             * @param babylonMesh - Babylon mesh used as the source for the transformation data.
+             * @param useRightHandedSystem - Indicates whether the data should be modified for a right or left handed coordinate system.
              */
             _Exporter.prototype.setNodeTransformation = function (node, babylonMesh, useRightHandedSystem) {
                 if (!(babylonMesh.position.x === 0 && babylonMesh.position.y === 0 && babylonMesh.position.z === 0)) {
@@ -485,8 +503,9 @@ var BABYLON;
             };
             /**
              *
-             * @param babylonTexture
-             * @return - glTF texture, or null if the texture format is not supported
+             * @param babylonTexture - Babylon texture to extract.
+             * @param mimeType - Mime Type of the babylonTexture.
+             * @return - glTF texture, or null if the texture format is not supported.
              */
             _Exporter.prototype.exportTexture = function (babylonTexture, mimeType) {
                 if (mimeType === void 0) { mimeType = "image/jpeg" /* JPEG */; }
@@ -561,289 +580,352 @@ var BABYLON;
                 return textureInfo;
             };
             /**
-             * Sets data for the primitive attributes of each submesh
-             * @param mesh
-             * @param babylonMesh
-             * @param byteOffset
-             * @param useRightHandedSystem
-             * @param dataBuffer
-             * @returns - bytelength of the primitive attributes plus the passed in byteOffset
+             * Creates a bufferview based on the vertices type for the Babylon mesh
+             * @param kind - Indicates the type of vertices data.
+             * @param babylonMesh - The Babylon mesh to get the vertices data from.
+             * @param byteOffset - The offset from the buffer to start indexing from.
+             * @param useRightHandedSystem - Indicates whether the data should be modified for a right or left handed coordinate system.
+             * @param dataBuffer - The buffer to write the bufferview data to.
+             * @returns bytelength of the bufferview data.
              */
-            _Exporter.prototype.setPrimitiveAttributes = function (mesh, babylonMesh, byteOffset, useRightHandedSystem, dataBuffer) {
-                // go through all mesh primitives (submeshes)
-                for (var j = 0; j < babylonMesh.subMeshes.length; ++j) {
-                    var bufferMesh = null;
-                    var submesh = babylonMesh.subMeshes[j];
-                    var meshPrimitive = { attributes: {} };
-                    if (babylonMesh instanceof BABYLON.Mesh) {
-                        bufferMesh = babylonMesh;
-                    }
-                    else if (babylonMesh instanceof BABYLON.InstancedMesh) {
-                        bufferMesh = babylonMesh.sourceMesh;
-                    }
-                    // Loop through each attribute of the submesh (mesh primitive)
-                    if (bufferMesh.isVerticesDataPresent(BABYLON.VertexBuffer.PositionKind)) {
-                        var positionVertexBuffer = bufferMesh.getVertexBuffer(BABYLON.VertexBuffer.PositionKind);
-                        var positionVertexBufferOffset = positionVertexBuffer.getOffset();
-                        var positions = positionVertexBuffer.getData();
-                        var positionStrideSize = positionVertexBuffer.getStrideSize();
-                        if (dataBuffer) {
-                            byteOffset += this.writeAttributeData(BABYLON.VertexBuffer.PositionKind, submesh, positions, positionStrideSize, byteOffset, dataBuffer, useRightHandedSystem);
-                        }
-                        else {
-                            // Create bufferview
-                            var byteLength = submesh.verticesCount * 12;
-                            var bufferview = this.createBufferView(0, byteOffset, byteLength, "Positions");
+            _Exporter.prototype.createBufferViewKind = function (kind, babylonMesh, byteOffset, useRightHandedSystem, dataBuffer) {
+                var bufferMesh = null;
+                var byteLength = 0;
+                if (babylonMesh instanceof BABYLON.Mesh) {
+                    bufferMesh = babylonMesh;
+                }
+                else if (babylonMesh instanceof BABYLON.InstancedMesh) {
+                    bufferMesh = babylonMesh.sourceMesh;
+                }
+                if (bufferMesh !== null) {
+                    var vertexBuffer = null;
+                    var vertexBufferOffset = null;
+                    var vertexData = null;
+                    var vertexStrideSize = null;
+                    if (bufferMesh.getVerticesDataKinds().indexOf(kind) > -1) {
+                        vertexBuffer = bufferMesh.getVertexBuffer(kind);
+                        vertexBufferOffset = vertexBuffer.getOffset();
+                        vertexData = vertexBuffer.getData();
+                        vertexStrideSize = vertexBuffer.getStrideSize();
+                        if (dataBuffer && vertexData) {
+                            byteLength = this.writeAttributeData(kind, vertexData, vertexStrideSize, vertexBufferOffset, byteOffset, dataBuffer, useRightHandedSystem);
                             byteOffset += byteLength;
-                            this.bufferViews.push(bufferview);
-                            // Create accessor
-                            var result = this.calculateMinMax(positions, submesh.verticesStart, submesh.verticesCount, positionVertexBufferOffset, positionStrideSize);
-                            var accessor = this.createAccessor(this.bufferViews.length - 1, "Position", "VEC3" /* VEC3 */, 5126 /* FLOAT */, submesh.verticesCount, result.min, result.max);
-                            this.accessors.push(accessor);
-                            meshPrimitive.attributes.POSITION = this.accessors.length - 1;
-                        }
-                    }
-                    if (bufferMesh.isVerticesDataPresent(BABYLON.VertexBuffer.NormalKind)) {
-                        var normalVertexBuffer = bufferMesh.getVertexBuffer(BABYLON.VertexBuffer.NormalKind);
-                        var normals = normalVertexBuffer.getData();
-                        var normalStrideSize = normalVertexBuffer.getStrideSize();
-                        if (dataBuffer) {
-                            byteOffset += this.writeAttributeData(BABYLON.VertexBuffer.NormalKind, submesh, normals, normalStrideSize, byteOffset, dataBuffer, useRightHandedSystem);
                         }
                         else {
-                            // Create bufferview
-                            var byteLength = submesh.verticesCount * 12;
-                            var bufferview = this.createBufferView(0, byteOffset, byteLength, "Normals");
-                            byteOffset += byteLength;
-                            this.bufferViews.push(bufferview);
-                            // Create accessor
-                            var accessor = this.createAccessor(this.bufferViews.length - 1, "Normal", "VEC3" /* VEC3 */, 5126 /* FLOAT */, submesh.verticesCount);
-                            this.accessors.push(accessor);
-                            meshPrimitive.attributes.NORMAL = this.accessors.length - 1;
+                            var bufferViewName = null;
+                            switch (kind) {
+                                case BABYLON.VertexBuffer.PositionKind: {
+                                    byteLength = vertexData.length * 4;
+                                    bufferViewName = "Position - " + bufferMesh.name;
+                                    break;
+                                }
+                                case BABYLON.VertexBuffer.NormalKind: {
+                                    byteLength = vertexData.length * 4;
+                                    bufferViewName = "Normal - " + bufferMesh.name;
+                                    break;
+                                }
+                                case BABYLON.VertexBuffer.TangentKind: {
+                                    byteLength = vertexData.length * 4;
+                                    bufferViewName = "Tangent - " + bufferMesh.name;
+                                    break;
+                                }
+                                case BABYLON.VertexBuffer.ColorKind: {
+                                    byteLength = vertexData.length * 4;
+                                    bufferViewName = "Color - " + bufferMesh.name;
+                                    break;
+                                }
+                                case BABYLON.VertexBuffer.UVKind: {
+                                    byteLength = vertexData.length * 4;
+                                    bufferViewName = "TexCoord 0 - " + bufferMesh.name;
+                                    break;
+                                }
+                                case BABYLON.VertexBuffer.UV2Kind: {
+                                    byteLength = vertexData.length * 4;
+                                    bufferViewName = "TexCoord 1 - " + bufferMesh.name;
+                                    break;
+                                }
+                                default: {
+                                    console.warn("Unsupported VertexBuffer kind: " + kind);
+                                }
+                            }
+                            if (bufferViewName !== null) {
+                                var bufferView = this.createBufferView(0, byteOffset, byteLength, vertexStrideSize * 4, bufferViewName);
+                                byteOffset += byteLength;
+                                this.bufferViews.push(bufferView);
+                            }
                         }
                     }
-                    if (bufferMesh.isVerticesDataPresent(BABYLON.VertexBuffer.TangentKind)) {
-                        var tangentVertexBuffer = bufferMesh.getVertexBuffer(BABYLON.VertexBuffer.TangentKind);
-                        var tangents = tangentVertexBuffer.getData();
-                        var tangentStrideSize = tangentVertexBuffer.getStrideSize();
-                        if (dataBuffer) {
-                            byteOffset += this.writeAttributeData(BABYLON.VertexBuffer.TangentKind, submesh, tangents, tangentStrideSize, byteOffset, dataBuffer, useRightHandedSystem);
-                        }
-                        else {
-                            // Create bufferview
-                            var byteLength = submesh.verticesCount * 16;
-                            var bufferview = this.createBufferView(0, byteOffset, byteLength, "Tangents");
-                            byteOffset += byteLength;
-                            this.bufferViews.push(bufferview);
-                            // Create accessor
-                            var accessor = this.createAccessor(this.bufferViews.length - 1, "Tangent", "VEC4" /* VEC4 */, 5126 /* FLOAT */, submesh.verticesCount);
-                            this.accessors.push(accessor);
-                            meshPrimitive.attributes.TANGENT = this.accessors.length - 1;
-                        }
+                }
+                return byteLength;
+            };
+            /**
+             * Sets data for the primitive attributes of each submesh
+             * @param mesh - glTF Mesh object to store the primitive attribute information.
+             * @param babylonMesh - Babylon mesh to get the primitive attribute data from.
+             * @param byteOffset - The offset in bytes of the buffer data.
+             * @param useRightHandedSystem - Indicates whether the data should be modified for a right or left handed coordinate system.
+             * @param dataBuffer - Buffer to write the attribute data to.
+             * @returns - bytelength of the primitive attributes plus the passed in byteOffset.
+             */
+            _Exporter.prototype.setPrimitiveAttributes = function (mesh, babylonMesh, byteOffset, useRightHandedSystem, dataBuffer) {
+                var bufferMesh = null;
+                if (babylonMesh instanceof BABYLON.Mesh) {
+                    bufferMesh = babylonMesh;
+                }
+                else if (babylonMesh instanceof BABYLON.InstancedMesh) {
+                    bufferMesh = babylonMesh.sourceMesh;
+                }
+                var positionBufferViewIndex = null;
+                var normalBufferViewIndex = null;
+                var colorBufferViewIndex = null;
+                var tangentBufferViewIndex = null;
+                var texCoord0BufferViewIndex = null;
+                var texCoord1BufferViewIndex = null;
+                var indexBufferViewIndex = null;
+                if (bufferMesh !== null) {
+                    // For each BabylonMesh, create bufferviews for each 'kind'
+                    if (bufferMesh.isVerticesDataPresent(BABYLON.VertexBuffer.PositionKind)) {
+                        byteOffset += this.createBufferViewKind(BABYLON.VertexBuffer.PositionKind, babylonMesh, byteOffset, useRightHandedSystem, dataBuffer);
+                        positionBufferViewIndex = this.bufferViews.length - 1;
+                    }
+                    if (bufferMesh.isVerticesDataPresent(BABYLON.VertexBuffer.NormalKind)) {
+                        byteOffset += this.createBufferViewKind(BABYLON.VertexBuffer.NormalKind, babylonMesh, byteOffset, useRightHandedSystem, dataBuffer);
+                        normalBufferViewIndex = this.bufferViews.length - 1;
                     }
                     if (bufferMesh.isVerticesDataPresent(BABYLON.VertexBuffer.ColorKind)) {
-                        var colorVertexBuffer = bufferMesh.getVertexBuffer(BABYLON.VertexBuffer.ColorKind);
-                        var colors = colorVertexBuffer.getData();
-                        var colorStrideSize = colorVertexBuffer.getStrideSize();
-                        if (dataBuffer) {
-                            byteOffset += this.writeAttributeData(BABYLON.VertexBuffer.ColorKind, submesh, colors, colorStrideSize, byteOffset, dataBuffer, useRightHandedSystem);
-                        }
-                        else {
-                            // Create bufferview
-                            var byteLength = submesh.verticesCount * 16;
-                            var bufferview = this.createBufferView(0, byteOffset, byteLength, "Colors");
-                            byteOffset += byteLength;
-                            this.bufferViews.push(bufferview);
-                            // Create accessor
-                            var accessor = this.createAccessor(this.bufferViews.length - 1, "Color", "VEC4" /* VEC4 */, 5126 /* FLOAT */, submesh.verticesCount);
-                            this.accessors.push(accessor);
-                            meshPrimitive.attributes.COLOR_0 = this.accessors.length - 1;
-                        }
+                        byteOffset += this.createBufferViewKind(BABYLON.VertexBuffer.ColorKind, babylonMesh, byteOffset, useRightHandedSystem, dataBuffer);
+                        colorBufferViewIndex = this.bufferViews.length - 1;
+                    }
+                    if (bufferMesh.isVerticesDataPresent(BABYLON.VertexBuffer.TangentKind)) {
+                        byteOffset += this.createBufferViewKind(BABYLON.VertexBuffer.TangentKind, babylonMesh, byteOffset, useRightHandedSystem, dataBuffer);
+                        colorBufferViewIndex = this.bufferViews.length - 1;
                     }
                     if (bufferMesh.isVerticesDataPresent(BABYLON.VertexBuffer.UVKind)) {
-                        var texCoord0VertexBuffer = bufferMesh.getVertexBuffer(BABYLON.VertexBuffer.UVKind);
-                        var texCoords0 = texCoord0VertexBuffer.getData();
-                        var texCoord0StrideSize = texCoord0VertexBuffer.getStrideSize();
-                        if (dataBuffer) {
-                            byteOffset += this.writeAttributeData(BABYLON.VertexBuffer.UVKind, submesh, texCoords0, texCoord0StrideSize, byteOffset, dataBuffer, useRightHandedSystem);
-                        }
-                        else {
-                            // Create bufferview
-                            var byteLength = submesh.verticesCount * 8;
-                            var bufferview = this.createBufferView(0, byteOffset, byteLength, "Texture Coords0");
-                            byteOffset += byteLength;
-                            this.bufferViews.push(bufferview);
-                            // Create accessor
-                            var accessor = this.createAccessor(this.bufferViews.length - 1, "Texture Coords", "VEC2" /* VEC2 */, 5126 /* FLOAT */, submesh.verticesCount);
-                            this.accessors.push(accessor);
-                            meshPrimitive.attributes.TEXCOORD_0 = this.accessors.length - 1;
-                        }
+                        byteOffset += this.createBufferViewKind(BABYLON.VertexBuffer.UVKind, babylonMesh, byteOffset, useRightHandedSystem, dataBuffer);
+                        texCoord0BufferViewIndex = this.bufferViews.length - 1;
                     }
                     if (bufferMesh.isVerticesDataPresent(BABYLON.VertexBuffer.UV2Kind)) {
-                        var texCoord1VertexBuffer = bufferMesh.getVertexBuffer(BABYLON.VertexBuffer.UV2Kind);
-                        var texCoords1 = texCoord1VertexBuffer.getData();
-                        var texCoord1StrideSize = texCoord1VertexBuffer.getStrideSize();
-                        if (dataBuffer) {
-                            byteOffset += this.writeAttributeData(BABYLON.VertexBuffer.UV2Kind, submesh, texCoords1, texCoord1StrideSize, byteOffset, dataBuffer, useRightHandedSystem);
-                        }
-                        else {
-                            // Create bufferview
-                            var byteLength = submesh.verticesCount * 8;
-                            var bufferview = this.createBufferView(0, byteOffset, byteLength, "Texture Coords 1");
-                            byteOffset += byteLength;
-                            this.bufferViews.push(bufferview);
-                            // Create accessor
-                            var accessor = this.createAccessor(this.bufferViews.length - 1, "Texture Coords", "VEC2" /* VEC2 */, 5126 /* FLOAT */, submesh.verticesCount);
-                            this.accessors.push(accessor);
-                            meshPrimitive.attributes.TEXCOORD_1 = this.accessors.length - 1;
-                        }
+                        byteOffset += this.createBufferViewKind(BABYLON.VertexBuffer.UV2Kind, babylonMesh, byteOffset, useRightHandedSystem, dataBuffer);
+                        texCoord1BufferViewIndex = this.bufferViews.length - 1;
                     }
                     if (bufferMesh.getTotalIndices() > 0) {
+                        var indices = bufferMesh.getIndices();
                         if (dataBuffer) {
-                            var indices = bufferMesh.getIndices();
-                            var start = submesh.indexStart;
-                            var end = submesh.indexCount + start;
+                            var end = indices.length;
                             var byteOff = byteOffset;
-                            for (var k = start; k < end; k = k + 3) {
+                            for (var k = 0; k < end; ++k) {
                                 dataBuffer.setUint32(byteOff, indices[k], true);
                                 byteOff += 4;
-                                dataBuffer.setUint32(byteOff, indices[k + 1], true);
-                                byteOff += 4;
-                                dataBuffer.setUint32(byteOff, indices[k + 2], true);
-                                byteOff += 4;
                             }
-                            var byteLength = submesh.indexCount * 4;
-                            byteOffset += byteLength;
+                            byteOffset = byteOff;
                         }
                         else {
-                            // Create bufferview
-                            var indicesCount = submesh.indexCount;
-                            var byteLength = indicesCount * 4;
-                            var bufferview = this.createBufferView(0, byteOffset, byteLength, "Indices");
+                            var byteLength = indices.length * 4;
+                            var bufferView = this.createBufferView(0, byteOffset, byteLength, undefined, "Indices - " + bufferMesh.name);
                             byteOffset += byteLength;
-                            this.bufferViews.push(bufferview);
-                            // Create accessor
-                            var accessor = this.createAccessor(this.bufferViews.length - 1, "Indices", "SCALAR" /* SCALAR */, 5125 /* UNSIGNED_INT */, indicesCount);
-                            this.accessors.push(accessor);
-                            meshPrimitive.indices = this.accessors.length - 1;
+                            this.bufferViews.push(bufferView);
+                            indexBufferViewIndex = this.bufferViews.length - 1;
                         }
                     }
-                    if (bufferMesh.material) {
-                        if (bufferMesh.material instanceof BABYLON.StandardMaterial) {
-                            var babylonStandardMaterial = bufferMesh.material;
-                            var glTFMaterial = { name: babylonStandardMaterial.name };
-                            if (!babylonStandardMaterial.backFaceCulling) {
-                                glTFMaterial.doubleSided = true;
-                            }
-                            if (babylonStandardMaterial.bumpTexture) {
-                                var glTFTexture = this.exportTexture(babylonStandardMaterial.bumpTexture);
-                                if (glTFTexture) {
-                                    glTFMaterial.normalTexture = glTFTexture;
-                                }
-                            }
-                            if (babylonStandardMaterial.emissiveTexture) {
-                                var glTFEmissiveTexture = this.exportTexture(babylonStandardMaterial.emissiveTexture);
-                                if (glTFEmissiveTexture) {
-                                    glTFMaterial.emissiveTexture = glTFEmissiveTexture;
-                                }
-                                glTFMaterial.emissiveFactor = [1.0, 1.0, 1.0];
+                }
+                // go through all mesh primitives (submeshes)
+                for (var j = 0; j < babylonMesh.subMeshes.length; ++j) {
+                    var submesh = babylonMesh.subMeshes[j];
+                    var meshPrimitive = { attributes: {} };
+                    if (bufferMesh !== null) {
+                        // Create a bufferview storing all the positions
+                        if (!dataBuffer) {
+                            // Loop through each attribute of the submesh (mesh primitive)
+                            if (positionBufferViewIndex !== null) {
+                                var positionVertexBuffer = bufferMesh.getVertexBuffer(BABYLON.VertexBuffer.PositionKind);
+                                var positions = positionVertexBuffer.getData();
+                                var positionStrideSize = positionVertexBuffer.getStrideSize();
+                                // Create accessor
+                                var result = this.calculateMinMax(positions, 0, positions.length / positionStrideSize, positionStrideSize, useRightHandedSystem);
+                                var accessor = this.createAccessor(positionBufferViewIndex, "Position", "VEC3" /* VEC3 */, 5126 /* FLOAT */, positions.length / positionStrideSize, 0, result.min, result.max);
+                                this.accessors.push(accessor);
+                                meshPrimitive.attributes.POSITION = this.accessors.length - 1;
                             }
-                            if (babylonStandardMaterial.ambientTexture) {
-                                var glTFOcclusionTexture = this.exportTexture(babylonStandardMaterial.ambientTexture);
-                                if (glTFOcclusionTexture) {
-                                    glTFMaterial.occlusionTexture = glTFOcclusionTexture;
-                                }
+                            if (normalBufferViewIndex !== null) {
+                                var normalVertexBuffer = bufferMesh.getVertexBuffer(BABYLON.VertexBuffer.NormalKind);
+                                var normals = normalVertexBuffer.getData();
+                                var normalStrideSize = normalVertexBuffer.getStrideSize();
+                                // Create accessor
+                                var accessor = this.createAccessor(normalBufferViewIndex, "Normal", "VEC3" /* VEC3 */, 5126 /* FLOAT */, normals.length / normalStrideSize);
+                                this.accessors.push(accessor);
+                                meshPrimitive.attributes.NORMAL = this.accessors.length - 1;
                             }
-                            // Spec Gloss
-                            var glTFPbrMetallicRoughness = GLTF2._GLTFMaterial.ConvertToGLTFPBRMetallicRoughness(babylonStandardMaterial);
-                            glTFMaterial.pbrMetallicRoughness = glTFPbrMetallicRoughness;
-                            // TODO: Handle Textures
-                            this.materials.push(glTFMaterial);
-                            meshPrimitive.material = this.materials.length - 1;
-                        }
-                        else if (bufferMesh.material instanceof BABYLON.PBRMetallicRoughnessMaterial) {
-                            if (!this.textures) {
-                                this.textures = new Array();
+                            if (tangentBufferViewIndex !== null) {
+                                var tangentVertexBuffer = bufferMesh.getVertexBuffer(BABYLON.VertexBuffer.TangentKind);
+                                var tangents = tangentVertexBuffer.getData();
+                                var tangentStrideSize = tangentVertexBuffer.getStrideSize();
+                                // Create accessor
+                                var accessor = this.createAccessor(tangentBufferViewIndex, "Tangent", "VEC4" /* VEC4 */, 5126 /* FLOAT */, tangents.length / tangentStrideSize);
+                                this.accessors.push(accessor);
+                                meshPrimitive.attributes.TANGENT = this.accessors.length - 1;
                             }
-                            var babylonPBRMaterial = bufferMesh.material;
-                            var glTFPbrMetallicRoughness = {};
-                            if (babylonPBRMaterial.baseColor) {
-                                glTFPbrMetallicRoughness.baseColorFactor = [
-                                    babylonPBRMaterial.baseColor.r,
-                                    babylonPBRMaterial.baseColor.g,
-                                    babylonPBRMaterial.baseColor.b,
-                                    babylonPBRMaterial.alpha
-                                ];
+                            if (colorBufferViewIndex !== null) {
+                                var colorVertexBuffer = bufferMesh.getVertexBuffer(BABYLON.VertexBuffer.ColorKind);
+                                var colors = colorVertexBuffer.getData();
+                                var colorStrideSize = colorVertexBuffer.getStrideSize();
+                                // Create accessor
+                                var accessor = this.createAccessor(colorBufferViewIndex, "Color", "VEC4" /* VEC4 */, 5126 /* FLOAT */, colors.length / colorStrideSize);
+                                this.accessors.push(accessor);
+                                meshPrimitive.attributes.COLOR_0 = this.accessors.length - 1;
                             }
-                            if (babylonPBRMaterial.baseTexture !== undefined) {
-                                var glTFTexture = this.exportTexture(babylonPBRMaterial.baseTexture);
-                                if (glTFTexture !== null) {
-                                    glTFPbrMetallicRoughness.baseColorTexture = glTFTexture;
-                                }
-                                glTFPbrMetallicRoughness.baseColorTexture;
+                            if (texCoord0BufferViewIndex !== null) {
+                                // Create accessor
+                                var texCoord0VertexBuffer = bufferMesh.getVertexBuffer(BABYLON.VertexBuffer.UVKind);
+                                var texCoord0s = texCoord0VertexBuffer.getData();
+                                var texCoord0StrideSize = texCoord0VertexBuffer.getStrideSize();
+                                var accessor = this.createAccessor(texCoord0BufferViewIndex, "Texture Coords 0", "VEC2" /* VEC2 */, 5126 /* FLOAT */, texCoord0s.length / texCoord0StrideSize);
+                                this.accessors.push(accessor);
+                                meshPrimitive.attributes.TEXCOORD_0 = this.accessors.length - 1;
                             }
-                            if (babylonPBRMaterial.metallic !== undefined) {
-                                glTFPbrMetallicRoughness.metallicFactor = babylonPBRMaterial.metallic;
+                            if (texCoord1BufferViewIndex !== null) {
+                                // Create accessor
+                                var texCoord1VertexBuffer = bufferMesh.getVertexBuffer(BABYLON.VertexBuffer.UV2Kind);
+                                var texCoord1s = texCoord1VertexBuffer.getData();
+                                var texCoord1StrideSize = texCoord1VertexBuffer.getStrideSize();
+                                var accessor = this.createAccessor(texCoord1BufferViewIndex, "Texture Coords 1", "VEC2" /* VEC2 */, 5126 /* FLOAT */, texCoord1s.length / texCoord1StrideSize);
+                                this.accessors.push(accessor);
+                                meshPrimitive.attributes.TEXCOORD_1 = this.accessors.length - 1;
                             }
-                            if (babylonPBRMaterial.roughness !== undefined) {
-                                glTFPbrMetallicRoughness.roughnessFactor = babylonPBRMaterial.roughness;
+                            if (indexBufferViewIndex) {
+                                // Create accessor
+                                var accessor = this.createAccessor(indexBufferViewIndex, "Indices", "SCALAR" /* SCALAR */, 5125 /* UNSIGNED_INT */, submesh.indexCount, submesh.indexStart * 4);
+                                this.accessors.push(accessor);
+                                meshPrimitive.indices = this.accessors.length - 1;
                             }
-                            var glTFMaterial = {
-                                name: babylonPBRMaterial.name
-                            };
-                            if (babylonPBRMaterial.doubleSided) {
-                                glTFMaterial.doubleSided = babylonPBRMaterial.doubleSided;
-                            }
-                            if (babylonPBRMaterial.normalTexture) {
-                                var glTFTexture = this.exportTexture(babylonPBRMaterial.normalTexture);
-                                if (glTFTexture) {
-                                    glTFMaterial.normalTexture = glTFTexture;
+                        }
+                        if (bufferMesh.material) {
+                            if (bufferMesh.material instanceof BABYLON.StandardMaterial) {
+                                console.warn("Standard Material is currently not fully supported/implemented in glTF serializer");
+                                var babylonStandardMaterial = bufferMesh.material;
+                                var glTFPbrMetallicRoughness = GLTF2._GLTFMaterial.ConvertToGLTFPBRMetallicRoughness(babylonStandardMaterial);
+                                var glTFMaterial = { name: babylonStandardMaterial.name };
+                                if (!babylonStandardMaterial.backFaceCulling) {
+                                    glTFMaterial.doubleSided = true;
                                 }
-                            }
-                            if (babylonPBRMaterial.occlusionTexture) {
-                                var glTFTexture = this.exportTexture(babylonPBRMaterial.occlusionTexture);
-                                if (glTFTexture) {
-                                    glTFMaterial.occlusionTexture = glTFTexture;
-                                    if (babylonPBRMaterial.occlusionStrength !== undefined) {
-                                        glTFMaterial.occlusionTexture.strength = babylonPBRMaterial.occlusionStrength;
+                                if (babylonStandardMaterial.diffuseTexture && bufferMesh.isVerticesDataPresent(BABYLON.VertexBuffer.UVKind)) {
+                                    var glTFTexture = this.exportTexture(babylonStandardMaterial.diffuseTexture);
+                                    if (glTFTexture !== null) {
+                                        glTFPbrMetallicRoughness.baseColorTexture = glTFTexture;
                                     }
                                 }
-                            }
-                            if (babylonPBRMaterial.emissiveTexture) {
-                                var glTFTexture = this.exportTexture(babylonPBRMaterial.emissiveTexture);
-                                if (glTFTexture !== null) {
-                                    glTFMaterial.emissiveTexture = glTFTexture;
+                                if (babylonStandardMaterial.bumpTexture && bufferMesh.isVerticesDataPresent(BABYLON.VertexBuffer.UVKind)) {
+                                    var glTFTexture = this.exportTexture(babylonStandardMaterial.bumpTexture);
+                                    if (glTFTexture) {
+                                        glTFMaterial.normalTexture = glTFTexture;
+                                    }
                                 }
+                                if (babylonStandardMaterial.emissiveTexture && bufferMesh.isVerticesDataPresent(BABYLON.VertexBuffer.UVKind)) {
+                                    var glTFEmissiveTexture = this.exportTexture(babylonStandardMaterial.emissiveTexture);
+                                    if (glTFEmissiveTexture) {
+                                        glTFMaterial.emissiveTexture = glTFEmissiveTexture;
+                                    }
+                                    glTFMaterial.emissiveFactor = [1.0, 1.0, 1.0];
+                                }
+                                if (babylonStandardMaterial.ambientTexture && bufferMesh.isVerticesDataPresent(BABYLON.VertexBuffer.UVKind)) {
+                                    var glTFOcclusionTexture = this.exportTexture(babylonStandardMaterial.ambientTexture);
+                                    if (glTFOcclusionTexture) {
+                                        glTFMaterial.occlusionTexture = glTFOcclusionTexture;
+                                    }
+                                }
+                                if (babylonStandardMaterial.alpha < 1.0 || babylonStandardMaterial.opacityTexture) {
+                                    if (babylonStandardMaterial.alphaMode === BABYLON.Engine.ALPHA_COMBINE) {
+                                        glTFMaterial.alphaMode = "BLEND" /* BLEND */;
+                                    }
+                                    else {
+                                        console.warn("glTF 2.0 does not support alpha mode: " + babylonStandardMaterial.alphaMode.toString());
+                                    }
+                                }
+                                glTFMaterial.pbrMetallicRoughness = glTFPbrMetallicRoughness;
+                                this.materials.push(glTFMaterial);
+                                meshPrimitive.material = this.materials.length - 1;
                             }
-                            if (!babylonPBRMaterial.emissiveColor.equals(new BABYLON.Color3(0.0, 0.0, 0.0))) {
-                                glTFMaterial.emissiveFactor = babylonPBRMaterial.emissiveColor.asArray();
-                            }
-                            if (babylonPBRMaterial.transparencyMode) {
-                                var alphaMode = GLTF2._GLTFMaterial.GetAlphaMode(babylonPBRMaterial);
-                                if (alphaMode !== "OPAQUE" /* OPAQUE */) {
-                                    glTFMaterial.alphaMode = alphaMode;
-                                    if (alphaMode === "BLEND" /* BLEND */) {
-                                        glTFMaterial.alphaCutoff = babylonPBRMaterial.alphaCutOff;
+                            else if (bufferMesh.material instanceof BABYLON.PBRMetallicRoughnessMaterial) {
+                                var babylonPBRMaterial = bufferMesh.material;
+                                var glTFPbrMetallicRoughness = {};
+                                if (babylonPBRMaterial.baseColor) {
+                                    glTFPbrMetallicRoughness.baseColorFactor = [
+                                        babylonPBRMaterial.baseColor.r,
+                                        babylonPBRMaterial.baseColor.g,
+                                        babylonPBRMaterial.baseColor.b,
+                                        babylonPBRMaterial.alpha
+                                    ];
+                                }
+                                if (babylonPBRMaterial.baseTexture !== undefined) {
+                                    var glTFTexture = this.exportTexture(babylonPBRMaterial.baseTexture);
+                                    if (glTFTexture !== null) {
+                                        glTFPbrMetallicRoughness.baseColorTexture = glTFTexture;
                                     }
+                                    glTFPbrMetallicRoughness.baseColorTexture;
                                 }
+                                if (babylonPBRMaterial.metallic !== undefined) {
+                                    glTFPbrMetallicRoughness.metallicFactor = babylonPBRMaterial.metallic;
+                                }
+                                if (babylonPBRMaterial.roughness !== undefined) {
+                                    glTFPbrMetallicRoughness.roughnessFactor = babylonPBRMaterial.roughness;
+                                }
+                                var glTFMaterial = {
+                                    name: babylonPBRMaterial.name
+                                };
+                                if (babylonPBRMaterial.doubleSided) {
+                                    glTFMaterial.doubleSided = babylonPBRMaterial.doubleSided;
+                                }
+                                if (babylonPBRMaterial.normalTexture) {
+                                    var glTFTexture = this.exportTexture(babylonPBRMaterial.normalTexture);
+                                    if (glTFTexture) {
+                                        glTFMaterial.normalTexture = glTFTexture;
+                                    }
+                                }
+                                if (babylonPBRMaterial.occlusionTexture) {
+                                    var glTFTexture = this.exportTexture(babylonPBRMaterial.occlusionTexture);
+                                    if (glTFTexture) {
+                                        glTFMaterial.occlusionTexture = glTFTexture;
+                                        if (babylonPBRMaterial.occlusionStrength !== undefined) {
+                                            glTFMaterial.occlusionTexture.strength = babylonPBRMaterial.occlusionStrength;
+                                        }
+                                    }
+                                }
+                                if (babylonPBRMaterial.emissiveTexture) {
+                                    var glTFTexture = this.exportTexture(babylonPBRMaterial.emissiveTexture);
+                                    if (glTFTexture !== null) {
+                                        glTFMaterial.emissiveTexture = glTFTexture;
+                                    }
+                                }
+                                if (!babylonPBRMaterial.emissiveColor.equals(new BABYLON.Color3(0.0, 0.0, 0.0))) {
+                                    glTFMaterial.emissiveFactor = babylonPBRMaterial.emissiveColor.asArray();
+                                }
+                                if (babylonPBRMaterial.transparencyMode) {
+                                    var alphaMode = GLTF2._GLTFMaterial.GetAlphaMode(babylonPBRMaterial);
+                                    if (alphaMode !== "OPAQUE" /* OPAQUE */) {
+                                        glTFMaterial.alphaMode = alphaMode;
+                                        if (alphaMode === "BLEND" /* BLEND */) {
+                                            glTFMaterial.alphaCutoff = babylonPBRMaterial.alphaCutOff;
+                                        }
+                                    }
+                                }
+                                glTFMaterial.pbrMetallicRoughness = glTFPbrMetallicRoughness;
+                                this.materials.push(glTFMaterial);
+                                meshPrimitive.material = this.materials.length - 1;
+                            }
+                            else {
+                                console.warn("Material type is not yet implemented in glTF serializer: " + bufferMesh.material.name);
                             }
-                            glTFMaterial.pbrMetallicRoughness = glTFPbrMetallicRoughness;
-                            // TODO: Handle Textures
-                            this.materials.push(glTFMaterial);
-                            meshPrimitive.material = this.materials.length - 1;
                         }
+                        mesh.primitives.push(meshPrimitive);
                     }
-                    mesh.primitives.push(meshPrimitive);
                 }
                 return byteOffset;
             };
             /**
              * Creates a glTF scene based on the array of meshes.
              * Returns the the total byte offset.
-             * @param gltf
-             * @param byteOffset
-             * @param buffer
-             * @param dataBuffer
+             * @param babylonScene - Babylon scene to get the mesh data from.
+             * @param byteOffset - Offset to start from in bytes.
+             * @param dataBuffer - Buffer to write geometry data to.
              * @returns bytelength + byteoffset
              */
             _Exporter.prototype.createScene = function (babylonScene, byteOffset, dataBuffer) {
@@ -996,7 +1078,7 @@ var BABYLON;
                 var diffuse = babylonSpecularGlossiness.diffuse;
                 var opacity = babylonSpecularGlossiness.opacity;
                 var specular = babylonSpecularGlossiness.specular;
-                var glossiness = babylonSpecularGlossiness.glossiness;
+                var glossiness = BABYLON.Scalar.Clamp(babylonSpecularGlossiness.glossiness);
                 var oneMinusSpecularStrength = 1 - Math.max(specular.r, Math.max(specular.g, specular.b));
                 var diffusePerceivedBrightness = _GLTFMaterial.PerceivedBrightness(diffuse);
                 var specularPerceivedBrightness = _GLTFMaterial.PerceivedBrightness(specular);

Những thai đổi đã bị hủy bỏ vì nó quá lớn
+ 1 - 1
dist/preview release/serializers/babylon.glTF2Serializer.min.js


+ 381 - 299
dist/preview release/serializers/babylonjs.serializers.js

@@ -222,22 +222,25 @@ var BABYLON;
                 this.nodes = new Array();
                 this.images = new Array();
                 this.materials = new Array();
+                this.textures = new Array();
                 this.imageData = {};
                 if (options !== undefined) {
                     this.options = options;
                 }
                 var totalByteLength = 0;
-                totalByteLength = this.createScene(this.babylonScene, totalByteLength);
+                totalByteLength = this.createScene(this.babylonScene, totalByteLength, null);
                 this.totalByteLength = totalByteLength;
             }
             /**
              * Creates a buffer view based on teh supplied arguments
-             * @param {number} bufferIndex - index value of the specified buffer
-             * @param {number} byteOffset - byte offset value
-             * @param {number} byteLength - byte length of the bufferView
+             * @param bufferIndex - index value of the specified buffer
+             * @param byteOffset - byte offset value
+             * @param byteLength - byte length of the bufferView
+             * @param byteStride - byte distance between conequential elements.
+             * @param name - name of the buffer view
              * @returns - bufferView for glTF
              */
-            _Exporter.prototype.createBufferView = function (bufferIndex, byteOffset, byteLength, name) {
+            _Exporter.prototype.createBufferView = function (bufferIndex, byteOffset, byteLength, byteStride, name) {
                 var bufferview = { buffer: bufferIndex, byteLength: byteLength };
                 if (byteOffset > 0) {
                     bufferview.byteOffset = byteOffset;
@@ -245,6 +248,9 @@ var BABYLON;
                 if (name) {
                     bufferview.name = name;
                 }
+                if (byteStride) {
+                    bufferview.byteStride = byteStride;
+                }
                 return bufferview;
             };
             /**
@@ -258,7 +264,7 @@ var BABYLON;
              * @param max
              * @returns - accessor for glTF
              */
-            _Exporter.prototype.createAccessor = function (bufferviewIndex, name, type, componentType, count, min, max) {
+            _Exporter.prototype.createAccessor = function (bufferviewIndex, name, type, componentType, count, byteOffset, min, max) {
                 var accessor = { name: name, bufferView: bufferviewIndex, componentType: componentType, count: count, type: type };
                 if (min) {
                     accessor.min = min;
@@ -266,30 +272,38 @@ var BABYLON;
                 if (max) {
                     accessor.max = max;
                 }
+                if (byteOffset) {
+                    accessor.byteOffset = byteOffset;
+                }
                 return accessor;
             };
             /**
              * Calculates the minimum and maximum values of an array of floats, based on stride
-             * @param buff
-             * @param vertexStart
-             * @param vertexCount
-             * @param arrayOffset
-             * @param stride
-             * @returns - min number array and max number array
+             * @param buff - Data to check for min and max values.
+             * @param vertexStart - Start offset to calculate min and max values.
+             * @param vertexCount - Number of vertices to check for min and max values.
+             * @param stride - Offset between consecutive attributes.
+             * @param useRightHandedSystem - Indicates whether the data should be modified for a right or left handed coordinate system.
+             * @returns - min number array and max number array.
              */
-            _Exporter.prototype.calculateMinMax = function (buff, vertexStart, vertexCount, arrayOffset, stride) {
+            _Exporter.prototype.calculateMinMax = function (buff, vertexStart, vertexCount, stride, useRightHandedSystem) {
                 var min = [Infinity, Infinity, Infinity];
                 var max = [-Infinity, -Infinity, -Infinity];
                 var end = vertexStart + vertexCount;
                 if (vertexCount > 0) {
                     for (var i = vertexStart; i < end; ++i) {
                         var index = stride * i;
+                        var scale = 1;
                         for (var j = 0; j < stride; ++j) {
-                            if (buff[index] < min[j]) {
-                                min[j] = buff[index];
+                            if (j === (stride - 1) && !useRightHandedSystem) {
+                                scale = -1;
                             }
-                            if (buff[index] > max[j]) {
-                                max[j] = buff[index];
+                            var num = scale * buff[index];
+                            if (num < min[j]) {
+                                min[j] = num;
+                            }
+                            if (num > max[j]) {
+                                max[j] = num;
                             }
                             ++index;
                         }
@@ -298,24 +312,24 @@ var BABYLON;
                 return { min: min, max: max };
             };
             /**
-             * Write mesh attribute data to buffer.
+             * Writes mesh attribute data to a data buffer.
              * Returns the bytelength of the data.
-             * @param vertexBufferType
-             * @param submesh
-             * @param meshAttributeArray
-             * @param strideSize
-             * @param byteOffset
-             * @param dataBuffer
-             * @param useRightHandedSystem
-             * @returns - byte length
+             * @param vertexBufferKind - Indicates what kind of vertex data is being passed in.
+             * @param meshAttributeArray - Array containing the attribute data.
+             * @param strideSize - Represents the offset between consecutive attributes
+             * @param byteOffset - The offset to start counting bytes from.
+             * @param dataBuffer - The buffer to write the binary data to.
+             * @param useRightHandedSystem - Indicates whether the data should be modified for a right or left handed coordinate system.
+             * @returns - Byte length of the attribute data.
              */
-            _Exporter.prototype.writeAttributeData = function (vertexBufferType, submesh, meshAttributeArray, strideSize, byteOffset, dataBuffer, useRightHandedSystem) {
+            _Exporter.prototype.writeAttributeData = function (vertexBufferKind, meshAttributeArray, strideSize, vertexBufferOffset, byteOffset, dataBuffer, useRightHandedSystem) {
                 var byteOff = byteOffset;
-                var end = submesh.verticesStart + submesh.verticesCount;
+                var start = 0;
+                var end = meshAttributeArray.length / strideSize;
                 var byteLength = 0;
-                switch (vertexBufferType) {
+                switch (vertexBufferKind) {
                     case BABYLON.VertexBuffer.PositionKind: {
-                        for (var k = submesh.verticesStart; k < end; ++k) {
+                        for (var k = start; k < end; ++k) {
                             var index = k * strideSize;
                             dataBuffer.setFloat32(byteOff, meshAttributeArray[index], true);
                             byteOff += 4;
@@ -329,11 +343,11 @@ var BABYLON;
                             }
                             byteOff += 4;
                         }
-                        byteLength = submesh.verticesCount * 12;
+                        byteLength = meshAttributeArray.length * 4;
                         break;
                     }
                     case BABYLON.VertexBuffer.NormalKind: {
-                        for (var k = submesh.verticesStart; k < end; ++k) {
+                        for (var k = start; k < end; ++k) {
                             var index = k * strideSize;
                             dataBuffer.setFloat32(byteOff, meshAttributeArray[index], true);
                             byteOff += 4;
@@ -347,11 +361,11 @@ var BABYLON;
                             }
                             byteOff += 4;
                         }
-                        byteLength = submesh.verticesCount * 12;
+                        byteLength = meshAttributeArray.length * 4;
                         break;
                     }
                     case BABYLON.VertexBuffer.TangentKind: {
-                        for (var k = submesh.indexStart; k < end; ++k) {
+                        for (var k = start; k < end; ++k) {
                             var index = k * strideSize;
                             dataBuffer.setFloat32(byteOff, meshAttributeArray[index], true);
                             byteOff += 4;
@@ -367,11 +381,11 @@ var BABYLON;
                             dataBuffer.setFloat32(byteOff, meshAttributeArray[index + 3], true);
                             byteOff += 4;
                         }
-                        byteLength = submesh.verticesCount * 16;
+                        byteLength = meshAttributeArray.length * 4;
                         break;
                     }
                     case BABYLON.VertexBuffer.ColorKind: {
-                        for (var k = submesh.verticesStart; k < end; ++k) {
+                        for (var k = start; k < end; ++k) {
                             var index = k * strideSize;
                             dataBuffer.setFloat32(byteOff, meshAttributeArray[index], true);
                             byteOff += 4;
@@ -382,45 +396,45 @@ var BABYLON;
                             dataBuffer.setFloat32(byteOff, meshAttributeArray[index + 3], true);
                             byteOff += 4;
                         }
-                        byteLength = submesh.verticesCount * 16;
+                        byteLength = meshAttributeArray.length * 4;
                         break;
                     }
                     case BABYLON.VertexBuffer.UVKind: {
-                        for (var k = submesh.verticesStart; k < end; ++k) {
+                        for (var k = start; k < end; ++k) {
                             var index = k * strideSize;
                             dataBuffer.setFloat32(byteOff, meshAttributeArray[index], true);
                             byteOff += 4;
                             dataBuffer.setFloat32(byteOff, meshAttributeArray[index + 1], true);
                             byteOff += 4;
                         }
-                        byteLength = submesh.verticesCount * 8;
+                        byteLength = meshAttributeArray.length * 4;
                         break;
                     }
                     case BABYLON.VertexBuffer.UV2Kind: {
-                        for (var k = submesh.verticesStart; k < end; ++k) {
+                        for (var k = start; k < end; ++k) {
                             var index = k * strideSize;
                             dataBuffer.setFloat32(byteOff, meshAttributeArray[index], true);
                             byteOff += 4;
                             dataBuffer.setFloat32(byteOff, meshAttributeArray[index + 1], true);
                             byteOff += 4;
                         }
-                        byteLength = submesh.verticesCount * 8;
+                        byteLength = meshAttributeArray.length * 4;
                         break;
                     }
                     default: {
-                        throw new Error("Unsupported vertex buffer type: " + vertexBufferType);
+                        throw new Error("Unsupported vertex buffer type: " + vertexBufferKind);
                     }
                 }
                 return byteLength;
             };
             /**
              * Generates glTF json data
-             * @param glb
-             * @param glTFPrefix
-             * @param prettyPrint
+             * @param shouldUseGlb - Indicates whether the json should be written for a glb file.
+             * @param glTFPrefix - Text to use when prefixing a glTF file.
+             * @param prettyPrint - Indicates whether the json file should be pretty printed (true) or not (false).
              * @returns - json data as string
              */
-            _Exporter.prototype.generateJSON = function (glb, glTFPrefix, prettyPrint) {
+            _Exporter.prototype.generateJSON = function (shouldUseGlb, glTFPrefix, prettyPrint) {
                 var buffer = { byteLength: this.totalByteLength };
                 var glTF = {
                     asset: this.asset
@@ -451,7 +465,7 @@ var BABYLON;
                     glTF.textures = this.textures;
                 }
                 if (this.images && this.images.length !== 0) {
-                    if (!glb) {
+                    if (!shouldUseGlb) {
                         glTF.images = this.images;
                     }
                     else {
@@ -464,7 +478,7 @@ var BABYLON;
                             if (image.uri !== undefined) {
                                 var imageData = this.imageData[image.uri];
                                 var imageName = image.uri.split('.')[0] + " image";
-                                var bufferView = this.createBufferView(0, byteOffset, imageData.data.length, imageName);
+                                var bufferView = this.createBufferView(0, byteOffset, imageData.data.length, undefined, imageName);
                                 byteOffset += imageData.data.buffer.byteLength;
                                 this.bufferViews.push(bufferView);
                                 image.bufferView = this.bufferViews.length - 1;
@@ -477,7 +491,7 @@ var BABYLON;
                         buffer.byteLength = byteOffset;
                     }
                 }
-                if (!glb) {
+                if (!shouldUseGlb) {
                     buffer.uri = glTFPrefix + ".bin";
                 }
                 var jsonText = prettyPrint ? JSON.stringify(glTF, null, 2) : JSON.stringify(glTF);
@@ -485,9 +499,8 @@ var BABYLON;
             };
             /**
              * Generates data for .gltf and .bin files based on the glTF prefix string
-             * @param glTFPrefix
-             * @returns - object with glTF json tex filename
-             * and binary file name as keys and their data as values
+             * @param glTFPrefix - Text to use when prefixing a glTF file.
+             * @returns - GLTFData with glTF file data.
              */
             _Exporter.prototype._generateGLTF = function (glTFPrefix) {
                 var jsonText = this.generateJSON(false, glTFPrefix, true);
@@ -517,7 +530,7 @@ var BABYLON;
                 return binaryBuffer;
             };
             /**
-             * Pads the number to a power of 4
+             * Pads the number to a multiple of 4
              * @param num - number to pad
              * @returns - padded number
              */
@@ -529,8 +542,6 @@ var BABYLON;
             /**
              * Generates a glb file from the json and binary data.
              * Returns an object with the glb file name as the key and data as the value.
-             * @param jsonText
-             * @param binaryBuffer
              * @param glTFPrefix
              * @returns - object with glb filename as key and data as value
              */
@@ -547,7 +558,8 @@ var BABYLON;
                 }
                 var jsonPadding = this._getPadding(jsonLength);
                 var binPadding = this._getPadding(binaryBuffer.byteLength);
-                var byteLength = headerLength + (2 * chunkLengthPrefix) + jsonLength + jsonPadding + binaryBuffer.byteLength + binPadding + imageByteLength;
+                var imagePadding = this._getPadding(imageByteLength);
+                var byteLength = headerLength + (2 * chunkLengthPrefix) + jsonLength + jsonPadding + binaryBuffer.byteLength + binPadding + imageByteLength + imagePadding;
                 //header
                 var headerBuffer = new ArrayBuffer(headerLength);
                 var headerBufferView = new DataView(headerBuffer);
@@ -572,7 +584,7 @@ var BABYLON;
                 //binary chunk
                 var binaryChunkBuffer = new ArrayBuffer(chunkLengthPrefix);
                 var binaryChunkBufferView = new DataView(binaryChunkBuffer);
-                binaryChunkBufferView.setUint32(0, binaryBuffer.byteLength + imageByteLength, true);
+                binaryChunkBufferView.setUint32(0, binaryBuffer.byteLength + imageByteLength + imagePadding, true);
                 binaryChunkBufferView.setUint32(4, 0x004E4942, true);
                 // binary padding
                 var binPaddingBuffer = new ArrayBuffer(binPadding);
@@ -580,12 +592,18 @@ var BABYLON;
                 for (var i = 0; i < binPadding; ++i) {
                     binPaddingView[i] = 0;
                 }
+                var imagePaddingBuffer = new ArrayBuffer(imagePadding);
+                var imagePaddingView = new Uint8Array(imagePaddingBuffer);
+                for (var i = 0; i < imagePadding; ++i) {
+                    imagePaddingView[i] = 0;
+                }
                 var glbData = [headerBuffer, jsonChunkBuffer, binaryChunkBuffer, binaryBuffer];
                 // binary data
                 for (var key in this.imageData) {
                     glbData.push(this.imageData[key].data.buffer);
                 }
                 glbData.push(binPaddingBuffer);
+                glbData.push(imagePaddingBuffer);
                 var glbFile = new Blob(glbData, { type: 'application/octet-stream' });
                 var container = new BABYLON._GLTFData();
                 container.glTFFiles[glbFileName] = glbFile;
@@ -593,9 +611,9 @@ var BABYLON;
             };
             /**
              * Sets the TRS for each node
-             * @param node
-             * @param babylonMesh
-             * @param useRightHandedSystem
+             * @param node - glTF Node for storing the transformation data.
+             * @param babylonMesh - Babylon mesh used as the source for the transformation data.
+             * @param useRightHandedSystem - Indicates whether the data should be modified for a right or left handed coordinate system.
              */
             _Exporter.prototype.setNodeTransformation = function (node, babylonMesh, useRightHandedSystem) {
                 if (!(babylonMesh.position.x === 0 && babylonMesh.position.y === 0 && babylonMesh.position.z === 0)) {
@@ -629,8 +647,9 @@ var BABYLON;
             };
             /**
              *
-             * @param babylonTexture
-             * @return - glTF texture, or null if the texture format is not supported
+             * @param babylonTexture - Babylon texture to extract.
+             * @param mimeType - Mime Type of the babylonTexture.
+             * @return - glTF texture, or null if the texture format is not supported.
              */
             _Exporter.prototype.exportTexture = function (babylonTexture, mimeType) {
                 if (mimeType === void 0) { mimeType = "image/jpeg" /* JPEG */; }
@@ -705,289 +724,352 @@ var BABYLON;
                 return textureInfo;
             };
             /**
-             * Sets data for the primitive attributes of each submesh
-             * @param mesh
-             * @param babylonMesh
-             * @param byteOffset
-             * @param useRightHandedSystem
-             * @param dataBuffer
-             * @returns - bytelength of the primitive attributes plus the passed in byteOffset
+             * Creates a bufferview based on the vertices type for the Babylon mesh
+             * @param kind - Indicates the type of vertices data.
+             * @param babylonMesh - The Babylon mesh to get the vertices data from.
+             * @param byteOffset - The offset from the buffer to start indexing from.
+             * @param useRightHandedSystem - Indicates whether the data should be modified for a right or left handed coordinate system.
+             * @param dataBuffer - The buffer to write the bufferview data to.
+             * @returns bytelength of the bufferview data.
              */
-            _Exporter.prototype.setPrimitiveAttributes = function (mesh, babylonMesh, byteOffset, useRightHandedSystem, dataBuffer) {
-                // go through all mesh primitives (submeshes)
-                for (var j = 0; j < babylonMesh.subMeshes.length; ++j) {
-                    var bufferMesh = null;
-                    var submesh = babylonMesh.subMeshes[j];
-                    var meshPrimitive = { attributes: {} };
-                    if (babylonMesh instanceof BABYLON.Mesh) {
-                        bufferMesh = babylonMesh;
-                    }
-                    else if (babylonMesh instanceof BABYLON.InstancedMesh) {
-                        bufferMesh = babylonMesh.sourceMesh;
-                    }
-                    // Loop through each attribute of the submesh (mesh primitive)
-                    if (bufferMesh.isVerticesDataPresent(BABYLON.VertexBuffer.PositionKind)) {
-                        var positionVertexBuffer = bufferMesh.getVertexBuffer(BABYLON.VertexBuffer.PositionKind);
-                        var positionVertexBufferOffset = positionVertexBuffer.getOffset();
-                        var positions = positionVertexBuffer.getData();
-                        var positionStrideSize = positionVertexBuffer.getStrideSize();
-                        if (dataBuffer) {
-                            byteOffset += this.writeAttributeData(BABYLON.VertexBuffer.PositionKind, submesh, positions, positionStrideSize, byteOffset, dataBuffer, useRightHandedSystem);
-                        }
-                        else {
-                            // Create bufferview
-                            var byteLength = submesh.verticesCount * 12;
-                            var bufferview = this.createBufferView(0, byteOffset, byteLength, "Positions");
+            _Exporter.prototype.createBufferViewKind = function (kind, babylonMesh, byteOffset, useRightHandedSystem, dataBuffer) {
+                var bufferMesh = null;
+                var byteLength = 0;
+                if (babylonMesh instanceof BABYLON.Mesh) {
+                    bufferMesh = babylonMesh;
+                }
+                else if (babylonMesh instanceof BABYLON.InstancedMesh) {
+                    bufferMesh = babylonMesh.sourceMesh;
+                }
+                if (bufferMesh !== null) {
+                    var vertexBuffer = null;
+                    var vertexBufferOffset = null;
+                    var vertexData = null;
+                    var vertexStrideSize = null;
+                    if (bufferMesh.getVerticesDataKinds().indexOf(kind) > -1) {
+                        vertexBuffer = bufferMesh.getVertexBuffer(kind);
+                        vertexBufferOffset = vertexBuffer.getOffset();
+                        vertexData = vertexBuffer.getData();
+                        vertexStrideSize = vertexBuffer.getStrideSize();
+                        if (dataBuffer && vertexData) {
+                            byteLength = this.writeAttributeData(kind, vertexData, vertexStrideSize, vertexBufferOffset, byteOffset, dataBuffer, useRightHandedSystem);
                             byteOffset += byteLength;
-                            this.bufferViews.push(bufferview);
-                            // Create accessor
-                            var result = this.calculateMinMax(positions, submesh.verticesStart, submesh.verticesCount, positionVertexBufferOffset, positionStrideSize);
-                            var accessor = this.createAccessor(this.bufferViews.length - 1, "Position", "VEC3" /* VEC3 */, 5126 /* FLOAT */, submesh.verticesCount, result.min, result.max);
-                            this.accessors.push(accessor);
-                            meshPrimitive.attributes.POSITION = this.accessors.length - 1;
-                        }
-                    }
-                    if (bufferMesh.isVerticesDataPresent(BABYLON.VertexBuffer.NormalKind)) {
-                        var normalVertexBuffer = bufferMesh.getVertexBuffer(BABYLON.VertexBuffer.NormalKind);
-                        var normals = normalVertexBuffer.getData();
-                        var normalStrideSize = normalVertexBuffer.getStrideSize();
-                        if (dataBuffer) {
-                            byteOffset += this.writeAttributeData(BABYLON.VertexBuffer.NormalKind, submesh, normals, normalStrideSize, byteOffset, dataBuffer, useRightHandedSystem);
                         }
                         else {
-                            // Create bufferview
-                            var byteLength = submesh.verticesCount * 12;
-                            var bufferview = this.createBufferView(0, byteOffset, byteLength, "Normals");
-                            byteOffset += byteLength;
-                            this.bufferViews.push(bufferview);
-                            // Create accessor
-                            var accessor = this.createAccessor(this.bufferViews.length - 1, "Normal", "VEC3" /* VEC3 */, 5126 /* FLOAT */, submesh.verticesCount);
-                            this.accessors.push(accessor);
-                            meshPrimitive.attributes.NORMAL = this.accessors.length - 1;
+                            var bufferViewName = null;
+                            switch (kind) {
+                                case BABYLON.VertexBuffer.PositionKind: {
+                                    byteLength = vertexData.length * 4;
+                                    bufferViewName = "Position - " + bufferMesh.name;
+                                    break;
+                                }
+                                case BABYLON.VertexBuffer.NormalKind: {
+                                    byteLength = vertexData.length * 4;
+                                    bufferViewName = "Normal - " + bufferMesh.name;
+                                    break;
+                                }
+                                case BABYLON.VertexBuffer.TangentKind: {
+                                    byteLength = vertexData.length * 4;
+                                    bufferViewName = "Tangent - " + bufferMesh.name;
+                                    break;
+                                }
+                                case BABYLON.VertexBuffer.ColorKind: {
+                                    byteLength = vertexData.length * 4;
+                                    bufferViewName = "Color - " + bufferMesh.name;
+                                    break;
+                                }
+                                case BABYLON.VertexBuffer.UVKind: {
+                                    byteLength = vertexData.length * 4;
+                                    bufferViewName = "TexCoord 0 - " + bufferMesh.name;
+                                    break;
+                                }
+                                case BABYLON.VertexBuffer.UV2Kind: {
+                                    byteLength = vertexData.length * 4;
+                                    bufferViewName = "TexCoord 1 - " + bufferMesh.name;
+                                    break;
+                                }
+                                default: {
+                                    console.warn("Unsupported VertexBuffer kind: " + kind);
+                                }
+                            }
+                            if (bufferViewName !== null) {
+                                var bufferView = this.createBufferView(0, byteOffset, byteLength, vertexStrideSize * 4, bufferViewName);
+                                byteOffset += byteLength;
+                                this.bufferViews.push(bufferView);
+                            }
                         }
                     }
-                    if (bufferMesh.isVerticesDataPresent(BABYLON.VertexBuffer.TangentKind)) {
-                        var tangentVertexBuffer = bufferMesh.getVertexBuffer(BABYLON.VertexBuffer.TangentKind);
-                        var tangents = tangentVertexBuffer.getData();
-                        var tangentStrideSize = tangentVertexBuffer.getStrideSize();
-                        if (dataBuffer) {
-                            byteOffset += this.writeAttributeData(BABYLON.VertexBuffer.TangentKind, submesh, tangents, tangentStrideSize, byteOffset, dataBuffer, useRightHandedSystem);
-                        }
-                        else {
-                            // Create bufferview
-                            var byteLength = submesh.verticesCount * 16;
-                            var bufferview = this.createBufferView(0, byteOffset, byteLength, "Tangents");
-                            byteOffset += byteLength;
-                            this.bufferViews.push(bufferview);
-                            // Create accessor
-                            var accessor = this.createAccessor(this.bufferViews.length - 1, "Tangent", "VEC4" /* VEC4 */, 5126 /* FLOAT */, submesh.verticesCount);
-                            this.accessors.push(accessor);
-                            meshPrimitive.attributes.TANGENT = this.accessors.length - 1;
-                        }
+                }
+                return byteLength;
+            };
+            /**
+             * Sets data for the primitive attributes of each submesh
+             * @param mesh - glTF Mesh object to store the primitive attribute information.
+             * @param babylonMesh - Babylon mesh to get the primitive attribute data from.
+             * @param byteOffset - The offset in bytes of the buffer data.
+             * @param useRightHandedSystem - Indicates whether the data should be modified for a right or left handed coordinate system.
+             * @param dataBuffer - Buffer to write the attribute data to.
+             * @returns - bytelength of the primitive attributes plus the passed in byteOffset.
+             */
+            _Exporter.prototype.setPrimitiveAttributes = function (mesh, babylonMesh, byteOffset, useRightHandedSystem, dataBuffer) {
+                var bufferMesh = null;
+                if (babylonMesh instanceof BABYLON.Mesh) {
+                    bufferMesh = babylonMesh;
+                }
+                else if (babylonMesh instanceof BABYLON.InstancedMesh) {
+                    bufferMesh = babylonMesh.sourceMesh;
+                }
+                var positionBufferViewIndex = null;
+                var normalBufferViewIndex = null;
+                var colorBufferViewIndex = null;
+                var tangentBufferViewIndex = null;
+                var texCoord0BufferViewIndex = null;
+                var texCoord1BufferViewIndex = null;
+                var indexBufferViewIndex = null;
+                if (bufferMesh !== null) {
+                    // For each BabylonMesh, create bufferviews for each 'kind'
+                    if (bufferMesh.isVerticesDataPresent(BABYLON.VertexBuffer.PositionKind)) {
+                        byteOffset += this.createBufferViewKind(BABYLON.VertexBuffer.PositionKind, babylonMesh, byteOffset, useRightHandedSystem, dataBuffer);
+                        positionBufferViewIndex = this.bufferViews.length - 1;
+                    }
+                    if (bufferMesh.isVerticesDataPresent(BABYLON.VertexBuffer.NormalKind)) {
+                        byteOffset += this.createBufferViewKind(BABYLON.VertexBuffer.NormalKind, babylonMesh, byteOffset, useRightHandedSystem, dataBuffer);
+                        normalBufferViewIndex = this.bufferViews.length - 1;
                     }
                     if (bufferMesh.isVerticesDataPresent(BABYLON.VertexBuffer.ColorKind)) {
-                        var colorVertexBuffer = bufferMesh.getVertexBuffer(BABYLON.VertexBuffer.ColorKind);
-                        var colors = colorVertexBuffer.getData();
-                        var colorStrideSize = colorVertexBuffer.getStrideSize();
-                        if (dataBuffer) {
-                            byteOffset += this.writeAttributeData(BABYLON.VertexBuffer.ColorKind, submesh, colors, colorStrideSize, byteOffset, dataBuffer, useRightHandedSystem);
-                        }
-                        else {
-                            // Create bufferview
-                            var byteLength = submesh.verticesCount * 16;
-                            var bufferview = this.createBufferView(0, byteOffset, byteLength, "Colors");
-                            byteOffset += byteLength;
-                            this.bufferViews.push(bufferview);
-                            // Create accessor
-                            var accessor = this.createAccessor(this.bufferViews.length - 1, "Color", "VEC4" /* VEC4 */, 5126 /* FLOAT */, submesh.verticesCount);
-                            this.accessors.push(accessor);
-                            meshPrimitive.attributes.COLOR_0 = this.accessors.length - 1;
-                        }
+                        byteOffset += this.createBufferViewKind(BABYLON.VertexBuffer.ColorKind, babylonMesh, byteOffset, useRightHandedSystem, dataBuffer);
+                        colorBufferViewIndex = this.bufferViews.length - 1;
+                    }
+                    if (bufferMesh.isVerticesDataPresent(BABYLON.VertexBuffer.TangentKind)) {
+                        byteOffset += this.createBufferViewKind(BABYLON.VertexBuffer.TangentKind, babylonMesh, byteOffset, useRightHandedSystem, dataBuffer);
+                        colorBufferViewIndex = this.bufferViews.length - 1;
                     }
                     if (bufferMesh.isVerticesDataPresent(BABYLON.VertexBuffer.UVKind)) {
-                        var texCoord0VertexBuffer = bufferMesh.getVertexBuffer(BABYLON.VertexBuffer.UVKind);
-                        var texCoords0 = texCoord0VertexBuffer.getData();
-                        var texCoord0StrideSize = texCoord0VertexBuffer.getStrideSize();
-                        if (dataBuffer) {
-                            byteOffset += this.writeAttributeData(BABYLON.VertexBuffer.UVKind, submesh, texCoords0, texCoord0StrideSize, byteOffset, dataBuffer, useRightHandedSystem);
-                        }
-                        else {
-                            // Create bufferview
-                            var byteLength = submesh.verticesCount * 8;
-                            var bufferview = this.createBufferView(0, byteOffset, byteLength, "Texture Coords0");
-                            byteOffset += byteLength;
-                            this.bufferViews.push(bufferview);
-                            // Create accessor
-                            var accessor = this.createAccessor(this.bufferViews.length - 1, "Texture Coords", "VEC2" /* VEC2 */, 5126 /* FLOAT */, submesh.verticesCount);
-                            this.accessors.push(accessor);
-                            meshPrimitive.attributes.TEXCOORD_0 = this.accessors.length - 1;
-                        }
+                        byteOffset += this.createBufferViewKind(BABYLON.VertexBuffer.UVKind, babylonMesh, byteOffset, useRightHandedSystem, dataBuffer);
+                        texCoord0BufferViewIndex = this.bufferViews.length - 1;
                     }
                     if (bufferMesh.isVerticesDataPresent(BABYLON.VertexBuffer.UV2Kind)) {
-                        var texCoord1VertexBuffer = bufferMesh.getVertexBuffer(BABYLON.VertexBuffer.UV2Kind);
-                        var texCoords1 = texCoord1VertexBuffer.getData();
-                        var texCoord1StrideSize = texCoord1VertexBuffer.getStrideSize();
-                        if (dataBuffer) {
-                            byteOffset += this.writeAttributeData(BABYLON.VertexBuffer.UV2Kind, submesh, texCoords1, texCoord1StrideSize, byteOffset, dataBuffer, useRightHandedSystem);
-                        }
-                        else {
-                            // Create bufferview
-                            var byteLength = submesh.verticesCount * 8;
-                            var bufferview = this.createBufferView(0, byteOffset, byteLength, "Texture Coords 1");
-                            byteOffset += byteLength;
-                            this.bufferViews.push(bufferview);
-                            // Create accessor
-                            var accessor = this.createAccessor(this.bufferViews.length - 1, "Texture Coords", "VEC2" /* VEC2 */, 5126 /* FLOAT */, submesh.verticesCount);
-                            this.accessors.push(accessor);
-                            meshPrimitive.attributes.TEXCOORD_1 = this.accessors.length - 1;
-                        }
+                        byteOffset += this.createBufferViewKind(BABYLON.VertexBuffer.UV2Kind, babylonMesh, byteOffset, useRightHandedSystem, dataBuffer);
+                        texCoord1BufferViewIndex = this.bufferViews.length - 1;
                     }
                     if (bufferMesh.getTotalIndices() > 0) {
+                        var indices = bufferMesh.getIndices();
                         if (dataBuffer) {
-                            var indices = bufferMesh.getIndices();
-                            var start = submesh.indexStart;
-                            var end = submesh.indexCount + start;
+                            var end = indices.length;
                             var byteOff = byteOffset;
-                            for (var k = start; k < end; k = k + 3) {
+                            for (var k = 0; k < end; ++k) {
                                 dataBuffer.setUint32(byteOff, indices[k], true);
                                 byteOff += 4;
-                                dataBuffer.setUint32(byteOff, indices[k + 1], true);
-                                byteOff += 4;
-                                dataBuffer.setUint32(byteOff, indices[k + 2], true);
-                                byteOff += 4;
                             }
-                            var byteLength = submesh.indexCount * 4;
-                            byteOffset += byteLength;
+                            byteOffset = byteOff;
                         }
                         else {
-                            // Create bufferview
-                            var indicesCount = submesh.indexCount;
-                            var byteLength = indicesCount * 4;
-                            var bufferview = this.createBufferView(0, byteOffset, byteLength, "Indices");
+                            var byteLength = indices.length * 4;
+                            var bufferView = this.createBufferView(0, byteOffset, byteLength, undefined, "Indices - " + bufferMesh.name);
                             byteOffset += byteLength;
-                            this.bufferViews.push(bufferview);
-                            // Create accessor
-                            var accessor = this.createAccessor(this.bufferViews.length - 1, "Indices", "SCALAR" /* SCALAR */, 5125 /* UNSIGNED_INT */, indicesCount);
-                            this.accessors.push(accessor);
-                            meshPrimitive.indices = this.accessors.length - 1;
+                            this.bufferViews.push(bufferView);
+                            indexBufferViewIndex = this.bufferViews.length - 1;
                         }
                     }
-                    if (bufferMesh.material) {
-                        if (bufferMesh.material instanceof BABYLON.StandardMaterial) {
-                            var babylonStandardMaterial = bufferMesh.material;
-                            var glTFMaterial = { name: babylonStandardMaterial.name };
-                            if (!babylonStandardMaterial.backFaceCulling) {
-                                glTFMaterial.doubleSided = true;
-                            }
-                            if (babylonStandardMaterial.bumpTexture) {
-                                var glTFTexture = this.exportTexture(babylonStandardMaterial.bumpTexture);
-                                if (glTFTexture) {
-                                    glTFMaterial.normalTexture = glTFTexture;
-                                }
-                            }
-                            if (babylonStandardMaterial.emissiveTexture) {
-                                var glTFEmissiveTexture = this.exportTexture(babylonStandardMaterial.emissiveTexture);
-                                if (glTFEmissiveTexture) {
-                                    glTFMaterial.emissiveTexture = glTFEmissiveTexture;
-                                }
-                                glTFMaterial.emissiveFactor = [1.0, 1.0, 1.0];
+                }
+                // go through all mesh primitives (submeshes)
+                for (var j = 0; j < babylonMesh.subMeshes.length; ++j) {
+                    var submesh = babylonMesh.subMeshes[j];
+                    var meshPrimitive = { attributes: {} };
+                    if (bufferMesh !== null) {
+                        // Create a bufferview storing all the positions
+                        if (!dataBuffer) {
+                            // Loop through each attribute of the submesh (mesh primitive)
+                            if (positionBufferViewIndex !== null) {
+                                var positionVertexBuffer = bufferMesh.getVertexBuffer(BABYLON.VertexBuffer.PositionKind);
+                                var positions = positionVertexBuffer.getData();
+                                var positionStrideSize = positionVertexBuffer.getStrideSize();
+                                // Create accessor
+                                var result = this.calculateMinMax(positions, 0, positions.length / positionStrideSize, positionStrideSize, useRightHandedSystem);
+                                var accessor = this.createAccessor(positionBufferViewIndex, "Position", "VEC3" /* VEC3 */, 5126 /* FLOAT */, positions.length / positionStrideSize, 0, result.min, result.max);
+                                this.accessors.push(accessor);
+                                meshPrimitive.attributes.POSITION = this.accessors.length - 1;
                             }
-                            if (babylonStandardMaterial.ambientTexture) {
-                                var glTFOcclusionTexture = this.exportTexture(babylonStandardMaterial.ambientTexture);
-                                if (glTFOcclusionTexture) {
-                                    glTFMaterial.occlusionTexture = glTFOcclusionTexture;
-                                }
+                            if (normalBufferViewIndex !== null) {
+                                var normalVertexBuffer = bufferMesh.getVertexBuffer(BABYLON.VertexBuffer.NormalKind);
+                                var normals = normalVertexBuffer.getData();
+                                var normalStrideSize = normalVertexBuffer.getStrideSize();
+                                // Create accessor
+                                var accessor = this.createAccessor(normalBufferViewIndex, "Normal", "VEC3" /* VEC3 */, 5126 /* FLOAT */, normals.length / normalStrideSize);
+                                this.accessors.push(accessor);
+                                meshPrimitive.attributes.NORMAL = this.accessors.length - 1;
                             }
-                            // Spec Gloss
-                            var glTFPbrMetallicRoughness = GLTF2._GLTFMaterial.ConvertToGLTFPBRMetallicRoughness(babylonStandardMaterial);
-                            glTFMaterial.pbrMetallicRoughness = glTFPbrMetallicRoughness;
-                            // TODO: Handle Textures
-                            this.materials.push(glTFMaterial);
-                            meshPrimitive.material = this.materials.length - 1;
-                        }
-                        else if (bufferMesh.material instanceof BABYLON.PBRMetallicRoughnessMaterial) {
-                            if (!this.textures) {
-                                this.textures = new Array();
+                            if (tangentBufferViewIndex !== null) {
+                                var tangentVertexBuffer = bufferMesh.getVertexBuffer(BABYLON.VertexBuffer.TangentKind);
+                                var tangents = tangentVertexBuffer.getData();
+                                var tangentStrideSize = tangentVertexBuffer.getStrideSize();
+                                // Create accessor
+                                var accessor = this.createAccessor(tangentBufferViewIndex, "Tangent", "VEC4" /* VEC4 */, 5126 /* FLOAT */, tangents.length / tangentStrideSize);
+                                this.accessors.push(accessor);
+                                meshPrimitive.attributes.TANGENT = this.accessors.length - 1;
                             }
-                            var babylonPBRMaterial = bufferMesh.material;
-                            var glTFPbrMetallicRoughness = {};
-                            if (babylonPBRMaterial.baseColor) {
-                                glTFPbrMetallicRoughness.baseColorFactor = [
-                                    babylonPBRMaterial.baseColor.r,
-                                    babylonPBRMaterial.baseColor.g,
-                                    babylonPBRMaterial.baseColor.b,
-                                    babylonPBRMaterial.alpha
-                                ];
+                            if (colorBufferViewIndex !== null) {
+                                var colorVertexBuffer = bufferMesh.getVertexBuffer(BABYLON.VertexBuffer.ColorKind);
+                                var colors = colorVertexBuffer.getData();
+                                var colorStrideSize = colorVertexBuffer.getStrideSize();
+                                // Create accessor
+                                var accessor = this.createAccessor(colorBufferViewIndex, "Color", "VEC4" /* VEC4 */, 5126 /* FLOAT */, colors.length / colorStrideSize);
+                                this.accessors.push(accessor);
+                                meshPrimitive.attributes.COLOR_0 = this.accessors.length - 1;
                             }
-                            if (babylonPBRMaterial.baseTexture !== undefined) {
-                                var glTFTexture = this.exportTexture(babylonPBRMaterial.baseTexture);
-                                if (glTFTexture !== null) {
-                                    glTFPbrMetallicRoughness.baseColorTexture = glTFTexture;
-                                }
-                                glTFPbrMetallicRoughness.baseColorTexture;
+                            if (texCoord0BufferViewIndex !== null) {
+                                // Create accessor
+                                var texCoord0VertexBuffer = bufferMesh.getVertexBuffer(BABYLON.VertexBuffer.UVKind);
+                                var texCoord0s = texCoord0VertexBuffer.getData();
+                                var texCoord0StrideSize = texCoord0VertexBuffer.getStrideSize();
+                                var accessor = this.createAccessor(texCoord0BufferViewIndex, "Texture Coords 0", "VEC2" /* VEC2 */, 5126 /* FLOAT */, texCoord0s.length / texCoord0StrideSize);
+                                this.accessors.push(accessor);
+                                meshPrimitive.attributes.TEXCOORD_0 = this.accessors.length - 1;
                             }
-                            if (babylonPBRMaterial.metallic !== undefined) {
-                                glTFPbrMetallicRoughness.metallicFactor = babylonPBRMaterial.metallic;
+                            if (texCoord1BufferViewIndex !== null) {
+                                // Create accessor
+                                var texCoord1VertexBuffer = bufferMesh.getVertexBuffer(BABYLON.VertexBuffer.UV2Kind);
+                                var texCoord1s = texCoord1VertexBuffer.getData();
+                                var texCoord1StrideSize = texCoord1VertexBuffer.getStrideSize();
+                                var accessor = this.createAccessor(texCoord1BufferViewIndex, "Texture Coords 1", "VEC2" /* VEC2 */, 5126 /* FLOAT */, texCoord1s.length / texCoord1StrideSize);
+                                this.accessors.push(accessor);
+                                meshPrimitive.attributes.TEXCOORD_1 = this.accessors.length - 1;
                             }
-                            if (babylonPBRMaterial.roughness !== undefined) {
-                                glTFPbrMetallicRoughness.roughnessFactor = babylonPBRMaterial.roughness;
+                            if (indexBufferViewIndex) {
+                                // Create accessor
+                                var accessor = this.createAccessor(indexBufferViewIndex, "Indices", "SCALAR" /* SCALAR */, 5125 /* UNSIGNED_INT */, submesh.indexCount, submesh.indexStart * 4);
+                                this.accessors.push(accessor);
+                                meshPrimitive.indices = this.accessors.length - 1;
                             }
-                            var glTFMaterial = {
-                                name: babylonPBRMaterial.name
-                            };
-                            if (babylonPBRMaterial.doubleSided) {
-                                glTFMaterial.doubleSided = babylonPBRMaterial.doubleSided;
-                            }
-                            if (babylonPBRMaterial.normalTexture) {
-                                var glTFTexture = this.exportTexture(babylonPBRMaterial.normalTexture);
-                                if (glTFTexture) {
-                                    glTFMaterial.normalTexture = glTFTexture;
+                        }
+                        if (bufferMesh.material) {
+                            if (bufferMesh.material instanceof BABYLON.StandardMaterial) {
+                                console.warn("Standard Material is currently not fully supported/implemented in glTF serializer");
+                                var babylonStandardMaterial = bufferMesh.material;
+                                var glTFPbrMetallicRoughness = GLTF2._GLTFMaterial.ConvertToGLTFPBRMetallicRoughness(babylonStandardMaterial);
+                                var glTFMaterial = { name: babylonStandardMaterial.name };
+                                if (!babylonStandardMaterial.backFaceCulling) {
+                                    glTFMaterial.doubleSided = true;
                                 }
-                            }
-                            if (babylonPBRMaterial.occlusionTexture) {
-                                var glTFTexture = this.exportTexture(babylonPBRMaterial.occlusionTexture);
-                                if (glTFTexture) {
-                                    glTFMaterial.occlusionTexture = glTFTexture;
-                                    if (babylonPBRMaterial.occlusionStrength !== undefined) {
-                                        glTFMaterial.occlusionTexture.strength = babylonPBRMaterial.occlusionStrength;
+                                if (babylonStandardMaterial.diffuseTexture && bufferMesh.isVerticesDataPresent(BABYLON.VertexBuffer.UVKind)) {
+                                    var glTFTexture = this.exportTexture(babylonStandardMaterial.diffuseTexture);
+                                    if (glTFTexture !== null) {
+                                        glTFPbrMetallicRoughness.baseColorTexture = glTFTexture;
                                     }
                                 }
-                            }
-                            if (babylonPBRMaterial.emissiveTexture) {
-                                var glTFTexture = this.exportTexture(babylonPBRMaterial.emissiveTexture);
-                                if (glTFTexture !== null) {
-                                    glTFMaterial.emissiveTexture = glTFTexture;
+                                if (babylonStandardMaterial.bumpTexture && bufferMesh.isVerticesDataPresent(BABYLON.VertexBuffer.UVKind)) {
+                                    var glTFTexture = this.exportTexture(babylonStandardMaterial.bumpTexture);
+                                    if (glTFTexture) {
+                                        glTFMaterial.normalTexture = glTFTexture;
+                                    }
                                 }
+                                if (babylonStandardMaterial.emissiveTexture && bufferMesh.isVerticesDataPresent(BABYLON.VertexBuffer.UVKind)) {
+                                    var glTFEmissiveTexture = this.exportTexture(babylonStandardMaterial.emissiveTexture);
+                                    if (glTFEmissiveTexture) {
+                                        glTFMaterial.emissiveTexture = glTFEmissiveTexture;
+                                    }
+                                    glTFMaterial.emissiveFactor = [1.0, 1.0, 1.0];
+                                }
+                                if (babylonStandardMaterial.ambientTexture && bufferMesh.isVerticesDataPresent(BABYLON.VertexBuffer.UVKind)) {
+                                    var glTFOcclusionTexture = this.exportTexture(babylonStandardMaterial.ambientTexture);
+                                    if (glTFOcclusionTexture) {
+                                        glTFMaterial.occlusionTexture = glTFOcclusionTexture;
+                                    }
+                                }
+                                if (babylonStandardMaterial.alpha < 1.0 || babylonStandardMaterial.opacityTexture) {
+                                    if (babylonStandardMaterial.alphaMode === BABYLON.Engine.ALPHA_COMBINE) {
+                                        glTFMaterial.alphaMode = "BLEND" /* BLEND */;
+                                    }
+                                    else {
+                                        console.warn("glTF 2.0 does not support alpha mode: " + babylonStandardMaterial.alphaMode.toString());
+                                    }
+                                }
+                                glTFMaterial.pbrMetallicRoughness = glTFPbrMetallicRoughness;
+                                this.materials.push(glTFMaterial);
+                                meshPrimitive.material = this.materials.length - 1;
                             }
-                            if (!babylonPBRMaterial.emissiveColor.equals(new BABYLON.Color3(0.0, 0.0, 0.0))) {
-                                glTFMaterial.emissiveFactor = babylonPBRMaterial.emissiveColor.asArray();
-                            }
-                            if (babylonPBRMaterial.transparencyMode) {
-                                var alphaMode = GLTF2._GLTFMaterial.GetAlphaMode(babylonPBRMaterial);
-                                if (alphaMode !== "OPAQUE" /* OPAQUE */) {
-                                    glTFMaterial.alphaMode = alphaMode;
-                                    if (alphaMode === "BLEND" /* BLEND */) {
-                                        glTFMaterial.alphaCutoff = babylonPBRMaterial.alphaCutOff;
+                            else if (bufferMesh.material instanceof BABYLON.PBRMetallicRoughnessMaterial) {
+                                var babylonPBRMaterial = bufferMesh.material;
+                                var glTFPbrMetallicRoughness = {};
+                                if (babylonPBRMaterial.baseColor) {
+                                    glTFPbrMetallicRoughness.baseColorFactor = [
+                                        babylonPBRMaterial.baseColor.r,
+                                        babylonPBRMaterial.baseColor.g,
+                                        babylonPBRMaterial.baseColor.b,
+                                        babylonPBRMaterial.alpha
+                                    ];
+                                }
+                                if (babylonPBRMaterial.baseTexture !== undefined) {
+                                    var glTFTexture = this.exportTexture(babylonPBRMaterial.baseTexture);
+                                    if (glTFTexture !== null) {
+                                        glTFPbrMetallicRoughness.baseColorTexture = glTFTexture;
                                     }
+                                    glTFPbrMetallicRoughness.baseColorTexture;
                                 }
+                                if (babylonPBRMaterial.metallic !== undefined) {
+                                    glTFPbrMetallicRoughness.metallicFactor = babylonPBRMaterial.metallic;
+                                }
+                                if (babylonPBRMaterial.roughness !== undefined) {
+                                    glTFPbrMetallicRoughness.roughnessFactor = babylonPBRMaterial.roughness;
+                                }
+                                var glTFMaterial = {
+                                    name: babylonPBRMaterial.name
+                                };
+                                if (babylonPBRMaterial.doubleSided) {
+                                    glTFMaterial.doubleSided = babylonPBRMaterial.doubleSided;
+                                }
+                                if (babylonPBRMaterial.normalTexture) {
+                                    var glTFTexture = this.exportTexture(babylonPBRMaterial.normalTexture);
+                                    if (glTFTexture) {
+                                        glTFMaterial.normalTexture = glTFTexture;
+                                    }
+                                }
+                                if (babylonPBRMaterial.occlusionTexture) {
+                                    var glTFTexture = this.exportTexture(babylonPBRMaterial.occlusionTexture);
+                                    if (glTFTexture) {
+                                        glTFMaterial.occlusionTexture = glTFTexture;
+                                        if (babylonPBRMaterial.occlusionStrength !== undefined) {
+                                            glTFMaterial.occlusionTexture.strength = babylonPBRMaterial.occlusionStrength;
+                                        }
+                                    }
+                                }
+                                if (babylonPBRMaterial.emissiveTexture) {
+                                    var glTFTexture = this.exportTexture(babylonPBRMaterial.emissiveTexture);
+                                    if (glTFTexture !== null) {
+                                        glTFMaterial.emissiveTexture = glTFTexture;
+                                    }
+                                }
+                                if (!babylonPBRMaterial.emissiveColor.equals(new BABYLON.Color3(0.0, 0.0, 0.0))) {
+                                    glTFMaterial.emissiveFactor = babylonPBRMaterial.emissiveColor.asArray();
+                                }
+                                if (babylonPBRMaterial.transparencyMode) {
+                                    var alphaMode = GLTF2._GLTFMaterial.GetAlphaMode(babylonPBRMaterial);
+                                    if (alphaMode !== "OPAQUE" /* OPAQUE */) {
+                                        glTFMaterial.alphaMode = alphaMode;
+                                        if (alphaMode === "BLEND" /* BLEND */) {
+                                            glTFMaterial.alphaCutoff = babylonPBRMaterial.alphaCutOff;
+                                        }
+                                    }
+                                }
+                                glTFMaterial.pbrMetallicRoughness = glTFPbrMetallicRoughness;
+                                this.materials.push(glTFMaterial);
+                                meshPrimitive.material = this.materials.length - 1;
+                            }
+                            else {
+                                console.warn("Material type is not yet implemented in glTF serializer: " + bufferMesh.material.name);
                             }
-                            glTFMaterial.pbrMetallicRoughness = glTFPbrMetallicRoughness;
-                            // TODO: Handle Textures
-                            this.materials.push(glTFMaterial);
-                            meshPrimitive.material = this.materials.length - 1;
                         }
+                        mesh.primitives.push(meshPrimitive);
                     }
-                    mesh.primitives.push(meshPrimitive);
                 }
                 return byteOffset;
             };
             /**
              * Creates a glTF scene based on the array of meshes.
              * Returns the the total byte offset.
-             * @param gltf
-             * @param byteOffset
-             * @param buffer
-             * @param dataBuffer
+             * @param babylonScene - Babylon scene to get the mesh data from.
+             * @param byteOffset - Offset to start from in bytes.
+             * @param dataBuffer - Buffer to write geometry data to.
              * @returns bytelength + byteoffset
              */
             _Exporter.prototype.createScene = function (babylonScene, byteOffset, dataBuffer) {
@@ -1140,7 +1222,7 @@ var BABYLON;
                 var diffuse = babylonSpecularGlossiness.diffuse;
                 var opacity = babylonSpecularGlossiness.opacity;
                 var specular = babylonSpecularGlossiness.specular;
-                var glossiness = babylonSpecularGlossiness.glossiness;
+                var glossiness = BABYLON.Scalar.Clamp(babylonSpecularGlossiness.glossiness);
                 var oneMinusSpecularStrength = 1 - Math.max(specular.r, Math.max(specular.g, specular.b));
                 var diffusePerceivedBrightness = _GLTFMaterial.PerceivedBrightness(diffuse);
                 var specularPerceivedBrightness = _GLTFMaterial.PerceivedBrightness(specular);

Những thai đổi đã bị hủy bỏ vì nó quá lớn
+ 1 - 1
dist/preview release/serializers/babylonjs.serializers.min.js


+ 57 - 49
dist/preview release/serializers/babylonjs.serializers.module.d.ts

@@ -121,12 +121,14 @@ declare module BABYLON.GLTF2 {
         constructor(babylonScene: Scene, options?: IExporterOptions);
         /**
          * Creates a buffer view based on teh supplied arguments
-         * @param {number} bufferIndex - index value of the specified buffer
-         * @param {number} byteOffset - byte offset value
-         * @param {number} byteLength - byte length of the bufferView
+         * @param bufferIndex - index value of the specified buffer
+         * @param byteOffset - byte offset value
+         * @param byteLength - byte length of the bufferView
+         * @param byteStride - byte distance between conequential elements.
+         * @param name - name of the buffer view
          * @returns - bufferView for glTF
          */
-        private createBufferView(bufferIndex, byteOffset, byteLength, name?);
+        private createBufferView(bufferIndex, byteOffset, byteLength, byteStride?, name?);
         /**
          * Creates an accessor based on the supplied arguments
          * @param bufferviewIndex
@@ -138,43 +140,41 @@ declare module BABYLON.GLTF2 {
          * @param max
          * @returns - accessor for glTF
          */
-        private createAccessor(bufferviewIndex, name, type, componentType, count, min?, max?);
+        private createAccessor(bufferviewIndex, name, type, componentType, count, byteOffset?, min?, max?);
         /**
          * Calculates the minimum and maximum values of an array of floats, based on stride
-         * @param buff
-         * @param vertexStart
-         * @param vertexCount
-         * @param arrayOffset
-         * @param stride
-         * @returns - min number array and max number array
+         * @param buff - Data to check for min and max values.
+         * @param vertexStart - Start offset to calculate min and max values.
+         * @param vertexCount - Number of vertices to check for min and max values.
+         * @param stride - Offset between consecutive attributes.
+         * @param useRightHandedSystem - Indicates whether the data should be modified for a right or left handed coordinate system.
+         * @returns - min number array and max number array.
          */
-        private calculateMinMax(buff, vertexStart, vertexCount, arrayOffset, stride);
+        private calculateMinMax(buff, vertexStart, vertexCount, stride, useRightHandedSystem);
         /**
-         * Write mesh attribute data to buffer.
+         * Writes mesh attribute data to a data buffer.
          * Returns the bytelength of the data.
-         * @param vertexBufferType
-         * @param submesh
-         * @param meshAttributeArray
-         * @param strideSize
-         * @param byteOffset
-         * @param dataBuffer
-         * @param useRightHandedSystem
-         * @returns - byte length
+         * @param vertexBufferKind - Indicates what kind of vertex data is being passed in.
+         * @param meshAttributeArray - Array containing the attribute data.
+         * @param strideSize - Represents the offset between consecutive attributes
+         * @param byteOffset - The offset to start counting bytes from.
+         * @param dataBuffer - The buffer to write the binary data to.
+         * @param useRightHandedSystem - Indicates whether the data should be modified for a right or left handed coordinate system.
+         * @returns - Byte length of the attribute data.
          */
-        private writeAttributeData(vertexBufferType, submesh, meshAttributeArray, strideSize, byteOffset, dataBuffer, useRightHandedSystem);
+        private writeAttributeData(vertexBufferKind, meshAttributeArray, strideSize, vertexBufferOffset, byteOffset, dataBuffer, useRightHandedSystem);
         /**
          * Generates glTF json data
-         * @param glb
-         * @param glTFPrefix
-         * @param prettyPrint
+         * @param shouldUseGlb - Indicates whether the json should be written for a glb file.
+         * @param glTFPrefix - Text to use when prefixing a glTF file.
+         * @param prettyPrint - Indicates whether the json file should be pretty printed (true) or not (false).
          * @returns - json data as string
          */
-        private generateJSON(glb, glTFPrefix?, prettyPrint?);
+        private generateJSON(shouldUseGlb, glTFPrefix?, prettyPrint?);
         /**
          * Generates data for .gltf and .bin files based on the glTF prefix string
-         * @param glTFPrefix
-         * @returns - object with glTF json tex filename
-         * and binary file name as keys and their data as values
+         * @param glTFPrefix - Text to use when prefixing a glTF file.
+         * @returns - GLTFData with glTF file data.
          */
         _generateGLTF(glTFPrefix: string): _GLTFData;
         /**
@@ -183,7 +183,7 @@ declare module BABYLON.GLTF2 {
          */
         private generateBinary();
         /**
-         * Pads the number to a power of 4
+         * Pads the number to a multiple of 4
          * @param num - number to pad
          * @returns - padded number
          */
@@ -191,45 +191,53 @@ declare module BABYLON.GLTF2 {
         /**
          * Generates a glb file from the json and binary data.
          * Returns an object with the glb file name as the key and data as the value.
-         * @param jsonText
-         * @param binaryBuffer
          * @param glTFPrefix
          * @returns - object with glb filename as key and data as value
          */
         _generateGLB(glTFPrefix: string): _GLTFData;
         /**
          * Sets the TRS for each node
-         * @param node
-         * @param babylonMesh
-         * @param useRightHandedSystem
+         * @param node - glTF Node for storing the transformation data.
+         * @param babylonMesh - Babylon mesh used as the source for the transformation data.
+         * @param useRightHandedSystem - Indicates whether the data should be modified for a right or left handed coordinate system.
          */
         private setNodeTransformation(node, babylonMesh, useRightHandedSystem);
         /**
          *
-         * @param babylonTexture
-         * @return - glTF texture, or null if the texture format is not supported
+         * @param babylonTexture - Babylon texture to extract.
+         * @param mimeType - Mime Type of the babylonTexture.
+         * @return - glTF texture, or null if the texture format is not supported.
          */
         private exportTexture(babylonTexture, mimeType?);
         /**
+         * Creates a bufferview based on the vertices type for the Babylon mesh
+         * @param kind - Indicates the type of vertices data.
+         * @param babylonMesh - The Babylon mesh to get the vertices data from.
+         * @param byteOffset - The offset from the buffer to start indexing from.
+         * @param useRightHandedSystem - Indicates whether the data should be modified for a right or left handed coordinate system.
+         * @param dataBuffer - The buffer to write the bufferview data to.
+         * @returns bytelength of the bufferview data.
+         */
+        private createBufferViewKind(kind, babylonMesh, byteOffset, useRightHandedSystem, dataBuffer);
+        /**
          * Sets data for the primitive attributes of each submesh
-         * @param mesh
-         * @param babylonMesh
-         * @param byteOffset
-         * @param useRightHandedSystem
-         * @param dataBuffer
-         * @returns - bytelength of the primitive attributes plus the passed in byteOffset
+         * @param mesh - glTF Mesh object to store the primitive attribute information.
+         * @param babylonMesh - Babylon mesh to get the primitive attribute data from.
+         * @param byteOffset - The offset in bytes of the buffer data.
+         * @param useRightHandedSystem - Indicates whether the data should be modified for a right or left handed coordinate system.
+         * @param dataBuffer - Buffer to write the attribute data to.
+         * @returns - bytelength of the primitive attributes plus the passed in byteOffset.
          */
-        private setPrimitiveAttributes(mesh, babylonMesh, byteOffset, useRightHandedSystem, dataBuffer?);
+        private setPrimitiveAttributes(mesh, babylonMesh, byteOffset, useRightHandedSystem, dataBuffer);
         /**
          * Creates a glTF scene based on the array of meshes.
          * Returns the the total byte offset.
-         * @param gltf
-         * @param byteOffset
-         * @param buffer
-         * @param dataBuffer
+         * @param babylonScene - Babylon scene to get the mesh data from.
+         * @param byteOffset - Offset to start from in bytes.
+         * @param dataBuffer - Buffer to write geometry data to.
          * @returns bytelength + byteoffset
          */
-        private createScene(babylonScene, byteOffset, dataBuffer?);
+        private createScene(babylonScene, byteOffset, dataBuffer);
     }
 }
 

+ 1 - 1
dist/preview release/serializers/package.json

@@ -4,7 +4,7 @@
     },
     "name": "babylonjs-serializers",
     "description": "The Babylon.js serializers library is an extension you can use to serialize Babylon scenes.",
-    "version": "3.2.0-alpha4",
+    "version": "3.2.0-alpha6",
     "repository": {
         "type": "git",
         "url": "https://github.com/BabylonJS/Babylon.js.git"

Những thai đổi đã bị hủy bỏ vì nó quá lớn
+ 31 - 31
dist/preview release/viewer/babylon.viewer.js


+ 1 - 1
dist/preview release/viewer/package.json

@@ -4,7 +4,7 @@
     },
     "name": "babylonjs-viewer",
     "description": "A simple-to-use viewer based on BabylonJS to display 3D elements natively",
-    "version": "3.2.0-alpha4",
+    "version": "3.2.0-alpha6",
     "repository": {
         "type": "git",
         "url": "https://github.com/BabylonJS/Babylon.js.git"

+ 1 - 1
package.json

@@ -9,7 +9,7 @@
     ],
     "name": "babylonjs",
     "description": "Babylon.js is a JavaScript 3D engine based on webgl.",
-    "version": "3.2.0-alpha4",
+    "version": "3.2.0-alpha6",
     "repository": {
         "type": "git",
         "url": "https://github.com/BabylonJS/Babylon.js.git"