Procházet zdrojové kódy

Merge branch 'master' into draco-web-workers

Gary Hsu před 7 roky
rodič
revize
f2a7eaf614
46 změnil soubory, kde provedl 18050 přidání a 18260 odebrání
  1. 2 0
      .gitignore
  2. 7813 7810
      Playground/babylon.d.txt
  3. 10 9
      Tools/Gulp/config.json
  4. 5 1
      Tools/Gulp/gulp-addModuleExports.js
  5. 8 1
      Tools/Gulp/gulpfile.js
  6. 1 0
      Viewer/dist/_redirects
  7. 15 18
      Viewer/src/configuration/loader.ts
  8. 0 26
      Viewer/src/helper.ts
  9. 47 24
      Viewer/src/templateManager.ts
  10. 2 2
      Viewer/src/viewer/defaultViewer.ts
  11. 41 7
      Viewer/src/viewer/viewer.ts
  12. 7999 7991
      dist/preview release/babylon.d.ts
  13. 13 13
      dist/preview release/babylon.js
  14. 50 22
      dist/preview release/babylon.max.js
  15. 13 13
      dist/preview release/babylon.worker.js
  16. 1506 1504
      dist/preview release/customConfigurations/minimalGLTFViewer/babylon.d.ts
  17. 6 6
      dist/preview release/customConfigurations/minimalGLTFViewer/babylon.js
  18. 10 8
      dist/preview release/customConfigurations/minimalGLTFViewer/babylon.max.js
  19. 10 8
      dist/preview release/customConfigurations/minimalGLTFViewer/es6.js
  20. 50 22
      dist/preview release/es6.js
  21. 1 1
      dist/preview release/gui/package.json
  22. 1 1
      dist/preview release/inspector/package.json
  23. 1 1
      dist/preview release/loaders/package.json
  24. 1 1
      dist/preview release/materialsLibrary/package.json
  25. 1 1
      dist/preview release/postProcessesLibrary/package.json
  26. 1 1
      dist/preview release/proceduralTexturesLibrary/package.json
  27. 1 1
      dist/preview release/serializers/package.json
  28. 8 24
      dist/preview release/viewer/babylon.viewer.d.ts
  29. 48 48
      dist/preview release/viewer/babylon.viewer.js
  30. 84 83
      dist/preview release/viewer/babylon.viewer.max.js
  31. 4 484
      dist/preview release/viewer/babylon.viewer.module.d.ts
  32. 3 1
      dist/preview release/viewer/package.json
  33. 25 12
      dist/preview release/viewer/readme.md
  34. 93 91
      dist/preview release/what's new.md
  35. 2 2
      package.json
  36. 2 2
      src/Engine/babylon.engine.ts
  37. 3 1
      src/Helpers/babylon.environmentHelper.ts
  38. 5 1
      src/Materials/Textures/babylon.cubeTexture.ts
  39. 33 10
      src/Particles/babylon.gpuParticleSystem.ts
  40. 23 1
      src/Shaders/default.fragment.fx
  41. 14 1
      src/Shaders/default.vertex.fx
  42. 8 0
      src/Shaders/gpuRenderParticles.fragment.fx
  43. 13 0
      src/Shaders/gpuRenderParticles.vertex.fx
  44. 12 6
      src/babylon.scene.ts
  45. 1 1
      tests/validation/config.json
  46. 61 0
      tests/validation/validate.html

+ 2 - 0
.gitignore

@@ -174,3 +174,5 @@ dist/preview release/package/
 # viewer dist files
 /Viewer/dist/viewer.js
 /Viewer/dist/viewer.min.js
+dist/preview release/viewer/babylon.d.ts
+Viewer/dist/viewer.max.js

Rozdílová data souboru nebyla zobrazena, protože soubor je příliš velký
+ 7813 - 7810
Playground/babylon.d.txt


+ 10 - 9
Tools/Gulp/config.json

@@ -275,10 +275,10 @@
             "files": [
                 "../../src/Particles/babylon.particle.js",
                 "../../src/Particles/babylon.particleSystem.js",
+                "../../src/Particles/EmitterTypes/babylon.IParticleEmitterType.js",
                 "../../src/Particles/EmitterTypes/babylon.boxParticleEmitter.js",
                 "../../src/Particles/EmitterTypes/babylon.coneParticleEmitter.js",
-                "../../src/Particles/EmitterTypes/babylon.sphereParticleEmitter.js",
-                "../../src/Particles/EmitterTypes/babylon.IParticleEmitterType.js"
+                "../../src/Particles/EmitterTypes/babylon.sphereParticleEmitter.js"
             ],
             "dependUpon": [
                 "core"
@@ -290,7 +290,7 @@
         },
         "gpuParticles": {
             "files": [
-                "../../src/Particles/babylon.gpuParticleSystem.js"          
+                "../../src/Particles/babylon.gpuParticleSystem.js"
             ],
             "dependUpon": [
                 "core",
@@ -431,8 +431,7 @@
                 "additionalMeshes"
             ]
         },
-        "meshCompression" :
-        {
+        "meshCompression": {
             "files": [
                 "../../src/Mesh/Compression/babylon.dracoCompression.js"
             ]
@@ -1677,7 +1676,8 @@
                 "output": "babylon.viewer.js",
                 "webpack": "../../Viewer/webpack.gulp.config.js",
                 "bundle": "true",
-                "moduleDeclaration": "BabylonViewer"
+                "moduleDeclaration": "BabylonViewer",
+                "babylonIncluded": true
             }
         ],
         "build": {
@@ -1686,12 +1686,13 @@
                 {
                     "destination": [
                         {
-                            "filename": "viewer.min.js",
+                            "filename": "viewer.js",
                             "outputDirectory": "/../../Viewer/dist/"
                         },
                         {
                             "filename": "babylon.viewer.js",
-                            "outputDirectory": "/viewer/"
+                            "outputDirectory": "/viewer/",
+                            "addBabylonDeclaration": true
                         }
                     ],
                     "minified": true
@@ -1699,7 +1700,7 @@
                 {
                     "destination": [
                         {
-                            "filename": "viewer.js",
+                            "filename": "viewer.max.js",
                             "outputDirectory": "/../../Viewer/dist/"
                         },
                         {

+ 5 - 1
Tools/Gulp/gulp-addModuleExports.js

@@ -5,7 +5,7 @@ var through = require('through2');
  * The parameters for this function has grown during development.
  * Eventually, this function will need to be reorganized. 
  */
-module.exports = function (varName, subModule, extendsRoot, externalUsingBabylon) {
+module.exports = function (varName, subModule, extendsRoot, externalUsingBabylon, noBabylonInit) {
     return through.obj(function (file, enc, cb) {
 
         var optionalRequire = `var globalObject = (typeof global !== 'undefined') ? global : ((typeof window !== 'undefined') ? window : this);
@@ -75,6 +75,10 @@ globalObject["${base}"] = f;` : '';
             return;
         }
 
+        if (noBabylonInit) {
+            optionalRequire = '';
+        }
+
         try {
             if (externalUsingBabylon) {
                 //file.contents = new Buffer(optionalRequire.concat(String(file.contents)));

+ 8 - 1
Tools/Gulp/gulpfile.js

@@ -434,7 +434,7 @@ var buildExternalLibrary = function (library, settings, watch) {
             let wpBuild = webpack(require(library.webpack));
             if (settings.build.outputs) {
                 let build = wpBuild
-                    .pipe(addModuleExports(library.moduleDeclaration, false, false, true));
+                    .pipe(addModuleExports(library.moduleDeclaration, false, false, true, library.babylonIncluded));
 
                 let unminifiedOutpus = [];
                 let minifiedOutputs = [];
@@ -455,6 +455,12 @@ var buildExternalLibrary = function (library, settings, watch) {
                     build = build
                         .pipe(rename(dest.filename.replace(".js", library.noBundleInName ? '.js' : ".bundle.js")))
                         .pipe(gulp.dest(outputDirectory));
+
+                    if (library.babylonIncluded && dest.addBabylonDeclaration) {
+                        // include the babylon declaration
+                        sequence.unshift(gulp.src(config.build.outputDirectory + '/' + config.build.declarationFilename)
+                            .pipe(gulp.dest(outputDirectory)))
+                    }
                 }
 
                 unminifiedOutpus.forEach(dest => {
@@ -472,6 +478,7 @@ var buildExternalLibrary = function (library, settings, watch) {
                 });
 
                 sequence.push(build);
+
             } else {
                 sequence.push(
                     wpBuild

+ 1 - 0
Viewer/dist/_redirects

@@ -0,0 +1 @@
+/viewer.min.js /viewer.js

+ 15 - 18
Viewer/src/configuration/loader.ts

@@ -3,13 +3,17 @@ import { ViewerConfiguration } from './configuration';
 import { getConfigurationType } from './types';
 
 import * as deepmerge from '../../assets/deepmerge.min.js';
+import { Tools, IFileRequest } from 'babylonjs';
 
 export class ConfigurationLoader {
 
     private configurationCache: { [url: string]: any };
 
+    private loadRequests: Array<IFileRequest>;
+
     constructor() {
         this.configurationCache = {};
+        this.loadRequests = [];
     }
 
     public loadConfiguration(initConfig: ViewerConfiguration = {}, callback?: (config: ViewerConfiguration) => void): Promise<ViewerConfiguration> {
@@ -65,33 +69,26 @@ export class ConfigurationLoader {
         }
     }
 
+    public dispose() {
+        this.loadRequests.forEach(request => {
+            request.abort();
+        });
+    }
+
     private loadFile(url: string): Promise<any> {
         let cacheReference = this.configurationCache;
         if (cacheReference[url]) {
             return Promise.resolve(cacheReference[url]);
         }
 
-        return new Promise(function (resolve, reject) {
-            var xhr = new XMLHttpRequest();
-            xhr.open('GET', url);
-            xhr.send();
-            xhr.onreadystatechange = function () {
-                var DONE = 4;
-                var OK = 200;
-                if (xhr.readyState === DONE) {
-                    if (xhr.status === OK) {
-                        cacheReference[url] = xhr.responseText;
-                        resolve(xhr.responseText); // 'This is the returned text.'
-                    } else {
-                        console.log('Error: ' + xhr.status, url);
-                        reject('Error: ' + xhr.status); // An error occurred during the request.
-                    }
-                }
-            }
+        return new Promise((resolve, reject) => {
+            let fileRequest = Tools.LoadFile(url, resolve, undefined, undefined, false, (request, error: any) => {
+                reject(error);
+            });
+            this.loadRequests.push(fileRequest);
         });
     }
 
-
 }
 
 export let configurationLoader = new ConfigurationLoader();

+ 0 - 26
Viewer/src/helper.ts

@@ -5,32 +5,6 @@ export function isUrl(urlToCheck: string): boolean {
     return false;
 }
 
-export function loadFile(url: string): Promise<any> {
-    /*let cacheReference = this.configurationCache;
-    if (cacheReference[url]) {
-        return Promise.resolve(cacheReference[url]);
-    }*/
-
-    return new Promise(function (resolve, reject) {
-        var xhr = new XMLHttpRequest();
-        xhr.open('GET', url);
-        xhr.send();
-        xhr.onreadystatechange = function () {
-            var DONE = 4;
-            var OK = 200;
-            if (xhr.readyState === DONE) {
-                if (xhr.status === OK) {
-                    //cacheReference[url] = xhr.responseText;
-                    resolve(xhr.responseText); // 'This is the returned text.'
-                }
-            } else {
-                console.log('Error: ' + xhr.status, url);
-                reject('Error: ' + xhr.status); // An error occurred during the request.
-            }
-        }
-    });
-}
-
 export function kebabToCamel(s) {
     return s.replace(/(\-\w)/g, function (m) { return m[1].toUpperCase(); });
 }

+ 47 - 24
Viewer/src/templateManager.ts

@@ -1,6 +1,6 @@
 
-import { Observable } from 'babylonjs';
-import { isUrl, loadFile, camelToKebab, kebabToCamel } from './helper';
+import { Observable, IFileRequest, Tools } from 'babylonjs';
+import { isUrl, camelToKebab, kebabToCamel } from './helper';
 
 export interface ITemplateConfiguration {
     location?: string; // #template-id OR http://example.com/loading.html
@@ -212,6 +212,8 @@ export class Template {
     private fragment: DocumentFragment;
     private htmlTemplate: string;
 
+    private loadRequests: Array<IFileRequest>;
+
     constructor(public name: string, private _configuration: ITemplateConfiguration) {
         this.onInit = new Observable<Template>();
         this.onLoaded = new Observable<Template>();
@@ -219,6 +221,8 @@ export class Template {
         this.onStateChange = new Observable<Template>();
         this.onEventTriggered = new Observable<EventCallback>();
 
+        this.loadRequests = [];
+
         this.isLoaded = false;
         this.isShown = false;
         /*
@@ -228,7 +232,7 @@ export class Template {
         */
         this.onInit.notifyObservers(this);
 
-        let htmlContentPromise = getTemplateAsHtml(_configuration);
+        let htmlContentPromise = this.getTemplateAsHtml(_configuration);
 
         this.initPromise = htmlContentPromise.then(htmlTemplate => {
             if (htmlTemplate) {
@@ -299,8 +303,12 @@ export class Template {
         });
     }
 
+    private isShowing: boolean;
+    private isHiding: boolean;
     public show(visibilityFunction?: (template: Template) => Promise<Template>): Promise<Template> {
+        if (this.isHiding) return Promise.resolve(this);
         return Promise.resolve().then(() => {
+            this.isShowing = true;
             if (visibilityFunction) {
                 return visibilityFunction(this);
             } else {
@@ -310,13 +318,16 @@ export class Template {
             }
         }).then(() => {
             this.isShown = true;
+            this.isShowing = false;
             this.onStateChange.notifyObservers(this);
             return this;
         });
     }
 
     public hide(visibilityFunction?: (template: Template) => Promise<Template>): Promise<Template> {
+        if (this.isShowing) return Promise.resolve(this);
         return Promise.resolve().then(() => {
+            this.isHiding = true;
             if (visibilityFunction) {
                 return visibilityFunction(this);
             } else {
@@ -326,6 +337,7 @@ export class Template {
             }
         }).then(() => {
             this.isShown = false;
+            this.isHiding = false;
             this.onStateChange.notifyObservers(this);
             return this;
         });
@@ -340,6 +352,38 @@ export class Template {
         this.isLoaded = false;
         // remove from parent
         this.parent.removeChild(this.fragment);
+
+        this.loadRequests.forEach(request => {
+            request.abort();
+        });
+    }
+
+    private getTemplateAsHtml(templateConfig: ITemplateConfiguration): Promise<string> {
+        if (!templateConfig) {
+            return Promise.reject('No templateConfig provided');
+        } else if (templateConfig.html) {
+            return Promise.resolve(templateConfig.html);
+        } else {
+            let location = getTemplateLocation(templateConfig);
+            if (isUrl(location)) {
+                return new Promise((resolve, reject) => {
+                    let fileRequest = Tools.LoadFile(location, (data: string) => {
+                        resolve(data);
+                    }, undefined, undefined, false, (request, error: any) => {
+                        reject(error);
+                    });
+                    this.loadRequests.push(fileRequest);
+                });
+            } else {
+                location = location.replace('#', '');
+                let element = document.getElementById(location);
+                if (element) {
+                    return Promise.resolve(element.innerHTML);
+                } else {
+                    return Promise.reject('Template ID not found');
+                }
+            }
+        }
     }
 
     private registeredEvents: Array<{ htmlElement: HTMLElement, eventName: string, function: EventListenerOrEventListenerObject }>;
@@ -389,27 +433,6 @@ export class Template {
     }
 }
 
-export function getTemplateAsHtml(templateConfig: ITemplateConfiguration): Promise<string> {
-    if (!templateConfig) {
-        return Promise.reject('No templateConfig provided');
-    } else if (templateConfig.html) {
-        return Promise.resolve(templateConfig.html);
-    } else {
-        let location = getTemplateLocation(templateConfig);
-        if (isUrl(location)) {
-            return loadFile(location);
-        } else {
-            location = location.replace('#', '');
-            let element = document.getElementById(location);
-            if (element) {
-                return Promise.resolve(element.innerHTML);
-            } else {
-                return Promise.reject('Template ID not found');
-            }
-        }
-    }
-}
-
 export function getTemplateLocation(templateConfig): string {
     if (!templateConfig || typeof templateConfig === 'string') {
         return templateConfig;

+ 2 - 2
Viewer/src/viewer/defaultViewer.ts

@@ -103,8 +103,8 @@ export class DefaultViewer extends AbstractViewer {
         this.containerElement.style.display = 'flex';
     }
 
-    protected configureModel(modelConfiguration: Partial<IModelConfiguration>) {
-        super.configureModel(modelConfiguration);
+    protected configureModel(modelConfiguration: Partial<IModelConfiguration>, focusMeshes: Array<AbstractMesh> = this.scene.meshes) {
+        super.configureModel(modelConfiguration, focusMeshes);
 
         let navbar = this.templateManager.getTemplate('navBar');
         if (!navbar) return;

+ 41 - 7
Viewer/src/viewer/viewer.ts

@@ -421,7 +421,9 @@ export abstract class AbstractViewer {
             }
         };
 
-        const sceneExtends = this.scene.getWorldExtends();
+        const sceneExtends = this.scene.getWorldExtends((mesh) => {
+            return !this.environmentHelper || (mesh !== this.environmentHelper.ground && mesh !== this.environmentHelper.rootMesh && mesh !== this.environmentHelper.skybox);
+        });
         const sceneDiagonal = sceneExtends.max.subtract(sceneExtends.min);
         const sceneDiagonalLenght = sceneDiagonal.length();
         if (isFinite(sceneDiagonalLenght))
@@ -744,13 +746,36 @@ export abstract class AbstractViewer {
         return Promise.resolve(this.scene);
     }
 
+    private isLoading: boolean;
+    private nextLoading: Function;
+
     public loadModel(model: any = this.configuration.model, clearScene: boolean = true): Promise<Scene> {
         // no model was provided? Do nothing!
-        if (!model.url) {
+        let modelUrl = (typeof model === 'string') ? model : model.url;
+        if (!modelUrl) {
             return Promise.resolve(this.scene);
         }
-        this.configuration.model = model;
-        let modelUrl = (typeof model === 'string') ? model : model.url;
+        if (this.isLoading) {
+            //another model is being model. Wait for it to finish, trigger the load afterwards
+            this.nextLoading = () => {
+                delete this.nextLoading;
+                this.loadModel(model, clearScene);
+            }
+            return Promise.resolve(this.scene);
+        }
+        this.isLoading = true;
+        if ((typeof model === 'string')) {
+            if (this.configuration.model && typeof this.configuration.model === 'object') {
+                this.configuration.model.url = model;
+            }
+        } else {
+            if (this.configuration.model) {
+                deepmerge(this.configuration.model, model)
+            } else {
+                this.configuration.model = model;
+            }
+        }
+
         let parts = modelUrl.split('/');
         let filename = parts.pop();
         let base = parts.join('/') + '/';
@@ -761,13 +786,18 @@ export abstract class AbstractViewer {
 
             if (clearScene) {
                 scene.meshes.forEach(mesh => {
-                    mesh.dispose();
+                    if (Tags.MatchesQuery(mesh, "viewerMesh")) {
+                        mesh.dispose();
+                    }
                 });
             }
             return scene!;
         }).then(() => {
             return new Promise<Array<AbstractMesh>>((resolve, reject) => {
                 this.lastUsedLoader = SceneLoader.ImportMesh(undefined, base, filename, this.scene, (meshes) => {
+                    meshes.forEach(mesh => {
+                        Tags.AddTagsTo(mesh, "viewerMesh");
+                    });
                     resolve(meshes);
                 }, (progressEvent) => {
                     this.onModelLoadProgressObservable.notifyObserversWithPromise(progressEvent);
@@ -783,7 +813,7 @@ export abstract class AbstractViewer {
             return this.onModelLoadedObservable.notifyObserversWithPromise(meshes)
                 .then(() => {
                     // update the models' configuration
-                    this.configureModel(model, meshes);
+                    this.configureModel(this.configuration.model || model, meshes);
                     this.configureLights(this.configuration.lights);
 
                     if (this.configuration.camera) {
@@ -791,12 +821,16 @@ export abstract class AbstractViewer {
                     }
                     return this.initEnvironment(meshes);
                 }).then(() => {
+                    this.isLoading = false;
+                    if (this.nextLoading) {
+                        return this.nextLoading();
+                    }
                     return this.scene;
                 });
         });
     }
 
-    protected initEnvironment(focusMeshes: Array<AbstractMesh> = []): Promise<Scene> {
+    protected initEnvironment(focusMeshes: Array<AbstractMesh> = this.scene.meshes): Promise<Scene> {
         this.configureEnvironment(this.configuration.skybox, this.configuration.ground);
 
         return Promise.resolve(this.scene);

Rozdílová data souboru nebyla zobrazena, protože soubor je příliš velký
+ 7999 - 7991
dist/preview release/babylon.d.ts


Rozdílová data souboru nebyla zobrazena, protože soubor je příliš velký
+ 13 - 13
dist/preview release/babylon.js


Rozdílová data souboru nebyla zobrazena, protože soubor je příliš velký
+ 50 - 22
dist/preview release/babylon.max.js


Rozdílová data souboru nebyla zobrazena, protože soubor je příliš velký
+ 13 - 13
dist/preview release/babylon.worker.js


Rozdílová data souboru nebyla zobrazena, protože soubor je příliš velký
+ 1506 - 1504
dist/preview release/customConfigurations/minimalGLTFViewer/babylon.d.ts


Rozdílová data souboru nebyla zobrazena, protože soubor je příliš velký
+ 6 - 6
dist/preview release/customConfigurations/minimalGLTFViewer/babylon.js


Rozdílová data souboru nebyla zobrazena, protože soubor je příliš velký
+ 10 - 8
dist/preview release/customConfigurations/minimalGLTFViewer/babylon.max.js


Rozdílová data souboru nebyla zobrazena, protože soubor je příliš velký
+ 10 - 8
dist/preview release/customConfigurations/minimalGLTFViewer/es6.js


Rozdílová data souboru nebyla zobrazena, protože soubor je příliš velký
+ 50 - 22
dist/preview release/es6.js


+ 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-alpha7",
+    "version": "3.2.0-alpha8",
     "repository": {
         "type": "git",
         "url": "https://github.com/BabylonJS/Babylon.js.git"

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

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

+ 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-alpha7",
+    "version": "3.2.0-alpha8",
     "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-alpha7",
+    "version": "3.2.0-alpha8",
     "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-alpha7",
+    "version": "3.2.0-alpha8",
     "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-alpha7",
+    "version": "3.2.0-alpha8",
     "repository": {
         "type": "git",
         "url": "https://github.com/BabylonJS/Babylon.js.git"

+ 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-alpha7",
+    "version": "3.2.0-alpha8",
     "repository": {
         "type": "git",
         "url": "https://github.com/BabylonJS/Babylon.js.git"

+ 8 - 24
dist/preview release/viewer/babylon.viewer.d.ts

@@ -1,5 +1,3 @@
-/// <reference path="../babylon.d.ts"/>
-
 declare module BabylonViewer {
 
     export let disableInit: boolean;
@@ -56,7 +54,7 @@ declare module BabylonViewer {
         selector: string;
         payload?: any;
     }
-    class TemplateManager {
+    interface TemplateManager {
         containerElement: HTMLElement;
         onInit: BABYLON.Observable<Template>;
         onLoaded: BABYLON.Observable<Template>;
@@ -64,20 +62,16 @@ declare module BabylonViewer {
         onAllLoaded: BABYLON.Observable<TemplateManager>;
         onEventTriggered: BABYLON.Observable<EventCallback>;
         eventManager: EventManager;
-        private templates;
         constructor(containerElement: HTMLElement);
         initTemplate(templates: {
             [key: string]: ITemplateConfiguration;
         }): void;
-        private buildHTMLTree(templates);
         getCanvas(): HTMLCanvasElement | null;
         getTemplate(name: string): Template | undefined;
-        private checkLoadedState();
     }
 
-    class Template {
+    interface Template {
         name: string;
-        private _configuration;
         onInit: BABYLON.Observable<Template>;
         onLoaded: BABYLON.Observable<Template>;
         onAppended: BABYLON.Observable<Template>;
@@ -87,7 +81,6 @@ declare module BabylonViewer {
         isShown: boolean;
         parent: HTMLElement;
         initPromise: Promise<Template>;
-        private fragment;
         constructor(name: string, _configuration: ITemplateConfiguration);
         readonly configuration: ITemplateConfiguration;
         getChildElements(): Array<string>;
@@ -95,11 +88,9 @@ declare module BabylonViewer {
         show(visibilityFunction?: (template: Template) => Promise<Template>): Promise<Template>;
         hide(visibilityFunction?: (template: Template) => Promise<Template>): Promise<Template>;
         dispose(): void;
-        private registerEvents();
     }
 
-    class ViewerManager {
-        private viewers;
+    interface ViewerManager {
         onViewerAdded: (viewer: AbstractViewer) => void;
         onViewerAddedObservable: BABYLON.Observable<AbstractViewer>;
         constructor();
@@ -107,7 +98,6 @@ declare module BabylonViewer {
         getViewerById(id: string): AbstractViewer;
         getViewerByHTMLElement(element: HTMLElement): AbstractViewer | undefined;
         getViewerPromiseById(id: string): Promise<AbstractViewer>;
-        private _onViewerAdded(viewer);
     }
     export let viewerManager: ViewerManager;
 
@@ -119,37 +109,31 @@ declare module BabylonViewer {
 
     export function InitTags(selector?: string): void;
 
-    class EventManager {
-        private templateManager;
-        private callbacksContainer;
+    interface EventManager {
         constructor(templateManager: TemplateManager);
         registerCallback(templateName: string, callback: (eventData: EventCallback) => void, eventType?: string, selector?: string): void;
         unregisterCallback(templateName: string, callback?: (eventData: EventCallback) => void, eventType?: string, selector?: string): void;
-        private eventTriggered(data);
     }
 
-    class PromiseObservable<T> extends BABYLON.Observable<T> {
+    interface PromiseObservable<T> extends BABYLON.Observable<T> {
         notifyWithPromise(eventData: T, mask?: number, target?: any, currentTarget?: any): Promise<any>;
     }
 
     export interface IMapper {
         map(rawSource: any): ViewerConfiguration;
     }
-    class MapperManager {
-        private mappers;
-        static DefaultMapper: string;
+    interface MapperManager {
+        DefaultMapper: string;
         constructor();
         getMapper(type: string): IMapper;
         registerMapper(type: string, mapper: IMapper): void;
     }
     export let mapperManager: MapperManager;
 
-    class ConfigurationLoader {
-        private configurationCache;
+    interface ConfigurationLoader {
         constructor();
         loadConfiguration(initConfig?: ViewerConfiguration): Promise<ViewerConfiguration>;
         getConfigurationType(type: string): void;
-        private loadFile(url);
     }
     export let configurationLoader: ConfigurationLoader;
 

Rozdílová data souboru nebyla zobrazena, protože soubor je příliš velký
+ 48 - 48
dist/preview release/viewer/babylon.viewer.js


Rozdílová data souboru nebyla zobrazena, protože soubor je příliš velký
+ 84 - 83
dist/preview release/viewer/babylon.viewer.max.js


+ 4 - 484
dist/preview release/viewer/babylon.viewer.module.d.ts

@@ -1,486 +1,6 @@
-/// <reference types="babylonjs"/>
+/// <reference path="./babylon.d.ts"/>
+/// <reference path="./babylon.viewer.d.ts"/>
 
-declare module BabylonViewer {
-
-    export let disableInit: boolean;
-
-    export interface ITemplateConfiguration {
-        location?: string;
-        html?: string;
-        id?: string;
-        params?: {
-            [key: string]: string | number | boolean | object;
-        };
-        events?: {
-            pointerdown?: boolean | {
-                [id: string]: boolean;
-            };
-            pointerup?: boolean | {
-                [id: string]: boolean;
-            };
-            pointermove?: boolean | {
-                [id: string]: boolean;
-            };
-            pointerover?: boolean | {
-                [id: string]: boolean;
-            };
-            pointerout?: boolean | {
-                [id: string]: boolean;
-            };
-            pointerenter?: boolean | {
-                [id: string]: boolean;
-            };
-            pointerleave?: boolean | {
-                [id: string]: boolean;
-            };
-            pointercancel?: boolean | {
-                [id: string]: boolean;
-            };
-            click?: boolean | {
-                [id: string]: boolean;
-            };
-            dragstart?: boolean | {
-                [id: string]: boolean;
-            };
-            drop?: boolean | {
-                [id: string]: boolean;
-            };
-            [key: string]: boolean | {
-                [id: string]: boolean;
-            } | undefined;
-        };
-    }
-    export interface EventCallback {
-        event: Event;
-        template: Template;
-        selector: string;
-        payload?: any;
-    }
-    class TemplateManager {
-        containerElement: HTMLElement;
-        onInit: BABYLON.Observable<Template>;
-        onLoaded: BABYLON.Observable<Template>;
-        onStateChange: BABYLON.Observable<Template>;
-        onAllLoaded: BABYLON.Observable<TemplateManager>;
-        onEventTriggered: BABYLON.Observable<EventCallback>;
-        eventManager: EventManager;
-        private templates;
-        constructor(containerElement: HTMLElement);
-        initTemplate(templates: {
-            [key: string]: ITemplateConfiguration;
-        }): void;
-        private buildHTMLTree(templates);
-        getCanvas(): HTMLCanvasElement | null;
-        getTemplate(name: string): Template | undefined;
-        private checkLoadedState();
-    }
-
-    class Template {
-        name: string;
-        private _configuration;
-        onInit: BABYLON.Observable<Template>;
-        onLoaded: BABYLON.Observable<Template>;
-        onAppended: BABYLON.Observable<Template>;
-        onStateChange: BABYLON.Observable<Template>;
-        onEventTriggered: BABYLON.Observable<EventCallback>;
-        isLoaded: boolean;
-        isShown: boolean;
-        parent: HTMLElement;
-        initPromise: Promise<Template>;
-        private fragment;
-        constructor(name: string, _configuration: ITemplateConfiguration);
-        readonly configuration: ITemplateConfiguration;
-        getChildElements(): Array<string>;
-        appendTo(parent: HTMLElement): void;
-        show(visibilityFunction?: (template: Template) => Promise<Template>): Promise<Template>;
-        hide(visibilityFunction?: (template: Template) => Promise<Template>): Promise<Template>;
-        dispose(): void;
-        private registerEvents();
-    }
-
-    class ViewerManager {
-        private viewers;
-        onViewerAdded: (viewer: AbstractViewer) => void;
-        onViewerAddedObservable: BABYLON.Observable<AbstractViewer>;
-        constructor();
-        addViewer(viewer: AbstractViewer): void;
-        getViewerById(id: string): AbstractViewer;
-        getViewerByHTMLElement(element: HTMLElement): AbstractViewer | undefined;
-        getViewerPromiseById(id: string): Promise<AbstractViewer>;
-        private _onViewerAdded(viewer);
-    }
-    export let viewerManager: ViewerManager;
-
-    export const enum CameraBehavior {
-        AUTOROTATION = 0,
-        BOUNCING = 1,
-        FRAMING = 2,
-    }
-
-    export function InitTags(selector?: string): void;
-
-    class EventManager {
-        private templateManager;
-        private callbacksContainer;
-        constructor(templateManager: TemplateManager);
-        registerCallback(templateName: string, callback: (eventData: EventCallback) => void, eventType?: string, selector?: string): void;
-        unregisterCallback(templateName: string, callback?: (eventData: EventCallback) => void, eventType?: string, selector?: string): void;
-        private eventTriggered(data);
-    }
-
-    class PromiseObservable<T> extends BABYLON.Observable<T> {
-        notifyWithPromise(eventData: T, mask?: number, target?: any, currentTarget?: any): Promise<any>;
-    }
-
-    export interface IMapper {
-        map(rawSource: any): ViewerConfiguration;
-    }
-    class MapperManager {
-        private mappers;
-        static DefaultMapper: string;
-        constructor();
-        getMapper(type: string): IMapper;
-        registerMapper(type: string, mapper: IMapper): void;
-    }
-    export let mapperManager: MapperManager;
-
-    class ConfigurationLoader {
-        private configurationCache;
-        constructor();
-        loadConfiguration(initConfig?: ViewerConfiguration): Promise<ViewerConfiguration>;
-        getConfigurationType(type: string): void;
-        private loadFile(url);
-    }
-    export let configurationLoader: ConfigurationLoader;
-
-
-    /////> configuration
-    export interface ViewerConfiguration {
-
-        // configuration version
-        version?: string;
-        extends?: string; // is this configuration extending an existing configuration?
-
-        pageUrl?: string; // will be used for sharing and other fun stuff. This is the page showing the model (not the model's url!)
-
-        configuration?: string | {
-            url?: string;
-            payload?: any;
-            mapper?: string; // json (default), html, yaml, xml, etc'. if not provided, file extension will be used.
-        };
-
-        // names of functions in the window context.
-        observers?: IObserversConfiguration;
-
-        canvasElement?: string; // if there is a need to override the standard implementation - ID of HTMLCanvasElement
-
-        model?: IModelConfiguration | string;
-
-        scene?: ISceneConfiguration;
-        optimizer?: ISceneOptimizerConfiguration | boolean;
-        // at the moment, support only a single camera.
-        camera?: ICameraConfiguration,
-        skybox?: boolean | ISkyboxConfiguration;
-
-        ground?: boolean | IGroundConfiguration;
-        lights?: { [name: string]: boolean | ILightConfiguration },
-        // engine configuration. optional!
-        engine?: {
-            antialiasing?: boolean;
-            disableResize?: boolean;
-            engineOptions?: { [key: string]: any };
-            adaptiveQuality?: boolean;
-        },
-        //templateStructure?: ITemplateStructure,
-        templates?: {
-            main: ITemplateConfiguration,
-            [key: string]: ITemplateConfiguration
-        };
-
-        customShaders?: {
-            shaders?: {
-                [key: string]: string;
-            };
-            includes?: {
-                [key: string]: string;
-            }
-        }
-
-        // features that are being tested.
-        // those features' syntax will change and move out! 
-        // Don't use in production (or be ready to make the changes :) )
-        lab?: {
-            flashlight?: boolean | {
-                exponent?: number;
-                angle?: number;
-                intensity?: number;
-                diffuse?: { r: number, g: number, b: number };
-                specular?: { r: number, g: number, b: number };
-            }
-            hideLoadingDelay?: number;
-        }
-    }
-
-    export interface IModelConfiguration {
-        url?: string;
-        loader?: string; // obj, gltf?
-        position?: { x: number, y: number, z: number };
-        rotation?: { x: number, y: number, z: number, w?: number };
-        scaling?: { x: number, y: number, z: number };
-        parentObjectIndex?: number; // the index of the parent object of the model in the loaded meshes array.
-
-        castShadow?: boolean;
-        normalize?: boolean | {
-            center?: boolean;
-            unitSize?: boolean;
-            parentIndex?: number;
-        }; // shoud the model be scaled to unit-size
-
-        title?: string;
-        subtitle?: string;
-        thumbnail?: string; // URL or data-url
-
-        // [propName: string]: any; // further configuration, like title and creator
-    }
-
-    export interface ISkyboxConfiguration {
-        cubeTexture?: {
-            noMipMap?: boolean;
-            gammaSpace?: boolean;
-            url?: string | Array<string>;
-        };
-        color?: { r: number, g: number, b: number };
-        pbr?: boolean; // deprecated
-        scale?: number;
-        blur?: number; // deprecated
-        material?: {
-            imageProcessingConfiguration?: IImageProcessingConfiguration;
-            [propName: string]: any;
-        };
-        infiniteDIstance?: boolean;
-
-    }
-
-    export interface IGroundConfiguration {
-        size?: number;
-        receiveShadows?: boolean;
-        shadowLevel?: number;
-        shadowOnly?: boolean; // deprecated
-        mirror?: boolean | {
-            sizeRatio?: number;
-            blurKernel?: number;
-            amount?: number;
-            fresnelWeight?: number;
-            fallOffDistance?: number;
-            textureType?: number;
-        };
-        texture?: string;
-        color?: { r: number, g: number, b: number };
-        opacity?: number;
-        material?: { // deprecated!
-            [propName: string]: any;
-        };
-    }
-
-    export interface ISceneConfiguration {
-        debug?: boolean;
-        autoRotate?: boolean; // deprecated
-        rotationSpeed?: number; // deprecated
-        defaultCamera?: boolean; // deprecated
-        defaultLight?: boolean; // deprecated
-        clearColor?: { r: number, g: number, b: number, a: number };
-        imageProcessingConfiguration?: IImageProcessingConfiguration;
-        environmentTexture?: string;
-    }
-
-    export interface ISceneOptimizerConfiguration {
-        targetFrameRate?: number;
-        trackerDuration?: number;
-        autoGeneratePriorities?: boolean;
-        improvementMode?: boolean;
-        degradation?: string; // low, moderate, high
-        types?: {
-            texture?: ISceneOptimizerParameters;
-            hardwareScaling?: ISceneOptimizerParameters;
-            shadow?: ISceneOptimizerParameters;
-            postProcess?: ISceneOptimizerParameters;
-            lensFlare?: ISceneOptimizerParameters;
-            particles?: ISceneOptimizerParameters;
-            renderTarget?: ISceneOptimizerParameters;
-            mergeMeshes?: ISceneOptimizerParameters;
-        }
-    }
-
-    export interface IObserversConfiguration {
-        onEngineInit?: string;
-        onSceneInit?: string;
-        onModelLoaded?: string;
-    }
-
-    export interface ICameraConfiguration {
-        position?: { x: number, y: number, z: number };
-        rotation?: { x: number, y: number, z: number, w: number };
-        fov?: number;
-        fovMode?: number;
-        minZ?: number;
-        maxZ?: number;
-        inertia?: number;
-        behaviors?: {
-            [name: string]: number | {
-                type: number;
-                [propName: string]: any;
-            };
-        };
-
-        [propName: string]: any;
-    }
-
-    export interface ILightConfiguration {
-        type: number;
-        name?: string;
-        disabled?: boolean;
-        position?: { x: number, y: number, z: number };
-        target?: { x: number, y: number, z: number };
-        direction?: { x: number, y: number, z: number };
-        diffuse?: { r: number, g: number, b: number };
-        specular?: { r: number, g: number, b: number };
-        intensity?: number;
-        intensityMode?: number;
-        radius?: number;
-        shadownEnabled?: boolean; // only on specific lights!
-        shadowConfig?: {
-            useBlurExponentialShadowMap?: boolean;
-            useKernelBlur?: boolean;
-            blurKernel?: number;
-            blurScale?: number;
-            minZ?: number;
-            maxZ?: number;
-            frustumSize?: number;
-            angleScale?: number;
-            [propName: string]: any;
-        }
-        [propName: string]: any;
-
-        // no behaviors for light at the moment, but allowing configuration for future reference.
-        behaviors?: {
-            [name: string]: number | {
-                type: number;
-                [propName: string]: any;
-            };
-        };
-    }
-
-    export interface ISceneOptimizerParameters {
-        priority?: number;
-        maximumSize?: number;
-        step?: number;
-    }
-
-    export interface IImageProcessingConfiguration {
-        colorGradingEnabled?: boolean;
-        colorCurvesEnabled?: boolean;
-        colorCurves?: {
-            globalHue?: number;
-            globalDensity?: number;
-            globalSaturation?: number;
-            globalExposure?: number;
-            highlightsHue?: number;
-            highlightsDensity?: number;
-            highlightsSaturation?: number;
-            highlightsExposure?: number;
-            midtonesHue?: number;
-            midtonesDensity?: number;
-            midtonesSaturation?: number;
-            midtonesExposure?: number;
-            shadowsHue?: number;
-            shadowsDensity?: number;
-            shadowsSaturation?: number;
-            shadowsExposure?: number;
-        };
-        colorGradingWithGreenDepth?: boolean;
-        colorGradingBGR?: boolean;
-        exposure?: number;
-        toneMappingEnabled?: boolean;
-        contrast?: number;
-        vignetteEnabled?: boolean;
-        vignetteStretch?: number;
-        vignetteCentreX?: number;
-        vignetteCentreY?: number;
-        vignetteWeight?: number;
-        vignetteColor?: { r: number, g: number, b: number, a?: number };
-        vignetteCameraFov?: number;
-        vignetteBlendMode?: number;
-        vignetteM?: boolean;
-        applyByPostProcess?: boolean;
-
-    }
-    /////>configuration
-
-    /////<viewer
-    export abstract class AbstractViewer {
-        containerElement: HTMLElement;
-        templateManager: TemplateManager;
-        camera: BABYLON.ArcRotateCamera;
-        engine: BABYLON.Engine;
-        scene: BABYLON.Scene;
-        baseId: string;
-        canvas: HTMLCanvasElement;
-        protected configuration: ViewerConfiguration;
-        environmentHelper: BABYLON.EnvironmentHelper;
-        protected defaultHighpTextureType: number;
-        protected shadowGeneratorBias: number;
-        protected defaultPipelineTextureType: number;
-        protected maxShadows: number;
-        onSceneInitObservable: BABYLON.Observable<BABYLON.Scene>;
-        onEngineInitObservable: BABYLON.Observable<BABYLON.Engine>;
-        onModelLoadedObservable: BABYLON.Observable<BABYLON.AbstractMesh[]>;
-        onModelLoadProgressObservable: BABYLON.Observable<BABYLON.SceneLoaderProgressEvent>;
-        onModelLoadErrorObservable: BABYLON.Observable<{ message: string; exception: any }>;
-        onLoaderInitObservable: BABYLON.Observable<BABYLON.ISceneLoaderPlugin | BABYLON.ISceneLoaderPluginAsync>;
-        onInitDoneObservable: BABYLON.Observable<AbstractViewer>;
-        constructor(containerElement: HTMLElement, initialConfiguration?: ViewerConfiguration);
-        getBaseId(): string;
-        protected abstract prepareContainerElement(): any;
-        protected onTemplatesLoaded(): Promise<AbstractViewer>;
-        protected initEngine(): Promise<BABYLON.Engine>;
-        protected initScene(): Promise<BABYLON.Scene>;
-        dispose(): void;
-        loadModel(model?: any, clearScene?: boolean): Promise<BABYLON.Scene>;
-        lastUsedLoader: BABYLON.ISceneLoaderPlugin | BABYLON.ISceneLoaderPluginAsync;
-        sceneOptimizer: BABYLON.SceneOptimizer;
-        protected registeredOnBeforerenderFunctions: Array<() => void>;
-        isCanvasInDOM(): boolean;
-        protected resize: () => void;
-        protected render: () => void;
-        updateConfiguration(newConfiguration: Partial<ViewerConfiguration>): void;
-        protected configureEnvironment(skyboxConifguration?: ISkyboxConfiguration | boolean, groundConfiguration?: IGroundConfiguration | boolean): void;
-        protected configureScene(sceneConfig: ISceneConfiguration, optimizerConfig?: ISceneOptimizerConfiguration): void;
-        protected configureOptimizer(optimizerConfig: ISceneOptimizerConfiguration | boolean): void;
-        protected configureObservers(observersConfiguration: IObserversConfiguration): void;
-        protected configureCamera(cameraConfig: ICameraConfiguration, focusMeshes: Array<BABYLON.AbstractMesh>): void;
-        protected configureLights(lightsConfiguration: { [name: string]: ILightConfiguration | boolean }, focusMeshes: Array<BABYLON.AbstractMesh>): void;
-        protected configureModel(modelConfiguration: Partial<IModelConfiguration>, focusMeshes: Array<BABYLON.AbstractMesh>): void;
-        dispose(): void;
-        protected initEnvironment(focusMeshes: Array<BABYLON.AbstractMesh>): Promise<BABYLON.Scene>;
-        protected injectCustomShaders(): void;
-        protected extendClassWithConfig(object: any, config: any): void;
-        protected handleHardwareLimitations(): void;
-
-
-    }
-
-    export class DefaultViewer extends AbstractViewer {
-        containerElement: HTMLElement;
-        camera: BABYLON.ArcRotateCamera;
-        constructor(containerElement: HTMLElement, initialConfiguration?: ViewerConfiguration);
-        initScene(): Promise<BABYLON.Scene>;
-        protected onTemplatesLoaded(): Promise<AbstractViewer>;
-        protected prepareContainerElement(): void;
-        loadModel(model?: any): Promise<BABYLON.Scene>;
-        initEnvironment(focusMeshes?: Array<BABYLON.AbstractMesh>): Promise<BABYLON.Scene>;
-        showOverlayScreen(subScreen: string): Promise<Template>;
-        hideOverlayScreen(): Promise<Template>;
-        showLoadingScreen(): Promise<Template>;
-        hideLoadingScreen(): Promise<Template>;
-    }
+declare module "babylonjs-viewer" {
+    export = BabylonViewer;
 }

+ 3 - 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-alpha7",
+    "version": "3.2.0-alpha8",
     "repository": {
         "type": "git",
         "url": "https://github.com/BabylonJS/Babylon.js.git"
@@ -12,7 +12,9 @@
     "main": "babylon.viewer.js",
     "files": [
         "babylon.viewer.js",
+        "babylon.viewer.d.ts",
         "babylon.viewer.module.d.ts",
+        "babylon.d.ts",
         "readme.md",
         "package.json"
     ],

+ 25 - 12
dist/preview release/viewer/readme.md

@@ -1,5 +1,4 @@
-Babylon.js Viewer
-=====================
+# Babylon.js Viewer
 
 Babylon's viewer is a wrapper around Babylon, that automatically initializes the needed components in order to display a loaded model. It is easy to use, and require no coding at all.
 
@@ -9,13 +8,13 @@ for basic and advanced usage instructions please read the doc at https://doc.bab
 
 The source code can be found at https://github.com/BabylonJS/Babylon.js/tree/master/Viewer
 
-# Basic usage
+## Basic usage
 
-to create a simple viewer add the following code to your HTML>
+to create a simple viewer add the following code to your HTML:
 
 ```HTML
 <babylon model="https://playground.babylonjs.com/scenes/Rabbit.babylon"></babylon>
-<script src="https://viewer.babylonjs.com/viewer.min.js"></script>
+<script src="https://viewer.babylonjs.com/viewer.js"></script>
 ```
 
 Make sure to size the babylon HTML tag. For example:
@@ -29,28 +28,42 @@ babylon {
 }
 ```
 
-# Installation instructions
+## Installation instructions
 
-## CDN
+### CDN
 
-Compiled js files (minified) are offered on our public CDN here:
+Compiled js files are offered on our public CDN here:
 
-* https://viewer.babylonjs.com/serializers/viewer.min.js
+* https://viewer.babylonjs.com/viewer.js (minified)
+* https://viewer.babylonjs.com/viewer.max.js
 
-## NPM
+### Using NPM
 
 To install using npm :
 
-```
+```javascript
 npm install --save babylonjs-viewer
 ```
 
 Afterwards it can be imported to the project using:
 
-```
+```javascript
 import from 'babylonjs-viewer';
 ```
 
 This will enable the BabylonViewer namespace.
 
 Using webpack to package your project will use the minified js file.
+
+## TypeScript
+
+If you use the npm package, starting 3.2.0-alpha8 the babylon viewer has a module declaration file that also includes the BABYLON namespace.
+
+Using TypeScript and NPM you could do the following:
+
+```javascript
+import from 'babylonjs-viewer';
+
+// both namespaces are now available
+console.log(BabylonViewer, BABYLON)
+```

+ 93 - 91
dist/preview release/what's new.md

@@ -1,91 +1,93 @@
-# 3.2.0
-
-## Major updates
-
-- Support for [GPU particles](https://doc.babylonjs.com/babylon101/particles#gpu-particles) ([deltakosh](https://github.com/deltakosh))
-- Improved building process: We now run a full visual validation test for each pull request. Furthermore, code comments and what's new updates are now mandatory ([sebavan](https://github.com/sebavan))
-- Introduced texture binding atlas. This optimization allows the engine to reuse texture bindings instead of rebinding textures when they are not on constant sampler indexes ([deltakosh](https://github.com/deltakosh))
-- New [AnimationGroup class](http://doc.babylonjs.com/how_to/group) to control simultaneously multiple animations with different targets ([deltakosh](https://github.com/deltakosh))
-- `WebVRCamera` now supports GearVR ([brianzinn](https://github.com/brianzinn))
-- New glTF [serializer](https://github.com/BabylonJS/Babylon.js/tree/master/serializers/src/glTF/2.0). You can now export glTF or glb files directly from a Babylon scene ([kcoley](https://github.com/kcoley))
-- Babylon.js now uses Promises in addition to callbacks. We created several `xxxAsync` functions all over the framework (`SceneLoader.AppendAsync` for instance, which returns a Promise). A polyfill is also integrated to support older browsers ([deltakosh](https://github.com/deltakosh))
-- Introduced [Projection Texture on SpotLight](http://doc.babylonjs.com/babylon101/lights#projection-texture) ([lostink](https://github.com/lostink))
-- Introduced support for [local cubemaps](http://doc.babylonjs.com/how_to/reflect#using-local-cubemap-mode) ([deltakosh](https://github.com/deltakosh))
-- Added [VideoDome](http://doc.babylonjs.com/how_to/360videodome) class to easily support 360 videos ([DavidHGillen](https://github.com/DavidHGillen))
-- Added [GlowLayer](https://doc.babylonjs.com/how_to/glow_layer) to easily support glow from emissive materials ([sebavan](https://github.com/sebavan))
-
-## Updates
-
-- Tons of functions and classes received the code comments they deserved (All the community)
-- Added `particleSystem.reset()` to clear a particle system ([deltakosh](https://github.com/deltakosh))
-- Added support for all RGBA orders (BGR, RGB, etc..) for the DDS loader ([deltakosh](https://github.com/deltakosh))
-- Improved [SceneOptimizer](http://doc.babylonjs.com/how_to/how_to_use_sceneoptimizer) to provide better adaptability ([deltakosh](https://github.com/deltakosh))
-- Improved `scene.isReady()` function which now takes in account shadows and LOD ([deltakosh](https://github.com/deltakosh))
-- New watcher configuration for VSCode. Now the task only compiles changed files ([sebavan](https://github.com/sebavan))
-- Added new draw modes to engine (points, lines, linesloop, linestrip, trianglestrip, trianglefan) ([benaadams](https://github.com/benaadams))
-- Added GUI Textblock.lineSpacing setter and getter to configure vertical space between lines in pixels or percentage values when working with text wrapping ([carloslanderas](https://github.com/carloslanderas))
-- VRHelper now has onSelectedMeshUnselected observable that will notify observers when the current selected mesh gets unselected
-  ([carloslanderas](https://github.com/carloslanderas))
-- VRHelper now has onBeforeCameraTeleport and onAfterCameraTeleport observables that will be notified before and after camera teleportation is triggered.
-  ([carloslanderas](https://github.com/carloslanderas))
-- VRHelper now has the public property teleportationEnabled to enable / disable camera teleportation.
-   ([carloslanderas](https://github.com/carloslanderas))
-- VRHelper now exposes onNewMeshPicked observable that will notify a PickingInfo object after meshSelectionPredicate evaluation
-   ([carloslanderas](https://github.com/carloslanderas))
-- `AssetsManager` will now clear its `tasks` lsit from all successfully loaded tasks ([deltakosh](https://github.com/deltakosh))
-- Added documentation to WebVRCamera and VRExperienceHelper ([trevordev](https://github.com/trevordev))
-- Introduced `isStroke` on `HighlightLayerOptions` which makes the highlight solid ([PixelsCommander](https://github.com/pixelscommander))
-- (Viewer) There is now an option to paste payload instead of a URL for configuration ([RaananW](https://github.com/RaananW))
-- (Viewer) Models can be loaded async using JavaScript ([RaananW](https://github.com/RaananW))
-- VRHelper will notify now onSelectedMeshUnselected observable to subscribers when the applied ray selection predicate does not produce a hit and a mesh compliant with the meshSelectionPredicate was previously selected
-   ([carloslanderas](https://github.com/carloslanderas))
-- (Viewer) initScene and initEngine can now be extended. onProgress during model loading is implemented as observable. ([RaananW](https://github.com/RaananW))
-- glTF loader now supports the KHR_lights extension ([MiiBond](https://github.com/MiiBond))
-- Added depth of field effect to the default pipeline ([trevordev](https://github.com/trevordev))
-- The observable can now notify observers using promise-based callback chain. ([RaananW](https://github.com/RaananW))
-- Added base64 helper functions to `Tools` ([bghgary](https://github.com/bghgary))
-- Added `createDefaultCamera` and `createDefaultLight` functions to `Scene` ([bghgary](https://github.com/bghgary))
-- Gulp process now supports multiple outputs when using webpack. ([RaananW](https://github.com/RaananW))
-- (Viewer) Scene Optimizer intergrated in viewer. ([RaananW](https://github.com/RaananW))
-- (Viewer) The viewer supports custom shaders in the configuration. ([RaananW](https://github.com/RaananW))
-- Documented PostProcessRenderEffect, DefaultRenderingPipeline, BlurPostProcess, DepthOfFieldEffect, PostProcess, PostProcessManager, Effect classes ([trevordev](https://github.com/trevordev))
-- SPS internal storage of each solid particle rotation matrix ([jbousquie](https://github.com/jbousquie)) 
-- SPS particle parenting feature ([jbousquie](https://github.com/jbousquie))
-- (Viewer) Introducing the viewer labs - testing new features. ([RaananW](https://github.com/RaananW))
-- AssetContainer Class and loading methods ([trevordev](https://github.com/trevordev))
-- KeepAssets class and AssetContainer.moveAllFromScene ([HoloLite](http://www.html5gamedevs.com/profile/28694-hololite/) [trevordev](https://github.com/trevordev))
-- (Viewer) It is now possible to update parts of the configuration without rcreating the objects. Extra configuration can be loaded sync (if provided) ([RaananW](https://github.com/RaananW))
-- (Gulp) extra/external declarations can be prepended to final declarations during build. ([RaananW](https://github.com/RaananW))
-- (Viewer) Model can be normalized using configuration, camera is dynamically configured. ([RaananW](https://github.com/RaananW))
-- (Gulp) extra/external declarations can be prepended to final NPM declarations during build. ([RaananW](https://github.com/RaananW))
-- GUI.Line can have its world position set from one end or the other ([SvenFrankson](https://github.com/SvenFrankson))
-- Added FOV system to background material for zoom effects in skyboxes without adjusting camera FOV ([DavidHGillen](https://github.com/DavidHGillen))
-- Improved glTF loader by using promises for asynchronous operations. ([bghgary](https://github.com/bghgary)]
-- Improved glTF loader performance by compiling materials in parallel with downloading external resources. ([bghgary](https://github.com/bghgary)]
-- Added unit tests for the glTF 2.0 loader. ([bghgary](https://github.com/bghgary)]
-- Added promise-based async functions to the SceneLoader, Scene.whenReadyAsync, and material.forceCompilationAsync. ([bghgary](https://github.com/bghgary)]
-- Added checks to VertexData.merge to ensure data is valid before merging. ([bghgary](https://github.com/bghgary)]
-- Ability to set a mesh to customize the webVR gaze tracker ([trevordev](https://github.com/trevordev))
-- Added promise-based async functions for initWebVRAsync and useStandingMatrixAsync ([trevordev](https://github.com/trevordev))
-- Add stroke (outline) options on GUI text control ([SvenFrankson](https://github.com/SvenFrankson))
-- Add isThumbClamped option on GUI slider control ([JeanPhilippeKernel](https://github.com/JeanPhilippeKernel))
-- Add floating point texture support for RenderTargetCubeTexture ([PeapBoy](https://github.com/NicolasBuecher))
-- Support for mutli-touch when interacting with multiple gui elements simultaneously ([trevordev](https://github.com/trevordev))
-- (Viewer) Declaration file published. ([RaananW](https://github.com/RaananW))
-- Added Draco mesh compression support to glTF 2.0 loader. ([bghgary](https://github.com/bghgary))
-- Added `Tools.WorkerPool` class for web worker management. ([bghgary](https://github.com/bghgary))
-
-## Bug fixes
-
-- `setPivotMatrix` ws not setting pivot correctly. This is now fixed. We also introduced a new `setPreTransformMatrix` to reproduce the sometimes needed behavior of the previous `setPivotMatrix` function ([deltakosh](https://github.com/deltakosh))
-- SPS solid particle `.pivot` property now also behaves like the standard mesh pivot. Former behavior (particle translation) can be kept with the particle property `.translateFromPivot` set to true ([jbousquie](https://github.com/jbousquie))
-- Texture extension detection in `Engine.CreateTexture` ([sebavan](https://github.com/sebavan))
-- SPS internal temporary vector3 instead of Tmp.Vector3 to avoid possible concurrent uses ([jbousquie](https://github.com/jbousquie))
-- Fixed a bug when calling load on an empty assets manager - [#3739](https://github.com/BabylonJS/Babylon.js/issues/3739). ([RaananW](https://github.com/RaananW))
-- Enabling teleportation in the vr helper class caused a redundant post process to be added ([trevordev](https://github.com/trevordev))
-
-## Breaking changes
-
-- Removed the unused PostProcessRenderPass class and extended postProcessingRenderingEffect to support multiple PostProcesses ([trevordev](https://github.com/trevordev))
-- VertexData.merge no longer supports merging of data that do not have the same set of attributes. ([bghgary](https://github.com/bghgary)]
-- glTF 2.0 loader will now create a mesh for each primitive instead of merging the primitives together into one mesh. ([bghgary](https://github.com/bghgary)]
+# 3.2.0
+
+## Major updates
+
+- Support for [GPU particles](https://doc.babylonjs.com/babylon101/particles#gpu-particles) ([deltakosh](https://github.com/deltakosh))
+- Improved building process: We now run a full visual validation test for each pull request. Furthermore, code comments and what's new updates are now mandatory ([sebavan](https://github.com/sebavan))
+- Introduced texture binding atlas. This optimization allows the engine to reuse texture bindings instead of rebinding textures when they are not on constant sampler indexes ([deltakosh](https://github.com/deltakosh))
+- New [AnimationGroup class](http://doc.babylonjs.com/how_to/group) to control simultaneously multiple animations with different targets ([deltakosh](https://github.com/deltakosh))
+- `WebVRCamera` now supports GearVR ([brianzinn](https://github.com/brianzinn))
+- New glTF [serializer](https://github.com/BabylonJS/Babylon.js/tree/master/serializers/src/glTF/2.0). You can now export glTF or glb files directly from a Babylon scene ([kcoley](https://github.com/kcoley))
+- Babylon.js now uses Promises in addition to callbacks. We created several `xxxAsync` functions all over the framework (`SceneLoader.AppendAsync` for instance, which returns a Promise). A polyfill is also integrated to support older browsers ([deltakosh](https://github.com/deltakosh))
+- Introduced [Projection Texture on SpotLight](http://doc.babylonjs.com/babylon101/lights#projection-texture) ([lostink](https://github.com/lostink))
+- Introduced support for [local cubemaps](http://doc.babylonjs.com/how_to/reflect#using-local-cubemap-mode) ([deltakosh](https://github.com/deltakosh))
+- Added [VideoDome](http://doc.babylonjs.com/how_to/360videodome) class to easily support 360 videos ([DavidHGillen](https://github.com/DavidHGillen))
+- Added [GlowLayer](https://doc.babylonjs.com/how_to/glow_layer) to easily support glow from emissive materials ([sebavan](https://github.com/sebavan))
+
+## Updates
+
+- Tons of functions and classes received the code comments they deserved (All the community)
+- Added `particleSystem.reset()` to clear a particle system ([deltakosh](https://github.com/deltakosh))
+- Added support for all RGBA orders (BGR, RGB, etc..) for the DDS loader ([deltakosh](https://github.com/deltakosh))
+- Improved [SceneOptimizer](http://doc.babylonjs.com/how_to/how_to_use_sceneoptimizer) to provide better adaptability ([deltakosh](https://github.com/deltakosh))
+- Improved `scene.isReady()` function which now takes in account shadows and LOD ([deltakosh](https://github.com/deltakosh))
+- New watcher configuration for VSCode. Now the task only compiles changed files ([sebavan](https://github.com/sebavan))
+- Added new draw modes to engine (points, lines, linesloop, linestrip, trianglestrip, trianglefan) ([benaadams](https://github.com/benaadams))
+- Added GUI Textblock.lineSpacing setter and getter to configure vertical space between lines in pixels or percentage values when working with text wrapping ([carloslanderas](https://github.com/carloslanderas))
+- VRHelper now has onSelectedMeshUnselected observable that will notify observers when the current selected mesh gets unselected
+  ([carloslanderas](https://github.com/carloslanderas))
+- VRHelper now has onBeforeCameraTeleport and onAfterCameraTeleport observables that will be notified before and after camera teleportation is triggered.
+  ([carloslanderas](https://github.com/carloslanderas))
+- VRHelper now has the public property teleportationEnabled to enable / disable camera teleportation.
+   ([carloslanderas](https://github.com/carloslanderas))
+- VRHelper now exposes onNewMeshPicked observable that will notify a PickingInfo object after meshSelectionPredicate evaluation
+   ([carloslanderas](https://github.com/carloslanderas))
+- `AssetsManager` will now clear its `tasks` lsit from all successfully loaded tasks ([deltakosh](https://github.com/deltakosh))
+- Added documentation to WebVRCamera and VRExperienceHelper ([trevordev](https://github.com/trevordev))
+- Introduced `isStroke` on `HighlightLayerOptions` which makes the highlight solid ([PixelsCommander](https://github.com/pixelscommander))
+- (Viewer) There is now an option to paste payload instead of a URL for configuration ([RaananW](https://github.com/RaananW))
+- (Viewer) Models can be loaded async using JavaScript ([RaananW](https://github.com/RaananW))
+- VRHelper will notify now onSelectedMeshUnselected observable to subscribers when the applied ray selection predicate does not produce a hit and a mesh compliant with the meshSelectionPredicate was previously selected
+   ([carloslanderas](https://github.com/carloslanderas))
+- (Viewer) initScene and initEngine can now be extended. onProgress during model loading is implemented as observable. ([RaananW](https://github.com/RaananW))
+- glTF loader now supports the KHR_lights extension ([MiiBond](https://github.com/MiiBond))
+- Added depth of field effect to the default pipeline ([trevordev](https://github.com/trevordev))
+- The observable can now notify observers using promise-based callback chain. ([RaananW](https://github.com/RaananW))
+- Added base64 helper functions to `Tools` ([bghgary](https://github.com/bghgary))
+- Added `createDefaultCamera` and `createDefaultLight` functions to `Scene` ([bghgary](https://github.com/bghgary))
+- Gulp process now supports multiple outputs when using webpack. ([RaananW](https://github.com/RaananW))
+- (Viewer) Scene Optimizer intergrated in viewer. ([RaananW](https://github.com/RaananW))
+- (Viewer) The viewer supports custom shaders in the configuration. ([RaananW](https://github.com/RaananW))
+- Documented PostProcessRenderEffect, DefaultRenderingPipeline, BlurPostProcess, DepthOfFieldEffect, PostProcess, PostProcessManager, Effect classes ([trevordev](https://github.com/trevordev))
+- SPS internal storage of each solid particle rotation matrix ([jbousquie](https://github.com/jbousquie)) 
+- SPS particle parenting feature ([jbousquie](https://github.com/jbousquie))
+- (Viewer) Introducing the viewer labs - testing new features. ([RaananW](https://github.com/RaananW))
+- AssetContainer Class and loading methods ([trevordev](https://github.com/trevordev))
+- KeepAssets class and AssetContainer.moveAllFromScene ([HoloLite](http://www.html5gamedevs.com/profile/28694-hololite/) [trevordev](https://github.com/trevordev))
+- (Viewer) It is now possible to update parts of the configuration without rcreating the objects. Extra configuration can be loaded sync (if provided) ([RaananW](https://github.com/RaananW))
+- (Gulp) extra/external declarations can be prepended to final declarations during build. ([RaananW](https://github.com/RaananW))
+- (Viewer) Model can be normalized using configuration, camera is dynamically configured. ([RaananW](https://github.com/RaananW))
+- (Gulp) extra/external declarations can be prepended to final NPM declarations during build. ([RaananW](https://github.com/RaananW))
+- GUI.Line can have its world position set from one end or the other ([SvenFrankson](https://github.com/SvenFrankson))
+- Added FOV system to background material for zoom effects in skyboxes without adjusting camera FOV ([DavidHGillen](https://github.com/DavidHGillen))
+- Improved glTF loader by using promises for asynchronous operations. ([bghgary](https://github.com/bghgary)]
+- Improved glTF loader performance by compiling materials in parallel with downloading external resources. ([bghgary](https://github.com/bghgary)]
+- Added unit tests for the glTF 2.0 loader. ([bghgary](https://github.com/bghgary)]
+- Added promise-based async functions to the SceneLoader, Scene.whenReadyAsync, and material.forceCompilationAsync. ([bghgary](https://github.com/bghgary)]
+- Added checks to VertexData.merge to ensure data is valid before merging. ([bghgary](https://github.com/bghgary)]
+- Ability to set a mesh to customize the webVR gaze tracker ([trevordev](https://github.com/trevordev))
+- Added promise-based async functions for initWebVRAsync and useStandingMatrixAsync ([trevordev](https://github.com/trevordev))
+- Add stroke (outline) options on GUI text control ([SvenFrankson](https://github.com/SvenFrankson))
+- Add isThumbClamped option on GUI slider control ([JeanPhilippeKernel](https://github.com/JeanPhilippeKernel))
+- Add floating point texture support for RenderTargetCubeTexture ([PeapBoy](https://github.com/NicolasBuecher))
+- Support for mutli-touch when interacting with multiple gui elements simultaneously ([trevordev](https://github.com/trevordev))
+- (Viewer) Declaration file published, ready for npm. ([RaananW](https://github.com/RaananW))
+- Added Draco mesh compression support to glTF 2.0 loader. ([bghgary](https://github.com/bghgary))
+- (Viewer) XHR requests not use Tools.LoadFile and are disposed correctly - [#3671](https://github.com/BabylonJS/Babylon.js/issues/3671) ([RaananW](https://github.com/RaananW))
+- Added `Tools.WorkerPool` class for web worker management. ([bghgary](https://github.com/bghgary))
+
+## Bug fixes
+
+- `setPivotMatrix` ws not setting pivot correctly. This is now fixed. We also introduced a new `setPreTransformMatrix` to reproduce the sometimes needed behavior of the previous `setPivotMatrix` function ([deltakosh](https://github.com/deltakosh))
+- SPS solid particle `.pivot` property now also behaves like the standard mesh pivot. Former behavior (particle translation) can be kept with the particle property `.translateFromPivot` set to true ([jbousquie](https://github.com/jbousquie))
+- Texture extension detection in `Engine.CreateTexture` ([sebavan](https://github.com/sebavan))
+- SPS internal temporary vector3 instead of Tmp.Vector3 to avoid possible concurrent uses ([jbousquie](https://github.com/jbousquie))
+- Fixed a bug when calling load on an empty assets manager - [#3739](https://github.com/BabylonJS/Babylon.js/issues/3739). ([RaananW](https://github.com/RaananW))
+- Enabling teleportation in the vr helper class caused a redundant post process to be added ([trevordev](https://github.com/trevordev))
+- (Viewer) Fixed a bug where loading another mesh positioned it incorrectly ([RaananW](https://github.com/RaananW))
+
+## Breaking changes
+
+- Removed the unused PostProcessRenderPass class and extended postProcessingRenderingEffect to support multiple PostProcesses ([trevordev](https://github.com/trevordev))
+- VertexData.merge no longer supports merging of data that do not have the same set of attributes. ([bghgary](https://github.com/bghgary)]
+- glTF 2.0 loader will now create a mesh for each primitive instead of merging the primitives together into one mesh. ([bghgary](https://github.com/bghgary)]

+ 2 - 2
package.json

@@ -9,7 +9,7 @@
     ],
     "name": "babylonjs",
     "description": "Babylon.js is a JavaScript 3D engine based on webgl.",
-    "version": "3.2.0-alpha7",
+    "version": "3.2.0-alpha8",
     "repository": {
         "type": "git",
         "url": "https://github.com/BabylonJS/Babylon.js.git"
@@ -41,4 +41,4 @@
     },
     "readme": "Babylon.js is a 3D engine based on webgl and javascript",
     "readmeFilename": "README.md"
-}
+}

+ 2 - 2
src/Engine/babylon.engine.ts

@@ -4268,7 +4268,7 @@
                 }, undefined, undefined, true, onerror);
             } else if (isDDS) {
                 if (files && files.length === 6) {
-                    this._cascadeLoadFiles(rootUrl,
+                    this._cascadeLoadFiles(
                         scene,
                         imgs => {
                             var info: DDSInfo | undefined;
@@ -5883,7 +5883,7 @@
             this._loadFile(url, onload, undefined, undefined, true, onerror);
         }
 
-        private _cascadeLoadFiles(rootUrl: string, scene: Nullable<Scene>, onfinish: (images: (string | ArrayBuffer)[]) => void, files: string[], onError: Nullable<(message?: string, exception?: any) => void> = null): void {
+        private _cascadeLoadFiles(scene: Nullable<Scene>, onfinish: (images: (string | ArrayBuffer)[]) => void, files: string[], onError: Nullable<(message?: string, exception?: any) => void> = null): void {
             var loadedFiles: (string | ArrayBuffer)[] = [];
             (<any>loadedFiles)._internalCount = 0;
 

+ 3 - 1
src/Helpers/babylon.environmentHelper.ts

@@ -476,7 +476,9 @@ module BABYLON {
                 return { groundSize, skyboxSize, rootPosition };
             }
 
-            const sceneExtends = this._scene.getWorldExtends();
+            const sceneExtends = this._scene.getWorldExtends((mesh) => {
+                return (mesh !== this._ground && mesh !== this._rootMesh && mesh !== this._skybox);
+            });
             const sceneDiagonal = sceneExtends.max.subtract(sceneExtends.min);
 
             if (this._options.sizeAuto) {

+ 5 - 1
src/Materials/Textures/babylon.cubeTexture.ts

@@ -39,7 +39,11 @@
         private _prefiltered: boolean;
 
         public static CreateFromImages(files: string[], scene: Scene, noMipmap?: boolean) {
-            return new CubeTexture("", scene, null, noMipmap, files);
+            let rootUrlKey = "";
+            
+            files.forEach(url => rootUrlKey += url);
+
+            return new CubeTexture(rootUrlKey, scene, null, noMipmap, files);
         }
 
         public static CreateFromPrefilteredData(url: string, scene: Scene, forcedExtension: any = null) {

+ 33 - 10
src/Particles/babylon.gpuParticleSystem.ts

@@ -335,10 +335,6 @@
                 transformFeedbackVaryings: ["outPosition", "outAge", "outLife", "outSeed", "outSize", "outColor", "outDirection"]
             };
 
-            this._updateEffect = new Effect("gpuUpdateParticles", this._updateEffectOptions, this._scene.getEngine());   
-
-            this._renderEffect = new Effect("gpuRenderParticles", ["position", "age", "life", "size", "color", "offset", "uv"], ["view", "projection", "colorDead"], ["textureSampler"], this._scene.getEngine());
-
             // Random data
             var maxTextureSize = Math.min(this._engine.getCaps().maxTextureSize, fullOptions.randomTextureSize);
             var d = [];
@@ -452,14 +448,32 @@
         }
 
         /** @ignore */
-        public _recreateUpdateEffect(defines: string) {
-            if (this._updateEffectOptions.defines === defines) {
+        public _recreateUpdateEffect() {
+            let defines = this.particleEmitterType ? this.particleEmitterType.getEffectDefines() : "";
+            if (this._updateEffect && this._updateEffectOptions.defines === defines) {
                 return;
             }
             this._updateEffectOptions.defines = defines;
             this._updateEffect = new Effect("gpuUpdateParticles", this._updateEffectOptions, this._scene.getEngine());   
         }
 
+        /** @ignore */
+        public _recreateRenderEffect() {
+            let defines = "";
+            if (this._scene.clipPlane) {
+                defines = "\n#define CLIPPLANE";
+            }
+
+            if (this._renderEffect && this._renderEffect.defines === defines) {
+                return;
+            }
+
+            this._renderEffect = new Effect("gpuRenderParticles", 
+                                            ["position", "age", "life", "size", "color", "offset", "uv"], 
+                                            ["view", "projection", "colorDead", "invView", "vClipPlane"], 
+                                            ["textureSampler"], this._scene.getEngine(), defines);
+        }        
+
         /**
          * Animates the particle system for the current frame by emitting new particles and or animating the living ones.
          */
@@ -484,9 +498,8 @@
                 return 0;
             }
 
-            if (this.particleEmitterType) {
-                this._recreateUpdateEffect(this.particleEmitterType.getEffectDefines());
-            }
+            this._recreateUpdateEffect();
+            this._recreateRenderEffect();
 
             if (!this.emitter || !this._updateEffect.isReady() || !this._renderEffect.isReady() ) {
                 return 0;
@@ -547,11 +560,21 @@
 
             // Enable render effect
             this._engine.enableEffect(this._renderEffect);
-            this._renderEffect.setMatrix("view", this._scene.getViewMatrix());
+            let viewMatrix = this._scene.getViewMatrix();
+            this._renderEffect.setMatrix("view", viewMatrix);
             this._renderEffect.setMatrix("projection", this._scene.getProjectionMatrix());
             this._renderEffect.setTexture("textureSampler", this.particleTexture);
             this._renderEffect.setDirectColor4("colorDead", this.colorDead);
 
+
+            if (this._scene.clipPlane) {
+                var clipPlane = this._scene.clipPlane;
+                var invView = viewMatrix.clone();
+                invView.invert();
+                this._renderEffect.setMatrix("invView", invView);
+                this._renderEffect.setFloat4("vClipPlane", clipPlane.normal.x, clipPlane.normal.y, clipPlane.normal.z, clipPlane.d);
+            }            
+
             // Draw order
             if (this.blendMode === ParticleSystem.BLENDMODE_ONEONE) {
                 this._engine.setAlphaMode(Engine.ALPHA_ONEONE);

+ 23 - 1
src/Shaders/default.fragment.fx

@@ -4,6 +4,8 @@
 #extension GL_OES_standard_derivatives : enable
 #endif
 
+#define CUSTOM_FRAGMENT_BEGIN
+
 #ifdef LOGARITHMICDEPTH
 #extension GL_EXT_frag_depth : enable
 #endif
@@ -152,14 +154,23 @@ varying vec3 vDirectionW;
 #include<logDepthDeclaration>
 #include<fogFragmentDeclaration>
 
+#define CUSTOM_FRAGMENT_DEFINITIONS
+
 void main(void) {
+
+#define CUSTOM_FRAGMENT_MAIN_BEGIN
+
 #include<clipPlaneFragment>
 
+
+
 	vec3 viewDirectionW = normalize(vEyePosition - vPositionW);
 
 	// Base color
 	vec4 baseColor = vec4(1., 1., 1., 1.);
 	vec3 diffuseColor = vDiffuseColor.rgb;
+	
+	
 
 	// Alpha
 	float alpha = vDiffuseColor.a;
@@ -188,16 +199,22 @@ void main(void) {
 	#ifdef ALPHAFROMDIFFUSE
 		alpha *= baseColor.a;
 	#endif
+	
+	#define CUSTOM_FRAGMENT_UPDATE_ALPHA
 
 	baseColor.rgb *= vDiffuseInfos.y;
 #endif
 
+
+
 #include<depthPrePass>
 
 #ifdef VERTEXCOLOR
 	baseColor.rgb *= vColor.rgb;
 #endif
 
+#define CUSTOM_FRAGMENT_UPDATE_DIFFUSE
+
 	// Ambient color
 	vec3 baseAmbientColor = vec3(1., 1., 1.);
 
@@ -205,6 +222,8 @@ void main(void) {
 	baseAmbientColor = texture2D(ambientSampler, vAmbientUV + uvOffset).rgb * vAmbientInfos.y;
 #endif
 
+#define CUSTOM_FRAGMENT_BEFORE_LIGHTS
+
 	// Specular map
 #ifdef SPECULARTERM
 	float glossiness = vSpecularColor.a;
@@ -398,6 +417,8 @@ void main(void) {
     #endif
 #endif
 
+#define CUSTOM_FRAGMENT_BEFORE_FOG
+
 #include<logDepthFragment>
 #include<fogFragment>
 
@@ -417,5 +438,6 @@ void main(void) {
 	color.rgb *= color.a;
 #endif
 
+#define CUSTOM_FRAGMENT_BEFORE_FRAGCOLOR
 	gl_FragColor = color;
-}
+}

+ 14 - 1
src/Shaders/default.vertex.fx

@@ -1,5 +1,8 @@
 #include<__decl__defaultVertex>
 // Attributes
+
+#define CUSTOM_VERTEX_BEGIN
+
 attribute vec3 position;
 #ifdef NORMAL
 attribute vec3 normal;
@@ -89,8 +92,12 @@ varying vec3 vDirectionW;
 #endif
 
 #include<logDepthDeclaration>
+#define CUSTOM_VERTEX_DEFINITIONS
 
 void main(void) {
+	
+	#define CUSTOM_VERTEX_MAIN_BEGIN
+	
 	vec3 positionUpdated = position;
 #ifdef NORMAL	
 	vec3 normalUpdated = normal;
@@ -105,6 +112,10 @@ void main(void) {
 	vPositionUVW = positionUpdated;
 #endif 
 
+#define CUSTOM_VERTEX_UPDATE_POSITION
+
+#define CUSTOM_VERTEX_UPDATE_NORMAL
+
 #include<instancesVertex>
 #include<bonesVertex>
 
@@ -233,4 +244,6 @@ void main(void) {
 #include<pointCloudVertex>
 #include<logDepthVertex>
 
-}
+#define CUSTOM_VERTEX_MAIN_END
+
+}

+ 8 - 0
src/Shaders/gpuRenderParticles.fragment.fx

@@ -7,6 +7,14 @@ in vec4 vColor;
 
 out vec4 outFragColor;
 
+#ifdef CLIPPLANE
+in float fClipDistance;
+#endif
+
 void main() {
+#ifdef CLIPPLANE
+	if (fClipDistance > 0.0)
+		discard;
+#endif  
   outFragColor = texture(textureSampler, vUV) * vColor;
 }

+ 13 - 0
src/Shaders/gpuRenderParticles.vertex.fx

@@ -16,6 +16,13 @@ in vec2 uv;
 out vec2 vUV;
 out vec4 vColor;
 
+#ifdef CLIPPLANE
+uniform vec4 vClipPlane;
+uniform mat4 invView;
+out float fClipDistance;
+#endif
+
+
 void main() {
   vUV = uv;
   float ratio = age / life;
@@ -24,4 +31,10 @@ void main() {
   // Expand position
   vec4 viewPosition = view * vec4(position, 1.0);
   gl_Position = projection * (viewPosition + vec4(offset * size, 0, 1.0));
+
+	// Clip plane
+#ifdef CLIPPLANE
+	vec4 worldPos = invView * viewPosition;
+	fClipDistance = dot(worldPos, vClipPlane);
+#endif  
 }

+ 12 - 6
src/babylon.scene.ts

@@ -4230,16 +4230,22 @@
         }
 
         // Octrees
-        public getWorldExtends(): { min: Vector3; max: Vector3 } {
+
+        /**
+         * Get the world extend vectors with an optional filter
+         * 
+         * @param filterPredicate the predicate - which meshes should be included when calculating the world size
+         * @returns {{ min: Vector3; max: Vector3 }} min and max vectors
+         */
+        public getWorldExtends(filterPredicate?: (mesh: AbstractMesh) => boolean): { min: Vector3; max: Vector3 } {
             var min = new Vector3(Number.MAX_VALUE, Number.MAX_VALUE, Number.MAX_VALUE);
             var max = new Vector3(-Number.MAX_VALUE, -Number.MAX_VALUE, -Number.MAX_VALUE);
-            for (var index = 0; index < this.meshes.length; index++) {
-                var mesh = this.meshes[index];
-
+            filterPredicate = filterPredicate || (() => true);
+            this.meshes.filter(filterPredicate).forEach(mesh => {
                 mesh.computeWorldMatrix(true);
 
                 if (!mesh.subMeshes || mesh.subMeshes.length === 0 || mesh.infiniteDistance) {
-                    continue;
+                    return;
                 }
 
                 let boundingInfo = mesh.getBoundingInfo();
@@ -4249,7 +4255,7 @@
 
                 Tools.CheckExtends(minBox, min, max);
                 Tools.CheckExtends(maxBox, min, max);
-            }
+            })
 
             return {
                 min: min,

+ 1 - 1
tests/validation/config.json

@@ -18,7 +18,7 @@
       "sceneFolder": "/Scenes/Espilit/",
       "sceneFilename": "espilit.babylon",
       "referenceImage": "Espilit.png"
-    },
+    },    
     {
       "title": "The car",
       "sceneFolder": "/Scenes/TheCar/",

+ 61 - 0
tests/validation/validate.html

@@ -0,0 +1,61 @@
+<!DOCTYPE html>
+<html>
+<head>
+	<title>BabylonJS - Build validation page</title>
+	<link href="index.css" rel="stylesheet" />
+    <script src="https://preview.babylonjs.com/draco_decoder.js"></script>
+    <script src="https://preview.babylonjs.com/cannon.js"></script>
+    <script src="https://preview.babylonjs.com/draco_decoder.js"></script>
+    <script src="https://preview.babylonjs.com/Oimo.js"></script>
+    <script src="https://preview.babylonjs.com/babylon.js"></script>
+    <script src="https://preview.babylonjs.com/inspector/babylon.inspector.bundle.js"></script>
+
+    <script src="https://preview.babylonjs.com/loaders/babylonjs.loaders.min.js"></script>
+	<script src="https://preview.babylonjs.com/materialsLibrary/babylonjs.materials.min.js"></script>
+    <script src="https://preview.babylonjs.com/proceduralTexturesLibrary/babylonjs.proceduralTextures.min.js"></script>
+	<script src="https://preview.babylonjs.com/postProcessesLibrary/babylonjs.postProcess.min.js"></script>
+    <script src="https://preview.babylonjs.com/gui/babylon.gui.min.js"></script>	
+</head>
+<body>
+	<script src="validation.js"></script>
+	<script>
+		// Loading tests
+		var xhr = new XMLHttpRequest();
+
+		xhr.open("GET", "config.json", true);
+
+		xhr.addEventListener("load", function () {
+			if (xhr.status === 200) {
+
+				config = JSON.parse(xhr.responseText);
+
+				// Run tests
+				var index = 0;
+				if (window.location.search) {
+					justOnce = true;
+					var title = window.location.search.replace("?", "").replace(/%20/g, " ");
+					for (var index = 0; index < config.tests.length; index++) {
+						if (config.tests[index].title === title) {
+							break;
+						}
+					}
+				}
+
+				var recursiveRunTest = function(i) {
+					runTest(i, function() {
+						i++;
+						if (justOnce || i >= config.tests.length) {
+							return;
+						}
+						recursiveRunTest(i);
+					});
+				}
+
+				recursiveRunTest(index);
+			}
+		}, false);
+
+		xhr.send();
+    </script>	
+</body>
+</html>