浏览代码

Merge master in

Sebastien Vandenberghe 6 年之前
父节点
当前提交
53d6fd3904
共有 100 个文件被更改,包括 7775 次插入2106 次删除
  1. 13 0
      .vscode/launch.json
  2. 632 178
      Playground/babylon.d.txt
  3. 4 4
      Playground/debug.html
  4. 1 2
      Playground/js/config_versions.js
  5. 47 8
      Playground/js/main.js
  6. 1 1
      Playground/js/settingsPG.js
  7. 1 2
      dist/gui/readme.md
  8. 646 180
      dist/preview release/babylon.d.ts
  9. 2 2
      dist/preview release/babylon.js
  10. 1980 276
      dist/preview release/babylon.max.js
  11. 1 1
      dist/preview release/babylon.max.js.map
  12. 1349 388
      dist/preview release/babylon.module.d.ts
  13. 646 180
      dist/preview release/documentation.d.ts
  14. 1 1
      dist/preview release/glTF2Interface/package.json
  15. 41 41
      dist/preview release/gui/babylon.gui.js
  16. 1 1
      dist/preview release/gui/babylon.gui.js.map
  17. 1 1
      dist/preview release/gui/babylon.gui.min.js
  18. 2 2
      dist/preview release/gui/package.json
  19. 1 1
      dist/preview release/inspector/babylon.inspector.bundle.js
  20. 8 4
      dist/preview release/inspector/babylon.inspector.bundle.max.js
  21. 1 1
      dist/preview release/inspector/babylon.inspector.bundle.max.js.map
  22. 7 7
      dist/preview release/inspector/package.json
  23. 8 1
      dist/preview release/loaders/babylon.glTF2FileLoader.js
  24. 1 1
      dist/preview release/loaders/babylon.glTF2FileLoader.js.map
  25. 1 1
      dist/preview release/loaders/babylon.glTF2FileLoader.min.js
  26. 8 1
      dist/preview release/loaders/babylon.glTFFileLoader.js
  27. 1 1
      dist/preview release/loaders/babylon.glTFFileLoader.js.map
  28. 1 1
      dist/preview release/loaders/babylon.glTFFileLoader.min.js
  29. 1 1
      dist/preview release/loaders/babylon.objFileLoader.js
  30. 1 1
      dist/preview release/loaders/babylon.objFileLoader.js.map
  31. 1 1
      dist/preview release/loaders/babylon.objFileLoader.min.js
  32. 1 0
      dist/preview release/loaders/babylon.stlFileLoader.js
  33. 1 1
      dist/preview release/loaders/babylon.stlFileLoader.js.map
  34. 10 2
      dist/preview release/loaders/babylonjs.loaders.js
  35. 1 1
      dist/preview release/loaders/babylonjs.loaders.js.map
  36. 2 2
      dist/preview release/loaders/babylonjs.loaders.min.js
  37. 1 0
      dist/preview release/loaders/babylonjs.loaders.module.d.ts
  38. 3 3
      dist/preview release/loaders/package.json
  39. 11 4
      dist/preview release/materialsLibrary/babylon.gridMaterial.js
  40. 1 1
      dist/preview release/materialsLibrary/babylon.gridMaterial.js.map
  41. 1 1
      dist/preview release/materialsLibrary/babylon.gridMaterial.min.js
  42. 11 4
      dist/preview release/materialsLibrary/babylonjs.materials.js
  43. 1 1
      dist/preview release/materialsLibrary/babylonjs.materials.js.map
  44. 1 1
      dist/preview release/materialsLibrary/babylonjs.materials.min.js
  45. 2 0
      dist/preview release/materialsLibrary/babylonjs.materials.module.d.ts
  46. 2 2
      dist/preview release/materialsLibrary/package.json
  47. 19 2
      dist/preview release/nodeEditor/babylon.nodeEditor.d.ts
  48. 7 7
      dist/preview release/nodeEditor/babylon.nodeEditor.js
  49. 149 89
      dist/preview release/nodeEditor/babylon.nodeEditor.max.js
  50. 1 1
      dist/preview release/nodeEditor/babylon.nodeEditor.max.js.map
  51. 44 4
      dist/preview release/nodeEditor/babylon.nodeEditor.module.d.ts
  52. 2 2
      dist/preview release/nodeEditor/package.json
  53. 1 1
      dist/preview release/package.json
  54. 1 1
      dist/preview release/packagesSizeBaseLine.json
  55. 2 2
      dist/preview release/postProcessesLibrary/package.json
  56. 2 2
      dist/preview release/proceduralTexturesLibrary/package.json
  57. 8 8
      dist/preview release/recast.js
  58. 3 3
      dist/preview release/serializers/package.json
  59. 1349 388
      dist/preview release/viewer/babylon.module.d.ts
  60. 108 84
      dist/preview release/viewer/babylon.viewer.js
  61. 2 2
      dist/preview release/viewer/babylon.viewer.max.js
  62. 1 0
      dist/preview release/viewer/babylonjs.loaders.module.d.ts
  63. 2 0
      dist/preview release/what's new.md
  64. 1 1
      gui/src/3D/gui3DManager.ts
  65. 1 1
      inspector/src/components/actionTabs/tabs/propertyGrids/materials/nodeMaterialPropertyGridComponent.tsx
  66. 7 3
      inspector/src/components/actionTabs/tabs/propertyGrids/meshes/meshPropertyGridComponent.tsx
  67. 1 1
      loaders/src/OBJ/objFileLoader.ts
  68. 2 0
      loaders/src/STL/stlFileLoader.ts
  69. 5 4
      materialsLibrary/src/grid/grid.vertex.fx
  70. 10 3
      materialsLibrary/src/grid/gridMaterial.ts
  71. 43 0
      nodeEditor/public/index-local.html
  72. 41 0
      nodeEditor/public/index.html
  73. 125 0
      nodeEditor/public/index.js
  74. 19 10
      nodeEditor/src/blockTools.ts
  75. 2 1
      nodeEditor/src/components/diagram/diagram.scss
  76. 26 26
      nodeEditor/src/components/diagram/input/inputNodePropertyComponent.tsx
  77. 11 11
      nodeEditor/src/components/diagram/input/inputNodeWidget.tsx
  78. 0 1
      nodeEditor/src/components/log/log.scss
  79. 1 1
      nodeEditor/src/components/nodeList/nodeList.scss
  80. 3 3
      nodeEditor/src/components/nodeList/nodeListComponent.tsx
  81. 5 2
      nodeEditor/src/components/preview/previewManager.ts
  82. 4 1
      nodeEditor/src/components/preview/previewMeshControlComponent.tsx
  83. 2 1
      nodeEditor/src/components/preview/previewMeshType.ts
  84. 9 35
      nodeEditor/src/components/propertyTab/propertyTabComponent.tsx
  85. 2 0
      nodeEditor/src/globalState.ts
  86. 19 2
      nodeEditor/src/nodeEditor.ts
  87. 42 0
      nodeEditor/src/serializationTools.ts
  88. 6 2
      nodeEditor/src/sharedComponents/color3LineComponent.tsx
  89. 2 2
      package.json
  90. 3 2
      src/Behaviors/Meshes/pointerDragBehavior.ts
  91. 4 4
      src/Engines/engine.ts
  92. 11 5
      src/Layers/highlightLayer.ts
  93. 6 7
      src/Materials/Node/Blocks/Dual/fogBlock.ts
  94. 5 12
      src/Materials/Node/Blocks/Dual/lightBlock.ts
  95. 7 7
      src/Materials/Node/Blocks/Dual/reflectionTextureBlock.ts
  96. 2 0
      src/Materials/Node/Blocks/Dual/textureBlock.ts
  97. 2 1
      src/Materials/Node/Blocks/Fragment/index.ts
  98. 139 0
      src/Materials/Node/Blocks/Fragment/pertubNormalBlock.ts
  99. 48 48
      src/Materials/Node/Blocks/Input/inputBlock.ts
  100. 0 0
      src/Materials/Node/Blocks/Vertex/bonesBlock.ts

+ 13 - 0
.vscode/launch.json

@@ -2,6 +2,19 @@
     "version": "2.0.0",
     "configurations": [
         {
+            "name": "Node Material Editor (Chrome)",
+            "type": "chrome",
+            "request": "launch",
+            "url": "http://localhost:1338/nodeEditor/public/index-local.html",
+            "webRoot": "${workspaceRoot}/",
+            "sourceMaps": true,
+            "preLaunchTask": "run",
+            "userDataDir": "${workspaceRoot}/.tempChromeProfileForDebug",
+            "runtimeArgs": [
+                "--enable-unsafe-es3-apis"
+            ]
+        },        
+        {
             "name": "Launch Viewer (Chrome)",
             "type": "chrome",
             "request": "launch",

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


+ 4 - 4
Playground/debug.html

@@ -27,7 +27,6 @@
     <link rel="icon" type="image/png" sizes="96x96" href="https://www.babylonjs.com/img/favicon/favicon-96x96.png">
     <link rel="icon" type="image/png" sizes="16x16" href="https://www.babylonjs.com/img/favicon/favicon-16x16.png">
 
-    <link rel="manifest" href="https://www.babylonjs.com/img/favicon/manifest.json">
     <meta name="msapplication-TileColor" content="#ffffff">
     <meta name="msapplication-TileImage" content="https://www.babylonjs.com/img/favicon/ms-icon-144x144.png">
     <meta name="msapplication-config" content="https://www.babylonjs.com/img/favicon/browserconfig.xml">
@@ -35,8 +34,7 @@
 
     <link rel="stylesheet" href="https://use.typekit.net/cta4xsb.css" />
     <link rel="stylesheet" href="css/index.css" />
-    <link rel="stylesheet" href="css/index710.css" />
-    <link rel="stylesheet" href="css/indexMobile.css" />
+    <link rel="stylesheet" href="css/index_mobile.css" />
 
     <!-- Pep -->
     <script src="https://code.jquery.com/pep/0.4.2/pep.min.js"></script>
@@ -416,7 +414,9 @@
     </div>
 
     <!-- jQuery -->
-    <script src="https://code.jquery.com/jquery.js"></script>
+    <script src="js/libs/jquery.min.js"></script>
+    <script src="js/jquery.qrcode.js"></script>
+    <script src="js/qrcode.js"></script>
 
     <!-- Main scripts -->
     <script src="js/config_versions.js"></script>

+ 1 - 2
Playground/js/config_versions.js

@@ -1,6 +1,5 @@
 CONFIG_last_versions = [
     ["Latest","https://preview.babylonjs.com/babylon.js"],
     ["4.0.3","https://unpkg.com/babylonjs@4.0.3/babylon.js"],
-    ["4.0.0","https://unpkg.com/babylonjs@4.0.0/babylon.js"],
-    ["3.0","https://unpkg.com/babylonjs@3.0.7/dist/preview%20release/babylon.js"]
+    ["3.3","https://unpkg.com/babylonjs@3.3.0/babylon.js"]
 ];

+ 47 - 8
Playground/js/main.js

@@ -288,15 +288,52 @@ class Main {
         }
         // Language (JS / TS)
         this.parent.utils.setToMultipleID("toTSbutton", "click", function () {
-            if (this.parent.settingsPG.ScriptLanguage == "JS") {
+            if(location.hash != null && location.hash != ""){
                 this.parent.settingsPG.ScriptLanguage = "TS";
-                location.reload();
+                window.location = "./";
+            }else{
+                if (this.parent.settingsPG.ScriptLanguage == "JS") {
+                    //revert in case the reload is cancel due to safe mode
+                    if(document.getElementById("safemodeToggle" + this.parent.utils.getCurrentSize()).classList.contains('checked')){
+                        // Message before unload
+                        var languageTSswapper =  function () {
+                            this.parent.settingsPG.ScriptLanguage = "TS";
+                            window.removeEventListener('unload', languageTSswapper.bind(this));
+                        };
+                        window.addEventListener('unload',languageTSswapper.bind(this));
+                        
+                        location.reload();
+                    }
+                    else {
+                        this.parent.settingsPG.ScriptLanguage = "TS";
+                        location.reload();
+                    }
+                }
             }
+           
         }.bind(this));
         this.parent.utils.setToMultipleID("toJSbutton", "click", function () {
-            if (this.parent.settingsPG.ScriptLanguage == "TS") {
+            if(location.hash != null && location.hash != ""){
                 this.parent.settingsPG.ScriptLanguage = "JS";
-                location.reload();
+                window.location = "./";
+            }else{
+                if (this.parent.settingsPG.ScriptLanguage == "TS") {
+                    //revert in case the reload is cancel due to safe mode
+                    if(document.getElementById("safemodeToggle" + this.parent.utils.getCurrentSize()).classList.contains('checked')){
+                        // Message before unload
+                        var LanguageJSswapper =  function () {
+                            this.parent.settingsPG.ScriptLanguage = "JS";
+                            window.removeEventListener('unload', LanguageJSswapper.bind(this));
+                        };
+                        window.addEventListener('unload',LanguageJSswapper.bind(this));
+                        
+                        location.reload();
+                    }
+                    else {
+                        this.parent.settingsPG.ScriptLanguage = "JS";
+                        location.reload();
+                    }
+                }
             }
         }.bind(this));
         // Safe mode
@@ -554,8 +591,6 @@ class Main {
                         }
                     }
 
-                    // Restore theme
-                    this.parent.settingsPG.restoreTheme(this.parent.monacoCreator);
                     // Restore language
                     this.parent.settingsPG.setScriptLanguage();
                 }
@@ -594,9 +629,13 @@ class Main {
         this.parent.monacoCreator.JsEditor.focus();
     };
 
+    compileAndRunFromOutside() {
+        compileAndRun(this.parent, this.fpsLabel);
+    };
+
     checkSafeMode(message) {
-        if (document.getElementById("safemodeToggle" + this.parent.getCurrentSize) &&
-            document.getElementById("safemodeToggle" + this.parent.getCurrentSize).classList.contains('checked')) {
+        if (document.getElementById("safemodeToggle" + this.parent.utils.getCurrentSize()) &&
+            document.getElementById("safemodeToggle" + this.parent.utils.getCurrentSize()).classList.contains('checked')) {
             let confirm = window.confirm(message);
             if (!confirm) {
                 return false;

+ 1 - 1
Playground/js/settingsPG.js

@@ -163,7 +163,7 @@ class SettingsPG {
                 localStorage.removeItem("bjs-playground-apiversion");
                 localStorage.removeItem("bjs-playground-apiversion-tempcode");
 
-                this.parent.main.compileAndRun();
+                this.parent.main.compileAndRunFromOutside();
             }.bind(this);
 
             document.head.appendChild(newBJSscript);

+ 1 - 2
dist/gui/readme.md

@@ -26,8 +26,7 @@ If using TypeScript, the typing needs to be added to tsconfig.json:
     ....
     "types": [
         "babylonjs",
-        "babylonjs-gui",
-        "angularFTW"
+        "babylonjs-gui"
     ],
     ....
 ```

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


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


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


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


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


文件差异内容过多而无法显示
+ 646 - 180
dist/preview release/documentation.d.ts


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

@@ -1,7 +1,7 @@
 {
     "name": "babylonjs-gltf2interface",
     "description": "A typescript declaration of babylon's gltf2 inteface.",
-    "version": "4.1.0-alpha.15",
+    "version": "4.1.0-alpha.17",
     "repository": {
         "type": "git",
         "url": "https://github.com/BabylonJS/Babylon.js.git"

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

@@ -7,7 +7,7 @@
 		exports["babylonjs-gui"] = factory(require("babylonjs"));
 	else
 		root["BABYLON"] = root["BABYLON"] || {}, root["BABYLON"]["GUI"] = factory(root["BABYLON"]);
-})((typeof self !== "undefined" ? self : typeof global !== "undefined" ? global : this), function(__WEBPACK_EXTERNAL_MODULE_babylonjs_Maths_math__) {
+})((typeof self !== "undefined" ? self : typeof global !== "undefined" ? global : this), function(__WEBPACK_EXTERNAL_MODULE_babylonjs_Misc_perfCounter__) {
 return /******/ (function(modules) { // webpackBootstrap
 /******/ 	// The module cache
 /******/ 	var installedModules = {};
@@ -366,7 +366,7 @@ module.exports = g;
 "use strict";
 __webpack_require__.r(__webpack_exports__);
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "AdvancedDynamicTextureInstrumentation", function() { return AdvancedDynamicTextureInstrumentation; });
-/* harmony import */ var babylonjs_Misc_perfCounter__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! babylonjs/Misc/perfCounter */ "babylonjs/Maths/math");
+/* harmony import */ var babylonjs_Misc_perfCounter__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! babylonjs/Misc/perfCounter */ "babylonjs/Misc/perfCounter");
 /* harmony import */ var babylonjs_Misc_perfCounter__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Misc_perfCounter__WEBPACK_IMPORTED_MODULE_0__);
 
 /**
@@ -509,7 +509,7 @@ var AdvancedDynamicTextureInstrumentation = /** @class */ (function () {
 __webpack_require__.r(__webpack_exports__);
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "AdvancedDynamicTexture", function() { return AdvancedDynamicTexture; });
 /* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tslib */ "../../node_modules/tslib/tslib.es6.js");
-/* harmony import */ var babylonjs_Misc_observable__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! babylonjs/Misc/observable */ "babylonjs/Maths/math");
+/* harmony import */ var babylonjs_Misc_observable__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! babylonjs/Misc/observable */ "babylonjs/Misc/perfCounter");
 /* harmony import */ var babylonjs_Misc_observable__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Misc_observable__WEBPACK_IMPORTED_MODULE_1__);
 /* harmony import */ var _controls_container__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./controls/container */ "./2D/controls/container.ts");
 /* harmony import */ var _style__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./style */ "./2D/style.ts");
@@ -1647,7 +1647,7 @@ var Button = /** @class */ (function (_super) {
 __webpack_require__.r(__webpack_exports__);
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Checkbox", function() { return Checkbox; });
 /* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tslib */ "../../node_modules/tslib/tslib.es6.js");
-/* harmony import */ var babylonjs_Misc_observable__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! babylonjs/Misc/observable */ "babylonjs/Maths/math");
+/* harmony import */ var babylonjs_Misc_observable__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! babylonjs/Misc/observable */ "babylonjs/Misc/perfCounter");
 /* harmony import */ var babylonjs_Misc_observable__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Misc_observable__WEBPACK_IMPORTED_MODULE_1__);
 /* harmony import */ var _control__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./control */ "./2D/controls/control.ts");
 /* harmony import */ var _stackPanel__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./stackPanel */ "./2D/controls/stackPanel.ts");
@@ -1828,7 +1828,7 @@ var Checkbox = /** @class */ (function (_super) {
 __webpack_require__.r(__webpack_exports__);
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ColorPicker", function() { return ColorPicker; });
 /* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tslib */ "../../node_modules/tslib/tslib.es6.js");
-/* harmony import */ var babylonjs_Misc_observable__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! babylonjs/Misc/observable */ "babylonjs/Maths/math");
+/* harmony import */ var babylonjs_Misc_observable__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! babylonjs/Misc/observable */ "babylonjs/Misc/perfCounter");
 /* harmony import */ var babylonjs_Misc_observable__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Misc_observable__WEBPACK_IMPORTED_MODULE_1__);
 /* harmony import */ var _control__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./control */ "./2D/controls/control.ts");
 /* harmony import */ var _inputText__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./inputText */ "./2D/controls/inputText.ts");
@@ -3215,7 +3215,7 @@ var ColorPicker = /** @class */ (function (_super) {
 __webpack_require__.r(__webpack_exports__);
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Container", function() { return Container; });
 /* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tslib */ "../../node_modules/tslib/tslib.es6.js");
-/* harmony import */ var babylonjs_Misc_logger__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! babylonjs/Misc/logger */ "babylonjs/Maths/math");
+/* harmony import */ var babylonjs_Misc_logger__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! babylonjs/Misc/logger */ "babylonjs/Misc/perfCounter");
 /* harmony import */ var babylonjs_Misc_logger__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Misc_logger__WEBPACK_IMPORTED_MODULE_1__);
 /* harmony import */ var _control__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./control */ "./2D/controls/control.ts");
 /* harmony import */ var _measure__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../measure */ "./2D/measure.ts");
@@ -3628,7 +3628,7 @@ var Container = /** @class */ (function (_super) {
 "use strict";
 __webpack_require__.r(__webpack_exports__);
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Control", function() { return Control; });
-/* harmony import */ var babylonjs_Misc_observable__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! babylonjs/Misc/observable */ "babylonjs/Maths/math");
+/* harmony import */ var babylonjs_Misc_observable__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! babylonjs/Misc/observable */ "babylonjs/Misc/perfCounter");
 /* harmony import */ var babylonjs_Misc_observable__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Misc_observable__WEBPACK_IMPORTED_MODULE_0__);
 /* harmony import */ var _valueAndUnit__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../valueAndUnit */ "./2D/valueAndUnit.ts");
 /* harmony import */ var _measure__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../measure */ "./2D/measure.ts");
@@ -5819,7 +5819,7 @@ __webpack_require__.r(__webpack_exports__);
 /* harmony import */ var _container__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./container */ "./2D/controls/container.ts");
 /* harmony import */ var _valueAndUnit__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../valueAndUnit */ "./2D/valueAndUnit.ts");
 /* harmony import */ var _control__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./control */ "./2D/controls/control.ts");
-/* harmony import */ var babylonjs_Misc_tools__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! babylonjs/Misc/tools */ "babylonjs/Maths/math");
+/* harmony import */ var babylonjs_Misc_tools__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! babylonjs/Misc/tools */ "babylonjs/Misc/perfCounter");
 /* harmony import */ var babylonjs_Misc_tools__WEBPACK_IMPORTED_MODULE_4___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Misc_tools__WEBPACK_IMPORTED_MODULE_4__);
 
 
@@ -6275,7 +6275,7 @@ var Grid = /** @class */ (function (_super) {
 __webpack_require__.r(__webpack_exports__);
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Image", function() { return Image; });
 /* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tslib */ "../../node_modules/tslib/tslib.es6.js");
-/* harmony import */ var babylonjs_Misc_observable__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! babylonjs/Misc/observable */ "babylonjs/Maths/math");
+/* harmony import */ var babylonjs_Misc_observable__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! babylonjs/Misc/observable */ "babylonjs/Misc/perfCounter");
 /* harmony import */ var babylonjs_Misc_observable__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Misc_observable__WEBPACK_IMPORTED_MODULE_1__);
 /* harmony import */ var _control__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./control */ "./2D/controls/control.ts");
 
@@ -7050,7 +7050,7 @@ var InputPassword = /** @class */ (function (_super) {
 __webpack_require__.r(__webpack_exports__);
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "InputText", function() { return InputText; });
 /* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tslib */ "../../node_modules/tslib/tslib.es6.js");
-/* harmony import */ var babylonjs_Misc_observable__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! babylonjs/Misc/observable */ "babylonjs/Maths/math");
+/* harmony import */ var babylonjs_Misc_observable__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! babylonjs/Misc/observable */ "babylonjs/Misc/perfCounter");
 /* harmony import */ var babylonjs_Misc_observable__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Misc_observable__WEBPACK_IMPORTED_MODULE_1__);
 /* harmony import */ var _control__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./control */ "./2D/controls/control.ts");
 /* harmony import */ var _valueAndUnit__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../valueAndUnit */ "./2D/valueAndUnit.ts");
@@ -8061,7 +8061,7 @@ var InputText = /** @class */ (function (_super) {
 __webpack_require__.r(__webpack_exports__);
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Line", function() { return Line; });
 /* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tslib */ "../../node_modules/tslib/tslib.es6.js");
-/* harmony import */ var babylonjs_Maths_math__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! babylonjs/Maths/math */ "babylonjs/Maths/math");
+/* harmony import */ var babylonjs_Maths_math__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! babylonjs/Maths/math */ "babylonjs/Misc/perfCounter");
 /* harmony import */ var babylonjs_Maths_math__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Maths_math__WEBPACK_IMPORTED_MODULE_1__);
 /* harmony import */ var _control__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./control */ "./2D/controls/control.ts");
 /* harmony import */ var _valueAndUnit__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../valueAndUnit */ "./2D/valueAndUnit.ts");
@@ -8329,7 +8329,7 @@ var Line = /** @class */ (function (_super) {
 __webpack_require__.r(__webpack_exports__);
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "MultiLine", function() { return MultiLine; });
 /* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tslib */ "../../node_modules/tslib/tslib.es6.js");
-/* harmony import */ var babylonjs_Meshes_abstractMesh__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! babylonjs/Meshes/abstractMesh */ "babylonjs/Maths/math");
+/* harmony import */ var babylonjs_Meshes_abstractMesh__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! babylonjs/Meshes/abstractMesh */ "babylonjs/Misc/perfCounter");
 /* harmony import */ var babylonjs_Meshes_abstractMesh__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Meshes_abstractMesh__WEBPACK_IMPORTED_MODULE_1__);
 /* harmony import */ var _control__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./control */ "./2D/controls/control.ts");
 /* harmony import */ var _multiLinePoint__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../multiLinePoint */ "./2D/multiLinePoint.ts");
@@ -8596,7 +8596,7 @@ var MultiLine = /** @class */ (function (_super) {
 __webpack_require__.r(__webpack_exports__);
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "RadioButton", function() { return RadioButton; });
 /* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tslib */ "../../node_modules/tslib/tslib.es6.js");
-/* harmony import */ var babylonjs_Misc_observable__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! babylonjs/Misc/observable */ "babylonjs/Maths/math");
+/* harmony import */ var babylonjs_Misc_observable__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! babylonjs/Misc/observable */ "babylonjs/Misc/perfCounter");
 /* harmony import */ var babylonjs_Misc_observable__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Misc_observable__WEBPACK_IMPORTED_MODULE_1__);
 /* harmony import */ var _control__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./control */ "./2D/controls/control.ts");
 /* harmony import */ var _stackPanel__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./stackPanel */ "./2D/controls/stackPanel.ts");
@@ -8941,7 +8941,7 @@ var Rectangle = /** @class */ (function (_super) {
 __webpack_require__.r(__webpack_exports__);
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ScrollViewer", function() { return ScrollViewer; });
 /* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tslib */ "../../node_modules/tslib/tslib.es6.js");
-/* harmony import */ var babylonjs_Events_pointerEvents__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! babylonjs/Events/pointerEvents */ "babylonjs/Maths/math");
+/* harmony import */ var babylonjs_Events_pointerEvents__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! babylonjs/Events/pointerEvents */ "babylonjs/Misc/perfCounter");
 /* harmony import */ var babylonjs_Events_pointerEvents__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Events_pointerEvents__WEBPACK_IMPORTED_MODULE_1__);
 /* harmony import */ var _rectangle__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../rectangle */ "./2D/controls/rectangle.ts");
 /* harmony import */ var _grid__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../grid */ "./2D/controls/grid.ts");
@@ -10032,7 +10032,7 @@ var SelectionPanel = /** @class */ (function (_super) {
 __webpack_require__.r(__webpack_exports__);
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "BaseSlider", function() { return BaseSlider; });
 /* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tslib */ "../../node_modules/tslib/tslib.es6.js");
-/* harmony import */ var babylonjs_Misc_observable__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! babylonjs/Misc/observable */ "babylonjs/Maths/math");
+/* harmony import */ var babylonjs_Misc_observable__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! babylonjs/Misc/observable */ "babylonjs/Misc/perfCounter");
 /* harmony import */ var babylonjs_Misc_observable__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Misc_observable__WEBPACK_IMPORTED_MODULE_1__);
 /* harmony import */ var _control__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../control */ "./2D/controls/control.ts");
 /* harmony import */ var _valueAndUnit__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../../valueAndUnit */ "./2D/valueAndUnit.ts");
@@ -10933,7 +10933,7 @@ var Slider = /** @class */ (function (_super) {
 __webpack_require__.r(__webpack_exports__);
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "StackPanel", function() { return StackPanel; });
 /* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tslib */ "../../node_modules/tslib/tslib.es6.js");
-/* harmony import */ var babylonjs_Misc_tools__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! babylonjs/Misc/tools */ "babylonjs/Maths/math");
+/* harmony import */ var babylonjs_Misc_tools__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! babylonjs/Misc/tools */ "babylonjs/Misc/perfCounter");
 /* harmony import */ var babylonjs_Misc_tools__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Misc_tools__WEBPACK_IMPORTED_MODULE_1__);
 /* harmony import */ var _container__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./container */ "./2D/controls/container.ts");
 /* harmony import */ var _control__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./control */ "./2D/controls/control.ts");
@@ -11199,7 +11199,7 @@ __webpack_require__.r(__webpack_exports__);
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "TextWrapping", function() { return TextWrapping; });
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "TextBlock", function() { return TextBlock; });
 /* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tslib */ "../../node_modules/tslib/tslib.es6.js");
-/* harmony import */ var babylonjs_Misc_observable__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! babylonjs/Misc/observable */ "babylonjs/Maths/math");
+/* harmony import */ var babylonjs_Misc_observable__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! babylonjs/Misc/observable */ "babylonjs/Misc/perfCounter");
 /* harmony import */ var babylonjs_Misc_observable__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Misc_observable__WEBPACK_IMPORTED_MODULE_1__);
 /* harmony import */ var _valueAndUnit__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../valueAndUnit */ "./2D/valueAndUnit.ts");
 /* harmony import */ var _control__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./control */ "./2D/controls/control.ts");
@@ -11660,7 +11660,7 @@ __webpack_require__.r(__webpack_exports__);
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "KeyPropertySet", function() { return KeyPropertySet; });
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "VirtualKeyboard", function() { return VirtualKeyboard; });
 /* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tslib */ "../../node_modules/tslib/tslib.es6.js");
-/* harmony import */ var babylonjs_Misc_observable__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! babylonjs/Misc/observable */ "babylonjs/Maths/math");
+/* harmony import */ var babylonjs_Misc_observable__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! babylonjs/Misc/observable */ "babylonjs/Misc/perfCounter");
 /* harmony import */ var babylonjs_Misc_observable__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Misc_observable__WEBPACK_IMPORTED_MODULE_1__);
 /* harmony import */ var _stackPanel__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./stackPanel */ "./2D/controls/stackPanel.ts");
 /* harmony import */ var _button__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./button */ "./2D/controls/button.ts");
@@ -12041,7 +12041,7 @@ __webpack_require__.r(__webpack_exports__);
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Vector2WithInfo", function() { return Vector2WithInfo; });
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Matrix2D", function() { return Matrix2D; });
 /* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tslib */ "../../node_modules/tslib/tslib.es6.js");
-/* harmony import */ var babylonjs_Maths_math__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! babylonjs/Maths/math */ "babylonjs/Maths/math");
+/* harmony import */ var babylonjs_Maths_math__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! babylonjs/Maths/math */ "babylonjs/Misc/perfCounter");
 /* harmony import */ var babylonjs_Maths_math__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Maths_math__WEBPACK_IMPORTED_MODULE_1__);
 
 
@@ -12265,7 +12265,7 @@ var Matrix2D = /** @class */ (function () {
 "use strict";
 __webpack_require__.r(__webpack_exports__);
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Measure", function() { return Measure; });
-/* harmony import */ var babylonjs_Maths_math__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! babylonjs/Maths/math */ "babylonjs/Maths/math");
+/* harmony import */ var babylonjs_Maths_math__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! babylonjs/Maths/math */ "babylonjs/Misc/perfCounter");
 /* harmony import */ var babylonjs_Maths_math__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Maths_math__WEBPACK_IMPORTED_MODULE_0__);
 
 
@@ -12398,7 +12398,7 @@ var Measure = /** @class */ (function () {
 "use strict";
 __webpack_require__.r(__webpack_exports__);
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "MultiLinePoint", function() { return MultiLinePoint; });
-/* harmony import */ var babylonjs_Maths_math__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! babylonjs/Maths/math */ "babylonjs/Maths/math");
+/* harmony import */ var babylonjs_Maths_math__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! babylonjs/Maths/math */ "babylonjs/Misc/perfCounter");
 /* harmony import */ var babylonjs_Maths_math__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Maths_math__WEBPACK_IMPORTED_MODULE_0__);
 /* harmony import */ var _valueAndUnit__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./valueAndUnit */ "./2D/valueAndUnit.ts");
 
@@ -12541,7 +12541,7 @@ var MultiLinePoint = /** @class */ (function () {
 "use strict";
 __webpack_require__.r(__webpack_exports__);
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Style", function() { return Style; });
-/* harmony import */ var babylonjs_Misc_observable__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! babylonjs/Misc/observable */ "babylonjs/Maths/math");
+/* harmony import */ var babylonjs_Misc_observable__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! babylonjs/Misc/observable */ "babylonjs/Misc/perfCounter");
 /* harmony import */ var babylonjs_Misc_observable__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Misc_observable__WEBPACK_IMPORTED_MODULE_0__);
 /* harmony import */ var _valueAndUnit__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./valueAndUnit */ "./2D/valueAndUnit.ts");
 
@@ -12848,7 +12848,7 @@ var ValueAndUnit = /** @class */ (function () {
 __webpack_require__.r(__webpack_exports__);
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "AbstractButton3D", function() { return AbstractButton3D; });
 /* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tslib */ "../../node_modules/tslib/tslib.es6.js");
-/* harmony import */ var babylonjs_Meshes_transformNode__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! babylonjs/Meshes/transformNode */ "babylonjs/Maths/math");
+/* harmony import */ var babylonjs_Meshes_transformNode__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! babylonjs/Meshes/transformNode */ "babylonjs/Misc/perfCounter");
 /* harmony import */ var babylonjs_Meshes_transformNode__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Meshes_transformNode__WEBPACK_IMPORTED_MODULE_1__);
 /* harmony import */ var _control3D__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./control3D */ "./3D/controls/control3D.ts");
 
@@ -12891,7 +12891,7 @@ var AbstractButton3D = /** @class */ (function (_super) {
 __webpack_require__.r(__webpack_exports__);
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Button3D", function() { return Button3D; });
 /* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tslib */ "../../node_modules/tslib/tslib.es6.js");
-/* harmony import */ var babylonjs_Maths_math__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! babylonjs/Maths/math */ "babylonjs/Maths/math");
+/* harmony import */ var babylonjs_Maths_math__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! babylonjs/Maths/math */ "babylonjs/Misc/perfCounter");
 /* harmony import */ var babylonjs_Maths_math__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Maths_math__WEBPACK_IMPORTED_MODULE_1__);
 /* harmony import */ var _abstractButton3D__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./abstractButton3D */ "./3D/controls/abstractButton3D.ts");
 /* harmony import */ var _2D_advancedDynamicTexture__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../../2D/advancedDynamicTexture */ "./2D/advancedDynamicTexture.ts");
@@ -13068,7 +13068,7 @@ var Button3D = /** @class */ (function (_super) {
 __webpack_require__.r(__webpack_exports__);
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Container3D", function() { return Container3D; });
 /* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tslib */ "../../node_modules/tslib/tslib.es6.js");
-/* harmony import */ var babylonjs_Meshes_transformNode__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! babylonjs/Meshes/transformNode */ "babylonjs/Maths/math");
+/* harmony import */ var babylonjs_Meshes_transformNode__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! babylonjs/Meshes/transformNode */ "babylonjs/Misc/perfCounter");
 /* harmony import */ var babylonjs_Meshes_transformNode__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Meshes_transformNode__WEBPACK_IMPORTED_MODULE_1__);
 /* harmony import */ var _control3D__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./control3D */ "./3D/controls/control3D.ts");
 
@@ -13225,7 +13225,7 @@ var Container3D = /** @class */ (function (_super) {
 "use strict";
 __webpack_require__.r(__webpack_exports__);
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Control3D", function() { return Control3D; });
-/* harmony import */ var babylonjs_Misc_observable__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! babylonjs/Misc/observable */ "babylonjs/Maths/math");
+/* harmony import */ var babylonjs_Misc_observable__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! babylonjs/Misc/observable */ "babylonjs/Misc/perfCounter");
 /* harmony import */ var babylonjs_Misc_observable__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Misc_observable__WEBPACK_IMPORTED_MODULE_0__);
 /* harmony import */ var _vector3WithInfo__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../vector3WithInfo */ "./3D/vector3WithInfo.ts");
 
@@ -13631,7 +13631,7 @@ var Control3D = /** @class */ (function () {
 __webpack_require__.r(__webpack_exports__);
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "CylinderPanel", function() { return CylinderPanel; });
 /* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tslib */ "../../node_modules/tslib/tslib.es6.js");
-/* harmony import */ var babylonjs_Misc_tools__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! babylonjs/Misc/tools */ "babylonjs/Maths/math");
+/* harmony import */ var babylonjs_Misc_tools__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! babylonjs/Misc/tools */ "babylonjs/Misc/perfCounter");
 /* harmony import */ var babylonjs_Misc_tools__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Misc_tools__WEBPACK_IMPORTED_MODULE_1__);
 /* harmony import */ var _volumeBasedPanel__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./volumeBasedPanel */ "./3D/controls/volumeBasedPanel.ts");
 /* harmony import */ var _container3D__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./container3D */ "./3D/controls/container3D.ts");
@@ -13717,7 +13717,7 @@ __webpack_require__.r(__webpack_exports__);
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "HolographicButton", function() { return HolographicButton; });
 /* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tslib */ "../../node_modules/tslib/tslib.es6.js");
 /* harmony import */ var _button3D__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./button3D */ "./3D/controls/button3D.ts");
-/* harmony import */ var babylonjs_Maths_math__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! babylonjs/Maths/math */ "babylonjs/Maths/math");
+/* harmony import */ var babylonjs_Maths_math__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! babylonjs/Maths/math */ "babylonjs/Misc/perfCounter");
 /* harmony import */ var babylonjs_Maths_math__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Maths_math__WEBPACK_IMPORTED_MODULE_2__);
 /* harmony import */ var _materials_fluentMaterial__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../materials/fluentMaterial */ "./3D/materials/fluentMaterial.ts");
 /* harmony import */ var _2D_controls_stackPanel__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../../2D/controls/stackPanel */ "./2D/controls/stackPanel.ts");
@@ -14193,7 +14193,7 @@ var MeshButton3D = /** @class */ (function (_super) {
 __webpack_require__.r(__webpack_exports__);
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "PlanePanel", function() { return PlanePanel; });
 /* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tslib */ "../../node_modules/tslib/tslib.es6.js");
-/* harmony import */ var babylonjs_Maths_math__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! babylonjs/Maths/math */ "babylonjs/Maths/math");
+/* harmony import */ var babylonjs_Maths_math__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! babylonjs/Maths/math */ "babylonjs/Misc/perfCounter");
 /* harmony import */ var babylonjs_Maths_math__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Maths_math__WEBPACK_IMPORTED_MODULE_1__);
 /* harmony import */ var _container3D__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./container3D */ "./3D/controls/container3D.ts");
 /* harmony import */ var _volumeBasedPanel__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./volumeBasedPanel */ "./3D/controls/volumeBasedPanel.ts");
@@ -14248,7 +14248,7 @@ var PlanePanel = /** @class */ (function (_super) {
 __webpack_require__.r(__webpack_exports__);
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ScatterPanel", function() { return ScatterPanel; });
 /* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tslib */ "../../node_modules/tslib/tslib.es6.js");
-/* harmony import */ var babylonjs_Misc_tools__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! babylonjs/Misc/tools */ "babylonjs/Maths/math");
+/* harmony import */ var babylonjs_Misc_tools__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! babylonjs/Misc/tools */ "babylonjs/Misc/perfCounter");
 /* harmony import */ var babylonjs_Misc_tools__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Misc_tools__WEBPACK_IMPORTED_MODULE_1__);
 /* harmony import */ var _volumeBasedPanel__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./volumeBasedPanel */ "./3D/controls/volumeBasedPanel.ts");
 /* harmony import */ var _container3D__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./container3D */ "./3D/controls/container3D.ts");
@@ -14375,7 +14375,7 @@ var ScatterPanel = /** @class */ (function (_super) {
 __webpack_require__.r(__webpack_exports__);
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "SpherePanel", function() { return SpherePanel; });
 /* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tslib */ "../../node_modules/tslib/tslib.es6.js");
-/* harmony import */ var babylonjs_Misc_tools__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! babylonjs/Misc/tools */ "babylonjs/Maths/math");
+/* harmony import */ var babylonjs_Misc_tools__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! babylonjs/Misc/tools */ "babylonjs/Misc/perfCounter");
 /* harmony import */ var babylonjs_Misc_tools__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Misc_tools__WEBPACK_IMPORTED_MODULE_1__);
 /* harmony import */ var _volumeBasedPanel__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./volumeBasedPanel */ "./3D/controls/volumeBasedPanel.ts");
 /* harmony import */ var _container3D__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./container3D */ "./3D/controls/container3D.ts");
@@ -14460,7 +14460,7 @@ var SpherePanel = /** @class */ (function (_super) {
 __webpack_require__.r(__webpack_exports__);
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "StackPanel3D", function() { return StackPanel3D; });
 /* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tslib */ "../../node_modules/tslib/tslib.es6.js");
-/* harmony import */ var babylonjs_Misc_tools__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! babylonjs/Misc/tools */ "babylonjs/Maths/math");
+/* harmony import */ var babylonjs_Misc_tools__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! babylonjs/Misc/tools */ "babylonjs/Misc/perfCounter");
 /* harmony import */ var babylonjs_Misc_tools__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Misc_tools__WEBPACK_IMPORTED_MODULE_1__);
 /* harmony import */ var _container3D__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./container3D */ "./3D/controls/container3D.ts");
 
@@ -14585,7 +14585,7 @@ var StackPanel3D = /** @class */ (function (_super) {
 __webpack_require__.r(__webpack_exports__);
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "VolumeBasedPanel", function() { return VolumeBasedPanel; });
 /* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tslib */ "../../node_modules/tslib/tslib.es6.js");
-/* harmony import */ var babylonjs_Misc_tools__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! babylonjs/Misc/tools */ "babylonjs/Maths/math");
+/* harmony import */ var babylonjs_Misc_tools__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! babylonjs/Misc/tools */ "babylonjs/Misc/perfCounter");
 /* harmony import */ var babylonjs_Misc_tools__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Misc_tools__WEBPACK_IMPORTED_MODULE_1__);
 /* harmony import */ var _container3D__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./container3D */ "./3D/controls/container3D.ts");
 
@@ -14776,7 +14776,7 @@ var VolumeBasedPanel = /** @class */ (function (_super) {
 "use strict";
 __webpack_require__.r(__webpack_exports__);
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "GUI3DManager", function() { return GUI3DManager; });
-/* harmony import */ var babylonjs_Misc_observable__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! babylonjs/Misc/observable */ "babylonjs/Maths/math");
+/* harmony import */ var babylonjs_Misc_observable__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! babylonjs/Misc/observable */ "babylonjs/Misc/perfCounter");
 /* harmony import */ var babylonjs_Misc_observable__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Misc_observable__WEBPACK_IMPORTED_MODULE_0__);
 /* harmony import */ var _controls_container3D__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./controls/container3D */ "./3D/controls/container3D.ts");
 
@@ -14867,7 +14867,7 @@ var GUI3DManager = /** @class */ (function () {
         this.onPickedPointChangedObservable.notifyObservers(null);
     };
     GUI3DManager.prototype._doPicking = function (pi) {
-        if (!this._utilityLayer || !this._utilityLayer.utilityLayerScene.activeCamera) {
+        if (!this._utilityLayer || !this._utilityLayer.shouldRender || !this._utilityLayer.utilityLayerScene.activeCamera) {
             return false;
         }
         var pointerEvent = (pi.event);
@@ -15043,7 +15043,7 @@ __webpack_require__.r(__webpack_exports__);
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "FluentMaterialDefines", function() { return FluentMaterialDefines; });
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "FluentMaterial", function() { return FluentMaterial; });
 /* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tslib */ "../../node_modules/tslib/tslib.es6.js");
-/* harmony import */ var babylonjs_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! babylonjs/Misc/decorators */ "babylonjs/Maths/math");
+/* harmony import */ var babylonjs_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! babylonjs/Misc/decorators */ "babylonjs/Misc/perfCounter");
 /* harmony import */ var babylonjs_Misc_decorators__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__);
 /* harmony import */ var _shaders_fluent_vertex__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./shaders/fluent.vertex */ "./3D/materials/shaders/fluent.vertex.ts");
 /* harmony import */ var _shaders_fluent_fragment__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./shaders/fluent.fragment */ "./3D/materials/shaders/fluent.fragment.ts");
@@ -15365,7 +15365,7 @@ __webpack_require__.r(__webpack_exports__);
 "use strict";
 __webpack_require__.r(__webpack_exports__);
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "fluentPixelShader", function() { return fluentPixelShader; });
-/* harmony import */ var babylonjs_Materials_effect__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! babylonjs/Materials/effect */ "babylonjs/Maths/math");
+/* harmony import */ var babylonjs_Materials_effect__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! babylonjs/Materials/effect */ "babylonjs/Misc/perfCounter");
 /* harmony import */ var babylonjs_Materials_effect__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Materials_effect__WEBPACK_IMPORTED_MODULE_0__);
 
 var name = 'fluentPixelShader';
@@ -15387,7 +15387,7 @@ var fluentPixelShader = { name: name, shader: shader };
 "use strict";
 __webpack_require__.r(__webpack_exports__);
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "fluentVertexShader", function() { return fluentVertexShader; });
-/* harmony import */ var babylonjs_Materials_effect__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! babylonjs/Materials/effect */ "babylonjs/Maths/math");
+/* harmony import */ var babylonjs_Materials_effect__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! babylonjs/Materials/effect */ "babylonjs/Misc/perfCounter");
 /* harmony import */ var babylonjs_Materials_effect__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Materials_effect__WEBPACK_IMPORTED_MODULE_0__);
 
 var name = 'fluentVertexShader';
@@ -15410,7 +15410,7 @@ var fluentVertexShader = { name: name, shader: shader };
 __webpack_require__.r(__webpack_exports__);
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Vector3WithInfo", function() { return Vector3WithInfo; });
 /* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! tslib */ "../../node_modules/tslib/tslib.es6.js");
-/* harmony import */ var babylonjs_Maths_math__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! babylonjs/Maths/math */ "babylonjs/Maths/math");
+/* harmony import */ var babylonjs_Maths_math__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! babylonjs/Maths/math */ "babylonjs/Misc/perfCounter");
 /* harmony import */ var babylonjs_Maths_math__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Maths_math__WEBPACK_IMPORTED_MODULE_1__);
 
 
@@ -15704,14 +15704,14 @@ if (typeof globalObject !== "undefined") {
 
 /***/ }),
 
-/***/ "babylonjs/Maths/math":
+/***/ "babylonjs/Misc/perfCounter":
 /*!****************************************************************************************************!*\
   !*** external {"root":"BABYLON","commonjs":"babylonjs","commonjs2":"babylonjs","amd":"babylonjs"} ***!
   \****************************************************************************************************/
 /*! no static exports found */
 /***/ (function(module, exports) {
 
-module.exports = __WEBPACK_EXTERNAL_MODULE_babylonjs_Maths_math__;
+module.exports = __WEBPACK_EXTERNAL_MODULE_babylonjs_Misc_perfCounter__;
 
 /***/ })
 

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


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


+ 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": "4.1.0-alpha.15",
+    "version": "4.1.0-alpha.17",
     "repository": {
         "type": "git",
         "url": "https://github.com/BabylonJS/Babylon.js.git"
@@ -28,7 +28,7 @@
     ],
     "license": "Apache-2.0",
     "dependencies": {
-        "babylonjs": "4.1.0-alpha.15"
+        "babylonjs": "4.1.0-alpha.17"
     },
     "engines": {
         "node": "*"

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


+ 8 - 4
dist/preview release/inspector/babylon.inspector.bundle.max.js

@@ -45127,7 +45127,7 @@ var NodeMaterialPropertyGridComponent = /** @class */ (function (_super) {
     NodeMaterialPropertyGridComponent.prototype.renderInputValues = function () {
         var _this = this;
         var configurableInputBlocks = this.props.material.getInputBlocks().filter(function (block) {
-            return block.visibleInInspector && block.isUniform && !block.isWellKnownValue;
+            return block.visibleInInspector && block.isUniform && !block.isSystemValue;
         }).sort(function (a, b) {
             return a.name.localeCompare(b.name);
         });
@@ -45972,7 +45972,9 @@ var MeshPropertyGridComponent = /** @class */ (function (_super) {
             if (!mesh.reservedDataStore) {
                 mesh.reservedDataStore = {};
             }
-            mesh.reservedDataStore.originalMaterial = mesh.material;
+            if (!mesh.reservedDataStore.originalMaterial) {
+                mesh.reservedDataStore.originalMaterial = mesh.material;
+            }
             var normalMaterial = new BABYLON.NormalMaterial("normalMaterial", scene);
             normalMaterial.disableLighting = true;
             if (mesh.material) {
@@ -45996,7 +45998,9 @@ var MeshPropertyGridComponent = /** @class */ (function (_super) {
             if (!mesh.reservedDataStore) {
                 mesh.reservedDataStore = {};
             }
-            mesh.reservedDataStore.originalMaterial = mesh.material;
+            if (!mesh.reservedDataStore.originalMaterial) {
+                mesh.reservedDataStore.originalMaterial = mesh.material;
+            }
             var vertexColorMaterial = new babylonjs_Misc_tools__WEBPACK_IMPORTED_MODULE_2__["StandardMaterial"]("vertex colors", scene);
             vertexColorMaterial.disableLighting = true;
             vertexColorMaterial.emissiveColor = babylonjs_Misc_tools__WEBPACK_IMPORTED_MODULE_2__["Color3"].White();
@@ -46056,7 +46060,7 @@ var MeshPropertyGridComponent = /** @class */ (function (_super) {
         var mesh = this.props.mesh;
         var scene = mesh.getScene();
         var displayNormals = mesh.material != null && mesh.material.getClassName() === "NormalMaterial";
-        var displayVertexColors = mesh.material != null && mesh.material.reservedDataStore && mesh.material.reservedDataStore.isVertexColorMaterial;
+        var displayVertexColors = !!(mesh.material != null && mesh.material.reservedDataStore && mesh.material.reservedDataStore.isVertexColorMaterial);
         var renderNormalVectors = (mesh.reservedDataStore && mesh.reservedDataStore.normalLines) ? true : false;
         var renderWireframeOver = (mesh.reservedDataStore && mesh.reservedDataStore.wireframeOver) ? true : false;
         var morphTargets = [];

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


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

@@ -4,7 +4,7 @@
     },
     "name": "babylonjs-inspector",
     "description": "The Babylon.js inspector.",
-    "version": "4.1.0-alpha.15",
+    "version": "4.1.0-alpha.17",
     "repository": {
         "type": "git",
         "url": "https://github.com/BabylonJS/Babylon.js.git"
@@ -29,12 +29,12 @@
     ],
     "license": "Apache-2.0",
     "dependencies": {
-        "babylonjs": "4.1.0-alpha.15",
-        "babylonjs-gui": "4.1.0-alpha.15",
-        "babylonjs-loaders": "4.1.0-alpha.15",
-        "babylonjs-materials": "4.1.0-alpha.15",
-        "babylonjs-serializers": "4.1.0-alpha.15",
-        "babylonjs-gltf2interface": "4.1.0-alpha.15"
+        "babylonjs": "4.1.0-alpha.17",
+        "babylonjs-gui": "4.1.0-alpha.17",
+        "babylonjs-loaders": "4.1.0-alpha.17",
+        "babylonjs-materials": "4.1.0-alpha.17",
+        "babylonjs-serializers": "4.1.0-alpha.17",
+        "babylonjs-gltf2interface": "4.1.0-alpha.17"
     },
     "devDependencies": {
         "@types/react": "~16.7.3",

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

@@ -2734,6 +2734,13 @@ var GLTFLoader = /** @class */ (function () {
                 return new babylonjs_Misc_deferred__WEBPACK_IMPORTED_MODULE_0__["VertexBuffer"](_this._babylonScene.getEngine(), data, kind, false);
             });
         }
+        // Load joint indices as a float array since the shaders expect float data but glTF uses unsigned byte/short.
+        // This prevents certain platforms (e.g. D3D) from having to convert the data to float on the fly.
+        else if (kind === babylonjs_Misc_deferred__WEBPACK_IMPORTED_MODULE_0__["VertexBuffer"].MatricesIndicesKind) {
+            accessor._babylonVertexBuffer = this._loadFloatAccessorAsync("/accessors/" + accessor.index, accessor).then(function (data) {
+                return new babylonjs_Misc_deferred__WEBPACK_IMPORTED_MODULE_0__["VertexBuffer"](_this._babylonScene.getEngine(), data, kind, false);
+            });
+        }
         else {
             var bufferView_2 = ArrayItem.Get(context + "/bufferView", this._gltf.bufferViews, accessor.bufferView);
             accessor._babylonVertexBuffer = this._loadVertexBufferViewAsync(bufferView_2, kind).then(function (babylonBuffer) {
@@ -3004,7 +3011,7 @@ var GLTFLoader = /** @class */ (function () {
             promises.push(this.loadImageAsync("/images/" + image.index, image).then(function (data) {
                 var name = image.uri || _this._fileName + "#image" + image.index;
                 var dataUrl = "data:" + _this._uniqueRootUrl + name;
-                babylonTexture.updateURL(dataUrl, new Blob([data], { type: image.mimeType }));
+                babylonTexture.updateURL(dataUrl, data);
             }));
         }
         babylonTexture.wrapU = samplerData.wrapU;

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


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


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

@@ -5294,6 +5294,13 @@ var GLTFLoader = /** @class */ (function () {
                 return new babylonjs_Misc_deferred__WEBPACK_IMPORTED_MODULE_0__["VertexBuffer"](_this._babylonScene.getEngine(), data, kind, false);
             });
         }
+        // Load joint indices as a float array since the shaders expect float data but glTF uses unsigned byte/short.
+        // This prevents certain platforms (e.g. D3D) from having to convert the data to float on the fly.
+        else if (kind === babylonjs_Misc_deferred__WEBPACK_IMPORTED_MODULE_0__["VertexBuffer"].MatricesIndicesKind) {
+            accessor._babylonVertexBuffer = this._loadFloatAccessorAsync("/accessors/" + accessor.index, accessor).then(function (data) {
+                return new babylonjs_Misc_deferred__WEBPACK_IMPORTED_MODULE_0__["VertexBuffer"](_this._babylonScene.getEngine(), data, kind, false);
+            });
+        }
         else {
             var bufferView_2 = ArrayItem.Get(context + "/bufferView", this._gltf.bufferViews, accessor.bufferView);
             accessor._babylonVertexBuffer = this._loadVertexBufferViewAsync(bufferView_2, kind).then(function (babylonBuffer) {
@@ -5564,7 +5571,7 @@ var GLTFLoader = /** @class */ (function () {
             promises.push(this.loadImageAsync("/images/" + image.index, image).then(function (data) {
                 var name = image.uri || _this._fileName + "#image" + image.index;
                 var dataUrl = "data:" + _this._uniqueRootUrl + name;
-                babylonTexture.updateURL(dataUrl, new Blob([data], { type: image.mimeType }));
+                babylonTexture.updateURL(dataUrl, data);
             }));
         }
         babylonTexture.wrapU = samplerData.wrapU;

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


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


+ 1 - 1
dist/preview release/loaders/babylon.objFileLoader.js

@@ -886,7 +886,7 @@ var OBJFileLoader = /** @class */ (function () {
         var lines = data.split('\n');
         //Look at each line
         for (var i = 0; i < lines.length; i++) {
-            var line = lines[i].trim();
+            var line = lines[i].trim().replace(/\s\s/g, " ");
             var result;
             //Comment or newLine
             if (line.length === 0 || line.charAt(0) === '#') {

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


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


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

@@ -161,6 +161,7 @@ __webpack_require__.r(__webpack_exports__);
 
 
 
+
 /**
  * STL file type loader.
  * This is a babylon scene loader plugin.

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


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

@@ -1115,7 +1115,7 @@ var OBJFileLoader = /** @class */ (function () {
         var lines = data.split('\n');
         //Look at each line
         for (var i = 0; i < lines.length; i++) {
-            var line = lines[i].trim();
+            var line = lines[i].trim().replace(/\s\s/g, " ");
             var result;
             //Comment or newLine
             if (line.length === 0 || line.charAt(0) === '#') {
@@ -1484,6 +1484,7 @@ __webpack_require__.r(__webpack_exports__);
 
 
 
+
 /**
  * STL file type loader.
  * This is a babylon scene loader plugin.
@@ -6636,6 +6637,13 @@ var GLTFLoader = /** @class */ (function () {
                 return new babylonjs_Misc_deferred__WEBPACK_IMPORTED_MODULE_0__["VertexBuffer"](_this._babylonScene.getEngine(), data, kind, false);
             });
         }
+        // Load joint indices as a float array since the shaders expect float data but glTF uses unsigned byte/short.
+        // This prevents certain platforms (e.g. D3D) from having to convert the data to float on the fly.
+        else if (kind === babylonjs_Misc_deferred__WEBPACK_IMPORTED_MODULE_0__["VertexBuffer"].MatricesIndicesKind) {
+            accessor._babylonVertexBuffer = this._loadFloatAccessorAsync("/accessors/" + accessor.index, accessor).then(function (data) {
+                return new babylonjs_Misc_deferred__WEBPACK_IMPORTED_MODULE_0__["VertexBuffer"](_this._babylonScene.getEngine(), data, kind, false);
+            });
+        }
         else {
             var bufferView_2 = ArrayItem.Get(context + "/bufferView", this._gltf.bufferViews, accessor.bufferView);
             accessor._babylonVertexBuffer = this._loadVertexBufferViewAsync(bufferView_2, kind).then(function (babylonBuffer) {
@@ -6906,7 +6914,7 @@ var GLTFLoader = /** @class */ (function () {
             promises.push(this.loadImageAsync("/images/" + image.index, image).then(function (data) {
                 var name = image.uri || _this._fileName + "#image" + image.index;
                 var dataUrl = "data:" + _this._uniqueRootUrl + name;
-                babylonTexture.updateURL(dataUrl, new Blob([data], { type: image.mimeType }));
+                babylonTexture.updateURL(dataUrl, data);
             }));
         }
         babylonTexture.wrapU = samplerData.wrapU;

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


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


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

@@ -2224,6 +2224,7 @@ declare module "babylonjs-loaders/STL/stlFileLoader" {
     import { ISceneLoaderPlugin, ISceneLoaderPluginExtensions } from "babylonjs/Loading/sceneLoader";
     import { AssetContainer } from "babylonjs/assetContainer";
     import { Scene } from "babylonjs/scene";
+    import "babylonjs/Helpers/sceneHelpers";
     /**
      * STL file type loader.
      * This is a babylon scene loader plugin.

+ 3 - 3
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": "4.1.0-alpha.15",
+    "version": "4.1.0-alpha.17",
     "repository": {
         "type": "git",
         "url": "https://github.com/BabylonJS/Babylon.js.git"
@@ -28,8 +28,8 @@
     ],
     "license": "Apache-2.0",
     "dependencies": {
-        "babylonjs-gltf2interface": "4.1.0-alpha.15",
-        "babylonjs": "4.1.0-alpha.15"
+        "babylonjs-gltf2interface": "4.1.0-alpha.17",
+        "babylonjs": "4.1.0-alpha.17"
     },
     "engines": {
         "node": "*"

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


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


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


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


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


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


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

@@ -459,7 +459,9 @@ declare module "babylonjs-materials/grid/grid.fragment" {
     };
 }
 declare module "babylonjs-materials/grid/grid.vertex" {
+    import "babylonjs/Shaders/ShadersInclude/instancesDeclaration";
     import "babylonjs/Shaders/ShadersInclude/fogVertexDeclaration";
+    import "babylonjs/Shaders/ShadersInclude/instancesVertex";
     import "babylonjs/Shaders/ShadersInclude/fogVertex";
     /** @hidden */
     export var gridVertexShader: {

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

@@ -4,7 +4,7 @@
     },
     "name": "babylonjs-materials",
     "description": "The Babylon.js materials library is a collection of advanced materials to be used in a Babylon.js scene.",
-    "version": "4.1.0-alpha.15",
+    "version": "4.1.0-alpha.17",
     "repository": {
         "type": "git",
         "url": "https://github.com/BabylonJS/Babylon.js.git"
@@ -28,7 +28,7 @@
     ],
     "license": "Apache-2.0",
     "dependencies": {
-        "babylonjs": "4.1.0-alpha.15"
+        "babylonjs": "4.1.0-alpha.17"
     },
     "engines": {
         "node": "*"

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


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


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


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


文件差异内容过多而无法显示
+ 44 - 4
dist/preview release/nodeEditor/babylon.nodeEditor.module.d.ts


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

@@ -4,14 +4,14 @@
     },
     "name": "babylonjs-node-editor",
     "description": "The Babylon.js node material editor.",
-    "version": "4.1.0-alpha.15",
+    "version": "4.1.0-alpha.17",
     "repository": {
         "type": "git",
         "url": "https://github.com/BabylonJS/Babylon.js.git"
     },
     "license": "Apache-2.0",
     "dependencies": {
-        "babylonjs": "4.1.0-alpha.15"
+        "babylonjs": "4.1.0-alpha.17"
     },
     "files": [
         "babylon.nodeEditor.max.js.map",

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

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

+ 1 - 1
dist/preview release/packagesSizeBaseLine.json

@@ -1 +1 @@
-{"engineOnly":167207,"sceneOnly":507666,"minGridMaterial":637325,"minStandardMaterial":766702}
+{"engineOnly":167802,"sceneOnly":508293,"minGridMaterial":638479,"minStandardMaterial":767609}

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

@@ -4,7 +4,7 @@
     },
     "name": "babylonjs-post-process",
     "description": "The Babylon.js materials library is a collection of advanced materials to be used in a Babylon.js scene.",
-    "version": "4.1.0-alpha.15",
+    "version": "4.1.0-alpha.17",
     "repository": {
         "type": "git",
         "url": "https://github.com/BabylonJS/Babylon.js.git"
@@ -28,7 +28,7 @@
     ],
     "license": "Apache-2.0",
     "dependencies": {
-        "babylonjs": "4.1.0-alpha.15"
+        "babylonjs": "4.1.0-alpha.17"
     },
     "engines": {
         "node": "*"

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

@@ -4,7 +4,7 @@
     },
     "name": "babylonjs-procedural-textures",
     "description": "The Babylon.js materials library is a collection of advanced materials to be used in a Babylon.js scene.",
-    "version": "4.1.0-alpha.15",
+    "version": "4.1.0-alpha.17",
     "repository": {
         "type": "git",
         "url": "https://github.com/BabylonJS/Babylon.js.git"
@@ -28,7 +28,7 @@
     ],
     "license": "Apache-2.0",
     "dependencies": {
-        "babylonjs": "4.1.0-alpha.15"
+        "babylonjs": "4.1.0-alpha.17"
     },
     "engines": {
         "node": "*"

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


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

@@ -4,7 +4,7 @@
     },
     "name": "babylonjs-serializers",
     "description": "The Babylon.js serializers library is an extension you can use to serialize Babylon scenes.",
-    "version": "4.1.0-alpha.15",
+    "version": "4.1.0-alpha.17",
     "repository": {
         "type": "git",
         "url": "https://github.com/BabylonJS/Babylon.js.git"
@@ -28,8 +28,8 @@
     ],
     "license": "Apache-2.0",
     "dependencies": {
-        "babylonjs": "4.1.0-alpha.15",
-        "babylonjs-gltf2interface": "4.1.0-alpha.15"
+        "babylonjs": "4.1.0-alpha.17",
+        "babylonjs-gltf2interface": "4.1.0-alpha.17"
     },
     "engines": {
         "node": "*"

文件差异内容过多而无法显示
+ 1349 - 388
dist/preview release/viewer/babylon.module.d.ts


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


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


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

@@ -2224,6 +2224,7 @@ declare module "babylonjs-loaders/STL/stlFileLoader" {
     import { ISceneLoaderPlugin, ISceneLoaderPluginExtensions } from "babylonjs/Loading/sceneLoader";
     import { AssetContainer } from "babylonjs/assetContainer";
     import { Scene } from "babylonjs/scene";
+    import "babylonjs/Helpers/sceneHelpers";
     /**
      * STL file type loader.
      * This is a babylon scene loader plugin.

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

@@ -29,6 +29,7 @@
 - Added support for sound sprites [Doc](https://doc.babylonjs.com/how_to/playing_sounds_and_music#playing-a-sound-sprite) ([Deltakosh](https://github.com/deltakosh/))
 - Display Oculus Quest controller when using a Quest in WebVR ([TrevorDev](https://github.com/TrevorDev))
 - Added startAndReleaseDragOnPointerEvents property to pointerDragBehavior which can be set to false for custom drag triggering ([TrevorDev](https://github.com/TrevorDev))
+- Added optional picking predicate to pointerDragBehavior for filtering affected meshes ([Exolun](https://github.com/Exolun))
 - Effect renderer to render one or multiple shader effects to a texture ([TrevorDev](https://github.com/TrevorDev))
 - Added url parameters to web request modifiers ([PierreLeBlond](https://github.com/PierreLeBlond))
 - Added `VRExperienceHelper.exitVROnDoubleTap` ([Deltakosh](https://github.com/deltakosh/))
@@ -62,6 +63,7 @@
 - Added `ShadowGenerator.onAfterShadowMapRenderObservable` and `ShadowGenerator.onAfterShadowMapMeshRenderObservable` ([Deltakosh](https://github.com/deltakosh/))
 - Added support for side by side and top bottom images in the `PhotoDome` ([Deltakosh](https://github.com/deltakosh/))
 - Added playground ts-local (TypeScript support for local playground) ([pjoe](https://github.com/pjoe/))
+- Added RGBD Texture tools [Sebavan](https://github.com/sebavan/)
 
 ### Meshes
 - Added `TransformNode.instantiateHierarchy()` which try to instantiate (or clone) a node and its entire hiearchy ([Deltakosh](https://github.com/deltakosh/))

+ 1 - 1
gui/src/3D/gui3DManager.ts

@@ -106,7 +106,7 @@ export class GUI3DManager implements IDisposable {
     }
 
     private _doPicking(pi: PointerInfo): boolean {
-        if (!this._utilityLayer || !this._utilityLayer.utilityLayerScene.activeCamera) {
+        if (!this._utilityLayer || !this._utilityLayer.shouldRender || !this._utilityLayer.utilityLayerScene.activeCamera) {
             return false;
         }
 

+ 1 - 1
inspector/src/components/actionTabs/tabs/propertyGrids/materials/nodeMaterialPropertyGridComponent.tsx

@@ -64,7 +64,7 @@ export class NodeMaterialPropertyGridComponent extends React.Component<INodeMate
 
     renderInputValues() {
         let configurableInputBlocks = this.props.material.getInputBlocks().filter(block => {
-            return block.visibleInInspector && block.isUniform && !block.isWellKnownValue
+            return block.visibleInInspector && block.isUniform && !block.isSystemValue
         }).sort( (a, b) => {
             return a.name.localeCompare(b.name);
         });

+ 7 - 3
inspector/src/components/actionTabs/tabs/propertyGrids/meshes/meshPropertyGridComponent.tsx

@@ -152,7 +152,9 @@ export class MeshPropertyGridComponent extends React.Component<IMeshPropertyGrid
                 mesh.reservedDataStore = {};
             }
 
-            mesh.reservedDataStore.originalMaterial = mesh.material;
+            if (!mesh.reservedDataStore.originalMaterial) {
+                mesh.reservedDataStore.originalMaterial = mesh.material;
+            }
             const normalMaterial = new (BABYLON as any).NormalMaterial("normalMaterial", scene);
             normalMaterial.disableLighting = true;
             if (mesh.material) {
@@ -180,7 +182,9 @@ export class MeshPropertyGridComponent extends React.Component<IMeshPropertyGrid
                 mesh.reservedDataStore = {};
             }
 
-            mesh.reservedDataStore.originalMaterial = mesh.material;
+            if (!mesh.reservedDataStore.originalMaterial) {
+                mesh.reservedDataStore.originalMaterial = mesh.material;
+            }
             const vertexColorMaterial = new StandardMaterial("vertex colors", scene);
             vertexColorMaterial.disableLighting = true;
             vertexColorMaterial.emissiveColor = Color3.White();
@@ -247,7 +251,7 @@ export class MeshPropertyGridComponent extends React.Component<IMeshPropertyGrid
         const scene = mesh.getScene();
 
         const displayNormals = mesh.material != null && mesh.material.getClassName() === "NormalMaterial";
-        const displayVertexColors = mesh.material != null && mesh.material.reservedDataStore && mesh.material.reservedDataStore.isVertexColorMaterial;
+        const displayVertexColors = !!(mesh.material != null && mesh.material.reservedDataStore && mesh.material.reservedDataStore.isVertexColorMaterial);
         const renderNormalVectors = (mesh.reservedDataStore && mesh.reservedDataStore.normalLines) ? true : false;
         const renderWireframeOver = (mesh.reservedDataStore && mesh.reservedDataStore.wireframeOver) ? true : false;
 

+ 1 - 1
loaders/src/OBJ/objFileLoader.ts

@@ -874,7 +874,7 @@ export class OBJFileLoader implements ISceneLoaderPluginAsync, ISceneLoaderPlugi
         var lines = data.split('\n');
         //Look at each line
         for (var i = 0; i < lines.length; i++) {
-            var line = lines[i].trim();
+            var line = lines[i].trim().replace(/\s\s/g, " ");
             var result;
 
             //Comment or newLine

+ 2 - 0
loaders/src/STL/stlFileLoader.ts

@@ -9,6 +9,8 @@ import { SceneLoader, ISceneLoaderPlugin, ISceneLoaderPluginExtensions } from "b
 import { AssetContainer } from "babylonjs/assetContainer";
 import { Scene } from "babylonjs/scene";
 
+import "babylonjs/Helpers/sceneHelpers";
+
 /**
  * STL file type loader.
  * This is a babylon scene loader plugin.

+ 5 - 4
materialsLibrary/src/grid/grid.vertex.fx

@@ -10,11 +10,11 @@ attribute vec2 uv;
 attribute vec2 uv2;
 #endif
 
+#include<instancesDeclaration>
+
 // Uniforms
 uniform mat4 projection;
-uniform mat4 world;
 uniform mat4 view;
-uniform mat4 worldView;
 
 // Varying
 varying vec3 vPosition;
@@ -29,14 +29,15 @@ uniform vec2 vOpacityInfos;
 #endif
 
 void main(void) {
+	#include<instancesVertex>
 
     #ifdef FOG
-    vec4 worldPos = world * vec4(position, 1.0);
+    vec4 worldPos = finalWorld * vec4(position, 1.0);
     #endif
 
     #include<fogVertex>
 
-    vec4 cameraSpacePosition = worldView * vec4(position, 1.0);
+    vec4 cameraSpacePosition = view * finalWorld * vec4(position, 1.0);
     gl_Position = projection * cameraSpacePosition;
 
 #ifdef OPACITY

+ 10 - 3
materialsLibrary/src/grid/gridMaterial.ts

@@ -23,6 +23,7 @@ class GridMaterialDefines extends MaterialDefines {
     public PREMULTIPLYALPHA = false;
     public UV1 = false;
     public UV2 = false;
+    public INSTANCES = false;
 
     constructor() {
         super();
@@ -160,6 +161,9 @@ export class GridMaterial extends PushMaterial {
 
         MaterialHelper.PrepareDefinesForMisc(mesh, scene, false, false, this.fogEnabled, false, defines);
 
+        // Values that need to be evaluated on every frame
+        MaterialHelper.PrepareDefinesForFrameBoundValues(scene, scene.getEngine(), defines, !!useInstances);
+
         // Get correct effect
         if (defines.isDirty) {
             defines.markAsProcessed();
@@ -176,11 +180,13 @@ export class GridMaterial extends PushMaterial {
                 attribs.push(VertexBuffer.UV2Kind);
             }
 
+            MaterialHelper.PrepareAttributesForInstances(attribs, defines);
+
             // Defines
             var join = defines.toString();
             subMesh.setEffect(scene.getEngine().createEffect("grid",
                 attribs,
-                ["projection", "worldView", "mainColor", "lineColor", "gridControl", "gridOffset", "vFogInfos", "vFogColor", "world", "view",
+                ["projection", "mainColor", "lineColor", "gridControl", "gridOffset", "vFogInfos", "vFogColor", "world", "view",
                     "opacityMatrix", "vOpacityInfos"],
                 ["opacitySampler"],
                 join,
@@ -214,8 +220,9 @@ export class GridMaterial extends PushMaterial {
         this._activeEffect = effect;
 
         // Matrices
-        this.bindOnlyWorldMatrix(world);
-        this._activeEffect.setMatrix("worldView", world.multiply(scene.getViewMatrix()));
+        if (!defines.INSTANCES) {
+            this.bindOnlyWorldMatrix(world);
+        }
         this._activeEffect.setMatrix("view", scene.getViewMatrix());
         this._activeEffect.setMatrix("projection", scene.getProjectionMatrix());
 

+ 43 - 0
nodeEditor/public/index-local.html

@@ -0,0 +1,43 @@
+<!DOCTYPE html>
+<html xmlns="http://www.w3.org/1999/xhtml">
+
+<head>
+    <title>Node Material Editor - Local Development</title>    
+    <meta name="viewport" content="width=device-width, user-scalable=no">
+    <link rel="shortcut icon" href="https://www.babylonjs.com/favicon.ico">
+
+    <script src="https://code.jquery.com/pep/0.4.2/pep.min.js"></script>
+    <script src="../../Tools/DevLoader/BabylonLoader.js"></script>
+    <link rel="stylesheet" href="https://use.typekit.net/cta4xsb.css"></style>
+
+    <style>
+        html,
+        body {
+            width: 100%;
+            height: 100%;
+            padding: 0;
+            margin: 0;
+            overflow: hidden;
+        }
+
+        #host-element {
+            width: 100%;
+            height: 100%;            
+        }
+    </style>
+</head>
+
+<body>
+    <div id="host-element">
+    </div>
+    <script>
+        // Load the scripts + map file to allow vscode debug.
+        BABYLONDEVTOOLS.Loader
+            .require("index.js")
+            .load(() => {
+                BABYLONDEVTOOLS.Loader.debugShortcut(engine);
+            });
+    </script>
+</body>
+
+</html>

+ 41 - 0
nodeEditor/public/index.html

@@ -0,0 +1,41 @@
+<!DOCTYPE html>
+<html xmlns="http://www.w3.org/1999/xhtml">
+
+<head>
+    <title>Babylon.js Node Material Editor</title>
+
+    <meta name="viewport" content="width=device-width, user-scalable=no">
+    <link rel="shortcut icon" href="https://www.babylonjs.com/favicon.ico">
+
+    <script src="https://code.jquery.com/pep/0.4.2/pep.min.js"></script>
+    <link rel="stylesheet" href="https://use.typekit.net/cta4xsb.css"></style>
+    <script src="https://preview.babylonjs.com/babylon.js"></script>
+    <script src="https://preview.babylonjs.com/nodeEditor/babylon.nodeEditor.js"></script>
+    
+    <style>
+        html,
+        body {
+            width: 100%;
+            height: 100%;
+            padding: 0;
+            margin: 0;
+            overflow: hidden;
+        }
+
+        #host-element {
+            width: 100%;
+            height: 100%;               
+            padding: 0;
+            margin: 0;
+            overflow: hidden;         
+        }
+    </style>
+</head>
+
+<body>    
+    <div id="host-element">
+    </div>
+    <script src="index.js"></script>
+</body>
+
+</html>

+ 125 - 0
nodeEditor/public/index.js

@@ -0,0 +1,125 @@
+var snippetUrl = "https://snippet.babylonjs.com";
+var currentSnippetToken;
+var previousHash = "";
+var nodeMaterial;
+
+var customLoadObservable = new BABYLON.Observable();
+var editorDisplayed = false;
+
+var cleanHash = function () {
+    var splits = decodeURIComponent(location.hash.substr(1)).split("#");
+
+    if (splits.length > 2) {
+        splits.splice(2, splits.length - 2);
+    }
+
+    location.hash = splits.join("#");
+}
+
+var checkHash = function () {
+    if (location.hash) {
+        if (previousHash != location.hash) {
+            cleanHash();
+
+            previousHash = location.hash;
+
+            try {
+                var xmlHttp = new XMLHttpRequest();
+                xmlHttp.onreadystatechange = function () {
+                    if (xmlHttp.readyState == 4) {
+                        if (xmlHttp.status == 200) {
+                            var snippet = JSON.parse(JSON.parse(xmlHttp.responseText).jsonPayload);
+
+                            if (editorDisplayed) {
+                                customLoadObservable.notifyObservers(JSON.parse(snippet.nodeMaterial));
+                            } else {
+                                nodeMaterial.loadFromSerialization(snippet.nodeMaterial);
+                                nodeMaterial.build(true);
+                                showEditor();
+                            }
+                        }
+                    }
+                }
+
+                var hash = location.hash.substr(1);
+                currentSnippetToken = hash.split("#")[0];
+                xmlHttp.open("GET", snippetUrl + "/" + hash.replace("#", "/"));
+                xmlHttp.send();
+            } catch (e) {
+
+            }
+        }
+    }
+
+    setTimeout(checkHash, 200);
+}
+
+var showEditor = function() {
+    editorDisplayed = true;
+    var hostElement = document.getElementById("host-element");
+
+    BABYLON.NodeEditor.Show({
+        nodeMaterial: nodeMaterial, 
+        hostElement: hostElement,
+        customLoadObservable: customLoadObservable,
+        customSave: {
+            label: "Save as unique URL",
+            action: (data) => {
+                var xmlHttp = new XMLHttpRequest();
+                xmlHttp.onreadystatechange = function () {
+                    if (xmlHttp.readyState == 4) {
+                        if (xmlHttp.status == 200) {
+                            var baseUrl = location.href.replace(location.hash, "").replace(location.search, "");
+                            var snippet = JSON.parse(xmlHttp.responseText);
+                            var newUrl = baseUrl + "#" + snippet.id;
+                            currentSnippetToken = snippet.id;
+                            if (snippet.version && snippet.version != "0") {
+                                newUrl += "#" + snippet.version;
+                            }
+                            location.href = newUrl;
+                        }
+                        else {
+                            console.log("Unable to save your code. Please retry.", null);
+                        }
+                    }
+                }
+    
+                xmlHttp.open("POST", snippetUrl + (currentSnippetToken ? "/" + currentSnippetToken : ""), true);
+                xmlHttp.setRequestHeader("Content-Type", "application/json");
+    
+                var dataToSend = {
+                    payload : JSON.stringify({
+                        nodeMaterial: data
+                    }),
+                    name: "",
+                    description: "",
+                    tags: ""
+                };
+    
+                xmlHttp.send(JSON.stringify(dataToSend));
+            }
+        }
+    });
+}
+
+// Let's start
+if (BABYLON.Engine.isSupported()) {
+    var canvas = document.createElement("canvas");
+    var engine = new BABYLON.Engine(canvas, false);
+    var scene = new BABYLON.Scene(engine);
+
+    nodeMaterial = new BABYLON.NodeMaterial("node");
+
+    // Set to default
+    if (!location.hash) {
+        nodeMaterial.setToDefault();
+        nodeMaterial.build(true);
+        showEditor();
+    }
+
+}
+else {
+    alert('Babylon.js is not supported.')
+}
+
+checkHash();

+ 19 - 10
nodeEditor/src/blockTools.ts

@@ -30,11 +30,14 @@ import { DivideBlock } from 'babylonjs/Materials/Node/Blocks/divideBlock';
 import { SubtractBlock } from 'babylonjs/Materials/Node/Blocks/subtractBlock';
 import { StepBlock } from 'babylonjs/Materials/Node/Blocks/stepBlock';
 import { InputBlock } from 'babylonjs/Materials/Node/Blocks/Input/inputBlock';
-import { NodeMaterialWellKnownValues } from 'babylonjs/Materials/Node/nodeMaterialWellKnownValues';
+import { NodeMaterialSystemValues } from 'babylonjs/Materials/Node/nodeMaterialSystemValues';
 import { AnimatedInputBlockTypes } from 'babylonjs/Materials/Node/Blocks/Input/animatedInputBlockTypes';
 import { OppositeBlock } from 'babylonjs/Materials/Node/Blocks/oppositeBlock';
 import { ViewDirectionBlock } from 'babylonjs/Materials/Node/Blocks/viewDirectionBlock';
 import { LightInformationBlock } from 'babylonjs/Materials/Node/Blocks/Vertex/lightInformationBlock';
+import { MaxBlock } from 'babylonjs/Materials/Node/Blocks/maxBlock';
+import { MinBlock } from 'babylonjs/Materials/Node/Blocks/minBlock';
+import { PertubNormalBlock } from 'babylonjs/Materials/Node/Blocks/Fragment/pertubNormalBlock';
 
 export class BlockTools {
     public static GetBlockFromString(data: string) {
@@ -104,7 +107,13 @@ export class BlockTools {
             case "ViewDirectionBlock":
                 return new ViewDirectionBlock("View direction");    
             case "LightInformationBlock":
-                return new LightInformationBlock("Light information");                                    
+                return new LightInformationBlock("Light information");         
+            case "MaxBlock":
+                return new MaxBlock("Max");       
+            case "MinBlock":
+                return new MinBlock("Min");        
+            case "PertubNormalBlock":                                          
+                return new PertubNormalBlock("Perturb normal");        
             case "CosBlock": {
                 let cosBlock = new TrigonometryBlock("Cos");
                 cosBlock.operation = TrigonometryBlockOperations.Cos;
@@ -147,42 +156,42 @@ export class BlockTools {
             }       
             case "WorldMatrixBlock": {
                 let worldMatrixBlock = new InputBlock("World");
-                worldMatrixBlock.setAsWellKnownValue(NodeMaterialWellKnownValues.World);
+                worldMatrixBlock.setAsSystemValue(NodeMaterialSystemValues.World);
                 return worldMatrixBlock;
             }             
             case "WorldViewMatrixBlock": {
                 let worldViewMatrixBlock = new InputBlock("World x View");
-                worldViewMatrixBlock.setAsWellKnownValue(NodeMaterialWellKnownValues.WorldView);
+                worldViewMatrixBlock.setAsSystemValue(NodeMaterialSystemValues.WorldView);
                 return worldViewMatrixBlock;
             }             
             case "WorldViewProjectionMatrixBlock": {
                 let worldViewProjectionMatrixBlock = new InputBlock("World x View x Projection");
-                worldViewProjectionMatrixBlock.setAsWellKnownValue(NodeMaterialWellKnownValues.WorldViewProjection);
+                worldViewProjectionMatrixBlock.setAsSystemValue(NodeMaterialSystemValues.WorldViewProjection);
                 return worldViewProjectionMatrixBlock;
             }                    
             case "ViewMatrixBlock": {
                 let viewMatrixBlock = new InputBlock("View");
-                viewMatrixBlock.setAsWellKnownValue(NodeMaterialWellKnownValues.View);
+                viewMatrixBlock.setAsSystemValue(NodeMaterialSystemValues.View);
                 return viewMatrixBlock;
             }                          
             case "ViewProjectionMatrixBlock": {
                 let viewProjectionMatrixBlock = new InputBlock("View x Projection");
-                viewProjectionMatrixBlock.setAsWellKnownValue(NodeMaterialWellKnownValues.ViewProjection);
+                viewProjectionMatrixBlock.setAsSystemValue(NodeMaterialSystemValues.ViewProjection);
                 return viewProjectionMatrixBlock;
             }                              
             case "ProjectionMatrixBlock": {
                 let projectionMatrixBlock = new InputBlock("Projection");
-                projectionMatrixBlock.setAsWellKnownValue(NodeMaterialWellKnownValues.Projection);
+                projectionMatrixBlock.setAsSystemValue(NodeMaterialSystemValues.Projection);
                 return projectionMatrixBlock;
             }                                 
             case "CameraPositionBlock": {
                 let cameraPosition = new InputBlock("Camera position");
-                cameraPosition.setAsWellKnownValue(NodeMaterialWellKnownValues.CameraPosition);
+                cameraPosition.setAsSystemValue(NodeMaterialSystemValues.CameraPosition);
                 return cameraPosition;
             }                              
             case "FogColorBlock": {
                 let FogColor = new InputBlock("Fog color");
-                FogColor.setAsWellKnownValue(NodeMaterialWellKnownValues.FogColor);
+                FogColor.setAsSystemValue(NodeMaterialSystemValues.FogColor);
                 return FogColor;
             }                                   
             case "PositionBlock": {

+ 2 - 1
nodeEditor/src/components/diagram/diagram.scss

@@ -97,7 +97,8 @@
         border-top-left-radius: 16px;
         font-size: 16px;
         text-align: center;
-        margin-top: -1px;
+        margin-top: -1px;    
+        transform: scaleX(1.001);
         
         white-space: nowrap;
         text-overflow: ellipsis;

+ 26 - 26
nodeEditor/src/components/diagram/input/inputNodePropertyComponent.tsx

@@ -6,7 +6,7 @@ import { GlobalState } from '../../../globalState';
 import { InputNodeModel } from './inputNodeModel';
 import { NodeMaterialBlockConnectionPointTypes } from 'babylonjs/Materials/Node/nodeMaterialBlockConnectionPointTypes';
 import { OptionsLineComponent } from '../../../sharedComponents/optionsLineComponent';
-import { NodeMaterialWellKnownValues } from 'babylonjs/Materials/Node/nodeMaterialWellKnownValues';
+import { NodeMaterialSystemValues } from 'babylonjs/Materials/Node/nodeMaterialSystemValues';
 import { TextLineComponent } from '../../../sharedComponents/textLineComponent';
 import { Color3PropertyTabComponent } from '../../propertyTab/properties/color3PropertyTabComponent';
 import { FloatPropertyTabComponent } from '../../propertyTab/properties/floatPropertyTabComponent';
@@ -60,7 +60,7 @@ export class InputPropertyTabComponentProps extends React.Component<IInputProper
     render() {
         let inputBlock = this.props.inputNode.inputBlock;
 
-        var wellKnownOptions: {label: string, value: NodeMaterialWellKnownValues}[] = [];
+        var systemValuesOptions: {label: string, value: NodeMaterialSystemValues}[] = [];
         var attributeOptions: {label: string, value: string}[] = [];
         var animationOptions: {label: string, value: AnimatedInputBlockTypes}[] = [];
 
@@ -72,18 +72,18 @@ export class InputPropertyTabComponentProps extends React.Component<IInputProper
                 ];
                 break;      
             case NodeMaterialBlockConnectionPointTypes.Matrix:
-                wellKnownOptions = [
-                    { label: "World", value: NodeMaterialWellKnownValues.World },
-                    { label: "WorldxView", value: NodeMaterialWellKnownValues.WorldView },
-                    { label: "WorldxViewxProjection", value: NodeMaterialWellKnownValues.WorldViewProjection },
-                    { label: "View", value: NodeMaterialWellKnownValues.View },
-                    { label: "ViewxProjection", value: NodeMaterialWellKnownValues.ViewProjection },
-                    { label: "Projection", value: NodeMaterialWellKnownValues.Projection }
+                systemValuesOptions = [
+                    { label: "World", value: NodeMaterialSystemValues.World },
+                    { label: "World x View", value: NodeMaterialSystemValues.WorldView },
+                    { label: "World x ViewxProjection", value: NodeMaterialSystemValues.WorldViewProjection },
+                    { label: "View", value: NodeMaterialSystemValues.View },
+                    { label: "View x Projection", value: NodeMaterialSystemValues.ViewProjection },
+                    { label: "Projection", value: NodeMaterialSystemValues.Projection }
                 ];
                 break;
             case NodeMaterialBlockConnectionPointTypes.Color3:
-                wellKnownOptions = [
-                    { label: "Fog color", value: NodeMaterialWellKnownValues.FogColor }
+                systemValuesOptions = [
+                    { label: "Fog color", value: NodeMaterialSystemValues.FogColor }
                 ];
                 break;
             case NodeMaterialBlockConnectionPointTypes.Color4:
@@ -98,8 +98,8 @@ export class InputPropertyTabComponentProps extends React.Component<IInputProper
                 ];
                 break;                
             case NodeMaterialBlockConnectionPointTypes.Vector3:
-                wellKnownOptions = [
-                    { label: "Camera position", value: NodeMaterialWellKnownValues.CameraPosition }
+                systemValuesOptions = [
+                    { label: "Camera position", value: NodeMaterialSystemValues.CameraPosition }
                 ];
                 attributeOptions = [
                     { label: "position", value: "position" },
@@ -123,8 +123,8 @@ export class InputPropertyTabComponentProps extends React.Component<IInputProper
             modeOptions.push({ label: "Mesh attribute", value: 1 });
         }
 
-        if (wellKnownOptions.length > 0) {
-            modeOptions.push({ label: "Well-known value", value: 2 });
+        if (systemValuesOptions.length > 0) {
+            modeOptions.push({ label: "System value", value: 2 });
         }
 
         return (
@@ -137,6 +137,10 @@ export class InputPropertyTabComponentProps extends React.Component<IInputProper
                     <TextLineComponent label="Type" value={StringTools.GetBaseType(inputBlock.type)} />
                 </LineContainerComponent>
                 <LineContainerComponent title="PROPERTIES">
+                    {
+                        inputBlock.isUniform && !inputBlock.isSystemValue && inputBlock.animationType === AnimatedInputBlockTypes.None &&
+                        <CheckBoxLineComponent label="Visible in the Inspector" target={inputBlock} propertyName="visibleInInspector"/>
+                    }                 
                     <OptionsLineComponent label="Mode" options={modeOptions} target={inputBlock} 
                         noDirectUpdate={true}
                         getSelection={(block) => {
@@ -144,7 +148,7 @@ export class InputPropertyTabComponentProps extends React.Component<IInputProper
                                 return 1;
                             }
 
-                            if (block.isWellKnownValue) {
+                            if (block.isSystemValue) {
                                 return 2;
                             }
 
@@ -154,14 +158,14 @@ export class InputPropertyTabComponentProps extends React.Component<IInputProper
                             switch (value) {
                                 case 0:
                                     inputBlock.isUniform = true;
-                                    inputBlock.setAsWellKnownValue(null);
+                                    inputBlock.setAsSystemValue(null);
                                     this.setDefaultValue();
                                     break;
                                 case 1:
                                     inputBlock.setAsAttribute(attributeOptions[0].value);
                                     break;
                                 case 2:
-                                    inputBlock.setAsWellKnownValue(wellKnownOptions[0].value);
+                                    inputBlock.setAsSystemValue(systemValuesOptions[0].value);
                                     break;
                             }
                             this.forceUpdate();
@@ -183,17 +187,13 @@ export class InputPropertyTabComponentProps extends React.Component<IInputProper
                         }} />
                     }   
                     {
-                        inputBlock.isUniform && !inputBlock.isWellKnownValue && inputBlock.animationType === AnimatedInputBlockTypes.None &&
-                        <CheckBoxLineComponent label="Visible in the Inspector" target={inputBlock} propertyName="visibleInInspector"/>
-                    }                 
-                    {
-                        inputBlock.isUniform && !inputBlock.isWellKnownValue && inputBlock.animationType === AnimatedInputBlockTypes.None &&
+                        inputBlock.isUniform && !inputBlock.isSystemValue && inputBlock.animationType === AnimatedInputBlockTypes.None &&
                         this.renderValue(this.props.globalState)
                     }
                     {
-                        inputBlock.isUniform && inputBlock.isWellKnownValue &&
-                        <OptionsLineComponent label="Well known value" options={wellKnownOptions} target={inputBlock} propertyName="wellKnownValue" onSelect={(value: any) => {
-                            inputBlock.setAsWellKnownValue(value);
+                        inputBlock.isUniform && inputBlock.isSystemValue &&
+                        <OptionsLineComponent label="System value" options={systemValuesOptions} target={inputBlock} propertyName="systemValue" onSelect={(value: any) => {
+                            inputBlock.setAsSystemValue(value);
                             this.forceUpdate();
                             this.props.globalState.onRebuildRequiredObservable.notifyObservers();
                         }} />

+ 11 - 11
nodeEditor/src/components/diagram/input/inputNodeWidget.tsx

@@ -2,7 +2,7 @@ import * as React from "react";
 import { InputNodeModel } from './inputNodeModel';
 import { Nullable } from 'babylonjs/types';
 import { GlobalState } from '../../../globalState';
-import { NodeMaterialWellKnownValues } from 'babylonjs/Materials/Node/nodeMaterialWellKnownValues';
+import { NodeMaterialSystemValues } from 'babylonjs/Materials/Node/nodeMaterialSystemValues';
 import { NodeMaterialBlockConnectionPointTypes } from 'babylonjs/Materials/Node/nodeMaterialBlockConnectionPointTypes';
 import { Color3, Vector2, Vector3, Vector4 } from 'babylonjs/Maths/math';
 import { StringTools } from '../../../stringTools';
@@ -63,30 +63,30 @@ export class InputNodeWidget extends React.Component<IInputNodeWidgetProps> {
             if (inputBlock.isAttribute) {
                 value = "mesh." + inputBlock.name;
                 name = StringTools.GetBaseType(inputBlock.output.type);
-            } else if (inputBlock.isWellKnownValue) {
-                switch (inputBlock.wellKnownValue) {
-                    case NodeMaterialWellKnownValues.World:
+            } else if (inputBlock.isSystemValue) {
+                switch (inputBlock.systemValue) {
+                    case NodeMaterialSystemValues.World:
                         value = "World";
                         break;
-                    case NodeMaterialWellKnownValues.WorldView:
+                    case NodeMaterialSystemValues.WorldView:
                         value = "World x View";
                         break;
-                    case NodeMaterialWellKnownValues.WorldViewProjection:
+                    case NodeMaterialSystemValues.WorldViewProjection:
                         value = "World x View x Projection";
                         break;
-                    case NodeMaterialWellKnownValues.View:
+                    case NodeMaterialSystemValues.View:
                         value = "View";
                         break;
-                    case NodeMaterialWellKnownValues.ViewProjection:
+                    case NodeMaterialSystemValues.ViewProjection:
                         value = "View x Projection";
                         break;
-                    case NodeMaterialWellKnownValues.Projection:
+                    case NodeMaterialSystemValues.Projection:
                         value = "Projection";
                         break;
-                    case NodeMaterialWellKnownValues.CameraPosition:
+                    case NodeMaterialSystemValues.CameraPosition:
                         value = "Camera position";
                         break;
-                    case NodeMaterialWellKnownValues.FogColor:
+                    case NodeMaterialSystemValues.FogColor:
                         value = "Fog color";
                         break;
                 }

+ 0 - 1
nodeEditor/src/components/log/log.scss

@@ -1,6 +1,5 @@
 #log-console {
     background: #333333;
-    border: #555555 solid 1px;
     height: 120px;
     box-sizing: border-box;
     margin: 0;

+ 1 - 1
nodeEditor/src/components/nodeList/nodeList.scss

@@ -49,7 +49,7 @@
             .list-container {
                 overflow-x: hidden;
                 overflow-y: auto;
-                height: 100%;
+                height: calc(100% - 32px);
 
                 .underline {
                     border-bottom: 0.5px solid rgba(255, 255, 255, 0.5);

+ 3 - 3
nodeEditor/src/components/nodeList/nodeListComponent.tsx

@@ -26,7 +26,7 @@ export class NodeListComponent extends React.Component<INodeListComponentProps,
         // Block types used to create the menu from
         const allBlocks = {
             Animation: ["BonesBlock", "MorphTargetsBlock"],
-            Basic_Math: ["AddBlock",  "DivideBlock", "MultiplyBlock", "ScaleBlock", "SubtractBlock", "OppositeBlock"],
+            Basic_Math: ["AddBlock",  "DivideBlock", "MultiplyBlock", "ScaleBlock", "SubtractBlock", "OppositeBlock", "MaxBlock", "MinBlock"],
             Conversion_Blocks: ["ColorMergerBlock", "ColorSplitterBlock", "VectorMergerBlock", "VectorSplitterBlock"],
             Inputs: ["Float", "Vector2", "Vector3", "Vector4", "Color3", "Color4", "TextureBlock", "TimeBlock"],
             Interpolation: ["LerpBlock"],
@@ -35,7 +35,7 @@ export class NodeListComponent extends React.Component<INodeListComponentProps,
             Output_Blocks: ["VertexOutputBlock", "FragmentOutputBlock", "AlphaTestBlock"],
             Range: ["ClampBlock", "RemapBlock", "NormalizeBlock"],
             Round: ["StepBlock", "RoundBlock", "CeilingBlock", "FloorBlock"],
-            Scene_Attributes: ["FogBlock", "CameraPositionBlock", "FogColorBlock", "ImageProcessingBlock", "LightBlock", "LightInformationBlock", "ReflectionTextureBlock", "ViewDirectionBlock"],
+            Scene_Attributes: ["FogBlock", "CameraPositionBlock", "FogColorBlock", "ImageProcessingBlock", "LightBlock", "LightInformationBlock", "ReflectionTextureBlock", "ViewDirectionBlock", "PertubNormalBlock"],
             Trigonometry: ["CosBlock", "SinBlock", "AbsBlock", "ExpBlock", "Exp2Block"],
             Vector_Math: ["CrossBlock", "DotBlock", "TransformBlock", "FresnelBlock"],
         }
@@ -59,7 +59,7 @@ export class NodeListComponent extends React.Component<INodeListComponentProps,
         }
 
         return (
-            <div id="nodeList" style={{ borderRightStyle: "solid", borderColor: "grey", borderWidth: "1px" }} >
+            <div id="nodeList">
                 <div className="panes">
                     <div className="pane">
                         <div className="filter">

+ 5 - 2
nodeEditor/src/components/preview/previewManager.ts

@@ -78,10 +78,13 @@ export class PreviewManager {
             case PreviewMeshType.Torus:
                 this._dummy = Mesh.CreateTorus("dummy-torus", 2, 0.5, 32, this._scene);
                 break;
-                case PreviewMeshType.Cylinder:
+            case PreviewMeshType.Cylinder:
                 this._dummy = Mesh.CreateCylinder("dummy-cylinder", 2, 1, 1.2, 32, 1, this._scene);
                 break;                
-        }
+            case PreviewMeshType.Plane:
+                this._dummy = Mesh.CreateGround("dummy-plane", 2, 2, 128, this._scene);
+                break;                
+            }
         this._dummy.material = this._material;
     }
 

+ 4 - 1
nodeEditor/src/components/preview/previewMeshControlComponent.tsx

@@ -2,7 +2,7 @@
 import * as React from "react";
 import { GlobalState } from '../../globalState';
 import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
-import { faCircle, faRing, faCube, faHockeyPuck } from '@fortawesome/free-solid-svg-icons';
+import { faCircle, faRing, faCube, faHockeyPuck, faSquareFull } from '@fortawesome/free-solid-svg-icons';
 import { PreviewMeshType } from './previewMeshType';
 import { DataStorage } from '../../dataStorage';
 
@@ -40,6 +40,9 @@ export class PreviewMeshControlComponent extends React.Component<IPreviewMeshCon
                 <div onClick={() => this.changeMeshType(PreviewMeshType.Cylinder)} className={"button" + (this.props.globalState.previewMeshType === PreviewMeshType.Cylinder ? " selected" : "")}>
                     <FontAwesomeIcon icon={faHockeyPuck} />
                 </div>
+                <div onClick={() => this.changeMeshType(PreviewMeshType.Plane)} className={"button" + (this.props.globalState.previewMeshType === PreviewMeshType.Plane ? " selected" : "")}>
+                    <FontAwesomeIcon icon={faSquareFull} />
+                </div>
             </div>
         );
 

+ 2 - 1
nodeEditor/src/components/preview/previewMeshType.ts

@@ -2,5 +2,6 @@ export enum PreviewMeshType {
     Sphere,
     Box, 
     Torus,
-    Cylinder
+    Cylinder,
+    Plane
 }

+ 9 - 35
nodeEditor/src/components/propertyTab/propertyTabComponent.tsx

@@ -8,7 +8,7 @@ import { LineContainerComponent } from '../../sharedComponents/lineContainerComp
 import { StringTools } from '../../stringTools';
 import { FileButtonLineComponent } from '../../sharedComponents/fileButtonLineComponent';
 import { Tools } from 'babylonjs/Misc/tools';
-import { INodeLocationInfo } from '../../nodeLocationInfo';
+import { SerializationTools } from '../../serializationTools';
 require("./propertyTab.scss");
 
 interface IPropertyTabComponentProps {
@@ -32,45 +32,13 @@ export class PropertyTabComponent extends React.Component<IPropertyTabComponentP
     load(file: File) {
         Tools.ReadFile(file, (data) => {
             let decoder = new TextDecoder("utf-8");
-            let serializationObject = JSON.parse(decoder.decode(data));
+            SerializationTools.Deserialize(JSON.parse(decoder.decode(data)), this.props.globalState);
 
-            this.props.globalState.nodeMaterial!.loadFromSerialization(serializationObject, "");
-
-            // Check for id mapping
-            if (serializationObject.locations && serializationObject.map) {
-                let map: {[key: number]: number} = serializationObject.map;
-                let locations: INodeLocationInfo[] = serializationObject.locations;
-
-                for (var location of locations) {
-                    location.blockId = map[location.blockId];
-                }
-            }
-            
-            this.props.globalState.onResetRequiredObservable.notifyObservers(serializationObject.locations);
         }, undefined, true);
     }
 
     save() {
-        let material = this.props.globalState.nodeMaterial;
-        let serializationObject = material.serialize();
-
-        // Store node locations
-        for (var block of material.attachedBlocks) {
-            let node = this.props.globalState.onGetNodeFromBlock(block);
-
-            if (!serializationObject.locations) {
-                serializationObject.locations = [];
-            }
-
-            serializationObject.locations.push({
-                blockId: block.uniqueId,
-                x: node ? node.x : 0,
-                y: node ? node.y : 0
-            });
-        }
-
-        // Output
-        let json = JSON.stringify(serializationObject, undefined, 2);
+        let json = SerializationTools.Serialize(this.props.globalState.nodeMaterial, this.props.globalState);
         StringTools.DownloadAsFile(this.props.globalState.hostDocument, json, "nodeMaterial.json");
     }
 
@@ -117,6 +85,12 @@ export class PropertyTabComponent extends React.Component<IPropertyTabComponentP
                         <ButtonLineComponent label="Save" onClick={() => {
                             this.save();
                         }} />
+                        {
+                            this.props.globalState.customSave && 
+                            <ButtonLineComponent label={this.props.globalState.customSave!.label} onClick={() => {
+                                this.props.globalState.customSave!.action(SerializationTools.Serialize(this.props.globalState.nodeMaterial, this.props.globalState));
+                            }} />
+                        }
                         <ButtonLineComponent label="Generate code" onClick={() => {
                             StringTools.DownloadAsFile(this.props.globalState.hostDocument, this.props.globalState.nodeMaterial!.generateCode(), "code.txt");
                         }} />

+ 2 - 0
nodeEditor/src/globalState.ts

@@ -25,6 +25,8 @@ export class GlobalState {
     onGetNodeFromBlock: (block: NodeMaterialBlock) => NodeModel;
     previewMeshType: PreviewMeshType;
     blockKeyboardEvents = false;
+    
+    customSave?: {label: string, action: (data: string) => void};
 
     public constructor() {
         this.previewMeshType = DataStorage.ReadNumber("PreviewMeshType", PreviewMeshType.Box);

+ 19 - 2
nodeEditor/src/nodeEditor.ts

@@ -4,11 +4,16 @@ import { GlobalState } from './globalState';
 import { GraphEditor } from './graphEditor';
 import { NodeMaterial } from "babylonjs/Materials/Node/nodeMaterial"
 import { Popup } from "../src/sharedComponents/popup"
+import { SerializationTools } from './serializationTools';
+import { Observable } from 'babylonjs/Misc/observable';
 /**
  * Interface used to specify creation options for the node editor
  */
 export interface INodeEditorOptions {
-    nodeMaterial: NodeMaterial
+    nodeMaterial: NodeMaterial,
+    hostElement?: HTMLElement,
+    customSave?: {label: string, action: (data: string) => void};
+    customLoadObservable?: Observable<any>
 }
 
 /**
@@ -29,11 +34,17 @@ export class NodeEditor {
             }
         }
 
-        let hostElement = Popup.CreatePopup("BABYLON.JS NODE EDITOR", "node-editor", 1000, 800)!;
+        let hostElement = options.hostElement;
+        
+        if (!hostElement) {
+            hostElement = Popup.CreatePopup("BABYLON.JS NODE EDITOR", "node-editor", 1000, 800)!;
+        }
+        
         let globalState = new GlobalState();
         globalState.nodeMaterial = options.nodeMaterial
         globalState.hostElement = hostElement;
         globalState.hostDocument = hostElement.ownerDocument!;
+        globalState.customSave = options.customSave;
 
         const graphEditor = React.createElement(GraphEditor, {
             globalState: globalState
@@ -41,6 +52,12 @@ export class NodeEditor {
 
         ReactDOM.render(graphEditor, hostElement);
 
+        if (options.customLoadObservable) {
+            options.customLoadObservable.add(data => {
+                SerializationTools.Deserialize(data, globalState);
+            })
+        }
+
         this._CurrentState = globalState;
 
         // Close the popup window when the page is refreshed or scene is disposed

+ 42 - 0
nodeEditor/src/serializationTools.ts

@@ -0,0 +1,42 @@
+import { NodeMaterial } from 'babylonjs/Materials/Node/nodeMaterial';
+import { GlobalState } from './globalState';
+import { INodeLocationInfo } from './nodeLocationInfo';
+
+export class SerializationTools {
+    public static Serialize(material: NodeMaterial, globalState: GlobalState) {
+        let serializationObject = material.serialize();
+
+        // Store node locations
+        for (var block of material.attachedBlocks) {
+            let node = globalState.onGetNodeFromBlock(block);
+
+            if (!serializationObject.locations) {
+                serializationObject.locations = [];
+            }
+
+            serializationObject.locations.push({
+                blockId: block.uniqueId,
+                x: node ? node.x : 0,
+                y: node ? node.y : 0
+            });
+        }
+
+        return JSON.stringify(serializationObject, undefined, 2);
+    }
+
+    public static Deserialize(serializationObject:any, globalState: GlobalState) {        
+        globalState.nodeMaterial!.loadFromSerialization(serializationObject, "");
+
+        // Check for id mapping
+        if (serializationObject.locations && serializationObject.map) {
+            let map: {[key: number]: number} = serializationObject.map;
+            let locations: INodeLocationInfo[] = serializationObject.locations;
+
+            for (var location of locations) {
+                location.blockId = map[location.blockId];
+            }
+        }
+        
+        globalState.onResetRequiredObservable.notifyObservers(serializationObject.locations);
+    }
+}

+ 6 - 2
nodeEditor/src/sharedComponents/color3LineComponent.tsx

@@ -1,6 +1,6 @@
 import * as React from "react";
 import { Observable } from "babylonjs/Misc/observable";
-import { Color3 } from "babylonjs/Maths/math";
+import { Color3, Color4 } from "babylonjs/Maths/math";
 import { PropertyChangedEvent } from "./propertyChangedEvent";
 import { NumericInputComponent } from "./numericInputComponent";
 import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
@@ -46,7 +46,11 @@ export class Color3LineComponent extends React.Component<IColor3LineComponentPro
             });
         }
 
-        this.props.target[this.props.propertyName] = newColor;
+        if (this.props.target[this.props.propertyName].getClassName() === "Color4") {
+            this.props.target[this.props.propertyName] = new Color4(newColor.r, newColor.g, newColor.b, 1.0);
+        } else {
+            this.props.target[this.props.propertyName] = newColor;
+        }
 
         this.setState({ color: newColor });
 

+ 2 - 2
package.json

@@ -7,7 +7,7 @@
     ],
     "name": "babylonjs",
     "description": "Babylon.js is a JavaScript 3D engine based on webgl.",
-    "version": "4.1.0-alpha.15",
+    "version": "4.1.0-alpha.17",
     "repository": {
         "type": "git",
         "url": "https://github.com/BabylonJS/Babylon.js.git"
@@ -107,4 +107,4 @@
         "xhr2": "^0.1.4",
         "xmlbuilder": "8.2.2"
     }
-}
+}

+ 3 - 2
src/Behaviors/Meshes/pointerDragBehavior.ts

@@ -142,8 +142,9 @@ export class PointerDragBehavior implements Behavior<AbstractMesh> {
     /**
      * Attaches the drag behavior the passed in mesh
      * @param ownerNode The mesh that will be dragged around once attached
+     * @param predicate Predicate to use for pick filtering
      */
-    public attach(ownerNode: AbstractMesh): void {
+    public attach(ownerNode: AbstractMesh, predicate?: (m: AbstractMesh) => boolean): void {
         this._scene = ownerNode.getScene();
         this.attachedNode = ownerNode;
 
@@ -165,7 +166,7 @@ export class PointerDragBehavior implements Behavior<AbstractMesh> {
         // State of the drag
         this.lastDragPosition = new Vector3(0, 0, 0);
 
-        var pickPredicate = (m: AbstractMesh) => {
+        var pickPredicate = !!predicate ? predicate : (m: AbstractMesh) => {
             return this.attachedNode == m || m.isDescendantOf(this.attachedNode);
         };
 

+ 4 - 4
src/Engines/engine.ts

@@ -513,14 +513,14 @@ export class Engine {
      */
     // Not mixed with Version for tooling purpose.
     public static get NpmPackage(): string {
-        return "babylonjs@4.1.0-alpha.15";
+        return "babylonjs@4.1.0-alpha.17";
     }
 
     /**
      * Returns the current version of the framework
      */
     public static get Version(): string {
-        return "4.1.0-alpha.15";
+        return "4.1.0-alpha.17";
     }
 
     /**
@@ -2751,7 +2751,7 @@ export class Engine {
             } else {
                 // number[] or Int32Array, check if 32 bit is necessary
                 for (var index = 0; index < indices.length; index++) {
-                    if (indices[index] > 65535) {
+                    if (indices[index] >= 65535) {
                         return new Uint32Array(indices);
                     }
                 }
@@ -5509,7 +5509,7 @@ export class Engine {
 
     private _bindSamplerUniformToChannel(sourceSlot: number, destination: number) {
         let uniform = this._boundUniforms[sourceSlot];
-        if (uniform._currentState === destination) {
+        if (!uniform || uniform._currentState === destination) {
             return;
         }
         this._gl.uniform1i(uniform, destination);

+ 11 - 5
src/Layers/highlightLayer.ts

@@ -631,14 +631,20 @@ export class HighlightLayer extends EffectLayer {
                 color: color,
                 // Lambda required for capture due to Observable this context
                 observerHighlight: mesh.onBeforeBindObservable.add((mesh: Mesh) => {
-                    if (this._excludedMeshes && this._excludedMeshes[mesh.uniqueId]) {
-                        this._defaultStencilReference(mesh);
+                    if (this.isEnabled) {
+                        if (this._excludedMeshes && this._excludedMeshes[mesh.uniqueId]) {
+                            this._defaultStencilReference(mesh);
+                        }
+                        else {
+                            mesh.getScene().getEngine().setStencilFunctionReference(this._instanceGlowingMeshStencilReference);
+                        }
                     }
-                    else {
-                        mesh.getScene().getEngine().setStencilFunctionReference(this._instanceGlowingMeshStencilReference);
+                }),
+                observerDefault: mesh.onAfterRenderObservable.add((mesh: Mesh) => {
+                    if (this.isEnabled) {
+                        this._defaultStencilReference(mesh);
                     }
                 }),
-                observerDefault: mesh.onAfterRenderObservable.add(this._defaultStencilReference),
                 glowEmissiveOnly: glowEmissiveOnly
             };
 

+ 6 - 7
src/Materials/Node/Blocks/Dual/fogBlock.ts

@@ -1,7 +1,7 @@
 import { NodeMaterialBlock } from '../../nodeMaterialBlock';
 import { NodeMaterialBlockConnectionPointTypes } from '../../nodeMaterialBlockConnectionPointTypes';
 import { NodeMaterialBuildState } from '../../nodeMaterialBuildState';
-import { NodeMaterialWellKnownValues } from '../../nodeMaterialWellKnownValues';
+import { NodeMaterialSystemValues } from '../../nodeMaterialSystemValues';
 import { NodeMaterialBlockTargets } from '../../nodeMaterialBlockTargets';
 import { Mesh } from '../../../../Meshes/mesh';
 import { Effect } from '../../../effect';
@@ -85,20 +85,20 @@ export class FogBlock extends NodeMaterialBlock {
 
     public autoConfigure(material: NodeMaterial) {
         if (!this.view.isConnected) {
-            let viewInput = material.getInputBlockByPredicate((b) => b.wellKnownValue === NodeMaterialWellKnownValues.View);
+            let viewInput = material.getInputBlockByPredicate((b) => b.systemValue === NodeMaterialSystemValues.View);
 
             if (!viewInput) {
                 viewInput = new InputBlock("view");
-                viewInput.setAsWellKnownValue(NodeMaterialWellKnownValues.View);
+                viewInput.setAsSystemValue(NodeMaterialSystemValues.View);
             }
             viewInput.output.connectTo(this.view);
         }
         if (!this.fogColor.isConnected) {
-            let fogColorInput = material.getInputBlockByPredicate((b) => b.wellKnownValue === NodeMaterialWellKnownValues.FogColor);
+            let fogColorInput = material.getInputBlockByPredicate((b) => b.systemValue === NodeMaterialSystemValues.FogColor);
 
             if (!fogColorInput) {
                 fogColorInput = new InputBlock("fogColor", undefined, NodeMaterialBlockConnectionPointTypes.Color3);
-                fogColorInput.setAsWellKnownValue(NodeMaterialWellKnownValues.FogColor);
+                fogColorInput.setAsSystemValue(NodeMaterialSystemValues.FogColor);
             }
             fogColorInput.output.connectTo(this.fogColor);
         }
@@ -121,9 +121,8 @@ export class FogBlock extends NodeMaterialBlock {
     protected _buildBlock(state: NodeMaterialBuildState) {
         super._buildBlock(state);
 
-        state.sharedData.blocksWithDefines.push(this);
-
         if (state.target === NodeMaterialBlockTargets.Fragment) {
+            state.sharedData.blocksWithDefines.push(this);
             state.sharedData.bindableBlocks.push(this);
 
             state._emitFunctionFromInclude("fogFragmentDeclaration", `//${this.name}`, {

+ 5 - 12
src/Materials/Node/Blocks/Dual/lightBlock.ts

@@ -8,7 +8,7 @@ import { AbstractMesh } from '../../../../Meshes/abstractMesh';
 import { NodeMaterial, NodeMaterialDefines } from '../../nodeMaterial';
 import { Effect } from '../../../effect';
 import { Mesh } from '../../../../Meshes/mesh';
-import { NodeMaterialWellKnownValues } from '../../nodeMaterialWellKnownValues';
+import { NodeMaterialSystemValues } from '../../nodeMaterialSystemValues';
 import { InputBlock } from '../Input/inputBlock';
 import { Light } from '../../../../Lights/light';
 import { Nullable } from '../../../../types';
@@ -34,7 +34,7 @@ export class LightBlock extends NodeMaterialBlock {
         super(name, NodeMaterialBlockTargets.VertexAndFragment);
 
         this.registerInput("worldPosition", NodeMaterialBlockConnectionPointTypes.Vector4, false, NodeMaterialBlockTargets.Vertex);
-        this.registerInput("worldNormal", NodeMaterialBlockConnectionPointTypes.Vector4, false, NodeMaterialBlockTargets.Vertex);
+        this.registerInput("worldNormal", NodeMaterialBlockConnectionPointTypes.Vector4, false, NodeMaterialBlockTargets.Fragment);
 
         this.registerInput("cameraPosition", NodeMaterialBlockConnectionPointTypes.Vector3, false, NodeMaterialBlockTargets.Fragment);
         this.registerOutput("diffuseOutput", NodeMaterialBlockConnectionPointTypes.Color3, NodeMaterialBlockTargets.Fragment);
@@ -86,11 +86,11 @@ export class LightBlock extends NodeMaterialBlock {
 
     public autoConfigure(material: NodeMaterial) {
         if (!this.cameraPosition.isConnected) {
-            let cameraPositionInput = material.getInputBlockByPredicate((b) => b.wellKnownValue === NodeMaterialWellKnownValues.CameraPosition);
+            let cameraPositionInput = material.getInputBlockByPredicate((b) => b.systemValue === NodeMaterialSystemValues.CameraPosition);
 
             if (!cameraPositionInput) {
                 cameraPositionInput = new InputBlock("cameraPosition");
-                cameraPositionInput.setAsWellKnownValue(NodeMaterialWellKnownValues.CameraPosition);
+                cameraPositionInput.setAsSystemValue(NodeMaterialSystemValues.CameraPosition);
             }
             cameraPositionInput.output.connectTo(this.cameraPosition);
         }
@@ -147,8 +147,6 @@ export class LightBlock extends NodeMaterialBlock {
 
     private _injectVertexCode(state: NodeMaterialBuildState) {
         let worldPos = this.worldPosition;
-        let worldNormal = this.worldNormal;
-
         let comments = `//${this.name}`;
 
         // Declaration
@@ -175,11 +173,6 @@ export class LightBlock extends NodeMaterialBlock {
             state.compilationString += `${worldPosVaryingName} = ${worldPos.associatedVariableName};\r\n`;
         }
 
-        let worldNormalVaryingName = "v_" + worldNormal.associatedVariableName;
-        if (state._emitVaryingFromString(worldNormalVaryingName, "vec4")) {
-            state.compilationString += `${worldNormalVaryingName} = ${worldNormal.associatedVariableName};\r\n`;
-        }
-
         if (this.light) {
             state.compilationString += state._emitCodeFromInclude("shadowsVertex", comments, {
                 replaceStrings: [
@@ -249,7 +242,7 @@ export class LightBlock extends NodeMaterialBlock {
             state.compilationString += `float glossiness = 0.;\r\n`;
             state.compilationString += `vec3 diffuseBase = vec3(0., 0., 0.);\r\n`;
             state.compilationString += `vec3 specularBase = vec3(0., 0., 0.);\r\n`;
-            state.compilationString += `vec3 normalW = v_${this.worldNormal.associatedVariableName}.xyz;\r\n`;
+            state.compilationString += `vec3 normalW = ${this.worldNormal.associatedVariableName}.xyz;\r\n`;
         }
 
         if (this.light) {

+ 7 - 7
src/Materials/Node/Blocks/Dual/reflectionTextureBlock.ts

@@ -13,7 +13,7 @@ import { _TypeStore } from '../../../../Misc/typeStore';
 import { Texture } from '../../../Textures/texture';
 import { Scene } from '../../../../scene';
 import { InputBlock } from '../Input/inputBlock';
-import { NodeMaterialWellKnownValues } from '../../nodeMaterialWellKnownValues';
+import { NodeMaterialSystemValues } from '../../nodeMaterialSystemValues';
 import { Constants } from '../../../../Engines/constants';
 
 /**
@@ -156,31 +156,31 @@ export class ReflectionTextureBlock extends NodeMaterialBlock {
         }
 
         if (!this.world.isConnected) {
-            let worldInput = material.getInputBlockByPredicate((b) => b.wellKnownValue === NodeMaterialWellKnownValues.World);
+            let worldInput = material.getInputBlockByPredicate((b) => b.systemValue === NodeMaterialSystemValues.World);
 
             if (!worldInput) {
                 worldInput = new InputBlock("world");
-                worldInput.setAsWellKnownValue(NodeMaterialWellKnownValues.World);
+                worldInput.setAsSystemValue(NodeMaterialSystemValues.World);
             }
             worldInput.output.connectTo(this.world);
         }
 
         if (!this.cameraPosition.isConnected) {
-            let cameraPositionInput = material.getInputBlockByPredicate((b) => b.wellKnownValue === NodeMaterialWellKnownValues.CameraPosition);
+            let cameraPositionInput = material.getInputBlockByPredicate((b) => b.systemValue === NodeMaterialSystemValues.CameraPosition);
 
             if (!cameraPositionInput) {
                 cameraPositionInput = new InputBlock("cameraPosition");
-                cameraPositionInput.setAsWellKnownValue(NodeMaterialWellKnownValues.CameraPosition);
+                cameraPositionInput.setAsSystemValue(NodeMaterialSystemValues.CameraPosition);
             }
             cameraPositionInput.output.connectTo(this.cameraPosition);
         }
 
         if (!this.view.isConnected) {
-            let viewInput = material.getInputBlockByPredicate((b) => b.wellKnownValue === NodeMaterialWellKnownValues.View);
+            let viewInput = material.getInputBlockByPredicate((b) => b.systemValue === NodeMaterialSystemValues.View);
 
             if (!viewInput) {
                 viewInput = new InputBlock("view");
-                viewInput.setAsWellKnownValue(NodeMaterialWellKnownValues.View);
+                viewInput.setAsSystemValue(NodeMaterialSystemValues.View);
             }
             viewInput.output.connectTo(this.view);
         }

+ 2 - 0
src/Materials/Node/Blocks/Dual/textureBlock.ts

@@ -109,6 +109,8 @@ export class TextureBlock extends NodeMaterialBlock {
     }
 
     public get target() {
+        // TextureBlock has a special optimizations for uvs that come from the vertex shaders as they can be packed into a single varyings.
+        // But we need to detect uvs coming from fragment then
         if (!this.uv.isConnected) {
             return NodeMaterialBlockTargets.VertexAndFragment;
         }

+ 2 - 1
src/Materials/Node/Blocks/Fragment/index.ts

@@ -1,4 +1,5 @@
 
 export * from "./fragmentOutputBlock";
 export * from "./alphaTestBlock";
-export * from "./imageProcessingBlock";
+export * from "./imageProcessingBlock";
+export * from "./pertubNormalBlock";

+ 139 - 0
src/Materials/Node/Blocks/Fragment/pertubNormalBlock.ts

@@ -0,0 +1,139 @@
+import { NodeMaterialBlock } from '../../nodeMaterialBlock';
+import { NodeMaterialBlockConnectionPointTypes } from '../../nodeMaterialBlockConnectionPointTypes';
+import { NodeMaterialBuildState } from '../../nodeMaterialBuildState';
+import { NodeMaterialBlockTargets } from '../../nodeMaterialBlockTargets';
+import { NodeMaterialConnectionPoint } from '../../nodeMaterialBlockConnectionPoint';
+import { _TypeStore } from '../../../../Misc/typeStore';
+import { NodeMaterial, NodeMaterialDefines } from '../../nodeMaterial';
+import { AbstractMesh } from '../../../../Meshes/abstractMesh';
+import { InputBlock } from '../Input/inputBlock';
+
+/**
+ * Block used to pertub normals based on a normal map
+ */
+export class PertubNormalBlock extends NodeMaterialBlock {
+    /**
+     * Create a new PertubNormalBlock
+     * @param name defines the block name
+     */
+    public constructor(name: string) {
+        super(name, NodeMaterialBlockTargets.Fragment);
+
+        // Vertex
+        this.registerInput("worldPosition", NodeMaterialBlockConnectionPointTypes.Vector4, false, NodeMaterialBlockTargets.Fragment);
+        this.registerInput("worldNormal", NodeMaterialBlockConnectionPointTypes.Vector4, false, NodeMaterialBlockTargets.Fragment);
+        this.registerInput("uv", NodeMaterialBlockConnectionPointTypes.Vector2, false, NodeMaterialBlockTargets.Fragment);
+        this.registerInput("normalMapColor", NodeMaterialBlockConnectionPointTypes.Color3, false, NodeMaterialBlockTargets.Fragment);
+        this.registerInput("strength", NodeMaterialBlockConnectionPointTypes.Float, false, NodeMaterialBlockTargets.Fragment);
+
+        // Fragment
+        this.registerOutput("output", NodeMaterialBlockConnectionPointTypes.Vector4, NodeMaterialBlockTargets.Fragment);
+    }
+
+    /**
+     * Gets the current class name
+     * @returns the class name
+     */
+    public getClassName() {
+        return "PertubNormalBlock";
+    }
+
+    /**
+     * Gets the world position input component
+     */
+    public get worldPosition(): NodeMaterialConnectionPoint {
+        return this._inputs[0];
+    }
+
+    /**
+     * Gets the world normal input component
+     */
+    public get worldNormal(): NodeMaterialConnectionPoint {
+        return this._inputs[1];
+    }
+
+    /**
+     * Gets the uv input component
+     */
+    public get uv(): NodeMaterialConnectionPoint {
+        return this._inputs[2];
+    }
+
+    /**
+    * Gets the normal map color input component
+    */
+    public get normalMapColor(): NodeMaterialConnectionPoint {
+        return this._inputs[3];
+    }
+
+    /**
+    * Gets the strength input component
+    */
+    public get strength(): NodeMaterialConnectionPoint {
+        return this._inputs[4];
+    }
+
+    /**
+     * Gets the output component
+     */
+    public get output(): NodeMaterialConnectionPoint {
+        return this._outputs[0];
+    }
+
+    public prepareDefines(mesh: AbstractMesh, nodeMaterial: NodeMaterial, defines: NodeMaterialDefines) {
+        defines.setValue("BUMP", true);
+    }
+
+    public autoConfigure(material: NodeMaterial) {
+        if (!this.uv.isConnected) {
+            let uvInput = material.getInputBlockByPredicate((b) => b.isAttribute && b.name === "uv");
+
+            if (!uvInput) {
+                uvInput = new InputBlock("uv");
+                uvInput.setAsAttribute();
+            }
+            uvInput.output.connectTo(this.uv);
+        }
+
+        if (!this.strength.isConnected) {
+            let strengthInput = new InputBlock("strength");
+            strengthInput.value = 1.0;
+            strengthInput.output.connectTo(this.strength);
+        }
+    }
+
+    protected _buildBlock(state: NodeMaterialBuildState) {
+        super._buildBlock(state);
+
+        let comments = `//${this.name}`;
+        let uv = this.uv;
+        let worldPosition = this.worldPosition;
+        let worldNormal = this.worldNormal;
+
+        state.sharedData.blocksWithDefines.push(this);
+
+        state._emitExtension("bump", "#extension GL_OES_standard_derivatives : enable");
+        state._emitFunctionFromInclude("bumpFragmentFunctions", comments, {
+            replaceStrings: [
+                { search: /vBumpInfos.y/g, replace: `1.0 / ${this.strength.associatedVariableName}`},
+                { search: /vTangentSpaceParams/g, replace: "vec2(1.0, 1.0)"},
+                { search: /vPositionW/g, replace: worldPosition.associatedVariableName + ".xyz"}
+            ]
+        });
+        state.compilationString += this._declareOutput(this.output, state) + " = vec4(0.);\r\n";
+        state.compilationString += state._emitCodeFromInclude("bumpFragment", comments, {
+            replaceStrings: [
+                { search: /perturbNormal\(TBN,vBumpUV\+uvOffset\)/g, replace: `perturbNormal(TBN, ${this.normalMapColor.associatedVariableName})` },
+                { search: /vBumpInfos.y/g, replace: `1.0 / ${this.strength.associatedVariableName}`},
+                { search: /vBumpUV/g, replace: uv.associatedVariableName},
+                { search: /vPositionW/g, replace: worldPosition.associatedVariableName + ".xyz"},
+                { search: /normalW=/g, replace: this.output.associatedVariableName + ".xyz = " },
+                { search: /normalW/g, replace: worldNormal.associatedVariableName + ".xyz" }
+            ]
+        });
+
+        return this;
+    }
+}
+
+_TypeStore.RegisteredTypes["BABYLON.PertubNormalBlock"] = PertubNormalBlock;

+ 48 - 48
src/Materials/Node/Blocks/Input/inputBlock.ts

@@ -1,7 +1,7 @@
 import { NodeMaterialBlock } from '../../nodeMaterialBlock';
 import { NodeMaterialBlockConnectionPointTypes } from '../../nodeMaterialBlockConnectionPointTypes';
 import { NodeMaterialBlockConnectionPointMode } from '../../NodeMaterialBlockConnectionPointMode';
-import { NodeMaterialWellKnownValues } from '../../nodeMaterialWellKnownValues';
+import { NodeMaterialSystemValues } from '../../nodeMaterialSystemValues';
 import { Nullable } from '../../../../types';
 import { Effect } from '../../../../Materials/effect';
 import { Matrix, Vector2, Vector3, Vector4 } from '../../../../Maths/math.vector';
@@ -25,7 +25,7 @@ export class InputBlock extends NodeMaterialBlock {
     private _animationType = AnimatedInputBlockTypes.None;
 
     /** @hidden */
-    public _wellKnownValue: Nullable<NodeMaterialWellKnownValues> = null;
+    public _systemValue: Nullable<NodeMaterialSystemValues> = null;
 
     /** Gets or sets a boolean indicating that this input can be edited in the Inspector (false by default) */
     public visibleInInspector = false;
@@ -85,20 +85,20 @@ export class InputBlock extends NodeMaterialBlock {
                 }
             }
 
-            if (this.isWellKnownValue) {
-                switch (this._wellKnownValue) {
-                    case NodeMaterialWellKnownValues.World:
-                    case NodeMaterialWellKnownValues.WorldView:
-                    case NodeMaterialWellKnownValues.WorldViewProjection:
-                    case NodeMaterialWellKnownValues.View:
-                    case NodeMaterialWellKnownValues.ViewProjection:
-                    case NodeMaterialWellKnownValues.Projection:
+            if (this.isSystemValue) {
+                switch (this._systemValue) {
+                    case NodeMaterialSystemValues.World:
+                    case NodeMaterialSystemValues.WorldView:
+                    case NodeMaterialSystemValues.WorldViewProjection:
+                    case NodeMaterialSystemValues.View:
+                    case NodeMaterialSystemValues.ViewProjection:
+                    case NodeMaterialSystemValues.Projection:
                         this._type = NodeMaterialBlockConnectionPointTypes.Matrix;
                         return this._type;
-                    case NodeMaterialWellKnownValues.CameraPosition:
+                    case NodeMaterialSystemValues.CameraPosition:
                         this._type = NodeMaterialBlockConnectionPointTypes.Vector3;
                         return this._type;
-                    case NodeMaterialWellKnownValues.FogColor:
+                    case NodeMaterialSystemValues.FogColor:
                         this._type = NodeMaterialBlockConnectionPointTypes.Color3;
                         return this._type;
                 }
@@ -145,12 +145,12 @@ export class InputBlock extends NodeMaterialBlock {
     }
 
     /**
-     * Set the source of this connection point to a well known value
-     * @param value define the well known value to use (world, view, etc...) or null to switch to manual value
+     * Set the source of this connection point to a system value
+     * @param value define the system value to use (world, view, etc...) or null to switch to manual value
      * @returns the current connection point
      */
-    public setAsWellKnownValue(value: Nullable<NodeMaterialWellKnownValues>): InputBlock {
-        this.wellKnownValue = value;
+    public setAsSystemValue(value: Nullable<NodeMaterialSystemValues>): InputBlock {
+        this.systemValue = value;
         return this;
     }
 
@@ -249,23 +249,23 @@ export class InputBlock extends NodeMaterialBlock {
     }
 
     /**
-     * Gets a boolean indicating that the current connection point is a well known value
+     * Gets a boolean indicating that the current connection point is a system value
      */
-    public get isWellKnownValue(): boolean {
-        return this._wellKnownValue != null;
+    public get isSystemValue(): boolean {
+        return this._systemValue != null;
     }
 
     /**
-     * Gets or sets the current well known value or null if not defined as well know value
+     * Gets or sets the current well known value or null if not defined as a system value
      */
-    public get wellKnownValue(): Nullable<NodeMaterialWellKnownValues> {
-        return this._wellKnownValue;
+    public get systemValue(): Nullable<NodeMaterialSystemValues> {
+        return this._systemValue;
     }
 
-    public set wellKnownValue(value: Nullable<NodeMaterialWellKnownValues>) {
+    public set systemValue(value: Nullable<NodeMaterialSystemValues>) {
         this._mode = NodeMaterialBlockConnectionPointMode.Uniform;
         this.associatedVariableName = "";
-        this._wellKnownValue = value;
+        this._systemValue = value;
     }
 
     /**
@@ -332,8 +332,8 @@ export class InputBlock extends NodeMaterialBlock {
         if (this.isAttribute) {
             return `${this._codeVariableName}.setAsAttribute("${this.name}");\r\n`;
         }
-        if (this.isWellKnownValue) {
-            return `${this._codeVariableName}.setAsWellKnownValue(BABYLON.NodeMaterialWellKnownValues.${NodeMaterialWellKnownValues[this._wellKnownValue!]});\r\n`;
+        if (this.isSystemValue) {
+            return `${this._codeVariableName}.setAsSystemValue(BABYLON.NodeMaterialSystemValues.${NodeMaterialSystemValues[this._systemValue!]});\r\n`;
         }
         if (this.isUniform) {
             let valueString = "";
@@ -384,12 +384,12 @@ export class InputBlock extends NodeMaterialBlock {
 
             // well known
             let hints = state.sharedData.hints;
-            if (this._wellKnownValue !== null) {
-                switch (this._wellKnownValue) {
-                    case NodeMaterialWellKnownValues.WorldView:
+            if (this._systemValue !== null && this._systemValue !== undefined) {
+                switch (this._systemValue) {
+                    case NodeMaterialSystemValues.WorldView:
                         hints.needWorldViewMatrix = true;
                         break;
-                    case NodeMaterialWellKnownValues.WorldViewProjection:
+                    case NodeMaterialSystemValues.WorldViewProjection:
                         hints.needWorldViewProjectionMatrix = true;
                         break;
                 }
@@ -428,19 +428,19 @@ export class InputBlock extends NodeMaterialBlock {
 
     /** @hidden */
     public _transmitWorld(effect: Effect, world: Matrix, worldView: Matrix, worldViewProjection: Matrix) {
-        if (!this._wellKnownValue) {
+        if (!this._systemValue) {
             return;
         }
 
         let variableName = this.associatedVariableName;
-        switch (this._wellKnownValue) {
-            case NodeMaterialWellKnownValues.World:
+        switch (this._systemValue) {
+            case NodeMaterialSystemValues.World:
                 effect.setMatrix(variableName, world);
                 break;
-            case NodeMaterialWellKnownValues.WorldView:
+            case NodeMaterialSystemValues.WorldView:
                 effect.setMatrix(variableName, worldView);
                 break;
-            case NodeMaterialWellKnownValues.WorldViewProjection:
+            case NodeMaterialSystemValues.WorldViewProjection:
                 effect.setMatrix(variableName, worldViewProjection);
                 break;
         }
@@ -453,25 +453,25 @@ export class InputBlock extends NodeMaterialBlock {
         }
 
         let variableName = this.associatedVariableName;
-        if (this._wellKnownValue) {
-            switch (this._wellKnownValue) {
-                case NodeMaterialWellKnownValues.World:
-                case NodeMaterialWellKnownValues.WorldView:
-                case NodeMaterialWellKnownValues.WorldViewProjection:
+        if (this._systemValue) {
+            switch (this._systemValue) {
+                case NodeMaterialSystemValues.World:
+                case NodeMaterialSystemValues.WorldView:
+                case NodeMaterialSystemValues.WorldViewProjection:
                     return;
-                case NodeMaterialWellKnownValues.View:
+                case NodeMaterialSystemValues.View:
                     effect.setMatrix(variableName, scene.getViewMatrix());
                     break;
-                case NodeMaterialWellKnownValues.Projection:
+                case NodeMaterialSystemValues.Projection:
                     effect.setMatrix(variableName, scene.getProjectionMatrix());
                     break;
-                case NodeMaterialWellKnownValues.ViewProjection:
+                case NodeMaterialSystemValues.ViewProjection:
                     effect.setMatrix(variableName, scene.getTransformMatrix());
                     break;
-                case NodeMaterialWellKnownValues.CameraPosition:
+                case NodeMaterialSystemValues.CameraPosition:
                     effect.setVector3(variableName, scene.activeCamera!.globalPosition);
                     break;
-                case NodeMaterialWellKnownValues.FogColor:
+                case NodeMaterialSystemValues.FogColor:
                     effect.setColor3(variableName, scene.fogColor);
                     break;
             }
@@ -515,7 +515,7 @@ export class InputBlock extends NodeMaterialBlock {
     protected _buildBlock(state: NodeMaterialBuildState) {
         super._buildBlock(state);
 
-        if (this.isUniform || this.isWellKnownValue) {
+        if (this.isUniform || this.isSystemValue) {
             state.sharedData.inputBlocks.push(this);
         }
 
@@ -527,7 +527,7 @@ export class InputBlock extends NodeMaterialBlock {
 
         serializationObject.type = this.type;
         serializationObject.mode = this._mode;
-        serializationObject.wellKnownValue = this._wellKnownValue;
+        serializationObject.systemValue = this._systemValue;
         serializationObject.animationType = this._animationType;
         serializationObject.visibleInInspector = this.visibleInInspector;
 
@@ -549,7 +549,7 @@ export class InputBlock extends NodeMaterialBlock {
 
         this._type = serializationObject.type;
         this._mode = serializationObject.mode;
-        this._wellKnownValue = serializationObject.wellKnownValue;
+        this._systemValue = serializationObject.systemValue || serializationObject.wellKnownValue;
         this._animationType = serializationObject.animationType;
         this.visibleInInspector = serializationObject.visibleInInspector;
 

+ 0 - 0
src/Materials/Node/Blocks/Vertex/bonesBlock.ts


部分文件因为文件数量过多而无法显示