David Catuhe 6 anos atrás
pai
commit
6bcfea77e2
61 arquivos alterados com 2674 adições e 1690 exclusões
  1. 762 726
      Playground/babylon.d.txt
  2. 756 725
      dist/preview release/babylon.d.ts
  3. 1 1
      dist/preview release/babylon.js
  4. 7 0
      dist/preview release/babylon.max.js
  5. 7 0
      dist/preview release/babylon.no-module.max.js
  6. 1 1
      dist/preview release/babylon.worker.js
  7. 7 0
      dist/preview release/es6.js
  8. 42 0
      dist/preview release/gui/babylon.gui.d.ts
  9. 1 1
      dist/preview release/gui/babylon.gui.js
  10. 1 1
      dist/preview release/gui/babylon.gui.min.js
  11. 1 1
      dist/preview release/gui/babylon.gui.min.js.map
  12. 84 0
      dist/preview release/gui/babylon.gui.module.d.ts
  13. 193 142
      dist/preview release/inspector/babylon.inspector.bundle.js
  14. 1 1
      dist/preview release/inspector/babylon.inspector.bundle.js.map
  15. 15 1
      dist/preview release/viewer/babylon.viewer.d.ts
  16. 1 1
      dist/preview release/viewer/babylon.viewer.js
  17. 1 1
      dist/preview release/viewer/babylon.viewer.max.js
  18. 18 1
      dist/preview release/viewer/babylon.viewer.module.d.ts
  19. 44 15
      gui/src/2D/advancedDynamicTexture.ts
  20. 22 10
      gui/src/2D/controls/colorpicker.ts
  21. 2 0
      gui/src/2D/controls/container.ts
  22. 51 1
      gui/src/2D/controls/control.ts
  23. 59 11
      gui/src/2D/controls/grid.ts
  24. 9 0
      gui/src/3D/controls/control3D.ts
  25. 23 0
      inspector/src/components/actionTabs/actionTabs.scss
  26. 1 0
      inspector/src/components/actionTabs/lines/floatLineComponent.tsx
  27. 69 0
      inspector/src/components/actionTabs/lines/textInputLineComponent.tsx
  28. 28 0
      inspector/src/components/actionTabs/tabs/propertyGridTabComponent.tsx
  29. 31 0
      inspector/src/components/actionTabs/tabs/propertyGrids/gui/colorPickerPropertyGridComponent.tsx
  30. 58 0
      inspector/src/components/actionTabs/tabs/propertyGrids/gui/commonControlPropertyGridComponent.tsx
  31. 26 0
      inspector/src/components/actionTabs/tabs/propertyGrids/gui/controlPropertyGridComponent.tsx
  32. 46 0
      inspector/src/components/actionTabs/tabs/propertyGrids/gui/inputTextPropertyGridComponent.tsx
  33. 31 0
      inspector/src/components/actionTabs/tabs/propertyGrids/gui/textBlockPropertyGridComponent.tsx
  34. 13 0
      inspector/src/components/actionTabs/tabs/propertyGrids/texturePropertyGridComponent.tsx
  35. 1 3
      inspector/src/components/sceneExplorer/entities/cameraTreeItemComponent.tsx
  36. 43 0
      inspector/src/components/sceneExplorer/entities/gui/advancedDynamicTextureTreeItemComponent.tsx
  37. 55 0
      inspector/src/components/sceneExplorer/entities/gui/controlTreeItemComponent.tsx
  38. 1 3
      inspector/src/components/sceneExplorer/entities/textureTreeItemComponent.tsx
  39. 41 0
      inspector/src/components/sceneExplorer/sceneExplorer.scss
  40. 8 1
      inspector/src/components/sceneExplorer/sceneExplorerComponent.tsx
  41. 4 3
      inspector/src/components/sceneExplorer/treeItemSelectableComponent.tsx
  42. 11 0
      inspector/src/components/sceneExplorer/treeItemSpecializedComponent.tsx
  43. 3 0
      inspector/src/tools.ts
  44. 2 0
      localDev/index.html
  45. 3 3
      src/Cameras/babylon.camera.ts
  46. 13 13
      src/Cameras/babylon.freeCamera.ts
  47. 2 2
      src/Cameras/babylon.virtualJoysticksCamera.ts
  48. 45 0
      src/Debug/babylon.debugLayer.ts
  49. 2 2
      src/Layer/babylon.layer.ts
  50. 9 9
      src/Lights/Shadows/babylon.shadowGenerator.ts
  51. 1 1
      src/Lights/babylon.light.ts
  52. 1 1
      src/Materials/PBR/babylon.pbrBaseMaterial.ts
  53. 1 1
      src/Materials/PBR/babylon.pbrMaterial.ts
  54. 1 1
      src/Materials/Textures/Procedurals/babylon.proceduralTexture.ts
  55. 8 0
      src/Materials/Textures/babylon.dynamicTexture.ts
  56. 1 1
      src/Materials/Textures/babylon.renderTargetTexture.ts
  57. 1 1
      src/Materials/Textures/babylon.texture.ts
  58. 1 1
      src/Materials/babylon.standardMaterial.ts
  59. 2 2
      src/Mesh/babylon.mesh.ts
  60. 1 1
      src/Rendering/babylon.depthRendererSceneComponent.ts
  61. 1 1
      src/Tools/HDR/babylon.panoramaToCubemap.ts

Diferenças do arquivo suprimidas por serem muito extensas
+ 762 - 726
Playground/babylon.d.txt


Diferenças do arquivo suprimidas por serem muito extensas
+ 756 - 725
dist/preview release/babylon.d.ts


Diferenças do arquivo suprimidas por serem muito extensas
+ 1 - 1
dist/preview release/babylon.js


+ 7 - 0
dist/preview release/babylon.max.js

@@ -75275,6 +75275,13 @@ var BABYLON;
             _this._context = _this._canvas.getContext("2d");
             return _this;
         }
+        /**
+         * Get the current class name of the texture usefull for serialization or dynamic coding.
+         * @returns "Texture"
+         */
+        DynamicTexture.prototype.getClassName = function () {
+            return "DynamicTexture";
+        };
         Object.defineProperty(DynamicTexture.prototype, "canRescale", {
             /**
              * Gets the current state of canRescale

+ 7 - 0
dist/preview release/babylon.no-module.max.js

@@ -75242,6 +75242,13 @@ var BABYLON;
             _this._context = _this._canvas.getContext("2d");
             return _this;
         }
+        /**
+         * Get the current class name of the texture usefull for serialization or dynamic coding.
+         * @returns "Texture"
+         */
+        DynamicTexture.prototype.getClassName = function () {
+            return "DynamicTexture";
+        };
         Object.defineProperty(DynamicTexture.prototype, "canRescale", {
             /**
              * Gets the current state of canRescale

Diferenças do arquivo suprimidas por serem muito extensas
+ 1 - 1
dist/preview release/babylon.worker.js


+ 7 - 0
dist/preview release/es6.js

@@ -75242,6 +75242,13 @@ var BABYLON;
             _this._context = _this._canvas.getContext("2d");
             return _this;
         }
+        /**
+         * Get the current class name of the texture usefull for serialization or dynamic coding.
+         * @returns "Texture"
+         */
+        DynamicTexture.prototype.getClassName = function () {
+            return "DynamicTexture";
+        };
         Object.defineProperty(DynamicTexture.prototype, "canRescale", {
             /**
              * Gets the current state of canRescale

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

@@ -65,6 +65,10 @@ declare module BABYLON.GUI {
                 */
             onClipboardObservable: BABYLON.Observable<BABYLON.ClipboardInfo>;
             /**
+                * BABYLON.Observable event triggered each time a pointer down is intercepted by a control
+                */
+            onControlPickedObservable: BABYLON.Observable<Control>;
+            /**
                 * Gets or sets a boolean defining if alpha is stored as premultiplied
                 */
             premulAlpha: boolean;
@@ -106,6 +110,11 @@ declare module BABYLON.GUI {
                 */
             readonly rootContainer: Container;
             /**
+                * Returns an array containing the root container.
+                * This is mostly used to let the Inspector introspects the ADT
+                */
+            getChildren(): Array<Container>;
+            /**
                 * Gets or sets the current focused control
                 */
             focusedControl: BABYLON.Nullable<IFocusableControl>;
@@ -128,6 +137,11 @@ declare module BABYLON.GUI {
              */
             constructor(name: string, width: number | undefined, height: number | undefined, scene: BABYLON.Nullable<BABYLON.Scene>, generateMipMaps?: boolean, samplingMode?: number);
             /**
+                * Get the current class name of the texture useful for serialization or dynamic coding.
+                * @returns "AdvancedDynamicTexture"
+                */
+            getClassName(): string;
+            /**
                 * Function used to execute a function on all controls
                 * @param func defines the function to execute
                 * @param container defines the container where controls belong. If null the root container will be used
@@ -171,6 +185,8 @@ declare module BABYLON.GUI {
             /** @hidden */
             _changeCursor(cursor: string): void;
             /** @hidden */
+            _registerLastControlDown(control: Control, pointerId: number): void;
+            /** @hidden */
             _cleanControlAfterRemovalFromList(list: {
                     [pointerId: number]: Control;
             }, control: Control): void;
@@ -880,6 +896,10 @@ declare module BABYLON.GUI {
             /** @hidden */
             _tag: any;
             /**
+                * Gets or sets the unique id of the node. Please note that this number will be updated when the control is added to a container
+                */
+            uniqueId: number;
+            /**
                 * Gets or sets an object used to store user defined information for the node
                 */
             metadata: any;
@@ -908,6 +928,11 @@ declare module BABYLON.GUI {
             /** Gets the control type name */
             readonly typeName: string;
             /**
+                * Get the current class name of the control.
+                * @returns current class name
+                */
+            getClassName(): string;
+            /**
              * An event triggered when the pointer move over the control.
              */
             onPointerMoveObservable: BABYLON.Observable<BABYLON.Vector2>;
@@ -951,6 +976,10 @@ declare module BABYLON.GUI {
             };
             /** Gets or sets alpha value for the control (1 means opaque and 0 means entirely transparent) */
             alpha: number;
+            /**
+                * Gets or sets a boolean indicating that we want to highlight the control (mostly for debugging purpose)
+                */
+            isHighlighted: boolean;
             /** Gets or sets a value indicating the scale factor on X axis (1 by default)
                 * @see http://doc.babylonjs.com/how_to/gui#rotation-and-scaling
              */
@@ -1183,6 +1212,10 @@ declare module BABYLON.GUI {
             /** @hidden */
             protected _transform(context: CanvasRenderingContext2D): void;
             /** @hidden */
+            _renderHighlight(context: CanvasRenderingContext2D): void;
+            /** @hidden */
+            protected _renderHighlightSpecific(context: CanvasRenderingContext2D): void;
+            /** @hidden */
             protected _applyStates(context: CanvasRenderingContext2D): void;
             /** @hidden */
             protected _processMeasures(parentMeasure: Measure, context: CanvasRenderingContext2D): boolean;
@@ -1361,7 +1394,10 @@ declare module BABYLON.GUI {
                 */
             constructor(name?: string | undefined);
             protected _getTypeName(): string;
+            protected _getGridDefinitions(definitionCallback: (lefts: number[], tops: number[], widths: number[], heights: number[]) => void): void;
             protected _additionalProcessing(parentMeasure: Measure, context: CanvasRenderingContext2D): void;
+            _flagDescendantsAsMatrixDirty(): void;
+            protected _renderHighlightSpecific(context: CanvasRenderingContext2D): void;
             /** Releases associated resources */
             dispose(): void;
     }
@@ -2454,8 +2490,14 @@ declare module BABYLON.GUI {
             name?: string | undefined);
             /**
                 * Gets a string representing the class name
+                * @returns current class name
                 */
             readonly typeName: string;
+            /**
+                * Get the current class name of the control.
+                * @returns current class name
+                */
+            readonly getClassName: string;
             protected _getTypeName(): string;
             /**
                 * Gets the transform node used by this control

Diferenças do arquivo suprimidas por serem muito extensas
+ 1 - 1
dist/preview release/gui/babylon.gui.js


Diferenças do arquivo suprimidas por serem muito extensas
+ 1 - 1
dist/preview release/gui/babylon.gui.min.js


Diferenças do arquivo suprimidas por serem muito extensas
+ 1 - 1
dist/preview release/gui/babylon.gui.min.js.map


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

@@ -110,6 +110,10 @@ declare module 'babylonjs-gui/2D/advancedDynamicTexture' {
                 */
             onClipboardObservable: Observable<ClipboardInfo>;
             /**
+                * Observable event triggered each time a pointer down is intercepted by a control
+                */
+            onControlPickedObservable: Observable<Control>;
+            /**
                 * Gets or sets a boolean defining if alpha is stored as premultiplied
                 */
             premulAlpha: boolean;
@@ -151,6 +155,11 @@ declare module 'babylonjs-gui/2D/advancedDynamicTexture' {
                 */
             readonly rootContainer: Container;
             /**
+                * Returns an array containing the root container.
+                * This is mostly used to let the Inspector introspects the ADT
+                */
+            getChildren(): Array<Container>;
+            /**
                 * Gets or sets the current focused control
                 */
             focusedControl: Nullable<IFocusableControl>;
@@ -173,6 +182,11 @@ declare module 'babylonjs-gui/2D/advancedDynamicTexture' {
              */
             constructor(name: string, width: number | undefined, height: number | undefined, scene: Nullable<Scene>, generateMipMaps?: boolean, samplingMode?: number);
             /**
+                * Get the current class name of the texture useful for serialization or dynamic coding.
+                * @returns "AdvancedDynamicTexture"
+                */
+            getClassName(): string;
+            /**
                 * Function used to execute a function on all controls
                 * @param func defines the function to execute
                 * @param container defines the container where controls belong. If null the root container will be used
@@ -216,6 +230,8 @@ declare module 'babylonjs-gui/2D/advancedDynamicTexture' {
             /** @hidden */
             _changeCursor(cursor: string): void;
             /** @hidden */
+            _registerLastControlDown(control: Control, pointerId: number): void;
+            /** @hidden */
             _cleanControlAfterRemovalFromList(list: {
                     [pointerId: number]: Control;
             }, control: Control): void;
@@ -987,6 +1003,10 @@ declare module 'babylonjs-gui/2D/controls/control' {
             /** @hidden */
             _tag: any;
             /**
+                * Gets or sets the unique id of the node. Please note that this number will be updated when the control is added to a container
+                */
+            uniqueId: number;
+            /**
                 * Gets or sets an object used to store user defined information for the node
                 */
             metadata: any;
@@ -1015,6 +1035,11 @@ declare module 'babylonjs-gui/2D/controls/control' {
             /** Gets the control type name */
             readonly typeName: string;
             /**
+                * Get the current class name of the control.
+                * @returns current class name
+                */
+            getClassName(): string;
+            /**
              * An event triggered when the pointer move over the control.
              */
             onPointerMoveObservable: Observable<Vector2>;
@@ -1058,6 +1083,10 @@ declare module 'babylonjs-gui/2D/controls/control' {
             };
             /** Gets or sets alpha value for the control (1 means opaque and 0 means entirely transparent) */
             alpha: number;
+            /**
+                * Gets or sets a boolean indicating that we want to highlight the control (mostly for debugging purpose)
+                */
+            isHighlighted: boolean;
             /** Gets or sets a value indicating the scale factor on X axis (1 by default)
                 * @see http://doc.babylonjs.com/how_to/gui#rotation-and-scaling
              */
@@ -1290,6 +1319,10 @@ declare module 'babylonjs-gui/2D/controls/control' {
             /** @hidden */
             protected _transform(context: CanvasRenderingContext2D): void;
             /** @hidden */
+            _renderHighlight(context: CanvasRenderingContext2D): void;
+            /** @hidden */
+            protected _renderHighlightSpecific(context: CanvasRenderingContext2D): void;
+            /** @hidden */
             protected _applyStates(context: CanvasRenderingContext2D): void;
             /** @hidden */
             protected _processMeasures(parentMeasure: Measure, context: CanvasRenderingContext2D): boolean;
@@ -1476,7 +1509,10 @@ declare module 'babylonjs-gui/2D/controls/grid' {
                 */
             constructor(name?: string | undefined);
             protected _getTypeName(): string;
+            protected _getGridDefinitions(definitionCallback: (lefts: number[], tops: number[], widths: number[], heights: number[]) => void): void;
             protected _additionalProcessing(parentMeasure: Measure, context: CanvasRenderingContext2D): void;
+            _flagDescendantsAsMatrixDirty(): void;
+            protected _renderHighlightSpecific(context: CanvasRenderingContext2D): void;
             /** Releases associated resources */
             dispose(): void;
     }
@@ -2644,8 +2680,14 @@ declare module 'babylonjs-gui/3D/controls/control3D' {
             name?: string | undefined);
             /**
                 * Gets a string representing the class name
+                * @returns current class name
                 */
             readonly typeName: string;
+            /**
+                * Get the current class name of the control.
+                * @returns current class name
+                */
+            readonly getClassName: string;
             protected _getTypeName(): string;
             /**
                 * Gets the transform node used by this control
@@ -3056,6 +3098,10 @@ declare module BABYLON.GUI {
                 */
             onClipboardObservable: BABYLON.Observable<BABYLON.ClipboardInfo>;
             /**
+                * BABYLON.Observable event triggered each time a pointer down is intercepted by a control
+                */
+            onControlPickedObservable: BABYLON.Observable<Control>;
+            /**
                 * Gets or sets a boolean defining if alpha is stored as premultiplied
                 */
             premulAlpha: boolean;
@@ -3097,6 +3143,11 @@ declare module BABYLON.GUI {
                 */
             readonly rootContainer: Container;
             /**
+                * Returns an array containing the root container.
+                * This is mostly used to let the Inspector introspects the ADT
+                */
+            getChildren(): Array<Container>;
+            /**
                 * Gets or sets the current focused control
                 */
             focusedControl: BABYLON.Nullable<IFocusableControl>;
@@ -3119,6 +3170,11 @@ declare module BABYLON.GUI {
              */
             constructor(name: string, width: number | undefined, height: number | undefined, scene: BABYLON.Nullable<BABYLON.Scene>, generateMipMaps?: boolean, samplingMode?: number);
             /**
+                * Get the current class name of the texture useful for serialization or dynamic coding.
+                * @returns "AdvancedDynamicTexture"
+                */
+            getClassName(): string;
+            /**
                 * Function used to execute a function on all controls
                 * @param func defines the function to execute
                 * @param container defines the container where controls belong. If null the root container will be used
@@ -3162,6 +3218,8 @@ declare module BABYLON.GUI {
             /** @hidden */
             _changeCursor(cursor: string): void;
             /** @hidden */
+            _registerLastControlDown(control: Control, pointerId: number): void;
+            /** @hidden */
             _cleanControlAfterRemovalFromList(list: {
                     [pointerId: number]: Control;
             }, control: Control): void;
@@ -3871,6 +3929,10 @@ declare module BABYLON.GUI {
             /** @hidden */
             _tag: any;
             /**
+                * Gets or sets the unique id of the node. Please note that this number will be updated when the control is added to a container
+                */
+            uniqueId: number;
+            /**
                 * Gets or sets an object used to store user defined information for the node
                 */
             metadata: any;
@@ -3899,6 +3961,11 @@ declare module BABYLON.GUI {
             /** Gets the control type name */
             readonly typeName: string;
             /**
+                * Get the current class name of the control.
+                * @returns current class name
+                */
+            getClassName(): string;
+            /**
              * An event triggered when the pointer move over the control.
              */
             onPointerMoveObservable: BABYLON.Observable<BABYLON.Vector2>;
@@ -3942,6 +4009,10 @@ declare module BABYLON.GUI {
             };
             /** Gets or sets alpha value for the control (1 means opaque and 0 means entirely transparent) */
             alpha: number;
+            /**
+                * Gets or sets a boolean indicating that we want to highlight the control (mostly for debugging purpose)
+                */
+            isHighlighted: boolean;
             /** Gets or sets a value indicating the scale factor on X axis (1 by default)
                 * @see http://doc.babylonjs.com/how_to/gui#rotation-and-scaling
              */
@@ -4174,6 +4245,10 @@ declare module BABYLON.GUI {
             /** @hidden */
             protected _transform(context: CanvasRenderingContext2D): void;
             /** @hidden */
+            _renderHighlight(context: CanvasRenderingContext2D): void;
+            /** @hidden */
+            protected _renderHighlightSpecific(context: CanvasRenderingContext2D): void;
+            /** @hidden */
             protected _applyStates(context: CanvasRenderingContext2D): void;
             /** @hidden */
             protected _processMeasures(parentMeasure: Measure, context: CanvasRenderingContext2D): boolean;
@@ -4352,7 +4427,10 @@ declare module BABYLON.GUI {
                 */
             constructor(name?: string | undefined);
             protected _getTypeName(): string;
+            protected _getGridDefinitions(definitionCallback: (lefts: number[], tops: number[], widths: number[], heights: number[]) => void): void;
             protected _additionalProcessing(parentMeasure: Measure, context: CanvasRenderingContext2D): void;
+            _flagDescendantsAsMatrixDirty(): void;
+            protected _renderHighlightSpecific(context: CanvasRenderingContext2D): void;
             /** Releases associated resources */
             dispose(): void;
     }
@@ -5445,8 +5523,14 @@ declare module BABYLON.GUI {
             name?: string | undefined);
             /**
                 * Gets a string representing the class name
+                * @returns current class name
                 */
             readonly typeName: string;
+            /**
+                * Get the current class name of the control.
+                * @returns current class name
+                */
+            readonly getClassName: string;
             protected _getTypeName(): string;
             /**
                 * Gets the transform node used by this control

+ 193 - 142
dist/preview release/inspector/babylon.inspector.bundle.js

@@ -27006,165 +27006,180 @@ if (false) {} else {
 
 /***/ }),
 
-/***/ "./node_modules/react-split/dist/react-split.js":
-/*!******************************************************!*\
-  !*** ./node_modules/react-split/dist/react-split.js ***!
-  \******************************************************/
-/*! no static exports found */
-/***/ (function(module, exports, __webpack_require__) {
+/***/ "./node_modules/react-split/dist/react-split.es.js":
+/*!*********************************************************!*\
+  !*** ./node_modules/react-split/dist/react-split.es.js ***!
+  \*********************************************************/
+/*! exports provided: default */
+/***/ (function(module, __webpack_exports__, __webpack_require__) {
 
-(function (global, factory) {
-     true ? module.exports = factory(__webpack_require__(/*! react */ "./node_modules/react-split/node_modules/react/react.js"), __webpack_require__(/*! split.js */ "./node_modules/split.js/dist/split.js")) :
-    undefined;
-}(this, (function (React,Split) { 'use strict';
+"use strict";
+__webpack_require__.r(__webpack_exports__);
+/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! react */ "./node_modules/react-split/node_modules/react/react.js");
+/* harmony import */ var react__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(react__WEBPACK_IMPORTED_MODULE_0__);
+/* harmony import */ var split_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! split.js */ "./node_modules/split.js/dist/split.js");
+/* harmony import */ var split_js__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(split_js__WEBPACK_IMPORTED_MODULE_1__);
 
-    React = React && React.hasOwnProperty('default') ? React['default'] : React;
-    Split = Split && Split.hasOwnProperty('default') ? Split['default'] : Split;
 
-    function objectWithoutProperties (obj, exclude) { var target = {}; for (var k in obj) if (Object.prototype.hasOwnProperty.call(obj, k) && exclude.indexOf(k) === -1) target[k] = obj[k]; return target; }
 
-    var SplitWrapper = (function (superclass) {
-        function SplitWrapper (props) {
-            superclass.call(this, props);
-        }
+function objectWithoutProperties (obj, exclude) { var target = {}; for (var k in obj) if (Object.prototype.hasOwnProperty.call(obj, k) && exclude.indexOf(k) === -1) target[k] = obj[k]; return target; }
 
-        if ( superclass ) SplitWrapper.__proto__ = superclass;
-        SplitWrapper.prototype = Object.create( superclass && superclass.prototype );
-        SplitWrapper.prototype.constructor = SplitWrapper;
+var SplitWrapper = /*@__PURE__*/(function (superclass) {
+    function SplitWrapper () {
+        superclass.apply(this, arguments);
+    }
 
-        SplitWrapper.prototype.componentDidMount = function componentDidMount () {
-            var ref = this.props;
-            var children = ref.children;
-            var gutter = ref.gutter;
-            var rest = objectWithoutProperties( ref, ["children", "gutter"] );
-            var options = rest;
+    if ( superclass ) SplitWrapper.__proto__ = superclass;
+    SplitWrapper.prototype = Object.create( superclass && superclass.prototype );
+    SplitWrapper.prototype.constructor = SplitWrapper;
 
-            options.gutter = function (index, direction) {
-                var gutterElement;
+    SplitWrapper.prototype.componentDidMount = function componentDidMount () {
+        var ref = this.props;
+        var children = ref.children;
+        var gutter = ref.gutter;
+        var rest = objectWithoutProperties( ref, ["children", "gutter"] );
+        var options = rest;
 
-                if (gutter) {
-                    gutterElement = gutter(index, direction);
-                } else {
-                    gutterElement = document.createElement('div');
-                    gutterElement.className = "gutter gutter-" + direction;
-                }
+        options.gutter = function (index, direction) {
+            var gutterElement;
 
-                gutterElement.__isSplitGutter = true;
-                return gutterElement
-            };
+            if (gutter) {
+                gutterElement = gutter(index, direction);
+            } else {
+                gutterElement = document.createElement('div');
+                gutterElement.className = "gutter gutter-" + direction;
+            }
 
-            this.split = Split(this.parent.children, options);
+            // eslint-disable-next-line no-underscore-dangle
+            gutterElement.__isSplitGutter = true;
+            return gutterElement
         };
 
-        SplitWrapper.prototype.componentDidUpdate = function componentDidUpdate (prevProps) {
-            var this$1 = this;
-
-            var ref = this.props;
-            var children = ref.children;
-            var minSize = ref.minSize;
-            var sizes = ref.sizes;
-            var collapsed = ref.collapsed;
-            var rest = objectWithoutProperties( ref, ["children", "minSize", "sizes", "collapsed"] );
-            var options = rest;
-            var prevMinSize = prevProps.minSize;
-            var prevSizes = prevProps.sizes;
-            var prevCollapsed = prevProps.collapsed;
-
-            var otherProps = [
-                'expandToMin',
-                'gutterSize',
-                'gutterAlign',
-                'snapOffset',
-                'dragInterval',
-                'direction',
-                'cursor' ];
-
-            var needsRecreate = otherProps
-                .map(function (prop) { return this$1.props[prop] !== prevProps[prop]; })
-                .reduce(function (accum, same) { return accum || same; }, false);
-
-            // Compare minSize when both are arrays, when one is an array and when neither is an array
-            if (Array.isArray(minSize) && Array.isArray(prevMinSize)) {
-                var minSizeChanged = false;
-
-                for (var i = 0; i < minSize.length; i++) {
-                     minSizeChanged = minSizeChanged || (minSize[i] !== prevMinSize[i]);
-                }
+        this.split = split_js__WEBPACK_IMPORTED_MODULE_1___default()(this.parent.children, options);
+    };
 
-                needsRecreate = needsRecreate || minSizeChanged;
-            } else if (Array.isArray(minSize) || Array.isArray(prevMinSize)) {
-                needsRecreate = true;
-            } else {
-                needsRecreate = needsRecreate || (minSize !== prevMinSize);
-            }
+    SplitWrapper.prototype.componentDidUpdate = function componentDidUpdate (prevProps) {
+        var this$1 = this;
+
+        var ref = this.props;
+        var children = ref.children;
+        var minSize = ref.minSize;
+        var sizes = ref.sizes;
+        var collapsed = ref.collapsed;
+        var rest = objectWithoutProperties( ref, ["children", "minSize", "sizes", "collapsed"] );
+        var options = rest;
+        var prevMinSize = prevProps.minSize;
+        var prevSizes = prevProps.sizes;
+        var prevCollapsed = prevProps.collapsed;
+
+        var otherProps = [
+            'expandToMin',
+            'gutterSize',
+            'gutterAlign',
+            'snapOffset',
+            'dragInterval',
+            'direction',
+            'cursor' ];
+
+        var needsRecreate = otherProps
+            // eslint-disable-next-line react/destructuring-assignment
+            .map(function (prop) { return this$1.props[prop] !== prevProps[prop]; })
+            .reduce(function (accum, same) { return accum || same; }, false);
+
+        // Compare minSize when both are arrays, when one is an array and when neither is an array
+        if (Array.isArray(minSize) && Array.isArray(prevMinSize)) {
+            var minSizeChanged = false;
+
+            minSize.forEach(function (minSizeI, i) {
+                minSizeChanged = minSizeChanged || minSizeI !== prevMinSize[i];
+            });
 
-            // Destroy and re-create split if options changed
-            if (needsRecreate) {
-                options.minSize = minSize;
-                options.sizes = this.split.getSizes();
-                this.split.destroy(true, true);
-                options.gutter = function (index, direction, pairB) { return pairB.previousSibling; };
-                this.split = Split(Array.from(this.parent.children).filter(function (element) { return !element.__isSplitGutter; }), options);
-            } else {
-                // If only the size has changed, set the size. No need to do this if re-created.
-                var sizeChanged = false;
+            needsRecreate = needsRecreate || minSizeChanged;
+        } else if (Array.isArray(minSize) || Array.isArray(prevMinSize)) {
+            needsRecreate = true;
+        } else {
+            needsRecreate = needsRecreate || minSize !== prevMinSize;
+        }
 
-                for (var i = 0; i < prevSizes.length; i++) {
-                    sizeChanged = sizeChanged || (sizes[i] !== prevSizes[i]);
-                }
+        // Destroy and re-create split if options changed
+        if (needsRecreate) {
+            options.minSize = minSize;
+            options.sizes = this.split.getSizes();
+            this.split.destroy(true, true);
+            options.gutter = function (index, direction, pairB) { return pairB.previousSibling; };
+            this.split = split_js__WEBPACK_IMPORTED_MODULE_1___default()(
+                Array.from(this.parent.children).filter(
+                    // eslint-disable-next-line no-underscore-dangle
+                    function (element) { return !element.__isSplitGutter; }
+                ),
+                options
+            );
+        } else {
+            // If only the size has changed, set the size. No need to do this if re-created.
+            var sizeChanged = false;
 
-                if (sizeChanged) {
-                    this.split.setSizes(this.props.sizes);
-                }
-            }
+            sizes.forEach(function (sizeI, i) {
+                sizeChanged = sizeChanged || sizeI !== prevSizes[i];
+            });
 
-            // Collapse after re-created or when collapsed changed.
-            if (Number.isInteger(collapsed) && ((collapsed !== prevCollapsed) || needsRecreate)) {
-                this.split.collapse(collapsed);
+            if (sizeChanged) {
+                // eslint-disable-next-line react/destructuring-assignment
+                this.split.setSizes(this.props.sizes);
             }
-        };
+        }
 
-        SplitWrapper.prototype.componentWillUnmount = function componentWillUnmount () {
-            this.split.destroy();
-            delete this.split;
-        };
+        // Collapse after re-created or when collapsed changed.
+        if (
+            Number.isInteger(collapsed) &&
+            (collapsed !== prevCollapsed || needsRecreate)
+        ) {
+            this.split.collapse(collapsed);
+        }
+    };
 
-        SplitWrapper.prototype.render = function render () {
-            var this$1 = this;
-
-            var ref = this.props;
-            var sizes = ref.sizes;
-            var minSize = ref.minSize;
-            var expandToMin = ref.expandToMin;
-            var gutterSize = ref.gutterSize;
-            var gutterAlign = ref.gutterAlign;
-            var snapOffset = ref.snapOffset;
-            var dragInterval = ref.dragInterval;
-            var direction = ref.direction;
-            var cursor = ref.cursor;
-            var gutter = ref.gutter;
-            var elementStyle = ref.elementStyle;
-            var gutterStyle = ref.gutterStyle;
-            var onDrag = ref.onDrag;
-            var onDragStart = ref.onDragStart;
-            var onDragEnd = ref.onDragEnd;
-            var collapsed = ref.collapsed;
-            var rest$1 = objectWithoutProperties( ref, ["sizes", "minSize", "expandToMin", "gutterSize", "gutterAlign", "snapOffset", "dragInterval", "direction", "cursor", "gutter", "elementStyle", "gutterStyle", "onDrag", "onDragStart", "onDragEnd", "collapsed"] );
-            var rest = rest$1;
-
-            return (
-                React.createElement( 'div', Object.assign({}, { ref: function (parent) { this$1.parent = parent; } }, rest),
-                    this.props.children
-                )
-            )
-        };
+    SplitWrapper.prototype.componentWillUnmount = function componentWillUnmount () {
+        this.split.destroy();
+        delete this.split;
+    };
 
-        return SplitWrapper;
-    }(React.Component));
+    SplitWrapper.prototype.render = function render () {
+        var this$1 = this;
+
+        var ref = this.props;
+        var sizes = ref.sizes;
+        var minSize = ref.minSize;
+        var expandToMin = ref.expandToMin;
+        var gutterSize = ref.gutterSize;
+        var gutterAlign = ref.gutterAlign;
+        var snapOffset = ref.snapOffset;
+        var dragInterval = ref.dragInterval;
+        var direction = ref.direction;
+        var cursor = ref.cursor;
+        var gutter = ref.gutter;
+        var elementStyle = ref.elementStyle;
+        var gutterStyle = ref.gutterStyle;
+        var onDrag = ref.onDrag;
+        var onDragStart = ref.onDragStart;
+        var onDragEnd = ref.onDragEnd;
+        var collapsed = ref.collapsed;
+        var children = ref.children;
+        var rest$1 = objectWithoutProperties( ref, ["sizes", "minSize", "expandToMin", "gutterSize", "gutterAlign", "snapOffset", "dragInterval", "direction", "cursor", "gutter", "elementStyle", "gutterStyle", "onDrag", "onDragStart", "onDragEnd", "collapsed", "children"] );
+        var rest = rest$1;
+
+        return (
+            react__WEBPACK_IMPORTED_MODULE_0___default.a.createElement( 'div', Object.assign({},
+                { ref: function (parent) {
+                    this$1.parent = parent;
+                } }, rest),
+                children
+            )
+        )
+    };
 
     return SplitWrapper;
+}(react__WEBPACK_IMPORTED_MODULE_0___default.a.Component));
 
-})));
+/* harmony default export */ __webpack_exports__["default"] = (SplitWrapper);
 
 
 /***/ }),
@@ -36393,7 +36408,8 @@ var CommonMaterialPropertyGridComponent = /** @class */ (function (_super) {
                 react__WEBPACK_IMPORTED_MODULE_0__["createElement"](_lines_sliderLineComponent__WEBPACK_IMPORTED_MODULE_2__["SliderLineComponent"], { label: "Z-offset", target: material, propertyName: "zOffset", minimum: -10, maximum: 10, step: 0.1, onPropertyChangedObservable: this.props.onPropertyChangedObservable })),
             react__WEBPACK_IMPORTED_MODULE_0__["createElement"](_lineContainerComponent__WEBPACK_IMPORTED_MODULE_3__["LineContainerComponent"], { title: "TRANSPARENCY" },
                 react__WEBPACK_IMPORTED_MODULE_0__["createElement"](_lines_sliderLineComponent__WEBPACK_IMPORTED_MODULE_2__["SliderLineComponent"], { label: "Alpha", target: material, propertyName: "alpha", minimum: 0, maximum: 1, step: 0.01, onPropertyChangedObservable: this.props.onPropertyChangedObservable }),
-                react__WEBPACK_IMPORTED_MODULE_0__["createElement"](_lines_optionsLineComponent__WEBPACK_IMPORTED_MODULE_5__["OptionsLineComponent"], { label: "Transparency mode", options: transparencyModeOptions, target: material, propertyName: "transparencyMode", onPropertyChangedObservable: this.props.onPropertyChangedObservable, onSelect: function (value) { return _this.setState({ transparencyMode: value }); } }),
+                material.transparencyMode &&
+                    react__WEBPACK_IMPORTED_MODULE_0__["createElement"](_lines_optionsLineComponent__WEBPACK_IMPORTED_MODULE_5__["OptionsLineComponent"], { label: "Transparency mode", options: transparencyModeOptions, target: material, propertyName: "transparencyMode", onPropertyChangedObservable: this.props.onPropertyChangedObservable, onSelect: function (value) { return _this.setState({ transparencyMode: value }); } }),
                 react__WEBPACK_IMPORTED_MODULE_0__["createElement"](_lines_optionsLineComponent__WEBPACK_IMPORTED_MODULE_5__["OptionsLineComponent"], { label: "Alpha mode", options: alphaModeOptions, target: material, propertyName: "alphaMode", onPropertyChangedObservable: this.props.onPropertyChangedObservable, onSelect: function (value) { return _this.setState({ alphaMode: value }); } }))));
     };
     return CommonMaterialPropertyGridComponent;
@@ -36621,8 +36637,7 @@ var StandardMaterialPropertyGridComponent = /** @class */ (function (_super) {
                 react__WEBPACK_IMPORTED_MODULE_0__["createElement"](_lines_color3LineComponent__WEBPACK_IMPORTED_MODULE_2__["Color3LineComponent"], { label: "Specular", target: material, propertyName: "specularColor", onPropertyChangedObservable: this.props.onPropertyChangedObservable }),
                 react__WEBPACK_IMPORTED_MODULE_0__["createElement"](_lines_sliderLineComponent__WEBPACK_IMPORTED_MODULE_3__["SliderLineComponent"], { label: "Specular power", target: material, propertyName: "specularPower", minimum: 0, maximum: 128, step: 0.1, onPropertyChangedObservable: this.props.onPropertyChangedObservable }),
                 react__WEBPACK_IMPORTED_MODULE_0__["createElement"](_lines_color3LineComponent__WEBPACK_IMPORTED_MODULE_2__["Color3LineComponent"], { label: "Emissive", target: material, propertyName: "emissiveColor", onPropertyChangedObservable: this.props.onPropertyChangedObservable }),
-                react__WEBPACK_IMPORTED_MODULE_0__["createElement"](_lines_color3LineComponent__WEBPACK_IMPORTED_MODULE_2__["Color3LineComponent"], { label: "Ambient", target: material, propertyName: "ambientColor", onPropertyChangedObservable: this.props.onPropertyChangedObservable }),
-                react__WEBPACK_IMPORTED_MODULE_0__["createElement"](_lines_sliderLineComponent__WEBPACK_IMPORTED_MODULE_3__["SliderLineComponent"], { label: "Alpha", target: material, propertyName: "alpha", minimum: 0, maximum: 1, step: 0.01, onPropertyChangedObservable: this.props.onPropertyChangedObservable })),
+                react__WEBPACK_IMPORTED_MODULE_0__["createElement"](_lines_color3LineComponent__WEBPACK_IMPORTED_MODULE_2__["Color3LineComponent"], { label: "Ambient", target: material, propertyName: "ambientColor", onPropertyChangedObservable: this.props.onPropertyChangedObservable })),
             this.renderTextures()));
     };
     return StandardMaterialPropertyGridComponent;
@@ -36674,9 +36689,38 @@ var MeshPropertyGridComponent = /** @class */ (function (_super) {
     __extends(MeshPropertyGridComponent, _super);
     function MeshPropertyGridComponent(props) {
         var _this = _super.call(this, props) || this;
-        _this.state = { displayNormals: false };
+        var mesh = _this.props.mesh;
+        _this.state = { displayNormals: false, renderNormalVectors: mesh.metadata && mesh.metadata.normalLines };
         return _this;
     }
+    MeshPropertyGridComponent.prototype.renderNormalVectors = function () {
+        var mesh = this.props.mesh;
+        var scene = mesh.getScene();
+        if (mesh.metadata && mesh.metadata.normalLines) {
+            mesh.metadata.normalLines.dispose();
+            mesh.metadata.normalLines = null;
+            this.setState({ renderNormalVectors: false });
+            return;
+        }
+        var normals = mesh.getVerticesData(BABYLON.VertexBuffer.NormalKind);
+        var positions = mesh.getVerticesData(BABYLON.VertexBuffer.PositionKind);
+        var color = BABYLON.Color3.White();
+        var size = mesh.getBoundingInfo().diagonalLength * 0.05;
+        var lines = [];
+        for (var i = 0; i < normals.length; i += 3) {
+            var v1 = BABYLON.Vector3.FromArray(positions, i);
+            var v2 = v1.add(BABYLON.Vector3.FromArray(normals, i).scaleInPlace(size));
+            lines.push([v1, v2]);
+        }
+        var normalLines = BABYLON.MeshBuilder.CreateLineSystem("normalLines", { lines: lines }, scene);
+        normalLines.color = color;
+        normalLines.parent = mesh;
+        if (!mesh.metadata) {
+            mesh.metadata = {};
+        }
+        mesh.metadata.normalLines = normalLines;
+        this.setState({ renderNormalVectors: true });
+    };
     MeshPropertyGridComponent.prototype.displayNormals = function () {
         var _this = this;
         var mesh = this.props.mesh;
@@ -36722,6 +36766,7 @@ var MeshPropertyGridComponent = /** @class */ (function (_super) {
         var mesh = this.props.mesh;
         var scene = mesh.getScene();
         var displayNormals = mesh.material != null && mesh.material.getClassName() === "NormalMaterial";
+        var renderNormalVectors = mesh.metadata && mesh.metadata.normalLines;
         return (react__WEBPACK_IMPORTED_MODULE_0__["createElement"]("div", { className: "pane" },
             react__WEBPACK_IMPORTED_MODULE_0__["createElement"](_lineContainerComponent__WEBPACK_IMPORTED_MODULE_1__["LineContainerComponent"], { title: "GENERAL" },
                 react__WEBPACK_IMPORTED_MODULE_0__["createElement"](_lines_textLineComponent__WEBPACK_IMPORTED_MODULE_2__["TextLineComponent"], { label: "ID", value: mesh.id }),
@@ -36767,7 +36812,9 @@ var MeshPropertyGridComponent = /** @class */ (function (_super) {
             react__WEBPACK_IMPORTED_MODULE_0__["createElement"](_lineContainerComponent__WEBPACK_IMPORTED_MODULE_1__["LineContainerComponent"], { title: "DEBUG", closed: true },
                 react__WEBPACK_IMPORTED_MODULE_0__["createElement"](_lines_checkBoxLineComponent__WEBPACK_IMPORTED_MODULE_3__["CheckBoxLineComponent"], { label: "Show bounding box", target: mesh, propertyName: "showBoundingBox", onPropertyChangedObservable: this.props.onPropertyChangedObservable }),
                 mesh.material &&
-                    react__WEBPACK_IMPORTED_MODULE_0__["createElement"](_lines_checkBoxLineComponent__WEBPACK_IMPORTED_MODULE_3__["CheckBoxLineComponent"], { label: "Display normals", isSelected: function () { return displayNormals; }, onSelect: function () { return _this.displayNormals(); } }))));
+                    react__WEBPACK_IMPORTED_MODULE_0__["createElement"](_lines_checkBoxLineComponent__WEBPACK_IMPORTED_MODULE_3__["CheckBoxLineComponent"], { label: "Display normals", isSelected: function () { return displayNormals; }, onSelect: function () { return _this.displayNormals(); } }),
+                mesh.isVerticesDataPresent(BABYLON.VertexBuffer.NormalKind) &&
+                    react__WEBPACK_IMPORTED_MODULE_0__["createElement"](_lines_checkBoxLineComponent__WEBPACK_IMPORTED_MODULE_3__["CheckBoxLineComponent"], { label: "Render vertex normals", isSelected: function () { return renderNormalVectors; }, onSelect: function () { return _this.renderNormalVectors(); } }))));
     };
     return MeshPropertyGridComponent;
 }(react__WEBPACK_IMPORTED_MODULE_0__["Component"]));
@@ -37395,7 +37442,7 @@ var __extends = (undefined && undefined.__extends) || (function () {
 
 
 
-var Split = __webpack_require__(/*! react-split */ "./node_modules/react-split/dist/react-split.js");
+var Split = __webpack_require__(/*! react-split */ "./node_modules/react-split/dist/react-split.es.js");
 __webpack_require__(/*! ./embedHost.scss */ "./src/components/embedHost/embedHost.scss");
 var EmbedHostComponent = /** @class */ (function (_super) {
     __extends(EmbedHostComponent, _super);
@@ -38409,12 +38456,16 @@ var SceneExplorerComponent = /** @class */ (function (_super) {
             this._onNewSceneAddedObserver = BABYLON.Engine.LastCreatedEngine.onNewSceneAddedObservable.addOnce(function (scene) { return _this.setState({ scene: scene }); });
             return null;
         }
+        var guiElements = scene.textures.filter(function (t) { return t.getClassName() === "AdvancedDynamicTexture"; });
+        var textures = scene.textures.filter(function (t) { return t.getClassName() !== "AdvancedDynamicTexture"; });
         return (react__WEBPACK_IMPORTED_MODULE_0__["createElement"]("div", { id: "tree" },
             react__WEBPACK_IMPORTED_MODULE_0__["createElement"](SceneExplorerFilterComponent, { onFilter: function (filter) { return _this.filterContent(filter); } }),
             react__WEBPACK_IMPORTED_MODULE_0__["createElement"](_entities_sceneTreeItemComponent__WEBPACK_IMPORTED_MODULE_4__["SceneTreeItemComponent"], { extensibilityGroups: this.props.extensibilityGroups, selectedEntity: this.state.selectedEntity, scene: scene, onRefresh: function () { return _this.forceUpdate(); }, onSelectionChangeObservable: this.props.globalState.onSelectionChangeObservable }),
             react__WEBPACK_IMPORTED_MODULE_0__["createElement"](_treeItemComponent__WEBPACK_IMPORTED_MODULE_1__["TreeItemComponent"], { extensibilityGroups: this.props.extensibilityGroups, selectedEntity: this.state.selectedEntity, items: scene.rootNodes, label: "Nodes", offset: 1, onSelectionChangeObservable: this.props.globalState.onSelectionChangeObservable, filter: this.state.filter }),
             react__WEBPACK_IMPORTED_MODULE_0__["createElement"](_treeItemComponent__WEBPACK_IMPORTED_MODULE_1__["TreeItemComponent"], { extensibilityGroups: this.props.extensibilityGroups, selectedEntity: this.state.selectedEntity, items: scene.materials, label: "Materials", offset: 1, onSelectionChangeObservable: this.props.globalState.onSelectionChangeObservable, filter: this.state.filter }),
-            react__WEBPACK_IMPORTED_MODULE_0__["createElement"](_treeItemComponent__WEBPACK_IMPORTED_MODULE_1__["TreeItemComponent"], { extensibilityGroups: this.props.extensibilityGroups, selectedEntity: this.state.selectedEntity, items: scene.textures, label: "Textures", offset: 1, onSelectionChangeObservable: this.props.globalState.onSelectionChangeObservable, filter: this.state.filter })));
+            react__WEBPACK_IMPORTED_MODULE_0__["createElement"](_treeItemComponent__WEBPACK_IMPORTED_MODULE_1__["TreeItemComponent"], { extensibilityGroups: this.props.extensibilityGroups, selectedEntity: this.state.selectedEntity, items: textures, label: "Textures", offset: 1, onSelectionChangeObservable: this.props.globalState.onSelectionChangeObservable, filter: this.state.filter }),
+            guiElements && guiElements.length > 0 &&
+                react__WEBPACK_IMPORTED_MODULE_0__["createElement"](_treeItemComponent__WEBPACK_IMPORTED_MODULE_1__["TreeItemComponent"], { extensibilityGroups: this.props.extensibilityGroups, selectedEntity: this.state.selectedEntity, items: guiElements, label: "GUI", offset: 1, onSelectionChangeObservable: this.props.globalState.onSelectionChangeObservable, filter: this.state.filter })));
     };
     SceneExplorerComponent.prototype.onClose = function () {
         if (!this.props.onClose) {

Diferenças do arquivo suprimidas por serem muito extensas
+ 1 - 1
dist/preview release/inspector/babylon.inspector.bundle.js.map


+ 15 - 1
dist/preview release/viewer/babylon.viewer.d.ts

@@ -924,7 +924,7 @@ declare module BabylonViewer {
       * @param name the name of the custom optimizer configuration
       * @param upgrade set to true if you want to upgrade optimizer and false if you want to degrade
       */
-    export function getCustomOptimizerByName(name: string, upgrade?: boolean): (sceneManager: SceneManager) => boolean;
+    export function getCustomOptimizerByName(name: string, upgrade?: boolean): typeof extendedUpgrade;
     export function registerCustomOptimizer(name: string, optimizer: (sceneManager: SceneManager) => boolean): void;
 }
 declare module BabylonViewer {
@@ -1558,6 +1558,20 @@ declare module BabylonViewer {
     export function addLoaderPlugin(name: string, plugin: ILoaderPlugin): void;
 }
 declare module BabylonViewer {
+    /**
+        * A custom upgrade-oriented function configuration for the scene optimizer.
+        *
+        * @param viewer the viewer to optimize
+        */
+    export function extendedUpgrade(sceneManager: SceneManager): boolean;
+    /**
+        * A custom degrade-oriented function configuration for the scene optimizer.
+        *
+        * @param viewer the viewer to optimize
+        */
+    export function extendedDegrade(sceneManager: SceneManager): boolean;
+}
+declare module BabylonViewer {
 }
 declare module BabylonViewer {
     export interface IEnvironmentMapConfiguration {

Diferenças do arquivo suprimidas por serem muito extensas
+ 1 - 1
dist/preview release/viewer/babylon.viewer.js


Diferenças do arquivo suprimidas por serem muito extensas
+ 1 - 1
dist/preview release/viewer/babylon.viewer.max.js


+ 18 - 1
dist/preview release/viewer/babylon.viewer.module.d.ts

@@ -985,13 +985,14 @@ declare module 'babylonjs-viewer/templating/viewerTemplatePlugin' {
 }
 
 declare module 'babylonjs-viewer/optimizer/custom' {
+    import { extendedUpgrade } from "babylonjs-viewer/optimizer/custom/extended";
     import { SceneManager } from "babylonjs-viewer/managers/sceneManager";
     /**
       *
       * @param name the name of the custom optimizer configuration
       * @param upgrade set to true if you want to upgrade optimizer and false if you want to degrade
       */
-    export function getCustomOptimizerByName(name: string, upgrade?: boolean): (sceneManager: SceneManager) => boolean;
+    export function getCustomOptimizerByName(name: string, upgrade?: boolean): typeof extendedUpgrade;
     export function registerCustomOptimizer(name: string, optimizer: (sceneManager: SceneManager) => boolean): void;
 }
 
@@ -1662,6 +1663,22 @@ declare module 'babylonjs-viewer/loader/plugins' {
     export function addLoaderPlugin(name: string, plugin: ILoaderPlugin): void;
 }
 
+declare module 'babylonjs-viewer/optimizer/custom/extended' {
+    import { SceneManager } from 'babylonjs-viewer/managers/sceneManager';
+    /**
+        * A custom upgrade-oriented function configuration for the scene optimizer.
+        *
+        * @param viewer the viewer to optimize
+        */
+    export function extendedUpgrade(sceneManager: SceneManager): boolean;
+    /**
+        * A custom degrade-oriented function configuration for the scene optimizer.
+        *
+        * @param viewer the viewer to optimize
+        */
+    export function extendedDegrade(sceneManager: SceneManager): boolean;
+}
+
 declare module 'babylonjs-viewer/configuration/interfaces' {
     export * from 'babylonjs-viewer/configuration/interfaces/cameraConfiguration';
     export * from 'babylonjs-viewer/configuration/interfaces/colorGradingConfiguration';

+ 44 - 15
gui/src/2D/advancedDynamicTexture.ts

@@ -80,6 +80,11 @@ export class AdvancedDynamicTexture extends DynamicTexture {
     public onClipboardObservable = new Observable<ClipboardInfo>();
 
     /**
+     * Observable event triggered each time a pointer down is intercepted by a control
+     */
+    public onControlPickedObservable = new Observable<Control>();
+
+    /**
      * Gets or sets a boolean defining if alpha is stored as premultiplied
      */
     public premulAlpha = false;
@@ -204,6 +209,14 @@ export class AdvancedDynamicTexture extends DynamicTexture {
     }
 
     /**
+     * Returns an array containing the root container.
+     * This is mostly used to let the Inspector introspects the ADT
+     */
+    public getChildren(): Array<Container> {
+        return [this._rootContainer];
+    }
+
+    /**
      * Gets or sets the current focused control
      */
     public get focusedControl(): Nullable<IFocusableControl> {
@@ -256,15 +269,15 @@ export class AdvancedDynamicTexture extends DynamicTexture {
         this._clipboardData = value;
     }
 
-     /**
-     * Creates a new AdvancedDynamicTexture
-     * @param name defines the name of the texture
-     * @param width defines the width of the texture
-     * @param height defines the height of the texture
-     * @param scene defines the hosting scene
-     * @param generateMipMaps defines a boolean indicating if mipmaps must be generated (false by default)
-     * @param samplingMode defines the texture sampling mode (Texture.NEAREST_SAMPLINGMODE by default)
-     */
+    /**
+    * Creates a new AdvancedDynamicTexture
+    * @param name defines the name of the texture
+    * @param width defines the width of the texture
+    * @param height defines the height of the texture
+    * @param scene defines the hosting scene
+    * @param generateMipMaps defines a boolean indicating if mipmaps must be generated (false by default)
+    * @param samplingMode defines the texture sampling mode (Texture.NEAREST_SAMPLINGMODE by default)
+    */
     constructor(name: string, width = 0, height = 0, scene: Nullable<Scene>, generateMipMaps = false, samplingMode = Texture.NEAREST_SAMPLINGMODE) {
         super(name, { width: width, height: height }, scene, generateMipMaps, samplingMode, Engine.TEXTUREFORMAT_RGBA);
 
@@ -302,6 +315,14 @@ export class AdvancedDynamicTexture extends DynamicTexture {
     }
 
     /**
+     * Get the current class name of the texture useful for serialization or dynamic coding.
+     * @returns "AdvancedDynamicTexture"
+     */
+    public getClassName(): string {
+        return "AdvancedDynamicTexture";
+    }
+
+    /**
      * Function used to execute a function on all controls
      * @param func defines the function to execute
      * @param container defines the container where controls belong. If null the root container will be used
@@ -401,6 +422,7 @@ export class AdvancedDynamicTexture extends DynamicTexture {
 
         this._rootContainer.dispose();
         this.onClipboardObservable.clear();
+        this.onControlPickedObservable.clear();
 
         super.dispose();
     }
@@ -549,6 +571,13 @@ export class AdvancedDynamicTexture extends DynamicTexture {
         }
     }
 
+    /** @hidden */
+    public _registerLastControlDown(control: Control, pointerId: number) {
+        this._lastControlDown[pointerId] = control;
+
+        this.onControlPickedObservable.notifyObservers(control);
+    }
+
     private _doPicking(x: number, y: number, type: number, pointerId: number, buttonIndex: number): void {
         var scene = this.getScene();
 
@@ -617,7 +646,7 @@ export class AdvancedDynamicTexture extends DynamicTexture {
             if (pi.type !== PointerEventTypes.POINTERMOVE
                 && pi.type !== PointerEventTypes.POINTERUP
                 && pi.type !== PointerEventTypes.POINTERDOWN) {
-                    return;
+                return;
             }
 
             if (!scene) {
@@ -653,7 +682,7 @@ export class AdvancedDynamicTexture extends DynamicTexture {
         this.onClipboardObservable.notifyObservers(ev);
         evt.preventDefault();
     }
-     /** @hidden */
+    /** @hidden */
     private onClipboardCut = (evt: ClipboardEvent) => {
         let ev = new ClipboardInfo(ClipboardEventTypes.CUT, evt);
         this.onClipboardObservable.notifyObservers(ev);
@@ -666,9 +695,9 @@ export class AdvancedDynamicTexture extends DynamicTexture {
         evt.preventDefault();
     }
 
-   /**
-    * Register the clipboard Events onto the canvas
-    */
+    /**
+     * Register the clipboard Events onto the canvas
+     */
     public registerClipboardEvents(): void {
         self.addEventListener("copy", this.onClipboardCopy, false);
         self.addEventListener("cut", this.onClipboardCut, false);
@@ -679,7 +708,7 @@ export class AdvancedDynamicTexture extends DynamicTexture {
      */
     public unRegisterClipboardEvents(): void {
         self.removeEventListener("copy", this.onClipboardCopy);
-        self.removeEventListener("cut",  this.onClipboardCut);
+        self.removeEventListener("cut", this.onClipboardCut);
         self.removeEventListener("paste", this.onClipboardPaste);
     }
 

+ 22 - 10
gui/src/2D/controls/colorpicker.ts

@@ -353,22 +353,22 @@ export class ColorPicker extends Control {
         this.value = this._tmpColor;
     }
 
-    private _isPointOnSquare(coordinates: Vector2): boolean {
+    private _isPointOnSquare(x: number, y: number): boolean {
         this._updateSquareProps();
 
         var left = this._squareLeft;
         var top = this._squareTop;
         var size = this._squareSize;
 
-        if (coordinates.x >= left && coordinates.x <= left + size &&
-            coordinates.y >= top && coordinates.y <= top + size) {
+        if (x >= left && x <= left + size &&
+            y >= top && y <= top + size) {
             return true;
         }
 
         return false;
     }
 
-    private _isPointOnWheel(coordinates: Vector2): boolean {
+    private _isPointOnWheel(x: number, y: number): boolean {
         var radius = Math.min(this._currentMeasure.width, this._currentMeasure.height) * .5;
         var centerX = radius + this._currentMeasure.left;
         var centerY = radius + this._currentMeasure.top;
@@ -377,8 +377,8 @@ export class ColorPicker extends Control {
         var radiusSq = radius * radius;
         var innerRadiusSq = innerRadius * innerRadius;
 
-        var dx = coordinates.x - centerX;
-        var dy = coordinates.y - centerY;
+        var dx = x - centerX;
+        var dy = y - centerY;
 
         var distSq = dx * dx + dy * dy;
 
@@ -399,21 +399,33 @@ export class ColorPicker extends Control {
         this._pointerStartedOnSquare = false;
         this._pointerStartedOnWheel = false;
 
-        if (this._isPointOnSquare(coordinates)) {
+        // Invert transform
+        this._invertTransformMatrix.transformCoordinates(coordinates.x, coordinates.y, this._transformedPosition);
+
+        let x = this._transformedPosition.x;
+        let y = this._transformedPosition.y;
+
+        if (this._isPointOnSquare(x, y)) {
             this._pointerStartedOnSquare = true;
-        } else if (this._isPointOnWheel(coordinates)) {
+        } else if (this._isPointOnWheel(x, y)) {
             this._pointerStartedOnWheel = true;
         }
 
-        this._updateValueFromPointer(coordinates.x, coordinates.y);
+        this._updateValueFromPointer(x, y);
         this._host._capturingControl[pointerId] = this;
 
         return true;
     }
 
     public _onPointerMove(target: Control, coordinates: Vector2): void {
+        // Invert transform
+        this._invertTransformMatrix.transformCoordinates(coordinates.x, coordinates.y, this._transformedPosition);
+
+        let x = this._transformedPosition.x;
+        let y = this._transformedPosition.y;
+
         if (this._pointerIsDown) {
-            this._updateValueFromPointer(coordinates.x, coordinates.y);
+            this._updateValueFromPointer(x, y);
         }
 
         super._onPointerMove(target, coordinates);

+ 2 - 0
gui/src/2D/controls/container.ts

@@ -270,6 +270,7 @@ export class Container extends Control {
             }
 
             this._localDraw(context);
+            this._renderHighlight(context);
 
             if (this.clipChildren) {
                 this._clipForChildren(context);
@@ -283,6 +284,7 @@ export class Container extends Control {
                     child._tempParentMeasure.copyFrom(this._measureForChildren);
 
                     child._draw(this._measureForChildren, context);
+                    child._renderHighlight(context);
 
                     if (child.onAfterDrawObservable.hasObservers()) {
                         child.onAfterDrawObservable.notifyObservers(child);

+ 51 - 1
gui/src/2D/controls/control.ts

@@ -73,6 +73,7 @@ export class Control {
     private _cachedOffsetX: number;
     private _cachedOffsetY: number;
     private _isVisible = true;
+    private _isHighlighted = false;
     /** @hidden */
     public _linkedMesh: Nullable<AbstractMesh>;
     private _fontSet = false;
@@ -87,6 +88,11 @@ export class Control {
     public _tag: any;
 
     /**
+     * Gets or sets the unique id of the node. Please note that this number will be updated when the control is added to a container
+     */
+    public uniqueId: number;
+
+    /**
      * Gets or sets an object used to store user defined information for the node
      */
     public metadata: any = null;
@@ -126,6 +132,14 @@ export class Control {
     }
 
     /**
+     * Get the current class name of the control.
+     * @returns current class name
+     */
+    public getClassName(): string {
+        return this._getTypeName();
+    }
+
+    /**
     * An event triggered when the pointer move over the control.
     */
     public onPointerMoveObservable = new Observable<Vector2>();
@@ -193,6 +207,22 @@ export class Control {
         this._markAsDirty();
     }
 
+    /**
+     * Gets or sets a boolean indicating that we want to highlight the control (mostly for debugging purpose)
+     */
+    public get isHighlighted(): boolean {
+        return this._isHighlighted;
+    }
+
+    public set isHighlighted(value: boolean) {
+        if (this._isHighlighted === value) {
+            return;
+        }
+
+        this._isHighlighted = value;
+        this._markAsDirty();
+    }
+
     /** Gets or sets a value indicating the scale factor on X axis (1 by default)
      * @see http://doc.babylonjs.com/how_to/gui#rotation-and-scaling
     */
@@ -946,6 +976,9 @@ export class Control {
     public _link(root: Nullable<Container>, host: AdvancedDynamicTexture): void {
         this._root = root;
         this._host = host;
+        if (this._host) {
+            this.uniqueId = this._host.getScene()!.getUniqueId();
+        }
     }
 
     /** @hidden */
@@ -982,6 +1015,23 @@ export class Control {
     }
 
     /** @hidden */
+    public _renderHighlight(context: CanvasRenderingContext2D): void {
+        if (!this.isHighlighted) {
+            return;
+        }
+
+        context.strokeStyle = "#4affff";
+        context.lineWidth = 2;
+
+        this._renderHighlightSpecific(context);
+    }
+
+    /** @hidden */
+    protected _renderHighlightSpecific(context: CanvasRenderingContext2D): void {
+        context.strokeRect(this._currentMeasure.left, this._currentMeasure.top, this._currentMeasure.width, this._currentMeasure.height);
+    }
+
+    /** @hidden */
     protected _applyStates(context: CanvasRenderingContext2D): void {
         if (this._isFontSizeInPercentage) {
             this._fontSet = true;
@@ -1378,7 +1428,7 @@ export class Control {
 
         if (type === PointerEventTypes.POINTERDOWN) {
             this._onPointerDown(this, this._dummyVector2, pointerId, buttonIndex);
-            this._host._lastControlDown[pointerId] = this;
+            this._host._registerLastControlDown(this, pointerId);
             this._host._lastPickedControl = this;
             return true;
         }

+ 59 - 11
gui/src/2D/controls/grid.ts

@@ -286,7 +286,7 @@ export class Grid extends Container {
         return "Grid";
     }
 
-    protected _additionalProcessing(parentMeasure: Measure, context: CanvasRenderingContext2D): void {
+    protected _getGridDefinitions(definitionCallback: (lefts: number[], tops: number[], widths: number[], heights: number[]) => void) {
         let widths = [];
         let heights = [];
         let lefts = [];
@@ -352,23 +352,71 @@ export class Grid extends Container {
             index++;
         }
 
-        // Setting child sizes
+        definitionCallback(lefts, tops, widths, heights);
+    }
+
+    protected _additionalProcessing(parentMeasure: Measure, context: CanvasRenderingContext2D): void {
+        this._getGridDefinitions((lefts: number[], tops: number[], widths: number[], heights: number[]) => {
+            // Setting child sizes
+            for (var key in this._cells) {
+                if (!this._cells.hasOwnProperty(key)) {
+                    continue;
+                }
+                let split = key.split(":");
+                let x = parseInt(split[0]);
+                let y = parseInt(split[1]);
+                let cell = this._cells[key];
+
+                cell.left = lefts[y] + "px";
+                cell.top = tops[x] + "px";
+                cell.width = widths[y] + "px";
+                cell.height = heights[x] + "px";
+            }
+        });
+
+        super._additionalProcessing(parentMeasure, context);
+    }
+
+    public _flagDescendantsAsMatrixDirty(): void {
         for (var key in this._cells) {
             if (!this._cells.hasOwnProperty(key)) {
                 continue;
             }
-            let split = key.split(":");
-            let x = parseInt(split[0]);
-            let y = parseInt(split[1]);
-            let cell = this._cells[key];
 
-            cell.left = lefts[y] + "px";
-            cell.top = tops[x] + "px";
-            cell.width = widths[y] + "px";
-            cell.height = heights[x] + "px";
+            let child = this._cells[key];
+            child._markMatrixAsDirty();
         }
+    }
 
-        super._additionalProcessing(parentMeasure, context);
+    protected _renderHighlightSpecific(context: CanvasRenderingContext2D): void {
+        if (!this.isHighlighted) {
+            return;
+        }
+
+        super._renderHighlightSpecific(context);
+
+        this._getGridDefinitions((lefts: number[], tops: number[], widths: number[], heights: number[]) => {
+
+            // Columns
+            for (var index = 0; index < lefts.length; index++) {
+                const left = this._currentMeasure.left + lefts[index] + widths[index];
+                context.beginPath();
+                context.moveTo(left, this._currentMeasure.top);
+                context.lineTo(left, this._currentMeasure.top + this._currentMeasure.height);
+                context.stroke();
+            }
+
+            // Rows
+            for (var index = 0; index < tops.length; index++) {
+                const top = this._currentMeasure.top + tops[index] + heights[index];
+                context.beginPath();
+                context.moveTo(this._currentMeasure.left, top);
+                context.lineTo(this._currentMeasure.left + this._currentMeasure.width, top);
+                context.stroke();
+            }
+        });
+
+        context.restore();
     }
 
     /** Releases associated resources */

+ 9 - 0
gui/src/3D/controls/control3D.ts

@@ -196,11 +196,20 @@ export class Control3D implements IDisposable, IBehaviorAware<Control3D> {
 
     /**
      * Gets a string representing the class name
+     * @returns current class name
      */
     public get typeName(): string {
         return this._getTypeName();
     }
 
+    /**
+     * Get the current class name of the control.
+     * @returns current class name
+     */
+    public get getClassName(): string {
+        return this._getTypeName();
+    }
+
     protected _getTypeName(): string {
         return "Control3D";
     }

+ 23 - 0
inspector/src/components/actionTabs/actionTabs.scss

@@ -211,6 +211,29 @@
                     }
                 }
 
+                .textInputLine {
+                    padding-left: 5px;
+                    height: 30px;
+                    display: grid;
+                    grid-template-columns: 1fr 120px;
+
+                    .label {
+                        grid-column: 1;
+                        display: flex;
+                        align-items: center;
+                    }
+
+                    .value {                        
+                        display: flex;
+                        align-items: center;
+                        grid-column: 2;
+                        
+                        input {
+                            width: 110px;
+                        }
+                    }
+                }
+
                 .buttonLine {
                     height: 30px;
                     display: grid;

+ 1 - 0
inspector/src/components/actionTabs/lines/floatLineComponent.tsx

@@ -64,6 +64,7 @@ export class FloatLineComponent extends React.Component<IFloatLineComponentProps
         }
 
         this.raiseOnPropertyChanged(valueAsNumber, this._store);
+        this.props.target[this.props.propertyName] = valueAsNumber;
 
         this._store = valueAsNumber;
     }

+ 69 - 0
inspector/src/components/actionTabs/lines/textInputLineComponent.tsx

@@ -0,0 +1,69 @@
+import * as React from "react";
+import { Observable } from "babylonjs";
+import { PropertyChangedEvent } from "components/propertyChangedEvent";
+
+interface ITextInputLineComponentProps {
+    label: string,
+    target: any,
+    propertyName: string,
+    onPropertyChangedObservable?: Observable<PropertyChangedEvent>
+}
+
+export class TextInputLineComponent extends React.Component<ITextInputLineComponentProps, { value: string }> {
+    private _localChange = false;
+
+    constructor(props: ITextInputLineComponentProps) {
+        super(props);
+
+        this.state = { value: this.props.target[this.props.propertyName] || "" }
+    }
+
+    shouldComponentUpdate(nextProps: ITextInputLineComponentProps, nextState: { value: string }) {
+        if (this._localChange) {
+            this._localChange = false;
+            return true;
+        }
+
+        const newValue = nextProps.target[nextProps.propertyName];
+        if (newValue !== nextState.value) {
+            nextState.value = newValue || "";
+            return true;
+        }
+        return false;
+    }
+
+    raiseOnPropertyChanged(newValue: string, previousValue: string) {
+        if (!this.props.onPropertyChangedObservable) {
+            return;
+        }
+        this.props.onPropertyChangedObservable.notifyObservers({
+            object: this.props.target,
+            property: this.props.propertyName,
+            value: newValue,
+            initialValue: previousValue
+        });
+    }
+
+    updateValue(value: string) {
+
+        this._localChange = true;
+        const store = this.props.target[this.props.propertyName];
+        this.setState({ value: value });
+
+        this.raiseOnPropertyChanged(value, store);
+        this.props.target[this.props.propertyName] = value;
+    }
+
+    render() {
+        return (
+            <div className="textInputLine">
+                <div className="label">
+                    {this.props.label}
+                </div>
+                <div className="value">
+                    <input value={this.state.value} onChange={evt => this.updateValue(evt.target.value)} />
+                </div>
+            </div>
+        );
+    }
+}

+ 28 - 0
inspector/src/components/actionTabs/tabs/propertyGridTabComponent.tsx

@@ -13,6 +13,14 @@ import { ArcRotateCameraPropertyGridComponent } from "./propertyGrids/cameras/ar
 import { MeshPropertyGridComponent } from "./propertyGrids/meshes/meshPropertyGridComponent";
 import { TransformNodePropertyGridComponent } from "./propertyGrids/meshes/transformNodePropertyGridComponent";
 import { BackgroundMaterialPropertyGridComponent } from "./propertyGrids/materials/backgroundMaterialPropertyGridComponent";
+import { Control } from "babylonjs-gui/2D/controls/control";
+import { ControlPropertyGridComponent } from "./propertyGrids/gui/controlPropertyGridComponent";
+import { TextBlockPropertyGridComponent } from "./propertyGrids/gui/textBlockPropertyGridComponent";
+import { TextBlock } from "babylonjs-gui/2D/controls/textBlock";
+import { InputText } from "babylonjs-gui/2D/controls/inputText";
+import { InputTextPropertyGridComponent } from "./propertyGrids/gui/inputTextPropertyGridComponent";
+import { ColorPicker } from "babylonjs-gui";
+import { ColorPickerPropertyGridComponent } from "./propertyGrids/gui/colorPickerPropertyGridComponent";
 
 export class PropertyGridTabComponent extends PaneComponent {
     constructor(props: IPaneComponentProps) {
@@ -104,6 +112,26 @@ export class PropertyGridTabComponent extends PaneComponent {
                 const texture = entity as Texture;
                 return (<TexturePropertyGridComponent texture={texture} onPropertyChangedObservable={this.props.onPropertyChangedObservable} />);
             }
+
+            if (className === "TextBlock") {
+                const textBlock = entity as TextBlock;
+                return (<TextBlockPropertyGridComponent textBlock={textBlock} onPropertyChangedObservable={this.props.onPropertyChangedObservable} />);
+            }
+
+            if (className === "InputText") {
+                const inputText = entity as InputText;
+                return (<InputTextPropertyGridComponent inputText={inputText} onPropertyChangedObservable={this.props.onPropertyChangedObservable} />);
+            }
+
+            if (className === "ColorPicker") {
+                const colorPicker = entity as ColorPicker;
+                return (<ColorPickerPropertyGridComponent colorPicker={colorPicker} onPropertyChangedObservable={this.props.onPropertyChangedObservable} />);
+            }
+
+            if (entity._host) {
+                const control = entity as Control;
+                return (<ControlPropertyGridComponent control={control} onPropertyChangedObservable={this.props.onPropertyChangedObservable} />);
+            }
         } else if (entity.transformNodes) {
             const scene = entity as Scene;
             return (<ScenePropertyGridComponent scene={scene} onPropertyChangedObservable={this.props.onPropertyChangedObservable} />);

+ 31 - 0
inspector/src/components/actionTabs/tabs/propertyGrids/gui/colorPickerPropertyGridComponent.tsx

@@ -0,0 +1,31 @@
+import * as React from "react";
+import { Observable } from "babylonjs";
+import { PropertyChangedEvent } from "../../../../propertyChangedEvent";
+import { CommonControlPropertyGridComponent } from "./commonControlPropertyGridComponent";
+import { LineContainerComponent } from "../../../lineContainerComponent";
+import { ColorPicker } from "babylonjs-gui/2D/controls/colorpicker";
+import { Color3LineComponent } from "../../../lines/color3LineComponent";
+
+interface IColorPickerPropertyGridComponentProps {
+    colorPicker: ColorPicker,
+    onPropertyChangedObservable?: Observable<PropertyChangedEvent>
+}
+
+export class ColorPickerPropertyGridComponent extends React.Component<IColorPickerPropertyGridComponentProps> {
+    constructor(props: IColorPickerPropertyGridComponentProps) {
+        super(props);
+    }
+
+    render() {
+        const colorPicker = this.props.colorPicker;
+
+        return (
+            <div className="pane">
+                <CommonControlPropertyGridComponent control={colorPicker} onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
+                <LineContainerComponent title="COLORPICKER">
+                    <Color3LineComponent label="Color" target={colorPicker} propertyName="value" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
+                </LineContainerComponent>
+            </div>
+        );
+    }
+}

+ 58 - 0
inspector/src/components/actionTabs/tabs/propertyGrids/gui/commonControlPropertyGridComponent.tsx

@@ -0,0 +1,58 @@
+import * as React from "react";
+import { Observable } from "babylonjs";
+import { PropertyChangedEvent } from "../../../../propertyChangedEvent";
+import { LineContainerComponent } from "../../../lineContainerComponent";
+import { TextLineComponent } from "../../../lines/textLineComponent";
+import { Control } from "babylonjs-gui/2D/controls/control";
+import { SliderLineComponent } from "../../../lines/sliderLineComponent";
+import { FloatLineComponent } from "../../../lines/floatLineComponent";
+import { TextInputLineComponent } from "../../../lines/textInputLineComponent";
+
+interface ICommonControlPropertyGridComponentProps {
+    control: Control,
+    onPropertyChangedObservable?: Observable<PropertyChangedEvent>
+}
+
+export class CommonControlPropertyGridComponent extends React.Component<ICommonControlPropertyGridComponentProps> {
+    constructor(props: ICommonControlPropertyGridComponentProps) {
+        super(props);
+    }
+
+    render() {
+        const control = this.props.control;
+
+        return (
+            <div>
+                <LineContainerComponent title="GENERAL">
+                    <TextLineComponent label="Class" value={control.getClassName()} />
+                    <SliderLineComponent label="Alpha" target={control} propertyName="alpha" minimum={0} maximum={1} step={0.01} onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
+                    <TextInputLineComponent label="Color" target={control} propertyName="color" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
+                    <TextInputLineComponent label="Background" target={control} propertyName="background" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
+                </LineContainerComponent>
+                <LineContainerComponent title="POSITION">
+                    <TextInputLineComponent label="Left" target={control} propertyName="left" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
+                    <TextInputLineComponent label="Top" target={control} propertyName="top" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
+                    <TextInputLineComponent label="Width" target={control} propertyName="width" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
+                    <TextInputLineComponent label="Height" target={control} propertyName="height" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
+                    <TextInputLineComponent label="Padding left" target={control} propertyName="paddingLeft" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
+                    <TextInputLineComponent label="Padding top" target={control} propertyName="paddingTop" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
+                    <TextInputLineComponent label="Padding right" target={control} propertyName="paddingRight" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
+                    <TextInputLineComponent label="Padding bottom" target={control} propertyName="paddingBottom" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
+                </LineContainerComponent>
+                <LineContainerComponent title="TRANSFORMATION" closed={true}>
+                    <FloatLineComponent label="ScaleX" target={control} propertyName="scaleX" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
+                    <FloatLineComponent 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 label="Transform center X" target={control} propertyName="transformCenterX" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
+                    <FloatLineComponent label="Transform center Y" target={control} propertyName="transformCenterY" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
+                </LineContainerComponent>
+                <LineContainerComponent title="FONT" closed={true}>
+                    <TextInputLineComponent label="Family" target={control} propertyName="fontFamily" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
+                    <TextInputLineComponent label="Size" target={control} propertyName="fontSize" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
+                    <TextInputLineComponent label="Weight" target={control} propertyName="fontWeight" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
+                    <TextInputLineComponent label="Style" target={control} propertyName="fontStyle" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
+                </LineContainerComponent>
+            </div>
+        );
+    }
+}

+ 26 - 0
inspector/src/components/actionTabs/tabs/propertyGrids/gui/controlPropertyGridComponent.tsx

@@ -0,0 +1,26 @@
+import * as React from "react";
+import { Observable } from "babylonjs";
+import { PropertyChangedEvent } from "../../../../propertyChangedEvent";
+import { Control } from "babylonjs-gui/2D/controls/control";
+import { CommonControlPropertyGridComponent } from "./commonControlPropertyGridComponent";
+
+interface IControlPropertyGridComponentProps {
+    control: Control,
+    onPropertyChangedObservable?: Observable<PropertyChangedEvent>
+}
+
+export class ControlPropertyGridComponent extends React.Component<IControlPropertyGridComponentProps> {
+    constructor(props: IControlPropertyGridComponentProps) {
+        super(props);
+    }
+
+    render() {
+        const control = this.props.control;
+
+        return (
+            <div className="pane">
+                <CommonControlPropertyGridComponent control={control} onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
+            </div>
+        );
+    }
+}

+ 46 - 0
inspector/src/components/actionTabs/tabs/propertyGrids/gui/inputTextPropertyGridComponent.tsx

@@ -0,0 +1,46 @@
+import * as React from "react";
+import { Observable } from "babylonjs";
+import { PropertyChangedEvent } from "../../../../propertyChangedEvent";
+import { CommonControlPropertyGridComponent } from "./commonControlPropertyGridComponent";
+import { InputText } from "babylonjs-gui";
+import { LineContainerComponent } from "../../../lineContainerComponent";
+import { TextInputLineComponent } from "../../../lines/textInputLineComponent";
+import { SliderLineComponent } from "../../../lines/sliderLineComponent";
+import { CheckBoxLineComponent } from "../../../lines/checkBoxLineComponent";
+import { FloatLineComponent } from "../../../lines/floatLineComponent";
+
+interface IInputTextPropertyGridComponentProps {
+    inputText: InputText,
+    onPropertyChangedObservable?: Observable<PropertyChangedEvent>
+}
+
+export class InputTextPropertyGridComponent extends React.Component<IInputTextPropertyGridComponentProps> {
+    constructor(props: IInputTextPropertyGridComponentProps) {
+        super(props);
+    }
+
+    render() {
+        const inputText = this.props.inputText;
+
+        return (
+            <div className="pane">
+                <CommonControlPropertyGridComponent control={inputText} onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
+                <LineContainerComponent title="INPUTTEXT">
+                    <TextInputLineComponent label="Text" target={inputText} propertyName="text" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
+                    <TextInputLineComponent label="Prompt" target={inputText} propertyName="promptMessage" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
+                    <TextInputLineComponent label="Max width" target={inputText} propertyName="maxWidth" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
+                    <TextInputLineComponent label="Highlight color" target={inputText} propertyName="textHighlightColor" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
+                    <SliderLineComponent label="Highligher opacity" minimum={0} maximum={1} step={0.01} target={inputText} propertyName="highligherOpacity" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
+                    <CheckBoxLineComponent label="On focus select all" target={inputText} propertyName="onFocusSelectAll" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
+                    <TextInputLineComponent label="Focused background" target={inputText} propertyName="focusedBackground" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
+                    <TextInputLineComponent label="Max width" target={inputText} propertyName="maxWidth" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
+                    <TextInputLineComponent label="Margin" target={inputText} propertyName="margin" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
+                    <CheckBoxLineComponent label="Auto stretch width" target={inputText} propertyName="autoStretchWidth" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
+                    <FloatLineComponent label="Thickness" target={inputText} propertyName="thickness" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
+                    <TextInputLineComponent label="Placeholder text" target={inputText} propertyName="placeholderText" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
+                    <TextInputLineComponent label="Placeholder color" target={inputText} propertyName="placeholderColor" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
+                </LineContainerComponent>
+            </div>
+        );
+    }
+}

+ 31 - 0
inspector/src/components/actionTabs/tabs/propertyGrids/gui/textBlockPropertyGridComponent.tsx

@@ -0,0 +1,31 @@
+import * as React from "react";
+import { Observable } from "babylonjs";
+import { PropertyChangedEvent } from "../../../../propertyChangedEvent";
+import { CommonControlPropertyGridComponent } from "./commonControlPropertyGridComponent";
+import { TextBlock } from "babylonjs-gui";
+import { LineContainerComponent } from "../../../lineContainerComponent";
+import { TextInputLineComponent } from "../../../lines/textInputLineComponent";
+
+interface ITextBlockPropertyGridComponentProps {
+    textBlock: TextBlock,
+    onPropertyChangedObservable?: Observable<PropertyChangedEvent>
+}
+
+export class TextBlockPropertyGridComponent extends React.Component<ITextBlockPropertyGridComponentProps> {
+    constructor(props: ITextBlockPropertyGridComponentProps) {
+        super(props);
+    }
+
+    render() {
+        const textBlock = this.props.textBlock;
+
+        return (
+            <div className="pane">
+                <CommonControlPropertyGridComponent control={textBlock} onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
+                <LineContainerComponent title="TEXTBLOCK">
+                    <TextInputLineComponent label="Text" target={textBlock} propertyName="text" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
+                </LineContainerComponent>
+            </div>
+        );
+    }
+}

+ 13 - 0
inspector/src/components/actionTabs/tabs/propertyGrids/texturePropertyGridComponent.tsx

@@ -7,6 +7,7 @@ import { TextLineComponent } from "../../lines/textLineComponent";
 import { CheckBoxLineComponent } from "../../lines/checkBoxLineComponent";
 import { TextureLineComponent } from "../../lines/textureLineComponent";
 import { FloatLineComponent } from "../../lines/floatLineComponent";
+import { AdvancedDynamicTexture } from "babylonjs-gui";
 
 interface ITexturePropertyGridComponentProps {
     texture: Texture,
@@ -20,6 +21,7 @@ export class TexturePropertyGridComponent extends React.Component<ITextureProper
 
     render() {
         const texture = this.props.texture;
+        const adtTexture = texture instanceof AdvancedDynamicTexture ? texture as AdvancedDynamicTexture : null;
 
         return (
             <div className="pane">
@@ -34,6 +36,17 @@ export class TexturePropertyGridComponent extends React.Component<ITextureProper
                     <TextLineComponent label="Has mipmaps" value={!texture.noMipmap ? "Yes" : "No"} />
                     <SliderLineComponent label="UV set" target={texture} propertyName="coordinatesIndex" minimum={0} maximum={3} step={1} onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
                 </LineContainerComponent>
+                {
+                    adtTexture &&
+                    <LineContainerComponent title="ADVANCED TEXTURE PROPERTIES">
+                        <SliderLineComponent label="Render scale" minimum={0.1} maximum={5} target={adtTexture} propertyName="renderScale" step={0.1} onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
+                        <CheckBoxLineComponent label="Premultiply alpha" target={adtTexture} propertyName="premulAlpha" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
+                        <FloatLineComponent label="Ideal width" target={adtTexture} propertyName="idealWidth" step={0.1} onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
+                        <FloatLineComponent label="Ideal height" target={adtTexture} propertyName="idealHeight" step={0.1} onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
+                        <CheckBoxLineComponent label="Use smallest ideal" target={adtTexture} propertyName="useSmallestIdeal" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
+                        <CheckBoxLineComponent label="Render at ideal size" target={adtTexture} propertyName="renderAtIdealSize" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
+                    </LineContainerComponent>
+                }
                 <LineContainerComponent title="TRANSFORM">
                     <FloatLineComponent label="U offset" target={texture} propertyName="uOffset" step={0.1} onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
                     <FloatLineComponent label="V offset" target={texture} propertyName="vOffset" step={0.1} onPropertyChangedObservable={this.props.onPropertyChangedObservable} />

+ 1 - 3
inspector/src/components/sceneExplorer/entities/cameraTreeItemComponent.tsx

@@ -64,9 +64,7 @@ export class CameraTreeItemComponent extends React.Component<ICameraTreeItemComp
                 <div className="activeCamera icon" onClick={() => this.setActive()} title="Set as main camera">
                     {isActiveElement}
                 </div>
-                {
-                    <ExtensionsComponent target={this.props.camera} extensibilityGroups={this.props.extensibilityGroups} />
-                }
+                <ExtensionsComponent target={this.props.camera} extensibilityGroups={this.props.extensibilityGroups} />
             </div>
         )
     }

+ 43 - 0
inspector/src/components/sceneExplorer/entities/gui/advancedDynamicTextureTreeItemComponent.tsx

@@ -0,0 +1,43 @@
+import { faImage, faCrosshairs } from '@fortawesome/free-solid-svg-icons';
+import { IExplorerExtensibilityGroup } from "babylonjs";
+import { TreeItemLabelComponent } from "../../treeItemLabelComponent";
+import { ExtensionsComponent } from "../../extensionsComponent";
+import * as React from 'react';
+import { AdvancedDynamicTexture } from 'babylonjs-gui';
+import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
+
+interface IAdvancedDynamicTextureTreeItemComponentProps {
+    texture: AdvancedDynamicTexture,
+    extensibilityGroups?: IExplorerExtensibilityGroup[],
+    onClick: () => void
+}
+
+export class AdvancedDynamicTextureTreeItemComponent extends React.Component<IAdvancedDynamicTextureTreeItemComponentProps, { isInPickingMode: boolean }> {
+    constructor(props: IAdvancedDynamicTextureTreeItemComponentProps) {
+        super(props);
+
+        this.state = { isInPickingMode: false };
+    }
+
+    onPickingMode() {
+        let adt = this.props.texture;
+
+
+        if (!this.state.isInPickingMode) {
+        }
+
+        this.setState({ isInPickingMode: !this.state.isInPickingMode });
+    }
+
+    render() {
+        return (
+            <div className="adtextureTools">
+                <TreeItemLabelComponent label={this.props.texture.name} onClick={() => this.props.onClick()} icon={faImage} color="mediumpurple" />
+                <div className={this.state.isInPickingMode ? "pickingMode selected icon" : "pickingMode icon"} onClick={() => this.onPickingMode()} title="Turn picking mode on/off">
+                    <FontAwesomeIcon icon={faCrosshairs} />
+                </div>
+                <ExtensionsComponent target={this.props.texture} extensibilityGroups={this.props.extensibilityGroups} />
+            </div>
+        )
+    }
+}

+ 55 - 0
inspector/src/components/sceneExplorer/entities/gui/controlTreeItemComponent.tsx

@@ -0,0 +1,55 @@
+import { faObjectGroup, faHighlighter, faEye, faEyeSlash } from '@fortawesome/free-solid-svg-icons';
+import { IExplorerExtensibilityGroup } from "babylonjs";
+import { Control } from "babylonjs-gui";
+import { TreeItemLabelComponent } from "../../treeItemLabelComponent";
+import { ExtensionsComponent } from "../../extensionsComponent";
+import * as React from 'react';
+import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
+
+interface IControlTreeItemComponentProps {
+    control: Control,
+    extensibilityGroups?: IExplorerExtensibilityGroup[],
+    onClick: () => void
+}
+
+export class ControlTreeItemComponent extends React.Component<IControlTreeItemComponentProps, { isActive: boolean, isVisible: boolean }> {
+    constructor(props: IControlTreeItemComponentProps) {
+        super(props);
+
+        const control = this.props.control;
+        this.state = { isActive: control.isHighlighted, isVisible: control.isVisible };
+    }
+
+    highlight() {
+        const control = this.props.control;
+        control.isHighlighted = !control.isHighlighted;
+
+        this.setState({ isActive: control.isHighlighted });
+    }
+
+    switchVisibility(): void {
+        const newState = !this.state.isVisible;
+        this.setState({ isVisible: newState });
+        this.props.control.isVisible = newState;
+    }
+
+    render() {
+        const control = this.props.control;
+        const name = (control.name || "No name") + ` [${control.getClassName()}]`;
+        const isActiveElement = this.state.isActive ? <FontAwesomeIcon icon={faHighlighter} /> : <FontAwesomeIcon icon={faHighlighter} className="isNotActive" />;
+        const visibilityElement = this.state.isVisible ? <FontAwesomeIcon icon={faEye} /> : <FontAwesomeIcon icon={faEyeSlash} className="isNotActive" />
+
+        return (
+            <div className="controlTools">
+                <TreeItemLabelComponent label={name} onClick={() => this.props.onClick()} icon={faObjectGroup} color="greenyellow" />
+                <div className="highlight icon" onClick={() => this.highlight()} title="Highlight this control">
+                    {isActiveElement}
+                </div>
+                <div className="visibility icon" onClick={() => this.switchVisibility()} title="Show/Hide control">
+                    {visibilityElement}
+                </div>
+                <ExtensionsComponent target={control} extensibilityGroups={this.props.extensibilityGroups} />
+            </div>
+        )
+    }
+}

+ 1 - 3
inspector/src/components/sceneExplorer/entities/textureTreeItemComponent.tsx

@@ -19,9 +19,7 @@ export class TextureTreeItemComponent extends React.Component<ITextureTreeItemCo
         return (
             <div className="textureTools">
                 <TreeItemLabelComponent label={this.props.texture.name} onClick={() => this.props.onClick()} icon={faImage} color="mediumpurple" />
-                {
-                    <ExtensionsComponent target={this.props.texture} extensibilityGroups={this.props.extensibilityGroups} />
-                }
+                <ExtensionsComponent target={this.props.texture} extensibilityGroups={this.props.extensibilityGroups} />
             </div>
         )
     }

+ 41 - 0
inspector/src/components/sceneExplorer/sceneExplorer.scss

@@ -365,6 +365,47 @@
                 grid-column: 2;
             }
         }      
+
+        .adtextureTools {
+            grid-column: 2;
+            display: grid;
+            grid-template-columns: 1fr 20px auto 5px;
+            align-items: center;
+            
+            .pickingMode {
+                grid-column: 2;
+                opacity: 0.6;
+
+                &.selected {
+                    opacity: 1;
+                }
+            }
+
+            .extensions {
+                width: 20px;
+                grid-column: 3;
+            }
+        }         
+
+        .controlTools {
+            grid-column: 2;
+            display: grid;
+            grid-template-columns: 1fr 20px 20px auto 5px;
+            align-items: center;
+
+            .highlight {
+                grid-column: 2;
+            }
+
+            .visibility {
+                grid-column: 3;
+            }
+
+            .extensions {
+                width: 20px;
+                grid-column: 4;
+            }
+        }   
         
         .transformNodeTools {
             grid-column: 2;

+ 8 - 1
inspector/src/components/sceneExplorer/sceneExplorerComponent.tsx

@@ -162,13 +162,20 @@ export class SceneExplorerComponent extends React.Component<ISceneExplorerCompon
             return null;
         }
 
+        var guiElements = scene.textures.filter(t => t.getClassName() === "AdvancedDynamicTexture");
+        var textures = scene.textures.filter(t => t.getClassName() !== "AdvancedDynamicTexture");
+
         return (
             <div id="tree">
                 <SceneExplorerFilterComponent onFilter={(filter) => this.filterContent(filter)} />
                 <SceneTreeItemComponent extensibilityGroups={this.props.extensibilityGroups} selectedEntity={this.state.selectedEntity} scene={scene} onRefresh={() => this.forceUpdate()} onSelectionChangeObservable={this.props.globalState.onSelectionChangeObservable} />
                 <TreeItemComponent extensibilityGroups={this.props.extensibilityGroups} selectedEntity={this.state.selectedEntity} items={scene.rootNodes} label="Nodes" offset={1} onSelectionChangeObservable={this.props.globalState.onSelectionChangeObservable} filter={this.state.filter} />
                 <TreeItemComponent extensibilityGroups={this.props.extensibilityGroups} selectedEntity={this.state.selectedEntity} items={scene.materials} label="Materials" offset={1} onSelectionChangeObservable={this.props.globalState.onSelectionChangeObservable} filter={this.state.filter} />
-                <TreeItemComponent extensibilityGroups={this.props.extensibilityGroups} selectedEntity={this.state.selectedEntity} items={scene.textures} label="Textures" offset={1} onSelectionChangeObservable={this.props.globalState.onSelectionChangeObservable} filter={this.state.filter} />
+                <TreeItemComponent extensibilityGroups={this.props.extensibilityGroups} selectedEntity={this.state.selectedEntity} items={textures} label="Textures" offset={1} onSelectionChangeObservable={this.props.globalState.onSelectionChangeObservable} filter={this.state.filter} />
+                {
+                    guiElements && guiElements.length > 0 &&
+                    <TreeItemComponent extensibilityGroups={this.props.extensibilityGroups} selectedEntity={this.state.selectedEntity} items={guiElements} label="GUI" offset={1} onSelectionChangeObservable={this.props.globalState.onSelectionChangeObservable} filter={this.state.filter} />
+                }
             </div>
         )
     }

+ 4 - 3
inspector/src/components/sceneExplorer/treeItemSelectableComponent.tsx

@@ -82,11 +82,11 @@ export class TreeItemSelectableComponent extends React.Component<ITreeItemSelect
 
     renderChildren() {
         const entity = this.props.entity;
-        if (!entity.getChildren || !this.state.isExpanded) {
+        if (!entity.getChildren && !entity.children || !this.state.isExpanded) {
             return null;
         }
 
-        const children = Tools.SortAndFilter(entity.getChildren());
+        const children = Tools.SortAndFilter(entity.getChildren ? entity.getChildren() : entity.children);
         return (
             children.map(item => {
 
@@ -104,7 +104,8 @@ export class TreeItemSelectableComponent extends React.Component<ITreeItemSelect
         const entity = this.props.entity;
 
         const chevron = this.state.isExpanded ? <FontAwesomeIcon icon={faMinus} /> : <FontAwesomeIcon icon={faPlus} />
-        const hasChildren = entity.getChildren && entity.getChildren().length > 0;
+        const children = Tools.SortAndFilter(entity.getChildren ? entity.getChildren() : entity.children);
+        const hasChildren = children.length > 0;
 
         if (!entity.metadata) {
             entity.metadata = {};

+ 11 - 0
inspector/src/components/sceneExplorer/treeItemSpecializedComponent.tsx

@@ -8,6 +8,9 @@ import { MaterialTreeItemComponent } from "./entities/materialTreeItemComponent"
 import { TextureTreeItemComponent } from "./entities/textureTreeItemComponent";
 import { TransformNodeItemComponent } from "./entities/transformNodeTreeItemComponent";
 import * as React from "react";
+import { ControlTreeItemComponent } from "./entities/gui/controlTreeItemComponent";
+import { Control, AdvancedDynamicTexture } from "babylonjs-gui";
+import { AdvancedDynamicTextureTreeItemComponent } from "./entities/gui/advancedDynamicTextureTreeItemComponent";
 
 interface ITreeItemSpecializedComponentProps {
     label: string,
@@ -60,9 +63,17 @@ export class TreeItemSpecializedComponent extends React.Component<ITreeItemSpeci
                 return (<MaterialTreeItemComponent extensibilityGroups={this.props.extensibilityGroups} material={entity as Material} onClick={() => this.onClick()} />);
             }
 
+            if (className === "AdvancedDynamicTexture") {
+                return (<AdvancedDynamicTextureTreeItemComponent extensibilityGroups={this.props.extensibilityGroups} texture={entity as AdvancedDynamicTexture} onClick={() => this.onClick()} />);
+            }
+
             if (className.indexOf("Texture") !== -1) {
                 return (<TextureTreeItemComponent extensibilityGroups={this.props.extensibilityGroups} texture={entity as Texture} onClick={() => this.onClick()} />);
             }
+
+            if (entity._host) {
+                return (<ControlTreeItemComponent extensibilityGroups={this.props.extensibilityGroups} control={entity as Control} onClick={() => this.onClick()} />);
+            }
         }
 
         return (

+ 3 - 0
inspector/src/tools.ts

@@ -16,6 +16,9 @@ export class Tools {
     }
 
     public static SortAndFilter(items: any[]): any[] {
+        if (!items) {
+            return [];
+        }
         return items.filter((i) => !i.metadata || !i.metadata.hidden).sort((a: any, b: any) => {
             const lowerCaseA = (a.name || "").toLowerCase();
             const lowerCaseB = (b.name || "").toLowerCase();

+ 2 - 0
localDev/index.html

@@ -25,6 +25,8 @@
         #renderCanvas {
             width: 100%;
             height: 100%;
+            display: block;
+            font-size: 0;
         }
 
         #fps {

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

@@ -155,7 +155,7 @@ module BABYLON {
 
         /**
          * Define wether the camera is intermediate.
-         * This is usefull to not present the output directly to the screen in case of rig without post process for instance
+         * This is useful to not present the output directly to the screen in case of rig without post process for instance
          */
         public isIntermediate = false;
 
@@ -180,7 +180,7 @@ module BABYLON {
 
         /**
          * Rig mode of the camera.
-         * This is usefull to create the camera with two "eyes" instead of one to create VR or stereoscopic scenes.
+         * This is useful to create the camera with two "eyes" instead of one to create VR or stereoscopic scenes.
          * This is normally controlled byt the camera themselves as internal use.
          */
         @serialize()
@@ -326,7 +326,7 @@ module BABYLON {
         }
 
         /**
-         * Gets a string representation of the camera usefull for debug purpose.
+         * Gets a string representation of the camera useful for debug purpose.
          * @param fullDetails Defines that a more verboe level of logging is required
          * @returns the string representation
          */

+ 13 - 13
src/Cameras/babylon.freeCamera.ts

@@ -5,7 +5,7 @@ module BABYLON {
     });
 
     /**
-     * This represents a free type of camera. It can be usefull in First Person Shooter game for instance.
+     * This represents a free type of camera. It can be useful in First Person Shooter game for instance.
      * Please consider using the new UniversalCamera instead as it adds more functionality like the gamepad.
      * @see http://doc.babylonjs.com/features/cameras#universal-camera
      */
@@ -50,7 +50,7 @@ module BABYLON {
         public get angularSensibility(): number {
             var mouse = <FreeCameraMouseInput>this.inputs.attached["mouse"];
             if (mouse) {
-                return mouse.angularSensibility;
+                return mouse.angularSensibility;
             }
 
             return 0;
@@ -63,7 +63,7 @@ module BABYLON {
         public set angularSensibility(value: number) {
             var mouse = <FreeCameraMouseInput>this.inputs.attached["mouse"];
             if (mouse) {
-                mouse.angularSensibility = value;
+                mouse.angularSensibility = value;
             }
         }
 
@@ -73,7 +73,7 @@ module BABYLON {
         public get keysUp(): number[] {
             var keyboard = <FreeCameraKeyboardMoveInput>this.inputs.attached["keyboard"];
             if (keyboard) {
-                return keyboard.keysUp;
+                return keyboard.keysUp;
             }
 
             return [];
@@ -82,7 +82,7 @@ module BABYLON {
         public set keysUp(value: number[]) {
             var keyboard = <FreeCameraKeyboardMoveInput>this.inputs.attached["keyboard"];
             if (keyboard) {
-                keyboard.keysUp = value;
+                keyboard.keysUp = value;
             }
         }
 
@@ -92,7 +92,7 @@ module BABYLON {
         public get keysDown(): number[] {
             var keyboard = <FreeCameraKeyboardMoveInput>this.inputs.attached["keyboard"];
             if (keyboard) {
-                return keyboard.keysDown;
+                return keyboard.keysDown;
             }
 
             return [];
@@ -101,7 +101,7 @@ module BABYLON {
         public set keysDown(value: number[]) {
             var keyboard = <FreeCameraKeyboardMoveInput>this.inputs.attached["keyboard"];
             if (keyboard) {
-                keyboard.keysDown = value;
+                keyboard.keysDown = value;
             }
         }
 
@@ -111,7 +111,7 @@ module BABYLON {
         public get keysLeft(): number[] {
             var keyboard = <FreeCameraKeyboardMoveInput>this.inputs.attached["keyboard"];
             if (keyboard) {
-                return keyboard.keysLeft;
+                return keyboard.keysLeft;
             }
 
             return [];
@@ -120,7 +120,7 @@ module BABYLON {
         public set keysLeft(value: number[]) {
             var keyboard = <FreeCameraKeyboardMoveInput>this.inputs.attached["keyboard"];
             if (keyboard) {
-                keyboard.keysLeft = value;
+                keyboard.keysLeft = value;
             }
         }
 
@@ -130,7 +130,7 @@ module BABYLON {
         public get keysRight(): number[] {
             var keyboard = <FreeCameraKeyboardMoveInput>this.inputs.attached["keyboard"];
             if (keyboard) {
-                return keyboard.keysRight;
+                return keyboard.keysRight;
             }
 
             return [];
@@ -139,7 +139,7 @@ module BABYLON {
         public set keysRight(value: number[]) {
             var keyboard = <FreeCameraKeyboardMoveInput>this.inputs.attached["keyboard"];
             if (keyboard) {
-                keyboard.keysRight = value;
+                keyboard.keysRight = value;
             }
         }
 
@@ -161,7 +161,7 @@ module BABYLON {
 
         /**
          * Instantiates a Free Camera.
-         * This represents a free type of camera. It can be usefull in First Person Shooter game for instance.
+         * This represents a free type of camera. It can be useful in First Person Shooter game for instance.
          * Please consider using the new UniversalCamera instead as it adds more functionality like touch to this camera.
          * @see http://doc.babylonjs.com/features/cameras#universal-camera
          * @param name Define the name of the camera in the scene
@@ -246,7 +246,7 @@ module BABYLON {
         private _onCollisionPositionChange = (collisionId: number, newPosition: Vector3, collidedMesh: Nullable<AbstractMesh> = null) => {
             //TODO move this to the collision coordinator!
             if (this.getScene().workerCollisions) {
-                newPosition.multiplyInPlace(this._collider._radius);
+                newPosition.multiplyInPlace(this._collider._radius);
             }
 
             var updatePosition = (newPos: Vector3) => {

+ 2 - 2
src/Cameras/babylon.virtualJoysticksCamera.ts

@@ -4,7 +4,7 @@ module BABYLON {
     });
 
     /**
-     * This represents a free type of camera. It can be usefull in First Person Shooter game for instance.
+     * This represents a free type of camera. It can be useful in First Person Shooter game for instance.
      * It is identical to the Free Camera and simply adds by default a virtual joystick.
      * Virtual Joysticks are on-screen 2D graphics that are used to control the camera or other scene items.
      * @see http://doc.babylonjs.com/features/cameras#virtual-joysticks-camera
@@ -12,7 +12,7 @@ module BABYLON {
     export class VirtualJoysticksCamera extends FreeCamera {
 
         /**
-         * Intantiates a VirtualJoysticksCamera. It can be usefull in First Person Shooter game for instance.
+         * Intantiates a VirtualJoysticksCamera. It can be useful in First Person Shooter game for instance.
          * It is identical to the Free Camera and simply adds by default a virtual joystick.
          * Virtual Joysticks are on-screen 2D graphics that are used to control the camera or other scene items.
          * @see http://doc.babylonjs.com/features/cameras#virtual-joysticks-camera

+ 45 - 0
src/Debug/babylon.debugLayer.ts

@@ -4,24 +4,69 @@ module BABYLON {
     declare var INSPECTOR: any;
     // load the inspector using require, if not present in the global namespace.
 
+    /**
+     * Interface used to define scene explorer extensibility option
+     */
     export interface IExplorerExtensibilityOption {
+        /**
+         * Define the option label
+         */
         label: string;
+        /**
+         * Defines the action to execute on click
+         */
         action: (entity: any) => void;
     }
 
+    /**
+     * Defines a group of actions associated with a predicate to use when extending the Inspector scene explorer
+     */
     export interface IExplorerExtensibilityGroup {
+        /**
+         * Defines a predicate to test if a given type mut be extended
+         */
         predicate: (entity: any) => boolean;
+        /**
+         * Gets the list of options added to a type
+         */
         entries: IExplorerExtensibilityOption[];
     }
 
+    /**
+     * Interface used to define the options to use to create the Inspector
+     */
     export interface IInspectorOptions {
+        /**
+         * Display in overlay mode (default: false)
+         */
         overlay?: boolean;
+        /**
+         * HTML element to use as root (the parent of the rendering canvas will be used as default value)
+         */
         globalRoot?: HTMLElement;
+        /**
+         * Display the Scene explorer
+         */
         showExplorer?: boolean;
+        /**
+         * Display the property inspector
+         */
         showInspector?: boolean;
+        /**
+         * Display in embed mode (both panes on the right)
+         */
         embedMode?: boolean;
+        /**
+         * let the Inspector handles resize of the canvas when panes are resized (default to true)
+         */
         handleResize?: boolean;
+        /**
+         * Allow the panes to popup (default: true)
+         */
         enablePopup?: boolean;
+        /**
+         * Optional list of extensibility entries
+         */
         explorerExtensibility?: IExplorerExtensibilityGroup[];
     }
 

+ 2 - 2
src/Layer/babylon.layer.ts

@@ -2,7 +2,7 @@ module BABYLON {
 
     /**
      * This represents a full screen 2d layer.
-     * This can be usefull to display a picture in the  background of your scene for instance.
+     * This can be useful to display a picture in the  background of your scene for instance.
      * @see https://www.babylonjs-playground.com/#08A2BS#1
      */
     export class Layer {
@@ -119,7 +119,7 @@ module BABYLON {
         /**
          * Instantiates a new layer.
          * This represents a full screen 2d layer.
-         * This can be usefull to display a picture in the  background of your scene for instance.
+         * This can be useful to display a picture in the  background of your scene for instance.
          * @see https://www.babylonjs-playground.com/#08A2BS#1
          * @param name Define the name of the layer in the scene
          * @param imgUrl Define the url of the texture to display in the layer

+ 9 - 9
src/Lights/Shadows/babylon.shadowGenerator.ts

@@ -184,14 +184,14 @@ module BABYLON {
         private _blurBoxOffset = 1;
         /**
          * Gets the blur box offset: offset applied during the blur pass.
-         * Only usefull if useKernelBlur = false
+         * Only useful if useKernelBlur = false
          */
         public get blurBoxOffset(): number {
             return this._blurBoxOffset;
         }
         /**
          * Sets the blur box offset: offset applied during the blur pass.
-         * Only usefull if useKernelBlur = false
+         * Only useful if useKernelBlur = false
          */
         public set blurBoxOffset(value: number) {
             if (this._blurBoxOffset === value) {
@@ -226,14 +226,14 @@ module BABYLON {
         private _blurKernel = 1;
         /**
          * Gets the blur kernel: kernel size of the blur pass.
-         * Only usefull if useKernelBlur = true
+         * Only useful if useKernelBlur = true
          */
         public get blurKernel(): number {
             return this._blurKernel;
         }
         /**
          * Sets the blur kernel: kernel size of the blur pass.
-         * Only usefull if useKernelBlur = true
+         * Only useful if useKernelBlur = true
          */
         public set blurKernel(value: number) {
             if (this._blurKernel === value) {
@@ -247,14 +247,14 @@ module BABYLON {
         private _useKernelBlur = false;
         /**
          * Gets whether the blur pass is a kernel blur (if true) or box blur.
-         * Only usefull in filtered mode (useBlurExponentialShadowMap...)
+         * Only useful in filtered mode (useBlurExponentialShadowMap...)
          */
         public get useKernelBlur(): boolean {
             return this._useKernelBlur;
         }
         /**
          * Sets whether the blur pass is a kernel blur (if true) or box blur.
-         * Only usefull in filtered mode (useBlurExponentialShadowMap...)
+         * Only useful in filtered mode (useBlurExponentialShadowMap...)
          */
         public set useKernelBlur(value: boolean) {
             if (this._useKernelBlur === value) {
@@ -647,9 +647,9 @@ module BABYLON {
          * Documentation : http://doc.babylonjs.com/tutorials/shadows
          * @param mapSize The size of the texture what stores the shadows. Example : 1024.
          * @param light The light object generating the shadows.
-         * @param useFullFloatFirst By default the generator will try to use half float textures but if you need precision (for self shadowing for instance), you can use this option to enforce full float texture.
+         * @param usefulFloatFirst By default the generator will try to use half float textures but if you need precision (for self shadowing for instance), you can use this option to enforce full float texture.
          */
-        constructor(mapSize: number, light: IShadowLight, useFullFloatFirst?: boolean) {
+        constructor(mapSize: number, light: IShadowLight, usefulFloatFirst?: boolean) {
             this._mapSize = mapSize;
             this._light = light;
             this._scene = light.getScene();
@@ -664,7 +664,7 @@ module BABYLON {
             // Texture type fallback from float to int if not supported.
             var caps = this._scene.getEngine().getCaps();
 
-            if (!useFullFloatFirst) {
+            if (!usefulFloatFirst) {
                 if (caps.textureHalfFloatRender && caps.textureHalfFloatLinearFiltering) {
                     this._textureType = Engine.TEXTURETYPE_HALF_FLOAT;
                 }

+ 1 - 1
src/Lights/babylon.light.ts

@@ -110,7 +110,7 @@ module BABYLON {
          * falling off base on range or angle.
          * This can be set to any values in Light.FALLOFF_x.
          *
-         * Note: This is only usefull for PBR Materials at the moment. This could be extended if required to
+         * Note: This is only useful for PBR Materials at the moment. This could be extended if required to
          * other types of materials.
          */
         @serialize()

+ 1 - 1
src/Materials/PBR/babylon.pbrBaseMaterial.ts

@@ -338,7 +338,7 @@ module BABYLON {
         protected _indexOfRefraction = 0.66;
 
         /**
-         * Controls if refraction needs to be inverted on Y. This could be usefull for procedural texture.
+         * Controls if refraction needs to be inverted on Y. This could be useful for procedural texture.
          */
         protected _invertRefractionY = false;
 

+ 1 - 1
src/Materials/PBR/babylon.pbrMaterial.ts

@@ -233,7 +233,7 @@ module BABYLON {
         public indexOfRefraction = 0.66;
 
         /**
-         * Controls if refraction needs to be inverted on Y. This could be usefull for procedural texture.
+         * Controls if refraction needs to be inverted on Y. This could be useful for procedural texture.
          */
         @serialize()
         @expandToProperty("_markAllSubMeshesAsTexturesDirty")

+ 1 - 1
src/Materials/Textures/Procedurals/babylon.proceduralTexture.ts

@@ -245,7 +245,7 @@ module BABYLON {
 
         /**
          * Resets the refresh counter of the texture and start bak from scratch.
-         * Could be usefull to regenerate the texture if it is setup to render only once.
+         * Could be useful to regenerate the texture if it is setup to render only once.
          */
         public resetRefreshCounter(): void {
             this._currentRefreshId = -1;

+ 8 - 0
src/Materials/Textures/babylon.dynamicTexture.ts

@@ -50,6 +50,14 @@ module BABYLON {
         }
 
         /**
+         * Get the current class name of the texture useful for serialization or dynamic coding.
+         * @returns "DynamicTexture"
+         */
+        public getClassName(): string {
+            return "DynamicTexture";
+        }
+
+        /**
          * Gets the current state of canRescale
          */
         public get canRescale(): boolean {

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

@@ -375,7 +375,7 @@ module BABYLON {
 
         /**
          * Resets the refresh counter of the texture and start bak from scratch.
-         * Could be usefull to regenerate the texture if it is setup to render only once.
+         * Could be useful to regenerate the texture if it is setup to render only once.
          */
         public resetRefreshCounter(): void {
             this._currentRefreshId = -1;

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

@@ -560,7 +560,7 @@ module BABYLON {
         }
 
         /**
-         * Get the current class name of the texture usefull for serialization or dynamic coding.
+         * Get the current class name of the texture useful for serialization or dynamic coding.
          * @returns "Texture"
          */
         public getClassName(): string {

+ 1 - 1
src/Materials/babylon.standardMaterial.ts

@@ -347,7 +347,7 @@ module BABYLON {
 
         /**
          * Invert the refraction texture alongside the y axis.
-         * It can be usefull with procedural textures or probe for instance.
+         * It can be useful with procedural textures or probe for instance.
          * @see http://doc.babylonjs.com/how_to/reflect#how-to-obtain-reflections-and-refractions
          */
         @serialize()

+ 2 - 2
src/Mesh/babylon.mesh.ts

@@ -2008,7 +2008,7 @@ module BABYLON {
          * @param onSuccess is an optional Javascript function to be called just after the mesh is modified. It is passed the modified mesh and must return nothing.
          * @param uvOffset is an optional vector2 used to offset UV.
          * @param uvScale is an optional vector2 used to scale UV.
-         * @param forceUpdate defines whether or not to force an update of the generated buffers. This is usefull to apply on a deserialized model for instance.
+         * @param forceUpdate defines whether or not to force an update of the generated buffers. This is useful to apply on a deserialized model for instance.
          * @returns the Mesh.
          */
         public applyDisplacementMap(url: string, minHeight: number, maxHeight: number, onSuccess?: (mesh: Mesh) => void, uvOffset?: Vector2, uvScale?: Vector2, forceUpdate = false): Mesh {
@@ -2052,7 +2052,7 @@ module BABYLON {
          * @param onSuccess is an optional Javascript function to be called just after the mesh is modified. It is passed the modified mesh and must return nothing.
          * @param uvOffset is an optional vector2 used to offset UV.
          * @param uvScale is an optional vector2 used to scale UV.
-         * @param forceUpdate defines whether or not to force an update of the generated buffers. This is usefull to apply on a deserialized model for instance.
+         * @param forceUpdate defines whether or not to force an update of the generated buffers. This is useful to apply on a deserialized model for instance.
          * @returns the Mesh.
          */
         public applyDisplacementMapFromBuffer(buffer: Uint8Array, heightMapWidth: number, heightMapHeight: number, minHeight: number, maxHeight: number, uvOffset?: Vector2, uvScale?: Vector2, forceUpdate = false): Mesh {

+ 1 - 1
src/Rendering/babylon.depthRendererSceneComponent.ts

@@ -52,7 +52,7 @@ module BABYLON {
     };
 
     /**
-     * Defines the Depth Renderer scene component responsible to manage a depth buffer usefull
+     * Defines the Depth Renderer scene component responsible to manage a depth buffer useful
      * in several rendering techniques.
      */
     export class DepthRendererSceneComponent implements ISceneComponent {

+ 1 - 1
src/Tools/HDR/babylon.panoramaToCubemap.ts

@@ -67,7 +67,7 @@ module BABYLON {
     }
 
     /**
-     * Helper class usefull to convert panorama picture to their cubemap representation in 6 faces.
+     * Helper class useful to convert panorama picture to their cubemap representation in 6 faces.
      */
     export class PanoramaToCubeMapTools {