Browse Source

Merge branch 'master' of https://github.com/BabylonJS/Babylon.js into FollowCamera_PointersInput

duncan law 6 years ago
parent
commit
691f65144e
100 changed files with 48356 additions and 40180 deletions
  1. 5 2
      .github/ISSUE_TEMPLATE.md
  2. 7379 6881
      Playground/babylon.d.txt
  3. 17 2
      Tools/Config/config.json
  4. 13 1
      Tools/Gulp/helpers/gulp-validateImports.js
  5. 4 3
      Tools/Gulp/tasks/gulpTasks-importLint.js
  6. 0 43
      Viewer/tests/unit/src/configuration/updateConfiguration.ts
  7. 7330 6963
      dist/preview release/babylon.d.ts
  8. 2 2
      dist/preview release/babylon.js
  9. 1296 443
      dist/preview release/babylon.max.js
  10. 1 1
      dist/preview release/babylon.max.js.map
  11. 13302 12549
      dist/preview release/babylon.module.d.ts
  12. 3 0
      dist/preview release/gui/babylon.gui.d.ts
  13. 72 48
      dist/preview release/gui/babylon.gui.js
  14. 1 1
      dist/preview release/gui/babylon.gui.js.map
  15. 1 1
      dist/preview release/gui/babylon.gui.min.js
  16. 6 0
      dist/preview release/gui/babylon.gui.module.d.ts
  17. 22 11
      dist/preview release/inspector/babylon.inspector.bundle.js
  18. 2342 178
      dist/preview release/inspector/babylon.inspector.bundle.max.js
  19. 1 1
      dist/preview release/inspector/babylon.inspector.bundle.max.js.map
  20. 189 4
      dist/preview release/inspector/babylon.inspector.d.ts
  21. 472 9
      dist/preview release/inspector/babylon.inspector.module.d.ts
  22. 3 0
      dist/preview release/loaders/babylon.glTF1FileLoader.js
  23. 1 1
      dist/preview release/loaders/babylon.glTF1FileLoader.js.map
  24. 2 2
      dist/preview release/loaders/babylon.glTF1FileLoader.min.js
  25. 3 0
      dist/preview release/loaders/babylon.glTF2FileLoader.js
  26. 1 1
      dist/preview release/loaders/babylon.glTF2FileLoader.js.map
  27. 1 1
      dist/preview release/loaders/babylon.glTF2FileLoader.min.js
  28. 3 0
      dist/preview release/loaders/babylon.glTFFileLoader.js
  29. 1 1
      dist/preview release/loaders/babylon.glTFFileLoader.js.map
  30. 2 2
      dist/preview release/loaders/babylon.glTFFileLoader.min.js
  31. 3 0
      dist/preview release/loaders/babylonjs.loaders.js
  32. 1 1
      dist/preview release/loaders/babylonjs.loaders.js.map
  33. 2 2
      dist/preview release/loaders/babylonjs.loaders.min.js
  34. 1 1
      dist/preview release/packagesSizeBaseLine.json
  35. 2 2
      dist/preview release/postProcessesLibrary/babylon.asciiArtPostProcess.min.js
  36. 2 2
      dist/preview release/postProcessesLibrary/babylon.digitalRainPostProcess.min.js
  37. 644 0
      dist/preview release/postProcessesLibrary/babylon.oceanPostProcess.js
  38. 1 0
      dist/preview release/postProcessesLibrary/babylon.oceanPostProcess.js.map
  39. 16 0
      dist/preview release/postProcessesLibrary/babylon.oceanPostProcess.min.js
  40. 95 0
      dist/preview release/postProcessesLibrary/babylonjs.postProcess.d.ts
  41. 262 2
      dist/preview release/postProcessesLibrary/babylonjs.postProcess.js
  42. 1 1
      dist/preview release/postProcessesLibrary/babylonjs.postProcess.js.map
  43. 2 2
      dist/preview release/postProcessesLibrary/babylonjs.postProcess.min.js
  44. 202 0
      dist/preview release/postProcessesLibrary/babylonjs.postProcess.module.d.ts
  45. 283 86
      dist/preview release/serializers/babylon.glTF2Serializer.js
  46. 1 1
      dist/preview release/serializers/babylon.glTF2Serializer.js.map
  47. 1 1
      dist/preview release/serializers/babylon.glTF2Serializer.min.js
  48. 61 17
      dist/preview release/serializers/babylonjs.serializers.d.ts
  49. 293 90
      dist/preview release/serializers/babylonjs.serializers.js
  50. 1 1
      dist/preview release/serializers/babylonjs.serializers.js.map
  51. 1 1
      dist/preview release/serializers/babylonjs.serializers.min.js
  52. 134 37
      dist/preview release/serializers/babylonjs.serializers.module.d.ts
  53. 13302 12549
      dist/preview release/viewer/babylon.module.d.ts
  54. 105 85
      dist/preview release/viewer/babylon.viewer.js
  55. 2 2
      dist/preview release/viewer/babylon.viewer.max.js
  56. 14 2
      dist/preview release/what's new.md
  57. 3 3
      gui/src/2D/controls/control.ts
  58. 4 0
      gui/src/2D/controls/grid.ts
  59. 21 2
      gui/src/2D/controls/sliders/baseSlider.ts
  60. 2 1
      gui/src/2D/measure.ts
  61. 45 24
      inspector/src/components/actionTabs/actionTabs.scss
  62. 1 1
      inspector/src/components/actionTabs/actionTabsComponent.tsx
  63. 37 20
      inspector/src/components/actionTabs/lineContainerComponent.tsx
  64. 3 2
      inspector/src/components/actionTabs/lines/sliderLineComponent.tsx
  65. 1 1
      inspector/src/components/actionTabs/lines/textInputLineComponent.tsx
  66. 1 1
      inspector/src/components/actionTabs/lines/textureLineComponent.tsx
  67. 108 0
      inspector/src/components/actionTabs/lines/vector2LineComponent.tsx
  68. 1 1
      inspector/src/components/actionTabs/paneComponent.tsx
  69. 4 4
      inspector/src/components/actionTabs/tabs/debugTabComponent.tsx
  70. 80 4
      inspector/src/components/actionTabs/tabs/propertyGridTabComponent.tsx
  71. 4 2
      inspector/src/components/actionTabs/tabs/propertyGrids/animationGroupPropertyGridComponent.tsx
  72. 11 9
      inspector/src/components/actionTabs/tabs/propertyGrids/cameras/arcRotateCameraPropertyGridComponent.tsx
  73. 3 1
      inspector/src/components/actionTabs/tabs/propertyGrids/cameras/commonCameraPropertyGridComponent.tsx
  74. 9 7
      inspector/src/components/actionTabs/tabs/propertyGrids/cameras/freeCameraPropertyGridComponent.tsx
  75. 2 0
      inspector/src/components/actionTabs/tabs/propertyGrids/fogPropertyGridComponent.tsx
  76. 7 5
      inspector/src/components/actionTabs/tabs/propertyGrids/gui/checkboxPropertyGridComponent.tsx
  77. 4 2
      inspector/src/components/actionTabs/tabs/propertyGrids/gui/colorPickerPropertyGridComponent.tsx
  78. 9 7
      inspector/src/components/actionTabs/tabs/propertyGrids/gui/commonControlPropertyGridComponent.tsx
  79. 3 1
      inspector/src/components/actionTabs/tabs/propertyGrids/gui/controlPropertyGridComponent.tsx
  80. 4 2
      inspector/src/components/actionTabs/tabs/propertyGrids/gui/ellipsePropertyGridComponent.tsx
  81. 4 2
      inspector/src/components/actionTabs/tabs/propertyGrids/gui/gridPropertyGridComponent.tsx
  82. 4 2
      inspector/src/components/actionTabs/tabs/propertyGrids/gui/imageBasedSliderPropertyGridComponent.tsx
  83. 5 3
      inspector/src/components/actionTabs/tabs/propertyGrids/gui/imagePropertyGridComponent.tsx
  84. 4 2
      inspector/src/components/actionTabs/tabs/propertyGrids/gui/inputTextPropertyGridComponent.tsx
  85. 4 2
      inspector/src/components/actionTabs/tabs/propertyGrids/gui/linePropertyGridComponent.tsx
  86. 4 2
      inspector/src/components/actionTabs/tabs/propertyGrids/gui/radioButtonPropertyGridComponent.tsx
  87. 4 2
      inspector/src/components/actionTabs/tabs/propertyGrids/gui/rectanglePropertyGridComponent.tsx
  88. 5 3
      inspector/src/components/actionTabs/tabs/propertyGrids/gui/scrollViewerPropertyGridComponent.tsx
  89. 4 2
      inspector/src/components/actionTabs/tabs/propertyGrids/gui/sliderPropertyGridComponent.tsx
  90. 4 2
      inspector/src/components/actionTabs/tabs/propertyGrids/gui/stackPanelPropertyGridComponent.tsx
  91. 5 3
      inspector/src/components/actionTabs/tabs/propertyGrids/gui/textBlockPropertyGridComponent.tsx
  92. 3 1
      inspector/src/components/actionTabs/tabs/propertyGrids/lights/commonLightPropertyGridComponent.tsx
  93. 3 1
      inspector/src/components/actionTabs/tabs/propertyGrids/lights/commonShadowLightPropertyGridComponent.tsx
  94. 5 3
      inspector/src/components/actionTabs/tabs/propertyGrids/lights/directionalLightPropertyGridComponent.tsx
  95. 4 2
      inspector/src/components/actionTabs/tabs/propertyGrids/lights/hemisphericLightPropertyGridComponent.tsx
  96. 5 3
      inspector/src/components/actionTabs/tabs/propertyGrids/lights/pointLightPropertyGridComponent.tsx
  97. 5 3
      inspector/src/components/actionTabs/tabs/propertyGrids/lights/spotLightPropertyGridComponent.tsx
  98. 6 4
      inspector/src/components/actionTabs/tabs/propertyGrids/materials/backgroundMaterialPropertyGridComponent.tsx
  99. 4 2
      inspector/src/components/actionTabs/tabs/propertyGrids/materials/commonMaterialPropertyGridComponent.tsx
  100. 0 0
      inspector/src/components/actionTabs/tabs/propertyGrids/materials/materialPropertyGridComponent.tsx

+ 5 - 2
.github/ISSUE_TEMPLATE.md

@@ -1,5 +1,8 @@
-Before creating an issue, please make sure to provide the following template (based on why you create the issue):
-(Please do not use Github issues for questions - We have a really active forum to help answering questions (https://forum.babylonjs.com/))
+**Use Github issues ONLY for validated bugs**
+
+We have a really active forum to help answering questions (https://forum.babylonjs.com/)
+
+*If you are convinced that you found a bug, please use the following template for your issue:*
 
 # Bugs
 

File diff suppressed because it is too large
+ 7379 - 6881
Playground/babylon.d.txt


+ 17 - 2
Tools/Config/config.json

@@ -30,7 +30,10 @@
             "../../dist/preview release/loaders/babylonjs.loaders.d.ts",
             "../../dist/preview release/serializers/babylonjs.serializers.d.ts"
         ],
-        "typedocEntryPoint": ["\"babylon.d\"", "BABYLON"],
+        "typedocEntryPoint": [
+            "\"babylon.d\"",
+            "BABYLON"
+        ],
         "typedocJSON": "../../.temp/babylon.typedoc.json",
         "typedocValidationBaseline": "../../dist/preview release/typedocValidationBaseline.json"
     },
@@ -243,6 +246,11 @@
                 "output": "babylon.digitalRainPostProcess.min.js",
                 "entry": "./legacy/legacy-digitalRain.ts",
                 "preventLoadLibrary": true
+            },
+            {
+                "output": "babylon.oceanPostProcess.min.js",
+                "entry": "./legacy/legacy-ocean.ts",
+                "preventLoadLibrary": true
             }
         ],
         "build": {
@@ -510,6 +518,12 @@
         "build": {
             "ignoreInTestMode": true,
             "mainFolder": "./inspector/",
+            "uncheckedLintImports": [
+                "react",
+                "react-dom",
+                "re-resizable",
+                "glTF"
+            ],
             "umd": {
                 "packageName": "babylonjs-inspector",
                 "webpackRoot": "INSPECTOR",
@@ -528,7 +542,8 @@
                         "@babylonjs/loaders": "BABYLON",
                         "@babylonjs/serializers": "BABYLON",
                         "@babylonjs/gui": "BABYLON.GUI",
-                        "@fortawesome": false
+                        "@fortawesome": false,
+                        "react-contextmenu": false
                     }
                 }
             },

+ 13 - 1
Tools/Gulp/helpers/gulp-validateImports.js

@@ -79,6 +79,7 @@ var validateImports = function(data, fileLocation, options) {
 
     // Let's go line by line and check if we have special folder replacements
     // Replaces declare module '...'; by declare module 'babylonjs/...'; for instance
+    mainSearch:
     for (let index = 0; index < lines.length; index++) {
         let line = lines[index];
         let module = null, externalModule = null;
@@ -111,13 +112,24 @@ var validateImports = function(data, fileLocation, options) {
                 }
             }
 
+            if (options.uncheckedLintImports) {
+                for (let ext of options.uncheckedLintImports) {
+                    if (line.indexOf(ext) > -1) {
+                        continue mainSearch;
+                    }
+                }
+            }
+
             // Check if path is correct internal.
             if (externalModule) {
                 const splitter = module.indexOf("/");
+                if (splitter === -1 && module !== "babylonjs-gltf2interface") {
+                    errors.push(`Line ${index + 1} Import ${module} needs to be relative.`);
+                }
+
                 const baseModule = module.substring(0, splitter);
                 if (mapping[baseModule]) {
                     const configName = mapping[baseModule];
-
                     const directory = config[configName].computed.srcDirectory;
                     module = module.substring(splitter);
                     validatePath(fileLocation, directory, module, index + 1, errors, false);

+ 4 - 3
Tools/Gulp/tasks/gulpTasks-importLint.js

@@ -28,7 +28,8 @@ var importLintLibrary = function(settings) {
         .pipe(fxFilter)
         .pipe(validateImports({
             externals: settings.build.umd.processDeclaration.classMap,
-            isCore: settings.isCore
+            isCore: settings.isCore,
+            uncheckedLintImports: settings.build.uncheckedLintImports
         }));
 }
 
@@ -49,7 +50,7 @@ var lintLibrary = function(settings) {
 /**
  * Dynamic module linting for library (mat, post processes, ...).
  */
-config.lintModules.map(function(module) {
+config.modules.map(function(module) {
     const settings = config[module];
     gulp.task(module + "-importLint", lintLibrary(settings));
 });
@@ -59,7 +60,7 @@ config.lintModules.map(function(module) {
  * Full Librairies importLint.
  */
 gulp.task("typescript-libraries-importLint",
-    gulp.series(config.lintModules.map((module) => {
+    gulp.series(config.modules.map((module) => {
         return module + "-importLint";
     })
 ));

+ 0 - 43
Viewer/tests/unit/src/configuration/updateConfiguration.ts

@@ -16,49 +16,6 @@ describe(name + " scene", () => {
         });
     });
 
-    it("should enable and disable the debug layer", (done) => {
-        let viewer = Helper.getNewViewerInstance(undefined, { extends: "none" });
-        let showCalled = 0;
-        let hideCalled = 0;
-        let isVisible = false;
-        viewer.onSceneInitObservable.add((scene) => {
-            scene.debugLayer.show = () => {
-                showCalled++;
-                isVisible = true;
-            };
-
-            scene.debugLayer.hide = () => {
-                hideCalled++;
-                isVisible = false;
-            };
-
-            scene.debugLayer.isVisible = () => {
-                return isVisible;
-            };
-        });
-        viewer.onInitDoneObservable.add(() => {
-            // assert.isUndefined(viewer.configuration.scene);
-            assert.equal(showCalled, 0);
-            assert.equal(hideCalled, 0);
-            viewer.updateConfiguration({
-                scene: {
-                    debug: true
-                }
-            });
-            assert.equal(showCalled, 1);
-
-            viewer.updateConfiguration({
-                scene: {
-                    debug: false
-                }
-            });
-            assert.equal(showCalled, 1);
-            assert.equal(hideCalled, 1);
-            viewer.dispose();
-            done();
-        });
-    });
-
     it("should update the image processing configuration values", (done) => {
         let viewer = Helper.getNewViewerInstance(undefined, { extends: "none" });
 

File diff suppressed because it is too large
+ 7330 - 6963
dist/preview release/babylon.d.ts


File diff suppressed because it is too large
+ 2 - 2
dist/preview release/babylon.js


File diff suppressed because it is too large
+ 1296 - 443
dist/preview release/babylon.max.js


File diff suppressed because it is too large
+ 1 - 1
dist/preview release/babylon.max.js.map


File diff suppressed because it is too large
+ 13302 - 12549
dist/preview release/babylon.module.d.ts


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

@@ -2372,6 +2372,7 @@ declare module BABYLON.GUI {
         protected _barOffset: ValueAndUnit;
         private _isThumbClamped;
         protected _displayThumb: boolean;
+        private _step;
         protected _effectiveBarOffset: number;
         protected _renderLeft: number;
         protected _renderTop: number;
@@ -2384,6 +2385,8 @@ declare module BABYLON.GUI {
         onValueChangedObservable: BABYLON.Observable<number>;
         /** Gets or sets a boolean indicating if the thumb must be rendered */
         displayThumb: boolean;
+        /** Gets or sets a step to apply to values (0 by default) */
+        step: number;
         /** Gets or sets main bar offset (ie. the margin applied to the value bar) */
         barOffset: string | number;
         /** Gets main bar offset in pixels*/

+ 72 - 48
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"]);
-})(window, function(__WEBPACK_EXTERNAL_MODULE_babylonjs_Misc_observable__) {
+})(window, function(__WEBPACK_EXTERNAL_MODULE_babylonjs_Misc_tools__) {
 return /******/ (function(modules) { // webpackBootstrap
 /******/ 	// The module cache
 /******/ 	var installedModules = {};
@@ -355,7 +355,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_tools__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! babylonjs/Misc/tools */ "babylonjs/Misc/observable");
+/* harmony import */ var babylonjs_Misc_tools__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! babylonjs/Misc/tools */ "babylonjs/Misc/tools");
 /* harmony import */ var babylonjs_Misc_tools__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Misc_tools__WEBPACK_IMPORTED_MODULE_0__);
 
 /**
@@ -498,7 +498,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/Misc/observable");
+/* harmony import */ var babylonjs_Misc_observable__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! babylonjs/Misc/observable */ "babylonjs/Misc/tools");
 /* 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");
@@ -1613,7 +1613,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/Misc/observable");
+/* harmony import */ var babylonjs_Misc_observable__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! babylonjs/Misc/observable */ "babylonjs/Misc/tools");
 /* 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");
@@ -1794,7 +1794,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/Misc/observable");
+/* harmony import */ var babylonjs_Misc_observable__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! babylonjs/Misc/observable */ "babylonjs/Misc/tools");
 /* 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");
@@ -3241,7 +3241,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/Misc/observable");
+/* harmony import */ var babylonjs_Misc_logger__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! babylonjs/Misc/logger */ "babylonjs/Misc/tools");
 /* 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");
@@ -3646,7 +3646,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/Misc/observable");
+/* harmony import */ var babylonjs_Misc_observable__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! babylonjs/Misc/observable */ "babylonjs/Misc/tools");
 /* 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");
@@ -5088,9 +5088,9 @@ var Control = /** @class */ (function () {
         // Transform
         this._transform(context);
         // Clip
-        if (this.clipChildren) {
-            this._clip(context, invalidatedRectangle);
-        }
+        //     if (this.clipChildren) {
+        this._clip(context, invalidatedRectangle);
+        //   }
         if (this.onBeforeDrawObservable.hasObservers()) {
             this.onBeforeDrawObservable.notifyObservers(this);
         }
@@ -6139,6 +6139,10 @@ var Grid = /** @class */ (function (_super) {
                 cell.top = tops[x] + "px";
                 cell.width = widths[y] + "px";
                 cell.height = heights[x] + "px";
+                cell._left.ignoreAdaptiveScaling = true;
+                cell._top.ignoreAdaptiveScaling = true;
+                cell._width.ignoreAdaptiveScaling = true;
+                cell._height.ignoreAdaptiveScaling = true;
             }
         });
         _super.prototype._additionalProcessing.call(this, parentMeasure, context);
@@ -6202,7 +6206,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/Misc/observable");
+/* harmony import */ var babylonjs_Misc_observable__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! babylonjs/Misc/observable */ "babylonjs/Misc/tools");
 /* 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");
 
@@ -6977,7 +6981,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/Misc/observable");
+/* harmony import */ var babylonjs_Misc_observable__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! babylonjs/Misc/observable */ "babylonjs/Misc/tools");
 /* 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");
@@ -7986,7 +7990,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/Misc/observable");
+/* harmony import */ var babylonjs_Maths_math__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! babylonjs/Maths/math */ "babylonjs/Misc/tools");
 /* 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");
@@ -8254,7 +8258,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/Misc/observable");
+/* harmony import */ var babylonjs_Meshes_abstractMesh__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! babylonjs/Meshes/abstractMesh */ "babylonjs/Misc/tools");
 /* 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");
@@ -8521,7 +8525,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/Misc/observable");
+/* harmony import */ var babylonjs_Misc_observable__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! babylonjs/Misc/observable */ "babylonjs/Misc/tools");
 /* 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");
@@ -8866,7 +8870,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/Misc/observable");
+/* harmony import */ var babylonjs_Events_pointerEvents__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! babylonjs/Events/pointerEvents */ "babylonjs/Misc/tools");
 /* 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");
@@ -9957,7 +9961,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/Misc/observable");
+/* harmony import */ var babylonjs_Misc_observable__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! babylonjs/Misc/observable */ "babylonjs/Misc/tools");
 /* 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");
@@ -9985,6 +9989,7 @@ var BaseSlider = /** @class */ (function (_super) {
         _this._barOffset = new _valueAndUnit__WEBPACK_IMPORTED_MODULE_3__["ValueAndUnit"](5, _valueAndUnit__WEBPACK_IMPORTED_MODULE_3__["ValueAndUnit"].UNITMODE_PIXEL, false);
         _this._isThumbClamped = false;
         _this._displayThumb = true;
+        _this._step = 0;
         // Shared rendering info
         _this._effectiveBarOffset = 0;
         /** Observable raised when the sldier value changes */
@@ -10009,6 +10014,21 @@ var BaseSlider = /** @class */ (function (_super) {
         enumerable: true,
         configurable: true
     });
+    Object.defineProperty(BaseSlider.prototype, "step", {
+        /** Gets or sets a step to apply to values (0 by default) */
+        get: function () {
+            return this._step;
+        },
+        set: function (value) {
+            if (this._step === value) {
+                return;
+            }
+            this._step = value;
+            this._markAsDirty();
+        },
+        enumerable: true,
+        configurable: true
+    });
     Object.defineProperty(BaseSlider.prototype, "barOffset", {
         /** Gets or sets main bar offset (ie. the margin applied to the value bar) */
         get: function () {
@@ -10215,12 +10235,15 @@ var BaseSlider = /** @class */ (function (_super) {
             x = this._transformedPosition.x;
             y = this._transformedPosition.y;
         }
+        var value;
         if (this._isVertical) {
-            this.value = this._minimum + (1 - ((y - this._currentMeasure.top) / this._currentMeasure.height)) * (this._maximum - this._minimum);
+            value = this._minimum + (1 - ((y - this._currentMeasure.top) / this._currentMeasure.height)) * (this._maximum - this._minimum);
         }
         else {
-            this.value = this._minimum + ((x - this._currentMeasure.left) / this._currentMeasure.width) * (this._maximum - this._minimum);
+            value = this._minimum + ((x - this._currentMeasure.left) / this._currentMeasure.width) * (this._maximum - this._minimum);
         }
+        var mult = (1 / this._step) | 0;
+        this.value = this._step ? ((value * mult) | 0) / mult : value;
     };
     BaseSlider.prototype._onPointerDown = function (target, coordinates, pointerId, buttonIndex) {
         if (!_super.prototype._onPointerDown.call(this, target, coordinates, pointerId, buttonIndex)) {
@@ -10833,7 +10856,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/Misc/observable");
+/* harmony import */ var babylonjs_Misc_tools__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! babylonjs/Misc/tools */ "babylonjs/Misc/tools");
 /* 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");
@@ -11091,7 +11114,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/Misc/observable");
+/* harmony import */ var babylonjs_Misc_observable__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! babylonjs/Misc/observable */ "babylonjs/Misc/tools");
 /* 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");
@@ -11531,7 +11554,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/Misc/observable");
+/* harmony import */ var babylonjs_Misc_observable__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! babylonjs/Misc/observable */ "babylonjs/Misc/tools");
 /* 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");
@@ -11906,7 +11929,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/Misc/observable");
+/* harmony import */ var babylonjs_Maths_math__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! babylonjs/Maths/math */ "babylonjs/Misc/tools");
 /* harmony import */ var babylonjs_Maths_math__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Maths_math__WEBPACK_IMPORTED_MODULE_1__);
 
 
@@ -12130,8 +12153,9 @@ 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__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! babylonjs */ "babylonjs/Misc/observable");
-/* harmony import */ var babylonjs__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(babylonjs__WEBPACK_IMPORTED_MODULE_0__);
+/* harmony import */ var babylonjs_Maths_math__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! babylonjs/Maths/math */ "babylonjs/Misc/tools");
+/* harmony import */ var babylonjs_Maths_math__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Maths_math__WEBPACK_IMPORTED_MODULE_0__);
+
 
 /**
  * Class used to store 2D control sizes
@@ -12203,9 +12227,9 @@ var Measure = /** @class */ (function () {
      * @param result the resulting AABB
      */
     Measure.prototype.transformToRef = function (transform, result) {
-        var rectanglePoints = babylonjs__WEBPACK_IMPORTED_MODULE_0__["Polygon"].Rectangle(this.left, this.top, this.left + this.width, this.top + this.height);
-        var min = new babylonjs__WEBPACK_IMPORTED_MODULE_0__["Vector2"](Number.MAX_VALUE, Number.MAX_VALUE);
-        var max = new babylonjs__WEBPACK_IMPORTED_MODULE_0__["Vector2"](0, 0);
+        var rectanglePoints = babylonjs_Maths_math__WEBPACK_IMPORTED_MODULE_0__["Polygon"].Rectangle(this.left, this.top, this.left + this.width, this.top + this.height);
+        var min = new babylonjs_Maths_math__WEBPACK_IMPORTED_MODULE_0__["Vector2"](Number.MAX_VALUE, Number.MAX_VALUE);
+        var max = new babylonjs_Maths_math__WEBPACK_IMPORTED_MODULE_0__["Vector2"](0, 0);
         for (var i = 0; i < 4; i++) {
             transform.transformCoordinates(rectanglePoints[i].x, rectanglePoints[i].y, rectanglePoints[i]);
             min.x = Math.floor(Math.min(min.x, rectanglePoints[i].x));
@@ -12262,7 +12286,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/Misc/observable");
+/* harmony import */ var babylonjs_Maths_math__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! babylonjs/Maths/math */ "babylonjs/Misc/tools");
 /* 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");
 
@@ -12405,7 +12429,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/Misc/observable");
+/* harmony import */ var babylonjs_Misc_observable__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! babylonjs/Misc/observable */ "babylonjs/Misc/tools");
 /* 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");
 
@@ -12709,7 +12733,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/Misc/observable");
+/* harmony import */ var babylonjs_Meshes_transformNode__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! babylonjs/Meshes/transformNode */ "babylonjs/Misc/tools");
 /* 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");
 
@@ -12752,7 +12776,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/Misc/observable");
+/* harmony import */ var babylonjs_Maths_math__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! babylonjs/Maths/math */ "babylonjs/Misc/tools");
 /* 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");
@@ -12929,7 +12953,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/Misc/observable");
+/* harmony import */ var babylonjs_Meshes_transformNode__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! babylonjs/Meshes/transformNode */ "babylonjs/Misc/tools");
 /* 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");
 
@@ -13086,7 +13110,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/Misc/observable");
+/* harmony import */ var babylonjs_Misc_observable__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! babylonjs/Misc/observable */ "babylonjs/Misc/tools");
 /* 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");
 
@@ -13480,7 +13504,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/Misc/observable");
+/* harmony import */ var babylonjs_Misc_tools__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! babylonjs/Misc/tools */ "babylonjs/Misc/tools");
 /* 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");
@@ -13565,7 +13589,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/Misc/observable");
+/* harmony import */ var babylonjs_Maths_math__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! babylonjs/Maths/math */ "babylonjs/Misc/tools");
 /* 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");
@@ -14041,7 +14065,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/Misc/observable");
+/* harmony import */ var babylonjs_Maths_math__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! babylonjs/Maths/math */ "babylonjs/Misc/tools");
 /* 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");
@@ -14096,7 +14120,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/Misc/observable");
+/* harmony import */ var babylonjs_Misc_tools__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! babylonjs/Misc/tools */ "babylonjs/Misc/tools");
 /* 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");
@@ -14223,7 +14247,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/Misc/observable");
+/* harmony import */ var babylonjs_Misc_tools__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! babylonjs/Misc/tools */ "babylonjs/Misc/tools");
 /* 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");
@@ -14308,7 +14332,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/Misc/observable");
+/* harmony import */ var babylonjs_Misc_tools__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! babylonjs/Misc/tools */ "babylonjs/Misc/tools");
 /* 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");
 
@@ -14433,7 +14457,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/Misc/observable");
+/* harmony import */ var babylonjs_Misc_tools__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! babylonjs/Misc/tools */ "babylonjs/Misc/tools");
 /* 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");
 
@@ -14624,7 +14648,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/Misc/observable");
+/* harmony import */ var babylonjs_Misc_observable__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! babylonjs/Misc/observable */ "babylonjs/Misc/tools");
 /* 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");
 
@@ -14891,7 +14915,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/Misc/observable");
+/* harmony import */ var babylonjs_Misc_decorators__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! babylonjs/Misc/decorators */ "babylonjs/Misc/tools");
 /* 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");
@@ -15213,7 +15237,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/Misc/observable");
+/* harmony import */ var babylonjs_Materials_effect__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! babylonjs/Materials/effect */ "babylonjs/Misc/tools");
 /* 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';
@@ -15235,7 +15259,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/Misc/observable");
+/* harmony import */ var babylonjs_Materials_effect__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! babylonjs/Materials/effect */ "babylonjs/Misc/tools");
 /* 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';
@@ -15258,7 +15282,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/Misc/observable");
+/* harmony import */ var babylonjs_Maths_math__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! babylonjs/Maths/math */ "babylonjs/Misc/tools");
 /* harmony import */ var babylonjs_Maths_math__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Maths_math__WEBPACK_IMPORTED_MODULE_1__);
 
 
@@ -15552,14 +15576,14 @@ if (typeof globalObject !== "undefined") {
 
 /***/ }),
 
-/***/ "babylonjs/Misc/observable":
+/***/ "babylonjs/Misc/tools":
 /*!****************************************************************************************************!*\
   !*** external {"root":"BABYLON","commonjs":"babylonjs","commonjs2":"babylonjs","amd":"babylonjs"} ***!
   \****************************************************************************************************/
 /*! no static exports found */
 /***/ (function(module, exports) {
 
-module.exports = __WEBPACK_EXTERNAL_MODULE_babylonjs_Misc_observable__;
+module.exports = __WEBPACK_EXTERNAL_MODULE_babylonjs_Misc_tools__;
 
 /***/ })
 

File diff suppressed because it is too large
+ 1 - 1
dist/preview release/gui/babylon.gui.js.map


File diff suppressed because it is too large
+ 1 - 1
dist/preview release/gui/babylon.gui.min.js


+ 6 - 0
dist/preview release/gui/babylon.gui.module.d.ts

@@ -2471,6 +2471,7 @@ declare module "babylonjs-gui/2D/controls/sliders/baseSlider" {
         protected _barOffset: ValueAndUnit;
         private _isThumbClamped;
         protected _displayThumb: boolean;
+        private _step;
         protected _effectiveBarOffset: number;
         protected _renderLeft: number;
         protected _renderTop: number;
@@ -2483,6 +2484,8 @@ declare module "babylonjs-gui/2D/controls/sliders/baseSlider" {
         onValueChangedObservable: Observable<number>;
         /** Gets or sets a boolean indicating if the thumb must be rendered */
         displayThumb: boolean;
+        /** Gets or sets a step to apply to values (0 by default) */
+        step: number;
         /** Gets or sets main bar offset (ie. the margin applied to the value bar) */
         barOffset: string | number;
         /** Gets main bar offset in pixels*/
@@ -6213,6 +6216,7 @@ declare module BABYLON.GUI {
         protected _barOffset: ValueAndUnit;
         private _isThumbClamped;
         protected _displayThumb: boolean;
+        private _step;
         protected _effectiveBarOffset: number;
         protected _renderLeft: number;
         protected _renderTop: number;
@@ -6225,6 +6229,8 @@ declare module BABYLON.GUI {
         onValueChangedObservable: BABYLON.Observable<number>;
         /** Gets or sets a boolean indicating if the thumb must be rendered */
         displayThumb: boolean;
+        /** Gets or sets a step to apply to values (0 by default) */
+        step: number;
         /** Gets or sets main bar offset (ie. the margin applied to the value bar) */
         barOffset: string | number;
         /** Gets main bar offset in pixels*/

File diff suppressed because it is too large
+ 22 - 11
dist/preview release/inspector/babylon.inspector.bundle.js


File diff suppressed because it is too large
+ 2342 - 178
dist/preview release/inspector/babylon.inspector.bundle.max.js


File diff suppressed because it is too large
+ 1 - 1
dist/preview release/inspector/babylon.inspector.bundle.max.js.map


+ 189 - 4
dist/preview release/inspector/babylon.inspector.d.ts

@@ -9,7 +9,7 @@ declare module INSPECTOR {
 }
 declare module INSPECTOR {
     export class GlobalState {
-        onSelectionChangedObservable: BABYLON.Observable<string>;
+        onSelectionChangedObservable: BABYLON.Observable<any>;
         onPropertyChangedObservable: BABYLON.Observable<PropertyChangedEvent>;
         onInspectorClosedObservable: BABYLON.Observable<BABYLON.Scene>;
         onTabChangedObservable: BABYLON.Observable<number>;
@@ -26,6 +26,7 @@ declare module INSPECTOR {
             [key: string]: any;
         };
         blockMutationUpdates: boolean;
+        selectedLineContainerTitle: string;
         prepareGLTFPlugin(loader: BABYLON.GLTFFileLoader): void;
         lightGizmos: Array<BABYLON.LightGizmo>;
         enableLightGizmo(light: BABYLON.Light, enable?: boolean): void;
@@ -77,16 +78,19 @@ declare module INSPECTOR {
 }
 declare module INSPECTOR {
     interface ILineContainerComponentProps {
+        globalState: GlobalState;
         title: string;
         children: any[] | any;
         closed?: boolean;
     }
     export class LineContainerComponent extends React.Component<ILineContainerComponentProps, {
         isExpanded: boolean;
+        isHighlighted: boolean;
     }> {
         private static _InMemoryStorage;
         constructor(props: ILineContainerComponentProps);
         switchExpandedState(): void;
+        componentDidMount(): void;
         renderHeader(): JSX.Element;
         render(): JSX.Element;
     }
@@ -150,6 +154,7 @@ declare module INSPECTOR {
 }
 declare module INSPECTOR {
     interface IRenderGridPropertyGridComponentProps {
+        globalState: GlobalState;
         scene: BABYLON.Scene;
     }
     export class RenderGridPropertyGridComponent extends React.Component<IRenderGridPropertyGridComponentProps, {
@@ -187,6 +192,7 @@ declare module INSPECTOR {
         onChange?: (value: number) => void;
         onInput?: (value: number) => void;
         onPropertyChangedObservable?: BABYLON.Observable<PropertyChangedEvent>;
+        decimalCount?: number;
     }
     export class SliderLineComponent extends React.Component<ISliderLineComponentProps, {
         value: number;
@@ -241,6 +247,7 @@ declare module INSPECTOR {
 }
 declare module INSPECTOR {
     interface ICommonMaterialPropertyGridComponentProps {
+        globalState: GlobalState;
         material: BABYLON.Material;
         lockObject: LockObject;
         onPropertyChangedObservable?: BABYLON.Observable<PropertyChangedEvent>;
@@ -252,6 +259,7 @@ declare module INSPECTOR {
 }
 declare module INSPECTOR {
     interface IMaterialPropertyGridComponentProps {
+        globalState: GlobalState;
         material: BABYLON.Material;
         lockObject: LockObject;
         onPropertyChangedObservable?: BABYLON.Observable<PropertyChangedEvent>;
@@ -327,6 +335,7 @@ declare module INSPECTOR {
 }
 declare module INSPECTOR {
     interface IStandardMaterialPropertyGridComponentProps {
+        globalState: GlobalState;
         material: BABYLON.StandardMaterial;
         lockObject: LockObject;
         onSelectionChangedObservable?: BABYLON.Observable<any>;
@@ -424,6 +433,7 @@ declare module INSPECTOR {
 }
 declare module INSPECTOR {
     interface IPBRMaterialPropertyGridComponentProps {
+        globalState: GlobalState;
         material: BABYLON.PBRMaterial;
         lockObject: LockObject;
         onSelectionChangedObservable?: BABYLON.Observable<any>;
@@ -431,7 +441,7 @@ declare module INSPECTOR {
     }
     export class PBRMaterialPropertyGridComponent extends React.Component<IPBRMaterialPropertyGridComponentProps> {
         constructor(props: IPBRMaterialPropertyGridComponentProps);
-        renderTextures(): JSX.Element | null;
+        renderTextures(onDebugSelectionChangeObservable: BABYLON.Observable<BABYLON.BaseTexture>): JSX.Element | null;
         render(): JSX.Element;
     }
 }
@@ -455,6 +465,7 @@ declare module INSPECTOR {
 }
 declare module INSPECTOR {
     interface IFogPropertyGridComponentProps {
+        globalState: GlobalState;
         scene: BABYLON.Scene;
         lockObject: LockObject;
         onPropertyChangedObservable?: BABYLON.Observable<PropertyChangedEvent>;
@@ -494,6 +505,7 @@ declare module INSPECTOR {
 }
 declare module INSPECTOR {
     interface IScenePropertyGridComponentProps {
+        globalState: GlobalState;
         scene: BABYLON.Scene;
         lockObject: LockObject;
         onPropertyChangedObservable?: BABYLON.Observable<PropertyChangedEvent>;
@@ -513,6 +525,7 @@ declare module INSPECTOR {
 }
 declare module INSPECTOR {
     interface ICommonLightPropertyGridComponentProps {
+        globalState: GlobalState;
         light: BABYLON.Light;
         lockObject: LockObject;
         onPropertyChangedObservable?: BABYLON.Observable<PropertyChangedEvent>;
@@ -524,6 +537,7 @@ declare module INSPECTOR {
 }
 declare module INSPECTOR {
     interface IHemisphericLightPropertyGridComponentProps {
+        globalState: GlobalState;
         light: BABYLON.HemisphericLight;
         lockObject: LockObject;
         onPropertyChangedObservable?: BABYLON.Observable<PropertyChangedEvent>;
@@ -535,6 +549,7 @@ declare module INSPECTOR {
 }
 declare module INSPECTOR {
     interface ICommonShadowLightPropertyGridComponentProps {
+        globalState: GlobalState;
         light: BABYLON.IShadowLight;
         lockObject: LockObject;
         onPropertyChangedObservable?: BABYLON.Observable<PropertyChangedEvent>;
@@ -546,6 +561,7 @@ declare module INSPECTOR {
 }
 declare module INSPECTOR {
     interface IPointLightPropertyGridComponentProps {
+        globalState: GlobalState;
         light: BABYLON.PointLight;
         lockObject: LockObject;
         onPropertyChangedObservable?: BABYLON.Observable<PropertyChangedEvent>;
@@ -557,6 +573,7 @@ declare module INSPECTOR {
 }
 declare module INSPECTOR {
     interface ICommonCameraPropertyGridComponentProps {
+        globalState: GlobalState;
         camera: BABYLON.Camera;
         lockObject: LockObject;
         onPropertyChangedObservable?: BABYLON.Observable<PropertyChangedEvent>;
@@ -570,6 +587,7 @@ declare module INSPECTOR {
 }
 declare module INSPECTOR {
     interface IFreeCameraPropertyGridComponentProps {
+        globalState: GlobalState;
         camera: BABYLON.FreeCamera;
         lockObject: LockObject;
         onPropertyChangedObservable?: BABYLON.Observable<PropertyChangedEvent>;
@@ -581,6 +599,7 @@ declare module INSPECTOR {
 }
 declare module INSPECTOR {
     interface IArcRotateCameraPropertyGridComponentProps {
+        globalState: GlobalState;
         camera: BABYLON.ArcRotateCamera;
         lockObject: LockObject;
         onPropertyChangedObservable?: BABYLON.Observable<PropertyChangedEvent>;
@@ -620,17 +639,22 @@ declare module INSPECTOR {
 declare module INSPECTOR {
     interface IAxisViewerComponentProps {
         node: BABYLON.TransformNode;
+        globalState: GlobalState;
     }
     export class AxesViewerComponent extends React.Component<IAxisViewerComponentProps, {
         displayAxis: boolean;
     }> {
         constructor(props: IAxisViewerComponentProps);
+        shouldComponentUpdate(nextProps: IAxisViewerComponentProps, nextState: {
+            displayAxis: boolean;
+        }): boolean;
         displayAxes(): void;
         render(): JSX.Element;
     }
 }
 declare module INSPECTOR {
     interface IMeshPropertyGridComponentProps {
+        globalState: GlobalState;
         mesh: BABYLON.Mesh;
         lockObject: LockObject;
         onSelectionChangedObservable?: BABYLON.Observable<any>;
@@ -650,6 +674,7 @@ declare module INSPECTOR {
 }
 declare module INSPECTOR {
     interface ITransformNodePropertyGridComponentProps {
+        globalState: GlobalState;
         transformNode: BABYLON.TransformNode;
         lockObject: LockObject;
         onPropertyChangedObservable?: BABYLON.Observable<PropertyChangedEvent>;
@@ -661,6 +686,7 @@ declare module INSPECTOR {
 }
 declare module INSPECTOR {
     interface IBackgroundMaterialPropertyGridComponentProps {
+        globalState: GlobalState;
         material: BABYLON.BackgroundMaterial;
         lockObject: LockObject;
         onSelectionChangedObservable?: BABYLON.Observable<any>;
@@ -698,6 +724,7 @@ declare module INSPECTOR {
 }
 declare module INSPECTOR {
     interface ICommonControlPropertyGridComponentProps {
+        globalState: GlobalState;
         control: BABYLON.GUI.Control;
         lockObject: LockObject;
         onPropertyChangedObservable?: BABYLON.Observable<PropertyChangedEvent>;
@@ -710,6 +737,7 @@ declare module INSPECTOR {
 }
 declare module INSPECTOR {
     interface IControlPropertyGridComponentProps {
+        globalState: GlobalState;
         control: BABYLON.GUI.Control;
         lockObject: LockObject;
         onPropertyChangedObservable?: BABYLON.Observable<PropertyChangedEvent>;
@@ -721,6 +749,7 @@ declare module INSPECTOR {
 }
 declare module INSPECTOR {
     interface ITextBlockPropertyGridComponentProps {
+        globalState: GlobalState;
         textBlock: BABYLON.GUI.TextBlock;
         lockObject: LockObject;
         onPropertyChangedObservable?: BABYLON.Observable<PropertyChangedEvent>;
@@ -732,6 +761,7 @@ declare module INSPECTOR {
 }
 declare module INSPECTOR {
     interface IInputTextPropertyGridComponentProps {
+        globalState: GlobalState;
         inputText: BABYLON.GUI.InputText;
         lockObject: LockObject;
         onPropertyChangedObservable?: BABYLON.Observable<PropertyChangedEvent>;
@@ -743,6 +773,7 @@ declare module INSPECTOR {
 }
 declare module INSPECTOR {
     interface IColorPickerPropertyGridComponentProps {
+        globalState: GlobalState;
         colorPicker: BABYLON.GUI.ColorPicker;
         lockObject: LockObject;
         onPropertyChangedObservable?: BABYLON.Observable<PropertyChangedEvent>;
@@ -764,6 +795,7 @@ declare module INSPECTOR {
 }
 declare module INSPECTOR {
     interface IAnimationGroupGridComponentProps {
+        globalState: GlobalState;
         animationGroup: BABYLON.AnimationGroup;
         scene: BABYLON.Scene;
         lockObject: LockObject;
@@ -790,6 +822,7 @@ declare module INSPECTOR {
 }
 declare module INSPECTOR {
     interface IImagePropertyGridComponentProps {
+        globalState: GlobalState;
         image: BABYLON.GUI.Image;
         lockObject: LockObject;
         onPropertyChangedObservable?: BABYLON.Observable<PropertyChangedEvent>;
@@ -801,6 +834,7 @@ declare module INSPECTOR {
 }
 declare module INSPECTOR {
     interface ISliderPropertyGridComponentProps {
+        globalState: GlobalState;
         slider: BABYLON.GUI.Slider;
         lockObject: LockObject;
         onPropertyChangedObservable?: BABYLON.Observable<PropertyChangedEvent>;
@@ -812,6 +846,7 @@ declare module INSPECTOR {
 }
 declare module INSPECTOR {
     interface IImageBasedSliderPropertyGridComponentProps {
+        globalState: GlobalState;
         imageBasedSlider: BABYLON.GUI.ImageBasedSlider;
         lockObject: LockObject;
         onPropertyChangedObservable?: BABYLON.Observable<PropertyChangedEvent>;
@@ -823,6 +858,7 @@ declare module INSPECTOR {
 }
 declare module INSPECTOR {
     interface IRectanglePropertyGridComponentProps {
+        globalState: GlobalState;
         rectangle: BABYLON.GUI.Rectangle;
         lockObject: LockObject;
         onPropertyChangedObservable?: BABYLON.Observable<PropertyChangedEvent>;
@@ -834,6 +870,7 @@ declare module INSPECTOR {
 }
 declare module INSPECTOR {
     interface IEllipsePropertyGridComponentProps {
+        globalState: GlobalState;
         ellipse: BABYLON.GUI.Ellipse;
         lockObject: LockObject;
         onPropertyChangedObservable?: BABYLON.Observable<PropertyChangedEvent>;
@@ -845,6 +882,7 @@ declare module INSPECTOR {
 }
 declare module INSPECTOR {
     interface ICheckboxPropertyGridComponentProps {
+        globalState: GlobalState;
         checkbox: BABYLON.GUI.Checkbox;
         lockObject: LockObject;
         onPropertyChangedObservable?: BABYLON.Observable<PropertyChangedEvent>;
@@ -856,6 +894,7 @@ declare module INSPECTOR {
 }
 declare module INSPECTOR {
     interface IRadioButtonPropertyGridComponentProps {
+        globalState: GlobalState;
         radioButton: BABYLON.GUI.RadioButton;
         lockObject: LockObject;
         onPropertyChangedObservable?: BABYLON.Observable<PropertyChangedEvent>;
@@ -867,6 +906,7 @@ declare module INSPECTOR {
 }
 declare module INSPECTOR {
     interface ILinePropertyGridComponentProps {
+        globalState: GlobalState;
         line: BABYLON.GUI.Line;
         lockObject: LockObject;
         onPropertyChangedObservable?: BABYLON.Observable<PropertyChangedEvent>;
@@ -879,6 +919,7 @@ declare module INSPECTOR {
 }
 declare module INSPECTOR {
     interface IScrollViewerPropertyGridComponentProps {
+        globalState: GlobalState;
         scrollViewer: BABYLON.GUI.ScrollViewer;
         lockObject: LockObject;
         onPropertyChangedObservable?: BABYLON.Observable<PropertyChangedEvent>;
@@ -890,6 +931,7 @@ declare module INSPECTOR {
 }
 declare module INSPECTOR {
     interface IGridPropertyGridComponentProps {
+        globalState: GlobalState;
         grid: BABYLON.GUI.Grid;
         lockObject: LockObject;
         onPropertyChangedObservable?: BABYLON.Observable<PropertyChangedEvent>;
@@ -903,6 +945,7 @@ declare module INSPECTOR {
 }
 declare module INSPECTOR {
     interface IPBRMetallicRoughnessMaterialPropertyGridComponentProps {
+        globalState: GlobalState;
         material: BABYLON.PBRMetallicRoughnessMaterial;
         lockObject: LockObject;
         onSelectionChangedObservable?: BABYLON.Observable<any>;
@@ -916,6 +959,7 @@ declare module INSPECTOR {
 }
 declare module INSPECTOR {
     interface IPBRSpecularGlossinessMaterialPropertyGridComponentProps {
+        globalState: GlobalState;
         material: BABYLON.PBRSpecularGlossinessMaterial;
         lockObject: LockObject;
         onSelectionChangedObservable?: BABYLON.Observable<any>;
@@ -929,6 +973,7 @@ declare module INSPECTOR {
 }
 declare module INSPECTOR {
     interface IStackPanelPropertyGridComponentProps {
+        globalState: GlobalState;
         stackPanel: BABYLON.GUI.StackPanel;
         lockObject: LockObject;
         onPropertyChangedObservable?: BABYLON.Observable<PropertyChangedEvent>;
@@ -939,6 +984,115 @@ declare module INSPECTOR {
     }
 }
 declare module INSPECTOR {
+    interface ICommonPostProcessPropertyGridComponentProps {
+        globalState: GlobalState;
+        postProcess: BABYLON.PostProcess;
+        lockObject: LockObject;
+        onPropertyChangedObservable?: BABYLON.Observable<PropertyChangedEvent>;
+    }
+    export class CommonPostProcessPropertyGridComponent extends React.Component<ICommonPostProcessPropertyGridComponentProps> {
+        constructor(props: ICommonPostProcessPropertyGridComponentProps);
+        render(): JSX.Element;
+    }
+}
+declare module INSPECTOR {
+    interface IPostProcessPropertyGridComponentProps {
+        globalState: GlobalState;
+        postProcess: BABYLON.PostProcess;
+        lockObject: LockObject;
+        onPropertyChangedObservable?: BABYLON.Observable<PropertyChangedEvent>;
+    }
+    export class PostProcessPropertyGridComponent extends React.Component<IPostProcessPropertyGridComponentProps> {
+        constructor(props: IPostProcessPropertyGridComponentProps);
+        render(): JSX.Element;
+    }
+}
+declare module INSPECTOR {
+    interface ICommonRenderingPipelinePropertyGridComponentProps {
+        globalState: GlobalState;
+        renderPipeline: BABYLON.PostProcessRenderPipeline;
+        lockObject: LockObject;
+        onPropertyChangedObservable?: BABYLON.Observable<PropertyChangedEvent>;
+    }
+    export class CommonRenderingPipelinePropertyGridComponent extends React.Component<ICommonRenderingPipelinePropertyGridComponentProps> {
+        constructor(props: ICommonRenderingPipelinePropertyGridComponentProps);
+        render(): JSX.Element;
+    }
+}
+declare module INSPECTOR {
+    interface IRenderingPipelinePropertyGridComponentProps {
+        globalState: GlobalState;
+        renderPipeline: BABYLON.PostProcessRenderPipeline;
+        lockObject: LockObject;
+        onPropertyChangedObservable?: BABYLON.Observable<PropertyChangedEvent>;
+    }
+    export class RenderingPipelinePropertyGridComponent extends React.Component<IRenderingPipelinePropertyGridComponentProps> {
+        constructor(props: IRenderingPipelinePropertyGridComponentProps);
+        render(): JSX.Element;
+    }
+}
+declare module INSPECTOR {
+    interface IVector2LineComponentProps {
+        label: string;
+        target: any;
+        propertyName: string;
+        onChange?: (newvalue: BABYLON.Vector2) => void;
+        onPropertyChangedObservable?: BABYLON.Observable<PropertyChangedEvent>;
+    }
+    export class Vector2LineComponent extends React.Component<IVector2LineComponentProps, {
+        isExpanded: boolean;
+        value: BABYLON.Vector2;
+    }> {
+        private _localChange;
+        constructor(props: IVector2LineComponentProps);
+        shouldComponentUpdate(nextProps: IVector2LineComponentProps, nextState: {
+            isExpanded: boolean;
+            value: BABYLON.Vector2;
+        }): boolean;
+        switchExpandState(): void;
+        raiseOnPropertyChanged(previousValue: BABYLON.Vector2): void;
+        updateStateX(value: number): void;
+        updateStateY(value: number): void;
+        render(): JSX.Element;
+    }
+}
+declare module INSPECTOR {
+    interface IDefaultRenderingPipelinePropertyGridComponentProps {
+        globalState: GlobalState;
+        renderPipeline: BABYLON.DefaultRenderingPipeline;
+        lockObject: LockObject;
+        onPropertyChangedObservable?: BABYLON.Observable<PropertyChangedEvent>;
+    }
+    export class DefaultRenderingPipelinePropertyGridComponent extends React.Component<IDefaultRenderingPipelinePropertyGridComponentProps> {
+        constructor(props: IDefaultRenderingPipelinePropertyGridComponentProps);
+        render(): JSX.Element;
+    }
+}
+declare module INSPECTOR {
+    interface ISSAORenderingPipelinePropertyGridComponentProps {
+        globalState: GlobalState;
+        renderPipeline: BABYLON.SSAORenderingPipeline;
+        lockObject: LockObject;
+        onPropertyChangedObservable?: BABYLON.Observable<PropertyChangedEvent>;
+    }
+    export class SSAORenderingPipelinePropertyGridComponent extends React.Component<ISSAORenderingPipelinePropertyGridComponentProps> {
+        constructor(props: ISSAORenderingPipelinePropertyGridComponentProps);
+        render(): JSX.Element;
+    }
+}
+declare module INSPECTOR {
+    interface ISSAO2RenderingPipelinePropertyGridComponentProps {
+        globalState: GlobalState;
+        renderPipeline: BABYLON.SSAO2RenderingPipeline;
+        lockObject: LockObject;
+        onPropertyChangedObservable?: BABYLON.Observable<PropertyChangedEvent>;
+    }
+    export class SSAO2RenderingPipelinePropertyGridComponent extends React.Component<ISSAO2RenderingPipelinePropertyGridComponentProps> {
+        constructor(props: ISSAO2RenderingPipelinePropertyGridComponentProps);
+        render(): JSX.Element;
+    }
+}
+declare module INSPECTOR {
     export class PropertyGridTabComponent extends PaneComponent {
         private _timerIntervalId;
         private _lockObject;
@@ -1004,7 +1158,7 @@ declare module INSPECTOR {
         componentWillUnmount(): void;
         captureScreenshot(): void;
         recordVideo(): void;
-        shouldExport(transformNode: BABYLON.TransformNode): boolean;
+        shouldExport(node: BABYLON.Node): boolean;
         exportGLTF(): void;
         exportBabylon(): void;
         createEnvTexture(): void;
@@ -1196,6 +1350,28 @@ declare module INSPECTOR {
     }
 }
 declare module INSPECTOR {
+    interface IPostProcessItemComponentProps {
+        postProcess: BABYLON.PostProcess;
+        extensibilityGroups?: BABYLON.IExplorerExtensibilityGroup[];
+        onClick: () => void;
+    }
+    export class PostProcessItemComponent extends React.Component<IPostProcessItemComponentProps> {
+        constructor(props: IPostProcessItemComponentProps);
+        render(): JSX.Element;
+    }
+}
+declare module INSPECTOR {
+    interface IRenderPipelineItemComponenttProps {
+        renderPipeline: BABYLON.PostProcessRenderPipeline;
+        extensibilityGroups?: BABYLON.IExplorerExtensibilityGroup[];
+        onClick: () => void;
+    }
+    export class RenderingPipelineItemComponent extends React.Component<IRenderPipelineItemComponenttProps> {
+        constructor(props: IRenderPipelineItemComponenttProps);
+        render(): JSX.Element;
+    }
+}
+declare module INSPECTOR {
     interface ITreeItemSpecializedComponentProps {
         label: string;
         entity?: any;
@@ -1255,17 +1431,23 @@ declare module INSPECTOR {
         entity?: any;
         selectedEntity: any;
         extensibilityGroups?: BABYLON.IExplorerExtensibilityGroup[];
+        contextMenuItems?: {
+            label: string;
+            action: () => void;
+        }[];
     }
     export class TreeItemComponent extends React.Component<ITreeItemComponentProps, {
         isExpanded: boolean;
         mustExpand: boolean;
     }> {
+        static _ContextMenuUniqueIdGenerator: number;
         constructor(props: ITreeItemComponentProps);
         switchExpandedState(): void;
         shouldComponentUpdate(nextProps: ITreeItemComponentProps, nextState: {
             isExpanded: boolean;
         }): boolean;
         expandAll(expand: boolean): void;
+        renderContextMenu(): JSX.Element | null;
         render(): JSX.Element;
     }
 }
@@ -1375,9 +1557,10 @@ declare module INSPECTOR {
         private static _Scene;
         private static _OpenedPane;
         private static _OnBeforeRenderObserver;
-        static OnSelectionChangeObservable: BABYLON.Observable<string>;
+        static OnSelectionChangeObservable: BABYLON.Observable<any>;
         static OnPropertyChangedObservable: BABYLON.Observable<PropertyChangedEvent>;
         private static _GlobalState;
+        static MarkLineContainerTitleForHighlighting(title: string): void;
         private static _CopyStyles;
         private static _CreateSceneExplorer;
         private static _CreateActionTabs;
@@ -1395,6 +1578,7 @@ declare module INSPECTOR {
 }
 declare module INSPECTOR {
     interface IDirectionalLightPropertyGridComponentProps {
+        globalState: GlobalState;
         light: BABYLON.DirectionalLight;
         lockObject: LockObject;
         onPropertyChangedObservable?: BABYLON.Observable<PropertyChangedEvent>;
@@ -1406,6 +1590,7 @@ declare module INSPECTOR {
 }
 declare module INSPECTOR {
     interface ISpotLightPropertyGridComponentProps {
+        globalState: GlobalState;
         light: BABYLON.SpotLight;
         lockObject: LockObject;
         onPropertyChangedObservable?: BABYLON.Observable<PropertyChangedEvent>;

File diff suppressed because it is too large
+ 472 - 9
dist/preview release/inspector/babylon.inspector.module.d.ts


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

@@ -3359,6 +3359,9 @@ var GLTFFileLoader = /** @class */ (function () {
         return 0;
     };
     GLTFFileLoader._decodeBufferToText = function (buffer) {
+        if (typeof TextDecoder !== "undefined") {
+            return new TextDecoder().decode(buffer);
+        }
         var result = "";
         var length = buffer.byteLength;
         for (var i = 0; i < length; i++) {

File diff suppressed because it is too large
+ 1 - 1
dist/preview release/loaders/babylon.glTF1FileLoader.js.map


File diff suppressed because it is too large
+ 2 - 2
dist/preview release/loaders/babylon.glTF1FileLoader.min.js


+ 3 - 0
dist/preview release/loaders/babylon.glTF2FileLoader.js

@@ -3986,6 +3986,9 @@ var GLTFFileLoader = /** @class */ (function () {
         return 0;
     };
     GLTFFileLoader._decodeBufferToText = function (buffer) {
+        if (typeof TextDecoder !== "undefined") {
+            return new TextDecoder().decode(buffer);
+        }
         var result = "";
         var length = buffer.byteLength;
         for (var i = 0; i < length; i++) {

File diff suppressed because it is too large
+ 1 - 1
dist/preview release/loaders/babylon.glTF2FileLoader.js.map


File diff suppressed because it is too large
+ 1 - 1
dist/preview release/loaders/babylon.glTF2FileLoader.min.js


+ 3 - 0
dist/preview release/loaders/babylon.glTFFileLoader.js

@@ -6535,6 +6535,9 @@ var GLTFFileLoader = /** @class */ (function () {
         return 0;
     };
     GLTFFileLoader._decodeBufferToText = function (buffer) {
+        if (typeof TextDecoder !== "undefined") {
+            return new TextDecoder().decode(buffer);
+        }
         var result = "";
         var length = buffer.byteLength;
         for (var i = 0; i < length; i++) {

File diff suppressed because it is too large
+ 1 - 1
dist/preview release/loaders/babylon.glTFFileLoader.js.map


File diff suppressed because it is too large
+ 2 - 2
dist/preview release/loaders/babylon.glTFFileLoader.min.js


+ 3 - 0
dist/preview release/loaders/babylonjs.loaders.js

@@ -7789,6 +7789,9 @@ var GLTFFileLoader = /** @class */ (function () {
         return 0;
     };
     GLTFFileLoader._decodeBufferToText = function (buffer) {
+        if (typeof TextDecoder !== "undefined") {
+            return new TextDecoder().decode(buffer);
+        }
         var result = "";
         var length = buffer.byteLength;
         for (var i = 0; i < length; i++) {

File diff suppressed because it is too large
+ 1 - 1
dist/preview release/loaders/babylonjs.loaders.js.map


File diff suppressed because it is too large
+ 2 - 2
dist/preview release/loaders/babylonjs.loaders.min.js


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

@@ -1 +1 @@
-{"engineOnly":304017,"sceneOnly":504022,"minGridMaterial":622541,"minStandardMaterial":743249}
+{"engineOnly":304108,"sceneOnly":504513,"minGridMaterial":623674,"minStandardMaterial":745822}

File diff suppressed because it is too large
+ 2 - 2
dist/preview release/postProcessesLibrary/babylon.asciiArtPostProcess.min.js


File diff suppressed because it is too large
+ 2 - 2
dist/preview release/postProcessesLibrary/babylon.digitalRainPostProcess.min.js


File diff suppressed because it is too large
+ 644 - 0
dist/preview release/postProcessesLibrary/babylon.oceanPostProcess.js


File diff suppressed because it is too large
+ 1 - 0
dist/preview release/postProcessesLibrary/babylon.oceanPostProcess.js.map


File diff suppressed because it is too large
+ 16 - 0
dist/preview release/postProcessesLibrary/babylon.oceanPostProcess.min.js


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

@@ -209,4 +209,99 @@ declare module BABYLON {
          */
         constructor(name: string, camera: BABYLON.Camera, options?: string | IDigitalRainPostProcessOptions);
     }
+}
+declare module BABYLON {
+    /** @hidden */
+    export var oceanPostProcessPixelShader: {
+        name: string;
+        shader: string;
+    };
+}
+declare module BABYLON {
+    /**
+     * Option available in the Ocean Post Process.
+     */
+    export interface IOceanPostProcessOptions {
+        /**
+         * The size of the reflection RTT (number if square, or {width: number, height:number} or {ratio:} to define a ratio from the main scene)
+         */
+        reflectionSize?: number | {
+            width: number;
+            height: number;
+        } | {
+            ratio: number;
+        };
+        /**
+         * The size of the refraction RTT (number if square, or {width: number, height:number} or {ratio:} to define a ratio from the main scene)
+         */
+        refractionSize?: number | {
+            width: number;
+            height: number;
+        } | {
+            ratio: number;
+        };
+    }
+    /**
+     * OceanPostProcess helps rendering an infinite ocean surface that can reflect and refract environment.
+     *
+     * Simmply add it to your scene and let the nerd that lives in you have fun.
+     * Example usage:
+     *  var pp = new OceanPostProcess("myOcean", camera);
+     *  pp.reflectionEnabled = true;
+     *  pp.refractionEnabled = true;
+     */
+    export class OceanPostProcess extends BABYLON.PostProcess {
+        /**
+         * Gets a boolean indicating if the real-time reflection is enabled on the ocean.
+         */
+        /**
+        * Sets weither or not the real-time reflection is enabled on the ocean.
+        * Is set to true, the reflection mirror texture will be used as reflection texture.
+        */
+        reflectionEnabled: boolean;
+        /**
+         * Gets a boolean indicating if the real-time refraction is enabled on the ocean.
+         */
+        /**
+        * Sets weither or not the real-time refraction is enabled on the ocean.
+        * Is set to true, the refraction render target texture will be used as refraction texture.
+        */
+        refractionEnabled: boolean;
+        /**
+         * Gets wether or not the post-processes is supported by the running hardware.
+         * This requires draw buffer supports.
+         */
+        readonly isSupported: boolean;
+        /**
+         * This is the reflection mirror texture used to display reflections on the ocean.
+         * By default, render list is empty.
+         */
+        reflectionTexture: BABYLON.MirrorTexture;
+        /**
+         * This is the refraction render target texture used to display refraction on the ocean.
+         * By default, render list is empty.
+         */
+        refractionTexture: BABYLON.RenderTargetTexture;
+        private _time;
+        private _cameraRotation;
+        private _cameraViewMatrix;
+        private _reflectionEnabled;
+        private _refractionEnabled;
+        private _geometryRenderer;
+        /**
+         * Instantiates a new Ocean Post Process.
+         * @param name the name to give to the postprocess.
+         * @camera the camera to apply the post process to.
+         * @param options optional object following the IOceanPostProcessOptions format used to customize reflection and refraction render targets sizes.
+         */
+        constructor(name: string, camera: BABYLON.TargetCamera, options?: IOceanPostProcessOptions);
+        /**
+         * Returns the appropriate defines according to the current configuration.
+         */
+        private _getDefines;
+        /**
+         * Computes the current camera rotation as the shader requires a camera rotation.
+         */
+        private _computeCameraRotation;
+    }
 }

File diff suppressed because it is too large
+ 262 - 2
dist/preview release/postProcessesLibrary/babylonjs.postProcess.js


File diff suppressed because it is too large
+ 1 - 1
dist/preview release/postProcessesLibrary/babylonjs.postProcess.js.map


File diff suppressed because it is too large
+ 2 - 2
dist/preview release/postProcessesLibrary/babylonjs.postProcess.min.js


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

@@ -228,9 +228,113 @@ declare module "babylonjs-post-process/digitalRain/digitalRainPostProcess" {
 declare module "babylonjs-post-process/digitalRain/index" {
     export * from "babylonjs-post-process/digitalRain/digitalRainPostProcess";
 }
+declare module "babylonjs-post-process/ocean/oceanPostProcess.fragment" {
+    /** @hidden */
+    export var oceanPostProcessPixelShader: {
+        name: string;
+        shader: string;
+    };
+}
+declare module "babylonjs-post-process/ocean/oceanPostProcess" {
+    import { TargetCamera } from "babylonjs/Cameras/targetCamera";
+    import { MirrorTexture } from "babylonjs/Materials/Textures/mirrorTexture";
+    import { RenderTargetTexture } from "babylonjs/Materials/Textures/renderTargetTexture";
+    import { PostProcess } from "babylonjs/PostProcesses/postProcess";
+    import "babylonjs-post-process/ocean/oceanPostProcess.fragment";
+    /**
+     * Option available in the Ocean Post Process.
+     */
+    export interface IOceanPostProcessOptions {
+        /**
+         * The size of the reflection RTT (number if square, or {width: number, height:number} or {ratio:} to define a ratio from the main scene)
+         */
+        reflectionSize?: number | {
+            width: number;
+            height: number;
+        } | {
+            ratio: number;
+        };
+        /**
+         * The size of the refraction RTT (number if square, or {width: number, height:number} or {ratio:} to define a ratio from the main scene)
+         */
+        refractionSize?: number | {
+            width: number;
+            height: number;
+        } | {
+            ratio: number;
+        };
+    }
+    /**
+     * OceanPostProcess helps rendering an infinite ocean surface that can reflect and refract environment.
+     *
+     * Simmply add it to your scene and let the nerd that lives in you have fun.
+     * Example usage:
+     *  var pp = new OceanPostProcess("myOcean", camera);
+     *  pp.reflectionEnabled = true;
+     *  pp.refractionEnabled = true;
+     */
+    export class OceanPostProcess extends PostProcess {
+        /**
+         * Gets a boolean indicating if the real-time reflection is enabled on the ocean.
+         */
+        /**
+        * Sets weither or not the real-time reflection is enabled on the ocean.
+        * Is set to true, the reflection mirror texture will be used as reflection texture.
+        */
+        reflectionEnabled: boolean;
+        /**
+         * Gets a boolean indicating if the real-time refraction is enabled on the ocean.
+         */
+        /**
+        * Sets weither or not the real-time refraction is enabled on the ocean.
+        * Is set to true, the refraction render target texture will be used as refraction texture.
+        */
+        refractionEnabled: boolean;
+        /**
+         * Gets wether or not the post-processes is supported by the running hardware.
+         * This requires draw buffer supports.
+         */
+        readonly isSupported: boolean;
+        /**
+         * This is the reflection mirror texture used to display reflections on the ocean.
+         * By default, render list is empty.
+         */
+        reflectionTexture: MirrorTexture;
+        /**
+         * This is the refraction render target texture used to display refraction on the ocean.
+         * By default, render list is empty.
+         */
+        refractionTexture: RenderTargetTexture;
+        private _time;
+        private _cameraRotation;
+        private _cameraViewMatrix;
+        private _reflectionEnabled;
+        private _refractionEnabled;
+        private _geometryRenderer;
+        /**
+         * Instantiates a new Ocean Post Process.
+         * @param name the name to give to the postprocess.
+         * @camera the camera to apply the post process to.
+         * @param options optional object following the IOceanPostProcessOptions format used to customize reflection and refraction render targets sizes.
+         */
+        constructor(name: string, camera: TargetCamera, options?: IOceanPostProcessOptions);
+        /**
+         * Returns the appropriate defines according to the current configuration.
+         */
+        private _getDefines;
+        /**
+         * Computes the current camera rotation as the shader requires a camera rotation.
+         */
+        private _computeCameraRotation;
+    }
+}
+declare module "babylonjs-post-process/ocean/index" {
+    export * from "babylonjs-post-process/ocean/oceanPostProcess";
+}
 declare module "babylonjs-post-process/index" {
     export * from "babylonjs-post-process/asciiArt/index";
     export * from "babylonjs-post-process/digitalRain/index";
+    export * from "babylonjs-post-process/ocean/index";
 }
 declare module "babylonjs-post-process/legacy/legacy-asciiArt" {
     export * from "babylonjs-post-process/asciiArt/index";
@@ -238,6 +342,9 @@ declare module "babylonjs-post-process/legacy/legacy-asciiArt" {
 declare module "babylonjs-post-process/legacy/legacy-digitalRain" {
     export * from "babylonjs-post-process/digitalRain/index";
 }
+declare module "babylonjs-post-process/legacy/legacy-ocean" {
+    export * from "babylonjs-post-process/ocean/index";
+}
 declare module "babylonjs-post-process/legacy/legacy" {
     export * from "babylonjs-post-process/index";
 }
@@ -455,4 +562,99 @@ declare module BABYLON {
          */
         constructor(name: string, camera: BABYLON.Camera, options?: string | IDigitalRainPostProcessOptions);
     }
+}
+declare module BABYLON {
+    /** @hidden */
+    export var oceanPostProcessPixelShader: {
+        name: string;
+        shader: string;
+    };
+}
+declare module BABYLON {
+    /**
+     * Option available in the Ocean Post Process.
+     */
+    export interface IOceanPostProcessOptions {
+        /**
+         * The size of the reflection RTT (number if square, or {width: number, height:number} or {ratio:} to define a ratio from the main scene)
+         */
+        reflectionSize?: number | {
+            width: number;
+            height: number;
+        } | {
+            ratio: number;
+        };
+        /**
+         * The size of the refraction RTT (number if square, or {width: number, height:number} or {ratio:} to define a ratio from the main scene)
+         */
+        refractionSize?: number | {
+            width: number;
+            height: number;
+        } | {
+            ratio: number;
+        };
+    }
+    /**
+     * OceanPostProcess helps rendering an infinite ocean surface that can reflect and refract environment.
+     *
+     * Simmply add it to your scene and let the nerd that lives in you have fun.
+     * Example usage:
+     *  var pp = new OceanPostProcess("myOcean", camera);
+     *  pp.reflectionEnabled = true;
+     *  pp.refractionEnabled = true;
+     */
+    export class OceanPostProcess extends BABYLON.PostProcess {
+        /**
+         * Gets a boolean indicating if the real-time reflection is enabled on the ocean.
+         */
+        /**
+        * Sets weither or not the real-time reflection is enabled on the ocean.
+        * Is set to true, the reflection mirror texture will be used as reflection texture.
+        */
+        reflectionEnabled: boolean;
+        /**
+         * Gets a boolean indicating if the real-time refraction is enabled on the ocean.
+         */
+        /**
+        * Sets weither or not the real-time refraction is enabled on the ocean.
+        * Is set to true, the refraction render target texture will be used as refraction texture.
+        */
+        refractionEnabled: boolean;
+        /**
+         * Gets wether or not the post-processes is supported by the running hardware.
+         * This requires draw buffer supports.
+         */
+        readonly isSupported: boolean;
+        /**
+         * This is the reflection mirror texture used to display reflections on the ocean.
+         * By default, render list is empty.
+         */
+        reflectionTexture: BABYLON.MirrorTexture;
+        /**
+         * This is the refraction render target texture used to display refraction on the ocean.
+         * By default, render list is empty.
+         */
+        refractionTexture: BABYLON.RenderTargetTexture;
+        private _time;
+        private _cameraRotation;
+        private _cameraViewMatrix;
+        private _reflectionEnabled;
+        private _refractionEnabled;
+        private _geometryRenderer;
+        /**
+         * Instantiates a new Ocean Post Process.
+         * @param name the name to give to the postprocess.
+         * @camera the camera to apply the post process to.
+         * @param options optional object following the IOceanPostProcessOptions format used to customize reflection and refraction render targets sizes.
+         */
+        constructor(name: string, camera: BABYLON.TargetCamera, options?: IOceanPostProcessOptions);
+        /**
+         * Returns the appropriate defines according to the current configuration.
+         */
+        private _getDefines;
+        /**
+         * Computes the current camera rotation as the shader requires a camera rotation.
+         */
+        private _computeCameraRotation;
+    }
 }

+ 283 - 86
dist/preview release/serializers/babylon.glTF2Serializer.js

@@ -127,6 +127,169 @@ module.exports = g;
 
 /***/ }),
 
+/***/ "./glTF/2.0/Extensions/KHR_lights_punctual.ts":
+/*!****************************************************!*\
+  !*** ./glTF/2.0/Extensions/KHR_lights_punctual.ts ***!
+  \****************************************************/
+/*! exports provided: KHR_lights_punctual */
+/***/ (function(module, __webpack_exports__, __webpack_require__) {
+
+"use strict";
+__webpack_require__.r(__webpack_exports__);
+/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "KHR_lights_punctual", function() { return KHR_lights_punctual; });
+/* 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___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Maths_math__WEBPACK_IMPORTED_MODULE_0__);
+/* harmony import */ var _glTFExporter__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../glTFExporter */ "./glTF/2.0/glTFExporter.ts");
+/* harmony import */ var _glTFUtilities__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../glTFUtilities */ "./glTF/2.0/glTFUtilities.ts");
+
+
+
+
+
+
+var NAME = "KHR_lights_punctual";
+var LightType;
+(function (LightType) {
+    LightType["DIRECTIONAL"] = "directional";
+    LightType["POINT"] = "point";
+    LightType["SPOT"] = "spot";
+})(LightType || (LightType = {}));
+/**
+ * [Specification](https://github.com/KhronosGroup/glTF/blob/master/extensions/2.0/Khronos/KHR_lights_punctual/README.md)
+ */
+var KHR_lights_punctual = /** @class */ (function () {
+    /** @hidden */
+    function KHR_lights_punctual(exporter) {
+        /** The name of this extension. */
+        this.name = NAME;
+        /** Defines whether this extension is enabled. */
+        this.enabled = true;
+        /** Defines whether this extension is required */
+        this.required = false;
+        this._exporter = exporter;
+    }
+    /** @hidden */
+    KHR_lights_punctual.prototype.dispose = function () {
+        delete this._exporter;
+        delete this._lights;
+    };
+    /** @hidden */
+    KHR_lights_punctual.prototype.onExporting = function () {
+        if (this._lights) {
+            if (this._exporter._glTF.extensionsUsed == null) {
+                this._exporter._glTF.extensionsUsed = [];
+            }
+            if (this._exporter._glTF.extensionsUsed.indexOf(NAME) === -1) {
+                this._exporter._glTF.extensionsUsed.push(NAME);
+            }
+            if (this.required) {
+                if (this._exporter._glTF.extensionsRequired == null) {
+                    this._exporter._glTF.extensionsRequired = [];
+                }
+                if (this._exporter._glTF.extensionsRequired.indexOf(NAME) === -1) {
+                    this._exporter._glTF.extensionsRequired.push(NAME);
+                }
+            }
+            if (this._exporter._glTF.extensions == null) {
+                this._exporter._glTF.extensions = {};
+            }
+            this._exporter._glTF.extensions[NAME] = this._lights;
+        }
+    };
+    /**
+     * Define this method to modify the default behavior when exporting a node
+     * @param context The context when exporting the node
+     * @param node glTF node
+     * @param babylonNode BabylonJS node
+     * @returns nullable INode promise
+     */
+    KHR_lights_punctual.prototype.postExportNodeAsync = function (context, node, babylonNode) {
+        var _this = this;
+        return new Promise(function (resolve, reject) {
+            if (babylonNode instanceof babylonjs_Maths_math__WEBPACK_IMPORTED_MODULE_0__["ShadowLight"]) {
+                var babylonLight = babylonNode;
+                var light = void 0;
+                var lightType = (babylonLight.getTypeID() == babylonjs_Maths_math__WEBPACK_IMPORTED_MODULE_0__["Light"].LIGHTTYPEID_POINTLIGHT ? LightType.POINT : (babylonLight.getTypeID() == babylonjs_Maths_math__WEBPACK_IMPORTED_MODULE_0__["Light"].LIGHTTYPEID_DIRECTIONALLIGHT ? LightType.DIRECTIONAL : (babylonLight.getTypeID() == babylonjs_Maths_math__WEBPACK_IMPORTED_MODULE_0__["Light"].LIGHTTYPEID_SPOTLIGHT ? LightType.SPOT : null)));
+                if (lightType == null) {
+                    babylonjs_Maths_math__WEBPACK_IMPORTED_MODULE_0__["Logger"].Warn(context + ": Light " + babylonLight.name + " is not supported in " + NAME);
+                }
+                else {
+                    var lightPosition = babylonLight.position.clone();
+                    if (!lightPosition.equals(babylonjs_Maths_math__WEBPACK_IMPORTED_MODULE_0__["Vector3"].Zero())) {
+                        if (_this._exporter._convertToRightHandedSystem) {
+                            _glTFUtilities__WEBPACK_IMPORTED_MODULE_2__["_GLTFUtilities"]._GetRightHandedPositionVector3FromRef(lightPosition);
+                        }
+                        node.translation = lightPosition.asArray();
+                    }
+                    if (lightType !== LightType.POINT) {
+                        var localAxis = babylonLight.direction;
+                        var yaw = -Math.atan2(localAxis.z, localAxis.x) + Math.PI / 2;
+                        var len = Math.sqrt(localAxis.x * localAxis.x + localAxis.z * localAxis.z);
+                        var pitch = -Math.atan2(localAxis.y, len);
+                        var lightRotationQuaternion = babylonjs_Maths_math__WEBPACK_IMPORTED_MODULE_0__["Quaternion"].RotationYawPitchRoll(yaw, pitch, 0);
+                        if (_this._exporter._convertToRightHandedSystem) {
+                            _glTFUtilities__WEBPACK_IMPORTED_MODULE_2__["_GLTFUtilities"]._GetRightHandedQuaternionFromRef(lightRotationQuaternion);
+                        }
+                        if (!lightRotationQuaternion.equals(babylonjs_Maths_math__WEBPACK_IMPORTED_MODULE_0__["Quaternion"].Identity())) {
+                            node.rotation = lightRotationQuaternion.asArray();
+                        }
+                    }
+                    if (babylonLight.falloffType !== babylonjs_Maths_math__WEBPACK_IMPORTED_MODULE_0__["Light"].FALLOFF_GLTF) {
+                        babylonjs_Maths_math__WEBPACK_IMPORTED_MODULE_0__["Logger"].Warn(context + ": Light falloff for " + babylonLight.name + " does not match the " + NAME + " specification!");
+                    }
+                    light = {
+                        type: lightType
+                    };
+                    if (!babylonLight.diffuse.equals(babylonjs_Maths_math__WEBPACK_IMPORTED_MODULE_0__["Color3"].White())) {
+                        light.color = babylonLight.diffuse.asArray();
+                    }
+                    if (babylonLight.intensity !== 1.0) {
+                        light.intensity = babylonLight.intensity;
+                    }
+                    if (babylonLight.range !== Number.MAX_VALUE) {
+                        light.range = babylonLight.range;
+                    }
+                    if (lightType === LightType.SPOT) {
+                        var babylonSpotLight = babylonLight;
+                        if (babylonSpotLight.angle !== Math.PI / 2.0) {
+                            if (light.spot == null) {
+                                light.spot = {};
+                            }
+                            light.spot.outerConeAngle = babylonSpotLight.angle / 2.0;
+                        }
+                        if (babylonSpotLight.innerAngle !== 0) {
+                            if (light.spot == null) {
+                                light.spot = {};
+                            }
+                            light.spot.innerConeAngle = babylonSpotLight.innerAngle / 2.0;
+                        }
+                    }
+                    if (_this._lights == null) {
+                        _this._lights = {
+                            lights: []
+                        };
+                    }
+                    _this._lights.lights.push(light);
+                    if (node.extensions == null) {
+                        node.extensions = {};
+                    }
+                    var lightReference = {
+                        light: _this._lights.lights.length - 1
+                    };
+                    node.extensions[NAME] = lightReference;
+                }
+            }
+            resolve(node);
+        });
+    };
+    return KHR_lights_punctual;
+}());
+
+_glTFExporter__WEBPACK_IMPORTED_MODULE_1__["_Exporter"].RegisterExtension(NAME, function (exporter) { return new KHR_lights_punctual(exporter); });
+
+
+/***/ }),
+
 /***/ "./glTF/2.0/Extensions/KHR_texture_transform.ts":
 /*!******************************************************!*\
   !*** ./glTF/2.0/Extensions/KHR_texture_transform.ts ***!
@@ -235,7 +398,7 @@ _glTFExporter__WEBPACK_IMPORTED_MODULE_1__["_Exporter"].RegisterExtension(NAME,
 /*!**************************************!*\
   !*** ./glTF/2.0/Extensions/index.ts ***!
   \**************************************/
-/*! exports provided: KHR_texture_transform */
+/*! exports provided: KHR_texture_transform, KHR_lights_punctual */
 /***/ (function(module, __webpack_exports__, __webpack_require__) {
 
 "use strict";
@@ -243,6 +406,10 @@ __webpack_require__.r(__webpack_exports__);
 /* harmony import */ var _KHR_texture_transform__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./KHR_texture_transform */ "./glTF/2.0/Extensions/KHR_texture_transform.ts");
 /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "KHR_texture_transform", function() { return _KHR_texture_transform__WEBPACK_IMPORTED_MODULE_0__["KHR_texture_transform"]; });
 
+/* harmony import */ var _KHR_lights_punctual__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./KHR_lights_punctual */ "./glTF/2.0/Extensions/KHR_lights_punctual.ts");
+/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "KHR_lights_punctual", function() { return _KHR_lights_punctual__WEBPACK_IMPORTED_MODULE_1__["KHR_lights_punctual"]; });
+
+
 
 
 
@@ -267,6 +434,7 @@ __webpack_require__.r(__webpack_exports__);
 
 
 
+
 /**
  * @hidden
  * Enum for handling in tangent and out tangent.
@@ -375,7 +543,7 @@ var _GLTFAnimation = /** @class */ (function () {
     /**
      * @ignore
      * Create node animations from the transform node animations
-     * @param babylonTransformNode
+     * @param babylonNode
      * @param runtimeGLTFAnimation
      * @param idleGLTFAnimations
      * @param nodeMap
@@ -385,21 +553,23 @@ var _GLTFAnimation = /** @class */ (function () {
      * @param accessors
      * @param convertToRightHandedSystem
      */
-    _GLTFAnimation._CreateNodeAnimationFromTransformNodeAnimations = function (babylonTransformNode, runtimeGLTFAnimation, idleGLTFAnimations, nodeMap, nodes, binaryWriter, bufferViews, accessors, convertToRightHandedSystem, animationSampleRate) {
+    _GLTFAnimation._CreateNodeAnimationFromNodeAnimations = function (babylonNode, runtimeGLTFAnimation, idleGLTFAnimations, nodeMap, nodes, binaryWriter, bufferViews, accessors, convertToRightHandedSystem, animationSampleRate) {
         var glTFAnimation;
-        if (babylonTransformNode.animations) {
-            for (var _i = 0, _a = babylonTransformNode.animations; _i < _a.length; _i++) {
-                var animation = _a[_i];
-                var animationInfo = _GLTFAnimation._DeduceAnimationInfo(animation);
-                if (animationInfo) {
-                    glTFAnimation = {
-                        name: animation.name,
-                        samplers: [],
-                        channels: []
-                    };
-                    _GLTFAnimation.AddAnimation("" + animation.name, animation.hasRunningRuntimeAnimations ? runtimeGLTFAnimation : glTFAnimation, babylonTransformNode, animation, animationInfo.dataAccessorType, animationInfo.animationChannelTargetPath, nodeMap, binaryWriter, bufferViews, accessors, convertToRightHandedSystem, animationInfo.useQuaternion, animationSampleRate);
-                    if (glTFAnimation.samplers.length && glTFAnimation.channels.length) {
-                        idleGLTFAnimations.push(glTFAnimation);
+        if (babylonNode instanceof babylonjs_Maths_math__WEBPACK_IMPORTED_MODULE_0__["TransformNode"]) {
+            if (babylonNode.animations) {
+                for (var _i = 0, _a = babylonNode.animations; _i < _a.length; _i++) {
+                    var animation = _a[_i];
+                    var animationInfo = _GLTFAnimation._DeduceAnimationInfo(animation);
+                    if (animationInfo) {
+                        glTFAnimation = {
+                            name: animation.name,
+                            samplers: [],
+                            channels: []
+                        };
+                        _GLTFAnimation.AddAnimation("" + animation.name, animation.hasRunningRuntimeAnimations ? runtimeGLTFAnimation : glTFAnimation, babylonNode, animation, animationInfo.dataAccessorType, animationInfo.animationChannelTargetPath, nodeMap, binaryWriter, bufferViews, accessors, convertToRightHandedSystem, animationInfo.useQuaternion, animationSampleRate);
+                        if (glTFAnimation.samplers.length && glTFAnimation.channels.length) {
+                            idleGLTFAnimations.push(glTFAnimation);
+                        }
                     }
                 }
             }
@@ -1010,6 +1180,7 @@ __webpack_require__.r(__webpack_exports__);
 
 
 
+
 /**
  * Converts Babylon Scene into glTF 2.0.
  * @hidden
@@ -1022,9 +1193,9 @@ var _Exporter = /** @class */ (function () {
      */
     function _Exporter(babylonScene, options) {
         this._extensions = {};
-        this._asset = { generator: "BabylonJS", version: "2.0" };
-        this._extensionsUsed = [];
-        this._extensionsRequired = [];
+        this._glTF = {
+            asset: { generator: "BabylonJS", version: "2.0" }
+        };
         this._babylonScene = babylonScene;
         this._bufferViews = [];
         this._accessors = [];
@@ -1040,7 +1211,7 @@ var _Exporter = /** @class */ (function () {
         this._imageData = {};
         this._convertToRightHandedSystem = this._babylonScene.useRightHandedSystem ? false : true;
         var _options = options || {};
-        this._shouldExportTransformNode = _options.shouldExportTransformNode ? _options.shouldExportTransformNode : function (babylonTransformNode) { return true; };
+        this._shouldExportNode = _options.shouldExportNode ? _options.shouldExportNode : function (babylonNode) { return true; };
         this._animationSampleRate = _options.animationSampleRate ? _options.animationSampleRate : 1 / 60;
         this._glTFMaterialExporter = new _glTFMaterialExporter__WEBPACK_IMPORTED_MODULE_1__["_GLTFMaterialExporter"](this);
         this._loadExtensions();
@@ -1076,14 +1247,29 @@ var _Exporter = /** @class */ (function () {
     _Exporter.prototype._extensionsPostExportMeshPrimitiveAsync = function (context, meshPrimitive, babylonSubMesh, binaryWriter) {
         return this._applyExtensions(meshPrimitive, function (extension) { return extension.postExportMeshPrimitiveAsync && extension.postExportMeshPrimitiveAsync(context, meshPrimitive, babylonSubMesh, binaryWriter); });
     };
+    _Exporter.prototype._extensionsPostExportNodeAsync = function (context, node, babylonNode) {
+        return this._applyExtensions(node, function (extension) { return extension.postExportNodeAsync && extension.postExportNodeAsync(context, node, babylonNode); });
+    };
+    _Exporter.prototype._forEachExtensions = function (action) {
+        for (var _i = 0, _a = _Exporter._ExtensionNames; _i < _a.length; _i++) {
+            var name_2 = _a[_i];
+            var extension = this._extensions[name_2];
+            if (extension.enabled) {
+                action(extension);
+            }
+        }
+    };
+    _Exporter.prototype._extensionsOnExporting = function () {
+        this._forEachExtensions(function (extension) { return extension.onExporting && extension.onExporting(); });
+    };
     /**
      * Load glTF serializer extensions
      */
     _Exporter.prototype._loadExtensions = function () {
         for (var _i = 0, _a = _Exporter._ExtensionNames; _i < _a.length; _i++) {
-            var name_2 = _a[_i];
-            var extension = _Exporter._ExtensionFactories[name_2](this);
-            this._extensions[name_2] = extension;
+            var name_3 = _a[_i];
+            var extension = _Exporter._ExtensionFactories[name_3](this);
+            this._extensions[name_3] = extension;
         }
     };
     /**
@@ -1515,52 +1701,43 @@ var _Exporter = /** @class */ (function () {
         var imageData;
         var bufferView;
         var byteOffset = this._totalByteLength;
-        var glTF = {
-            asset: this._asset
-        };
-        if (this._extensionsUsed && this._extensionsUsed.length) {
-            glTF.extensionsUsed = this._extensionsUsed;
-        }
-        if (this._extensionsRequired && this._extensionsRequired.length) {
-            glTF.extensionsRequired = this._extensionsRequired;
-        }
         if (buffer.byteLength) {
-            glTF.buffers = [buffer];
+            this._glTF.buffers = [buffer];
         }
         if (this._nodes && this._nodes.length) {
-            glTF.nodes = this._nodes;
+            this._glTF.nodes = this._nodes;
         }
         if (this._meshes && this._meshes.length) {
-            glTF.meshes = this._meshes;
+            this._glTF.meshes = this._meshes;
         }
         if (this._scenes && this._scenes.length) {
-            glTF.scenes = this._scenes;
-            glTF.scene = 0;
+            this._glTF.scenes = this._scenes;
+            this._glTF.scene = 0;
         }
         if (this._bufferViews && this._bufferViews.length) {
-            glTF.bufferViews = this._bufferViews;
+            this._glTF.bufferViews = this._bufferViews;
         }
         if (this._accessors && this._accessors.length) {
-            glTF.accessors = this._accessors;
+            this._glTF.accessors = this._accessors;
         }
         if (this._animations && this._animations.length) {
-            glTF.animations = this._animations;
+            this._glTF.animations = this._animations;
         }
         if (this._materials && this._materials.length) {
-            glTF.materials = this._materials;
+            this._glTF.materials = this._materials;
         }
         if (this._textures && this._textures.length) {
-            glTF.textures = this._textures;
+            this._glTF.textures = this._textures;
         }
         if (this._samplers && this._samplers.length) {
-            glTF.samplers = this._samplers;
+            this._glTF.samplers = this._samplers;
         }
         if (this._images && this._images.length) {
             if (!shouldUseGlb) {
-                glTF.images = this._images;
+                this._glTF.images = this._images;
             }
             else {
-                glTF.images = [];
+                this._glTF.images = [];
                 this._images.forEach(function (image) {
                     if (image.uri) {
                         imageData = _this._imageData[image.uri];
@@ -1572,10 +1749,10 @@ var _Exporter = /** @class */ (function () {
                         image.name = imageName;
                         image.mimeType = imageData.mimeType;
                         image.uri = undefined;
-                        if (!glTF.images) {
-                            glTF.images = [];
+                        if (!_this._glTF.images) {
+                            _this._glTF.images = [];
                         }
-                        glTF.images.push(image);
+                        _this._glTF.images.push(image);
                     }
                 });
                 // Replace uri with bufferview and mime type for glb
@@ -1585,7 +1762,7 @@ var _Exporter = /** @class */ (function () {
         if (!shouldUseGlb) {
             buffer.uri = glTFPrefix + ".bin";
         }
-        var jsonText = prettyPrint ? JSON.stringify(glTF, null, 2) : JSON.stringify(glTF);
+        var jsonText = prettyPrint ? JSON.stringify(this._glTF, null, 2) : JSON.stringify(this._glTF);
         return jsonText;
     };
     /**
@@ -1596,6 +1773,7 @@ var _Exporter = /** @class */ (function () {
     _Exporter.prototype._generateGLTFAsync = function (glTFPrefix) {
         var _this = this;
         return this._generateBinaryAsync().then(function (binaryBuffer) {
+            _this._extensionsOnExporting();
             var jsonText = _this.generateJSON(false, glTFPrefix, true);
             var bin = new Blob([binaryBuffer], { type: 'application/octet-stream' });
             var glTFFileName = glTFPrefix + '.gltf';
@@ -1644,6 +1822,7 @@ var _Exporter = /** @class */ (function () {
     _Exporter.prototype._generateGLBAsync = function (glTFPrefix) {
         var _this = this;
         return this._generateBinaryAsync().then(function (binaryBuffer) {
+            _this._extensionsOnExporting();
             var jsonText = _this.generateJSON(true);
             var glbFileName = glTFPrefix + '.glb';
             var headerLength = 12;
@@ -2039,9 +2218,9 @@ var _Exporter = /** @class */ (function () {
         var glTFNodeIndex;
         var glTFNode;
         var directDescendents;
-        var nodes = babylonScene.transformNodes.concat(babylonScene.meshes);
+        var nodes = babylonScene.transformNodes.concat(babylonScene.meshes, babylonScene.lights);
         return this._glTFMaterialExporter._convertMaterialsToGLTFAsync(babylonScene.materials, "image/png" /* PNG */, true).then(function () {
-            return _this.createNodeMapAndAnimationsAsync(babylonScene, nodes, _this._shouldExportTransformNode, binaryWriter).then(function (nodeMap) {
+            return _this.createNodeMapAndAnimationsAsync(babylonScene, nodes, _this._shouldExportNode, binaryWriter).then(function (nodeMap) {
                 _this._nodeMap = nodeMap;
                 _this._totalByteLength = binaryWriter.getByteOffset();
                 if (_this._totalByteLength == undefined) {
@@ -2049,13 +2228,13 @@ var _Exporter = /** @class */ (function () {
                 }
                 // Build Hierarchy with the node map.
                 for (var _i = 0, nodes_1 = nodes; _i < nodes_1.length; _i++) {
-                    var babylonTransformNode = nodes_1[_i];
-                    glTFNodeIndex = _this._nodeMap[babylonTransformNode.uniqueId];
-                    if (glTFNodeIndex != null) {
+                    var babylonNode = nodes_1[_i];
+                    glTFNodeIndex = _this._nodeMap[babylonNode.uniqueId];
+                    if (glTFNodeIndex !== undefined) {
                         glTFNode = _this._nodes[glTFNodeIndex];
-                        if (!babylonTransformNode.parent) {
-                            if (!_this._shouldExportTransformNode(babylonTransformNode)) {
-                                babylonjs_Maths_math__WEBPACK_IMPORTED_MODULE_0__["Tools"].Log("Omitting " + babylonTransformNode.name + " from scene.");
+                        if (!babylonNode.parent) {
+                            if (!_this._shouldExportNode(babylonNode)) {
+                                babylonjs_Maths_math__WEBPACK_IMPORTED_MODULE_0__["Tools"].Log("Omitting " + babylonNode.name + " from scene.");
                             }
                             else {
                                 if (_this._convertToRightHandedSystem) {
@@ -2068,7 +2247,7 @@ var _Exporter = /** @class */ (function () {
                                 scene.nodes.push(glTFNodeIndex);
                             }
                         }
-                        directDescendents = babylonTransformNode.getDescendants(true);
+                        directDescendents = babylonNode.getDescendants(true);
                         if (!glTFNode.children && directDescendents && directDescendents.length) {
                             var children = [];
                             for (var _a = 0, directDescendents_1 = directDescendents; _a < directDescendents_1.length; _a++) {
@@ -2093,11 +2272,11 @@ var _Exporter = /** @class */ (function () {
      * Creates a mapping of Node unique id to node index and handles animations
      * @param babylonScene Babylon Scene
      * @param nodes Babylon transform nodes
-     * @param shouldExportTransformNode Callback specifying if a transform node should be exported
+     * @param shouldExportNode Callback specifying if a transform node should be exported
      * @param binaryWriter Buffer to write binary data to
      * @returns Node mapping of unique id to index
      */
-    _Exporter.prototype.createNodeMapAndAnimationsAsync = function (babylonScene, nodes, shouldExportTransformNode, binaryWriter) {
+    _Exporter.prototype.createNodeMapAndAnimationsAsync = function (babylonScene, nodes, shouldExportNode, binaryWriter) {
         var _this = this;
         var promiseChain = Promise.resolve();
         var nodeMap = {};
@@ -2108,29 +2287,38 @@ var _Exporter = /** @class */ (function () {
             samplers: []
         };
         var idleGLTFAnimations = [];
-        var _loop_1 = function (babylonTransformNode) {
-            if (shouldExportTransformNode(babylonTransformNode)) {
+        var _loop_1 = function (babylonNode) {
+            if (shouldExportNode(babylonNode)) {
                 promiseChain = promiseChain.then(function () {
-                    return _this.createNodeAsync(babylonTransformNode, binaryWriter).then(function (node) {
-                        var directDescendents = babylonTransformNode.getDescendants(true, function (node) { return (node instanceof babylonjs_Maths_math__WEBPACK_IMPORTED_MODULE_0__["TransformNode"]); });
-                        if (directDescendents.length || node.mesh != null) {
-                            _this._nodes.push(node);
-                            nodeIndex = _this._nodes.length - 1;
-                            nodeMap[babylonTransformNode.uniqueId] = nodeIndex;
+                    return _this.createNodeAsync(babylonNode, binaryWriter).then(function (node) {
+                        var promise = _this._extensionsPostExportNodeAsync("createNodeAsync", node, babylonNode);
+                        if (promise == null) {
+                            babylonjs_Maths_math__WEBPACK_IMPORTED_MODULE_0__["Tools"].Warn("Not exporting node " + babylonNode.name);
+                            return Promise.resolve();
                         }
-                        if (!babylonScene.animationGroups.length && babylonTransformNode.animations.length) {
-                            _glTFAnimation__WEBPACK_IMPORTED_MODULE_4__["_GLTFAnimation"]._CreateNodeAnimationFromTransformNodeAnimations(babylonTransformNode, runtimeGLTFAnimation, idleGLTFAnimations, nodeMap, _this._nodes, binaryWriter, _this._bufferViews, _this._accessors, _this._convertToRightHandedSystem, _this._animationSampleRate);
+                        else {
+                            return promise.then(function (node) {
+                                var directDescendents = babylonNode.getDescendants(true, function (node) { return (node instanceof babylonjs_Maths_math__WEBPACK_IMPORTED_MODULE_0__["Node"]); });
+                                if (directDescendents.length || node.mesh != null || (node.extensions)) {
+                                    _this._nodes.push(node);
+                                    nodeIndex = _this._nodes.length - 1;
+                                    nodeMap[babylonNode.uniqueId] = nodeIndex;
+                                }
+                                if (!babylonScene.animationGroups.length && babylonNode.animations.length) {
+                                    _glTFAnimation__WEBPACK_IMPORTED_MODULE_4__["_GLTFAnimation"]._CreateNodeAnimationFromNodeAnimations(babylonNode, runtimeGLTFAnimation, idleGLTFAnimations, nodeMap, _this._nodes, binaryWriter, _this._bufferViews, _this._accessors, _this._convertToRightHandedSystem, _this._animationSampleRate);
+                                }
+                            });
                         }
                     });
                 });
             }
             else {
-                "Excluding mesh " + babylonTransformNode.name;
+                "Excluding node " + babylonNode.name;
             }
         };
         for (var _i = 0, nodes_2 = nodes; _i < nodes_2.length; _i++) {
-            var babylonTransformNode = nodes_2[_i];
-            _loop_1(babylonTransformNode);
+            var babylonNode = nodes_2[_i];
+            _loop_1(babylonNode);
         }
         return promiseChain.then(function () {
             if (runtimeGLTFAnimation.channels.length && runtimeGLTFAnimation.samplers.length) {
@@ -2153,25 +2341,30 @@ var _Exporter = /** @class */ (function () {
      * @param binaryWriter Buffer for storing geometry data
      * @returns glTF node
      */
-    _Exporter.prototype.createNodeAsync = function (babylonTransformNode, binaryWriter) {
+    _Exporter.prototype.createNodeAsync = function (babylonNode, binaryWriter) {
         var _this = this;
         return Promise.resolve().then(function () {
             // create node to hold translation/rotation/scale and the mesh
             var node = {};
             // create mesh
             var mesh = { primitives: [] };
-            if (babylonTransformNode.name) {
-                node.name = babylonTransformNode.name;
+            if (babylonNode.name) {
+                node.name = babylonNode.name;
+            }
+            if (babylonNode instanceof babylonjs_Maths_math__WEBPACK_IMPORTED_MODULE_0__["TransformNode"]) {
+                // Set transformation
+                _this.setNodeTransformation(node, babylonNode);
+                return _this.setPrimitiveAttributesAsync(mesh, babylonNode, binaryWriter).then(function () {
+                    if (mesh.primitives.length) {
+                        _this._meshes.push(mesh);
+                        node.mesh = _this._meshes.length - 1;
+                    }
+                    return node;
+                });
             }
-            // Set transformation
-            _this.setNodeTransformation(node, babylonTransformNode);
-            return _this.setPrimitiveAttributesAsync(mesh, babylonTransformNode, binaryWriter).then(function () {
-                if (mesh.primitives.length) {
-                    _this._meshes.push(mesh);
-                    node.mesh = _this._meshes.length - 1;
-                }
+            else {
                 return node;
-            });
+            }
         });
     };
     _Exporter._ExtensionNames = new Array();
@@ -3778,7 +3971,7 @@ var _GLTFUtilities = /** @class */ (function () {
 /*!***************************!*\
   !*** ./glTF/2.0/index.ts ***!
   \***************************/
-/*! exports provided: GLTFData, GLTF2Export, _GLTFAnimation, _Exporter, _BinaryWriter, __IGLTFExporterExtensionV2, _GLTFMaterialExporter, _GLTFUtilities, KHR_texture_transform */
+/*! exports provided: GLTFData, GLTF2Export, _GLTFAnimation, _Exporter, _BinaryWriter, __IGLTFExporterExtensionV2, _GLTFMaterialExporter, _GLTFUtilities, KHR_texture_transform, KHR_lights_punctual */
 /***/ (function(module, __webpack_exports__, __webpack_require__) {
 
 "use strict";
@@ -3809,6 +4002,8 @@ __webpack_require__.r(__webpack_exports__);
 /* harmony import */ var _Extensions__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ./Extensions */ "./glTF/2.0/Extensions/index.ts");
 /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "KHR_texture_transform", function() { return _Extensions__WEBPACK_IMPORTED_MODULE_7__["KHR_texture_transform"]; });
 
+/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "KHR_lights_punctual", function() { return _Extensions__WEBPACK_IMPORTED_MODULE_7__["KHR_lights_punctual"]; });
+
 
 
 
@@ -3863,7 +4058,7 @@ var __IGLTFExporterExtension = 0; // I am here to allow dts to be created
 /*!******************************************!*\
   !*** ./legacy/legacy-glTF2Serializer.ts ***!
   \******************************************/
-/*! exports provided: __IGLTFExporterExtension, GLTFData, GLTF2Export, _GLTFAnimation, _Exporter, _BinaryWriter, __IGLTFExporterExtensionV2, _GLTFMaterialExporter, _GLTFUtilities, KHR_texture_transform */
+/*! exports provided: __IGLTFExporterExtension, GLTFData, GLTF2Export, _GLTFAnimation, _Exporter, _BinaryWriter, __IGLTFExporterExtensionV2, _GLTFMaterialExporter, _GLTFUtilities, KHR_texture_transform, KHR_lights_punctual */
 /***/ (function(module, __webpack_exports__, __webpack_require__) {
 
 "use strict";
@@ -3893,6 +4088,8 @@ __webpack_require__.r(__webpack_exports__);
 
 /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "KHR_texture_transform", function() { return _glTF_2_0__WEBPACK_IMPORTED_MODULE_4__["KHR_texture_transform"]; });
 
+/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "KHR_lights_punctual", function() { return _glTF_2_0__WEBPACK_IMPORTED_MODULE_4__["KHR_lights_punctual"]; });
+
 
 
 

File diff suppressed because it is too large
+ 1 - 1
dist/preview release/serializers/babylon.glTF2Serializer.js.map


File diff suppressed because it is too large
+ 1 - 1
dist/preview release/serializers/babylon.glTF2Serializer.min.js


+ 61 - 17
dist/preview release/serializers/babylonjs.serializers.d.ts

@@ -64,8 +64,21 @@ declare module BABYLON.GLTF2.Exporter {
          * @param meshPrimitive glTF mesh primitive
          * @param babylonSubMesh Babylon submesh
          * @param binaryWriter glTF serializer binary writer instance
+         * @returns nullable IMeshPrimitive promise
          */
         postExportMeshPrimitiveAsync?(context: string, meshPrimitive: IMeshPrimitive, babylonSubMesh: SubMesh, binaryWriter: _BinaryWriter): Nullable<Promise<IMeshPrimitive>>;
+        /**
+         * Define this method to modify the default behavior when exporting a node
+         * @param context The context when exporting the node
+         * @param node glTF node
+         * @param babylonNode BabylonJS node
+         * @returns nullable INode promise
+         */
+        postExportNodeAsync?(context: string, node: INode, babylonNode: Node): Nullable<Promise<INode>>;
+        /**
+         * Called after the exporter state changes to EXPORTING
+         */
+        onExporting?(): void;
     }
 }
 declare module BABYLON.GLTF2.Exporter {
@@ -316,11 +329,11 @@ declare module BABYLON {
      */
     export interface IExportOptions {
         /**
-         * Function which indicates whether a babylon mesh should be exported or not
-         * @param transformNode source Babylon transform node. It is used to check whether it should be exported to glTF or not
-         * @returns boolean, which indicates whether the mesh should be exported (true) or not (false)
+         * Function which indicates whether a babylon node should be exported or not
+         * @param node source Babylon node. It is used to check whether it should be exported to glTF or not
+         * @returns boolean, which indicates whether the node should be exported (true) or not (false)
          */
-        shouldExportTransformNode?(transformNode: TransformNode): boolean;
+        shouldExportNode?(node: Node): boolean;
         /**
          * The sample rate to bake animation curves
          */
@@ -456,6 +469,10 @@ declare module BABYLON.GLTF2.Exporter {
      */
     export class _Exporter {
         /**
+         * Stores the glTF to export
+         */
+        _glTF: IGLTF;
+        /**
          * Stores all generated buffer views, which represents views into the main glTF buffer data
          */
         _bufferViews: IBufferView[];
@@ -468,10 +485,6 @@ declare module BABYLON.GLTF2.Exporter {
          */
         private _nodes;
         /**
-         * Stores the glTF asset information, which represents the glTF version and this file generator
-         */
-        private _asset;
-        /**
          * Stores all the generated glTF scenes, which stores multiple node hierarchies
          */
         private _scenes;
@@ -512,7 +525,7 @@ declare module BABYLON.GLTF2.Exporter {
         /**
          * Stores a reference to the Babylon scene containing the source geometry and material information
          */
-        private _babylonScene;
+        _babylonScene: Scene;
         /**
          * Stores a map of the image data, where the key is the file name and the value
          * is the image data
@@ -530,25 +543,26 @@ declare module BABYLON.GLTF2.Exporter {
         /**
          * Specifies if the Babylon scene should be converted to right-handed on export
          */
-        private _convertToRightHandedSystem;
+        _convertToRightHandedSystem: boolean;
         /**
          * Baked animation sample rate
          */
         private _animationSampleRate;
         /**
-         * Callback which specifies if a transform node should be exported or not
+         * Callback which specifies if a node should be exported or not
          */
-        private _shouldExportTransformNode;
+        private _shouldExportNode;
         private _localEngine;
         _glTFMaterialExporter: _GLTFMaterialExporter;
         private _extensions;
-        private _extensionsUsed;
-        private _extensionsRequired;
         private static _ExtensionNames;
         private static _ExtensionFactories;
         private _applyExtensions;
         _extensionsPreExportTextureAsync(context: string, babylonTexture: Texture, mimeType: ImageMimeType): Nullable<Promise<BaseTexture>>;
         _extensionsPostExportMeshPrimitiveAsync(context: string, meshPrimitive: IMeshPrimitive, babylonSubMesh: SubMesh, binaryWriter: _BinaryWriter): Nullable<Promise<IMeshPrimitive>>;
+        _extensionsPostExportNodeAsync(context: string, node: INode, babylonNode: Node): Nullable<Promise<INode>>;
+        private _forEachExtensions;
+        private _extensionsOnExporting;
         /**
          * Load glTF serializer extensions
          */
@@ -724,7 +738,7 @@ declare module BABYLON.GLTF2.Exporter {
          * Creates a mapping of Node unique id to node index and handles animations
          * @param babylonScene Babylon Scene
          * @param nodes Babylon transform nodes
-         * @param shouldExportTransformNode Callback specifying if a transform node should be exported
+         * @param shouldExportNode Callback specifying if a transform node should be exported
          * @param binaryWriter Buffer to write binary data to
          * @returns Node mapping of unique id to index
          */
@@ -869,7 +883,7 @@ declare module BABYLON.GLTF2.Exporter {
         /**
          * @ignore
          * Create node animations from the transform node animations
-         * @param babylonTransformNode
+         * @param babylonNode
          * @param runtimeGLTFAnimation
          * @param idleGLTFAnimations
          * @param nodeMap
@@ -879,7 +893,7 @@ declare module BABYLON.GLTF2.Exporter {
          * @param accessors
          * @param convertToRightHandedSystem
          */
-        static _CreateNodeAnimationFromTransformNodeAnimations(babylonTransformNode: TransformNode, runtimeGLTFAnimation: IAnimation, idleGLTFAnimations: IAnimation[], nodeMap: {
+        static _CreateNodeAnimationFromNodeAnimations(babylonNode: Node, runtimeGLTFAnimation: IAnimation, idleGLTFAnimations: IAnimation[], nodeMap: {
             [key: number]: number;
         }, nodes: INode[], binaryWriter: _BinaryWriter, bufferViews: IBufferView[], accessors: IAccessor[], convertToRightHandedSystem: boolean, animationSampleRate: number): void;
         /**
@@ -1011,4 +1025,34 @@ declare module BABYLON.GLTF2.Exporter.Extensions {
          */
         textureTransformTextureAsync(babylonTexture: Texture, offset: Vector2, rotation: number, scale: Vector2, scene: Scene): Promise<BaseTexture>;
     }
+}
+declare module BABYLON.GLTF2.Exporter.Extensions {
+    /**
+     * [Specification](https://github.com/KhronosGroup/glTF/blob/master/extensions/2.0/Khronos/KHR_lights_punctual/README.md)
+     */
+    export class KHR_lights_punctual implements IGLTFExporterExtensionV2 {
+        /** The name of this extension. */
+        readonly name: string;
+        /** Defines whether this extension is enabled. */
+        enabled: boolean;
+        /** Defines whether this extension is required */
+        required: boolean;
+        /** Reference to the glTF exporter */
+        private _exporter;
+        private _lights;
+        /** @hidden */
+        constructor(exporter: _Exporter);
+        /** @hidden */
+        dispose(): void;
+        /** @hidden */
+        onExporting(): void;
+        /**
+         * Define this method to modify the default behavior when exporting a node
+         * @param context The context when exporting the node
+         * @param node glTF node
+         * @param babylonNode BabylonJS node
+         * @returns nullable INode promise
+         */
+        postExportNodeAsync(context: string, node: INode, babylonNode: Node): Nullable<Promise<INode>>;
+    }
 }

+ 293 - 90
dist/preview release/serializers/babylonjs.serializers.js

@@ -305,6 +305,169 @@ var OBJExport = /** @class */ (function () {
 
 /***/ }),
 
+/***/ "./glTF/2.0/Extensions/KHR_lights_punctual.ts":
+/*!****************************************************!*\
+  !*** ./glTF/2.0/Extensions/KHR_lights_punctual.ts ***!
+  \****************************************************/
+/*! exports provided: KHR_lights_punctual */
+/***/ (function(module, __webpack_exports__, __webpack_require__) {
+
+"use strict";
+__webpack_require__.r(__webpack_exports__);
+/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "KHR_lights_punctual", function() { return KHR_lights_punctual; });
+/* 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___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Maths_math__WEBPACK_IMPORTED_MODULE_0__);
+/* harmony import */ var _glTFExporter__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ../glTFExporter */ "./glTF/2.0/glTFExporter.ts");
+/* harmony import */ var _glTFUtilities__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../glTFUtilities */ "./glTF/2.0/glTFUtilities.ts");
+
+
+
+
+
+
+var NAME = "KHR_lights_punctual";
+var LightType;
+(function (LightType) {
+    LightType["DIRECTIONAL"] = "directional";
+    LightType["POINT"] = "point";
+    LightType["SPOT"] = "spot";
+})(LightType || (LightType = {}));
+/**
+ * [Specification](https://github.com/KhronosGroup/glTF/blob/master/extensions/2.0/Khronos/KHR_lights_punctual/README.md)
+ */
+var KHR_lights_punctual = /** @class */ (function () {
+    /** @hidden */
+    function KHR_lights_punctual(exporter) {
+        /** The name of this extension. */
+        this.name = NAME;
+        /** Defines whether this extension is enabled. */
+        this.enabled = true;
+        /** Defines whether this extension is required */
+        this.required = false;
+        this._exporter = exporter;
+    }
+    /** @hidden */
+    KHR_lights_punctual.prototype.dispose = function () {
+        delete this._exporter;
+        delete this._lights;
+    };
+    /** @hidden */
+    KHR_lights_punctual.prototype.onExporting = function () {
+        if (this._lights) {
+            if (this._exporter._glTF.extensionsUsed == null) {
+                this._exporter._glTF.extensionsUsed = [];
+            }
+            if (this._exporter._glTF.extensionsUsed.indexOf(NAME) === -1) {
+                this._exporter._glTF.extensionsUsed.push(NAME);
+            }
+            if (this.required) {
+                if (this._exporter._glTF.extensionsRequired == null) {
+                    this._exporter._glTF.extensionsRequired = [];
+                }
+                if (this._exporter._glTF.extensionsRequired.indexOf(NAME) === -1) {
+                    this._exporter._glTF.extensionsRequired.push(NAME);
+                }
+            }
+            if (this._exporter._glTF.extensions == null) {
+                this._exporter._glTF.extensions = {};
+            }
+            this._exporter._glTF.extensions[NAME] = this._lights;
+        }
+    };
+    /**
+     * Define this method to modify the default behavior when exporting a node
+     * @param context The context when exporting the node
+     * @param node glTF node
+     * @param babylonNode BabylonJS node
+     * @returns nullable INode promise
+     */
+    KHR_lights_punctual.prototype.postExportNodeAsync = function (context, node, babylonNode) {
+        var _this = this;
+        return new Promise(function (resolve, reject) {
+            if (babylonNode instanceof babylonjs_Maths_math__WEBPACK_IMPORTED_MODULE_0__["ShadowLight"]) {
+                var babylonLight = babylonNode;
+                var light = void 0;
+                var lightType = (babylonLight.getTypeID() == babylonjs_Maths_math__WEBPACK_IMPORTED_MODULE_0__["Light"].LIGHTTYPEID_POINTLIGHT ? LightType.POINT : (babylonLight.getTypeID() == babylonjs_Maths_math__WEBPACK_IMPORTED_MODULE_0__["Light"].LIGHTTYPEID_DIRECTIONALLIGHT ? LightType.DIRECTIONAL : (babylonLight.getTypeID() == babylonjs_Maths_math__WEBPACK_IMPORTED_MODULE_0__["Light"].LIGHTTYPEID_SPOTLIGHT ? LightType.SPOT : null)));
+                if (lightType == null) {
+                    babylonjs_Maths_math__WEBPACK_IMPORTED_MODULE_0__["Logger"].Warn(context + ": Light " + babylonLight.name + " is not supported in " + NAME);
+                }
+                else {
+                    var lightPosition = babylonLight.position.clone();
+                    if (!lightPosition.equals(babylonjs_Maths_math__WEBPACK_IMPORTED_MODULE_0__["Vector3"].Zero())) {
+                        if (_this._exporter._convertToRightHandedSystem) {
+                            _glTFUtilities__WEBPACK_IMPORTED_MODULE_2__["_GLTFUtilities"]._GetRightHandedPositionVector3FromRef(lightPosition);
+                        }
+                        node.translation = lightPosition.asArray();
+                    }
+                    if (lightType !== LightType.POINT) {
+                        var localAxis = babylonLight.direction;
+                        var yaw = -Math.atan2(localAxis.z, localAxis.x) + Math.PI / 2;
+                        var len = Math.sqrt(localAxis.x * localAxis.x + localAxis.z * localAxis.z);
+                        var pitch = -Math.atan2(localAxis.y, len);
+                        var lightRotationQuaternion = babylonjs_Maths_math__WEBPACK_IMPORTED_MODULE_0__["Quaternion"].RotationYawPitchRoll(yaw, pitch, 0);
+                        if (_this._exporter._convertToRightHandedSystem) {
+                            _glTFUtilities__WEBPACK_IMPORTED_MODULE_2__["_GLTFUtilities"]._GetRightHandedQuaternionFromRef(lightRotationQuaternion);
+                        }
+                        if (!lightRotationQuaternion.equals(babylonjs_Maths_math__WEBPACK_IMPORTED_MODULE_0__["Quaternion"].Identity())) {
+                            node.rotation = lightRotationQuaternion.asArray();
+                        }
+                    }
+                    if (babylonLight.falloffType !== babylonjs_Maths_math__WEBPACK_IMPORTED_MODULE_0__["Light"].FALLOFF_GLTF) {
+                        babylonjs_Maths_math__WEBPACK_IMPORTED_MODULE_0__["Logger"].Warn(context + ": Light falloff for " + babylonLight.name + " does not match the " + NAME + " specification!");
+                    }
+                    light = {
+                        type: lightType
+                    };
+                    if (!babylonLight.diffuse.equals(babylonjs_Maths_math__WEBPACK_IMPORTED_MODULE_0__["Color3"].White())) {
+                        light.color = babylonLight.diffuse.asArray();
+                    }
+                    if (babylonLight.intensity !== 1.0) {
+                        light.intensity = babylonLight.intensity;
+                    }
+                    if (babylonLight.range !== Number.MAX_VALUE) {
+                        light.range = babylonLight.range;
+                    }
+                    if (lightType === LightType.SPOT) {
+                        var babylonSpotLight = babylonLight;
+                        if (babylonSpotLight.angle !== Math.PI / 2.0) {
+                            if (light.spot == null) {
+                                light.spot = {};
+                            }
+                            light.spot.outerConeAngle = babylonSpotLight.angle / 2.0;
+                        }
+                        if (babylonSpotLight.innerAngle !== 0) {
+                            if (light.spot == null) {
+                                light.spot = {};
+                            }
+                            light.spot.innerConeAngle = babylonSpotLight.innerAngle / 2.0;
+                        }
+                    }
+                    if (_this._lights == null) {
+                        _this._lights = {
+                            lights: []
+                        };
+                    }
+                    _this._lights.lights.push(light);
+                    if (node.extensions == null) {
+                        node.extensions = {};
+                    }
+                    var lightReference = {
+                        light: _this._lights.lights.length - 1
+                    };
+                    node.extensions[NAME] = lightReference;
+                }
+            }
+            resolve(node);
+        });
+    };
+    return KHR_lights_punctual;
+}());
+
+_glTFExporter__WEBPACK_IMPORTED_MODULE_1__["_Exporter"].RegisterExtension(NAME, function (exporter) { return new KHR_lights_punctual(exporter); });
+
+
+/***/ }),
+
 /***/ "./glTF/2.0/Extensions/KHR_texture_transform.ts":
 /*!******************************************************!*\
   !*** ./glTF/2.0/Extensions/KHR_texture_transform.ts ***!
@@ -413,7 +576,7 @@ _glTFExporter__WEBPACK_IMPORTED_MODULE_1__["_Exporter"].RegisterExtension(NAME,
 /*!**************************************!*\
   !*** ./glTF/2.0/Extensions/index.ts ***!
   \**************************************/
-/*! exports provided: KHR_texture_transform */
+/*! exports provided: KHR_texture_transform, KHR_lights_punctual */
 /***/ (function(module, __webpack_exports__, __webpack_require__) {
 
 "use strict";
@@ -421,6 +584,10 @@ __webpack_require__.r(__webpack_exports__);
 /* harmony import */ var _KHR_texture_transform__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./KHR_texture_transform */ "./glTF/2.0/Extensions/KHR_texture_transform.ts");
 /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "KHR_texture_transform", function() { return _KHR_texture_transform__WEBPACK_IMPORTED_MODULE_0__["KHR_texture_transform"]; });
 
+/* harmony import */ var _KHR_lights_punctual__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./KHR_lights_punctual */ "./glTF/2.0/Extensions/KHR_lights_punctual.ts");
+/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "KHR_lights_punctual", function() { return _KHR_lights_punctual__WEBPACK_IMPORTED_MODULE_1__["KHR_lights_punctual"]; });
+
+
 
 
 
@@ -445,6 +612,7 @@ __webpack_require__.r(__webpack_exports__);
 
 
 
+
 /**
  * @hidden
  * Enum for handling in tangent and out tangent.
@@ -553,7 +721,7 @@ var _GLTFAnimation = /** @class */ (function () {
     /**
      * @ignore
      * Create node animations from the transform node animations
-     * @param babylonTransformNode
+     * @param babylonNode
      * @param runtimeGLTFAnimation
      * @param idleGLTFAnimations
      * @param nodeMap
@@ -563,21 +731,23 @@ var _GLTFAnimation = /** @class */ (function () {
      * @param accessors
      * @param convertToRightHandedSystem
      */
-    _GLTFAnimation._CreateNodeAnimationFromTransformNodeAnimations = function (babylonTransformNode, runtimeGLTFAnimation, idleGLTFAnimations, nodeMap, nodes, binaryWriter, bufferViews, accessors, convertToRightHandedSystem, animationSampleRate) {
+    _GLTFAnimation._CreateNodeAnimationFromNodeAnimations = function (babylonNode, runtimeGLTFAnimation, idleGLTFAnimations, nodeMap, nodes, binaryWriter, bufferViews, accessors, convertToRightHandedSystem, animationSampleRate) {
         var glTFAnimation;
-        if (babylonTransformNode.animations) {
-            for (var _i = 0, _a = babylonTransformNode.animations; _i < _a.length; _i++) {
-                var animation = _a[_i];
-                var animationInfo = _GLTFAnimation._DeduceAnimationInfo(animation);
-                if (animationInfo) {
-                    glTFAnimation = {
-                        name: animation.name,
-                        samplers: [],
-                        channels: []
-                    };
-                    _GLTFAnimation.AddAnimation("" + animation.name, animation.hasRunningRuntimeAnimations ? runtimeGLTFAnimation : glTFAnimation, babylonTransformNode, animation, animationInfo.dataAccessorType, animationInfo.animationChannelTargetPath, nodeMap, binaryWriter, bufferViews, accessors, convertToRightHandedSystem, animationInfo.useQuaternion, animationSampleRate);
-                    if (glTFAnimation.samplers.length && glTFAnimation.channels.length) {
-                        idleGLTFAnimations.push(glTFAnimation);
+        if (babylonNode instanceof babylonjs_Maths_math__WEBPACK_IMPORTED_MODULE_0__["TransformNode"]) {
+            if (babylonNode.animations) {
+                for (var _i = 0, _a = babylonNode.animations; _i < _a.length; _i++) {
+                    var animation = _a[_i];
+                    var animationInfo = _GLTFAnimation._DeduceAnimationInfo(animation);
+                    if (animationInfo) {
+                        glTFAnimation = {
+                            name: animation.name,
+                            samplers: [],
+                            channels: []
+                        };
+                        _GLTFAnimation.AddAnimation("" + animation.name, animation.hasRunningRuntimeAnimations ? runtimeGLTFAnimation : glTFAnimation, babylonNode, animation, animationInfo.dataAccessorType, animationInfo.animationChannelTargetPath, nodeMap, binaryWriter, bufferViews, accessors, convertToRightHandedSystem, animationInfo.useQuaternion, animationSampleRate);
+                        if (glTFAnimation.samplers.length && glTFAnimation.channels.length) {
+                            idleGLTFAnimations.push(glTFAnimation);
+                        }
                     }
                 }
             }
@@ -1188,6 +1358,7 @@ __webpack_require__.r(__webpack_exports__);
 
 
 
+
 /**
  * Converts Babylon Scene into glTF 2.0.
  * @hidden
@@ -1200,9 +1371,9 @@ var _Exporter = /** @class */ (function () {
      */
     function _Exporter(babylonScene, options) {
         this._extensions = {};
-        this._asset = { generator: "BabylonJS", version: "2.0" };
-        this._extensionsUsed = [];
-        this._extensionsRequired = [];
+        this._glTF = {
+            asset: { generator: "BabylonJS", version: "2.0" }
+        };
         this._babylonScene = babylonScene;
         this._bufferViews = [];
         this._accessors = [];
@@ -1218,7 +1389,7 @@ var _Exporter = /** @class */ (function () {
         this._imageData = {};
         this._convertToRightHandedSystem = this._babylonScene.useRightHandedSystem ? false : true;
         var _options = options || {};
-        this._shouldExportTransformNode = _options.shouldExportTransformNode ? _options.shouldExportTransformNode : function (babylonTransformNode) { return true; };
+        this._shouldExportNode = _options.shouldExportNode ? _options.shouldExportNode : function (babylonNode) { return true; };
         this._animationSampleRate = _options.animationSampleRate ? _options.animationSampleRate : 1 / 60;
         this._glTFMaterialExporter = new _glTFMaterialExporter__WEBPACK_IMPORTED_MODULE_1__["_GLTFMaterialExporter"](this);
         this._loadExtensions();
@@ -1254,14 +1425,29 @@ var _Exporter = /** @class */ (function () {
     _Exporter.prototype._extensionsPostExportMeshPrimitiveAsync = function (context, meshPrimitive, babylonSubMesh, binaryWriter) {
         return this._applyExtensions(meshPrimitive, function (extension) { return extension.postExportMeshPrimitiveAsync && extension.postExportMeshPrimitiveAsync(context, meshPrimitive, babylonSubMesh, binaryWriter); });
     };
+    _Exporter.prototype._extensionsPostExportNodeAsync = function (context, node, babylonNode) {
+        return this._applyExtensions(node, function (extension) { return extension.postExportNodeAsync && extension.postExportNodeAsync(context, node, babylonNode); });
+    };
+    _Exporter.prototype._forEachExtensions = function (action) {
+        for (var _i = 0, _a = _Exporter._ExtensionNames; _i < _a.length; _i++) {
+            var name_2 = _a[_i];
+            var extension = this._extensions[name_2];
+            if (extension.enabled) {
+                action(extension);
+            }
+        }
+    };
+    _Exporter.prototype._extensionsOnExporting = function () {
+        this._forEachExtensions(function (extension) { return extension.onExporting && extension.onExporting(); });
+    };
     /**
      * Load glTF serializer extensions
      */
     _Exporter.prototype._loadExtensions = function () {
         for (var _i = 0, _a = _Exporter._ExtensionNames; _i < _a.length; _i++) {
-            var name_2 = _a[_i];
-            var extension = _Exporter._ExtensionFactories[name_2](this);
-            this._extensions[name_2] = extension;
+            var name_3 = _a[_i];
+            var extension = _Exporter._ExtensionFactories[name_3](this);
+            this._extensions[name_3] = extension;
         }
     };
     /**
@@ -1693,52 +1879,43 @@ var _Exporter = /** @class */ (function () {
         var imageData;
         var bufferView;
         var byteOffset = this._totalByteLength;
-        var glTF = {
-            asset: this._asset
-        };
-        if (this._extensionsUsed && this._extensionsUsed.length) {
-            glTF.extensionsUsed = this._extensionsUsed;
-        }
-        if (this._extensionsRequired && this._extensionsRequired.length) {
-            glTF.extensionsRequired = this._extensionsRequired;
-        }
         if (buffer.byteLength) {
-            glTF.buffers = [buffer];
+            this._glTF.buffers = [buffer];
         }
         if (this._nodes && this._nodes.length) {
-            glTF.nodes = this._nodes;
+            this._glTF.nodes = this._nodes;
         }
         if (this._meshes && this._meshes.length) {
-            glTF.meshes = this._meshes;
+            this._glTF.meshes = this._meshes;
         }
         if (this._scenes && this._scenes.length) {
-            glTF.scenes = this._scenes;
-            glTF.scene = 0;
+            this._glTF.scenes = this._scenes;
+            this._glTF.scene = 0;
         }
         if (this._bufferViews && this._bufferViews.length) {
-            glTF.bufferViews = this._bufferViews;
+            this._glTF.bufferViews = this._bufferViews;
         }
         if (this._accessors && this._accessors.length) {
-            glTF.accessors = this._accessors;
+            this._glTF.accessors = this._accessors;
         }
         if (this._animations && this._animations.length) {
-            glTF.animations = this._animations;
+            this._glTF.animations = this._animations;
         }
         if (this._materials && this._materials.length) {
-            glTF.materials = this._materials;
+            this._glTF.materials = this._materials;
         }
         if (this._textures && this._textures.length) {
-            glTF.textures = this._textures;
+            this._glTF.textures = this._textures;
         }
         if (this._samplers && this._samplers.length) {
-            glTF.samplers = this._samplers;
+            this._glTF.samplers = this._samplers;
         }
         if (this._images && this._images.length) {
             if (!shouldUseGlb) {
-                glTF.images = this._images;
+                this._glTF.images = this._images;
             }
             else {
-                glTF.images = [];
+                this._glTF.images = [];
                 this._images.forEach(function (image) {
                     if (image.uri) {
                         imageData = _this._imageData[image.uri];
@@ -1750,10 +1927,10 @@ var _Exporter = /** @class */ (function () {
                         image.name = imageName;
                         image.mimeType = imageData.mimeType;
                         image.uri = undefined;
-                        if (!glTF.images) {
-                            glTF.images = [];
+                        if (!_this._glTF.images) {
+                            _this._glTF.images = [];
                         }
-                        glTF.images.push(image);
+                        _this._glTF.images.push(image);
                     }
                 });
                 // Replace uri with bufferview and mime type for glb
@@ -1763,7 +1940,7 @@ var _Exporter = /** @class */ (function () {
         if (!shouldUseGlb) {
             buffer.uri = glTFPrefix + ".bin";
         }
-        var jsonText = prettyPrint ? JSON.stringify(glTF, null, 2) : JSON.stringify(glTF);
+        var jsonText = prettyPrint ? JSON.stringify(this._glTF, null, 2) : JSON.stringify(this._glTF);
         return jsonText;
     };
     /**
@@ -1774,6 +1951,7 @@ var _Exporter = /** @class */ (function () {
     _Exporter.prototype._generateGLTFAsync = function (glTFPrefix) {
         var _this = this;
         return this._generateBinaryAsync().then(function (binaryBuffer) {
+            _this._extensionsOnExporting();
             var jsonText = _this.generateJSON(false, glTFPrefix, true);
             var bin = new Blob([binaryBuffer], { type: 'application/octet-stream' });
             var glTFFileName = glTFPrefix + '.gltf';
@@ -1822,6 +2000,7 @@ var _Exporter = /** @class */ (function () {
     _Exporter.prototype._generateGLBAsync = function (glTFPrefix) {
         var _this = this;
         return this._generateBinaryAsync().then(function (binaryBuffer) {
+            _this._extensionsOnExporting();
             var jsonText = _this.generateJSON(true);
             var glbFileName = glTFPrefix + '.glb';
             var headerLength = 12;
@@ -2217,9 +2396,9 @@ var _Exporter = /** @class */ (function () {
         var glTFNodeIndex;
         var glTFNode;
         var directDescendents;
-        var nodes = babylonScene.transformNodes.concat(babylonScene.meshes);
+        var nodes = babylonScene.transformNodes.concat(babylonScene.meshes, babylonScene.lights);
         return this._glTFMaterialExporter._convertMaterialsToGLTFAsync(babylonScene.materials, "image/png" /* PNG */, true).then(function () {
-            return _this.createNodeMapAndAnimationsAsync(babylonScene, nodes, _this._shouldExportTransformNode, binaryWriter).then(function (nodeMap) {
+            return _this.createNodeMapAndAnimationsAsync(babylonScene, nodes, _this._shouldExportNode, binaryWriter).then(function (nodeMap) {
                 _this._nodeMap = nodeMap;
                 _this._totalByteLength = binaryWriter.getByteOffset();
                 if (_this._totalByteLength == undefined) {
@@ -2227,13 +2406,13 @@ var _Exporter = /** @class */ (function () {
                 }
                 // Build Hierarchy with the node map.
                 for (var _i = 0, nodes_1 = nodes; _i < nodes_1.length; _i++) {
-                    var babylonTransformNode = nodes_1[_i];
-                    glTFNodeIndex = _this._nodeMap[babylonTransformNode.uniqueId];
-                    if (glTFNodeIndex != null) {
+                    var babylonNode = nodes_1[_i];
+                    glTFNodeIndex = _this._nodeMap[babylonNode.uniqueId];
+                    if (glTFNodeIndex !== undefined) {
                         glTFNode = _this._nodes[glTFNodeIndex];
-                        if (!babylonTransformNode.parent) {
-                            if (!_this._shouldExportTransformNode(babylonTransformNode)) {
-                                babylonjs_Maths_math__WEBPACK_IMPORTED_MODULE_0__["Tools"].Log("Omitting " + babylonTransformNode.name + " from scene.");
+                        if (!babylonNode.parent) {
+                            if (!_this._shouldExportNode(babylonNode)) {
+                                babylonjs_Maths_math__WEBPACK_IMPORTED_MODULE_0__["Tools"].Log("Omitting " + babylonNode.name + " from scene.");
                             }
                             else {
                                 if (_this._convertToRightHandedSystem) {
@@ -2246,7 +2425,7 @@ var _Exporter = /** @class */ (function () {
                                 scene.nodes.push(glTFNodeIndex);
                             }
                         }
-                        directDescendents = babylonTransformNode.getDescendants(true);
+                        directDescendents = babylonNode.getDescendants(true);
                         if (!glTFNode.children && directDescendents && directDescendents.length) {
                             var children = [];
                             for (var _a = 0, directDescendents_1 = directDescendents; _a < directDescendents_1.length; _a++) {
@@ -2271,11 +2450,11 @@ var _Exporter = /** @class */ (function () {
      * Creates a mapping of Node unique id to node index and handles animations
      * @param babylonScene Babylon Scene
      * @param nodes Babylon transform nodes
-     * @param shouldExportTransformNode Callback specifying if a transform node should be exported
+     * @param shouldExportNode Callback specifying if a transform node should be exported
      * @param binaryWriter Buffer to write binary data to
      * @returns Node mapping of unique id to index
      */
-    _Exporter.prototype.createNodeMapAndAnimationsAsync = function (babylonScene, nodes, shouldExportTransformNode, binaryWriter) {
+    _Exporter.prototype.createNodeMapAndAnimationsAsync = function (babylonScene, nodes, shouldExportNode, binaryWriter) {
         var _this = this;
         var promiseChain = Promise.resolve();
         var nodeMap = {};
@@ -2286,29 +2465,38 @@ var _Exporter = /** @class */ (function () {
             samplers: []
         };
         var idleGLTFAnimations = [];
-        var _loop_1 = function (babylonTransformNode) {
-            if (shouldExportTransformNode(babylonTransformNode)) {
+        var _loop_1 = function (babylonNode) {
+            if (shouldExportNode(babylonNode)) {
                 promiseChain = promiseChain.then(function () {
-                    return _this.createNodeAsync(babylonTransformNode, binaryWriter).then(function (node) {
-                        var directDescendents = babylonTransformNode.getDescendants(true, function (node) { return (node instanceof babylonjs_Maths_math__WEBPACK_IMPORTED_MODULE_0__["TransformNode"]); });
-                        if (directDescendents.length || node.mesh != null) {
-                            _this._nodes.push(node);
-                            nodeIndex = _this._nodes.length - 1;
-                            nodeMap[babylonTransformNode.uniqueId] = nodeIndex;
+                    return _this.createNodeAsync(babylonNode, binaryWriter).then(function (node) {
+                        var promise = _this._extensionsPostExportNodeAsync("createNodeAsync", node, babylonNode);
+                        if (promise == null) {
+                            babylonjs_Maths_math__WEBPACK_IMPORTED_MODULE_0__["Tools"].Warn("Not exporting node " + babylonNode.name);
+                            return Promise.resolve();
                         }
-                        if (!babylonScene.animationGroups.length && babylonTransformNode.animations.length) {
-                            _glTFAnimation__WEBPACK_IMPORTED_MODULE_4__["_GLTFAnimation"]._CreateNodeAnimationFromTransformNodeAnimations(babylonTransformNode, runtimeGLTFAnimation, idleGLTFAnimations, nodeMap, _this._nodes, binaryWriter, _this._bufferViews, _this._accessors, _this._convertToRightHandedSystem, _this._animationSampleRate);
+                        else {
+                            return promise.then(function (node) {
+                                var directDescendents = babylonNode.getDescendants(true, function (node) { return (node instanceof babylonjs_Maths_math__WEBPACK_IMPORTED_MODULE_0__["Node"]); });
+                                if (directDescendents.length || node.mesh != null || (node.extensions)) {
+                                    _this._nodes.push(node);
+                                    nodeIndex = _this._nodes.length - 1;
+                                    nodeMap[babylonNode.uniqueId] = nodeIndex;
+                                }
+                                if (!babylonScene.animationGroups.length && babylonNode.animations.length) {
+                                    _glTFAnimation__WEBPACK_IMPORTED_MODULE_4__["_GLTFAnimation"]._CreateNodeAnimationFromNodeAnimations(babylonNode, runtimeGLTFAnimation, idleGLTFAnimations, nodeMap, _this._nodes, binaryWriter, _this._bufferViews, _this._accessors, _this._convertToRightHandedSystem, _this._animationSampleRate);
+                                }
+                            });
                         }
                     });
                 });
             }
             else {
-                "Excluding mesh " + babylonTransformNode.name;
+                "Excluding node " + babylonNode.name;
             }
         };
         for (var _i = 0, nodes_2 = nodes; _i < nodes_2.length; _i++) {
-            var babylonTransformNode = nodes_2[_i];
-            _loop_1(babylonTransformNode);
+            var babylonNode = nodes_2[_i];
+            _loop_1(babylonNode);
         }
         return promiseChain.then(function () {
             if (runtimeGLTFAnimation.channels.length && runtimeGLTFAnimation.samplers.length) {
@@ -2331,25 +2519,30 @@ var _Exporter = /** @class */ (function () {
      * @param binaryWriter Buffer for storing geometry data
      * @returns glTF node
      */
-    _Exporter.prototype.createNodeAsync = function (babylonTransformNode, binaryWriter) {
+    _Exporter.prototype.createNodeAsync = function (babylonNode, binaryWriter) {
         var _this = this;
         return Promise.resolve().then(function () {
             // create node to hold translation/rotation/scale and the mesh
             var node = {};
             // create mesh
             var mesh = { primitives: [] };
-            if (babylonTransformNode.name) {
-                node.name = babylonTransformNode.name;
-            }
-            // Set transformation
-            _this.setNodeTransformation(node, babylonTransformNode);
-            return _this.setPrimitiveAttributesAsync(mesh, babylonTransformNode, binaryWriter).then(function () {
-                if (mesh.primitives.length) {
-                    _this._meshes.push(mesh);
-                    node.mesh = _this._meshes.length - 1;
-                }
+            if (babylonNode.name) {
+                node.name = babylonNode.name;
+            }
+            if (babylonNode instanceof babylonjs_Maths_math__WEBPACK_IMPORTED_MODULE_0__["TransformNode"]) {
+                // Set transformation
+                _this.setNodeTransformation(node, babylonNode);
+                return _this.setPrimitiveAttributesAsync(mesh, babylonNode, binaryWriter).then(function () {
+                    if (mesh.primitives.length) {
+                        _this._meshes.push(mesh);
+                        node.mesh = _this._meshes.length - 1;
+                    }
+                    return node;
+                });
+            }
+            else {
                 return node;
-            });
+            }
         });
     };
     _Exporter._ExtensionNames = new Array();
@@ -3956,7 +4149,7 @@ var _GLTFUtilities = /** @class */ (function () {
 /*!***************************!*\
   !*** ./glTF/2.0/index.ts ***!
   \***************************/
-/*! exports provided: GLTFData, GLTF2Export, _GLTFAnimation, _Exporter, _BinaryWriter, __IGLTFExporterExtensionV2, _GLTFMaterialExporter, _GLTFUtilities, KHR_texture_transform */
+/*! exports provided: GLTFData, GLTF2Export, _GLTFAnimation, _Exporter, _BinaryWriter, __IGLTFExporterExtensionV2, _GLTFMaterialExporter, _GLTFUtilities, KHR_texture_transform, KHR_lights_punctual */
 /***/ (function(module, __webpack_exports__, __webpack_require__) {
 
 "use strict";
@@ -3987,6 +4180,8 @@ __webpack_require__.r(__webpack_exports__);
 /* harmony import */ var _Extensions__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ./Extensions */ "./glTF/2.0/Extensions/index.ts");
 /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "KHR_texture_transform", function() { return _Extensions__WEBPACK_IMPORTED_MODULE_7__["KHR_texture_transform"]; });
 
+/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "KHR_lights_punctual", function() { return _Extensions__WEBPACK_IMPORTED_MODULE_7__["KHR_lights_punctual"]; });
+
 
 
 
@@ -4041,7 +4236,7 @@ var __IGLTFExporterExtension = 0; // I am here to allow dts to be created
 /*!***********************!*\
   !*** ./glTF/index.ts ***!
   \***********************/
-/*! exports provided: __IGLTFExporterExtension, GLTFData, GLTF2Export, _GLTFAnimation, _Exporter, _BinaryWriter, __IGLTFExporterExtensionV2, _GLTFMaterialExporter, _GLTFUtilities, KHR_texture_transform */
+/*! exports provided: __IGLTFExporterExtension, GLTFData, GLTF2Export, _GLTFAnimation, _Exporter, _BinaryWriter, __IGLTFExporterExtensionV2, _GLTFMaterialExporter, _GLTFUtilities, KHR_texture_transform, KHR_lights_punctual */
 /***/ (function(module, __webpack_exports__, __webpack_require__) {
 
 "use strict";
@@ -4068,6 +4263,8 @@ __webpack_require__.r(__webpack_exports__);
 
 /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "KHR_texture_transform", function() { return _2_0__WEBPACK_IMPORTED_MODULE_1__["KHR_texture_transform"]; });
 
+/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "KHR_lights_punctual", function() { return _2_0__WEBPACK_IMPORTED_MODULE_1__["KHR_lights_punctual"]; });
+
 
 
 
@@ -4078,7 +4275,7 @@ __webpack_require__.r(__webpack_exports__);
 /*!******************!*\
   !*** ./index.ts ***!
   \******************/
-/*! exports provided: __IGLTFExporterExtension, GLTFData, GLTF2Export, OBJExport, _GLTFAnimation, _Exporter, _BinaryWriter, __IGLTFExporterExtensionV2, _GLTFMaterialExporter, _GLTFUtilities, KHR_texture_transform */
+/*! exports provided: __IGLTFExporterExtension, GLTFData, GLTF2Export, OBJExport, _GLTFAnimation, _Exporter, _BinaryWriter, __IGLTFExporterExtensionV2, _GLTFMaterialExporter, _GLTFUtilities, KHR_texture_transform, KHR_lights_punctual */
 /***/ (function(module, __webpack_exports__, __webpack_require__) {
 
 "use strict";
@@ -4107,6 +4304,8 @@ __webpack_require__.r(__webpack_exports__);
 
 /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "KHR_texture_transform", function() { return _glTF__WEBPACK_IMPORTED_MODULE_1__["KHR_texture_transform"]; });
 
+/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "KHR_lights_punctual", function() { return _glTF__WEBPACK_IMPORTED_MODULE_1__["KHR_lights_punctual"]; });
+
 
 
 
@@ -4117,7 +4316,7 @@ __webpack_require__.r(__webpack_exports__);
 /*!******************************************!*\
   !*** ./legacy/legacy-glTF2Serializer.ts ***!
   \******************************************/
-/*! exports provided: __IGLTFExporterExtension, GLTFData, GLTF2Export, _GLTFAnimation, _Exporter, _BinaryWriter, __IGLTFExporterExtensionV2, _GLTFMaterialExporter, _GLTFUtilities, KHR_texture_transform */
+/*! exports provided: __IGLTFExporterExtension, GLTFData, GLTF2Export, _GLTFAnimation, _Exporter, _BinaryWriter, __IGLTFExporterExtensionV2, _GLTFMaterialExporter, _GLTFUtilities, KHR_texture_transform, KHR_lights_punctual */
 /***/ (function(module, __webpack_exports__, __webpack_require__) {
 
 "use strict";
@@ -4147,6 +4346,8 @@ __webpack_require__.r(__webpack_exports__);
 
 /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "KHR_texture_transform", function() { return _glTF_2_0__WEBPACK_IMPORTED_MODULE_4__["KHR_texture_transform"]; });
 
+/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "KHR_lights_punctual", function() { return _glTF_2_0__WEBPACK_IMPORTED_MODULE_4__["KHR_lights_punctual"]; });
+
 
 
 
@@ -4228,7 +4429,7 @@ if (typeof globalObject !== "undefined") {
 /*!**************************!*\
   !*** ./legacy/legacy.ts ***!
   \**************************/
-/*! exports provided: __IGLTFExporterExtension, GLTFData, GLTF2Export, _GLTFAnimation, _Exporter, _BinaryWriter, __IGLTFExporterExtensionV2, _GLTFMaterialExporter, _GLTFUtilities, OBJExport, KHR_texture_transform */
+/*! exports provided: __IGLTFExporterExtension, GLTFData, GLTF2Export, _GLTFAnimation, _Exporter, _BinaryWriter, __IGLTFExporterExtensionV2, _GLTFMaterialExporter, _GLTFUtilities, OBJExport, KHR_texture_transform, KHR_lights_punctual */
 /***/ (function(module, __webpack_exports__, __webpack_require__) {
 
 "use strict";
@@ -4255,6 +4456,8 @@ __webpack_require__.r(__webpack_exports__);
 
 /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "KHR_texture_transform", function() { return _legacy_glTF2Serializer__WEBPACK_IMPORTED_MODULE_1__["KHR_texture_transform"]; });
 
+/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "KHR_lights_punctual", function() { return _legacy_glTF2Serializer__WEBPACK_IMPORTED_MODULE_1__["KHR_lights_punctual"]; });
+
 /* harmony import */ var _legacy_objSerializer__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./legacy-objSerializer */ "./legacy/legacy-objSerializer.ts");
 /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "OBJExport", function() { return _legacy_objSerializer__WEBPACK_IMPORTED_MODULE_2__["OBJExport"]; });
 

File diff suppressed because it is too large
+ 1 - 1
dist/preview release/serializers/babylonjs.serializers.js.map


File diff suppressed because it is too large
+ 1 - 1
dist/preview release/serializers/babylonjs.serializers.min.js


+ 134 - 37
dist/preview release/serializers/babylonjs.serializers.module.d.ts

@@ -47,7 +47,8 @@ declare module "babylonjs-serializers/glTF/glTFFileExporter" {
     }
 }
 declare module "babylonjs-serializers/glTF/2.0/glTFExporterExtension" {
-    import { ImageMimeType, IMeshPrimitive } from "babylonjs-gltf2interface";
+    import { ImageMimeType, IMeshPrimitive, INode } from "babylonjs-gltf2interface";
+    import { Node } from "babylonjs/node";
     import { Nullable } from "babylonjs/types";
     import { Texture } from "babylonjs/Materials/Textures/texture";
     import { SubMesh } from "babylonjs/Meshes/subMesh";
@@ -75,8 +76,21 @@ declare module "babylonjs-serializers/glTF/2.0/glTFExporterExtension" {
          * @param meshPrimitive glTF mesh primitive
          * @param babylonSubMesh Babylon submesh
          * @param binaryWriter glTF serializer binary writer instance
+         * @returns nullable IMeshPrimitive promise
          */
         postExportMeshPrimitiveAsync?(context: string, meshPrimitive: IMeshPrimitive, babylonSubMesh: SubMesh, binaryWriter: _BinaryWriter): Nullable<Promise<IMeshPrimitive>>;
+        /**
+         * Define this method to modify the default behavior when exporting a node
+         * @param context The context when exporting the node
+         * @param node glTF node
+         * @param babylonNode BabylonJS node
+         * @returns nullable INode promise
+         */
+        postExportNodeAsync?(context: string, node: INode, babylonNode: Node): Nullable<Promise<INode>>;
+        /**
+         * Called after the exporter state changes to EXPORTING
+         */
+        onExporting?(): void;
     }
 }
 declare module "babylonjs-serializers/glTF/2.0/glTFMaterialExporter" {
@@ -330,7 +344,7 @@ declare module "babylonjs-serializers/glTF/2.0/glTFData" {
     }
 }
 declare module "babylonjs-serializers/glTF/2.0/glTFSerializer" {
-    import { TransformNode } from "babylonjs/Meshes/transformNode";
+    import { Node } from "babylonjs/node";
     import { Scene } from "babylonjs/scene";
     import { GLTFData } from "babylonjs-serializers/glTF/2.0/glTFData";
     /**
@@ -338,11 +352,11 @@ declare module "babylonjs-serializers/glTF/2.0/glTFSerializer" {
      */
     export interface IExportOptions {
         /**
-         * Function which indicates whether a babylon mesh should be exported or not
-         * @param transformNode source Babylon transform node. It is used to check whether it should be exported to glTF or not
-         * @returns boolean, which indicates whether the mesh should be exported (true) or not (false)
+         * Function which indicates whether a babylon node should be exported or not
+         * @param node source Babylon node. It is used to check whether it should be exported to glTF or not
+         * @returns boolean, which indicates whether the node should be exported (true) or not (false)
          */
-        shouldExportTransformNode?(transformNode: TransformNode): boolean;
+        shouldExportNode?(node: Node): boolean;
         /**
          * The sample rate to bake animation curves
          */
@@ -475,9 +489,10 @@ declare module "babylonjs-serializers/glTF/2.0/glTFUtilities" {
     }
 }
 declare module "babylonjs-serializers/glTF/2.0/glTFExporter" {
-    import { IBufferView, IAccessor, IMaterial, ITexture, IImage, ISampler, ImageMimeType, IMeshPrimitive } from "babylonjs-gltf2interface";
+    import { IBufferView, IAccessor, INode, IMaterial, ITexture, IImage, ISampler, ImageMimeType, IMeshPrimitive, IGLTF } from "babylonjs-gltf2interface";
     import { FloatArray, Nullable } from "babylonjs/types";
     import { Vector3, Vector4 } from "babylonjs/Maths/math";
+    import { Node } from "babylonjs/node";
     import { SubMesh } from "babylonjs/Meshes/subMesh";
     import { BaseTexture } from "babylonjs/Materials/Textures/baseTexture";
     import { Texture } from "babylonjs/Materials/Textures/texture";
@@ -493,6 +508,10 @@ declare module "babylonjs-serializers/glTF/2.0/glTFExporter" {
      */
     export class _Exporter {
         /**
+         * Stores the glTF to export
+         */
+        _glTF: IGLTF;
+        /**
          * Stores all generated buffer views, which represents views into the main glTF buffer data
          */
         _bufferViews: IBufferView[];
@@ -505,10 +524,6 @@ declare module "babylonjs-serializers/glTF/2.0/glTFExporter" {
          */
         private _nodes;
         /**
-         * Stores the glTF asset information, which represents the glTF version and this file generator
-         */
-        private _asset;
-        /**
          * Stores all the generated glTF scenes, which stores multiple node hierarchies
          */
         private _scenes;
@@ -549,7 +564,7 @@ declare module "babylonjs-serializers/glTF/2.0/glTFExporter" {
         /**
          * Stores a reference to the Babylon scene containing the source geometry and material information
          */
-        private _babylonScene;
+        _babylonScene: Scene;
         /**
          * Stores a map of the image data, where the key is the file name and the value
          * is the image data
@@ -567,25 +582,26 @@ declare module "babylonjs-serializers/glTF/2.0/glTFExporter" {
         /**
          * Specifies if the Babylon scene should be converted to right-handed on export
          */
-        private _convertToRightHandedSystem;
+        _convertToRightHandedSystem: boolean;
         /**
          * Baked animation sample rate
          */
         private _animationSampleRate;
         /**
-         * Callback which specifies if a transform node should be exported or not
+         * Callback which specifies if a node should be exported or not
          */
-        private _shouldExportTransformNode;
+        private _shouldExportNode;
         private _localEngine;
         _glTFMaterialExporter: _GLTFMaterialExporter;
         private _extensions;
-        private _extensionsUsed;
-        private _extensionsRequired;
         private static _ExtensionNames;
         private static _ExtensionFactories;
         private _applyExtensions;
         _extensionsPreExportTextureAsync(context: string, babylonTexture: Texture, mimeType: ImageMimeType): Nullable<Promise<BaseTexture>>;
         _extensionsPostExportMeshPrimitiveAsync(context: string, meshPrimitive: IMeshPrimitive, babylonSubMesh: SubMesh, binaryWriter: _BinaryWriter): Nullable<Promise<IMeshPrimitive>>;
+        _extensionsPostExportNodeAsync(context: string, node: INode, babylonNode: Node): Nullable<Promise<INode>>;
+        private _forEachExtensions;
+        private _extensionsOnExporting;
         /**
          * Load glTF serializer extensions
          */
@@ -761,7 +777,7 @@ declare module "babylonjs-serializers/glTF/2.0/glTFExporter" {
          * Creates a mapping of Node unique id to node index and handles animations
          * @param babylonScene Babylon Scene
          * @param nodes Babylon transform nodes
-         * @param shouldExportTransformNode Callback specifying if a transform node should be exported
+         * @param shouldExportNode Callback specifying if a transform node should be exported
          * @param binaryWriter Buffer to write binary data to
          * @returns Node mapping of unique id to index
          */
@@ -843,6 +859,7 @@ declare module "babylonjs-serializers/glTF/2.0/glTFExporter" {
 }
 declare module "babylonjs-serializers/glTF/2.0/glTFAnimation" {
     import { AnimationSamplerInterpolation, AnimationChannelTargetPath, AccessorType, IAnimation, INode, IBufferView, IAccessor } from "babylonjs-gltf2interface";
+    import { Node } from "babylonjs/node";
     import { Nullable } from "babylonjs/types";
     import { Animation } from "babylonjs/Animations/animation";
     import { TransformNode } from "babylonjs/Meshes/transformNode";
@@ -912,7 +929,7 @@ declare module "babylonjs-serializers/glTF/2.0/glTFAnimation" {
         /**
          * @ignore
          * Create node animations from the transform node animations
-         * @param babylonTransformNode
+         * @param babylonNode
          * @param runtimeGLTFAnimation
          * @param idleGLTFAnimations
          * @param nodeMap
@@ -922,7 +939,7 @@ declare module "babylonjs-serializers/glTF/2.0/glTFAnimation" {
          * @param accessors
          * @param convertToRightHandedSystem
          */
-        static _CreateNodeAnimationFromTransformNodeAnimations(babylonTransformNode: TransformNode, runtimeGLTFAnimation: IAnimation, idleGLTFAnimations: IAnimation[], nodeMap: {
+        static _CreateNodeAnimationFromNodeAnimations(babylonNode: Node, runtimeGLTFAnimation: IAnimation, idleGLTFAnimations: IAnimation[], nodeMap: {
             [key: number]: number;
         }, nodes: INode[], binaryWriter: _BinaryWriter, bufferViews: IBufferView[], accessors: IAccessor[], convertToRightHandedSystem: boolean, animationSampleRate: number): void;
         /**
@@ -1064,8 +1081,44 @@ declare module "babylonjs-serializers/glTF/2.0/Extensions/KHR_texture_transform"
         textureTransformTextureAsync(babylonTexture: Texture, offset: Vector2, rotation: number, scale: Vector2, scene: Scene): Promise<BaseTexture>;
     }
 }
+declare module "babylonjs-serializers/glTF/2.0/Extensions/KHR_lights_punctual" {
+    import { Nullable } from "babylonjs/types";
+    import { Node } from "babylonjs/node";
+    import { INode } from "babylonjs-gltf2interface";
+    import { IGLTFExporterExtensionV2 } from "babylonjs-serializers/glTF/2.0/glTFExporterExtension";
+    import { _Exporter } from "babylonjs-serializers/glTF/2.0/glTFExporter";
+    /**
+     * [Specification](https://github.com/KhronosGroup/glTF/blob/master/extensions/2.0/Khronos/KHR_lights_punctual/README.md)
+     */
+    export class KHR_lights_punctual implements IGLTFExporterExtensionV2 {
+        /** The name of this extension. */
+        readonly name: string;
+        /** Defines whether this extension is enabled. */
+        enabled: boolean;
+        /** Defines whether this extension is required */
+        required: boolean;
+        /** Reference to the glTF exporter */
+        private _exporter;
+        private _lights;
+        /** @hidden */
+        constructor(exporter: _Exporter);
+        /** @hidden */
+        dispose(): void;
+        /** @hidden */
+        onExporting(): void;
+        /**
+         * Define this method to modify the default behavior when exporting a node
+         * @param context The context when exporting the node
+         * @param node glTF node
+         * @param babylonNode BabylonJS node
+         * @returns nullable INode promise
+         */
+        postExportNodeAsync(context: string, node: INode, babylonNode: Node): Nullable<Promise<INode>>;
+    }
+}
 declare module "babylonjs-serializers/glTF/2.0/Extensions/index" {
     export * from "babylonjs-serializers/glTF/2.0/Extensions/KHR_texture_transform";
+    export * from "babylonjs-serializers/glTF/2.0/Extensions/KHR_lights_punctual";
 }
 declare module "babylonjs-serializers/glTF/2.0/index" {
     export * from "babylonjs-serializers/glTF/2.0/glTFAnimation";
@@ -1166,8 +1219,21 @@ declare module BABYLON.GLTF2.Exporter {
          * @param meshPrimitive glTF mesh primitive
          * @param babylonSubMesh Babylon submesh
          * @param binaryWriter glTF serializer binary writer instance
+         * @returns nullable IMeshPrimitive promise
          */
         postExportMeshPrimitiveAsync?(context: string, meshPrimitive: IMeshPrimitive, babylonSubMesh: SubMesh, binaryWriter: _BinaryWriter): Nullable<Promise<IMeshPrimitive>>;
+        /**
+         * Define this method to modify the default behavior when exporting a node
+         * @param context The context when exporting the node
+         * @param node glTF node
+         * @param babylonNode BabylonJS node
+         * @returns nullable INode promise
+         */
+        postExportNodeAsync?(context: string, node: INode, babylonNode: Node): Nullable<Promise<INode>>;
+        /**
+         * Called after the exporter state changes to EXPORTING
+         */
+        onExporting?(): void;
     }
 }
 declare module BABYLON.GLTF2.Exporter {
@@ -1418,11 +1484,11 @@ declare module BABYLON {
      */
     export interface IExportOptions {
         /**
-         * Function which indicates whether a babylon mesh should be exported or not
-         * @param transformNode source Babylon transform node. It is used to check whether it should be exported to glTF or not
-         * @returns boolean, which indicates whether the mesh should be exported (true) or not (false)
+         * Function which indicates whether a babylon node should be exported or not
+         * @param node source Babylon node. It is used to check whether it should be exported to glTF or not
+         * @returns boolean, which indicates whether the node should be exported (true) or not (false)
          */
-        shouldExportTransformNode?(transformNode: TransformNode): boolean;
+        shouldExportNode?(node: Node): boolean;
         /**
          * The sample rate to bake animation curves
          */
@@ -1558,6 +1624,10 @@ declare module BABYLON.GLTF2.Exporter {
      */
     export class _Exporter {
         /**
+         * Stores the glTF to export
+         */
+        _glTF: IGLTF;
+        /**
          * Stores all generated buffer views, which represents views into the main glTF buffer data
          */
         _bufferViews: IBufferView[];
@@ -1570,10 +1640,6 @@ declare module BABYLON.GLTF2.Exporter {
          */
         private _nodes;
         /**
-         * Stores the glTF asset information, which represents the glTF version and this file generator
-         */
-        private _asset;
-        /**
          * Stores all the generated glTF scenes, which stores multiple node hierarchies
          */
         private _scenes;
@@ -1614,7 +1680,7 @@ declare module BABYLON.GLTF2.Exporter {
         /**
          * Stores a reference to the Babylon scene containing the source geometry and material information
          */
-        private _babylonScene;
+        _babylonScene: Scene;
         /**
          * Stores a map of the image data, where the key is the file name and the value
          * is the image data
@@ -1632,25 +1698,26 @@ declare module BABYLON.GLTF2.Exporter {
         /**
          * Specifies if the Babylon scene should be converted to right-handed on export
          */
-        private _convertToRightHandedSystem;
+        _convertToRightHandedSystem: boolean;
         /**
          * Baked animation sample rate
          */
         private _animationSampleRate;
         /**
-         * Callback which specifies if a transform node should be exported or not
+         * Callback which specifies if a node should be exported or not
          */
-        private _shouldExportTransformNode;
+        private _shouldExportNode;
         private _localEngine;
         _glTFMaterialExporter: _GLTFMaterialExporter;
         private _extensions;
-        private _extensionsUsed;
-        private _extensionsRequired;
         private static _ExtensionNames;
         private static _ExtensionFactories;
         private _applyExtensions;
         _extensionsPreExportTextureAsync(context: string, babylonTexture: Texture, mimeType: ImageMimeType): Nullable<Promise<BaseTexture>>;
         _extensionsPostExportMeshPrimitiveAsync(context: string, meshPrimitive: IMeshPrimitive, babylonSubMesh: SubMesh, binaryWriter: _BinaryWriter): Nullable<Promise<IMeshPrimitive>>;
+        _extensionsPostExportNodeAsync(context: string, node: INode, babylonNode: Node): Nullable<Promise<INode>>;
+        private _forEachExtensions;
+        private _extensionsOnExporting;
         /**
          * Load glTF serializer extensions
          */
@@ -1826,7 +1893,7 @@ declare module BABYLON.GLTF2.Exporter {
          * Creates a mapping of Node unique id to node index and handles animations
          * @param babylonScene Babylon Scene
          * @param nodes Babylon transform nodes
-         * @param shouldExportTransformNode Callback specifying if a transform node should be exported
+         * @param shouldExportNode Callback specifying if a transform node should be exported
          * @param binaryWriter Buffer to write binary data to
          * @returns Node mapping of unique id to index
          */
@@ -1971,7 +2038,7 @@ declare module BABYLON.GLTF2.Exporter {
         /**
          * @ignore
          * Create node animations from the transform node animations
-         * @param babylonTransformNode
+         * @param babylonNode
          * @param runtimeGLTFAnimation
          * @param idleGLTFAnimations
          * @param nodeMap
@@ -1981,7 +2048,7 @@ declare module BABYLON.GLTF2.Exporter {
          * @param accessors
          * @param convertToRightHandedSystem
          */
-        static _CreateNodeAnimationFromTransformNodeAnimations(babylonTransformNode: TransformNode, runtimeGLTFAnimation: IAnimation, idleGLTFAnimations: IAnimation[], nodeMap: {
+        static _CreateNodeAnimationFromNodeAnimations(babylonNode: Node, runtimeGLTFAnimation: IAnimation, idleGLTFAnimations: IAnimation[], nodeMap: {
             [key: number]: number;
         }, nodes: INode[], binaryWriter: _BinaryWriter, bufferViews: IBufferView[], accessors: IAccessor[], convertToRightHandedSystem: boolean, animationSampleRate: number): void;
         /**
@@ -2113,4 +2180,34 @@ declare module BABYLON.GLTF2.Exporter.Extensions {
          */
         textureTransformTextureAsync(babylonTexture: Texture, offset: Vector2, rotation: number, scale: Vector2, scene: Scene): Promise<BaseTexture>;
     }
+}
+declare module BABYLON.GLTF2.Exporter.Extensions {
+    /**
+     * [Specification](https://github.com/KhronosGroup/glTF/blob/master/extensions/2.0/Khronos/KHR_lights_punctual/README.md)
+     */
+    export class KHR_lights_punctual implements IGLTFExporterExtensionV2 {
+        /** The name of this extension. */
+        readonly name: string;
+        /** Defines whether this extension is enabled. */
+        enabled: boolean;
+        /** Defines whether this extension is required */
+        required: boolean;
+        /** Reference to the glTF exporter */
+        private _exporter;
+        private _lights;
+        /** @hidden */
+        constructor(exporter: _Exporter);
+        /** @hidden */
+        dispose(): void;
+        /** @hidden */
+        onExporting(): void;
+        /**
+         * Define this method to modify the default behavior when exporting a node
+         * @param context The context when exporting the node
+         * @param node glTF node
+         * @param babylonNode BabylonJS node
+         * @returns nullable INode promise
+         */
+        postExportNodeAsync(context: string, node: INode, babylonNode: Node): Nullable<Promise<INode>>;
+    }
 }

File diff suppressed because it is too large
+ 13302 - 12549
dist/preview release/viewer/babylon.module.d.ts


File diff suppressed because it is too large
+ 105 - 85
dist/preview release/viewer/babylon.viewer.js


File diff suppressed because it is too large
+ 2 - 2
dist/preview release/viewer/babylon.viewer.max.js


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

@@ -23,7 +23,11 @@
   - Added new [ScrollViewer](https://doc.babylonjs.com/how_to/scrollviewer) with mouse wheel scrolling for larger containers to be viewed using Sliders ([JohnK](https://github.com/BabylonJSGuide/) / [Deltakosh](https://github.com/deltakosh))
   - Moved to a measure / draw mechanism ([Deltakosh](https://github.com/deltakosh))
   - Added support for [nine patch stretch](https://www.babylonjs-playground.com/#G5H9IN#2) mode for images. ([Deltakosh](https://github.com/deltakosh))
-  - InvalidateRect added to AdvancedDynamicTexture to improve perf for heavily populated GUIs, works with shadows ([TrevorDev](https://github.com/TrevorDev))
+  - InvalidateRect added to AdvancedDynamicTexture to improve perf for heavily populated GUIs, works with shadows ([TrevorDev](https://github.com/TrevorDev)) **** NEED DEMO or DOC LINK)
+- Migrated the code to modules and deploy ES6 npm packages ([Sebavan](https://github.com/Sebavan)) **** NEED DEMO or DOC LINK)
+- Added clear coat support to PBR ([Sebavan](https://github.com/Sebavan)) **** NEED DEMO or DOC LINK)
+- Added anisotropy support to PBR ([Sebavan](https://github.com/Sebavan)) **** NEED DEMO or DOC LINK)
+- Added `TrailMesh` class. Credit to furcatomasz ([danjpar](https://github.com/danjpar)) **** NEED DEMO or DOC LINK)
 
 ## Updates
 
@@ -117,8 +121,13 @@
 
 ### glTF Serializer
 
+- Added support for exporting `KHR_lights_punctual`
+
 ### Viewer
 
+### Post-Processes Library
+- Added the `Ocean` post-process ([julien-moreau](https://github.com/julien-moreau))
+
 ### Materials Library
 - Added the `cameraOffset` vector property in the `SkyMaterial` to get an offset according to the horizon ([julien-moreau](https://github.com/julien-moreau))
 - Fixed `GradientMaterial` to consider disableLighting working as emissive ([julien-moreau](https://github.com/julien-moreau))
@@ -126,6 +135,7 @@
 - Fixed `TerrainMaterial.isReadyForSubMesh` to remove WebGL warnings ([julien-moreau](https://github.com/julien-moreau))
 
 ## Bug fixes
+- Fixed ArcRotateCamera.setTarget (position was sometimes wrong) ([Deltakosh](https://github.com/deltakosh))
 - Fixed TransformNode.setDirection (orientation was wrong) ([Deltakosh](https://github.com/deltakosh))
 - Fixed ArcRotateCamera control when upVector was modified ([Deltakosh](https://github.com/deltakosh))
 - Fixed anaglyph mode for Free and Universal cameras ([Deltakosh](https://github.com/deltakosh))
@@ -157,9 +167,10 @@
 - Fix more case sensitive paths ([mrdunk](https://github.com))
 - Attaching a BoundingBoxGizmo on a child should not remove its parent ([TrevorDev](https://github.com/TrevorDev)))
 - AmmoJS fix include issue caused after modules update and use world contact point to be consistent with oimo and cannon ([TrevorDev](https://github.com/TrevorDev)))
-- Warn of motor with maxForce in Oimo, cannonJS support no impostor, cannonJS cylinder axis, ammoJS wake up impostor when apply force/impulse ([TrevorDev](https://github.com/TrevorDev)))
+- Warn of motor with maxForce in Oimo plugin and set default force to be consistent with others, cannonJS support no impostor, cannonJS cylinder axis, ammoJS wake up impostor when apply force/impulse ([TrevorDev](https://github.com/TrevorDev)))
 - Utility layer should render on last active camera ([TrevorDev](https://github.com/TrevorDev))
 - PointerDragBehavior should not let the drag plane get out of sync when rotating the object during dragging ([TrevorDev](https://github.com/TrevorDev))
+- Do not crash the application if webVR submitFrame fails ([TrevorDev](https://github.com/TrevorDev))
 
 ### Core Engine
 - Fixed a bug with `mesh.alwaysSelectAsActiveMesh` preventing layerMask to be taken in account ([Deltakosh](https://github.com/deltakosh))
@@ -230,3 +241,4 @@
 - No more `babylon.worker.js` javascript following the lack of usage from the feature ([Sebavan]
 (https://github.com/Sebavan))
 - No more `Primitive Geometries` as they were not in use since 2.0 ([Sebavan](https://github.com/Sebavan))
+- Change `shouldExportTransformNode` callback in glTF serializer options to `shouldExportNode`([kcoley](https://github.com/kcoley))

+ 3 - 3
gui/src/2D/controls/control.ts

@@ -1512,9 +1512,9 @@ export class Control {
         this._transform(context);
 
         // Clip
-        if (this.clipChildren) {
-            this._clip(context, invalidatedRectangle);
-        }
+        //     if (this.clipChildren) {
+        this._clip(context, invalidatedRectangle);
+        //   }
 
         if (this.onBeforeDrawObservable.hasObservers()) {
             this.onBeforeDrawObservable.notifyObservers(this);

+ 4 - 0
gui/src/2D/controls/grid.ts

@@ -418,6 +418,10 @@ export class Grid extends Container {
                 cell.top = tops[x] + "px";
                 cell.width = widths[y] + "px";
                 cell.height = heights[x] + "px";
+                cell._left.ignoreAdaptiveScaling = true;
+                cell._top.ignoreAdaptiveScaling = true;
+                cell._width.ignoreAdaptiveScaling = true;
+                cell._height.ignoreAdaptiveScaling = true;
             }
         });
 

+ 21 - 2
gui/src/2D/controls/sliders/baseSlider.ts

@@ -16,6 +16,7 @@ export class BaseSlider extends Control {
     protected _barOffset = new ValueAndUnit(5, ValueAndUnit.UNITMODE_PIXEL, false);
     private _isThumbClamped = false;
     protected _displayThumb = true;
+    private _step = 0;
 
     // Shared rendering info
     protected _effectiveBarOffset = 0;
@@ -44,6 +45,20 @@ export class BaseSlider extends Control {
         this._markAsDirty();
     }
 
+    /** Gets or sets a step to apply to values (0 by default) */
+    public get step(): number {
+        return this._step;
+    }
+
+    public set step(value: number) {
+        if (this._step === value) {
+            return;
+        }
+
+        this._step = value;
+        this._markAsDirty();
+    }
+
     /** Gets or sets main bar offset (ie. the margin applied to the value bar) */
     public get barOffset(): string | number {
         return this._barOffset.toString(this._host);
@@ -265,12 +280,16 @@ export class BaseSlider extends Control {
             y = this._transformedPosition.y;
         }
 
+        let value: number;
         if (this._isVertical) {
-            this.value = this._minimum + (1 - ((y - this._currentMeasure.top) / this._currentMeasure.height)) * (this._maximum - this._minimum);
+            value = this._minimum + (1 - ((y - this._currentMeasure.top) / this._currentMeasure.height)) * (this._maximum - this._minimum);
         }
         else {
-            this.value = this._minimum + ((x - this._currentMeasure.left) / this._currentMeasure.width) * (this._maximum - this._minimum);
+            value = this._minimum + ((x - this._currentMeasure.left) / this._currentMeasure.width) * (this._maximum - this._minimum);
         }
+
+        const mult = (1 / this._step) | 0;
+        this.value = this._step ? ((value * mult) | 0) / mult : value;
     }
 
     public _onPointerDown(target: Control, coordinates: Vector2, pointerId: number, buttonIndex: number): boolean {

+ 2 - 1
gui/src/2D/measure.ts

@@ -1,5 +1,6 @@
 import { Matrix2D } from "./math2D";
-import { Vector2, Polygon } from "babylonjs";
+import { Vector2 } from "babylonjs/Maths/math";
+import { Polygon } from "babylonjs/Meshes/polygonMesh";
 
 /**
  * Class used to store 2D control sizes

+ 45 - 24
inspector/src/components/actionTabs/actionTabs.scss

@@ -801,37 +801,58 @@
 
                 .paneContainer {
                     margin-top: 3px;
+                    display:grid;
+                    grid-template-rows: 100%;
+                    grid-template-columns: 100%;
                     
-                    .header {
-                        display: grid;
-                        grid-template-columns: 1fr auto;
-                        background: #555555;    
-                        height: 30px;   
-                        padding-right: 5px;                        
-                        cursor: pointer;
+                    .paneContainer-highlight-border {
+                        grid-row: 1;
+                        grid-column: 1;
+                        opacity: 1;
+                        border: 3px solid red;
+                        transition: opacity 250ms;
+                        pointer-events: none;
                         
-                        .title {
-                            margin-left: 5px;
-                            grid-column: 1;
-                            display: flex;
-                            align-items: center;
+                        &.transparent {
+                            opacity: 0;
                         }
+                    }
 
-                        .collapse {
-                            grid-column: 2;
-                            display: flex;
-                            align-items: center;  
-                            justify-items: center;
-                            transform-origin: center;
+                    .paneContainer-content {
+                        grid-row: 1;
+                        grid-column: 1;
 
-                            &.closed {
-                                transform: rotate(180deg);
+                        .header {
+                            display: grid;
+                            grid-template-columns: 1fr auto;
+                            background: #555555;    
+                            height: 30px;   
+                            padding-right: 5px;                        
+                            cursor: pointer;
+                            
+                            .title {
+                                margin-left: 5px;
+                                grid-column: 1;
+                                display: flex;
+                                align-items: center;
                             }
-                        }                        
-                    }
 
-                    .paneList > div:not(:last-child) {
-                        border-bottom: 0.5px solid rgba(255, 255, 255, 0.1);
+                            .collapse {
+                                grid-column: 2;
+                                display: flex;
+                                align-items: center;  
+                                justify-items: center;
+                                transform-origin: center;
+
+                                &.closed {
+                                    transform: rotate(180deg);
+                                }
+                            }                        
+                        }
+
+                        .paneList > div:not(:last-child) {
+                            border-bottom: 0.5px solid rgba(255, 255, 255, 0.1);
+                        }
                     }
                 }
             }

+ 1 - 1
inspector/src/components/actionTabs/actionTabsComponent.tsx

@@ -10,7 +10,7 @@ import Resizable from "re-resizable";
 import { PropertyGridTabComponent } from "./tabs/propertyGridTabComponent";
 import { HeaderComponent } from "../headerComponent";
 import { ToolsTabComponent } from "./tabs/toolsTabComponent";
-import { GlobalState } from "components/globalState";
+import { GlobalState } from "../../components/globalState";
 
 require("./actionTabs.scss");
 

+ 37 - 20
inspector/src/components/actionTabs/lineContainerComponent.tsx

@@ -1,30 +1,31 @@
 import * as React from "react";
 import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
 import { faChevronDown } from '@fortawesome/free-solid-svg-icons';
+import { GlobalState } from '../../components/globalState';
 
 interface ILineContainerComponentProps {
+    globalState: GlobalState;
     title: string;
     children: any[] | any;
     closed?: boolean;
 }
 
-export class LineContainerComponent extends React.Component<ILineContainerComponentProps, { isExpanded: boolean }> {
-    private static _InMemoryStorage: {[key: string]: boolean};
-    
+export class LineContainerComponent extends React.Component<ILineContainerComponentProps, { isExpanded: boolean, isHighlighted: boolean }> {
+    private static _InMemoryStorage: { [key: string]: boolean };
+
     constructor(props: ILineContainerComponentProps) {
         super(props);
 
         let initialState: boolean;
 
-        try
-        { 
+        try {
             if (LineContainerComponent._InMemoryStorage && LineContainerComponent._InMemoryStorage[this.props.title] !== undefined) {
                 initialState = LineContainerComponent._InMemoryStorage[this.props.title];
             } else if (typeof (Storage) !== "undefined" && localStorage.getItem(this.props.title) !== null) {
                 initialState = localStorage.getItem(this.props.title) === "true";
             } else {
                 initialState = !this.props.closed;
-            }   
+            }
         }
         catch (e) {
             LineContainerComponent._InMemoryStorage = {};
@@ -32,14 +33,13 @@ export class LineContainerComponent extends React.Component<ILineContainerCompon
             initialState = !this.props.closed;
         }
 
-        this.state = { isExpanded: initialState };
+        this.state = { isExpanded: initialState, isHighlighted: false };
     }
 
     switchExpandedState(): void {
         const newState = !this.state.isExpanded;
-        
-        try
-        { 
+
+        try {
             if (LineContainerComponent._InMemoryStorage) {
                 LineContainerComponent._InMemoryStorage[this.props.title] = newState;
             } else if (typeof (Storage) !== "undefined") {
@@ -50,9 +50,20 @@ export class LineContainerComponent extends React.Component<ILineContainerCompon
             LineContainerComponent._InMemoryStorage = {};
             LineContainerComponent._InMemoryStorage[this.props.title] = newState;
         }
-        
+
         this.setState({ isExpanded: newState });
+    }
+
+    componentDidMount() {
+        if (this.props.globalState.selectedLineContainerTitle === this.props.title) {
+            this.props.globalState.selectedLineContainerTitle = "";
 
+            this.setState({ isExpanded: true, isHighlighted: true });
+
+            window.setTimeout(() => {
+                this.setState({ isHighlighted: false });
+            }, 5000);
+        }
     }
 
     renderHeader() {
@@ -74,21 +85,27 @@ export class LineContainerComponent extends React.Component<ILineContainerCompon
         if (!this.state.isExpanded) {
             return (
                 <div className="paneContainer">
-                    {
-                        this.renderHeader()
-                    }
+                    <div className="paneContainer-content">
+                        {
+                            this.renderHeader()
+                        }
+                    </div>
                 </div>
             );
         }
 
         return (
             <div className="paneContainer">
-                {
-                    this.renderHeader()
-                }
-                <div className="paneList">
-                    {this.props.children}
-                </div >
+                <div className="paneContainer-content">
+                    {
+                        this.renderHeader()
+                    }
+                    <div className="paneList">
+                        {this.props.children}
+                    </div >
+                </div>
+                <div className={"paneContainer-highlight-border" + (!this.state.isHighlighted ? " transparent" : "")}>
+                </div>
             </div>
         );
     }

+ 3 - 2
inspector/src/components/actionTabs/lines/sliderLineComponent.tsx

@@ -12,7 +12,8 @@ interface ISliderLineComponentProps {
     directValue?: number,
     onChange?: (value: number) => void,
     onInput?: (value: number) => void,
-    onPropertyChangedObservable?: Observable<PropertyChangedEvent>
+    onPropertyChangedObservable?: Observable<PropertyChangedEvent>,
+    decimalCount?: number
 }
 
 export class SliderLineComponent extends React.Component<ISliderLineComponentProps, { value: number }> {
@@ -82,7 +83,7 @@ export class SliderLineComponent extends React.Component<ISliderLineComponentPro
                     {this.props.label}
                 </div>
                 <div className="slider">
-                    {this.state.value ? this.state.value.toFixed(2) : "0"}&nbsp;<input className="range" type="range" step={this.props.step} min={this.props.minimum} max={this.props.maximum} value={this.state.value}
+                    {this.state.value ? this.state.value.toFixed(this.props.decimalCount || 2) : "0"}&nbsp;<input className="range" type="range" step={this.props.step} min={this.props.minimum} max={this.props.maximum} value={this.state.value}
                         onInput={evt => this.onInput((evt.target as HTMLInputElement).value)}
                         onChange={evt => this.onChange(evt.target.value)} />
                 </div>

+ 1 - 1
inspector/src/components/actionTabs/lines/textInputLineComponent.tsx

@@ -1,6 +1,6 @@
 import * as React from "react";
 import { Observable } from "babylonjs/Misc/observable";
-import { PropertyChangedEvent } from "components/propertyChangedEvent";
+import { PropertyChangedEvent } from "../../../components/propertyChangedEvent";
 import { LockObject } from "../tabs/propertyGrids/lockObject";
 
 interface ITextInputLineComponentProps {

+ 1 - 1
inspector/src/components/actionTabs/lines/textureLineComponent.tsx

@@ -7,7 +7,7 @@ import { RenderTargetTexture } from "babylonjs/Materials/Textures/renderTargetTe
 import { PostProcess } from "babylonjs/PostProcesses/postProcess";
 import { PassPostProcess, PassCubePostProcess } from "babylonjs/PostProcesses/passPostProcess";
 
-import { GlobalState } from "components/globalState";
+import { GlobalState } from "../../../components/globalState";
 
 interface ITextureLineComponentProps {
     texture: BaseTexture,

+ 108 - 0
inspector/src/components/actionTabs/lines/vector2LineComponent.tsx

@@ -0,0 +1,108 @@
+import * as React from "react";
+import { Vector2 } from "babylonjs/Maths/math";
+import { Observable } from "babylonjs/Misc/observable";
+
+import { NumericInputComponent } from "./numericInputComponent";
+import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
+import { faMinus, faPlus } from "@fortawesome/free-solid-svg-icons";
+import { PropertyChangedEvent } from "../../propertyChangedEvent";
+
+interface IVector2LineComponentProps {
+    label: string,
+    target: any,
+    propertyName: string,
+    onChange?: (newvalue: Vector2) => void,
+    onPropertyChangedObservable?: Observable<PropertyChangedEvent>
+}
+
+export class Vector2LineComponent extends React.Component<IVector2LineComponentProps, { isExpanded: boolean, value: Vector2 }> {
+    private _localChange = false;
+
+    constructor(props: IVector2LineComponentProps) {
+        super(props);
+
+        this.state = { isExpanded: false, value: this.props.target[this.props.propertyName].clone() }
+    }
+
+    shouldComponentUpdate(nextProps: IVector2LineComponentProps, nextState: { isExpanded: boolean, value: Vector2 }) {
+        const nextPropsValue = nextProps.target[nextProps.propertyName];
+
+        if (!nextPropsValue.equals(nextState.value) || this._localChange) {
+            nextState.value = nextPropsValue.clone();
+            this._localChange = false;
+            return true;
+        }
+        return false;
+    }
+
+    switchExpandState() {
+        this._localChange = true;
+        this.setState({ isExpanded: !this.state.isExpanded });
+    }
+
+    raiseOnPropertyChanged(previousValue: Vector2) {
+        if (this.props.onChange) {
+            this.props.onChange(this.state.value);
+        }
+
+        if (!this.props.onPropertyChangedObservable) {
+            return;
+        }
+        this.props.onPropertyChangedObservable.notifyObservers({
+            object: this.props.target,
+            property: this.props.propertyName,
+            value: this.state.value,
+            initialValue: previousValue
+        });
+    }
+
+    updateStateX(value: number) {
+        this._localChange = true;
+
+        const store = this.state.value.clone();
+        this.props.target[this.props.propertyName].x = value;
+        this.state.value.x = value;
+        this.setState({ value: this.state.value });
+
+        this.raiseOnPropertyChanged(store);
+    }
+
+    updateStateY(value: number) {
+        this._localChange = true;
+
+        const store = this.state.value.clone();
+        this.props.target[this.props.propertyName].y = value;
+        this.state.value.y = value;
+        this.setState({ value: this.state.value });
+
+        this.raiseOnPropertyChanged(store);
+    }
+
+    render() {
+        const chevron = this.state.isExpanded ? <FontAwesomeIcon icon={faMinus} /> : <FontAwesomeIcon icon={faPlus} />
+
+        return (
+            <div className="vector3Line">
+                <div className="firstLine">
+                    <div className="label">
+                        {this.props.label}
+                    </div>
+                    <div className="vector">
+                        {`X: ${this.state.value.x.toFixed(2)}, Y: ${this.state.value.y.toFixed(2)}`}
+
+                    </div>
+                    <div className="expand hoverIcon" onClick={() => this.switchExpandState()} title="Expand">
+                        {chevron}
+                    </div>
+                </div>
+                {
+                    this.state.isExpanded &&
+                    <div className="secondLine">
+                        <NumericInputComponent label="x" value={this.state.value.x} onChange={value => this.updateStateX(value)} />
+                        <NumericInputComponent label="y" value={this.state.value.y} onChange={value => this.updateStateY(value)} />
+                    </div>
+                }
+            </div>
+        );
+    }
+}

+ 1 - 1
inspector/src/components/actionTabs/paneComponent.tsx

@@ -3,7 +3,7 @@ import { IconDefinition } from '@fortawesome/free-solid-svg-icons';
 import { Observable } from "babylonjs/Misc/observable";
 import { Scene } from "babylonjs/scene";
 import { PropertyChangedEvent } from "../propertyChangedEvent";
-import { GlobalState } from "components/globalState";
+import { GlobalState } from "../../components/globalState";
 
 export interface IPaneComponentProps {
     title: string,

+ 4 - 4
inspector/src/components/actionTabs/tabs/debugTabComponent.tsx

@@ -110,12 +110,12 @@ export class DebugTabComponent extends PaneComponent {
 
         return (
             <div className="pane">
-                <LineContainerComponent title="HELPERS">
-                    <RenderGridPropertyGridComponent scene={scene} />
+                <LineContainerComponent globalState={this.props.globalState} title="HELPERS">
+                    <RenderGridPropertyGridComponent globalState={this.props.globalState} scene={scene} />
                     <CheckBoxLineComponent label="Bones" isSelected={() => this._skeletonViewersEnabled} onSelect={() => this.switchSkeletonViewers()} />
                     <CheckBoxLineComponent label="Physics" isSelected={() => this._physicsViewersEnabled} onSelect={() => this.switchPhysicsViewers()} />
                 </LineContainerComponent>
-                <LineContainerComponent title="TEXTURE CHANNELS">
+                <LineContainerComponent globalState={this.props.globalState} title="TEXTURE CHANNELS">
                     <CheckBoxLineComponent label="Diffuse" isSelected={() => StandardMaterial.DiffuseTextureEnabled} onSelect={() => StandardMaterial.DiffuseTextureEnabled = !StandardMaterial.DiffuseTextureEnabled} />
                     <CheckBoxLineComponent label="Ambient" isSelected={() => StandardMaterial.AmbientTextureEnabled} onSelect={() => StandardMaterial.AmbientTextureEnabled = !StandardMaterial.AmbientTextureEnabled} />
                     <CheckBoxLineComponent label="Specular" isSelected={() => StandardMaterial.SpecularTextureEnabled} onSelect={() => StandardMaterial.SpecularTextureEnabled = !StandardMaterial.SpecularTextureEnabled} />
@@ -128,7 +128,7 @@ export class DebugTabComponent extends PaneComponent {
                     <CheckBoxLineComponent label="Lightmap" isSelected={() => StandardMaterial.LightmapTextureEnabled} onSelect={() => StandardMaterial.LightmapTextureEnabled = !StandardMaterial.LightmapTextureEnabled} />
                     <CheckBoxLineComponent label="Fresnel" isSelected={() => StandardMaterial.FresnelEnabled} onSelect={() => StandardMaterial.FresnelEnabled = !StandardMaterial.FresnelEnabled} />
                 </LineContainerComponent>
-                <LineContainerComponent title="FEATURES">
+                <LineContainerComponent globalState={this.props.globalState} title="FEATURES">
                     <CheckBoxLineComponent label="Animations" isSelected={() => scene.animationsEnabled} onSelect={() => scene.animationsEnabled = !scene.animationsEnabled} />
                     <CheckBoxLineComponent label="Collisions" isSelected={() => scene.collisionsEnabled} onSelect={() => scene.collisionsEnabled = !scene.collisionsEnabled} />
                     <CheckBoxLineComponent label="Fog" isSelected={() => scene.fogEnabled} onSelect={() => scene.fogEnabled = !scene.fogEnabled} />

+ 80 - 4
inspector/src/components/actionTabs/tabs/propertyGridTabComponent.tsx

@@ -65,6 +65,16 @@ import { GridPropertyGridComponent } from "./propertyGrids/gui/gridPropertyGridC
 import { PBRMetallicRoughnessMaterialPropertyGridComponent } from "./propertyGrids/materials/pbrMetallicRoughnessMaterialPropertyGridComponent";
 import { PBRSpecularGlossinessMaterialPropertyGridComponent } from "./propertyGrids/materials/pbrSpecularGlossinessMaterialPropertyGridComponent";
 import { StackPanelPropertyGridComponent } from "./propertyGrids/gui/stackPanelPropertyGridComponent";
+import { PostProcess } from 'babylonjs/PostProcesses/postProcess';
+import { PostProcessPropertyGridComponent } from './propertyGrids/postProcesses/postProcessPropertyGridComponent';
+import { RenderingPipelinePropertyGridComponent } from './propertyGrids/postProcesses/renderingPipelinePropertyGridComponent';
+import { PostProcessRenderPipeline } from 'babylonjs/PostProcesses/RenderPipeline/postProcessRenderPipeline';
+import { DefaultRenderingPipelinePropertyGridComponent } from './propertyGrids/postProcesses/defaultRenderingPipelinePropertyGridComponent';
+import { DefaultRenderingPipeline } from 'babylonjs/PostProcesses/RenderPipeline/Pipelines/defaultRenderingPipeline';
+import { SSAORenderingPipeline } from 'babylonjs/PostProcesses/RenderPipeline/Pipelines/ssaoRenderingPipeline';
+import { SSAORenderingPipelinePropertyGridComponent } from './propertyGrids/postProcesses/ssaoRenderingPipelinePropertyGridComponent';
+import { SSAO2RenderingPipeline } from 'babylonjs/PostProcesses/RenderPipeline/Pipelines/ssao2RenderingPipeline';
+import { SSAO2RenderingPipelinePropertyGridComponent } from './propertyGrids/postProcesses/ssao2RenderingPipelinePropertyGridComponent';
 
 export class PropertyGridTabComponent extends PaneComponent {
     private _timerIntervalId: number;
@@ -105,7 +115,7 @@ export class PropertyGridTabComponent extends PaneComponent {
             if (className.indexOf("Mesh") !== -1) {
                 const mesh = entity as Mesh;
                 if (mesh.getTotalVertices() > 0) {
-                    return (<MeshPropertyGridComponent mesh={mesh}
+                    return (<MeshPropertyGridComponent globalState={this.props.globalState} mesh={mesh}
                         lockObject={this._lockObject}
                         onSelectionChangedObservable={this.props.onSelectionChangedObservable}
                         onPropertyChangedObservable={this.props.onPropertyChangedObservable} />);
@@ -114,14 +124,14 @@ export class PropertyGridTabComponent extends PaneComponent {
 
             if (className.indexOf("FreeCamera") !== -1) {
                 const freeCamera = entity as FreeCamera;
-                return (<FreeCameraPropertyGridComponent camera={freeCamera}
+                return (<FreeCameraPropertyGridComponent globalState={this.props.globalState} camera={freeCamera}
                     lockObject={this._lockObject}
                     onPropertyChangedObservable={this.props.onPropertyChangedObservable} />);
             }
 
             if (className.indexOf("ArcRotateCamera") !== -1) {
                 const arcRotateCamera = entity as ArcRotateCamera;
-                return (<ArcRotateCameraPropertyGridComponent camera={arcRotateCamera}
+                return (<ArcRotateCameraPropertyGridComponent globalState={this.props.globalState} camera={arcRotateCamera}
                     lockObject={this._lockObject}
                     onPropertyChangedObservable={this.props.onPropertyChangedObservable} />);
             }
@@ -129,6 +139,7 @@ export class PropertyGridTabComponent extends PaneComponent {
             if (className === "HemisphericLight") {
                 const hemisphericLight = entity as HemisphericLight;
                 return (<HemisphericLightPropertyGridComponent
+                    globalState={this.props.globalState}
                     light={hemisphericLight}
                     lockObject={this._lockObject}
                     onPropertyChangedObservable={this.props.onPropertyChangedObservable} />);
@@ -137,6 +148,7 @@ export class PropertyGridTabComponent extends PaneComponent {
             if (className === "PointLight") {
                 const pointLight = entity as PointLight;
                 return (<PointLightPropertyGridComponent
+                    globalState={this.props.globalState}
                     light={pointLight}
                     lockObject={this._lockObject}
                     onPropertyChangedObservable={this.props.onPropertyChangedObservable} />);
@@ -145,6 +157,7 @@ export class PropertyGridTabComponent extends PaneComponent {
             if (className.indexOf("TransformNode") !== -1 || className.indexOf("Mesh") !== -1) {
                 const transformNode = entity as TransformNode;
                 return (<TransformNodePropertyGridComponent transformNode={transformNode}
+                    globalState={this.props.globalState}
                     lockObject={this._lockObject}
                     onPropertyChangedObservable={this.props.onPropertyChangedObservable} />);
             }
@@ -152,6 +165,7 @@ export class PropertyGridTabComponent extends PaneComponent {
             if (className === "StandardMaterial") {
                 const material = entity as StandardMaterial;
                 return (<StandardMaterialPropertyGridComponent
+                    globalState={this.props.globalState}
                     material={material}
                     lockObject={this._lockObject}
                     onSelectionChangedObservable={this.props.onSelectionChangedObservable}
@@ -161,6 +175,7 @@ export class PropertyGridTabComponent extends PaneComponent {
             if (className === "PBRMaterial") {
                 const material = entity as PBRMaterial;
                 return (<PBRMaterialPropertyGridComponent
+                    globalState={this.props.globalState}
                     material={material}
                     lockObject={this._lockObject}
                     onSelectionChangedObservable={this.props.onSelectionChangedObservable}
@@ -170,6 +185,7 @@ export class PropertyGridTabComponent extends PaneComponent {
             if (className === "PBRMetallicRoughnessMaterial") {
                 const material = entity as PBRMetallicRoughnessMaterial;
                 return (<PBRMetallicRoughnessMaterialPropertyGridComponent
+                    globalState={this.props.globalState}
                     material={material}
                     lockObject={this._lockObject}
                     onSelectionChangedObservable={this.props.onSelectionChangedObservable}
@@ -179,6 +195,7 @@ export class PropertyGridTabComponent extends PaneComponent {
             if (className === "PBRSpecularGlossinessMaterial") {
                 const material = entity as PBRSpecularGlossinessMaterial;
                 return (<PBRSpecularGlossinessMaterialPropertyGridComponent
+                    globalState={this.props.globalState}
                     material={material}
                     lockObject={this._lockObject}
                     onSelectionChangedObservable={this.props.onSelectionChangedObservable}
@@ -188,6 +205,7 @@ export class PropertyGridTabComponent extends PaneComponent {
             if (className === "BackgroundMaterial") {
                 const material = entity as BackgroundMaterial;
                 return (<BackgroundMaterialPropertyGridComponent
+                    globalState={this.props.globalState}
                     material={material}
                     lockObject={this._lockObject}
                     onSelectionChangedObservable={this.props.onSelectionChangedObservable}
@@ -197,6 +215,7 @@ export class PropertyGridTabComponent extends PaneComponent {
             if (className === "AnimationGroup") {
                 const animationGroup = entity as AnimationGroup;
                 return (<AnimationGroupGridComponent
+                    globalState={this.props.globalState}
                     animationGroup={animationGroup}
                     scene={this.props.scene}
                     lockObject={this._lockObject}
@@ -206,6 +225,47 @@ export class PropertyGridTabComponent extends PaneComponent {
             if (className.indexOf("Material") !== -1) {
                 const material = entity as Material;
                 return (<MaterialPropertyGridComponent material={material}
+                    globalState={this.props.globalState}
+                    lockObject={this._lockObject}
+                    onPropertyChangedObservable={this.props.onPropertyChangedObservable} />);
+            }
+
+            if (className.indexOf("DefaultRenderingPipeline") !== -1) {
+                const renderPipeline = entity as DefaultRenderingPipeline;
+                return (<DefaultRenderingPipelinePropertyGridComponent renderPipeline={renderPipeline}
+                    globalState={this.props.globalState}
+                    lockObject={this._lockObject}
+                    onPropertyChangedObservable={this.props.onPropertyChangedObservable} />);
+            }
+
+            if (className.indexOf("SSAORenderingPipeline") !== -1) {
+                const renderPipeline = entity as SSAORenderingPipeline;
+                return (<SSAORenderingPipelinePropertyGridComponent renderPipeline={renderPipeline}
+                    globalState={this.props.globalState}
+                    lockObject={this._lockObject}
+                    onPropertyChangedObservable={this.props.onPropertyChangedObservable} />);
+            }
+
+            if (className.indexOf("SSAO2RenderingPipeline") !== -1) {
+                const renderPipeline = entity as SSAO2RenderingPipeline;
+                return (<SSAO2RenderingPipelinePropertyGridComponent renderPipeline={renderPipeline}
+                    globalState={this.props.globalState}
+                    lockObject={this._lockObject}
+                    onPropertyChangedObservable={this.props.onPropertyChangedObservable} />);
+            }
+
+            if (className.indexOf("RenderingPipeline") !== -1) {
+                const renderPipeline = entity as PostProcessRenderPipeline;
+                return (<RenderingPipelinePropertyGridComponent renderPipeline={renderPipeline}
+                    globalState={this.props.globalState}
+                    lockObject={this._lockObject}
+                    onPropertyChangedObservable={this.props.onPropertyChangedObservable} />);
+            }
+
+            if (className.indexOf("PostProcess") !== -1) {
+                const postProcess = entity as PostProcess;
+                return (<PostProcessPropertyGridComponent postProcess={postProcess}
+                    globalState={this.props.globalState}
                     lockObject={this._lockObject}
                     onPropertyChangedObservable={this.props.onPropertyChangedObservable} />);
             }
@@ -221,6 +281,7 @@ export class PropertyGridTabComponent extends PaneComponent {
             if (className === "TextBlock") {
                 const textBlock = entity as TextBlock;
                 return (<TextBlockPropertyGridComponent textBlock={textBlock}
+                    globalState={this.props.globalState}
                     lockObject={this._lockObject}
                     onPropertyChangedObservable={this.props.onPropertyChangedObservable} />);
             }
@@ -228,6 +289,7 @@ export class PropertyGridTabComponent extends PaneComponent {
             if (className === "InputText") {
                 const inputText = entity as InputText;
                 return (<InputTextPropertyGridComponent inputText={inputText}
+                    globalState={this.props.globalState}
                     lockObject={this._lockObject}
                     onPropertyChangedObservable={this.props.onPropertyChangedObservable} />);
             }
@@ -235,6 +297,7 @@ export class PropertyGridTabComponent extends PaneComponent {
             if (className === "ColorPicker") {
                 const colorPicker = entity as ColorPicker;
                 return (<ColorPickerPropertyGridComponent colorPicker={colorPicker}
+                    globalState={this.props.globalState}
                     lockObject={this._lockObject}
                     onPropertyChangedObservable={this.props.onPropertyChangedObservable} />);
             }
@@ -242,6 +305,7 @@ export class PropertyGridTabComponent extends PaneComponent {
             if (className === "Image") {
                 const image = entity as Image;
                 return (<ImagePropertyGridComponent image={image}
+                    globalState={this.props.globalState}
                     lockObject={this._lockObject}
                     onPropertyChangedObservable={this.props.onPropertyChangedObservable} />);
             }
@@ -249,6 +313,7 @@ export class PropertyGridTabComponent extends PaneComponent {
             if (className === "Slider") {
                 const slider = entity as Slider;
                 return (<SliderPropertyGridComponent slider={slider}
+                    globalState={this.props.globalState}
                     lockObject={this._lockObject}
                     onPropertyChangedObservable={this.props.onPropertyChangedObservable} />);
             }
@@ -256,6 +321,7 @@ export class PropertyGridTabComponent extends PaneComponent {
             if (className === "ImageBasedSlider") {
                 const imageBasedSlider = entity as ImageBasedSlider;
                 return (<ImageBasedSliderPropertyGridComponent imageBasedSlider={imageBasedSlider}
+                    globalState={this.props.globalState}
                     lockObject={this._lockObject}
                     onPropertyChangedObservable={this.props.onPropertyChangedObservable} />);
             }
@@ -263,6 +329,7 @@ export class PropertyGridTabComponent extends PaneComponent {
             if (className === "Rectangle") {
                 const rectangle = entity as Rectangle;
                 return (<RectanglePropertyGridComponent rectangle={rectangle}
+                    globalState={this.props.globalState}
                     lockObject={this._lockObject}
                     onPropertyChangedObservable={this.props.onPropertyChangedObservable} />);
             }
@@ -270,13 +337,15 @@ export class PropertyGridTabComponent extends PaneComponent {
             if (className === "StackPanel") {
                 const stackPanel = entity as StackPanel;
                 return (<StackPanelPropertyGridComponent stackPanel={stackPanel}
+                    globalState={this.props.globalState}
                     lockObject={this._lockObject}
                     onPropertyChangedObservable={this.props.onPropertyChangedObservable} />);
-            }            
+            }
 
             if (className === "Grid") {
                 const grid = entity as Grid;
                 return (<GridPropertyGridComponent grid={grid}
+                    globalState={this.props.globalState}
                     lockObject={this._lockObject}
                     onPropertyChangedObservable={this.props.onPropertyChangedObservable} />);
             }
@@ -284,6 +353,7 @@ export class PropertyGridTabComponent extends PaneComponent {
             if (className === "ScrollViewer") {
                 const scrollViewer = entity as ScrollViewer;
                 return (<ScrollViewerPropertyGridComponent scrollViewer={scrollViewer}
+                    globalState={this.props.globalState}
                     lockObject={this._lockObject}
                     onPropertyChangedObservable={this.props.onPropertyChangedObservable} />);
             }
@@ -291,6 +361,7 @@ export class PropertyGridTabComponent extends PaneComponent {
             if (className === "Ellipse") {
                 const ellipse = entity as Ellipse;
                 return (<EllipsePropertyGridComponent ellipse={ellipse}
+                    globalState={this.props.globalState}
                     lockObject={this._lockObject}
                     onPropertyChangedObservable={this.props.onPropertyChangedObservable} />);
             }
@@ -298,6 +369,7 @@ export class PropertyGridTabComponent extends PaneComponent {
             if (className === "Checkbox") {
                 const checkbox = entity as Checkbox;
                 return (<CheckboxPropertyGridComponent checkbox={checkbox}
+                    globalState={this.props.globalState}
                     lockObject={this._lockObject}
                     onPropertyChangedObservable={this.props.onPropertyChangedObservable} />);
             }
@@ -305,6 +377,7 @@ export class PropertyGridTabComponent extends PaneComponent {
             if (className === "RadioButton") {
                 const radioButton = entity as RadioButton;
                 return (<RadioButtonPropertyGridComponent radioButton={radioButton}
+                    globalState={this.props.globalState}
                     lockObject={this._lockObject}
                     onPropertyChangedObservable={this.props.onPropertyChangedObservable} />);
             }
@@ -312,6 +385,7 @@ export class PropertyGridTabComponent extends PaneComponent {
             if (className === "Line") {
                 const line = entity as Line;
                 return (<LinePropertyGridComponent line={line}
+                    globalState={this.props.globalState}
                     lockObject={this._lockObject}
                     onPropertyChangedObservable={this.props.onPropertyChangedObservable} />);
             }
@@ -319,12 +393,14 @@ export class PropertyGridTabComponent extends PaneComponent {
             if (entity._host) {
                 const control = entity as Control;
                 return (<ControlPropertyGridComponent control={control}
+                    globalState={this.props.globalState}
                     lockObject={this._lockObject}
                     onPropertyChangedObservable={this.props.onPropertyChangedObservable} />);
             }
         } else if (entity.transformNodes) {
             const scene = entity as Scene;
             return (<ScenePropertyGridComponent scene={scene}
+                globalState={this.props.globalState}
                 lockObject={this._lockObject}
                 onSelectionChangedObservable={this.props.onSelectionChangedObservable}
                 onPropertyChangedObservable={this.props.onPropertyChangedObservable} />);

+ 4 - 2
inspector/src/components/actionTabs/tabs/propertyGrids/animationGroupPropertyGridComponent.tsx

@@ -11,8 +11,10 @@ import { LineContainerComponent } from "../../lineContainerComponent";
 import { TextLineComponent } from "../../lines/textLineComponent";
 import { SliderLineComponent } from "../../lines/sliderLineComponent";
 import { LockObject } from "./lockObject";
+import { GlobalState } from '../../../globalState';
 
 interface IAnimationGroupGridComponentProps {
+    globalState: GlobalState;
     animationGroup: AnimationGroup,
     scene: Scene,
     lockObject: LockObject,
@@ -127,12 +129,12 @@ export class AnimationGroupGridComponent extends React.Component<IAnimationGroup
 
         return (
             <div className="pane">
-                <LineContainerComponent title="CONTROLS">
+                <LineContainerComponent globalState={this.props.globalState} title="CONTROLS">
                     <ButtonLineComponent label={playButtonText} onClick={() => this.playOrPause()} />
                     <SliderLineComponent label="Speed ratio" minimum={0} maximum={10} step={0.1} target={animationGroup} propertyName="speedRatio" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
                     <SliderLineComponent ref="timeline" label="Current frame" minimum={animationGroup.from} maximum={animationGroup.to} step={(animationGroup.to - animationGroup.from) / 1000.0} directValue={this.state.currentFrame} onInput={value => this.onCurrentFrameChange(value)} />
                 </LineContainerComponent>
-                <LineContainerComponent title="INFOS">
+                <LineContainerComponent globalState={this.props.globalState} title="INFOS">
                     <TextLineComponent label="Animation count" value={animationGroup.targetedAnimations.length.toString()} />
                     <TextLineComponent label="From" value={animationGroup.from.toFixed(2)} />
                     <TextLineComponent label="To" value={animationGroup.to.toFixed(2)} />

+ 11 - 9
inspector/src/components/actionTabs/tabs/propertyGrids/cameras/arcRotateCameraPropertyGridComponent.tsx

@@ -11,11 +11,13 @@ import { FloatLineComponent } from "../../../lines/floatLineComponent";
 import { SliderLineComponent } from "../../../lines/sliderLineComponent";
 import { Vector3LineComponent } from "../../../lines/vector3LineComponent";
 import { LockObject } from "../lockObject";
+import { GlobalState } from '../../../../globalState';
 
 interface IArcRotateCameraPropertyGridComponentProps {
-    camera: ArcRotateCamera,
-    lockObject: LockObject,
-    onPropertyChangedObservable?: Observable<PropertyChangedEvent>
+    globalState: GlobalState;
+    camera: ArcRotateCamera;
+    lockObject: LockObject;
+    onPropertyChangedObservable?: Observable<PropertyChangedEvent>;
 }
 
 export class ArcRotateCameraPropertyGridComponent extends React.Component<IArcRotateCameraPropertyGridComponentProps> {
@@ -28,13 +30,13 @@ export class ArcRotateCameraPropertyGridComponent extends React.Component<IArcRo
 
         return (
             <div className="pane">
-                <CommonCameraPropertyGridComponent lockObject={this.props.lockObject} camera={camera} onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
-                <LineContainerComponent title="TRANSFORMS">
+                <CommonCameraPropertyGridComponent globalState={this.props.globalState} lockObject={this.props.lockObject} camera={camera} onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
+                <LineContainerComponent globalState={this.props.globalState} title="TRANSFORMS">
                     <SliderLineComponent label="Alpha" target={camera} propertyName="alpha" minimum={camera.lowerAlphaLimit || 0} maximum={camera.upperAlphaLimit || 2 * Math.PI} step={0.01} onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
                     <SliderLineComponent label="Beta" target={camera} propertyName="beta" minimum={camera.lowerAlphaLimit || 0} maximum={camera.upperBetaLimit || 2 * Math.PI} step={0.01} onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
                     <FloatLineComponent lockObject={this.props.lockObject} label="Radius" target={camera} propertyName="radius" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
                 </LineContainerComponent>
-                <LineContainerComponent title="CONTROLS" closed={true}>
+                <LineContainerComponent globalState={this.props.globalState} title="CONTROLS" closed={true}>
                     <FloatLineComponent lockObject={this.props.lockObject} label="Angular sensitivity X" target={camera} propertyName="angularSensibilityX" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
                     <FloatLineComponent lockObject={this.props.lockObject} label="Angular sensitivity Y" target={camera} propertyName="angularSensibilityY" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
                     <FloatLineComponent lockObject={this.props.lockObject} label="Panning sensitivity" target={camera} propertyName="panningSensibility" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
@@ -42,11 +44,11 @@ export class ArcRotateCameraPropertyGridComponent extends React.Component<IArcRo
                     <FloatLineComponent lockObject={this.props.lockObject} label="Wheel delta percentage" target={camera} propertyName="wheelDeltaPercentage" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
                     <FloatLineComponent lockObject={this.props.lockObject} label="Speed" target={camera} propertyName="speed" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
                 </LineContainerComponent>
-                <LineContainerComponent title="COLLISIONS" closed={true}>
+                <LineContainerComponent globalState={this.props.globalState} title="COLLISIONS" closed={true}>
                     <CheckBoxLineComponent label="Check collisions" target={camera} propertyName="checkCollisions" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
                     <Vector3LineComponent label="Collision radius" target={camera} propertyName="collisionRadius" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
                 </LineContainerComponent>
-                <LineContainerComponent title="LIMITS" closed={true}>
+                <LineContainerComponent globalState={this.props.globalState} title="LIMITS" closed={true}>
                     <FloatLineComponent lockObject={this.props.lockObject} label="Lower alpha limit" target={camera} propertyName="lowerAlphaLimit" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
                     <FloatLineComponent lockObject={this.props.lockObject} label="Upper alpha limit" target={camera} propertyName="upperAlphaLimit" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
                     <FloatLineComponent lockObject={this.props.lockObject} label="Lower beta limit" target={camera} propertyName="lowerBetaLimit" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
@@ -54,7 +56,7 @@ export class ArcRotateCameraPropertyGridComponent extends React.Component<IArcRo
                     <FloatLineComponent lockObject={this.props.lockObject} label="Lower radius limit" target={camera} propertyName="lowerRadiusLimit" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
                     <FloatLineComponent lockObject={this.props.lockObject} label="Upper radius limit" target={camera} propertyName="upperRadiusLimit" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
                 </LineContainerComponent>
-                <LineContainerComponent title="BEHAVIORS" closed={true}>
+                <LineContainerComponent globalState={this.props.globalState} title="BEHAVIORS" closed={true}>
                     <CheckBoxLineComponent label="Auto rotation" target={camera} propertyName="useAutoRotationBehavior" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
                     <CheckBoxLineComponent label="Bouncing" target={camera} propertyName="useBouncingBehavior" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
                     <CheckBoxLineComponent label="Framing" target={camera} propertyName="useFramingBehavior" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />

+ 3 - 1
inspector/src/components/actionTabs/tabs/propertyGrids/cameras/commonCameraPropertyGridComponent.tsx

@@ -8,8 +8,10 @@ import { FloatLineComponent } from "../../../lines/floatLineComponent";
 import { TextLineComponent } from "../../../lines/textLineComponent";
 import { OptionsLineComponent } from "../../../lines/optionsLineComponent";
 import { LockObject } from "../lockObject";
+import { GlobalState } from '../../../../globalState';
 
 interface ICommonCameraPropertyGridComponentProps {
+    globalState: GlobalState;
     camera: Camera;
     lockObject: LockObject;
     onPropertyChangedObservable?: Observable<PropertyChangedEvent>;
@@ -31,7 +33,7 @@ export class CommonCameraPropertyGridComponent extends React.Component<ICommonCa
         ];
 
         return (
-            <LineContainerComponent title="GENERAL">
+            <LineContainerComponent globalState={this.props.globalState} title="GENERAL">
                 <TextLineComponent label="ID" value={camera.id} />
                 <TextLineComponent label="Unique ID" value={camera.uniqueId.toString()} />
                 <TextLineComponent label="Class" value={camera.getClassName()} />

+ 9 - 7
inspector/src/components/actionTabs/tabs/propertyGrids/cameras/freeCameraPropertyGridComponent.tsx

@@ -8,11 +8,13 @@ import { Vector3LineComponent } from "../../../lines/vector3LineComponent";
 import { FloatLineComponent } from "../../../lines/floatLineComponent";
 import { CheckBoxLineComponent } from "../../../lines/checkBoxLineComponent";
 import { LockObject } from "../lockObject";
+import { GlobalState } from '../../../../globalState';
 
 interface IFreeCameraPropertyGridComponentProps {
-    camera: FreeCamera,
-    lockObject: LockObject,
-    onPropertyChangedObservable?: Observable<PropertyChangedEvent>
+    globalState: GlobalState;
+    camera: FreeCamera;
+    lockObject: LockObject;
+    onPropertyChangedObservable?: Observable<PropertyChangedEvent>;
 }
 
 export class FreeCameraPropertyGridComponent extends React.Component<IFreeCameraPropertyGridComponentProps> {
@@ -25,15 +27,15 @@ export class FreeCameraPropertyGridComponent extends React.Component<IFreeCamera
 
         return (
             <div className="pane">
-                <CommonCameraPropertyGridComponent lockObject={this.props.lockObject} camera={camera} onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
-                <LineContainerComponent title="TRANSFORMS">
+                <CommonCameraPropertyGridComponent globalState={this.props.globalState} lockObject={this.props.lockObject} camera={camera} onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
+                <LineContainerComponent globalState={this.props.globalState} title="TRANSFORMS">
                     <Vector3LineComponent label="Position" target={camera} propertyName="position" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
                 </LineContainerComponent>
-                <LineContainerComponent title="CONTROLS" closed={true}>
+                <LineContainerComponent globalState={this.props.globalState} title="CONTROLS" closed={true}>
                     <FloatLineComponent lockObject={this.props.lockObject} label="Angular sensitivity" target={camera} propertyName="angularSensibility" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
                     <FloatLineComponent lockObject={this.props.lockObject} label="Speed" target={camera} propertyName="speed" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
                 </LineContainerComponent>
-                <LineContainerComponent title="COLLISIONS" closed={true}>
+                <LineContainerComponent globalState={this.props.globalState} title="COLLISIONS" closed={true}>
                     <CheckBoxLineComponent label="Check collisions" target={camera} propertyName="checkCollisions" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
                     <CheckBoxLineComponent label="Apply gravity" target={camera} propertyName="applYGravity" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
                     <Vector3LineComponent label="Ellipsoid" target={camera} propertyName="ellipsoid" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />

+ 2 - 0
inspector/src/components/actionTabs/tabs/propertyGrids/fogPropertyGridComponent.tsx

@@ -7,8 +7,10 @@ import { Color3LineComponent } from "../../lines/color3LineComponent";
 import { FloatLineComponent } from "../../lines/floatLineComponent";
 import { OptionsLineComponent } from "../../lines/optionsLineComponent";
 import { LockObject } from "./lockObject";
+import { GlobalState } from '../../../globalState';
 
 interface IFogPropertyGridComponentProps {
+    globalState: GlobalState;
     scene: Scene;
     lockObject: LockObject;
     onPropertyChangedObservable?: Observable<PropertyChangedEvent>;

+ 7 - 5
inspector/src/components/actionTabs/tabs/propertyGrids/gui/checkboxPropertyGridComponent.tsx

@@ -7,11 +7,13 @@ import { Checkbox } from "babylonjs-gui/2D/controls/checkbox";
 import { LineContainerComponent } from "../../../lineContainerComponent";
 import { FloatLineComponent } from "../../../lines/floatLineComponent";
 import { CheckBoxLineComponent } from "../../../lines/checkBoxLineComponent";
+import { GlobalState } from '../../../../globalState';
 
 interface ICheckboxPropertyGridComponentProps {
-    checkbox: Checkbox,
-    lockObject: LockObject,
-    onPropertyChangedObservable?: Observable<PropertyChangedEvent>
+    globalState: GlobalState;
+    checkbox: Checkbox;
+    lockObject: LockObject;
+    onPropertyChangedObservable?: Observable<PropertyChangedEvent>;
 }
 
 export class CheckboxPropertyGridComponent extends React.Component<ICheckboxPropertyGridComponentProps> {
@@ -24,8 +26,8 @@ export class CheckboxPropertyGridComponent extends React.Component<ICheckboxProp
 
         return (
             <div className="pane">
-                <CommonControlPropertyGridComponent lockObject={this.props.lockObject} control={checkbox} onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
-                <LineContainerComponent title="CHECKBOX">
+                <CommonControlPropertyGridComponent globalState={this.props.globalState} lockObject={this.props.lockObject} control={checkbox} onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
+                <LineContainerComponent globalState={this.props.globalState} title="CHECKBOX">
                     <FloatLineComponent lockObject={this.props.lockObject} label="Check size ratio" target={checkbox} propertyName="checkSizeRatio" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
                     <CheckBoxLineComponent label="Checked" target={checkbox} propertyName="isChecked" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
                 </LineContainerComponent>

+ 4 - 2
inspector/src/components/actionTabs/tabs/propertyGrids/gui/colorPickerPropertyGridComponent.tsx

@@ -6,8 +6,10 @@ import { LineContainerComponent } from "../../../lineContainerComponent";
 import { ColorPicker } from "babylonjs-gui/2D/controls/colorpicker";
 import { Color3LineComponent } from "../../../lines/color3LineComponent";
 import { LockObject } from "../lockObject";
+import { GlobalState } from '../../../../globalState';
 
 interface IColorPickerPropertyGridComponentProps {
+    globalState: GlobalState;
     colorPicker: ColorPicker;
     lockObject: LockObject;
     onPropertyChangedObservable?: Observable<PropertyChangedEvent>;
@@ -23,8 +25,8 @@ export class ColorPickerPropertyGridComponent extends React.Component<IColorPick
 
         return (
             <div className="pane">
-                <CommonControlPropertyGridComponent lockObject={this.props.lockObject} control={colorPicker} onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
-                <LineContainerComponent title="COLORPICKER">
+                <CommonControlPropertyGridComponent globalState={this.props.globalState} lockObject={this.props.lockObject} control={colorPicker} onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
+                <LineContainerComponent globalState={this.props.globalState} title="COLORPICKER">
                     <Color3LineComponent label="Color" target={colorPicker} propertyName="value" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
                 </LineContainerComponent>
             </div>

+ 9 - 7
inspector/src/components/actionTabs/tabs/propertyGrids/gui/commonControlPropertyGridComponent.tsx

@@ -10,8 +10,10 @@ import { FloatLineComponent } from "../../../lines/floatLineComponent";
 import { TextInputLineComponent } from "../../../lines/textInputLineComponent";
 import { LockObject } from "../lockObject";
 import { OptionsLineComponent } from "../../../lines/optionsLineComponent";
+import { GlobalState } from '../../../../globalState';
 
 interface ICommonControlPropertyGridComponentProps {
+    globalState: GlobalState;
     control: Control;
     lockObject: LockObject;
     onPropertyChangedObservable?: Observable<PropertyChangedEvent>;
@@ -39,7 +41,7 @@ export class CommonControlPropertyGridComponent extends React.Component<ICommonC
         const cellInfos = grid.getChildCellInfo(control).split(":");
 
         return (
-            <LineContainerComponent title="GRID">
+            <LineContainerComponent globalState={this.props.globalState} title="GRID">
                 <TextLineComponent label={"Row"} value={cellInfos[0]} />
                 <TextLineComponent label={"Column"} value={cellInfos[1]} />
             </LineContainerComponent>
@@ -63,7 +65,7 @@ export class CommonControlPropertyGridComponent extends React.Component<ICommonC
 
         return (
             <div>
-                <LineContainerComponent title="GENERAL">
+                <LineContainerComponent globalState={this.props.globalState} title="GENERAL">
                     <TextLineComponent label="Class" value={control.getClassName()} />
                     <TextLineComponent label="Unique ID" value={control.uniqueId.toString()} />
                     <SliderLineComponent label="Alpha" target={control} propertyName="alpha" minimum={0} maximum={1} step={0.01} onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
@@ -79,11 +81,11 @@ export class CommonControlPropertyGridComponent extends React.Component<ICommonC
                 {
                     this.renderGridInformation()
                 }
-                <LineContainerComponent title="ALIGNMENT">
+                <LineContainerComponent globalState={this.props.globalState} title="ALIGNMENT">
                     <OptionsLineComponent label="Horizontal" options={horizontalOptions} target={control} propertyName="horizontalAlignment" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
                     <OptionsLineComponent label="Vertical" options={verticalOptions} target={control} propertyName="verticalAlignment" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
                 </LineContainerComponent>
-                <LineContainerComponent title="POSITION">
+                <LineContainerComponent globalState={this.props.globalState} title="POSITION">
                     <TextInputLineComponent lockObject={this.props.lockObject} label="Left" target={control} propertyName="left" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
                     <TextInputLineComponent lockObject={this.props.lockObject} label="Top" target={control} propertyName="top" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
                     <TextInputLineComponent lockObject={this.props.lockObject} label="Width" target={control} propertyName="width" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
@@ -93,20 +95,20 @@ export class CommonControlPropertyGridComponent extends React.Component<ICommonC
                     <TextInputLineComponent lockObject={this.props.lockObject} label="Padding right" target={control} propertyName="paddingRight" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
                     <TextInputLineComponent lockObject={this.props.lockObject} label="Padding bottom" target={control} propertyName="paddingBottom" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
                 </LineContainerComponent>
-                <LineContainerComponent title="TRANSFORMATION" closed={true}>
+                <LineContainerComponent globalState={this.props.globalState} title="TRANSFORMATION" closed={true}>
                     <FloatLineComponent lockObject={this.props.lockObject} label="ScaleX" target={control} propertyName="scaleX" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
                     <FloatLineComponent lockObject={this.props.lockObject} label="ScaleY" target={control} propertyName="scaleY" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
                     <SliderLineComponent label="Rotation" target={control} propertyName="rotation" minimum={0} maximum={2 * Math.PI} step={0.01} onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
                     <FloatLineComponent lockObject={this.props.lockObject} label="Transform center X" target={control} propertyName="transformCenterX" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
                     <FloatLineComponent lockObject={this.props.lockObject} label="Transform center Y" target={control} propertyName="transformCenterY" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
                 </LineContainerComponent>
-                <LineContainerComponent title="FONT" closed={true}>
+                <LineContainerComponent globalState={this.props.globalState} title="FONT" closed={true}>
                     <TextInputLineComponent lockObject={this.props.lockObject} label="Family" target={control} propertyName="fontFamily" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
                     <TextInputLineComponent lockObject={this.props.lockObject} label="Size" target={control} propertyName="fontSize" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
                     <TextInputLineComponent lockObject={this.props.lockObject} label="Weight" target={control} propertyName="fontWeight" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
                     <TextInputLineComponent lockObject={this.props.lockObject} label="Style" target={control} propertyName="fontStyle" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
                 </LineContainerComponent>
-                <LineContainerComponent title="SHADOWS" closed={true}>
+                <LineContainerComponent globalState={this.props.globalState} title="SHADOWS" closed={true}>
                     <TextInputLineComponent lockObject={this.props.lockObject} label="Color" target={control} propertyName="shadowColor" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
                     <FloatLineComponent lockObject={this.props.lockObject} label="Offset X" target={control} propertyName="shadowOffsetX" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
                     <FloatLineComponent lockObject={this.props.lockObject} label="Offset Y" target={control} propertyName="shadowOffsetY" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />

+ 3 - 1
inspector/src/components/actionTabs/tabs/propertyGrids/gui/controlPropertyGridComponent.tsx

@@ -3,9 +3,11 @@ import { Observable } from "babylonjs/Misc/observable";
 import { PropertyChangedEvent } from "../../../../propertyChangedEvent";
 import { Control } from "babylonjs-gui/2D/controls/control";
 import { CommonControlPropertyGridComponent } from "./commonControlPropertyGridComponent";
+import { GlobalState } from '../../../../globalState';
 import { LockObject } from "../lockObject";
 
 interface IControlPropertyGridComponentProps {
+    globalState: GlobalState;
     control: Control,
     lockObject: LockObject,
     onPropertyChangedObservable?: Observable<PropertyChangedEvent>
@@ -21,7 +23,7 @@ export class ControlPropertyGridComponent extends React.Component<IControlProper
 
         return (
             <div className="pane">
-                <CommonControlPropertyGridComponent lockObject={this.props.lockObject} control={control} onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
+                <CommonControlPropertyGridComponent globalState={this.props.globalState} lockObject={this.props.lockObject} control={control} onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
             </div>
         );
     }

+ 4 - 2
inspector/src/components/actionTabs/tabs/propertyGrids/gui/ellipsePropertyGridComponent.tsx

@@ -7,8 +7,10 @@ import { Ellipse } from "babylonjs-gui/2D/controls/ellipse";
 import { LineContainerComponent } from "../../../lineContainerComponent";
 import { FloatLineComponent } from "../../../lines/floatLineComponent";
 import { CheckBoxLineComponent } from "../../../lines/checkBoxLineComponent";
+import { GlobalState } from '../../../../globalState';
 
 interface IEllipsePropertyGridComponentProps {
+    globalState: GlobalState;
     ellipse: Ellipse,
     lockObject: LockObject,
     onPropertyChangedObservable?: Observable<PropertyChangedEvent>
@@ -24,8 +26,8 @@ export class EllipsePropertyGridComponent extends React.Component<IEllipseProper
 
         return (
             <div className="pane">
-                <CommonControlPropertyGridComponent lockObject={this.props.lockObject} control={ellipse} onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
-                <LineContainerComponent title="ELLIPSE">
+                <CommonControlPropertyGridComponent globalState={this.props.globalState} lockObject={this.props.lockObject} control={ellipse} onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
+                <LineContainerComponent globalState={this.props.globalState} title="ELLIPSE">
                     <CheckBoxLineComponent label="Clip children" target={ellipse} propertyName="clipChildren" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
                     <FloatLineComponent lockObject={this.props.lockObject} label="Thickness" target={ellipse} propertyName="thickness" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
                 </LineContainerComponent>

+ 4 - 2
inspector/src/components/actionTabs/tabs/propertyGrids/gui/gridPropertyGridComponent.tsx

@@ -6,8 +6,10 @@ import { LockObject } from "../lockObject";
 import { Grid } from "babylonjs-gui/2D/controls/grid";
 import { LineContainerComponent } from "../../../lineContainerComponent";
 import { TextLineComponent } from "../../../lines/textLineComponent";
+import { GlobalState } from '../../../../globalState';
 
 interface IGridPropertyGridComponentProps {
+    globalState: GlobalState;
     grid: Grid,
     lockObject: LockObject,
     onPropertyChangedObservable?: Observable<PropertyChangedEvent>
@@ -65,8 +67,8 @@ export class GridPropertyGridComponent extends React.Component<IGridPropertyGrid
 
         return (
             <div className="pane">
-                <CommonControlPropertyGridComponent lockObject={this.props.lockObject} control={grid} onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
-                <LineContainerComponent title="GRID">
+                <CommonControlPropertyGridComponent globalState={this.props.globalState} lockObject={this.props.lockObject} control={grid} onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
+                <LineContainerComponent globalState={this.props.globalState} title="GRID">
                     {
                         this.renderRows()
                     }

+ 4 - 2
inspector/src/components/actionTabs/tabs/propertyGrids/gui/imageBasedSliderPropertyGridComponent.tsx

@@ -8,8 +8,10 @@ import { ImageBasedSlider } from "babylonjs-gui/2D/controls/sliders/imageBasedSl
 import { FloatLineComponent } from "../../../lines/floatLineComponent";
 import { CheckBoxLineComponent } from "../../../lines/checkBoxLineComponent";
 import { TextInputLineComponent } from "../../../lines/textInputLineComponent";
+import { GlobalState } from '../../../../globalState';
 
 interface IImageBasedSliderPropertyGridComponentProps {
+    globalState: GlobalState;
     imageBasedSlider: ImageBasedSlider,
     lockObject: LockObject,
     onPropertyChangedObservable?: Observable<PropertyChangedEvent>
@@ -25,8 +27,8 @@ export class ImageBasedSliderPropertyGridComponent extends React.Component<IImag
 
         return (
             <div className="pane">
-                <CommonControlPropertyGridComponent lockObject={this.props.lockObject} control={imageBasedSlider} onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
-                <LineContainerComponent title="IMAGE BASED SLIDER">
+                <CommonControlPropertyGridComponent globalState={this.props.globalState} lockObject={this.props.lockObject} control={imageBasedSlider} onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
+                <LineContainerComponent globalState={this.props.globalState} title="IMAGE BASED SLIDER">
                     <CheckBoxLineComponent label="Display thumb" target={imageBasedSlider} propertyName="displayThumb" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
                     <CheckBoxLineComponent label="Vertical" target={imageBasedSlider} propertyName="isVertical" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
                     <CheckBoxLineComponent label="Thumb clamped" target={imageBasedSlider} propertyName="isThumbClamped" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />

+ 5 - 3
inspector/src/components/actionTabs/tabs/propertyGrids/gui/imagePropertyGridComponent.tsx

@@ -8,8 +8,10 @@ import { Image } from "babylonjs-gui/2D/controls/image";
 import { FloatLineComponent } from "../../../lines/floatLineComponent";
 import { CheckBoxLineComponent } from "../../../lines/checkBoxLineComponent";
 import { OptionsLineComponent } from "../../../lines/optionsLineComponent";
+import { GlobalState } from '../../../../globalState';
 
 interface IImagePropertyGridComponentProps {
+    globalState: GlobalState;
     image: Image,
     lockObject: LockObject,
     onPropertyChangedObservable?: Observable<PropertyChangedEvent>
@@ -33,8 +35,8 @@ export class ImagePropertyGridComponent extends React.Component<IImagePropertyGr
 
         return (
             <div className="pane">
-                <CommonControlPropertyGridComponent lockObject={this.props.lockObject} control={image} onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
-                <LineContainerComponent title="IMAGE">
+                <CommonControlPropertyGridComponent globalState={this.props.globalState} lockObject={this.props.lockObject} control={image} onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
+                <LineContainerComponent globalState={this.props.globalState} title="IMAGE">
                     <FloatLineComponent lockObject={this.props.lockObject} label="Source left" target={image} propertyName="sourceLeft" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
                     <FloatLineComponent lockObject={this.props.lockObject} label="Source top" target={image} propertyName="sourceTop" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
                     <FloatLineComponent lockObject={this.props.lockObject} label="Source width" target={image} propertyName="sourceWidth" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
@@ -42,7 +44,7 @@ export class ImagePropertyGridComponent extends React.Component<IImagePropertyGr
                     <CheckBoxLineComponent label="Autoscale" target={image} propertyName="autoScale" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
                     <OptionsLineComponent label="Stretch" options={stretchOptions} target={image} propertyName="stretch" onPropertyChangedObservable={this.props.onPropertyChangedObservable} onSelect={value => this.setState({ mode: value })} />
                 </LineContainerComponent>
-                <LineContainerComponent title="ANIMATION SHEET">
+                <LineContainerComponent globalState={this.props.globalState} title="ANIMATION SHEET">
                     <FloatLineComponent lockObject={this.props.lockObject} label="Cell Id" isInteger={true} target={image} propertyName="cellId" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
                     <FloatLineComponent lockObject={this.props.lockObject} label="Cell width" target={image} propertyName="cellWidth" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
                     <FloatLineComponent lockObject={this.props.lockObject} label="Cell height" target={image} propertyName="cellHeight" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />

+ 4 - 2
inspector/src/components/actionTabs/tabs/propertyGrids/gui/inputTextPropertyGridComponent.tsx

@@ -9,8 +9,10 @@ import { SliderLineComponent } from "../../../lines/sliderLineComponent";
 import { CheckBoxLineComponent } from "../../../lines/checkBoxLineComponent";
 import { FloatLineComponent } from "../../../lines/floatLineComponent";
 import { LockObject } from "../lockObject";
+import { GlobalState } from '../../../../globalState';
 
 interface IInputTextPropertyGridComponentProps {
+    globalState: GlobalState;
     inputText: InputText;
     lockObject: LockObject;
     onPropertyChangedObservable?: Observable<PropertyChangedEvent>;
@@ -26,8 +28,8 @@ export class InputTextPropertyGridComponent extends React.Component<IInputTextPr
 
         return (
             <div className="pane">
-                <CommonControlPropertyGridComponent lockObject={this.props.lockObject} control={inputText} onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
-                <LineContainerComponent title="INPUTTEXT">
+                <CommonControlPropertyGridComponent globalState={this.props.globalState} lockObject={this.props.lockObject} control={inputText} onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
+                <LineContainerComponent globalState={this.props.globalState} title="INPUTTEXT">
                     <TextInputLineComponent lockObject={this.props.lockObject} label="Text" target={inputText} propertyName="text" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
                     <TextInputLineComponent lockObject={this.props.lockObject} label="Prompt" target={inputText} propertyName="promptMessage" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
                     <TextInputLineComponent lockObject={this.props.lockObject} label="Max width" target={inputText} propertyName="maxWidth" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />

+ 4 - 2
inspector/src/components/actionTabs/tabs/propertyGrids/gui/linePropertyGridComponent.tsx

@@ -7,8 +7,10 @@ import { Line } from "babylonjs-gui/2D/controls/line";
 import { LineContainerComponent } from "../../../lineContainerComponent";
 import { FloatLineComponent } from "../../../lines/floatLineComponent";
 import { TextInputLineComponent } from "../../../lines/textInputLineComponent";
+import { GlobalState } from '../../../../globalState';
 
 interface ILinePropertyGridComponentProps {
+    globalState: GlobalState;
     line: Line,
     lockObject: LockObject,
     onPropertyChangedObservable?: Observable<PropertyChangedEvent>
@@ -40,8 +42,8 @@ export class LinePropertyGridComponent extends React.Component<ILinePropertyGrid
 
         return (
             <div className="pane">
-                <CommonControlPropertyGridComponent lockObject={this.props.lockObject} control={line} onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
-                <LineContainerComponent title="LINE">
+                <CommonControlPropertyGridComponent globalState={this.props.globalState} lockObject={this.props.lockObject} control={line} onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
+                <LineContainerComponent globalState={this.props.globalState} title="LINE">
                     <FloatLineComponent lockObject={this.props.lockObject} label="Line width" target={line} propertyName="lineWidth" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
                     <TextInputLineComponent lockObject={this.props.lockObject} label="X1" target={line} propertyName="x1" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
                     <TextInputLineComponent lockObject={this.props.lockObject} label="Y1" target={line} propertyName="y1" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />

+ 4 - 2
inspector/src/components/actionTabs/tabs/propertyGrids/gui/radioButtonPropertyGridComponent.tsx

@@ -8,8 +8,10 @@ import { LineContainerComponent } from "../../../lineContainerComponent";
 import { FloatLineComponent } from "../../../lines/floatLineComponent";
 import { TextInputLineComponent } from "../../../lines/textInputLineComponent";
 import { CheckBoxLineComponent } from "../../../lines/checkBoxLineComponent";
+import { GlobalState } from '../../../../globalState';
 
 interface IRadioButtonPropertyGridComponentProps {
+    globalState: GlobalState;
     radioButton: RadioButton,
     lockObject: LockObject,
     onPropertyChangedObservable?: Observable<PropertyChangedEvent>
@@ -25,8 +27,8 @@ export class RadioButtonPropertyGridComponent extends React.Component<IRadioButt
 
         return (
             <div className="pane">
-                <CommonControlPropertyGridComponent lockObject={this.props.lockObject} control={radioButton} onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
-                <LineContainerComponent title="RADIO BUTTON">
+                <CommonControlPropertyGridComponent globalState={this.props.globalState} lockObject={this.props.lockObject} control={radioButton} onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
+                <LineContainerComponent globalState={this.props.globalState} title="RADIO BUTTON">
                     <FloatLineComponent lockObject={this.props.lockObject} label="Thickness" target={radioButton} propertyName="thickness" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
                     <FloatLineComponent lockObject={this.props.lockObject} label="Check size ratio" target={radioButton} propertyName="checkSizeRatio" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
                     <TextInputLineComponent lockObject={this.props.lockObject} label="Group" target={radioButton} propertyName="group" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />

+ 4 - 2
inspector/src/components/actionTabs/tabs/propertyGrids/gui/rectanglePropertyGridComponent.tsx

@@ -7,8 +7,10 @@ import { Rectangle } from "babylonjs-gui/2D/controls/rectangle";
 import { LineContainerComponent } from "../../../lineContainerComponent";
 import { FloatLineComponent } from "../../../lines/floatLineComponent";
 import { CheckBoxLineComponent } from "../../../lines/checkBoxLineComponent";
+import { GlobalState } from '../../../../globalState';
 
 interface IRectanglePropertyGridComponentProps {
+    globalState: GlobalState;
     rectangle: Rectangle,
     lockObject: LockObject,
     onPropertyChangedObservable?: Observable<PropertyChangedEvent>
@@ -24,8 +26,8 @@ export class RectanglePropertyGridComponent extends React.Component<IRectanglePr
 
         return (
             <div className="pane">
-                <CommonControlPropertyGridComponent lockObject={this.props.lockObject} control={rectangle} onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
-                <LineContainerComponent title="RECTANGLE">
+                <CommonControlPropertyGridComponent globalState={this.props.globalState} lockObject={this.props.lockObject} control={rectangle} onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
+                <LineContainerComponent globalState={this.props.globalState} title="RECTANGLE">
                     <CheckBoxLineComponent label="Clip children" target={rectangle} propertyName="clipChildren" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
                     <FloatLineComponent lockObject={this.props.lockObject} label="Thickness" target={rectangle} propertyName="thickness" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
                     <FloatLineComponent lockObject={this.props.lockObject} label="Corner radius" target={rectangle} propertyName="cornerRadius" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />

+ 5 - 3
inspector/src/components/actionTabs/tabs/propertyGrids/gui/scrollViewerPropertyGridComponent.tsx

@@ -7,8 +7,10 @@ import { ScrollViewer } from "babylonjs-gui/2D/controls/scrollViewers/scrollView
 import { LineContainerComponent } from "../../../lineContainerComponent";
 import { FloatLineComponent } from "../../../lines/floatLineComponent";
 import { TextInputLineComponent } from "../../../lines/textInputLineComponent";
+import { GlobalState } from '../../../../globalState';
 
 interface IScrollViewerPropertyGridComponentProps {
+    globalState: GlobalState;
     scrollViewer: ScrollViewer,
     lockObject: LockObject,
     onPropertyChangedObservable?: Observable<PropertyChangedEvent>
@@ -24,12 +26,12 @@ export class ScrollViewerPropertyGridComponent extends React.Component<IScrollVi
 
         return (
             <div className="pane">
-                <CommonControlPropertyGridComponent lockObject={this.props.lockObject} control={scrollViewer} onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
-                <LineContainerComponent title="RECTANGLE">
+                <CommonControlPropertyGridComponent globalState={this.props.globalState} lockObject={this.props.lockObject} control={scrollViewer} onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
+                <LineContainerComponent globalState={this.props.globalState} title="RECTANGLE">
                     <FloatLineComponent lockObject={this.props.lockObject} label="Thickness" target={scrollViewer} propertyName="thickness" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
                     <FloatLineComponent lockObject={this.props.lockObject} label="Corner radius" target={scrollViewer} propertyName="cornerRadius" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
                 </LineContainerComponent>
-                <LineContainerComponent title="SCROLLVIEWER">
+                <LineContainerComponent globalState={this.props.globalState} title="SCROLLVIEWER">
                     <FloatLineComponent lockObject={this.props.lockObject} label="Bar size" target={scrollViewer} propertyName="barSize" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
                     <TextInputLineComponent lockObject={this.props.lockObject} label="Bar color" target={scrollViewer} propertyName="barColor" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
                     <TextInputLineComponent lockObject={this.props.lockObject} label="Bar background" target={scrollViewer} propertyName="barBackground" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />

+ 4 - 2
inspector/src/components/actionTabs/tabs/propertyGrids/gui/sliderPropertyGridComponent.tsx

@@ -8,8 +8,10 @@ import { Slider } from "babylonjs-gui/2D/controls/sliders/slider";
 import { FloatLineComponent } from "../../../lines/floatLineComponent";
 import { CheckBoxLineComponent } from "../../../lines/checkBoxLineComponent";
 import { TextInputLineComponent } from "../../../lines/textInputLineComponent";
+import { GlobalState } from '../../../../globalState';
 
 interface ISliderPropertyGridComponentProps {
+    globalState: GlobalState;
     slider: Slider,
     lockObject: LockObject,
     onPropertyChangedObservable?: Observable<PropertyChangedEvent>
@@ -25,8 +27,8 @@ export class SliderPropertyGridComponent extends React.Component<ISliderProperty
 
         return (
             <div className="pane">
-                <CommonControlPropertyGridComponent lockObject={this.props.lockObject} control={slider} onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
-                <LineContainerComponent title="SLIDER">
+                <CommonControlPropertyGridComponent globalState={this.props.globalState} lockObject={this.props.lockObject} control={slider} onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
+                <LineContainerComponent globalState={this.props.globalState} title="SLIDER">
                     <TextInputLineComponent lockObject={this.props.lockObject} label="Border color" target={slider} propertyName="borderColor" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
                     <CheckBoxLineComponent label="Display thumb" target={slider} propertyName="displayThumb" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
                     <CheckBoxLineComponent label="Thumb circle" target={slider} propertyName="isThumbCircle" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />

+ 4 - 2
inspector/src/components/actionTabs/tabs/propertyGrids/gui/stackPanelPropertyGridComponent.tsx

@@ -6,8 +6,10 @@ import { LockObject } from "../lockObject";
 import { StackPanel } from "babylonjs-gui/2D/controls/stackPanel";
 import { LineContainerComponent } from "../../../lineContainerComponent";
 import { CheckBoxLineComponent } from "../../../lines/checkBoxLineComponent";
+import { GlobalState } from '../../../../globalState';
 
 interface IStackPanelPropertyGridComponentProps {
+    globalState: GlobalState;
     stackPanel: StackPanel,
     lockObject: LockObject,
     onPropertyChangedObservable?: Observable<PropertyChangedEvent>
@@ -23,8 +25,8 @@ export class StackPanelPropertyGridComponent extends React.Component<IStackPanel
 
         return (
             <div className="pane">
-                <CommonControlPropertyGridComponent lockObject={this.props.lockObject} control={stackPanel} onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
-                <LineContainerComponent title="STACKPANEL">
+                <CommonControlPropertyGridComponent globalState={this.props.globalState} lockObject={this.props.lockObject} control={stackPanel} onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
+                <LineContainerComponent globalState={this.props.globalState} title="STACKPANEL">
                     <CheckBoxLineComponent label="Clip children" target={stackPanel} propertyName="clipChildren" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
                     <CheckBoxLineComponent label="Vertical" target={stackPanel} propertyName="isVertical" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
                 </LineContainerComponent>

+ 5 - 3
inspector/src/components/actionTabs/tabs/propertyGrids/gui/textBlockPropertyGridComponent.tsx

@@ -10,8 +10,10 @@ import { LockObject } from "../lockObject";
 import { OptionsLineComponent } from "../../../lines/optionsLineComponent";
 import { CheckBoxLineComponent } from "../../../lines/checkBoxLineComponent";
 import { FloatLineComponent } from "../../../lines/floatLineComponent";
+import { GlobalState } from '../../../../globalState';
 
 interface ITextBlockPropertyGridComponentProps {
+    globalState: GlobalState;
     textBlock: TextBlock;
     lockObject: LockObject;
     onPropertyChangedObservable?: Observable<PropertyChangedEvent>;
@@ -45,8 +47,8 @@ export class TextBlockPropertyGridComponent extends React.Component<ITextBlockPr
 
         return (
             <div className="pane">
-                <CommonControlPropertyGridComponent lockObject={this.props.lockObject} control={textBlock} onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
-                <LineContainerComponent title="TEXTBLOCK">
+                <CommonControlPropertyGridComponent globalState={this.props.globalState} lockObject={this.props.lockObject} control={textBlock} onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
+                <LineContainerComponent globalState={this.props.globalState} title="TEXTBLOCK">
                     <TextInputLineComponent lockObject={this.props.lockObject} label="Text" target={textBlock} propertyName="text" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
                     <OptionsLineComponent label="Horizontal text alignment" options={horizontalOptions} target={textBlock} propertyName="textHorizontalAlignment" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
                     <OptionsLineComponent label="Vertical text alignment" options={verticalOptions} target={textBlock} propertyName="textVerticalAlignment" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
@@ -54,7 +56,7 @@ export class TextBlockPropertyGridComponent extends React.Component<ITextBlockPr
                     <OptionsLineComponent label="Wrapping" options={wrappingOptions} target={textBlock} propertyName="textWrapping" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
                     <TextInputLineComponent lockObject={this.props.lockObject} label="Line spacing" target={textBlock} propertyName="lineSpacing" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
                 </LineContainerComponent>
-                <LineContainerComponent title="OUTLINE">
+                <LineContainerComponent globalState={this.props.globalState} title="OUTLINE">
                     <FloatLineComponent lockObject={this.props.lockObject} label="Outline width" target={textBlock} propertyName="outlineWidth" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
                     <TextInputLineComponent lockObject={this.props.lockObject} label="Outline color" target={textBlock} propertyName="outlineColor" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
                 </LineContainerComponent>

+ 3 - 1
inspector/src/components/actionTabs/tabs/propertyGrids/lights/commonLightPropertyGridComponent.tsx

@@ -6,8 +6,10 @@ import { LineContainerComponent } from "../../../lineContainerComponent";
 import { FloatLineComponent } from "../../../lines/floatLineComponent";
 import { TextLineComponent } from "../../../lines/textLineComponent";
 import { LockObject } from "../lockObject";
+import { GlobalState } from '../../../../globalState';
 
 interface ICommonLightPropertyGridComponentProps {
+    globalState: GlobalState,
     light: Light,
     lockObject: LockObject,
     onPropertyChangedObservable?: Observable<PropertyChangedEvent>
@@ -22,7 +24,7 @@ export class CommonLightPropertyGridComponent extends React.Component<ICommonLig
         const light = this.props.light;
 
         return (
-            <LineContainerComponent title="GENERAL">
+            <LineContainerComponent globalState={this.props.globalState} title="GENERAL">
                 <TextLineComponent label="ID" value={light.id} />
                 <TextLineComponent label="Unique ID" value={light.uniqueId.toString()} />
                 <TextLineComponent label="Class" value={light.getClassName()} />

+ 3 - 1
inspector/src/components/actionTabs/tabs/propertyGrids/lights/commonShadowLightPropertyGridComponent.tsx

@@ -6,8 +6,10 @@ import { LineContainerComponent } from "../../../lineContainerComponent";
 import { CheckBoxLineComponent } from "../../../lines/checkBoxLineComponent";
 import { FloatLineComponent } from "../../../lines/floatLineComponent";
 import { LockObject } from "../lockObject";
+import { GlobalState } from '../../../../globalState';
 
 interface ICommonShadowLightPropertyGridComponentProps {
+    globalState: GlobalState,
     light: IShadowLight,
     lockObject: LockObject,
     onPropertyChangedObservable?: Observable<PropertyChangedEvent>
@@ -22,7 +24,7 @@ export class CommonShadowLightPropertyGridComponent extends React.Component<ICom
         const light = this.props.light;
 
         return (
-            <LineContainerComponent title="SHADOWS">
+            <LineContainerComponent globalState={this.props.globalState} title="SHADOWS">
                 <CheckBoxLineComponent label="Shadows enabled" target={light} propertyName="shadowEnabled" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
                 <FloatLineComponent lockObject={this.props.lockObject} label="Shadows near plane" target={light} propertyName="shadowMinZ" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
                 <FloatLineComponent lockObject={this.props.lockObject} label="Shadows far plane" target={light} propertyName="shadowMaxZ" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />

+ 5 - 3
inspector/src/components/actionTabs/tabs/propertyGrids/lights/directionalLightPropertyGridComponent.tsx

@@ -8,8 +8,10 @@ import { Color3LineComponent } from "../../../lines/color3LineComponent";
 import { Vector3LineComponent } from "../../../lines/vector3LineComponent";
 import { CommonShadowLightPropertyGridComponent } from "./commonShadowLightPropertyGridComponent";
 import { LockObject } from "../lockObject";
+import { GlobalState } from '../../../../globalState';
 
 interface IDirectionalLightPropertyGridComponentProps {
+    globalState: GlobalState,
     light: DirectionalLight,
     lockObject: LockObject,
     onPropertyChangedObservable?: Observable<PropertyChangedEvent>
@@ -25,14 +27,14 @@ export class DirectionalLightPropertyGridComponent extends React.Component<IDire
 
         return (
             <div className="pane">
-                <CommonLightPropertyGridComponent lockObject={this.props.lockObject} light={light} onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
-                <LineContainerComponent title="SETUP">
+                <CommonLightPropertyGridComponent globalState={this.props.globalState} lockObject={this.props.lockObject} light={light} onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
+                <LineContainerComponent globalState={this.props.globalState} title="SETUP">
                     <Color3LineComponent label="Diffuse" target={light} propertyName="diffuse" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
                     <Color3LineComponent label="Specular" target={light} propertyName="specular" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
                     <Vector3LineComponent label="Position" target={light} propertyName="position" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
                     <Vector3LineComponent label="Direction" target={light} propertyName="direction" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
                 </LineContainerComponent>
-                <CommonShadowLightPropertyGridComponent lockObject={this.props.lockObject} light={light} onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
+                <CommonShadowLightPropertyGridComponent globalState={this.props.globalState} lockObject={this.props.lockObject} light={light} onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
             </div>
         );
     }

+ 4 - 2
inspector/src/components/actionTabs/tabs/propertyGrids/lights/hemisphericLightPropertyGridComponent.tsx

@@ -7,8 +7,10 @@ import { LineContainerComponent } from "../../../lineContainerComponent";
 import { Color3LineComponent } from "../../../lines/color3LineComponent";
 import { Vector3LineComponent } from "../../../lines/vector3LineComponent";
 import { LockObject } from "../lockObject";
+import { GlobalState } from '../../../../globalState';
 
 interface IHemisphericLightPropertyGridComponentProps {
+    globalState: GlobalState,
     light: HemisphericLight,
     lockObject: LockObject,
     onPropertyChangedObservable?: Observable<PropertyChangedEvent>
@@ -24,8 +26,8 @@ export class HemisphericLightPropertyGridComponent extends React.Component<IHemi
 
         return (
             <div className="pane">
-                <CommonLightPropertyGridComponent lockObject={this.props.lockObject} light={light} onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
-                <LineContainerComponent title="SETUP">
+                <CommonLightPropertyGridComponent globalState={this.props.globalState} lockObject={this.props.lockObject} light={light} onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
+                <LineContainerComponent globalState={this.props.globalState} title="SETUP">
                     <Color3LineComponent label="Diffuse" target={light} propertyName="diffuse" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
                     <Color3LineComponent label="Ground" target={light} propertyName="groundColor" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
                     <Vector3LineComponent label="Direction" target={light} propertyName="direction" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />

+ 5 - 3
inspector/src/components/actionTabs/tabs/propertyGrids/lights/pointLightPropertyGridComponent.tsx

@@ -8,8 +8,10 @@ import { Color3LineComponent } from "../../../lines/color3LineComponent";
 import { Vector3LineComponent } from "../../../lines/vector3LineComponent";
 import { CommonShadowLightPropertyGridComponent } from "./commonShadowLightPropertyGridComponent";
 import { LockObject } from "../lockObject";
+import { GlobalState } from '../../../../globalState';
 
 interface IPointLightPropertyGridComponentProps {
+    globalState: GlobalState,
     light: PointLight,
     lockObject: LockObject,
     onPropertyChangedObservable?: Observable<PropertyChangedEvent>
@@ -25,13 +27,13 @@ export class PointLightPropertyGridComponent extends React.Component<IPointLight
 
         return (
             <div className="pane">
-                <CommonLightPropertyGridComponent lockObject={this.props.lockObject} light={light} onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
-                <LineContainerComponent title="SETUP">
+                <CommonLightPropertyGridComponent globalState={this.props.globalState} lockObject={this.props.lockObject} light={light} onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
+                <LineContainerComponent globalState={this.props.globalState} title="SETUP">
                     <Color3LineComponent label="Diffuse" target={light} propertyName="diffuse" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
                     <Color3LineComponent label="Specular" target={light} propertyName="specular" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
                     <Vector3LineComponent label="Position" target={light} propertyName="position" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
                 </LineContainerComponent>
-                <CommonShadowLightPropertyGridComponent lockObject={this.props.lockObject} light={light} onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
+                <CommonShadowLightPropertyGridComponent globalState={this.props.globalState} lockObject={this.props.lockObject} light={light} onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
             </div>
         );
     }

+ 5 - 3
inspector/src/components/actionTabs/tabs/propertyGrids/lights/spotLightPropertyGridComponent.tsx

@@ -9,8 +9,10 @@ import { Vector3LineComponent } from "../../../lines/vector3LineComponent";
 import { FloatLineComponent } from "../../../lines/floatLineComponent";
 import { CommonShadowLightPropertyGridComponent } from "./commonShadowLightPropertyGridComponent";
 import { LockObject } from "../lockObject";
+import { GlobalState } from '../../../../globalState';
 
 interface ISpotLightPropertyGridComponentProps {
+    globalState: GlobalState,
     light: SpotLight,
     lockObject: LockObject,
     onPropertyChangedObservable?: Observable<PropertyChangedEvent>
@@ -26,8 +28,8 @@ export class SpotLightPropertyGridComponent extends React.Component<ISpotLightPr
 
         return (
             <div className="pane">
-                <CommonLightPropertyGridComponent lockObject={this.props.lockObject} light={light} onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
-                <LineContainerComponent title="SETUP">
+                <CommonLightPropertyGridComponent globalState={this.props.globalState} lockObject={this.props.lockObject} light={light} onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
+                <LineContainerComponent globalState={this.props.globalState} title="SETUP">
                     <Color3LineComponent label="Diffuse" target={light} propertyName="diffuse" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
                     <Color3LineComponent label="Specular" target={light} propertyName="specular" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
                     <Vector3LineComponent label="Position" target={light} propertyName="position" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
@@ -35,7 +37,7 @@ export class SpotLightPropertyGridComponent extends React.Component<ISpotLightPr
                     <FloatLineComponent lockObject={this.props.lockObject} label="Angle" target={light} propertyName="angle" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
                     <FloatLineComponent lockObject={this.props.lockObject} label="Exponent" target={light} propertyName="exponent" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
                 </LineContainerComponent>
-                <CommonShadowLightPropertyGridComponent lockObject={this.props.lockObject} light={light} onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
+                <CommonShadowLightPropertyGridComponent globalState={this.props.globalState} lockObject={this.props.lockObject} light={light} onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
             </div>
         );
     }

+ 6 - 4
inspector/src/components/actionTabs/tabs/propertyGrids/materials/backgroundMaterialPropertyGridComponent.tsx

@@ -12,8 +12,10 @@ import { SliderLineComponent } from "../../../lines/sliderLineComponent";
 import { CommonMaterialPropertyGridComponent } from "./commonMaterialPropertyGridComponent";
 import { TextureLinkLineComponent } from "../../../lines/textureLinkLineComponent";
 import { LockObject } from "../lockObject";
+import { GlobalState } from '../../../../globalState';
 
 interface IBackgroundMaterialPropertyGridComponentProps {
+    globalState: GlobalState,
     material: BackgroundMaterial;
     lockObject: LockObject;
     onSelectionChangedObservable?: Observable<any>;
@@ -31,7 +33,7 @@ export class BackgroundMaterialPropertyGridComponent extends React.Component<IBa
         const onDebugSelectionChangeObservable = new Observable<BaseTexture>();
 
         return (
-            <LineContainerComponent title="TEXTURES">
+            <LineContainerComponent globalState={this.props.globalState} title="TEXTURES">
                 <TextureLinkLineComponent label="Diffuse" texture={material.diffuseTexture} material={material} onSelectionChangedObservable={this.props.onSelectionChangedObservable} onDebugSelectionChangeObservable={onDebugSelectionChangeObservable} />
                 <TextureLinkLineComponent label="Reflection" texture={material.reflectionTexture} material={material} onSelectionChangedObservable={this.props.onSelectionChangedObservable} onDebugSelectionChangeObservable={onDebugSelectionChangeObservable} />
                 {
@@ -47,14 +49,14 @@ export class BackgroundMaterialPropertyGridComponent extends React.Component<IBa
 
         return (
             <div className="pane">
-                <CommonMaterialPropertyGridComponent lockObject={this.props.lockObject} material={material} onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
-                <LineContainerComponent title="LIGHTING & COLORS">
+                <CommonMaterialPropertyGridComponent globalState={this.props.globalState} lockObject={this.props.lockObject} material={material} onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
+                <LineContainerComponent globalState={this.props.globalState} title="LIGHTING & COLORS">
                     <Color3LineComponent label="Primary" target={material} propertyName="primaryColor" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
                     <SliderLineComponent label="Shadow level" target={material} propertyName="primaryColorShadowLevel" minimum={0} maximum={1} step={0.01} onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
                     <SliderLineComponent label="Highlight level" target={material} propertyName="primaryColorHighlightLevel" minimum={0} maximum={1} step={0.01} onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
                 </LineContainerComponent>
                 {this.renderTextures()}
-                <LineContainerComponent title="RENDERING" closed={true}>
+                <LineContainerComponent globalState={this.props.globalState} title="RENDERING" closed={true}>
                     <CheckBoxLineComponent label="Enable noise" target={material} propertyName="enableNoise" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
                     <CheckBoxLineComponent label="Opacity fresnel" target={material} propertyName="opacityFresnel" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
                     <CheckBoxLineComponent label="Reflection fresnel" target={material} propertyName="reflectionFresnel" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />

+ 4 - 2
inspector/src/components/actionTabs/tabs/propertyGrids/materials/commonMaterialPropertyGridComponent.tsx

@@ -12,8 +12,10 @@ import { LineContainerComponent } from "../../../lineContainerComponent";
 import { TextLineComponent } from "../../../lines/textLineComponent";
 import { OptionsLineComponent } from "../../../lines/optionsLineComponent";
 import { LockObject } from "../lockObject";
+import { GlobalState } from '../../../../globalState';
 
 interface ICommonMaterialPropertyGridComponentProps {
+    globalState: GlobalState;
     material: Material;
     lockObject: LockObject;
     onPropertyChangedObservable?: Observable<PropertyChangedEvent>;
@@ -51,7 +53,7 @@ export class CommonMaterialPropertyGridComponent extends React.Component<ICommon
 
         return (
             <div>
-                <LineContainerComponent title="GENERAL">
+                <LineContainerComponent globalState={this.props.globalState} title="GENERAL">
                     <TextLineComponent label="ID" value={material.id} />
                     <TextLineComponent label="Unique ID" value={material.uniqueId.toString()} />
                     <TextLineComponent label="Class" value={material.getClassName()} />
@@ -65,7 +67,7 @@ export class CommonMaterialPropertyGridComponent extends React.Component<ICommon
                     <SliderLineComponent label="Point size" target={material} propertyName="pointSize" minimum={0} maximum={100} step={0.1} onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
                     <SliderLineComponent label="Z-offset" target={material} propertyName="zOffset" minimum={-10} maximum={10} step={0.1} onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
                 </LineContainerComponent>
-                <LineContainerComponent title="TRANSPARENCY">
+                <LineContainerComponent globalState={this.props.globalState} title="TRANSPARENCY">
                     <SliderLineComponent label="Alpha" target={material} propertyName="alpha" minimum={0} maximum={1} step={0.01} onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
                     {
                         (material as any).transparencyMode !== undefined &&

+ 0 - 0
inspector/src/components/actionTabs/tabs/propertyGrids/materials/materialPropertyGridComponent.tsx


Some files were not shown because too many files changed in this diff