فهرست منبع

Merge from master

David Catuhe 7 سال پیش
والد
کامیت
f3088fa6b0
63فایلهای تغییر یافته به همراه6120 افزوده شده و 2922 حذف شده
  1. 1121 1120
      Playground/babylon.d.txt
  2. 183 0
      Playground/scenes/BoomBox/UnlitBoomBox.gltf
  3. 6 1
      Tools/Gulp/config.json
  4. 3 3
      Tools/Gulp/gulp-addDtsExport.js
  5. 1 1
      Tools/Gulp/gulp-addES6Exports.js
  6. 1 1
      Tools/Gulp/gulp-addModuleExports.js
  7. 9 4
      Tools/Gulp/gulp-validateTypedoc.js
  8. 7 3
      Tools/Gulp/gulpfile.js
  9. 1 1
      Viewer/tsconfig-gulp.json
  10. 1 1
      Viewer/tsconfig.json
  11. 4 0
      dist/babylon.glTF2Interface.d.ts
  12. 18 18
      dist/preview release/babylon.js
  13. 323 257
      dist/preview release/babylon.max.js
  14. 18 18
      dist/preview release/babylon.worker.js
  15. 325 259
      dist/preview release/es6.js
  16. 3 3
      dist/preview release/inspector/babylon.inspector.bundle.js
  17. 3 0
      dist/preview release/inspector/babylon.inspector.d.ts
  18. 31 29
      dist/preview release/inspector/babylon.inspector.js
  19. 4 4
      dist/preview release/inspector/babylon.inspector.min.js
  20. 1119 0
      dist/preview release/loaders/babylonjs.loaders.d.ts
  21. 2 0
      dist/preview release/loaders/babylonjs.loaders.module.d.ts
  22. 580 0
      dist/preview release/materialsLibrary/babylonjs.materials.d.ts
  23. 201 0
      dist/preview release/postProcessesLibrary/babylonjs.postProcess.d.ts
  24. 155 0
      dist/preview release/proceduralTexturesLibrary/babylonjs.proceduralTextures.d.ts
  25. 512 0
      dist/preview release/serializers/babylonjs.serializers.d.ts
  26. 2 0
      dist/preview release/serializers/babylonjs.serializers.module.d.ts
  27. 23 23
      dist/preview release/viewer/babylon.viewer.js
  28. 416 390
      dist/preview release/viewer/babylon.viewer.max.js
  29. 3 1
      dist/preview release/what's new.md
  30. 15 2
      inspector/src/adapters/CameraAdapter.ts
  31. 0 18
      inspector/src/tabs/SceneTab.ts
  32. 26 10
      inspector/src/treetools/CameraPOV.ts
  33. 6 6
      inspector/test/index.js
  34. 9 9
      loaders/src/glTF/2.0/Extensions/KHR_lights.ts
  35. 2 2
      loaders/src/glTF/2.0/Extensions/KHR_materials_pbrSpecularGlossiness.ts
  36. 76 0
      loaders/src/glTF/2.0/Extensions/KHR_materials_unlit.ts
  37. 4 4
      loaders/src/glTF/2.0/Extensions/MSFT_lod.ts
  38. 1 1
      loaders/src/glTF/2.0/babylon.glTFLoaderExtension.ts
  39. 4 1
      src/Bones/babylon.skeleton.ts
  40. 101 0
      src/Debug/babylon.axesViewer.ts
  41. 53 0
      src/Debug/babylon.boneAxesViewer.ts
  42. 0 461
      src/Debug/babylon.debugModules.ts
  43. 192 0
      src/Debug/babylon.physicsViewer.ts
  44. 134 0
      src/Debug/babylon.skeletonViewer.ts
  45. 3 0
      src/Engine/babylon.nullEngine.ts
  46. 20 1
      src/Layer/babylon.effectLayer.ts
  47. 78 1
      src/Layer/babylon.glowLayer.ts
  48. 189 178
      src/PostProcess/babylon.blurPostProcess.ts
  49. 5 3
      src/PostProcess/babylon.depthOfFieldEffect.ts
  50. 2 2
      src/PostProcess/babylon.depthOfFieldMergePostProcess.ts
  51. 2 0
      src/PostProcess/babylon.postProcessManager.ts
  52. 1 2
      src/Shaders/ShadersInclude/kernelBlurFragment.fx
  53. 1 2
      src/Shaders/ShadersInclude/kernelBlurFragment2.fx
  54. 3 7
      src/Shaders/circleOfConfusion.fragment.fx
  55. 11 8
      src/Shaders/depthOfFieldMerge.fragment.fx
  56. 58 53
      src/Shaders/kernelBlur.fragment.fx
  57. 22 0
      src/Tools/babylon.decorators.ts
  58. 4 0
      src/babylon.scene.ts
  59. 18 14
      tests/nullEngine/app.js
  60. BIN
      tests/validation/ReferenceImages/defaultPipeline.png
  61. BIN
      tests/validation/ReferenceImages/depthOfField.png
  62. BIN
      tests/validation/ReferenceImages/gltfUnlit.png
  63. 5 0
      tests/validation/config.json

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


+ 183 - 0
Playground/scenes/BoomBox/UnlitBoomBox.gltf

@@ -0,0 +1,183 @@
+{
+  "accessors": [
+    {
+      "bufferView": 0,
+      "componentType": 5126,
+      "count": 3575,
+      "type": "VEC2"
+    },
+    {
+      "bufferView": 1,
+      "componentType": 5126,
+      "count": 3575,
+      "type": "VEC3"
+    },
+    {
+      "bufferView": 2,
+      "componentType": 5126,
+      "count": 3575,
+      "type": "VEC4"
+    },
+    {
+      "bufferView": 3,
+      "componentType": 5126,
+      "count": 3575,
+      "type": "VEC3",
+      "max": [
+        0.009921154,
+        0.00977163,
+        0.0100762453
+      ],
+      "min": [
+        -0.009921154,
+        -0.00977163,
+        -0.0100762453
+      ]
+    },
+    {
+      "bufferView": 4,
+      "componentType": 5123,
+      "count": 18108,
+      "type": "SCALAR"
+    }
+  ],
+  "asset": {
+    "generator": "glTF Tools for Unity",
+    "version": "2.0"
+  },
+  "bufferViews": [
+    {
+      "buffer": 0,
+      "byteLength": 28600
+    },
+    {
+      "buffer": 0,
+      "byteOffset": 28600,
+      "byteLength": 42900
+    },
+    {
+      "buffer": 0,
+      "byteOffset": 71500,
+      "byteLength": 57200
+    },
+    {
+      "buffer": 0,
+      "byteOffset": 128700,
+      "byteLength": 42900
+    },
+    {
+      "buffer": 0,
+      "byteOffset": 171600,
+      "byteLength": 36216
+    }
+  ],
+  "buffers": [
+    {
+      "uri": "BoomBox.bin",
+      "byteLength": 207816
+    }
+  ],
+  "extensionsUsed": [
+    "KHR_materials_unlit"
+  ],
+  "images": [
+    {
+      "uri": "BoomBox_baseColor.png"
+    },
+    {
+      "uri": "BoomBox_occlusionRoughnessMetallic.png"
+    },
+    {
+      "uri": "BoomBox_normal.png"
+    },
+    {
+      "uri": "BoomBox_emissive.png"
+    }
+  ],
+  "meshes": [
+    {
+      "primitives": [
+        {
+          "attributes": {
+            "TEXCOORD_0": 0,
+            "NORMAL": 1,
+            "TANGENT": 2,
+            "POSITION": 3
+          },
+          "indices": 4,
+          "material": 0
+        }
+      ],
+      "name": "BoomBox"
+    }
+  ],
+  "materials": [
+    {
+      "pbrMetallicRoughness": {
+        "baseColorTexture": {
+          "index": 0
+        },
+        "metallicRoughnessTexture": {
+          "index": 1
+        }
+      },
+      "normalTexture": {
+        "index": 2
+      },
+      "occlusionTexture": {
+        "index": 1
+      },
+      "emissiveFactor": [
+        1.0,
+        1.0,
+        1.0
+      ],
+      "emissiveTexture": {
+        "index": 3
+      },
+      "name": "BoomBox_Mat",
+      "extensions": {
+        "KHR_materials_unlit": {}
+      }
+    }
+  ],
+  "nodes": [
+    {
+      "mesh": 0,
+      "rotation": [
+        0.0,
+        1.0,
+        0.0,
+        0.0
+      ],
+      "scale": [ 1, 1, 1 ],
+      "name": "BoomBox"
+    }
+  ],
+  "scene": 0,
+  "scenes": [
+    {
+      "nodes": [
+        0
+      ]
+    }
+  ],
+  "textures": [
+    {
+      "name": "baseColor",
+      "source": 0
+    },
+    {
+      "name": "occlusionRoughnessMetallic",
+      "source": 1
+    },
+    {
+      "name": "normal",
+      "source": 2
+    },
+    {
+      "name": "emissive",
+      "source": 3
+    }
+  ]
+}

+ 6 - 1
Tools/Gulp/config.json

@@ -999,9 +999,12 @@
         },
         "debug": {
             "files": [
-                "../../src/Debug/babylon.debugModules.js",
+                "../../src/Debug/babylon.skeletonViewer.js",
+                "../../src/Debug/babylon.axesViewer.js",
+                "../../src/Debug/babylon.boneAxesViewer.js",
                 "../../src/Debug/babylon.rayHelper.js",
                 "../../src/Debug/babylon.debugLayer.js",
+                "../../src/Debug/babylon.physicsViewer.js",
                 "../../src/Rendering/babylon.boundingBoxRenderer.js"
             ],
             "dependUpon": [
@@ -1527,6 +1530,7 @@
                     "../../loaders/src/glTF/2.0/Extensions/MSFT_lod.ts",
                     "../../loaders/src/glTF/2.0/Extensions/KHR_draco_mesh_compression.ts",
                     "../../loaders/src/glTF/2.0/Extensions/KHR_materials_pbrSpecularGlossiness.ts",
+                    "../../loaders/src/glTF/2.0/Extensions/KHR_materials_unlit.ts",
                     "../../loaders/src/glTF/2.0/Extensions/KHR_lights.ts"
                 ],
                 "doNotIncludeInBundle": true,
@@ -1548,6 +1552,7 @@
                     "../../loaders/src/glTF/2.0/Extensions/MSFT_lod.ts",
                     "../../loaders/src/glTF/2.0/Extensions/KHR_draco_mesh_compression.ts",
                     "../../loaders/src/glTF/2.0/Extensions/KHR_materials_pbrSpecularGlossiness.ts",
+                    "../../loaders/src/glTF/2.0/Extensions/KHR_materials_unlit.ts",
                     "../../loaders/src/glTF/2.0/Extensions/KHR_lights.ts"
                 ],
                 "output": "babylon.glTFFileLoader.js"

+ 3 - 3
Tools/Gulp/gulp-addDtsExport.js

@@ -11,15 +11,15 @@ module.exports = function (varName, moduleName, subModule, extendsRoot, dependen
 
         let referenceText = '';
         if (subModule) {
-            // referenceText = '/// <reference types="babylonjs"/>\n';
+            //referenceText = '/// <reference types="babylonjs"/>\n';
         }
 
         if (dependencies) {
             referenceText = '';
             dependencies.forEach(element => {
                 // was "babylonjs/${element}""
-                /*referenceText += `/// <reference types="${element}"/>
-`;*/
+                referenceText += `/// <reference types="${element}"/>
+`;
             });
         }
 

+ 1 - 1
Tools/Gulp/gulp-addES6Exports.js

@@ -37,7 +37,7 @@ globalObject["${base}"] = ${base}${(subModule && !extendsRoot) ? '.' + varName :
             let enumMatcher = new RegExp(`\\(${base}\\.([A-Za-z0-9].*)= {}\\)`, "g");
             let enumMatch = enumMatcher.exec(fileContent);
             while (enumMatch != null) {
-                if (enumMatch[1]) {
+                if (enumMatch[1] && listOfExports.indexOf(enumMatch[1]) === -1) {
                     listOfExports.push(enumMatch[1]);
                 }
                 enumMatch = enumMatcher.exec(fileContent);

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

@@ -46,7 +46,7 @@ module.exports = function (varName, config) {
                     amdText += `        ${dep.optional ? ' if(require.specified && require.specified("' + dep.module + '"))' : ''} amdDependencies.push("${dep.module}");
 `;
                     dependenciesDefinition += `
-    var ${dep.name} = root.${dep.name};`;
+    var ${dep.name} = root.${dep.name} || this.${dep.name};`;
                     afterInitText += `  ${dep.name} = ${dep.name} || this.${dep.name};
 `
                 });

+ 9 - 4
Tools/Gulp/gulp-validateTypedoc.js

@@ -289,7 +289,7 @@ Validate.prototype.validateTypedocNamespaces = function (namespaces) {
         this.validateNaming(null, containerNode);
 
         // Validate Comments.
-        if (isPublic && !this.validateComment(containerNode)) {            
+        if (isPublic && !this.validateComment(containerNode)) {      
             this.errorCallback(null,
                 containerNode.name,
                 containerNode.kindString,
@@ -448,7 +448,7 @@ Validate.prototype.validateComment = function(node) {
     // Return true for overwrited properties
     if (node.overwrites) {
         return true;
-    }
+    } 
 
     // Check comments.
     if (node.comment) {
@@ -459,6 +459,11 @@ Validate.prototype.validateComment = function(node) {
         return false;
     }
 
+    // Return true for inherited properties (need to check signatures)
+    if (node.kindString === "Function") {
+        return true;
+    }
+
     return false;
 }
 
@@ -553,13 +558,13 @@ Validate.prototype.validateNaming = function(parent, node) {
         }
     }
     else if (node.kindString == "Module") {
-        if (!Validate.upperCase.test(node.name)) {
+        if (!(Validate.upperCase.test(node.name) || Validate.pascalCase.test(node.name))) {
             this.errorCallback(parent ? parent.name : null,
                 node.name,
                 node.kindString,
                 "Naming",
                 "NotUpperCase",
-                "Module is not Upper Case " + node.name + " (id: " + node.id + ")", Validate.position(node));
+                "Module is not Upper Case or Pascal Case " + node.name + " (id: " + node.id + ")", Validate.position(node));
         }
     }
     else if (node.kindString == "Interface" ||

+ 7 - 3
Tools/Gulp/gulpfile.js

@@ -331,13 +331,17 @@ var buildExternalLibraries = function (settings) {
             let dtsFiles = files.map(function (filename) {
                 return filename.replace(".js", ".d.ts");
             });
-            let dtsTask = gulp.src(dtsFiles)
+            let dtsModuleTask = gulp.src(dtsFiles)
                 .pipe(concat(settings.build.outputFilename + ".module.d.ts"))
                 .pipe(replace(referenceSearchRegex, ""))
                 .pipe(addDtsExport(settings.build.moduleDeclaration, settings.build.moduleName, true, settings.build.extendsRoot, settings.build.extraTypesDependencies))
                 .pipe(gulp.dest(outputDirectory));
+            let dtsTask = gulp.src(dtsFiles)
+                .pipe(concat(settings.build.outputFilename + ".d.ts"))
+                .pipe(replace(referenceSearchRegex, ""))
+                .pipe(gulp.dest(outputDirectory));
 
-            return merge2([srcTask, dtsTask]);
+            return merge2([srcTask, dtsTask, dtsModuleTask]);
         });
     }
 
@@ -589,7 +593,7 @@ gulp.task("watch", ["srcTscWatch"], function () {
 
 gulp.task("intellisense", function () {
     gulp.src(config.build.intellisenseSources)
-        .pipe(concat(config.build.intellisenseFile))    
+        .pipe(concat(config.build.intellisenseFile))
         .pipe(replace(/^\s+_.*?;/gm, ""))
         .pipe(replace(/^\s+_[\S\s]*?}/gm, ""))
         .pipe(replace(/^\s*readonly _/gm, "protected readonly _"))

+ 1 - 1
Viewer/tsconfig-gulp.json

@@ -25,7 +25,7 @@
                 "../dist/preview release/babylon.d.ts"
             ],
             "babylonjs-loaders": [
-                "../dist/preview release/loaders/babylonjs.loaders.module.d.ts"
+                "../dist/preview release/loaders/babylonjs.loaders.d.ts"
             ],
             "babylonjs-gltf2interface": [
                 "../dist/babylon.glTF2Interface.d.ts"

+ 1 - 1
Viewer/tsconfig.json

@@ -25,7 +25,7 @@
                 "../../dist/preview release/babylon.d.ts"
             ],
             "babylonjs-loaders": [
-                "../../dist/preview release/loaders/babylonjs.loaders.module.d.ts"
+                "../../dist/preview release/loaders/babylonjs.loaders.d.ts"
             ],
             "babylonjs-gltf2interface": [
                 "../../dist/babylon.glTF2Interface.d.ts"

+ 4 - 0
dist/babylon.glTF2Interface.d.ts

@@ -1,3 +1,7 @@
+declare module "babylonjs-gltf2interface" {
+    export = BABYLON.GLTF2;
+}
+
 declare module BABYLON.GLTF2 {
     const enum AccessorComponentType {
         BYTE = 5120,

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


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


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


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


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


+ 3 - 0
dist/preview release/inspector/babylon.inspector.d.ts

@@ -294,6 +294,7 @@ declare module INSPECTOR {
         getProperties(): Array<PropertyLine>;
         getTools(): Array<AbstractTreeTool>;
         setPOV(): void;
+        getCurrentActiveCamera(): string;
     }
 }
 
@@ -1256,6 +1257,8 @@ declare module INSPECTOR {
 declare module INSPECTOR {
     interface ICameraPOV {
         setPOV: () => void;
+        getCurrentActiveCamera: () => string;
+        id: () => string;
     }
     /**
      *

+ 31 - 29
dist/preview release/inspector/babylon.inspector.js

@@ -710,12 +710,22 @@ var INSPECTOR;
         };
         CameraAdapter.prototype.getTools = function () {
             var tools = [];
-            // tools.push(new Checkbox(this));
             tools.push(new INSPECTOR.CameraPOV(this));
             return tools;
         };
+        // Set the point of view of the chosen camera
         CameraAdapter.prototype.setPOV = function () {
-            this._obj.getScene().activeCamera = this._obj;
+            this._obj.getScene().switchActiveCamera(this._obj);
+        };
+        // Return the name of the current active camera
+        CameraAdapter.prototype.getCurrentActiveCamera = function () {
+            var activeCamera = this._obj.getScene().activeCamera;
+            if (activeCamera != null) {
+                return activeCamera.name;
+            }
+            else {
+                return "0";
+            }
         };
         return CameraAdapter;
     }(INSPECTOR.Adapter));
@@ -3441,25 +3451,6 @@ var INSPECTOR;
                 point.addEventListener('click', function () { _this._inspector.scene.forcePointsCloud = true; _this._inspector.scene.forceWireframe = false; });
                 wireframe.addEventListener('click', function () { _this._inspector.scene.forcePointsCloud = false; _this._inspector.scene.forceWireframe = true; });
                 solid.addEventListener('click', function () { _this._inspector.scene.forcePointsCloud = false; _this._inspector.scene.forceWireframe = false; });
-                // Cameras
-                title = INSPECTOR.Helpers.CreateDiv('actions-title', _this._actions);
-                title.textContent = 'Cameras';
-                var cameraRadioButtons = [];
-                var _loop_1 = function (camera) {
-                    var cameraRadio = INSPECTOR.Helpers.CreateDiv('action-radio', this_1._actions);
-                    cameraRadio.textContent = camera.name;
-                    if (this_1._inspector.scene.activeCamera == camera) {
-                        cameraRadio.classList.add('active');
-                    }
-                    cameraRadioButtons.push(cameraRadio);
-                    cameraRadio.addEventListener('click', function () { _this._inspector.scene.switchActiveCamera(camera); });
-                };
-                var this_1 = this;
-                for (var _a = 0, _b = _this._inspector.scene.cameras; _a < _b.length; _a++) {
-                    var camera = _b[_a];
-                    _loop_1(camera);
-                }
-                _this._generateRadioAction(cameraRadioButtons);
                 // Textures
                 title = INSPECTOR.Helpers.CreateDiv('actions-title', _this._actions);
                 title.textContent = 'Textures channels';
@@ -5023,7 +5014,15 @@ var INSPECTOR;
         function CameraPOV(camera) {
             var _this = _super.call(this) || this;
             _this.cameraPOV = camera;
-            _this._elem.classList.add('fa-video-camera');
+            // Setting the id of the line with the name of the camera
+            _this._elem.id = _this.cameraPOV.id();
+            // Put the right icon 
+            if (_this._elem.id == _this.cameraPOV.getCurrentActiveCamera()) {
+                _this._elem.classList.add('fa-check-circle');
+            }
+            else {
+                _this._elem.classList.add('fa-circle');
+            }
             return _this;
         }
         CameraPOV.prototype.action = function () {
@@ -5031,16 +5030,19 @@ var INSPECTOR;
             this._gotoPOV();
         };
         CameraPOV.prototype._gotoPOV = function () {
-            var actives = INSPECTOR.Inspector.DOCUMENT.querySelectorAll(".fa-video-camera.active");
-            console.log(actives);
+            // Uncheck all the radio buttons
+            var actives = INSPECTOR.Inspector.DOCUMENT.querySelectorAll(".fa-check-circle");
             for (var i = 0; i < actives.length; i++) {
-                actives[i].classList.remove('active');
+                actives[i].classList.remove('fa-check-circle');
+                actives[i].classList.add('fa-circle');
             }
-            //if (this._on) {
-            // set icon camera
-            this._elem.classList.add('active');
-            //}
+            // setting the point off view to the right camera
             this.cameraPOV.setPOV();
+            // Check the right radio button
+            if (this._elem.id == this.cameraPOV.getCurrentActiveCamera()) {
+                this._elem.classList.remove('fa-circle');
+                this._elem.classList.add('fa-check-circle');
+            }
         };
         return CameraPOV;
     }(INSPECTOR.AbstractTreeTool));

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


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


+ 2 - 0
dist/preview release/loaders/babylonjs.loaders.module.d.ts

@@ -1,3 +1,5 @@
+/// <reference types="babylonjs"/>
+/// <reference types="babylonjs-gltf2interface"/>
 
 
 declare module 'babylonjs-loaders' { 

+ 580 - 0
dist/preview release/materialsLibrary/babylonjs.materials.d.ts

@@ -0,0 +1,580 @@
+
+declare module BABYLON {
+    class ShadowOnlyMaterial extends PushMaterial {
+        private _renderId;
+        private _activeLight;
+        constructor(name: string, scene: Scene);
+        needAlphaBlending(): boolean;
+        needAlphaTesting(): boolean;
+        getAlphaTestTexture(): Nullable<BaseTexture>;
+        activeLight: IShadowLight;
+        isReadyForSubMesh(mesh: AbstractMesh, subMesh: SubMesh, useInstances?: boolean): boolean;
+        bindForSubMesh(world: Matrix, mesh: Mesh, subMesh: SubMesh): void;
+        clone(name: string): ShadowOnlyMaterial;
+        serialize(): any;
+        getClassName(): string;
+        static Parse(source: any, scene: Scene, rootUrl: string): ShadowOnlyMaterial;
+    }
+}
+
+
+declare module BABYLON {
+    class GradientMaterial extends PushMaterial {
+        private _maxSimultaneousLights;
+        maxSimultaneousLights: number;
+        topColor: Color3;
+        topColorAlpha: number;
+        bottomColor: Color3;
+        bottomColorAlpha: number;
+        offset: number;
+        smoothness: number;
+        disableLighting: boolean;
+        private _scaledDiffuse;
+        private _renderId;
+        constructor(name: string, scene: Scene);
+        needAlphaBlending(): boolean;
+        needAlphaTesting(): boolean;
+        getAlphaTestTexture(): Nullable<BaseTexture>;
+        isReadyForSubMesh(mesh: AbstractMesh, subMesh: SubMesh, useInstances?: boolean): boolean;
+        bindForSubMesh(world: Matrix, mesh: Mesh, subMesh: SubMesh): void;
+        getAnimatables(): IAnimatable[];
+        dispose(forceDisposeEffect?: boolean): void;
+        clone(name: string): GradientMaterial;
+        serialize(): any;
+        getClassName(): string;
+        static Parse(source: any, scene: Scene, rootUrl: string): GradientMaterial;
+    }
+}
+
+
+declare module BABYLON {
+    class NormalMaterial extends PushMaterial {
+        private _diffuseTexture;
+        diffuseTexture: BaseTexture;
+        diffuseColor: Color3;
+        private _disableLighting;
+        disableLighting: boolean;
+        private _maxSimultaneousLights;
+        maxSimultaneousLights: number;
+        private _renderId;
+        constructor(name: string, scene: Scene);
+        needAlphaBlending(): boolean;
+        needAlphaTesting(): boolean;
+        getAlphaTestTexture(): Nullable<BaseTexture>;
+        isReadyForSubMesh(mesh: AbstractMesh, subMesh: SubMesh, useInstances?: boolean): boolean;
+        bindForSubMesh(world: Matrix, mesh: Mesh, subMesh: SubMesh): void;
+        getAnimatables(): IAnimatable[];
+        getActiveTextures(): BaseTexture[];
+        hasTexture(texture: BaseTexture): boolean;
+        dispose(forceDisposeEffect?: boolean): void;
+        clone(name: string): NormalMaterial;
+        serialize(): any;
+        getClassName(): string;
+        static Parse(source: any, scene: Scene, rootUrl: string): NormalMaterial;
+    }
+}
+
+
+declare module BABYLON {
+    class LavaMaterial extends PushMaterial {
+        private _diffuseTexture;
+        diffuseTexture: BaseTexture;
+        noiseTexture: BaseTexture;
+        fogColor: Color3;
+        speed: number;
+        movingSpeed: number;
+        lowFrequencySpeed: number;
+        fogDensity: number;
+        private _lastTime;
+        diffuseColor: Color3;
+        private _disableLighting;
+        disableLighting: boolean;
+        private _maxSimultaneousLights;
+        maxSimultaneousLights: number;
+        private _scaledDiffuse;
+        private _renderId;
+        constructor(name: string, scene: Scene);
+        needAlphaBlending(): boolean;
+        needAlphaTesting(): boolean;
+        getAlphaTestTexture(): Nullable<BaseTexture>;
+        isReadyForSubMesh(mesh: AbstractMesh, subMesh: SubMesh, useInstances?: boolean): boolean;
+        bindForSubMesh(world: Matrix, mesh: Mesh, subMesh: SubMesh): void;
+        getAnimatables(): IAnimatable[];
+        getActiveTextures(): BaseTexture[];
+        hasTexture(texture: BaseTexture): boolean;
+        dispose(forceDisposeEffect?: boolean): void;
+        clone(name: string): LavaMaterial;
+        serialize(): any;
+        getClassName(): string;
+        static Parse(source: any, scene: Scene, rootUrl: string): LavaMaterial;
+    }
+}
+
+
+declare module BABYLON {
+    class SimpleMaterial extends PushMaterial {
+        private _diffuseTexture;
+        diffuseTexture: BaseTexture;
+        diffuseColor: Color3;
+        private _disableLighting;
+        disableLighting: boolean;
+        private _maxSimultaneousLights;
+        maxSimultaneousLights: number;
+        private _renderId;
+        constructor(name: string, scene: Scene);
+        needAlphaBlending(): boolean;
+        needAlphaTesting(): boolean;
+        getAlphaTestTexture(): Nullable<BaseTexture>;
+        isReadyForSubMesh(mesh: AbstractMesh, subMesh: SubMesh, useInstances?: boolean): boolean;
+        bindForSubMesh(world: Matrix, mesh: Mesh, subMesh: SubMesh): void;
+        getAnimatables(): IAnimatable[];
+        getActiveTextures(): BaseTexture[];
+        hasTexture(texture: BaseTexture): boolean;
+        dispose(forceDisposeEffect?: boolean): void;
+        clone(name: string): SimpleMaterial;
+        serialize(): any;
+        getClassName(): string;
+        static Parse(source: any, scene: Scene, rootUrl: string): SimpleMaterial;
+    }
+}
+
+
+declare module BABYLON {
+    class WaterMaterial extends PushMaterial {
+        renderTargetSize: Vector2;
+        private _bumpTexture;
+        bumpTexture: BaseTexture;
+        diffuseColor: Color3;
+        specularColor: Color3;
+        specularPower: number;
+        private _disableLighting;
+        disableLighting: boolean;
+        private _maxSimultaneousLights;
+        maxSimultaneousLights: number;
+        /**
+        * @param {number}: Represents the wind force
+        */
+        windForce: number;
+        /**
+        * @param {Vector2}: The direction of the wind in the plane (X, Z)
+        */
+        windDirection: Vector2;
+        /**
+        * @param {number}: Wave height, represents the height of the waves
+        */
+        waveHeight: number;
+        /**
+        * @param {number}: Bump height, represents the bump height related to the bump map
+        */
+        bumpHeight: number;
+        /**
+         * @param {boolean}: Add a smaller moving bump to less steady waves.
+         */
+        private _bumpSuperimpose;
+        bumpSuperimpose: boolean;
+        /**
+         * @param {boolean}: Color refraction and reflection differently with .waterColor2 and .colorBlendFactor2. Non-linear (physically correct) fresnel.
+         */
+        private _fresnelSeparate;
+        fresnelSeparate: boolean;
+        /**
+         * @param {boolean}: bump Waves modify the reflection.
+         */
+        private _bumpAffectsReflection;
+        bumpAffectsReflection: boolean;
+        /**
+        * @param {number}: The water color blended with the refraction (near)
+        */
+        waterColor: Color3;
+        /**
+        * @param {number}: The blend factor related to the water color
+        */
+        colorBlendFactor: number;
+        /**
+         * @param {number}: The water color blended with the reflection (far)
+         */
+        waterColor2: Color3;
+        /**
+         * @param {number}: The blend factor related to the water color (reflection, far)
+         */
+        colorBlendFactor2: number;
+        /**
+        * @param {number}: Represents the maximum length of a wave
+        */
+        waveLength: number;
+        /**
+        * @param {number}: Defines the waves speed
+        */
+        waveSpeed: number;
+        protected _renderTargets: SmartArray<RenderTargetTexture>;
+        private _mesh;
+        private _refractionRTT;
+        private _reflectionRTT;
+        private _reflectionTransform;
+        private _lastTime;
+        private _lastDeltaTime;
+        private _renderId;
+        private _useLogarithmicDepth;
+        private _waitingRenderList;
+        /**
+        * Constructor
+        */
+        constructor(name: string, scene: Scene, renderTargetSize?: Vector2);
+        useLogarithmicDepth: boolean;
+        readonly refractionTexture: Nullable<RenderTargetTexture>;
+        readonly reflectionTexture: Nullable<RenderTargetTexture>;
+        addToRenderList(node: any): void;
+        enableRenderTargets(enable: boolean): void;
+        getRenderList(): Nullable<AbstractMesh[]>;
+        readonly renderTargetsEnabled: boolean;
+        needAlphaBlending(): boolean;
+        needAlphaTesting(): boolean;
+        getAlphaTestTexture(): Nullable<BaseTexture>;
+        isReadyForSubMesh(mesh: AbstractMesh, subMesh: SubMesh, useInstances?: boolean): boolean;
+        bindForSubMesh(world: Matrix, mesh: Mesh, subMesh: SubMesh): void;
+        private _createRenderTargets(scene, renderTargetSize);
+        getAnimatables(): IAnimatable[];
+        getActiveTextures(): BaseTexture[];
+        hasTexture(texture: BaseTexture): boolean;
+        dispose(forceDisposeEffect?: boolean): void;
+        clone(name: string): WaterMaterial;
+        serialize(): any;
+        getClassName(): string;
+        static Parse(source: any, scene: Scene, rootUrl: string): WaterMaterial;
+        static CreateDefaultMesh(name: string, scene: Scene): Mesh;
+    }
+}
+
+
+declare module BABYLON {
+    class FireMaterial extends PushMaterial {
+        private _diffuseTexture;
+        diffuseTexture: Nullable<BaseTexture>;
+        private _distortionTexture;
+        distortionTexture: Nullable<BaseTexture>;
+        private _opacityTexture;
+        opacityTexture: Nullable<BaseTexture>;
+        diffuseColor: Color3;
+        speed: number;
+        private _scaledDiffuse;
+        private _renderId;
+        private _lastTime;
+        constructor(name: string, scene: Scene);
+        needAlphaBlending(): boolean;
+        needAlphaTesting(): boolean;
+        getAlphaTestTexture(): Nullable<BaseTexture>;
+        isReadyForSubMesh(mesh: AbstractMesh, subMesh: SubMesh, useInstances?: boolean): boolean;
+        bindForSubMesh(world: Matrix, mesh: Mesh, subMesh: SubMesh): void;
+        getAnimatables(): IAnimatable[];
+        getActiveTextures(): BaseTexture[];
+        hasTexture(texture: BaseTexture): boolean;
+        getClassName(): string;
+        dispose(forceDisposeEffect?: boolean): void;
+        clone(name: string): FireMaterial;
+        serialize(): any;
+        static Parse(source: any, scene: Scene, rootUrl: string): FireMaterial;
+    }
+}
+
+
+declare module BABYLON {
+    class FurMaterial extends PushMaterial {
+        private _diffuseTexture;
+        diffuseTexture: BaseTexture;
+        private _heightTexture;
+        heightTexture: BaseTexture;
+        diffuseColor: Color3;
+        furLength: number;
+        furAngle: number;
+        furColor: Color3;
+        furOffset: number;
+        furSpacing: number;
+        furGravity: Vector3;
+        furSpeed: number;
+        furDensity: number;
+        furTexture: DynamicTexture;
+        private _disableLighting;
+        disableLighting: boolean;
+        private _maxSimultaneousLights;
+        maxSimultaneousLights: number;
+        highLevelFur: boolean;
+        _meshes: AbstractMesh[];
+        private _renderId;
+        private _furTime;
+        constructor(name: string, scene: Scene);
+        furTime: number;
+        needAlphaBlending(): boolean;
+        needAlphaTesting(): boolean;
+        getAlphaTestTexture(): Nullable<BaseTexture>;
+        updateFur(): void;
+        isReadyForSubMesh(mesh: AbstractMesh, subMesh: SubMesh, useInstances?: boolean): boolean;
+        bindForSubMesh(world: Matrix, mesh: Mesh, subMesh: SubMesh): void;
+        getAnimatables(): IAnimatable[];
+        getActiveTextures(): BaseTexture[];
+        hasTexture(texture: BaseTexture): boolean;
+        dispose(forceDisposeEffect?: boolean): void;
+        clone(name: string): FurMaterial;
+        serialize(): any;
+        getClassName(): string;
+        static Parse(source: any, scene: Scene, rootUrl: string): FurMaterial;
+        static GenerateTexture(name: string, scene: Scene): DynamicTexture;
+        static FurifyMesh(sourceMesh: Mesh, quality: number): Mesh[];
+    }
+}
+
+
+declare module BABYLON {
+    class TerrainMaterial extends PushMaterial {
+        private _mixTexture;
+        mixTexture: BaseTexture;
+        private _diffuseTexture1;
+        diffuseTexture1: Texture;
+        private _diffuseTexture2;
+        diffuseTexture2: Texture;
+        private _diffuseTexture3;
+        diffuseTexture3: Texture;
+        private _bumpTexture1;
+        bumpTexture1: Texture;
+        private _bumpTexture2;
+        bumpTexture2: Texture;
+        private _bumpTexture3;
+        bumpTexture3: Texture;
+        diffuseColor: Color3;
+        specularColor: Color3;
+        specularPower: number;
+        private _disableLighting;
+        disableLighting: boolean;
+        private _maxSimultaneousLights;
+        maxSimultaneousLights: number;
+        private _renderId;
+        constructor(name: string, scene: Scene);
+        needAlphaBlending(): boolean;
+        needAlphaTesting(): boolean;
+        getAlphaTestTexture(): Nullable<BaseTexture>;
+        isReadyForSubMesh(mesh: AbstractMesh, subMesh: SubMesh, useInstances?: boolean): boolean;
+        bindForSubMesh(world: Matrix, mesh: Mesh, subMesh: SubMesh): void;
+        getAnimatables(): IAnimatable[];
+        getActiveTextures(): BaseTexture[];
+        hasTexture(texture: BaseTexture): boolean;
+        dispose(forceDisposeEffect?: boolean): void;
+        clone(name: string): TerrainMaterial;
+        serialize(): any;
+        getClassName(): string;
+        static Parse(source: any, scene: Scene, rootUrl: string): TerrainMaterial;
+    }
+}
+
+
+declare module BABYLON {
+    class TriPlanarMaterial extends PushMaterial {
+        mixTexture: BaseTexture;
+        private _diffuseTextureX;
+        diffuseTextureX: BaseTexture;
+        private _diffuseTextureY;
+        diffuseTextureY: BaseTexture;
+        private _diffuseTextureZ;
+        diffuseTextureZ: BaseTexture;
+        private _normalTextureX;
+        normalTextureX: BaseTexture;
+        private _normalTextureY;
+        normalTextureY: BaseTexture;
+        private _normalTextureZ;
+        normalTextureZ: BaseTexture;
+        tileSize: number;
+        diffuseColor: Color3;
+        specularColor: Color3;
+        specularPower: number;
+        private _disableLighting;
+        disableLighting: boolean;
+        private _maxSimultaneousLights;
+        maxSimultaneousLights: number;
+        private _renderId;
+        constructor(name: string, scene: Scene);
+        needAlphaBlending(): boolean;
+        needAlphaTesting(): boolean;
+        getAlphaTestTexture(): Nullable<BaseTexture>;
+        isReadyForSubMesh(mesh: AbstractMesh, subMesh: SubMesh, useInstances?: boolean): boolean;
+        bindForSubMesh(world: Matrix, mesh: Mesh, subMesh: SubMesh): void;
+        getAnimatables(): IAnimatable[];
+        getActiveTextures(): BaseTexture[];
+        hasTexture(texture: BaseTexture): boolean;
+        dispose(forceDisposeEffect?: boolean): void;
+        clone(name: string): TriPlanarMaterial;
+        serialize(): any;
+        getClassName(): string;
+        static Parse(source: any, scene: Scene, rootUrl: string): TriPlanarMaterial;
+    }
+}
+
+
+declare module BABYLON {
+    class SkyMaterial extends PushMaterial {
+        luminance: number;
+        turbidity: number;
+        rayleigh: number;
+        mieCoefficient: number;
+        mieDirectionalG: number;
+        distance: number;
+        inclination: number;
+        azimuth: number;
+        sunPosition: Vector3;
+        useSunPosition: boolean;
+        private _cameraPosition;
+        private _renderId;
+        constructor(name: string, scene: Scene);
+        needAlphaBlending(): boolean;
+        needAlphaTesting(): boolean;
+        getAlphaTestTexture(): Nullable<BaseTexture>;
+        isReadyForSubMesh(mesh: AbstractMesh, subMesh: SubMesh, useInstances?: boolean): boolean;
+        bindForSubMesh(world: Matrix, mesh: Mesh, subMesh: SubMesh): void;
+        getAnimatables(): IAnimatable[];
+        dispose(forceDisposeEffect?: boolean): void;
+        clone(name: string): SkyMaterial;
+        serialize(): any;
+        getClassName(): string;
+        static Parse(source: any, scene: Scene, rootUrl: string): SkyMaterial;
+    }
+}
+
+
+declare module BABYLON {
+    /**
+     * The grid materials allows you to wrap any shape with a grid.
+     * Colors are customizable.
+     */
+    class GridMaterial extends BABYLON.PushMaterial {
+        /**
+         * Main color of the grid (e.g. between lines)
+         */
+        mainColor: Color3;
+        /**
+         * Color of the grid lines.
+         */
+        lineColor: Color3;
+        /**
+         * The scale of the grid compared to unit.
+         */
+        gridRatio: number;
+        /**
+         * Allows setting an offset for the grid lines.
+         */
+        gridOffset: Vector3;
+        /**
+         * The frequency of thicker lines.
+         */
+        majorUnitFrequency: number;
+        /**
+         * The visibility of minor units in the grid.
+         */
+        minorUnitVisibility: number;
+        /**
+         * The grid opacity outside of the lines.
+         */
+        opacity: number;
+        /**
+         * Determine RBG output is premultiplied by alpha value.
+         */
+        preMultiplyAlpha: boolean;
+        private _gridControl;
+        private _renderId;
+        /**
+         * constructor
+         * @param name The name given to the material in order to identify it afterwards.
+         * @param scene The scene the material is used in.
+         */
+        constructor(name: string, scene: Scene);
+        /**
+         * Returns wehter or not the grid requires alpha blending.
+         */
+        needAlphaBlending(): boolean;
+        needAlphaBlendingForMesh(mesh: AbstractMesh): boolean;
+        isReadyForSubMesh(mesh: AbstractMesh, subMesh: SubMesh, useInstances?: boolean): boolean;
+        bindForSubMesh(world: Matrix, mesh: Mesh, subMesh: SubMesh): void;
+        dispose(forceDisposeEffect?: boolean): void;
+        clone(name: string): GridMaterial;
+        serialize(): any;
+        getClassName(): string;
+        static Parse(source: any, scene: Scene, rootUrl: string): GridMaterial;
+    }
+}
+
+
+declare module BABYLON {
+    class CustomShaderStructure {
+        FragmentStore: string;
+        VertexStore: string;
+        constructor();
+    }
+    class ShaderSpecialParts {
+        constructor();
+        Fragment_Begin: string;
+        Fragment_Definitions: string;
+        Fragment_MainBegin: string;
+        Fragment_Custom_Diffuse: string;
+        Fragment_Custom_Alpha: string;
+        Fragment_Before_FragColor: string;
+        Vertex_Begin: string;
+        Vertex_Definitions: string;
+        Vertex_MainBegin: string;
+        Vertex_Before_PositionUpdated: string;
+        Vertex_Before_NormalUpdated: string;
+    }
+    class CustomMaterial extends StandardMaterial {
+        static ShaderIndexer: number;
+        CustomParts: ShaderSpecialParts;
+        _isCreatedShader: boolean;
+        _createdShaderName: string;
+        _customUniform: string[];
+        _newUniforms: string[];
+        _newUniformInstances: any[];
+        _newSamplerInstances: Texture[];
+        FragmentShader: string;
+        VertexShader: string;
+        AttachAfterBind(mesh: Mesh, effect: Effect): void;
+        ReviewUniform(name: string, arr: string[]): string[];
+        Builder(shaderName: string, uniforms: string[], uniformBuffers: string[], samplers: string[], defines: StandardMaterialDefines): string;
+        constructor(name: string, scene: Scene);
+        AddUniform(name: string, kind: string, param: any): CustomMaterial;
+        Fragment_Begin(shaderPart: string): CustomMaterial;
+        Fragment_Definitions(shaderPart: string): CustomMaterial;
+        Fragment_MainBegin(shaderPart: string): CustomMaterial;
+        Fragment_Custom_Diffuse(shaderPart: string): CustomMaterial;
+        Fragment_Custom_Alpha(shaderPart: string): CustomMaterial;
+        Fragment_Before_FragColor(shaderPart: string): CustomMaterial;
+        Vertex_Begin(shaderPart: string): CustomMaterial;
+        Vertex_Definitions(shaderPart: string): CustomMaterial;
+        Vertex_MainBegin(shaderPart: string): CustomMaterial;
+        Vertex_Before_PositionUpdated(shaderPart: string): CustomMaterial;
+        Vertex_Before_NormalUpdated(shaderPart: string): CustomMaterial;
+    }
+}
+
+
+declare module BABYLON {
+    class CellMaterial extends PushMaterial {
+        private _diffuseTexture;
+        diffuseTexture: BaseTexture;
+        diffuseColor: Color3;
+        _computeHighLevel: boolean;
+        computeHighLevel: boolean;
+        private _disableLighting;
+        disableLighting: boolean;
+        private _maxSimultaneousLights;
+        maxSimultaneousLights: number;
+        private _renderId;
+        constructor(name: string, scene: Scene);
+        needAlphaBlending(): boolean;
+        needAlphaTesting(): boolean;
+        getAlphaTestTexture(): Nullable<BaseTexture>;
+        isReadyForSubMesh(mesh: AbstractMesh, subMesh: SubMesh, useInstances?: boolean): boolean;
+        bindForSubMesh(world: Matrix, mesh: Mesh, subMesh: SubMesh): void;
+        getAnimatables(): IAnimatable[];
+        getActiveTextures(): BaseTexture[];
+        hasTexture(texture: BaseTexture): boolean;
+        dispose(forceDisposeEffect?: boolean): void;
+        getClassName(): string;
+        clone(name: string): CellMaterial;
+        serialize(): any;
+        static Parse(source: any, scene: Scene, rootUrl: string): CellMaterial;
+    }
+}

+ 201 - 0
dist/preview release/postProcessesLibrary/babylonjs.postProcess.d.ts

@@ -0,0 +1,201 @@
+
+declare module BABYLON {
+    /**
+     * AsciiArtFontTexture is the helper class used to easily create your ascii art font texture.
+     *
+     * It basically takes care rendering the font front the given font size to a texture.
+     * This is used later on in the postprocess.
+     */
+    class AsciiArtFontTexture extends BaseTexture {
+        private _font;
+        private _text;
+        private _charSize;
+        /**
+         * Gets the size of one char in the texture (each char fits in size * size space in the texture).
+         */
+        readonly charSize: number;
+        /**
+         * Create a new instance of the Ascii Art FontTexture class
+         * @param name the name of the texture
+         * @param font the font to use, use the W3C CSS notation
+         * @param text the caracter set to use in the rendering.
+         * @param scene the scene that owns the texture
+         */
+        constructor(name: string, font: string, text: string, scene?: Nullable<Scene>);
+        /**
+         * Gets the max char width of a font.
+         * @param font the font to use, use the W3C CSS notation
+         * @return the max char width
+         */
+        private getFontWidth(font);
+        /**
+         * Gets the max char height of a font.
+         * @param font the font to use, use the W3C CSS notation
+         * @return the max char height
+         */
+        private getFontHeight(font);
+        /**
+         * Clones the current AsciiArtTexture.
+         * @return the clone of the texture.
+         */
+        clone(): AsciiArtFontTexture;
+        /**
+         * Parses a json object representing the texture and returns an instance of it.
+         * @param source the source JSON representation
+         * @param scene the scene to create the texture for
+         * @return the parsed texture
+         */
+        static Parse(source: any, scene: Scene): AsciiArtFontTexture;
+    }
+    /**
+     * Option available in the Ascii Art Post Process.
+     */
+    interface IAsciiArtPostProcessOptions {
+        /**
+         * The font to use following the w3c font definition.
+         */
+        font?: string;
+        /**
+         * The character set to use in the postprocess.
+         */
+        characterSet?: string;
+        /**
+         * This defines the amount you want to mix the "tile" or caracter space colored in the ascii art.
+         * This number is defined between 0 and 1;
+         */
+        mixToTile?: number;
+        /**
+         * This defines the amount you want to mix the normal rendering pass in the ascii art.
+         * This number is defined between 0 and 1;
+         */
+        mixToNormal?: number;
+    }
+    /**
+     * AsciiArtPostProcess helps rendering everithing in Ascii Art.
+     *
+     * Simmply add it to your scene and let the nerd that lives in you have fun.
+     * Example usage: var pp = new AsciiArtPostProcess("myAscii", "20px Monospace", camera);
+     */
+    class AsciiArtPostProcess extends PostProcess {
+        /**
+         * The font texture used to render the char in the post process.
+         */
+        private _asciiArtFontTexture;
+        /**
+         * This defines the amount you want to mix the "tile" or caracter space colored in the ascii art.
+         * This number is defined between 0 and 1;
+         */
+        mixToTile: number;
+        /**
+         * This defines the amount you want to mix the normal rendering pass in the ascii art.
+         * This number is defined between 0 and 1;
+         */
+        mixToNormal: number;
+        /**
+         * Instantiates a new Ascii Art Post Process.
+         * @param name the name to give to the postprocess
+         * @camera the camera to apply the post process to.
+         * @param options can either be the font name or an option object following the IAsciiArtPostProcessOptions format
+         */
+        constructor(name: string, camera: Camera, options?: string | IAsciiArtPostProcessOptions);
+    }
+}
+
+
+declare module BABYLON {
+    /**
+     * DigitalRainFontTexture is the helper class used to easily create your digital rain font texture.
+     *
+     * It basically takes care rendering the font front the given font size to a texture.
+     * This is used later on in the postprocess.
+     */
+    class DigitalRainFontTexture extends BaseTexture {
+        private _font;
+        private _text;
+        private _charSize;
+        /**
+         * Gets the size of one char in the texture (each char fits in size * size space in the texture).
+         */
+        readonly charSize: number;
+        /**
+         * Create a new instance of the Digital Rain FontTexture class
+         * @param name the name of the texture
+         * @param font the font to use, use the W3C CSS notation
+         * @param text the caracter set to use in the rendering.
+         * @param scene the scene that owns the texture
+         */
+        constructor(name: string, font: string, text: string, scene?: Nullable<Scene>);
+        /**
+         * Gets the max char width of a font.
+         * @param font the font to use, use the W3C CSS notation
+         * @return the max char width
+         */
+        private getFontWidth(font);
+        /**
+         * Gets the max char height of a font.
+         * @param font the font to use, use the W3C CSS notation
+         * @return the max char height
+         */
+        private getFontHeight(font);
+        /**
+         * Clones the current DigitalRainFontTexture.
+         * @return the clone of the texture.
+         */
+        clone(): DigitalRainFontTexture;
+        /**
+         * Parses a json object representing the texture and returns an instance of it.
+         * @param source the source JSON representation
+         * @param scene the scene to create the texture for
+         * @return the parsed texture
+         */
+        static Parse(source: any, scene: Scene): DigitalRainFontTexture;
+    }
+    /**
+     * Option available in the Digital Rain Post Process.
+     */
+    interface IDigitalRainPostProcessOptions {
+        /**
+         * The font to use following the w3c font definition.
+         */
+        font?: string;
+        /**
+         * This defines the amount you want to mix the "tile" or caracter space colored in the digital rain.
+         * This number is defined between 0 and 1;
+         */
+        mixToTile?: number;
+        /**
+         * This defines the amount you want to mix the normal rendering pass in the digital rain.
+         * This number is defined between 0 and 1;
+         */
+        mixToNormal?: number;
+    }
+    /**
+     * DigitalRainPostProcess helps rendering everithing in digital rain.
+     *
+     * Simmply add it to your scene and let the nerd that lives in you have fun.
+     * Example usage: var pp = new DigitalRainPostProcess("digitalRain", "20px Monospace", camera);
+     */
+    class DigitalRainPostProcess extends PostProcess {
+        /**
+         * The font texture used to render the char in the post process.
+         */
+        private _digitalRainFontTexture;
+        /**
+         * This defines the amount you want to mix the "tile" or caracter space colored in the digital rain.
+         * This number is defined between 0 and 1;
+         */
+        mixToTile: number;
+        /**
+         * This defines the amount you want to mix the normal rendering pass in the digital rain.
+         * This number is defined between 0 and 1;
+         */
+        mixToNormal: number;
+        /**
+         * Instantiates a new Digital Rain Post Process.
+         * @param name the name to give to the postprocess
+         * @camera the camera to apply the post process to.
+         * @param options can either be the font name or an option object following the IDigitalRainPostProcessOptions format
+         */
+        constructor(name: string, camera: Camera, options?: string | IDigitalRainPostProcessOptions);
+    }
+}

+ 155 - 0
dist/preview release/proceduralTexturesLibrary/babylonjs.proceduralTextures.d.ts

@@ -0,0 +1,155 @@
+
+declare module BABYLON {
+    class WoodProceduralTexture extends ProceduralTexture {
+        private _ampScale;
+        private _woodColor;
+        constructor(name: string, size: number, scene: Scene, fallbackTexture?: Texture, generateMipMaps?: boolean);
+        updateShaderUniforms(): void;
+        ampScale: number;
+        woodColor: Color3;
+    }
+}
+
+
+declare module BABYLON {
+    class FireProceduralTexture extends ProceduralTexture {
+        private _time;
+        private _speed;
+        private _autoGenerateTime;
+        private _fireColors;
+        private _alphaThreshold;
+        constructor(name: string, size: number, scene: Scene, fallbackTexture?: Texture, generateMipMaps?: boolean);
+        updateShaderUniforms(): void;
+        render(useCameraPostProcess?: boolean): void;
+        static readonly PurpleFireColors: Color3[];
+        static readonly GreenFireColors: Color3[];
+        static readonly RedFireColors: Color3[];
+        static readonly BlueFireColors: Color3[];
+        fireColors: Color3[];
+        time: number;
+        speed: Vector2;
+        alphaThreshold: number;
+    }
+}
+
+
+declare module BABYLON {
+    class CloudProceduralTexture extends ProceduralTexture {
+        private _skyColor;
+        private _cloudColor;
+        constructor(name: string, size: number, scene: Scene, fallbackTexture?: Texture, generateMipMaps?: boolean);
+        updateShaderUniforms(): void;
+        skyColor: Color4;
+        cloudColor: Color4;
+    }
+}
+
+
+declare module BABYLON {
+    class GrassProceduralTexture extends ProceduralTexture {
+        private _grassColors;
+        private _groundColor;
+        constructor(name: string, size: number, scene: Scene, fallbackTexture?: Texture, generateMipMaps?: boolean);
+        updateShaderUniforms(): void;
+        grassColors: Color3[];
+        groundColor: Color3;
+    }
+}
+
+
+declare module BABYLON {
+    class RoadProceduralTexture extends ProceduralTexture {
+        private _roadColor;
+        constructor(name: string, size: number, scene: Scene, fallbackTexture?: Texture, generateMipMaps?: boolean);
+        updateShaderUniforms(): void;
+        roadColor: Color3;
+    }
+}
+
+
+declare module BABYLON {
+    class BrickProceduralTexture extends ProceduralTexture {
+        private _numberOfBricksHeight;
+        private _numberOfBricksWidth;
+        private _jointColor;
+        private _brickColor;
+        constructor(name: string, size: number, scene: Scene, fallbackTexture?: Texture, generateMipMaps?: boolean);
+        updateShaderUniforms(): void;
+        numberOfBricksHeight: number;
+        numberOfBricksWidth: number;
+        jointColor: Color3;
+        brickColor: Color3;
+    }
+}
+
+
+declare module BABYLON {
+    class MarbleProceduralTexture extends ProceduralTexture {
+        private _numberOfTilesHeight;
+        private _numberOfTilesWidth;
+        private _amplitude;
+        private _jointColor;
+        constructor(name: string, size: number, scene: Scene, fallbackTexture?: Texture, generateMipMaps?: boolean);
+        updateShaderUniforms(): void;
+        numberOfTilesHeight: number;
+        amplitude: number;
+        numberOfTilesWidth: number;
+        jointColor: Color3;
+    }
+}
+
+
+declare module BABYLON {
+    class StarfieldProceduralTexture extends ProceduralTexture {
+        private _time;
+        private _alpha;
+        private _beta;
+        private _zoom;
+        private _formuparam;
+        private _stepsize;
+        private _tile;
+        private _brightness;
+        private _darkmatter;
+        private _distfading;
+        private _saturation;
+        constructor(name: string, size: number, scene: Scene, fallbackTexture?: Texture, generateMipMaps?: boolean);
+        updateShaderUniforms(): void;
+        time: number;
+        alpha: number;
+        beta: number;
+        formuparam: number;
+        stepsize: number;
+        zoom: number;
+        tile: number;
+        brightness: number;
+        darkmatter: number;
+        distfading: number;
+        saturation: number;
+    }
+}
+
+
+declare module BABYLON {
+    class NormalMapProceduralTexture extends ProceduralTexture {
+        private _baseTexture;
+        constructor(name: string, size: number, scene: Scene, fallbackTexture?: Texture, generateMipMaps?: boolean);
+        updateShaderUniforms(): void;
+        render(useCameraPostProcess?: boolean): void;
+        resize(size: any, generateMipMaps: any): void;
+        baseTexture: Texture;
+    }
+}
+
+
+declare module BABYLON {
+    class PerlinNoiseProceduralTexture extends ProceduralTexture {
+        time: number;
+        speed: number;
+        translationSpeed: number;
+        private _currentTranslation;
+        constructor(name: string, size: number, scene: Scene, fallbackTexture?: Texture, generateMipMaps?: boolean);
+        updateShaderUniforms(): void;
+        render(useCameraPostProcess?: boolean): void;
+        resize(size: any, generateMipMaps: any): void;
+    }
+}

+ 512 - 0
dist/preview release/serializers/babylonjs.serializers.d.ts

@@ -0,0 +1,512 @@
+
+declare module BABYLON {
+    class OBJExport {
+        static OBJ(mesh: Mesh[], materials?: boolean, matlibname?: string, globalposition?: boolean): string;
+        static MTL(mesh: Mesh): string;
+    }
+}
+
+
+declare module BABYLON {
+    /**
+     * Holds a collection of exporter options and parameters
+     */
+    interface IExporterOptions {
+        /**
+         * Function which indicates whether a babylon mesh should be exported or not.
+         * @param mesh - source Babylon mesh. It is used to check whether it should be
+         * exported to glTF or not.
+         * @returns boolean, which indicates whether the mesh should be exported (true) or not (false)
+         */
+        shouldExportMesh?(mesh: AbstractMesh): boolean;
+    }
+    /**
+     * Class for generating glTF data from a Babylon scene.
+     */
+    class GLTF2Export {
+        /**
+         * Exports the geometry of the scene to .gltf file format.
+         * @param scene - Babylon scene with scene hierarchy information.
+         * @param filePrefix - File prefix to use when generating the glTF file.
+         * @param options - Exporter options.
+         * @returns - Returns an object with a .gltf file and associates texture names
+         * as keys and their data and paths as values.
+         */
+        static GLTF(scene: Scene, filePrefix: string, options?: IExporterOptions): _GLTFData;
+        /**
+         * Exports the geometry of the scene to .glb file format.
+         * @param scene - Babylon scene with scene hierarchy information.
+         * @param filePrefix - File prefix to use when generating glb file.
+         * @param options - Exporter options.
+         * @returns - Returns an object with a .glb filename as key and data as value
+         */
+        static GLB(scene: Scene, filePrefix: string, options?: IExporterOptions): _GLTFData;
+    }
+}
+
+
+/**
+ * Module for the Babylon glTF 2.0 exporter.  Should ONLY be used internally.
+ * @ignore - capitalization of GLTF2 module.
+ */
+declare module BABYLON.GLTF2 {
+    /**
+     * Converts Babylon Scene into glTF 2.0.
+     */
+    class _Exporter {
+        /**
+         * Stores all generated buffer views, which represents views into the main glTF buffer data.
+         */
+        private bufferViews;
+        /**
+         * Stores all the generated accessors, which is used for accessing the data within the buffer views in glTF.
+         */
+        private accessors;
+        /**
+         * Stores all the generated nodes, which contains transform and/or mesh information per node.
+         */
+        private nodes;
+        /**
+         * Stores the glTF asset information, which represents the glTF version and this file generator.
+         */
+        private asset;
+        /**
+         * Stores all the generated glTF scenes, which stores multiple node hierarchies.
+         */
+        private scenes;
+        /**
+         * Stores all the generated mesh information, each containing a set of primitives to render in glTF.
+         */
+        private meshes;
+        /**
+         * Stores all the generated material information, which represents the appearance of each primitive.
+         */
+        private materials;
+        /**
+         * Stores all the generated texture information, which is referenced by glTF materials.
+         */
+        private textures;
+        /**
+         * Stores all the generated image information, which is referenced by glTF textures.
+         */
+        private images;
+        /**
+         * Stores the total amount of bytes stored in the glTF buffer.
+         */
+        private totalByteLength;
+        /**
+         * Stores a reference to the Babylon scene containing the source geometry and material information.
+         */
+        private babylonScene;
+        /**
+         * Stores the exporter options, which are optionally passed in from the glTF serializer.
+         */
+        private options?;
+        /**
+         * Stores a map of the image data, where the key is the file name and the value
+         * is the image data.
+         */
+        private imageData;
+        /**
+         * Stores a map of the unique id of a node to its index in the node array.
+         */
+        private nodeMap;
+        /**
+         * Stores the binary buffer used to store geometry data.
+         */
+        private binaryBuffer;
+        /**
+         * Specifies if the Babylon scene should be converted to right-handed on export.
+         */
+        private convertToRightHandedSystem;
+        /**
+         * Creates a glTF Exporter instance, which can accept optional exporter options.
+         * @param babylonScene - Babylon scene object
+         * @param options - Options to modify the behavior of the exporter.
+         */
+        constructor(babylonScene: Scene, options?: IExporterOptions);
+        /**
+         * Creates a buffer view based on teh supplied arguments
+         * @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, byteStride?, name?);
+        /**
+         * Creates an accessor based on the supplied arguments
+         * @param bufferviewIndex - The index of the bufferview referenced by this accessor.
+         * @param name - The name of the accessor.
+         * @param type - The type of the accessor.
+         * @param componentType - The datatype of components in the attribute.
+         * @param count - The number of attributes referenced by this accessor.
+         * @param byteOffset - The offset relative to the start of the bufferView in bytes.
+         * @param min - Minimum value of each component in this attribute.
+         * @param max - Maximum value of each component in this attribute.
+         * @returns - accessor for glTF
+         */
+        private createAccessor(bufferviewIndex, name, type, componentType, count, byteOffset, min, max);
+        /**
+         * Calculates the minimum and maximum values of an array of position floats.
+         * @param positions - Positions array of a mesh.
+         * @param vertexStart - Starting vertex offset to calculate min and max values.
+         * @param vertexCount - Number of vertices to check for min and max values.
+         * @returns - min number array and max number array.
+         */
+        private calculateMinMaxPositions(positions, vertexStart, vertexCount);
+        /**
+         * Converts a vector3 array to right-handed.
+         * @param vector - vector3 Array to convert to right-handed.
+         * @returns - right-handed Vector3 array.
+         */
+        private static GetRightHandedVector3(vector);
+        /**
+         * Converts a vector4 array to right-handed.
+         * @param vector - vector4 Array to convert to right-handed.
+         * @returns - right-handed vector4 array.
+         */
+        private static GetRightHandedVector4(vector);
+        /**
+         * Converts a quaternion to right-handed.
+         * @param quaternion - Source quaternion to convert to right-handed.
+         */
+        private static GetRightHandedQuaternion(quaternion);
+        /**
+         * Writes mesh attribute data to a data buffer.
+         * Returns the bytelength of the data.
+         * @param vertexBufferKind - Indicates what kind of vertex data is being passed in.
+         * @param meshAttributeArray - Array containing the attribute data.
+         * @param byteOffset - The offset to start counting bytes from.
+         * @param dataBuffer - The buffer to write the binary data to.
+         * @returns - Byte length of the attribute data.
+         */
+        private writeAttributeData(vertexBufferKind, meshAttributeArray, byteOffset, dataBuffer);
+        /**
+         * Generates glTF json data
+         * @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(shouldUseGlb, glTFPrefix?, prettyPrint?);
+        /**
+         * Generates data for .gltf and .bin files based on the glTF prefix string
+         * @param glTFPrefix - Text to use when prefixing a glTF file.
+         * @returns - GLTFData with glTF file data.
+         */
+        _generateGLTF(glTFPrefix: string): _GLTFData;
+        /**
+         * Creates a binary buffer for glTF
+         * @returns - array buffer for binary data
+         */
+        private generateBinary();
+        /**
+         * Pads the number to a multiple of 4
+         * @param num - number to pad
+         * @returns - padded number
+         */
+        private _getPadding(num);
+        /**
+         * 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 glTFPrefix
+         * @returns - object with glb filename as key and data as value
+         */
+        _generateGLB(glTFPrefix: string): _GLTFData;
+        /**
+         * Sets the TRS for each node
+         * @param node - glTF Node for storing the transformation data.
+         * @param babylonMesh - Babylon mesh used as the source for the transformation data.
+         */
+        private setNodeTransformation(node, babylonMesh);
+        /**
+         * 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 dataBuffer - The buffer to write the bufferview data to.
+         * @returns bytelength of the bufferview data.
+         */
+        private createBufferViewKind(kind, babylonMesh, byteOffset, dataBuffer);
+        /**
+         * 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 dataBuffer - Buffer to write the attribute data to.
+         * @returns - bytelength of the primitive attributes plus the passed in byteOffset.
+         */
+        private setPrimitiveAttributes(mesh, babylonMesh, byteOffset, dataBuffer);
+        /**
+         * Creates a glTF scene based on the array of meshes.
+         * Returns the the total byte offset.
+         * @param babylonScene - Babylon scene to get the mesh data from.
+         * @param byteOffset - Offset to start from in bytes.
+         * @returns bytelength + byteoffset
+         */
+        private createScene(babylonScene, byteOffset);
+        /**
+         * Creates a mapping of Node unique id to node index
+         * @param scene - Babylon Scene.
+         * @param byteOffset - The initial byte offset.
+         * @returns - Node mapping of unique id to index.
+         */
+        private createNodeMap(scene, byteOffset);
+        /**
+         * Creates a glTF node from a Babylon mesh.
+         * @param babylonMesh - Source Babylon mesh.
+         * @param byteOffset - The initial byte offset.
+         * @param dataBuffer - Buffer for storing geometry data.
+         * @returns - Object containing an INode and byteoffset.
+         */
+        private createNode(babylonMesh, byteOffset, dataBuffer);
+    }
+}
+
+
+declare module BABYLON {
+    /**
+     * Class for holding and downloading glTF file data
+     */
+    class _GLTFData {
+        /**
+         * Object which contains the file name as the key and its data as the value.
+         */
+        glTFFiles: {
+            [fileName: string]: string | Blob;
+        };
+        /**
+         * Initializes the glTF file object.
+         */
+        constructor();
+        /**
+         * Downloads the glTF data as files based on their names and data.
+         */
+        downloadFiles(): void;
+    }
+}
+
+
+declare module BABYLON.GLTF2 {
+    /**
+     * Utility methods for working with glTF material conversion properties.  This class should only be used internally.
+     */
+    class _GLTFMaterial {
+        /**
+         * Represents the dielectric specular values for R, G and B.
+         */
+        private static readonly _dielectricSpecular;
+        /**
+         * Allows the maximum specular power to be defined for material calculations.
+         */
+        private static _maxSpecularPower;
+        /**
+         * Numeric tolerance value
+         */
+        private static _epsilon;
+        /**
+         * Specifies if two colors are approximately equal in value.
+         * @param color1 - first color to compare to.
+         * @param color2 - second color to compare to.
+         * @param epsilon - threshold value
+         */
+        private static FuzzyEquals(color1, color2, epsilon);
+        /**
+         * Gets the materials from a Babylon scene and converts them to glTF materials.
+         * @param scene - babylonjs scene.
+         * @param mimeType - texture mime type.
+         * @param images - array of images.
+         * @param textures - array of textures.
+         * @param materials - array of materials.
+         * @param imageData - mapping of texture names to base64 textures
+         * @param hasTextureCoords - specifies if texture coordinates are present on the material.
+         */
+        static _ConvertMaterialsToGLTF(babylonMaterials: Material[], mimeType: ImageMimeType, images: IImage[], textures: ITexture[], materials: IMaterial[], imageData: {
+            [fileName: string]: {
+                data: Uint8Array;
+                mimeType: ImageMimeType;
+            };
+        }, hasTextureCoords: boolean): void;
+        /**
+         * Makes a copy of the glTF material without the texture parameters.
+         * @param originalMaterial - original glTF material.
+         * @returns glTF material without texture parameters
+         */
+        static _StripTexturesFromMaterial(originalMaterial: IMaterial): IMaterial;
+        /**
+         * Specifies if the material has any texture parameters present.
+         * @param material - glTF Material.
+         * @returns boolean specifying if texture parameters are present
+         */
+        static _HasTexturesPresent(material: IMaterial): boolean;
+        /**
+         * Converts a Babylon StandardMaterial to a glTF Metallic Roughness Material.
+         * @param babylonStandardMaterial
+         * @returns - glTF Metallic Roughness Material representation
+         */
+        static _ConvertToGLTFPBRMetallicRoughness(babylonStandardMaterial: StandardMaterial): IMaterialPbrMetallicRoughness;
+        /**
+         * Computes the metallic factor
+         * @param diffuse - diffused value
+         * @param specular - specular value
+         * @param oneMinusSpecularStrength - one minus the specular strength
+         * @returns - metallic value
+         */
+        static _SolveMetallic(diffuse: number, specular: number, oneMinusSpecularStrength: number): number;
+        /**
+         * Gets the glTF alpha mode from the Babylon Material
+         * @param babylonMaterial - Babylon Material
+         * @returns - The Babylon alpha mode value
+         */
+        static _GetAlphaMode(babylonMaterial: Material): MaterialAlphaMode;
+        /**
+         * Converts a Babylon Standard Material to a glTF Material.
+         * @param babylonStandardMaterial - BJS Standard Material.
+         * @param mimeType - mime type to use for the textures.
+         * @param images - array of glTF image interfaces.
+         * @param textures - array of glTF texture interfaces.
+         * @param materials - array of glTF material interfaces.
+         * @param imageData - map of image file name to data.
+         * @param hasTextureCoords - specifies if texture coordinates are present on the submesh to determine if textures should be applied.
+         */
+        static _ConvertStandardMaterial(babylonStandardMaterial: StandardMaterial, mimeType: ImageMimeType, images: IImage[], textures: ITexture[], materials: IMaterial[], imageData: {
+            [fileName: string]: {
+                data: Uint8Array;
+                mimeType: ImageMimeType;
+            };
+        }, hasTextureCoords: boolean): void;
+        /**
+         * Converts a Babylon PBR Metallic Roughness Material to a glTF Material.
+         * @param babylonPBRMetalRoughMaterial - BJS PBR Metallic Roughness Material.
+         * @param mimeType - mime type to use for the textures.
+         * @param images - array of glTF image interfaces.
+         * @param textures - array of glTF texture interfaces.
+         * @param materials - array of glTF material interfaces.
+         * @param imageData - map of image file name to data.
+         * @param hasTextureCoords - specifies if texture coordinates are present on the submesh to determine if textures should be applied.
+         */
+        static _ConvertPBRMetallicRoughnessMaterial(babylonPBRMetalRoughMaterial: PBRMetallicRoughnessMaterial, mimeType: ImageMimeType, images: IImage[], textures: ITexture[], materials: IMaterial[], imageData: {
+            [fileName: string]: {
+                data: Uint8Array;
+                mimeType: ImageMimeType;
+            };
+        }, hasTextureCoords: boolean): void;
+        /**
+         * Converts an image typed array buffer to a base64 image.
+         * @param buffer - typed array buffer.
+         * @param width - width of the image.
+         * @param height - height of the image.
+         * @param mimeType - mimetype of the image.
+         * @returns - base64 image string.
+         */
+        private static _CreateBase64FromCanvas(buffer, width, height, mimeType);
+        /**
+         * Generates a white texture based on the specified width and height.
+         * @param width - width of the texture in pixels.
+         * @param height - height of the texture in pixels.
+         * @param scene - babylonjs scene.
+         * @returns - white texture.
+         */
+        private static _CreateWhiteTexture(width, height, scene);
+        /**
+         * Resizes the two source textures to the same dimensions.  If a texture is null, a default white texture is generated.  If both textures are null, returns null.
+         * @param texture1 - first texture to resize.
+         * @param texture2 - second texture to resize.
+         * @param scene - babylonjs scene.
+         * @returns resized textures or null.
+         */
+        private static _ResizeTexturesToSameDimensions(texture1, texture2, scene);
+        /**
+         * Convert Specular Glossiness Textures to Metallic Roughness.
+         * See link below for info on the material conversions from PBR Metallic/Roughness and Specular/Glossiness
+         * @link https://github.com/KhronosGroup/glTF/blob/master/extensions/2.0/Khronos/KHR_materials_pbrSpecularGlossiness/examples/convert-between-workflows-bjs/js/babylon.pbrUtilities.js
+         * @param diffuseTexture - texture used to store diffuse information.
+         * @param specularGlossinessTexture - texture used to store specular and glossiness information.
+         * @param factors - specular glossiness material factors.
+         * @param mimeType - the mime type to use for the texture.
+         * @returns pbr metallic roughness interface or null.
+         */
+        private static _ConvertSpecularGlossinessTexturesToMetallicRoughness(diffuseTexture, specularGlossinessTexture, factors, mimeType);
+        /**
+         * Converts specular glossiness material properties to metallic roughness.
+         * @param specularGlossiness - interface with specular glossiness material properties.
+         * @returns - interface with metallic roughness material properties.
+         */
+        private static _ConvertSpecularGlossinessToMetallicRoughness(specularGlossiness);
+        /**
+         * Calculates the surface reflectance, independent of lighting conditions.
+         * @param color - Color source to calculate brightness from.
+         * @returns number representing the perceived brightness, or zero if color is undefined.
+         */
+        private static _GetPerceivedBrightness(color);
+        /**
+         * Returns the maximum color component value.
+         * @param color
+         * @returns maximum color component value, or zero if color is null or undefined.
+         */
+        private static _GetMaxComponent(color);
+        /**
+         * Convert a PBRMaterial (Metallic/Roughness) to Metallic Roughness factors.
+         * @param babylonPBRMaterial - BJS PBR Metallic Roughness Material.
+         * @param mimeType - mime type to use for the textures.
+         * @param images - array of glTF image interfaces.
+         * @param textures - array of glTF texture interfaces.
+         * @param glTFPbrMetallicRoughness - glTF PBR Metallic Roughness interface.
+         * @param imageData - map of image file name to data.
+         * @param hasTextureCoords - specifies if texture coordinates are present on the submesh to determine if textures should be applied.
+         * @returns - glTF PBR Metallic Roughness factors.
+         */
+        private static _ConvertMetalRoughFactorsToMetallicRoughness(babylonPBRMaterial, mimeType, images, textures, glTFPbrMetallicRoughness, imageData, hasTextureCoords);
+        /**
+         * Convert a PBRMaterial (Specular/Glossiness) to Metallic Roughness factors.
+         * @param babylonPBRMaterial - BJS PBR Metallic Roughness Material.
+         * @param mimeType - mime type to use for the textures.
+         * @param images - array of glTF image interfaces.
+         * @param textures - array of glTF texture interfaces.
+         * @param glTFPbrMetallicRoughness - glTF PBR Metallic Roughness interface.
+         * @param imageData - map of image file name to data.
+         * @param hasTextureCoords - specifies if texture coordinates are present on the submesh to determine if textures should be applied.
+         * @returns - glTF PBR Metallic Roughness factors.
+         */
+        private static _ConvertSpecGlossFactorsToMetallicRoughness(babylonPBRMaterial, mimeType, images, textures, glTFPbrMetallicRoughness, imageData, hasTextureCoords);
+        /**
+         * Converts a Babylon PBR Metallic Roughness Material to a glTF Material.
+         * @param babylonPBRMaterial - BJS PBR Metallic Roughness Material.
+         * @param mimeType - mime type to use for the textures.
+         * @param images - array of glTF image interfaces.
+         * @param textures - array of glTF texture interfaces.
+         * @param materials - array of glTF material interfaces.
+         * @param imageData - map of image file name to data.
+         * @param hasTextureCoords - specifies if texture coordinates are present on the submesh to determine if textures should be applied.
+         */
+        static _ConvertPBRMaterial(babylonPBRMaterial: PBRMaterial, mimeType: ImageMimeType, images: IImage[], textures: ITexture[], materials: IMaterial[], imageData: {
+            [fileName: string]: {
+                data: Uint8Array;
+                mimeType: ImageMimeType;
+            };
+        }, hasTextureCoords: boolean): void;
+        /**
+         * Extracts a texture from a Babylon texture into file data and glTF data.
+         * @param babylonTexture - Babylon texture to extract.
+         * @param mimeType - Mime Type of the babylonTexture.
+         * @param images - Array of glTF images.
+         * @param textures - Array of glTF textures.
+         * @param imageData - map of image file name and data.
+         * @return - glTF texture info, or null if the texture format is not supported.
+         */
+        private static _ExportTexture(babylonTexture, mimeType, images, textures, imageData);
+        /**
+         * Builds a texture from base64 string.
+         * @param base64Texture - base64 texture string.
+         * @param textureName - Name to use for the texture.
+         * @param mimeType - image mime type for the texture.
+         * @param images - array of images.
+         * @param textures - array of textures.
+         * @param imageData - map of image data.
+         * @returns - glTF texture info, or null if the texture format is not supported.
+         */
+        private static _GetTextureInfoFromBase64(base64Texture, textureName, mimeType, images, textures, imageData);
+    }
+}

+ 2 - 0
dist/preview release/serializers/babylonjs.serializers.module.d.ts

@@ -1,3 +1,5 @@
+/// <reference types="babylonjs"/>
+/// <reference types="babylonjs-gltf2interface"/>
 
 
 declare module 'babylonjs-serializers' { 

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


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


+ 3 - 1
dist/preview release/what's new.md

@@ -13,7 +13,7 @@
 - Added [VideoDome](http://doc.babylonjs.com/how_to/360videodome) class to easily support 360 videos. Demo [here](https://www.babylonjs-playground.com/frame.html#1E9JQ8#7) ([DavidHGillen](https://github.com/DavidHGillen))
 - Added [GlowLayer](https://doc.babylonjs.com/how_to/glow_layer) to easily support glow from emissive materials. Demo [here](http://www.babylonjs.com/demos/GlowLayer/) ([sebavan](https://github.com/sebavan))
 - New [AssetContainer](http://doc.babylonjs.com/how_to/how_to_use_assetcontainer) class and loading methods ([trevordev](https://github.com/trevordev))
-- Added [depth of field](https://www.babylonjs-playground.com/frame.html#8F5HYV#9), [sharpening, MSAA, chromatic aberration and grain effect](https://www.babylonjs-playground.com/#Y3C0HQ#146) to the default pipeline ([trevordev](https://github.com/trevordev))
+- Added [depth of field](https://www.babylonjs-playground.com/frame.html#8F5HYV#9), [MSAA, sharpening, chromatic aberration and grain effect](https://www.babylonjs-playground.com/#Y3C0HQ#146) to the default pipeline ([trevordev](https://github.com/trevordev))
 - Added support for [animation weights](http://doc.babylonjs.com/babylon101/animations#animation-weights). Demo [here](https://www.babylonjs-playground.com/#IQN716#9) ([deltakosh](https://github.com/deltakosh))
 - Added [sub emitters for particle system](http://doc.babylonjs.com/babylon101/particles#sub-emitters) which will spawn new particle systems when particles dies. Demo [here](https://www.babylonjs-playground.com/frame.html#9NHBCC#1) ([IbraheemOsama](https://github.com/IbraheemOsama))
 - New [Babylon.js](http://doc.babylonjs.com/resources/maya) and [glTF](http://doc.babylonjs.com/resources/maya_to_gltf) exporter for Autodesk Maya ([Noalak](https://github.com/Noalak))
@@ -23,6 +23,7 @@
 - Introduces [PCF](https://doc.babylonjs.com/babylon101/shadows#percentage-closer-filtering-webgl2-only) and [PCSS](https://doc.babylonjs.com/babylon101/shadows#contact-hardening-shadow-webgl2-only) shadow support in Webgl 2 ([sebavan](https://github.com/sebavan)))
 
 ## Documentation
+
 - Tons of functions and classes received the code comments they deserved (All the community with a special thanks to [John King](https://github.com/BabylonJSGuide))
 - Moved the class API documentation to Typedoc ([deltakosh](https://github.com/deltakosh))
 
@@ -108,6 +109,7 @@
 - Earcut is an external, optional dependency. ([RaananW](https://github.com/RaananW))
 - Return animation groups when calling `SceneLoader.ImportMesh`. ([bghgary](https://github.com/bghgary)]
 - Add support for normalized and non-float data to `Buffer` and `VertexBuffer`. ([bghgary](https://github.com/bghgary)]
+- Added unlit material extension support to glTF 2.0 loader. ([bghgary](https://github.com/bghgary))
 
 ## Bug fixes
 

+ 15 - 2
inspector/src/adapters/CameraAdapter.ts

@@ -29,14 +29,27 @@ module INSPECTOR {
         
         public getTools() : Array<AbstractTreeTool> {
             let tools = [];
-            // tools.push(new Checkbox(this));
             tools.push(new CameraPOV(this));
             return tools;
         }
 
+        // Set the point of view of the chosen camera
         public setPOV() {
-           (this._obj as BABYLON.Camera).getScene().activeCamera = this._obj;
+           (this._obj as BABYLON.Camera).getScene().switchActiveCamera(this._obj);
         }
+
+        // Return the name of the current active camera
+        public getCurrentActiveCamera() {
+            let activeCamera = (this._obj as BABYLON.Camera).getScene().activeCamera;
+            if(activeCamera != null)
+            {
+                return activeCamera.name;
+            }else{
+                return "0";
+            }
+        }
+
+
         
     }
 }

+ 0 - 18
inspector/src/tabs/SceneTab.ts

@@ -67,24 +67,6 @@ module INSPECTOR {
                 wireframe.addEventListener('click', () => { this._inspector.scene.forcePointsCloud = false; this._inspector.scene.forceWireframe = true; });
                 solid.addEventListener('click', () => { this._inspector.scene.forcePointsCloud = false; this._inspector.scene.forceWireframe = false; });
 
-                // Cameras
-                title = Helpers.CreateDiv('actions-title', this._actions);
-                title.textContent = 'Cameras';
-                let cameraRadioButtons = [];
-                for (let camera of this._inspector.scene.cameras) {
-                    let cameraRadio = Helpers.CreateDiv('action-radio', this._actions);
-                    cameraRadio.textContent = camera.name;
-                    if(this._inspector.scene.activeCamera == camera)
-                    {
-                        cameraRadio.classList.add('active');
-                    }
-                    cameraRadioButtons.push(cameraRadio);
-                    cameraRadio.addEventListener('click', () => { this._inspector.scene.switchActiveCamera(camera);});
-                }
-
-                this._generateRadioAction(cameraRadioButtons);
-                
-
                 // Textures
                 title = Helpers.CreateDiv('actions-title', this._actions);
                 title.textContent = 'Textures channels';

+ 26 - 10
inspector/src/treetools/CameraPOV.ts

@@ -1,7 +1,9 @@
 module INSPECTOR {
 
     export interface ICameraPOV {
-        setPOV: () => void
+        setPOV: () => void,
+        getCurrentActiveCamera: () => string,
+        id: () => string
     }
 
     /**
@@ -13,7 +15,16 @@ module INSPECTOR {
         constructor(camera: ICameraPOV) {
             super();
             this.cameraPOV = camera;
-            this._elem.classList.add('fa-video-camera');
+
+            // Setting the id of the line with the name of the camera
+            this._elem.id = this.cameraPOV.id();
+
+            // Put the right icon 
+            if(this._elem.id == this.cameraPOV.getCurrentActiveCamera()){
+                this._elem.classList.add('fa-check-circle');
+            }else{
+                this._elem.classList.add('fa-circle');
+            }
         }
 
         protected action() {
@@ -22,18 +33,23 @@ module INSPECTOR {
         }
 
         private _gotoPOV() {
-
-            let actives = Inspector.DOCUMENT.querySelectorAll(".fa-video-camera.active");
-            console.log(actives);
+            // Uncheck all the radio buttons
+            let actives = Inspector.DOCUMENT.querySelectorAll(".fa-check-circle");
             for (let i = 0; i < actives.length; i++) {
-                actives[i].classList.remove('active');
+                actives[i].classList.remove('fa-check-circle');
+                actives[i].classList.add('fa-circle');
             }
-            //if (this._on) {
-                // set icon camera
-                this._elem.classList.add('active');
-            //}
+            
+            // setting the point off view to the right camera
             this.cameraPOV.setPOV();
 
+            // Check the right radio button
+            if(this._elem.id == this.cameraPOV.getCurrentActiveCamera())
+            {
+                this._elem.classList.remove('fa-circle');
+                this._elem.classList.add('fa-check-circle');
+            }
+
         }
     }
 }

+ 6 - 6
inspector/test/index.js

@@ -36,17 +36,17 @@ var Test = (function () {
         var scene = new BABYLON.Scene(this.engine);
         var canvas = scene.getEngine().getRenderingCanvas();
 
-        var camera = new BABYLON.FreeCamera("Camera", new BABYLON.Vector3(0, 0, 0), scene); 
+        var camera = new BABYLON.FreeCamera("Camera", new BABYLON.Vector3(0, 2, -2), scene); 
         
-        var camera2 = new BABYLON.ArcRotateCamera("Camera2", 0, 0, -0.1, new BABYLON.Vector3(0, 0, 0), scene);
+        var camera2 = new BABYLON.ArcRotateCamera("Camera2", 0, 0, 5, new BABYLON.Vector3(0, 0, 0), scene);
 
-        var camera3 = new BABYLON.ArcRotateCamera("Camera3", 0, 0, -0.1, new BABYLON.Vector3(0, 0, 0), scene);
+        var camera3 = new BABYLON.ArcRotateCamera("Camera3", 0, 0, 10, new BABYLON.Vector3(0, 0, 0), scene);
 
-        var camera4 = new BABYLON.ArcRotateCamera("Camera4", 0, 0, -0.1, new BABYLON.Vector3(0, 0, 0), scene);
+        var camera4 = new BABYLON.ArcRotateCamera("Camera4", 0, 0, 15, new BABYLON.Vector3(0, 0, 0), scene);
 
-        var camera5 = new BABYLON.ArcRotateCamera("Camera5", 0, 0, -0.1, new BABYLON.Vector3(0, 0, 0), scene);
+        var camera5 = new BABYLON.ArcRotateCamera("Camera5", 0, 0, 20, new BABYLON.Vector3(0, 0, 0), scene);
 
-        var camera6 = new BABYLON.ArcRotateCamera("Camera6", 0, 0, -0.1, new BABYLON.Vector3(0, 0, 0), scene);
+        var camera6 = new BABYLON.ArcRotateCamera("Camera6", 0, 0, 25, new BABYLON.Vector3(0, 0, 0), scene);
 
         scene.activeCamera = camera2;
         

+ 9 - 9
loaders/src/glTF/2.0/Extensions/KHR_lights.ts

@@ -35,12 +35,12 @@ module BABYLON.GLTF2.Extensions {
         public readonly name = NAME;
 
         protected _loadSceneAsync(context: string, scene: ILoaderScene): Nullable<Promise<void>> { 
-            return this._loadExtensionAsync<ILightReference>(context, scene, (context, extension) => {
-                const promise = this._loader._loadSceneAsync(context, scene);
+            return this._loadExtensionAsync<ILightReference>(context, scene, (extensionContext, extension) => {
+                const promise = this._loader._loadSceneAsync(extensionContext, scene);
 
-                const light = GLTFLoader._GetProperty(context, this._lights, extension.light);
+                const light = GLTFLoader._GetProperty(extensionContext, this._lights, extension.light);
                 if (light.type !== LightType.AMBIENT) {
-                    throw new Error(`${context}: Only ambient lights are allowed on a scene`);
+                    throw new Error(`${extensionContext}: Only ambient lights are allowed on a scene`);
                 }
 
                 this._loader._babylonScene.ambientColor = light.color ? Color3.FromArray(light.color) : Color3.Black();
@@ -50,16 +50,16 @@ module BABYLON.GLTF2.Extensions {
         }
 
         protected _loadNodeAsync(context: string, node: ILoaderNode): Nullable<Promise<void>> { 
-            return this._loadExtensionAsync<ILightReference>(context, node, (context, extension) => {
-                const promise = this._loader._loadNodeAsync(context, node);
+            return this._loadExtensionAsync<ILightReference>(context, node, (extensionContext, extension) => {
+                const promise = this._loader._loadNodeAsync(extensionContext, node);
 
                 let babylonLight: Light;
 
-                const light = GLTFLoader._GetProperty(context, this._lights, extension.light);
+                const light = GLTFLoader._GetProperty(extensionContext, this._lights, extension.light);
                 const name = node._babylonMesh!.name;
                 switch (light.type) {
                     case LightType.AMBIENT: {
-                        throw new Error(`${context}: Ambient lights are not allowed on a node`);
+                        throw new Error(`${extensionContext}: Ambient lights are not allowed on a node`);
                     }
                     case LightType.DIRECTIONAL: {
                         babylonLight = new DirectionalLight(name, Vector3.Forward(), this._loader._babylonScene);
@@ -78,7 +78,7 @@ module BABYLON.GLTF2.Extensions {
                         break;
                     }
                     default: {
-                        throw new Error(`${context}: Invalid light type (${light.type})`);
+                        throw new Error(`${extensionContext}: Invalid light type (${light.type})`);
                     }
                 }
 

+ 2 - 2
loaders/src/glTF/2.0/Extensions/KHR_materials_pbrSpecularGlossiness.ts

@@ -17,7 +17,7 @@ module BABYLON.GLTF2.Extensions {
         public readonly name = NAME;
 
         protected _loadMaterialAsync(context: string, material: ILoaderMaterial, babylonMesh: Mesh, babylonDrawMode: number, assign: (babylonMaterial: Material) => void): Nullable<Promise<void>> {
-            return this._loadExtensionAsync<IKHRMaterialsPbrSpecularGlossiness>(context, material, (context, extension) => {
+            return this._loadExtensionAsync<IKHRMaterialsPbrSpecularGlossiness>(context, material, (extensionContext, extension) => {
                 material._babylonData = material._babylonData || {};
                 let babylonData = material._babylonData[babylonDrawMode];
                 if (!babylonData) {
@@ -27,7 +27,7 @@ module BABYLON.GLTF2.Extensions {
                     const babylonMaterial = this._loader._createMaterial(PBRMaterial, name, babylonDrawMode);
 
                     promises.push(this._loader._loadMaterialBasePropertiesAsync(context, material, babylonMaterial));
-                    promises.push(this._loadSpecularGlossinessPropertiesAsync(context, material, extension, babylonMaterial));
+                    promises.push(this._loadSpecularGlossinessPropertiesAsync(extensionContext, material, extension, babylonMaterial));
 
                     this._loader.onMaterialLoadedObservable.notifyObservers(babylonMaterial);
 

+ 76 - 0
loaders/src/glTF/2.0/Extensions/KHR_materials_unlit.ts

@@ -0,0 +1,76 @@
+/// <reference path="../../../../../dist/preview release/babylon.d.ts"/>
+
+module BABYLON.GLTF2.Extensions {
+    // https://github.com/donmccurdy/glTF/tree/feat-khr-materials-cmnConstant/extensions/2.0/Khronos/KHR_materials_unlit
+
+    const NAME = "KHR_materials_unlit";
+
+    export class KHR_materials_unlit extends GLTFLoaderExtension {
+        public readonly name = NAME;
+
+        protected _loadMaterialAsync(context: string, material: ILoaderMaterial, babylonMesh: Mesh, babylonDrawMode: number, assign: (babylonMaterial: Material) => void): Nullable<Promise<void>> {
+            return this._loadExtensionAsync<{}>(context, material, () => {
+                material._babylonData = material._babylonData || {};
+                let babylonData = material._babylonData[babylonDrawMode];
+                if (!babylonData) {
+                    const name = material.name || `materialUnlit_${material._index}`;
+                    const babylonMaterial = this._loader._createMaterial(PBRMaterial, name, babylonDrawMode);
+                    babylonMaterial.unlit = true;
+
+                    const promise = this._loadUnlitPropertiesAsync(context, material, babylonMaterial);
+
+                    this._loader.onMaterialLoadedObservable.notifyObservers(babylonMaterial);
+
+                    babylonData = {
+                        material: babylonMaterial,
+                        meshes: [],
+                        loaded: promise
+                    };
+
+                    material._babylonData[babylonDrawMode] = babylonData;
+                }
+
+                babylonData.meshes.push(babylonMesh);
+
+                assign(babylonData.material);
+                return babylonData.loaded;
+            });
+        }
+
+        private _loadUnlitPropertiesAsync(context: string, material: ILoaderMaterial, babylonMaterial: PBRMaterial): Promise<void> {
+            const promises = new Array<Promise<void>>();
+
+            // Ensure metallic workflow
+            babylonMaterial.metallic = 1;
+            babylonMaterial.roughness = 1;
+
+            const properties = material.pbrMetallicRoughness;
+            if (properties) {
+                if (properties.baseColorFactor) {
+                    babylonMaterial.albedoColor = Color3.FromArray(properties.baseColorFactor);
+                    babylonMaterial.alpha = properties.baseColorFactor[3];
+                }
+                else {
+                    babylonMaterial.albedoColor = Color3.White();
+                }
+
+                if (properties.baseColorTexture) {
+                    promises.push(this._loader._loadTextureAsync(`${context}/baseColorTexture`, properties.baseColorTexture, texture => {
+                        babylonMaterial.albedoTexture = texture;
+                    }));
+                }
+            }
+
+            if (material.doubleSided) {
+                babylonMaterial.backFaceCulling = false;
+                babylonMaterial.twoSidedLighting = true;
+            }
+
+            this._loader._loadMaterialAlphaProperties(context, material, babylonMaterial);
+
+            return Promise.all(promises).then(() => {});
+        }
+    }
+
+    GLTFLoader._Register(NAME, loader => new KHR_materials_unlit(loader));
+}

+ 4 - 4
loaders/src/glTF/2.0/Extensions/MSFT_lod.ts

@@ -24,10 +24,10 @@ module BABYLON.GLTF2.Extensions {
         private _loadMaterialSignals: { [materialIndex: number]: Deferred<void> } = {};
 
         protected _loadNodeAsync(context: string, node: ILoaderNode): Nullable<Promise<void>> {
-            return this._loadExtensionAsync<IMSFTLOD>(context, node, (context, extension) => {
+            return this._loadExtensionAsync<IMSFTLOD>(context, node, (extensionContext, extension) => {
                 let firstPromise: Promise<void>;
 
-                const nodeLODs = this._getLODs(context, node, this._loader._gltf.nodes, extension.ids);
+                const nodeLODs = this._getLODs(extensionContext, node, this._loader._gltf.nodes, extension.ids);
                 for (let indexLOD = 0; indexLOD < nodeLODs.length; indexLOD++) {
                     const nodeLOD = nodeLODs[indexLOD];
 
@@ -77,10 +77,10 @@ module BABYLON.GLTF2.Extensions {
                 return null;
             }
 
-            return this._loadExtensionAsync<IMSFTLOD>(context, material, (context, extension) => {
+            return this._loadExtensionAsync<IMSFTLOD>(context, material, (extensionContext, extension) => {
                 let firstPromise: Promise<void>;
 
-                const materialLODs = this._getLODs(context, material, this._loader._gltf.materials, extension.ids);
+                const materialLODs = this._getLODs(extensionContext, material, this._loader._gltf.materials, extension.ids);
                 for (let indexLOD = 0; indexLOD < materialLODs.length; indexLOD++) {
                     const materialLOD = materialLODs[indexLOD];
 

+ 1 - 1
loaders/src/glTF/2.0/babylon.glTFLoaderExtension.ts

@@ -35,7 +35,7 @@ module BABYLON.GLTF2 {
         // #endregion
 
         /** Helper method called by a loader extension to load an glTF extension. */
-        protected _loadExtensionAsync<TProperty, TResult = void>(context: string, property: IProperty, actionAsync: (context: string, extension: TProperty) => Promise<TResult>): Nullable<Promise<TResult>> {
+        protected _loadExtensionAsync<TProperty, TResult = void>(context: string, property: IProperty, actionAsync: (extensionContext: string, extension: TProperty) => Promise<TResult>): Nullable<Promise<TResult>> {
             if (!property.extensions) {
                 return null;
             }

+ 4 - 1
src/Bones/babylon.skeleton.ts

@@ -370,7 +370,10 @@
 
             serializationObject.name = this.name;
             serializationObject.id = this.id;
-            serializationObject.dimensionsAtRest = this.dimensionsAtRest.asArray();
+
+            if (this.dimensionsAtRest) {
+                serializationObject.dimensionsAtRest = this.dimensionsAtRest.asArray();
+            }
 
             serializationObject.bones = [];
 

+ 101 - 0
src/Debug/babylon.axesViewer.ts

@@ -0,0 +1,101 @@
+/**
+ * Module Debug contains the (visual) components to debug a scene correctly
+ */
+module BABYLON.Debug {
+
+    /**
+     * The Axes viewer will show 3 axes in a specific point in space
+     */
+    export class AxesViewer {
+
+        private _xline = [Vector3.Zero(), Vector3.Zero()];
+        private _yline = [Vector3.Zero(), Vector3.Zero()];
+        private _zline = [Vector3.Zero(), Vector3.Zero()];
+
+        private _xmesh: Nullable<LinesMesh>;
+        private _ymesh: Nullable<LinesMesh>;
+        private _zmesh: Nullable<LinesMesh>;
+
+        public scene: Nullable<Scene>;
+        public scaleLines = 1;
+
+        constructor(scene: Scene, scaleLines = 1) {
+
+            this.scaleLines = scaleLines;
+
+            this._xmesh = Mesh.CreateLines("xline", this._xline, scene, true);
+            this._ymesh = Mesh.CreateLines("yline", this._yline, scene, true);
+            this._zmesh = Mesh.CreateLines("zline", this._zline, scene, true);
+
+            this._xmesh.renderingGroupId = 2;
+            this._ymesh.renderingGroupId = 2;
+            this._zmesh.renderingGroupId = 2;
+
+            this._xmesh.material.checkReadyOnlyOnce = true;
+            this._xmesh.color = new Color3(1, 0, 0);
+            this._ymesh.material.checkReadyOnlyOnce = true;
+            this._ymesh.color = new Color3(0, 1, 0);
+            this._zmesh.material.checkReadyOnlyOnce = true;
+            this._zmesh.color = new Color3(0, 0, 1);
+
+            this.scene = scene;
+
+        }
+
+        public update(position: Vector3, xaxis: Vector3, yaxis: Vector3, zaxis: Vector3): void {
+
+            var scaleLines = this.scaleLines;
+
+            if (this._xmesh) {
+                this._xmesh.position.copyFrom(position);
+            }
+            if (this._ymesh) {
+                this._ymesh.position.copyFrom(position);
+            }
+            if (this._zmesh) {
+                this._zmesh.position.copyFrom(position);
+            }
+
+            var point2 = this._xline[1];
+            point2.x = xaxis.x * scaleLines;
+            point2.y = xaxis.y * scaleLines;
+            point2.z = xaxis.z * scaleLines;
+            Mesh.CreateLines("", this._xline, null, false, this._xmesh);
+
+            point2 = this._yline[1];
+            point2.x = yaxis.x * scaleLines;
+            point2.y = yaxis.y * scaleLines;
+            point2.z = yaxis.z * scaleLines;
+            Mesh.CreateLines("", this._yline, null, false, this._ymesh);
+
+            point2 = this._zline[1];
+            point2.x = zaxis.x * scaleLines;
+            point2.y = zaxis.y * scaleLines;
+            point2.z = zaxis.z * scaleLines;
+            Mesh.CreateLines("", this._zline, null, false, this._zmesh);
+
+        }
+
+        public dispose() {
+
+            if (this._xmesh) {
+                this._xmesh.dispose();
+            }
+
+            if (this._ymesh) {
+                this._ymesh.dispose();
+            }
+
+            if (this._zmesh) {
+                this._zmesh.dispose();
+            }
+
+            this._xmesh = null;
+            this._ymesh = null;
+            this._zmesh = null;
+
+            this.scene = null;
+        }
+
+    }
+}

+ 53 - 0
src/Debug/babylon.boneAxesViewer.ts

@@ -0,0 +1,53 @@
+module BABYLON.Debug {
+
+    /**
+     * The BoneAxesViewer will attach 3 axes to a specific bone of a specific mesh
+     */
+    export class BoneAxesViewer extends AxesViewer {
+
+        public mesh: Nullable<Mesh>;
+        public bone: Nullable<Bone>;
+
+        public pos = Vector3.Zero();
+        public xaxis = Vector3.Zero();
+        public yaxis = Vector3.Zero();
+        public zaxis = Vector3.Zero();
+
+        constructor(scene: Scene, bone: Bone, mesh: Mesh, scaleLines = 1) {
+
+            super(scene, scaleLines);
+
+            this.mesh = mesh;
+            this.bone = bone;
+
+        }
+
+        public update(): void {
+
+            if (!this.mesh || !this.bone) {
+                return;
+            }
+
+            var bone = this.bone;
+            bone.getAbsolutePositionToRef(this.mesh, this.pos);
+            bone.getDirectionToRef(Axis.X, this.mesh, this.xaxis);
+            bone.getDirectionToRef(Axis.Y, this.mesh, this.yaxis);
+            bone.getDirectionToRef(Axis.Z, this.mesh, this.zaxis);
+
+            super.update(this.pos, this.xaxis, this.yaxis, this.zaxis);
+
+        }
+
+        public dispose() {
+
+            if (this.mesh) {
+                this.mesh = null;
+                this.bone = null;
+
+                super.dispose();
+
+            }
+        }
+
+    }
+}

+ 0 - 461
src/Debug/babylon.debugModules.ts

@@ -1,461 +0,0 @@
-module BABYLON {
-    export class Debug {
-        public static AxesViewer = class AxesViewer {
-            _xline = [Vector3.Zero(), Vector3.Zero()];
-            _yline = [Vector3.Zero(), Vector3.Zero()];
-            _zline = [Vector3.Zero(), Vector3.Zero()];
-
-            _xmesh: Nullable<LinesMesh>;
-            _ymesh: Nullable<LinesMesh>;
-            _zmesh: Nullable<LinesMesh>;
-
-            public scene: Nullable<Scene>;
-            public scaleLines = 1;
-
-            constructor(scene: Scene, scaleLines = 1) {
-
-                this.scaleLines = scaleLines;
-
-                this._xmesh = Mesh.CreateLines("xline", this._xline, scene, true);
-                this._ymesh = Mesh.CreateLines("yline", this._yline, scene, true);
-                this._zmesh = Mesh.CreateLines("zline", this._zline, scene, true);
-
-                this._xmesh.renderingGroupId = 2;
-                this._ymesh.renderingGroupId = 2;
-                this._zmesh.renderingGroupId = 2;
-
-                this._xmesh.material.checkReadyOnlyOnce = true;
-                this._xmesh.color = new Color3(1, 0, 0);
-                this._ymesh.material.checkReadyOnlyOnce = true;
-                this._ymesh.color = new Color3(0, 1, 0);
-                this._zmesh.material.checkReadyOnlyOnce = true;
-                this._zmesh.color = new Color3(0, 0, 1);
-
-                this.scene = scene;
-
-            }
-
-            public update(position: Vector3, xaxis: Vector3, yaxis: Vector3, zaxis: Vector3): void {
-
-                var scaleLines = this.scaleLines;
-
-                if (this._xmesh) {
-                    this._xmesh.position.copyFrom(position);
-                }
-                if (this._ymesh) {
-                    this._ymesh.position.copyFrom(position);
-                }
-                if (this._zmesh) {
-                    this._zmesh.position.copyFrom(position);
-                }
-
-                var point2 = this._xline[1];
-                point2.x = xaxis.x * scaleLines;
-                point2.y = xaxis.y * scaleLines;
-                point2.z = xaxis.z * scaleLines;
-                Mesh.CreateLines("", this._xline, null, false, this._xmesh);
-
-                point2 = this._yline[1];
-                point2.x = yaxis.x * scaleLines;
-                point2.y = yaxis.y * scaleLines;
-                point2.z = yaxis.z * scaleLines;
-                Mesh.CreateLines("", this._yline, null, false, this._ymesh);
-
-                point2 = this._zline[1];
-                point2.x = zaxis.x * scaleLines;
-                point2.y = zaxis.y * scaleLines;
-                point2.z = zaxis.z * scaleLines;
-                Mesh.CreateLines("", this._zline, null, false, this._zmesh);
-
-            }
-
-            public dispose() {
-
-                if (this._xmesh) {
-                    this._xmesh.dispose();
-                }
-
-                if (this._ymesh) {
-                    this._ymesh.dispose();
-                }
-
-                if (this._zmesh) {
-                    this._zmesh.dispose();
-                }
-
-                this._xmesh = null;
-                this._ymesh = null;
-                this._zmesh = null;
-
-                this.scene = null;
-            }
-        }
-
-        public static BoneAxesViewer = class BoneAxesViewer extends Debug.AxesViewer {
-
-            public mesh: Nullable<Mesh>;
-            public bone: Nullable<Bone>;
-
-            public pos = Vector3.Zero();
-            public xaxis = Vector3.Zero();
-            public yaxis = Vector3.Zero();
-            public zaxis = Vector3.Zero();
-
-            constructor(scene: Scene, bone: Bone, mesh: Mesh, scaleLines = 1) {
-
-                super(scene, scaleLines);
-
-                this.mesh = mesh;
-                this.bone = bone;
-
-            }
-
-            public update(): void {
-
-                if (!this.mesh || !this.bone) {
-                    return;
-                }
-
-                var bone = this.bone;
-                bone.getAbsolutePositionToRef(this.mesh, this.pos);
-                bone.getDirectionToRef(Axis.X, this.mesh, this.xaxis);
-                bone.getDirectionToRef(Axis.Y, this.mesh, this.yaxis);
-                bone.getDirectionToRef(Axis.Z, this.mesh, this.zaxis);
-
-                super.update(this.pos, this.xaxis, this.yaxis, this.zaxis);
-
-            }
-
-            public dispose() {
-
-                if (this.mesh) {
-                    this.mesh = null;
-                    this.bone = null;
-
-                    super.dispose();
-
-                }
-            }
-
-        }
-
-        public static PhysicsViewer = class PhysicsViewer {
-
-            _impostors: Array<Nullable<PhysicsImpostor>> = [];
-            _meshes: Array<Nullable<AbstractMesh>> = [];
-            _scene: Nullable<Scene>;
-            _numMeshes = 0;
-            _physicsEnginePlugin: Nullable<IPhysicsEnginePlugin>;
-            _renderFunction: () => void;
-
-            _debugBoxMesh: Mesh;
-            _debugSphereMesh: Mesh;
-            _debugMaterial: StandardMaterial;
-
-            constructor(scene: Scene) {
-                this._scene = scene || Engine.LastCreatedScene;
-                let physicEngine = this._scene.getPhysicsEngine();
-
-                if (physicEngine) {
-                    this._physicsEnginePlugin = physicEngine.getPhysicsPlugin();
-                }
-            }
-
-            _updateDebugMeshes(): void {
-
-                var plugin = this._physicsEnginePlugin;
-
-                for (var i = 0; i < this._numMeshes; i++) {
-                    let impostor = this._impostors[i];
-
-                    if (!impostor) {
-                        continue;
-                    }
-
-                    if (impostor.isDisposed) {
-                        this.hideImpostor(this._impostors[i--]);
-                    } else {
-                        let mesh = this._meshes[i];
-
-                        if (mesh && plugin) {
-                            plugin.syncMeshWithImpostor(mesh, impostor);
-                        }
-                    }
-                }
-
-            }
-
-            public showImpostor(impostor: PhysicsImpostor): void {
-
-                if (!this._scene) {
-                    return;
-                }
-
-                for (var i = 0; i < this._numMeshes; i++) {
-                    if (this._impostors[i] == impostor) {
-                        return;
-                    }
-                }
-
-                var debugMesh = this._getDebugMesh(impostor, this._scene);
-
-                if (debugMesh) {
-                    this._impostors[this._numMeshes] = impostor;
-                    this._meshes[this._numMeshes] = debugMesh;
-
-                    if (this._numMeshes === 0) {
-                        this._renderFunction = this._updateDebugMeshes.bind(this);
-                        this._scene.registerBeforeRender(this._renderFunction);
-                    }
-
-                    this._numMeshes++;
-                }
-
-            }
-
-            public hideImpostor(impostor: Nullable<PhysicsImpostor>) {
-
-                if (!impostor || !this._scene) {
-                    return;
-                }
-
-                var removed = false;
-
-                for (var i = 0; i < this._numMeshes; i++) {
-                    if (this._impostors[i] == impostor) {
-                        let mesh = this._meshes[i];
-
-                        if (!mesh) {
-                            continue;
-                        }
-
-                        this._scene.removeMesh(mesh);
-                        mesh.dispose();
-                        this._numMeshes--;
-                        if (this._numMeshes > 0) {
-                            this._meshes[i] = this._meshes[this._numMeshes];
-                            this._impostors[i] = this._impostors[this._numMeshes];
-                            this._meshes[this._numMeshes] = null;
-                            this._impostors[this._numMeshes] = null;
-                        } else {
-                            this._meshes[0] = null;
-                            this._impostors[0] = null;
-                        }
-                        removed = true;
-                        break;
-                    }
-                }
-
-                if (removed && this._numMeshes === 0) {
-                    this._scene.unregisterBeforeRender(this._renderFunction);
-                }
-
-            }
-
-            _getDebugMaterial(scene: Scene): Material {
-                if (!this._debugMaterial) {
-                    this._debugMaterial = new StandardMaterial('', scene);
-                    this._debugMaterial.wireframe = true;
-                }
-
-                return this._debugMaterial;
-            }
-
-            _getDebugBoxMesh(scene: Scene): AbstractMesh {
-                if (!this._debugBoxMesh) {
-                    this._debugBoxMesh = MeshBuilder.CreateBox('physicsBodyBoxViewMesh', { size: 1 }, scene);
-                    this._debugBoxMesh.renderingGroupId = 1;
-                    this._debugBoxMesh.rotationQuaternion = Quaternion.Identity();
-                    this._debugBoxMesh.material = this._getDebugMaterial(scene);
-                    scene.removeMesh(this._debugBoxMesh);
-                }
-
-                return this._debugBoxMesh.createInstance('physicsBodyBoxViewInstance');
-            }
-
-            _getDebugSphereMesh(scene: Scene): AbstractMesh {
-                if (!this._debugSphereMesh) {
-                    this._debugSphereMesh = MeshBuilder.CreateSphere('physicsBodySphereViewMesh', { diameter: 1 }, scene);
-                    this._debugSphereMesh.renderingGroupId = 1;
-                    this._debugSphereMesh.rotationQuaternion = Quaternion.Identity();
-                    this._debugSphereMesh.material = this._getDebugMaterial(scene);
-                    scene.removeMesh(this._debugSphereMesh);
-                }
-
-                return this._debugSphereMesh.createInstance('physicsBodyBoxViewInstance');
-            }
-
-            _getDebugMesh(impostor: PhysicsImpostor, scene: Scene): Nullable<AbstractMesh> {
-                var mesh: Nullable<AbstractMesh> = null;
-
-                if (impostor.type == PhysicsImpostor.BoxImpostor) {
-                    mesh = this._getDebugBoxMesh(scene);
-                    impostor.getBoxSizeToRef(mesh.scaling);
-                } else if (impostor.type == PhysicsImpostor.SphereImpostor) {
-                    mesh = this._getDebugSphereMesh(scene);
-                    var radius = impostor.getRadius();
-                    mesh.scaling.x = radius * 2;
-                    mesh.scaling.y = radius * 2;
-                    mesh.scaling.z = radius * 2;
-                }
-
-                return mesh;
-            }
-
-            public dispose() {
-
-                for (var i = 0; i < this._numMeshes; i++) {
-                    this.hideImpostor(this._impostors[i]);
-                }
-
-                if (this._debugBoxMesh) {
-                    this._debugBoxMesh.dispose();
-                }
-                if (this._debugSphereMesh) {
-                    this._debugSphereMesh.dispose();
-                }
-                if (this._debugMaterial) {
-                    this._debugMaterial.dispose();
-                }
-
-                this._impostors.length = 0;
-                this._scene = null;
-                this._physicsEnginePlugin = null;
-
-            }
-
-        }
-
-        public static SkeletonViewer = class SkeletonViewer {
-            public color: Color3 = Color3.White();
-
-            _scene: Scene;
-            _debugLines = new Array<Array<Vector3>>();
-            _debugMesh: Nullable<LinesMesh>;
-            _isEnabled = false;
-            _renderFunction: () => void;
-
-            constructor(public skeleton: Skeleton, public mesh: AbstractMesh, scene: Scene, public autoUpdateBonesMatrices = true, public renderingGroupId = 1) {
-                this._scene = scene;
-
-                this.update();
-
-                this._renderFunction = this.update.bind(this);
-            }
-
-            public set isEnabled(value: boolean) {
-                if (this._isEnabled === value) {
-                    return;
-                }
-
-                this._isEnabled = value;
-
-                if (value) {
-                    this._scene.registerBeforeRender(this._renderFunction);
-                } else {
-                    this._scene.unregisterBeforeRender(this._renderFunction);
-                }
-            }
-
-            public get isEnabled(): boolean {
-                return this._isEnabled;
-            }
-
-            _getBonePosition(position: Vector3, bone: Bone, meshMat: Matrix, x = 0, y = 0, z = 0): void {
-                var tmat = Tmp.Matrix[0];
-                var parentBone = bone.getParent();
-                tmat.copyFrom(bone.getLocalMatrix());
-
-                if (x !== 0 || y !== 0 || z !== 0) {
-                    var tmat2 = Tmp.Matrix[1];
-                    Matrix.IdentityToRef(tmat2);
-                    tmat2.m[12] = x;
-                    tmat2.m[13] = y;
-                    tmat2.m[14] = z;
-                    tmat2.multiplyToRef(tmat, tmat);
-                }
-
-                if (parentBone) {
-                    tmat.multiplyToRef(parentBone.getAbsoluteTransform(), tmat);
-                }
-
-                tmat.multiplyToRef(meshMat, tmat);
-
-                position.x = tmat.m[12];
-                position.y = tmat.m[13];
-                position.z = tmat.m[14];
-            }
-
-            _getLinesForBonesWithLength(bones: Bone[], meshMat: Matrix): void {
-                var len = bones.length;
-                var meshPos = this.mesh.position;
-                for (var i = 0; i < len; i++) {
-                    var bone = bones[i];
-                    var points = this._debugLines[i];
-                    if (!points) {
-                        points = [Vector3.Zero(), Vector3.Zero()];
-                        this._debugLines[i] = points;
-                    }
-                    this._getBonePosition(points[0], bone, meshMat);
-                    this._getBonePosition(points[1], bone, meshMat, 0, bone.length, 0);
-                    points[0].subtractInPlace(meshPos);
-                    points[1].subtractInPlace(meshPos);
-                }
-            }
-
-            _getLinesForBonesNoLength(bones: Bone[], meshMat: Matrix): void {
-                var len = bones.length;
-                var boneNum = 0;
-                var meshPos = this.mesh.position;
-                for (var i = len - 1; i >= 0; i--) {
-                    var childBone = bones[i];
-                    var parentBone = childBone.getParent();
-                    if (!parentBone) {
-                        continue;
-                    }
-                    var points = this._debugLines[boneNum];
-                    if (!points) {
-                        points = [Vector3.Zero(), Vector3.Zero()];
-                        this._debugLines[boneNum] = points;
-                    }
-                    childBone.getAbsolutePositionToRef(this.mesh, points[0]);
-                    parentBone.getAbsolutePositionToRef(this.mesh, points[1]);
-                    points[0].subtractInPlace(meshPos);
-                    points[1].subtractInPlace(meshPos);
-                    boneNum++;
-                }
-            }
-
-            public update() {
-                if (this.autoUpdateBonesMatrices) {
-                    this.skeleton.computeAbsoluteTransforms();
-                }
-
-                if (this.skeleton.bones[0].length === undefined) {
-                    this._getLinesForBonesNoLength(this.skeleton.bones, this.mesh.getWorldMatrix());
-                } else {
-                    this._getLinesForBonesWithLength(this.skeleton.bones, this.mesh.getWorldMatrix());
-                }
-
-                if (!this._debugMesh) {
-                    this._debugMesh = MeshBuilder.CreateLineSystem("", { lines: this._debugLines, updatable: true, instance: null }, this._scene);
-                    this._debugMesh.renderingGroupId = this.renderingGroupId;
-                } else {
-                    MeshBuilder.CreateLineSystem("", { lines: this._debugLines, updatable: true, instance: this._debugMesh }, this._scene);
-                }
-                this._debugMesh.position.copyFrom(this.mesh.position);
-                this._debugMesh.color = this.color;
-            }
-
-            public dispose() {
-                if (this._debugMesh) {
-                    this.isEnabled = false;
-                    this._debugMesh.dispose();
-                    this._debugMesh = null;
-                }
-            }
-        }
-    }
-
-
-}

+ 192 - 0
src/Debug/babylon.physicsViewer.ts

@@ -0,0 +1,192 @@
+module BABYLON.Debug {
+
+    /**
+     * Used to show the physics impostor around the specific mesh.
+     */
+    export class PhysicsViewer {
+
+        protected _impostors: Array<Nullable<PhysicsImpostor>> = [];
+        protected _meshes: Array<Nullable<AbstractMesh>> = [];
+        protected _scene: Nullable<Scene>;
+        protected _numMeshes = 0;
+        protected _physicsEnginePlugin: Nullable<IPhysicsEnginePlugin>;
+        private _renderFunction: () => void;
+
+        private _debugBoxMesh: Mesh;
+        private _debugSphereMesh: Mesh;
+        private _debugMaterial: StandardMaterial;
+
+        constructor(scene: Scene) {
+            this._scene = scene || Engine.LastCreatedScene;
+            let physicEngine = this._scene.getPhysicsEngine();
+
+            if (physicEngine) {
+                this._physicsEnginePlugin = physicEngine.getPhysicsPlugin();
+            }
+        }
+
+        protected _updateDebugMeshes(): void {
+
+            var plugin = this._physicsEnginePlugin;
+
+            for (var i = 0; i < this._numMeshes; i++) {
+                let impostor = this._impostors[i];
+
+                if (!impostor) {
+                    continue;
+                }
+
+                if (impostor.isDisposed) {
+                    this.hideImpostor(this._impostors[i--]);
+                } else {
+                    let mesh = this._meshes[i];
+
+                    if (mesh && plugin) {
+                        plugin.syncMeshWithImpostor(mesh, impostor);
+                    }
+                }
+            }
+
+        }
+
+        public showImpostor(impostor: PhysicsImpostor): void {
+
+            if (!this._scene) {
+                return;
+            }
+
+            for (var i = 0; i < this._numMeshes; i++) {
+                if (this._impostors[i] == impostor) {
+                    return;
+                }
+            }
+
+            var debugMesh = this._getDebugMesh(impostor, this._scene);
+
+            if (debugMesh) {
+                this._impostors[this._numMeshes] = impostor;
+                this._meshes[this._numMeshes] = debugMesh;
+
+                if (this._numMeshes === 0) {
+                    this._renderFunction = this._updateDebugMeshes.bind(this);
+                    this._scene.registerBeforeRender(this._renderFunction);
+                }
+
+                this._numMeshes++;
+            }
+
+        }
+
+        public hideImpostor(impostor: Nullable<PhysicsImpostor>) {
+
+            if (!impostor || !this._scene) {
+                return;
+            }
+
+            var removed = false;
+
+            for (var i = 0; i < this._numMeshes; i++) {
+                if (this._impostors[i] == impostor) {
+                    let mesh = this._meshes[i];
+
+                    if (!mesh) {
+                        continue;
+                    }
+
+                    this._scene.removeMesh(mesh);
+                    mesh.dispose();
+                    this._numMeshes--;
+                    if (this._numMeshes > 0) {
+                        this._meshes[i] = this._meshes[this._numMeshes];
+                        this._impostors[i] = this._impostors[this._numMeshes];
+                        this._meshes[this._numMeshes] = null;
+                        this._impostors[this._numMeshes] = null;
+                    } else {
+                        this._meshes[0] = null;
+                        this._impostors[0] = null;
+                    }
+                    removed = true;
+                    break;
+                }
+            }
+
+            if (removed && this._numMeshes === 0) {
+                this._scene.unregisterBeforeRender(this._renderFunction);
+            }
+
+        }
+
+        private _getDebugMaterial(scene: Scene): Material {
+            if (!this._debugMaterial) {
+                this._debugMaterial = new StandardMaterial('', scene);
+                this._debugMaterial.wireframe = true;
+            }
+
+            return this._debugMaterial;
+        }
+
+        private _getDebugBoxMesh(scene: Scene): AbstractMesh {
+            if (!this._debugBoxMesh) {
+                this._debugBoxMesh = MeshBuilder.CreateBox('physicsBodyBoxViewMesh', { size: 1 }, scene);
+                this._debugBoxMesh.renderingGroupId = 1;
+                this._debugBoxMesh.rotationQuaternion = Quaternion.Identity();
+                this._debugBoxMesh.material = this._getDebugMaterial(scene);
+                scene.removeMesh(this._debugBoxMesh);
+            }
+
+            return this._debugBoxMesh.createInstance('physicsBodyBoxViewInstance');
+        }
+
+        private _getDebugSphereMesh(scene: Scene): AbstractMesh {
+            if (!this._debugSphereMesh) {
+                this._debugSphereMesh = MeshBuilder.CreateSphere('physicsBodySphereViewMesh', { diameter: 1 }, scene);
+                this._debugSphereMesh.renderingGroupId = 1;
+                this._debugSphereMesh.rotationQuaternion = Quaternion.Identity();
+                this._debugSphereMesh.material = this._getDebugMaterial(scene);
+                scene.removeMesh(this._debugSphereMesh);
+            }
+
+            return this._debugSphereMesh.createInstance('physicsBodyBoxViewInstance');
+        }
+
+        private _getDebugMesh(impostor: PhysicsImpostor, scene: Scene): Nullable<AbstractMesh> {
+            var mesh: Nullable<AbstractMesh> = null;
+
+            if (impostor.type == PhysicsImpostor.BoxImpostor) {
+                mesh = this._getDebugBoxMesh(scene);
+                impostor.getBoxSizeToRef(mesh.scaling);
+            } else if (impostor.type == PhysicsImpostor.SphereImpostor) {
+                mesh = this._getDebugSphereMesh(scene);
+                var radius = impostor.getRadius();
+                mesh.scaling.x = radius * 2;
+                mesh.scaling.y = radius * 2;
+                mesh.scaling.z = radius * 2;
+            }
+
+            return mesh;
+        }
+
+        public dispose() {
+
+            for (var i = 0; i < this._numMeshes; i++) {
+                this.hideImpostor(this._impostors[i]);
+            }
+
+            if (this._debugBoxMesh) {
+                this._debugBoxMesh.dispose();
+            }
+            if (this._debugSphereMesh) {
+                this._debugSphereMesh.dispose();
+            }
+            if (this._debugMaterial) {
+                this._debugMaterial.dispose();
+            }
+
+            this._impostors.length = 0;
+            this._scene = null;
+            this._physicsEnginePlugin = null;
+
+        }
+
+    }
+}

+ 134 - 0
src/Debug/babylon.skeletonViewer.ts

@@ -0,0 +1,134 @@
+module BABYLON.Debug {
+    /**
+    * Demo available here: http://www.babylonjs-playground.com/#1BZJVJ#8
+    */
+    export class SkeletonViewer {
+        public color: Color3 = Color3.White();
+
+        private _scene: Scene;
+        private _debugLines = new Array<Array<Vector3>>();
+        private _debugMesh: Nullable<LinesMesh>;
+        private _isEnabled = false;
+        private _renderFunction: () => void;
+
+        constructor(public skeleton: Skeleton, public mesh: AbstractMesh, scene: Scene, public autoUpdateBonesMatrices = true, public renderingGroupId = 1) {
+            this._scene = scene;
+
+            this.update();
+
+            this._renderFunction = this.update.bind(this);
+        }
+
+        public set isEnabled(value: boolean) {
+            if (this._isEnabled === value) {
+                return;
+            }
+
+            this._isEnabled = value;
+
+            if (value) {
+                this._scene.registerBeforeRender(this._renderFunction);
+            } else {
+                this._scene.unregisterBeforeRender(this._renderFunction);
+            }
+        }
+
+        public get isEnabled(): boolean {
+            return this._isEnabled;
+        }
+
+        private _getBonePosition(position: Vector3, bone: Bone, meshMat: Matrix, x = 0, y = 0, z = 0): void {
+            var tmat = Tmp.Matrix[0];
+            var parentBone = bone.getParent();
+            tmat.copyFrom(bone.getLocalMatrix());
+
+            if (x !== 0 || y !== 0 || z !== 0) {
+                var tmat2 = Tmp.Matrix[1];
+                BABYLON.Matrix.IdentityToRef(tmat2);
+                tmat2.m[12] = x;
+                tmat2.m[13] = y;
+                tmat2.m[14] = z;
+                tmat2.multiplyToRef(tmat, tmat);
+            }
+
+            if (parentBone) {
+                tmat.multiplyToRef(parentBone.getAbsoluteTransform(), tmat);
+            }
+
+            tmat.multiplyToRef(meshMat, tmat);
+
+            position.x = tmat.m[12];
+            position.y = tmat.m[13];
+            position.z = tmat.m[14];
+        }
+
+        private _getLinesForBonesWithLength(bones: Bone[], meshMat: Matrix): void {
+            var len = bones.length;
+            var meshPos = this.mesh.position;
+            for (var i = 0; i < len; i++) {
+                var bone = bones[i];
+                var points = this._debugLines[i];
+                if (!points) {
+                    points = [Vector3.Zero(), Vector3.Zero()];
+                    this._debugLines[i] = points;
+                }
+                this._getBonePosition(points[0], bone, meshMat);
+                this._getBonePosition(points[1], bone, meshMat, 0, bone.length, 0);
+                points[0].subtractInPlace(meshPos);
+                points[1].subtractInPlace(meshPos);
+            }
+        }
+
+        private _getLinesForBonesNoLength(bones: Bone[], meshMat: Matrix): void {
+            var len = bones.length;
+            var boneNum = 0;
+            var meshPos = this.mesh.position;
+            for (var i = len - 1; i >= 0; i--) {
+                var childBone = bones[i];
+                var parentBone = childBone.getParent();
+                if (!parentBone) {
+                    continue;
+                }
+                var points = this._debugLines[boneNum];
+                if (!points) {
+                    points = [Vector3.Zero(), Vector3.Zero()];
+                    this._debugLines[boneNum] = points;
+                }
+                childBone.getAbsolutePositionToRef(this.mesh, points[0]);
+                parentBone.getAbsolutePositionToRef(this.mesh, points[1]);
+                points[0].subtractInPlace(meshPos);
+                points[1].subtractInPlace(meshPos);
+                boneNum++;
+            }
+        }
+
+        public update() {
+            if (this.autoUpdateBonesMatrices) {
+                this.skeleton.computeAbsoluteTransforms();
+            }
+
+            if (this.skeleton.bones[0].length === undefined) {
+                this._getLinesForBonesNoLength(this.skeleton.bones, this.mesh.getWorldMatrix());
+            } else {
+                this._getLinesForBonesWithLength(this.skeleton.bones, this.mesh.getWorldMatrix());
+            }
+
+            if (!this._debugMesh) {
+                this._debugMesh = BABYLON.MeshBuilder.CreateLineSystem("", { lines: this._debugLines, updatable: true, instance: null }, this._scene);
+                this._debugMesh.renderingGroupId = this.renderingGroupId;
+            } else {
+                BABYLON.MeshBuilder.CreateLineSystem("", { lines: this._debugLines, updatable: true, instance: this._debugMesh }, this._scene);
+            }
+            this._debugMesh.position.copyFrom(this.mesh.position);
+            this._debugMesh.color = this.color;
+        }
+
+        public dispose() {
+            if (this._debugMesh) {
+                this.isEnabled = false;
+                this._debugMesh.dispose();
+                this._debugMesh = null;
+            }
+        }
+    }
+}

+ 3 - 0
src/Engine/babylon.nullEngine.ts

@@ -290,6 +290,9 @@
             return {};
         }
 
+        public _releaseTexture(texture: InternalTexture): void {
+        }
+
         public createTexture(urlArg: string, noMipmap: boolean, invertY: boolean, scene: Scene, samplingMode: number = Texture.TRILINEAR_SAMPLINGMODE, onLoad: Nullable<() => void> = null, onError: Nullable<(message: string, exception: any) => void> = null, buffer: Nullable<ArrayBuffer | HTMLImageElement> = null, fallBack?: InternalTexture, format?: number): InternalTexture {
             var texture = new InternalTexture(this, InternalTexture.DATASOURCE_URL);
             var url = String(urlArg);

+ 20 - 1
src/Layer/babylon.effectLayer.ts

@@ -54,18 +54,27 @@
         protected _emissiveTextureAndColor: { texture: Nullable<BaseTexture>, color: Color4 } = { texture: null, color: new Color4() };
 
         /**
+         * The name of the layer
+         */
+        @serialize()
+        public name: string;
+
+        /**
          * The clear color of the texture used to generate the glow map.
          */
+        @serializeAsColor4()
         public neutralColor: Color4 = new Color4();
 
         /**
          * Specifies wether the highlight layer is enabled or not.
          */
+        @serialize()
         public isEnabled: boolean = true;
 
         /**
          * Gets the camera attached to the layer.
          */
+        @serializeAsCameraReference()
         public get camera(): Nullable<Camera> {
             return this._effectLayerOptions.camera;
         }
@@ -102,8 +111,10 @@
          */
         constructor(
             /** The Friendly of the effect in the scene */
-            public name: string, 
+            name: string,
             scene: Scene) {
+            this.name = name;
+
             this._scene = scene || Engine.LastCreatedScene;
             this._engine = scene.getEngine();
             this._maxSize = this._engine.getCaps().maxTextureSize;
@@ -651,5 +662,13 @@
             this.onAfterComposeObservable.clear();
             this.onSizeChangedObservable.clear();
         }
+
+        /**
+          * Gets the class name of the effect layer
+          * @returns the string with the class name of the effect layer
+          */
+         public getClassName(): string {
+            return "EffectLayer";
+        }
     }
 } 

+ 78 - 1
src/Layer/babylon.glowLayer.ts

@@ -68,6 +68,7 @@
         /**
          * Gets the kernel size of the blur.
          */
+        @serialize()
         public get blurKernelSize(): number {
             return this._horizontalBlurPostprocess1.kernel;
         }
@@ -82,11 +83,14 @@
         /**
          * Gets the glow intensity.
          */
+        @serialize()
         public get intensity(): number {
             return this._intensity;
         }
 
+        @serialize('options')
         private _options: IGlowLayerOptions;
+
         private _intensity: number = 1.0;
         private _horizontalBlurPostprocess1: BlurPostProcess;
         private _verticalBlurPostprocess1: BlurPostProcess;
@@ -115,7 +119,7 @@
          * @param scene The scene to use the layer in
          * @param options Sets of none mandatory options to use with the layer (see IGlowLayerOptions for more information)
          */
-        constructor(public name: string, scene: Scene, options?: Partial<IGlowLayerOptions>) {
+        constructor(name: string, scene: Scene, options?: Partial<IGlowLayerOptions>) {
             super(name, scene);
             this.neutralColor = new Color4(0, 0, 0, 1);
 
@@ -441,5 +445,78 @@
             this.removeIncludedOnlyMesh(mesh);
             this.removeExcludedMesh(mesh);
         }
+
+        /**
+          * Gets the class name of the effect layer
+          * @returns the string with the class name of the effect layer
+          */
+         public getClassName(): string {
+            return "GlowLayer";
+        }
+
+        /**
+         * Serializes this glow layer
+         * @returns a serialized glow layer object
+         */
+        public serialize(): any {
+            var serializationObject = SerializationHelper.Serialize(this);
+            var index;
+
+            // Included meshes
+            serializationObject.includedMeshes = [];
+
+            if (this._includedOnlyMeshes.length) {
+                for (index = 0; index < this._includedOnlyMeshes.length; index++) {
+                    var mesh = this._scene.getMeshByUniqueID(this._includedOnlyMeshes[index]);
+                    if (mesh) {
+                        serializationObject.includedMeshes.push(mesh.id);
+                    }
+                }
+            }
+
+            // Excluded meshes
+            serializationObject.excludedMeshes = [];
+
+            if (this._excludedMeshes.length) {
+                for (index = 0; index < this._excludedMeshes.length; index++) {
+                    var mesh = this._scene.getMeshByUniqueID(this._excludedMeshes[index]);
+                    if (mesh) {
+                        serializationObject.excludedMeshes.push(mesh.id);
+                    }
+                }
+            }
+
+            return serializationObject;
+        }
+
+        /**
+         * Creates a Glow Layer from parsed glow layer data
+         * @param parsedGlowLayer defines glow layer data
+         * @param scene defines the current scene
+         * @param rootUrl defines the root URL containing the glow layer information
+         * @returns a parsed Glow Layer
+         */
+        public static Parse(parsedGlowLayer: any, scene: Scene, rootUrl: string): GlowLayer {
+            var gl = SerializationHelper.Parse(() => new GlowLayer(parsedGlowLayer.name, scene, parsedGlowLayer.options), parsedGlowLayer, scene, rootUrl);
+            var index;
+
+            // Excluded meshes
+            for (index = 0; index < parsedGlowLayer.excludedMeshes.length; index++) {
+                var mesh = scene.getMeshByID(parsedGlowLayer.excludedMeshes[index]);
+                if (mesh) {
+                    gl.addExcludedMesh(<Mesh>mesh);
+                }
+            }
+
+            // Included meshes
+            for (index = 0; index < parsedGlowLayer.includedMeshes.length; index++) {
+                var mesh = scene.getMeshByID(parsedGlowLayer.includedMeshes[index]);
+                if (mesh) {
+                    gl.addIncludedOnlyMesh(<Mesh>mesh);
+                }
+            }
+
+            return gl;
+        }
     }
 } 

+ 189 - 178
src/PostProcess/babylon.blurPostProcess.ts

@@ -1,80 +1,84 @@
 module 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.
+    /**
+     * 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.
      */
     export class BlurPostProcess extends PostProcess {
-		protected _kernel: number;
-		protected _idealKernel: number;
-		protected _packedFloat: boolean	= false;
-		private _staticDefines:string = ""
-		/**
-		 * Sets the length in pixels of the blur sample region
-		 */
-		public set kernel(v: number) {
-			if (this._idealKernel === v) {
-				return;
-			}
-
-			v = Math.max(v, 1);
-			this._idealKernel = v;
-			this._kernel = this._nearestBestKernel(v);
-			if(!this.blockCompilation){
-				this._updateParameters();
-			}
-		}
-
-		/**
-		 * Gets the length in pixels of the blur sample region
-		 */
-		public get kernel(): number {
-			return this._idealKernel;
-		}
-
-		/**
-		 * Sets wether or not the blur needs to unpack/repack floats
-		 */
-		public set packedFloat(v: boolean) {
-			if (this._packedFloat === v) {
-				return;
-			}
-			this._packedFloat = v;
+        protected _kernel: number;
+        protected _idealKernel: number;
+        protected _packedFloat: boolean	= false;
+        private _staticDefines:string = ""
+        /**
+         * Sets the length in pixels of the blur sample region
+         */
+        public set kernel(v: number) {
+            if (this._idealKernel === v) {
+                return;
+            }
+
+            v = Math.max(v, 1);
+            this._idealKernel = v;
+            this._kernel = this._nearestBestKernel(v);
+            if(!this.blockCompilation){
+                this._updateParameters();
+            }
+        }
+
+        /**
+         * Gets the length in pixels of the blur sample region
+         */
+        public get kernel(): number {
+            return this._idealKernel;
+        }
+
+        /**
+         * Sets wether or not the blur needs to unpack/repack floats
+         */
+        public set packedFloat(v: boolean) {
+            if (this._packedFloat === v) {
+                return;
+            }
+            this._packedFloat = v;
             if(!this.blockCompilation){
-				this._updateParameters();
-			}
-		}
-
-		/**
-		 * Gets wether or not the blur is unpacking/repacking floats
-		 */
-		public get packedFloat(): boolean {
-			return this._packedFloat;
-		}
-
-		/**
+                this._updateParameters();
+            }
+        }
+
+        /**
+         * Gets wether or not the blur is unpacking/repacking floats
+         */
+        public get packedFloat(): boolean {
+            return this._packedFloat;
+        }
+
+        /**
          * Creates a new instance 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 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)
-		 * @param blockCompilation If compilation of the shader should not be done in the constructor. The updateEffect method can be used to compile the shader at a later time. (default: false)
+         * @param blockCompilation If compilation of the shader should not be done in the constructor. The updateEffect method can be used to compile the shader at a later time. (default: false)
          */
         constructor(name: string, /** The direction in which to blur the image. */ public direction: Vector2, kernel: number, options: number | PostProcessOptions, camera: Nullable<Camera>, samplingMode: number = Texture.BILINEAR_SAMPLINGMODE, engine?: Engine, reusable?: boolean, textureType: number = Engine.TEXTURETYPE_UNSIGNED_INT, defines = "", private blockCompilation = false) {
-			super(name, "kernelBlur", ["delta", "direction", "cameraMinMaxZ"], ["circleOfConfusionSampler"], options, camera, samplingMode, engine, reusable, null, textureType, "kernelBlur", {varyingCount: 0, depCount: 0}, true);
-			this._staticDefines = defines;
-			this.onApplyObservable.add((effect: Effect) => {
-				effect.setFloat2('delta', (1 / this.width) * this.direction.x, (1 / this.height) * this.direction.y);
-			});
+            super(name, "kernelBlur", ["delta", "direction", "cameraMinMaxZ"], ["circleOfConfusionSampler"], options, camera, samplingMode, engine, reusable, null, textureType, "kernelBlur", {varyingCount: 0, depCount: 0}, true);
+            this._staticDefines = defines;
+            this.onApplyObservable.add((effect: Effect) => {
+                if(this._outputTexture){
+                    effect.setFloat2('delta', (1 / this._outputTexture.width) * this.direction.x, (1 / this._outputTexture.height) * this.direction.y);
+                }else{
+                    effect.setFloat2('delta', (1 / this.width) * this.direction.x, (1 / this.height) * this.direction.y);
+                }
+            });
 
             this.kernel = kernel;
         }
 
-		/**
+        /**
          * 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)
@@ -90,144 +94,151 @@
 
         protected _updateParameters(onCompiled?: (effect: Effect) => void, onError?: (effect: Effect, errors: string) => void): void {
             // Generate sampling offsets and weights
-			let N = this._kernel;
-			let centerIndex = (N - 1) / 2;
-
-			// Generate Gaussian sampling weights over kernel
-			let offsets = [];
-			let weights = [];
-			let totalWeight = 0;
-			for (let i = 0; i < N; i++) {
-				let u = i / (N - 1);
-				let w = this._gaussianWeight(u * 2.0 - 1);
-				offsets[i] = (i - centerIndex);
-				weights[i] = w;
-				totalWeight += w;
-			}
-
-			// Normalize weights
-			for (let i = 0; i < weights.length; i++) {
-				weights[i] /= totalWeight;
-			}
-
-			// Optimize: combine samples to take advantage of hardware linear sampling
-			// Walk from left to center, combining pairs (symmetrically)
-			let linearSamplingWeights = [];
-			let linearSamplingOffsets = [];
-
-			let linearSamplingMap = [];
-
-			for (let i = 0; i <= centerIndex; i += 2) {
-				let j = Math.min(i + 1, Math.floor(centerIndex));
-
-				let singleCenterSample = i === j;
-
-				if (singleCenterSample) {
-					linearSamplingMap.push({ o: offsets[i], w: weights[i] });
-				} else {
-					let sharedCell = j === centerIndex;
-
-					let weightLinear = (weights[i] + weights[j] * (sharedCell ? .5 : 1.));
-					let offsetLinear = offsets[i] + 1 / (1 + weights[i] / weights[j]);
-
-					if (offsetLinear === 0) {
-						linearSamplingMap.push({ o: offsets[i], w: weights[i] });
-						linearSamplingMap.push({ o: offsets[i + 1], w: weights[i + 1] });
-					} else {
-						linearSamplingMap.push({ o: offsetLinear, w: weightLinear });
-						linearSamplingMap.push({ o: -offsetLinear, w: weightLinear });
-					}
-
-				}
-			}
-
-			for (let i = 0; i < linearSamplingMap.length; i++) {
-				linearSamplingOffsets[i] = linearSamplingMap[i].o;
-				linearSamplingWeights[i] = linearSamplingMap[i].w;
-			}
-
-			// Replace with optimized
-			offsets = linearSamplingOffsets;
-			weights = linearSamplingWeights;
-
-			// Generate shaders
-			let maxVaryingRows = this.getEngine().getCaps().maxVaryingVectors;
-			let freeVaryingVec2 = Math.max(maxVaryingRows, 0.) - 1; // Because of sampleCenter
+            let N = this._kernel;
+            let centerIndex = (N - 1) / 2;
+
+            // Generate Gaussian sampling weights over kernel
+            let offsets = [];
+            let weights = [];
+            let totalWeight = 0;
+            for (let i = 0; i < N; i++) {
+                let u = i / (N - 1);
+                let w = this._gaussianWeight(u * 2.0 - 1);
+                offsets[i] = (i - centerIndex);
+                weights[i] = w;
+                totalWeight += w;
+            }
+
+            // Normalize weights
+            for (let i = 0; i < weights.length; i++) {
+                weights[i] /= totalWeight;
+            }
+
+            // Optimize: combine samples to take advantage of hardware linear sampling
+            // Walk from left to center, combining pairs (symmetrically)
+            let linearSamplingWeights = [];
+            let linearSamplingOffsets = [];
+
+            let linearSamplingMap = [];
+
+            for (let i = 0; i <= centerIndex; i += 2) {
+                let j = Math.min(i + 1, Math.floor(centerIndex));
+
+                let singleCenterSample = i === j;
+
+                if (singleCenterSample) {
+                    linearSamplingMap.push({ o: offsets[i], w: weights[i] });
+                } else {
+                    let sharedCell = j === centerIndex;
+
+                    let weightLinear = (weights[i] + weights[j] * (sharedCell ? .5 : 1.));
+                    let offsetLinear = offsets[i] + 1 / (1 + weights[i] / weights[j]);
+
+                    if (offsetLinear === 0) {
+                        linearSamplingMap.push({ o: offsets[i], w: weights[i] });
+                        linearSamplingMap.push({ o: offsets[i + 1], w: weights[i + 1] });
+                    } else {
+                        linearSamplingMap.push({ o: offsetLinear, w: weightLinear });
+                        linearSamplingMap.push({ o: -offsetLinear, w: weightLinear });
+                    }
+
+                }
+            }
+
+            for (let i = 0; i < linearSamplingMap.length; i++) {
+                linearSamplingOffsets[i] = linearSamplingMap[i].o;
+                linearSamplingWeights[i] = linearSamplingMap[i].w;
+            }
+
+            // Replace with optimized
+            offsets = linearSamplingOffsets;
+            weights = linearSamplingWeights;
+
+            // Generate shaders
+            let maxVaryingRows = this.getEngine().getCaps().maxVaryingVectors;
+            let freeVaryingVec2 = Math.max(maxVaryingRows, 0.) - 1; // Because of sampleCenter
 
             let varyingCount = Math.min(offsets.length, freeVaryingVec2);
-        
-			let defines = "";
-			defines+=this._staticDefines;
+
+            let defines = "";
+            defines+=this._staticDefines;
+
+            // The DOF fragment should ignore the center pixel when looping as it is handled manualy in the fragment shader.
+            if(this._staticDefines.indexOf("DOF") != -1){
+                defines += `#define CENTER_WEIGHT ${this._glslFloat(weights[varyingCount-1])}\r\n`;
+                varyingCount--;
+            }
+            
             for (let i = 0; i < varyingCount; i++) {
                 defines += `#define KERNEL_OFFSET${i} ${this._glslFloat(offsets[i])}\r\n`;
                 defines += `#define KERNEL_WEIGHT${i} ${this._glslFloat(weights[i])}\r\n`;
-			}
+            }
 
             let depCount = 0;
             for (let i = freeVaryingVec2; i < offsets.length; i++) {
                 defines += `#define KERNEL_DEP_OFFSET${depCount} ${this._glslFloat(offsets[i])}\r\n`;
                 defines += `#define KERNEL_DEP_WEIGHT${depCount} ${this._glslFloat(weights[i])}\r\n`;
                 depCount++;
-			}
+            }
 
-			if (this.packedFloat) {
-				defines += `#define PACKEDFLOAT 1`;
-			}
+            if (this.packedFloat) {
+                defines += `#define PACKEDFLOAT 1`;
+            }
 
-			this.blockCompilation = false;
+            this.blockCompilation = false;
             super.updateEffect(defines, null, null, {
-				varyingCount: varyingCount,
-				depCount: depCount
-			}, onCompiled, onError);
+                varyingCount: varyingCount,
+                depCount: depCount
+            }, onCompiled, onError);
         }
 
         /**
-		 * Best kernels are odd numbers that when divided by 2, their integer part is even, so 5, 9 or 13.
-		 * Other odd kernels optimize correctly but require proportionally more samples, even kernels are
-		 * possible but will produce minor visual artifacts. Since each new kernel requires a new shader we
-		 * want to minimize kernel changes, having gaps between physical kernels is helpful in that regard.
-		 * The gaps between physical kernels are compensated for in the weighting of the samples
-		 * @param idealKernel Ideal blur kernel.
-		 * @return Nearest best kernel.
-		 */
-		protected _nearestBestKernel(idealKernel: number): number {
-			let v = Math.round(idealKernel);
-			for (let k of [v, v - 1, v + 1, v - 2, v + 2]) {
-				if (((k % 2) !== 0) && ((Math.floor(k / 2) % 2) === 0) && k > 0) {
-					return Math.max(k, 3);
-				}
-			}
-			return Math.max(v, 3);
-		}
-
-		/**
-		 * Calculates the value of a Gaussian distribution with sigma 3 at a given point.
-		 * @param x The point on the Gaussian distribution to sample.
-		 * @return the value of the Gaussian function at x.
-		 */
-		protected _gaussianWeight(x: number): number {
-			//reference: Engine/ImageProcessingBlur.cpp #dcc760
-			// We are evaluating the Gaussian (normal) distribution over a kernel parameter space of [-1,1],
-			// so we truncate at three standard deviations by setting stddev (sigma) to 1/3.
-			// The choice of 3-sigma truncation is common but arbitrary, and means that the signal is
-			// truncated at around 1.3% of peak strength.
-
-			//the distribution is scaled to account for the difference between the actual kernel size and the requested kernel size
-			let sigma = (1 / 3);
-			let denominator = Math.sqrt(2.0 * Math.PI) * sigma;
-			let exponent = -((x * x) / (2.0 * sigma * sigma));
-			let weight = (1.0 / denominator) * Math.exp(exponent);
-			return weight;
-		}      
+         * Best kernels are odd numbers that when divided by 2, their integer part is even, so 5, 9 or 13.
+         * Other odd kernels optimize correctly but require proportionally more samples, even kernels are
+         * possible but will produce minor visual artifacts. Since each new kernel requires a new shader we
+         * want to minimize kernel changes, having gaps between physical kernels is helpful in that regard.
+         * The gaps between physical kernels are compensated for in the weighting of the samples
+         * @param idealKernel Ideal blur kernel.
+         * @return Nearest best kernel.
+         */
+        protected _nearestBestKernel(idealKernel: number): number {
+            let v = Math.round(idealKernel);
+            for (let k of [v, v - 1, v + 1, v - 2, v + 2]) {
+                if (((k % 2) !== 0) && ((Math.floor(k / 2) % 2) === 0) && k > 0) {
+                    return Math.max(k, 3);
+                }
+            }
+            return Math.max(v, 3);
+        }
+
+        /**
+         * Calculates the value of a Gaussian distribution with sigma 3 at a given point.
+         * @param x The point on the Gaussian distribution to sample.
+         * @return the value of the Gaussian function at x.
+         */
+        protected _gaussianWeight(x: number): number {
+            //reference: Engine/ImageProcessingBlur.cpp #dcc760
+            // We are evaluating the Gaussian (normal) distribution over a kernel parameter space of [-1,1],
+            // so we truncate at three standard deviations by setting stddev (sigma) to 1/3.
+            // The choice of 3-sigma truncation is common but arbitrary, and means that the signal is
+            // truncated at around 1.3% of peak strength.
+
+            //the distribution is scaled to account for the difference between the actual kernel size and the requested kernel size
+            let sigma = (1 / 3);
+            let denominator = Math.sqrt(2.0 * Math.PI) * sigma;
+            let exponent = -((x * x) / (2.0 * sigma * sigma));
+            let weight = (1.0 / denominator) * Math.exp(exponent);
+            return weight;
+        }      
 
        /**
-		 * Generates a string that can be used as a floating point number in GLSL.
-		 * @param x Value to print.
-		 * @param decimalFigures Number of decimal places to print the number to (excluding trailing 0s).
-		 * @return GLSL float string.
-		 */
-		protected _glslFloat(x: number, decimalFigures = 8) {
-			return x.toFixed(decimalFigures).replace(/0+$/, '');
-		}      
+         * Generates a string that can be used as a floating point number in GLSL.
+         * @param x Value to print.
+         * @param decimalFigures Number of decimal places to print the number to (excluding trailing 0s).
+         * @return GLSL float string.
+         */
+        protected _glslFloat(x: number, decimalFigures = 8) {
+            return x.toFixed(decimalFigures).replace(/0+$/, '');
+        }      
     }
 } 

+ 5 - 3
src/PostProcess/babylon.depthOfFieldEffect.ts

@@ -109,10 +109,12 @@ module BABYLON {
                 }
             }
             var adjustedKernelSize = kernelSize/Math.pow(2, blurCount-1);
+            var ratio = 1.0;
             for(var i = 0;i<blurCount;i++){
-                var blurY = new DepthOfFieldBlurPostProcess("verticle blur", scene, new Vector2(0, 1.0), adjustedKernelSize, 1.0/Math.pow(2, i), null, this._circleOfConfusion, i == 0 ? this._circleOfConfusion : null, Texture.BILINEAR_SAMPLINGMODE, scene.getEngine(), false, pipelineTextureType, blockCompilation);
+                var blurY = new DepthOfFieldBlurPostProcess("verticle blur", scene, new Vector2(0, 1.0), adjustedKernelSize, ratio, null, this._circleOfConfusion, i == 0 ? this._circleOfConfusion : null, Texture.BILINEAR_SAMPLINGMODE, scene.getEngine(), false, pipelineTextureType, blockCompilation);
                 blurY.autoClear = false;
-                var blurX = new DepthOfFieldBlurPostProcess("horizontal blur", scene, new Vector2(1.0, 0), adjustedKernelSize, 1.0/Math.pow(2, i), null,  this._circleOfConfusion, null, Texture.BILINEAR_SAMPLINGMODE, scene.getEngine(), false, pipelineTextureType, blockCompilation);
+                ratio = 0.75/Math.pow(2, i);
+                var blurX = new DepthOfFieldBlurPostProcess("horizontal blur", scene, new Vector2(1.0, 0), adjustedKernelSize, ratio, null,  this._circleOfConfusion, null, Texture.BILINEAR_SAMPLINGMODE, scene.getEngine(), false, pipelineTextureType, blockCompilation);
                 blurX.autoClear = false;
                 this._depthOfFieldBlurY.push(blurY);
                 this._depthOfFieldBlurX.push(blurX);
@@ -126,7 +128,7 @@ module BABYLON {
             }
 
             // Merge blurred images with original image based on circleOfConfusion
-            this._dofMerge = new DepthOfFieldMergePostProcess("dofMerge", this._circleOfConfusion, this._circleOfConfusion, this._depthOfFieldBlurX, 1, null, BABYLON.Texture.BILINEAR_SAMPLINGMODE, scene.getEngine(), false, pipelineTextureType, blockCompilation);
+            this._dofMerge = new DepthOfFieldMergePostProcess("dofMerge", this._circleOfConfusion, this._circleOfConfusion, this._depthOfFieldBlurX, ratio, null, BABYLON.Texture.BILINEAR_SAMPLINGMODE, scene.getEngine(), false, pipelineTextureType, blockCompilation);
             this._dofMerge.autoClear = false;
             this._effects.push(this._dofMerge);
         }

+ 2 - 2
src/PostProcess/babylon.depthOfFieldMergePostProcess.ts

@@ -42,13 +42,13 @@ module BABYLON {
          * @param blockCompilation If compilation of the shader should not be done in the constructor. The updateEffect method can be used to compile the shader at a later time. (default: false)
          */
         constructor(name: string, originalFromInput:PostProcess, circleOfConfusion:PostProcess, private blurSteps:Array<PostProcess>, options: number | PostProcessOptions, camera: Nullable<Camera>, samplingMode?: number, engine?: Engine, reusable?: boolean, textureType: number = Engine.TEXTURETYPE_UNSIGNED_INT, blockCompilation = false) {
-            super(name, "depthOfFieldMerge", ["bloomWeight"], ["circleOfConfusionSampler", "blurStep0", "blurStep1", "blurStep2", "bloomBlur"], options, camera, samplingMode, engine, reusable, null, textureType, undefined, null, true);
+            super(name, "depthOfFieldMerge", [], ["circleOfConfusionSampler", "blurStep0", "blurStep1", "blurStep2"], options, camera, samplingMode, engine, reusable, null, textureType, undefined, null, true);
             this.onApplyObservable.add((effect: Effect) => {
                 effect.setTextureFromPostProcess("textureSampler", originalFromInput);
                 effect.setTextureFromPostProcessOutput("circleOfConfusionSampler", circleOfConfusion);
                 blurSteps.forEach((step,index)=>{
                     effect.setTextureFromPostProcessOutput("blurStep"+(blurSteps.length-index-1), step);
-                });    
+                });  
             });
 
             if(!blockCompilation){

+ 2 - 0
src/PostProcess/babylon.postProcessManager.ts

@@ -154,8 +154,10 @@
                 } else {
                     if (targetTexture) {
                         engine.bindFramebuffer(targetTexture, faceIndex, undefined, undefined, forceFullscreenViewport);
+                        pp._outputTexture = targetTexture;
                     } else {
                         engine.restoreDefaultFramebuffer();
+                        pp._outputTexture = null;
                     }
                 }
 

+ 1 - 2
src/Shaders/ShadersInclude/kernelBlurFragment.fx

@@ -1,6 +1,5 @@
 #ifdef DOF
-    sampleDepth = sampleDistance(sampleCoord{X});
-    factor = clamp(1.0-((centerSampleDepth - sampleDepth)/centerSampleDepth),0.0,1.0);
+    factor = sampleCoC(sampleCoord{X});    
     computedWeight = KERNEL_WEIGHT{X} * factor;
     sumOfWeights += computedWeight;
 #else

+ 1 - 2
src/Shaders/ShadersInclude/kernelBlurFragment2.fx

@@ -1,6 +1,5 @@
 #ifdef DOF
-    sampleDepth = sampleDistance(sampleCoord{X});
-    factor = clamp(1.0-((centerSampleDepth - sampleDepth)/centerSampleDepth),0.0,1.0);
+    factor = sampleCoC(sampleCenter + delta * KERNEL_DEP_OFFSET{X});
     computedWeight = KERNEL_DEP_WEIGHT{X} * factor;
     sumOfWeights += computedWeight;
 #else

+ 3 - 7
src/Shaders/circleOfConfusion.fragment.fx

@@ -11,15 +11,11 @@ uniform vec2 cameraMinMaxZ;
 uniform float focusDistance;
 uniform float cocPrecalculation;
 
-float sampleDistance(const in vec2 offset) {
-    float depth = texture2D(depthSampler, offset).r;	// depth value from DepthRenderer: 0 to 1
-	return (cameraMinMaxZ.x + (cameraMinMaxZ.y - cameraMinMaxZ.x)*depth)*1000.0;		            // actual distance from the lens in scene units/1000 (eg. millimeter)
-}
-
 void main(void)
 {
-    float pixelDistance = sampleDistance(vUV);
+    float depth = texture2D(depthSampler, vUV).r;
+    float pixelDistance = (cameraMinMaxZ.x + (cameraMinMaxZ.y - cameraMinMaxZ.x)*depth)*1000.0;	// actual distance from the lens in scene units/1000 (eg. millimeter)
     float coc = abs(cocPrecalculation* ((focusDistance - pixelDistance)/pixelDistance));
     coc = clamp(coc, 0.0, 1.0);
-    gl_FragColor = vec4(coc, texture2D(depthSampler, vUV).r, coc, 1.0);
+    gl_FragColor = vec4(coc, depth, coc, 1.0);
 }

+ 11 - 8
src/Shaders/depthOfFieldMerge.fragment.fx

@@ -13,32 +13,35 @@ uniform sampler2D blurStep2;
 
 void main(void)
 {
-    gl_FragColor = texture2D(textureSampler, vUV);
-
     float coc = texture2D(circleOfConfusionSampler, vUV).r;
-    vec4 original = texture2D(textureSampler, vUV);
 #if BLUR_LEVEL == 0
+    vec4 original = texture2D(textureSampler, vUV);
     vec4 blurred0 = texture2D(blurStep0, vUV);
     gl_FragColor = mix(original, blurred0, coc);
 #endif
 #if BLUR_LEVEL == 1
-    vec4 blurred0 = texture2D(blurStep0, vUV);   
-    vec4 blurred1 = texture2D(blurStep1, vUV);
     if(coc < 0.5){
+        vec4 original = texture2D(textureSampler, vUV);
+        vec4 blurred1 = texture2D(blurStep1, vUV);
         gl_FragColor = mix(original, blurred1, coc/0.5);
     }else{
+        vec4 blurred0 = texture2D(blurStep0, vUV);   
+        vec4 blurred1 = texture2D(blurStep1, vUV);
         gl_FragColor = mix(blurred1, blurred0, (coc-0.5)/0.5);
     }
 #endif
 #if BLUR_LEVEL == 2
-    vec4 blurred0 = texture2D(blurStep0, vUV);
-    vec4 blurred1 = texture2D(blurStep1, vUV);
-    vec4 blurred2 = texture2D(blurStep2, vUV);
     if(coc < 0.33){
+        vec4 original = texture2D(textureSampler, vUV);
+        vec4 blurred2 = texture2D(blurStep2, vUV);
         gl_FragColor = mix(original, blurred2, coc/0.33);
     }else if(coc < 0.66){
+        vec4 blurred1 = texture2D(blurStep1, vUV);
+        vec4 blurred2 = texture2D(blurStep2, vUV);
         gl_FragColor = mix(blurred2, blurred1, (coc-0.33)/0.33);
     }else{
+        vec4 blurred0 = texture2D(blurStep0, vUV);
+        vec4 blurred1 = texture2D(blurStep1, vUV);
         gl_FragColor = mix(blurred1, blurred0, (coc-0.66)/0.34);
     }
 #endif

+ 58 - 53
src/Shaders/kernelBlur.fragment.fx

@@ -6,68 +6,73 @@ uniform vec2 delta;
 varying vec2 sampleCenter;
 
 #ifdef DOF
-	uniform sampler2D circleOfConfusionSampler;
+    uniform sampler2D circleOfConfusionSampler;
 
-	uniform vec2 cameraMinMaxZ;
+    uniform vec2 cameraMinMaxZ;
 
-	float sampleDistance(const in vec2 offset) {
-		float depth = texture2D(circleOfConfusionSampler, offset).g; // depth value from DepthRenderer: 0 to 1 
-		return cameraMinMaxZ.x + (cameraMinMaxZ.y - cameraMinMaxZ.x)*depth; // actual distance from the lens 
-	}
+    float sampleDistance(const in vec2 offset) {
+        float depth = texture2D(circleOfConfusionSampler, offset).g; // depth value from DepthRenderer: 0 to 1 
+        return cameraMinMaxZ.x + (cameraMinMaxZ.y - cameraMinMaxZ.x)*depth; // actual distance from the lens 
+    }
+    float sampleCoC(const in vec2 offset) {
+        float coc = texture2D(circleOfConfusionSampler, offset).r; 
+        return coc; // actual distance from the lens 
+    }
 #endif
 
 #include<kernelBlurVaryingDeclaration>[0..varyingCount]
 
 #ifdef PACKEDFLOAT
-	vec4 pack(float depth)
-	{
-		const vec4 bit_shift = vec4(255.0 * 255.0 * 255.0, 255.0 * 255.0, 255.0, 1.0);
-		const vec4 bit_mask = vec4(0.0, 1.0 / 255.0, 1.0 / 255.0, 1.0 / 255.0);
-
-		vec4 res = fract(depth * bit_shift);
-		res -= res.xxyz * bit_mask;
-
-		return res;
-	}
-
-	float unpack(vec4 color)
-	{
-		const vec4 bit_shift = vec4(1.0 / (255.0 * 255.0 * 255.0), 1.0 / (255.0 * 255.0), 1.0 / 255.0, 1.0);
-		return dot(color, bit_shift);
-	}
+    vec4 pack(float depth)
+    {
+        const vec4 bit_shift = vec4(255.0 * 255.0 * 255.0, 255.0 * 255.0, 255.0, 1.0);
+        const vec4 bit_mask = vec4(0.0, 1.0 / 255.0, 1.0 / 255.0, 1.0 / 255.0);
+
+        vec4 res = fract(depth * bit_shift);
+        res -= res.xxyz * bit_mask;
+
+        return res;
+    }
+
+    float unpack(vec4 color)
+    {
+        const vec4 bit_shift = vec4(1.0 / (255.0 * 255.0 * 255.0), 1.0 / (255.0 * 255.0), 1.0 / 255.0, 1.0);
+        return dot(color, bit_shift);
+    }
 #endif
 
 void main(void)
 {
-	#ifdef DOF
-		float sumOfWeights = 0.0; // Since not all values are blended, keep track of sum to devide result by at the end to get an average
-		float sampleDepth = 0.0;
-    	float factor = 0.0;
-		float centerSampleDepth = sampleDistance(sampleCenter);
-	#endif
-
-	float computedWeight = 0.0;
-
-	#ifdef PACKEDFLOAT	
-		float blend = 0.;
-	#else
-		vec4 blend = vec4(0.);
-	#endif
-
-	#include<kernelBlurFragment>[0..varyingCount]
-	#include<kernelBlurFragment2>[0..depCount]
-
-	#ifdef PACKEDFLOAT
-		gl_FragColor = pack(blend);
-	#else
-		gl_FragColor = blend;
-	#endif
-
-	#ifdef DOF
-		// If there are no samples to blend, make pixel black.
-		if(sumOfWeights == 0.0){
-			gl_FragColor = vec4(0.0,0.0,0.0,1.0);
-		}
-		gl_FragColor /= sumOfWeights;
-	#endif
+    float computedWeight = 0.0;
+
+    #ifdef PACKEDFLOAT	
+        float blend = 0.;
+    #else
+        vec4 blend = vec4(0.);
+    #endif
+
+    #ifdef DOF
+        float sumOfWeights = CENTER_WEIGHT; // Since not all values are blended, keep track of sum to devide result by at the end to get an average (start at center weight as center pixel is added by default)
+        float factor = 0.0;
+
+        // Add center pixel to the blur by default
+        #ifdef PACKEDFLOAT
+            blend += unpack(texture2D(textureSampler, sampleCenter)) * CENTER_WEIGHT;
+        #else
+            blend += texture2D(textureSampler, sampleCenter) * CENTER_WEIGHT;
+        #endif
+    #endif
+
+    #include<kernelBlurFragment>[0..varyingCount]
+    #include<kernelBlurFragment2>[0..depCount]
+
+    #ifdef PACKEDFLOAT
+        gl_FragColor = pack(blend);
+    #else
+        gl_FragColor = blend;
+    #endif
+
+    #ifdef DOF
+        gl_FragColor /= sumOfWeights;
+    #endif
 }

+ 22 - 0
src/Tools/babylon.decorators.ts

@@ -22,6 +22,7 @@
                 switch (propertyType) {
                     case 0:     // Value
                     case 6:     // Mesh reference
+                    case 11:    // Camera reference
                         (<any>destination)[property] = sourceProperty;
                         break;
                     case 1:     // Texture
@@ -182,6 +183,13 @@
         return generateSerializableMember(10, sourceName); // quaternion member
     }
 
+    /**
+     * Decorator used to define property that can be serialized as reference to a camera
+     * @param sourceName defines the name of the property to decorate
+     */
+    export function serializeAsCameraReference(sourceName?: string) {
+        return generateSerializableMember(11, sourceName); // camera reference member
+    }
 
     export class SerializationHelper {
 
@@ -236,6 +244,12 @@
                         case 9:     // Image Processing
                             serializationObject[targetPropertyName] = (<ImageProcessingConfiguration>sourceProperty).serialize();
                             break;
+                        case 10:    // Quaternion
+                            serializationObject[targetPropertyName] = (<Quaternion>sourceProperty).asArray();
+                            break;
+                        case 11:    // Camera reference
+                            serializationObject[targetPropertyName] = (<Camera>sourceProperty).id;
+                            break;
                     }
                 }
             }
@@ -300,6 +314,14 @@
                         case 9:     // Image Processing
                             dest[property] = ImageProcessingConfiguration.Parse(sourceProperty);
                             break;
+                        case 10:    // Quaternion
+                            dest[property] = Quaternion.FromArray(sourceProperty);
+                            break;
+                        case 11:    // Camera reference
+                            if (scene) {
+                                dest[property] = scene.getCameraByID(sourceProperty);
+                            }
+                            break;
                     }
                 }
             }

+ 4 - 0
src/babylon.scene.ts

@@ -2635,6 +2635,10 @@
                 }
                 this._activeAnimatables = [];
             }
+
+            for (var group of this.animationGroups) {
+                group.stop();
+            }
         }
 
         private _animate(): void {

+ 18 - 14
tests/nullEngine/app.js

@@ -1,5 +1,5 @@
 var BABYLON = require("../../dist/preview release/babylon.max");
-var LOADERS = require("../../dist/preview release/loaders/babylonjs.loaders");
+// var LOADERS = require("../../dist/preview release/loaders/babylonjs.loaders");
 global.XMLHttpRequest = require('xhr2').XMLHttpRequest;
 
 var engine = new BABYLON.NullEngine();
@@ -142,16 +142,20 @@ var engine = new BABYLON.NullEngine();
 //     //});
   
 //   }, progress => {}, (scene, err) => console.error('error:', err));
-var scene = new BABYLON.Scene(engine);
-var camera = new BABYLON.ArcRotateCamera("camera", 0, 0, 0, BABYLON.Vector3.Zero(), scene);
-scene.render();
-var pos = BABYLON.Vector3.Project(
-              new BABYLON.Vector3(0.5, 0.5, 0.5),
-              BABYLON.Matrix.Identity(),
-              scene.getTransformMatrix(),
-              scene.activeCamera.viewport.toGlobal(
-              engine.getRenderWidth(),
-              engine.getRenderHeight()
-            ));;
-
-            console.log(pos);
+// var scene = new BABYLON.Scene(engine);
+// var camera = new BABYLON.ArcRotateCamera("camera", 0, 0, 0, BABYLON.Vector3.Zero(), scene);
+// scene.render();
+// var pos = BABYLON.Vector3.Project(
+//               new BABYLON.Vector3(0.5, 0.5, 0.5),
+//               BABYLON.Matrix.Identity(),
+//               scene.getTransformMatrix(),
+//               scene.activeCamera.viewport.toGlobal(
+//               engine.getRenderWidth(),
+//               engine.getRenderHeight()
+//             ));;
+
+//             console.log(pos);
+
+const scene = new BABYLON.Scene(engine);
+new BABYLON.PBRMetallicRoughnessMaterial("asdfasf", scene);
+scene.dispose();

BIN
tests/validation/ReferenceImages/defaultPipeline.png


BIN
tests/validation/ReferenceImages/depthOfField.png


BIN
tests/validation/ReferenceImages/gltfUnlit.png


+ 5 - 0
tests/validation/config.json

@@ -292,6 +292,11 @@
       "referenceImage": "gltfBuggyDraco.png"
     },
     {
+      "title": "GLTF BoomBox with Unlit Material",
+      "playgroundId": "#GYM97C#2",
+      "referenceImage": "gltfUnlit.png"
+    },
+    {
       "title": "Asset Containers",
       "playgroundId": "#P3U079#19",
       "referenceImage": "assetContainer.png"