David Catuhe 7 年之前
父节点
当前提交
56b5ed7011
共有 94 个文件被更改,包括 155126 次插入26782 次删除
  1. 4 4
      .vscode/launch.json
  2. 28 3
      .vscode/tasks.json
  3. 32297 17377
      Playground/babylon.d.txt
  4. 5 3
      Playground/debug.html
  5. 4 2
      Playground/frame.html
  6. 4 2
      Playground/full.html
  7. 5 2
      Playground/index-local.html
  8. 5 3
      Playground/index.html
  9. 5 2
      Playground/indexStable.html
  10. 1 0
      Playground/scenes/dummy3.babylon
  11. 6 2
      Playground/zipContent/index.html
  12. 1 0
      Tools/Gulp/config.json
  13. 4 11
      Tools/Gulp/gulp-addModuleExports.js
  14. 37 0
      Tools/Gulp/gulp-decorateAndExtends.js
  15. 7 1
      Tools/Gulp/gulpfile.js
  16. 1 1
      Viewer/tsconfig.json
  17. 2 2
      Viewer/webpack.config.js
  18. 21729 7133
      dist/preview release/babylon.d.ts
  19. 55 55
      dist/preview release/babylon.js
  20. 898 222
      dist/preview release/babylon.max.js
  21. 96638 0
      dist/preview release/babylon.no-module.max.js
  22. 54 54
      dist/preview release/babylon.worker.js
  23. 30 31
      dist/preview release/draco_decoder.js
  24. 二进制
      dist/preview release/draco_decoder.wasm
  25. 115 0
      dist/preview release/draco_wasm_wrapper.js
  26. 896 220
      dist/preview release/es6.js
  27. 2 2
      dist/preview release/gui/babylon.gui.js
  28. 4 4
      dist/preview release/gui/babylon.gui.min.js
  29. 4 4
      dist/preview release/inspector/babylon.inspector.bundle.js
  30. 3 3
      dist/preview release/inspector/babylon.inspector.min.js
  31. 2 2
      dist/preview release/loaders/babylon.glTF1FileLoader.min.js
  32. 8 8
      dist/preview release/loaders/babylon.glTF2FileLoader.js
  33. 2 2
      dist/preview release/loaders/babylon.glTF2FileLoader.min.js
  34. 8 8
      dist/preview release/loaders/babylon.glTFFileLoader.js
  35. 3 3
      dist/preview release/loaders/babylon.glTFFileLoader.min.js
  36. 1 1
      dist/preview release/loaders/babylon.objFileLoader.min.js
  37. 10 10
      dist/preview release/loaders/babylonjs.loaders.js
  38. 3 3
      dist/preview release/loaders/babylonjs.loaders.min.js
  39. 1 1
      dist/preview release/materialsLibrary/babylon.customMaterial.min.js
  40. 1 1
      dist/preview release/materialsLibrary/babylon.shadowOnlyMaterial.min.js
  41. 1 1
      dist/preview release/materialsLibrary/babylon.waterMaterial.min.js
  42. 2 2
      dist/preview release/materialsLibrary/babylonjs.materials.js
  43. 5 5
      dist/preview release/materialsLibrary/babylonjs.materials.min.js
  44. 1 1
      dist/preview release/postProcessesLibrary/babylon.asciiArtPostProcess.min.js
  45. 1 1
      dist/preview release/postProcessesLibrary/babylon.digitalRainPostProcess.min.js
  46. 2 2
      dist/preview release/postProcessesLibrary/babylonjs.postProcess.js
  47. 1 1
      dist/preview release/postProcessesLibrary/babylonjs.postProcess.min.js
  48. 2 2
      dist/preview release/proceduralTexturesLibrary/babylonjs.proceduralTextures.js
  49. 1 1
      dist/preview release/proceduralTexturesLibrary/babylonjs.proceduralTextures.min.js
  50. 1 1
      dist/preview release/serializers/babylon.glTF2Serializer.min.js
  51. 2 2
      dist/preview release/serializers/babylonjs.serializers.js
  52. 1 1
      dist/preview release/serializers/babylonjs.serializers.min.js
  53. 115 944
      dist/preview release/typedocValidationBaseline.json
  54. 64 64
      dist/preview release/viewer/babylon.viewer.js
  55. 913 237
      dist/preview release/viewer/babylon.viewer.max.js
  56. 5 0
      dist/preview release/what's new.md
  57. 14 9
      loaders/src/glTF/2.0/Extensions/KHR_draco_mesh_compression.ts
  58. 3 1
      localDev/index.html
  59. 3 1
      sandbox/index-local.html
  60. 5 1
      sandbox/index.html
  61. 4 2
      sandbox/index.js
  62. 11 4
      src/Actions/babylon.actionManager.ts
  63. 19 3
      src/Animations/babylon.animation.ts
  64. 17 3
      src/Animations/babylon.runtimeAnimation.ts
  65. 3 3
      src/Cameras/babylon.camera.ts
  66. 19 0
      src/Layer/babylon.effectLayer.ts
  67. 3 1
      src/Layer/babylon.glowLayer.ts
  68. 86 0
      src/Layer/babylon.highlightLayer.ts
  69. 16 1
      src/Loading/Plugins/babylon.babylonFileLoader.ts
  70. 17 0
      src/Materials/Textures/babylon.cubeTexture.ts
  71. 19 0
      src/Materials/Textures/babylon.hdrCubeTexture.ts
  72. 13 1
      src/Materials/Textures/babylon.mirrorTexture.ts
  73. 1 1
      src/Materials/Textures/babylon.renderTargetTexture.ts
  74. 13 0
      src/Materials/babylon.standardMaterial.ts
  75. 62 27
      src/Math/babylon.math.ts
  76. 153 105
      src/Mesh/Compression/babylon.dracoCompression.ts
  77. 6 6
      src/Mesh/babylon.buffer.ts
  78. 10 8
      src/Mesh/babylon.geometry.ts
  79. 308 57
      src/Mesh/babylon.mesh.vertexData.ts
  80. 6 3
      src/Mesh/babylon.vertexBuffer.ts
  81. 70 4
      src/Morph/babylon.morphTarget.ts
  82. 72 8
      src/Morph/babylon.morphTargetManager.ts
  83. 6 3
      src/PostProcess/RenderPipeline/babylon.postProcessRenderEffect.ts
  84. 6 6
      src/PostProcess/babylon.bloomEffect.ts
  85. 7 7
      src/PostProcess/babylon.depthOfFieldEffect.ts
  86. 58 55
      src/Shaders/default.fragment.fx
  87. 10 0
      src/Tools/babylon.sceneSerializer.ts
  88. 1 1
      src/Tools/babylon.tools.ts
  89. 16 1
      src/babylon.assetContainer.ts
  90. 53 10
      src/babylon.scene.ts
  91. 二进制
      tests/validation/ReferenceImages/enableDisablePostProcess.png
  92. 4 1
      tests/validation/index.html
  93. 0 1
      tests/validation/validate.html
  94. 12 1
      tests/validation/validation.js

+ 4 - 4
.vscode/launch.json

@@ -5,10 +5,10 @@
             "name": "Launch Viewer (Chrome)",
             "type": "chrome",
             "request": "launch",
-            "url": "http://localhost:9000/",
-            "webRoot": "${workspaceRoot}/Viewer/dist/",
+            "url": "http://localhost:9000/basicExample.html",
+            "webRoot": "${workspaceRoot}/Viewer/",
             "sourceMaps": true,
-            //"preLaunchTask": "build-viewer", // TODO - test why this fails.
+            "preLaunchTask": "serve-viewer",
             "userDataDir": "${workspaceRoot}/.tempChromeProfileForDebug",
             "runtimeArgs": [
                 "--enable-unsafe-es3-apis"
@@ -171,6 +171,6 @@
             "runtimeArgs": [
                 "--enable-unsafe-es3-apis"
             ]
-        },        
+        },
     ]
 }

+ 28 - 3
.vscode/tasks.json

@@ -15,7 +15,7 @@
         "panel": "shared"
     },
     "tasks": [
-        { 
+        {
             "label": "run",
             "group": {
                 "kind": "build",
@@ -40,12 +40,37 @@
                 }
             }
         },
-        { 
+        {
             "taskName": "typescript-all",
             "isBuildCommand": true,
             "problemMatcher": [
                 "$tsc"
             ]
+        },
+        {
+            "label": "serve-viewer",
+            "type": "npm",
+            "script": "start:server",
+            "path": "Viewer/",
+            "problemMatcher": [
+                {
+                    "owner": "webpack-dev-server",
+                    "pattern": {
+                        "regexp": "^([^\\s].*)\\((\\d+|\\,\\d+|\\d+,\\d+,\\d+,\\d+)\\):\\s+(error|warning|info)\\s+(TS\\d+)\\s*:\\s*(.*)$",
+                        "file": 1,
+                        "location": 2,
+                        "severity": 3,
+                        "code": 4,
+                        "message": 5
+                    },
+                    "background": {
+                        "activeOnStart": true,
+                        "beginsPattern": "Project is running at",
+                        "endsPattern": "webpack: Compiled successfully."
+                    }
+                }
+            ],
+            "isBackground": true
         }
     ]
-}
+}

文件差异内容过多而无法显示
+ 32297 - 17377
Playground/babylon.d.txt


+ 5 - 3
Playground/debug.html

@@ -33,11 +33,14 @@
     <!-- jszip -->
     <script src="js/libs/jszip.min.js"></script>
     <script src="js/libs/fileSaver.js"></script>
-    <!--Monaco-->
+    <!-- Draco -->
+    <script src="https://preview.babylonjs.com/draco_decoder.js" type="text/x-draco-decoder"></script>
+    <script src="https://preview.babylonjs.com/draco_decoder.wasm" type="text/x-draco-decoder-wasm-binary"></script>
+    <script src="https://preview.babylonjs.com/draco_wasm_wrapper.js" type="text/x-draco-decoder-wasm-wrapper"></script>
+    <!-- Monaco -->
     <script src="node_modules/monaco-editor/min/vs/loader.js"></script>
     <!-- Babylon.js -->
     <script src="https://preview.babylonjs.com/cannon.js"></script>
-    <script src="https://preview.babylonjs.com/draco_decoder.js" type="text/x-draco-decoder"></script>
     <script src="https://preview.babylonjs.com/Oimo.js"></script>
     <script src="https://preview.babylonjs.com/babylon.max.js"></script>
     <script src="https://preview.babylonjs.com/inspector/babylon.inspector.bundle.js"></script>
@@ -77,7 +80,6 @@
     <script src="https://preview.babylonjs.com/serializers/babylonjs.serializers.min.js"></script>
 
     <script src="https://rawgit.com/BabylonJS/Extensions/master/ClonerSystem/src/babylonx.cloner.js"></script>
-    <script src="https://rawgit.com/BabylonJS/Extensions/master/canvas2D/dist/preview%20release/babylon.canvas2d.js"></script>
     <script src="https://rawgit.com/BabylonJS/Extensions/master/CompoundShader/src/babylonx.CompoundShader.js"></script>
     <link href="css/index.css" rel="stylesheet" />
 

+ 4 - 2
Playground/frame.html

@@ -24,9 +24,12 @@
     <meta name="theme-color" content="#ffffff">
 
     <script src="https://code.jquery.com/pep/0.4.2/pep.min.js"></script>
+    <!-- Draco -->
+    <script src="https://preview.babylonjs.com/draco_decoder.js" type="text/x-draco-decoder"></script>
+    <script src="https://preview.babylonjs.com/draco_decoder.wasm" type="text/x-draco-decoder-wasm-binary"></script>
+    <script src="https://preview.babylonjs.com/draco_wasm_wrapper.js" type="text/x-draco-decoder-wasm-wrapper"></script>
     <!-- Babylon.js -->
     <script src="https://preview.babylonjs.com/cannon.js"></script>
-    <script src="https://preview.babylonjs.com/draco_decoder.js" type="text/x-draco-decoder"></script>
     <script src="https://preview.babylonjs.com/Oimo.js"></script>
     <script src="https://preview.babylonjs.com/babylon.js"></script>
     <script src="https://preview.babylonjs.com/inspector/babylon.inspector.bundle.js"></script>
@@ -66,7 +69,6 @@
     <script src="https://preview.babylonjs.com/gui/babylon.gui.min.js"></script>
 
     <script src="https://rawgit.com/BabylonJS/Extensions/master/ClonerSystem/src/babylonx.cloner.js"></script>
-    <script src="https://rawgit.com/BabylonJS/Extensions/master/canvas2D/dist/preview%20release/babylon.canvas2d.min.js"></script>
     <script src="https://rawgit.com/BabylonJS/Extensions/master/CompoundShader/src/babylonx.CompoundShader.js"></script>
     <link href="frame.css" rel="stylesheet" />
 </head>

+ 4 - 2
Playground/full.html

@@ -24,9 +24,12 @@
         <meta name="theme-color" content="#ffffff">
 
         <script src="https://code.jquery.com/pep/0.4.2/pep.min.js"></script>
+        <!-- Draco -->
+        <script src="https://preview.babylonjs.com/draco_decoder.js" type="text/x-draco-decoder"></script>
+        <script src="https://preview.babylonjs.com/draco_decoder.wasm" type="text/x-draco-decoder-wasm-binary"></script>
+        <script src="https://preview.babylonjs.com/draco_wasm_wrapper.js" type="text/x-draco-decoder-wasm-wrapper"></script>
         <!-- Babylon.js -->
         <script src="https://preview.babylonjs.com/cannon.js"></script>
-        <script src="https://preview.babylonjs.com/draco_decoder.js" type="text/x-draco-decoder"></script>
         <script src="https://preview.babylonjs.com/Oimo.js"></script>
         <script src="https://preview.babylonjs.com/babylon.js"></script>
         <script src="https://preview.babylonjs.com/inspector/babylon.inspector.bundle.js"></script>
@@ -42,7 +45,6 @@
         <script src="https://preview.babylonjs.com/gui/babylon.gui.min.js"></script>
 
         <script src="https://rawgit.com/BabylonJS/Extensions/master/ClonerSystem/src/babylonx.cloner.js"></script>
-        <script src="https://rawgit.com/BabylonJS/Extensions/master/canvas2D/dist/preview%20release/babylon.canvas2d.min.js"></script>
         <script src="https://rawgit.com/BabylonJS/Extensions/master/CompoundShader/src/babylonx.CompoundShader.js"></script>
         <link href="frame.css" rel="stylesheet" />
     </head>

+ 5 - 2
Playground/index-local.html

@@ -17,10 +17,13 @@
         <script src="../dist/preview%20release/cannon.js"></script>
         <script src="../dist/preview%20release/Oimo.js"></script>
         <script src="../dist/preview%20release/earcut.min.js"></script>
-        <!--Monaco-->
+        <!-- Draco -->
+        <script src="../dist/preview%20release/draco_decoder.js" type="text/x-draco-decoder"></script>
+        <script src="../dist/preview%20release/draco_decoder.wasm" type="text/x-draco-decoder-wasm-binary"></script>
+        <script src="../dist/preview%20release/draco_wasm_wrapper.js" type="text/x-draco-decoder-wasm-wrapper"></script>
+        <!-- Monaco -->
         <script src="node_modules/monaco-editor/min/vs/loader.js"></script>
         <!-- Babylon.js -->
-        <script src="../dist/preview%20release/draco_decoder.js" type="text/x-draco-decoder"></script>
         <script src="../tools/DevLoader/BabylonLoader.js"></script>
 
         <link href="css/index.css" rel="stylesheet" />

+ 5 - 3
Playground/index.html

@@ -37,10 +37,13 @@
         <script src="https://preview.babylonjs.com/cannon.js"></script>
         <script src="https://preview.babylonjs.com/Oimo.js"></script>
         <script src="https://preview.babylonjs.com/earcut.min.js"></script>
-        <!--Monaco-->
+        <!-- Draco -->
+        <script src="https://preview.babylonjs.com/draco_decoder.js" type="text/x-draco-decoder"></script>
+        <script src="https://preview.babylonjs.com/draco_decoder.wasm" type="text/x-draco-decoder-wasm-binary"></script>
+        <script src="https://preview.babylonjs.com/draco_wasm_wrapper.js" type="text/x-draco-decoder-wasm-wrapper"></script>
+        <!-- Monaco -->
         <script src="node_modules/monaco-editor/min/vs/loader.js"></script>
         <!-- Babylon.js -->
-        <script src="https://preview.babylonjs.com/draco_decoder.js" type="text/x-draco-decoder"></script>
         <script src="https://preview.babylonjs.com/babylon.js"></script>
         <script src="https://preview.babylonjs.com/inspector/babylon.inspector.bundle.js"></script>
 
@@ -57,7 +60,6 @@
         <script src="https://preview.babylonjs.com/gui/babylon.gui.min.js"></script>
 
         <script src="https://rawgit.com/BabylonJS/Extensions/master/ClonerSystem/src/babylonx.cloner.js"></script>
-        <script src="https://rawgit.com/BabylonJS/Extensions/master/canvas2D/dist/preview%20release/babylon.canvas2d.min.js"></script>
         <script src="https://rawgit.com/BabylonJS/Extensions/master/CompoundShader/src/babylonx.CompoundShader.js"></script>
         <link href="css/index.css" rel="stylesheet" />
     </head>

+ 5 - 2
Playground/indexStable.html

@@ -36,10 +36,13 @@
         <!-- Physics -->
         <script src="https://cdn.babylonjs.com/cannon.js"></script>
         <script src="https://cdn.babylonjs.com/Oimo.js"></script>
-        <!--Monaco-->
+        <!-- Draco -->
+        <script src="https://cdn.babylonjs.com/draco_decoder.js" type="text/x-draco-decoder"></script>
+        <script src="https://cdn.babylonjs.com/draco_decoder.wasm" type="text/x-draco-decoder-wasm-binary"></script>
+        <script src="https://cdn.babylonjs.com/draco_wasm_wrapper.js" type="text/x-draco-decoder-wasm-wrapper"></script>
+        <!-- Monaco -->
         <script src="node_modules/monaco-editor/min/vs/loader.js"></script>
         <!-- Babylon.js -->
-        <script src="https://cdn.babylonjs.com/draco_decoder.js" type="text/x-draco-decoder"></script>
         <script src="https://cdn.babylonjs.com/babylon.js"></script>
         <script src="https://cdn.babylonjs.com/inspector/babylon.inspector.bundle.js"></script>
 

文件差异内容过多而无法显示
+ 1 - 0
Playground/scenes/dummy3.babylon


+ 6 - 2
Playground/zipContent/index.html

@@ -4,14 +4,18 @@
         <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
 
         <title>Babylon.js sample code</title>
+
+        <!-- Draco -->
+        <script src="https://preview.babylonjs.com/draco_decoder.js" type="text/x-draco-decoder"></script>
+        <script src="https://preview.babylonjs.com/draco_decoder.wasm" type="text/x-draco-decoder-wasm-binary"></script>
+        <script src="https://preview.babylonjs.com/draco_wasm_wrapper.js" type="text/x-draco-decoder-wasm-wrapper"></script>
         <!-- Babylon.js -->
         <script src="https://www.babylonjs.com/hand.minified-1.2.js"></script>
         <script src="https://preview.babylonjs.com/babylon.js"></script>
         <script src="https://preview.babylonjs.com/gui/babylon.gui.min.js"></script>
         <script src="https://preview.babylonjs.com/cannon.js"></script>
-        <script src="https://preview.babylonjs.com/draco_decoder.js" type="text/x-draco-decoder"></script>
         <script src="https://preview.babylonjs.com/oimo.js"></script>
-        
+
         <style>
             html, body {
                 overflow: hidden;

+ 1 - 0
Tools/Gulp/config.json

@@ -3,6 +3,7 @@
         "filename": "babylon.max.js",
         "minFilename": "babylon.js",
         "minWorkerFilename": "babylon.worker.js",
+        "noModuleFilename": "babylon.no-module.max.js",
         "declarationFilename": "babylon.d.ts",
         "declarationModuleFilename": "babylon.module.d.ts",
         "outputDirectory": "../../dist/preview release",

+ 4 - 11
Tools/Gulp/gulp-addModuleExports.js

@@ -87,13 +87,6 @@ if(typeof earcut !== 'undefined') {
 `;
         }
 
-        var extendsAddition =
-            `var __extends=this&&this.__extends||function(){var t=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(t,o){t.__proto__=o}||function(t,o){for(var n in o)o.hasOwnProperty(n)&&(t[n]=o[n])};return function(o,n){function r(){this.constructor=o}t(o,n),o.prototype=null===n?Object.create(n):(r.prototype=n.prototype,new r)}}();
-`;
-
-        var decorateAddition = `var __decorate=this&&this.__decorate||function(e,t,r,c){var o,f=arguments.length,n=f<3?t:null===c?c=Object.getOwnPropertyDescriptor(t,r):c;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)n=Reflect.decorate(e,t,r,c);else for(var l=e.length-1;l>=0;l--)(o=e[l])&&(n=(f<3?o(n):f>3?o(t,r,n):o(t,r))||n);return f>3&&n&&Object.defineProperty(t,r,n),n};
-`;
-
         if (file.isNull()) {
             cb(null, file);
             return;
@@ -105,12 +98,12 @@ if(typeof earcut !== 'undefined') {
         }
 
         try {
-            if (config.externalUsingBabylon) {
-                file.contents = new Buffer(String('').concat(moduleExportAddition(varName)));
-            } else {
+            //if (config.externalUsingBabylon) {
+            file.contents = new Buffer(String('').concat(moduleExportAddition(varName)));
+            /*} else {
                 let pretext = '';
                 file.contents = new Buffer(decorateAddition.concat(new Buffer(extendsAddition.concat(String('')).concat(moduleExportAddition(varName)))));
-            }
+            }*/
             this.push(file);
         } catch (err) {
             this.emit('error', new gutil.PluginError('gulp-add-module-exports', err, { fileName: file.path }));

+ 37 - 0
Tools/Gulp/gulp-decorateAndExtends.js

@@ -0,0 +1,37 @@
+var gutil = require('gulp-util');
+var through = require('through2');
+
+/**
+ * The parameters for this function has grown during development.
+ * Eventually, this function will need to be reorganized. 
+ */
+//  subModule, extendsRoot, externalUsingBabylon, noBabylonInit
+module.exports = function (varName, config) {
+    return through.obj(function (file, enc, cb) {
+
+        var extendsAddition =
+            `var __extends=this&&this.__extends||function(){var t=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(t,o){t.__proto__=o}||function(t,o){for(var n in o)o.hasOwnProperty(n)&&(t[n]=o[n])};return function(o,n){function r(){this.constructor=o}t(o,n),o.prototype=null===n?Object.create(n):(r.prototype=n.prototype,new r)}}();
+`;
+
+        var decorateAddition = `var __decorate=this&&this.__decorate||function(e,t,r,c){var o,f=arguments.length,n=f<3?t:null===c?c=Object.getOwnPropertyDescriptor(t,r):c;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)n=Reflect.decorate(e,t,r,c);else for(var l=e.length-1;l>=0;l--)(o=e[l])&&(n=(f<3?o(n):f>3?o(t,r,n):o(t,r))||n);return f>3&&n&&Object.defineProperty(t,r,n),n};
+`;
+
+        if (file.isNull()) {
+            cb(null, file);
+            return;
+        }
+
+        if (file.isStream()) {
+            //streams not supported, no need for now.
+            return;
+        }
+
+        try {
+            file.contents = new Buffer(decorateAddition.concat(extendsAddition).concat(file.contents));
+            this.push(file);
+        } catch (err) {
+            this.emit('error', new gutil.PluginError('gulp-decorate-and-extends', err, { fileName: file.path }));
+        }
+        cb();
+    });
+};

+ 7 - 1
Tools/Gulp/gulpfile.js

@@ -5,6 +5,7 @@ var sourcemaps = require("gulp-sourcemaps");
 var srcToVariable = require("gulp-content-to-variable");
 var appendSrcToVariable = require("./gulp-appendSrcToVariable");
 var addDtsExport = require("./gulp-addDtsExport");
+var addDecorateAndExtends = require("./gulp-decorateAndExtends");
 var addModuleExports = require("./gulp-addModuleExports");
 var addES6Exports = require("./gulp-addES6Exports");
 var babylonModuleExports = require("./gulp-babylonModule");
@@ -239,10 +240,13 @@ gulp.task("build", ["shaders"], function () {
     )
     return merge2(
         mergedStreams
-            .pipe(concat(config.build.filename))
+            .pipe(concat(config.build.noModuleFilename))
             .pipe(cleants())
             .pipe(replace(extendsSearchRegex, ""))
             .pipe(replace(decorateSearchRegex, ""))
+            .pipe(addDecorateAndExtends())
+            .pipe(gulp.dest(config.build.outputDirectory))
+            .pipe(rename(config.build.filename))
             .pipe(addModuleExports("BABYLON", {
                 dependencies: config.build.dependencies
             }))
@@ -322,6 +326,7 @@ var buildExternalLibraries = function (settings) {
                 .pipe(replace(extendsSearchRegex, ""))
                 .pipe(replace(decorateSearchRegex, ""))
                 .pipe(replace(referenceSearchRegex, ""))
+                .pipe(addDecorateAndExtends())
                 .pipe(addModuleExports(settings.build.moduleDeclaration, { subModule: true, extendsRoot: settings.build.extendsRoot }))
                 .pipe(gulp.dest(outputDirectory))
                 .pipe(cleants())
@@ -405,6 +410,7 @@ var buildExternalLibrary = function (library, settings, watch) {
         if (library.buildAsModule) {
             code = code.pipe(replace(extendsSearchRegex, ""))
                 .pipe(replace(decorateSearchRegex, ""))
+                .pipe(addDecorateAndExtends())
                 .pipe(addModuleExports(library.moduleDeclaration, { subModule: true, extendsRoot: library.extendsRoot }))
         }
 

+ 1 - 1
Viewer/tsconfig.json

@@ -7,7 +7,7 @@
         "strictNullChecks": true,
         "removeComments": true,
         "preserveConstEnums": true,
-        "sourceMap": false,
+        "sourceMap": true,
         "experimentalDecorators": true,
         "isolatedModules": false,
         "declaration": false,

+ 2 - 2
Viewer/webpack.config.js

@@ -11,7 +11,7 @@ module.exports = {
         libraryTarget: 'umd',
         library: 'BabylonViewer',
         umdNamedDefine: true,
-        devtoolModuleFilenameTemplate: '[absolute-resource-path]'
+        devtoolModuleFilenameTemplate: '[relative-resource-path]'
     },
     resolve: {
         extensions: ['.ts', '.js'],
@@ -57,7 +57,7 @@ module.exports = {
     },
     devServer: {
         contentBase: path.join(__dirname, "dist"),
-        compress: true,
+        compress: false,
         //open: true,
         port: 9000
     }

文件差异内容过多而无法显示
+ 21729 - 7133
dist/preview release/babylon.d.ts


文件差异内容过多而无法显示
+ 55 - 55
dist/preview release/babylon.js


文件差异内容过多而无法显示
+ 898 - 222
dist/preview release/babylon.max.js


文件差异内容过多而无法显示
+ 96638 - 0
dist/preview release/babylon.no-module.max.js


文件差异内容过多而无法显示
+ 54 - 54
dist/preview release/babylon.worker.js


文件差异内容过多而无法显示
+ 30 - 31
dist/preview release/draco_decoder.js


二进制
dist/preview release/draco_decoder.wasm


文件差异内容过多而无法显示
+ 115 - 0
dist/preview release/draco_wasm_wrapper.js


文件差异内容过多而无法显示
+ 896 - 220
dist/preview release/es6.js


+ 2 - 2
dist/preview release/gui/babylon.gui.js

@@ -1,5 +1,3 @@
-var __decorate=this&&this.__decorate||function(e,t,r,c){var o,f=arguments.length,n=f<3?t:null===c?c=Object.getOwnPropertyDescriptor(t,r):c;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)n=Reflect.decorate(e,t,r,c);else for(var l=e.length-1;l>=0;l--)(o=e[l])&&(n=(f<3?o(n):f>3?o(t,r,n):o(t,r))||n);return f>3&&n&&Object.defineProperty(t,r,n),n};
-var __extends=this&&this.__extends||function(){var t=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(t,o){t.__proto__=o}||function(t,o){for(var n in o)o.hasOwnProperty(n)&&(t[n]=o[n])};return function(o,n){function r(){this.constructor=o}t(o,n),o.prototype=null===n?Object.create(n):(r.prototype=n.prototype,new r)}}();
 
 
 (function universalModuleDefinition(root, factory) {
@@ -23,6 +21,8 @@ var __extends=this&&this.__extends||function(){var t=Object.setPrototypeOf||{__p
 })(this, function(BABYLON) {
   BABYLON = BABYLON || this.BABYLON;
 
+var __decorate=this&&this.__decorate||function(e,t,r,c){var o,f=arguments.length,n=f<3?t:null===c?c=Object.getOwnPropertyDescriptor(t,r):c;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)n=Reflect.decorate(e,t,r,c);else for(var l=e.length-1;l>=0;l--)(o=e[l])&&(n=(f<3?o(n):f>3?o(t,r,n):o(t,r))||n);return f>3&&n&&Object.defineProperty(t,r,n),n};
+var __extends=this&&this.__extends||function(){var t=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(t,o){t.__proto__=o}||function(t,o){for(var n in o)o.hasOwnProperty(n)&&(t[n]=o[n])};return function(o,n){function r(){this.constructor=o}t(o,n),o.prototype=null===n?Object.create(n):(r.prototype=n.prototype,new r)}}();
 "use strict";
 /// <reference path="../../dist/preview release/babylon.d.ts"/>
 

文件差异内容过多而无法显示
+ 4 - 4
dist/preview release/gui/babylon.gui.min.js


文件差异内容过多而无法显示
+ 4 - 4
dist/preview release/inspector/babylon.inspector.bundle.js


文件差异内容过多而无法显示
+ 3 - 3
dist/preview release/inspector/babylon.inspector.min.js


文件差异内容过多而无法显示
+ 2 - 2
dist/preview release/loaders/babylon.glTF1FileLoader.min.js


+ 8 - 8
dist/preview release/loaders/babylon.glTF2FileLoader.js

@@ -2189,7 +2189,7 @@ var BABYLON;
                     _this.name = NAME;
                     _this._dracoCompression = null;
                     // Disable extension if decoder is not available.
-                    if (!BABYLON.DracoCompression.DecoderUrl) {
+                    if (!BABYLON.DracoCompression.DecoderAvailable) {
                         _this.enabled = false;
                     }
                     return _this;
@@ -2234,8 +2234,8 @@ var BABYLON;
                         loadAttribute("WEIGHTS_0", BABYLON.VertexBuffer.MatricesWeightsKind);
                         loadAttribute("COLOR_0", BABYLON.VertexBuffer.ColorKind);
                         var bufferView = GLTF2.GLTFLoader._GetProperty(extensionContext, _this._loader._gltf.bufferViews, extension.bufferView);
-                        return _this._loader._loadBufferViewAsync("#/bufferViews/" + bufferView._index, bufferView).then(function (data) {
-                            try {
+                        if (!bufferView._dracoBabylonGeometry) {
+                            bufferView._dracoBabylonGeometry = _this._loader._loadBufferViewAsync("#/bufferViews/" + bufferView._index, bufferView).then(function (data) {
                                 if (!_this._dracoCompression) {
                                     _this._dracoCompression = new BABYLON.DracoCompression();
                                 }
@@ -2243,12 +2243,12 @@ var BABYLON;
                                     var babylonGeometry = new BABYLON.Geometry(babylonMesh.name, _this._loader._babylonScene);
                                     babylonVertexData.applyToGeometry(babylonGeometry);
                                     return babylonGeometry;
+                                }).catch(function (error) {
+                                    throw new Error(context + ": " + error.message);
                                 });
-                            }
-                            catch (e) {
-                                throw new Error(context + ": " + e.message);
-                            }
-                        });
+                            });
+                        }
+                        return bufferView._dracoBabylonGeometry;
                     });
                 };
                 return KHR_draco_mesh_compression;

文件差异内容过多而无法显示
+ 2 - 2
dist/preview release/loaders/babylon.glTF2FileLoader.min.js


+ 8 - 8
dist/preview release/loaders/babylon.glTFFileLoader.js

@@ -4387,7 +4387,7 @@ var BABYLON;
                     _this.name = NAME;
                     _this._dracoCompression = null;
                     // Disable extension if decoder is not available.
-                    if (!BABYLON.DracoCompression.DecoderUrl) {
+                    if (!BABYLON.DracoCompression.DecoderAvailable) {
                         _this.enabled = false;
                     }
                     return _this;
@@ -4432,8 +4432,8 @@ var BABYLON;
                         loadAttribute("WEIGHTS_0", BABYLON.VertexBuffer.MatricesWeightsKind);
                         loadAttribute("COLOR_0", BABYLON.VertexBuffer.ColorKind);
                         var bufferView = GLTF2.GLTFLoader._GetProperty(extensionContext, _this._loader._gltf.bufferViews, extension.bufferView);
-                        return _this._loader._loadBufferViewAsync("#/bufferViews/" + bufferView._index, bufferView).then(function (data) {
-                            try {
+                        if (!bufferView._dracoBabylonGeometry) {
+                            bufferView._dracoBabylonGeometry = _this._loader._loadBufferViewAsync("#/bufferViews/" + bufferView._index, bufferView).then(function (data) {
                                 if (!_this._dracoCompression) {
                                     _this._dracoCompression = new BABYLON.DracoCompression();
                                 }
@@ -4441,12 +4441,12 @@ var BABYLON;
                                     var babylonGeometry = new BABYLON.Geometry(babylonMesh.name, _this._loader._babylonScene);
                                     babylonVertexData.applyToGeometry(babylonGeometry);
                                     return babylonGeometry;
+                                }).catch(function (error) {
+                                    throw new Error(context + ": " + error.message);
                                 });
-                            }
-                            catch (e) {
-                                throw new Error(context + ": " + e.message);
-                            }
-                        });
+                            });
+                        }
+                        return bufferView._dracoBabylonGeometry;
                     });
                 };
                 return KHR_draco_mesh_compression;

文件差异内容过多而无法显示
+ 3 - 3
dist/preview release/loaders/babylon.glTFFileLoader.min.js


文件差异内容过多而无法显示
+ 1 - 1
dist/preview release/loaders/babylon.objFileLoader.min.js


+ 10 - 10
dist/preview release/loaders/babylonjs.loaders.js

@@ -1,5 +1,3 @@
-var __decorate=this&&this.__decorate||function(e,t,r,c){var o,f=arguments.length,n=f<3?t:null===c?c=Object.getOwnPropertyDescriptor(t,r):c;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)n=Reflect.decorate(e,t,r,c);else for(var l=e.length-1;l>=0;l--)(o=e[l])&&(n=(f<3?o(n):f>3?o(t,r,n):o(t,r))||n);return f>3&&n&&Object.defineProperty(t,r,n),n};
-var __extends=this&&this.__extends||function(){var t=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(t,o){t.__proto__=o}||function(t,o){for(var n in o)o.hasOwnProperty(n)&&(t[n]=o[n])};return function(o,n){function r(){this.constructor=o}t(o,n),o.prototype=null===n?Object.create(n):(r.prototype=n.prototype,new r)}}();
 
 
 (function universalModuleDefinition(root, factory) {
@@ -23,6 +21,8 @@ var __extends=this&&this.__extends||function(){var t=Object.setPrototypeOf||{__p
 })(this, function(BABYLON) {
   BABYLON = BABYLON || this.BABYLON;
 
+var __decorate=this&&this.__decorate||function(e,t,r,c){var o,f=arguments.length,n=f<3?t:null===c?c=Object.getOwnPropertyDescriptor(t,r):c;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)n=Reflect.decorate(e,t,r,c);else for(var l=e.length-1;l>=0;l--)(o=e[l])&&(n=(f<3?o(n):f>3?o(t,r,n):o(t,r))||n);return f>3&&n&&Object.defineProperty(t,r,n),n};
+var __extends=this&&this.__extends||function(){var t=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(t,o){t.__proto__=o}||function(t,o){for(var n in o)o.hasOwnProperty(n)&&(t[n]=o[n])};return function(o,n){function r(){this.constructor=o}t(o,n),o.prototype=null===n?Object.create(n):(r.prototype=n.prototype,new r)}}();
 "use strict";
 
 var BABYLON;
@@ -5348,7 +5348,7 @@ var BABYLON;
                     _this.name = NAME;
                     _this._dracoCompression = null;
                     // Disable extension if decoder is not available.
-                    if (!BABYLON.DracoCompression.DecoderUrl) {
+                    if (!BABYLON.DracoCompression.DecoderAvailable) {
                         _this.enabled = false;
                     }
                     return _this;
@@ -5393,8 +5393,8 @@ var BABYLON;
                         loadAttribute("WEIGHTS_0", BABYLON.VertexBuffer.MatricesWeightsKind);
                         loadAttribute("COLOR_0", BABYLON.VertexBuffer.ColorKind);
                         var bufferView = GLTF2.GLTFLoader._GetProperty(extensionContext, _this._loader._gltf.bufferViews, extension.bufferView);
-                        return _this._loader._loadBufferViewAsync("#/bufferViews/" + bufferView._index, bufferView).then(function (data) {
-                            try {
+                        if (!bufferView._dracoBabylonGeometry) {
+                            bufferView._dracoBabylonGeometry = _this._loader._loadBufferViewAsync("#/bufferViews/" + bufferView._index, bufferView).then(function (data) {
                                 if (!_this._dracoCompression) {
                                     _this._dracoCompression = new BABYLON.DracoCompression();
                                 }
@@ -5402,12 +5402,12 @@ var BABYLON;
                                     var babylonGeometry = new BABYLON.Geometry(babylonMesh.name, _this._loader._babylonScene);
                                     babylonVertexData.applyToGeometry(babylonGeometry);
                                     return babylonGeometry;
+                                }).catch(function (error) {
+                                    throw new Error(context + ": " + error.message);
                                 });
-                            }
-                            catch (e) {
-                                throw new Error(context + ": " + e.message);
-                            }
-                        });
+                            });
+                        }
+                        return bufferView._dracoBabylonGeometry;
                     });
                 };
                 return KHR_draco_mesh_compression;

文件差异内容过多而无法显示
+ 3 - 3
dist/preview release/loaders/babylonjs.loaders.min.js


文件差异内容过多而无法显示
+ 1 - 1
dist/preview release/materialsLibrary/babylon.customMaterial.min.js


文件差异内容过多而无法显示
+ 1 - 1
dist/preview release/materialsLibrary/babylon.shadowOnlyMaterial.min.js


文件差异内容过多而无法显示
+ 1 - 1
dist/preview release/materialsLibrary/babylon.waterMaterial.min.js


+ 2 - 2
dist/preview release/materialsLibrary/babylonjs.materials.js

@@ -1,5 +1,3 @@
-var __decorate=this&&this.__decorate||function(e,t,r,c){var o,f=arguments.length,n=f<3?t:null===c?c=Object.getOwnPropertyDescriptor(t,r):c;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)n=Reflect.decorate(e,t,r,c);else for(var l=e.length-1;l>=0;l--)(o=e[l])&&(n=(f<3?o(n):f>3?o(t,r,n):o(t,r))||n);return f>3&&n&&Object.defineProperty(t,r,n),n};
-var __extends=this&&this.__extends||function(){var t=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(t,o){t.__proto__=o}||function(t,o){for(var n in o)o.hasOwnProperty(n)&&(t[n]=o[n])};return function(o,n){function r(){this.constructor=o}t(o,n),o.prototype=null===n?Object.create(n):(r.prototype=n.prototype,new r)}}();
 
 
 (function universalModuleDefinition(root, factory) {
@@ -23,6 +21,8 @@ var __extends=this&&this.__extends||function(){var t=Object.setPrototypeOf||{__p
 })(this, function(BABYLON) {
   BABYLON = BABYLON || this.BABYLON;
 
+var __decorate=this&&this.__decorate||function(e,t,r,c){var o,f=arguments.length,n=f<3?t:null===c?c=Object.getOwnPropertyDescriptor(t,r):c;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)n=Reflect.decorate(e,t,r,c);else for(var l=e.length-1;l>=0;l--)(o=e[l])&&(n=(f<3?o(n):f>3?o(t,r,n):o(t,r))||n);return f>3&&n&&Object.defineProperty(t,r,n),n};
+var __extends=this&&this.__extends||function(){var t=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(t,o){t.__proto__=o}||function(t,o){for(var n in o)o.hasOwnProperty(n)&&(t[n]=o[n])};return function(o,n){function r(){this.constructor=o}t(o,n),o.prototype=null===n?Object.create(n):(r.prototype=n.prototype,new r)}}();
 "use strict";
 
 

文件差异内容过多而无法显示
+ 5 - 5
dist/preview release/materialsLibrary/babylonjs.materials.min.js


文件差异内容过多而无法显示
+ 1 - 1
dist/preview release/postProcessesLibrary/babylon.asciiArtPostProcess.min.js


文件差异内容过多而无法显示
+ 1 - 1
dist/preview release/postProcessesLibrary/babylon.digitalRainPostProcess.min.js


+ 2 - 2
dist/preview release/postProcessesLibrary/babylonjs.postProcess.js

@@ -1,5 +1,3 @@
-var __decorate=this&&this.__decorate||function(e,t,r,c){var o,f=arguments.length,n=f<3?t:null===c?c=Object.getOwnPropertyDescriptor(t,r):c;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)n=Reflect.decorate(e,t,r,c);else for(var l=e.length-1;l>=0;l--)(o=e[l])&&(n=(f<3?o(n):f>3?o(t,r,n):o(t,r))||n);return f>3&&n&&Object.defineProperty(t,r,n),n};
-var __extends=this&&this.__extends||function(){var t=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(t,o){t.__proto__=o}||function(t,o){for(var n in o)o.hasOwnProperty(n)&&(t[n]=o[n])};return function(o,n){function r(){this.constructor=o}t(o,n),o.prototype=null===n?Object.create(n):(r.prototype=n.prototype,new r)}}();
 
 
 (function universalModuleDefinition(root, factory) {
@@ -23,6 +21,8 @@ var __extends=this&&this.__extends||function(){var t=Object.setPrototypeOf||{__p
 })(this, function(BABYLON) {
   BABYLON = BABYLON || this.BABYLON;
 
+var __decorate=this&&this.__decorate||function(e,t,r,c){var o,f=arguments.length,n=f<3?t:null===c?c=Object.getOwnPropertyDescriptor(t,r):c;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)n=Reflect.decorate(e,t,r,c);else for(var l=e.length-1;l>=0;l--)(o=e[l])&&(n=(f<3?o(n):f>3?o(t,r,n):o(t,r))||n);return f>3&&n&&Object.defineProperty(t,r,n),n};
+var __extends=this&&this.__extends||function(){var t=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(t,o){t.__proto__=o}||function(t,o){for(var n in o)o.hasOwnProperty(n)&&(t[n]=o[n])};return function(o,n){function r(){this.constructor=o}t(o,n),o.prototype=null===n?Object.create(n):(r.prototype=n.prototype,new r)}}();
 "use strict";
 
 

文件差异内容过多而无法显示
+ 1 - 1
dist/preview release/postProcessesLibrary/babylonjs.postProcess.min.js


+ 2 - 2
dist/preview release/proceduralTexturesLibrary/babylonjs.proceduralTextures.js

@@ -1,5 +1,3 @@
-var __decorate=this&&this.__decorate||function(e,t,r,c){var o,f=arguments.length,n=f<3?t:null===c?c=Object.getOwnPropertyDescriptor(t,r):c;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)n=Reflect.decorate(e,t,r,c);else for(var l=e.length-1;l>=0;l--)(o=e[l])&&(n=(f<3?o(n):f>3?o(t,r,n):o(t,r))||n);return f>3&&n&&Object.defineProperty(t,r,n),n};
-var __extends=this&&this.__extends||function(){var t=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(t,o){t.__proto__=o}||function(t,o){for(var n in o)o.hasOwnProperty(n)&&(t[n]=o[n])};return function(o,n){function r(){this.constructor=o}t(o,n),o.prototype=null===n?Object.create(n):(r.prototype=n.prototype,new r)}}();
 
 
 (function universalModuleDefinition(root, factory) {
@@ -23,6 +21,8 @@ var __extends=this&&this.__extends||function(){var t=Object.setPrototypeOf||{__p
 })(this, function(BABYLON) {
   BABYLON = BABYLON || this.BABYLON;
 
+var __decorate=this&&this.__decorate||function(e,t,r,c){var o,f=arguments.length,n=f<3?t:null===c?c=Object.getOwnPropertyDescriptor(t,r):c;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)n=Reflect.decorate(e,t,r,c);else for(var l=e.length-1;l>=0;l--)(o=e[l])&&(n=(f<3?o(n):f>3?o(t,r,n):o(t,r))||n);return f>3&&n&&Object.defineProperty(t,r,n),n};
+var __extends=this&&this.__extends||function(){var t=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(t,o){t.__proto__=o}||function(t,o){for(var n in o)o.hasOwnProperty(n)&&(t[n]=o[n])};return function(o,n){function r(){this.constructor=o}t(o,n),o.prototype=null===n?Object.create(n):(r.prototype=n.prototype,new r)}}();
 "use strict";
 
 

文件差异内容过多而无法显示
+ 1 - 1
dist/preview release/proceduralTexturesLibrary/babylonjs.proceduralTextures.min.js


文件差异内容过多而无法显示
+ 1 - 1
dist/preview release/serializers/babylon.glTF2Serializer.min.js


+ 2 - 2
dist/preview release/serializers/babylonjs.serializers.js

@@ -1,5 +1,3 @@
-var __decorate=this&&this.__decorate||function(e,t,r,c){var o,f=arguments.length,n=f<3?t:null===c?c=Object.getOwnPropertyDescriptor(t,r):c;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)n=Reflect.decorate(e,t,r,c);else for(var l=e.length-1;l>=0;l--)(o=e[l])&&(n=(f<3?o(n):f>3?o(t,r,n):o(t,r))||n);return f>3&&n&&Object.defineProperty(t,r,n),n};
-var __extends=this&&this.__extends||function(){var t=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(t,o){t.__proto__=o}||function(t,o){for(var n in o)o.hasOwnProperty(n)&&(t[n]=o[n])};return function(o,n){function r(){this.constructor=o}t(o,n),o.prototype=null===n?Object.create(n):(r.prototype=n.prototype,new r)}}();
 
 
 (function universalModuleDefinition(root, factory) {
@@ -23,6 +21,8 @@ var __extends=this&&this.__extends||function(){var t=Object.setPrototypeOf||{__p
 })(this, function(BABYLON) {
   BABYLON = BABYLON || this.BABYLON;
 
+var __decorate=this&&this.__decorate||function(e,t,r,c){var o,f=arguments.length,n=f<3?t:null===c?c=Object.getOwnPropertyDescriptor(t,r):c;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)n=Reflect.decorate(e,t,r,c);else for(var l=e.length-1;l>=0;l--)(o=e[l])&&(n=(f<3?o(n):f>3?o(t,r,n):o(t,r))||n);return f>3&&n&&Object.defineProperty(t,r,n),n};
+var __extends=this&&this.__extends||function(){var t=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(t,o){t.__proto__=o}||function(t,o){for(var n in o)o.hasOwnProperty(n)&&(t[n]=o[n])};return function(o,n){function r(){this.constructor=o}t(o,n),o.prototype=null===n?Object.create(n):(r.prototype=n.prototype,new r)}}();
 "use strict";
 
 var BABYLON;

文件差异内容过多而无法显示
+ 1 - 1
dist/preview release/serializers/babylonjs.serializers.min.js


文件差异内容过多而无法显示
+ 115 - 944
dist/preview release/typedocValidationBaseline.json


文件差异内容过多而无法显示
+ 64 - 64
dist/preview release/viewer/babylon.viewer.js


文件差异内容过多而无法显示
+ 913 - 237
dist/preview release/viewer/babylon.viewer.max.js


+ 5 - 0
dist/preview release/what's new.md

@@ -30,6 +30,7 @@
 
 ## Updates
 
+- Improved [animation blending](https://www.babylonjs-playground.com/#DMLMIP#1) ([deltakosh](https://github.com/deltakosh))
 - New [particle system emitter shapes](http://doc.babylonjs.com/babylon101/particles#particles-shapes): cone and sphere ([IbraheemOsama](https://github.com/IbraheemOsama))
 - Added support for 16bits TGA ([deltakosh](https://github.com/deltakosh))
 - New `AnimationPropertiesOverride` class used to simplify setting animation properties on child animations. [Documentation](http://doc.babylonjs.com/babylon101/animations#overriding-properties) ([deltakosh](https://github.com/deltakosh))
@@ -112,6 +113,7 @@
 - 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))
 - (Viewer) Viewer's declaration file automatically generated ([RaananW](https://github.com/RaananW))
+- New serialize and parse functions for effect layers (Highlight and Glow layers) ([julien-moreau](https://github.com/julien-moreau))
 
 ## Bug fixes
 
@@ -131,6 +133,9 @@
 - Add onLoadObservable on VideoTexture - [#3845](https://github.com/BabylonJS/Babylon.js/issues/3845) ([sebavan](https://github.com/sebavan))
 - beforeRender is now triggered after the camera updated its state - [#3873](https://github.com/BabylonJS/Babylon.js/issues/3873) ([RaananW](https://github.com/RaananW))
 - Tools.DeepCopy no longer copying getter-only elements - [#3929](https://github.com/BabylonJS/Babylon.js/issues/3929) ([RaananW](https://github.com/RaananW))
+- Reflection and refraction no longer apply a toLinear conversion twice when applying image processing as a post process - [#4060](https://github.com/BabylonJS/Babylon.js/issues/4060) ([trevordev](https://github.com/trevordev))
+- Fix ember.js compatibility in ```PostProcessRenderEffect``` ([sebavan](https://github.com/sebavan))
+- Fix ember.js compatibility in ```BloomEffect``` and ```Camera``` ([kaysabelle](https://github.com/kaysabelle))
 
 ## Breaking changes
 

+ 14 - 9
loaders/src/glTF/2.0/Extensions/KHR_draco_mesh_compression.ts

@@ -10,6 +10,10 @@ module BABYLON.GLTF2.Extensions {
         attributes: { [name: string]: number };
     }
 
+    interface ILoaderBufferViewDraco extends ILoaderBufferView {
+        _dracoBabylonGeometry?: Promise<Geometry>;
+    }
+
     export class KHR_draco_mesh_compression extends GLTFLoaderExtension {
         public readonly name = NAME;
 
@@ -19,7 +23,7 @@ module BABYLON.GLTF2.Extensions {
             super(loader);
 
             // Disable extension if decoder is not available.
-            if (!DracoCompression.DecoderUrl) {
+            if (!DracoCompression.DecoderAvailable) {
                 this.enabled = false;
             }
         }
@@ -70,9 +74,9 @@ module BABYLON.GLTF2.Extensions {
                 loadAttribute("WEIGHTS_0", VertexBuffer.MatricesWeightsKind);
                 loadAttribute("COLOR_0", VertexBuffer.ColorKind);
 
-                var bufferView = GLTFLoader._GetProperty(extensionContext, this._loader._gltf.bufferViews, extension.bufferView);
-                return this._loader._loadBufferViewAsync(`#/bufferViews/${bufferView._index}`, bufferView).then(data => {
-                    try {
+                var bufferView = GLTFLoader._GetProperty(extensionContext, this._loader._gltf.bufferViews, extension.bufferView) as ILoaderBufferViewDraco;
+                if (!bufferView._dracoBabylonGeometry) {
+                    bufferView._dracoBabylonGeometry = this._loader._loadBufferViewAsync(`#/bufferViews/${bufferView._index}`, bufferView).then(data => {
                         if (!this._dracoCompression) {
                             this._dracoCompression = new DracoCompression();
                         }
@@ -81,12 +85,13 @@ module BABYLON.GLTF2.Extensions {
                             const babylonGeometry = new Geometry(babylonMesh.name, this._loader._babylonScene);
                             babylonVertexData.applyToGeometry(babylonGeometry);
                             return babylonGeometry;
+                        }).catch(error => {
+                            throw new Error(`${context}: ${error.message}`);
                         });
-                    }
-                    catch (e) {
-                        throw new Error(`${context}: ${e.message}`);
-                    }
-                });
+                    });
+                }
+
+                return bufferView._dracoBabylonGeometry;
             });
         }
     }

+ 3 - 1
localDev/index.html

@@ -7,8 +7,10 @@
     <script src="https://code.jquery.com/pep/0.4.2/pep.min.js"></script>
     <script src="https://cdnjs.cloudflare.com/ajax/libs/dat-gui/0.6.2/dat.gui.min.js"></script>
     <script src="../dist/preview%20release/cannon.js"></script>
-    <script src="../dist/preview%20release/draco_decoder.js" type="text/x-draco-decoder"></script>
     <script src="../dist/preview%20release/Oimo.js"></script>
+    <script src="../dist/preview%20release/draco_decoder.js" type="text/x-draco-decoder"></script>
+    <script src="../dist/preview%20release/draco_decoder.wasm" type="text/x-draco-decoder-wasm-binary"></script>
+    <script src="../dist/preview%20release/draco_wasm_wrapper.js" type="text/x-draco-decoder-wasm-wrapper"></script>
     <script src="../Tools/DevLoader/BabylonLoader.js"></script>
     <script src="src/webgl-debug.js"></script>
 

+ 3 - 1
sandbox/index-local.html

@@ -4,8 +4,10 @@
     <title>BabylonJS - Sandbox</title>
     <link href="index.css" rel="stylesheet" />
     <script src="../dist/preview%20release/cannon.js"></script>
-    <script src="../dist/preview%20release/draco_decoder.js" type="text/x-draco-decoder"></script>
     <script src="../dist/preview%20release/Oimo.js"></script>
+    <script src="../dist/preview%20release/draco_decoder.js" type="text/x-draco-decoder"></script>
+    <script src="../dist/preview%20release/draco_decoder.wasm" type="text/x-draco-decoder-wasm-binary"></script>
+    <script src="../dist/preview%20release/draco_wasm_wrapper.js" type="text/x-draco-decoder-wasm-wrapper"></script>
     <script src="../Tools/DevLoader/BabylonLoader.js"></script>
 </head>
 <body>

+ 5 - 1
sandbox/index.html

@@ -26,8 +26,12 @@
     <link href="index.css" rel="stylesheet" />
     <script src="https://code.jquery.com/pep/0.4.2/pep.min.js"></script>
 
-    <script src="https://preview.babylonjs.com/cannon.js"></script>
+    <!-- Draco -->
     <script src="https://preview.babylonjs.com/draco_decoder.js" type="text/x-draco-decoder"></script>
+    <script src="https://preview.babylonjs.com/draco_decoder.wasm" type="text/x-draco-decoder-wasm-binary"></script>
+    <script src="https://preview.babylonjs.com/draco_wasm_wrapper.js" type="text/x-draco-decoder-wasm-wrapper"></script>
+
+    <script src="https://preview.babylonjs.com/cannon.js"></script>
     <script src="https://preview.babylonjs.com/Oimo.js"></script>
     <script src="https://preview.babylonjs.com/babylon.js"></script>
     <script src="https://preview.babylonjs.com/inspector/babylon.inspector.bundle.js"></script>

+ 4 - 2
sandbox/index.js

@@ -9,14 +9,16 @@ var indexOf = location.href.indexOf("?");
 if (indexOf !== -1) {
     var params = location.href.substr(indexOf + 1).split("&");
     for (var index = 0; index < params.length; index++) {
-        var [name, value] = params[index].split("=");
+        var param = params[index].split("=");
+        var name = param[0];
+        var value = param[1];
         switch (name) {
             case "assetUrl": {
                 assetUrl = value;
                 break;
             }
             case "cameraPosition": {
-                cameraPosition = BABYLON.Vector3.FromArray(value.split(",").map(component => +component));
+                cameraPosition = BABYLON.Vector3.FromArray(value.split(",").map(function (component) { return +component; }));
                 break;
             }
             case "kiosk": {

+ 11 - 4
src/Actions/babylon.actionManager.ts

@@ -197,15 +197,22 @@
 
         /**
          * Does this action manager handles actions of a given trigger
-         * @param {number} trigger - the trigger to be tested
-         * @return {boolean} whether the trigger is handeled 
+         * @param trigger defines the trigger to be tested
+         * @param parameterPredicate defines an optional predicate to filter triggers by parameter
+         * @return whether the trigger is handled 
          */
-        public hasSpecificTrigger(trigger: number): boolean {
+        public hasSpecificTrigger(trigger: number, parameterPredicate?: (parameter: any) => boolean): boolean {
             for (var index = 0; index < this.actions.length; index++) {
                 var action = this.actions[index];
 
                 if (action.trigger === trigger) {
-                    return true;
+                    if (parameterPredicate) {
+                        if (parameterPredicate(action.getTriggerParameter())) {
+                            return true;
+                        }
+                    } else {
+                        return true;
+                    }
                 }
             }
 

+ 19 - 3
src/Animations/babylon.animation.ts

@@ -101,12 +101,12 @@
      */
     export class Animation {
         /**
-         * Gets or sets a general value used to allow matrices interpolation (off by default as it could be expensive)
+         * Use matrix interpolation instead of using direct key value when animating matrices
          */
         public static AllowMatricesInterpolation = false;
 
         /**
-         * Gets or sets a boolean indicating if Matrix.DecomposeLerp should be used instead of Matrix.Lerp for matrix interpolation
+         * When matrix interpolation is enabled, this boolean forces the system to use Matrix.DecomposeLerp instead of Matrix.Lerp. Interpolation is more precise but slower
          */
         public static AllowMatrixDecomposeForInterpolation = true;
 
@@ -459,11 +459,27 @@
             return Color3.Lerp(startValue, endValue, gradient);
         }
 
-        public matrixInterpolateFunction(startValue: Matrix, endValue: Matrix, gradient: number): Matrix {
+        /**
+         * Defines the function to use to interpolate matrices
+         * @param startValue defines the start matrix
+         * @param endValue defines the end matrix
+         * @param gradient defines the gradient between both matrices 
+         * @param result defines an optional target matrix where to store the interpolation
+         * @returns the interpolated matrix
+         */
+        public matrixInterpolateFunction(startValue: Matrix, endValue: Matrix, gradient: number, result?: Matrix): Matrix {
             if (Animation.AllowMatrixDecomposeForInterpolation) {
+                if (result) {
+                    Matrix.DecomposeLerpToRef(startValue, endValue, gradient, result);    
+                    return result;
+                }
                 return Matrix.DecomposeLerp(startValue, endValue, gradient);
             }
 
+            if (result) {
+                Matrix.LerpToRef(startValue, endValue, gradient, result);
+                return result;
+            }
             return Matrix.Lerp(startValue, endValue, gradient);
         }
 

+ 17 - 3
src/Animations/babylon.runtimeAnimation.ts

@@ -15,6 +15,7 @@
         private _scene: Scene;
 
         private _currentValue: any;
+        private _workValue: any;
         private _activeTarget: any;
         private _targetPath: string = "";
         private _weight = 1.0;
@@ -172,7 +173,7 @@
                                 case Animation.ANIMATIONLOOPMODE_CONSTANT:
                                     return quatValue;
                                 case Animation.ANIMATIONLOOPMODE_RELATIVE:
-                                    return quatValue.add(offsetValue.scale(repeatCount));
+                                    return quatValue.addInPlace(offsetValue.scale(repeatCount));
                             }
 
                             return quatValue;
@@ -220,7 +221,8 @@
                                 case Animation.ANIMATIONLOOPMODE_CYCLE:
                                 case Animation.ANIMATIONLOOPMODE_CONSTANT:
                                     if (Animation.AllowMatricesInterpolation) {
-                                        return this._animation.matrixInterpolateFunction(startValue, endValue, gradient);
+                                        this._workValue = this._animation.matrixInterpolateFunction(startValue, endValue, gradient, this._workValue);
+                                        return this._workValue;
                                     }
                                 case Animation.ANIMATIONLOOPMODE_RELATIVE:
                                     return startValue;
@@ -308,7 +310,19 @@
                     }
 
                 } else if (this._originalBlendValue.m) { // Matrix
-                    this._currentValue = Matrix.Lerp(this._originalBlendValue, currentValue, this._blendingFactor);
+                    if (Animation.AllowMatrixDecomposeForInterpolation) {
+                        if (this._currentValue) {
+                            Matrix.DecomposeLerpToRef(this._originalBlendValue, currentValue, this._blendingFactor, this._currentValue);
+                        } else {
+                            this._currentValue = Matrix.DecomposeLerp(this._originalBlendValue, currentValue, this._blendingFactor);
+                        }
+                    } else {
+                        if (this._currentValue) {
+                            Matrix.LerpToRef(this._originalBlendValue, currentValue, this._blendingFactor, this._currentValue);
+                        } else {
+                            this._currentValue = Matrix.Lerp(this._originalBlendValue, currentValue, this._blendingFactor);
+                        }
+                    }
                 } else { // Direct value
                     this._currentValue = this._originalBlendValue * (1.0 - this._blendingFactor) + this._blendingFactor * currentValue;
                 }

+ 3 - 3
src/Cameras/babylon.camera.ts

@@ -373,9 +373,9 @@
          * @returns the first post process to be run on this camera.
          */
         public _getFirstPostProcess():Nullable<PostProcess>{
-            for(var pp in this._postProcesses){
-                if(this._postProcesses[pp] !== null){
-                    return this._postProcesses[pp];
+            for(var ppIndex = 0; ppIndex < this._postProcesses.length; ppIndex++){
+                if(this._postProcesses[ppIndex] !== null){
+                    return this._postProcesses[ppIndex];
                 }
             }
             return null;

+ 19 - 0
src/Layer/babylon.effectLayer.ts

@@ -176,6 +176,12 @@
         public abstract _disposeMesh(mesh: Mesh): void;
 
         /**
+         * Serializes this layer (Glow or Highlight for example)
+         * @returns a serialized layer object
+         */
+        public abstract serialize?(): any;
+
+        /**
          * Initializes the effect layer with the required options.
          * @param options Sets of none mandatory options to use with the layer (see IEffectLayerOptions for more information)
          */
@@ -670,5 +676,18 @@
          public getClassName(): string {
             return "EffectLayer";
         }
+
+        /**
+         * Creates an effect layer from parsed effect layer data
+         * @param parsedEffectLayer defines effect layer data
+         * @param scene defines the current scene
+         * @param rootUrl defines the root URL containing the effect layer information
+         * @returns a parsed effect Layer
+         */
+        public static Parse(parsedEffectLayer: any, scene: Scene, rootUrl: string): EffectLayer {
+            var effectLayerType = Tools.Instantiate(parsedEffectLayer.customType);
+            
+            return effectLayerType.Parse(parsedEffectLayer, scene, rootUrl);
+        }
     }
 } 

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

@@ -88,7 +88,7 @@
             return this._intensity;
         }
 
-        @serialize('options')
+        @serialize("options")
         private _options: IGlowLayerOptions;
 
         private _intensity: number = 1.0;
@@ -460,6 +460,8 @@
          */
         public serialize(): any {
             var serializationObject = SerializationHelper.Serialize(this);
+            serializationObject.customType = "BABYLON.GlowLayer";
+
             var index;
 
             // Included meshes

+ 86 - 0
src/Layer/babylon.highlightLayer.ts

@@ -141,11 +141,13 @@
         /**
          * Specifies whether or not the inner glow is ACTIVE in the layer.
          */
+        @serialize()
         public innerGlow: boolean = true;
 
         /**
          * Specifies whether or not the outer glow is ACTIVE in the layer.
          */
+        @serialize()
         public outerGlow: boolean = true;
 
         /**
@@ -165,6 +167,7 @@
         /**
          * Gets the horizontal size of the blur.
          */
+        @serialize()
         public get blurHorizontalSize(): number {
             return this._horizontalBlurPostprocess.kernel
         }
@@ -172,6 +175,7 @@
         /**
          * Gets the vertical size of the blur.
          */
+        @serialize()
         public get blurVerticalSize(): number {
             return this._verticalBlurPostprocess.kernel;
         }
@@ -188,6 +192,7 @@
 
         private _instanceGlowingMeshStencilReference = HighlightLayer.GlowingMeshStencilReference++;
 
+        @serialize("options")
         private _options: IHighlightLayerOptions;
         private _downSamplePostprocess: PassPostProcess;
         private _horizontalBlurPostprocess: GlowBlurPostProcess;
@@ -668,5 +673,86 @@
 
             super.dispose();
         }
+
+        /**
+          * Gets the class name of the effect layer
+          * @returns the string with the class name of the effect layer
+          */
+         public getClassName(): string {
+            return "HighlightLayer";
+        }
+
+        /**
+         * Serializes this Highlight layer
+         * @returns a serialized Highlight layer object
+         */
+        public serialize(): any {
+            var serializationObject = SerializationHelper.Serialize(this);
+            serializationObject.customType = "BABYLON.HighlightLayer";
+
+            // Highlighted meshes
+            serializationObject.meshes = [];
+
+            if (this._meshes) {
+                for (var m in this._meshes) {
+                    var mesh = this._meshes[m];
+
+                    if (mesh) {
+                        serializationObject.meshes.push({
+                            glowEmissiveOnly: mesh.glowEmissiveOnly,
+                            color: mesh.color.asArray(),
+                            meshId: mesh.mesh.id
+                        });
+                    }
+                }
+            }
+
+            // Excluded meshes
+            serializationObject.excludedMeshes = [];
+
+            if (this._excludedMeshes) {
+                for (var e in this._excludedMeshes) {
+                    var excludedMesh = this._excludedMeshes[e];
+
+                    if (excludedMesh) {
+                        serializationObject.excludedMeshes.push(excludedMesh.mesh.id);
+                    }
+                }
+            }
+
+            return serializationObject;
+        }
+
+        /**
+         * Creates a Highlight layer from parsed Highlight layer data
+         * @param parsedHightlightLayer defines the Highlight layer data
+         * @param scene defines the current scene
+         * @param rootUrl defines the root URL containing the Highlight layer information
+         * @returns a parsed Highlight layer
+         */
+        public static Parse(parsedHightlightLayer: any, scene: Scene, rootUrl: string): HighlightLayer {
+            var hl = SerializationHelper.Parse(() => new HighlightLayer(parsedHightlightLayer.name, scene, parsedHightlightLayer.options), parsedHightlightLayer, scene, rootUrl);
+            var index;
+
+            // Excluded meshes
+            for (index = 0; index < parsedHightlightLayer.excludedMeshes.length; index++) {
+                var mesh = scene.getMeshByID(parsedHightlightLayer.excludedMeshes[index]);
+                if (mesh) {
+                    hl.addExcludedMesh(<Mesh> mesh);
+                }
+            }
+
+            // Included meshes
+            for (index = 0; index < parsedHightlightLayer.meshes.length; index++) {
+                var highlightedMesh = parsedHightlightLayer.meshes[index];
+                var mesh = scene.getMeshByID(highlightedMesh.meshId);
+
+                if (mesh) {
+                    hl.addMesh(<Mesh> mesh, Color3.FromArray(highlightedMesh.color), highlightedMesh.glowEmissiveOnly);
+                }
+            }
+
+            return hl;
+        }
     }
 } 

+ 16 - 1
src/Loading/Plugins/babylon.babylonFileLoader.ts

@@ -357,6 +357,14 @@
                 }
             }
 
+            // Effect layers
+            if (parsedData.effectLayers) {
+                for (index = 0; index < parsedData.effectLayers.length; index++) {
+                    var effectLayer = EffectLayer.Parse(parsedData.effectLayers[index], scene, rootUrl);
+                    container.effectLayers.push(effectLayer);
+                }
+            }
+
             // Actions (scene)
             if (parsedData.actions !== undefined && parsedData.actions !== null) {
                 ActionManager.Parse(parsedData.actions, null, scene);
@@ -526,9 +534,16 @@
                                 }
                             }
 
+                            // Morph targets ?
+                            if (parsedData.morphTargetManagers !== undefined && parsedData.morphTargetManagers !== null) {
+                                for (var managerData of parsedData.morphTargetManagers) {
+                                    MorphTargetManager.Parse(managerData, scene);
+                                }
+                            }                               
+
                             var mesh = Mesh.Parse(parsedMesh, scene, rootUrl);
                             meshes.push(mesh);
-                            log += "\n\tMesh " + mesh.toString(fullDetails);
+                            log += "\n\tMesh " + mesh.toString(fullDetails);                         
                         }
                     }
 

+ 17 - 0
src/Materials/Textures/babylon.cubeTexture.ts

@@ -31,6 +31,23 @@
             return this._boundingBoxSize;
         }
 
+
+        @serialize("rotationY")
+        protected _rotationY: number = 0;
+        /**
+         * Sets texture matrix rotation angle around Y axis in radians.
+         */
+        public set rotationY(value: number) {
+            this._rotationY = value;
+            this.setReflectionTextureMatrix(BABYLON.Matrix.RotationY(this._rotationY));
+        }
+        /**
+         * Gets texture matrix rotation angle around Y axis radians.
+         */
+        public get rotationY(): number {
+            return this._rotationY;
+        }        
+
         private _noMipmap: boolean;
         private _files: string[];
         private _extensions: string[];

+ 19 - 0
src/Materials/Textures/babylon.hdrCubeTexture.ts

@@ -57,6 +57,21 @@ module BABYLON {
             return this._isBlocking;
         }
 
+        protected _rotationY: number = 0;
+        /**
+         * Sets texture matrix rotation angle around Y axis in radians.
+         */
+        public set rotationY(value: number) {
+            this._rotationY = value;
+            this.setReflectionTextureMatrix(BABYLON.Matrix.RotationY(this._rotationY));
+        }
+        /**
+         * Gets texture matrix rotation angle around Y axis radians.
+         */
+        public get rotationY(): number {
+            return this._rotationY;
+        }
+        
         /**
          * Gets or sets the center of the bounding box associated with the cube texture
          * It must define where the camera used to render the texture was set
@@ -477,6 +492,9 @@ module BABYLON {
                 if (parsedTexture.boundingBoxSize) {
                     (<any>texture).boundingBoxSize = Vector3.FromArray(parsedTexture.boundingBoxSize);
                 }
+                if (parsedTexture.rotationY) {
+                    (<any>texture).rotationY = parsedTexture.rotationY;
+                }
             }
             return texture;
         }
@@ -500,6 +518,7 @@ module BABYLON {
             serializationObject.customType = "BABYLON.HDRCubeTexture";
             serializationObject.noMipmap = this._noMipmap;
             serializationObject.isBlocking = this._isBlocking;
+            serializationObject.rotationY = this._rotationY;
 
             return serializationObject;
         }

+ 13 - 1
src/Materials/Textures/babylon.mirrorTexture.ts

@@ -83,11 +83,18 @@
                 this._autoComputeBlurKernel();
             }
         }
+        private _updateGammaSpace(){
+            this.gammaSpace = !this.scene.imageProcessingConfiguration.isEnabled || !this.scene.imageProcessingConfiguration.applyByPostProcess;
+        }
 
-        constructor(name: string, size: number | { width: number, height: number } | { ratio: number }, scene: Scene, generateMipMaps?: boolean, type: number = Engine.TEXTURETYPE_UNSIGNED_INT, samplingMode = Texture.BILINEAR_SAMPLINGMODE, generateDepthBuffer = true) {
+        private _imageProcessingConfigChangeObserver:Nullable<Observer<ImageProcessingConfiguration>>;
+        constructor(name: string, size: number | { width: number, height: number } | { ratio: number }, private scene: Scene, generateMipMaps?: boolean, type: number = Engine.TEXTURETYPE_UNSIGNED_INT, samplingMode = Texture.BILINEAR_SAMPLINGMODE, generateDepthBuffer = true) {
             super(name, size, scene, generateMipMaps, true, type, false, samplingMode, generateDepthBuffer);
 
             this.ignoreCameraViewport = true;
+            
+            this._updateGammaSpace();
+            this._imageProcessingConfigChangeObserver = scene.imageProcessingConfiguration.onUpdateParameters.add(this._updateGammaSpace)
 
             this.onBeforeRenderObservable.add(() => {
                 Matrix.ReflectionToRef(this.mirrorPlane, this._mirrorMatrix);
@@ -193,5 +200,10 @@
 
             return serializationObject;
         }
+
+        public dispose(){
+            super.dispose();
+            this.scene.imageProcessingConfiguration.onUpdateParameters.remove(this._imageProcessingConfigChangeObserver);
+        }
     }
 } 

+ 1 - 1
src/Materials/Textures/babylon.renderTargetTexture.ts

@@ -675,7 +675,7 @@
             var textureSize = this.getSize();
             var newTexture = new RenderTargetTexture(
                 this.name,
-                textureSize.width,
+                textureSize,
                 this.getScene(),
                 this._renderTargetOptions.generateMipMaps,
                 this._doNotChangeAspectRatio,

+ 13 - 0
src/Materials/babylon.standardMaterial.ts

@@ -87,6 +87,16 @@ module BABYLON {
         public SAMPLER3DGREENDEPTH = false;
         public SAMPLER3DBGRMAP = false;
         public IMAGEPROCESSINGPOSTPROCESS = false;
+        /**
+         * If the reflection texture on this material is in linear color space
+         * @ignore
+         */
+        public IS_REFLECTION_LINEAR = false;
+        /**
+         * If the refraction texture on this material is in linear color space
+         * @ignore
+         */
+        public IS_REFRACTION_LINEAR = false;
         public EXPOSURE = false;
 
         constructor() {
@@ -724,6 +734,9 @@ module BABYLON {
                 }
 
                 this._imageProcessingConfiguration.prepareDefines(defines);
+
+                defines.IS_REFLECTION_LINEAR = (this.reflectionTexture != null && !this.reflectionTexture.gammaSpace);
+                defines.IS_REFRACTION_LINEAR = (this.refractionTexture != null && !this.refractionTexture.gammaSpace);
             }
 
             if (defines._areFresnelDirty) {

+ 62 - 27
src/Math/babylon.math.ts

@@ -3204,6 +3204,18 @@
         }
 
         /**
+         * Add a quaternion to the current one
+         * @param other defines the quaternion to add
+         * @returns the current quaternion  
+         */
+        public addInPlace(other: Quaternion): Quaternion {
+            this.x += other.x;
+            this.y += other.y;
+            this.z += other.z;
+            this.w += other.w;
+            return this;
+        }        
+        /**
          * Subtract two quaternions
          * @param other defines the second operand
          * @returns a new quaternion as the subtraction result of the given one from the current one
@@ -3688,7 +3700,6 @@
         public static SlerpToRef(left: Quaternion, right: Quaternion, amount: number, result: Quaternion): void {
             var num2;
             var num3;
-            var num = amount;
             var num4 = (((left.x * right.x) + (left.y * right.y)) + (left.z * right.z)) + (left.w * right.w);
             var flag = false;
 
@@ -3698,14 +3709,14 @@
             }
 
             if (num4 > 0.999999) {
-                num3 = 1 - num;
-                num2 = flag ? -num : num;
+                num3 = 1 - amount;
+                num2 = flag ? -amount : amount;
             }
             else {
                 var num5 = Math.acos(num4);
                 var num6 = (1.0 / Math.sin(num5));
-                num3 = (Math.sin((1.0 - num) * num5)) * num6;
-                num2 = flag ? ((-Math.sin(num * num5)) * num6) : ((Math.sin(num * num5)) * num6);
+                num3 = (Math.sin((1.0 - amount) * num5)) * num6;
+                num2 = flag ? ((-Math.sin(amount * num5)) * num6) : ((Math.sin(amount * num5)) * num6);
             }
 
             result.x = (num3 * left.x) + (num2 * right.x);
@@ -4184,7 +4195,8 @@
                 hash = (hash * 397) ^ (this.m[i] || 0);
             }
             return hash;
-        }
+        }     
+
         /**
          * Decomposes the current Matrix into a translation, rotation and scaling components
          * @param scale defines the scale vector3 given as a reference to update
@@ -4192,10 +4204,12 @@
          * @param translation defines the translation vector3 given as a reference to update
          * @returns true if operation was successful
          */
-        public decompose(scale: Vector3, rotation: Quaternion, translation: Vector3): boolean {
-            translation.x = this.m[12];
-            translation.y = this.m[13];
-            translation.z = this.m[14];
+        public decompose(scale: Vector3, rotation?: Quaternion, translation?: Vector3): boolean {
+            if (translation) {
+                translation.x = this.m[12];
+                translation.y = this.m[13];
+                translation.z = this.m[14];
+            }
 
             scale.x = Math.sqrt(this.m[0] * this.m[0] + this.m[1] * this.m[1] + this.m[2] * this.m[2]);
             scale.y = Math.sqrt(this.m[4] * this.m[4] + this.m[5] * this.m[5] + this.m[6] * this.m[6]);
@@ -4205,21 +4219,23 @@
                 scale.y *= -1;
             }
 
-            if (scale.x === 0 || scale.y === 0 || scale.z === 0) {
-                rotation.x = 0;
-                rotation.y = 0;
-                rotation.z = 0;
-                rotation.w = 1;
-                return false;
-            }
+            if (rotation) {
+                if (scale.x === 0 || scale.y === 0 || scale.z === 0) {
+                    rotation.x = 0;
+                    rotation.y = 0;
+                    rotation.z = 0;
+                    rotation.w = 1;
+                    return false;
+                }
 
-            Matrix.FromValuesToRef(
-                this.m[0] / scale.x, this.m[1] / scale.x, this.m[2] / scale.x, 0,
-                this.m[4] / scale.y, this.m[5] / scale.y, this.m[6] / scale.y, 0,
-                this.m[8] / scale.z, this.m[9] / scale.z, this.m[10] / scale.z, 0,
-                0, 0, 0, 1, MathTmp.Matrix[0]);
+                Matrix.FromValuesToRef(
+                    this.m[0] / scale.x, this.m[1] / scale.x, this.m[2] / scale.x, 0,
+                    this.m[4] / scale.y, this.m[5] / scale.y, this.m[6] / scale.y, 0,
+                    this.m[8] / scale.z, this.m[9] / scale.z, this.m[10] / scale.z, 0,
+                    0, 0, 0, 1, MathTmp.Matrix[0]);
 
-            Quaternion.FromRotationMatrixToRef(MathTmp.Matrix[0], rotation);
+                Quaternion.FromRotationMatrixToRef(MathTmp.Matrix[0], rotation);
+            }
 
             return true;
         }
@@ -4911,6 +4927,22 @@
          * @returns the new matrix
          */
         public static DecomposeLerp(startValue: Matrix, endValue: Matrix, gradient: number): Matrix {
+            var result = Matrix.Zero();
+            Matrix.DecomposeLerpToRef(startValue, endValue, gradient, result);
+            return result;
+        }
+
+        /**
+         * Update a matrix to values which are computed by: 
+         * * decomposing the the "startValue" and "endValue" matrices into their respective scale, rotation and translation matrices
+         * * interpolating for "gradient" (float) the values between each of these decomposed matrices between the start and the end
+         * * recomposing a new matrix from these 3 interpolated scale, rotation and translation matrices
+         * @param startValue defines the first matrix
+         * @param endValue defines the second matrix
+         * @param gradient defines the gradient between the two matrices
+         * @param result defines the target matrix
+         */
+        public static DecomposeLerpToRef(startValue: Matrix, endValue: Matrix, gradient: number, result: Matrix) {
             var startScale = MathTmp.Vector3[0];
             var startRotation = MathTmp.Quaternion[0];
             var startTranslation = MathTmp.Vector3[1];
@@ -4923,15 +4955,14 @@
 
             var resultScale = MathTmp.Vector3[4];
             Vector3.LerpToRef(startScale, endScale, gradient, resultScale);
-
             var resultRotation = MathTmp.Quaternion[2];
             Quaternion.SlerpToRef(startRotation, endRotation, gradient, resultRotation);
-
+            
             var resultTranslation = MathTmp.Vector3[5];
             Vector3.LerpToRef(startTranslation, endTranslation, gradient, resultTranslation);
 
-            return Matrix.Compose(resultScale, resultRotation, resultTranslation);
-        }
+            Matrix.ComposeToRef(resultScale, resultRotation, resultTranslation, result);
+        }        
 
         /**
          * Gets a new rotation matrix used to rotate an entity so as it looks at the target vector3, from the eye vector3 position, the up vector3 being oriented like "up"
@@ -6411,7 +6442,11 @@
     }
     // Same as Tmp but not exported to keep it only for math functions to avoid conflicts
     class MathTmp {
+<<<<<<< HEAD
         public static Vector3: Vector3[] = [Vector3.Zero(), Vector3.Zero(), Vector3.Zero(), Vector3.Zero(), Vector3.Zero(), Vector3.Zero(), Vector3.Zero()];
+=======
+        public static Vector3: Vector3[] = [Vector3.Zero(), Vector3.Zero(), Vector3.Zero(), Vector3.Zero(), Vector3.Zero(), Vector3.Zero()];
+>>>>>>> 978800c067c8ba16e1edb1c8643779b800e0f4c6
         public static Matrix: Matrix[] = [Matrix.Zero(), Matrix.Zero()];
         public static Quaternion: Quaternion[] = [Quaternion.Zero(), Quaternion.Zero(), Quaternion.Zero()];
     }

+ 153 - 105
src/Mesh/Compression/babylon.dracoCompression.ts

@@ -1,43 +1,59 @@
 declare var DracoDecoderModule: any;
+declare var WebAssembly: any;
 
 module BABYLON {
     /**
+     * Configuration for Draco compression
+     */
+    export interface IDracoCompressionConfiguration {
+        /**
+         * Configuration for the JavaScript decoder or null if not available.
+         */
+        decoder: Nullable<{
+            url: string;
+        }>;
+
+        /**
+         * Configuration for the WebAssembly decoder or null if not available.
+         */
+        decoderWasm: Nullable<{
+            binaryUrl: string;
+            wrapperUrl: string;
+        }>;
+    }
+
+    /**
      * Draco compression (https://google.github.io/draco/)
      */
     export class DracoCompression implements IDisposable {
-        private _workerPool: WorkerPool;
+        private static _DecoderModulePromise: Promise<any>;
 
         /**
-         * Gets the url to the draco decoder if available.
+         * Gets the configuration.
          */
-        public static DecoderUrl: Nullable<string> = DracoCompression._GetDefaultDecoderUrl();
+        public static Configuration = DracoCompression._GetDefaultConfig();
 
         /**
-         * Constructor
-         * @param numWorkers The number of workers for async operations
+         * Returns true if the decoder is available.
          */
-        constructor(numWorkers = (navigator.hardwareConcurrency || 4)) {
-            let workerBlobUrl = URL && URL.createObjectURL && URL.createObjectURL(new Blob([`(${DracoCompression._Worker.toString()})()`], { type: "application/javascript" }));
-            if (!workerBlobUrl || !Worker) {
-                Tools.Error("Draco Compression disabled. The current context doesn't support worker creation or URL.createObjectURL");
-                return;
-            }
-            const workers = new Array<Worker>(numWorkers);
-            for (let i = 0; i < workers.length; i++) {
-                const worker = new Worker(workerBlobUrl);
-                worker.postMessage({ id: "initDecoder", url: DracoCompression.DecoderUrl });
-                workers[i] = worker;
-            }
+        public static get DecoderAvailable(): boolean {
+            return (
+                typeof DracoDecoderModule !== "undefined" ||
+                (typeof WebAssembly === "object" && !!DracoCompression.Configuration.decoderWasm) ||
+                !!DracoCompression.Configuration.decoder
+            );
+        }
 
-            this._workerPool = new WorkerPool(workers);
+        /**
+         * Constructor
+         */
+        constructor() {
         }
 
         /**
          * Stop all async operations and release resources.
          */
         public dispose(): void {
-            this._workerPool.dispose();
-            delete this._workerPool;
         }
 
         /**
@@ -47,72 +63,26 @@ module BABYLON {
          * @returns A promise that resolves with the decoded vertex data
          */
         public decodeMeshAsync(data: ArrayBufferView, attributes: { [kind: string]: number }): Promise<VertexData> {
-            return new Promise((resolve, reject) => {
-                this._workerPool.push((worker, onComplete) => {
-                    const vertexData = new VertexData();
-
-                    const onError = (error: ErrorEvent) => {
-                        worker.removeEventListener("error", onError);
-                        worker.removeEventListener("message", onMessage);
-                        reject(error);
-                        onComplete();
-                    };
+            return DracoCompression._GetDecoderModule().then(wrappedModule => {
+                const module = wrappedModule.module;
+                const vertexData = new VertexData();
 
-                    const onMessage = (message: MessageEvent) => {
-                        if (message.data === "done") {
-                            worker.removeEventListener("error", onError);
-                            worker.removeEventListener("message", onMessage);
-                            resolve(vertexData);
-                            onComplete();
-                        }
-                        else if (message.data.id === "indices") {
-                            vertexData.indices = message.data.value;
-                        }
-                        else {
-                            vertexData.set(message.data.value, message.data.id);
-                        }
-                    };
-
-                    worker.addEventListener("error", onError);
-                    worker.addEventListener("message", onMessage);
-
-                    const dataCopy = new Uint8Array(data.byteLength);
-                    dataCopy.set(new Uint8Array(data.buffer, data.byteOffset, data.byteLength));
-
-                    worker.postMessage({ id: "decodeMesh", data: dataCopy, attributes: attributes }, [dataCopy.buffer]);
-                });
-            });
-        }
-
-        /**
-         * The worker function that gets converted to a blob url to pass into a worker.
-         */
-        private static _Worker(): void {
-            // self is actually a DedicatedWorkerGlobalScope
-            const _self = self as any as {
-                onmessage: (event: MessageEvent) => void;
-                postMessage: (message: any, transfer?: any[]) => void;
-                close: () => void;
-            };
-
-            const decodeMesh = (data: ArrayBufferView, attributes: { [kind: string]: number }): void => {
-                const dracoModule = new DracoDecoderModule();
-                const buffer = new dracoModule.DecoderBuffer();
+                const buffer = new module.DecoderBuffer();
                 buffer.Init(data, data.byteLength);
 
-                const decoder = new dracoModule.Decoder();
+                const decoder = new module.Decoder();
                 let geometry: any;
                 let status: any;
 
                 try {
                     const type = decoder.GetEncodedGeometryType(buffer);
                     switch (type) {
-                        case dracoModule.TRIANGULAR_MESH:
-                            geometry = new dracoModule.Mesh();
+                        case module.TRIANGULAR_MESH:
+                            geometry = new module.Mesh();
                             status = decoder.DecodeBufferToMesh(buffer, geometry);
                             break;
-                        case dracoModule.POINT_CLOUD:
-                            geometry = new dracoModule.PointCloud();
+                        case module.POINT_CLOUD:
+                            geometry = new module.PointCloud();
                             status = decoder.DecodeBufferToPointCloud(buffer, geometry);
                             break;
                         default:
@@ -125,9 +95,9 @@ module BABYLON {
 
                     const numPoints = geometry.num_points();
 
-                    if (type === dracoModule.TRIANGULAR_MESH) {
+                    if (type === module.TRIANGULAR_MESH) {
                         const numFaces = geometry.num_faces();
-                        const faceIndices = new dracoModule.DracoInt32Array();
+                        const faceIndices = new module.DracoInt32Array();
                         try {
                             const indices = new Uint32Array(numFaces * 3);
                             for (let i = 0; i < numFaces; i++) {
@@ -137,68 +107,146 @@ module BABYLON {
                                 indices[offset + 1] = faceIndices.GetValue(1);
                                 indices[offset + 2] = faceIndices.GetValue(2);
                             }
-                            _self.postMessage({ id: "indices", value: indices }, [indices.buffer]);
+                            vertexData.indices = indices;
                         }
                         finally {
-                            dracoModule.destroy(faceIndices);
+                            module.destroy(faceIndices);
                         }
                     }
 
                     for (const kind in attributes) {
                         const uniqueId = attributes[kind];
                         const attribute = decoder.GetAttributeByUniqueId(geometry, uniqueId);
-                        const dracoData = new dracoModule.DracoFloat32Array();
+                        const dracoData = new module.DracoFloat32Array();
                         try {
                             decoder.GetAttributeFloatForAllPoints(geometry, attribute, dracoData);
                             const babylonData = new Float32Array(numPoints * attribute.num_components());
                             for (let i = 0; i < babylonData.length; i++) {
                                 babylonData[i] = dracoData.GetValue(i);
                             }
-                            _self.postMessage({ id: kind, value: babylonData }, [babylonData.buffer]);
+                            vertexData.set(babylonData, kind);
                         }
                         finally {
-                            dracoModule.destroy(dracoData);
+                            module.destroy(dracoData);
                         }
                     }
                 }
                 finally {
                     if (geometry) {
-                        dracoModule.destroy(geometry);
+                        module.destroy(geometry);
                     }
 
-                    dracoModule.destroy(decoder);
-                    dracoModule.destroy(buffer);
+                    module.destroy(decoder);
+                    module.destroy(buffer);
                 }
 
-                _self.postMessage("done");
+                return vertexData;
+            });
+        }
+
+        private static _GetDecoderModule(): Promise<any> {
+            if (!DracoCompression._DecoderModulePromise) {
+                let promise: Promise<any>;
+                let config: any = {};
+
+                if (typeof DracoDecoderModule !== "undefined") {
+                    promise = Promise.resolve();
+                }
+                else if (typeof WebAssembly === "object" && DracoCompression.Configuration.decoderWasm) {
+                    promise = Promise.all([
+                        DracoCompression._LoadScriptAsync(DracoCompression.Configuration.decoderWasm.wrapperUrl),
+                        DracoCompression._LoadFileAsync(DracoCompression.Configuration.decoderWasm.binaryUrl).then(data => {
+                            config.wasmBinary = data;
+                        })
+                    ]);
+                }
+                else if (DracoCompression.Configuration.decoder) {
+                    promise = DracoCompression._LoadScriptAsync(DracoCompression.Configuration.decoder.url);
+                }
+                else {
+                    throw new Error("Invalid decoder configuration");
+                }
+
+                DracoCompression._DecoderModulePromise = promise.then(() => {
+                    return new Promise(resolve => {
+                        config.onModuleLoaded = (decoderModule: any) => {
+                            // decoderModule is Promise-like. Wrap before resolving to avoid loop.
+                            resolve({ module: decoderModule });
+                        };
+
+                        DracoDecoderModule(config);
+                    });
+                });
             }
 
-            _self.onmessage = event => {
-                switch (event.data.id) {
-                    case "initDecoder": {
-                        importScripts(event.data.url);
-                        break;
-                    }
-                    case "decodeMesh": {
-                        decodeMesh(event.data.data, event.data.attributes);
-                        break;
+            return DracoCompression._DecoderModulePromise;
+        }
+
+        private static _LoadScriptAsync(url: string): Promise<void> {
+            return new Promise((resolve, reject) => {
+                Tools.LoadScript(url, () => {
+                    resolve();
+                }, message => {
+                    reject(new Error(message));
+                });
+            });
+        }
+
+        private static _LoadFileAsync(url: string): Promise<ArrayBuffer> {
+            return new Promise((resolve, reject) => {
+                Tools.LoadFile(url, data => {
+                    resolve(data as ArrayBuffer);
+                }, undefined, undefined, true, (request, exception) => {
+                    reject(exception);
+                });
+            });
+        }
+
+        private static _GetDefaultConfig(): IDracoCompressionConfiguration {
+            const configuration: IDracoCompressionConfiguration = {
+                decoder: null,
+                decoderWasm: null
+            };
+
+            if (Tools.IsWindowObjectExist()) {
+                let decoderUrl: Nullable<string> = null;
+                let decoderWasmBinaryUrl: Nullable<string> = null;
+                let decoderWasmWrapperUrl: Nullable<string> = null;
+
+                for (let i = 0; i < document.scripts.length; i++) {
+                    const type = document.scripts[i].type;
+                    const src = document.scripts[i].src;
+                    switch (type) {
+                        case "text/x-draco-decoder": {
+                            decoderUrl = src;
+                            break;
+                        }
+                        case "text/x-draco-decoder-wasm-binary": {
+                            decoderWasmBinaryUrl = src;
+                            break;
+                        }
+                        case "text/x-draco-decoder-wasm-wrapper": {
+                            decoderWasmWrapperUrl = src;
+                            break;
+                        }
                     }
                 }
-            };
-        }
 
-        private static _GetDefaultDecoderUrl(): Nullable<string> {
-            if (!Tools.IsWindowObjectExist()) {
-                return null;
-            }
+                if (decoderUrl) {
+                    configuration.decoder = {
+                        url: decoderUrl
+                    };
+                }
 
-            for (let i = 0; i < document.scripts.length; i++) {
-                if (document.scripts[i].type === "text/x-draco-decoder") {
-                    return document.scripts[i].src;
+                if (decoderWasmWrapperUrl && decoderWasmBinaryUrl) {
+                    configuration.decoderWasm = {
+                        binaryUrl: decoderWasmBinaryUrl,
+                        wrapperUrl: decoderWasmWrapperUrl
+                    };
                 }
             }
 
-            return null;
+            return configuration;
         }
     }
 }

+ 6 - 6
src/Mesh/babylon.buffer.ts

@@ -34,7 +34,7 @@
 
             this._data = data;
 
-            this.byteStride = useBytes ? stride : stride * 4;
+            this.byteStride = useBytes ? stride : stride * Float32Array.BYTES_PER_ELEMENT;
 
             if (!postponeInternalCreation) { // by default
                 this.create();
@@ -52,8 +52,8 @@
          * @returns the new vertex buffer
          */
         public createVertexBuffer(kind: string, offset: number, size: number, stride?: number, instanced?: boolean, useBytes = false): VertexBuffer {
-            const byteOffset = useBytes ? offset : offset * 4;
-            const byteStride = stride ? (useBytes ? stride : stride * 4) : this.byteStride;
+            const byteOffset = useBytes ? offset : offset * Float32Array.BYTES_PER_ELEMENT;
+            const byteStride = stride ? (useBytes ? stride : stride * Float32Array.BYTES_PER_ELEMENT) : this.byteStride;
 
             // a lot of these parameters are ignored as they are overriden by the buffer
             return new VertexBuffer(this._engine, this, kind, this._updatable, true, byteStride, instanced === undefined ? this._instanced : instanced, byteOffset, size, undefined, undefined, true);
@@ -79,7 +79,7 @@
          * @returns the stride in float32 units
          */
         public getStrideSize(): number {
-            return this.byteStride / 4;
+            return this.byteStride / Float32Array.BYTES_PER_ELEMENT;
         }
 
         // Methods
@@ -123,13 +123,13 @@
          * @param vertexCount the vertex count (optional)
          * @param useBytes set to true if the offset is in bytes
          */
-        public updateDirectly(data: DataArray, offset: number, vertexCount?: number, useBytes = false): void {
+        public updateDirectly(data: DataArray, offset: number, vertexCount?: number, useBytes: boolean = false): void {
             if (!this._buffer) {
                 return;
             }
 
             if (this._updatable) { // update buffer
-                this._engine.updateDynamicVertexBuffer(this._buffer, data, useBytes ? offset : offset * 4, (vertexCount ? vertexCount * this.byteStride : undefined));
+                this._engine.updateDynamicVertexBuffer(this._buffer, data, useBytes ? offset : offset * Float32Array.BYTES_PER_ELEMENT, (vertexCount ? vertexCount * this.byteStride : undefined));
                 this._data = null;
             }
         }

+ 10 - 8
src/Mesh/babylon.geometry.ts

@@ -204,10 +204,6 @@
          * @param stride defines the stride to use (0 by default). This value is deduced from the kind value if not specified
          */
         public setVerticesData(kind: string, data: FloatArray, updatable: boolean = false, stride?: number): void {
-            if (kind === VertexBuffer.PositionKind) {
-                this._totalVertices = data.length / (stride || 3);
-            }
-
             var buffer = new VertexBuffer(this._engine, data, kind, updatable, this._meshes.length === 0, stride);
             this.setVerticesBuffer(buffer);
         }
@@ -236,12 +232,17 @@
 
             this._vertexBuffers[kind] = buffer;
 
-            if (kind === VertexBuffer.PositionKind) {
+            if (kind === VertexBuffer.PositionKind) {                
+                var data = <FloatArray>buffer.getData();
                 if (totalVertices != null) {
                     this._totalVertices = totalVertices;
+                } else {
+                    if (data != null) {
+                        this._totalVertices = data.length / (buffer.byteStride / 4);
+                    }
                 }
 
-                this._updateExtend();
+                this._updateExtend(data);
                 this._resetPointsArrayCache();
 
                 var meshes = this._meshes;
@@ -270,15 +271,16 @@
          * @param kind defines the data kind (Position, normal, etc...)
          * @param data defines the data to use 
          * @param offset defines the offset in the target buffer where to store the data
+         * @param useBytes set to true if the offset is in bytes
          */
-        public updateVerticesDataDirectly(kind: string, data: Float32Array, offset: number): void {
+        public updateVerticesDataDirectly(kind: string, data: DataArray, offset: number, useBytes: boolean = false): void {
             var vertexBuffer = this.getVertexBuffer(kind);
 
             if (!vertexBuffer) {
                 return;
             }
 
-            vertexBuffer.updateDirectly(data, offset);
+            vertexBuffer.updateDirectly(data, offset, useBytes);
             this.notifyUpdate(kind);
         }
 

+ 308 - 57
src/Mesh/babylon.mesh.vertexData.ts

@@ -1,4 +1,7 @@
 module BABYLON {
+    /**
+     * Define an interface for all classes that will get and set the data on vertices
+     */
     export interface IGetSetVerticesData {
         isVerticesDataPresent(kind: string): boolean;
         getVerticesData(kind: string, copyWhenShared?: boolean, forceCopy?: boolean): Nullable<FloatArray>;
@@ -8,23 +11,91 @@
         setIndices(indices: IndicesArray, totalVertices: Nullable<number>, updatable?: boolean): void;
     }
 
+    /**
+     * This class contains the various kinds of data on every vertex of a mesh used in determining its shape and appearance 
+     */
     export class VertexData {
+        
+        /**
+         * An array of the x, y, z position of each vertex  [...., x, y, z, .....]
+         */
         public positions: Nullable<FloatArray>;
+        
+        /**
+         * An array of the x, y, z normal vector of each vertex  [...., x, y, z, .....]
+         */
         public normals: Nullable<FloatArray>;
+        
+        /**
+         * An array of the x, y, z tangent vector of each vertex  [...., x, y, z, .....]
+         */
         public tangents: Nullable<FloatArray>;
+        
+        /**
+         * An array of u,v which maps a texture image onto each vertex  [...., u, v, .....]
+         */
         public uvs: Nullable<FloatArray>;
+        
+        /**
+         * A second array of u,v which maps a texture image onto each vertex  [...., u, v, .....]
+         */
         public uvs2: Nullable<FloatArray>;
+        
+        /**
+         * A third array of u,v which maps a texture image onto each vertex  [...., u, v, .....]
+         */
         public uvs3: Nullable<FloatArray>;
+        
+        /**
+         * A fourth array of u,v which maps a texture image onto each vertex  [...., u, v, .....]
+         */
         public uvs4: Nullable<FloatArray>;
+        
+        /**
+         * A fifth array of u,v which maps a texture image onto each vertex  [...., u, v, .....]
+         */
         public uvs5: Nullable<FloatArray>;
+        
+        /**
+         * A sixth array of u,v which maps a texture image onto each vertex  [...., u, v, .....]
+         */
         public uvs6: Nullable<FloatArray>;
+        
+        /**
+         * An array of the r, g, b, a, color of each vertex  [...., r, g, b, a, .....]
+         */
         public colors: Nullable<FloatArray>;
+
+        /**
+         * An array containing the list of indices to the array of matrices produced by bones, each vertex have up to 4 indices (8 if the matricesIndicesExtra is set).
+         */
         public matricesIndices: Nullable<FloatArray>;
+
+        /**
+         * An array containing the list of weights defining the weight of each indexed matrix in the final computation
+         */
         public matricesWeights: Nullable<FloatArray>;
+
+        /**
+         * An array extending the number of possible indices
+         */
         public matricesIndicesExtra: Nullable<FloatArray>;
+
+        /**
+         * An array extending the number of possible weights when the number of indices is extended
+         */
         public matricesWeightsExtra: Nullable<FloatArray>;
+        
+        /**
+         * An array of i, j, k the three vertex indices required for each triangular facet  [...., i, j, k .....]
+         */
         public indices: Nullable<IndicesArray>;
 
+        /**
+         * Uses the passed data array to set the set the values for the specified kind of data
+         * @param data a linear array of floating numbers
+         * @param kind the type of data that is being set, eg positions, colors etc
+         */
         public set(data: FloatArray, kind: string) {
             switch (kind) {
                 case VertexBuffer.PositionKind:
@@ -73,9 +144,11 @@
         }
 
         /**
-         * Associates the vertexData to the passed Mesh.  
-         * Sets it as updatable or not (default `false`).  
-         * Returns the VertexData.  
+         * Associates the vertexData to the passed Mesh.
+         * Sets it as updatable or not (default `false`) 
+         * @param mesh the mesh the vertexData is applied to 
+         * @param updatable when used and having the value true allows new data to update the vertexData 
+         * @returns the VertexData 
          */
         public applyToMesh(mesh: Mesh, updatable?: boolean): VertexData {
             this._applyTo(mesh, updatable);
@@ -83,9 +156,11 @@
         }
 
         /**
-         * Associates the vertexData to the passed Geometry.  
-         * Sets it as updatable or not (default `false`).  
-         * Returns the VertexData.  
+         * Associates the vertexData to the passed Geometry.
+         * Sets it as updatable or not (default `false`)
+         * @param geometry the geometry the vertexData is applied to 
+         * @param updatable when used and having the value true allows new data to update the vertexData 
+         * @returns VertexData
          */
         public applyToGeometry(geometry: Geometry, updatable?: boolean): VertexData {
             this._applyTo(geometry, updatable);
@@ -93,8 +168,11 @@
         }
 
         /**
-         * Updates the associated mesh.  
-         * Returns the VertexData.  
+         * Updates the associated mesh
+         * @param mesh the mesh to be updated
+         * @param updateExtends when true the mesh BoundingInfo will be renewed when and if position kind is updated, optional with default false
+         * @param makeItUnique when true, and when and if position kind is updated, a new global geometry will be  created from these positions and set to the mesh, optional with default false 
+         * @returns VertexData
          */
         public updateMesh(mesh: Mesh, updateExtends?: boolean, makeItUnique?: boolean): VertexData {
             this._update(mesh);
@@ -102,8 +180,11 @@
         }
 
         /**
-         * Updates the associated geometry.  
-         * Returns the VertexData.  
+         * Updates the associated geometry 
+         * @param geometry the geometry to be updated
+         * @param updateExtends when true BoundingInfo will be renewed when and if position kind is updated, optional with default false
+         * @param makeItUnique when true, and when and if position kind is updated, a new global geometry will be created from these positions and set to the mesh, optional with default false 
+         * @returns VertexData.
          */
         public updateGeometry(geometry: Geometry, updateExtends?: boolean, makeItUnique?: boolean): VertexData {
             this._update(geometry);
@@ -237,8 +318,9 @@
         }
 
         /**
-         * Transforms each position and each normal of the vertexData according to the passed Matrix.  
-         * Returns the VertexData.  
+         * Transforms each position and each normal of the vertexData according to the passed Matrix
+         * @param matrix the transforming matrix
+         * @returns the VertexData 
          */
         public transform(matrix: Matrix): VertexData {
             var transformed = Vector3.Zero();
@@ -288,8 +370,9 @@
         }
 
         /**
-         * Merges the passed VertexData into the current one.  
-         * Returns the modified VertexData.  
+         * Merges the passed VertexData into the current one
+         * @param other the VertexData to be merged into the current one  
+         * @returns the modified VertexData 
          */
         public merge(other: VertexData): VertexData {
             this._validate();
@@ -414,8 +497,8 @@
         }
 
         /**
-         * Serializes the VertexData.  
-         * Returns a serialized object.  
+         * Serializes the VertexData  
+         * @returns a serialized object 
          */
         public serialize(): any {
             var serializationObject = this.serialize();
@@ -485,14 +568,22 @@
 
         // Statics
         /**
-         * Returns the object VertexData associated to the passed mesh.  
+         * Extracts the vertexData from a mesh
+         * @param mesh the mesh from which to extract the VertexData
+         * @param copyWhenShared defines if the VertexData must be cloned when shared between multiple meshes, optional, default false
+         * @param forceCopy indicating that the VertexData must be cloned, optional, default false
+         * @returns the object VertexData associated to the passed mesh 
          */
         public static ExtractFromMesh(mesh: Mesh, copyWhenShared?: boolean, forceCopy?: boolean): VertexData {
             return VertexData._ExtractFrom(mesh, copyWhenShared, forceCopy);
         }
 
         /**
-         * Returns the object VertexData associated to the passed geometry.  
+         * Extracts the vertexData from the geometry
+         * @param geometry the geometry from which to extract the VertexData
+         * @param copyWhenShared defines if the VertexData must be cloned when the geometrty is shared between multiple meshes, optional, default false
+         * @param forceCopy indicating that the VertexData must be cloned, optional, default false
+         * @returns the object VertexData associated to the passed mesh 
          */
         public static ExtractFromGeometry(geometry: Geometry, copyWhenShared?: boolean, forceCopy?: boolean): VertexData {
             return VertexData._ExtractFrom(geometry, copyWhenShared, forceCopy);
@@ -563,7 +654,19 @@
         }
 
         /**
-         * Creates the vertexData of the Ribbon.  
+         * Creates the VertexData for a Ribbon
+         * @param options an object used to set the following optional parameters for the ribbon, required but can be empty 
+          * * pathArray array of paths, each of which an array of successive Vector3    
+          * * closeArray creates a seam between the first and the last paths of the pathArray, optional, default false  
+          * * closePath creates a seam between the first and the last points of each path of the path array, optional, default false
+          * * offset a positive integer, only used when pathArray contains a single path (offset = 10 means the point 1 is joined to the point 11), default rounded half size of the pathArray length
+          * * sideOrientation optional and takes the values : BABYLON.Mesh.FRONTSIDE (default), BABYLON.Mesh.BACKSIDE or BABYLON.Mesh.DOUBLESIDE     
+          * * frontUvs only usable when you create a double-sided mesh, used to choose what parts of the texture image to crop and apply on the front side, optional, default vector4 (0, 0, 1, 1)
+          * * backUVs only usable when you create a double-sided mesh, used to choose what parts of the texture image to crop and apply on the back side, optional, default vector4 (0, 0, 1, 1)
+          * * invertUV swaps in the U and V coordinates when applying a texture, optional, default false
+          * * uvs a linear array, of length 2 * number of vertices, of custom UV values, optional
+          * * colors a linear array, of length 4 * number of vertices, of custom color values, optional
+         * @returns the VertexData of the ribbon
          */
         public static CreateRibbon(options: { pathArray: Vector3[][], closeArray?: boolean, closePath?: boolean, offset?: number, sideOrientation?: number, frontUVs?: Vector4, backUVs?: Vector4, invertUV?: boolean, uvs?: Vector2[], colors?: Color4[] }): VertexData {
             var pathArray: Vector3[][] = options.pathArray;
@@ -797,8 +900,19 @@
         }
 
         /**
-         * Creates the VertexData of the Box.  
-         */
+         * Creates the VertexData for a box
+         * @param options an object used to set the following optional parameters for the box, required but can be empty 
+          * * size sets the width, height and depth of the box to the value of size, optional default 1  
+          * * width sets the width (x direction) of the box, overwrites the width set by size, optional, default size
+          * * height sets the height (y direction) of the box, overwrites the height set by size, optional, default size
+          * * depth sets the depth (z direction) of the box, overwrites the depth set by size, optional, default size
+          * * faceUV an array of 6 Vector4 elements used to set different images to each box side
+          * * faceColors an array of 6 Color3 elements used to set different colors to each box side   
+          * * sideOrientation optional and takes the values : BABYLON.Mesh.FRONTSIDE (default), BABYLON.Mesh.BACKSIDE or BABYLON.Mesh.DOUBLESIDE     
+          * * frontUvs only usable when you create a double-sided mesh, used to choose what parts of the texture image to crop and apply on the front side, optional, default vector4 (0, 0, 1, 1)
+          * * backUVs only usable when you create a double-sided mesh, used to choose what parts of the texture image to crop and apply on the back side, optional, default vector4 (0, 0, 1, 1) 
+         * @returns the VertexData of the box
+         */ 
         public static CreateBox(options: { size?: number, width?: number, height?: number, depth?: number, faceUV?: Vector4[], faceColors?: Color4[], sideOrientation?: number, frontUVs?: Vector4, backUVs?: Vector4 }): VertexData {
             var normalsSource = [
                 new Vector3(0, 0, 1),
@@ -906,8 +1020,20 @@
         }
 
         /**
-         * Creates the VertexData of the Sphere.  
-         */
+         * Creates the VertexData for an ellipsoid, defaults to a sphere
+         * @param options an object used to set the following optional parameters for the box, required but can be empty 
+          * * segments sets the number of horizontal strips optional, default 32
+          * * diameter sets the axes dimensions, diameterX, diameterY and diameterZ to the value of diameter, optional default 1  
+          * * diameterX sets the diameterX (x direction) of the ellipsoid, overwrites the diameterX set by diameter, optional, default diameter
+          * * diameterY sets the diameterY (y direction) of the ellipsoid, overwrites the diameterY set by diameter, optional, default diameter
+          * * diameterZ sets the diameterZ (z direction) of the ellipsoid, overwrites the diameterZ set by diameter, optional, default diameter
+          * * arc a number from 0 to 1, to create an unclosed ellipsoid based on the fraction of the circumference (latitude) given by the arc value, optional, default 1 
+          * * slice a number from 0 to 1, to create an unclosed ellipsoid based on the fraction of the height (latitude) given by the arc value, optional, default 1   
+          * * sideOrientation optional and takes the values : BABYLON.Mesh.FRONTSIDE (default), BABYLON.Mesh.BACKSIDE or BABYLON.Mesh.DOUBLESIDE     
+          * * frontUvs only usable when you create a double-sided mesh, used to choose what parts of the texture image to crop and apply on the front side, optional, default vector4 (0, 0, 1, 1)
+          * * backUVs only usable when you create a double-sided mesh, used to choose what parts of the texture image to crop and apply on the back side, optional, default vector4 (0, 0, 1, 1) 
+         * @returns the VertexData of the ellipsoid
+         */         
         public static CreateSphere(options: { segments?: number, diameter?: number, diameterX?: number, diameterY?: number, diameterZ?: number, arc?: number, slice?: number, sideOrientation?: number, frontUVs?: Vector4, backUVs?: Vector4 }): VertexData {
             var segments: number = options.segments || 32;
             var diameterX: number = options.diameterX || options.diameter || 1;
@@ -978,8 +1104,24 @@
         }
 
         /**
-         * Creates the VertexData of the Cylinder or Cone.  
-         */
+         * Creates the VertexData for a cylinder, cone or prism
+         * @param options an object used to set the following optional parameters for the box, required but can be empty 
+          * * height sets the height (y direction) of the cylinder, optional, default 2  
+          * * diameterTop sets the diameter of the top of the cone, overwrites diameter,  optional, default diameter
+          * * diameterBottom sets the diameter of the bottom of the cone, overwrites diameter,  optional, default diameter
+          * * diameter sets the diameter of the top and bottom of the cone, optional default 1
+          * * tessellation the number of prism sides, 3 for a triangular prism, optional, default 24
+          * * subdivisions` the number of rings along the cylinder height, optional, default 1
+          * * arc a number from 0 to 1, to create an unclosed cylinder based on the fraction of the circumference given by the arc value, optional, default 1
+          * * faceColors an array of Color3 elements used to set different colors to the top, rings and bottom respectively
+          * * faceUV an array of Vector4 elements used to set different images to the top, rings and bottom respectively
+          * * hasRings when true makes each subdivision independantly treated as a face for faceUV and faceColors, optional, default false
+          * * enclose when true closes an open cylinder by adding extra flat faces between the height axis and vertical edges, think cut cake
+          * * sideOrientation optional and takes the values : BABYLON.Mesh.FRONTSIDE (default), BABYLON.Mesh.BACKSIDE or BABYLON.Mesh.DOUBLESIDE     
+          * * frontUvs only usable when you create a double-sided mesh, used to choose what parts of the texture image to crop and apply on the front side, optional, default vector4 (0, 0, 1, 1)
+          * * backUVs only usable when you create a double-sided mesh, used to choose what parts of the texture image to crop and apply on the back side, optional, default vector4 (0, 0, 1, 1) 
+         * @returns the VertexData of the cylinder, cone or prism
+         */         
         public static CreateCylinder(options: { height?: number, diameterTop?: number, diameterBottom?: number, diameter?: number, tessellation?: number, subdivisions?: number, arc?: number, faceColors?: Color4[], faceUV?: Vector4[], hasRings?: boolean, enclose?: boolean, sideOrientation?: number, frontUVs?: Vector4, backUVs?: Vector4 }): VertexData {
             var height: number = options.height || 2;
             var diameterTop: number = (options.diameterTop === 0) ? 0 : options.diameterTop || options.diameter || 1;
@@ -1232,8 +1374,16 @@
         }
 
         /**
-         * Creates the VertexData of the Torus.  
-         */
+         * Creates the VertexData for a torus
+         * @param options an object used to set the following optional parameters for the box, required but can be empty 
+          * * diameter the diameter of the torus, optional default 1
+          * * thickness the diameter of the tube forming the torus, optional default 0.5
+          * * tessellation the number of prism sides, 3 for a triangular prism, optional, default 24
+          * * sideOrientation optional and takes the values : BABYLON.Mesh.FRONTSIDE (default), BABYLON.Mesh.BACKSIDE or BABYLON.Mesh.DOUBLESIDE     
+          * * frontUvs only usable when you create a double-sided mesh, used to choose what parts of the texture image to crop and apply on the front side, optional, default vector4 (0, 0, 1, 1)
+          * * backUVs only usable when you create a double-sided mesh, used to choose what parts of the texture image to crop and apply on the back side, optional, default vector4 (0, 0, 1, 1) 
+         * @returns the VertexData of the torus
+         */ 
         public static CreateTorus(options: { diameter?: number, thickness?: number, tessellation?: number, sideOrientation?: number, frontUVs?: Vector4, backUVs?: Vector4 }) {
             var indices = [];
             var positions = [];
@@ -1303,7 +1453,11 @@
         }
 
         /**
-         * Creates the VertexData of the LineSystem.  
+         * Creates the VertexData of the LineSystem
+         * @param options an object used to set the following optional parameters for the LineSystem, required but can be empty
+         *  - lines an array of lines, each line being an array of successive Vector3
+         *  - colors an array of line colors, each of the line colors being an array of successive Color4, one per line point
+         * @returns the VertexData of the LineSystem 
          */
         public static CreateLineSystem(options: { lines: Vector3[][], colors?: Nullable<Color4[][]> }): VertexData {
             var indices = [];
@@ -1338,7 +1492,13 @@
         }
 
         /**
-         * Create the VertexData of the DashedLines.  
+         * Create the VertexData for a DashedLines
+         * @param options an object used to set the following optional parameters for the DashedLines, required but can be empty
+         *  - points an array successive Vector3
+         *  - dashSize the size of the dashes relative to the dash number, optional, default 3
+         *  - gapSize the size of the gap between two successive dashes relative to the dash number, optional, default 1
+         *  - dashNb the intended total number of dashes, optional, default 200
+         * @returns the VertexData for the DashedLines  
          */
         public static CreateDashedLines(options: { points: Vector3[], dashSize?: number, gapSize?: number, dashNb?: number }): VertexData {
             var dashSize = options.dashSize || 3;
@@ -1385,7 +1545,12 @@
         }
 
         /**
-         * Creates the VertexData of the Ground.  
+         * Creates the VertexData for a Ground
+         * @param options an object used to set the following optional parameters for the Ground, required but can be empty
+         *  - width the width (x direction) of the ground, optional, default 1
+         *  - height the height (z direction) of the ground, optional, default 1
+         *  - subdivisions the number of subdivisions per side, optional, default 1
+         * @returns the VertexData of the Ground  
          */
         public static CreateGround(options: { width?: number, height?: number, subdivisions?: number, subdivisionsX?: number, subdivisionsY?: number }): VertexData {
             var indices = [];
@@ -1434,7 +1599,15 @@
         }
 
         /**
-         * Creates the VertexData of the TiledGround.  
+         * Creates the VertexData for a TiledGround by subdividing the ground into tiles
+         * @param options an object used to set the following optional parameters for the Ground, required but can be empty
+          * * xmin the ground minimum X coordinate, optional, default -1
+          * * zmin the ground minimum Z coordinate, optional, default -1
+          * * xmax the ground maximum X coordinate, optional, default 1
+          * * zmax the ground maximum Z coordinate, optional, default 1
+          * * subdivisions a javascript object {w: positive integer, h: positive integer}, `w` and `h` are the numbers of subdivisions on the ground width and height creating 'tiles', default {w: 6, h: 6}
+          * * precision a javascript object {w: positive integer, h: positive integer}, `w` and `h` are the numbers of subdivisions on the tile width and height, default {w: 2, h: 2}
+         * @returns the VertexData of the TiledGround  
          */
         public static CreateTiledGround(options: { xmin: number, zmin: number, xmax: number, zmax: number, subdivisions?: { w: number; h: number; }, precision?: { w: number; h: number; } }): VertexData {
             var xmin = (options.xmin !== undefined && options.xmin !== null) ? options.xmin : -1.0;
@@ -1521,7 +1694,18 @@
         }
 
         /**
-         * Creates the VertexData of the Ground designed from a heightmap.  
+         * Creates the VertexData of the Ground designed from a heightmap
+         * @param options an object used to set the following parameters for the Ground, required and provided by MeshBuilder.CreateGroundFromHeightMap
+          * * width the width (x direction) of the ground
+          * * height the height (z direction) of the ground
+          * * subdivisions the number of subdivisions per side
+          * * minHeight the minimum altitude on the ground, optional, default 0
+          * * maxHeight the maximum altitude on the ground, optional default 1
+          * * colorFilter the filter to apply to the image pixel colors to compute the height, optional Color3, default (0.3, 0.59, 0.11)
+          * * buffer the array holding the image color data 
+          * * bufferWidth the width of image
+          * * bufferHeight the height of image
+         * @returns the VertexData of the Ground designed from a heightmap   
          */
         public static CreateGroundFromHeightMap(options: { width: number, height: number, subdivisions: number, minHeight: number, maxHeight: number, colorFilter: Color3, buffer: Uint8Array, bufferWidth: number, bufferHeight: number }): VertexData {
             var indices = [];
@@ -1584,8 +1768,16 @@
         }
 
         /**
-         * Creates the VertexData of the Plane.  
-         */
+         * Creates the VertexData for a Plane
+         * @param options an object used to set the following optional parameters for the plane, required but can be empty 
+          * * size sets the width and height of the plane to the value of size, optional default 1  
+          * * width sets the width (x direction) of the plane, overwrites the width set by size, optional, default size
+          * * height sets the height (y direction) of the plane, overwrites the height set by size, optional, default size  
+          * * sideOrientation optional and takes the values : BABYLON.Mesh.FRONTSIDE (default), BABYLON.Mesh.BACKSIDE or BABYLON.Mesh.DOUBLESIDE     
+          * * frontUvs only usable when you create a double-sided mesh, used to choose what parts of the texture image to crop and apply on the front side, optional, default vector4 (0, 0, 1, 1)
+          * * backUVs only usable when you create a double-sided mesh, used to choose what parts of the texture image to crop and apply on the back side, optional, default vector4 (0, 0, 1, 1) 
+         * @returns the VertexData of the box
+         */  
         public static CreatePlane(options: { size?: number, width?: number, height?: number, sideOrientation?: number, frontUVs?: Vector4, backUVs?: Vector4 }): VertexData {
             var indices = [];
             var positions = [];
@@ -1640,8 +1832,16 @@
         }
 
         /**
-         * Creates the VertexData of the Disc or regular Polygon.  
-         */
+         * Creates the VertexData of the Disc or regular Polygon
+         * @param options an object used to set the following optional parameters for the disc, required but can be empty 
+          * * radius the radius of the disc, optional default 0.5  
+          * * tessellation the number of polygon sides, optional, default 64
+          * * arc a number from 0 to 1, to create an unclosed polygon based on the fraction of the circumference given by the arc value, optional, default 1 
+          * * sideOrientation optional and takes the values : BABYLON.Mesh.FRONTSIDE (default), BABYLON.Mesh.BACKSIDE or BABYLON.Mesh.DOUBLESIDE     
+          * * frontUvs only usable when you create a double-sided mesh, used to choose what parts of the texture image to crop and apply on the front side, optional, default vector4 (0, 0, 1, 1)
+          * * backUVs only usable when you create a double-sided mesh, used to choose what parts of the texture image to crop and apply on the back side, optional, default vector4 (0, 0, 1, 1) 
+         * @returns the VertexData of the box
+         */ 
         public static CreateDisc(options: { radius?: number, tessellation?: number, arc?: number, sideOrientation?: number, frontUVs?: Vector4, backUVs?: Vector4 }): VertexData {
             var positions = new Array<number>();
             var indices = new Array<number>();
@@ -1693,7 +1893,15 @@
         }
 
         /**
-         * Re-creates the VertexData of the Polygon for sideOrientation.  
+         * Creates the VertexData for an irregular Polygon in the XoZ plane using a mesh built by polygonTriangulation.build()
+         * All parameters are provided by MeshBuilder.CreatePolygon as needed
+         * @param polygon a mesh built from polygonTriangulation.build()
+         * @param sideOrientation takes the values BABYLON.Mesh.FRONTSIDE (default), BABYLON.Mesh.BACKSIDE or BABYLON.Mesh.DOUBLESIDE
+         * @param fUV an array of Vector4 elements used to set different images to the top, rings and bottom respectively
+         * @param fColors an array of Color3 elements used to set different colors to the top, rings and bottom respectively
+         * @param frontUVs only usable when you create a double-sided mesh, used to choose what parts of the texture image to crop and apply on the front side, optional, default vector4 (0, 0, 1, 1)
+         * @param backUVs only usable when you create a double-sided mesh, used to choose what parts of the texture image to crop and apply on the back side, optional, default vector4 (0, 0, 1, 1)
+         * @returns the VertexData of the Polygon
          */
         public static CreatePolygon(polygon: Mesh, sideOrientation: number, fUV?: Vector4[], fColors?: Color4[], frontUVs?: Vector4, backUVs?: Vector4) {
             var faceUV: Vector4[] = fUV || new Array<Vector4>(3);
@@ -1759,8 +1967,19 @@
         }
 
         /**
-         * Creates the VertexData of the IcoSphere.  
-         */
+         * Creates the VertexData of the IcoSphere
+         * @param options an object used to set the following optional parameters for the IcoSphere, required but can be empty 
+          * * radius the radius of the IcoSphere, optional default 1  
+          * * radiusX allows stretching in the x direction, optional, default radius
+          * * radiusY allows stretching in the y direction, optional, default radius
+          * * radiusZ allows stretching in the z direction, optional, default radius
+          * * flat when true creates a flat shaded mesh, optional, default true
+          * * subdivisions increasing the subdivisions increases the number of faces, optional, default 4 
+          * * sideOrientation optional and takes the values : BABYLON.Mesh.FRONTSIDE (default), BABYLON.Mesh.BACKSIDE or BABYLON.Mesh.DOUBLESIDE     
+          * * frontUvs only usable when you create a double-sided mesh, used to choose what parts of the texture image to crop and apply on the front side, optional, default vector4 (0, 0, 1, 1)
+          * * backUVs only usable when you create a double-sided mesh, used to choose what parts of the texture image to crop and apply on the back side, optional, default vector4 (0, 0, 1, 1) 
+         * @returns the VertexData of the IcoSphere
+         */ 
         public static CreateIcoSphere(options: { radius?: number, radiusX?: number, radiusY?: number, radiusZ?: number, flat?: boolean, subdivisions?: number, sideOrientation?: number, frontUVs?: Vector4, backUVs?: Vector4 }): VertexData {
             var sideOrientation = options.sideOrientation || Mesh.DEFAULTSIDE;
             var radius = options.radius || 1;
@@ -2023,7 +2242,24 @@
 
         // inspired from // http://stemkoski.github.io/Three.js/Polyhedra.html
         /**
-         * Creates the VertexData of the Polyhedron.  
+         * Creates the VertexData for a Polyhedron
+         * @param options an object used to set the following optional parameters for the polyhedron, required but can be empty 
+         * * type provided types are:
+         *  * 0 : Tetrahedron, 1 : Octahedron, 2 : Dodecahedron, 3 : Icosahedron, 4 : Rhombicuboctahedron, 5 : Triangular Prism, 6 : Pentagonal Prism, 7 : Hexagonal Prism, 8 : Square Pyramid (J1)
+         *  * 9 : Pentagonal Pyramid (J2), 10 : Triangular Dipyramid (J12), 11 : Pentagonal Dipyramid (J13), 12 : Elongated Square Dipyramid (J15), 13 : Elongated Pentagonal Dipyramid (J16), 14 : Elongated Pentagonal Cupola (J20)
+         * * size the size of the IcoSphere, optional default 1  
+         * * sizeX allows stretching in the x direction, optional, default size
+         * * sizeY allows stretching in the y direction, optional, default size
+         * * sizeZ allows stretching in the z direction, optional, default size
+         * * custom a number that overwrites the type to create from an extended set of polyhedron from https://www.babylonjs-playground.com/#21QRSK#15 with minimised editor
+         * * faceUV an array of Vector4 elements used to set different images to the top, rings and bottom respectively
+         * * faceColors an array of Color3 elements used to set different colors to the top, rings and bottom respectively
+         * * flat when true creates a flat shaded mesh, optional, default true
+         * * subdivisions increasing the subdivisions increases the number of faces, optional, default 4 
+         * * sideOrientation optional and takes the values : BABYLON.Mesh.FRONTSIDE (default), BABYLON.Mesh.BACKSIDE or BABYLON.Mesh.DOUBLESIDE     
+         * * frontUvs only usable when you create a double-sided mesh, used to choose what parts of the texture image to crop and apply on the front side, optional, default vector4 (0, 0, 1, 1)
+         * * backUVs only usable when you create a double-sided mesh, used to choose what parts of the texture image to crop and apply on the back side, optional, default vector4 (0, 0, 1, 1) 
+         * @returns the VertexData of the Polyhedron 
          */
         public static CreatePolyhedron(options: { type?: number, size?: number, sizeX?: number, sizeY?: number, sizeZ?: number, custom?: any, faceUV?: Vector4[], faceColors?: Color4[], flat?: boolean, sideOrientation?: number, frontUVs?: Vector4, backUVs?: Vector4 }): VertexData {
             // provided polyhedron types :
@@ -2158,7 +2394,18 @@
 
         // based on http://code.google.com/p/away3d/source/browse/trunk/fp10/Away3D/src/away3d/primitives/TorusKnot.as?spec=svn2473&r=2473
         /**
-         * Creates the VertexData of the Torus Knot.  
+         * Creates the VertexData for a TorusKnot
+         * @param options an object used to set the following optional parameters for the TorusKnot, required but can be empty
+          * * radius the radius of the torus knot, optional, default 2
+          * * tube the thickness of the tube, optional, default 0.5 
+          * * radialSegments the number of sides on each tube segments, optional, default 32
+          * * tubularSegments the number of tubes to decompose the knot into, optional, default 32
+          * * p the number of windings around the z axis, optional,  default 2
+          * * q the number of windings around the x axis, optional,  default 3
+          * * sideOrientation optional and takes the values : BABYLON.Mesh.FRONTSIDE (default), BABYLON.Mesh.BACKSIDE or BABYLON.Mesh.DOUBLESIDE     
+          * * frontUvs only usable when you create a double-sided mesh, used to choose what parts of the texture image to crop and apply on the front side, optional, default vector4 (0, 0, 1, 1)
+          * * backUVs only usable when you create a double-sided mesh, used to choose what parts of the texture image to crop and apply on the back side, optional, default vector4 (0, 0, 1, 1) 
+         * @returns the VertexData of the Torus Knot
          */
         public static CreateTorusKnot(options: { radius?: number, tube?: number, radialSegments?: number, tubularSegments?: number, p?: number, q?: number, sideOrientation?: number, frontUVs?: Vector4, backUVs?: Vector4 }): VertexData {
             var indices = new Array<number>();
@@ -2252,22 +2499,24 @@
         }
 
         // Tools
+
         /**
-         * @param {any} - positions (number[] or Float32Array)
-         * @param {any} - indices   (number[] or Uint16Array)
-         * @param {any} - normals   (number[] or Float32Array)
-         * options (optional) :
-         * facetPositions : optional array of facet positions (vector3)
-         * facetNormals : optional array of facet normals (vector3)
-         * facetPartitioning : optional partitioning array. facetPositions is required for facetPartitioning computation
-         * subDiv : optional partitioning data about subdivsions on  each axis (int), required for facetPartitioning computation
-         * ratio : optional partitioning ratio / bounding box, required for facetPartitioning computation
-         * bbSize : optional bounding box size data, required for facetPartitioning computation
-         * bInfo : optional bounding info, required for facetPartitioning computation
-         * useRightHandedSystem: optional boolean to for right handed system computation
-         * depthSort : optional boolean to enable the facet depth sort computation
-         * distanceTo : optional Vector3 to compute the facet depth from this location
-         * depthSortedFacets : optional array of depthSortedFacets to store the facet distances from the reference location
+         * Compute normals for given positions and indices
+         * @param positions an array of vertex positions, [...., x, y, z, ......]
+         * @param indices an array of indices in groups of three for each triangular facet, [...., i, j, k, ......]
+         * @param normals an array of vertex normals, [...., x, y, z, ......]
+         * @param options an object used to set the following optional parameters for the TorusKnot, optional
+          * * facetNormals : optional array of facet normals (vector3)
+          * * facetPositions : optional array of facet positions (vector3)
+          * * facetPartitioning : optional partitioning array. facetPositions is required for facetPartitioning computation
+          * * ratio : optional partitioning ratio / bounding box, required for facetPartitioning computation
+          * * bInfo : optional bounding info, required for facetPartitioning computation
+          * * bbSize : optional bounding box size data, required for facetPartitioning computation
+          * * subDiv : optional partitioning data about subdivsions on  each axis (int), required for facetPartitioning computation
+          * * useRightHandedSystem: optional boolean to for right handed system computation
+          * * depthSort : optional boolean to enable the facet depth sort computation
+          * * distanceTo : optional Vector3 to compute the facet depth from this location
+          * * depthSortedFacets : optional array of depthSortedFacets to store the facet distances from the reference location
          */
         public static ComputeNormals(positions: any, indices: any, normals: any,
             options?: {
@@ -2543,7 +2792,9 @@
         }
 
         /**
-         * Creates a new VertexData from the imported parameters.  
+         * Applies VertexData created from the imported parameters to the geometry
+         * @param parsedVertexData the parsed data from an imported file
+         * @param geometry the geometry to apply the VertexData to
          */
         public static ImportVertexData(parsedVertexData: any, geometry: Geometry) {
             var vertexData = new VertexData();

+ 6 - 3
src/Mesh/babylon.vertexBuffer.ts

@@ -232,10 +232,13 @@
 
         /**
          * Updates directly the underlying WebGLBuffer according to the passed numeric array or Float32Array.  
-         * Returns the directly updated WebGLBuffer. 
+         * Returns the directly updated WebGLBuffer.
+         * @param data the new data
+         * @param offset the new offset
+         * @param useBytes set to true if the offset is in bytes
          */
-        public updateDirectly(data: DataArray, offset: number): void {
-            return this._buffer.updateDirectly(data, offset);
+        public updateDirectly(data: DataArray, offset: number, useBytes: boolean = false): void {
+            this._buffer.updateDirectly(data, offset, undefined, useBytes);
         }
 
         /** 

+ 70 - 4
src/Morph/babylon.morphTarget.ts

@@ -1,5 +1,12 @@
 module BABYLON {
-    export class MorphTarget {
+    /**
+     * Defines a target to use with MorphTargetManager
+     * @see http://doc.babylonjs.com/how_to/how_to_use_morphtargets
+     */
+    export class MorphTarget implements IAnimatable {
+        /**
+         * Gets or sets the list of animations
+         */
         public animations = new Array<Animation>();
 
         private _positions: Nullable<FloatArray> = null;
@@ -7,8 +14,14 @@ module BABYLON {
         private _tangents: Nullable<FloatArray> = null;
         private _influence: number;
 
+        /**
+         * Observable raised when the influence changes
+         */
         public onInfluenceChanged = new Observable<boolean>();
 
+        /**
+         * Gets or sets the influence of this target (ie. its weight in the overall morphing)
+         */
         public get influence(): number {
             return this._influence;
         }
@@ -26,49 +39,89 @@ module BABYLON {
             }
         }
 
-        public constructor(public name: string, influence = 0) {
+        /**
+         * Creates a new MorphTarget
+         * @param name defines the name of the target
+         * @param influence defines the influence to use
+         */
+        public constructor(
+            /** defines the name of the target */
+            public name: string, influence = 0) {
             this.influence = influence;
         }
 
+        /**
+         * Gets a boolean defining if the target contains position data
+         */
         public get hasPositions(): boolean {
             return !!this._positions;
         }
 
+        /**
+         * Gets a boolean defining if the target contains normal data
+         */
         public get hasNormals(): boolean {
             return !!this._normals;
         }
 
+        /**
+         * Gets a boolean defining if the target contains tangent data
+         */        
         public get hasTangents(): boolean {
             return !!this._tangents;
         }
 
+        /**
+         * Affects position data to this target
+         * @param data defines the position data to use
+         */
         public setPositions(data: Nullable<FloatArray>) {
             this._positions = data;
         }
 
+        /**
+         * Gets the position data stored in this target
+         * @returns a FloatArray containing the position data (or null if not present)
+         */
         public getPositions(): Nullable<FloatArray> {
             return this._positions;
         }
 
+        /**
+         * Affects normal data to this target
+         * @param data defines the normal data to use
+         */        
         public setNormals(data: Nullable<FloatArray>) {
             this._normals = data;
         }
 
+        /**
+         * Gets the normal data stored in this target
+         * @returns a FloatArray containing the normal data (or null if not present)
+         */        
         public getNormals(): Nullable<FloatArray> {
             return this._normals;
         }
 
+        /**
+         * Affects tangent data to this target
+         * @param data defines the tangent data to use
+         */        
         public setTangents(data: Nullable<FloatArray>) {
             this._tangents = data;
         }
 
+        /**
+         * Gets the tangent data stored in this target
+         * @returns a FloatArray containing the tangent data (or null if not present)
+         */   
         public getTangents(): Nullable<FloatArray> {
             return this._tangents;
         }
 
         /**
-         * Serializes the current target into a Serialization object.  
-         * Returns the serialized object.  
+         * Serializes the current target into a Serialization object
+         * @returns the serialized object
          */
         public serialize(): any {
             var serializationObject:any = {};
@@ -91,6 +144,12 @@ module BABYLON {
         }
 
         // Statics
+
+        /**
+         * Creates a new target from serialized data
+         * @param serializationObject defines the serialized data to use
+         * @returns a new MorphTarget
+         */
         public static Parse(serializationObject: any): MorphTarget {
             var result = new MorphTarget(serializationObject.name , serializationObject.influence);
 
@@ -115,6 +174,13 @@ module BABYLON {
             return result;
         }
 
+        /**
+         * Creates a MorphTarget from mesh data
+         * @param mesh defines the source mesh
+         * @param name defines the name to use for the new target
+         * @param influence defines the influence to attach to the target
+         * @returns a new MorphTarget
+         */
         public static FromMesh(mesh: AbstractMesh, name?: string, influence?: number): MorphTarget {
             if (!name) {
                 name = mesh.name;

+ 72 - 8
src/Morph/babylon.morphTargetManager.ts

@@ -1,4 +1,8 @@
 module BABYLON {
+    /**
+     * This class is used to deform meshes using morphing between different targets
+     * @see http://doc.babylonjs.com/how_to/how_to_use_morphtargets
+     */
     export class MorphTargetManager {
         private _targets = new Array<MorphTarget>();
         private _targetObservable = new Array<Nullable<Observer<boolean>>>();
@@ -11,6 +15,10 @@ module BABYLON {
         private _uniqueId = 0;
         private _tempInfluences = new Array<number>();
 
+        /**
+         * Creates a new MorphTargetManager
+         * @param scene defines the current scene
+         */
         public constructor(scene: Nullable<Scene> = null) {
             if (!scene) {
                 scene = Engine.LastCreatedScene;
@@ -25,42 +33,77 @@ module BABYLON {
             }
         }
 
+        /**
+         * Gets the unique ID of this manager
+         */
         public get uniqueId(): number {
             return this._uniqueId;
         }
 
+        /**
+         * Gets the number of vertices handled by this manager
+         */
         public get vertexCount(): number {
             return this._vertexCount
         }
 
+        /**
+         * Gets a boolean indicating if this manager supports morphing of normals
+         */
         public get supportsNormals(): boolean {
             return this._supportsNormals;
         }
 
+        /**
+         * Gets a boolean indicating if this manager supports morphing of tangents
+         */        
         public get supportsTangents(): boolean {
             return this._supportsTangents;
         }
 
+        /**
+         * Gets the number of targets stored in this manager
+         */
         public get numTargets(): number {
             return this._targets.length;
         }
 
+        /**
+         * Gets the number of influencers (ie. the number of targets with influences > 0)
+         */
         public get numInfluencers(): number {
             return this._activeTargets.length;
         }
 
+        /**
+         * Gets the list of influences (one per target)
+         */
         public get influences(): Float32Array {
             return this._influences;
         }
 
+        /**
+         * Gets the active target at specified index. An active target is a target with an influence > 0
+         * @param index defines the index to check
+         * @returns the requested target
+         */
         public getActiveTarget(index: number): MorphTarget {
             return this._activeTargets.data[index];
         }
 
+        /**
+         * Gets the target at specified index
+         * @param index defines the index to check
+         * @returns the requested target
+         */
         public getTarget(index: number): MorphTarget {
             return this._targets[index];
         }
 
+        /**
+         * Add a new target to this manager
+         * @param target defines the target to add
+         */
         public addTarget(target: MorphTarget): void {
             this._targets.push(target);
             this._targetObservable.push(target.onInfluenceChanged.add(needUpdate => {
@@ -69,6 +112,10 @@ module BABYLON {
             this._syncActiveTargets(true);
         }
 
+        /**
+         * Removes a target from the manager
+         * @param target defines the target to remove
+         */
         public removeTarget(target: MorphTarget): void {
             var index = this._targets.indexOf(target);
             if (index >= 0) {
@@ -80,8 +127,8 @@ module BABYLON {
         }
 
         /**
-         * Serializes the current manager into a Serialization object.  
-         * Returns the serialized object.  
+         * Serializes the current manager into a Serialization object
+         * @returns the serialized object
          */
         public serialize(): any {
             var serializationObject:any = {};
@@ -130,17 +177,34 @@ module BABYLON {
                 this._influences[index] = this._tempInfluences[index];
             }
 
-            if (needUpdate && this._scene) {
-                // Flag meshes as dirty to resync with the active targets
-                for (var mesh of this._scene.meshes) {
-                    if ((<any>mesh).morphTargetManager === this) {
-                        (<Mesh>mesh)._syncGeometryWithMorphTargetManager();
-                    }
+            if (needUpdate) {
+                this.synchronize();
+            }
+        }
+
+        /**
+         * Syncrhonize the targets with all the meshes using this morph target manager
+         */
+        public synchronize(): void {
+            if (!this._scene) {
+                return;
+            }
+            // Flag meshes as dirty to resync with the active targets
+            for (var mesh of this._scene.meshes) {
+                if ((<any>mesh).morphTargetManager === this) {
+                    (<Mesh>mesh)._syncGeometryWithMorphTargetManager();
                 }
             }
         }
 
         // Statics
+
+        /**
+         * Creates a new MorphTargetManager from serialized data
+         * @param serializationObject defines the serialized data
+         * @param scene defines the hosting scene
+         * @returns the new MorphTargetManager
+         */
         public static Parse(serializationObject: any, scene: Scene): MorphTargetManager {
             var result = new MorphTargetManager(scene);
 

+ 6 - 3
src/PostProcess/RenderPipeline/babylon.postProcessRenderEffect.ts

@@ -43,9 +43,12 @@ module BABYLON {
          */
         public get isSupported(): boolean {
             for (var index in this._postProcesses) {
-                for(var ppIndex in this._postProcesses[index]){
-                    if (!this._postProcesses[index][ppIndex].isSupported) {
-                        return false;
+                if (this._postProcesses.hasOwnProperty(index)) {
+                    let pps = this._postProcesses[index];
+                    for(var ppIndex = 0; ppIndex < pps.length; ppIndex++){
+                        if (!pps[ppIndex].isSupported) {
+                            return false;
+                        }
                     }
                 }
             }

+ 6 - 6
src/PostProcess/babylon.bloomEffect.ts

@@ -84,8 +84,8 @@ module BABYLON {
          * @param camera The camera to dispose the effect on.
          */
         public disposeEffects(camera:Camera){
-            for(var effect in this._effects){
-                this._effects[effect].dispose(camera);
+            for(var effectIndex = 0; effectIndex < this._effects.length; effectIndex++){
+                this._effects[effectIndex].dispose(camera);
             }
         }
         
@@ -93,8 +93,8 @@ module BABYLON {
          * Internal
          */
         public _updateEffects(){
-            for(var effect in this._effects){
-                this._effects[effect].updateEffect();
+            for(var effectIndex = 0; effectIndex < this._effects.length; effectIndex++){
+                this._effects[effectIndex].updateEffect();
             }
         }
 
@@ -103,8 +103,8 @@ module BABYLON {
          * @returns if all the contained post processes are ready.
          */
         public _isReady(){
-            for(var effect in this._effects){
-                if(!this._effects[effect].isReady()){
+            for(var effectIndex = 0; effectIndex < this._effects.length; effectIndex++){
+                if(!this._effects[effectIndex].isReady()){
                     return false;
                 }
             }

+ 7 - 7
src/PostProcess/babylon.depthOfFieldEffect.ts

@@ -145,17 +145,17 @@ module BABYLON {
          * @param camera The camera to dispose the effect on.
          */
         public disposeEffects(camera:Camera){
-            for(var effect in this._effects){
-                this._effects[effect].dispose(camera);
-            }            
+            for(var effectIndex = 0; effectIndex < this._effects.length; effectIndex++){
+                this._effects[effectIndex].dispose(camera);
+            }
         }
 
         /**
          * Internal
          */
         public _updateEffects(){
-            for(var effect in this._effects){
-                this._effects[effect].updateEffect();
+            for(var effectIndex = 0; effectIndex <  this._effects.length; effectIndex++){
+                this._effects[effectIndex].updateEffect();
             }
         }
 
@@ -164,8 +164,8 @@ module BABYLON {
          * @returns if all the contained post processes are ready.
          */
         public _isReady(){
-            for(var effect in this._effects){
-                if(!this._effects[effect].isReady()){
+            for(var effectIndex = 0; effectIndex < this._effects.length; effectIndex++){
+                if(!this._effects[effectIndex].isReady()){
                     return false;
                 }
             }

+ 58 - 55
src/Shaders/default.fragment.fx

@@ -259,73 +259,76 @@ void main(void) {
 
 #ifdef REFRACTION
 	vec3 refractionVector = normalize(refract(-viewDirectionW, normalW, vRefractionInfos.y));
-#ifdef REFRACTIONMAP_3D
-
-	refractionVector.y = refractionVector.y * vRefractionInfos.w;
+	#ifdef REFRACTIONMAP_3D
+		refractionVector.y = refractionVector.y * vRefractionInfos.w;
 
-	if (dot(refractionVector, viewDirectionW) < 1.0)
-	{
-		refractionColor = textureCube(refractionCubeSampler, refractionVector).rgb * vRefractionInfos.x;
-	}
-#else
-	vec3 vRefractionUVW = vec3(refractionMatrix * (view * vec4(vPositionW + refractionVector * vRefractionInfos.z, 1.0)));
-
-	vec2 refractionCoords = vRefractionUVW.xy / vRefractionUVW.z;
+		if (dot(refractionVector, viewDirectionW) < 1.0) {
+			refractionColor = textureCube(refractionCubeSampler, refractionVector).rgb;
+		}
+	#else
+		vec3 vRefractionUVW = vec3(refractionMatrix * (view * vec4(vPositionW + refractionVector * vRefractionInfos.z, 1.0)));
 
-	refractionCoords.y = 1.0 - refractionCoords.y;
+		vec2 refractionCoords = vRefractionUVW.xy / vRefractionUVW.z;
 
-	refractionColor = texture2D(refraction2DSampler, refractionCoords).rgb * vRefractionInfos.x;
-#endif
+		refractionCoords.y = 1.0 - refractionCoords.y;
+		
+		refractionColor = texture2D(refraction2DSampler, refractionCoords).rgb;
+	#endif
+	#ifdef IS_REFRACTION_LINEAR
+		refractionColor = toGammaSpace(refractionColor);
+	#endif
+	refractionColor *= vRefractionInfos.x;
 #endif
 
-	// Reflection
-	vec3 reflectionColor = vec3(0., 0., 0.);
+// Reflection
+vec3 reflectionColor = vec3(0., 0., 0.);
 
 #ifdef REFLECTION
 	vec3 vReflectionUVW = computeReflectionCoords(vec4(vPositionW, 1.0), normalW);
 
-#ifdef REFLECTIONMAP_3D
-#ifdef ROUGHNESS
-	float bias = vReflectionInfos.y;
-
-#ifdef SPECULARTERM
-	#ifdef SPECULAR
-		#ifdef GLOSSINESS
-			bias *= (1.0 - specularMapColor.a);
+	#ifdef REFLECTIONMAP_3D
+		#ifdef ROUGHNESS
+			float bias = vReflectionInfos.y;
+
+			#ifdef SPECULARTERM
+				#ifdef SPECULAR
+					#ifdef GLOSSINESS
+						bias *= (1.0 - specularMapColor.a);
+					#endif
+				#endif
+			#endif
+
+			reflectionColor = textureCube(reflectionCubeSampler, vReflectionUVW, bias).rgb;
+		#else
+			reflectionColor = textureCube(reflectionCubeSampler, vReflectionUVW).rgb;
 		#endif
-	#endif
-#endif
-
-	reflectionColor = textureCube(reflectionCubeSampler, vReflectionUVW, bias).rgb * vReflectionInfos.x;
-#else
-	reflectionColor = textureCube(reflectionCubeSampler, vReflectionUVW).rgb * vReflectionInfos.x;
-#endif
-
-#else
-	vec2 coords = vReflectionUVW.xy;
-
-#ifdef REFLECTIONMAP_PROJECTION
-	coords /= vReflectionUVW.z;
-#endif
-
-	coords.y = 1.0 - coords.y;
-
-	reflectionColor = texture2D(reflection2DSampler, coords).rgb * vReflectionInfos.x;
-#endif
+	#else
+		vec2 coords = vReflectionUVW.xy;
 
-#ifdef REFLECTIONFRESNEL
-	float reflectionFresnelTerm = computeFresnelTerm(viewDirectionW, normalW, reflectionRightColor.a, reflectionLeftColor.a);
+		#ifdef REFLECTIONMAP_PROJECTION
+			coords /= vReflectionUVW.z;
+		#endif
 
-#ifdef REFLECTIONFRESNELFROMSPECULAR
-#ifdef SPECULARTERM
-	reflectionColor *= specularColor.rgb * (1.0 - reflectionFresnelTerm) + reflectionFresnelTerm * reflectionRightColor.rgb;
-#else
-	reflectionColor *= reflectionLeftColor.rgb * (1.0 - reflectionFresnelTerm) + reflectionFresnelTerm * reflectionRightColor.rgb;
-#endif
-#else
-	reflectionColor *= reflectionLeftColor.rgb * (1.0 - reflectionFresnelTerm) + reflectionFresnelTerm * reflectionRightColor.rgb;
-#endif
-#endif
+		coords.y = 1.0 - coords.y;
+		reflectionColor = texture2D(reflection2DSampler, coords).rgb;
+	#endif
+	#ifdef IS_REFLECTION_LINEAR
+		reflectionColor = toGammaSpace(reflectionColor);
+	#endif
+	reflectionColor *= vReflectionInfos.x;
+	#ifdef REFLECTIONFRESNEL
+		float reflectionFresnelTerm = computeFresnelTerm(viewDirectionW, normalW, reflectionRightColor.a, reflectionLeftColor.a);
+
+		#ifdef REFLECTIONFRESNELFROMSPECULAR
+			#ifdef SPECULARTERM
+				reflectionColor *= specularColor.rgb * (1.0 - reflectionFresnelTerm) + reflectionFresnelTerm * reflectionRightColor.rgb;
+			#else
+				reflectionColor *= reflectionLeftColor.rgb * (1.0 - reflectionFresnelTerm) + reflectionFresnelTerm * reflectionRightColor.rgb;
+			#endif
+		#else
+			reflectionColor *= reflectionLeftColor.rgb * (1.0 - reflectionFresnelTerm) + reflectionFresnelTerm * reflectionRightColor.rgb;
+		#endif
+	#endif
 #endif
 
 #ifdef REFRACTIONFRESNEL

+ 10 - 0
src/Tools/babylon.sceneSerializer.ts

@@ -305,6 +305,16 @@
                 }
             }
 
+            // Effect layers
+            serializationObject.effectLayers = [];
+
+            for (index = 0; index < scene.effectLayers.length; index++) {
+                var layer = scene.effectLayers[index];
+                if (layer.serialize) {
+                    serializationObject.effectLayers.push(layer.serialize());
+                }
+            }
+
             return serializationObject;
         }
 

+ 1 - 1
src/Tools/babylon.tools.ts

@@ -716,7 +716,7 @@
 
             script.onerror = (e) => {
                 if (onError) {
-                    onError("Unable to load script", e);
+                    onError(`Unable to load script '${scriptUrl}'`, e);
                 }
             };
 

+ 16 - 1
src/babylon.assetContainer.ts

@@ -71,6 +71,10 @@ module BABYLON {
          * Textures to keep.
          */
         public textures = new Array<Texture>();
+        /**
+         * Effect layers to keep.
+         */
+        public effectLayers = new Array<EffectLayer>();
     }
 
     /**
@@ -151,6 +155,10 @@ module BABYLON {
          * Textures populated in the container.
          */
         public textures = new Array<Texture>();
+        /**
+         * Effect layers populated in the container.
+         */
+        public effectLayers = new Array<EffectLayer>();
 
         /**
          * Instantiates an AssetContainer.
@@ -212,7 +220,10 @@ module BABYLON {
                 this.scene.mainSoundTrack.AddSound(o);
             });
             this.textures.forEach((o) => {
-                this.scene.addTexture
+                this.scene.addTexture(o);
+            });
+            this.effectLayers.forEach((o) => {
+                this.scene.addEffectLayer(o);
             });
         }
 
@@ -270,6 +281,9 @@ module BABYLON {
             this.textures.forEach((o) => {
                 this.scene.removeTexture(o);
             });
+            this.effectLayers.forEach((o) => {
+                this.scene.removeEffectLayer(o);
+            });
         }
 
         private _moveAssets<T>(sourceAssets: T[], targetAssets: T[], keepAssets: T[]): void {
@@ -314,6 +328,7 @@ module BABYLON {
             this._moveAssets(this.scene.mainSoundTrack.soundCollection, this.sounds, keepAssets.sounds);
             this._moveAssets(this.scene.transformNodes, this.transformNodes, keepAssets.transformNodes);
             this._moveAssets(this.scene.textures, this.textures, keepAssets.textures);
+            this._moveAssets(this.scene.effectLayers, this.effectLayers, keepAssets.effectLayers);
 
             this.removeAllFromScene();
         }

+ 53 - 10
src/babylon.scene.ts

@@ -2693,32 +2693,49 @@
                 var target = this._registeredForLateAnimationBindings.data[index];
 
                 for (var path in target._lateAnimationHolders) {
-                    var holder = target._lateAnimationHolders[path];       
+                    var holder = target._lateAnimationHolders[path];                     
+                    let originalValue = holder.animations[0].originalValue;      
                     
                     // Sanity check
-                    if (!holder.animations[0].originalValue.scaleAndAddToRef) {
+                    if (!originalValue.scaleAndAddToRef) {
                         continue;
                     }
 
+                    let matrixDecomposeMode = Animation.AllowMatrixDecomposeForInterpolation && originalValue.m; // ie. data is matrix
                     let normalizer = 1.0;
                     let finalValue: any;
 
                     if (holder.totalWeight < 1.0) {
-                        // We need to mix the original value in
-                        let originalValue = holder.animations[0].originalValue;                       
-
-                        finalValue = originalValue.scale(1.0 - holder.totalWeight)
+                        // We need to mix the original value in     
+                        if (matrixDecomposeMode) {
+                            finalValue = originalValue.clone();
+                        } else {            
+                            finalValue = originalValue.scale(1.0 - holder.totalWeight)
+                        }
                     } else {
                         // We need to normalize the weights
                         normalizer = holder.totalWeight;
                     }
 
                     for (var animIndex = 0; animIndex < holder.animations.length; animIndex++) {
-                        var runtimeAnimation = holder.animations[animIndex];    
+                        var runtimeAnimation = holder.animations[animIndex];   
+                        var scale = runtimeAnimation.weight / normalizer;
                         if (finalValue) {
-                            runtimeAnimation.currentValue.scaleAndAddToRef(runtimeAnimation.weight / normalizer, finalValue);
+                            if (matrixDecomposeMode) {
+                                Matrix.DecomposeLerpToRef(finalValue, runtimeAnimation.currentValue, scale, finalValue);
+                            } else {
+                                runtimeAnimation.currentValue.scaleAndAddToRef(scale, finalValue);
+                            }
                         } else {
-                            finalValue = runtimeAnimation.currentValue.scale(runtimeAnimation.weight / normalizer);
+                            if (scale !== 1) {
+                                if (matrixDecomposeMode) {
+                                    finalValue = runtimeAnimation.currentValue.clone();
+                                } else {
+                                    finalValue = runtimeAnimation.currentValue.scale(scale);
+                                }
+                            } else {
+                                finalValue = runtimeAnimation.currentValue;
+                            }
                         }
                     }
 
@@ -3075,6 +3092,21 @@
             return index;
         }
 
+        
+        /**
+         * Removes the given effect layer from this scene.
+         * @param toRemove defines the effect layer to remove
+         * @returns the index of the removed effect layer
+         */    
+        public removeEffectLayer(toRemove: EffectLayer): number {
+            var index = this.effectLayers.indexOf(toRemove);
+            if (index !== -1) {
+                this.effectLayers.splice(index, 1);
+            }
+
+            return index;
+        }
+
         /**
          * Removes the given texture from this scene.
          * @param toRemove The texture to remove
@@ -3198,6 +3230,14 @@
         }
 
         /**
+         * Adds the given effect layer to this scene
+         * @param newEffectLayer defines the effect layer to add
+         */     
+        public addEffectLayer(newEffectLayer: EffectLayer): void {
+            this.effectLayers.push(newEffectLayer);
+        }
+
+        /**
          * Adds the given action manager to this scene
          * @param newActionManager The action manager to add
          */   
@@ -4475,7 +4515,10 @@
                             }
 
                             //if this is an exit trigger, or no exit trigger exists, remove the id from the intersection in progress array.
-                            if (!sourceMesh.actionManager.hasSpecificTrigger(ActionManager.OnIntersectionExitTrigger) || action.trigger === ActionManager.OnIntersectionExitTrigger) {
+                            if (!sourceMesh.actionManager.hasSpecificTrigger(ActionManager.OnIntersectionExitTrigger, parameter => {
+                                var parameterMesh = parameter instanceof AbstractMesh ? parameter : parameter.mesh;
+                                return otherMesh === parameterMesh;
+                            }) || action.trigger === ActionManager.OnIntersectionExitTrigger) {
                                 sourceMesh._intersectionsInProgress.splice(currentIntersectionInProgress, 1);
                             }
                         }

二进制
tests/validation/ReferenceImages/enableDisablePostProcess.png


+ 4 - 1
tests/validation/index.html

@@ -2,7 +2,10 @@
 <html>
 <head>
 	<title>BabylonJS - Build validation page</title>
-	<link href="index.css" rel="stylesheet" />
+	<link href="index.css" rel="stylesheet" />	
+    <script src="https://preview.babylonjs.com/draco_decoder.js" type="text/x-draco-decoder"></script>
+    <script src="https://preview.babylonjs.com/draco_decoder.wasm" type="text/x-draco-decoder-wasm-binary"></script>
+    <script src="https://preview.babylonjs.com/draco_wasm_wrapper.js" type="text/x-draco-decoder-wasm-wrapper"></script>
 	<script src="https://unpkg.com/earcut@2.1.1/dist/earcut.min.js"></script>
 	<script src="../../Tools/DevLoader/BabylonLoader.js"></script>
 </head>

+ 0 - 1
tests/validation/validate.html

@@ -5,7 +5,6 @@
 	<link href="index.css" rel="stylesheet" />
     <script src="https://preview.babylonjs.com/draco_decoder.js"></script>
     <script src="https://preview.babylonjs.com/cannon.js"></script>
-    <script src="https://preview.babylonjs.com/draco_decoder.js"></script>
     <script src="https://preview.babylonjs.com/Oimo.js"></script>
     <script src="https://preview.babylonjs.com/babylon.js"></script>
     <script src="https://preview.babylonjs.com/inspector/babylon.inspector.bundle.js"></script>

+ 12 - 1
tests/validation/validation.js

@@ -312,7 +312,18 @@ function runTest(index, done) {
 function init() {
     BABYLON.SceneLoader.ShowLoadingScreen = false;
     BABYLON.SceneLoader.ForceFullSceneLoadingForIncremental = true;
-    BABYLON.DracoCompression.DecoderUrl = BABYLON.Tools.GetFolderPath(document.location.href) + "../../dist/preview%20release/draco_decoder.js";
+
+    // Draco configuration
+    var baseUrl = BABYLON.Tools.GetFolderPath(document.location.href);
+    BABYLON.DracoCompression.Configuration = {
+        decoder: {
+            url: baseUrl + "../../dist/preview%20release/draco_decoder.js"
+        },
+        decoderWasm: {
+            binaryUrl: baseUrl + "../../dist/preview%20release/draco_decoder.wasm",
+            wrapperUrl: baseUrl + "../../dist/preview%20release/draco_wasm_wrapper.js"
+        }
+    };
 
     canvas = document.createElement("canvas");
     canvas.className = "renderCanvas";