Преглед изворни кода

Merge remote-tracking branch 'BabylonJS/master'

MackeyK24 пре 7 година
родитељ
комит
2d3caea344
100 измењених фајлова са 218486 додато и 27257 уклоњено
  1. 2 0
      .gitignore
  2. 26 8
      .travis.yml
  3. 6 4
      .vscode/launch.json
  4. 9 1
      .vscode/settings.json
  5. 5107 2546
      Playground/babylon.d.txt
  6. 18 104
      Tools/Gulp/config.json
  7. 79 0
      Tools/Gulp/gulp-addES6Exports.js
  8. 36 6
      Tools/Gulp/gulp-appendSrcToVariable.js
  9. 66 46
      Tools/Gulp/gulp-babylonModule.js
  10. 80 0
      Tools/Gulp/gulp-calculateDependencies.js
  11. 38 4
      Tools/Gulp/gulp-dtsModuleSupport.js
  12. 139 36
      Tools/Gulp/gulp-es6ModuleExports.js
  13. 725 0
      Tools/Gulp/gulp-validateTypedoc.js
  14. 337 70
      Tools/Gulp/gulpfile.js
  15. 17 11
      Tools/Gulp/package.json
  16. 47 19
      Tools/Publisher/index.js
  17. 3 0
      Tools/Publisher/package.json
  18. 4 3
      Viewer/dist/basicExample.html
  19. 5 0
      Viewer/dist/config.json
  20. 18444 15388
      Viewer/dist/viewer.js
  21. 1 1
      Viewer/dist/viewer.min.js
  22. 10 10
      Viewer/package.json
  23. 0 14
      Viewer/src/configuration/configuration.ts
  24. 8 4
      Viewer/src/configuration/loader.ts
  25. 1 2
      Viewer/src/configuration/mappers.ts
  26. 7 1
      Viewer/src/configuration/types/default.ts
  27. 2 1
      Viewer/src/configuration/types/index.ts
  28. 40 0
      Viewer/src/eventManager.ts
  29. 49 18
      Viewer/src/templateManager.ts
  30. 42 59
      Viewer/src/viewer/defaultViewer.ts
  31. 1 0
      Viewer/src/viewer/viewer.ts
  32. 1 1
      Viewer/src/viewer/viewerManager.ts
  33. 251 0
      dist/babylon.glTFInterface.d.ts
  34. 5438 2973
      dist/preview release/babylon.d.ts
  35. 51 51
      dist/preview release/babylon.js
  36. 4012 1230
      dist/preview release/babylon.max.js
  37. 53 53
      dist/preview release/babylon.worker.js
  38. 5598 3133
      dist/preview release/customConfigurations/minimalGLTFViewer/babylon.d.ts
  39. 55 55
      dist/preview release/customConfigurations/minimalGLTFViewer/babylon.js
  40. 4001 1248
      dist/preview release/customConfigurations/minimalGLTFViewer/babylon.max.js
  41. 88667 0
      dist/preview release/customConfigurations/minimalGLTFViewer/es6.js
  42. 84468 0
      dist/preview release/es6.js
  43. 72 1
      dist/preview release/gui/babylon.gui.d.ts
  44. 112 16
      dist/preview release/gui/babylon.gui.js
  45. 2 2
      dist/preview release/gui/babylon.gui.min.js
  46. 72 1
      dist/preview release/gui/babylon.gui.module.d.ts
  47. 2 2
      dist/preview release/gui/package.json
  48. 4 4
      dist/preview release/inspector/babylon.inspector.bundle.js
  49. 2 0
      dist/preview release/inspector/babylon.inspector.d.ts
  50. 6 4
      dist/preview release/inspector/babylon.inspector.js
  51. 4 4
      dist/preview release/inspector/babylon.inspector.min.js
  52. 2 2
      dist/preview release/inspector/package.json
  53. 1 0
      dist/preview release/loaders/babylon.glTF1FileLoader.d.ts
  54. 22 0
      dist/preview release/loaders/babylon.glTF1FileLoader.js
  55. 2 2
      dist/preview release/loaders/babylon.glTF1FileLoader.min.js
  56. 2 1
      dist/preview release/loaders/babylon.glTF2FileLoader.d.ts
  57. 43 20
      dist/preview release/loaders/babylon.glTF2FileLoader.js
  58. 2 2
      dist/preview release/loaders/babylon.glTF2FileLoader.min.js
  59. 2 1
      dist/preview release/loaders/babylon.glTFFileLoader.d.ts
  60. 43 20
      dist/preview release/loaders/babylon.glTFFileLoader.js
  61. 3 3
      dist/preview release/loaders/babylon.glTFFileLoader.min.js
  62. 1 0
      dist/preview release/loaders/babylon.objFileLoader.d.ts
  63. 9 0
      dist/preview release/loaders/babylon.objFileLoader.js
  64. 1 1
      dist/preview release/loaders/babylon.objFileLoader.min.js
  65. 1 0
      dist/preview release/loaders/babylon.stlFileLoader.d.ts
  66. 9 0
      dist/preview release/loaders/babylon.stlFileLoader.js
  67. 1 1
      dist/preview release/loaders/babylon.stlFileLoader.min.js
  68. 61 20
      dist/preview release/loaders/babylonjs.loaders.js
  69. 3 3
      dist/preview release/loaders/babylonjs.loaders.min.js
  70. 4 1
      dist/preview release/loaders/babylonjs.loaders.module.d.ts
  71. 2 2
      dist/preview release/loaders/package.json
  72. 1 1
      dist/preview release/materialsLibrary/babylon.cellMaterial.js
  73. 1 1
      dist/preview release/materialsLibrary/babylon.cellMaterial.min.js
  74. 1 0
      dist/preview release/materialsLibrary/babylon.customMaterial.d.ts
  75. 4 1
      dist/preview release/materialsLibrary/babylon.customMaterial.js
  76. 2 2
      dist/preview release/materialsLibrary/babylon.customMaterial.min.js
  77. 1 1
      dist/preview release/materialsLibrary/babylon.fireMaterial.js
  78. 1 1
      dist/preview release/materialsLibrary/babylon.fireMaterial.min.js
  79. 1 1
      dist/preview release/materialsLibrary/babylon.furMaterial.js
  80. 1 1
      dist/preview release/materialsLibrary/babylon.furMaterial.min.js
  81. 1 1
      dist/preview release/materialsLibrary/babylon.gradientMaterial.js
  82. 1 1
      dist/preview release/materialsLibrary/babylon.gradientMaterial.min.js
  83. 1 1
      dist/preview release/materialsLibrary/babylon.lavaMaterial.js
  84. 1 1
      dist/preview release/materialsLibrary/babylon.lavaMaterial.min.js
  85. 1 1
      dist/preview release/materialsLibrary/babylon.normalMaterial.js
  86. 1 1
      dist/preview release/materialsLibrary/babylon.normalMaterial.min.js
  87. 1 1
      dist/preview release/materialsLibrary/babylon.shadowOnlyMaterial.js
  88. 1 1
      dist/preview release/materialsLibrary/babylon.shadowOnlyMaterial.min.js
  89. 1 1
      dist/preview release/materialsLibrary/babylon.simpleMaterial.js
  90. 1 1
      dist/preview release/materialsLibrary/babylon.simpleMaterial.min.js
  91. 1 1
      dist/preview release/materialsLibrary/babylon.terrainMaterial.js
  92. 1 1
      dist/preview release/materialsLibrary/babylon.terrainMaterial.min.js
  93. 1 1
      dist/preview release/materialsLibrary/babylon.triPlanarMaterial.js
  94. 1 1
      dist/preview release/materialsLibrary/babylon.triPlanarMaterial.min.js
  95. 1 1
      dist/preview release/materialsLibrary/babylon.waterMaterial.js
  96. 1 1
      dist/preview release/materialsLibrary/babylon.waterMaterial.min.js
  97. 15 12
      dist/preview release/materialsLibrary/babylonjs.materials.js
  98. 7 7
      dist/preview release/materialsLibrary/babylonjs.materials.min.js
  99. 1 0
      dist/preview release/materialsLibrary/babylonjs.materials.module.d.ts
  100. 0 0
      dist/preview release/materialsLibrary/package.json

+ 2 - 0
.gitignore

@@ -24,6 +24,8 @@ postProcessLibrary/src/**/*.js
 inspector/src/**/*.js
 serializers/src/**/*.js
 gui/src/**/*.js
+tests/unit/**/*.js
+!tests/unit/karma.conf.js
 
 # Build results
 [Rr]elease/

+ 26 - 8
.travis.yml

@@ -1,16 +1,34 @@
+sudo: required
+dist: trusty
 language: node_js
 node_js:
 - '6'
-addons:
-  sauce_connect:
-    username: vandenberghe.sebastien@gmail.com
-  jwt:
-    secure: kbaJ3o6cVqpB8Gzfd0yDSgGwH+SQXukevtpjMQ8Gip+N6FOumQxihPDqsqYKxc8svvR024nDmkIhbjPjz/YguvC3WUgYW4xk3Za7P7C9cpj2fYdrFuO7pD4sd/fNdUCqvKQ8jcxlIq4eEdBuoBTOHsP9J5KH7Z1M7e58atkx0o8=
+cache:
+  directories:
+    - Tools/Gulp/node_modules
+    - Playground/node_modules
+    - tests/unit/node_modules
+git:
+  depth: 3
 before_script:
-- npm install -g gulp
+- travis_retry npm install -g gulp
 - cd ./Tools/Gulp
-- npm install
-script: gulp
+- travis_retry npm install
+- "export DISPLAY=:99.0"
+- "sh -e /etc/init.d/xvfb start"
+- sleep 3 # give xvfb some time to start
+script: 
+- gulp tests-whatsnew
+- set -e
+- gulp typescript-all
+- gulp typedoc-all
+- gulp tests-unit
+- travis_retry gulp tests-validation-virtualscreen
+- travis_retry gulp tests-validation-browserstack
 notifications:
   slack:
     secure: TBYDAN8Dlkx3dM+Q5ClAZem7agAhQ1oB/fGT665qn7D+j2YfWChvlfXegvXL4LPDmQgbI0UfazcjWId5a0EwmmPkRb+kMJItPiMt5jiIp2WKoZQ+qob6H9tBCRJbbpWM430wiPeKfBfbcZP/XSlpVMWhgU5ogAFDSUKjvHT7IuE=
+env:
+  global:
+  - secure: XVMhWPm3ByrZduLmbyBMsKU462bEbYPNRp+42HcdOuC3YOl2ODPvANrE/qZneZzGqlyiFAg6X4mDGD71Qw9ekbFt5q0PmvIxkRrX0KNJEJl9/gnFadOz3xFWEfFw4tiSHp36PUu9aT6ti9mn9gnM8C+vQZhqVpaMgkLpWzeEeXQ=
+  - secure: jaGc/NJwACWJPLfI/L1UfYvWKX6AGVjFwXA+31elOVNAmG4XRwaTUaugqP4FhjTw0g2pqTB1BlSML+Fs3dVaUGy3bpslQLL74iG06XZbFUqrtVV2/sOcJaoWxIc69ld0tcqLdPvMSrCIzGQYAWaNNllyMnBjsWBZ+0J0ghtbBDA=

+ 6 - 4
.vscode/launch.json

@@ -130,10 +130,12 @@
             "request": "launch",
             "reAttach": true,
             "url": "http://localhost:1338/localDev/index.html",
-            "pathMappings": [{
-                "url": "http://localhost:1338",
-                "path": "${workspaceFolder}"
-            }],
+            "pathMappings": [
+                {
+                    "url": "http://localhost:1338",
+                    "path": "${workspaceFolder}"
+                }
+            ],
             "preLaunchTask": "run"
         },
         {

+ 9 - 1
.vscode/settings.json

@@ -11,7 +11,15 @@
         "**/node_modules": true,
         "**/temp": true,
         "**/.temp": true,
-        "**/*.d.ts": true,
+        "src/**/*.d.ts": true,
+        "gui/**/*.d.ts": true,
+        "inspector/**/*.d.ts": true,
+        "loaders/**/*.d.ts": true,
+        "materialsLibrary/**/*.d.ts": true,
+        "postProcessesLibrary/**/*.d.ts": true,
+        "proceduralTexturesLibrary/**/*.d.ts": true,
+        "serielazers/**/*.d.ts": true,
+        "viewer/**/*.d.ts": true,
         "**/*.js.map": true,
         "**/*.js.fx": true,
         "**/*.js": { 

Разлика између датотеке није приказан због своје велике величине
+ 5107 - 2546
Playground/babylon.d.txt


+ 18 - 104
Tools/Gulp/config.json

@@ -14,7 +14,9 @@
         ],
         "outputCustomConfigurationsDirectory": "../../dist/preview release/customConfigurations",
         "srcOutputDirectory": "../../src/",
-        "currentConfig": "all"
+        "currentConfig": "all",
+        "typedocJSON": "../../.temp/babylon.typedoc.json",
+        "typedocValidationBaseline": "../../dist/preview release/typedocValidationBaseline.json"
     },
     "buildConfigurations": {
         "all": [
@@ -67,7 +69,6 @@
             "debug",
             "morphTargets",
             "octrees",
-            "simd",
             "vr",
             "virtualJoystick",
             "optimizations",
@@ -141,7 +142,6 @@
             "debug",
             "morphTargets",
             "octrees",
-            "simd",
             "vr",
             "virtualJoystick",
             "optimizations",
@@ -192,8 +192,10 @@
                 "../../src/Rendering/babylon.renderingManager.js",
                 "../../src/Rendering/babylon.renderingGroup.js",
                 "../../src/babylon.scene.js",
+                "../../src/babylon.assetContainer.js",
                 "../../src/Mesh/babylon.buffer.js",
                 "../../src/Mesh/babylon.vertexBuffer.js",
+                "../../src/Materials/Textures/babylon.internalTextureTracker.js",
                 "../../src/Materials/Textures/babylon.internalTexture.js",
                 "../../src/Materials/Textures/babylon.baseTexture.js",
                 "../../src/Materials/Textures/babylon.texture.js",
@@ -251,7 +253,6 @@
                 "imageProcessingFunctions",
                 "bumpFragmentFunctions",
                 "clipPlaneFragmentDeclaration",
-                "logDepthDeclaration",
                 "fogFragmentDeclaration",
                 "clipPlaneFragment",
                 "bumpFragment",
@@ -443,45 +444,12 @@
                 "pbr.fragment"
             ],
             "shaderIncludes": [
-                "bonesDeclaration",
-                "instancesDeclaration",
-                "bumpVertexDeclaration",
-                "clipPlaneVertexDeclaration",
-                "fogVertexDeclaration",
-                "morphTargetsVertexGlobalDeclaration",
-                "morphTargetsVertexDeclaration",
-                "logDepthDeclaration",
-                "morphTargetsVertex",
-                "instancesVertex",
-                "bonesVertex",
-                "bumpVertex",
-                "clipPlaneVertex",
-                "fogVertex",
-                "shadowsVertex",
-                "logDepthVertex",
-                "lightFragmentDeclaration",
-                "lightUboDeclaration",
                 "pbrVertexDeclaration",
                 "pbrFragmentDeclaration",
                 "pbrUboDeclaration",
-                "fresnelFunction",
-                "reflectionFunction",
-                "shadowsFragmentFunctions",
                 "pbrFunctions",
-                "imageProcessingDeclaration",
-                "imageProcessingFunctions",
                 "harmonicsFunctions",
-                "pbrLightFunctions",
-                "helperFunctions",
-                "bumpFragmentFunctions",
-                "clipPlaneFragmentDeclaration",
-                "logDepthDeclaration",
-                "fogFragmentDeclaration",
-                "clipPlaneFragment",
-                "bumpFragment",
-                "lightFragment",
-                "logDepthFragment",
-                "fogFragment"
+                "pbrLightFunctions"
             ]
         },
         "targetCamera": {
@@ -615,7 +583,6 @@
                 "../../src/Tools/babylon.andOrNotEvaluator.js"
             ],
             "dependUpon": [
-                "core",
                 "stringDictionary"
             ]
         },
@@ -676,7 +643,8 @@
                 "../../src/Gamepad/Controllers/babylon.oculusTouchController.js",
                 "../../src/Gamepad/Controllers/babylon.viveController.js",
                 "../../src/Gamepad/Controllers/babylon.genericController.js",
-                "../../src/Gamepad/Controllers/babylon.windowsMotionController.js"
+                "../../src/Gamepad/Controllers/babylon.windowsMotionController.js",
+                "../../src/Gamepad/Controllers/babylon.gearVRController.js"
             ],
             "dependUpon": [
                 "core"
@@ -703,12 +671,7 @@
                 "depth.vertex",
                 "depth.fragment"
             ],
-            "shaderIncludes": [
-                "bonesDeclaration",
-                "instancesDeclaration",
-                "instancesVertex",
-                "bonesVertex"
-            ]
+            "shaderIncludes": []
         },
         "geometryBufferRenderer": {
             "files": [
@@ -724,9 +687,7 @@
             "shaderIncludes": [
                 "mrtFragmentDeclaration",
                 "bones300Declaration",
-                "instances300Declaration",
-                "instancesVertex",
-                "bonesVertex"
+                "instances300Declaration"
             ]
         },
         "postProcesses": {
@@ -793,10 +754,7 @@
             "shaders": [
                 "imageProcessing.fragment"
             ],
-            "shaderIncludes": [
-                "imageProcessingDeclaration",
-                "imageProcessingFunctions"
-            ]
+            "shaderIncludes": []
         },
         "additionalPostProcesses": {
             "files": [
@@ -962,10 +920,7 @@
                 "stringDictionary",
                 "actions"
             ],
-            "shaders": [
-                "color.vertex",
-                "color.fragment"
-            ]
+            "shaders": []
         },
         "morphTargets": {
             "files": [
@@ -985,14 +940,6 @@
                 "core"
             ]
         },
-        "simd": {
-            "files": [
-                "../../src/Math/babylon.math.SIMD.js"
-            ],
-            "dependUpon": [
-                "core"
-            ]
-        },
         "vr": {
             "files": [
                 "../../src/PostProcess/babylon.vrDistortionCorrectionPostProcess.js",
@@ -1008,7 +955,9 @@
                 "../../src/Cameras/VR/babylon.vrExperienceHelper.js"
             ],
             "dependUpon": [
-                "core"
+                "core",
+                "postProcesses",
+                "freeCamera"
             ],
             "shaders": [
                 "anaglyph.fragment",
@@ -1105,45 +1054,9 @@
                 "background.fragment"
             ],
             "shaderIncludes": [
-                "bonesDeclaration",
-                "instancesDeclaration",
-                "pointCloudVertexDeclaration",
-                "bumpVertexDeclaration",
-                "clipPlaneVertexDeclaration",
-                "fogVertexDeclaration",
-                "morphTargetsVertexGlobalDeclaration",
-                "morphTargetsVertexDeclaration",
-                "logDepthDeclaration",
-                "morphTargetsVertex",
-                "instancesVertex",
-                "bonesVertex",
-                "bumpVertex",
-                "clipPlaneVertex",
-                "fogVertex",
-                "shadowsVertex",
-                "pointCloudVertex",
-                "logDepthVertex",
-                "helperFunctions",
-                "lightFragmentDeclaration",
-                "lightsFragmentFunctions",
-                "lightUboDeclaration",
                 "backgroundVertexDeclaration",
                 "backgroundFragmentDeclaration",
-                "backgroundUboDeclaration",
-                "shadowsFragmentFunctions",
-                "fresnelFunction",
-                "reflectionFunction",
-                "imageProcessingDeclaration",
-                "imageProcessingFunctions",
-                "bumpFragmentFunctions",
-                "clipPlaneFragmentDeclaration",
-                "logDepthDeclaration",
-                "fogFragmentDeclaration",
-                "clipPlaneFragment",
-                "bumpFragment",
-                "lightFragment",
-                "logDepthFragment",
-                "fogFragment"
+                "backgroundUboDeclaration"
             ]
         },
         "environmentHelper": {
@@ -1546,7 +1459,8 @@
                 "files": [
                     "../../serializers/src/glTF/2.0/babylon.glTFSerializer.ts",
                     "../../serializers/src/glTF/2.0/babylon.glTFExporter.ts",
-                    "../../serializers/src/glTF/2.0/babylon.glTFData.ts"
+                    "../../serializers/src/glTF/2.0/babylon.glTFData.ts",
+                    "../../serializers/src/glTF/2.0/babylon.glTFMaterial.ts"
                 ],
                 "output": "babylon.glTF2Serializer.js"
             }

+ 79 - 0
Tools/Gulp/gulp-addES6Exports.js

@@ -0,0 +1,79 @@
+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. 
+ */
+module.exports = function (baseModule, subModule, extendsRoot, externalUsingBabylon) {
+    return through.obj(function (file, enc, cb) {
+
+        var optionalRequire = `var globalObject = (typeof global !== 'undefined') ? global : ((typeof window !== 'undefined') ? window : this);
+var babylonDependency = (globalObject && globalObject.BABYLON) || BABYLON || (typeof require !== 'undefined' && require("babylonjs"));
+var BABYLON = babylonDependency;
+`;
+        let fileContent = file.contents.toString();
+        function moduleExportAddition(varName) {
+
+            let base = subModule ? 'BABYLON' : baseModule;
+
+            let sadGlobalPolution = (!subModule) ? `var globalObject = (typeof global !== 'undefined') ? global : ((typeof window !== 'undefined') ? window : this);
+globalObject["${base}"] = ${base}${(subModule && !extendsRoot) ? '.' + varName : ''};` : '';
+            /*if (extendsRoot) {
+                basicInit = `__extends(root["BABYLON"], factory()); `
+            }*/
+
+            let listOfExports = [];
+            // find the exported members. es6 exports can NOT be generated dynamically.
+            let matcher = new RegExp(base + "\\.(\\w*) = (\\w*);", "g");
+            let match = matcher.exec(fileContent);
+            while (match != null) {
+                if (match[1] && match[2] && match[1] === match[2]) {
+                    listOfExports.push(match[1]);
+                }
+                match = matcher.exec(fileContent);
+            }
+
+            let exportsText = '';
+            listOfExports.forEach(cls => {
+                exportsText += `var ${cls} = ${base}.${cls};`;
+            });
+            exportsText += `
+export { ${listOfExports.join(",")} };`
+
+            return `${sadGlobalPolution}
+${exportsText}
+`;
+        }
+
+        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};\n';
+
+
+        if (file.isNull()) {
+            cb(null, file);
+            return;
+        }
+
+        if (file.isStream()) {
+            //streams not supported, no need for now.
+            return;
+        }
+
+        try {
+            if (externalUsingBabylon) {
+                //file.contents = new Buffer(optionalRequire.concat(String(file.contents)));
+                file.contents = new Buffer(optionalRequire.concat(new Buffer(String(file.contents).concat(moduleExportAddition(baseModule)))));
+            } else {
+                let pretext = subModule ? optionalRequire : '';
+                file.contents = new Buffer(pretext.concat(decorateAddition).concat(new Buffer(extendsAddition.concat(String(file.contents)).concat(moduleExportAddition(baseModule)))));
+            }
+            this.push(file);
+        } catch (err) {
+            this.emit('error', new gutil.PluginError('gulp-add-module-exports', err, { fileName: file.path }));
+        }
+        cb();
+    });
+};

+ 36 - 6
Tools/Gulp/gulp-appendSrcToVariable.js

@@ -7,7 +7,7 @@ var File = gutil.File;
 // Consts
 const PLUGIN_NAME = 'gulp-appendSrcToVariable';
 
-var appendSrcToVariable = function appendSrcToVariable(varName, namingCallback, output, lastFile) {
+var appendSrcToVariable = function appendSrcToVariable(varName, namingCallback, output, moduleType) {
 
     var content;
     var firstFile;
@@ -28,17 +28,47 @@ var appendSrcToVariable = function appendSrcToVariable(varName, namingCallback,
             return;
         }
 
+        // construct concat instance
+        if (!content) {
+            content = "";
+        }
+
         // set first file if not already set
         if (!firstFile) {
+            if (moduleType === "es6") {
+                content += `
+// import * as BABYLON from 'babylonjs/core/es6';
+`;
+            }
             firstFile = file;
         }
 
-        // construct concat instance
-        if (!content) {
-            content = "";
-        }
+
         var name = namingCallback(file.relative);
-        content += varName + "['" + name + "'] = " + JSON.stringify(file.contents.toString()) + ";\r\n";
+        if (moduleType) {
+            let vars = varName.split(".");
+            // shader support when using modules
+            if (moduleType === "es6") {
+                content += `
+let ${name} = ${JSON.stringify(file.contents.toString())};
+// ${varName}["${name}"] = ${varName}["${name}"] || ${name};
+export { ${name}  };
+`;
+            } else {
+                // commonjs
+                content += `
+if(typeof require !== 'undefined'){
+var BABYLON = require("babylonjs/core");
+let data = ${JSON.stringify(file.contents.toString())};
+${varName}["${name}"] = ${varName}["${name}"] || data;
+module.exports = module.exports || {};
+module.exports["${name}"] = data;
+}
+`;
+            }
+        } else {
+            content += varName + "['" + name + "'] = " + JSON.stringify(file.contents.toString()) + ";\r\n";
+        }
         cb();
     }
 

+ 66 - 46
Tools/Gulp/gulp-babylonModule.js

@@ -1,34 +1,23 @@
 var gutil = require('gulp-util');
 var through = require('through2');
+var path = require('path');
 
-module.exports = function (moduleName, dependencies) {
+module.exports = function (moduleName, dependencyTree, generateIndex, perFile, shaders, shaderIncludes) {
     return through.obj(function (file, enc, cb) {
 
-        console.log("Compiling module: " + moduleName);
+        let basename = (path.basename(file.path, ".js"));
+
+        //console.log("Compiling module: " + moduleName + "/" + basename.replace("babylon.", ""));
 
         var extendsAddition =
-            `var __extends = (this && this.__extends) || (function () {
-var extendStatics = Object.setPrototypeOf ||
-    ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
-    function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
-return function (d, b) {
-    extendStatics(d, b);
-    function __() { this.constructor = d; }
-    d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
-};
-})();
+            `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 (decorators, target, key, desc) {\n' +
-            'var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;\n' +
-            'if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);\n' +
-            'else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;\n' +
-            'return c > 3 && r && Object.defineProperty(target, key, r), r;\n' +
-            '};\n';
+            '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};\n';
 
         let content = file.contents.toString();
-        if (content.indexOf('__extends') === -1 && dependencies.length < 2) {
+        if (content.indexOf('__extends') === -1 && !dependencyTree.length) {
             extendsAddition = '';
         }
 
@@ -41,23 +30,68 @@ ${decorateAddition}
 if(typeof require !== 'undefined'){
     var globalObject = (typeof global !== 'undefined') ? global : ((typeof window !== 'undefined') ? window : this);
     var BABYLON = globalObject["BABYLON"] || {}; 
+    var EXPORTS = {};
+`;
+        let exportsText = '';
+        if (!generateIndex) {
+            let loadedFiles = [];
+            dependencyTree[basename].forEach(function (d, idx) {
+                if (d.module.indexOf("core") !== -1) return;
+                let name = d.file.split(".").pop();
+
+                if (loadedFiles.indexOf(name) === -1) {
+                    if (d.main)
+                        dependenciesText += `var ${name}Module = require('babylonjs/${d.module[0]}/${name}');
 `;
-        if (dependencies) {
-            /*if (dependencies.length > 1) {
-                dependenciesText += 'function nse(ns1, ns2) { Object.keys(ns2).forEach(function(c) {if(!ns1[c]) {ns1[c] = ns2[c]}}) };\n';
-            }*/
+                    else
+                        exportsText += `var ${name}Module = require('babylonjs/${d.module[0]}/${name}');
+`;
+                    loadedFiles.push(name);
+                }
 
-            dependencies.forEach(function (d, idx) {
-                dependenciesText += `var BABYLON${idx} = require('babylonjs/${d}');
+                dependenciesText += `BABYLON["${d.name}"] = ${name}Module["${d.name}"];
 `;
-                dependenciesText += `if(BABYLON !== BABYLON${idx}) __extends(BABYLON, BABYLON${idx});
+                //dependenciesText += `if(BABYLON !== BABYLON${idx}) __extends(BABYLON, BABYLON${idx});
+            });
+            perFile[basename].declarations.forEach(dec => {
+                exportsText += `EXPORTS['${dec}'] = BABYLON["${dec}"];
 `;
             });
+            if (shaders) {
+                dependenciesText += `require("babylonjs/${moduleName}/shaders");
+`;
+            }
+            if (shaderIncludes) {
+                dependenciesText += `require("babylonjs/${moduleName}/shaderIncludes");
+`;
+            }
+        } else {
+            content = '';
+            let basenames = Object.keys(perFile).filter(basefilename => {
+                return perFile[basefilename].module.indexOf(moduleName) !== -1;
+            });
+
+            basenames.forEach(bname => {
+                let name = bname.split(".").pop();
+                dependenciesText += `var ${name} = require("babylonjs/${moduleName}/${name}");
+`;
+                // now add the internal dependencies to EXPORTS
+                perFile[bname].declarations.forEach(dec => {
+                    dependenciesText += `EXPORTS['${dec}'] = BABYLON["${dec}"] = ${name}["${dec}"];
+`;
+                });
+            })
         }
 
+        exportsText += `(function() {
+    globalObject["BABYLON"] = globalObject["BABYLON"] || BABYLON;
+    module.exports = EXPORTS;
+    })();
+}`;
+
 
 
-        let exportRegex = /BABYLON.([0-9A-Za-z-_]*) = .*;\n/g
+        /*let exportRegex = /BABYLON.([0-9A-Za-z-_]*) = .*;\n/g
 
         var match = exportRegex.exec(content);
 
@@ -67,30 +101,16 @@ if(typeof require !== 'undefined'){
                 exportsArray.push(match[1])
             }
             match = exportRegex.exec(content);
-        }
+        }*/
 
-        let exportsText = '';
-        if (moduleName === "core") {
+
+        /*if (moduleName === "core") {
             exportsText = `(function() {
     globalObject["BABYLON"] = globalObject["BABYLON"] || BABYLON;
     module.exports = BABYLON; 
 })();
 }`
-        }
-        else {
-            exportsText = `(function() {
-var EXPORTS = {};`
-            exportsArray.forEach(e => {
-                if (e.indexOf('.') === -1)
-                    exportsText += `EXPORTS['${e}'] = BABYLON['${e}'];`
-            });
-
-            exportsText += `
-    globalObject["BABYLON"] = globalObject["BABYLON"] || BABYLON;
-    module.exports = EXPORTS;
-    })();
-}`
-        }
+        }*/
 
         if (file.isNull()) {
             cb(null, file);
@@ -103,7 +123,7 @@ var EXPORTS = {};`
         }
 
         try {
-            file.contents = new Buffer(dependenciesText.concat(new Buffer(String(file.contents).concat(exportsText))));
+            file.contents = new Buffer(dependenciesText.concat(new Buffer(String(content).concat(exportsText))));
             this.push(file);
         } catch (err) {
             this.emit('error', new gutil.PluginError('gulp-add-babylon-module', err, { fileName: file.path }));

+ 80 - 0
Tools/Gulp/gulp-calculateDependencies.js

@@ -0,0 +1,80 @@
+var gutil = require('gulp-util');
+var through = require('through2');
+var path = require('path');
+
+module.exports = function (moduleName, perFile, declared, depTree) {
+    return through.obj(function (file, enc, cb) {
+        let basename = (path.basename(file.path, ".ts"));
+        depTree[basename] = depTree[basename] || [];
+        // detect dependencies
+        let depReg1 = /[:,][ ]{0,1}([A-Z]\w*)/g;
+        let depReg2 = /<([A-Z]\w*)(\[\]){0,1}>/g;
+        let depReg3 = /[\s(]([A-Z]\w*)\./g;
+        let depReg4 = /[extends|implements] ([A-Z]\w*)/g;
+        let depReg5 = /new ([A-Z]\w*)/g;
+
+        let dependencies = [];
+        fileContent = file.contents.toString().replace(/(\/\*([\s\S]*?)\*\/)|(\/\/(.*)$)/gm, "");
+        function findWhereDeclared(objectName) {
+            let fileLocator;
+            Object.keys(perFile).some((filename => {
+                filedec = perFile[filename];
+                if (filedec.declarations.indexOf(objectName) !== -1) {
+                    fileLocator = filename;
+                    return true;
+                }
+                return false;
+            }))
+            return fileLocator;
+        }
+
+        //if (basename === "babylon.webVRCamera") {
+        [depReg4, depReg1, depReg5, depReg3, depReg2].forEach((reg, idx) => {
+            var match = reg.exec(fileContent);
+            while (match != null) {
+                if (match[1]) {
+                    let dep = match[1];
+                    if (basename === "babylon.poseEnabledController") {
+                        console.log(dep, idx);
+                    }
+                    //find if it is declared internally
+                    if (perFile[basename].declarations.indexOf(dep) === -1) {
+                        // not internally? maybe it is in core?
+                        //if (declared.core.indexOf(dep) === -1) {
+                        // seems like a legit dependency! was it already added?
+                        if (perFile[basename].dependencies.indexOf(dep) === -1) {
+                            //no! add it.
+                            let whereDeclared = (findWhereDeclared(dep));
+                            if (whereDeclared) {
+                                perFile[basename].dependencies.push(dep);
+                                if (basename === "babylon.poseEnabledController") {
+                                    console.log("adding ", dep, idx === 2);
+                                }
+                                depTree[basename].push({
+                                    name: dep,
+                                    file: whereDeclared,
+                                    module: perFile[whereDeclared].module,
+                                    main: idx === 0, // is it a main import
+                                    newDec: idx === 2 // is it "new"
+                                });
+                            }
+                        }
+                        //}
+                    }
+                }
+                match = reg.exec(fileContent);
+            }
+        });
+        //}
+
+
+        try {
+            this.push(file);
+
+        } catch (err) {
+            this.emit('error', new gutil.PluginError('gulp-calculateDependencies', err, { fileName: file.path }));
+        }
+        cb();
+    });
+};
+

+ 38 - 4
Tools/Gulp/gulp-dtsModuleSupport.js

@@ -1,14 +1,23 @@
 var gutil = require('gulp-util');
 var through = require('through2');
+var path = require('path');
 
 // inject - if set to true, it will add all declarations as imports.
-module.exports = function (moduleName, inject, declarations) {
+module.exports = function (moduleName, inject, declarations, perFile, dependencyTree) {
     return through.obj(function (file, enc, cb) {
-
+        let basename = (path.basename(file.path, ".d.ts"));
         let fileContent = file.contents.toString();
         let importsString = '';
 
         if (!inject) {
+            perFile[basename] = perFile[basename] || {
+                module: [moduleName],
+                dependencies: [],
+                declarations: []
+            };
+            if (perFile[basename].module.indexOf(moduleName) === -1) {
+                perFile[basename].module.push(moduleName);
+            }
             declarations[moduleName] = declarations[moduleName] || [];
             let regexp = /    (abstract class|function|class|interface|type|const|enum|var) ([\w]*)/g;
 
@@ -17,13 +26,15 @@ module.exports = function (moduleName, inject, declarations) {
                 if (match[2]) {
                     // check it is not SIMD:
                     let simdMatch = /    interface (\w*\dx\d{1,2}\w*)/.exec(match[0]);
-                    if (!simdMatch && match[2] !== 'earcut' && match[2] !== 'deviation' && match[2] !== 'flatten')
+                    if (!simdMatch && match[2] !== 'earcut' && match[2] !== 'deviation' && match[2] !== 'flatten') {
                         declarations[moduleName].push(match[2]);
+                        perFile[basename].declarations.push(match[2]);
+                    }
                 }
                 match = regexp.exec(fileContent);
             }
         } else {
-            let declared = [];
+            /*let declared = [];
             Object.keys(declarations).forEach(name => {
                 if (name === moduleName) return;
                 let imports = declarations[name].filter(obj => {
@@ -36,6 +47,29 @@ module.exports = function (moduleName, inject, declarations) {
                 if (imports.length)
                     importsString += `import {${imports.join(',')}} from 'babylonjs/${name}';
 `;
+            });*/
+
+            // find all of the related files for the dependency tree integration
+            let basenames = Object.keys(perFile).filter(basefilename => {
+                return perFile[basefilename].module.indexOf(moduleName) !== -1;
+            });
+
+            let classesForImports = {} // key : module name, content - array of objects
+            basenames.forEach(bname => {
+                dependencyTree[bname].forEach(dep => {
+                    if (dep.module.indexOf(moduleName) !== -1) return;
+                    let depModule = dep.module.indexOf("core") === -1 ? dep.module[0] : "core";
+                    classesForImports[depModule] = classesForImports[depModule] || [];
+                    if (classesForImports[depModule].indexOf(dep.name) === -1) {
+                        //babylon.imageProcessingPostProcess
+                        classesForImports[depModule].push(dep.name);
+                    }
+                });
+            });
+
+            Object.keys(classesForImports).forEach(modName => {
+                importsString += `import {${classesForImports[modName].join(',')}} from 'babylonjs/${modName}';
+`;
             });
         }
 

+ 139 - 36
Tools/Gulp/gulp-es6ModuleExports.js

@@ -1,34 +1,23 @@
 var gutil = require('gulp-util');
 var through = require('through2');
+var path = require('path');
 
-module.exports = function (moduleName, dependencies, es6) {
+module.exports = function (moduleName, dependencyTree, generateIndex, perFile, shaders, shaderIncludes) {
     return through.obj(function (file, enc, cb) {
 
-        console.log("Compiling es6 module: " + moduleName);
+        let basename = (path.basename(file.path, ".js"));
+
+        //console.log("Compiling es6 module: " + moduleName + "/" + basename.replace("babylon.", ""));
 
         var extendsAddition =
-            `var __extends = (this && this.__extends) || (function () {
-var extendStatics = Object.setPrototypeOf ||
-    ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
-    function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
-return function (d, b) {
-    extendStatics(d, b);
-    function __() { this.constructor = d; }
-    d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
-};
-})();
+            `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 (decorators, target, key, desc) {\n' +
-            'var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;\n' +
-            'if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);\n' +
-            'else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;\n' +
-            'return c > 3 && r && Object.defineProperty(target, key, r), r;\n' +
-            '};\n';
+            '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};\n';
 
         let content = file.contents.toString();
-        if (content.indexOf('__extends') === -1 && dependencies.length < 2) {
+        if (content.indexOf('__extends') === -1 && !dependencyTree.length) {
             extendsAddition = '';
         }
 
@@ -39,28 +28,135 @@ return function (d, b) {
         let dependenciesText = `${extendsAddition}
 ${decorateAddition}
 `;
-        if (dependencies) {
-            /*if (dependencies.length > 1) {
-                dependenciesText += 'function nse(ns1, ns2) { Object.keys(ns2).forEach(function(c) {if(!ns1[c]) {ns1[c] = ns2[c]}}) };\n';
-            }*/
+        //if (moduleName !== 'core') {
+        dependenciesText += `var globalObject = (typeof global !== 'undefined') ? global : ((typeof window !== 'undefined') ? window : this);
+            var BABYLON = globalObject["BABYLON"] || {};
+`;
+        /*} else {
+            dependenciesText += `var BABYLON;
+`;
+        }*/
 
-            dependencies.forEach(function (d, idx) {
-                let name = d === 'core' ? 'BABYLON' : d;
-                dependenciesText += `import * as ${name} from 'babylonjs/${d}/es6';
+        let exportsText = '';
+        if (!generateIndex) {
+
+            // process parenting!
+            let parentRegex = /__extends\(([A-Z]\w*), _super\)/g;
+            var match = parentRegex.exec(content);
+            while (match != null) {
+                let extendingClass = match[1];
+                // find the first row
+                let extendedMatcher = new RegExp("}\\([BABYLON\\.]*([A-Z]\\w*)\\)\\);\\n\\s*BABYLON." + extendingClass + " = " + extendingClass + ";");
+
+                let extendedArray = extendedMatcher.exec(content);
+                if (extendedArray) {
+                    let firstRowReg = new RegExp("var " + extendingClass + " = .* \\(function");
+                    content = content.replace(firstRowReg, "var " + extendingClass + " = function");
+
+                    extended = extendedArray[1];
+                    content = content.replace(extendedMatcher, `};
+    var CLS${extendingClass};
+    BABYLON.__${extendingClass} = function() {
+        CLS${extendingClass} = CLS${extendingClass} || ${extendingClass}.call(null, BABYLON.__${extended} && BABYLON.__${extended}() || BABYLON.${extended});
+    }
+    Object.defineProperty(BABYLON, "${extendingClass}", {
+        get: function () {
+            BABYLON.__${extendingClass}();
+            return CLS${extendingClass};
+        },
+        enumerable: true,
+        configurable: true
+    });`);
+                    console.log(extendingClass, extended);
+                } else {
+                    console.log(extendingClass + " is not exported");
+                }
+
+                match = parentRegex.exec(content);
+            }
+
+            let loadedFiles = [];
+            dependencyTree[basename].forEach(function (d, idx) {
+                //if (d.module.indexOf("core") !== -1) return;
+                let name = d.file.split(".").pop();
+
+                if (loadedFiles.indexOf(name) === -1/* && !d.newDec*/) {
+                    let regexp = new RegExp("BABYLON." + d.name);
+                    let match = regexp.exec(content);
+                    if (!match) return;
+                    if (d.main)
+                        dependenciesText += `import {${d.name}} from 'babylonjs/${d.module[0]}/es6/${name}';
 `;
-                if (idx > 0) {
-                    dependenciesText += `__extends(BABYLON, ${d});
+                    else
+                        exportsText += `import {${d.name}} from 'babylonjs/${d.module[0]}/es6/${name}';
 `;
+                    loadedFiles.push(name);
                 }
+                //dependenciesText += `if(BABYLON !== BABYLON${idx}) __extends(BABYLON, BABYLON${idx});
             });
+            let exported = [];
+            perFile[basename].declarations.forEach(dec => {
+                if (exported.indexOf(dec) !== -1) return;
+                exported.push(dec);
+                exportsText += `var ${dec} = BABYLON.${dec}; export {${dec}};
+`;
+            });
+            if (shaders) {
+                dependenciesText += `import * as Shaders from "babylonjs/${moduleName}/es6/shaders";
+if(BABYLON.Effect) Object.keys(Shaders).forEach(function(shaderName) {BABYLON.Effect.ShadersStore[shaderName] = Shaders[shaderName]})
+`;
+            }
+            if (shaderIncludes) {
+                dependenciesText += `import * as ShaderIncludes from "babylonjs/${moduleName}/es6/shaderIncludes";
+if(BABYLON.Effect) Object.keys(ShaderIncludes).forEach(function(shaderName) {BABYLON.Effect.IncludesShadersStore[shaderName] = ShaderIncludes[shaderName]})
+`;
+            }
+
+            //if (moduleName === "core") {
+            exportsText += `(function() {
+    //var globalObject = (typeof global !== 'undefined') ? global : ((typeof window !== 'undefined') ? window : this);
+    globalObject["BABYLON"] = globalObject["BABYLON"] || BABYLON;
+})();
+`;
+            //}
+        } else {
+            content = '';
+            let basenames = Object.keys(perFile).filter(basefilename => {
+                return perFile[basefilename].module.indexOf(moduleName) !== -1;
+            });
+
+            basenames.forEach(bname => {
+                let name = bname.split(".").pop();
+                dependenciesText += `export * from "babylonjs/${moduleName}/es6/${name}";
+`;
+            })
         }
 
 
 
-        let exportRegex = /BABYLON.([0-9A-Za-z-_]*) = .*;\n/g
+        /*exportsText += `(function() {
+    globalObject["BABYLON"] = globalObject["BABYLON"] || BABYLON;
+    })();
+`;*/
 
+        /*if (dependencies) {
+            dependencies.forEach(function (d, idx) {
+                if (d === 'core') return;
+                dependenciesText += `import * as ${d} from 'babylonjs/${d}/es6';
+`;
+                //if (idx > 0) {
+                dependenciesText += `__extends(BABYLON, ${d});
+`;
+                //}
+            });
+        }
+ 
+ 
+ 
+        let exportRegex = /BABYLON.([0-9A-Za-z-_]*) = .*;\n/g
+ 
         var match = exportRegex.exec(content);
-
+ 
         let exportsArray = [];
         while (match != null) {
             if (match[1]) {
@@ -68,16 +164,16 @@ ${decorateAddition}
             }
             match = exportRegex.exec(content);
         }
-
+ 
         let exportsText = '';
         if (moduleName === "core") {
             exportsText = `(function() {
     var globalObject = (typeof global !== 'undefined') ? global : ((typeof window !== 'undefined') ? window : this);
     globalObject["BABYLON"] = BABYLON;
-})();;
+})();
 `
         }
-
+ 
         let exportedItems = '';
         exportsArray.forEach((e, idx) => {
             if (e.indexOf('.') === -1) {
@@ -86,9 +182,16 @@ ${decorateAddition}
 `
             }
         });
-
+ 
         exportsText += `
-export { ${exportedItems} };`
+export { ${exportedItems} };`*/
+
+        /*if (moduleName === "core") {
+            exportsText = `(function() {
+var globalObject = (typeof global !== 'undefined') ? global : ((typeof window !== 'undefined') ? window : this);
+globalObject["BABYLON"] = BABYLON;
+})();
+`*/
 
         if (file.isNull()) {
             cb(null, file);
@@ -101,7 +204,7 @@ export { ${exportedItems} };`
         }
 
         try {
-            file.contents = new Buffer(dependenciesText.concat(new Buffer(String(file.contents).concat(exportsText))));
+            file.contents = new Buffer(dependenciesText.concat(new Buffer(String(content).concat(exportsText))));
             this.push(file);
         } catch (err) {
             this.emit('error', new gutil.PluginError('gulp-es6-module-exports', err, { fileName: file.path }));

+ 725 - 0
Tools/Gulp/gulp-validateTypedoc.js

@@ -0,0 +1,725 @@
+'use strict';
+
+var fs = require('fs');
+var Vinyl = require('vinyl');
+var path = require('path');
+var through = require('through2');
+var PluginError = require('plugin-error');
+var supportsColor = require('color-support');
+
+// ______________________________________________ LOGS ______________________________________________
+
+var hasColors = supportsColor();
+
+var red =       hasColors ? '\x1b[31m' : '';
+var yellow =    hasColors ? '\x1b[33m' : '';
+var green =     hasColors ? '\x1b[32m' : '';
+var gray =      hasColors ? '\x1b[90m' : '';
+var white =     hasColors ? '\x1b[97m' : '';
+var clear =     hasColors ? '\x1b[0m' : '';
+
+var currentColor = undefined;
+
+function getTimestamp() {
+    var time = new Date();
+    var timeInString = ("0" + time.getHours()).slice(-2) + ":" + 
+        ("0" + time.getMinutes()).slice(-2) + ":" + 
+        ("0" + time.getSeconds()).slice(-2);
+
+    if (currentColor) {
+        return white + '[' + currentColor + timeInString + clear + white + ']';
+    }
+    else {
+        return white + '[' + gray + timeInString + white + ']';
+    }
+}
+
+function log() {
+    currentColor = gray;
+    var time = getTimestamp();
+    process.stdout.write(time + ' ');
+    currentColor = undefined;
+
+    console.log.apply(console, arguments);
+    return this;
+}
+
+function warn() {
+    currentColor = yellow;
+    var time = getTimestamp();
+    process.stdout.write(time + ' ');
+    currentColor = undefined;
+
+    console.warn.apply(console, arguments);
+    return this;
+}
+
+function err() {
+    currentColor = red;
+    var time = getTimestamp();
+    process.stderr.write(time + ' ');
+    currentColor = undefined;
+    
+    console.error.apply(console, arguments);
+    return this;
+}
+
+function success() {
+    currentColor = green;
+    var time = getTimestamp();
+    process.stdout.write(time + ' ');
+    currentColor = undefined;
+
+    console.log.apply(console, arguments);
+    return this;
+}
+
+// ______________________________________________ VALIDATION ____________________________________________
+
+function unixStylePath(filePath) {
+    return filePath.replace(/\\/g, '/');
+}
+
+function Validate(validationBaselineFileName, namespaceName, validateNamingConvention, generateBaseLine) {
+    this.validationBaselineFileName = validationBaselineFileName;
+    this.namespaceName = namespaceName;
+    this.validateNamingConvention = validateNamingConvention;
+    this.generateBaseLine = generateBaseLine;
+
+    this.previousResults = { };
+    this.results = {
+        errors: 0
+    };
+}
+
+Validate.hasTag = function(node, tagName) {
+    tagName = tagName.trim().toLowerCase();
+
+    if (node.comment && node.comment.tags) {
+        for (var i = 0; i < node.comment.tags.length; i++) {
+            if (node.comment.tags[i].tag === tagName) {
+                return true;
+            }
+        }
+    }
+
+    return false;
+}
+
+Validate.position = function(node) {
+    if (!node.sources) {
+        log(node);
+    }
+    return node.sources[0].fileName + ':' + node.sources[0].line;
+}
+
+Validate.upperCase = new RegExp("^[A-Z_]*$");
+Validate.pascalCase = new RegExp("^[A-Z][a-zA-Z0-9_]*$");
+Validate.camelCase = new RegExp("^[a-z][a-zA-Z0-9_]*$");
+Validate.underscoreCamelCase = new RegExp("^_[a-z][a-zA-Z0-9_]*$");
+Validate.underscorePascalCase = new RegExp("^_[A-Z][a-zA-Z0-9_]*$");
+
+Validate.prototype.errorCallback = function (parent, node, nodeKind, category, type, msg, position) {
+    this.results[this.filePath] = this.results[this.filePath] || { errors: 0 };
+    var results = this.results[this.filePath];
+
+    if (node === "toString") {
+        node = "ToString";
+    }
+    
+    // Checks against previous results.
+    var previousResults = this.previousResults[this.filePath];
+    if (previousResults) {
+        var previousRootName = parent ? parent : node;
+        var needCheck = true; 
+
+        if (Array.isArray(previousRootName)) {
+            while (previousRootName.length > 1) {
+                var previousFirst = previousRootName.shift();
+                previousResults = previousResults[previousFirst];
+                if (!previousResults) {
+                    needCheck = false;
+                    break;
+                }
+            }
+            previousRootName = previousRootName.shift();
+        }
+
+        if (needCheck) {
+            var previousNode = previousResults[previousRootName];
+            if (previousNode) {
+                var previousNodeKind = previousNode[nodeKind];
+                if (previousNodeKind) {
+
+                    if (parent) {
+                        previousNode = previousNodeKind[node];
+                    }
+                    else {
+                        previousNode = previousNodeKind;
+                    }
+
+                    if (previousNode) {
+                        var previousCategory = previousNode[category];
+                        if (previousCategory) {
+                            var previousType = previousCategory[type];
+                            if (previousType) {
+                                // Early exit as it was already in the previous build.
+                                return;
+                            }    
+                        }
+                    }
+                }
+            }
+        }
+    }
+
+    // Write Error in output JSON.
+    var rootName = parent ? parent : node;
+    var current = results;
+    if (Array.isArray(rootName)) {
+        while (rootName.length > 1) {
+            var first = rootName.shift();
+            current = current[first] = current[first] || { };
+        }
+        rootName = rootName.shift();
+    }
+
+    current = current[rootName] = current[rootName] || { };
+    current = current[nodeKind] = current[nodeKind] || { };    
+    if (parent) {
+        current = current[node] = current[node] || { };
+    }
+    current = current[category] = current[category] || { };
+    current = current[type] = true;
+    
+    results.errors++;
+
+    if (!this.generateBaseLine) {
+        err(msg, position);
+    }
+}
+
+Validate.prototype.init = function (cb) {
+    var self = this;
+    if (!this.generateBaseLine && fs.existsSync(this.validationBaselineFileName)) {
+        fs.readFile(this.validationBaselineFileName, "utf-8", function (err, data) {
+            self.previousResults = JSON.parse(data);
+            cb();
+        });
+    }
+    else {
+        cb();
+    }
+}
+
+Validate.prototype.add = function (filePath, content) {
+    this.filePath = filePath && unixStylePath(filePath);
+
+    if (!Buffer.isBuffer(content)) {
+        content = new Buffer(content);
+    }
+
+    var contentString = content.toString();
+    var json = JSON.parse(contentString);
+
+    this.validateTypedoc(json);
+    this.results.errors += this.results[this.filePath].errors;
+}
+
+Validate.prototype.getResults = function () {
+    return this.results;
+}
+
+Validate.prototype.getContents = function () {
+    return Buffer.from(JSON.stringify(this.results));
+}
+
+/**
+ * Validate a TypeDoc JSON file
+ */
+Validate.prototype.validateTypedoc = function (json) {
+    for (var i = 0; i < json.children.length; i++) {
+        var namespaces = json.children[i].children;
+        this.validateTypedocNamespaces(namespaces);
+    }
+}
+/**
+ * Validate namespaces attach to a declaration file from a TypeDoc JSON file
+ */
+Validate.prototype.validateTypedocNamespaces = function (namespaces) {
+    var namespace = null;
+
+    var containerNode;
+    var childNode;
+    var children;
+    var signatures;
+    var signatureNode;
+    var tags;
+    var isPublic;
+
+    // Check for BABYLON namespace
+    for (var child in namespaces) {
+        if (namespaces[child].name === this.namespaceName) {
+            namespace = namespaces[child];
+            break;
+        }
+    }
+
+    // Exit if not BABYLON related.
+    if (!namespace || !namespace.children) {
+        return;
+    }
+
+    // Validate Classes
+    for (var a in namespace.children) {
+        containerNode = namespace.children[a];
+
+        // If comment contains @ignore then skip validation completely
+        if (Validate.hasTag(containerNode, 'ignore')) continue;
+
+        // Account for undefined access modifiers.
+        if (!containerNode.flags.isPublic &&
+            !containerNode.flags.isPrivate &&
+            !containerNode.flags.isProtected) {
+                containerNode.flags.isPublic = true;
+        }
+        isPublic = containerNode.flags.isPublic;
+
+        // Validate naming.
+        this.validateNaming(null, containerNode);
+
+        // Validate Comments.
+        if (isPublic && !this.validateComment(containerNode)) {            
+            this.errorCallback(null,
+                containerNode.name,
+                containerNode.kindString,
+                "Comments",
+                "MissingText",
+                "Missing text for " + containerNode.kindString + " : " + containerNode.name + " (id: " + containerNode.id + ")", Validate.position(containerNode));
+        }
+
+        //if comment contains tag @ignoreChildren, then don't validate children
+        var validateChildren = !Validate.hasTag(containerNode, 'ignoreChildren');
+        children = containerNode.children;
+
+        //Validate Properties
+        if (validateChildren && children) {
+            for (var b in children) {
+                childNode = children[b];
+
+                // Account for undefined access modifiers.
+                if (!childNode.flags.isPublic &&
+                    !childNode.flags.isPrivate &&
+                    !childNode.flags.isProtected) {
+                    childNode.flags.isPublic = true;
+                }
+                isPublic = childNode.flags.isPublic;
+
+                // Validate Naming.
+                this.validateNaming(containerNode, childNode);
+
+                //if comment contains @ignore then skip validation completely
+                if (Validate.hasTag(childNode, 'ignore')) continue;                
+
+                if (isPublic) {
+                    tags = this.validateTags(childNode);
+                    if (tags) {
+                        this.errorCallback(containerNode.name,
+                            childNode.name,
+                            childNode.kindString,
+                            "Tags",
+                            tags,
+                            "Unrecognized tag " + tags + " at " + childNode.name + " (id: " + childNode.id + ") in " + containerNode.name + " (id: " + containerNode.id + ")", Validate.position(childNode));
+                    }
+                }
+
+                if (!this.validateComment(childNode)) {
+                    //Validate Signatures
+                    signatures = childNode.signatures;
+                    if (signatures) {
+                        for (var c in signatures) {
+                            signatureNode = signatures[c];
+
+                            //if node contains @ignore then skip validation completely
+                            if (Validate.hasTag(signatureNode, 'ignore')) continue;
+
+                            if (isPublic) {
+                                if (!this.validateComment(signatureNode)) {
+                                    this.errorCallback(containerNode.name,
+                                        signatureNode.name,
+                                        childNode.kindString,
+                                        "Comments",
+                                        "MissingText",
+                                        "Missing text for " + childNode.kindString + " : " + signatureNode.name + " (id: " + signatureNode.id + ") in " + containerNode.name + " (id: " + containerNode.id + ")", Validate.position(childNode));
+                                }
+
+                                tags = this.validateTags(signatureNode);
+                                if (tags) {
+                                    this.errorCallback(containerNode.name,
+                                        signatureNode.name,
+                                        childNode.kindString,
+                                        "Tags",
+                                        tags,
+                                        "Unrecognized tag " + tags + " at " + signatureNode.name + " (id: " + signatureNode.id + ") in " + containerNode.name + " (id: " + containerNode.id + ")", Validate.position(childNode));
+                                }
+
+                                if (signatureNode.type.name !== "void" && signatureNode.comment && !signatureNode.comment.returns) {
+                                    this.errorCallback(containerNode.name,
+                                        signatureNode.name,
+                                        childNode.kindString,
+                                        "Comments",
+                                        "MissingReturn",
+                                        "No Return Comment at " + signatureNode.name + " (id: " + signatureNode.id + ") in " + containerNode.name + " (id: " + containerNode.id + ")", Validate.position(childNode));
+                                }
+
+                                if (signatureNode.type.name === "void" && signatureNode.comment && signatureNode.comment.returns) {
+                                    this.errorCallback(containerNode.name,
+                                        signatureNode.name,
+                                        childNode.kindString,
+                                        "Comments",
+                                        "UselessReturn",
+                                        "No Return Comment Needed at " + signatureNode.name + " (id: " + signatureNode.id + ") in " + containerNode.name + " (id: " + containerNode.id + ")", Validate.position(childNode));
+                                }
+                            }
+
+                            this.validateParameters(containerNode, childNode, signatureNode, signatureNode.parameters, isPublic);
+                        }
+                    } else {
+                        this.errorCallback(containerNode.name,
+                            childNode.name,
+                            childNode.kindString,
+                            "Comments",
+                            "MissingText",
+                            "Missing text for " + childNode.kindString + " : " + childNode.name + " (id: " + childNode.id + ") in " + containerNode.name + " (id: " + containerNode.id + ")", Validate.position(childNode));
+                    }
+                }
+
+                // this.validateParameters(containerNode, childNode, childNode.parameters, isPublic);
+            }
+        }
+    }
+}
+
+/**
+ * Validate that tags are recognized
+ */
+Validate.prototype.validateTags = function(node) {
+    var tags;
+    var errorTags = [];
+
+    if (node.comment) {
+
+        tags = node.comment.tags;
+        if (tags) {
+            for (var i = 0; i < tags.length; i++) {
+                var tag = tags[i];
+                var validTags = ["constructor", "throw", "type", "deprecated", "example", "examples", "remark", "see", "remarks"]
+                if (validTags.indexOf(tag.tag) === -1) {
+                    errorTags.push(tag.tag);
+                }
+            }
+        }
+
+    }
+
+    return errorTags.join(",");
+}
+
+/**
+ * Validate that a JSON node has the correct TypeDoc comments
+ */
+Validate.prototype.validateComment = function(node) {
+
+    // Return-only methods are allowed to just have a @return tag
+    if ((node.kindString === "Call signature" || node.kindString === "Accessor") && !node.parameters && node.comment && node.comment.returns) {
+        return true;
+    }
+
+    // Return true for private properties (dont validate)
+    if ((node.kindString === "Property" || node.kindString === "Object literal") && (node.flags.isPrivate || node.flags.isProtected)) {
+        return true;
+    }
+
+    // Return true for inherited properties
+    if (node.inheritedFrom) {
+        return true;
+    }
+
+    // Return true for overwrited properties
+    if (node.overwrites) {
+        return true;
+    }
+    
+
+    if (node.comment) {
+
+        if (node.comment.text || node.comment.shortText) {
+            return true;
+        }
+
+        return false;
+    }
+
+    return false;
+}
+
+/**
+ * Validate comments for paramters on a node
+ */
+Validate.prototype.validateParameters = function(containerNode, method, signature, parameters, isPublic) {
+    var parametersNode;
+    for (var parameter in parameters) {
+        parametersNode = parameters[parameter];
+
+        if (isPublic && !this.validateComment(parametersNode)) {
+            // throw containerNode.name + " " + method.kindString + " " + method.name + " " + parametersNode.name + " " + parametersNode.kindString;
+            this.errorCallback([containerNode.name, method.kindString, signature.name],
+                parametersNode.name,
+                parametersNode.kindString,
+                "Comments",
+                "MissingText",
+                "Missing text for parameter " + parametersNode.name + " (id: " + parametersNode.id + ") of " + method.name + " (id: " + method.id + ")", Validate.position(method));
+        }
+
+        if (this.validateNamingConvention && !Validate.camelCase.test(parametersNode.name)) {
+            this.errorCallback([containerNode.name, method.kindString, signature.name],
+                parametersNode.name,
+                parametersNode.kindString,
+                "Naming",
+                "NotCamelCase",
+                "Parameter " + parametersNode.name + " should be Camel Case (id: " + method.id + ")", Validate.position(method));
+        }
+    }
+}
+
+/**
+ * Validate naming conventions of a node
+ */
+Validate.prototype.validateNaming = function(parent, node) {
+    if (!this.validateNamingConvention) {
+        return;
+    }
+
+    if (node.inheritedFrom) {
+        return;
+    }
+
+    // Internals are not subject to the public visibility policy.
+    if (node.name && node.name.length > 0 && node.name[0] === "_") {
+        return;
+    }
+
+    if ((node.flags.isPrivate || node.flags.isProtected) && node.flags.isStatic) {
+        if (!Validate.underscorePascalCase.test(node.name)) {
+            this.errorCallback(parent ? parent.name : null,
+                node.name,
+                node.kindString,
+                "Naming",
+                "NotUnderscorePascalCase",
+                node.name + " should be Underscore Pascal Case (id: " + node.id + ")", Validate.position(node));
+        }
+    }
+    else if (node.flags.isPrivate || node.flags.isProtected) {
+        if (!Validate.underscoreCamelCase.test(node.name)) {
+            this.errorCallback(parent ? parent.name : null,
+                node.name,
+                node.kindString,
+                "Naming",
+                "NotUnderscoreCamelCase",
+                node.name + " should be Underscore Camel Case (id: " + node.id + ")", Validate.position(node));
+        }
+    }
+    else if (node.flags.isStatic) {
+        if (!Validate.pascalCase.test(node.name)) {
+            this.errorCallback(parent ? parent.name : null,
+                node.name,
+                node.kindString,
+                "Naming",
+                "NotPascalCase",
+                node.name + " should be Pascal Case (id: " + node.id + ")", Validate.position(node));
+        }
+    }
+    else if (node.kindString == "Module") {
+        if (!Validate.upperCase.test(node.name)) {
+            this.errorCallback(parent ? parent.name : null,
+                node.name,
+                node.kindString,
+                "Naming",
+                "NotUpperCase",
+                "Module is not Upper Case " + node.name + " (id: " + node.id + ")", Validate.position(node));
+        }
+    }
+    else if (node.kindString == "Interface" ||
+        node.kindString == "Class" ||
+        node.kindString == "Enumeration" ||
+        node.kindString == "Enumeration member" ||
+        node.kindString == "Accessor" ||
+        node.kindString == "Type alias") {
+        if (!Validate.pascalCase.test(node.name)) {
+            this.errorCallback(parent ? parent.name : null,
+                node.name,
+                node.kindString,
+                "Naming",
+                "NotPascalCase",
+                node.name + " should be Pascal Case (id: " + node.id + ")", Validate.position(node));
+        }
+    }
+    else if (node.kindString == "Method" ||
+        node.kindString == "Property" ||
+        node.kindString == "Object literal") {
+
+        // Only warn here as special properties such as FOV may be better capitalized 
+        if (!Validate.camelCase.test(node.name)) {
+            this.errorCallback(parent ? parent.name : null,
+                node.name,
+                node.kindString,
+                "Naming",
+                "NotCamelCase",
+                node.name + " should be Camel Case (id: " + node.id + ")", Validate.position(node));
+        }
+    }
+    else if (node.kindString == "Variable") {
+        this.errorCallback(parent ? parent.name : null,
+            node.name,
+            node.kindString,
+            "Naming",
+            "ShouldNotBeLooseVariable",
+            node.name + " should not be a variable (id: " + node.id + ")", Validate.position(node));
+    }
+    else if (node.kindString === "Function") {
+        if (!Validate.camelCase.test(node.name)) {
+            this.errorCallback(parent ? parent.name : null,
+                node.name,
+                node.kindString,
+                "Naming",
+                "NotCamelCase",
+                node.name + " should be Camel Case (id: " + node.id + ")", Validate.position(node));
+        }
+    }
+    else if (node.kindString == "Constructor") {
+        // Do Nothing Here, this is handled through the class name.
+    }
+    else {
+        this.errorCallback(parent ? parent.name : null,
+            node.name,
+            node.kindString,
+            "Naming",
+            "UnknownNamingConvention",
+            "Unknown naming convention for " + node.kindString + " at " + node.name + " (id: " + node.id + ")", Validate.position(node));
+    }
+}
+
+// ______________________________________________ PLUGIN ____________________________________________
+
+// consts
+const PLUGIN_NAME = 'gulp-validateTypedoc';
+
+// plugin level function (dealing with files)
+function gulpValidateTypedoc(validationBaselineFileName, namespaceName, validateNamingConvention, generateBaseLine) {
+
+    if (!validationBaselineFileName) {
+        throw new PluginError(PLUGIN_NAME, 'Missing validation filename!');
+    }
+    if (typeof validationBaselineFileName !== "string") {
+        throw new PluginError(PLUGIN_NAME, 'Validation filename must be a string!');
+    }
+
+    var validate;
+    var latestFile;
+
+    function bufferContents(file, enc, cb) {
+        // ignore empty files
+        if (file.isNull()) {
+            cb();
+            return;
+        }
+
+        // we don't do streams (yet)
+        if (file.isStream()) {
+            this.emit('error', new Error('gulp-validatTypedoc: Streaming not supported'));
+            cb();
+            return;
+        }
+
+        // set latest file if not already set,
+        // or if the current file was modified more recently.
+        latestFile = file;
+
+        // What will happen once all set.
+        var done = function () {
+            // add file to concat instance
+            validate.add(file.relative, file.contents);
+
+            cb();
+        }
+
+        // Do the validation.
+        if (!validate) {
+            validate = new Validate(validationBaselineFileName, namespaceName, validateNamingConvention, generateBaseLine);
+            validate.init(done);
+        }
+        else {
+            done();
+        }
+    }
+
+    function endStream(cb) {
+        // no files passed in, no file goes out
+        if (!latestFile) {
+            var error = new PluginError(PLUGIN_NAME, 'gulp-validatTypedoc: No Baseline found.');
+            this.emit('error', error);
+            cb();
+            return;
+        }
+
+        var results = validate.getResults();
+        var buffer = Buffer.from(JSON.stringify(results, null, 2))
+
+        if (generateBaseLine) {
+            fs.writeFileSync(validationBaselineFileName, buffer || '');
+        }
+
+        var jsFile = new Vinyl({
+            cwd: process.cwd,
+            base: null,
+            path: validationBaselineFileName,
+            contents: buffer
+        });
+
+        this.push(jsFile);
+
+        var action = generateBaseLine ? "baseline generation" : "validation";
+        var self = this;
+        var error = function(message) {
+            generateBaseLine ? warn : err;
+            if (generateBaseLine) {
+                warn(message);
+            }
+            else {
+                err(message);
+                var error = new PluginError(PLUGIN_NAME, message);
+                self.emit('error', error);
+            }
+        }
+
+        if (results.errors > 1) {
+            var message = results.errors + " errors have been detected during the " + action + " !";
+            error(message);
+        }
+        else if (results.errors === 1) {
+            var message = "1 error has been detected during the " + action + " !";
+            error(message);
+        }
+        else {
+            var message = "All formatting check passed successfully during the " + action + " !";
+            success(message);
+        }
+
+        cb();
+    }
+
+    return through.obj(bufferContents, endStream);
+};
+
+// exporting the plugin main function
+module.exports = gulpValidateTypedoc;

+ 337 - 70
Tools/Gulp/gulpfile.js

@@ -6,9 +6,11 @@ var srcToVariable = require("gulp-content-to-variable");
 var appendSrcToVariable = require("./gulp-appendSrcToVariable");
 var addDtsExport = require("./gulp-addDtsExport");
 var addModuleExports = require("./gulp-addModuleExports");
+var addES6Exports = require("./gulp-addES6Exports");
 var babylonModuleExports = require("./gulp-babylonModule");
 var babylonES6ModuleExports = require("./gulp-es6ModuleExports");
 var dtsModuleSupport = require("./gulp-dtsModuleSupport");
+let calculateDependencies = require("./gulp-calculateDependencies");
 var merge2 = require("merge2");
 var concat = require("gulp-concat");
 var rename = require("gulp-rename");
@@ -23,13 +25,16 @@ var webserver = require("gulp-webserver");
 var path = require("path");
 var sass = require("gulp-sass");
 var webpack = require("webpack-stream");
+var typedoc = require("gulp-typedoc");
+var validateTypedoc = require("./gulp-validateTypedoc");
+var request = require('request');
+var fs = require("fs");
+var karmaServer = require('karma').Server;
 
 var config = require("./config.json");
 
 var del = require("del");
 
-var karmaServer = require('karma').Server;
-
 var debug = require("gulp-debug");
 var includeShadersStream;
 var shadersStream;
@@ -79,8 +84,8 @@ var commandLineOptions = minimist(process.argv.slice(2), {
     boolean: "public"
 });
 
-function processDependency(kind, dependency, filesToLoad) {
-    if (dependency.dependUpon) {
+function processDependency(kind, dependency, filesToLoad, firstLevelOnly) {
+    if (!firstLevelOnly && dependency.dependUpon) {
         for (var i = 0; i < dependency.dependUpon.length; i++) {
             var dependencyName = dependency.dependUpon[i];
             var parent = config.workloads[dependencyName];
@@ -209,23 +214,33 @@ gulp.task("buildWorker", ["workers", "shaders"], function () {
 gulp.task("build", ["shaders"], function () {
     var filesToProcess = determineFilesToProcess("files");
     var directFilesToProcess = determineFilesToProcess("directFiles");
-    return merge2(
+    let mergedStreams = merge2(
         gulp.src(filesToProcess).
             pipe(expect.real({ errorOnFailure: true }, filesToProcess)),
         shadersStream,
         includeShadersStream,
         gulp.src(directFilesToProcess)
     )
-        .pipe(concat(config.build.filename))
-        .pipe(cleants())
-        .pipe(replace(extendsSearchRegex, ""))
-        .pipe(replace(decorateSearchRegex, ""))
-        .pipe(addModuleExports("BABYLON"))
-        .pipe(gulp.dest(config.build.outputDirectory))
-        .pipe(rename(config.build.minFilename))
-        .pipe(uglify())
-        .pipe(optimisejs())
-        .pipe(gulp.dest(config.build.outputDirectory));
+    return merge2(
+        mergedStreams
+            .pipe(concat(config.build.filename))
+            .pipe(cleants())
+            .pipe(replace(extendsSearchRegex, ""))
+            .pipe(replace(decorateSearchRegex, ""))
+            .pipe(addModuleExports("BABYLON"))
+            .pipe(gulp.dest(config.build.outputDirectory))
+            .pipe(rename(config.build.minFilename))
+            .pipe(uglify())
+            .pipe(optimisejs())
+            .pipe(gulp.dest(config.build.outputDirectory)),
+        mergedStreams
+            .pipe(concat("es6.js"))
+            .pipe(cleants())
+            .pipe(replace(extendsSearchRegex, ""))
+            .pipe(replace(decorateSearchRegex, ""))
+            .pipe(addES6Exports("BABYLON"))
+            .pipe(gulp.dest(config.build.outputDirectory))
+    );
 });
 
 /*
@@ -238,14 +253,11 @@ gulp.task("typescript-compile", function () {
 
     //If this gulp task is running on travis, file the build!
     if (process.env.TRAVIS) {
-        var error = false;
-        tsResult.on("error", function () {
-            error = true;
-        }).on("end", function () {
-            if (error) {
+        tsResult.once("error", function () {
+            tsResult.once("finish", function () {
                 console.log("Typescript compile failed");
                 process.exit(1);
-            }
+            });
         });
     }
 
@@ -423,8 +435,7 @@ var buildExternalLibrary = function (library, settings, watch) {
  * The default task, concat and min the main BJS files.
  */
 gulp.task("default", function (cb) {
-    // runSequence("typescript-all", "intellisense", "tests-browserStack", cb);
-    runSequence("typescript-all", "intellisense", cb);
+    runSequence("typescript-all", "intellisense", "typedoc-all", "tests-unit", "tests-validation-virtualscreen", "tests-validation-browserstack", cb);
 });
 
 gulp.task("mainBuild", function (cb) {
@@ -563,32 +574,9 @@ gulp.task("webserver", function () {
 gulp.task("run", ["watch", "webserver"], function () {
 });
 
-
-gulp.task("tests-integration", function (done) {
-    var kamaServerOptions = {
-        configFile: __dirname + "/../../tests/validation/karma.conf.js",
-        singleRun: false
-    };
-
-    var server = new karmaServer(kamaServerOptions, done);
-    server.start();
-});
-
-gulp.task("tests-browserStack", function (done) {
-    if (!process.env.TRAVIS) {
-        done();
-        return;
-    }
-
-    var kamaServerOptions = {
-        configFile: __dirname + "/../../tests/validation/karma.conf.browserstack.js",
-        singleRun: true
-    };
-
-    var server = new karmaServer(kamaServerOptions, done);
-    server.start();
-});
-
+/**
+ * Cleans map and js files from the src folder.
+ */
 gulp.task("clean-JS-MAP", function () {
     return del([
         "../../src/**/*.js.map", "../../src/**/*.js"
@@ -603,14 +591,11 @@ gulp.task("modules-compile", function () {
 
     // If this gulp task is running on travis
     if (process.env.TRAVIS) {
-        var error = false;
-        tsResult.on("error", function () {
-            error = true;
-        }).on("end", function () {
-            if (error) {
+        tsResult.once("error", function () {
+            tsResult.once("finish", function () {
                 console.log("Typescript compile failed");
                 process.exit(1);
-            }
+            });
         });
     }
 
@@ -631,48 +616,128 @@ gulp.task("modules-compile", function () {
 
 // this holds the declared objects in each module
 let declared = {}
+let perFile = {};
+let dependencyTree = {};
 
-gulp.task('prepare-for-modules', ["modules-compile"], function () {
+gulp.task('prepare-for-modules', /*["modules-compile"],*/ function () {
     let tasks = [];
     Object.keys(config.workloads).forEach((moduleName) => {
         let dtsFiles = config.workloads[moduleName].files.map(f => f.replace(".js", ".d.ts"))
         let dtsTask = gulp.src(dtsFiles)
-            .pipe(dtsModuleSupport(moduleName, false, declared));
+            .pipe(dtsModuleSupport(moduleName, false, declared, perFile));
 
         tasks.push(dtsTask);
     });
 
+    // now calculate internal dependencies in the .ts files!
+    /*Object.keys(config.workloads).forEach((moduleName) => {
+        let tsFiles = config.workloads[moduleName].files.map(f => f.replace(".js", ".ts"))
+        let depTask = gulp.src(tsFiles)
+            .pipe(calculateDependencies(moduleName, perFile, dependencyTree));
+
+        tasks.push(depTask);
+    });*/
+
+    return merge2(tasks);
+});
+
+gulp.task('prepare-dependency-tree', ["prepare-for-modules"], function () {
+    let tasks = [];
+
+    // now calculate internal dependencies in the .ts files!
+    Object.keys(config.workloads).forEach((moduleName) => {
+        let tsFiles = config.workloads[moduleName].files.map(f => f.replace(".js", ".ts"))
+        let depTask = gulp.src(tsFiles)
+            .pipe(calculateDependencies(moduleName, perFile, declared, dependencyTree));
+
+        tasks.push(depTask);
+    });
+
     return merge2(tasks);
 });
 
 // generate the modules directory, along with commonjs modules and es6 modules
 // Note - the generated modules are UNMINIFIED! The user will choose whether they want to minify or not.
-gulp.task("modules", ["prepare-for-modules"], function () {
+gulp.task("modules", ["prepare-dependency-tree"], function () {
     let tasks = [];
 
     Object.keys(config.workloads)
         .forEach((moduleName) => {
             let shadersFiles = [];
-            processDependency("shaders", config.workloads[moduleName], shadersFiles);
+            processDependency("shaders", config.workloads[moduleName], shadersFiles, true);
             for (var index = 0; index < shadersFiles.length; index++) {
                 shadersFiles[index] = "../../src/Shaders/" + shadersFiles[index] + ".fx";
             }
 
             let shaderIncludeFiles = [];
-            processDependency("shaderIncludes", config.workloads[moduleName], shaderIncludeFiles);
+            processDependency("shaderIncludes", config.workloads[moduleName], shaderIncludeFiles, true);
             for (var index = 0; index < shaderIncludeFiles.length; index++) {
                 shaderIncludeFiles[index] = "../../src/Shaders/ShadersInclude/" + shaderIncludeFiles[index] + ".fx";
             }
 
+            let commonJsTask = merge2([
+                gulp.src(config.workloads[moduleName].files)
+                    .pipe(replace(extendsSearchRegex, ""))
+                    .pipe(replace(decorateSearchRegex, ""))
+                    .pipe(replace(referenceSearchRegex, ""))
+                    .pipe(replace(/var BABYLON;\n/g, ""))
+                    .pipe(babylonModuleExports(moduleName, dependencyTree, false, perFile, shadersFiles.length, shaderIncludeFiles.length))
+                    .pipe(rename(function (path) {
+                        path.basename = path.basename.split(".").pop()
+                        path.extname = ".js"
+                    })),
+                gulp.src(shadersFiles)
+                    .pipe(expect.real({ errorOnFailure: true }, shadersFiles))
+                    .pipe(uncommentShader())
+                    .pipe(appendSrcToVariable("BABYLON.Effect.ShadersStore", shadersName, config.build.outputDirectory + '/commonjs/' + moduleName + ".fx", "commonjs"))
+                    .pipe(rename("shaders.js")),
+                gulp.src(shaderIncludeFiles)
+                    .pipe(expect.real({ errorOnFailure: true }, shaderIncludeFiles))
+                    .pipe(uncommentShader())
+                    .pipe(appendSrcToVariable("BABYLON.Effect.IncludesShadersStore", includeShadersName, config.build.outputDirectory + '/commonjs/' + moduleName + ".include.fx", "commonjs"))
+                    .pipe(rename("shaderIncludes.js")),
+                gulp.src(config.workloads[moduleName].files)
+                    .pipe(concat('index.js'))
+                    .pipe(babylonModuleExports(moduleName, dependencyTree, true, perFile))
+
+            ]).pipe(gulp.dest(config.build.outputDirectory + '/modules/' + moduleName + '/'))
+
+            let es6Tasks = merge2([
+                gulp.src(config.workloads[moduleName].files)
+                    .pipe(replace(extendsSearchRegex, ""))
+                    .pipe(replace(decorateSearchRegex, ""))
+                    .pipe(replace(referenceSearchRegex, ""))
+                    .pipe(replace(/var BABYLON;\n/g, ""))
+                    .pipe(babylonES6ModuleExports(moduleName, dependencyTree, false, perFile, shadersFiles.length, shaderIncludeFiles.length))
+                    .pipe(rename(function (path) {
+                        path.basename = path.basename.split(".").pop()
+                        path.extname = ".js"
+                    })),
+                gulp.src(shadersFiles)
+                    .pipe(expect.real({ errorOnFailure: true }, shadersFiles))
+                    .pipe(uncommentShader())
+                    .pipe(appendSrcToVariable("BABYLON.Effect.ShadersStore", shadersName, config.build.outputDirectory + '/es6/' + moduleName + ".fx", "es6"))
+                    .pipe(rename("shaders.js")),
+                gulp.src(shaderIncludeFiles)
+                    .pipe(expect.real({ errorOnFailure: true }, shaderIncludeFiles))
+                    .pipe(uncommentShader())
+                    .pipe(appendSrcToVariable("BABYLON.Effect.IncludesShadersStore", includeShadersName, config.build.outputDirectory + '/es6/' + moduleName + ".include.fx", "es6"))
+                    .pipe(rename("shaderIncludes.js")),
+                gulp.src(config.workloads[moduleName].files)
+                    .pipe(concat('index.js'))
+                    .pipe(babylonES6ModuleExports(moduleName, dependencyTree, true, perFile))
+
+            ]).pipe(gulp.dest(config.build.outputDirectory + '/modules/' + moduleName + '/es6/'))
+
             //commonjs js generation task
-            let jsTask = merge2([
+            /*let jsTask = merge2([
                 gulp.src(config.workloads[moduleName].files),
                 gulp.src(shadersFiles).
-                    pipe(expect.real({ errorOnFailure: true }, shadersFiles)).
+                    //pipe(expect.real({ errorOnFailure: true }, shadersFiles)).
                     pipe(uncommentShader()).
                     pipe(appendSrcToVariable("BABYLON.Effect.ShadersStore", shadersName, config.build.outputDirectory + '/commonjs/' + moduleName + ".fx", true)),
                 gulp.src(shaderIncludeFiles).
-                    pipe(expect.real({ errorOnFailure: true }, shaderIncludeFiles)).
+                    //pipe(expect.real({ errorOnFailure: true }, shaderIncludeFiles)).
                     pipe(uncommentShader()).
                     pipe(appendSrcToVariable("BABYLON.Effect.IncludesShadersStore", includeShadersName, config.build.outputDirectory + '/commonjs/' + moduleName + ".include.fx", true))
             ]).pipe(concat('index.js'))
@@ -680,23 +745,25 @@ gulp.task("modules", ["prepare-for-modules"], function () {
                 .pipe(replace(decorateSearchRegex, ""))
                 .pipe(replace(referenceSearchRegex, ""))
                 .pipe(babylonModuleExports(moduleName, config.workloads[moduleName].dependUpon))
-                .pipe(gulp.dest(config.build.outputDirectory + '/modules/' + moduleName + '/'));
+                .pipe(gulp.dest(config.build.outputDirectory + '/modules/' + moduleName + '/'));*/
+
 
             // es6 modules generation task
-            let es6Task = merge2([
+            /*let es6Task = merge2([
                 gulp.src(config.workloads[moduleName].files),
                 gulp.src(shadersFiles).
-                    pipe(expect.real({ errorOnFailure: true }, shadersFiles)).
+                    //pipe(expect.real({ errorOnFailure: true }, shadersFiles)).
                     pipe(uncommentShader()).
                     pipe(appendSrcToVariable("BABYLON.Effect.ShadersStore", shadersName, config.build.outputDirectory + '/commonjs/' + moduleName + ".fx", true)),
                 gulp.src(shaderIncludeFiles).
-                    pipe(expect.real({ errorOnFailure: true }, shaderIncludeFiles)).
+                    //pipe(expect.real({ errorOnFailure: true }, shaderIncludeFiles)).
                     pipe(uncommentShader()).
                     pipe(appendSrcToVariable("BABYLON.Effect.IncludesShadersStore", includeShadersName, config.build.outputDirectory + '/commonjs/' + moduleName + ".include.fx", true))
             ]).pipe(concat('es6.js'))
                 .pipe(replace(extendsSearchRegex, ""))
                 .pipe(replace(decorateSearchRegex, ""))
                 .pipe(replace(referenceSearchRegex, ""))
+                .pipe(replace(/var BABYLON;/g, ""))
                 .pipe(babylonES6ModuleExports(moduleName, config.workloads[moduleName].dependUpon))
                 .pipe(gulp.dest(config.build.outputDirectory + '/modules/' + moduleName + '/'));
 
@@ -706,12 +773,212 @@ gulp.task("modules", ["prepare-for-modules"], function () {
                 .pipe(concat("index.d.ts"))
                 .pipe(replace(/declare module BABYLON {/g, `declare module 'babylonjs/${moduleName}' {`))
                 .pipe(replace(/\ninterface /g, `\nexport interface `))
-                .pipe(dtsModuleSupport(moduleName, true, declared))
+                .pipe(dtsModuleSupport(moduleName, true, declared, perFile, dependencyTree))
                 .pipe(gulp.dest(config.build.outputDirectory + '/modules/' + moduleName + '/'));
-
-            tasks.push(jsTask, es6Task, dtsTask);
+*/
+            tasks.push(commonJsTask, es6Tasks);
         });
 
     // run da tasks man!
     return merge2(tasks);
 })
+
+/**
+ * Generate the TypeDoc JSON output in order to create code metadata.
+ */
+gulp.task("typedoc-generate", function () {
+    return gulp
+        .src(["../../dist/preview release/babylon.d.ts"])
+        .pipe(typedoc({
+            // TypeScript options (see typescript docs)
+            mode: "modules",
+            module: "commonjs",
+            target: "es5",
+            includeDeclarations: true,
+
+            // Output options (see typedoc docs)
+            json: config.build.typedocJSON,
+
+            // TypeDoc options (see typedoc docs)
+            ignoreCompilerErrors: true,
+
+            readme: "none",
+
+            excludeExternals: true,
+            excludePrivate: true,
+            excludeProtected: true,
+
+            entryPoint: ["\"babylon.d\"", "BABYLON"]
+        }));
+});
+
+/**
+ * Validate the TypeDoc JSON output against the current baselin to ensure our code is correctly documented.
+ * (in the newly introduced areas)
+ */
+gulp.task("typedoc-validate", function () {
+    return gulp.src(config.build.typedocJSON)
+        .pipe(validateTypedoc(config.build.typedocValidationBaseline, "BABYLON", true, false));
+});
+
+/**
+ * Generate the validation reference to ensure our code is correctly documented.
+ */
+gulp.task("typedoc-generateValidationBaseline", function () {
+    return gulp.src(config.build.typedocJSON)
+        .pipe(validateTypedoc(config.build.typedocValidationBaseline, "BABYLON", true, true));
+});
+
+/**
+ * Validate the code comments and style case convention through typedoc and
+ * generate the new baseline.
+ */
+gulp.task("typedoc-all", function (cb) {
+    runSequence("typedoc-generate", "typedoc-validate", "typedoc-generateValidationBaseline", cb);
+});
+
+
+/**
+ * Validate compile the code and check the comments and style case convention through typedoc
+ */
+gulp.task("typedoc-check", function (cb) {
+    runSequence("typescript-compile", "typedoc-generate", "typedoc-validate", cb);
+});
+
+/**
+ * Launches the KARMA validation tests in chrome in order to debug them.
+ * (Can only be launch locally.)
+ */
+gulp.task("tests-validation-karma", function (done) {
+    var kamaServerOptions = {
+        configFile: __dirname + "/../../tests/validation/karma.conf.js",
+        singleRun: false
+    };
+
+    var server = new karmaServer(kamaServerOptions, done);
+    server.start();
+});
+
+/**
+ * Launches the KARMA validation tests in ff or virtual screen ff on travis for a quick analysis during the build.
+ * (Can only be launch on any branches.)
+ */
+gulp.task("tests-validation-virtualscreen", function (done) {
+    var kamaServerOptions = {
+        configFile: __dirname + "/../../tests/validation/karma.conf.js",
+        singleRun: true,
+        browsers: ['Firefox']
+    };
+
+    var server = new karmaServer(kamaServerOptions, done);
+    server.start();
+});
+
+/**
+ * Launches the KARMA validation tests in browser stack for remote and cross devices validation tests.
+ * (Can only be launch from secure branches.)
+ */
+gulp.task("tests-validation-browserstack", function (done) {
+    if (!process.env.BROWSER_STACK_USERNAME) {
+        done();
+        return;
+    }
+
+    var kamaServerOptions = {
+        configFile: __dirname + "/../../tests/validation/karma.conf.browserstack.js",
+        singleRun: true
+    };
+
+    var server = new karmaServer(kamaServerOptions, done);
+    server.start();
+});
+
+/**
+ * Transpiles typescript unit tests. 
+ */
+gulp.task("tests-unit-transpile", function (done) {
+    var tsProject = typescript.createProject('../../tests/unit/tsconfig.json');
+
+    var tsResult = gulp.src("../../tests/unit/**/*.ts", { base: "../../" })
+        .pipe(tsProject());
+    
+    tsResult.once("error", function () {
+        tsResult.once("finish", function () {
+            console.log("Typescript compile failed");
+            process.exit(1);
+        });
+    });
+ 
+    return tsResult.js.pipe(gulp.dest("../../"));
+});
+
+/**
+ * Launches the KARMA unit tests in phantomJS.
+ * (Can only be launch on any branches.)
+ */
+gulp.task("tests-unit-debug", ["tests-unit-transpile"], function (done) {
+    var kamaServerOptions = {
+        configFile: __dirname + "/../../tests/unit/karma.conf.js",
+        singleRun: false,
+        browsers: ['Chrome']
+    };
+
+    var server = new karmaServer(kamaServerOptions, done);
+    server.start();
+});
+
+/**
+ * Launches the KARMA unit tests in phantomJS.
+ * (Can only be launch on any branches.)
+ */
+gulp.task("tests-unit", ["tests-unit-transpile"], function (done) {
+    var kamaServerOptions = {
+        configFile: __dirname + "/../../tests/unit/karma.conf.js",
+        singleRun: true
+    };
+
+    var server = new karmaServer(kamaServerOptions, done);
+    server.start();
+});
+
+gulp.task("tests-whatsnew", function(done) {
+    // Only checks on Travis
+    if (!process.env.TRAVIS) {
+        done();
+        return;
+    }
+
+    // Only checks on Pull Requests
+    if (process.env.TRAVIS_PULL_REQUEST == "false") {
+        done();
+        return;
+    }
+
+    // Do not check deploy
+    if (process.env.TRAVIS_BRANCH == "preview") {
+        done();
+        return;
+    }
+
+    // Compare what's new with the current one in the preview release folder.
+    const https = require("https");
+    const url = "https://rawgit.com/BabylonJS/Babylon.js/master/dist/preview%20release/what's%20new.md";
+    https.get(url, res => {
+        res.setEncoding("utf8");
+        let oldData = "";
+        res.on("data", data => {
+            oldData += data;
+        });
+        res.on("end", () => {
+            fs.readFile("../../dist/preview release/what's new.md", "utf-8", function(err, newData) {
+                if (err || oldData != newData) {
+                    done();
+                    return;
+                }
+                
+                console.error("What's new file did not change.");
+                process.exit(1);
+            });
+        });
+    });
+});

+ 17 - 11
Tools/Gulp/package.json

@@ -11,6 +11,8 @@
     "devDependencies": {
         "@types/node": "^8.5.0",
         "base64-image-loader": "^1.2.1",
+        "chai": "^4.1.2",
+        "color-support": "^1.1.3",
         "css-loader": "^0.25.0",
         "deepmerge": "^2.0.1",
         "del": "2.2.2",
@@ -28,6 +30,7 @@
         "gulp-replace": "~0.5.3",
         "gulp-sass": "3.1.0",
         "gulp-sourcemaps": "~1.9.1",
+        "gulp-typedoc": "^2.1.2",
         "gulp-typescript": "^3.2.3",
         "gulp-uglify": "^2.1.2",
         "gulp-util": "~3.0.4",
@@ -36,25 +39,28 @@
         "html-loader": "^0.5.1",
         "imports-loader": "^0.7.1",
         "json-loader": "^0.5.7",
+        "karma": "^2.0.0",
+        "karma-browserstack-launcher": "^1.3.0",
+        "karma-chai": "^0.1.0",
+        "karma-chrome-launcher": "^2.2.0",
+        "karma-firefox-launcher": "^1.1.0",
+        "karma-mocha": "^1.3.0",
+        "karma-phantomjs-launcher": "^1.0.4",
+        "karma-sinon": "^1.0.5",
         "merge2": "~0.3.5",
         "minimist": "^1.2.0",
+        "mocha": "^4.0.1",
+        "phantomjs": "^2.1.7",
         "run-sequence": "~1.1.0",
+        "sinon": "^4.1.3",
         "style-loader": "^0.13.2",
         "through2": "~0.6.5",
         "ts-loader": "^2.3.7",
+        "typedoc": "^0.9.0",
         "typescript": "^2.6.2",
-        "webpack-stream": "^4.0.0",
-        "karma": "^2.0.0",
-        "karma-chrome-launcher": "^2.2.0",
-        "karma-browserstack-launcher": "^1.3.0",
-        "mocha": "^4.0.1",
-        "chai": "^4.1.2",
-        "sinon": "^4.1.3",
-        "karma-mocha": "^1.3.0",
-        "karma-chai": "^0.1.0",
-        "karma-sinon": "^1.0.5"
+        "webpack-stream": "^4.0.0"
     },
     "scripts": {
-        "install": "npm --prefix ../../Playground/ install ../../Playground/ && gulp typescript-compile && gulp typescript-libraries && gulp deployLocalDev"
+        "install": "npm --prefix ../../Playground/ install ../../Playground/ && npm --prefix ../../tests/unit/ install ../../tests/unit/ && gulp deployLocalDev"
     }
 }

+ 47 - 19
Tools/Publisher/index.js

@@ -46,30 +46,53 @@ let packages = [
     }
 ];
 
+function updateEngineVersion(newVersion) {
+    console.log("updating version in babylon.engine.ts");
+    let engineContent = fs.readFileSync("../../src/Engine/babylon.engine.ts").toString();
+    let replaced = engineContent.replace(/(public static get Version\(\): string {\s*return ")(.*)(";\s*})/g, "$1" + newVersion + "$3");
+    fs.writeFileSync("../../src/Engine/babylon.engine.ts", replaced);
+}
+
+function runGulp() {
+    // run gulp typescript-all
+    let exec = shelljs.exec("gulp typescript-all --gulpfile ../Gulp/gulpfile.js");
+    if (exec.code) {
+        console.log("error during compilation, aborting");
+        process.exit(1);
+    }
+}
+
+function processPackages() {
+    packages.forEach((package) => {
+        if (package.name === "core") {
+            processCore(package, version);
+        } else {
+            let packageJson = require(package.path + 'package.json');
+            packageJson.version = version;
+            if (packageJson.peerDependencies) packageJson.peerDependencies.babylonjs = minimumDependency;
+            fs.writeFileSync(package.path + 'package.json', JSON.stringify(packageJson, null, 4));
+            console.log('Publishing ' + package.name + " from " + package.path);
+            //publish the respected package
+            shelljs.exec('npm publish \"' + package.path + "\"");
+        }
+
+    });
+}
+
 //check if logged in
 console.log("Using npm user:");
 let loginCheck = shelljs.exec('npm whoami');
-console.log("No that I can check, but - did you forget to run gulp typescript-all?");
+console.log("Not that I can check, but - did you run gulp typescript-all?");
 if (loginCheck.code === 0) {
     prompt.start();
 
     prompt.get(['version'], function (err, result) {
         let version = result.version;
-        packages.forEach((package) => {
-            if (package.name === "core") {
-                processCore(package, version);
-            } else {
-                let packageJson = require(package.path + 'package.json');
-                packageJson.version = version;
-                if (packageJson.peerDependencies) packageJson.peerDependencies.babylonjs = minimumDependency;
-                fs.writeFileSync(package.path + 'package.json', JSON.stringify(packageJson, null, 4));
-                console.log('Publishing ' + package.name + " from " + package.path);
-                //publish the respected package
-                shelljs.exec('npm publish \"' + package.path + "\"");
-            }
-
-        });
-        console.log("done, please don't forget to commit the changes")
+        updateEngineVersion(version);
+        runGulp();
+        processPackages();
+
+        console.log("done, please tag git with " + version);
     });
 } else {
     console.log('not logged in.');
@@ -87,6 +110,10 @@ function processCore(package, version) {
             objectName: "babylon.d.ts"
         },
         {
+            path: basePath + "/es6.js",
+            objectName: "es6.js"
+        },
+        {
             path: basePath + "/babylon.js",
             objectName: "babylon.js"
         },
@@ -108,7 +135,8 @@ function processCore(package, version) {
         }
     ];
 
-    fs.readdirSync(basePath + '/modules/').forEach(object => {
+    // remove the modules for now
+    /*fs.readdirSync(basePath + '/modules/').forEach(object => {
         console.log(object);
         if (fs.statSync(basePath + '/modules/' + object).isDirectory) {
             files.push({
@@ -117,7 +145,7 @@ function processCore(package, version) {
                 isDir: true
             });
         }
-    })
+    })*/
 
     //copy them to the package path
     files.forEach(file => {
@@ -143,7 +171,7 @@ function processCore(package, version) {
 
     fs.writeFileSync(basePath + '/package/' + 'package.json', JSON.stringify(packageJson, null, 4));
 
-    console.log('Publishing ' + package.name + " from " + package.path);
+    console.log('Publishing ' + package.name + " from " + basePath + '/package/');
     //publish the respected package
     shelljs.exec('npm publish \"' + basePath + '/package/' + "\"");
 

+ 3 - 0
Tools/Publisher/package.json

@@ -12,5 +12,8 @@
     "fs-extra": "^5.0.0",
     "prompt": "^1.0.0",
     "shelljs": "^0.7.8"
+  },
+  "devDependencies": {
+    "gulp": "^3.9.1"
   }
 }

+ 4 - 3
Viewer/dist/basicExample.html

@@ -17,8 +17,9 @@
     </head>
 
     <body>
-        <babylon model.title="Damaged Helmet" model.subtitle="BabylonJS" model.thumbnail="https://www.babylonjs.com/img/favicon/apple-icon-144x144.png"
-            model.url="https://www.babylonjs.com/Assets/DamagedHelmet/glTF/DamagedHelmet.gltf" camera.behaviors.auto-rotate="0" templates.nav-bar.params.disable-on-fullscreen="true"></babylon>
+        <babylon configuration="config.json" model.title="Damaged Helmet" model.subtitle="BabylonJS" model.thumbnail="https://www.babylonjs.com/img/favicon/apple-icon-144x144.png"
+            model.url="https://www.babylonjs.com/Assets/DamagedHelmet/glTF/DamagedHelmet.gltf" camera.behaviors.auto-rotate="0"
+            templates.nav-bar.params.disable-on-fullscreen="true"></babylon>
         <script src="viewer.js"></script>
         <script>
             // The following lines are redundant. 
@@ -31,4 +32,4 @@
         </script>
     </body>
 
-</html>
+</html>

+ 5 - 0
Viewer/dist/config.json

@@ -0,0 +1,5 @@
+{
+    "scene": {
+        "debug": false
+    }
+}

Разлика између датотеке није приказан због своје велике величине
+ 18444 - 15388
Viewer/dist/viewer.js


Разлика између датотеке није приказан због своје велике величине
+ 1 - 1
Viewer/dist/viewer.min.js


+ 10 - 10
Viewer/package.json

@@ -23,21 +23,21 @@
     },
     "homepage": "https://github.com/BabylonJS/Babylon.js#readme",
     "devDependencies": {
-        "@types/node": "^8.0.53",
-        "base64-image-loader": "^1.2.0",
-        "html-loader": "^0.5.1",
+        "@types/node": "^8.5.8",
+        "base64-image-loader": "^1.2.1",
+        "html-loader": "^0.5.4",
         "json-loader": "^0.5.7",
         "ts-loader": "^2.3.7",
         "typescript": "^2.6.2",
-        "uglifyjs-webpack-plugin": "^1.1.1",
-        "webpack": "^3.8.1",
-        "webpack-dev-server": "^2.9.5"
+        "uglifyjs-webpack-plugin": "^1.1.6",
+        "webpack": "^3.10.0",
+        "webpack-dev-server": "^2.11.0"
     },
     "dependencies": {
-        "babylonjs": "^3.1.0-beta6",
-        "babylonjs-loaders": "^3.1.0-beta6",
+        "babylonjs": "^3.2.0-alpha4",
+        "babylonjs-loaders": "^3.2.0-alpha4",
         "deepmerge": "^2.0.1",
-        "es6-promise": "^4.1.1",
+        "es6-promise": "^4.2.2",
         "handlebars": "^4.0.11"
     }
-}
+}

+ 0 - 14
Viewer/src/configuration/configuration.ts

@@ -13,20 +13,6 @@ export interface ViewerConfiguration {
         mapper?: string; // json (default), html, yaml, xml, etc'. if not provided, file extension will be used.
     };
 
-    // Deprecated
-    /*// native (!!!) javascript events. Mainly used in the JSON-format.
-    // those events will be triggered by the container element (the <babylon> tag);
-    events?: {
-        load: boolean | string;
-        init: boolean | string;
-        meshselected: boolean | string;
-        pointerdown: boolean | string;
-        pointerup: boolean | string;
-        pointermove: boolean | string;
-        // load: 'onViewerLoaded' // will trigger the event prefix-onViewerLoaded instead of prefix-onLoad (and ONLY this event).
-    } | boolean; //events: true - fire all events*/
-    //eventPrefix?: string;
-
     // names of functions in the window context.
     observers?: {
         onEngineInit?: string;

+ 8 - 4
Viewer/src/configuration/loader.ts

@@ -6,7 +6,11 @@ import * as deepmerge from '../../assets/deepmerge.min.js';
 
 export class ConfigurationLoader {
 
-    private configurationCache: { (url: string): any };
+    private configurationCache: { [url: string]: any };
+
+    constructor() {
+        this.configurationCache = {};
+    }
 
     public loadConfiguration(initConfig: ViewerConfiguration = {}): Promise<ViewerConfiguration> {
 
@@ -62,10 +66,10 @@ export class ConfigurationLoader {
                     if (xhr.status === OK) {
                         cacheReference[url] = xhr.responseText;
                         resolve(xhr.responseText); // 'This is the returned text.'
+                    } else {
+                        console.log('Error: ' + xhr.status, url);
+                        reject('Error: ' + xhr.status); // An error occurred during the request.
                     }
-                } else {
-                    console.log('Error: ' + xhr.status, url);
-                    reject('Error: ' + xhr.status); // An error occurred during the request.
                 }
             }
         });

+ 1 - 2
Viewer/src/configuration/mappers.ts

@@ -117,5 +117,4 @@ export class MapperManager {
 
 }
 
-export let mapperManager = new MapperManager();
-export default mapperManager;
+export let mapperManager = new MapperManager();

+ 7 - 1
Viewer/src/configuration/types/default.ts

@@ -17,6 +17,11 @@ export let defaultConfiguration: ViewerConfiguration = {
         },
         viewer: {
             html: require("../../../assets/templates/default/defaultViewer.html"),
+            events: {
+                pointerout: true,
+                pointerdown: true,
+                pointerup: true
+            }
         },
         navBar: {
             html: require("../../../assets/templates/default/navbar.html"),
@@ -34,7 +39,8 @@ export let defaultConfiguration: ViewerConfiguration = {
                 visibilityTimeout: 2000
             },
             events: {
-                pointerdown: { 'fullscreen-button': true/*, '#help-button': true*/ }
+                pointerdown: { 'fullscreen-button': true/*, '#help-button': true*/ },
+                pointerover: true
             }
         },
         overlay: {

+ 2 - 1
Viewer/src/configuration/types/index.ts

@@ -1,7 +1,8 @@
 import { minimalConfiguration } from './minimal';
 import { defaultConfiguration } from './default';
+import { ViewerConfiguration } from '../configuration';
 
-let getConfigurationType = function (type: string) {
+let getConfigurationType = function (type: string): ViewerConfiguration {
     switch (type) {
         case 'default':
             return defaultConfiguration;

+ 40 - 0
Viewer/src/eventManager.ts

@@ -0,0 +1,40 @@
+import { EventCallback, TemplateManager } from "./templateManager";
+
+
+export class EventManager {
+
+    private callbacksContainer: { [key: string]: Array<{ eventType?: string, selector?: string, callback: (eventData: EventCallback) => void }> }
+
+    constructor(private templateManager: TemplateManager) {
+        this.callbacksContainer = {};
+        this.templateManager.onEventTriggered.add(eventData => {
+            this.eventTriggered(eventData);
+        })
+    }
+
+    public registerCallback(templateName: string, callback: (eventData: EventCallback) => void, eventType?: string, selector?: string) {
+        if (!this.callbacksContainer[templateName]) {
+            this.callbacksContainer[templateName] = [];
+        }
+        this.callbacksContainer[templateName].push({
+            eventType: eventType,
+            callback: callback
+        });
+    }
+
+    public unregisterCallback(templateName: string, callback?: (eventData: EventCallback) => void, eventType?: string, selector?: string) {
+        let callbackDefs = this.callbacksContainer[templateName] || [];
+        this.callbacksContainer[templateName] = callbackDefs.filter(callbackDef => (!callbackDef.eventType || callbackDef.eventType === eventType) && (!callbackDef.selector || callbackDef.selector === selector));
+    }
+
+    private eventTriggered(data: EventCallback) {
+        let templateName = data.template.name;
+        let eventType = data.event.type;
+        let selector = data.selector;
+
+        let callbackDefs = this.callbacksContainer[templateName] || [];
+        callbackDefs.filter(callbackDef => (!callbackDef.eventType || callbackDef.eventType === eventType) && (!callbackDef.selector || callbackDef.selector === selector)).forEach(callbackDef => {
+            callbackDef.callback(data);
+        });
+    }
+}

+ 49 - 18
Viewer/src/templateManager.ts

@@ -40,6 +40,9 @@ export class TemplateManager {
     public onLoaded: Observable<Template>;
     public onStateChange: Observable<Template>;
     public onAllLoaded: Observable<TemplateManager>;
+    public onEventTriggered: Observable<EventCallback>;
+
+    public eventManager: EventManager;
 
     private templates: { [name: string]: Template };
 
@@ -50,6 +53,9 @@ export class TemplateManager {
         this.onLoaded = new Observable<Template>();
         this.onStateChange = new Observable<Template>();
         this.onAllLoaded = new Observable<TemplateManager>();
+        this.onEventTriggered = new Observable<EventCallback>();
+
+        this.eventManager = new EventManager(this);
     }
 
     public initTemplate(templates: { [key: string]: ITemplateConfiguration }) {
@@ -101,6 +107,8 @@ export class TemplateManager {
     private buildHTMLTree(templates: { [key: string]: ITemplateConfiguration }): Promise<object> {
         let promises = Object.keys(templates).map(name => {
             let template = new Template(name, templates[name]);
+            // make sure the global onEventTriggered is called as well
+            template.onEventTriggered.add(eventData => this.onEventTriggered.notifyObservers(eventData));
             this.templates[name] = template;
             return template.initPromise;
         });
@@ -144,6 +152,8 @@ export class TemplateManager {
 
 
 import * as Handlebars from '../assets/handlebars.min.js';
+import { PromiseObservable } from './util/promiseObservable';
+import { EventManager } from './eventManager';
 // register a new helper. modified https://stackoverflow.com/questions/9838925/is-there-any-method-to-iterate-a-map-with-handlebars-js
 Handlebars.registerHelper('eachInMap', function (map, block) {
     var out = '';
@@ -168,6 +178,11 @@ export class Template {
     public onEventTriggered: Observable<EventCallback>;
 
     public isLoaded: boolean;
+    /**
+     * This is meant to be used to track the show and hide functions.
+     * This is NOT (!!) a flag to check if the element is actually visible to the user.
+     */
+    public isShown: boolean;
 
     public parent: HTMLElement;
 
@@ -183,6 +198,7 @@ export class Template {
         this.onEventTriggered = new Observable<EventCallback>();
 
         this.isLoaded = false;
+        this.isShown = false;
         /*
         if (configuration.id) {
             this.parent.id = configuration.id;
@@ -199,6 +215,7 @@ export class Template {
                 let rawHtml = compiledTemplate(config);
                 this.fragment = document.createRange().createContextualFragment(rawHtml);
                 this.isLoaded = true;
+                this.isShown = true;
                 this.onLoaded.notifyObservers(this);
             }
             return this;
@@ -243,30 +260,44 @@ export class Template {
     }
 
     public show(visibilityFunction?: (template: Template) => Promise<Template>): Promise<Template> {
-        if (visibilityFunction) {
-            return visibilityFunction(this).then(() => {
-                this.onStateChange.notifyObservers(this);
+        return Promise.resolve().then(() => {
+            if (visibilityFunction) {
+                return visibilityFunction(this);
+            } else {
+                // flex? box? should this be configurable easier than the visibilityFunction?
+                this.parent.style.display = 'flex';
                 return this;
-            });
-        } else {
-            // flex? box? should this be configurable easier than the visibilityFunction?
-            this.parent.style.display = 'flex';
+            }
+        }).then(() => {
+            this.isShown = true;
             this.onStateChange.notifyObservers(this);
-            return Promise.resolve(this);
-        }
+            return this;
+        });
     }
 
     public hide(visibilityFunction?: (template: Template) => Promise<Template>): Promise<Template> {
-        if (visibilityFunction) {
-            return visibilityFunction(this).then(() => {
-                this.onStateChange.notifyObservers(this);
+        return Promise.resolve().then(() => {
+            if (visibilityFunction) {
+                return visibilityFunction(this);
+            } else {
+                // flex? box? should this be configurable easier than the visibilityFunction?
+                this.parent.style.display = 'hide';
                 return this;
-            });
-        } else {
-            this.parent.style.display = 'none';
+            }
+        }).then(() => {
+            this.isShown = false;
             this.onStateChange.notifyObservers(this);
-            return Promise.resolve(this);
-        }
+            return this;
+        });
+    }
+
+    public dispose() {
+        this.onAppended.clear();
+        this.onEventTriggered.clear();
+        this.onInit.clear();
+        this.onLoaded.clear();
+        this.onStateChange.clear();
+        this.isLoaded = false;
     }
 
     // TODO - Should events be removed as well? when are templates disposed?
@@ -286,7 +317,7 @@ export class Template {
                         // strict null checl is working incorrectly, must override:
                         let event = this._configuration.events[eventName] || {};
                         selectorsArray.filter(selector => event[selector]).forEach(selector => {
-                            if (selector.indexOf('#') !== 0) {
+                            if (selector && selector.indexOf('#') !== 0) {
                                 selector = '#' + selector;
                             }
                             let htmlElement = <HTMLElement>this.parent.querySelector(selector);

+ 42 - 59
Viewer/src/viewer/defaultViewer.ts

@@ -1,7 +1,7 @@
 
 
 import { ViewerConfiguration } from './../configuration/configuration';
-import { Template } from './../templateManager';
+import { Template, EventCallback } from './../templateManager';
 import { AbstractViewer } from './viewer';
 import { MirrorTexture, Plane, ShadowGenerator, Texture, BackgroundMaterial, Observable, ShadowLight, CubeTexture, BouncingBehavior, FramingBehavior, Behavior, Light, Engine, Scene, AutoRotationBehavior, AbstractMesh, Quaternion, StandardMaterial, ArcRotateCamera, ImageProcessingConfiguration, Color3, Vector3, SceneLoader, Mesh, HemisphericLight } from 'babylonjs';
 import { CameraBehavior } from '../interfaces';
@@ -27,9 +27,22 @@ export class DefaultViewer extends AbstractViewer {
         this.showLoadingScreen();
 
         // navbar
-        let viewerElement = this.templateManager.getTemplate('viewer');
+        this.initNavbar();
+
+        // close overlay button
+        let closeButton = document.getElementById('close-button');
+        if (closeButton) {
+            closeButton.addEventListener('pointerdown', () => {
+                this.hideOverlayScreen();
+            })
+        }
+
+        return super.onTemplatesLoaded();
+    }
+
+    private initNavbar() {
         let navbar = this.templateManager.getTemplate('navBar');
-        if (viewerElement && navbar) {
+        if (navbar) {
             let navbarHeight = navbar.parent.clientHeight + 'px';
 
             let navbarShown: boolean = true;
@@ -61,64 +74,30 @@ export class DefaultViewer extends AbstractViewer {
                 }
             }
 
-
-
-            viewerElement.parent.addEventListener('pointerout', triggerNavbar.bind(this, false));
-            viewerElement.parent.addEventListener('pointerdown', triggerNavbar.bind(this, true));
-            viewerElement.parent.addEventListener('pointerup', triggerNavbar.bind(this, false));
-            navbar.parent.addEventListener('pointerover', triggerNavbar.bind(this, true))
-            // triggerNavbar(false);
-
-            // events registration
-            this.registerNavbarButtons();
-        }
-
-        // close overlay button
-        let closeButton = document.getElementById('close-button');
-        if (closeButton) {
-            closeButton.addEventListener('pointerdown', () => {
-                this.hideOverlayScreen();
-            })
-        }
-
-        return super.onTemplatesLoaded();
-    }
-
-    private registerNavbarButtons() {
-        let isFullscreen = false;
-
-        let navbar = this.templateManager.getTemplate('navBar');
-        let viewerTemplate = this.templateManager.getTemplate('viewer');
-        if (!navbar || !viewerTemplate) return;
-
-        let viewerElement = viewerTemplate.parent;
-
-
-        navbar.onEventTriggered.add((data) => {
-            switch (data.event.type) {
-                case 'pointerdown':
-                    let event: PointerEvent = <PointerEvent>data.event;
-                    if (event.button === 0) {
-                        switch (data.selector) {
-                            case '#fullscreen-button':
-                                if (!isFullscreen) {
-                                    let requestFullScreen = viewerElement.requestFullscreen || viewerElement.webkitRequestFullscreen || (<any>viewerElement).msRequestFullscreen || (<any>viewerElement).mozRequestFullScreen;
-                                    requestFullScreen.call(viewerElement);
-                                } else {
-                                    let exitFullscreen = document.exitFullscreen || document.webkitExitFullscreen || (<any>document).msExitFullscreen || (<any>document).mozCancelFullScreen
-                                    exitFullscreen.call(document);
-                                }
-
-                                isFullscreen = !isFullscreen;
-                                break;
-                            case '#help-button':
-                                this.showOverlayScreen('help');
-                                break;
-                        }
+            this.templateManager.eventManager.registerCallback('viewer', triggerNavbar.bind(this, false), 'pointerout');
+            this.templateManager.eventManager.registerCallback('viewer', triggerNavbar.bind(this, true), 'pointerdown');
+            this.templateManager.eventManager.registerCallback('viewer', triggerNavbar.bind(this, false), 'pointerup');
+            this.templateManager.eventManager.registerCallback('navBar', triggerNavbar.bind(this, true), 'pointerover');
+
+            // other events
+            let viewerTemplate = this.templateManager.getTemplate('viewer');
+            let viewerElement = viewerTemplate && viewerTemplate.parent;
+            // full screen
+            let triggerFullscren = (eventData: EventCallback) => {
+                if (viewerElement) {
+                    let fullscreenElement = document.fullscreenElement || document.webkitFullscreenElement || (<any>document).mozFullScreenElement || (<any>document).msFullscreenElement;
+                    if (!fullscreenElement) {
+                        let requestFullScreen = viewerElement.requestFullscreen || viewerElement.webkitRequestFullscreen || (<any>viewerElement).msRequestFullscreen || (<any>viewerElement).mozRequestFullScreen;
+                        requestFullScreen.call(viewerElement);
+                    } else {
+                        let exitFullscreen = document.exitFullscreen || document.webkitExitFullscreen || (<any>document).msExitFullscreen || (<any>document).mozCancelFullScreen
+                        exitFullscreen.call(document);
                     }
-                    break;
+                }
             }
-        });
+
+            this.templateManager.eventManager.registerCallback('navBar', triggerFullscren, 'pointerdown', '#fullscreen-button');
+        }
     }
 
     protected prepareContainerElement() {
@@ -228,6 +207,10 @@ export class DefaultViewer extends AbstractViewer {
             ground.rotation.x = Math.PI / 2; // Face up by default.
             ground.receiveShadows = groundConfig.receiveShadows || false;
 
+            // position the ground correctly
+            let groundPosition = focusMeshes[0].getHierarchyBoundingVectors().min.y;
+            ground.position.y = groundPosition;
+
             // default values
             backgroundMaterial.alpha = 0.9;
             backgroundMaterial.alphaMode = Engine.ALPHA_PREMULTIPLIED_PORTERDUFF;

+ 1 - 0
Viewer/src/viewer/viewer.ts

@@ -145,6 +145,7 @@ export abstract class AbstractViewer {
     }
 
     public loadModel(model: any = this.configuration.model, clearScene: boolean = true): Promise<Scene> {
+        this.configuration.model = model;
         let modelUrl = (typeof model === 'string') ? model : model.url;
         let parts = modelUrl.split('/');
         let filename = parts.pop();

+ 1 - 1
Viewer/src/viewer/viewerManager.ts

@@ -3,7 +3,7 @@
 import { Observable } from 'babylonjs';
 import { AbstractViewer } from './viewer';
 
-class ViewerManager {
+export class ViewerManager {
 
     private viewers: { [key: string]: AbstractViewer };
 

+ 251 - 0
dist/babylon.glTFInterface.d.ts

@@ -0,0 +1,251 @@
+declare module BABYLON.GLTF2 {
+    /**
+     * Specifies if the attribute is a scalar, vector, or matrix.
+     */
+    const enum AccessorType {
+        SCALAR = "SCALAR",
+        VEC2 = "VEC2",
+        VEC3 = "VEC3",
+        VEC4 = "VEC4",
+        MAT2 = "MAT2",
+        MAT3 = "MAT3",
+        MAT4 = "MAT4",
+    }
+    const enum MaterialAlphaMode {
+        OPAQUE = "OPAQUE",
+        MASK = "MASK",
+        BLEND = "BLEND",
+    }
+    const enum AnimationChannelTargetPath {
+        TRANSLATION = "translation",
+        ROTATION = "rotation",
+        SCALE = "scale",
+        WEIGHTS = "weights",
+    }
+    const enum CameraType {
+        PERSPECTIVE = "perspective",
+        ORTHOGRAPHIC = "orthographic",
+    }
+    const enum AccessorComponentType {
+        BYTE = 5120,
+        UNSIGNED_BYTE = 5121,
+        SHORT = 5122,
+        UNSIGNED_SHORT = 5123,
+        UNSIGNED_INT = 5125,
+        FLOAT = 5126,
+    }
+    const enum AnimationInterpolation {
+        LINEAR = "LINEAR",
+        STEP = "STEP",
+        CUBICSPLINE = "CUBICSPLINE",
+    }
+    const enum MeshPrimitiveMode {
+        POINTS = 0,
+        LINES = 1,
+        LINE_LOOP = 2,
+        LINE_STRIP = 3,
+        TRIANGLES = 4,
+        TRIANGLE_STRIP = 5,
+        TRIANGLE_FAN = 6,
+    }
+    const enum ImageMimeType {
+        JPEG = "image/jpeg",
+        PNG = "image/png",
+    }
+    const enum TextureMagFilter {
+        NEAREST = 9728,
+        LINEAR = 9729,
+    }
+    const enum TextureMinFilter {
+        NEAREST = 9728,
+        LINEAR = 9729,
+        NEAREST_MIPMAP_NEAREST = 9984,
+        LINEAR_MIPMAP_NEAREST = 9985,
+        NEAREST_MIPMAP_LINEAR = 9986,
+        LINEAR_MIPMAP_LINEAR = 9987,
+    }
+    const enum TextureWrapMode {
+        CLAMP_TO_EDGE = 33071,
+        MIRRORED_REPEAT = 33648,
+        REPEAT = 10497,
+    }
+    interface IProperty {
+        extensions?: {
+            [key: string]: any;
+        };
+        extras?: any;
+    }
+    interface IChildRootProperty extends IProperty {
+        name?: string;
+    }
+    interface IAccessorSparseIndices extends IProperty {
+        bufferView: number;
+        byteOffset?: number;
+        componentType: AccessorComponentType;
+    }
+    interface IAccessorSparseValues extends IProperty {
+        bufferView: number;
+        byteOffset?: number;
+    }
+    interface IAccessorSparse extends IProperty {
+        count: number;
+        indices: IAccessorSparseIndices;
+        values: IAccessorSparseValues;
+    }
+    interface IAccessor extends IChildRootProperty {
+        bufferView?: number;
+        byteOffset?: number;
+        componentType: AccessorComponentType;
+        normalized?: boolean;
+        count: number;
+        type: AccessorType;
+        max?: number[];
+        min?: number[];
+        sparse?: IAccessorSparse;
+    }
+    interface IAnimationChannel extends IProperty {
+        sampler: number;
+        target: IAnimationChannelTarget;
+    }
+    interface IAnimationChannelTarget extends IProperty {
+        node: number;
+        path: AnimationChannelTargetPath;
+    }
+    interface IAnimationSampler extends IProperty {
+        input: number;
+        interpolation?: AnimationInterpolation;
+        output: number;
+    }
+    interface IAnimation extends IChildRootProperty {
+        channels: IAnimationChannel[];
+        samplers: IAnimationSampler[];
+    }
+    interface IAsset extends IChildRootProperty {
+        copyright?: string;
+        generator?: string;
+        version: string;
+        minVersion?: string;
+    }
+    interface IBuffer extends IChildRootProperty {
+        uri?: string;
+        byteLength: number;
+    }
+    interface IBufferView extends IChildRootProperty {
+        buffer: number;
+        byteOffset?: number;
+        byteLength: number;
+        byteStride?: number;
+    }
+    interface ICameraOrthographic extends IProperty {
+        xmag: number;
+        ymag: number;
+        zfar: number;
+        znear: number;
+    }
+    interface ICameraPerspective extends IProperty {
+        aspectRatio: number;
+        yfov: number;
+        zfar: number;
+        znear: number;
+    }
+    interface ICamera extends IChildRootProperty {
+        orthographic?: ICameraOrthographic;
+        perspective?: ICameraPerspective;
+        type: CameraType;
+    }
+    interface IImage extends IChildRootProperty {
+        uri?: string;
+        mimeType?: ImageMimeType;
+        bufferView?: number;
+    }
+    interface IMaterialNormalTextureInfo extends ITextureInfo {
+        scale?: number;
+    }
+    interface IMaterialOcclusionTextureInfo extends ITextureInfo {
+        strength?: number;
+    }
+    interface IMaterialPbrMetallicRoughness {
+        baseColorFactor?: number[];
+        baseColorTexture?: ITextureInfo;
+        metallicFactor?: number;
+        roughnessFactor?: number;
+        metallicRoughnessTexture?: ITextureInfo;
+    }
+    interface IMaterial extends IChildRootProperty {
+        pbrMetallicRoughness?: IMaterialPbrMetallicRoughness;
+        normalTexture?: IMaterialNormalTextureInfo;
+        occlusionTexture?: IMaterialOcclusionTextureInfo;
+        emissiveTexture?: ITextureInfo;
+        emissiveFactor?: number[];
+        alphaMode?: MaterialAlphaMode;
+        alphaCutoff?: number;
+        doubleSided?: boolean;
+    }
+    interface IMeshPrimitive extends IProperty {
+        attributes: {
+            [name: string]: number;
+        };
+        indices?: number;
+        material?: number;
+        mode?: MeshPrimitiveMode;
+        targets?: {
+            [name: string]: number;
+        }[];
+    }
+    interface IMesh extends IChildRootProperty {
+        primitives: IMeshPrimitive[];
+        weights?: number[];
+    }
+    interface INode extends IChildRootProperty {
+        camera?: number;
+        children?: number[];
+        skin?: number;
+        matrix?: number[];
+        mesh?: number;
+        rotation?: number[];
+        scale?: number[];
+        translation?: number[];
+        weights?: number[];
+    }
+    interface ISampler extends IChildRootProperty {
+        magFilter?: TextureMagFilter;
+        minFilter?: TextureMinFilter;
+        wrapS?: TextureWrapMode;
+        wrapT?: TextureWrapMode;
+    }
+    interface IScene extends IChildRootProperty {
+        nodes: number[];
+    }
+    interface ISkin extends IChildRootProperty {
+        inverseBindMatrices?: number;
+        skeleton?: number;
+        joints: number[];
+    }
+    interface ITexture extends IChildRootProperty {
+        sampler?: number;
+        source: number;
+    }
+    interface ITextureInfo {
+        index: number;
+        texCoord?: number;
+    }
+    interface IGLTF extends IProperty {
+        accessors?: IAccessor[];
+        animations?: IAnimation[];
+        asset: IAsset;
+        buffers?: IBuffer[];
+        bufferViews?: IBufferView[];
+        cameras?: ICamera[];
+        extensionsUsed?: string[];
+        extensionsRequired?: string[];
+        images?: IImage[];
+        materials?: IMaterial[];
+        meshes?: IMesh[];
+        nodes?: INode[];
+        samplers?: ISampler[];
+        scene?: number;
+        scenes?: IScene[];
+        skins?: ISkin[];
+        textures?: ITexture[];
+    }
+}

Разлика између датотеке није приказан због своје велике величине
+ 5438 - 2973
dist/preview release/babylon.d.ts


Разлика између датотеке није приказан због своје велике величине
+ 51 - 51
dist/preview release/babylon.js


Разлика између датотеке није приказан због своје велике величине
+ 4012 - 1230
dist/preview release/babylon.max.js


Разлика између датотеке није приказан због своје велике величине
+ 53 - 53
dist/preview release/babylon.worker.js


Разлика између датотеке није приказан због своје велике величине
+ 5598 - 3133
dist/preview release/customConfigurations/minimalGLTFViewer/babylon.d.ts


Разлика између датотеке није приказан због своје велике величине
+ 55 - 55
dist/preview release/customConfigurations/minimalGLTFViewer/babylon.js


Разлика између датотеке није приказан због своје велике величине
+ 4001 - 1248
dist/preview release/customConfigurations/minimalGLTFViewer/babylon.max.js


Разлика између датотеке није приказан због своје велике величине
+ 88667 - 0
dist/preview release/customConfigurations/minimalGLTFViewer/es6.js


Разлика између датотеке није приказан због своје велике величине
+ 84468 - 0
dist/preview release/es6.js


+ 72 - 1
dist/preview release/gui/babylon.gui.d.ts

@@ -56,6 +56,17 @@ declare module BABYLON.GUI {
         private _manageFocus();
         private _attachToOnPointerOut(scene);
         static CreateForMesh(mesh: AbstractMesh, width?: number, height?: number, supportPointerMove?: boolean): AdvancedDynamicTexture;
+        /**
+         * FullScreenUI is created in a layer. This allows it to be treated like any other layer.
+         * As such, if you have a multi camera setup, you can set the layerMask on the GUI as well.
+         * When the GUI is not Created as FullscreenUI it does not respect the layerMask.
+         * layerMask is set through advancedTexture.layer.layerMask
+         * @param name name for the Texture
+         * @param foreground render in foreground (default is true)
+         * @param scene scene to be rendered in
+         * @param sampling method for scaling to fit screen
+         * @returns AdvancedDynamicTexture
+         */
         static CreateFullscreenUI(name: string, foreground?: boolean, scene?: Nullable<Scene>, sampling?: number): AdvancedDynamicTexture;
     }
 }
@@ -441,6 +452,7 @@ declare module BABYLON.GUI {
         private _borderColor;
         private _barOffset;
         private _isThumbCircle;
+        private _isThumbClamped;
         onValueChangedObservable: Observable<number>;
         borderColor: string;
         background: string;
@@ -452,6 +464,7 @@ declare module BABYLON.GUI {
         maximum: number;
         value: number;
         isThumbCircle: boolean;
+        isThumbClamped: boolean;
         constructor(name?: string | undefined);
         protected _getTypeName(): string;
         _draw(parentMeasure: Measure, context: CanvasRenderingContext2D): void;
@@ -507,6 +520,9 @@ declare module BABYLON.GUI {
 
 declare module BABYLON.GUI {
     class TextBlock extends Control {
+        /**
+         * Defines the name of the control
+         */
         name: string | undefined;
         private _text;
         private _textWrapping;
@@ -520,15 +536,70 @@ declare module BABYLON.GUI {
         * @type {BABYLON.Observable}
         */
         onTextChangedObservable: Observable<TextBlock>;
+        /**
+        * An event triggered after the text was broken up into lines
+        * @type {BABYLON.Observable}
+        */
+        onLinesReadyObservable: Observable<TextBlock>;
+        /**
+         * Return the line list (you may need to use the onLinesReadyObservable to make sure the list is ready)
+         */
+        readonly lines: any[];
+        /**
+         * Gets or sets an boolean indicating that the TextBlock will be resized to fit container
+         */
+        /**
+         * Gets or sets an boolean indicating that the TextBlock will be resized to fit container
+         */
         resizeToFit: boolean;
+        /**
+         * Gets or sets a boolean indicating if text must be wrapped
+         */
+        /**
+         * Gets or sets a boolean indicating if text must be wrapped
+         */
         textWrapping: boolean;
+        /**
+         * Gets or sets text to display
+         */
+        /**
+         * Gets or sets text to display
+         */
         text: string;
+        /**
+         * Gets or sets text horizontal alignment (BABYLON.GUI.Control.HORIZONTAL_ALIGNMENT_CENTER by default)
+         */
+        /**
+         * Gets or sets text horizontal alignment (BABYLON.GUI.Control.HORIZONTAL_ALIGNMENT_CENTER by default)
+         */
         textHorizontalAlignment: number;
+        /**
+         * Gets or sets text vertical alignment (BABYLON.GUI.Control.VERTICAL_ALIGNMENT_CENTER by default)
+         */
+        /**
+         * Gets or sets text vertical alignment (BABYLON.GUI.Control.VERTICAL_ALIGNMENT_CENTER by default)
+         */
         textVerticalAlignment: number;
+        /**
+         * Gets or sets line spacing value
+         */
+        /**
+         * Gets or sets line spacing value
+         */
         lineSpacing: string | number;
-        constructor(name?: string | undefined, text?: string);
+        /**
+         * Creates a new TextBlock object
+         * @param name defines the name of the control
+         * @param text defines the text to display (emptry string by default)
+         */
+        constructor(
+            /**
+             * Defines the name of the control
+             */
+            name?: string | undefined, text?: string);
         protected _getTypeName(): string;
         private _drawText(text, textWidth, y, context);
+        /** @ignore */
         _draw(parentMeasure: Measure, context: CanvasRenderingContext2D): void;
         protected _additionalProcessing(parentMeasure: Measure, context: CanvasRenderingContext2D): void;
         protected _parseLine(line: string | undefined, context: CanvasRenderingContext2D): object;

+ 112 - 16
dist/preview release/gui/babylon.gui.js

@@ -476,6 +476,17 @@ var BABYLON;
                 result.attachToMesh(mesh, supportPointerMove);
                 return result;
             };
+            /**
+             * FullScreenUI is created in a layer. This allows it to be treated like any other layer.
+             * As such, if you have a multi camera setup, you can set the layerMask on the GUI as well.
+             * When the GUI is not Created as FullscreenUI it does not respect the layerMask.
+             * layerMask is set through advancedTexture.layer.layerMask
+             * @param name name for the Texture
+             * @param foreground render in foreground (default is true)
+             * @param scene scene to be rendered in
+             * @param sampling method for scaling to fit screen
+             * @returns AdvancedDynamicTexture
+             */
             AdvancedDynamicTexture.CreateFullscreenUI = function (name, foreground, scene, sampling) {
                 if (foreground === void 0) { foreground = true; }
                 if (scene === void 0) { scene = null; }
@@ -2622,6 +2633,7 @@ var BABYLON;
                 _this._borderColor = "white";
                 _this._barOffset = new GUI.ValueAndUnit(5, GUI.ValueAndUnit.UNITMODE_PIXEL, false);
                 _this._isThumbCircle = false;
+                _this._isThumbClamped = false;
                 _this.onValueChangedObservable = new BABYLON.Observable();
                 // Events
                 _this._pointerIsDown = false;
@@ -2760,6 +2772,20 @@ var BABYLON;
                 enumerable: true,
                 configurable: true
             });
+            Object.defineProperty(Slider.prototype, "isThumbClamped", {
+                get: function () {
+                    return this._isThumbClamped;
+                },
+                set: function (value) {
+                    if (this._isThumbClamped === value) {
+                        return;
+                    }
+                    this._isThumbClamped = value;
+                    this._markAsDirty();
+                },
+                enumerable: true,
+                configurable: true
+            });
             Slider.prototype._getTypeName = function () {
                 return "Slider";
             };
@@ -2770,12 +2796,6 @@ var BABYLON;
                     // Main bar
                     var effectiveThumbWidth;
                     var effectiveBarOffset;
-                    if (this.shadowBlur || this.shadowOffsetX || this.shadowOffsetY) {
-                        context.shadowColor = this.shadowColor;
-                        context.shadowBlur = this.shadowBlur;
-                        context.shadowOffsetX = this.shadowOffsetX;
-                        context.shadowOffsetY = this.shadowOffsetY;
-                    }
                     if (this._thumbWidth.isPixel) {
                         effectiveThumbWidth = Math.min(this._thumbWidth.getValue(this._host), this._currentMeasure.width);
                     }
@@ -2788,29 +2808,43 @@ var BABYLON;
                     else {
                         effectiveBarOffset = this._currentMeasure.height * this._barOffset.getValue(this._host);
                     }
-                    var left = this._currentMeasure.left + effectiveThumbWidth / 2;
+                    if (this.shadowBlur || this.shadowOffsetX || this.shadowOffsetY) {
+                        context.shadowColor = this.shadowColor;
+                        context.shadowBlur = this.shadowBlur;
+                        context.shadowOffsetX = this.shadowOffsetX;
+                        context.shadowOffsetY = this.shadowOffsetY;
+                    }
+                    var left = this._currentMeasure.left;
                     var width = this._currentMeasure.width - effectiveThumbWidth;
-                    var thumbPosition = (this._value - this._minimum) / (this._maximum - this._minimum) * width;
-                    // Bar
+                    var thumbPosition = ((this._value - this._minimum) / (this._maximum - this._minimum)) * width;
                     context.fillStyle = this._background;
-                    context.fillRect(left, this._currentMeasure.top + effectiveBarOffset, width, this._currentMeasure.height - effectiveBarOffset * 2);
+                    if (this.isThumbClamped) {
+                        context.fillRect(left, this._currentMeasure.top + effectiveBarOffset, width + effectiveThumbWidth, this._currentMeasure.height - effectiveBarOffset * 2);
+                    }
+                    else {
+                        context.fillRect(left + (effectiveThumbWidth / 2), this._currentMeasure.top + effectiveBarOffset, width, this._currentMeasure.height - effectiveBarOffset * 2);
+                    }
                     if (this.shadowBlur || this.shadowOffsetX || this.shadowOffsetY) {
                         context.shadowBlur = 0;
                         context.shadowOffsetX = 0;
                         context.shadowOffsetY = 0;
                     }
                     context.fillStyle = this.color;
-                    context.fillRect(left, this._currentMeasure.top + effectiveBarOffset, thumbPosition, this._currentMeasure.height - effectiveBarOffset * 2);
+                    if (this.isThumbClamped) {
+                        context.fillRect(left, this._currentMeasure.top + effectiveBarOffset, thumbPosition, this._currentMeasure.height - effectiveBarOffset * 2);
+                    }
+                    else {
+                        context.fillRect(left + (effectiveThumbWidth / 2), this._currentMeasure.top + effectiveBarOffset, thumbPosition, this._currentMeasure.height - effectiveBarOffset * 2);
+                    }
                     if (this.shadowBlur || this.shadowOffsetX || this.shadowOffsetY) {
                         context.shadowColor = this.shadowColor;
                         context.shadowBlur = this.shadowBlur;
                         context.shadowOffsetX = this.shadowOffsetX;
                         context.shadowOffsetY = this.shadowOffsetY;
                     }
-                    // Thumb
                     if (this._isThumbCircle) {
                         context.beginPath();
-                        context.arc(left + thumbPosition, this._currentMeasure.top + this._currentMeasure.height / 2, effectiveThumbWidth / 2, 0, 2 * Math.PI);
+                        context.arc(left + thumbPosition + (effectiveThumbWidth / 2), this._currentMeasure.top + this._currentMeasure.height / 2, effectiveThumbWidth / 2, 0, 2 * Math.PI);
                         context.fill();
                         if (this.shadowBlur || this.shadowOffsetX || this.shadowOffsetY) {
                             context.shadowBlur = 0;
@@ -2821,14 +2855,14 @@ var BABYLON;
                         context.stroke();
                     }
                     else {
-                        context.fillRect(left + thumbPosition - effectiveThumbWidth / 2, this._currentMeasure.top, effectiveThumbWidth, this._currentMeasure.height);
+                        context.fillRect(left + thumbPosition, this._currentMeasure.top, effectiveThumbWidth, this._currentMeasure.height);
                         if (this.shadowBlur || this.shadowOffsetX || this.shadowOffsetY) {
                             context.shadowBlur = 0;
                             context.shadowOffsetX = 0;
                             context.shadowOffsetY = 0;
                         }
                         context.strokeStyle = this._borderColor;
-                        context.strokeRect(left + thumbPosition - effectiveThumbWidth / 2, this._currentMeasure.top, effectiveThumbWidth, this._currentMeasure.height);
+                        context.strokeRect(left + thumbPosition, this._currentMeasure.top, effectiveThumbWidth, this._currentMeasure.height);
                     }
                 }
                 context.restore();
@@ -3151,7 +3185,16 @@ var BABYLON;
     (function (GUI) {
         var TextBlock = /** @class */ (function (_super) {
             __extends(TextBlock, _super);
-            function TextBlock(name, text) {
+            /**
+             * Creates a new TextBlock object
+             * @param name defines the name of the control
+             * @param text defines the text to display (emptry string by default)
+             */
+            function TextBlock(
+                /**
+                 * Defines the name of the control
+                 */
+                name, text) {
                 if (text === void 0) { text = ""; }
                 var _this = _super.call(this, name) || this;
                 _this.name = name;
@@ -3166,13 +3209,34 @@ var BABYLON;
                 * @type {BABYLON.Observable}
                 */
                 _this.onTextChangedObservable = new BABYLON.Observable();
+                /**
+                * An event triggered after the text was broken up into lines
+                * @type {BABYLON.Observable}
+                */
+                _this.onLinesReadyObservable = new BABYLON.Observable();
                 _this.text = text;
                 return _this;
             }
+            Object.defineProperty(TextBlock.prototype, "lines", {
+                /**
+                 * Return the line list (you may need to use the onLinesReadyObservable to make sure the list is ready)
+                 */
+                get: function () {
+                    return this._lines;
+                },
+                enumerable: true,
+                configurable: true
+            });
             Object.defineProperty(TextBlock.prototype, "resizeToFit", {
+                /**
+                 * Gets or sets an boolean indicating that the TextBlock will be resized to fit container
+                 */
                 get: function () {
                     return this._resizeToFit;
                 },
+                /**
+                 * Gets or sets an boolean indicating that the TextBlock will be resized to fit container
+                 */
                 set: function (value) {
                     this._resizeToFit = value;
                     if (this._resizeToFit) {
@@ -3184,9 +3248,15 @@ var BABYLON;
                 configurable: true
             });
             Object.defineProperty(TextBlock.prototype, "textWrapping", {
+                /**
+                 * Gets or sets a boolean indicating if text must be wrapped
+                 */
                 get: function () {
                     return this._textWrapping;
                 },
+                /**
+                 * Gets or sets a boolean indicating if text must be wrapped
+                 */
                 set: function (value) {
                     if (this._textWrapping === value) {
                         return;
@@ -3198,9 +3268,15 @@ var BABYLON;
                 configurable: true
             });
             Object.defineProperty(TextBlock.prototype, "text", {
+                /**
+                 * Gets or sets text to display
+                 */
                 get: function () {
                     return this._text;
                 },
+                /**
+                 * Gets or sets text to display
+                 */
                 set: function (value) {
                     if (this._text === value) {
                         return;
@@ -3213,9 +3289,15 @@ var BABYLON;
                 configurable: true
             });
             Object.defineProperty(TextBlock.prototype, "textHorizontalAlignment", {
+                /**
+                 * Gets or sets text horizontal alignment (BABYLON.GUI.Control.HORIZONTAL_ALIGNMENT_CENTER by default)
+                 */
                 get: function () {
                     return this._textHorizontalAlignment;
                 },
+                /**
+                 * Gets or sets text horizontal alignment (BABYLON.GUI.Control.HORIZONTAL_ALIGNMENT_CENTER by default)
+                 */
                 set: function (value) {
                     if (this._textHorizontalAlignment === value) {
                         return;
@@ -3227,9 +3309,15 @@ var BABYLON;
                 configurable: true
             });
             Object.defineProperty(TextBlock.prototype, "textVerticalAlignment", {
+                /**
+                 * Gets or sets text vertical alignment (BABYLON.GUI.Control.VERTICAL_ALIGNMENT_CENTER by default)
+                 */
                 get: function () {
                     return this._textVerticalAlignment;
                 },
+                /**
+                 * Gets or sets text vertical alignment (BABYLON.GUI.Control.VERTICAL_ALIGNMENT_CENTER by default)
+                 */
                 set: function (value) {
                     if (this._textVerticalAlignment === value) {
                         return;
@@ -3241,9 +3329,15 @@ var BABYLON;
                 configurable: true
             });
             Object.defineProperty(TextBlock.prototype, "lineSpacing", {
+                /**
+                 * Gets or sets line spacing value
+                 */
                 get: function () {
                     return this._lineSpacing.toString(this._host);
                 },
+                /**
+                 * Gets or sets line spacing value
+                 */
                 set: function (value) {
                     if (this._lineSpacing.fromString(value)) {
                         this._markAsDirty();
@@ -3277,6 +3371,7 @@ var BABYLON;
                 }
                 context.fillText(text, this._currentMeasure.left + x, y);
             };
+            /** @ignore */
             TextBlock.prototype._draw = function (parentMeasure, context) {
                 context.save();
                 this._applyStates(context);
@@ -3301,6 +3396,7 @@ var BABYLON;
                         this._lines.push(this._parseLine(_line, context));
                     }
                 }
+                this.onLinesReadyObservable.notifyObservers(this);
             };
             TextBlock.prototype._parseLine = function (line, context) {
                 if (line === void 0) { line = ''; }

Разлика између датотеке није приказан због своје велике величине
+ 2 - 2
dist/preview release/gui/babylon.gui.min.js


+ 72 - 1
dist/preview release/gui/babylon.gui.module.d.ts

@@ -62,6 +62,17 @@ declare module BABYLON.GUI {
         private _manageFocus();
         private _attachToOnPointerOut(scene);
         static CreateForMesh(mesh: AbstractMesh, width?: number, height?: number, supportPointerMove?: boolean): AdvancedDynamicTexture;
+        /**
+         * FullScreenUI is created in a layer. This allows it to be treated like any other layer.
+         * As such, if you have a multi camera setup, you can set the layerMask on the GUI as well.
+         * When the GUI is not Created as FullscreenUI it does not respect the layerMask.
+         * layerMask is set through advancedTexture.layer.layerMask
+         * @param name name for the Texture
+         * @param foreground render in foreground (default is true)
+         * @param scene scene to be rendered in
+         * @param sampling method for scaling to fit screen
+         * @returns AdvancedDynamicTexture
+         */
         static CreateFullscreenUI(name: string, foreground?: boolean, scene?: Nullable<Scene>, sampling?: number): AdvancedDynamicTexture;
     }
 }
@@ -447,6 +458,7 @@ declare module BABYLON.GUI {
         private _borderColor;
         private _barOffset;
         private _isThumbCircle;
+        private _isThumbClamped;
         onValueChangedObservable: Observable<number>;
         borderColor: string;
         background: string;
@@ -458,6 +470,7 @@ declare module BABYLON.GUI {
         maximum: number;
         value: number;
         isThumbCircle: boolean;
+        isThumbClamped: boolean;
         constructor(name?: string | undefined);
         protected _getTypeName(): string;
         _draw(parentMeasure: Measure, context: CanvasRenderingContext2D): void;
@@ -513,6 +526,9 @@ declare module BABYLON.GUI {
 
 declare module BABYLON.GUI {
     class TextBlock extends Control {
+        /**
+         * Defines the name of the control
+         */
         name: string | undefined;
         private _text;
         private _textWrapping;
@@ -526,15 +542,70 @@ declare module BABYLON.GUI {
         * @type {BABYLON.Observable}
         */
         onTextChangedObservable: Observable<TextBlock>;
+        /**
+        * An event triggered after the text was broken up into lines
+        * @type {BABYLON.Observable}
+        */
+        onLinesReadyObservable: Observable<TextBlock>;
+        /**
+         * Return the line list (you may need to use the onLinesReadyObservable to make sure the list is ready)
+         */
+        readonly lines: any[];
+        /**
+         * Gets or sets an boolean indicating that the TextBlock will be resized to fit container
+         */
+        /**
+         * Gets or sets an boolean indicating that the TextBlock will be resized to fit container
+         */
         resizeToFit: boolean;
+        /**
+         * Gets or sets a boolean indicating if text must be wrapped
+         */
+        /**
+         * Gets or sets a boolean indicating if text must be wrapped
+         */
         textWrapping: boolean;
+        /**
+         * Gets or sets text to display
+         */
+        /**
+         * Gets or sets text to display
+         */
         text: string;
+        /**
+         * Gets or sets text horizontal alignment (BABYLON.GUI.Control.HORIZONTAL_ALIGNMENT_CENTER by default)
+         */
+        /**
+         * Gets or sets text horizontal alignment (BABYLON.GUI.Control.HORIZONTAL_ALIGNMENT_CENTER by default)
+         */
         textHorizontalAlignment: number;
+        /**
+         * Gets or sets text vertical alignment (BABYLON.GUI.Control.VERTICAL_ALIGNMENT_CENTER by default)
+         */
+        /**
+         * Gets or sets text vertical alignment (BABYLON.GUI.Control.VERTICAL_ALIGNMENT_CENTER by default)
+         */
         textVerticalAlignment: number;
+        /**
+         * Gets or sets line spacing value
+         */
+        /**
+         * Gets or sets line spacing value
+         */
         lineSpacing: string | number;
-        constructor(name?: string | undefined, text?: string);
+        /**
+         * Creates a new TextBlock object
+         * @param name defines the name of the control
+         * @param text defines the text to display (emptry string by default)
+         */
+        constructor(
+            /**
+             * Defines the name of the control
+             */
+            name?: string | undefined, text?: string);
         protected _getTypeName(): string;
         private _drawText(text, textWidth, y, context);
+        /** @ignore */
         _draw(parentMeasure: Measure, context: CanvasRenderingContext2D): void;
         protected _additionalProcessing(parentMeasure: Measure, context: CanvasRenderingContext2D): void;
         protected _parseLine(line: string | undefined, context: CanvasRenderingContext2D): object;

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

@@ -4,7 +4,7 @@
     },
     "name": "babylonjs-gui",
     "description": "The Babylon.js GUI library is an extension you can use to generate interactive user interface. It is build on top of the DynamicTexture.",
-    "version": "3.2.0-alpha0",
+    "version": "3.2.0-alpha4",
     "repository": {
         "type": "git",
         "url": "https://github.com/BabylonJS/Babylon.js.git"
@@ -28,7 +28,7 @@
     ],
     "license": "Apache-2.0",
     "peerDependencies": {
-        "babylonjs": ">=3.1.0-alpha"
+        "babylonjs": ">=3.2.0-alpha"
     },
     "engines": {
         "node": "*"

Разлика између датотеке није приказан због своје велике величине
+ 4 - 4
dist/preview release/inspector/babylon.inspector.bundle.js


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

@@ -780,6 +780,7 @@ declare module INSPECTOR {
         static REFRESH_TIME: number;
         /** The list of data to update */
         private _updatableProperties;
+        private interval;
         constructor();
         static getInstance(): Scheduler;
         /** Add a property line to be updated every X ms */
@@ -787,6 +788,7 @@ declare module INSPECTOR {
         /** Removes the given property from the list of properties to update */
         remove(prop: PropertyLine): void;
         private _update();
+        dispose(): void;
     }
 }
 

+ 6 - 4
dist/preview release/inspector/babylon.inspector.js

@@ -289,6 +289,7 @@ var INSPECTOR;
                     }
                 }
             }
+            INSPECTOR.Scheduler.getInstance().dispose();
         };
         /** Open the inspector in a new popup
          * Set 'firstTime' to true if there is no inspector created beforehands
@@ -1041,9 +1042,7 @@ var INSPECTOR;
     var MeshAdapter = /** @class */ (function (_super) {
         __extends(MeshAdapter, _super);
         function MeshAdapter(mesh) {
-            var _this = _super.call(this, mesh) || this;
-            new BABYLON.Debug.AxesViewer(mesh.getScene());
-            return _this;
+            return _super.call(this, mesh) || this;
         }
         /** Returns the name displayed in the tree */
         MeshAdapter.prototype.id = function () {
@@ -2433,7 +2432,7 @@ var INSPECTOR;
             this.pause = false;
             /** The list of data to update */
             this._updatableProperties = [];
-            setInterval(this._update.bind(this), Scheduler.REFRESH_TIME);
+            this.interval = setInterval(this._update.bind(this), Scheduler.REFRESH_TIME);
         }
         Scheduler.getInstance = function () {
             if (!Scheduler._instance) {
@@ -2461,6 +2460,9 @@ var INSPECTOR;
                 }
             }
         };
+        Scheduler.prototype.dispose = function () {
+            window.clearInterval(this.interval);
+        };
         /** All properties are refreshed every 250ms */
         Scheduler.REFRESH_TIME = 250;
         return Scheduler;

Разлика између датотеке није приказан због своје велике величине
+ 4 - 4
dist/preview release/inspector/babylon.inspector.min.js


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

@@ -4,7 +4,7 @@
     },
     "name": "babylonjs-inspector",
     "description": "The Babylon.js inspector.",
-    "version": "3.2.0-alpha0",
+    "version": "3.2.0-alpha4",
     "repository": {
         "type": "git",
         "url": "https://github.com/BabylonJS/Babylon.js.git"
@@ -25,7 +25,7 @@
     ],
     "license": "Apache-2.0",
     "peerDependencies": {
-        "babylonjs": ">=3.1.0-alpha"
+        "babylonjs": ">=3.2.0-alpha"
     },
     "engines": {
         "node": "*"

+ 1 - 0
dist/preview release/loaders/babylon.glTF1FileLoader.d.ts

@@ -116,6 +116,7 @@ declare module BABYLON {
         dispose(): void;
         importMeshAsync(meshesNames: any, scene: Scene, data: any, rootUrl: string, onSuccess?: (meshes: AbstractMesh[], particleSystems: ParticleSystem[], skeletons: Skeleton[]) => void, onProgress?: (event: SceneLoaderProgressEvent) => void, onError?: (message: string, exception?: any) => void): void;
         loadAsync(scene: Scene, data: string | ArrayBuffer, rootUrl: string, onSuccess?: () => void, onProgress?: (event: SceneLoaderProgressEvent) => void, onError?: (message: string, exception?: any) => void): void;
+        loadAssetsAsync(scene: Scene, data: string | ArrayBuffer, rootUrl: string, onSuccess: (assets: AssetContainer) => void, onProgress?: (event: SceneLoaderProgressEvent) => void, onError?: (message: string, exception?: any) => void): void;
         canDirectLoad(data: string): boolean;
         rewriteRootURL: (rootUrl: string, responseURL?: string) => string;
         createPlugin(): ISceneLoaderPlugin | ISceneLoaderPluginAsync;

+ 22 - 0
dist/preview release/loaders/babylon.glTF1FileLoader.js

@@ -194,6 +194,28 @@ var BABYLON;
                 }
             }
         };
+        GLTFFileLoader.prototype.loadAssetsAsync = function (scene, data, rootUrl, onSuccess, onProgress, onError) {
+            try {
+                var loaderData = this._parse(data);
+                this._loader = this._getLoader(loaderData);
+                this._loader.importMeshAsync(null, scene, loaderData, rootUrl, function (meshes, particleSystems, skeletons) {
+                    var container = new BABYLON.AssetContainer(scene);
+                    Array.prototype.push.apply(container.meshes, meshes);
+                    Array.prototype.push.apply(container.particleSystems, particleSystems);
+                    Array.prototype.push.apply(container.skeletons, skeletons);
+                    container.removeAllFromScene();
+                    onSuccess(container);
+                }, onProgress, onError);
+            }
+            catch (e) {
+                if (onError) {
+                    onError(e.message, e);
+                }
+                else {
+                    BABYLON.Tools.Error(e.message);
+                }
+            }
+        };
         GLTFFileLoader.prototype.canDirectLoad = function (data) {
             return ((data.indexOf("scene") !== -1) && (data.indexOf("node") !== -1));
         };

Разлика између датотеке није приказан због своје велике величине
+ 2 - 2
dist/preview release/loaders/babylon.glTF1FileLoader.min.js


+ 2 - 1
dist/preview release/loaders/babylon.glTF2FileLoader.d.ts

@@ -116,6 +116,7 @@ declare module BABYLON {
         dispose(): void;
         importMeshAsync(meshesNames: any, scene: Scene, data: any, rootUrl: string, onSuccess?: (meshes: AbstractMesh[], particleSystems: ParticleSystem[], skeletons: Skeleton[]) => void, onProgress?: (event: SceneLoaderProgressEvent) => void, onError?: (message: string, exception?: any) => void): void;
         loadAsync(scene: Scene, data: string | ArrayBuffer, rootUrl: string, onSuccess?: () => void, onProgress?: (event: SceneLoaderProgressEvent) => void, onError?: (message: string, exception?: any) => void): void;
+        loadAssetsAsync(scene: Scene, data: string | ArrayBuffer, rootUrl: string, onSuccess: (assets: AssetContainer) => void, onProgress?: (event: SceneLoaderProgressEvent) => void, onError?: (message: string, exception?: any) => void): void;
         canDirectLoad(data: string): boolean;
         rewriteRootURL: (rootUrl: string, responseURL?: string) => string;
         createPlugin(): ISceneLoaderPlugin | ISceneLoaderPluginAsync;
@@ -224,7 +225,7 @@ declare module BABYLON.GLTF2 {
         channels: IGLTFAnimationChannel[];
         samplers: IGLTFAnimationSampler[];
         index: number;
-        targets: any[];
+        babylonAnimationGroup: AnimationGroup;
     }
     interface IGLTFAsset extends IGLTFChildRootProperty {
         copyright?: string;

+ 43 - 20
dist/preview release/loaders/babylon.glTF2FileLoader.js

@@ -194,6 +194,28 @@ var BABYLON;
                 }
             }
         };
+        GLTFFileLoader.prototype.loadAssetsAsync = function (scene, data, rootUrl, onSuccess, onProgress, onError) {
+            try {
+                var loaderData = this._parse(data);
+                this._loader = this._getLoader(loaderData);
+                this._loader.importMeshAsync(null, scene, loaderData, rootUrl, function (meshes, particleSystems, skeletons) {
+                    var container = new BABYLON.AssetContainer(scene);
+                    Array.prototype.push.apply(container.meshes, meshes);
+                    Array.prototype.push.apply(container.particleSystems, particleSystems);
+                    Array.prototype.push.apply(container.skeletons, skeletons);
+                    container.removeAllFromScene();
+                    onSuccess(container);
+                }, onProgress, onError);
+            }
+            catch (e) {
+                if (onError) {
+                    onError(e.message, e);
+                }
+                else {
+                    BABYLON.Tools.Error(e.message);
+                }
+            }
+        };
         GLTFFileLoader.prototype.canDirectLoad = function (data) {
             return ((data.indexOf("scene") !== -1) && (data.indexOf("node") !== -1));
         };
@@ -651,6 +673,10 @@ var BABYLON;
                 if (!animations) {
                     return;
                 }
+                for (var _i = 0, animations_1 = animations; _i < animations_1.length; _i++) {
+                    var animation = animations_1[_i];
+                    animation.babylonAnimationGroup.normalize();
+                }
                 switch (this.animationStartMode) {
                     case BABYLON.GLTFLoaderAnimationStartMode.NONE: {
                         // do nothing
@@ -658,19 +684,13 @@ var BABYLON;
                     }
                     case BABYLON.GLTFLoaderAnimationStartMode.FIRST: {
                         var animation = animations[0];
-                        for (var _i = 0, _a = animation.targets; _i < _a.length; _i++) {
-                            var target = _a[_i];
-                            this._babylonScene.beginAnimation(target, 0, Number.MAX_VALUE, true);
-                        }
+                        animation.babylonAnimationGroup.start(true);
                         break;
                     }
                     case BABYLON.GLTFLoaderAnimationStartMode.ALL: {
-                        for (var _b = 0, animations_1 = animations; _b < animations_1.length; _b++) {
-                            var animation = animations_1[_b];
-                            for (var _c = 0, _d = animation.targets; _c < _d.length; _c++) {
-                                var target = _d[_c];
-                                this._babylonScene.beginAnimation(target, 0, Number.MAX_VALUE, true);
-                            }
+                        for (var _a = 0, animations_2 = animations; _a < animations_2.length; _a++) {
+                            var animation = animations_2[_a];
+                            animation.babylonAnimationGroup.start(true);
                         }
                         break;
                     }
@@ -1282,7 +1302,7 @@ var BABYLON;
                 }
             };
             GLTFLoader.prototype._loadAnimation = function (context, animation) {
-                animation.targets = [];
+                animation.babylonAnimationGroup = new BABYLON.AnimationGroup(animation.name || "animation" + animation.index, this._babylonScene);
                 for (var index = 0; index < animation.channels.length; index++) {
                     var channel = GLTFLoader._GetProperty(animation.channels, index);
                     if (!channel) {
@@ -1375,6 +1395,14 @@ var BABYLON;
                     sampler.interpolation = sampler.interpolation || "LINEAR";
                     var getNextKey;
                     switch (sampler.interpolation) {
+                        case "STEP": {
+                            getNextKey = function (frameIndex) { return ({
+                                frame: inputData[frameIndex],
+                                value: getNextOutputValue(),
+                                interpolation: BABYLON.AnimationKeyInterpolation.STEP
+                            }); };
+                            break;
+                        }
                         case "LINEAR": {
                             getNextKey = function (frameIndex) { return ({
                                 frame: inputData[frameIndex],
@@ -1414,7 +1442,7 @@ var BABYLON;
                         var morphTargetManager = targetNode.babylonMesh.morphTargetManager;
                         var _loop_7 = function (targetIndex) {
                             var morphTarget = morphTargetManager.getTarget(targetIndex);
-                            var animationName = (animation.name || "anim" + animation.index) + "_" + targetIndex;
+                            var animationName = animation.babylonAnimationGroup.name + "_channel" + animation.babylonAnimationGroup.targetedAnimations.length;
                             var babylonAnimation = new BABYLON.Animation(animationName, targetPath, 1, animationType);
                             babylonAnimation.setKeys(keys.map(function (key) { return ({
                                 frame: key.frame,
@@ -1422,22 +1450,20 @@ var BABYLON;
                                 value: key.value[targetIndex],
                                 outTangent: key.outTangent ? key.outTangent[targetIndex] : undefined
                             }); }));
-                            morphTarget.animations.push(babylonAnimation);
-                            animation.targets.push(morphTarget);
+                            animation.babylonAnimationGroup.addTargetedAnimation(babylonAnimation, morphTarget);
                         };
                         for (var targetIndex = 0; targetIndex < morphTargetManager.numTargets; targetIndex++) {
                             _loop_7(targetIndex);
                         }
                     }
                     else {
-                        var animationName = animation.name || "anim" + animation.index;
+                        var animationName = animation.babylonAnimationGroup.name + "_channel" + animation.babylonAnimationGroup.targetedAnimations.length;
                         var babylonAnimation = new BABYLON.Animation(animationName, targetPath, 1, animationType);
                         babylonAnimation.setKeys(keys);
                         if (targetNode.babylonAnimationTargets) {
                             for (var _i = 0, _a = targetNode.babylonAnimationTargets; _i < _a.length; _i++) {
                                 var target = _a[_i];
-                                target.animations.push(babylonAnimation.clone());
-                                animation.targets.push(target);
+                                animation.babylonAnimationGroup.addTargetedAnimation(babylonAnimation, target);
                             }
                         }
                     }
@@ -1865,9 +1891,6 @@ var BABYLON;
                     });
                 });
                 this._requests.push(request);
-                request.onCompleteObservable.add(function () {
-                    _this._requests.splice(_this._requests.indexOf(request), 1);
-                });
             };
             GLTFLoader.prototype._tryCatchOnError = function (handler) {
                 if (this._disposed) {

Разлика између датотеке није приказан због своје велике величине
+ 2 - 2
dist/preview release/loaders/babylon.glTF2FileLoader.min.js


+ 2 - 1
dist/preview release/loaders/babylon.glTFFileLoader.d.ts

@@ -116,6 +116,7 @@ declare module BABYLON {
         dispose(): void;
         importMeshAsync(meshesNames: any, scene: Scene, data: any, rootUrl: string, onSuccess?: (meshes: AbstractMesh[], particleSystems: ParticleSystem[], skeletons: Skeleton[]) => void, onProgress?: (event: SceneLoaderProgressEvent) => void, onError?: (message: string, exception?: any) => void): void;
         loadAsync(scene: Scene, data: string | ArrayBuffer, rootUrl: string, onSuccess?: () => void, onProgress?: (event: SceneLoaderProgressEvent) => void, onError?: (message: string, exception?: any) => void): void;
+        loadAssetsAsync(scene: Scene, data: string | ArrayBuffer, rootUrl: string, onSuccess: (assets: AssetContainer) => void, onProgress?: (event: SceneLoaderProgressEvent) => void, onError?: (message: string, exception?: any) => void): void;
         canDirectLoad(data: string): boolean;
         rewriteRootURL: (rootUrl: string, responseURL?: string) => string;
         createPlugin(): ISceneLoaderPlugin | ISceneLoaderPluginAsync;
@@ -781,7 +782,7 @@ declare module BABYLON.GLTF2 {
         channels: IGLTFAnimationChannel[];
         samplers: IGLTFAnimationSampler[];
         index: number;
-        targets: any[];
+        babylonAnimationGroup: AnimationGroup;
     }
     interface IGLTFAsset extends IGLTFChildRootProperty {
         copyright?: string;

+ 43 - 20
dist/preview release/loaders/babylon.glTFFileLoader.js

@@ -194,6 +194,28 @@ var BABYLON;
                 }
             }
         };
+        GLTFFileLoader.prototype.loadAssetsAsync = function (scene, data, rootUrl, onSuccess, onProgress, onError) {
+            try {
+                var loaderData = this._parse(data);
+                this._loader = this._getLoader(loaderData);
+                this._loader.importMeshAsync(null, scene, loaderData, rootUrl, function (meshes, particleSystems, skeletons) {
+                    var container = new BABYLON.AssetContainer(scene);
+                    Array.prototype.push.apply(container.meshes, meshes);
+                    Array.prototype.push.apply(container.particleSystems, particleSystems);
+                    Array.prototype.push.apply(container.skeletons, skeletons);
+                    container.removeAllFromScene();
+                    onSuccess(container);
+                }, onProgress, onError);
+            }
+            catch (e) {
+                if (onError) {
+                    onError(e.message, e);
+                }
+                else {
+                    BABYLON.Tools.Error(e.message);
+                }
+            }
+        };
         GLTFFileLoader.prototype.canDirectLoad = function (data) {
             return ((data.indexOf("scene") !== -1) && (data.indexOf("node") !== -1));
         };
@@ -2817,6 +2839,10 @@ var BABYLON;
                 if (!animations) {
                     return;
                 }
+                for (var _i = 0, animations_1 = animations; _i < animations_1.length; _i++) {
+                    var animation = animations_1[_i];
+                    animation.babylonAnimationGroup.normalize();
+                }
                 switch (this.animationStartMode) {
                     case BABYLON.GLTFLoaderAnimationStartMode.NONE: {
                         // do nothing
@@ -2824,19 +2850,13 @@ var BABYLON;
                     }
                     case BABYLON.GLTFLoaderAnimationStartMode.FIRST: {
                         var animation = animations[0];
-                        for (var _i = 0, _a = animation.targets; _i < _a.length; _i++) {
-                            var target = _a[_i];
-                            this._babylonScene.beginAnimation(target, 0, Number.MAX_VALUE, true);
-                        }
+                        animation.babylonAnimationGroup.start(true);
                         break;
                     }
                     case BABYLON.GLTFLoaderAnimationStartMode.ALL: {
-                        for (var _b = 0, animations_1 = animations; _b < animations_1.length; _b++) {
-                            var animation = animations_1[_b];
-                            for (var _c = 0, _d = animation.targets; _c < _d.length; _c++) {
-                                var target = _d[_c];
-                                this._babylonScene.beginAnimation(target, 0, Number.MAX_VALUE, true);
-                            }
+                        for (var _a = 0, animations_2 = animations; _a < animations_2.length; _a++) {
+                            var animation = animations_2[_a];
+                            animation.babylonAnimationGroup.start(true);
                         }
                         break;
                     }
@@ -3448,7 +3468,7 @@ var BABYLON;
                 }
             };
             GLTFLoader.prototype._loadAnimation = function (context, animation) {
-                animation.targets = [];
+                animation.babylonAnimationGroup = new BABYLON.AnimationGroup(animation.name || "animation" + animation.index, this._babylonScene);
                 for (var index = 0; index < animation.channels.length; index++) {
                     var channel = GLTFLoader._GetProperty(animation.channels, index);
                     if (!channel) {
@@ -3541,6 +3561,14 @@ var BABYLON;
                     sampler.interpolation = sampler.interpolation || "LINEAR";
                     var getNextKey;
                     switch (sampler.interpolation) {
+                        case "STEP": {
+                            getNextKey = function (frameIndex) { return ({
+                                frame: inputData[frameIndex],
+                                value: getNextOutputValue(),
+                                interpolation: BABYLON.AnimationKeyInterpolation.STEP
+                            }); };
+                            break;
+                        }
                         case "LINEAR": {
                             getNextKey = function (frameIndex) { return ({
                                 frame: inputData[frameIndex],
@@ -3580,7 +3608,7 @@ var BABYLON;
                         var morphTargetManager = targetNode.babylonMesh.morphTargetManager;
                         var _loop_7 = function (targetIndex) {
                             var morphTarget = morphTargetManager.getTarget(targetIndex);
-                            var animationName = (animation.name || "anim" + animation.index) + "_" + targetIndex;
+                            var animationName = animation.babylonAnimationGroup.name + "_channel" + animation.babylonAnimationGroup.targetedAnimations.length;
                             var babylonAnimation = new BABYLON.Animation(animationName, targetPath, 1, animationType);
                             babylonAnimation.setKeys(keys.map(function (key) { return ({
                                 frame: key.frame,
@@ -3588,22 +3616,20 @@ var BABYLON;
                                 value: key.value[targetIndex],
                                 outTangent: key.outTangent ? key.outTangent[targetIndex] : undefined
                             }); }));
-                            morphTarget.animations.push(babylonAnimation);
-                            animation.targets.push(morphTarget);
+                            animation.babylonAnimationGroup.addTargetedAnimation(babylonAnimation, morphTarget);
                         };
                         for (var targetIndex = 0; targetIndex < morphTargetManager.numTargets; targetIndex++) {
                             _loop_7(targetIndex);
                         }
                     }
                     else {
-                        var animationName = animation.name || "anim" + animation.index;
+                        var animationName = animation.babylonAnimationGroup.name + "_channel" + animation.babylonAnimationGroup.targetedAnimations.length;
                         var babylonAnimation = new BABYLON.Animation(animationName, targetPath, 1, animationType);
                         babylonAnimation.setKeys(keys);
                         if (targetNode.babylonAnimationTargets) {
                             for (var _i = 0, _a = targetNode.babylonAnimationTargets; _i < _a.length; _i++) {
                                 var target = _a[_i];
-                                target.animations.push(babylonAnimation.clone());
-                                animation.targets.push(target);
+                                animation.babylonAnimationGroup.addTargetedAnimation(babylonAnimation, target);
                             }
                         }
                     }
@@ -4031,9 +4057,6 @@ var BABYLON;
                     });
                 });
                 this._requests.push(request);
-                request.onCompleteObservable.add(function () {
-                    _this._requests.splice(_this._requests.indexOf(request), 1);
-                });
             };
             GLTFLoader.prototype._tryCatchOnError = function (handler) {
                 if (this._disposed) {

Разлика између датотеке није приказан због своје велике величине
+ 3 - 3
dist/preview release/loaders/babylon.glTFFileLoader.min.js


+ 1 - 0
dist/preview release/loaders/babylon.objFileLoader.d.ts

@@ -58,6 +58,7 @@ declare module BABYLON {
         private _loadMTL(url, rootUrl, onSuccess);
         importMesh(meshesNames: any, scene: Scene, data: any, rootUrl: string, meshes: Nullable<AbstractMesh[]>, particleSystems: Nullable<ParticleSystem[]>, skeletons: Nullable<Skeleton[]>): boolean;
         load(scene: Scene, data: string, rootUrl: string): boolean;
+        loadAssets(scene: Scene, data: string, rootUrl: string, onError?: (message: string, exception?: any) => void): Nullable<AssetContainer>;
         /**
          * Read the OBJ file and create an Array of meshes.
          * Each mesh contains all information given by the OBJ and the MTL file.

+ 9 - 0
dist/preview release/loaders/babylon.objFileLoader.js

@@ -260,6 +260,15 @@ var BABYLON;
             //Get the 3D model
             return this.importMesh(null, scene, data, rootUrl, null, null, null);
         };
+        OBJFileLoader.prototype.loadAssets = function (scene, data, rootUrl, onError) {
+            var container = new BABYLON.AssetContainer(scene);
+            var result = this.importMesh(null, scene, data, rootUrl, container.meshes, null, null);
+            if (result) {
+                container.removeAllFromScene();
+                return container;
+            }
+            return null;
+        };
         /**
          * Read the OBJ file and create an Array of meshes.
          * Each mesh contains all information given by the OBJ and the MTL file.

Разлика између датотеке није приказан због своје велике величине
+ 1 - 1
dist/preview release/loaders/babylon.objFileLoader.min.js


+ 1 - 0
dist/preview release/loaders/babylon.stlFileLoader.d.ts

@@ -9,6 +9,7 @@ declare module BABYLON {
         extensions: ISceneLoaderPluginExtensions;
         importMesh(meshesNames: any, scene: Scene, data: any, rootUrl: string, meshes: Nullable<AbstractMesh[]>, particleSystems: Nullable<ParticleSystem[]>, skeletons: Nullable<Skeleton[]>): boolean;
         load(scene: Scene, data: any, rootUrl: string): boolean;
+        loadAssets(scene: Scene, data: string, rootUrl: string, onError?: (message: string, exception?: any) => void): Nullable<AssetContainer>;
         private isBinary(data);
         private parseBinary(mesh, data);
         private parseASCII(mesh, solidData);

+ 9 - 0
dist/preview release/loaders/babylon.stlFileLoader.js

@@ -70,6 +70,15 @@ var BABYLON;
             }
             return result;
         };
+        STLFileLoader.prototype.loadAssets = function (scene, data, rootUrl, onError) {
+            var container = new BABYLON.AssetContainer(scene);
+            var result = this.importMesh(null, scene, data, rootUrl, container.meshes, null, null);
+            if (result) {
+                container.removeAllFromScene();
+                return container;
+            }
+            return null;
+        };
         STLFileLoader.prototype.isBinary = function (data) {
             // check if file size is correct for binary stl
             var faceSize, nFaces, reader;

Разлика између датотеке није приказан због своје велике величине
+ 1 - 1
dist/preview release/loaders/babylon.stlFileLoader.min.js


+ 61 - 20
dist/preview release/loaders/babylonjs.loaders.js

@@ -89,6 +89,15 @@ var BABYLON;
             }
             return result;
         };
+        STLFileLoader.prototype.loadAssets = function (scene, data, rootUrl, onError) {
+            var container = new BABYLON.AssetContainer(scene);
+            var result = this.importMesh(null, scene, data, rootUrl, container.meshes, null, null);
+            if (result) {
+                container.removeAllFromScene();
+                return container;
+            }
+            return null;
+        };
         STLFileLoader.prototype.isBinary = function (data) {
             // check if file size is correct for binary stl
             var faceSize, nFaces, reader;
@@ -444,6 +453,15 @@ var BABYLON;
             //Get the 3D model
             return this.importMesh(null, scene, data, rootUrl, null, null, null);
         };
+        OBJFileLoader.prototype.loadAssets = function (scene, data, rootUrl, onError) {
+            var container = new BABYLON.AssetContainer(scene);
+            var result = this.importMesh(null, scene, data, rootUrl, container.meshes, null, null);
+            if (result) {
+                container.removeAllFromScene();
+                return container;
+            }
+            return null;
+        };
         /**
          * Read the OBJ file and create an Array of meshes.
          * Each mesh contains all information given by the OBJ and the MTL file.
@@ -1168,6 +1186,28 @@ var BABYLON;
                 }
             }
         };
+        GLTFFileLoader.prototype.loadAssetsAsync = function (scene, data, rootUrl, onSuccess, onProgress, onError) {
+            try {
+                var loaderData = this._parse(data);
+                this._loader = this._getLoader(loaderData);
+                this._loader.importMeshAsync(null, scene, loaderData, rootUrl, function (meshes, particleSystems, skeletons) {
+                    var container = new BABYLON.AssetContainer(scene);
+                    Array.prototype.push.apply(container.meshes, meshes);
+                    Array.prototype.push.apply(container.particleSystems, particleSystems);
+                    Array.prototype.push.apply(container.skeletons, skeletons);
+                    container.removeAllFromScene();
+                    onSuccess(container);
+                }, onProgress, onError);
+            }
+            catch (e) {
+                if (onError) {
+                    onError(e.message, e);
+                }
+                else {
+                    BABYLON.Tools.Error(e.message);
+                }
+            }
+        };
         GLTFFileLoader.prototype.canDirectLoad = function (data) {
             return ((data.indexOf("scene") !== -1) && (data.indexOf("node") !== -1));
         };
@@ -3773,6 +3813,10 @@ var BABYLON;
                 if (!animations) {
                     return;
                 }
+                for (var _i = 0, animations_1 = animations; _i < animations_1.length; _i++) {
+                    var animation = animations_1[_i];
+                    animation.babylonAnimationGroup.normalize();
+                }
                 switch (this.animationStartMode) {
                     case BABYLON.GLTFLoaderAnimationStartMode.NONE: {
                         // do nothing
@@ -3780,19 +3824,13 @@ var BABYLON;
                     }
                     case BABYLON.GLTFLoaderAnimationStartMode.FIRST: {
                         var animation = animations[0];
-                        for (var _i = 0, _a = animation.targets; _i < _a.length; _i++) {
-                            var target = _a[_i];
-                            this._babylonScene.beginAnimation(target, 0, Number.MAX_VALUE, true);
-                        }
+                        animation.babylonAnimationGroup.start(true);
                         break;
                     }
                     case BABYLON.GLTFLoaderAnimationStartMode.ALL: {
-                        for (var _b = 0, animations_1 = animations; _b < animations_1.length; _b++) {
-                            var animation = animations_1[_b];
-                            for (var _c = 0, _d = animation.targets; _c < _d.length; _c++) {
-                                var target = _d[_c];
-                                this._babylonScene.beginAnimation(target, 0, Number.MAX_VALUE, true);
-                            }
+                        for (var _a = 0, animations_2 = animations; _a < animations_2.length; _a++) {
+                            var animation = animations_2[_a];
+                            animation.babylonAnimationGroup.start(true);
                         }
                         break;
                     }
@@ -4404,7 +4442,7 @@ var BABYLON;
                 }
             };
             GLTFLoader.prototype._loadAnimation = function (context, animation) {
-                animation.targets = [];
+                animation.babylonAnimationGroup = new BABYLON.AnimationGroup(animation.name || "animation" + animation.index, this._babylonScene);
                 for (var index = 0; index < animation.channels.length; index++) {
                     var channel = GLTFLoader._GetProperty(animation.channels, index);
                     if (!channel) {
@@ -4497,6 +4535,14 @@ var BABYLON;
                     sampler.interpolation = sampler.interpolation || "LINEAR";
                     var getNextKey;
                     switch (sampler.interpolation) {
+                        case "STEP": {
+                            getNextKey = function (frameIndex) { return ({
+                                frame: inputData[frameIndex],
+                                value: getNextOutputValue(),
+                                interpolation: BABYLON.AnimationKeyInterpolation.STEP
+                            }); };
+                            break;
+                        }
                         case "LINEAR": {
                             getNextKey = function (frameIndex) { return ({
                                 frame: inputData[frameIndex],
@@ -4536,7 +4582,7 @@ var BABYLON;
                         var morphTargetManager = targetNode.babylonMesh.morphTargetManager;
                         var _loop_7 = function (targetIndex) {
                             var morphTarget = morphTargetManager.getTarget(targetIndex);
-                            var animationName = (animation.name || "anim" + animation.index) + "_" + targetIndex;
+                            var animationName = animation.babylonAnimationGroup.name + "_channel" + animation.babylonAnimationGroup.targetedAnimations.length;
                             var babylonAnimation = new BABYLON.Animation(animationName, targetPath, 1, animationType);
                             babylonAnimation.setKeys(keys.map(function (key) { return ({
                                 frame: key.frame,
@@ -4544,22 +4590,20 @@ var BABYLON;
                                 value: key.value[targetIndex],
                                 outTangent: key.outTangent ? key.outTangent[targetIndex] : undefined
                             }); }));
-                            morphTarget.animations.push(babylonAnimation);
-                            animation.targets.push(morphTarget);
+                            animation.babylonAnimationGroup.addTargetedAnimation(babylonAnimation, morphTarget);
                         };
                         for (var targetIndex = 0; targetIndex < morphTargetManager.numTargets; targetIndex++) {
                             _loop_7(targetIndex);
                         }
                     }
                     else {
-                        var animationName = animation.name || "anim" + animation.index;
+                        var animationName = animation.babylonAnimationGroup.name + "_channel" + animation.babylonAnimationGroup.targetedAnimations.length;
                         var babylonAnimation = new BABYLON.Animation(animationName, targetPath, 1, animationType);
                         babylonAnimation.setKeys(keys);
                         if (targetNode.babylonAnimationTargets) {
                             for (var _i = 0, _a = targetNode.babylonAnimationTargets; _i < _a.length; _i++) {
                                 var target = _a[_i];
-                                target.animations.push(babylonAnimation.clone());
-                                animation.targets.push(target);
+                                animation.babylonAnimationGroup.addTargetedAnimation(babylonAnimation, target);
                             }
                         }
                     }
@@ -4987,9 +5031,6 @@ var BABYLON;
                     });
                 });
                 this._requests.push(request);
-                request.onCompleteObservable.add(function () {
-                    _this._requests.splice(_this._requests.indexOf(request), 1);
-                });
             };
             GLTFLoader.prototype._tryCatchOnError = function (handler) {
                 if (this._disposed) {

Разлика између датотеке није приказан због своје велике величине
+ 3 - 3
dist/preview release/loaders/babylonjs.loaders.min.js


+ 4 - 1
dist/preview release/loaders/babylonjs.loaders.module.d.ts

@@ -15,6 +15,7 @@ declare module BABYLON {
         extensions: ISceneLoaderPluginExtensions;
         importMesh(meshesNames: any, scene: Scene, data: any, rootUrl: string, meshes: Nullable<AbstractMesh[]>, particleSystems: Nullable<ParticleSystem[]>, skeletons: Nullable<Skeleton[]>): boolean;
         load(scene: Scene, data: any, rootUrl: string): boolean;
+        loadAssets(scene: Scene, data: string, rootUrl: string, onError?: (message: string, exception?: any) => void): Nullable<AssetContainer>;
         private isBinary(data);
         private parseBinary(mesh, data);
         private parseASCII(mesh, solidData);
@@ -81,6 +82,7 @@ declare module BABYLON {
         private _loadMTL(url, rootUrl, onSuccess);
         importMesh(meshesNames: any, scene: Scene, data: any, rootUrl: string, meshes: Nullable<AbstractMesh[]>, particleSystems: Nullable<ParticleSystem[]>, skeletons: Nullable<Skeleton[]>): boolean;
         load(scene: Scene, data: string, rootUrl: string): boolean;
+        loadAssets(scene: Scene, data: string, rootUrl: string, onError?: (message: string, exception?: any) => void): Nullable<AssetContainer>;
         /**
          * Read the OBJ file and create an Array of meshes.
          * Each mesh contains all information given by the OBJ and the MTL file.
@@ -215,6 +217,7 @@ declare module BABYLON {
         dispose(): void;
         importMeshAsync(meshesNames: any, scene: Scene, data: any, rootUrl: string, onSuccess?: (meshes: AbstractMesh[], particleSystems: ParticleSystem[], skeletons: Skeleton[]) => void, onProgress?: (event: SceneLoaderProgressEvent) => void, onError?: (message: string, exception?: any) => void): void;
         loadAsync(scene: Scene, data: string | ArrayBuffer, rootUrl: string, onSuccess?: () => void, onProgress?: (event: SceneLoaderProgressEvent) => void, onError?: (message: string, exception?: any) => void): void;
+        loadAssetsAsync(scene: Scene, data: string | ArrayBuffer, rootUrl: string, onSuccess: (assets: AssetContainer) => void, onProgress?: (event: SceneLoaderProgressEvent) => void, onError?: (message: string, exception?: any) => void): void;
         canDirectLoad(data: string): boolean;
         rewriteRootURL: (rootUrl: string, responseURL?: string) => string;
         createPlugin(): ISceneLoaderPlugin | ISceneLoaderPluginAsync;
@@ -880,7 +883,7 @@ declare module BABYLON.GLTF2 {
         channels: IGLTFAnimationChannel[];
         samplers: IGLTFAnimationSampler[];
         index: number;
-        targets: any[];
+        babylonAnimationGroup: AnimationGroup;
     }
     interface IGLTFAsset extends IGLTFChildRootProperty {
         copyright?: string;

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

@@ -4,7 +4,7 @@
     },
     "name": "babylonjs-loaders",
     "description": "The Babylon.js file loaders library is an extension you can use to load different 3D file types into a Babylon scene.",
-    "version": "3.2.0-alpha0",
+    "version": "3.2.0-alpha4",
     "repository": {
         "type": "git",
         "url": "https://github.com/BabylonJS/Babylon.js.git"
@@ -27,7 +27,7 @@
     ],
     "license": "Apache-2.0",
     "peerDependencies": {
-        "babylonjs": ">=3.1.0-alpha"
+        "babylonjs": ">=3.2.0-alpha"
     },
     "engines": {
         "node": "*"

+ 1 - 1
dist/preview release/materialsLibrary/babylon.cellMaterial.js

@@ -102,7 +102,7 @@ var BABYLON;
             // Lights
             defines._needNormals = BABYLON.MaterialHelper.PrepareDefinesForLights(scene, mesh, defines, false, this._maxSimultaneousLights, this._disableLighting);
             // Values that need to be evaluated on every frame
-            BABYLON.MaterialHelper.PrepareDefinesForFrameBoundValues(scene, engine, defines, useInstances ? true : false);
+            BABYLON.MaterialHelper.PrepareDefinesForFrameBoundValues(scene, engine, defines, useInstances ? true : false, this._shouldTurnAlphaTestOn(mesh));
             // Attribs
             BABYLON.MaterialHelper.PrepareDefinesForAttributes(mesh, defines, true, true);
             // Get correct effect      

Разлика између датотеке није приказан због своје велике величине
+ 1 - 1
dist/preview release/materialsLibrary/babylon.cellMaterial.min.js


+ 1 - 0
dist/preview release/materialsLibrary/babylon.customMaterial.d.ts

@@ -222,6 +222,7 @@ declare module BABYLON {
          * Sets the Color Grading 2D Lookup Texture.
          */
         cameraColorGradingTexture: Nullable<BaseTexture>;
+        protected _shouldTurnAlphaTestOn(mesh: AbstractMesh): boolean;
         customShaderNameResolve: (shaderName: string, uniforms: string[], uniformBuffers: string[], samplers: string[], defines: StandardMaterialDefines_OldVer) => string;
         protected _renderTargets: SmartArray<RenderTargetTexture>;
         protected _worldViewProjectionMatrix: Matrix;

+ 4 - 1
dist/preview release/materialsLibrary/babylon.customMaterial.js

@@ -315,6 +315,9 @@ var BABYLON;
             enumerable: true,
             configurable: true
         });
+        StandardMaterial_OldVer.prototype._shouldTurnAlphaTestOn = function (mesh) {
+            return (!this.needAlphaBlendingForMesh(mesh) && this.needAlphaTesting());
+        };
         StandardMaterial_OldVer.prototype.getClassName = function () {
             return "StandardMaterial_OldVer";
         };
@@ -564,7 +567,7 @@ var BABYLON;
             // Attribs
             BABYLON.MaterialHelper.PrepareDefinesForAttributes(mesh, defines, true, true, true);
             // Values that need to be evaluated on every frame
-            BABYLON.MaterialHelper.PrepareDefinesForFrameBoundValues(scene, engine, defines, useInstances ? true : false);
+            BABYLON.MaterialHelper.PrepareDefinesForFrameBoundValues(scene, engine, defines, useInstances ? true : false, this._shouldTurnAlphaTestOn(mesh));
             // Get correct effect      
             if (defines.isDirty) {
                 defines.markAsProcessed();

Разлика између датотеке није приказан због своје велике величине
+ 2 - 2
dist/preview release/materialsLibrary/babylon.customMaterial.min.js


+ 1 - 1
dist/preview release/materialsLibrary/babylon.fireMaterial.js

@@ -94,7 +94,7 @@ var BABYLON;
                 defines.FOG = (scene.fogEnabled && mesh.applyFog && scene.fogMode !== BABYLON.Scene.FOGMODE_NONE && this.fogEnabled);
             }
             // Values that need to be evaluated on every frame
-            BABYLON.MaterialHelper.PrepareDefinesForFrameBoundValues(scene, engine, defines, useInstances ? true : false);
+            BABYLON.MaterialHelper.PrepareDefinesForFrameBoundValues(scene, engine, defines, useInstances ? true : false, this._shouldTurnAlphaTestOn(mesh));
             // Attribs
             BABYLON.MaterialHelper.PrepareDefinesForAttributes(mesh, defines, false, true);
             // Get correct effect      

Разлика између датотеке није приказан због своје велике величине
+ 1 - 1
dist/preview release/materialsLibrary/babylon.fireMaterial.min.js


+ 1 - 1
dist/preview release/materialsLibrary/babylon.furMaterial.js

@@ -147,7 +147,7 @@ var BABYLON;
             // Lights
             defines._needNormals = BABYLON.MaterialHelper.PrepareDefinesForLights(scene, mesh, defines, false, this._maxSimultaneousLights, this._disableLighting);
             // Values that need to be evaluated on every frame
-            BABYLON.MaterialHelper.PrepareDefinesForFrameBoundValues(scene, engine, defines, useInstances ? true : false);
+            BABYLON.MaterialHelper.PrepareDefinesForFrameBoundValues(scene, engine, defines, useInstances ? true : false, this._shouldTurnAlphaTestOn(mesh));
             // Attribs
             BABYLON.MaterialHelper.PrepareDefinesForAttributes(mesh, defines, true, true);
             // Get correct effect      

Разлика између датотеке није приказан због своје велике величине
+ 1 - 1
dist/preview release/materialsLibrary/babylon.furMaterial.min.js


+ 1 - 1
dist/preview release/materialsLibrary/babylon.gradientMaterial.js

@@ -118,7 +118,7 @@ var BABYLON;
                 }
             }
             var engine = scene.getEngine();
-            BABYLON.MaterialHelper.PrepareDefinesForFrameBoundValues(scene, engine, defines, useInstances ? true : false);
+            BABYLON.MaterialHelper.PrepareDefinesForFrameBoundValues(scene, engine, defines, useInstances ? true : false, this._shouldTurnAlphaTestOn(mesh));
             BABYLON.MaterialHelper.PrepareDefinesForMisc(mesh, scene, false, this.pointsCloud, this.fogEnabled, defines);
             defines._needNormals = BABYLON.MaterialHelper.PrepareDefinesForLights(scene, mesh, defines, false, this._maxSimultaneousLights);
             // Attribs

Разлика између датотеке није приказан због своје велике величине
+ 1 - 1
dist/preview release/materialsLibrary/babylon.gradientMaterial.min.js


+ 1 - 1
dist/preview release/materialsLibrary/babylon.lavaMaterial.js

@@ -135,7 +135,7 @@ var BABYLON;
             // Lights
             defines._needNormals = BABYLON.MaterialHelper.PrepareDefinesForLights(scene, mesh, defines, false, this._maxSimultaneousLights, this._disableLighting);
             // Values that need to be evaluated on every frame
-            BABYLON.MaterialHelper.PrepareDefinesForFrameBoundValues(scene, engine, defines, useInstances ? true : false);
+            BABYLON.MaterialHelper.PrepareDefinesForFrameBoundValues(scene, engine, defines, useInstances ? true : false, this._shouldTurnAlphaTestOn(mesh));
             // Attribs
             BABYLON.MaterialHelper.PrepareDefinesForAttributes(mesh, defines, true, true);
             // Get correct effect      

Разлика између датотеке није приказан због своје велике величине
+ 1 - 1
dist/preview release/materialsLibrary/babylon.lavaMaterial.min.js


+ 1 - 1
dist/preview release/materialsLibrary/babylon.normalMaterial.js

@@ -129,7 +129,7 @@ var BABYLON;
             // Lights
             defines._needNormals = BABYLON.MaterialHelper.PrepareDefinesForLights(scene, mesh, defines, false, this._maxSimultaneousLights, this._disableLighting);
             // Values that need to be evaluated on every frame
-            BABYLON.MaterialHelper.PrepareDefinesForFrameBoundValues(scene, engine, defines, useInstances ? true : false);
+            BABYLON.MaterialHelper.PrepareDefinesForFrameBoundValues(scene, engine, defines, useInstances ? true : false, this._shouldTurnAlphaTestOn(mesh));
             // Attribs
             BABYLON.MaterialHelper.PrepareDefinesForAttributes(mesh, defines, true, true);
             // Get correct effect      

Разлика између датотеке није приказан због своје велике величине
+ 1 - 1
dist/preview release/materialsLibrary/babylon.normalMaterial.min.js


+ 1 - 1
dist/preview release/materialsLibrary/babylon.shadowOnlyMaterial.js

@@ -86,7 +86,7 @@ var BABYLON;
                     }
                 }
             }
-            BABYLON.MaterialHelper.PrepareDefinesForFrameBoundValues(scene, engine, defines, useInstances ? true : false);
+            BABYLON.MaterialHelper.PrepareDefinesForFrameBoundValues(scene, engine, defines, useInstances ? true : false, this._shouldTurnAlphaTestOn(mesh));
             BABYLON.MaterialHelper.PrepareDefinesForMisc(mesh, scene, false, this.pointsCloud, this.fogEnabled, defines);
             defines._needNormals = BABYLON.MaterialHelper.PrepareDefinesForLights(scene, mesh, defines, false, 1);
             // Attribs

Разлика између датотеке није приказан због своје велике величине
+ 1 - 1
dist/preview release/materialsLibrary/babylon.shadowOnlyMaterial.min.js


+ 1 - 1
dist/preview release/materialsLibrary/babylon.simpleMaterial.js

@@ -96,7 +96,7 @@ var BABYLON;
             // Lights
             defines._needNormals = BABYLON.MaterialHelper.PrepareDefinesForLights(scene, mesh, defines, false, this._maxSimultaneousLights, this._disableLighting);
             // Values that need to be evaluated on every frame
-            BABYLON.MaterialHelper.PrepareDefinesForFrameBoundValues(scene, engine, defines, useInstances ? true : false);
+            BABYLON.MaterialHelper.PrepareDefinesForFrameBoundValues(scene, engine, defines, useInstances ? true : false, this._shouldTurnAlphaTestOn(mesh));
             // Attribs
             BABYLON.MaterialHelper.PrepareDefinesForAttributes(mesh, defines, true, true);
             // Get correct effect      

Разлика између датотеке није приказан због своје велике величине
+ 1 - 1
dist/preview release/materialsLibrary/babylon.simpleMaterial.min.js


+ 1 - 1
dist/preview release/materialsLibrary/babylon.terrainMaterial.js

@@ -102,7 +102,7 @@ var BABYLON;
             // Lights
             defines._needNormals = BABYLON.MaterialHelper.PrepareDefinesForLights(scene, mesh, defines, false, this._maxSimultaneousLights, this._disableLighting);
             // Values that need to be evaluated on every frame
-            BABYLON.MaterialHelper.PrepareDefinesForFrameBoundValues(scene, engine, defines, useInstances ? true : false);
+            BABYLON.MaterialHelper.PrepareDefinesForFrameBoundValues(scene, engine, defines, useInstances ? true : false, this._shouldTurnAlphaTestOn(mesh));
             // Attribs
             BABYLON.MaterialHelper.PrepareDefinesForAttributes(mesh, defines, true, true);
             // Get correct effect      

Разлика између датотеке није приказан због своје велике величине
+ 1 - 1
dist/preview release/materialsLibrary/babylon.terrainMaterial.min.js


+ 1 - 1
dist/preview release/materialsLibrary/babylon.triPlanarMaterial.js

@@ -121,7 +121,7 @@ var BABYLON;
             // Lights
             defines._needNormals = BABYLON.MaterialHelper.PrepareDefinesForLights(scene, mesh, defines, false, this._maxSimultaneousLights, this._disableLighting);
             // Values that need to be evaluated on every frame
-            BABYLON.MaterialHelper.PrepareDefinesForFrameBoundValues(scene, engine, defines, useInstances ? true : false);
+            BABYLON.MaterialHelper.PrepareDefinesForFrameBoundValues(scene, engine, defines, useInstances ? true : false, this._shouldTurnAlphaTestOn(mesh));
             // Attribs
             BABYLON.MaterialHelper.PrepareDefinesForAttributes(mesh, defines, true, true);
             // Get correct effect      

Разлика између датотеке није приказан због своје велике величине
+ 1 - 1
dist/preview release/materialsLibrary/babylon.triPlanarMaterial.min.js


+ 1 - 1
dist/preview release/materialsLibrary/babylon.waterMaterial.js

@@ -228,7 +228,7 @@ var BABYLON;
                     }
                 }
             }
-            BABYLON.MaterialHelper.PrepareDefinesForFrameBoundValues(scene, engine, defines, useInstances ? true : false);
+            BABYLON.MaterialHelper.PrepareDefinesForFrameBoundValues(scene, engine, defines, useInstances ? true : false, this._shouldTurnAlphaTestOn(mesh));
             BABYLON.MaterialHelper.PrepareDefinesForMisc(mesh, scene, this._useLogarithmicDepth, this.pointsCloud, this.fogEnabled, defines);
             if (defines._areMiscDirty) {
                 if (this._fresnelSeparate) {

Разлика између датотеке није приказан због своје велике величине
+ 1 - 1
dist/preview release/materialsLibrary/babylon.waterMaterial.min.js


+ 15 - 12
dist/preview release/materialsLibrary/babylonjs.materials.js

@@ -96,7 +96,7 @@ var BABYLON;
                     }
                 }
             }
-            BABYLON.MaterialHelper.PrepareDefinesForFrameBoundValues(scene, engine, defines, useInstances ? true : false);
+            BABYLON.MaterialHelper.PrepareDefinesForFrameBoundValues(scene, engine, defines, useInstances ? true : false, this._shouldTurnAlphaTestOn(mesh));
             BABYLON.MaterialHelper.PrepareDefinesForMisc(mesh, scene, false, this.pointsCloud, this.fogEnabled, defines);
             defines._needNormals = BABYLON.MaterialHelper.PrepareDefinesForLights(scene, mesh, defines, false, 1);
             // Attribs
@@ -326,7 +326,7 @@ var BABYLON;
                 }
             }
             var engine = scene.getEngine();
-            BABYLON.MaterialHelper.PrepareDefinesForFrameBoundValues(scene, engine, defines, useInstances ? true : false);
+            BABYLON.MaterialHelper.PrepareDefinesForFrameBoundValues(scene, engine, defines, useInstances ? true : false, this._shouldTurnAlphaTestOn(mesh));
             BABYLON.MaterialHelper.PrepareDefinesForMisc(mesh, scene, false, this.pointsCloud, this.fogEnabled, defines);
             defines._needNormals = BABYLON.MaterialHelper.PrepareDefinesForLights(scene, mesh, defines, false, this._maxSimultaneousLights);
             // Attribs
@@ -615,7 +615,7 @@ var BABYLON;
             // Lights
             defines._needNormals = BABYLON.MaterialHelper.PrepareDefinesForLights(scene, mesh, defines, false, this._maxSimultaneousLights, this._disableLighting);
             // Values that need to be evaluated on every frame
-            BABYLON.MaterialHelper.PrepareDefinesForFrameBoundValues(scene, engine, defines, useInstances ? true : false);
+            BABYLON.MaterialHelper.PrepareDefinesForFrameBoundValues(scene, engine, defines, useInstances ? true : false, this._shouldTurnAlphaTestOn(mesh));
             // Attribs
             BABYLON.MaterialHelper.PrepareDefinesForAttributes(mesh, defines, true, true);
             // Get correct effect      
@@ -926,7 +926,7 @@ var BABYLON;
             // Lights
             defines._needNormals = BABYLON.MaterialHelper.PrepareDefinesForLights(scene, mesh, defines, false, this._maxSimultaneousLights, this._disableLighting);
             // Values that need to be evaluated on every frame
-            BABYLON.MaterialHelper.PrepareDefinesForFrameBoundValues(scene, engine, defines, useInstances ? true : false);
+            BABYLON.MaterialHelper.PrepareDefinesForFrameBoundValues(scene, engine, defines, useInstances ? true : false, this._shouldTurnAlphaTestOn(mesh));
             // Attribs
             BABYLON.MaterialHelper.PrepareDefinesForAttributes(mesh, defines, true, true);
             // Get correct effect      
@@ -1238,7 +1238,7 @@ var BABYLON;
             // Lights
             defines._needNormals = BABYLON.MaterialHelper.PrepareDefinesForLights(scene, mesh, defines, false, this._maxSimultaneousLights, this._disableLighting);
             // Values that need to be evaluated on every frame
-            BABYLON.MaterialHelper.PrepareDefinesForFrameBoundValues(scene, engine, defines, useInstances ? true : false);
+            BABYLON.MaterialHelper.PrepareDefinesForFrameBoundValues(scene, engine, defines, useInstances ? true : false, this._shouldTurnAlphaTestOn(mesh));
             // Attribs
             BABYLON.MaterialHelper.PrepareDefinesForAttributes(mesh, defines, true, true);
             // Get correct effect      
@@ -1642,7 +1642,7 @@ var BABYLON;
                     }
                 }
             }
-            BABYLON.MaterialHelper.PrepareDefinesForFrameBoundValues(scene, engine, defines, useInstances ? true : false);
+            BABYLON.MaterialHelper.PrepareDefinesForFrameBoundValues(scene, engine, defines, useInstances ? true : false, this._shouldTurnAlphaTestOn(mesh));
             BABYLON.MaterialHelper.PrepareDefinesForMisc(mesh, scene, this._useLogarithmicDepth, this.pointsCloud, this.fogEnabled, defines);
             if (defines._areMiscDirty) {
                 if (this._fresnelSeparate) {
@@ -2124,7 +2124,7 @@ var BABYLON;
                 defines.FOG = (scene.fogEnabled && mesh.applyFog && scene.fogMode !== BABYLON.Scene.FOGMODE_NONE && this.fogEnabled);
             }
             // Values that need to be evaluated on every frame
-            BABYLON.MaterialHelper.PrepareDefinesForFrameBoundValues(scene, engine, defines, useInstances ? true : false);
+            BABYLON.MaterialHelper.PrepareDefinesForFrameBoundValues(scene, engine, defines, useInstances ? true : false, this._shouldTurnAlphaTestOn(mesh));
             // Attribs
             BABYLON.MaterialHelper.PrepareDefinesForAttributes(mesh, defines, false, true);
             // Get correct effect      
@@ -2498,7 +2498,7 @@ var BABYLON;
             // Lights
             defines._needNormals = BABYLON.MaterialHelper.PrepareDefinesForLights(scene, mesh, defines, false, this._maxSimultaneousLights, this._disableLighting);
             // Values that need to be evaluated on every frame
-            BABYLON.MaterialHelper.PrepareDefinesForFrameBoundValues(scene, engine, defines, useInstances ? true : false);
+            BABYLON.MaterialHelper.PrepareDefinesForFrameBoundValues(scene, engine, defines, useInstances ? true : false, this._shouldTurnAlphaTestOn(mesh));
             // Attribs
             BABYLON.MaterialHelper.PrepareDefinesForAttributes(mesh, defines, true, true);
             // Get correct effect      
@@ -2915,7 +2915,7 @@ var BABYLON;
             // Lights
             defines._needNormals = BABYLON.MaterialHelper.PrepareDefinesForLights(scene, mesh, defines, false, this._maxSimultaneousLights, this._disableLighting);
             // Values that need to be evaluated on every frame
-            BABYLON.MaterialHelper.PrepareDefinesForFrameBoundValues(scene, engine, defines, useInstances ? true : false);
+            BABYLON.MaterialHelper.PrepareDefinesForFrameBoundValues(scene, engine, defines, useInstances ? true : false, this._shouldTurnAlphaTestOn(mesh));
             // Attribs
             BABYLON.MaterialHelper.PrepareDefinesForAttributes(mesh, defines, true, true);
             // Get correct effect      
@@ -3321,7 +3321,7 @@ var BABYLON;
             // Lights
             defines._needNormals = BABYLON.MaterialHelper.PrepareDefinesForLights(scene, mesh, defines, false, this._maxSimultaneousLights, this._disableLighting);
             // Values that need to be evaluated on every frame
-            BABYLON.MaterialHelper.PrepareDefinesForFrameBoundValues(scene, engine, defines, useInstances ? true : false);
+            BABYLON.MaterialHelper.PrepareDefinesForFrameBoundValues(scene, engine, defines, useInstances ? true : false, this._shouldTurnAlphaTestOn(mesh));
             // Attribs
             BABYLON.MaterialHelper.PrepareDefinesForAttributes(mesh, defines, true, true);
             // Get correct effect      
@@ -4311,6 +4311,9 @@ var BABYLON;
             enumerable: true,
             configurable: true
         });
+        StandardMaterial_OldVer.prototype._shouldTurnAlphaTestOn = function (mesh) {
+            return (!this.needAlphaBlendingForMesh(mesh) && this.needAlphaTesting());
+        };
         StandardMaterial_OldVer.prototype.getClassName = function () {
             return "StandardMaterial_OldVer";
         };
@@ -4560,7 +4563,7 @@ var BABYLON;
             // Attribs
             BABYLON.MaterialHelper.PrepareDefinesForAttributes(mesh, defines, true, true, true);
             // Values that need to be evaluated on every frame
-            BABYLON.MaterialHelper.PrepareDefinesForFrameBoundValues(scene, engine, defines, useInstances ? true : false);
+            BABYLON.MaterialHelper.PrepareDefinesForFrameBoundValues(scene, engine, defines, useInstances ? true : false, this._shouldTurnAlphaTestOn(mesh));
             // Get correct effect      
             if (defines.isDirty) {
                 defines.markAsProcessed();
@@ -6150,7 +6153,7 @@ var BABYLON;
             // Lights
             defines._needNormals = BABYLON.MaterialHelper.PrepareDefinesForLights(scene, mesh, defines, false, this._maxSimultaneousLights, this._disableLighting);
             // Values that need to be evaluated on every frame
-            BABYLON.MaterialHelper.PrepareDefinesForFrameBoundValues(scene, engine, defines, useInstances ? true : false);
+            BABYLON.MaterialHelper.PrepareDefinesForFrameBoundValues(scene, engine, defines, useInstances ? true : false, this._shouldTurnAlphaTestOn(mesh));
             // Attribs
             BABYLON.MaterialHelper.PrepareDefinesForAttributes(mesh, defines, true, true);
             // Get correct effect      

Разлика између датотеке није приказан због своје велике величине
+ 7 - 7
dist/preview release/materialsLibrary/babylonjs.materials.min.js


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

@@ -728,6 +728,7 @@ declare module BABYLON {
          * Sets the Color Grading 2D Lookup Texture.
          */
         cameraColorGradingTexture: Nullable<BaseTexture>;
+        protected _shouldTurnAlphaTestOn(mesh: AbstractMesh): boolean;
         customShaderNameResolve: (shaderName: string, uniforms: string[], uniformBuffers: string[], samplers: string[], defines: StandardMaterialDefines_OldVer) => string;
         protected _renderTargets: SmartArray<RenderTargetTexture>;
         protected _worldViewProjectionMatrix: Matrix;

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


Неке датотеке нису приказане због велике количине промена