Bläddra i källkod

moving to es imports

Raanan Weber 7 år sedan
förälder
incheckning
786870abdf
60 ändrade filer med 4983 tillägg och 4789 borttagningar
  1. 373 368
      inspector/src/Inspector.ts
  2. 33 31
      inspector/src/adapters/Adapter.ts
  3. 53 49
      inspector/src/adapters/CameraAdapter.ts
  4. 48 43
      inspector/src/adapters/GUIAdapter.ts
  5. 49 46
      inspector/src/adapters/LightAdapter.ts
  6. 34 31
      inspector/src/adapters/MaterialAdapter.ts
  7. 102 94
      inspector/src/adapters/MeshAdapter.ts
  8. 48 43
      inspector/src/adapters/PhysicsImpostorAdapter.ts
  9. 44 39
      inspector/src/adapters/SoundAdapter.ts
  10. 33 30
      inspector/src/adapters/TextureAdapter.ts
  11. 186 182
      inspector/src/details/DetailPanel.ts
  12. 65 65
      inspector/src/details/Property.ts
  13. 491 483
      inspector/src/details/PropertyLine.ts
  14. 29 29
      inspector/src/gui/BasicElement.ts
  15. 31 30
      inspector/src/gui/ColorElement.ts
  16. 60 56
      inspector/src/gui/ColorPickerElement.ts
  17. 110 108
      inspector/src/gui/CubeTextureElement.ts
  18. 31 30
      inspector/src/gui/HDRCubeTextureElement.ts
  19. 76 73
      inspector/src/gui/SearchBar.ts
  20. 40 38
      inspector/src/gui/TextureElement.ts
  21. 29 28
      inspector/src/gui/Tooltip.ts
  22. 190 186
      inspector/src/helpers/Helpers.ts
  23. 126 128
      inspector/src/properties.ts
  24. 114 116
      inspector/src/properties_gui.ts
  25. 38 38
      inspector/src/scheduler/Scheduler.ts
  26. 22 19
      inspector/src/tabs/CameraTab.ts
  27. 135 132
      inspector/src/tabs/ConsoleTab.ts
  28. 199 195
      inspector/src/tabs/GLTFTab.ts
  29. 39 35
      inspector/src/tabs/GUITab.ts
  30. 23 20
      inspector/src/tabs/LightTab.ts
  31. 21 19
      inspector/src/tabs/MaterialTab.ts
  32. 64 61
      inspector/src/tabs/MeshTab.ts
  33. 26 22
      inspector/src/tabs/PhysicsTab.ts
  34. 140 133
      inspector/src/tabs/PropertyTab.ts
  35. 173 165
      inspector/src/tabs/SceneTab.ts
  36. 21 19
      inspector/src/tabs/SoundTab.ts
  37. 370 367
      inspector/src/tabs/StatsTab.ts
  38. 64 61
      inspector/src/tabs/Tab.ts
  39. 219 199
      inspector/src/tabs/TabBar.ts
  40. 165 160
      inspector/src/tabs/TextureTab.ts
  41. 115 112
      inspector/src/tabs/ToolsTab.ts
  42. 37 36
      inspector/src/tools/AbstractTool.ts
  43. 14 14
      inspector/src/tools/DisposeTool.ts
  44. 17 17
      inspector/src/tools/FullscreenTool.ts
  45. 99 95
      inspector/src/tools/LabelTool.ts
  46. 21 19
      inspector/src/tools/PauseScheduleTool.ts
  47. 52 50
      inspector/src/tools/PickTool.ts
  48. 14 13
      inspector/src/tools/PopupTool.ts
  49. 14 13
      inspector/src/tools/RefreshTool.ts
  50. 61 51
      inspector/src/tools/Toolbar.ts
  51. 160 152
      inspector/src/tree/TreeItem.ts
  52. 29 29
      inspector/src/treetools/AbstractTreeTool.ts
  53. 35 36
      inspector/src/treetools/BoundingBox.ts
  54. 47 47
      inspector/src/treetools/CameraPOV.ts
  55. 40 41
      inspector/src/treetools/Checkbox.ts
  56. 25 25
      inspector/src/treetools/DebugArea.ts
  57. 23 23
      inspector/src/treetools/Info.ts
  58. 32 32
      inspector/src/treetools/SoundInteractions.ts
  59. 0 13
      inspector/src/tsconfig.json
  60. 34 0
      inspector/tsconfig.json

+ 373 - 368
inspector/src/Inspector.ts

@@ -1,421 +1,426 @@
-module INSPECTOR {
-    export class Inspector {
-
-        private _c2diwrapper: HTMLElement;
-        // private _detailsPanel: DetailPanel;
-        /** The panel displayed at the top of the inspector */
-        private _topPanel: HTMLElement;
-        /** The div containing the content of the active tab */
-        private _tabPanel: HTMLElement;
-        /** The panel containing the list if items */
-        // private _treePanel   : HTMLElement;
-        private _tabbar: TabBar;
-        private _scene: BABYLON.Scene;
-        /** The HTML document relative to this inspector (the window or the popup depending on its mode) */
-        public static DOCUMENT: HTMLDocument;
-        /** The HTML window. In popup mode, it's the popup itself. Otherwise, it's the current tab */
-        public static WINDOW: Window;
-        /** True if the inspector is built as a popup tab */
-        private _popupMode: boolean = false;
-        /** The original canvas style, before applying the inspector*/
-        private _canvasStyle: any;
-
-        private _initialTab: number;
-
-        private _parentElement: BABYLON.Nullable<HTMLElement>;
-
-        /** The inspector is created with the given engine.
-         * If the parameter 'popup' is false, the inspector is created as a right panel on the main window.
-         * If the parameter 'popup' is true, the inspector is created in another popup.
-         */
-        constructor(scene: BABYLON.Scene, popup?: boolean, initialTab: number = 0, parentElement: BABYLON.Nullable<HTMLElement> = null, newColors?: {
-            backgroundColor?: string,
-            backgroundColorLighter?: string,
-            backgroundColorLighter2?: string,
-            backgroundColorLighter3?: string,
-            color?: string,
-            colorTop?: string,
-            colorBot?: string
-        }) {
-
-            // Load GUI library if not already done
-            if (!BABYLON.GUI) {
-                BABYLON.Tools.LoadScript("https://preview.babylonjs.com/gui/babylon.gui.js", () => {
-                    //Load properties of GUI objects now as BABYLON.GUI has to be declared before 
-                    loadGUIProperties();
-                }, () => {
-                    console.warn('Error : loading "babylon.gui.js". Please add script https://preview.babylonjs.com/gui/babylon.gui.js to the HTML file.');
-                });
-            }
-            else {
-                //Load properties of GUI objects now as BABYLON.GUI has to be declared before 
+import { Scene, Nullable, Tools, AbstractMesh } from "babylonjs";
+import { TabBar } from "./tabs/TabBar";
+import { Helpers } from "./helpers/Helpers";
+import { Scheduler } from "./scheduler/Scheduler";
+
+import * as GUI from "babylonjs-gui";
+
+export class Inspector {
+
+    private _c2diwrapper: HTMLElement;
+    // private _detailsPanel: DetailPanel;
+    /** The panel displayed at the top of the inspector */
+    private _topPanel: HTMLElement;
+    /** The div containing the content of the active tab */
+    private _tabPanel: HTMLElement;
+    /** The panel containing the list if items */
+    // private _treePanel   : HTMLElement;
+    private _tabbar: TabBar;
+    private _scene: Scene;
+    /** The HTML document relative to this inspector (the window or the popup depending on its mode) */
+    public static DOCUMENT: HTMLDocument;
+    /** The HTML window. In popup mode, it's the popup itself. Otherwise, it's the current tab */
+    public static WINDOW: Window;
+    /** True if the inspector is built as a popup tab */
+    private _popupMode: boolean = false;
+    /** The original canvas style, before applying the inspector*/
+    private _canvasStyle: any;
+
+    private _initialTab: number;
+
+    private _parentElement: Nullable<HTMLElement>;
+
+    /** The inspector is created with the given engine.
+     * If the parameter 'popup' is false, the inspector is created as a right panel on the main window.
+     * If the parameter 'popup' is true, the inspector is created in another popup.
+     */
+    constructor(scene: Scene, popup?: boolean, initialTab: number = 0, parentElement: Nullable<HTMLElement> = null, newColors?: {
+        backgroundColor?: string,
+        backgroundColorLighter?: string,
+        backgroundColorLighter2?: string,
+        backgroundColorLighter3?: string,
+        color?: string,
+        colorTop?: string,
+        colorBot?: string
+    }) {
+
+        // Load GUI library if not already done
+        if (!GUI) {
+            Tools.LoadScript("https://preview.babylonjs.com/gui/gui.js", () => {
+                //Load properties of GUI objects now as GUI has to be declared before 
                 loadGUIProperties();
-            }
+            }, () => {
+                console.warn('Error : loading "gui.js". Please add script https://preview.babylonjs.com/gui/gui.js to the HTML file.');
+            });
+        }
+        else {
+            //Load properties of GUI objects now as GUI has to be declared before 
+            loadGUIProperties();
+        }
 
-            //get Tabbar initialTab
-            this._initialTab = initialTab;
+        //get Tabbar initialTab
+        this._initialTab = initialTab;
+
+        //get parentElement of our Inspector
+        this._parentElement = parentElement;
+
+        // get canvas parent only if needed.
+        this._scene = scene;
+
+        // Save HTML document and window
+        Inspector.DOCUMENT = window.document;
+        Inspector.WINDOW = window;
+
+        // POPUP MODE
+        if (popup) {
+            // Build the inspector in the given parent
+            this.openPopup(true);// set to true in order to NOT dispose the inspector (done in openPopup), as it's not existing yet
+        } else {
+            // Get canvas and its DOM parent
+            let canvas = <HTMLElement>this._scene.getEngine().getRenderingCanvas();
+            let canvasParent = canvas.parentElement;
+
+            // get canvas style                
+            let canvasComputedStyle = Inspector.WINDOW.getComputedStyle(canvas);
+
+            this._canvasStyle = {
+                width: Helpers.Css(canvas, 'width'),
+                height: Helpers.Css(canvas, 'height'),
+
+                position: canvasComputedStyle.position,
+                top: canvasComputedStyle.top,
+                bottom: canvasComputedStyle.bottom,
+                left: canvasComputedStyle.left,
+                right: canvasComputedStyle.right,
+
+                padding: canvasComputedStyle.padding,
+                paddingBottom: canvasComputedStyle.paddingBottom,
+                paddingLeft: canvasComputedStyle.paddingLeft,
+                paddingTop: canvasComputedStyle.paddingTop,
+                paddingRight: canvasComputedStyle.paddingRight,
+
+                margin: canvasComputedStyle.margin,
+                marginBottom: canvasComputedStyle.marginBottom,
+                marginLeft: canvasComputedStyle.marginLeft,
+                marginTop: canvasComputedStyle.marginTop,
+                marginRight: canvasComputedStyle.marginRight
+
+            };
+
+            if (this._parentElement) {
+                // Build the inspector wrapper
+                this._c2diwrapper = Helpers.CreateDiv('insp-wrapper', this._parentElement);
+                this._c2diwrapper.style.width = '100%';
+                this._c2diwrapper.style.height = '100%';
+                this._c2diwrapper.style.paddingLeft = '5px';
+
+                // add inspector     
+                let inspector = Helpers.CreateDiv('insp-right-panel', this._c2diwrapper);
+                inspector.style.width = '100%';
+                inspector.style.height = '100%';
+                // and build it in the popup  
+                this._buildInspector(inspector);
+            } else {
+                // Create c2di wrapper
+                this._c2diwrapper = Helpers.CreateDiv('insp-wrapper');
 
-            //get parentElement of our Inspector
-            this._parentElement = parentElement;
+                // copy style from canvas to wrapper
+                for (let prop in this._canvasStyle) {
+                    (<any>this._c2diwrapper.style)[prop] = this._canvasStyle[prop];
+                }
 
-            // get canvas parent only if needed.
-            this._scene = scene;
+                if (!canvasComputedStyle.width || !canvasComputedStyle.height || !canvasComputedStyle.left) {
+                    return;
+                }
 
-            // Save HTML document and window
-            Inspector.DOCUMENT = window.document;
-            Inspector.WINDOW = window;
+                // Convert wrapper size in % (because getComputedStyle returns px only)
+                let widthPx = parseFloat(canvasComputedStyle.width.substr(0, canvasComputedStyle.width.length - 2)) || 0;
+                let heightPx = parseFloat(canvasComputedStyle.height.substr(0, canvasComputedStyle.height.length - 2)) || 0;
 
-            // POPUP MODE
-            if (popup) {
-                // Build the inspector in the given parent
-                this.openPopup(true);// set to true in order to NOT dispose the inspector (done in openPopup), as it's not existing yet
-            } else {
-                // Get canvas and its DOM parent
-                let canvas = <HTMLElement>this._scene.getEngine().getRenderingCanvas();
-                let canvasParent = canvas.parentElement;
-
-                // get canvas style                
-                let canvasComputedStyle = Inspector.WINDOW.getComputedStyle(canvas);
-
-                this._canvasStyle = {
-                    width: Helpers.Css(canvas, 'width'),
-                    height: Helpers.Css(canvas, 'height'),
-
-                    position: canvasComputedStyle.position,
-                    top: canvasComputedStyle.top,
-                    bottom: canvasComputedStyle.bottom,
-                    left: canvasComputedStyle.left,
-                    right: canvasComputedStyle.right,
-
-                    padding: canvasComputedStyle.padding,
-                    paddingBottom: canvasComputedStyle.paddingBottom,
-                    paddingLeft: canvasComputedStyle.paddingLeft,
-                    paddingTop: canvasComputedStyle.paddingTop,
-                    paddingRight: canvasComputedStyle.paddingRight,
-
-                    margin: canvasComputedStyle.margin,
-                    marginBottom: canvasComputedStyle.marginBottom,
-                    marginLeft: canvasComputedStyle.marginLeft,
-                    marginTop: canvasComputedStyle.marginTop,
-                    marginRight: canvasComputedStyle.marginRight
-
-                };
-
-                if (this._parentElement) {
-                    // Build the inspector wrapper
-                    this._c2diwrapper = Helpers.CreateDiv('insp-wrapper', this._parentElement);
-                    this._c2diwrapper.style.width = '100%';
-                    this._c2diwrapper.style.height = '100%';
-                    this._c2diwrapper.style.paddingLeft = '5px';
-
-                    // add inspector     
-                    let inspector = Helpers.CreateDiv('insp-right-panel', this._c2diwrapper);
-                    inspector.style.width = '100%';
-                    inspector.style.height = '100%';
-                    // and build it in the popup  
-                    this._buildInspector(inspector);
-                } else {
-                    // Create c2di wrapper
-                    this._c2diwrapper = Helpers.CreateDiv('insp-wrapper');
-
-                    // copy style from canvas to wrapper
-                    for (let prop in this._canvasStyle) {
-                        (<any>this._c2diwrapper.style)[prop] = this._canvasStyle[prop];
+                // If the canvas position is absolute, restrain the wrapper width to the window width + left positionning
+                if (canvasComputedStyle.position === "absolute" || canvasComputedStyle.position === "relative") {
+                    // compute only left as it takes predominance if right is also specified (and it will be for the wrapper)
+                    let leftPx = parseFloat(canvasComputedStyle.left.substr(0, canvasComputedStyle.left.length - 2)) || 0;
+                    if (widthPx + leftPx >= Inspector.WINDOW.innerWidth) {
+                        this._c2diwrapper.style.maxWidth = `${widthPx - leftPx}px`;
                     }
+                }
 
-                    if (!canvasComputedStyle.width || !canvasComputedStyle.height || !canvasComputedStyle.left) {
-                        return;
-                    }
 
-                    // Convert wrapper size in % (because getComputedStyle returns px only)
-                    let widthPx = parseFloat(canvasComputedStyle.width.substr(0, canvasComputedStyle.width.length - 2)) || 0;
-                    let heightPx = parseFloat(canvasComputedStyle.height.substr(0, canvasComputedStyle.height.length - 2)) || 0;
+                // Check if the parent of the canvas is the body page. If yes, the size ratio is computed
+                let parent = this._getRelativeParent(canvas);
 
-                    // If the canvas position is absolute, restrain the wrapper width to the window width + left positionning
-                    if (canvasComputedStyle.position === "absolute" || canvasComputedStyle.position === "relative") {
-                        // compute only left as it takes predominance if right is also specified (and it will be for the wrapper)
-                        let leftPx = parseFloat(canvasComputedStyle.left.substr(0, canvasComputedStyle.left.length - 2)) || 0;
-                        if (widthPx + leftPx >= Inspector.WINDOW.innerWidth) {
-                            this._c2diwrapper.style.maxWidth = `${widthPx - leftPx}px`;
-                        }
-                    }
+                let parentWidthPx = parent.clientWidth;
+                let parentHeightPx = parent.clientHeight;
 
+                let pWidth = widthPx / parentWidthPx * 100;
+                let pheight = heightPx / parentHeightPx * 100;
 
-                    // Check if the parent of the canvas is the body page. If yes, the size ratio is computed
-                    let parent = this._getRelativeParent(canvas);
+                this._c2diwrapper.style.width = pWidth + "%";
+                this._c2diwrapper.style.height = pheight + "%";
 
-                    let parentWidthPx = parent.clientWidth;
-                    let parentHeightPx = parent.clientHeight;
+                // reset canvas style
+                canvas.style.position = "static";
+                canvas.style.width = "100%";
+                canvas.style.height = "100%";
+                canvas.style.paddingBottom = "0";
+                canvas.style.paddingLeft = "0";
+                canvas.style.paddingTop = "0";
+                canvas.style.paddingRight = "0";
 
-                    let pWidth = widthPx / parentWidthPx * 100;
-                    let pheight = heightPx / parentHeightPx * 100;
+                canvas.style.margin = "0";
+                canvas.style.marginBottom = "0";
+                canvas.style.marginLeft = "0";
+                canvas.style.marginTop = "0";
+                canvas.style.marginRight = "0";
 
-                    this._c2diwrapper.style.width = pWidth + "%";
-                    this._c2diwrapper.style.height = pheight + "%";
+                // Replace canvas with the wrapper...
+                if (canvasParent) {
+                    canvasParent.replaceChild(this._c2diwrapper, canvas);
+                }
+                // ... and add canvas to the wrapper
+                this._c2diwrapper.appendChild(canvas);
+
+                // add inspector
+                let inspector = Helpers.CreateDiv('insp-right-panel', this._c2diwrapper);
+
+                // Add split bar
+                if (!this._parentElement) {
+                    Split([canvas, inspector], {
+                        direction: 'horizontal',
+                        sizes: [75, 25],
+                        onDrag: () => {
+                            Helpers.SEND_EVENT('resize');
+                            if (this._tabbar) {
+                                this._tabbar.updateWidth()
+                            }
+                        }
+                    });
+                }
 
-                    // reset canvas style
-                    canvas.style.position = "static";
-                    canvas.style.width = "100%";
-                    canvas.style.height = "100%";
-                    canvas.style.paddingBottom = "0";
-                    canvas.style.paddingLeft = "0";
-                    canvas.style.paddingTop = "0";
-                    canvas.style.paddingRight = "0";
+                // Build the inspector
+                this._buildInspector(inspector);
+            }
+            // Send resize event to the window
+            Helpers.SEND_EVENT('resize');
+            this._tabbar.updateWidth();
+        }
 
-                    canvas.style.margin = "0";
-                    canvas.style.marginBottom = "0";
-                    canvas.style.marginLeft = "0";
-                    canvas.style.marginTop = "0";
-                    canvas.style.marginRight = "0";
+        /*
+        * Refresh the inspector if the browser is not edge
+        *   Why not ?! Condition commented on 180525
+        *   To be tested
+        */
+        // if (!Helpers.IsBrowserEdge()) {
+        this.refresh();
+        // }
 
-                    // Replace canvas with the wrapper...
-                    if (canvasParent) {
-                        canvasParent.replaceChild(this._c2diwrapper, canvas);
-                    }
-                    // ... and add canvas to the wrapper
-                    this._c2diwrapper.appendChild(canvas);
-
-                    // add inspector
-                    let inspector = Helpers.CreateDiv('insp-right-panel', this._c2diwrapper);
-
-                    // Add split bar
-                    if (!this._parentElement) {
-                        Split([canvas, inspector], {
-                            direction: 'horizontal',
-                            sizes: [75, 25],
-                            onDrag: () => {
-                                Helpers.SEND_EVENT('resize');
-                                if (this._tabbar) {
-                                    this._tabbar.updateWidth()
-                                }
-                            }
-                        });
-                    }
+        // Check custom css colors
+        if (newColors) {
 
-                    // Build the inspector
-                    this._buildInspector(inspector);
-                }
-                // Send resize event to the window
-                Helpers.SEND_EVENT('resize');
-                this._tabbar.updateWidth();
-            }
+            let bColor = newColors.backgroundColor || '#242424';
+            let bColorl1 = newColors.backgroundColorLighter || '#2c2c2c';
+            let bColorl2 = newColors.backgroundColorLighter2 || '#383838';
+            let bColorl3 = newColors.backgroundColorLighter3 || '#454545';
 
-            /*
-            * Refresh the inspector if the browser is not edge
-            *   Why not ?! Condition commented on 180525
-            *   To be tested
-            */
-            // if (!Helpers.IsBrowserEdge()) {
-                this.refresh();
-            // }
-
-            // Check custom css colors
-            if (newColors) {
-
-                let bColor = newColors.backgroundColor || '#242424';
-                let bColorl1 = newColors.backgroundColorLighter || '#2c2c2c';
-                let bColorl2 = newColors.backgroundColorLighter2 || '#383838';
-                let bColorl3 = newColors.backgroundColorLighter3 || '#454545';
-
-                let color = newColors.color || '#ccc';
-                let colorTop = newColors.colorTop || '#f29766';
-                let colorBot = newColors.colorBot || '#5db0d7';
-
-                let styles = Inspector.DOCUMENT.querySelectorAll('style');
-                for (let s = 0; s < styles.length; s++) {
-                    let style = styles[s];
-
-                    if (style.innerHTML.indexOf('insp-wrapper') != -1) {
-
-                        styles[s].innerHTML = styles[s].innerHTML
-                            .replace(/#242424/g, bColor) // background color
-                            .replace(/#2c2c2c/g, bColorl1) // background-lighter
-                            .replace(/#383838/g, bColorl2) // background-lighter2
-                            .replace(/#454545/g, bColorl3) // background-lighter3
-                            .replace(/#ccc/g, color) // color
-                            .replace(/#f29766/g, colorTop) // color-top
-                            .replace(/#5db0d7/g, colorBot) // color-bot
-                    }
+            let color = newColors.color || '#ccc';
+            let colorTop = newColors.colorTop || '#f29766';
+            let colorBot = newColors.colorBot || '#5db0d7';
+
+            let styles = Inspector.DOCUMENT.querySelectorAll('style');
+            for (let s = 0; s < styles.length; s++) {
+                let style = styles[s];
+
+                if (style.innerHTML.indexOf('insp-wrapper') != -1) {
+
+                    styles[s].innerHTML = styles[s].innerHTML
+                        .replace(/#242424/g, bColor) // background color
+                        .replace(/#2c2c2c/g, bColorl1) // background-lighter
+                        .replace(/#383838/g, bColorl2) // background-lighter2
+                        .replace(/#454545/g, bColorl3) // background-lighter3
+                        .replace(/#ccc/g, color) // color
+                        .replace(/#f29766/g, colorTop) // color-top
+                        .replace(/#5db0d7/g, colorBot) // color-bot
                 }
             }
         }
+    }
 
-        /**
-         * If the given element has a position 'asbolute' or 'relative', 
-         * returns the first parent of the given element that has a position 'relative' or 'absolute'.
-         * If the given element has no position, returns the first parent
-         * 
-         */
-        private _getRelativeParent(elem: HTMLElement, lookForAbsoluteOrRelative?: boolean): HTMLElement {
-            // If the elem has no parent, returns himself
-            if (!elem.parentElement) {
+    /**
+     * If the given element has a position 'asbolute' or 'relative', 
+     * returns the first parent of the given element that has a position 'relative' or 'absolute'.
+     * If the given element has no position, returns the first parent
+     * 
+     */
+    private _getRelativeParent(elem: HTMLElement, lookForAbsoluteOrRelative?: boolean): HTMLElement {
+        // If the elem has no parent, returns himself
+        if (!elem.parentElement) {
+            return elem;
+        }
+        let computedStyle = Inspector.WINDOW.getComputedStyle(elem);
+        // looking for the first element absolute or relative
+        if (lookForAbsoluteOrRelative) {
+            // if found, return this one
+            if (computedStyle.position === "relative" || computedStyle.position === "absolute") {
                 return elem;
+            } else {
+                // otherwise keep looking
+                return this._getRelativeParent(elem.parentElement, true);
             }
-            let computedStyle = Inspector.WINDOW.getComputedStyle(elem);
-            // looking for the first element absolute or relative
-            if (lookForAbsoluteOrRelative) {
-                // if found, return this one
-                if (computedStyle.position === "relative" || computedStyle.position === "absolute") {
-                    return elem;
-                } else {
-                    // otherwise keep looking
-                    return this._getRelativeParent(elem.parentElement, true);
-                }
-            }
-            // looking for the relative parent of the element 
-            else {
-                if (computedStyle.position == "static") {
-                    return elem.parentElement;
-                } else {
-                    // the elem has a position relative or absolute, look for the closest relative/absolute parent
-                    return this._getRelativeParent(elem.parentElement, true);
-                }
+        }
+        // looking for the relative parent of the element 
+        else {
+            if (computedStyle.position == "static") {
+                return elem.parentElement;
+            } else {
+                // the elem has a position relative or absolute, look for the closest relative/absolute parent
+                return this._getRelativeParent(elem.parentElement, true);
             }
         }
+    }
 
-        /** Build the inspector panel in the given HTML element */
-        private _buildInspector(parent: HTMLElement) {
-            // tabbar
-            this._tabbar = new TabBar(this, this._initialTab);
-
-            // Top panel
-            this._topPanel = Helpers.CreateDiv('top-panel', parent);
-            // Add tabbar
-            this._topPanel.appendChild(this._tabbar.toHtml());
-            this._tabbar.updateWidth();
+    /** Build the inspector panel in the given HTML element */
+    private _buildInspector(parent: HTMLElement) {
+        // tabbar
+        this._tabbar = new TabBar(this, this._initialTab);
 
-            // Tab panel
-            this._tabPanel = Helpers.CreateDiv('tab-panel-content', this._topPanel);
+        // Top panel
+        this._topPanel = Helpers.CreateDiv('top-panel', parent);
+        // Add tabbar
+        this._topPanel.appendChild(this._tabbar.toHtml());
+        this._tabbar.updateWidth();
 
-        }
+        // Tab panel
+        this._tabPanel = Helpers.CreateDiv('tab-panel-content', this._topPanel);
 
-        public get scene(): BABYLON.Scene {
-            return this._scene;
-        }
-        public get popupMode(): boolean {
-            return this._popupMode;
-        }
+    }
 
-        /**  
-         * Filter the list of item present in the tree.
-         * All item returned should have the given filter contained in the item id.
-        */
-        public filterItem(filter: string) {
-            let tab = this._tabbar.getActiveTab();
+    public get scene(): Scene {
+        return this._scene;
+    }
+    public get popupMode(): boolean {
+        return this._popupMode;
+    }
 
-            if (tab) {
-                tab.filter(filter);
-            }
-        }
+    /**  
+     * Filter the list of item present in the tree.
+     * All item returned should have the given filter contained in the item id.
+    */
+    public filterItem(filter: string) {
+        let tab = this._tabbar.getActiveTab();
 
-        /** Display the mesh tab on the given object */
-        public displayObjectDetails(mesh: BABYLON.AbstractMesh) {
-            this._tabbar.switchMeshTab(mesh);
+        if (tab) {
+            tab.filter(filter);
         }
+    }
 
-        /** Clean the whole tree of item and rebuilds it */
-        public refresh() {
-            // Clean top panel
-            Helpers.CleanDiv(this._tabPanel);
+    /** Display the mesh tab on the given object */
+    public displayObjectDetails(mesh: AbstractMesh) {
+        this._tabbar.switchMeshTab(mesh);
+    }
 
-            // Get the active tab and its items
-            let activeTab = this._tabbar.getActiveTab();
+    /** Clean the whole tree of item and rebuilds it */
+    public refresh() {
+        // Clean top panel
+        Helpers.CleanDiv(this._tabPanel);
 
-            if (!activeTab) {
-                return;
-            }
-            activeTab.update();
-            this._tabPanel.appendChild(activeTab.getPanel());
-            Helpers.SEND_EVENT('resize');
+        // Get the active tab and its items
+        let activeTab = this._tabbar.getActiveTab();
 
+        if (!activeTab) {
+            return;
         }
+        activeTab.update();
+        this._tabPanel.appendChild(activeTab.getPanel());
+        Helpers.SEND_EVENT('resize');
 
-        /** Remove the inspector panel when it's built as a right panel:
-         * remove the right panel and remove the wrapper
-         */
-        public dispose() {
-            if (!this._popupMode) {
-                let activeTab = this._tabbar.getActiveTab();
-                if (activeTab) {
-                    activeTab.dispose();
-                }
-
-                // Get canvas
-                let canvas = <HTMLElement>this._scene.getEngine().getRenderingCanvas();
+    }
 
-                // restore canvas style
-                for (let prop in this._canvasStyle) {
-                    (<any>canvas.style)[prop] = this._canvasStyle[prop];
-                }
-                // Get parent of the wrapper 
-                if (canvas.parentElement) {
-                    let canvasParent = canvas.parentElement.parentElement;
-
-                    if (canvasParent) {
-                        canvasParent.insertBefore(canvas, this._c2diwrapper);
-                        // Remove wrapper
-                        Helpers.CleanDiv(this._c2diwrapper);
-                        this._c2diwrapper.remove();
-                        // Send resize event to the window
-                        Helpers.SEND_EVENT('resize');
-                    }
-                }
+    /** Remove the inspector panel when it's built as a right panel:
+     * remove the right panel and remove the wrapper
+     */
+    public dispose() {
+        if (!this._popupMode) {
+            let activeTab = this._tabbar.getActiveTab();
+            if (activeTab) {
+                activeTab.dispose();
             }
-            Scheduler.getInstance().dispose();
-        }
 
-        /** Open the inspector in a new popup
-         * Set 'firstTime' to true if there is no inspector created beforehands
-         */
-        public openPopup(firstTime?: boolean) {
+            // Get canvas
+            let canvas = <HTMLElement>this._scene.getEngine().getRenderingCanvas();
 
-            // Create popup
-            let popup = window.open('', 'Babylon.js INSPECTOR', 'toolbar=no,resizable=yes,menubar=no,width=750,height=1000');
-            if (!popup) {
-                alert("Please update your browser to open the Babylon.js inspector in an external view.");
-                return;
-            }
-            popup.document.title = "Babylon.js INSPECTOR";
-            // Get the inspector style      
-            let styles = Inspector.DOCUMENT.querySelectorAll('style');
-            for (let s = 0; s < styles.length; s++) {
-                popup.document.body.appendChild(styles[s].cloneNode(true));
-            }
-            let links = document.querySelectorAll('link');
-            for (let l = 0; l < links.length; l++) {
-                let link = popup.document.createElement("link");
-                link.rel = "stylesheet";
-                link.href = (links[l] as HTMLLinkElement).href;
-                popup.document.head.appendChild(link);
-            }
-            // Dispose the right panel if existing
-            if (!firstTime) {
-                this.dispose();
+            // restore canvas style
+            for (let prop in this._canvasStyle) {
+                (<any>canvas.style)[prop] = this._canvasStyle[prop];
             }
-            // set the mode as popup
-            this._popupMode = true;
-            // Save the HTML document
-            Inspector.DOCUMENT = popup.document;
-            Inspector.WINDOW = popup;
-            // Build the inspector wrapper
-            this._c2diwrapper = Helpers.CreateDiv('insp-wrapper', popup.document.body);
-            // add inspector     
-            let inspector = Helpers.CreateDiv('insp-right-panel', this._c2diwrapper);
-            inspector.classList.add('popupmode');
-            // and build it in the popup  
-            this._buildInspector(inspector);
-            // Rebuild it
-            this.refresh();
-
-            popup.addEventListener('resize', () => {
-                if (this._tabbar) {
-                    this._tabbar.updateWidth()
+            // Get parent of the wrapper 
+            if (canvas.parentElement) {
+                let canvasParent = canvas.parentElement.parentElement;
+
+                if (canvasParent) {
+                    canvasParent.insertBefore(canvas, this._c2diwrapper);
+                    // Remove wrapper
+                    Helpers.CleanDiv(this._c2diwrapper);
+                    this._c2diwrapper.remove();
+                    // Send resize event to the window
+                    Helpers.SEND_EVENT('resize');
                 }
-            });
+            }
         }
+        Scheduler.getInstance().dispose();
+    }
 
-        public getActiveTabIndex(): number {
-            return this._tabbar.getActiveTabIndex();
+    /** Open the inspector in a new popup
+     * Set 'firstTime' to true if there is no inspector created beforehands
+     */
+    public openPopup(firstTime?: boolean) {
+
+        // Create popup
+        let popup = window.open('', 'js INSPECTOR', 'toolbar=no,resizable=yes,menubar=no,width=750,height=1000');
+        if (!popup) {
+            alert("Please update your browser to open the js inspector in an external view.");
+            return;
+        }
+        popup.document.title = "js INSPECTOR";
+        // Get the inspector style      
+        let styles = Inspector.DOCUMENT.querySelectorAll('style');
+        for (let s = 0; s < styles.length; s++) {
+            popup.document.body.appendChild(styles[s].cloneNode(true));
         }
+        let links = document.querySelectorAll('link');
+        for (let l = 0; l < links.length; l++) {
+            let link = popup.document.createElement("link");
+            link.rel = "stylesheet";
+            link.href = (links[l] as HTMLLinkElement).href;
+            popup.document.head.appendChild(link);
+        }
+        // Dispose the right panel if existing
+        if (!firstTime) {
+            this.dispose();
+        }
+        // set the mode as popup
+        this._popupMode = true;
+        // Save the HTML document
+        Inspector.DOCUMENT = popup.document;
+        Inspector.WINDOW = popup;
+        // Build the inspector wrapper
+        this._c2diwrapper = Helpers.CreateDiv('insp-wrapper', popup.document.body);
+        // add inspector     
+        let inspector = Helpers.CreateDiv('insp-right-panel', this._c2diwrapper);
+        inspector.classList.add('popupmode');
+        // and build it in the popup  
+        this._buildInspector(inspector);
+        // Rebuild it
+        this.refresh();
+
+        popup.addEventListener('resize', () => {
+            if (this._tabbar) {
+                this._tabbar.updateWidth()
+            }
+        });
+    }
+
+    public getActiveTabIndex(): number {
+        return this._tabbar.getActiveTabIndex();
     }
 }

+ 33 - 31
inspector/src/adapters/Adapter.ts

@@ -1,43 +1,45 @@
-module INSPECTOR {
+import { AbstractTreeTool } from "../treetools/AbstractTreeTool";
+import { PropertyLine } from "../details/PropertyLine";
 
-    export abstract class Adapter {
+import { Geometry } from "babylonjs";
 
-        protected _obj: any;
-        // a unique name for this adapter, to retrieve its own key in the local storage
-        private static _name: string = BABYLON.Geometry.RandomId();
+export abstract class Adapter {
 
-        constructor(obj: any) {
-            this._obj = obj;
-        }
+    protected _obj: any;
+    // a unique name for this adapter, to retrieve its own key in the local storage
+    private static _name: string = Geometry.RandomId();
 
+    constructor(obj: any) {
+        this._obj = obj;
+    }
 
-        /** Returns the name displayed in the tree */
-        public abstract id(): string;
 
-        /** Returns the type of this object - displayed in the tree */
-        public abstract type(): string;
+    /** Returns the name displayed in the tree */
+    public abstract id(): string;
 
-        /** Returns the list of properties to be displayed for this adapter */
-        public abstract getProperties(): Array<PropertyLine>;
+    /** Returns the type of this object - displayed in the tree */
+    public abstract type(): string;
 
-        /** Returns true if the given object correspond to this  */
-        public correspondsTo(obj: any) {
-            return obj === this._obj;
-        }
+    /** Returns the list of properties to be displayed for this adapter */
+    public abstract getProperties(): Array<PropertyLine>;
 
-        /** Returns the adapter unique name */
-        public get name(): string {
-            return Adapter._name;
-        }
+    /** Returns true if the given object correspond to this  */
+    public correspondsTo(obj: any) {
+        return obj === this._obj;
+    }
 
-        /**
-         * Returns the actual object used for this adapter
-         */
-        public get object(): any {
-            return this._obj;
-        }
+    /** Returns the adapter unique name */
+    public get name(): string {
+        return Adapter._name;
+    }
 
-        /** Returns the list of tools available for this adapter */
-        public abstract getTools(): Array<AbstractTreeTool>;
+    /**
+     * Returns the actual object used for this adapter
+     */
+    public get object(): any {
+        return this._obj;
     }
-}
+
+    /** Returns the list of tools available for this adapter */
+    public abstract getTools(): Array<AbstractTreeTool>;
+}

+ 53 - 49
inspector/src/adapters/CameraAdapter.ts

@@ -1,55 +1,59 @@
-module INSPECTOR {
-    
-    export class CameraAdapter 
-        extends Adapter 
-         implements ICameraPOV{
-        
-        constructor(obj:BABYLON.Camera) {
-            super(obj);
-        }
-        
-        /** Returns the name displayed in the tree */
-        public id() : string {
-            let str = '';
-            if (this._obj.name) {
-                str = this._obj.name;
-            } // otherwise nothing displayed        
-            return str;
-        }
-        
-        /** Returns the type of this object - displayed in the tree */
-        public type() : string{
-            return Helpers.GET_TYPE(this._obj);
-        }
-        
-        /** Returns the list of properties to be displayed for this adapter */
-        public getProperties() : Array<PropertyLine> {
-            return Helpers.GetAllLinesProperties(this._obj);
-        }
-        
-        public getTools() : Array<AbstractTreeTool> {
-            let tools = [];
-            tools.push(new CameraPOV(this));
-            return tools;
-        }
+import { Adapter } from "./Adapter";
+import { ICameraPOV, CameraPOV } from "../treetools/CameraPOV";
+import { Camera } from "babylonjs";
+import { Helpers } from "../helpers/Helpers";
+import { PropertyLine } from "../details/PropertyLine";
+import { AbstractTreeTool } from "treetools/AbstractTreeTool";
 
-        // Set the point of view of the chosen camera
-        public setPOV() {
-           (this._obj as BABYLON.Camera).getScene().switchActiveCamera(this._obj);
-        }
 
-        // Return the name of the current active camera
-        public getCurrentActiveCamera() {
-            let activeCamera = (this._obj as BABYLON.Camera).getScene().activeCamera;
-            if(activeCamera != null)
-            {
-                return activeCamera.name;
-            }else{
-                return "0";
-            }
-        }
+export class CameraAdapter
+    extends Adapter
+    implements ICameraPOV {
+
+    constructor(obj: Camera) {
+        super(obj);
+    }
+
+    /** Returns the name displayed in the tree */
+    public id(): string {
+        let str = '';
+        if (this._obj.name) {
+            str = this._obj.name;
+        } // otherwise nothing displayed        
+        return str;
+    }
 
+    /** Returns the type of this object - displayed in the tree */
+    public type(): string {
+        return Helpers.GET_TYPE(this._obj);
+    }
+
+    /** Returns the list of properties to be displayed for this adapter */
+    public getProperties(): Array<PropertyLine> {
+        return Helpers.GetAllLinesProperties(this._obj);
+    }
 
-        
+    public getTools(): Array<AbstractTreeTool> {
+        let tools = [];
+        tools.push(new CameraPOV(this));
+        return tools;
     }
+
+    // Set the point of view of the chosen camera
+    public setPOV() {
+        (this._obj as Camera).getScene().switchActiveCamera(this._obj);
+    }
+
+    // Return the name of the current active camera
+    public getCurrentActiveCamera() {
+        let activeCamera = (this._obj as Camera).getScene().activeCamera;
+        if (activeCamera != null) {
+            return activeCamera.name;
+        } else {
+            return "0";
+        }
+    }
+
+
+
 }

+ 48 - 43
inspector/src/adapters/GUIAdapter.ts

@@ -1,44 +1,49 @@
-module INSPECTOR {
-    
-    export class GUIAdapter 
-        extends Adapter 
-        implements IToolVisible {
-
-        constructor(obj: BABYLON.GUI.Control) {
-            super(obj);
-        }
-
-        /** Returns the name displayed in the tree */
-        public id(): string {
-            let str = '';
-            if (this._obj.name) {
-                str = this._obj.name;
-            } // otherwise nothing displayed        
-            return str;
-        }
-
-        /** Returns the type of this object - displayed in the tree */
-        public type(): string {
-            return Helpers.GET_TYPE(this._obj);
-        }
-
-        /** Returns the list of properties to be displayed for this adapter */
-        public getProperties(): Array<PropertyLine> {
-            return Helpers.GetAllLinesProperties(this._obj);
-        }
-
-        public getTools(): Array<AbstractTreeTool> {
-            let tools = [];
-            tools.push(new Checkbox(this));
-            return tools;
-        }
-
-        public setVisible(b: boolean){
-            (this._obj as BABYLON.GUI.Control).isVisible = b;
-        }
-
-        public isVisible(): boolean{
-            return (this._obj as BABYLON.GUI.Control).isVisible;
-        }
+import { Adapter } from "./Adapter";
+import { IToolVisible, Checkbox } from "treetools/Checkbox";
+import { Helpers } from "helpers/Helpers";
+import { PropertyLine } from "details/PropertyLine";
+import { AbstractTreeTool } from "treetools/AbstractTreeTool";
+
+import * as GUI from "babylonjs-gui";
+
+export class GUIAdapter
+    extends Adapter
+    implements IToolVisible {
+
+    constructor(obj: GUI.Control) {
+        super(obj);
+    }
+
+    /** Returns the name displayed in the tree */
+    public id(): string {
+        let str = '';
+        if (this._obj.name) {
+            str = this._obj.name;
+        } // otherwise nothing displayed        
+        return str;
+    }
+
+    /** Returns the type of this object - displayed in the tree */
+    public type(): string {
+        return Helpers.GET_TYPE(this._obj);
+    }
+
+    /** Returns the list of properties to be displayed for this adapter */
+    public getProperties(): Array<PropertyLine> {
+        return Helpers.GetAllLinesProperties(this._obj);
+    }
+
+    public getTools(): Array<AbstractTreeTool> {
+        let tools = [];
+        tools.push(new Checkbox(this));
+        return tools;
+    }
+
+    public setVisible(b: boolean) {
+        (this._obj as GUI.Control).isVisible = b;
+    }
+
+    public isVisible(): boolean {
+        return (this._obj as GUI.Control).isVisible;
     }
-}
+}

+ 49 - 46
inspector/src/adapters/LightAdapter.ts

@@ -1,48 +1,51 @@
-module INSPECTOR {
-    
-    export class LightAdapter 
-        extends Adapter 
-        implements IToolVisible{
-        
-        constructor(obj:BABYLON.Light) {
-            super(obj);
-        }
-        
-        /** Returns the name displayed in the tree */
-        public id() : string {
-            let str = '';
-            if (this._obj.name) {
-                str = this._obj.name;
-            } // otherwise nothing displayed        
-            return str;
-        }
-        
-        /** Returns the type of this object - displayed in the tree */
-        public type() : string{
-            return Helpers.GET_TYPE(this._obj);
-        }
-        
-        /** Returns the list of properties to be displayed for this adapter */
-        public getProperties() : Array<PropertyLine> {
-            return Helpers.GetAllLinesProperties(this._obj);
-        }
-        
-        public getTools() : Array<AbstractTreeTool> {
-            let tools = [];
-            tools.push(new Checkbox(this));
-            return tools;
-        }
-        
-        public setVisible(b:boolean) {
-            this._obj.setEnabled(b);
-        }        
-        public isVisible() : boolean {
-            return this._obj.isEnabled(); 
-        }
-
-        /** Returns some information about this mesh */
-        // public getInfo() : string {
-        //     return `${(this._obj as BABYLON.AbstractMesh).getTotalVertices()} vertices`;
-        // }
+import { Adapter } from "./Adapter";
+import { IToolVisible, Checkbox } from "treetools/Checkbox";
+import { Helpers } from "helpers/Helpers";
+import { PropertyLine } from "details/PropertyLine";
+import { AbstractTreeTool } from "treetools/AbstractTreeTool";
+
+export class LightAdapter
+    extends Adapter
+    implements IToolVisible {
+
+    constructor(obj: BABYLON.Light) {
+        super(obj);
+    }
+
+    /** Returns the name displayed in the tree */
+    public id(): string {
+        let str = '';
+        if (this._obj.name) {
+            str = this._obj.name;
+        } // otherwise nothing displayed        
+        return str;
+    }
+
+    /** Returns the type of this object - displayed in the tree */
+    public type(): string {
+        return Helpers.GET_TYPE(this._obj);
+    }
+
+    /** Returns the list of properties to be displayed for this adapter */
+    public getProperties(): Array<PropertyLine> {
+        return Helpers.GetAllLinesProperties(this._obj);
+    }
+
+    public getTools(): Array<AbstractTreeTool> {
+        let tools = [];
+        tools.push(new Checkbox(this));
+        return tools;
     }
+
+    public setVisible(b: boolean) {
+        this._obj.setEnabled(b);
+    }
+    public isVisible(): boolean {
+        return this._obj.isEnabled();
+    }
+
+    /** Returns some information about this mesh */
+    // public getInfo() : string {
+    //     return `${(this._obj as BABYLON.AbstractMesh).getTotalVertices()} vertices`;
+    // }
 }

+ 34 - 31
inspector/src/adapters/MaterialAdapter.ts

@@ -1,34 +1,37 @@
-module INSPECTOR {
-    
-    export class MaterialAdapter 
-        extends Adapter {
+import { Adapter } from "./Adapter";
+import { Material } from "babylonjs";
+import { Helpers } from "helpers/Helpers";
+import { PropertyLine } from "details/PropertyLine";
+import { AbstractTreeTool } from "treetools/AbstractTreeTool";
 
-        constructor(obj:BABYLON.Material) {
-            super(obj);
-        }
-        
-        /** Returns the name displayed in the tree */
-        public id() : string {
-            let str = '';
-            if (this._obj.name) {
-                str = this._obj.name;
-            } // otherwise nothing displayed        
-            return str;
-        }
-        
-        /** Returns the type of this object - displayed in the tree */
-        public type() : string{
-            return Helpers.GET_TYPE(this._obj);
-        }
-        
-        /** Returns the list of properties to be displayed for this adapter */
-        public getProperties() : Array<PropertyLine> {
-            return Helpers.GetAllLinesProperties(this._obj);
-        }
-        
-        /** No tools for a material adapter */
-        public getTools() : Array<AbstractTreeTool> {
-            return [];
-        }
+export class MaterialAdapter
+    extends Adapter {
+
+    constructor(obj: Material) {
+        super(obj);
+    }
+
+    /** Returns the name displayed in the tree */
+    public id(): string {
+        let str = '';
+        if (this._obj.name) {
+            str = this._obj.name;
+        } // otherwise nothing displayed        
+        return str;
+    }
+
+    /** Returns the type of this object - displayed in the tree */
+    public type(): string {
+        return Helpers.GET_TYPE(this._obj);
+    }
+
+    /** Returns the list of properties to be displayed for this adapter */
+    public getProperties(): Array<PropertyLine> {
+        return Helpers.GetAllLinesProperties(this._obj);
+    }
+
+    /** No tools for a material adapter */
+    public getTools(): Array<AbstractTreeTool> {
+        return [];
     }
 }

+ 102 - 94
inspector/src/adapters/MeshAdapter.ts

@@ -1,110 +1,118 @@
-module INSPECTOR {
-
-    export class MeshAdapter
-        extends Adapter
-        implements IToolVisible, IToolDebug, IToolBoundingBox, IToolInfo {
-
-        /** Keep track of the axis of the actual object */
-        private _axesViewer: BABYLON.Nullable<any>;
-        private onBeforeRenderObserver: BABYLON.Nullable<BABYLON.Observer<BABYLON.Scene>>;
+import { Adapter } from "./Adapter";
+import { IToolVisible, Checkbox } from "treetools/Checkbox";
+import { IToolDebug, DebugArea } from "treetools/DebugArea";
+import { IToolBoundingBox, BoundingBox } from "treetools/BoundingBox";
+import { IToolInfo, Info } from "treetools/Info";
+import { Nullable, Observer, Scene, AbstractMesh, Vector3, Debug, TransformNode, Node } from "babylonjs";
+import { Helpers } from "helpers/Helpers";
+import { PropertyLine } from "details/PropertyLine";
+import { AbstractTreeTool } from "treetools/AbstractTreeTool";
+
+
+export class MeshAdapter
+    extends Adapter
+    implements IToolVisible, IToolDebug, IToolBoundingBox, IToolInfo {
+
+    /** Keep track of the axis of the actual object */
+    private _axesViewer: Nullable<any>;
+    private onBeforeRenderObserver: Nullable<Observer<Scene>>;
+
+    constructor(mesh: Node) {
+        super(mesh);
+    }
 
-        constructor(mesh: BABYLON.Node) {
-            super(mesh);
-        }
+    /** Returns the name displayed in the tree */
+    public id(): string {
+        let str = '';
+        if (this._obj.name) {
+            str = this._obj.name;
+        } // otherwise nothing displayed        
+        return str;
+    }
 
-        /** Returns the name displayed in the tree */
-        public id(): string {
-            let str = '';
-            if (this._obj.name) {
-                str = this._obj.name;
-            } // otherwise nothing displayed        
-            return str;
-        }
+    /** Returns the type of this object - displayed in the tree */
+    public type(): string {
+        return Helpers.GET_TYPE(this._obj);
+    }
 
-        /** Returns the type of this object - displayed in the tree */
-        public type(): string {
-            return Helpers.GET_TYPE(this._obj);
-        }
+    /** Returns the list of properties to be displayed for this adapter */
+    public getProperties(): Array<PropertyLine> {
+        return Helpers.GetAllLinesProperties(this._obj);
+    }
 
-        /** Returns the list of properties to be displayed for this adapter */
-        public getProperties(): Array<PropertyLine> {
-            return Helpers.GetAllLinesProperties(this._obj);
+    public getTools(): Array<AbstractTreeTool> {
+        let tools = [];
+        tools.push(new Checkbox(this));
+        tools.push(new DebugArea(this));
+        if (this._obj instanceof AbstractMesh) {
+            if ((this._obj as AbstractMesh).getTotalVertices() > 0) {
+                tools.push(new BoundingBox(this));
+            }
         }
 
-        public getTools(): Array<AbstractTreeTool> {
-            let tools = [];
-            tools.push(new Checkbox(this));
-            tools.push(new DebugArea(this));
-            if (this._obj instanceof BABYLON.AbstractMesh) {
-                if ((this._obj as BABYLON.AbstractMesh).getTotalVertices() > 0) {
-                    tools.push(new BoundingBox(this));
-                }
-            }
 
+        tools.push(new Info(this));
+        return tools;
+    }
 
-            tools.push(new Info(this));
-            return tools;
-        }
+    public setVisible(b: boolean) {
+        this._obj.setEnabled(b);
+        this._obj.isVisible = b;
+    }
+    public isVisible(): boolean {
+        return this._obj.isEnabled() && (this._obj.isVisible === undefined || this._obj.isVisible);
+    }
+    public isBoxVisible(): boolean {
+        return (this._obj as AbstractMesh).showBoundingBox;
+    }
+    public setBoxVisible(b: boolean) {
+        return (this._obj as AbstractMesh).showBoundingBox = b;
+    }
 
-        public setVisible(b: boolean) {
-            this._obj.setEnabled(b);
-            this._obj.isVisible = b;
+    public debug(enable: boolean) {
+        // Draw axis the first time
+        if (!this._axesViewer) {
+            this._drawAxis();
         }
-        public isVisible(): boolean {
-            return this._obj.isEnabled() && (this._obj.isVisible === undefined || this._obj.isVisible);
-        }
-        public isBoxVisible(): boolean {
-            return (this._obj as BABYLON.AbstractMesh).showBoundingBox;
-        }
-        public setBoxVisible(b: boolean) {
-            return (this._obj as BABYLON.AbstractMesh).showBoundingBox = b;
+        // Display or hide axis
+        if (!enable && this._axesViewer) {
+            let mesh = this._obj as AbstractMesh;
+            mesh.getScene().onBeforeRenderObservable.remove(this.onBeforeRenderObserver);
+            this._axesViewer.dispose();
+            this._axesViewer = null;
         }
+    }
 
-        public debug(enable: boolean) {
-            // Draw axis the first time
-            if (!this._axesViewer) {
-                this._drawAxis();
-            }
-            // Display or hide axis
-            if (!enable && this._axesViewer) {
-                let mesh = this._obj as BABYLON.AbstractMesh;
-                mesh.getScene().onBeforeRenderObservable.remove(this.onBeforeRenderObserver);
-                this._axesViewer.dispose();
-                this._axesViewer = null;
-            }
+    /** Returns some information about this mesh */
+    public getInfo(): string {
+        if (this._obj instanceof AbstractMesh) {
+            return `${(this._obj as AbstractMesh).getTotalVertices()} vertices`;
         }
+        return '0 vertices';
+    }
 
-        /** Returns some information about this mesh */
-        public getInfo(): string {
-            if (this._obj instanceof BABYLON.AbstractMesh) {
-                return `${(this._obj as BABYLON.AbstractMesh).getTotalVertices()} vertices`;
+    /** Draw X, Y and Z axis for the actual object if this adapter.
+     * Should be called only one time as it will fill this._axis
+     */
+    private _drawAxis() {
+        this._obj.computeWorldMatrix();
+
+        // Axis
+        var x = new Vector3(1, 0, 0);
+        var y = new Vector3(0, 1, 0);
+        var z = new Vector3(0, 0, 1);
+
+        this._axesViewer = new Debug.AxesViewer(this._obj.getScene());
+
+        let mesh = this._obj as TransformNode;
+        this.onBeforeRenderObserver = mesh.getScene().onBeforeRenderObservable.add(() => {
+            let matrix = mesh.getWorldMatrix();
+            let extend = new Vector3(1, 1, 1);
+            if (mesh instanceof AbstractMesh) {
+                extend = mesh.getBoundingInfo().boundingBox.extendSizeWorld;
             }
-            return '0 vertices';
-        }
-
-        /** Draw X, Y and Z axis for the actual object if this adapter.
-         * Should be called only one time as it will fill this._axis
-         */
-        private _drawAxis() {
-            this._obj.computeWorldMatrix();
-
-            // Axis
-            var x = new BABYLON.Vector3(1, 0, 0);
-            var y = new BABYLON.Vector3(0, 1, 0);
-            var z = new BABYLON.Vector3(0, 0, 1);
-
-            this._axesViewer = new BABYLON.Debug.AxesViewer(this._obj.getScene());
-
-            let mesh = this._obj as BABYLON.TransformNode;
-            this.onBeforeRenderObserver = mesh.getScene().onBeforeRenderObservable.add(() => {
-                let matrix = mesh.getWorldMatrix();
-                let extend = new BABYLON.Vector3(1, 1, 1);
-                if (mesh instanceof BABYLON.AbstractMesh) {
-                    extend = mesh.getBoundingInfo().boundingBox.extendSizeWorld;
-                }
-                this._axesViewer!.scaleLines = Math.max(extend.x, extend.y, extend.z) * 2;
-                this._axesViewer!.update(this._obj.position, BABYLON.Vector3.TransformNormal(x, matrix), BABYLON.Vector3.TransformNormal(y, matrix), BABYLON.Vector3.TransformNormal(z, matrix));
-            });
-        }
+            this._axesViewer!.scaleLines = Math.max(extend.x, extend.y, extend.z) * 2;
+            this._axesViewer!.update(this._obj.position, Vector3.TransformNormal(x, matrix), Vector3.TransformNormal(y, matrix), Vector3.TransformNormal(z, matrix));
+        });
     }
-}
+}

+ 48 - 43
inspector/src/adapters/PhysicsImpostorAdapter.ts

@@ -1,55 +1,60 @@
-module INSPECTOR {
+import { Adapter } from "./Adapter";
+import { IToolVisible, Checkbox } from "treetools/Checkbox";
+import { PhysicsImpostor, AbstractMesh } from "babylonjs";
+import { Helpers } from "helpers/Helpers";
+import { PropertyLine } from "../details/PropertyLine";
+import { AbstractTreeTool } from "../treetools/AbstractTreeTool";
 
-    export class PhysicsImpostorAdapter
-        extends Adapter
-        implements IToolVisible {
 
-        private _viewer: any;
-        private _isVisible = false;
+export class PhysicsImpostorAdapter
+    extends Adapter
+    implements IToolVisible {
 
-        constructor(obj: BABYLON.PhysicsImpostor, viewer: any) {
-            super(obj);
-            this._viewer = viewer;
-        }
+    private _viewer: any;
+    private _isVisible = false;
 
-        /** Returns the name displayed in the tree */
-        public id(): string {
-            let str = '';
-            let physicsImposter = (<BABYLON.PhysicsImpostor>this._obj);
-            if (physicsImposter && physicsImposter.object) {
-                str = (<BABYLON.AbstractMesh>physicsImposter.object).name || "";
-            } // otherwise nothing displayed        
-            return str;
-        }
+    constructor(obj: PhysicsImpostor, viewer: any) {
+        super(obj);
+        this._viewer = viewer;
+    }
 
-        /** Returns the type of this object - displayed in the tree */
-        public type(): string {
-            return Helpers.GET_TYPE(this._obj);
-        }
+    /** Returns the name displayed in the tree */
+    public id(): string {
+        let str = '';
+        let physicsImposter = (<PhysicsImpostor>this._obj);
+        if (physicsImposter && physicsImposter.object) {
+            str = (<AbstractMesh>physicsImposter.object).name || "";
+        } // otherwise nothing displayed        
+        return str;
+    }
 
-        /** Returns the list of properties to be displayed for this adapter */
-        public getProperties(): Array<PropertyLine> {
-            return Helpers.GetAllLinesProperties(this._obj);
-        }
+    /** Returns the type of this object - displayed in the tree */
+    public type(): string {
+        return Helpers.GET_TYPE(this._obj);
+    }
 
-        public getTools(): Array<AbstractTreeTool> {
-            let tools = [];
-            tools.push(new Checkbox(this));
-            return tools;
-        }
+    /** Returns the list of properties to be displayed for this adapter */
+    public getProperties(): Array<PropertyLine> {
+        return Helpers.GetAllLinesProperties(this._obj);
+    }
 
-        public setVisible(b: boolean) {
-            this._isVisible = b;
-            if (b) {
-                this._viewer.showImpostor(this._obj);
-            } else {
-                this._viewer.hideImpostor(this._obj);
-            }
-        }
+    public getTools(): Array<AbstractTreeTool> {
+        let tools = [];
+        tools.push(new Checkbox(this));
+        return tools;
+    }
 
-        public isVisible(): boolean {
-            return this._isVisible;
+    public setVisible(b: boolean) {
+        this._isVisible = b;
+        if (b) {
+            this._viewer.showImpostor(this._obj);
+        } else {
+            this._viewer.hideImpostor(this._obj);
         }
+    }
 
+    public isVisible(): boolean {
+        return this._isVisible;
     }
-}
+
+}

+ 44 - 39
inspector/src/adapters/SoundAdapter.ts

@@ -1,48 +1,53 @@
-module INSPECTOR {
+import { Adapter } from "./Adapter";
+import { ISoundInteractions, SoundInteractions } from "treetools/SoundInteractions";
+import { Sound } from "babylonjs";
+import { Helpers } from "helpers/Helpers";
+import { PropertyLine } from "../details/PropertyLine";
+import { AbstractTreeTool } from "../treetools/AbstractTreeTool";
 
-    export class SoundAdapter
-        extends Adapter
-        implements ISoundInteractions {
 
-        constructor(obj: BABYLON.Sound) {
-            super(obj);
-        }
+export class SoundAdapter
+    extends Adapter
+    implements ISoundInteractions {
 
-        /** Returns the name displayed in the tree */
-        public id(): string {
-            let str = '';
-            if (this._obj.name) {
-                str = this._obj.name;
-            } // otherwise nothing displayed        
-            return str;
-        }
+    constructor(obj: Sound) {
+        super(obj);
+    }
 
-        /** Returns the type of this object - displayed in the tree */
-        public type(): string {
-            return Helpers.GET_TYPE(this._obj);
-        }
+    /** Returns the name displayed in the tree */
+    public id(): string {
+        let str = '';
+        if (this._obj.name) {
+            str = this._obj.name;
+        } // otherwise nothing displayed        
+        return str;
+    }
 
-        /** Returns the list of properties to be displayed for this adapter */
-        public getProperties(): Array<PropertyLine> {
-            return Helpers.GetAllLinesProperties(this._obj);
-        }
+    /** Returns the type of this object - displayed in the tree */
+    public type(): string {
+        return Helpers.GET_TYPE(this._obj);
+    }
 
-        public getTools(): Array<AbstractTreeTool> {
-            let tools = [];
-            tools.push(new SoundInteractions(this));
-            return tools;
-        }
+    /** Returns the list of properties to be displayed for this adapter */
+    public getProperties(): Array<PropertyLine> {
+        return Helpers.GetAllLinesProperties(this._obj);
+    }
+
+    public getTools(): Array<AbstractTreeTool> {
+        let tools = [];
+        tools.push(new SoundInteractions(this));
+        return tools;
+    }
 
-        public setPlaying(callback: Function) {
-            if ((this._obj as BABYLON.Sound).isPlaying) {
-                (this._obj as BABYLON.Sound).pause();
-            }
-            else {
-                (this._obj as BABYLON.Sound).play();
-            }
-            (this._obj as BABYLON.Sound).onended = () => {
-                callback();
-            }
+    public setPlaying(callback: Function) {
+        if ((this._obj as Sound).isPlaying) {
+            (this._obj as Sound).pause();
+        }
+        else {
+            (this._obj as Sound).play();
+        }
+        (this._obj as Sound).onended = () => {
+            callback();
         }
     }
-}
+}

+ 33 - 30
inspector/src/adapters/TextureAdapter.ts

@@ -1,37 +1,40 @@
-module INSPECTOR {
+import { Adapter } from "./Adapter";
+import { BaseTexture } from "babylonjs";
+import { Helpers } from "../helpers/Helpers";
+import { PropertyLine } from "../details/PropertyLine";
+import { AbstractTreeTool } from "../treetools/AbstractTreeTool";
 
-    export class TextureAdapter
-        extends Adapter {
+export class TextureAdapter
+    extends Adapter {
 
-        constructor(obj: BABYLON.BaseTexture) {
-            super(obj);
-        }
-
-        /** Returns the name displayed in the tree */
-        public id(): string {
-            let str = '';
-            if (this._obj.name) {
-                str = this._obj.name;
-            } // otherwise nothing displayed        
-            return str;
-        }
+    constructor(obj: BaseTexture) {
+        super(obj);
+    }
 
-        /** Returns the type of this object - displayed in the tree */
-        public type(): string {
-            return Helpers.GET_TYPE(this._obj);
-        }
+    /** Returns the name displayed in the tree */
+    public id(): string {
+        let str = '';
+        if (this._obj.name) {
+            str = this._obj.name;
+        } // otherwise nothing displayed        
+        return str;
+    }
 
-        /** Returns the list of properties to be displayed for this adapter */
-        public getProperties(): Array<PropertyLine> {
-            // Not used in this tab
-            return [];
-        }
+    /** Returns the type of this object - displayed in the tree */
+    public type(): string {
+        return Helpers.GET_TYPE(this._obj);
+    }
 
-        public getTools(): Array<AbstractTreeTool> {
-            let tools = new Array<AbstractTreeTool>();
-            // tools.push(new CameraPOV(this));
-            return tools;
-        }
+    /** Returns the list of properties to be displayed for this adapter */
+    public getProperties(): Array<PropertyLine> {
+        // Not used in this tab
+        return [];
+    }
 
+    public getTools(): Array<AbstractTreeTool> {
+        let tools = new Array<AbstractTreeTool>();
+        // tools.push(new CameraPOV(this));
+        return tools;
     }
-}
+
+}

+ 186 - 182
inspector/src/details/DetailPanel.ts

@@ -1,211 +1,215 @@
- module INSPECTOR {
-    export interface SortDirection {
-        [property: string]: number;
+import { BasicElement } from "../gui/BasicElement";
+import { PropertyLine } from "./PropertyLine";
+import { SearchBarDetails } from "../gui/SearchBar";
+import { Helpers } from "../helpers/Helpers";
+import { Inspector } from "../Inspector";
+
+export interface SortDirection {
+    [property: string]: number;
+}
+
+export class DetailPanel extends BasicElement {
+
+    // The header row
+    private _headerRow: HTMLElement;
+    // Contains all details rows that belongs to the item above
+    private _detailRows: Array<PropertyLine> = [];
+    // Store the sort direction of each header column
+    private _sortDirection: SortDirection = {};
+    // The search bar
+    private _searchDetails: SearchBarDetails;
+    private _details: HTMLElement;
+
+    constructor(dr?: Array<PropertyLine>) {
+        super();
+        this._build();
+
+        if (dr) {
+            this._detailRows = dr;
+            this.update();
+        }
     }
 
-    export class DetailPanel extends BasicElement {
-
-        // The header row
-        private _headerRow : HTMLElement;
-        // Contains all details rows that belongs to the item above
-        private _detailRows : Array<PropertyLine> = [];
-        // Store the sort direction of each header column
-        private _sortDirection : SortDirection = {};
-        // The search bar
-        private _searchDetails : SearchBarDetails;
-        private _details : HTMLElement;
-
-        constructor(dr? : Array<PropertyLine>) {
-            super();
-            this._build();
-            
-            if (dr) {
-                this._detailRows = dr;
-                this.update();
-            }
-        }
+    set details(detailsRow: Array<PropertyLine>) {
+        this.clean();
+        //add the searchBar
+        this._addSearchBarDetails();
+        this._details = Helpers.CreateDiv('details', this._div);
+        this._detailRows = detailsRow;
+        // Refresh HTML
+        this.update();
+    }
 
-        set details(detailsRow : Array<PropertyLine>) {
-            this.clean();
-            //add the searchBar
-            this._addSearchBarDetails();
-            this._details = Helpers.CreateDiv('details', this._div);
-            this._detailRows = detailsRow;
-            // Refresh HTML
-            this.update();
-        }
+    protected _build() {
+        this._div.className = 'insp-details';
+        this._div.id = 'insp-details';
+        // Create header row
+        this._createHeaderRow();
+        this._div.appendChild(this._headerRow);
 
-        protected _build() {
-            this._div.className = 'insp-details';
-            this._div.id = 'insp-details';
-            // Create header row
-            this._createHeaderRow();
-            this._div.appendChild(this._headerRow);
-            
-        } 
-        
-        /** Updates the HTML of the detail panel */
-        public update(_items?: Array<PropertyLine>) {            
-            this._sortDetails('name', 1);
-            // Check the searchbar
-            if (_items) {
-                this.cleanRow();
-                this._addSearchDetails(_items);
-                //console.log(_items);
-            } else {
-                this._addDetails();
-                //console.log("np");
-            }
+    }
+
+    /** Updates the HTML of the detail panel */
+    public update(_items?: Array<PropertyLine>) {
+        this._sortDetails('name', 1);
+        // Check the searchbar
+        if (_items) {
+            this.cleanRow();
+            this._addSearchDetails(_items);
+            //console.log(_items);
+        } else {
+            this._addDetails();
+            //console.log("np");
         }
+    }
 
-         /** Add the search bar for the details */
-        private _addSearchBarDetails() {
-            let searchDetails = Helpers.CreateDiv('searchbar-details', this._div);
-            // Create search bar
-            this._searchDetails = new SearchBarDetails(this);
+    /** Add the search bar for the details */
+    private _addSearchBarDetails() {
+        let searchDetails = Helpers.CreateDiv('searchbar-details', this._div);
+        // Create search bar
+        this._searchDetails = new SearchBarDetails(this);
 
-            searchDetails.appendChild(this._searchDetails.toHtml());
-            this._div.appendChild(searchDetails);
-        }
+        searchDetails.appendChild(this._searchDetails.toHtml());
+        this._div.appendChild(searchDetails);
+    }
 
-        /** Search an element by name  */
-        public searchByName(searchName: string) {
-            let rows = [];
-            for (let row of this._detailRows) {
-                if(row.name.indexOf(searchName) >= 0){
-                    rows.push(row);
-                }
+    /** Search an element by name  */
+    public searchByName(searchName: string) {
+        let rows = [];
+        for (let row of this._detailRows) {
+            if (row.name.indexOf(searchName) >= 0) {
+                rows.push(row);
             }
-            this.update(rows);
         }
+        this.update(rows);
+    }
 
-        /** Add all lines in the html div. Does not sort them! */
-        private _addDetails() {
-            for (let row of this._detailRows) {
-                this._details.appendChild(row.toHtml());
-            }
+    /** Add all lines in the html div. Does not sort them! */
+    private _addDetails() {
+        for (let row of this._detailRows) {
+            this._details.appendChild(row.toHtml());
         }
+    }
 
-        private _addSearchDetails(_items: Array<PropertyLine>) {
-            for (let row of _items) {
-                this._details.appendChild(row.toHtml());
-            }   
+    private _addSearchDetails(_items: Array<PropertyLine>) {
+        for (let row of _items) {
+            this._details.appendChild(row.toHtml());
         }
+    }
 
-        /**
-         * Sort the details row by comparing the given property of each row
-         */
-        private _sortDetails(property:string, _direction?:number) {
-                
-            // Clean header
-            let elems = Inspector.DOCUMENT.querySelectorAll('.sort-direction');
-            for (let e=0; e<elems.length; e++) {
-                elems[e].classList.remove('fa-chevron-up');
-                elems[e].classList.remove('fa-chevron-down');
-            }
+    /**
+     * Sort the details row by comparing the given property of each row
+     */
+    private _sortDetails(property: string, _direction?: number) {
 
+        // Clean header
+        let elems = Inspector.DOCUMENT.querySelectorAll('.sort-direction');
+        for (let e = 0; e < elems.length; e++) {
+            elems[e].classList.remove('fa-chevron-up');
+            elems[e].classList.remove('fa-chevron-down');
+        }
 
-            if (_direction || !this._sortDirection[property]) {
-                this._sortDirection[property] = _direction || 1;
-            } else {
-                this._sortDirection[property] *= -1;
-            }
-            let direction = this._sortDirection[property];
-            let query = this._headerRow.querySelector(`#sort-direction-${property}`);
-            if (query) {
-                if (direction == 1) {
-                    query.classList.remove('fa-chevron-down');
-                    query.classList.add('fa-chevron-up');
-                } else {
-                    query.classList.remove('fa-chevron-up');
-                    query.classList.add('fa-chevron-down');
-                }
-            }
 
-            let isString = (s: any) => {
-                return typeof(s) === 'string' || s instanceof String;
-            };
-
-            this._detailRows.forEach((property) => {
-                property.closeDetails();
-            })
-
-            this._detailRows.sort((detail1: any, detail2: any) : number => {
-                let str1 = String(detail1[property]);
-                let str2 = String(detail2[property]);
-                if (!isString(str1)) {
-                    str1 = detail1[property].toString();
-                }
-                if (!isString(str2)) {
-                    str2 = detail2[property].toString();
-                }
-                // Compare numbers as numbers and string as string with 'numeric=true'
-                return str1.localeCompare(str2, [], {numeric:true}) * direction;
-            });
+        if (_direction || !this._sortDirection[property]) {
+            this._sortDirection[property] = _direction || 1;
+        } else {
+            this._sortDirection[property] *= -1;
         }
-
-        /**
-         * Removes all data in the detail panel but keep the header row
-         */
-        public clean() {         
-            // Delete all details row
-            for (let pline of this._detailRows) {
-                pline.dispose();
+        let direction = this._sortDirection[property];
+        let query = this._headerRow.querySelector(`#sort-direction-${property}`);
+        if (query) {
+            if (direction == 1) {
+                query.classList.remove('fa-chevron-down');
+                query.classList.add('fa-chevron-up');
+            } else {
+                query.classList.remove('fa-chevron-up');
+                query.classList.add('fa-chevron-down');
             }
-            Helpers.CleanDiv(this._div);
-            // Header row
-            this._div.appendChild(this._headerRow);
         }
 
-        /**
-         * Clean the rows only
-         */
-        public cleanRow() {           
-            // Delete all details row
-            for (let pline of this._detailRows) {
-                pline.dispose();
+        let isString = (s: any) => {
+            return typeof (s) === 'string' || s instanceof String;
+        };
+
+        this._detailRows.forEach((property) => {
+            property.closeDetails();
+        })
+
+        this._detailRows.sort((detail1: any, detail2: any): number => {
+            let str1 = String(detail1[property]);
+            let str2 = String(detail2[property]);
+            if (!isString(str1)) {
+                str1 = detail1[property].toString();
             }
-            Helpers.CleanDiv(this._details);
+            if (!isString(str2)) {
+                str2 = detail2[property].toString();
+            }
+            // Compare numbers as numbers and string as string with 'numeric=true'
+            return str1.localeCompare(str2, [], { numeric: true }) * direction;
+        });
+    }
+
+    /**
+     * Removes all data in the detail panel but keep the header row
+     */
+    public clean() {
+        // Delete all details row
+        for (let pline of this._detailRows) {
+            pline.dispose();
         }
+        Helpers.CleanDiv(this._div);
+        // Header row
+        this._div.appendChild(this._headerRow);
+    }
 
-        /** Overrides basicelement.dispose */
-        public dispose() {
-            // Delete all details row
-            for (let pline of this._detailRows) {
-                pline.dispose();
-            }
+    /**
+     * Clean the rows only
+     */
+    public cleanRow() {
+        // Delete all details row
+        for (let pline of this._detailRows) {
+            pline.dispose();
         }
+        Helpers.CleanDiv(this._details);
+    }
 
-        /**
-         * Creates the header row : name, value, id
-         */
-        private _createHeaderRow() {   
-            this._headerRow = Helpers.CreateDiv('header-row');
-
-            let createDiv = (name:string, cssClass:string)  : HTMLElement => {
-                let div =  Helpers.CreateDiv(cssClass+' header-col');
-
-                // Column title - first letter in uppercase
-                let spanName = Inspector.DOCUMENT.createElement('span');
-                spanName.textContent = name.charAt(0).toUpperCase() + name.slice(1);
-                
-                // sort direction
-                let spanDirection = Inspector.DOCUMENT.createElement('i');
-                spanDirection.className = 'sort-direction fa';
-                spanDirection.id = 'sort-direction-'+name; 
-
-                div.appendChild(spanName);
-                div.appendChild(spanDirection);
-
-                div.addEventListener('click', (e) => {
-                    this._sortDetails(name);
-                    this._addDetails();
-                });
-                return div;
-            };
-
-            this._headerRow.appendChild(createDiv('name', 'prop-name'));
-            this._headerRow.appendChild(createDiv('value', 'prop-value'));
+    /** Overrides basicelement.dispose */
+    public dispose() {
+        // Delete all details row
+        for (let pline of this._detailRows) {
+            pline.dispose();
         }
     }
- }
+
+    /**
+     * Creates the header row : name, value, id
+     */
+    private _createHeaderRow() {
+        this._headerRow = Helpers.CreateDiv('header-row');
+
+        let createDiv = (name: string, cssClass: string): HTMLElement => {
+            let div = Helpers.CreateDiv(cssClass + ' header-col');
+
+            // Column title - first letter in uppercase
+            let spanName = Inspector.DOCUMENT.createElement('span');
+            spanName.textContent = name.charAt(0).toUpperCase() + name.slice(1);
+
+            // sort direction
+            let spanDirection = Inspector.DOCUMENT.createElement('i');
+            spanDirection.className = 'sort-direction fa';
+            spanDirection.id = 'sort-direction-' + name;
+
+            div.appendChild(spanName);
+            div.appendChild(spanDirection);
+
+            div.addEventListener('click', (e) => {
+                this._sortDetails(name);
+                this._addDetails();
+            });
+            return div;
+        };
+
+        this._headerRow.appendChild(createDiv('name', 'prop-name'));
+        this._headerRow.appendChild(createDiv('value', 'prop-value'));
+    }
+}

+ 65 - 65
inspector/src/details/Property.ts

@@ -1,84 +1,84 @@
-module INSPECTOR {
+import { Scene } from "babylonjs";
+import { Helpers } from "../helpers/Helpers";
 
-    /**
-     * A property is a link between a data (string) and an object.
-     */
-    export class Property {
+/**
+ * A property is a link between a data (string) and an object.
+ */
+export class Property {
 
-        /** The property name */
-        private _property: string;
-        /** The obj this property refers to */
-        private _obj: any;
-        /** The obj parent  */
-        private _parentObj: any;
+    /** The property name */
+    private _property: string;
+    /** The obj this property refers to */
+    private _obj: any;
+    /** The obj parent  */
+    private _parentObj: any;
 
-        constructor(prop: string, obj: any, parentObj?: any) {
-            this._property = prop;
-            this._obj = obj;
-            this._parentObj = parentObj || null;
-        }
+    constructor(prop: string, obj: any, parentObj?: any) {
+        this._property = prop;
+        this._obj = obj;
+        this._parentObj = parentObj || null;
+    }
 
-        public get name(): string {
-            return this._property;
-        }
+    public get name(): string {
+        return this._property;
+    }
 
-        public get value(): any {
-            return this._obj[this._property];
-        }
-        public set value(newValue: any) {
-            if (newValue != undefined && this._obj[this._property] != undefined) {
-                if (this._obj instanceof BABYLON.Scene) {
-                    (<BABYLON.Scene>this._obj).debugLayer.onPropertyChangedObservable.notifyObservers({
-                        object: this._obj,
-                        property: this._property,
-                        value: newValue,
-                        initialValue: (<any>this._obj)[this._property]
-                    });
-                }
-                else {
-                    if(this._parentObj != null) {
-                        // Object that have "children" properties : Color, Vector, imageProcessingConfiguration
+    public get value(): any {
+        return this._obj[this._property];
+    }
+    public set value(newValue: any) {
+        if (newValue != undefined && this._obj[this._property] != undefined) {
+            if (this._obj instanceof Scene) {
+                (<Scene>this._obj).debugLayer.onPropertyChangedObservable.notifyObservers({
+                    object: this._obj,
+                    property: this._property,
+                    value: newValue,
+                    initialValue: (<any>this._obj)[this._property]
+                });
+            }
+            else {
+                if (this._parentObj != null) {
+                    // Object that have "children" properties : Color, Vector, imageProcessingConfiguration
 
-                        if (this._parentObj instanceof BABYLON.Scene) {
-                            (<BABYLON.Scene>this._parentObj).debugLayer.onPropertyChangedObservable.notifyObservers({
-                                object: this._parentObj,
-                                property: this._property,
-                                value: newValue,
-                                initialValue: (<any>this._obj)[this._property]
-                            });
-                        }
-                        else {
-                            this._parentObj.getScene().debugLayer.onPropertyChangedObservable.notifyObservers({
-                                object: this._parentObj,
-                                property: this._property,
-                                value: newValue,
-                                initialValue: this._obj[this._property]
-                            });
-                        }
+                    if (this._parentObj instanceof Scene) {
+                        (<Scene>this._parentObj).debugLayer.onPropertyChangedObservable.notifyObservers({
+                            object: this._parentObj,
+                            property: this._property,
+                            value: newValue,
+                            initialValue: (<any>this._obj)[this._property]
+                        });
                     }
                     else {
-                        this._obj.getScene().debugLayer.onPropertyChangedObservable.notifyObservers({
-                            object: this._obj,
+                        this._parentObj.getScene().debugLayer.onPropertyChangedObservable.notifyObservers({
+                            object: this._parentObj,
                             property: this._property,
                             value: newValue,
                             initialValue: this._obj[this._property]
                         });
                     }
                 }
+                else {
+                    this._obj.getScene().debugLayer.onPropertyChangedObservable.notifyObservers({
+                        object: this._obj,
+                        property: this._property,
+                        value: newValue,
+                        initialValue: this._obj[this._property]
+                    });
+                }
             }
-            this._obj[this._property] = newValue;
-        }
-
-        public get type(): string {
-            return Helpers.GET_TYPE(this.value);
         }
+        this._obj[this._property] = newValue;
+    }
 
-        public get obj(): any {
-            return this._obj;
-        }
-        public set obj(newObj: any) {
-            this._obj = newObj;
-        }
+    public get type(): string {
+        return Helpers.GET_TYPE(this.value);
+    }
 
+    public get obj(): any {
+        return this._obj;
+    }
+    public set obj(newObj: any) {
+        this._obj = newObj;
     }
-}
+
+}

Filskillnaden har hållts tillbaka eftersom den är för stor
+ 491 - 483
inspector/src/details/PropertyLine.ts


+ 29 - 29
inspector/src/gui/BasicElement.ts

@@ -1,32 +1,32 @@
- module INSPECTOR {
+import { Helpers } from "../helpers/Helpers";
+
+/**
+ * Represents a html div element. 
+ * The div is built when an instance of BasicElement is created.
+ */
+export abstract class BasicElement {
+
+    protected _div: HTMLElement;
+
+    constructor() {
+        this._div = Helpers.CreateDiv();
+    }
+
     /**
-     * Represents a html div element. 
-     * The div is built when an instance of BasicElement is created.
+     * Returns the div element
      */
-    export abstract class BasicElement {
-        
-        protected _div : HTMLElement;
-        
-        constructor() {        
-            this._div = Helpers.CreateDiv();  
-        }
-            
-        /**
-         * Returns the div element
-         */
-        public toHtml() : HTMLElement {
-            return this._div;
-        }
-        
-        /**
-         * Build the html element
-         */
-        protected _build(){};
-        
-        public abstract update(data?:any): void;
-        
-        /** Default dispose method if needed */
-        public dispose() {};
-        
+    public toHtml(): HTMLElement {
+        return this._div;
     }
-}
+
+    /**
+     * Build the html element
+     */
+    protected _build() { };
+
+    public abstract update(data?: any): void;
+
+    /** Default dispose method if needed */
+    public dispose() { };
+
+}

+ 31 - 30
inspector/src/gui/ColorElement.ts

@@ -1,35 +1,36 @@
- module INSPECTOR {
-     /**
-     * Display a very small div corresponding to the given color
-     */
-    export class ColorElement extends BasicElement{
-                
-        // The color as hexadecimal string
-        constructor(color:BABYLON.Color4|BABYLON.Color3) {
-            super();
-            this._div.className = 'color-element';
+import { BasicElement } from "./BasicElement";
+import { Color4, Color3 } from "babylonjs";
+
+/**
+* Display a very small div corresponding to the given color
+*/
+export class ColorElement extends BasicElement {
+
+    // The color as hexadecimal string
+    constructor(color: Color4 | Color3) {
+        super();
+        this._div.className = 'color-element';
+        this._div.style.backgroundColor = this._toRgba(color);
+    }
+
+    public update(color?: Color4 | Color3) {
+        if (color) {
             this._div.style.backgroundColor = this._toRgba(color);
         }
-        
-        public update(color?:BABYLON.Color4|BABYLON.Color3) {
-            if (color) {
-                this._div.style.backgroundColor = this._toRgba(color);
-            }
-        }
-        
-        private _toRgba(color:BABYLON.Color4|BABYLON.Color3) : string {
-            if (color) {
-                let r = (color.r * 255) | 0;
-                let g = (color.g * 255) | 0;
-                let b = (color.b * 255) | 0;
-                let a = 1;
-                if (color instanceof BABYLON.Color4) {
-                    a = (color as BABYLON.Color4).a;
-                }
-                return `rgba(${r}, ${g}, ${b}, ${a})`;
-            } else {
-                return '';
+    }
+
+    private _toRgba(color: Color4 | Color3): string {
+        if (color) {
+            let r = (color.r * 255) | 0;
+            let g = (color.g * 255) | 0;
+            let b = (color.b * 255) | 0;
+            let a = 1;
+            if (color instanceof Color4) {
+                a = (color as Color4).a;
             }
+            return `rgba(${r}, ${g}, ${b}, ${a})`;
+        } else {
+            return '';
         }
     }
- }
+}

+ 60 - 56
inspector/src/gui/ColorPickerElement.ts

@@ -1,63 +1,67 @@
-module INSPECTOR {
-    /**
-     * Represents a html div element. 
-     * The div is built when an instance of BasicElement is created.
-     */
-    export class ColorPickerElement extends BasicElement {
-        
-        protected _input : HTMLInputElement;
-        private pline : PropertyLine;
-        
-        constructor(color:BABYLON.Color4|BABYLON.Color3, propertyLine: PropertyLine) {
-            super();
-            let scheduler = Scheduler.getInstance();
-            this._div.className = 'color-element';
-            this._div.style.backgroundColor = this._toRgba(color);
-            this.pline = propertyLine;
+import { BasicElement } from "./BasicElement";
+import { PropertyLine } from "../details/PropertyLine";
+import { Color4, Color3 } from "babylonjs";
+import { Scheduler } from "../scheduler/Scheduler";
+import { Helpers } from "../helpers/Helpers";
 
-            this._input = Helpers.CreateInput();  
-            this._input.type = 'color';
-            this._input.style.opacity = "0";
-            this._input.style.width = '10px';
-            this._input.style.height = '15px';
-            this._input.value = color.toHexString();
-            
-            this._input.addEventListener('input', (e) => {
-                let color = BABYLON.Color3.FromHexString(this._input.value);
-                color.r = parseFloat(color.r.toPrecision(2));
-                color.g = parseFloat(color.g.toPrecision(2));
-                color.b = parseFloat(color.b.toPrecision(2));
-                this.pline.validateInput(color);
-                scheduler.pause = false;
-            });
-            
-            this._div.appendChild(this._input);
-
-            this._input.addEventListener('click', (e) => {
-                scheduler.pause = true;
-            });
-        }
+/**
+ * Represents a html div element. 
+ * The div is built when an instance of BasicElement is created.
+ */
+export class ColorPickerElement extends BasicElement {
 
-        public update(color?:BABYLON.Color4|BABYLON.Color3) {
-            if (color) {
-                this._div.style.backgroundColor = this._toRgba(color);
-                this._input.value = color.toHexString();
-            }
+    protected _input: HTMLInputElement;
+    private pline: PropertyLine;
+
+    constructor(color: Color4 | Color3, propertyLine: PropertyLine) {
+        super();
+        let scheduler = Scheduler.getInstance();
+        this._div.className = 'color-element';
+        this._div.style.backgroundColor = this._toRgba(color);
+        this.pline = propertyLine;
+
+        this._input = Helpers.CreateInput();
+        this._input.type = 'color';
+        this._input.style.opacity = "0";
+        this._input.style.width = '10px';
+        this._input.style.height = '15px';
+        this._input.value = color.toHexString();
+
+        this._input.addEventListener('input', (e) => {
+            let color = Color3.FromHexString(this._input.value);
+            color.r = parseFloat(color.r.toPrecision(2));
+            color.g = parseFloat(color.g.toPrecision(2));
+            color.b = parseFloat(color.b.toPrecision(2));
+            this.pline.validateInput(color);
+            scheduler.pause = false;
+        });
+
+        this._div.appendChild(this._input);
+
+        this._input.addEventListener('click', (e) => {
+            scheduler.pause = true;
+        });
+    }
+
+    public update(color?: Color4 | Color3) {
+        if (color) {
+            this._div.style.backgroundColor = this._toRgba(color);
+            this._input.value = color.toHexString();
         }
+    }
 
-        private _toRgba(color:BABYLON.Color4|BABYLON.Color3) : string {
-            if (color) {
-                let r = (color.r * 255) | 0;
-                let g = (color.g * 255) | 0;
-                let b = (color.b * 255) | 0;
-                let a = 1;
-                if (color instanceof BABYLON.Color4) {
-                    a = (color as BABYLON.Color4).a;
-                }
-                return `rgba(${r}, ${g}, ${b}, ${a})`;
-            } else {
-                return '';
+    private _toRgba(color: Color4 | Color3): string {
+        if (color) {
+            let r = (color.r * 255) | 0;
+            let g = (color.g * 255) | 0;
+            let b = (color.b * 255) | 0;
+            let a = 1;
+            if (color instanceof Color4) {
+                a = (color as Color4).a;
             }
+            return `rgba(${r}, ${g}, ${b}, ${a})`;
+        } else {
+            return '';
         }
     }
-}
+}

+ 110 - 108
inspector/src/gui/CubeTextureElement.ts

@@ -1,119 +1,121 @@
- module INSPECTOR {
-     /**
-     * Display a very small div. A new canvas is created, with a new Babylon.js scene, containing only the 
-     * cube texture in a cube
-     */
-    export class CubeTextureElement extends BasicElement{
-
-        /** The big div displaying the full image */
-        private _textureDiv: HTMLElement;
-        
-        private _engine    : BABYLON.Engine;
-        protected _scene     : BABYLON.Scene;
-        protected _cube      : BABYLON.Mesh;
-        private _canvas    : HTMLCanvasElement;
-        protected _textureUrl: string;
-        
-        // On pause the engine will not render anything
-        private _pause     : boolean = false;
-            
-        /** The texture given as a parameter should be cube. */
-        constructor(tex : BABYLON.Texture) {
-            super();
-            this._div.className    = 'fa fa-search texture-element';
-            
-            // Create the texture viewer
-            this._textureDiv       = Helpers.CreateDiv('texture-viewer', this._div);
-            // canvas
-            this._canvas             = Helpers.CreateElement('canvas', 'texture-viewer-img', this._textureDiv) as HTMLCanvasElement;
-            
-            if (tex) {
-                this._textureUrl = tex.name;
-            }
+import { BasicElement } from "./BasicElement";
+import { Engine, Scene, Mesh, Texture, CubeTexture, StandardMaterial, Color4 } from "babylonjs";
+import { Helpers } from "../helpers/Helpers";
 
-            this._div.addEventListener('mouseover', this._showViewer.bind(this, 'flex'));
-            this._div.addEventListener('mouseout', this._showViewer.bind(this, 'none')); 
+/**
+* Display a very small div. A new canvas is created, with a new js scene, containing only the 
+* cube texture in a cube
+*/
+export class CubeTextureElement extends BasicElement {
 
-        }
-        
-        public update(tex?:BABYLON.Texture) {
-            if (tex && tex.url === this._textureUrl) {
-                // Nothing to do, as the old texture is the same as the old one
-            } else {                    
-                if (tex) {
-                    this._textureUrl = tex.name;
-                }
-                if (this._engine) {
-                    // Dispose old material and cube
-                    if (this._cube.material) {
-                        this._cube.material.dispose(true, true);
-                    }
-                    this._cube.dispose();
-                } else {
-                    this._initEngine();
-                }
-                // and create it again
-                this._populateScene();
-            }       
-        }
-        
-        /** Creates the box  */
-        protected _populateScene() {
-            // Create the hdr texture
-            let hdrTexture                      = new BABYLON.CubeTexture(this._textureUrl, this._scene);
-            hdrTexture.coordinatesMode          = BABYLON.Texture.SKYBOX_MODE;
-            
-            this._cube                          = BABYLON.Mesh.CreateBox("hdrSkyBox", 10.0, this._scene);
-            let hdrSkyboxMaterial               = new BABYLON.StandardMaterial("skyBox", this._scene);
-            hdrSkyboxMaterial.backFaceCulling   = false;
-            hdrSkyboxMaterial.reflectionTexture = hdrTexture;
-            hdrSkyboxMaterial.reflectionTexture.coordinatesMode = BABYLON.Texture.SKYBOX_MODE;        
-            hdrSkyboxMaterial.disableLighting   = true;
-            this._cube.material                 = hdrSkyboxMaterial;
-            this._cube.registerBeforeRender(() => {
-                this._cube.rotation.y += 0.01;
-            })
-        }
-        
-        /** Init the babylon engine */
-        private _initEngine() {
-            this._engine           = new BABYLON.Engine(this._canvas);
-            this._scene            = new BABYLON.Scene(this._engine);
-            this._scene.clearColor = new BABYLON.Color4(0,0,0, 0);
-            
-            this._engine.runRenderLoop(() => {
-                if (!this._pause) {
-                    this._scene.render();
-                }
-            });
-            
-            this._canvas.setAttribute('width', '110');
-            this._canvas.setAttribute('height', '110');
+    /** The big div displaying the full image */
+    private _textureDiv: HTMLElement;
+
+    private _engine: Engine;
+    protected _scene: Scene;
+    protected _cube: Mesh;
+    private _canvas: HTMLCanvasElement;
+    protected _textureUrl: string;
+
+    // On pause the engine will not render anything
+    private _pause: boolean = false;
+
+    /** The texture given as a parameter should be cube. */
+    constructor(tex: Texture) {
+        super();
+        this._div.className = 'fa fa-search texture-element';
+
+        // Create the texture viewer
+        this._textureDiv = Helpers.CreateDiv('texture-viewer', this._div);
+        // canvas
+        this._canvas = Helpers.CreateElement('canvas', 'texture-viewer-img', this._textureDiv) as HTMLCanvasElement;
+
+        if (tex) {
+            this._textureUrl = tex.name;
         }
 
-        private _showViewer(mode:string) {
-            // If displaying...
-            if (mode != 'none') {
-                // ... and the canvas is not initialized                
-                if (!this._engine) {
-                    this._initEngine();
-                    this._populateScene();
+        this._div.addEventListener('mouseover', this._showViewer.bind(this, 'flex'));
+        this._div.addEventListener('mouseout', this._showViewer.bind(this, 'none'));
+
+    }
+
+    public update(tex?: Texture) {
+        if (tex && tex.url === this._textureUrl) {
+            // Nothing to do, as the old texture is the same as the old one
+        } else {
+            if (tex) {
+                this._textureUrl = tex.name;
+            }
+            if (this._engine) {
+                // Dispose old material and cube
+                if (this._cube.material) {
+                    this._cube.material.dispose(true, true);
                 }
-                // In every cases, unpause the engine
-                this._pause = false;
+                this._cube.dispose();
             } else {
-                // hide : pause the engine
-                this._pause = true;
+                this._initEngine();
             }
-            this._textureDiv.style.display = mode;
+            // and create it again
+            this._populateScene();
         }
-        
-        /** Removes properly the babylon engine */
-        public dispose () {
-            if (this._engine) {
-                this._engine.dispose();
-                (<any>this._engine) = null;
+    }
+
+    /** Creates the box  */
+    protected _populateScene() {
+        // Create the hdr texture
+        let hdrTexture = new CubeTexture(this._textureUrl, this._scene);
+        hdrTexture.coordinatesMode = Texture.SKYBOX_MODE;
+
+        this._cube = Mesh.CreateBox("hdrSkyBox", 10.0, this._scene);
+        let hdrSkyboxMaterial = new StandardMaterial("skyBox", this._scene);
+        hdrSkyboxMaterial.backFaceCulling = false;
+        hdrSkyboxMaterial.reflectionTexture = hdrTexture;
+        hdrSkyboxMaterial.reflectionTexture.coordinatesMode = Texture.SKYBOX_MODE;
+        hdrSkyboxMaterial.disableLighting = true;
+        this._cube.material = hdrSkyboxMaterial;
+        this._cube.registerBeforeRender(() => {
+            this._cube.rotation.y += 0.01;
+        })
+    }
+
+    /** Init the babylon engine */
+    private _initEngine() {
+        this._engine = new Engine(this._canvas);
+        this._scene = new Scene(this._engine);
+        this._scene.clearColor = new Color4(0, 0, 0, 0);
+
+        this._engine.runRenderLoop(() => {
+            if (!this._pause) {
+                this._scene.render();
             }
+        });
+
+        this._canvas.setAttribute('width', '110');
+        this._canvas.setAttribute('height', '110');
+    }
+
+    private _showViewer(mode: string) {
+        // If displaying...
+        if (mode != 'none') {
+            // ... and the canvas is not initialized                
+            if (!this._engine) {
+                this._initEngine();
+                this._populateScene();
+            }
+            // In every cases, unpause the engine
+            this._pause = false;
+        } else {
+            // hide : pause the engine
+            this._pause = true;
+        }
+        this._textureDiv.style.display = mode;
+    }
+
+    /** Removes properly the babylon engine */
+    public dispose() {
+        if (this._engine) {
+            this._engine.dispose();
+            (<any>this._engine) = null;
         }
     }
- }
+}

+ 31 - 30
inspector/src/gui/HDRCubeTextureElement.ts

@@ -1,32 +1,33 @@
- module INSPECTOR {
-     /**
-     * Display a very small div. A new canvas is created, with a new Babylon.js scene, containing only the 
-     * cube texture in a cube
-     */
-    export class HDRCubeTextureElement extends CubeTextureElement{
+import { CubeTextureElement } from "./CubeTextureElement";
+import { Texture, HDRCubeTexture, Mesh, PBRMaterial } from "babylonjs";
 
-            
-        /** The texture given as a parameter should be cube. */
-        constructor(tex : BABYLON.Texture) {
-            super(tex);
-        }
-        
-        /** Creates the box  */
-        protected _populateScene() {
-            // Create the hdr texture
-            let hdrTexture                      = new BABYLON.HDRCubeTexture(this._textureUrl, this._scene, 512);
-            hdrTexture.coordinatesMode          = BABYLON.Texture.SKYBOX_MODE;
-            
-            this._cube                          = BABYLON.Mesh.CreateBox("hdrSkyBox", 10.0, this._scene);
-            let hdrSkyboxMaterial               = new BABYLON.PBRMaterial("skyBox", this._scene);
-            hdrSkyboxMaterial.backFaceCulling   = false;
-            hdrSkyboxMaterial.reflectionTexture = hdrTexture;
-            hdrSkyboxMaterial.microSurface      = 1.0;
-            hdrSkyboxMaterial.disableLighting   = true;
-            this._cube.material                 = hdrSkyboxMaterial;
-            this._cube.registerBeforeRender(() => {
-                this._cube.rotation.y += 0.01;
-            })
-        }        
+/**
+* Display a very small div. A new canvas is created, with a new js scene, containing only the 
+* cube texture in a cube
+*/
+export class HDRCubeTextureElement extends CubeTextureElement {
+
+
+    /** The texture given as a parameter should be cube. */
+    constructor(tex: Texture) {
+        super(tex);
+    }
+
+    /** Creates the box  */
+    protected _populateScene() {
+        // Create the hdr texture
+        let hdrTexture = new HDRCubeTexture(this._textureUrl, this._scene, 512);
+        hdrTexture.coordinatesMode = Texture.SKYBOX_MODE;
+
+        this._cube = Mesh.CreateBox("hdrSkyBox", 10.0, this._scene);
+        let hdrSkyboxMaterial = new PBRMaterial("skyBox", this._scene);
+        hdrSkyboxMaterial.backFaceCulling = false;
+        hdrSkyboxMaterial.reflectionTexture = hdrTexture;
+        hdrSkyboxMaterial.microSurface = 1.0;
+        hdrSkyboxMaterial.disableLighting = true;
+        this._cube.material = hdrSkyboxMaterial;
+        this._cube.registerBeforeRender(() => {
+            this._cube.rotation.y += 0.01;
+        })
     }
- }
+}

+ 76 - 73
inspector/src/gui/SearchBar.ts

@@ -1,78 +1,81 @@
-module INSPECTOR {
-
-    /**
-     * A search bar can be used to filter elements in the tree panel.
-     * At each keypress on the input, the treepanel will be filtered.
-     */
-    export class SearchBar extends BasicElement {
-
-        private _propTab   : PropertyTab;
-        private _inputElement: HTMLInputElement;
-
-        constructor(tab:PropertyTab) {
-            super();
-            this._propTab = tab;
-            this._div.classList.add('searchbar');
-            
-            let filter = Inspector.DOCUMENT.createElement('i');
-            filter.className = 'fa fa-search';
-            
-            this._div.appendChild(filter);
-            // Create input
-            this._inputElement = Inspector.DOCUMENT.createElement('input');
-            this._inputElement.placeholder = 'Filter by name...';
-            this._div.appendChild(this._inputElement);
-            
-            this._inputElement.addEventListener('keyup', (evt : KeyboardEvent)=> {
-                let filter = this._inputElement.value;
-                this._propTab.filter(filter);
-            })
-        }
-
-        /** Delete all characters typped in the input element */
-        public reset() {
-            this._inputElement.value = '';
-        }
-
-        public update() {
-            // Nothing to update
-        }
+import { BasicElement } from "./BasicElement";
+import { PropertyTab } from "../tabs/PropertyTab";
+import { Inspector } from "../Inspector";
+import { DetailPanel } from "../details/DetailPanel";
 
+
+/**
+ * A search bar can be used to filter elements in the tree panel.
+ * At each keypress on the input, the treepanel will be filtered.
+ */
+export class SearchBar extends BasicElement {
+
+    private _propTab: PropertyTab;
+    private _inputElement: HTMLInputElement;
+
+    constructor(tab: PropertyTab) {
+        super();
+        this._propTab = tab;
+        this._div.classList.add('searchbar');
+
+        let filter = Inspector.DOCUMENT.createElement('i');
+        filter.className = 'fa fa-search';
+
+        this._div.appendChild(filter);
+        // Create input
+        this._inputElement = Inspector.DOCUMENT.createElement('input');
+        this._inputElement.placeholder = 'Filter by name...';
+        this._div.appendChild(this._inputElement);
+
+        this._inputElement.addEventListener('keyup', (evt: KeyboardEvent) => {
+            let filter = this._inputElement.value;
+            this._propTab.filter(filter);
+        })
+    }
+
+    /** Delete all characters typped in the input element */
+    public reset() {
+        this._inputElement.value = '';
+    }
+
+    public update() {
+        // Nothing to update
     }
 
-    export class SearchBarDetails extends BasicElement {
-
-        private _detailTab  : DetailPanel;
-        private _inputElement: HTMLInputElement;
-
-        constructor(tab:DetailPanel) {
-            super();
-            this._detailTab = tab;
-            this._div.classList.add('searchbar');
-            
-            let filter = Inspector.DOCUMENT.createElement('i');
-            filter.className = 'fa fa-search';
-            
-            this._div.appendChild(filter);
-            // Create input
-            this._inputElement = Inspector.DOCUMENT.createElement('input');
-            this._inputElement.placeholder = 'Filter by name...';
-            this._div.appendChild(this._inputElement);
-            
-            this._inputElement.addEventListener('keyup', (evt : KeyboardEvent)=> {
-                let filter = this._inputElement.value;
-                this._detailTab.searchByName(filter);
-            })
-        }
-
-        /** Delete all characters typped in the input element */
-        public reset() {
-            this._inputElement.value = '';
-        }
-
-        public update() {
-            // Nothing to update
-        }
+}
 
+export class SearchBarDetails extends BasicElement {
+
+    private _detailTab: DetailPanel;
+    private _inputElement: HTMLInputElement;
+
+    constructor(tab: DetailPanel) {
+        super();
+        this._detailTab = tab;
+        this._div.classList.add('searchbar');
+
+        let filter = Inspector.DOCUMENT.createElement('i');
+        filter.className = 'fa fa-search';
+
+        this._div.appendChild(filter);
+        // Create input
+        this._inputElement = Inspector.DOCUMENT.createElement('input');
+        this._inputElement.placeholder = 'Filter by name...';
+        this._div.appendChild(this._inputElement);
+
+        this._inputElement.addEventListener('keyup', (evt: KeyboardEvent) => {
+            let filter = this._inputElement.value;
+            this._detailTab.searchByName(filter);
+        })
     }
-}
+
+    /** Delete all characters typped in the input element */
+    public reset() {
+        this._inputElement.value = '';
+    }
+
+    public update() {
+        // Nothing to update
+    }
+
+}

+ 40 - 38
inspector/src/gui/TextureElement.ts

@@ -1,42 +1,44 @@
- module INSPECTOR {
-     /**
-     * Display a very small div corresponding to the given texture. On mouse over, display the full image
-     */
-    export class TextureElement extends BasicElement{
-
-        /** The big div displaying the full image */
-        private _textureDiv : HTMLElement;
-            
-        constructor(tex : BABYLON.Texture) {
-            super();
-            this._div.className = 'fa fa-search texture-element';
-
-            // Create the texture viewer
-            this._textureDiv = Helpers.CreateDiv('texture-viewer', this._div);
-            // Img
-            let imgDiv = Helpers.CreateDiv('texture-viewer-img', this._textureDiv);
-
-            // Texture size
-            let sizeDiv = Helpers.CreateDiv(null, this._textureDiv);
-            
-            if (tex) {
-                sizeDiv.textContent = `${tex.getBaseSize().width}px x ${tex.getBaseSize().height}px`;
-                imgDiv.style.backgroundImage = `url('${tex.url}')`;     
-                imgDiv.style.width = `${tex.getBaseSize().width}px`;
-                imgDiv.style.height = `${tex.getBaseSize().height}px`;
-            }
-
-            this._div.addEventListener('mouseover', this._showViewer.bind(this, 'flex'));
-            this._div.addEventListener('mouseout', this._showViewer.bind(this, 'none')); 
+import { BasicElement } from "./BasicElement";
+import { Texture } from "babylonjs";
+import { Helpers } from "../helpers/Helpers";
 
-        }
-        
-        public update(tex?:BABYLON.Texture) {
-            
-        }
+/**
+* Display a very small div corresponding to the given texture. On mouse over, display the full image
+*/
+export class TextureElement extends BasicElement {
+
+    /** The big div displaying the full image */
+    private _textureDiv: HTMLElement;
+
+    constructor(tex: Texture) {
+        super();
+        this._div.className = 'fa fa-search texture-element';
 
-        private _showViewer(mode:string) {
-            this._textureDiv.style.display = mode;
+        // Create the texture viewer
+        this._textureDiv = Helpers.CreateDiv('texture-viewer', this._div);
+        // Img
+        let imgDiv = Helpers.CreateDiv('texture-viewer-img', this._textureDiv);
+
+        // Texture size
+        let sizeDiv = Helpers.CreateDiv(null, this._textureDiv);
+
+        if (tex) {
+            sizeDiv.textContent = `${tex.getBaseSize().width}px x ${tex.getBaseSize().height}px`;
+            imgDiv.style.backgroundImage = `url('${tex.url}')`;
+            imgDiv.style.width = `${tex.getBaseSize().width}px`;
+            imgDiv.style.height = `${tex.getBaseSize().height}px`;
         }
+
+        this._div.addEventListener('mouseover', this._showViewer.bind(this, 'flex'));
+        this._div.addEventListener('mouseout', this._showViewer.bind(this, 'none'));
+
+    }
+
+    public update(tex?: Texture) {
+
+    }
+
+    private _showViewer(mode: string) {
+        this._textureDiv.style.display = mode;
     }
- }
+}

+ 29 - 28
inspector/src/gui/Tooltip.ts

@@ -1,30 +1,31 @@
-module INSPECTOR {
-    
-    /**
-     * Creates a tooltip for the parent of the given html element
-     */
-    export class Tooltip {
-        
-        /** The tooltip is displayed for this element */
-        private _elem : HTMLElement;
-        
-        /** The tooltip div */
-        private _infoDiv : HTMLDivElement;
-        
-        constructor(elem: HTMLElement, tip:string, attachTo: BABYLON.Nullable<HTMLElement> = null) {
-            
-            this._elem = elem;
-            if (!attachTo) {
-                attachTo = this._elem.parentElement;
-            }
-            this._infoDiv = Helpers.CreateDiv('tooltip', <HTMLElement>attachTo) as HTMLDivElement;
-            
-
-            this._elem.addEventListener('mouseover', () => { 
-                this._infoDiv.textContent = tip;
-                this._infoDiv.style.display = 'block'
-            });
-            this._elem.addEventListener('mouseout', () => { this._infoDiv.style.display = 'none'});
+import { Nullable } from "babylonjs";
+import { Helpers } from "../helpers/Helpers";
+
+
+/**
+ * Creates a tooltip for the parent of the given html element
+ */
+export class Tooltip {
+
+    /** The tooltip is displayed for this element */
+    private _elem: HTMLElement;
+
+    /** The tooltip div */
+    private _infoDiv: HTMLDivElement;
+
+    constructor(elem: HTMLElement, tip: string, attachTo: Nullable<HTMLElement> = null) {
+
+        this._elem = elem;
+        if (!attachTo) {
+            attachTo = this._elem.parentElement;
         }
+        this._infoDiv = Helpers.CreateDiv('tooltip', <HTMLElement>attachTo) as HTMLDivElement;
+
+
+        this._elem.addEventListener('mouseover', () => {
+            this._infoDiv.textContent = tip;
+            this._infoDiv.style.display = 'block'
+        });
+        this._elem.addEventListener('mouseout', () => { this._infoDiv.style.display = 'none' });
     }
-}
+}

+ 190 - 186
inspector/src/helpers/Helpers.ts

@@ -1,227 +1,231 @@
-module INSPECTOR {
-    export class Helpers {
-
-
-        /** 
-         * Returns the type of the given object. First
-         * uses getClassName. If nothing is returned, used the type of the constructor
-         */
-        public static GET_TYPE(obj: any): string {
-            if (typeof obj === 'boolean') {
-                return 'boolean';
-            }
-
-            if (obj != null && obj != undefined) {
-                let classname = BABYLON.Tools.GetClassName(obj);
-                if (!classname || classname === 'object') {
-                    classname = obj.constructor.name;
-                    // classname is undefined in IE11
-                    if (!classname) {
-                        classname = this._GetFnName(obj.constructor);
-                    }
-                }
-                // If the class name has no matching properties, check every type
-                if (!this._CheckIfTypeExists(classname)) {
-                    return this._GetTypeFor(obj);
+import { Tools, Nullable } from "babylonjs";
+import { PROPERTIES } from "../properties";
+import { Inspector } from "../Inspector";
+import { PropertyLine } from "../details/PropertyLine";
+import { Property } from "../details/Property";
+
+export class Helpers {
+
+
+    /** 
+     * Returns the type of the given object. First
+     * uses getClassName. If nothing is returned, used the type of the constructor
+     */
+    public static GET_TYPE(obj: any): string {
+        if (typeof obj === 'boolean') {
+            return 'boolean';
+        }
+
+        if (obj != null && obj != undefined) {
+            let classname = Tools.GetClassName(obj);
+            if (!classname || classname === 'object') {
+                classname = obj.constructor.name;
+                // classname is undefined in IE11
+                if (!classname) {
+                    classname = this._GetFnName(obj.constructor);
                 }
+            }
+            // If the class name has no matching properties, check every type
+            if (!this._CheckIfTypeExists(classname)) {
+                return this._GetTypeFor(obj);
+            }
 
-                return classname;
-            } else {
+            return classname;
+        } else {
 
-                return 'type_not_defined';
-            }
+            return 'type_not_defined';
         }
+    }
 
-        /**
-         * Check if some properties are defined for the given type.
-         */
-        private static _CheckIfTypeExists(type: string) {
-            let properties = (<any>PROPERTIES)[type];
-            if (properties) {
-                return true;
-            }
-            return false;
+    /**
+     * Check if some properties are defined for the given type.
+     */
+    private static _CheckIfTypeExists(type: string) {
+        let properties = (<any>PROPERTIES)[type];
+        if (properties) {
+            return true;
         }
+        return false;
+    }
 
-        /**
-         * Returns true if the user browser is edge.
-         */
-        public static IsBrowserEdge(): boolean {
-            var regexp = /Edge/
-            return regexp.test(navigator.userAgent);
-        }
-        /**
-         * Returns true if the user browser is IE.
-         */
-        public static IsBrowserIE(): boolean {
-            var regexp = /Trident.*rv\:11\./
-            return regexp.test(navigator.userAgent);
-        }
+    /**
+     * Returns true if the user browser is edge.
+     */
+    public static IsBrowserEdge(): boolean {
+        var regexp = /Edge/
+        return regexp.test(navigator.userAgent);
+    }
+    /**
+     * Returns true if the user browser is IE.
+     */
+    public static IsBrowserIE(): boolean {
+        var regexp = /Trident.*rv\:11\./
+        return regexp.test(navigator.userAgent);
+    }
 
-        /** 
-         * Returns the name of the type of the given object, where the name 
-         * is in PROPERTIES constant.
-         * Returns 'Undefined' if no type exists for this object
-         */
-        private static _GetTypeFor(obj: any) {
-            for (let type in PROPERTIES) {
-                let typeBlock = (<any>PROPERTIES)[type];
-                if (typeBlock.type) {
-                    if (obj instanceof typeBlock.type) {
-                        return type;
-                    }
+    /** 
+     * Returns the name of the type of the given object, where the name 
+     * is in PROPERTIES constant.
+     * Returns 'Undefined' if no type exists for this object
+     */
+    private static _GetTypeFor(obj: any) {
+        for (let type in PROPERTIES) {
+            let typeBlock = (<any>PROPERTIES)[type];
+            if (typeBlock.type) {
+                if (obj instanceof typeBlock.type) {
+                    return type;
                 }
             }
-            return 'type_not_defined';
-        }
-        /**
-         * Returns the name of a function (workaround to get object type for IE11)
-         */
-        private static _GetFnName(fn: any) {
-            var f = typeof fn == 'function';
-            var s = f && ((fn.name && ['', fn.name]) || fn.toString().match(/function ([^\(]+)/));
-            return (!f && 'not a function') || (s && s[1] || 'anonymous');
         }
+        return 'type_not_defined';
+    }
+    /**
+     * Returns the name of a function (workaround to get object type for IE11)
+     */
+    private static _GetFnName(fn: any) {
+        var f = typeof fn == 'function';
+        var s = f && ((fn.name && ['', fn.name]) || fn.toString().match(/function ([^\(]+)/));
+        return (!f && 'not a function') || (s && s[1] || 'anonymous');
+    }
 
-        /** Send the event which name is given in parameter to the window */
-        public static SEND_EVENT(eventName: string) {
-            let event;
-            if (Inspector.DOCUMENT.createEvent) {
-                event = Inspector.DOCUMENT.createEvent('HTMLEvents');
-                event.initEvent(eventName, true, true);
-            } else {
-                event = new Event(eventName);
-            }
-            window.dispatchEvent(event);
+    /** Send the event which name is given in parameter to the window */
+    public static SEND_EVENT(eventName: string) {
+        let event;
+        if (Inspector.DOCUMENT.createEvent) {
+            event = Inspector.DOCUMENT.createEvent('HTMLEvents');
+            event.initEvent(eventName, true, true);
+        } else {
+            event = new Event(eventName);
         }
+        window.dispatchEvent(event);
+    }
 
-        /** Returns the given number with 2 decimal number max if a decimal part exists */
-        public static Trunc(nb: number): number {
-            if (typeof nb !== 'number') {
-                return 0;
-            }
-            if (Math.round(nb) !== nb) {
-                return (<any>nb.toFixed(2));
-            }
-            return nb;
-        };
-
-        /**
-         * Useful function used to create a div
-         */
-        public static CreateDiv(className: BABYLON.Nullable<string> = null, parent?: HTMLElement): HTMLElement {
-            return Helpers.CreateElement('div', className, parent);
+    /** Returns the given number with 2 decimal number max if a decimal part exists */
+    public static Trunc(nb: number): number {
+        if (typeof nb !== 'number') {
+            return 0;
         }
-
-        /**
-         * Useful function used to create a input
-         */
-        public static CreateInput(className?: string, parent?: HTMLElement): HTMLInputElement {
-            return <HTMLInputElement>Helpers.CreateElement('input', className, parent);
+        if (Math.round(nb) !== nb) {
+            return (<any>nb.toFixed(2));
         }
+        return nb;
+    };
 
-        public static CreateElement(element: string, className: BABYLON.Nullable<string> = null, parent?: HTMLElement): HTMLElement {
-            let elem = Inspector.DOCUMENT.createElement(element);
+    /**
+     * Useful function used to create a div
+     */
+    public static CreateDiv(className: Nullable<string> = null, parent?: HTMLElement): HTMLElement {
+        return Helpers.CreateElement('div', className, parent);
+    }
 
-            if (className) {
-                elem.className = className;
-            }
-            if (parent) {
-                parent.appendChild(elem);
-            }
-            return elem;
-        }
+    /**
+     * Useful function used to create a input
+     */
+    public static CreateInput(className?: string, parent?: HTMLElement): HTMLInputElement {
+        return <HTMLInputElement>Helpers.CreateElement('input', className, parent);
+    }
 
-        /**
-         * Removes all children of the given div.
-         */
-        public static CleanDiv(div: HTMLElement) {
-            while (div.firstChild) {
-                div.removeChild(div.firstChild);
-            }
+    public static CreateElement(element: string, className: Nullable<string> = null, parent?: HTMLElement): HTMLElement {
+        let elem = Inspector.DOCUMENT.createElement(element);
+
+        if (className) {
+            elem.className = className;
+        }
+        if (parent) {
+            parent.appendChild(elem);
         }
+        return elem;
+    }
 
-        /**
-         * Returns the true value of the given CSS Attribute from the given element (in percentage or in pixel, as it was specified in the css)
-         */
-        public static Css(elem: HTMLElement, cssAttribute: string): string {
-            let clone = elem.cloneNode(true) as HTMLElement;
-            let div = Helpers.CreateDiv('', Inspector.DOCUMENT.body);
-            div.style.display = 'none';
-            div.appendChild(clone);
-            let value = (<any>Inspector.WINDOW.getComputedStyle(clone))[cssAttribute];
-            if (div.parentNode) {
-                div.parentNode.removeChild(div);
-            }
-            return value;
+    /**
+     * Removes all children of the given div.
+     */
+    public static CleanDiv(div: HTMLElement) {
+        while (div.firstChild) {
+            div.removeChild(div.firstChild);
         }
+    }
+
+    /**
+     * Returns the true value of the given CSS Attribute from the given element (in percentage or in pixel, as it was specified in the css)
+     */
+    public static Css(elem: HTMLElement, cssAttribute: string): string {
+        let clone = elem.cloneNode(true) as HTMLElement;
+        let div = Helpers.CreateDiv('', Inspector.DOCUMENT.body);
+        div.style.display = 'none';
+        div.appendChild(clone);
+        let value = (<any>Inspector.WINDOW.getComputedStyle(clone))[cssAttribute];
+        if (div.parentNode) {
+            div.parentNode.removeChild(div);
+        }
+        return value;
+    }
+
+    public static LoadScript() {
+        Tools.LoadFile("https://cdnjs.cloudflare.com/ajax/libs/highlight.js/9.7.0/highlight.min.js", (elem) => {
+            let script = Helpers.CreateElement('script', '', Inspector.DOCUMENT.body);
+            script.textContent = elem as string;
 
-        public static LoadScript() {
-            BABYLON.Tools.LoadFile("https://cdnjs.cloudflare.com/ajax/libs/highlight.js/9.7.0/highlight.min.js", (elem) => {
+            // Load glsl detection
+            Tools.LoadFile("https://cdnjs.cloudflare.com/ajax/libs/highlight.js/9.7.0/languages/glsl.min.js", (elem) => {
                 let script = Helpers.CreateElement('script', '', Inspector.DOCUMENT.body);
                 script.textContent = elem as string;
 
-                // Load glsl detection
-                BABYLON.Tools.LoadFile("https://cdnjs.cloudflare.com/ajax/libs/highlight.js/9.7.0/languages/glsl.min.js", (elem) => {
-                    let script = Helpers.CreateElement('script', '', Inspector.DOCUMENT.body);
-                    script.textContent = elem as string;
-
-                    // Load css style
-                    BABYLON.Tools.LoadFile("https://cdnjs.cloudflare.com/ajax/libs/highlight.js/9.7.0/styles/zenburn.min.css", (elem) => {
-                        let style = Helpers.CreateElement('style', '', Inspector.DOCUMENT.body);
-                        style.textContent = elem as string;
-                    });
-                }, undefined, undefined, undefined, () => {
-                    console.log('Error : LoadFile "glsl.min.js"');
+                // Load css style
+                Tools.LoadFile("https://cdnjs.cloudflare.com/ajax/libs/highlight.js/9.7.0/styles/zenburn.min.css", (elem) => {
+                    let style = Helpers.CreateElement('style', '', Inspector.DOCUMENT.body);
+                    style.textContent = elem as string;
                 });
-
             }, undefined, undefined, undefined, () => {
-                console.log('Error : LoadFile "highlight.min.js"')
+                console.log('Error : LoadFile "glsl.min.js"');
             });
 
-        }
+        }, undefined, undefined, undefined, () => {
+            console.log('Error : LoadFile "highlight.min.js"')
+        });
 
-        public static IsSystemName(name: string): boolean {
-            if (name == null) {
-                return false;
-            }
-            return name.indexOf("###") === 0 && name.lastIndexOf("###") === (name.length - 3);
+    }
+
+    public static IsSystemName(name: string): boolean {
+        if (name == null) {
+            return false;
         }
+        return name.indexOf("###") === 0 && name.lastIndexOf("###") === (name.length - 3);
+    }
 
-        /**
-         * Return an array of PropertyLine for an obj
-         * @param obj 
-         */
-        public static GetAllLinesProperties(obj: any): Array<PropertyLine> {
-            let propertiesLines: Array<PropertyLine> = [];
-            let props = Helpers.GetAllLinesPropertiesAsString(obj);
-
-            for (let prop of props) {
-                let infos = new Property(prop, obj);
-                propertiesLines.push(new PropertyLine(infos));
-            }
-            return propertiesLines;
+    /**
+     * Return an array of PropertyLine for an obj
+     * @param obj 
+     */
+    public static GetAllLinesProperties(obj: any): Array<PropertyLine> {
+        let propertiesLines: Array<PropertyLine> = [];
+        let props = Helpers.GetAllLinesPropertiesAsString(obj);
+
+        for (let prop of props) {
+            let infos = new Property(prop, obj);
+            propertiesLines.push(new PropertyLine(infos));
         }
+        return propertiesLines;
+    }
 
 
-        /**
-         * Returns an array of string corresponding to tjhe list of properties of the object to be displayed
-         * @param obj 
-         */
-        public static GetAllLinesPropertiesAsString(obj: any, dontTakeThis: Array<string> = []): Array<string> {
-            let props: Array<string> = [];
+    /**
+     * Returns an array of string corresponding to tjhe list of properties of the object to be displayed
+     * @param obj 
+     */
+    public static GetAllLinesPropertiesAsString(obj: any, dontTakeThis: Array<string> = []): Array<string> {
+        let props: Array<string> = [];
 
-            for (let prop in obj) {
-                //No private and no function
-                if (dontTakeThis.indexOf(prop) === -1 && prop.substring(0, 1) !== '_' && typeof obj[prop] !== 'function') {
-                    props.push(prop);
-                }
+        for (let prop in obj) {
+            //No private and no function
+            if (dontTakeThis.indexOf(prop) === -1 && prop.substring(0, 1) !== '_' && typeof obj[prop] !== 'function') {
+                props.push(prop);
             }
-            return props;
         }
+        return props;
+    }
 
-        public static Capitalize(str: string): string {
-            return str.charAt(0).toUpperCase() + str.slice(1);
-        }
+    public static Capitalize(str: string): string {
+        return str.charAt(0).toUpperCase() + str.slice(1);
     }
-}
+}

+ 126 - 128
inspector/src/properties.ts

@@ -1,132 +1,130 @@
-/// <reference path="../../dist/preview release/babylon.d.ts"/>
+import { Helpers } from "./helpers/Helpers";
+import { Vector2, Vector3, Color3, Color4, Quaternion, Size, Texture, RenderTargetTexture, DynamicTexture, BaseTexture, CubeTexture, HDRCubeTexture, Sound, ArcRotateCamera, FreeCamera, Scene, TransformNode, AbstractMesh, Mesh, StandardMaterial, PBRMaterial, PhysicsImpostor, ImageProcessingConfiguration, ColorCurves } from "babylonjs";
 
-module INSPECTOR {
 
-    export var PROPERTIES = {
-        /** Format the given object : 
-         * If a format function exists, returns the result of this function.
-         * If this function doesn't exists, return the object type instead */
-        format: (obj: any): any => {
-            let type = Helpers.GET_TYPE(obj) || 'type_not_defined';
-            if ((<any>PROPERTIES)[type] && (<any>PROPERTIES)[type].format) {
-                return (<any>PROPERTIES)[type].format(obj);
-            } else {
-                return Helpers.GET_TYPE(obj);
-            }
-        },
-        'type_not_defined': {
-            properties: new Array(),
-            format: () => ''
-        },
-        'Vector2': {
-            type: BABYLON.Vector2,
-            format: (vec: BABYLON.Vector2) => { return `x:${Helpers.Trunc(vec.x)}, y:${Helpers.Trunc(vec.y)}`; }
-        },
-        'Vector3': {
-            type: BABYLON.Vector3,
-            format: (vec: BABYLON.Vector3) => { return `x:${Helpers.Trunc(vec.x)}, y:${Helpers.Trunc(vec.y)}, z:${Helpers.Trunc(vec.z)}` }
-        },
-        'Color3': {
-            type: BABYLON.Color3,
-            format: (color: BABYLON.Color3) => { return `R:${color.r.toPrecision(2)}, G:${color.g.toPrecision(2)}, B:${color.b.toPrecision(2)}` },
-            slider: {
-                r: { min: 0, max: 1, step: 0.01 },
-                g: { min: 0, max: 1, step: 0.01 },
-                b: { min: 0, max: 1, step: 0.01 }
-            }
-        },
-        'Color4': {
-            type: BABYLON.Color4,
-            format: (color: BABYLON.Color4) => { return `R:${color.r}, G:${color.g}, B:${color.b}` },
-            slider: {
-                r: { min: 0, max: 1, step: 0.01 },
-                g: { min: 0, max: 1, step: 0.01 },
-                b: { min: 0, max: 1, step: 0.01 }
-            }
-        },
-        'Quaternion': {
-            type: BABYLON.Quaternion
-        },
-        'Size': {
-            type: BABYLON.Size,
-            format: (size: BABYLON.Size) => { return `Size - w:${Helpers.Trunc(size.width)}, h:${Helpers.Trunc(size.height)}` }
-        },
-        'Texture': {
-            type: BABYLON.Texture,
-            format: (tex: BABYLON.Texture) => { return tex.name }
-        },
-        'RenderTargetTexture': {
-            type: BABYLON.RenderTargetTexture
-        },
-        'DynamicTexture': {
-            type: BABYLON.DynamicTexture
-        },
-        'BaseTexture': {
-            type: BABYLON.BaseTexture
-        },
-        'CubeTexture': {
-            type: BABYLON.CubeTexture
-        },
-        'HDRCubeTexture': {
-            type: BABYLON.HDRCubeTexture
-        },
-        'Sound': {
-            type: BABYLON.Sound
-        },
-        'ArcRotateCamera': {
-            type: BABYLON.ArcRotateCamera,
-            slider: {
-                alpha: { min: 0, max: 2 * Math.PI, step: 0.01 },
-                beta: { min: -Math.PI, max: Math.PI, step: 0.01 },
-                fov: { min: 0, max: 180, step: 1 }
-            }
-        },
-        'FreeCamera': {
-            type: BABYLON.FreeCamera,
-            slider: {
-                fov: { min: 0, max: 180, step: 1 }
-            }
-        },
-        'Scene': {
-            type: BABYLON.Scene,
-        },
-        'TransformNode': {
-            type: BABYLON.TransformNode,
-            format: (m: BABYLON.TransformNode): string => { return m.name; }
-        },        
-        'AbstractMesh': {
-            type: BABYLON.AbstractMesh,
-            format: (m: BABYLON.AbstractMesh): string => { return m.name; }
-        },          
-        'Mesh': {
-            type: BABYLON.Mesh,
-            format: (m: BABYLON.Mesh): string => { return m.name; },
-            slider: {
-                visibility: { min: 0, max: 1, step: 0.1 }
-            }
-        },
-        'StandardMaterial': {
-            type: BABYLON.StandardMaterial,
-            format: (mat: BABYLON.StandardMaterial): string => { return mat.name; },
-            slider: {
-                alpha: { min: 0, max: 1, step: 0.01 }
-            }
-        },
-        'PBRMaterial': {
-            type: BABYLON.PBRMaterial,
-            slider: {
-                alpha: { min: 0, max: 1, step: 0.01 }
-            }
-        },
-        'PhysicsImpostor': {
-            type: BABYLON.PhysicsImpostor
-        },
-        'ImageProcessingConfiguration': {
-            type: BABYLON.ImageProcessingConfiguration
-        },
-        'ColorCurves': {
-            type: BABYLON.ColorCurves
+export var PROPERTIES = {
+    /** Format the given object : 
+     * If a format function exists, returns the result of this function.
+     * If this function doesn't exists, return the object type instead */
+    format: (obj: any): any => {
+        let type = Helpers.GET_TYPE(obj) || 'type_not_defined';
+        if ((<any>PROPERTIES)[type] && (<any>PROPERTIES)[type].format) {
+            return (<any>PROPERTIES)[type].format(obj);
+        } else {
+            return Helpers.GET_TYPE(obj);
         }
+    },
+    'type_not_defined': {
+        properties: new Array(),
+        format: () => ''
+    },
+    'Vector2': {
+        type: Vector2,
+        format: (vec: Vector2) => { return `x:${Helpers.Trunc(vec.x)}, y:${Helpers.Trunc(vec.y)}`; }
+    },
+    'Vector3': {
+        type: Vector3,
+        format: (vec: Vector3) => { return `x:${Helpers.Trunc(vec.x)}, y:${Helpers.Trunc(vec.y)}, z:${Helpers.Trunc(vec.z)}` }
+    },
+    'Color3': {
+        type: Color3,
+        format: (color: Color3) => { return `R:${color.r.toPrecision(2)}, G:${color.g.toPrecision(2)}, B:${color.b.toPrecision(2)}` },
+        slider: {
+            r: { min: 0, max: 1, step: 0.01 },
+            g: { min: 0, max: 1, step: 0.01 },
+            b: { min: 0, max: 1, step: 0.01 }
+        }
+    },
+    'Color4': {
+        type: Color4,
+        format: (color: Color4) => { return `R:${color.r}, G:${color.g}, B:${color.b}` },
+        slider: {
+            r: { min: 0, max: 1, step: 0.01 },
+            g: { min: 0, max: 1, step: 0.01 },
+            b: { min: 0, max: 1, step: 0.01 }
+        }
+    },
+    'Quaternion': {
+        type: Quaternion
+    },
+    'Size': {
+        type: Size,
+        format: (size: Size) => { return `Size - w:${Helpers.Trunc(size.width)}, h:${Helpers.Trunc(size.height)}` }
+    },
+    'Texture': {
+        type: Texture,
+        format: (tex: Texture) => { return tex.name }
+    },
+    'RenderTargetTexture': {
+        type: RenderTargetTexture
+    },
+    'DynamicTexture': {
+        type: DynamicTexture
+    },
+    'BaseTexture': {
+        type: BaseTexture
+    },
+    'CubeTexture': {
+        type: CubeTexture
+    },
+    'HDRCubeTexture': {
+        type: HDRCubeTexture
+    },
+    'Sound': {
+        type: Sound
+    },
+    'ArcRotateCamera': {
+        type: ArcRotateCamera,
+        slider: {
+            alpha: { min: 0, max: 2 * Math.PI, step: 0.01 },
+            beta: { min: -Math.PI, max: Math.PI, step: 0.01 },
+            fov: { min: 0, max: 180, step: 1 }
+        }
+    },
+    'FreeCamera': {
+        type: FreeCamera,
+        slider: {
+            fov: { min: 0, max: 180, step: 1 }
+        }
+    },
+    'Scene': {
+        type: Scene,
+    },
+    'TransformNode': {
+        type: TransformNode,
+        format: (m: TransformNode): string => { return m.name; }
+    },
+    'AbstractMesh': {
+        type: AbstractMesh,
+        format: (m: AbstractMesh): string => { return m.name; }
+    },
+    'Mesh': {
+        type: Mesh,
+        format: (m: Mesh): string => { return m.name; },
+        slider: {
+            visibility: { min: 0, max: 1, step: 0.1 }
+        }
+    },
+    'StandardMaterial': {
+        type: StandardMaterial,
+        format: (mat: StandardMaterial): string => { return mat.name; },
+        slider: {
+            alpha: { min: 0, max: 1, step: 0.01 }
+        }
+    },
+    'PBRMaterial': {
+        type: PBRMaterial,
+        slider: {
+            alpha: { min: 0, max: 1, step: 0.01 }
+        }
+    },
+    'PhysicsImpostor': {
+        type: PhysicsImpostor
+    },
+    'ImageProcessingConfiguration': {
+        type: ImageProcessingConfiguration
+    },
+    'ColorCurves': {
+        type: ColorCurves
     }
-
-}
+}

+ 114 - 116
inspector/src/properties_gui.ts

@@ -1,118 +1,116 @@
-/// <reference path="../../dist/preview release/gui/babylon.gui.d.ts"/>
+import * as GUI from "babylonjs-gui";
+import { PROPERTIES } from "./properties";
 
-module INSPECTOR {
-    /**
-     * Function that add gui objects properties to the variable PROPERTIES
-     */
-    export function loadGUIProperties(){
-        let PROPERTIES_GUI = {
-            'ValueAndUnit': {
-                type: BABYLON.GUI.ValueAndUnit,
-                properties: ['_value', 'unit'],
-                format: (valueAndUnit: BABYLON.GUI.ValueAndUnit) => 
-                    { return valueAndUnit }
-            },
-            'Control': {
-                type: BABYLON.GUI.Control,
-                properties: [
-                    '_alpha',
-                    '_fontFamily',
-                    '_color',
-                    '_scaleX',
-                    '_scaleY',
-                    '_rotation',
-                    '_currentMeasure',
-                    '_width',
-                    '_height',
-                    '_left',
-                    '_top',
-                    '_linkedMesh',
-                    'isHitTestVisible',
-                    'isPointerBlocker',
-                ],
-                format: (control: BABYLON.GUI.Control) => { return control.name }
-            },
-            'Button': {
-                type: BABYLON.GUI.Button,
-                properties: new Array(),
-                format: (button: BABYLON.GUI.Button) => { return button.name }
-            },
-            'ColorPicker': {
-                type: BABYLON.GUI.ColorPicker,
-                properties: ['_value'],
-                format: (colorPicker: BABYLON.GUI.ColorPicker) => { return colorPicker.name }
-            },
-            'Checkbox': {
-                type: BABYLON.GUI.Checkbox,
-                properties: ['_isChecked', '_background'],
-                format: (checkbox: BABYLON.GUI.Checkbox) => { return checkbox.name }
-            },
-            'Ellipse': {
-                type: BABYLON.GUI.Ellipse,
-                properties: ['_thickness'],
-                format: (ellipse: BABYLON.GUI.Ellipse) => { return ellipse.name }
-            },
-            'Image': {
-                type: BABYLON.GUI.Image,
-                properties: [
-                    '_imageWidth', 
-                    '_imageHeight',
-                    '_loaded',
-                    '_source',
-                ],
-                format: (image: BABYLON.GUI.Image) => { return image.name }
-            },
-            'Line': {
-                type: BABYLON.GUI.Line,
-                properties: ['_lineWidth',
-                    '_background',
-                    '_x1',
-                    '_y1',
-                    '_x2',
-                    '_y2',
-                ],
-                format: (line: BABYLON.GUI.Line) => { return line.name }
-            },
-            'RadioButton': {
-                type: BABYLON.GUI.RadioButton,
-                properties: ['_isChecked', '_background'],
-                format: (radioButton: BABYLON.GUI.RadioButton) => { return radioButton.name }
-            },
-            'Rectangle': {
-                type: BABYLON.GUI.Rectangle,
-                properties: ['_thickness', '_cornerRadius'],
-                format: (rectangle: BABYLON.GUI.Rectangle) => { return rectangle.name }
-            },
-            'Slider': {
-                type: BABYLON.GUI.Slider,
-                properties: [
-                    '_minimum',
-                    '_maximum',
-                    '_value',
-                    '_background',
-                    '_borderColor',
-                ],
-                format: (slider: BABYLON.GUI.Slider) => { return slider.name }
-            },
-            'StackPanel': {
-                type: BABYLON.GUI.StackPanel,
-                properties: ['_isVertical'],
-                format: (stackPanel: BABYLON.GUI.StackPanel) => { return stackPanel.name }
-            },
-            'TextBlock': {
-                type: BABYLON.GUI.TextBlock,
-                properties: ['_text', '_textWrapping'],
-                format: (textBlock: BABYLON.GUI.TextBlock) => { return textBlock.name }
-            },
-            'Container': {
-                type: BABYLON.GUI.Container,
-                properties: ['_background'],
-                format: (container: BABYLON.GUI.Container) => { return container.name }
-            },
-        }
+/**
+  * Function that add gui objects properties to the variable PROPERTIES
+  */
+export function loadGUIProperties() {
+    let PROPERTIES_GUI = {
+        'ValueAndUnit': {
+            type: GUI.ValueAndUnit,
+            properties: ['_value', 'unit'],
+            format: (valueAndUnit: GUI.ValueAndUnit) => { return valueAndUnit }
+        },
+        'Control': {
+            type: GUI.Control,
+            properties: [
+                '_alpha',
+                '_fontFamily',
+                '_color',
+                '_scaleX',
+                '_scaleY',
+                '_rotation',
+                '_currentMeasure',
+                '_width',
+                '_height',
+                '_left',
+                '_top',
+                '_linkedMesh',
+                'isHitTestVisible',
+                'isPointerBlocker',
+            ],
+            format: (control: GUI.Control) => { return control.name }
+        },
+        'Button': {
+            type: GUI.Button,
+            properties: new Array(),
+            format: (button: GUI.Button) => { return button.name }
+        },
+        'ColorPicker': {
+            type: GUI.ColorPicker,
+            properties: ['_value'],
+            format: (colorPicker: GUI.ColorPicker) => { return colorPicker.name }
+        },
+        'Checkbox': {
+            type: GUI.Checkbox,
+            properties: ['_isChecked', '_background'],
+            format: (checkbox: GUI.Checkbox) => { return checkbox.name }
+        },
+        'Ellipse': {
+            type: GUI.Ellipse,
+            properties: ['_thickness'],
+            format: (ellipse: GUI.Ellipse) => { return ellipse.name }
+        },
+        'Image': {
+            type: GUI.Image,
+            properties: [
+                '_imageWidth',
+                '_imageHeight',
+                '_loaded',
+                '_source',
+            ],
+            format: (image: GUI.Image) => { return image.name }
+        },
+        'Line': {
+            type: GUI.Line,
+            properties: ['_lineWidth',
+                '_background',
+                '_x1',
+                '_y1',
+                '_x2',
+                '_y2',
+            ],
+            format: (line: GUI.Line) => { return line.name }
+        },
+        'RadioButton': {
+            type: GUI.RadioButton,
+            properties: ['_isChecked', '_background'],
+            format: (radioButton: GUI.RadioButton) => { return radioButton.name }
+        },
+        'Rectangle': {
+            type: GUI.Rectangle,
+            properties: ['_thickness', '_cornerRadius'],
+            format: (rectangle: GUI.Rectangle) => { return rectangle.name }
+        },
+        'Slider': {
+            type: GUI.Slider,
+            properties: [
+                '_minimum',
+                '_maximum',
+                '_value',
+                '_background',
+                '_borderColor',
+            ],
+            format: (slider: GUI.Slider) => { return slider.name }
+        },
+        'StackPanel': {
+            type: GUI.StackPanel,
+            properties: ['_isVertical'],
+            format: (stackPanel: GUI.StackPanel) => { return stackPanel.name }
+        },
+        'TextBlock': {
+            type: GUI.TextBlock,
+            properties: ['_text', '_textWrapping'],
+            format: (textBlock: GUI.TextBlock) => { return textBlock.name }
+        },
+        'Container': {
+            type: GUI.Container,
+            properties: ['_background'],
+            format: (container: GUI.Container) => { return container.name }
+        },
+    }
 
-        for (let prop in PROPERTIES_GUI) {
-            (<any>PROPERTIES)[prop] = (<any>PROPERTIES_GUI)[prop];
-        }
-    } 
-}
+    for (let prop in PROPERTIES_GUI) {
+        (<any>PROPERTIES)[prop] = (<any>PROPERTIES_GUI)[prop];
+    }
+} 

+ 38 - 38
inspector/src/scheduler/Scheduler.ts

@@ -1,55 +1,55 @@
-module INSPECTOR {
+import { PropertyLine } from "../details/PropertyLine";
 
-    export class Scheduler {
 
-        private static _instance: Scheduler;
+export class Scheduler {
 
-        /** Is this scheduler in pause ? */
-        public pause: boolean = false;
+    private static _instance: Scheduler;
 
-        /** All properties are refreshed every 250ms */
-        public static REFRESH_TIME: number = 250;
+    /** Is this scheduler in pause ? */
+    public pause: boolean = false;
 
-        /** The list of data to update */
-        private _updatableProperties: Array<PropertyLine> = [];
+    /** All properties are refreshed every 250ms */
+    public static REFRESH_TIME: number = 250;
 
-        private interval: number;
+    /** The list of data to update */
+    private _updatableProperties: Array<PropertyLine> = [];
 
-        constructor() {
-            this.interval = setInterval(this._update.bind(this), Scheduler.REFRESH_TIME);
-        }
+    private interval: number;
 
-        public static getInstance(): Scheduler {
-            if (!Scheduler._instance) {
-                Scheduler._instance = new Scheduler();
-            }
-            return Scheduler._instance;
-        }
+    constructor() {
+        this.interval = setInterval(this._update.bind(this), Scheduler.REFRESH_TIME);
+    }
 
-        /** Add a property line to be updated every X ms */
-        public add(prop: PropertyLine) {
-            this._updatableProperties.push(prop);
+    public static getInstance(): Scheduler {
+        if (!Scheduler._instance) {
+            Scheduler._instance = new Scheduler();
         }
+        return Scheduler._instance;
+    }
 
-        /** Removes the given property from the list of properties to update */
-        public remove(prop: PropertyLine) {
-            let index = this._updatableProperties.indexOf(prop);
-            if (index != -1) {
-                this._updatableProperties.splice(index, 1);
-            }
+    /** Add a property line to be updated every X ms */
+    public add(prop: PropertyLine) {
+        this._updatableProperties.push(prop);
+    }
+
+    /** Removes the given property from the list of properties to update */
+    public remove(prop: PropertyLine) {
+        let index = this._updatableProperties.indexOf(prop);
+        if (index != -1) {
+            this._updatableProperties.splice(index, 1);
         }
+    }
 
-        private _update() {
-            // If not in pause, update 
-            if (!this.pause) {
-                for (let prop of this._updatableProperties) {
-                    prop.update();
-                }
+    private _update() {
+        // If not in pause, update 
+        if (!this.pause) {
+            for (let prop of this._updatableProperties) {
+                prop.update();
             }
         }
+    }
 
-        public dispose() {
-            window.clearInterval(this.interval);
-        }
+    public dispose() {
+        window.clearInterval(this.interval);
     }
-}
+}

+ 22 - 19
inspector/src/tabs/CameraTab.ts

@@ -1,22 +1,25 @@
-module INSPECTOR{
-    
-    export class CameraTab extends PropertyTab {
-                
-        constructor(tabbar:TabBar, inspector:Inspector) {
-            super(tabbar, 'Camera', inspector); 
-        }
+import { PropertyTab } from "./PropertyTab";
+import { Inspector } from "../Inspector";
+import { TabBar } from "./TabBar";
+import { TreeItem } from "../tree/TreeItem";
+import { CameraAdapter } from "../adapters/CameraAdapter";
+
+
+export class CameraTab extends PropertyTab {
+
+    constructor(tabbar: TabBar, inspector: Inspector) {
+        super(tabbar, 'Camera', inspector);
+    }
     /* Overrides super */
-        protected _getTree() : Array<TreeItem> {
-            let arr = [];
-                        
-            // get all cameras from the first scene
-            let instances = this._inspector.scene;
-            for (let camera of instances.cameras) {
-                arr.push(new TreeItem(this, new CameraAdapter(camera)));
-            }
-            return arr;
-        }
+    protected _getTree(): Array<TreeItem> {
+        let arr = [];
 
+        // get all cameras from the first scene
+        let instances = this._inspector.scene;
+        for (let camera of instances.cameras) {
+            arr.push(new TreeItem(this, new CameraAdapter(camera)));
+        }
+        return arr;
     }
-    
-}
+
+}

+ 135 - 132
inspector/src/tabs/ConsoleTab.ts

@@ -1,152 +1,155 @@
+import { Tab } from "./Tab";
+import { Inspector } from "../Inspector";
+import { TabBar } from "./TabBar";
+import { Helpers } from "../helpers/Helpers";
+import { Tools } from "babylonjs";
+
 declare function Split(elements: HTMLDivElement[], options: any): void;
 
-module INSPECTOR {
-
-    /** 
-     * The console tab will have two features : 
-     * - hook all console.log call and display them in this panel (and in the browser console as well)
-     * - display all Babylon logs (called with Tools.Log...)
-     */
-    export class ConsoleTab extends Tab {
-
-        private _inspector : Inspector;
-        
-        private _consolePanelContent : HTMLElement;
-        private _bjsPanelContent : HTMLElement;
-
-        private _oldConsoleLog : any;
-        private _oldConsoleWarn : any;
-        private _oldConsoleError : any;
-        
-
-        constructor(tabbar:TabBar, insp:Inspector) {
-            super(tabbar, 'Console');            
-            this._inspector = insp;
-
-            // Build the shaders panel : a div that will contains the shaders tree and both shaders panels
-            this._panel         = Helpers.CreateDiv('tab-panel') as HTMLDivElement;
-
-            let consolePanel = Helpers.CreateDiv('console-panel') as HTMLDivElement;
-            let bjsPanel     = Helpers.CreateDiv('console-panel') as HTMLDivElement;
-
-            this._panel.appendChild(consolePanel);
-            this._panel.appendChild(bjsPanel);
-                        
-            Split([consolePanel, bjsPanel], {
-                blockDrag : this._inspector.popupMode,
-                sizes:[50, 50],
-                direction:'vertical'}
-            );  
-
-            // Titles
-            let title = Helpers.CreateDiv('console-panel-title', consolePanel);
-            title.textContent = 'Console logs';
-            title = Helpers.CreateDiv('console-panel-title', bjsPanel);
-            title.textContent = 'Babylon.js logs';
-
-            // Contents
-            this._consolePanelContent = Helpers.CreateDiv('console-panel-content', consolePanel) as HTMLDivElement;
-            this._bjsPanelContent     = Helpers.CreateDiv('console-panel-content', bjsPanel) as HTMLDivElement;
-
-            // Bjs logs
-            this._bjsPanelContent.innerHTML = BABYLON.Tools.LogCache;
-            BABYLON.Tools.OnNewCacheEntry = (entry: string) => {
-                this._bjsPanelContent.innerHTML += entry;
-                this._bjsPanelContent.scrollTop = this._bjsPanelContent.scrollHeight; 
-            };
-
-            // Testing
-            //console.log("This is a console.log message");
-            // console.log("That's right, console.log calls are hooked to be written in this window");
-            // console.log("Object are also stringify-ed", {width:10, height:30, shape:'rectangular'});
-            // console.warn("This is a console.warn message");
-            // console.error("This is a console.error message");
-
-            // BABYLON.Tools.Log("This is a message");
-            // BABYLON.Tools.Warn("This is a warning");
-            // BABYLON.Tools.Error("This is a error");
+/** 
+ * The console tab will have two features : 
+ * - hook all console.log call and display them in this panel (and in the browser console as well)
+ * - display all Babylon logs (called with Tools.Log...)
+ */
+export class ConsoleTab extends Tab {
 
-        }
+    private _inspector: Inspector;
 
-        /** Overrides super.dispose */
-        public dispose() {
-            console.log = this._oldConsoleLog;
-            console.warn = this._oldConsoleWarn;
-            console.error = this._oldConsoleError;
+    private _consolePanelContent: HTMLElement;
+    private _bjsPanelContent: HTMLElement;
 
+    private _oldConsoleLog: any;
+    private _oldConsoleWarn: any;
+    private _oldConsoleError: any;
+
+
+    constructor(tabbar: TabBar, insp: Inspector) {
+        super(tabbar, 'Console');
+        this._inspector = insp;
+
+        // Build the shaders panel : a div that will contains the shaders tree and both shaders panels
+        this._panel = Helpers.CreateDiv('tab-panel') as HTMLDivElement;
+
+        let consolePanel = Helpers.CreateDiv('console-panel') as HTMLDivElement;
+        let bjsPanel = Helpers.CreateDiv('console-panel') as HTMLDivElement;
+
+        this._panel.appendChild(consolePanel);
+        this._panel.appendChild(bjsPanel);
+
+        Split([consolePanel, bjsPanel], {
+            blockDrag: this._inspector.popupMode,
+            sizes: [50, 50],
+            direction: 'vertical'
         }
-        
-        public active(b: boolean){
-            super.active(b);
-            if(b){
-                // save old console.log
-                this._oldConsoleLog       = console.log;
-                this._oldConsoleWarn      = console.warn;
-                this._oldConsoleError     = console.error;
-
-                console.log               = this._addConsoleLog.bind(this);
-                console.warn              = this._addConsoleWarn.bind(this);
-                console.error             = this._addConsoleError.bind(this);
-            }
-        }
+        );
+
+        // Titles
+        let title = Helpers.CreateDiv('console-panel-title', consolePanel);
+        title.textContent = 'Console logs';
+        title = Helpers.CreateDiv('console-panel-title', bjsPanel);
+        title.textContent = 'js logs';
+
+        // Contents
+        this._consolePanelContent = Helpers.CreateDiv('console-panel-content', consolePanel) as HTMLDivElement;
+        this._bjsPanelContent = Helpers.CreateDiv('console-panel-content', bjsPanel) as HTMLDivElement;
+
+        // Bjs logs
+        this._bjsPanelContent.innerHTML = Tools.LogCache;
+        Tools.OnNewCacheEntry = (entry: string) => {
+            this._bjsPanelContent.innerHTML += entry;
+            this._bjsPanelContent.scrollTop = this._bjsPanelContent.scrollHeight;
+        };
+
+        // Testing
+        //console.log("This is a console.log message");
+        // console.log("That's right, console.log calls are hooked to be written in this window");
+        // console.log("Object are also stringify-ed", {width:10, height:30, shape:'rectangular'});
+        // console.warn("This is a console.warn message");
+        // console.error("This is a console.error message");
+
+        // Tools.Log("This is a message");
+        // Tools.Warn("This is a warning");
+        // Tools.Error("This is a error");
 
-        private _message(type:string, message:any, caller:string) {
-            let callerLine = Helpers.CreateDiv('caller', this._consolePanelContent);
-            callerLine.textContent = caller.replace(' ', '\u00A0');
+    }
+
+    /** Overrides super.dispose */
+    public dispose() {
+        console.log = this._oldConsoleLog;
+        console.warn = this._oldConsoleWarn;
+        console.error = this._oldConsoleError;
 
-            let line = Helpers.CreateDiv(type, this._consolePanelContent); 
-            line.textContent = message.replace(' ', '\u00A0');
+    }
 
-            this._consolePanelContent.scrollTop = this._consolePanelContent.scrollHeight; 
+    public active(b: boolean) {
+        super.active(b);
+        if (b) {
+            // save old console.log
+            this._oldConsoleLog = console.log;
+            this._oldConsoleWarn = console.warn;
+            this._oldConsoleError = console.error;
+
+            console.log = this._addConsoleLog.bind(this);
+            console.warn = this._addConsoleWarn.bind(this);
+            console.error = this._addConsoleError.bind(this);
         }
-        private _addConsoleLog(...params : any[]) {
-            
-            // Get caller name if not null
-            let callerFunc = this._addConsoleLog.caller as Function;
-            let caller = callerFunc==null? "Window" : "Function "+ (<any>callerFunc)['name'] + ": ";
-
-            for (var i = 0; i < params.length; i++) {
-                this._message('log', params[i], caller);
-                // Write again in console does not work on edge, as the console object                 
-                // is not instantiate if debugger tools is not open
-                if (!Helpers.IsBrowserEdge()) {    
-                    this._oldConsoleLog(params[i]);
-                }
+    }
+
+    private _message(type: string, message: any, caller: string) {
+        let callerLine = Helpers.CreateDiv('caller', this._consolePanelContent);
+        callerLine.textContent = caller.replace(' ', '\u00A0');
+
+        let line = Helpers.CreateDiv(type, this._consolePanelContent);
+        line.textContent = message.replace(' ', '\u00A0');
+
+        this._consolePanelContent.scrollTop = this._consolePanelContent.scrollHeight;
+    }
+    private _addConsoleLog(...params: any[]) {
+
+        // Get caller name if not null
+        let callerFunc = this._addConsoleLog.caller as Function;
+        let caller = callerFunc == null ? "Window" : "Function " + (<any>callerFunc)['name'] + ": ";
+
+        for (var i = 0; i < params.length; i++) {
+            this._message('log', params[i], caller);
+            // Write again in console does not work on edge, as the console object                 
+            // is not instantiate if debugger tools is not open
+            if (!Helpers.IsBrowserEdge()) {
+                this._oldConsoleLog(params[i]);
             }
         }
+    }
 
-        private _addConsoleWarn(...params : any[]) {
-            
-            // Get caller name if not null
-            let callerFunc = this._addConsoleLog.caller as Function;
-            let caller = callerFunc==null? "Window" : (<any>callerFunc)['name'];
-
-            for (var i = 0; i < params.length; i++) {
-                this._message('warn', params[i], caller);
-                // Write again in console does not work on edge, as the console object 
-                // is not instantiate if debugger tools is not open
-                if (!Helpers.IsBrowserEdge()) {    
-                    this._oldConsoleWarn(params[i]);
-                }
+    private _addConsoleWarn(...params: any[]) {
+
+        // Get caller name if not null
+        let callerFunc = this._addConsoleLog.caller as Function;
+        let caller = callerFunc == null ? "Window" : (<any>callerFunc)['name'];
+
+        for (var i = 0; i < params.length; i++) {
+            this._message('warn', params[i], caller);
+            // Write again in console does not work on edge, as the console object 
+            // is not instantiate if debugger tools is not open
+            if (!Helpers.IsBrowserEdge()) {
+                this._oldConsoleWarn(params[i]);
             }
         }
+    }
 
-        private _addConsoleError(...params : any[]) {
-            
-            // Get caller name if not null
-            let callerFunc = this._addConsoleLog.caller as Function;
-            let caller = callerFunc==null? "Window" : (<any>callerFunc)['name'];
-
-            for (var i = 0; i < params.length; i++) {
-                this._message('error', params[i], caller);
-                // Write again in console does not work on edge, as the console object 
-                // is not instantiate if debugger tools is not open
-                if (!Helpers.IsBrowserEdge()) {    
-                    this._oldConsoleError(params[i]);
-                }
+    private _addConsoleError(...params: any[]) {
+
+        // Get caller name if not null
+        let callerFunc = this._addConsoleLog.caller as Function;
+        let caller = callerFunc == null ? "Window" : (<any>callerFunc)['name'];
+
+        for (var i = 0; i < params.length; i++) {
+            this._message('error', params[i], caller);
+            // Write again in console does not work on edge, as the console object 
+            // is not instantiate if debugger tools is not open
+            if (!Helpers.IsBrowserEdge()) {
+                this._oldConsoleError(params[i]);
             }
         }
-
     }
 
-}
+}

+ 199 - 195
inspector/src/tabs/GLTFTab.ts

@@ -1,264 +1,268 @@
-/// <reference path="../../../dist/preview release/glTF2Interface/babylon.glTF2Interface.d.ts"/>
-/// <reference path="../../../dist/preview release/loaders/babylon.glTF2FileLoader.d.ts"/>
-/// <reference path="../../../dist/preview release/serializers/babylon.glTF2Serializer.d.ts"/>
+import { Tab } from "./Tab";
+import { Inspector } from "../Inspector";
+import { DetailPanel } from "../details/DetailPanel";
+import { SceneLoader, NullEngine, Scene, TransformNode, Mesh, PBRMaterial, StandardMaterial, Texture } from "babylonjs";
+import { TabBar } from "./TabBar";
+import { Helpers } from "../helpers/Helpers";
+import { PropertyLine } from "../details/PropertyLine";
+import { Property } from "../details/Property";
+
 
 declare function Split(elements: HTMLElement[], options: any): any;
 
-module INSPECTOR {
-    interface ILoaderDefaults {
+interface ILoaderDefaults {
+    [extensionName: string]: {
+        [key: string]: any
+    },
+    extensions: {
         [extensionName: string]: {
             [key: string]: any
-        },
-        extensions: {
-            [extensionName: string]: {
-                [key: string]: any
-            }
         }
     }
+}
 
-    export class GLTFTab extends Tab {
-        private static _LoaderDefaults: ILoaderDefaults | null = null;
+export class GLTFTab extends Tab {
+    private static _LoaderDefaults: ILoaderDefaults | null = null;
 
-        private _inspector: Inspector;
-        private _actions: HTMLDivElement;
-        private _detailsPanel: DetailPanel | null = null;
-        private _split: any;
+    private _inspector: Inspector;
+    private _actions: HTMLDivElement;
+    private _detailsPanel: DetailPanel | null = null;
+    private _split: any;
 
-        public static get IsSupported(): boolean {
-            return !!(BABYLON.SceneLoader && BABYLON.GLTFFileLoader && BABYLON.GLTF2.GLTFLoader) || !!BABYLON.GLTF2Export;
-        }
+    public static get IsSupported(): boolean {
+        return !!(SceneLoader && GLTFFileLoader && GLTF2.GLTFLoader) || !!GLTF2Export;
+    }
 
-        /** @hidden */
-        public static _Initialize(): void {
-            // Must register with OnPluginActivatedObservable as early as possible to override the loader defaults.
-            BABYLON.SceneLoader.OnPluginActivatedObservable.add((loader: BABYLON.GLTFFileLoader) => {
-                if (loader.name === "gltf" && GLTFTab._LoaderDefaults) {
-                    const defaults = GLTFTab._LoaderDefaults;
-                    for (const key in defaults) {
-                        if (key !== "extensions") {
-                            (loader as any)[key] = GLTFTab._LoaderDefaults[key];
-                        }
+    /** @hidden */
+    public static _Initialize(): void {
+        // Must register with OnPluginActivatedObservable as early as possible to override the loader defaults.
+        SceneLoader.OnPluginActivatedObservable.add((loader: GLTFFileLoader) => {
+            if (loader.name === "gltf" && GLTFTab._LoaderDefaults) {
+                const defaults = GLTFTab._LoaderDefaults;
+                for (const key in defaults) {
+                    if (key !== "extensions") {
+                        (loader as any)[key] = GLTFTab._LoaderDefaults[key];
                     }
-
-                    loader.onExtensionLoadedObservable.add(extension => {
-                        const extensionDefaults = defaults.extensions[extension.name];
-                        for (const key in extensionDefaults) {
-                            (extension as any)[key] = extensionDefaults[key];
-                        }
-                    });
                 }
-            });
-        }
 
-        constructor(tabbar: TabBar, inspector: Inspector) {
-            super(tabbar, 'GLTF');
+                loader.onExtensionLoadedObservable.add(extension => {
+                    const extensionDefaults = defaults.extensions[extension.name];
+                    for (const key in extensionDefaults) {
+                        (extension as any)[key] = extensionDefaults[key];
+                    }
+                });
+            }
+        });
+    }
 
-            this._inspector = inspector;
-            this._panel = Helpers.CreateDiv('tab-panel') as HTMLDivElement;
-            this._actions = Helpers.CreateDiv('gltf-actions', this._panel) as HTMLDivElement;
-            this._actions.addEventListener('click', event => {
-                this._closeDetailsPanel();
-            });
+    constructor(tabbar: TabBar, inspector: Inspector) {
+        super(tabbar, 'GLTF');
 
-            if (BABYLON.SceneLoader && BABYLON.GLTFFileLoader && BABYLON.GLTF2.GLTFLoader) {
-                this._addImport();
-            }
+        this._inspector = inspector;
+        this._panel = Helpers.CreateDiv('tab-panel') as HTMLDivElement;
+        this._actions = Helpers.CreateDiv('gltf-actions', this._panel) as HTMLDivElement;
+        this._actions.addEventListener('click', event => {
+            this._closeDetailsPanel();
+        });
 
-            if (BABYLON.GLTF2Export) {
-                this._addExport();
-            }
+        if (SceneLoader && GLTFFileLoader && GLTF2.GLTFLoader) {
+            this._addImport();
         }
 
-        public dispose() {
-            if (this._detailsPanel) {
-                this._detailsPanel.dispose();
-            }
+        if (GLTF2Export) {
+            this._addExport();
         }
+    }
 
-        private _addImport() {
-            const importTitle = Helpers.CreateDiv('gltf-title', this._actions);
-            importTitle.textContent = 'Import';
-
-            const importActions = Helpers.CreateDiv('gltf-actions', this._actions) as HTMLDivElement;
+    public dispose() {
+        if (this._detailsPanel) {
+            this._detailsPanel.dispose();
+        }
+    }
 
-            this._getLoaderDefaultsAsync().then(defaults => {
-                importTitle.addEventListener('click', event => {
-                    this._showLoaderDefaults(defaults);
-                    event.stopPropagation();
-                });
+    private _addImport() {
+        const importTitle = Helpers.CreateDiv('gltf-title', this._actions);
+        importTitle.textContent = 'Import';
 
-                importActions.addEventListener('click', event => {
-                    this._showLoaderDefaults(defaults);
-                    event.stopPropagation();
-                });
+        const importActions = Helpers.CreateDiv('gltf-actions', this._actions) as HTMLDivElement;
 
-                const extensionsTitle = Helpers.CreateDiv('gltf-title', importActions) as HTMLDivElement;
-                extensionsTitle.textContent = "Extensions";
+        this._getLoaderDefaultsAsync().then(defaults => {
+            importTitle.addEventListener('click', event => {
+                this._showLoaderDefaults(defaults);
+                event.stopPropagation();
+            });
 
-                for (const extensionName in defaults.extensions) {
-                    const extensionDefaults = defaults.extensions[extensionName];
+            importActions.addEventListener('click', event => {
+                this._showLoaderDefaults(defaults);
+                event.stopPropagation();
+            });
 
-                    const extensionAction = Helpers.CreateDiv('gltf-action', importActions);
-                    extensionAction.addEventListener('click', event => {
-                        if (this._showLoaderExtensionDefaults(extensionDefaults)) {
-                            event.stopPropagation();
-                        }
-                    });
+            const extensionsTitle = Helpers.CreateDiv('gltf-title', importActions) as HTMLDivElement;
+            extensionsTitle.textContent = "Extensions";
 
-                    const checkbox = Helpers.CreateElement('span', 'gltf-checkbox', extensionAction);
+            for (const extensionName in defaults.extensions) {
+                const extensionDefaults = defaults.extensions[extensionName];
 
-                    if (extensionDefaults.enabled) {
-                        checkbox.classList.add('action', 'active');
+                const extensionAction = Helpers.CreateDiv('gltf-action', importActions);
+                extensionAction.addEventListener('click', event => {
+                    if (this._showLoaderExtensionDefaults(extensionDefaults)) {
+                        event.stopPropagation();
                     }
+                });
 
-                    checkbox.addEventListener('click', () => {
-                        checkbox.classList.toggle('active');
-                        extensionDefaults.enabled = checkbox.classList.contains('active');
-                    });
+                const checkbox = Helpers.CreateElement('span', 'gltf-checkbox', extensionAction);
 
-                    const label = Helpers.CreateElement('span', null, extensionAction);
-                    label.textContent = extensionName;
+                if (extensionDefaults.enabled) {
+                    checkbox.classList.add('action', 'active');
                 }
-            });
-        }
 
-        private static _EnumeratePublic(obj: any, callback: (key: string, value: any) => void): void {
-            for (const key in obj) {
-                if (key !== "name" && key[0] !== '_') {
-                    const value = obj[key];
-                    const type = typeof value;
-                    if (type !== "object" && type !== "function" && type !== "undefined") {
-                        callback(key, value);
-                    }
+                checkbox.addEventListener('click', () => {
+                    checkbox.classList.toggle('active');
+                    extensionDefaults.enabled = checkbox.classList.contains('active');
+                });
+
+                const label = Helpers.CreateElement('span', null, extensionAction);
+                label.textContent = extensionName;
+            }
+        });
+    }
+
+    private static _EnumeratePublic(obj: any, callback: (key: string, value: any) => void): void {
+        for (const key in obj) {
+            if (key !== "name" && key[0] !== '_') {
+                const value = obj[key];
+                const type = typeof value;
+                if (type !== "object" && type !== "function" && type !== "undefined") {
+                    callback(key, value);
                 }
             }
         }
+    }
 
-        private _getLoaderDefaultsAsync(): Promise<ILoaderDefaults> {
-            if (GLTFTab._LoaderDefaults) {
-                return Promise.resolve(GLTFTab._LoaderDefaults);
-            }
+    private _getLoaderDefaultsAsync(): Promise<ILoaderDefaults> {
+        if (GLTFTab._LoaderDefaults) {
+            return Promise.resolve(GLTFTab._LoaderDefaults);
+        }
 
-            const defaults: ILoaderDefaults = {
-                extensions: {}
-            };
+        const defaults: ILoaderDefaults = {
+            extensions: {}
+        };
 
-            const engine = new BABYLON.NullEngine();
-            const scene = new BABYLON.Scene(engine);
+        const engine = new NullEngine();
+        const scene = new Scene(engine);
 
-            const loader = new BABYLON.GLTFFileLoader();
-            GLTFTab._EnumeratePublic(loader, (key, value) => {
-                defaults[key] = value;
-            });
+        const loader = new GLTFFileLoader();
+        GLTFTab._EnumeratePublic(loader, (key, value) => {
+            defaults[key] = value;
+        });
 
-            loader.onExtensionLoadedObservable.add(extension => {
-                const extensionDefaults: any = {};
-                GLTFTab._EnumeratePublic(extension, (key, value) => {
-                    extensionDefaults[key] = value;
-                });
-                defaults.extensions[extension.name] = extensionDefaults;
+        loader.onExtensionLoadedObservable.add(extension => {
+            const extensionDefaults: any = {};
+            GLTFTab._EnumeratePublic(extension, (key, value) => {
+                extensionDefaults[key] = value;
             });
+            defaults.extensions[extension.name] = extensionDefaults;
+        });
+
+        const data = '{ "asset": { "version": "2.0" } }';
+        return loader.importMeshAsync([], scene, data, "").then(() => {
+            scene.dispose();
+            engine.dispose();
+
+            return (GLTFTab._LoaderDefaults = defaults);
+        });
+    }
 
-            const data = '{ "asset": { "version": "2.0" } }';
-            return loader.importMeshAsync([], scene, data, "").then(() => {
-                scene.dispose();
-                engine.dispose();
+    private _openDetailsPanel(): DetailPanel {
+        if (!this._detailsPanel) {
+            this._detailsPanel = new DetailPanel();
+            this._panel.appendChild(this._detailsPanel.toHtml());
 
-                return (GLTFTab._LoaderDefaults = defaults);
+            this._split = Split([this._actions, this._detailsPanel.toHtml()], {
+                blockDrag: this._inspector.popupMode,
+                sizes: [50, 50],
+                direction: 'vertical'
             });
         }
 
-        private _openDetailsPanel(): DetailPanel {
-            if (!this._detailsPanel) {
-                this._detailsPanel = new DetailPanel();
-                this._panel.appendChild(this._detailsPanel.toHtml());
-
-                this._split = Split([this._actions, this._detailsPanel.toHtml()], {
-                    blockDrag: this._inspector.popupMode,
-                    sizes: [50, 50],
-                    direction: 'vertical'
-                });
-            }
+        this._detailsPanel.clean();
+        return this._detailsPanel;
+    }
 
-            this._detailsPanel.clean();
-            return this._detailsPanel;
+    private _closeDetailsPanel(): void {
+        if (this._detailsPanel) {
+            this._detailsPanel.toHtml().remove();
+            this._detailsPanel.dispose();
+            this._detailsPanel = null;
         }
 
-        private _closeDetailsPanel(): void {
-            if (this._detailsPanel) {
-                this._detailsPanel.toHtml().remove();
-                this._detailsPanel.dispose();
-                this._detailsPanel = null;
-            }
-
-            if (this._split) {
-                this._split.destroy();
-                delete this._split;
-            }
+        if (this._split) {
+            this._split.destroy();
+            delete this._split;
         }
+    }
 
-        private _showLoaderDefaults(defaults: { [key: string]: any }): void {
-            var detailsPanel = this._openDetailsPanel();
-            const details = new Array<PropertyLine>();
-            for (const key in defaults) {
-                if (key !== "extensions") {
-                    details.push(new PropertyLine(new Property(key, defaults, this._inspector.scene)));
-                }
+    private _showLoaderDefaults(defaults: { [key: string]: any }): void {
+        var detailsPanel = this._openDetailsPanel();
+        const details = new Array<PropertyLine>();
+        for (const key in defaults) {
+            if (key !== "extensions") {
+                details.push(new PropertyLine(new Property(key, defaults, this._inspector.scene)));
             }
-            detailsPanel.details = details;
         }
+        detailsPanel.details = details;
+    }
 
-        private _showLoaderExtensionDefaults(defaults: { [key: string]: any }): boolean {
-            if (Object.keys(defaults).length === 1) {
-                return false;
-            }
+    private _showLoaderExtensionDefaults(defaults: { [key: string]: any }): boolean {
+        if (Object.keys(defaults).length === 1) {
+            return false;
+        }
 
-            var detailsPanel = this._openDetailsPanel();
-            const details = new Array<PropertyLine>();
-            for (const key in defaults) {
-                if (key !== "enabled") {
-                    details.push(new PropertyLine(new Property(key, defaults, this._inspector.scene)));
-                }
+        var detailsPanel = this._openDetailsPanel();
+        const details = new Array<PropertyLine>();
+        for (const key in defaults) {
+            if (key !== "enabled") {
+                details.push(new PropertyLine(new Property(key, defaults, this._inspector.scene)));
             }
-            detailsPanel.details = details;
-
-            return true;
         }
+        detailsPanel.details = details;
+
+        return true;
+    }
 
-        private _addExport() {
-            const exportTitle = Helpers.CreateDiv('gltf-title', this._actions);
-            exportTitle.textContent = 'Export';
+    private _addExport() {
+        const exportTitle = Helpers.CreateDiv('gltf-title', this._actions);
+        exportTitle.textContent = 'Export';
 
-            const exportActions = Helpers.CreateDiv('gltf-actions', this._actions) as HTMLDivElement;
+        const exportActions = Helpers.CreateDiv('gltf-actions', this._actions) as HTMLDivElement;
 
-            const name = Helpers.CreateInput('gltf-input', exportActions);
-            name.placeholder = "File name...";
+        const name = Helpers.CreateInput('gltf-input', exportActions);
+        name.placeholder = "File name...";
 
-            const button = Helpers.CreateElement('button', 'gltf-button', exportActions) as HTMLButtonElement;
-            button.innerText = 'Export GLB';
-            button.addEventListener('click', () => {
-                BABYLON.GLTF2Export.GLBAsync(this._inspector.scene, name.value || "scene", {
-                    shouldExportTransformNode: transformNode => !GLTFTab._IsSkyBox(transformNode)
-                }).then((glb) => {
-                    glb.downloadFiles();
-                });
+        const button = Helpers.CreateElement('button', 'gltf-button', exportActions) as HTMLButtonElement;
+        button.innerText = 'Export GLB';
+        button.addEventListener('click', () => {
+            GLTF2Export.GLBAsync(this._inspector.scene, name.value || "scene", {
+                shouldExportTransformNode: transformNode => !GLTFTab._IsSkyBox(transformNode)
+            }).then((glb) => {
+                glb.downloadFiles();
             });
-        }
+        });
+    }
 
-        private static _IsSkyBox(transformNode: BABYLON.TransformNode): boolean {
-            if (transformNode instanceof BABYLON.Mesh) {
-                if (transformNode.material) {
-                    const material = transformNode.material as BABYLON.PBRMaterial | BABYLON.StandardMaterial;
-                    const reflectionTexture = material.reflectionTexture;
-                    if (reflectionTexture && reflectionTexture.coordinatesMode === BABYLON.Texture.SKYBOX_MODE) {
-                        return true;
-                    }
+    private static _IsSkyBox(transformNode: TransformNode): boolean {
+        if (transformNode instanceof Mesh) {
+            if (transformNode.material) {
+                const material = transformNode.material as PBRMaterial | StandardMaterial;
+                const reflectionTexture = material.reflectionTexture;
+                if (reflectionTexture && reflectionTexture.coordinatesMode === Texture.SKYBOX_MODE) {
+                    return true;
                 }
             }
-
-            return false;
         }
+
+        return false;
     }
+}
 
-    GLTFTab._Initialize();
-}
+GLTFTab._Initialize();

+ 39 - 35
inspector/src/tabs/GUITab.ts

@@ -1,42 +1,46 @@
-module INSPECTOR{
-    
-    export class GUITab extends PropertyTab {
-                
-        constructor(tabbar:TabBar, inspector:Inspector) {
-            super(tabbar, 'GUI', inspector); 
-        }
+import { AdvancedDynamicTexture, Container, Control } from "babylonjs-gui";
+import { GUIAdapter } from "../adapters/GUIAdapter";
+import { Inspector } from "../Inspector";
+import { TreeItem } from "../tree/TreeItem";
+import { PropertyTab } from "./PropertyTab";
+import { TabBar } from "./TabBar";
+
+export class GUITab extends PropertyTab {
 
-        /* Overrides super */
-        protected _getTree() : Array<TreeItem> {
-            let arr = [];
+    constructor(tabbar: TabBar, inspector: Inspector) {
+        super(tabbar, 'GUI', inspector);
+    }
 
-            // Recursive method building the tree panel
-            let createNode = (obj: BABYLON.GUI.Control) => {
-                let descendants = (obj as BABYLON.GUI.Container).children;
+    /* Overrides super */
+    protected _getTree(): Array<TreeItem> {
+        let arr = [];
 
-                if (descendants && descendants.length > 0) {
-                    let node = new TreeItem(this, new GUIAdapter(obj));
-                    for (let child of descendants) {     
-                        let n = createNode(child);
-                        node.add(n); 
-                    }
-                    node.update();
-                    return node;
-                } else {
-                    return new TreeItem(this, new GUIAdapter(obj));
-                }
-            };
-            
-            // get all textures from the first scene
-            let instances = this._inspector.scene;
-            for (let tex of instances.textures) {
-                //only get GUI's textures
-                if (tex instanceof BABYLON.GUI.AdvancedDynamicTexture) {
-                    let node = createNode(tex._rootContainer);
-                    arr.push(node);
+        // Recursive method building the tree panel
+        let createNode = (obj: Control) => {
+            let descendants = (obj as Container).children;
+
+            if (descendants && descendants.length > 0) {
+                let node = new TreeItem(this, new GUIAdapter(obj));
+                for (let child of descendants) {
+                    let n = createNode(child);
+                    node.add(n);
                 }
+                node.update();
+                return node;
+            } else {
+                return new TreeItem(this, new GUIAdapter(obj));
+            }
+        };
+
+        // get all textures from the first scene
+        let instances = this._inspector.scene;
+        for (let tex of instances.textures) {
+            //only get GUI's textures
+            if (tex instanceof AdvancedDynamicTexture) {
+                let node = createNode(tex._rootContainer);
+                arr.push(node);
             }
-            return arr;
         }
+        return arr;
     }
-}
+}

+ 23 - 20
inspector/src/tabs/LightTab.ts

@@ -1,22 +1,25 @@
-module INSPECTOR{
-    
-    export class LightTab extends PropertyTab {
-                
-        constructor(tabbar:TabBar, inspector:Inspector) {
-            super(tabbar, 'Light', inspector); 
-        }
+import { LightAdapter } from "../adapters/LightAdapter";
+import { Inspector } from "../Inspector";
+import { TreeItem } from "../tree/TreeItem";
+import { PropertyTab } from "./PropertyTab";
+import { TabBar } from "./TabBar";
+
 
-        /* Overrides super */
-        protected _getTree() : Array<TreeItem> {
-            let arr = [];
-                        
-            // get all lights from the first scene
-            let instances = this._inspector.scene;
-            for (let light of instances.lights) {
-                arr.push(new TreeItem(this, new LightAdapter(light)));
-            }
-            return arr;
-        }  
+export class LightTab extends PropertyTab {
+
+    constructor(tabbar: TabBar, inspector: Inspector) {
+        super(tabbar, 'Light', inspector);
+    }
+
+    /* Overrides super */
+    protected _getTree(): Array<TreeItem> {
+        let arr = [];
+
+        // get all lights from the first scene
+        let instances = this._inspector.scene;
+        for (let light of instances.lights) {
+            arr.push(new TreeItem(this, new LightAdapter(light)));
+        }
+        return arr;
     }
-    
-}
+}

+ 21 - 19
inspector/src/tabs/MaterialTab.ts

@@ -1,22 +1,24 @@
-module INSPECTOR{
-    
-    export class MaterialTab extends PropertyTab {
-                
-        constructor(tabbar:TabBar, inspector:Inspector) {
-            super(tabbar, 'Material', inspector); 
-        }
+import { PropertyTab } from "./PropertyTab";
+import { TabBar } from "./TabBar";
+import { Inspector } from "../Inspector";
+import { TreeItem } from "../tree/TreeItem";
+import { MaterialAdapter } from "../adapters/MaterialAdapter";
+
+export class MaterialTab extends PropertyTab {
+
+    constructor(tabbar: TabBar, inspector: Inspector) {
+        super(tabbar, 'Material', inspector);
+    }
+
+    /* Overrides super */
+    protected _getTree(): Array<TreeItem> {
+        let arr = [];
 
-        /* Overrides super */
-        protected _getTree() : Array<TreeItem> {
-            let arr = [];
-            
-            // get all meshes from the first scene
-            let instances = this._inspector.scene;
-            for (let mat of instances.materials) {
-                arr.push(new TreeItem(this, new MaterialAdapter(mat)))
-            }
-            return arr;
+        // get all meshes from the first scene
+        let instances = this._inspector.scene;
+        for (let mat of instances.materials) {
+            arr.push(new TreeItem(this, new MaterialAdapter(mat)))
         }
+        return arr;
     }
-    
-}
+}

+ 64 - 61
inspector/src/tabs/MeshTab.ts

@@ -1,83 +1,86 @@
-/// <reference path="../../../dist/preview release/babylon.d.ts"/>
+import { PropertyTab } from "./PropertyTab";
+import { Inspector } from "../Inspector";
+import { TabBar } from "./TabBar";
+import { TreeItem } from "../tree/TreeItem";
+import { Node, TransformNode } from "babylonjs";
+import { MeshAdapter } from "../adapters/MeshAdapter";
+import { Helpers } from "../helpers/Helpers";
 
-module INSPECTOR {
 
-    export class MeshTab extends PropertyTab {
+export class MeshTab extends PropertyTab {
 
-        constructor(tabbar: TabBar, inspector: Inspector) {
-            super(tabbar, 'Mesh', inspector);
-        }
+    constructor(tabbar: TabBar, inspector: Inspector) {
+        super(tabbar, 'Mesh', inspector);
+    }
 
-        /* Overrides super */
-        protected _getTree(): Array<TreeItem> {
-            let arr = new Array<TreeItem>();
-            // Tab containing mesh already in results
-            let alreadyIn = new Array<BABYLON.Node>();
+    /* Overrides super */
+    protected _getTree(): Array<TreeItem> {
+        let arr = new Array<TreeItem>();
+        // Tab containing mesh already in results
+        let alreadyIn = new Array<Node>();
 
-            // Recursive method building the tree panel
-            let createNode = (obj: BABYLON.Node) => {
-                let descendants = obj.getDescendants(true);
+        // Recursive method building the tree panel
+        let createNode = (obj: Node) => {
+            let descendants = obj.getDescendants(true);
 
-                let node = new TreeItem(this, new MeshAdapter(obj));
+            let node = new TreeItem(this, new MeshAdapter(obj));
 
-                if (descendants.length > 0) {
-                    for (let child of descendants) {
-                        if (child instanceof BABYLON.TransformNode) {
-                            if (!Helpers.IsSystemName(child.name)) {
-                                let n = createNode(child);
-                                node.add(n);
-                            }
+            if (descendants.length > 0) {
+                for (let child of descendants) {
+                    if (child instanceof TransformNode) {
+                        if (!Helpers.IsSystemName(child.name)) {
+                            let n = createNode(child);
+                            node.add(n);
                         }
                     }
-                    node.update();
                 }
+                node.update();
+            }
 
-                // Retrieve the root node if the mesh is actually child of another mesh
-                // This can hapen if the child mesh has been created before the parent mesh
-                if (obj.parent != null && alreadyIn.indexOf(obj) != -1) {
-                    let i: number = 0;
-                    let notFound: boolean = true;
-                    // Find and delete the root node standing for this mesh
-                    while (i < arr.length && notFound) {
-                        if (obj.name === arr[i].id) {
-                            arr.splice(i, 1);
-                            notFound = false;
-                        }
-                        i++;
+            // Retrieve the root node if the mesh is actually child of another mesh
+            // This can hapen if the child mesh has been created before the parent mesh
+            if (obj.parent != null && alreadyIn.indexOf(obj) != -1) {
+                let i: number = 0;
+                let notFound: boolean = true;
+                // Find and delete the root node standing for this mesh
+                while (i < arr.length && notFound) {
+                    if (obj.name === arr[i].id) {
+                        arr.splice(i, 1);
+                        notFound = false;
                     }
+                    i++;
                 }
+            }
 
-                alreadyIn.push(obj);
-                return node;
-            };
+            alreadyIn.push(obj);
+            return node;
+        };
 
-            // get all meshes from the first scene
-            let instances = this._inspector.scene;
+        // get all meshes from the first scene
+        let instances = this._inspector.scene;
 
-            // Find top of hierarchy for meshes...
-            let meshWithoutAnyParent: Array<BABYLON.Node> = [];
-            for (let mesh of instances.meshes) {
-                // Not already in the array, not system name and no parent
-                if (meshWithoutAnyParent.indexOf(mesh) == -1 && !Helpers.IsSystemName(mesh.name) && !mesh.parent) {
-                    meshWithoutAnyParent.push(mesh);
-                }
+        // Find top of hierarchy for meshes...
+        let meshWithoutAnyParent: Array<Node> = [];
+        for (let mesh of instances.meshes) {
+            // Not already in the array, not system name and no parent
+            if (meshWithoutAnyParent.indexOf(mesh) == -1 && !Helpers.IsSystemName(mesh.name) && !mesh.parent) {
+                meshWithoutAnyParent.push(mesh);
             }
-            // ... and for transforms
-            for (let tn of instances.transformNodes) {
-                // Not already in the array, not system name and no parent
-                if (meshWithoutAnyParent.indexOf(tn) == -1 && !Helpers.IsSystemName(tn.name) && !tn.parent) {
-                    meshWithoutAnyParent.push(tn);
-                }
+        }
+        // ... and for transforms
+        for (let tn of instances.transformNodes) {
+            // Not already in the array, not system name and no parent
+            if (meshWithoutAnyParent.indexOf(tn) == -1 && !Helpers.IsSystemName(tn.name) && !tn.parent) {
+                meshWithoutAnyParent.push(tn);
             }
+        }
 
-            for (let mesh of meshWithoutAnyParent) {
-                if (alreadyIn.indexOf(mesh) == -1 && !Helpers.IsSystemName(mesh.name)) {
-                    let node = createNode(mesh);
-                    arr.push(node);
-                }
+        for (let mesh of meshWithoutAnyParent) {
+            if (alreadyIn.indexOf(mesh) == -1 && !Helpers.IsSystemName(mesh.name)) {
+                let node = createNode(mesh);
+                arr.push(node);
             }
-            return arr;
         }
+        return arr;
     }
-
-}
+}

+ 26 - 22
inspector/src/tabs/PhysicsTab.ts

@@ -1,34 +1,38 @@
-module INSPECTOR {
+import { PropertyTab } from "./PropertyTab";
+import { TabBar } from "./TabBar";
+import { Inspector } from "../Inspector";
+import { TreeItem } from "../tree/TreeItem";
+import { Debug } from "babylonjs";
+import { PhysicsImpostorAdapter } from "../adapters/PhysicsImpostorAdapter";
 
-    export class PhysicsTab extends PropertyTab {
+export class PhysicsTab extends PropertyTab {
 
-        public viewer: any;
+    public viewer: any;
 
-        constructor(tabbar: TabBar, inspector: Inspector) {
-            super(tabbar, 'Physics', inspector);
-        }
+    constructor(tabbar: TabBar, inspector: Inspector) {
+        super(tabbar, 'Physics', inspector);
+    }
 
-        /* Overrides super */
-        protected _getTree(): Array<TreeItem> {
-            let arr = new Array<TreeItem>();
+    /* Overrides super */
+    protected _getTree(): Array<TreeItem> {
+        let arr = new Array<TreeItem>();
 
-            let scene = this._inspector.scene;
+        let scene = this._inspector.scene;
 
-            if (!scene.isPhysicsEnabled()) {
-                return arr;
-            }
+        if (!scene.isPhysicsEnabled()) {
+            return arr;
+        }
 
-            if (!this.viewer) {
-                this.viewer = new BABYLON.Debug.PhysicsViewer(scene);
-            }
+        if (!this.viewer) {
+            this.viewer = new Debug.PhysicsViewer(scene);
+        }
 
-            for (let mesh of scene.meshes) {
-                if (mesh.physicsImpostor) {
-                    arr.push(new TreeItem(this, new PhysicsImpostorAdapter(mesh.physicsImpostor, this.viewer)));
-                }
+        for (let mesh of scene.meshes) {
+            if (mesh.physicsImpostor) {
+                arr.push(new TreeItem(this, new PhysicsImpostorAdapter(mesh.physicsImpostor, this.viewer)));
             }
-            return arr;
         }
-
+        return arr;
     }
+
 }

+ 140 - 133
inspector/src/tabs/PropertyTab.ts

@@ -1,162 +1,169 @@
+import { DetailPanel } from "../details/DetailPanel";
+import { SearchBar } from "../gui/SearchBar";
+import { Helpers } from "../helpers/Helpers";
+import { Inspector } from "../Inspector";
+import { TreeItem } from "../tree/TreeItem";
+import { Tab } from "./Tab";
+import { TabBar } from "./TabBar";
+import { Nullable, AbstractMesh } from "babylonjs";
+
 declare function Split(elements: HTMLDivElement[], options: any): void;
-module INSPECTOR {
-
-    /**
-     * A Property tab can creates two panels: 
-     * a tree panel and a detail panel, 
-     * in which properties will be displayed.
-     * Both panels are separated by a resize bar
-     */
-    export abstract class PropertyTab extends Tab {
-
-        protected _inspector: Inspector;
-        /** The panel containing a list of items */
-        protected _treePanel: HTMLElement;
-        /** The panel containing a list if properties corresponding to an item */
-        protected _detailsPanel: DetailPanel;
-        protected _treeItems: Array<TreeItem> = [];
-        protected _searchBar: SearchBar;
-
-        constructor(tabbar: TabBar, name: string, insp: Inspector) {
-            super(tabbar, name);
-
-            this._inspector = insp;
-
-            // Build the properties panel : a div that will contains the tree and the detail panel
-            this._panel = Helpers.CreateDiv('tab-panel') as HTMLDivElement;
-            this._panel.classList.add('searchable');
-
-            // Search bar
-            this._searchBar = new SearchBar(this);
-            // Add searchbar
-            this._panel.appendChild(this._searchBar.toHtml());
-
-            // Build the treepanel
-            this._treePanel = Helpers.CreateDiv('insp-tree', this._panel);
-
-            // Build the detail panel
-            this._detailsPanel = new DetailPanel();
-            this._panel.appendChild(this._detailsPanel.toHtml());
-
-            Split([this._treePanel, this._detailsPanel.toHtml()], {
-                blockDrag: this._inspector.popupMode,
-                direction: 'vertical'
-            });
-
-            this.update();
-        }
 
-        /** Overrides dispose */
-        public dispose() {
-            this._detailsPanel.dispose();
-        }
+/**
+ * A Property tab can creates two panels: 
+ * a tree panel and a detail panel, 
+ * in which properties will be displayed.
+ * Both panels are separated by a resize bar
+ */
+export abstract class PropertyTab extends Tab {
+
+    protected _inspector: Inspector;
+    /** The panel containing a list of items */
+    protected _treePanel: HTMLElement;
+    /** The panel containing a list if properties corresponding to an item */
+    protected _detailsPanel: DetailPanel;
+    protected _treeItems: Array<TreeItem> = [];
+    protected _searchBar: SearchBar;
+
+    constructor(tabbar: TabBar, name: string, insp: Inspector) {
+        super(tabbar, name);
+
+        this._inspector = insp;
+
+        // Build the properties panel : a div that will contains the tree and the detail panel
+        this._panel = Helpers.CreateDiv('tab-panel') as HTMLDivElement;
+        this._panel.classList.add('searchable');
+
+        // Search bar
+        this._searchBar = new SearchBar(this);
+        // Add searchbar
+        this._panel.appendChild(this._searchBar.toHtml());
+
+        // Build the treepanel
+        this._treePanel = Helpers.CreateDiv('insp-tree', this._panel);
+
+        // Build the detail panel
+        this._detailsPanel = new DetailPanel();
+        this._panel.appendChild(this._detailsPanel.toHtml());
+
+        Split([this._treePanel, this._detailsPanel.toHtml()], {
+            blockDrag: this._inspector.popupMode,
+            direction: 'vertical'
+        });
+
+        this.update();
+    }
 
-        public update(_items?: Array<TreeItem>) {
+    /** Overrides dispose */
+    public dispose() {
+        this._detailsPanel.dispose();
+    }
 
-            let items;
-            if (_items) {
-                items = _items;
-            } else {
-                // Rebuild the tree
-                this._treeItems = this._getTree();
-                items = this._treeItems;
-            }
-            // Clean the tree
-            Helpers.CleanDiv(this._treePanel);
-            // Clean the detail properties
-            this._detailsPanel.clean();
+    public update(_items?: Array<TreeItem>) {
 
+        let items;
+        if (_items) {
+            items = _items;
+        } else {
+            // Rebuild the tree
+            this._treeItems = this._getTree();
+            items = this._treeItems;
+        }
+        // Clean the tree
+        Helpers.CleanDiv(this._treePanel);
+        // Clean the detail properties
+        this._detailsPanel.clean();
 
-            // Sort items alphabetically
-            items.sort((item1, item2) => {
-                return item1.compareTo(item2);
-            });
 
-            // Display items
-            for (let item of items) {
-                this._treePanel.appendChild(item.toHtml());
-            }
-        }
+        // Sort items alphabetically
+        items.sort((item1, item2) => {
+            return item1.compareTo(item2);
+        });
 
-        /** Display the details of the given item */
-        public displayDetails(item: TreeItem) {
-            // Remove active state on all items
-            this.activateNode(item);
-            // Update the detail panel
-            this._detailsPanel.details = item.getDetails();
+        // Display items
+        for (let item of items) {
+            this._treePanel.appendChild(item.toHtml());
         }
+    }
 
-        /** Select an item in the tree */
-        public select(item: TreeItem) {
-            // Active the node
-            this.activateNode(item);
-            // Display its details
-            this.displayDetails(item);
-        }
+    /** Display the details of the given item */
+    public displayDetails(item: TreeItem) {
+        // Remove active state on all items
+        this.activateNode(item);
+        // Update the detail panel
+        this._detailsPanel.details = item.getDetails();
+    }
 
-        /** Set the given item as active in the tree */
-        public activateNode(item: TreeItem) {
-            if (this._treeItems) {
-                for (let node of this._treeItems) {
-                    node.active(false);
-                }
+    /** Select an item in the tree */
+    public select(item: TreeItem) {
+        // Active the node
+        this.activateNode(item);
+        // Display its details
+        this.displayDetails(item);
+    }
+
+    /** Set the given item as active in the tree */
+    public activateNode(item: TreeItem) {
+        if (this._treeItems) {
+            for (let node of this._treeItems) {
+                node.active(false);
             }
-          //  item.getDiv().scrollIntoView();
-            item.active(true);
         }
+        //  item.getDiv().scrollIntoView();
+        item.active(true);
+    }
 
-        /** Returns the treeitem corersponding to the given obj, null if not found */
-        public getItemFor(_obj: any): BABYLON.Nullable<TreeItem> {
-            let obj = _obj as BABYLON.AbstractMesh;
+    /** Returns the treeitem corersponding to the given obj, null if not found */
+    public getItemFor(_obj: any): Nullable<TreeItem> {
+        let obj = _obj as AbstractMesh;
 
-            // Search recursively
-            let searchObjectInTree = (object: any, treeItem: TreeItem): BABYLON.Nullable<TreeItem> => {
-                if (treeItem.correspondsTo(object)) {
-                    return treeItem;
-                }
-                else {
-                    if (treeItem.children.length > 0) {
-                        for (let item of treeItem.children) {
-                            let it = searchObjectInTree(obj, item);
-                            if (it) {
-                                return it;
-                            }
+        // Search recursively
+        let searchObjectInTree = (object: any, treeItem: TreeItem): Nullable<TreeItem> => {
+            if (treeItem.correspondsTo(object)) {
+                return treeItem;
+            }
+            else {
+                if (treeItem.children.length > 0) {
+                    for (let item of treeItem.children) {
+                        let it = searchObjectInTree(obj, item);
+                        if (it) {
+                            return it;
                         }
                     }
-                    else {
-                        return null;
-                    }
                 }
-
-                return null;
-            }
-
-            for (let item of this._treeItems) {
-                let it = searchObjectInTree(obj, item);
-                if (it) {
-                    return it;
+                else {
+                    return null;
                 }
             }
+
             return null;
         }
 
-        public filter(filter: string) {
-            let items = [];
+        for (let item of this._treeItems) {
+            let it = searchObjectInTree(obj, item);
+            if (it) {
+                return it;
+            }
+        }
+        return null;
+    }
 
-            for (let item of this._treeItems) {
-                if (item.id.toLowerCase().indexOf(filter.toLowerCase()) != -1) {
+    public filter(filter: string) {
+        let items = [];
+
+        for (let item of this._treeItems) {
+            if (item.id.toLowerCase().indexOf(filter.toLowerCase()) != -1) {
+                items.push(item);
+            }
+            for (let child of item.children) {
+                if (child.id.toLowerCase().indexOf(filter.toLowerCase()) != -1) {
                     items.push(item);
                 }
-                for (let child of item.children) {
-                    if (child.id.toLowerCase().indexOf(filter.toLowerCase()) != -1) {
-                        items.push(item);
-                    }
-                }
             }
-            this.update(items);
         }
-
-        /** Builds the tree panel */
-        protected abstract _getTree(): Array<TreeItem>;
+        this.update(items);
     }
-}
+
+    /** Builds the tree panel */
+    protected abstract _getTree(): Array<TreeItem>;
+}

+ 173 - 165
inspector/src/tabs/SceneTab.ts

@@ -1,189 +1,197 @@
-declare function Split(elements: HTMLElement[], options: any): void;
-module INSPECTOR {
+import { Tab } from "./Tab";
+import { Inspector } from "../Inspector";
+import { DetailPanel } from "../details/DetailPanel";
+import { TabBar } from "./TabBar";
+import { Helpers } from "../helpers/Helpers";
+import { PropertyLine } from "../details/PropertyLine";
+import { Property } from "../details/Property";
+import { StandardMaterial, Debug } from "babylonjs";
 
-    export class SceneTab extends Tab {
+declare function Split(elements: HTMLElement[], options: any): void;
 
-        private _inspector: Inspector;
-        /** The list of  channels/options that can be activated/deactivated */
-        private _actions: HTMLDivElement;
 
-        /** The list of skeleton viewer */
-        private _skeletonViewers: Array<any> = [];
+export class SceneTab extends Tab {
 
-        /** The detail of the scene */
-        private _detailsPanel: DetailPanel;
+    private _inspector: Inspector;
+    /** The list of  channels/options that can be activated/deactivated */
+    private _actions: HTMLDivElement;
 
-        constructor(tabbar: TabBar, insp: Inspector) {
-            super(tabbar, 'Scene');
-            this._inspector = insp;
+    /** The list of skeleton viewer */
+    private _skeletonViewers: Array<any> = [];
 
-            // Build the properties panel : a div that will contains the tree and the detail panel
-            this._panel = Helpers.CreateDiv('tab-panel') as HTMLDivElement;
+    /** The detail of the scene */
+    private _detailsPanel: DetailPanel;
 
-            this._actions = Helpers.CreateDiv('scene-actions', this._panel) as HTMLDivElement;
+    constructor(tabbar: TabBar, insp: Inspector) {
+        super(tabbar, 'Scene');
+        this._inspector = insp;
 
-            this._detailsPanel = new DetailPanel();
-            this._panel.appendChild(this._detailsPanel.toHtml());
+        // Build the properties panel : a div that will contains the tree and the detail panel
+        this._panel = Helpers.CreateDiv('tab-panel') as HTMLDivElement;
 
-            // build propertiesline
-            let details = [];
-            // Remove deprecated properties generating warning in console
-            let dontTakeThis = ['interFramePerfCounter', 'lastFramePerfCounter', 'evaluateActiveMeshesDurationPerfCounter', 'renderDurationPerfCounter', 'particlesDurationPerfCounter', 'spriteDuractionPerfCounter'];
-            let props = Helpers.GetAllLinesPropertiesAsString(this._inspector.scene, dontTakeThis);
+        this._actions = Helpers.CreateDiv('scene-actions', this._panel) as HTMLDivElement;
 
-            for (let propString of props) {
-                let prop = new PropertyLine(new Property(propString, this._inspector.scene));
-                details.push(prop);
-            }
-            this._detailsPanel.details = details;
+        this._detailsPanel = new DetailPanel();
+        this._panel.appendChild(this._detailsPanel.toHtml());
 
-            Split([this._actions, this._detailsPanel.toHtml()], {
-                blockDrag: this._inspector.popupMode,
-                sizes: [50, 50],
-                direction: 'vertical'
-            });
+        // build propertiesline
+        let details = [];
+        // Remove deprecated properties generating warning in console
+        let dontTakeThis = ['interFramePerfCounter', 'lastFramePerfCounter', 'evaluateActiveMeshesDurationPerfCounter', 'renderDurationPerfCounter', 'particlesDurationPerfCounter', 'spriteDuractionPerfCounter'];
+        let props = Helpers.GetAllLinesPropertiesAsString(this._inspector.scene, dontTakeThis);
 
-            // Build actions
-            {
-
-                // Rendering mode
-                let title = Helpers.CreateDiv('actions-title', this._actions);
-                title.textContent = 'Rendering mode';
-                let point = Helpers.CreateDiv('action-radio', this._actions);
-                let wireframe = Helpers.CreateDiv('action-radio', this._actions);
-                let solid = Helpers.CreateDiv('action-radio', this._actions);
-                point.textContent = 'Point';
-                wireframe.textContent = 'Wireframe';
-                solid.textContent = 'Solid';
-                if (this._inspector.scene.forcePointsCloud) {
-                    point.classList.add('active');
-                } else if (this._inspector.scene.forceWireframe) {
-                    wireframe.classList.add('active');
-                } else {
-                    solid.classList.add('active');
-                }
-                this._generateRadioAction([point, wireframe, solid]);
-                point.addEventListener('click', () => { this._inspector.scene.forcePointsCloud = true; this._inspector.scene.forceWireframe = false; });
-                wireframe.addEventListener('click', () => { this._inspector.scene.forcePointsCloud = false; this._inspector.scene.forceWireframe = true; });
-                solid.addEventListener('click', () => { this._inspector.scene.forcePointsCloud = false; this._inspector.scene.forceWireframe = false; });
-
-                // Textures
-                title = Helpers.CreateDiv('actions-title', this._actions);
-                title.textContent = 'Textures channels';
-                this._generateActionLine('Diffuse Texture', BABYLON.StandardMaterial.DiffuseTextureEnabled, (b: boolean) => { BABYLON.StandardMaterial.DiffuseTextureEnabled = b });
-                this._generateActionLine('Ambient Texture', BABYLON.StandardMaterial.AmbientTextureEnabled, (b: boolean) => { BABYLON.StandardMaterial.AmbientTextureEnabled = b });
-                this._generateActionLine('Specular Texture', BABYLON.StandardMaterial.SpecularTextureEnabled, (b: boolean) => { BABYLON.StandardMaterial.SpecularTextureEnabled = b });
-                this._generateActionLine('Emissive Texture', BABYLON.StandardMaterial.EmissiveTextureEnabled, (b: boolean) => { BABYLON.StandardMaterial.EmissiveTextureEnabled = b });
-                this._generateActionLine('Bump Texture', BABYLON.StandardMaterial.BumpTextureEnabled, (b: boolean) => { BABYLON.StandardMaterial.BumpTextureEnabled = b });
-                this._generateActionLine('Opacity Texture', BABYLON.StandardMaterial.OpacityTextureEnabled, (b: boolean) => { BABYLON.StandardMaterial.OpacityTextureEnabled = b });
-                this._generateActionLine('Reflection Texture', BABYLON.StandardMaterial.ReflectionTextureEnabled, (b: boolean) => { BABYLON.StandardMaterial.ReflectionTextureEnabled = b });
-                this._generateActionLine('Refraction Texture', BABYLON.StandardMaterial.RefractionTextureEnabled, (b: boolean) => { BABYLON.StandardMaterial.RefractionTextureEnabled = b });
-                this._generateActionLine('ColorGrading', BABYLON.StandardMaterial.ColorGradingTextureEnabled, (b: boolean) => { BABYLON.StandardMaterial.ColorGradingTextureEnabled = b });
-                this._generateActionLine('Lightmap Texture', BABYLON.StandardMaterial.LightmapTextureEnabled, (b: boolean) => { BABYLON.StandardMaterial.LightmapTextureEnabled = b });
-                this._generateActionLine('Fresnel', BABYLON.StandardMaterial.FresnelEnabled, (b: boolean) => { BABYLON.StandardMaterial.FresnelEnabled = b });
-
-                // Options
-                title = Helpers.CreateDiv('actions-title', this._actions);
-                title.textContent = 'Options';
-                this._generateActionLine('Animations', this._inspector.scene.animationsEnabled, (b: boolean) => { this._inspector.scene.animationsEnabled = b });
-                this._generateActionLine('Collisions', this._inspector.scene.collisionsEnabled, (b: boolean) => { this._inspector.scene.collisionsEnabled = b });
-                this._generateActionLine('Fog', this._inspector.scene.fogEnabled, (b: boolean) => { this._inspector.scene.fogEnabled = b });
-                this._generateActionLine('Lens flares', this._inspector.scene.lensFlaresEnabled, (b: boolean) => { this._inspector.scene.lensFlaresEnabled = b });
-                this._generateActionLine('Lights', this._inspector.scene.lightsEnabled, (b: boolean) => { this._inspector.scene.lightsEnabled = b });
-                this._generateActionLine('Particles', this._inspector.scene.particlesEnabled, (b: boolean) => { this._inspector.scene.particlesEnabled = b });
-                this._generateActionLine('Post-processes', this._inspector.scene.postProcessesEnabled, (b: boolean) => { this._inspector.scene.postProcessesEnabled = b });
-                this._generateActionLine('Probes', this._inspector.scene.probesEnabled, (b: boolean) => { this._inspector.scene.probesEnabled = b });
-                this._generateActionLine('Procedural textures', this._inspector.scene.proceduralTexturesEnabled, (b: boolean) => { this._inspector.scene.proceduralTexturesEnabled = b });
-                this._generateActionLine('Render targets', this._inspector.scene.renderTargetsEnabled, (b: boolean) => { this._inspector.scene.renderTargetsEnabled = b });
-                this._generateActionLine('Shadows', this._inspector.scene.shadowsEnabled, (b: boolean) => { this._inspector.scene.shadowsEnabled = b });
-                this._generateActionLine('Skeletons', this._inspector.scene.skeletonsEnabled, (b: boolean) => { this._inspector.scene.skeletonsEnabled = b });
-                this._generateActionLine('Sprites', this._inspector.scene.spritesEnabled, (b: boolean) => { this._inspector.scene.spritesEnabled = b });
-                this._generateActionLine('Textures', this._inspector.scene.texturesEnabled, (b: boolean) => { this._inspector.scene.texturesEnabled = b });
-
-                // Audio
-                title = Helpers.CreateDiv('actions-title', this._actions);
-                title.textContent = 'Audio';
-                let headphones = Helpers.CreateDiv('action-radio', this._actions);
-                let normalSpeaker = Helpers.CreateDiv('action-radio', this._actions);
-                this._generateActionLine('Disable audio', !this._inspector.scene.audioEnabled, (b: boolean) => { this._inspector.scene.audioEnabled = !b });
-                headphones.textContent = 'Headphones';
-                normalSpeaker.textContent = 'Normal speakers';
-                this._generateRadioAction([headphones, normalSpeaker]);
-                if (this._inspector.scene.headphone) {
-                    headphones.classList.add('active');
-                } else {
-                    normalSpeaker.classList.add('active');
-                }
-                headphones.addEventListener('click', () => { this._inspector.scene.headphone = true; });
-                normalSpeaker.addEventListener('click', () => { this._inspector.scene.headphone = false; });
-
-                // Viewers
-                title = Helpers.CreateDiv('actions-title', this._actions);
-                title.textContent = 'Viewer';
-                this._generateActionLine('Skeletons', false, (b: boolean) => {
-                    if (b) {
-                        for (var index = 0; index < this._inspector.scene.meshes.length; index++) {
-                            var mesh = this._inspector.scene.meshes[index];
-                            if (mesh.skeleton) {
-                                var found = false;
-                                for (var sIndex = 0; sIndex < this._skeletonViewers.length; sIndex++) {
-                                    if (this._skeletonViewers[sIndex].skeleton === mesh.skeleton) {
-                                        found = true;
-                                        break;
-                                    }
-                                }
-                                if (found) {
-                                    continue;
+        for (let propString of props) {
+            let prop = new PropertyLine(new Property(propString, this._inspector.scene));
+            details.push(prop);
+        }
+        this._detailsPanel.details = details;
+
+        Split([this._actions, this._detailsPanel.toHtml()], {
+            blockDrag: this._inspector.popupMode,
+            sizes: [50, 50],
+            direction: 'vertical'
+        });
+
+        // Build actions
+        {
+
+            // Rendering mode
+            let title = Helpers.CreateDiv('actions-title', this._actions);
+            title.textContent = 'Rendering mode';
+            let point = Helpers.CreateDiv('action-radio', this._actions);
+            let wireframe = Helpers.CreateDiv('action-radio', this._actions);
+            let solid = Helpers.CreateDiv('action-radio', this._actions);
+            point.textContent = 'Point';
+            wireframe.textContent = 'Wireframe';
+            solid.textContent = 'Solid';
+            if (this._inspector.scene.forcePointsCloud) {
+                point.classList.add('active');
+            } else if (this._inspector.scene.forceWireframe) {
+                wireframe.classList.add('active');
+            } else {
+                solid.classList.add('active');
+            }
+            this._generateRadioAction([point, wireframe, solid]);
+            point.addEventListener('click', () => { this._inspector.scene.forcePointsCloud = true; this._inspector.scene.forceWireframe = false; });
+            wireframe.addEventListener('click', () => { this._inspector.scene.forcePointsCloud = false; this._inspector.scene.forceWireframe = true; });
+            solid.addEventListener('click', () => { this._inspector.scene.forcePointsCloud = false; this._inspector.scene.forceWireframe = false; });
+
+            // Textures
+            title = Helpers.CreateDiv('actions-title', this._actions);
+            title.textContent = 'Textures channels';
+            this._generateActionLine('Diffuse Texture', StandardMaterial.DiffuseTextureEnabled, (b: boolean) => { StandardMaterial.DiffuseTextureEnabled = b });
+            this._generateActionLine('Ambient Texture', StandardMaterial.AmbientTextureEnabled, (b: boolean) => { StandardMaterial.AmbientTextureEnabled = b });
+            this._generateActionLine('Specular Texture', StandardMaterial.SpecularTextureEnabled, (b: boolean) => { StandardMaterial.SpecularTextureEnabled = b });
+            this._generateActionLine('Emissive Texture', StandardMaterial.EmissiveTextureEnabled, (b: boolean) => { StandardMaterial.EmissiveTextureEnabled = b });
+            this._generateActionLine('Bump Texture', StandardMaterial.BumpTextureEnabled, (b: boolean) => { StandardMaterial.BumpTextureEnabled = b });
+            this._generateActionLine('Opacity Texture', StandardMaterial.OpacityTextureEnabled, (b: boolean) => { StandardMaterial.OpacityTextureEnabled = b });
+            this._generateActionLine('Reflection Texture', StandardMaterial.ReflectionTextureEnabled, (b: boolean) => { StandardMaterial.ReflectionTextureEnabled = b });
+            this._generateActionLine('Refraction Texture', StandardMaterial.RefractionTextureEnabled, (b: boolean) => { StandardMaterial.RefractionTextureEnabled = b });
+            this._generateActionLine('ColorGrading', StandardMaterial.ColorGradingTextureEnabled, (b: boolean) => { StandardMaterial.ColorGradingTextureEnabled = b });
+            this._generateActionLine('Lightmap Texture', StandardMaterial.LightmapTextureEnabled, (b: boolean) => { StandardMaterial.LightmapTextureEnabled = b });
+            this._generateActionLine('Fresnel', StandardMaterial.FresnelEnabled, (b: boolean) => { StandardMaterial.FresnelEnabled = b });
+
+            // Options
+            title = Helpers.CreateDiv('actions-title', this._actions);
+            title.textContent = 'Options';
+            this._generateActionLine('Animations', this._inspector.scene.animationsEnabled, (b: boolean) => { this._inspector.scene.animationsEnabled = b });
+            this._generateActionLine('Collisions', this._inspector.scene.collisionsEnabled, (b: boolean) => { this._inspector.scene.collisionsEnabled = b });
+            this._generateActionLine('Fog', this._inspector.scene.fogEnabled, (b: boolean) => { this._inspector.scene.fogEnabled = b });
+            this._generateActionLine('Lens flares', this._inspector.scene.lensFlaresEnabled, (b: boolean) => { this._inspector.scene.lensFlaresEnabled = b });
+            this._generateActionLine('Lights', this._inspector.scene.lightsEnabled, (b: boolean) => { this._inspector.scene.lightsEnabled = b });
+            this._generateActionLine('Particles', this._inspector.scene.particlesEnabled, (b: boolean) => { this._inspector.scene.particlesEnabled = b });
+            this._generateActionLine('Post-processes', this._inspector.scene.postProcessesEnabled, (b: boolean) => { this._inspector.scene.postProcessesEnabled = b });
+            this._generateActionLine('Probes', this._inspector.scene.probesEnabled, (b: boolean) => { this._inspector.scene.probesEnabled = b });
+            this._generateActionLine('Procedural textures', this._inspector.scene.proceduralTexturesEnabled, (b: boolean) => { this._inspector.scene.proceduralTexturesEnabled = b });
+            this._generateActionLine('Render targets', this._inspector.scene.renderTargetsEnabled, (b: boolean) => { this._inspector.scene.renderTargetsEnabled = b });
+            this._generateActionLine('Shadows', this._inspector.scene.shadowsEnabled, (b: boolean) => { this._inspector.scene.shadowsEnabled = b });
+            this._generateActionLine('Skeletons', this._inspector.scene.skeletonsEnabled, (b: boolean) => { this._inspector.scene.skeletonsEnabled = b });
+            this._generateActionLine('Sprites', this._inspector.scene.spritesEnabled, (b: boolean) => { this._inspector.scene.spritesEnabled = b });
+            this._generateActionLine('Textures', this._inspector.scene.texturesEnabled, (b: boolean) => { this._inspector.scene.texturesEnabled = b });
+
+            // Audio
+            title = Helpers.CreateDiv('actions-title', this._actions);
+            title.textContent = 'Audio';
+            let headphones = Helpers.CreateDiv('action-radio', this._actions);
+            let normalSpeaker = Helpers.CreateDiv('action-radio', this._actions);
+            this._generateActionLine('Disable audio', !this._inspector.scene.audioEnabled, (b: boolean) => { this._inspector.scene.audioEnabled = !b });
+            headphones.textContent = 'Headphones';
+            normalSpeaker.textContent = 'Normal speakers';
+            this._generateRadioAction([headphones, normalSpeaker]);
+            if (this._inspector.scene.headphone) {
+                headphones.classList.add('active');
+            } else {
+                normalSpeaker.classList.add('active');
+            }
+            headphones.addEventListener('click', () => { this._inspector.scene.headphone = true; });
+            normalSpeaker.addEventListener('click', () => { this._inspector.scene.headphone = false; });
+
+            // Viewers
+            title = Helpers.CreateDiv('actions-title', this._actions);
+            title.textContent = 'Viewer';
+            this._generateActionLine('Skeletons', false, (b: boolean) => {
+                if (b) {
+                    for (var index = 0; index < this._inspector.scene.meshes.length; index++) {
+                        var mesh = this._inspector.scene.meshes[index];
+                        if (mesh.skeleton) {
+                            var found = false;
+                            for (var sIndex = 0; sIndex < this._skeletonViewers.length; sIndex++) {
+                                if (this._skeletonViewers[sIndex].skeleton === mesh.skeleton) {
+                                    found = true;
+                                    break;
                                 }
-                                var viewer = new BABYLON.Debug.SkeletonViewer(mesh.skeleton, mesh, this._inspector.scene);
-                                viewer.isEnabled = true;
-                                this._skeletonViewers.push(viewer);
                             }
+                            if (found) {
+                                continue;
+                            }
+                            var viewer = new Debug.SkeletonViewer(mesh.skeleton, mesh, this._inspector.scene);
+                            viewer.isEnabled = true;
+                            this._skeletonViewers.push(viewer);
                         }
-                    } else {
-                        for (var index = 0; index < this._skeletonViewers.length; index++) {
-                            this._skeletonViewers[index].dispose();
-                        }
-                        this._skeletonViewers = [];
                     }
-                });
-            }
+                } else {
+                    for (var index = 0; index < this._skeletonViewers.length; index++) {
+                        this._skeletonViewers[index].dispose();
+                    }
+                    this._skeletonViewers = [];
+                }
+            });
         }
+    }
 
-        /** Overrides super.dispose */
-        public dispose() {
-            this._detailsPanel.dispose();
-        }
+    /** Overrides super.dispose */
+    public dispose() {
+        this._detailsPanel.dispose();
+    }
 
-        /** generates a div which correspond to an option that can be activated/deactivated */
-        private _generateActionLine(name: string, initValue: boolean, action: (b: boolean) => void) {
-            let div = Helpers.CreateDiv('scene-actions', this._actions);
-            div.textContent = name;
-            div.classList.add('action');
-            if (initValue) {
-                div.classList.add('active');
-            }
-            div.addEventListener('click', (e) => {
-                div.classList.toggle('active');
-                let isActivated = div.classList.contains('active');
-                action(isActivated);
-            })
+    /** generates a div which correspond to an option that can be activated/deactivated */
+    private _generateActionLine(name: string, initValue: boolean, action: (b: boolean) => void) {
+        let div = Helpers.CreateDiv('scene-actions', this._actions);
+        div.textContent = name;
+        div.classList.add('action');
+        if (initValue) {
+            div.classList.add('active');
         }
+        div.addEventListener('click', (e) => {
+            div.classList.toggle('active');
+            let isActivated = div.classList.contains('active');
+            action(isActivated);
+        })
+    }
 
-        /** 
-         * Add a click action for all given elements : 
-         * the clicked element is set as active, all others elements are deactivated
-         */
-        private _generateRadioAction(arr: Array<HTMLElement>) {
-            let active = (elem: HTMLElement, evt: any) => {
-                for (let e of arr) {
-                    e.classList.remove('active');
-                }
-                elem.classList.add('active');
-            }
-            for (let elem of arr) {
-                elem.addEventListener('click', active.bind(this, elem));
+    /** 
+     * Add a click action for all given elements : 
+     * the clicked element is set as active, all others elements are deactivated
+     */
+    private _generateRadioAction(arr: Array<HTMLElement>) {
+        let active = (elem: HTMLElement, evt: any) => {
+            for (let e of arr) {
+                e.classList.remove('active');
             }
+            elem.classList.add('active');
+        }
+        for (let elem of arr) {
+            elem.addEventListener('click', active.bind(this, elem));
         }
     }
-}
+}

+ 21 - 19
inspector/src/tabs/SoundTab.ts

@@ -1,26 +1,28 @@
-module INSPECTOR {
+import { SoundAdapter } from "../adapters/SoundAdapter";
+import { Inspector } from "../Inspector";
+import { TreeItem } from "../tree/TreeItem";
+import { PropertyTab } from "./PropertyTab";
+import { TabBar } from "./TabBar";
 
-    export class SoundTab extends PropertyTab {
+export class SoundTab extends PropertyTab {
 
-        constructor(tabbar: TabBar, inspector: Inspector) {
-            super(tabbar, 'Audio', inspector);
-        }
-        /* Overrides super */
-        protected _getTree(): Array<TreeItem> {
-            let arr = new Array<TreeItem>();
+    constructor(tabbar: TabBar, inspector: Inspector) {
+        super(tabbar, 'Audio', inspector);
+    }
+    /* Overrides super */
+    protected _getTree(): Array<TreeItem> {
+        let arr = new Array<TreeItem>();
 
-            // get all cameras from the first scene
-            let instances = this._inspector.scene;
-            for (let sounds of instances.soundTracks) {
-                let sound = sounds.soundCollection;
-                sound.forEach(element => {
-                    arr.push(new TreeItem(this, new SoundAdapter(element)));
-                });
+        // get all cameras from the first scene
+        let instances = this._inspector.scene;
+        for (let sounds of instances.soundTracks) {
+            let sound = sounds.soundCollection;
+            sound.forEach(element => {
+                arr.push(new TreeItem(this, new SoundAdapter(element)));
+            });
 
-            }
-            return arr;
         }
-
+        return arr;
     }
 
-}
+}

+ 370 - 367
inspector/src/tabs/StatsTab.ts

@@ -1,395 +1,398 @@
-module INSPECTOR {
+import { Tab } from "./Tab";
+import { Inspector } from "../Inspector";
+import { Scene, Engine, Nullable, SceneInstrumentation, EngineInstrumentation, Tools } from "babylonjs";
+import { TabBar } from "./TabBar";
+import { Helpers } from "../helpers/Helpers";
 
-    export class StatsTab extends Tab {
+export class StatsTab extends Tab {
 
-        private _inspector: Inspector;
+    private _inspector: Inspector;
 
-        /** 
-         * Properties in this array will be updated
-         * in a render loop - Mostly stats properties
-         */
-        private _updatableProperties: Array<{ elem: HTMLElement, updateFct: () => string }> = [];
+    /** 
+     * Properties in this array will be updated
+     * in a render loop - Mostly stats properties
+     */
+    private _updatableProperties: Array<{ elem: HTMLElement, updateFct: () => string }> = [];
 
-        private _scene: BABYLON.Scene;
-        private _engine: BABYLON.Engine;
-        private _glInfo: any;
+    private _scene: Scene;
+    private _engine: Engine;
+    private _glInfo: any;
 
-        private _updateLoopHandler: any;
-        private _refreshRateCounter: any;
-        private refreshRate: any;
+    private _updateLoopHandler: any;
+    private _refreshRateCounter: any;
+    private refreshRate: any;
 
-        private _sceneInstrumentation: BABYLON.Nullable<BABYLON.SceneInstrumentation>;
-        private _engineInstrumentation: BABYLON.Nullable<BABYLON.EngineInstrumentation>;
+    private _sceneInstrumentation: Nullable<SceneInstrumentation>;
+    private _engineInstrumentation: Nullable<EngineInstrumentation>;
 
-        private _inputElement: HTMLInputElement;
+    private _inputElement: HTMLInputElement;
 
-        private _connectToInstrumentation() {
-            if (this._sceneInstrumentation) {
-                return;
-            }
-
-            this._sceneInstrumentation = new BABYLON.SceneInstrumentation(this._scene);
-            this._sceneInstrumentation.captureActiveMeshesEvaluationTime = true;
-            this._sceneInstrumentation.captureRenderTargetsRenderTime = true;
-            this._sceneInstrumentation.captureFrameTime = true;
-            this._sceneInstrumentation.captureRenderTime = true;
-            this._sceneInstrumentation.captureInterFrameTime = true;
-            this._sceneInstrumentation.captureParticlesRenderTime = true;
-            this._sceneInstrumentation.captureSpritesRenderTime = true;
-            this._sceneInstrumentation.capturePhysicsTime = true;
-            this._sceneInstrumentation.captureAnimationsTime = true;
-
-            this._engineInstrumentation = new BABYLON.EngineInstrumentation(this._engine);
-            this._engineInstrumentation.captureGPUFrameTime = true;
+    private _connectToInstrumentation() {
+        if (this._sceneInstrumentation) {
+            return;
         }
 
-        constructor(tabbar: TabBar, insp: Inspector) {
-            super(tabbar, 'Stats');
+        this._sceneInstrumentation = new SceneInstrumentation(this._scene);
+        this._sceneInstrumentation.captureActiveMeshesEvaluationTime = true;
+        this._sceneInstrumentation.captureRenderTargetsRenderTime = true;
+        this._sceneInstrumentation.captureFrameTime = true;
+        this._sceneInstrumentation.captureRenderTime = true;
+        this._sceneInstrumentation.captureInterFrameTime = true;
+        this._sceneInstrumentation.captureParticlesRenderTime = true;
+        this._sceneInstrumentation.captureSpritesRenderTime = true;
+        this._sceneInstrumentation.capturePhysicsTime = true;
+        this._sceneInstrumentation.captureAnimationsTime = true;
+
+        this._engineInstrumentation = new EngineInstrumentation(this._engine);
+        this._engineInstrumentation.captureGPUFrameTime = true;
+    }
 
-            this._inspector = insp;
+    constructor(tabbar: TabBar, insp: Inspector) {
+        super(tabbar, 'Stats');
 
-            this._scene = this._inspector.scene;
-            this._engine = this._scene.getEngine();
-            this._glInfo = this._engine.getGlInfo();
+        this._inspector = insp;
 
-            this._connectToInstrumentation();
+        this._scene = this._inspector.scene;
+        this._engine = this._scene.getEngine();
+        this._glInfo = this._engine.getGlInfo();
 
-            // Build the stats panel: a div that will contains all stats
-            this._panel = Helpers.CreateDiv('tab-panel') as HTMLDivElement;
-            this._panel.classList.add("stats-panel")
-
-            let title = Helpers.CreateDiv('stat-title1', this._panel);
-            let fpsSpan = Helpers.CreateElement('span', 'stats-fps');
-            this._updatableProperties.push({
-                elem: fpsSpan,
-                updateFct: () => { return BABYLON.Tools.Format(this._inspector.scene.getEngine().getFps(), 0) + " fps" }
-            });
-
-            let versionSpan = Helpers.CreateElement('span');
-            versionSpan.textContent = `Babylon.js v${BABYLON.Engine.Version} - `;
-            title.appendChild(versionSpan);
-            title.appendChild(fpsSpan);
-
-            this._updateLoopHandler = this._update.bind(this);
-            this._refreshRateCounter = 0;
-            this.refreshRate = 4;
-
-            // Count block
-            title = Helpers.CreateDiv('stat-title2', this._panel);
-            title.textContent = "Count";
-            {
-                this._createStatLabel("Total meshes", this._panel);
-                let elemValue = Helpers.CreateDiv('stat-value', this._panel);
-                this._updatableProperties.push({
-                    elem: elemValue,
-                    updateFct: () => { return this._scene.meshes.length.toString() }
-                });
-
-                this._createStatLabel("Draw calls", this._panel);
-                elemValue = Helpers.CreateDiv('stat-value', this._panel);
-                this._updatableProperties.push({
-                    elem: elemValue,
-                    updateFct: () => { return this._sceneInstrumentation!.drawCallsCounter.current.toString() }
-                });
-
-                this._createStatLabel("Texture collisions", this._panel);
-                elemValue = Helpers.CreateDiv('stat-value', this._panel);
-                this._updatableProperties.push({
-                    elem: elemValue,
-                    updateFct: () => { return this._sceneInstrumentation!.textureCollisionsCounter.current.toString() }
-                });
-
-                this._createStatLabel("Total lights", this._panel);
-                elemValue = Helpers.CreateDiv('stat-value', this._panel);
-                this._updatableProperties.push({
-                    elem: elemValue,
-                    updateFct: () => { return this._scene.lights.length.toString() }
-                });
-
-                this._createStatLabel("Total vertices", this._panel);
-                elemValue = Helpers.CreateDiv('stat-value', this._panel);
-                this._updatableProperties.push({
-                    elem: elemValue,
-                    updateFct: () => { return this._scene.getTotalVertices().toString() }
-                });
-
-                this._createStatLabel("Total materials", this._panel);
-                elemValue = Helpers.CreateDiv('stat-value', this._panel);
-                this._updatableProperties.push({
-                    elem: elemValue,
-                    updateFct: () => { return this._scene.materials.length.toString() }
-                });
-
-                this._createStatLabel("Total textures", this._panel);
-                elemValue = Helpers.CreateDiv('stat-value', this._panel);
-                this._updatableProperties.push({
-                    elem: elemValue,
-                    updateFct: () => { return this._scene.textures.length.toString() }
-                });
-
-                this._createStatLabel("Active meshes", this._panel);
-                elemValue = Helpers.CreateDiv('stat-value', this._panel);
-                this._updatableProperties.push({
-                    elem: elemValue,
-                    updateFct: () => { return this._scene.getActiveMeshes().length.toString() }
-                });
-
-                this._createStatLabel("Active indices", this._panel);
-                elemValue = Helpers.CreateDiv('stat-value', this._panel);
-                this._updatableProperties.push({
-                    elem: elemValue,
-                    updateFct: () => { return this._scene.getActiveIndices().toString() }
-                });
-
-                this._createStatLabel("Active bones", this._panel);
-                elemValue = Helpers.CreateDiv('stat-value', this._panel);
-                this._updatableProperties.push({
-                    elem: elemValue,
-                    updateFct: () => { return this._scene.getActiveBones().toString() }
-                });
-
-                this._createStatLabel("Active particles", this._panel);
-                elemValue = Helpers.CreateDiv('stat-value', this._panel);
-                this._updatableProperties.push({
-                    elem: elemValue,
-                    updateFct: () => { return this._scene.getActiveParticles().toString() }
-                });
-            }
+        this._connectToInstrumentation();
 
-            title = Helpers.CreateDiv('stat-title2', this._panel);
-            title.textContent = "Duration";
-            {
-                this._createStatLabel("Properties refresh rate (per second)", this._panel);
-                let elemValue = Helpers.CreateDiv('stat-value', this._panel);
-                this._inputElement = Inspector.DOCUMENT.createElement('input');
-                this._inputElement.value = this.refreshRate;
-                elemValue.appendChild(this._inputElement);
-                this._inputElement.addEventListener('keyup', (evt : KeyboardEvent)=> {
-                this.refreshRate = this._inputElement.value;
-                })
-                this._createStatLabel("Meshes selection", this._panel);
-                elemValue = Helpers.CreateDiv('stat-value', this._panel);
-                this._updatableProperties.push({
-                    elem: elemValue,
-                    updateFct: () => { return BABYLON.Tools.Format(this._sceneInstrumentation!.activeMeshesEvaluationTimeCounter.current) }
-                });
-                this._createStatLabel("Render targets", this._panel);
-                elemValue = Helpers.CreateDiv('stat-value', this._panel);
-                this._updatableProperties.push({
-                    elem: elemValue,
-                    updateFct: () => { return BABYLON.Tools.Format(this._sceneInstrumentation!.renderTargetsRenderTimeCounter.current) }
-                });
-                this._createStatLabel("Particles", this._panel);
-                elemValue = Helpers.CreateDiv('stat-value', this._panel);
-                this._updatableProperties.push({
-                    elem: elemValue,
-                    updateFct: () => { return BABYLON.Tools.Format(this._sceneInstrumentation!.particlesRenderTimeCounter.current) }
-                });
-                this._createStatLabel("Sprites", this._panel);
-                elemValue = Helpers.CreateDiv('stat-value', this._panel);
-                this._updatableProperties.push({
-                    elem: elemValue,
-                    updateFct: () => { return BABYLON.Tools.Format(this._sceneInstrumentation!.spritesRenderTimeCounter.current) }
-                });
-                this._createStatLabel("Animations", this._panel);
-                elemValue = Helpers.CreateDiv('stat-value', this._panel);
-                this._updatableProperties.push({
-                    elem: elemValue,
-                    updateFct: () => { return BABYLON.Tools.Format(this._sceneInstrumentation!.animationsTimeCounter.current) }
-                });
-                this._createStatLabel("Physics", this._panel);
-                elemValue = Helpers.CreateDiv('stat-value', this._panel);
-                this._updatableProperties.push({
-                    elem: elemValue,
-                    updateFct: () => { return BABYLON.Tools.Format(this._sceneInstrumentation!.physicsTimeCounter.current) }
-                });
-                this._createStatLabel("Render", this._panel);
-                elemValue = Helpers.CreateDiv('stat-value', this._panel);
-                this._updatableProperties.push({
-                    elem: elemValue,
-                    updateFct: () => { return BABYLON.Tools.Format(this._sceneInstrumentation!.renderTimeCounter.current) }
-                });
-                this._createStatLabel("Frame", this._panel);
-                elemValue = Helpers.CreateDiv('stat-value', this._panel);
-                this._updatableProperties.push({
-                    elem: elemValue,
-                    updateFct: () => { return BABYLON.Tools.Format(this._sceneInstrumentation!.frameTimeCounter.current) }
-                });
-                this._createStatLabel("Inter-frame", this._panel);
-                elemValue = Helpers.CreateDiv('stat-value', this._panel);
-                this._updatableProperties.push({
-                    elem: elemValue,
-                    updateFct: () => { return BABYLON.Tools.Format(this._sceneInstrumentation!.interFrameTimeCounter.current) }
-                });
-                this._createStatLabel("GPU Frame time", this._panel);
-                elemValue = Helpers.CreateDiv('stat-value', this._panel);
-                this._updatableProperties.push({
-                    elem: elemValue,
-                    updateFct: () => { return BABYLON.Tools.Format(this._engineInstrumentation!.gpuFrameTimeCounter.current * 0.000001) }
-                });
-                this._createStatLabel("GPU Frame time (average)", this._panel);
-                elemValue = Helpers.CreateDiv('stat-value', this._panel);
-                this._updatableProperties.push({
-                    elem: elemValue,
-                    updateFct: () => { return BABYLON.Tools.Format(this._engineInstrumentation!.gpuFrameTimeCounter.average * 0.000001) }
-                });
-                this._createStatLabel("Potential FPS", this._panel);
-                elemValue = Helpers.CreateDiv('stat-value', this._panel);
-                this._updatableProperties.push({
-                    elem: elemValue,
-                    updateFct: () => { return BABYLON.Tools.Format(1000.0 / this._sceneInstrumentation!.frameTimeCounter.current, 0) }
-                });
-                this._createStatLabel("Resolution", this._panel);
-                elemValue = Helpers.CreateDiv('stat-value', this._panel);
-                this._updatableProperties.push({
-                    elem: elemValue,
-                    updateFct: () => { return this._engine.getRenderWidth() + "x" + this._engine.getRenderHeight() }
-                });
-            }
+        // Build the stats panel: a div that will contains all stats
+        this._panel = Helpers.CreateDiv('tab-panel') as HTMLDivElement;
+        this._panel.classList.add("stats-panel")
 
-            title = Helpers.CreateDiv('stat-title2', this._panel);
-            title.textContent = "Extensions";
-            {
-                this._createStatLabel("Std derivatives", this._panel);
-                let elemValue = Helpers.CreateDiv('stat-value', this._panel);
-                this._updatableProperties.push({
-                    elem: elemValue,
-                    updateFct: () => { return (this._engine.getCaps().standardDerivatives ? "Yes" : "No") }
-                });
-                this._createStatLabel("Compressed textures", this._panel);
-                elemValue = Helpers.CreateDiv('stat-value', this._panel);
-                this._updatableProperties.push({
-                    elem: elemValue,
-                    updateFct: () => { return (this._engine.getCaps().s3tc ? "Yes" : "No") }
-                });
-                this._createStatLabel("Hardware instances", this._panel);
-                elemValue = Helpers.CreateDiv('stat-value', this._panel);
-                this._updatableProperties.push({
-                    elem: elemValue,
-                    updateFct: () => { return (this._engine.getCaps().instancedArrays ? "Yes" : "No") }
-                });
-                this._createStatLabel("Texture float", this._panel);
-                elemValue = Helpers.CreateDiv('stat-value', this._panel);
-                this._updatableProperties.push({
-                    elem: elemValue,
-                    updateFct: () => { return (this._engine.getCaps().textureFloat ? "Yes" : "No") }
-                });
-                this._createStatLabel("32bits indices", this._panel);
-                elemValue = Helpers.CreateDiv('stat-value', this._panel);
-                this._updatableProperties.push({
-                    elem: elemValue,
-                    updateFct: () => { return (this._engine.getCaps().uintIndices ? "Yes" : "No") }
-                });
-                this._createStatLabel("Fragment depth", this._panel);
-                elemValue = Helpers.CreateDiv('stat-value', this._panel);
-                this._updatableProperties.push({
-                    elem: elemValue,
-                    updateFct: () => { return (this._engine.getCaps().fragmentDepthSupported ? "Yes" : "No") }
-                });
-                this._createStatLabel("High precision shaders", this._panel);
-                elemValue = Helpers.CreateDiv('stat-value', this._panel);
-                this._updatableProperties.push({
-                    elem: elemValue,
-                    updateFct: () => { return (this._engine.getCaps().highPrecisionShaderSupported ? "Yes" : "No") }
-                });
-                this._createStatLabel("Draw buffers", this._panel);
-                elemValue = Helpers.CreateDiv('stat-value', this._panel);
-                this._updatableProperties.push({
-                    elem: elemValue,
-                    updateFct: () => { return (this._engine.getCaps().drawBuffersExtension ? "Yes" : "No") }
-                });
-                this._createStatLabel("Vertex array object", this._panel);
-                elemValue = Helpers.CreateDiv('stat-value', this._panel);
-                this._updatableProperties.push({
-                    elem: elemValue,
-                    updateFct: () => { return (this._engine.getCaps().vertexArrayObject ? "Yes" : "No") }
-                });
-                this._createStatLabel("Timer query", this._panel);
-                elemValue = Helpers.CreateDiv('stat-value', this._panel);
-                this._updatableProperties.push({
-                    elem: elemValue,
-                    updateFct: () => { return (this._engine.getCaps().timerQuery ? "Yes" : "No") }
-                });
-            }
+        let title = Helpers.CreateDiv('stat-title1', this._panel);
+        let fpsSpan = Helpers.CreateElement('span', 'stats-fps');
+        this._updatableProperties.push({
+            elem: fpsSpan,
+            updateFct: () => { return Tools.Format(this._inspector.scene.getEngine().getFps(), 0) + " fps" }
+        });
 
-            title = Helpers.CreateDiv('stat-title2', this._panel);
-            title.textContent = "Caps.";
-            {
-                this._createStatLabel("Stencil", this._panel);
-                let elemValue = Helpers.CreateDiv('stat-value', this._panel);
-                this._updatableProperties.push({
-                    elem: elemValue,
-                    updateFct: () => { return (this._engine.isStencilEnable ? "Enabled" : "Disabled") }
-                });
-                this._createStatLabel("Max textures units", this._panel);
-                elemValue = Helpers.CreateDiv('stat-value', this._panel);
-                this._updatableProperties.push({
-                    elem: elemValue,
-                    updateFct: () => { return this._engine.getCaps().maxTexturesImageUnits.toString() }
-                });
-                this._createStatLabel("Max textures size", this._panel);
-                elemValue = Helpers.CreateDiv('stat-value', this._panel);
-                this._updatableProperties.push({
-                    elem: elemValue,
-                    updateFct: () => { return this._engine.getCaps().maxTextureSize.toString() }
-                });
-                this._createStatLabel("Max anisotropy", this._panel);
-                elemValue = Helpers.CreateDiv('stat-value', this._panel);
-                this._updatableProperties.push({
-                    elem: elemValue,
-                    updateFct: () => { return this._engine.getCaps().maxAnisotropy.toString() }
-                });
-            }
-            title = Helpers.CreateDiv('stat-title2', this._panel);
-            title.textContent = "Info";
-            {
-                let elemValue = Helpers.CreateDiv('stat-infos', this._panel);
-                this._updatableProperties.push({
-                    elem: elemValue,
-                    updateFct: () => { return "WebGL v" + this._engine.webGLVersion + " - " + this._glInfo.version + " - " + this._glInfo.renderer }
-                });
-            }
+        let versionSpan = Helpers.CreateElement('span');
+        versionSpan.textContent = `js v${Engine.Version} - `;
+        title.appendChild(versionSpan);
+        title.appendChild(fpsSpan);
+
+        this._updateLoopHandler = this._update.bind(this);
+        this._refreshRateCounter = 0;
+        this.refreshRate = 4;
+
+        // Count block
+        title = Helpers.CreateDiv('stat-title2', this._panel);
+        title.textContent = "Count";
+        {
+            this._createStatLabel("Total meshes", this._panel);
+            let elemValue = Helpers.CreateDiv('stat-value', this._panel);
+            this._updatableProperties.push({
+                elem: elemValue,
+                updateFct: () => { return this._scene.meshes.length.toString() }
+            });
+
+            this._createStatLabel("Draw calls", this._panel);
+            elemValue = Helpers.CreateDiv('stat-value', this._panel);
+            this._updatableProperties.push({
+                elem: elemValue,
+                updateFct: () => { return this._sceneInstrumentation!.drawCallsCounter.current.toString() }
+            });
+
+            this._createStatLabel("Texture collisions", this._panel);
+            elemValue = Helpers.CreateDiv('stat-value', this._panel);
+            this._updatableProperties.push({
+                elem: elemValue,
+                updateFct: () => { return this._sceneInstrumentation!.textureCollisionsCounter.current.toString() }
+            });
+
+            this._createStatLabel("Total lights", this._panel);
+            elemValue = Helpers.CreateDiv('stat-value', this._panel);
+            this._updatableProperties.push({
+                elem: elemValue,
+                updateFct: () => { return this._scene.lights.length.toString() }
+            });
+
+            this._createStatLabel("Total vertices", this._panel);
+            elemValue = Helpers.CreateDiv('stat-value', this._panel);
+            this._updatableProperties.push({
+                elem: elemValue,
+                updateFct: () => { return this._scene.getTotalVertices().toString() }
+            });
+
+            this._createStatLabel("Total materials", this._panel);
+            elemValue = Helpers.CreateDiv('stat-value', this._panel);
+            this._updatableProperties.push({
+                elem: elemValue,
+                updateFct: () => { return this._scene.materials.length.toString() }
+            });
+
+            this._createStatLabel("Total textures", this._panel);
+            elemValue = Helpers.CreateDiv('stat-value', this._panel);
+            this._updatableProperties.push({
+                elem: elemValue,
+                updateFct: () => { return this._scene.textures.length.toString() }
+            });
+
+            this._createStatLabel("Active meshes", this._panel);
+            elemValue = Helpers.CreateDiv('stat-value', this._panel);
+            this._updatableProperties.push({
+                elem: elemValue,
+                updateFct: () => { return this._scene.getActiveMeshes().length.toString() }
+            });
+
+            this._createStatLabel("Active indices", this._panel);
+            elemValue = Helpers.CreateDiv('stat-value', this._panel);
+            this._updatableProperties.push({
+                elem: elemValue,
+                updateFct: () => { return this._scene.getActiveIndices().toString() }
+            });
+
+            this._createStatLabel("Active bones", this._panel);
+            elemValue = Helpers.CreateDiv('stat-value', this._panel);
+            this._updatableProperties.push({
+                elem: elemValue,
+                updateFct: () => { return this._scene.getActiveBones().toString() }
+            });
+
+            this._createStatLabel("Active particles", this._panel);
+            elemValue = Helpers.CreateDiv('stat-value', this._panel);
+            this._updatableProperties.push({
+                elem: elemValue,
+                updateFct: () => { return this._scene.getActiveParticles().toString() }
+            });
         }
 
-        private _createStatLabel(content: string, parent: HTMLElement): HTMLElement {
-            let elem = Helpers.CreateDiv('stat-label', parent);
-            elem.textContent = content;
-            return elem;
+        title = Helpers.CreateDiv('stat-title2', this._panel);
+        title.textContent = "Duration";
+        {
+            this._createStatLabel("Properties refresh rate (per second)", this._panel);
+            let elemValue = Helpers.CreateDiv('stat-value', this._panel);
+            this._inputElement = Inspector.DOCUMENT.createElement('input');
+            this._inputElement.value = this.refreshRate;
+            elemValue.appendChild(this._inputElement);
+            this._inputElement.addEventListener('keyup', (evt: KeyboardEvent) => {
+                this.refreshRate = this._inputElement.value;
+            })
+            this._createStatLabel("Meshes selection", this._panel);
+            elemValue = Helpers.CreateDiv('stat-value', this._panel);
+            this._updatableProperties.push({
+                elem: elemValue,
+                updateFct: () => { return Tools.Format(this._sceneInstrumentation!.activeMeshesEvaluationTimeCounter.current) }
+            });
+            this._createStatLabel("Render targets", this._panel);
+            elemValue = Helpers.CreateDiv('stat-value', this._panel);
+            this._updatableProperties.push({
+                elem: elemValue,
+                updateFct: () => { return Tools.Format(this._sceneInstrumentation!.renderTargetsRenderTimeCounter.current) }
+            });
+            this._createStatLabel("Particles", this._panel);
+            elemValue = Helpers.CreateDiv('stat-value', this._panel);
+            this._updatableProperties.push({
+                elem: elemValue,
+                updateFct: () => { return Tools.Format(this._sceneInstrumentation!.particlesRenderTimeCounter.current) }
+            });
+            this._createStatLabel("Sprites", this._panel);
+            elemValue = Helpers.CreateDiv('stat-value', this._panel);
+            this._updatableProperties.push({
+                elem: elemValue,
+                updateFct: () => { return Tools.Format(this._sceneInstrumentation!.spritesRenderTimeCounter.current) }
+            });
+            this._createStatLabel("Animations", this._panel);
+            elemValue = Helpers.CreateDiv('stat-value', this._panel);
+            this._updatableProperties.push({
+                elem: elemValue,
+                updateFct: () => { return Tools.Format(this._sceneInstrumentation!.animationsTimeCounter.current) }
+            });
+            this._createStatLabel("Physics", this._panel);
+            elemValue = Helpers.CreateDiv('stat-value', this._panel);
+            this._updatableProperties.push({
+                elem: elemValue,
+                updateFct: () => { return Tools.Format(this._sceneInstrumentation!.physicsTimeCounter.current) }
+            });
+            this._createStatLabel("Render", this._panel);
+            elemValue = Helpers.CreateDiv('stat-value', this._panel);
+            this._updatableProperties.push({
+                elem: elemValue,
+                updateFct: () => { return Tools.Format(this._sceneInstrumentation!.renderTimeCounter.current) }
+            });
+            this._createStatLabel("Frame", this._panel);
+            elemValue = Helpers.CreateDiv('stat-value', this._panel);
+            this._updatableProperties.push({
+                elem: elemValue,
+                updateFct: () => { return Tools.Format(this._sceneInstrumentation!.frameTimeCounter.current) }
+            });
+            this._createStatLabel("Inter-frame", this._panel);
+            elemValue = Helpers.CreateDiv('stat-value', this._panel);
+            this._updatableProperties.push({
+                elem: elemValue,
+                updateFct: () => { return Tools.Format(this._sceneInstrumentation!.interFrameTimeCounter.current) }
+            });
+            this._createStatLabel("GPU Frame time", this._panel);
+            elemValue = Helpers.CreateDiv('stat-value', this._panel);
+            this._updatableProperties.push({
+                elem: elemValue,
+                updateFct: () => { return Tools.Format(this._engineInstrumentation!.gpuFrameTimeCounter.current * 0.000001) }
+            });
+            this._createStatLabel("GPU Frame time (average)", this._panel);
+            elemValue = Helpers.CreateDiv('stat-value', this._panel);
+            this._updatableProperties.push({
+                elem: elemValue,
+                updateFct: () => { return Tools.Format(this._engineInstrumentation!.gpuFrameTimeCounter.average * 0.000001) }
+            });
+            this._createStatLabel("Potential FPS", this._panel);
+            elemValue = Helpers.CreateDiv('stat-value', this._panel);
+            this._updatableProperties.push({
+                elem: elemValue,
+                updateFct: () => { return Tools.Format(1000.0 / this._sceneInstrumentation!.frameTimeCounter.current, 0) }
+            });
+            this._createStatLabel("Resolution", this._panel);
+            elemValue = Helpers.CreateDiv('stat-value', this._panel);
+            this._updatableProperties.push({
+                elem: elemValue,
+                updateFct: () => { return this._engine.getRenderWidth() + "x" + this._engine.getRenderHeight() }
+            });
         }
 
-        /** Update each properties of the stats panel */
-        private _update() {
-            
-            if(this._refreshRateCounter > 1){
-                this._refreshRateCounter--;
-            }else{
-                for (let prop of this._updatableProperties) {
-                    prop.elem.textContent = prop.updateFct();
-                }
-                if(this._inspector.scene.getEngine().getFps()/this.refreshRate == Infinity){
-                    this._refreshRateCounter = 1;
-                }else{
-                    this._refreshRateCounter = this._inspector.scene.getEngine().getFps()/this.refreshRate;
-                }
-                
-            }
-            
+        title = Helpers.CreateDiv('stat-title2', this._panel);
+        title.textContent = "Extensions";
+        {
+            this._createStatLabel("Std derivatives", this._panel);
+            let elemValue = Helpers.CreateDiv('stat-value', this._panel);
+            this._updatableProperties.push({
+                elem: elemValue,
+                updateFct: () => { return (this._engine.getCaps().standardDerivatives ? "Yes" : "No") }
+            });
+            this._createStatLabel("Compressed textures", this._panel);
+            elemValue = Helpers.CreateDiv('stat-value', this._panel);
+            this._updatableProperties.push({
+                elem: elemValue,
+                updateFct: () => { return (this._engine.getCaps().s3tc ? "Yes" : "No") }
+            });
+            this._createStatLabel("Hardware instances", this._panel);
+            elemValue = Helpers.CreateDiv('stat-value', this._panel);
+            this._updatableProperties.push({
+                elem: elemValue,
+                updateFct: () => { return (this._engine.getCaps().instancedArrays ? "Yes" : "No") }
+            });
+            this._createStatLabel("Texture float", this._panel);
+            elemValue = Helpers.CreateDiv('stat-value', this._panel);
+            this._updatableProperties.push({
+                elem: elemValue,
+                updateFct: () => { return (this._engine.getCaps().textureFloat ? "Yes" : "No") }
+            });
+            this._createStatLabel("32bits indices", this._panel);
+            elemValue = Helpers.CreateDiv('stat-value', this._panel);
+            this._updatableProperties.push({
+                elem: elemValue,
+                updateFct: () => { return (this._engine.getCaps().uintIndices ? "Yes" : "No") }
+            });
+            this._createStatLabel("Fragment depth", this._panel);
+            elemValue = Helpers.CreateDiv('stat-value', this._panel);
+            this._updatableProperties.push({
+                elem: elemValue,
+                updateFct: () => { return (this._engine.getCaps().fragmentDepthSupported ? "Yes" : "No") }
+            });
+            this._createStatLabel("High precision shaders", this._panel);
+            elemValue = Helpers.CreateDiv('stat-value', this._panel);
+            this._updatableProperties.push({
+                elem: elemValue,
+                updateFct: () => { return (this._engine.getCaps().highPrecisionShaderSupported ? "Yes" : "No") }
+            });
+            this._createStatLabel("Draw buffers", this._panel);
+            elemValue = Helpers.CreateDiv('stat-value', this._panel);
+            this._updatableProperties.push({
+                elem: elemValue,
+                updateFct: () => { return (this._engine.getCaps().drawBuffersExtension ? "Yes" : "No") }
+            });
+            this._createStatLabel("Vertex array object", this._panel);
+            elemValue = Helpers.CreateDiv('stat-value', this._panel);
+            this._updatableProperties.push({
+                elem: elemValue,
+                updateFct: () => { return (this._engine.getCaps().vertexArrayObject ? "Yes" : "No") }
+            });
+            this._createStatLabel("Timer query", this._panel);
+            elemValue = Helpers.CreateDiv('stat-value', this._panel);
+            this._updatableProperties.push({
+                elem: elemValue,
+                updateFct: () => { return (this._engine.getCaps().timerQuery ? "Yes" : "No") }
+            });
         }
 
-        public dispose() {
-            this._scene.unregisterAfterRender(this._updateLoopHandler);
-            this._sceneInstrumentation!.dispose();
-            this._sceneInstrumentation = null;
-            this._engineInstrumentation!.dispose();
-            this._engineInstrumentation = null;
+        title = Helpers.CreateDiv('stat-title2', this._panel);
+        title.textContent = "Caps.";
+        {
+            this._createStatLabel("Stencil", this._panel);
+            let elemValue = Helpers.CreateDiv('stat-value', this._panel);
+            this._updatableProperties.push({
+                elem: elemValue,
+                updateFct: () => { return (this._engine.isStencilEnable ? "Enabled" : "Disabled") }
+            });
+            this._createStatLabel("Max textures units", this._panel);
+            elemValue = Helpers.CreateDiv('stat-value', this._panel);
+            this._updatableProperties.push({
+                elem: elemValue,
+                updateFct: () => { return this._engine.getCaps().maxTexturesImageUnits.toString() }
+            });
+            this._createStatLabel("Max textures size", this._panel);
+            elemValue = Helpers.CreateDiv('stat-value', this._panel);
+            this._updatableProperties.push({
+                elem: elemValue,
+                updateFct: () => { return this._engine.getCaps().maxTextureSize.toString() }
+            });
+            this._createStatLabel("Max anisotropy", this._panel);
+            elemValue = Helpers.CreateDiv('stat-value', this._panel);
+            this._updatableProperties.push({
+                elem: elemValue,
+                updateFct: () => { return this._engine.getCaps().maxAnisotropy.toString() }
+            });
         }
+        title = Helpers.CreateDiv('stat-title2', this._panel);
+        title.textContent = "Info";
+        {
+            let elemValue = Helpers.CreateDiv('stat-infos', this._panel);
+            this._updatableProperties.push({
+                elem: elemValue,
+                updateFct: () => { return "WebGL v" + this._engine.webGLVersion + " - " + this._glInfo.version + " - " + this._glInfo.renderer }
+            });
+        }
+    }
+
+    private _createStatLabel(content: string, parent: HTMLElement): HTMLElement {
+        let elem = Helpers.CreateDiv('stat-label', parent);
+        elem.textContent = content;
+        return elem;
+    }
 
-        public active(b: boolean) {
-            super.active(b);
-            if (b) {
-                this._connectToInstrumentation();
-                this._scene.registerAfterRender(this._updateLoopHandler);
+    /** Update each properties of the stats panel */
+    private _update() {
+
+        if (this._refreshRateCounter > 1) {
+            this._refreshRateCounter--;
+        } else {
+            for (let prop of this._updatableProperties) {
+                prop.elem.textContent = prop.updateFct();
+            }
+            if (this._inspector.scene.getEngine().getFps() / this.refreshRate == Infinity) {
+                this._refreshRateCounter = 1;
+            } else {
+                this._refreshRateCounter = this._inspector.scene.getEngine().getFps() / this.refreshRate;
             }
+
+        }
+
+    }
+
+    public dispose() {
+        this._scene.unregisterAfterRender(this._updateLoopHandler);
+        this._sceneInstrumentation!.dispose();
+        this._sceneInstrumentation = null;
+        this._engineInstrumentation!.dispose();
+        this._engineInstrumentation = null;
+    }
+
+    public active(b: boolean) {
+        super.active(b);
+        if (b) {
+            this._connectToInstrumentation();
+            this._scene.registerAfterRender(this._updateLoopHandler);
         }
     }
-}
+}

+ 64 - 61
inspector/src/tabs/Tab.ts

@@ -1,78 +1,81 @@
-module INSPECTOR {
+import { BasicElement } from "../gui/BasicElement";
+import { TabBar } from "./TabBar";
+import { Inspector } from "../Inspector";
+import { TreeItem } from "../tree/TreeItem";
 
-    export abstract class Tab extends BasicElement {
-        protected _tabbar: TabBar;
-        // The tab name displayed in the tabbar
-        public name: string;
-        protected _isActive: boolean = false;
 
-        // The whole panel corresponding to this tab. It's what is displayed when the tab is activacted
-        protected _panel: HTMLDivElement;
+export abstract class Tab extends BasicElement {
+    protected _tabbar: TabBar;
+    // The tab name displayed in the tabbar
+    public name: string;
+    protected _isActive: boolean = false;
 
-        constructor(tabbar: TabBar, name: string) {
-            super();
-            this._tabbar = tabbar;
-            this.name = name;
-            this._build();
-        }
+    // The whole panel corresponding to this tab. It's what is displayed when the tab is activacted
+    protected _panel: HTMLDivElement;
 
-        /** True if the tab is active, false otherwise */
-        public isActive(): boolean {
-            return this._isActive;
-        }
+    constructor(tabbar: TabBar, name: string) {
+        super();
+        this._tabbar = tabbar;
+        this.name = name;
+        this._build();
+    }
 
-        protected _build() {
-            this._div.className = 'tab';
-            this._div.textContent = this.name;
+    /** True if the tab is active, false otherwise */
+    public isActive(): boolean {
+        return this._isActive;
+    }
 
-            this._div.addEventListener('click', (evt) => {
-                // Set this tab as active
-                this._tabbar.switchTab(this);
-            });
-        }
+    protected _build() {
+        this._div.className = 'tab';
+        this._div.textContent = this.name;
 
-        /** Set this tab as active or not, depending on the current state */
-        public active(b: boolean) {
-            if (b) {
-                this._div.classList.add('active');
-            } else {
-                this._div.classList.remove('active');
-            }
-            this._isActive = b;
-        }
+        this._div.addEventListener('click', (evt) => {
+            // Set this tab as active
+            this._tabbar.switchTab(this);
+        });
+    }
 
-        public update() {
-            // Nothing for the moment
+    /** Set this tab as active or not, depending on the current state */
+    public active(b: boolean) {
+        if (b) {
+            this._div.classList.add('active');
+        } else {
+            this._div.classList.remove('active');
         }
+        this._isActive = b;
+    }
 
-        /** Creates the tab panel for this tab. */
-        public getPanel(): HTMLElement {
-            return this._panel;
-        }
+    public update() {
+        // Nothing for the moment
+    }
 
-        /** Add this in the propertytab with the searchbar */
-        public filter(str: string) { };
+    /** Creates the tab panel for this tab. */
+    public getPanel(): HTMLElement {
+        return this._panel;
+    }
 
-        /** Dispose properly this tab */
-        public abstract dispose(): void;
+    /** Add this in the propertytab with the searchbar */
+    public filter(str: string) { };
 
-        /** Select an item in the tree */
-        public select(item: TreeItem) {
-            // To define in subclasses if needed 
-        }
+    /** Dispose properly this tab */
+    public abstract dispose(): void;
+
+    /** Select an item in the tree */
+    public select(item: TreeItem) {
+        // To define in subclasses if needed 
+    }
 
-        /** 
-         * Returns the total width in pixel of this tab, 0 by default
-        */
-        public getPixelWidth(): number {
-            let style = Inspector.WINDOW.getComputedStyle(this._div);
-            if (!style.marginLeft || !style.marginRight) {
-                return 0;
-            }
-            let left = parseFloat(style.marginLeft.substr(0, style.marginLeft.length - 2)) || 0;
-            let right = parseFloat(style.marginRight.substr(0, style.marginRight.length - 2)) || 0;
-            return (this._div.clientWidth || 0) + left + right;
+    /** 
+     * Returns the total width in pixel of this tab, 0 by default
+    */
+    public getPixelWidth(): number {
+        let style = Inspector.WINDOW.getComputedStyle(this._div);
+        if (!style.marginLeft || !style.marginRight) {
+            return 0;
         }
+        let left = parseFloat(style.marginLeft.substr(0, style.marginLeft.length - 2)) || 0;
+        let right = parseFloat(style.marginRight.substr(0, style.marginRight.length - 2)) || 0;
+        return (this._div.clientWidth || 0) + left + right;
     }
+}
 
-}

+ 219 - 199
inspector/src/tabs/TabBar.ts

@@ -1,236 +1,256 @@
-module INSPECTOR {
-    /**
-     * A tab bar will contains each view the inspector can have : Canvas2D, Meshes...
-     * The default active tab is the first one of the list.
-     */
-    export class TabBar extends BasicElement {
-
-        // The list of available tabs
-        private _tabs: Array<Tab> = [];
-        private _inspector: Inspector;
-        /** The tab displaying all meshes */
-        private _meshTab: MeshTab;
-        /** The toolbar */
-        private _toolBar: Toolbar;
-        /** The icon displayed at the end of the toolbar displaying a combo box of tabs not displayed */
-        private _moreTabsIcon: HTMLElement;
-        /** The panel displayed when the 'more-tab' icon is selected */
-        private _moreTabsPanel: HTMLElement;
-        /** The list of tab displayed by clicking on the remainingIcon */
-        private _invisibleTabs: Array<Tab> = [];
-        /** The list of tabs visible, displayed in the tab bar */
-        private _visibleTabs: Array<Tab> = [];
-
-        constructor(inspector: Inspector, initialTab?: number) {
-            super();
-            this._inspector = inspector;
-            this._tabs.push(new SceneTab(this, this._inspector));
-            this._tabs.push(new ConsoleTab(this, this._inspector));
-            this._tabs.push(new StatsTab(this, this._inspector));
-            this._meshTab = new MeshTab(this, this._inspector);
-            this._tabs.push(new TextureTab(this, this._inspector));
-            this._tabs.push(this._meshTab);
-            this._tabs.push(new LightTab(this, this._inspector));
-            this._tabs.push(new MaterialTab(this, this._inspector));
-            if (GLTFTab.IsSupported) {
-                this._tabs.push(new GLTFTab(this, this._inspector));
-            }
-            if (BABYLON.GUI) {
-                this._tabs.push(new GUITab(this, this._inspector));
-            }
-            this._tabs.push(new PhysicsTab(this, this._inspector));
-            this._tabs.push(new CameraTab(this, this._inspector));
-            this._tabs.push(new SoundTab(this, this._inspector));
-            this._tabs.push(new ToolsTab(this, this._inspector));
-            this._toolBar = new Toolbar(this._inspector);
+import { BasicElement } from "../gui/BasicElement";
+import { Tab } from "./Tab";
+import { Inspector } from "../Inspector";
+import { MeshTab } from "./MeshTab";
+import { Toolbar } from "../tools/Toolbar";
+import { SceneTab } from "./SceneTab";
+import { ConsoleTab } from "./ConsoleTab";
+import { StatsTab } from "./StatsTab";
+import { TextureTab } from "./TextureTab";
+import { LightTab } from "./LightTab";
+import { MaterialTab } from "./MaterialTab";
+import { GLTFTab } from "./GLTFTab";
 
-            this._build();
+import * as GUI from "babylonjs-gui";
+import { GUITab } from "./GUITab";
+import { PhysicsTab } from "./PhysicsTab";
+import { CameraTab } from "./CameraTab";
+import { SoundTab } from "./SoundTab";
+import { ToolsTab } from "./ToolsTab";
+import { Helpers } from "../helpers/Helpers";
+import { AbstractMesh, Nullable } from "babylonjs";
 
-            //Check initialTab is defined and between tabs bounds
-            if (!initialTab || initialTab < 0 || initialTab >= this._tabs.length) {
-                initialTab = 0;
-            }
+/**
+ * A tab bar will contains each view the inspector can have : Canvas2D, Meshes...
+ * The default active tab is the first one of the list.
+ */
+export class TabBar extends BasicElement {
 
-            this._tabs[initialTab].active(true);
+    // The list of available tabs
+    private _tabs: Array<Tab> = [];
+    private _inspector: Inspector;
+    /** The tab displaying all meshes */
+    private _meshTab: MeshTab;
+    /** The toolbar */
+    private _toolBar: Toolbar;
+    /** The icon displayed at the end of the toolbar displaying a combo box of tabs not displayed */
+    private _moreTabsIcon: HTMLElement;
+    /** The panel displayed when the 'more-tab' icon is selected */
+    private _moreTabsPanel: HTMLElement;
+    /** The list of tab displayed by clicking on the remainingIcon */
+    private _invisibleTabs: Array<Tab> = [];
+    /** The list of tabs visible, displayed in the tab bar */
+    private _visibleTabs: Array<Tab> = [];
 
-            // set all tab as visible
-            for (let tab of this._tabs) {
-                this._visibleTabs.push(tab);
-            }
+    constructor(inspector: Inspector, initialTab?: number) {
+        super();
+        this._inspector = inspector;
+        this._tabs.push(new SceneTab(this, this._inspector));
+        this._tabs.push(new ConsoleTab(this, this._inspector));
+        this._tabs.push(new StatsTab(this, this._inspector));
+        this._meshTab = new MeshTab(this, this._inspector);
+        this._tabs.push(new TextureTab(this, this._inspector));
+        this._tabs.push(this._meshTab);
+        this._tabs.push(new LightTab(this, this._inspector));
+        this._tabs.push(new MaterialTab(this, this._inspector));
+        if (GLTFTab.IsSupported) {
+            this._tabs.push(new GLTFTab(this, this._inspector));
         }
+        if (GUI) {
+            this._tabs.push(new GUITab(this, this._inspector));
+        }
+        this._tabs.push(new PhysicsTab(this, this._inspector));
+        this._tabs.push(new CameraTab(this, this._inspector));
+        this._tabs.push(new SoundTab(this, this._inspector));
+        this._tabs.push(new ToolsTab(this, this._inspector));
+        this._toolBar = new Toolbar(this._inspector);
 
-        // No update
-        public update() { }
-
-        protected _build() {
-            this._div.className = 'tabbar';
+        this._build();
 
-            this._div.appendChild(this._toolBar.toHtml());
-            for (let tab of this._tabs) {
-                this._div.appendChild(tab.toHtml());
-            }
+        //Check initialTab is defined and between tabs bounds
+        if (!initialTab || initialTab < 0 || initialTab >= this._tabs.length) {
+            initialTab = 0;
+        }
 
+        this._tabs[initialTab].active(true);
 
-            this._moreTabsIcon = Helpers.CreateElement('i', 'fa fa-angle-double-right more-tabs');
-
-            this._moreTabsPanel = Helpers.CreateDiv('more-tabs-panel');
-
-            this._moreTabsIcon.addEventListener('click', () => {
-                // Hide the 'more-tabs-panel' if already displayed 
-                if (this._moreTabsPanel.style.display == 'flex') {
-                    this._moreTabsPanel.style.display = 'none';
-                } else {
-                    // Attach more-tabs-panel if not attached yet
-                    let topPanel = this._div.parentNode as HTMLElement;
-                    if (!topPanel.contains(this._moreTabsPanel)) {
-                        topPanel.appendChild(this._moreTabsPanel);
-                    }
-                    // Clean the 'more-tabs-panel'
-                    Helpers.CleanDiv(this._moreTabsPanel);
-                    // Add each invisible tabs to this panel
-                    for (let tab of this._invisibleTabs) {
-                        this._addInvisibleTabToPanel(tab);
-                    }
-                    // And display it
-                    this._moreTabsPanel.style.display = 'flex';
-                }
-            });
+        // set all tab as visible
+        for (let tab of this._tabs) {
+            this._visibleTabs.push(tab);
         }
+    }
 
-        /** 
-         * Add a tab to the 'more-tabs' panel, displayed by clicking on the 
-         * 'more-tabs' icon
-         */
-        private _addInvisibleTabToPanel(tab: Tab) {
-            let div = Helpers.CreateDiv('invisible-tab', this._moreTabsPanel);
-            div.textContent = tab.name;
-            div.addEventListener('click', () => {
-                this._moreTabsPanel.style.display = 'none';
-                this.switchTab(tab);
-            });
+    // No update
+    public update() { }
+
+    protected _build() {
+        this._div.className = 'tabbar';
+
+        this._div.appendChild(this._toolBar.toHtml());
+        for (let tab of this._tabs) {
+            this._div.appendChild(tab.toHtml());
         }
 
-        /** Dispose the current tab, set the given tab as active, and refresh the treeview */
-        public switchTab(tab: Tab) {
-            // Dispose the active tab
-            let activeTab = this.getActiveTab();
 
-            if (activeTab) {
-                activeTab.dispose();
-            }
+        this._moreTabsIcon = Helpers.CreateElement('i', 'fa fa-angle-double-right more-tabs');
 
-            // Deactivate all tabs
-            for (let t of this._tabs) {
-                t.active(false);
-            }
-            // activate the given tab
-            tab.active(true);
-
-            // Refresh the inspector
-            this._inspector.refresh();
-        }
-
-        /** Display the mesh tab.
-         * If a parameter is given, the given mesh details are displayed
-         */
-        public switchMeshTab(mesh?: BABYLON.AbstractMesh) {
-            this.switchTab(this._meshTab);
-            if (mesh) {
-                let item = this._meshTab.getItemFor(mesh);
-                if (item) {
-                    this._meshTab.select(item);
+        this._moreTabsPanel = Helpers.CreateDiv('more-tabs-panel');
+
+        this._moreTabsIcon.addEventListener('click', () => {
+            // Hide the 'more-tabs-panel' if already displayed 
+            if (this._moreTabsPanel.style.display == 'flex') {
+                this._moreTabsPanel.style.display = 'none';
+            } else {
+                // Attach more-tabs-panel if not attached yet
+                let topPanel = this._div.parentNode as HTMLElement;
+                if (!topPanel.contains(this._moreTabsPanel)) {
+                    topPanel.appendChild(this._moreTabsPanel);
                 }
+                // Clean the 'more-tabs-panel'
+                Helpers.CleanDiv(this._moreTabsPanel);
+                // Add each invisible tabs to this panel
+                for (let tab of this._invisibleTabs) {
+                    this._addInvisibleTabToPanel(tab);
+                }
+                // And display it
+                this._moreTabsPanel.style.display = 'flex';
             }
+        });
+    }
+
+    /** 
+     * Add a tab to the 'more-tabs' panel, displayed by clicking on the 
+     * 'more-tabs' icon
+     */
+    private _addInvisibleTabToPanel(tab: Tab) {
+        let div = Helpers.CreateDiv('invisible-tab', this._moreTabsPanel);
+        div.textContent = tab.name;
+        div.addEventListener('click', () => {
+            this._moreTabsPanel.style.display = 'none';
+            this.switchTab(tab);
+        });
+    }
+
+    /** Dispose the current tab, set the given tab as active, and refresh the treeview */
+    public switchTab(tab: Tab) {
+        // Dispose the active tab
+        let activeTab = this.getActiveTab();
+
+        if (activeTab) {
+            activeTab.dispose();
         }
 
-        /** Returns the active tab */
-        public getActiveTab(): BABYLON.Nullable<Tab> {
-            for (let tab of this._tabs) {
-                if (tab.isActive()) {
-                    return tab;
-                }
+        // Deactivate all tabs
+        for (let t of this._tabs) {
+            t.active(false);
+        }
+        // activate the given tab
+        tab.active(true);
+
+        // Refresh the inspector
+        this._inspector.refresh();
+    }
+
+    /** Display the mesh tab.
+     * If a parameter is given, the given mesh details are displayed
+     */
+    public switchMeshTab(mesh?: AbstractMesh) {
+        this.switchTab(this._meshTab);
+        if (mesh) {
+            let item = this._meshTab.getItemFor(mesh);
+            if (item) {
+                this._meshTab.select(item);
             }
+        }
+    }
 
-            return null;
+    /** Returns the active tab */
+    public getActiveTab(): Nullable<Tab> {
+        for (let tab of this._tabs) {
+            if (tab.isActive()) {
+                return tab;
+            }
         }
 
-        public getActiveTabIndex(): number {
-            for (let i = 0; i < this._tabs.length; i++) {
-                if (this._tabs[i].isActive()) {
-                    return i;
-                }
+        return null;
+    }
+
+    public getActiveTabIndex(): number {
+        for (let i = 0; i < this._tabs.length; i++) {
+            if (this._tabs[i].isActive()) {
+                return i;
             }
-            return 0;
         }
+        return 0;
+    }
 
-        public get inspector(): Inspector {
-            return this._inspector;
+    public get inspector(): Inspector {
+        return this._inspector;
+    }
+
+    /** 
+     * Returns the total width in pixel of the tabbar, 
+     * that corresponds to the sum of the width of each visible tab + toolbar width
+    */
+    public getPixelWidth(): number {
+        let sum = 0;
+        for (let tab of this._visibleTabs) {
+            sum += tab.getPixelWidth();
+        }
+        sum += this._toolBar.getPixelWidth();
+        if (this._div.contains(this._moreTabsIcon)) {
+            sum += 30; // $tabbarheight
         }
+        return sum;
+    }
 
-        /** 
-         * Returns the total width in pixel of the tabbar, 
-         * that corresponds to the sum of the width of each visible tab + toolbar width
-        */
-        public getPixelWidth(): number {
-            let sum = 0;
-            for (let tab of this._visibleTabs) {
-                sum += tab.getPixelWidth();
-            }
-            sum += this._toolBar.getPixelWidth();
-            if (this._div.contains(this._moreTabsIcon)) {
-                sum += 30; // $tabbarheight
-            }
-            return sum;
+    /** Display the remaining icon or not depending on the tabbar width.
+     * This function should be called each time the inspector width is updated
+     */
+    public updateWidth(): void {
+        if (!this._div.parentElement) {
+            return;
         }
+        let parentSize = this._div.parentElement.clientWidth;
+        let lastTabWidth = 75;
+        let currentSize = this.getPixelWidth();
 
-        /** Display the remaining icon or not depending on the tabbar width.
-         * This function should be called each time the inspector width is updated
-         */
-        public updateWidth(): void {
-            if (!this._div.parentElement) {
-                return;
-            }
-            let parentSize = this._div.parentElement.clientWidth;
-            let lastTabWidth = 75;
-            let currentSize = this.getPixelWidth();
-
-            // Check if a tab should be removed : if the tab bar width is greater than
-            // its parent width
-            while (this._visibleTabs.length > 0 && currentSize > parentSize) {
-                // Start by the last element
-                let tab = this._visibleTabs.pop();
-
-                if (!tab) {
-                    break;
-                }
+        // Check if a tab should be removed : if the tab bar width is greater than
+        // its parent width
+        while (this._visibleTabs.length > 0 && currentSize > parentSize) {
+            // Start by the last element
+            let tab = this._visibleTabs.pop();
 
-                // set it invisible
-                this._invisibleTabs.push(tab);
-                // and removes it from the DOM
-                this._div.removeChild(tab.toHtml());
-                currentSize = this.getPixelWidth() + lastTabWidth;
+            if (!tab) {
+                break;
             }
 
-            // Check if a tab can be added to the tab bar : if the tab bar width
-            // + 100 (at least 100px is needed to add a tab) is less than its parent width
-            if (this._invisibleTabs.length > 0) {
-                if (currentSize + lastTabWidth < parentSize) {
-                    let lastTab = this._invisibleTabs.pop();
-
-                    if (lastTab) {
-                        this._div.appendChild(lastTab.toHtml());
-                        this._visibleTabs.push(lastTab);
-                    }
-                    // Update more-tab icon in last position if needed
-                    if (this._div.contains(this._moreTabsIcon)) {
-                        this._div.removeChild(this._moreTabsIcon);
-                    }
+            // set it invisible
+            this._invisibleTabs.push(tab);
+            // and removes it from the DOM
+            this._div.removeChild(tab.toHtml());
+            currentSize = this.getPixelWidth() + lastTabWidth;
+        }
+
+        // Check if a tab can be added to the tab bar : if the tab bar width
+        // + 100 (at least 100px is needed to add a tab) is less than its parent width
+        if (this._invisibleTabs.length > 0) {
+            if (currentSize + lastTabWidth < parentSize) {
+                let lastTab = this._invisibleTabs.pop();
+
+                if (lastTab) {
+                    this._div.appendChild(lastTab.toHtml());
+                    this._visibleTabs.push(lastTab);
+                }
+                // Update more-tab icon in last position if needed
+                if (this._div.contains(this._moreTabsIcon)) {
+                    this._div.removeChild(this._moreTabsIcon);
                 }
-            }
-            if (this._invisibleTabs.length > 0 && !this._div.contains(this._moreTabsIcon)) {
-                this._div.appendChild(this._moreTabsIcon);
             }
         }
-
+        if (this._invisibleTabs.length > 0 && !this._div.contains(this._moreTabsIcon)) {
+            this._div.appendChild(this._moreTabsIcon);
+        }
     }
-}
+
+}

+ 165 - 160
inspector/src/tabs/TextureTab.ts

@@ -1,193 +1,198 @@
-module INSPECTOR {
+import { CubeTexture, RenderTargetTexture, Tools } from "babylonjs";
+import { TextureAdapter } from "../adapters/TextureAdapter";
+import { Helpers } from "../helpers/Helpers";
+import { Inspector } from "../Inspector";
+import { TreeItem } from "../tree/TreeItem";
+import { Tab } from "./Tab";
+import { TabBar } from "./TabBar";
 
-    export class TextureTab extends Tab {
 
-        private _inspector: Inspector;
-        /** The panel containing a list of items */
-        protected _treePanel: HTMLElement;
-        protected _treeItems: Array<TreeItem> = [];
+export class TextureTab extends Tab {
 
-        /* Panel containing the texture image */
-        private _imagePanel: HTMLElement;
+    private _inspector: Inspector;
+    /** The panel containing a list of items */
+    protected _treePanel: HTMLElement;
+    protected _treeItems: Array<TreeItem> = [];
 
-        constructor(tabbar: TabBar, inspector: Inspector) {
-            super(tabbar, 'Textures');
-            this._inspector = inspector;
+    /* Panel containing the texture image */
+    private _imagePanel: HTMLElement;
 
-            // Build the properties panel : a div that will contains the tree and the detail panel
-            this._panel = Helpers.CreateDiv('tab-panel') as HTMLDivElement;
+    constructor(tabbar: TabBar, inspector: Inspector) {
+        super(tabbar, 'Textures');
+        this._inspector = inspector;
 
-            // Build the treepanel
-            this._treePanel = Helpers.CreateDiv('insp-tree', this._panel);
+        // Build the properties panel : a div that will contains the tree and the detail panel
+        this._panel = Helpers.CreateDiv('tab-panel') as HTMLDivElement;
 
-            this._imagePanel = Helpers.CreateDiv('insp-details', this._panel) as HTMLDivElement;
+        // Build the treepanel
+        this._treePanel = Helpers.CreateDiv('insp-tree', this._panel);
 
-            Split([this._treePanel, this._imagePanel], {
-                blockDrag: this._inspector.popupMode,
-                direction: 'vertical'
-            });
+        this._imagePanel = Helpers.CreateDiv('insp-details', this._panel) as HTMLDivElement;
+
+        Split([this._treePanel, this._imagePanel], {
+            blockDrag: this._inspector.popupMode,
+            direction: 'vertical'
+        });
+
+        this.update();
+    }
 
-            this.update();
+    public dispose() {
+        // Nothing to dispose
+    }
+
+    public update(_items?: Array<TreeItem>) {
+        let items;
+        if (_items) {
+            items = _items;
+        } else {
+            // Rebuild the tree
+            this._treeItems = this._getTree();
+            items = this._treeItems;
+        }
+        // Clean the tree
+        Helpers.CleanDiv(this._treePanel);
+        Helpers.CleanDiv(this._imagePanel);
+
+        // Sort items alphabetically
+        items.sort((item1, item2) => {
+            return item1.compareTo(item2);
+        });
+
+        // Display items
+        for (let item of items) {
+            this._treePanel.appendChild(item.toHtml());
         }
+    }
+
+    /* Overrides super */
+    private _getTree(): Array<TreeItem> {
+        let arr = [];
 
-        public dispose() {
-            // Nothing to dispose
+        // get all cameras from the first scene
+        let instances = this._inspector.scene;
+        for (let tex of instances.textures) {
+            arr.push(new TreeItem(this, new TextureAdapter(tex)));
         }
+        return arr;
+    }
 
-        public update(_items?: Array<TreeItem>) {
-            let items;
-            if (_items) {
-                items = _items;
-            } else {
-                // Rebuild the tree
-                this._treeItems = this._getTree();
-                items = this._treeItems;
-            }
-            // Clean the tree
-            Helpers.CleanDiv(this._treePanel);
-            Helpers.CleanDiv(this._imagePanel);
+    /** Display the details of the given item */
+    public displayDetails(item: TreeItem) {
+        // Remove active state on all items
+        this.activateNode(item);
+        Helpers.CleanDiv(this._imagePanel);
+        // Get the texture object
+        let texture = item.adapter.object;
+        let imgs: HTMLImageElement[] = [];
+        let img = Helpers.CreateElement('img', 'texture-image', this._imagePanel) as HTMLImageElement;
+        imgs.push(img);
+        //Create five other images elements
+        for (let i = 0; i < 5; i++) {
+            imgs.push(Helpers.CreateElement('img', 'texture-image', this._imagePanel) as HTMLImageElement);
+        }
 
-            // Sort items alphabetically
-            items.sort((item1, item2) => {
-                return item1.compareTo(item2);
+        if (texture instanceof RenderTargetTexture) {
+            // RenderTarget textures
+            let scene = this._inspector.scene;
+            let engine = scene.getEngine();
+            let size = texture.getSize();
+
+            // Clone the texture
+            let screenShotTexture = texture.clone();
+            screenShotTexture.activeCamera = texture.activeCamera;
+            screenShotTexture.onBeforeRender = texture.onBeforeRender;
+            screenShotTexture.onAfterRender = texture.onAfterRender;
+            screenShotTexture.onBeforeRenderObservable = texture.onBeforeRenderObservable;
+
+            // To display the texture after rendering
+            screenShotTexture.onAfterRenderObservable.add((faceIndex: number) => {
+                Tools.DumpFramebuffer(size.width, size.height, engine,
+                    (data) => imgs[faceIndex].src = data);
             });
 
-            // Display items
-            for (let item of items) {
-                this._treePanel.appendChild(item.toHtml());
+            // Render the texture
+            scene.incrementRenderId();
+            scene.resetCachedMaterial();
+            screenShotTexture.render();
+            screenShotTexture.dispose();
+        } else if (texture instanceof CubeTexture) {
+            // Cannot open correctly DDS File
+            // Display all textures of the CubeTexture
+            let pixels = <ArrayBufferView>texture.readPixels();
+            let canvas = document.createElement('canvas');
+            canvas.id = "MyCanvas";
+
+            if (img.parentElement) {
+                img.parentElement.appendChild(canvas);
             }
-        }
+            let ctx = <CanvasRenderingContext2D>canvas.getContext('2d');
+            let size = texture.getSize();
 
-        /* Overrides super */
-        private _getTree(): Array<TreeItem> {
-            let arr = [];
+            let tmp = pixels.buffer.slice(0, size.height * size.width * 4);
+            let u = new Uint8ClampedArray(tmp)
 
-            // get all cameras from the first scene
-            let instances = this._inspector.scene;
-            for (let tex of instances.textures) {
-                arr.push(new TreeItem(this, new TextureAdapter(tex)));
-            }
-            return arr;
-        }
+            let colors = new ImageData(size.width * 6, size.height);
 
-        /** Display the details of the given item */
-        public displayDetails(item: TreeItem) {
-            // Remove active state on all items
-            this.activateNode(item);
-            Helpers.CleanDiv(this._imagePanel);
-            // Get the texture object
-            let texture = item.adapter.object;
-            let imgs: HTMLImageElement[] = [];
-            let img = Helpers.CreateElement('img', 'texture-image', this._imagePanel) as HTMLImageElement;
-            imgs.push(img);
-            //Create five other images elements
-            for (let i = 0; i < 5; i++) {
-                imgs.push(Helpers.CreateElement('img', 'texture-image', this._imagePanel) as HTMLImageElement);
-            }
+            colors.data.set(u);
+            let imgData = ctx.createImageData(size.width * 6, size.height);
 
-            if (texture instanceof BABYLON.RenderTargetTexture) {
-                // RenderTarget textures
-                let scene = this._inspector.scene;
-                let engine = scene.getEngine();
-                let size = texture.getSize();
-
-                // Clone the texture
-                let screenShotTexture = texture.clone();
-                screenShotTexture.activeCamera = texture.activeCamera;
-                screenShotTexture.onBeforeRender = texture.onBeforeRender;
-                screenShotTexture.onAfterRender = texture.onAfterRender;
-                screenShotTexture.onBeforeRenderObservable = texture.onBeforeRenderObservable;
-
-                // To display the texture after rendering
-                screenShotTexture.onAfterRenderObservable.add((faceIndex: number) => {
-                    BABYLON.Tools.DumpFramebuffer(size.width, size.height, engine,
-                        (data) => imgs[faceIndex].src = data);
-                });
-
-                // Render the texture
-                scene.incrementRenderId();
-                scene.resetCachedMaterial();
-                screenShotTexture.render();
-                screenShotTexture.dispose();
-            } else if (texture instanceof BABYLON.CubeTexture) {
-                // Cannot open correctly DDS File
-                // Display all textures of the CubeTexture
-                let pixels = <ArrayBufferView>texture.readPixels();
-                let canvas = document.createElement('canvas');
-                canvas.id = "MyCanvas";
-
-                if (img.parentElement) {
-                    img.parentElement.appendChild(canvas);
-                }
-                let ctx = <CanvasRenderingContext2D>canvas.getContext('2d');
-                let size = texture.getSize();
-
-                let tmp = pixels.buffer.slice(0, size.height * size.width * 4);
-                let u = new Uint8ClampedArray(tmp)
-
-                let colors = new ImageData(size.width * 6, size.height);
-
-                colors.data.set(u);
-                let imgData = ctx.createImageData(size.width * 6, size.height);
-
-                imgData.data.set(u);
-
-                // let data = imgData.data;
-
-                // for(let i = 0, len = size.height * size.width; i < len; i++) {
-                //     data[i] = pixels[i];
-                // }
-                ctx.putImageData(imgData, 0, 0);
-                // let i: number = 0;
-                // for(let filename of (texture as BABYLON.CubeTexture)['_files']){
-                //     imgs[i].src = filename;
-                //     i++;
-                // }
-            }
-            else if (texture['_canvas']) {
-                // Dynamic texture
-                let base64Image = texture['_canvas'].toDataURL("image/png");
-                img.src = base64Image;
-            } else if (texture.url) {
-                let pixels = texture.readPixels();
-                let canvas = document.createElement('canvas');
-                canvas.id = "MyCanvas";
+            imgData.data.set(u);
 
-                if (img.parentElement) {
-                    img.parentElement.appendChild(canvas);
-                }
-                let ctx = <CanvasRenderingContext2D>canvas.getContext('2d');
-                let size = texture.getSize();
+            // let data = imgData.data;
 
-                let imgData = ctx.createImageData(size.width, size.height);
+            // for(let i = 0, len = size.height * size.width; i < len; i++) {
+            //     data[i] = pixels[i];
+            // }
+            ctx.putImageData(imgData, 0, 0);
+            // let i: number = 0;
+            // for(let filename of (texture as CubeTexture)['_files']){
+            //     imgs[i].src = filename;
+            //     i++;
+            // }
+        }
+        else if (texture['_canvas']) {
+            // Dynamic texture
+            let base64Image = texture['_canvas'].toDataURL("image/png");
+            img.src = base64Image;
+        } else if (texture.url) {
+            let pixels = texture.readPixels();
+            let canvas = document.createElement('canvas');
+            canvas.id = "MyCanvas";
+
+            if (img.parentElement) {
+                img.parentElement.appendChild(canvas);
+            }
+            let ctx = <CanvasRenderingContext2D>canvas.getContext('2d');
+            let size = texture.getSize();
 
-                imgData.data.set(pixels);
+            let imgData = ctx.createImageData(size.width, size.height);
 
-                ctx.putImageData(imgData, 0, 0);
-                // If an url is present, the texture is an image
-                // img.src = texture.url;
+            imgData.data.set(pixels);
 
-            }
+            ctx.putImageData(imgData, 0, 0);
+            // If an url is present, the texture is an image
+            // img.src = texture.url;
 
         }
 
-        /** Select an item in the tree */
-        public select(item: TreeItem) {
-            // Active the node
-            this.activateNode(item);
-            // Display its details
-            this.displayDetails(item);
-        }
+    }
 
-        /** Set the given item as active in the tree */
-        public activateNode(item: TreeItem) {
-            if (this._treeItems) {
-                for (let node of this._treeItems) {
-                    node.active(false);
-                }
+    /** Select an item in the tree */
+    public select(item: TreeItem) {
+        // Active the node
+        this.activateNode(item);
+        // Display its details
+        this.displayDetails(item);
+    }
+
+    /** Set the given item as active in the tree */
+    public activateNode(item: TreeItem) {
+        if (this._treeItems) {
+            for (let node of this._treeItems) {
+                node.active(false);
             }
-            item.active(true);
         }
+        item.active(true);
     }
-
-}
+}

+ 115 - 112
inspector/src/tabs/ToolsTab.ts

@@ -1,144 +1,147 @@
-module INSPECTOR {
+import { Tab } from "./Tab";
+import { Inspector } from "../Inspector";
+import { Scene, Engine, Nullable, Tools, CubeTexture, EnvironmentTextureTools } from "babylonjs";
+import { TabBar } from "./TabBar";
+import { Helpers } from "../helpers/Helpers";
 
-    export class ToolsTab extends Tab {
+export class ToolsTab extends Tab {
 
-        private _inspector: Inspector;
+    private _inspector: Inspector;
 
-        private _scene: BABYLON.Scene;
+    private _scene: Scene;
 
-        constructor(tabbar: TabBar, insp: Inspector) {
-            super(tabbar, 'Tools');
+    constructor(tabbar: TabBar, insp: Inspector) {
+        super(tabbar, 'Tools');
 
-            this._inspector = insp;
+        this._inspector = insp;
 
-            this._scene = this._inspector.scene;
+        this._scene = this._inspector.scene;
 
-            // Build the tools panel: a div that will contains all tools
-            this._panel = Helpers.CreateDiv('tab-panel') as HTMLDivElement;
-            this._panel.classList.add("tools-panel")
+        // Build the tools panel: a div that will contains all tools
+        this._panel = Helpers.CreateDiv('tab-panel') as HTMLDivElement;
+        this._panel.classList.add("tools-panel")
 
-            let title = Helpers.CreateDiv('tool-title1', this._panel);
-            let versionSpan = Helpers.CreateElement('span');
-            versionSpan.textContent = `Babylon.js v${BABYLON.Engine.Version} - Tools`;
-            title.appendChild(versionSpan);
+        let title = Helpers.CreateDiv('tool-title1', this._panel);
+        let versionSpan = Helpers.CreateElement('span');
+        versionSpan.textContent = `js v${Engine.Version} - Tools`;
+        title.appendChild(versionSpan);
 
-            // Environment block
-            title = Helpers.CreateDiv('tool-title2', this._panel);
-            title.textContent = "Environment Texture (.dds, .env)";
-            {
-                let errorElemm = Inspector.DOCUMENT.createElement('div');
-                errorElemm.className = "tool-label-error";
-                errorElemm.style.display = "none";
+        // Environment block
+        title = Helpers.CreateDiv('tool-title2', this._panel);
+        title.textContent = "Environment Texture (.dds, .env)";
+        {
+            let errorElemm = Inspector.DOCUMENT.createElement('div');
+            errorElemm.className = "tool-label-error";
+            errorElemm.style.display = "none";
 
-                let elemValue = Helpers.CreateDiv(null, this._panel);
+            let elemValue = Helpers.CreateDiv(null, this._panel);
 
-                let inputElement = Inspector.DOCUMENT.createElement('input');
-                inputElement.className = "tool-input";
-                inputElement.type = "file";
-                inputElement.accept =".dds, .env";
-                inputElement.onchange = (event: any) => {
-                    var files: File[] = event.target.files;
-                    let file: BABYLON.Nullable<File> = null;
-                    if (files && files.length) {
-                        file = files[0];
-                    }
+            let inputElement = Inspector.DOCUMENT.createElement('input');
+            inputElement.className = "tool-input";
+            inputElement.type = "file";
+            inputElement.accept = ".dds, .env";
+            inputElement.onchange = (event: any) => {
+                var files: File[] = event.target.files;
+                let file: Nullable<File> = null;
+                if (files && files.length) {
+                    file = files[0];
+                }
 
-                    if (!file) {
-                        errorElemm.style.display = "block";
-                        errorElemm.textContent = "Please, select a file first."
-                        return;
+                if (!file) {
+                    errorElemm.style.display = "block";
+                    errorElemm.textContent = "Please, select a file first."
+                    return;
+                }
+
+                let isFileDDS = file.name.toLowerCase().indexOf(".dds") > 0;
+                let isFileEnv = file.name.toLowerCase().indexOf(".env") > 0;
+                if (!isFileDDS && !isFileEnv) {
+                    errorElemm.style.display = "block";
+                    errorElemm.textContent = "Please, select a dds or env file."
+                    return;
+                }
+
+                Tools.ReadFile(file, data => {
+                    var blob = new Blob([data], { type: "octet/stream" });
+                    var url = URL.createObjectURL(blob);
+                    if (isFileDDS) {
+                        this._scene.environmentTexture = CubeTexture.CreateFromPrefilteredData(url, this._scene, ".dds");
+                        errorElemm.style.display = "none";
                     }
+                    else {
+                        this._scene.environmentTexture = new CubeTexture(url, this._scene,
+                            undefined, undefined, undefined,
+                            () => {
+                                errorElemm.style.display = "none";
+                            },
+                            (message) => {
+                                if (message) {
+                                    errorElemm.style.display = "block";
+                                    errorElemm.textContent = message;
+                                }
+                            },
+                            undefined, undefined,
+                            ".env");
+                    }
+                }, undefined, true);
+            };
+            elemValue.appendChild(inputElement);
 
-                    let isFileDDS = file.name.toLowerCase().indexOf(".dds") > 0;
-                    let isFileEnv = file.name.toLowerCase().indexOf(".env") > 0;
-                    if (!isFileDDS && ! isFileEnv) {
+            if (!this._scene.getEngine().premultipliedAlpha) {
+                elemValue = Helpers.CreateDiv(null, this._panel);
+
+                inputElement = Inspector.DOCUMENT.createElement('input');
+                inputElement.value = "Compress current texture to .env";
+                inputElement.className = "tool-input";
+                inputElement.type = "button";
+                inputElement.onclick = () => {
+                    if (!this._scene.environmentTexture) {
                         errorElemm.style.display = "block";
-                        errorElemm.textContent = "Please, select a dds or env file."
+                        errorElemm.textContent = "You must load an environment texture first.";
                         return;
                     }
-
-                    BABYLON.Tools.ReadFile(file, data => {
-                        var blob = new Blob([data], {type: "octet/stream"});
-                        var url = URL.createObjectURL(blob);
-                        if (isFileDDS) {
-                            this._scene.environmentTexture = BABYLON.CubeTexture.CreateFromPrefilteredData(url, this._scene, ".dds");
-                            errorElemm.style.display = "none";
-                        }
-                        else {
-                            this._scene.environmentTexture = new BABYLON.CubeTexture(url, this._scene, 
-                                undefined, undefined, undefined, 
-                                () => {
-                                    errorElemm.style.display = "none";
-                                }, 
-                                (message) => {
-                                    if (message) {
-                                        errorElemm.style.display = "block";
-                                        errorElemm.textContent = message;
-                                    }
-                                }, 
-                                undefined, undefined,
-                                ".env");
-                        }
-                    }, undefined, true);
-                };
-                elemValue.appendChild(inputElement);
-
-                if (!this._scene.getEngine().premultipliedAlpha) {
-                    elemValue = Helpers.CreateDiv(null, this._panel);
-
-                    inputElement = Inspector.DOCUMENT.createElement('input');
-                    inputElement.value = "Compress current texture to .env";
-                    inputElement.className = "tool-input";
-                    inputElement.type = "button";
-                    inputElement.onclick = () => {
-                        if (!this._scene.environmentTexture) {
-                            errorElemm.style.display = "block";
-                            errorElemm.textContent = "You must load an environment texture first.";
-                            return;
-                        }
-                        if (this._scene.activeCamera) {
-                            BABYLON.EnvironmentTextureTools.CreateEnvTextureAsync(<BABYLON.CubeTexture>this._scene.environmentTexture)
+                    if (this._scene.activeCamera) {
+                        EnvironmentTextureTools.CreateEnvTextureAsync(<CubeTexture>this._scene.environmentTexture)
                             .then((buffer: ArrayBuffer) => {
-                                var blob = new Blob([buffer], {type: "octet/stream"});
-                                BABYLON.Tools.Download(blob, "environment.env");
+                                var blob = new Blob([buffer], { type: "octet/stream" });
+                                Tools.Download(blob, "environment.env");
                                 errorElemm.style.display = "none";
                             })
                             .catch((error: any) => {
                                 errorElemm.style.display = "block";
                                 errorElemm.textContent = error;
                             });
-                        }
-                        else {
-                            errorElemm.style.display = "block";
-                            errorElemm.textContent = "An active camera is required.";
-                        }
-                    };
-                    elemValue.appendChild(inputElement);
-                }
-                
-                this._panel.appendChild(errorElemm);
-            }
-
-            title = Helpers.CreateDiv('tool-title2', this._panel);
-            title.textContent = "Capture";
-            {
-                let elemValue = Helpers.CreateDiv(null, this._panel);
-
-                let inputElement = Inspector.DOCUMENT.createElement('input');
-                inputElement.value = "Take Screenshot";
-                inputElement.type = "button";
-                inputElement.className = "tool-input";
-                inputElement.onclick = () => {
-                    if (this._scene.activeCamera) {
-                        BABYLON.Tools.CreateScreenshot(this._scene.getEngine(), this._scene.activeCamera, {precision: 0.5});
+                    }
+                    else {
+                        errorElemm.style.display = "block";
+                        errorElemm.textContent = "An active camera is required.";
                     }
                 };
                 elemValue.appendChild(inputElement);
             }
+
+            this._panel.appendChild(errorElemm);
         }
 
-        public dispose() {
-            // Nothing to dispose
+        title = Helpers.CreateDiv('tool-title2', this._panel);
+        title.textContent = "Capture";
+        {
+            let elemValue = Helpers.CreateDiv(null, this._panel);
+
+            let inputElement = Inspector.DOCUMENT.createElement('input');
+            inputElement.value = "Take Screenshot";
+            inputElement.type = "button";
+            inputElement.className = "tool-input";
+            inputElement.onclick = () => {
+                if (this._scene.activeCamera) {
+                    Tools.CreateScreenshot(this._scene.getEngine(), this._scene.activeCamera, { precision: 0.5 });
+                }
+            };
+            elemValue.appendChild(inputElement);
         }
     }
-}
+
+    public dispose() {
+        // Nothing to dispose
+    }
+}

+ 37 - 36
inspector/src/tools/AbstractTool.ts

@@ -1,48 +1,49 @@
-module INSPECTOR {
-    export abstract class AbstractTool {
-        private _elem: HTMLElement;
-        protected _inspector: Inspector;
+import { Inspector } from "../Inspector";
+import { Tooltip } from "../gui/Tooltip";
 
-        constructor(iconSet: string, icon: string, parent: HTMLElement, inspector: Inspector, tooltip: string) {
-            this._inspector = inspector;
+export abstract class AbstractTool {
+    private _elem: HTMLElement;
+    protected _inspector: Inspector;
 
-            this._elem = Inspector.DOCUMENT.createElement('i');
-            this._elem.className = `tool ${iconSet} ${icon}`;
-            parent.appendChild(this._elem);
+    constructor(iconSet: string, icon: string, parent: HTMLElement, inspector: Inspector, tooltip: string) {
+        this._inspector = inspector;
 
-            this._elem.addEventListener('click', (e) => {
-                this.action();
-            });
+        this._elem = Inspector.DOCUMENT.createElement('i');
+        this._elem.className = `tool ${iconSet} ${icon}`;
+        parent.appendChild(this._elem);
 
-            new Tooltip(this._elem, tooltip);
-        }
+        this._elem.addEventListener('click', (e) => {
+            this.action();
+        });
 
-        public toHtml(): HTMLElement {
-            return this._elem;
-        }
+        new Tooltip(this._elem, tooltip);
+    }
 
-        /** 
-         * Returns the total width in pixel of this tool, 0 by default
-        */
-        public getPixelWidth(): number {
-            let style = Inspector.WINDOW.getComputedStyle(this._elem);
+    public toHtml(): HTMLElement {
+        return this._elem;
+    }
 
-            if (!style.marginLeft || !style.marginRight) {
-                return 0;
-            }
+    /** 
+     * Returns the total width in pixel of this tool, 0 by default
+    */
+    public getPixelWidth(): number {
+        let style = Inspector.WINDOW.getComputedStyle(this._elem);
 
-            let left = parseFloat(style.marginLeft.substr(0, style.marginLeft.length - 2)) || 0;
-            let right = parseFloat(style.marginRight.substr(0, style.marginRight.length - 2)) || 0;
-            return (this._elem.clientWidth || 0) + left + right;
+        if (!style.marginLeft || !style.marginRight) {
+            return 0;
         }
 
-        /** 
-         * Updates the icon of this tool with the given string
-         */
-        protected _updateIcon(icon: string) {
-            this._elem.className = `tool fa ${icon}`;
-        }
+        let left = parseFloat(style.marginLeft.substr(0, style.marginLeft.length - 2)) || 0;
+        let right = parseFloat(style.marginRight.substr(0, style.marginRight.length - 2)) || 0;
+        return (this._elem.clientWidth || 0) + left + right;
+    }
 
-        public abstract action(): void;
+    /** 
+     * Updates the icon of this tool with the given string
+     */
+    protected _updateIcon(icon: string) {
+        this._elem.className = `tool fa ${icon}`;
     }
-}
+
+    public abstract action(): void;
+}

+ 14 - 14
inspector/src/tools/DisposeTool.ts

@@ -1,17 +1,17 @@
-module INSPECTOR {
-     
-    /**
-     * Removes the inspector panel
-     */
-    export class DisposeTool extends AbstractTool {
+import { AbstractTool } from "./AbstractTool";
+import { Inspector } from "../Inspector";
 
-        constructor(parent:HTMLElement, inspector:Inspector) {
-            super('fa', 'fa-times', parent, inspector, 'Close the inspector panel');
-        }
+/**
+ * Removes the inspector panel
+ */
+export class DisposeTool extends AbstractTool {
 
-        // Action : refresh the whole panel
-        public action() {
-            this._inspector.dispose();
-        }
+    constructor(parent: HTMLElement, inspector: Inspector) {
+        super('fa', 'fa-times', parent, inspector, 'Close the inspector panel');
     }
-}
+
+    // Action : refresh the whole panel
+    public action() {
+        this._inspector.dispose();
+    }
+}

+ 17 - 17
inspector/src/tools/FullscreenTool.ts

@@ -1,23 +1,23 @@
-module INSPECTOR {
-     
-    export class FullscreenTool extends AbstractTool {
+import { AbstractTool } from "./AbstractTool";
+import { Inspector } from "../Inspector";
 
-        constructor(parent:HTMLElement, inspector:Inspector) {
-            super('fa', 'fa-expand', parent, inspector, 'Open the scene in fullscreen, press Esc to exit');
-        }
+export class FullscreenTool extends AbstractTool {
+
+    constructor(parent: HTMLElement, inspector: Inspector) {
+        super('fa', 'fa-expand', parent, inspector, 'Open the scene in fullscreen, press Esc to exit');
+    }
 
-        // Action : refresh the whole panel
-        public action() {
+    // Action : refresh the whole panel
+    public action() {
 
-            var elem = document.body;
+        var elem = document.body;
 
-            function requestFullScreen(element:HTMLElement) {
-                // Supports most browsers and their versions.
-                var requestMethod = element.requestFullscreen || element.webkitRequestFullScreen;
-                requestMethod.call(element);
-            }
-           
-            requestFullScreen(elem);
+        function requestFullScreen(element: HTMLElement) {
+            // Supports most browsers and their versions.
+            var requestMethod = element.requestFullscreen || element.webkitRequestFullScreen;
+            requestMethod.call(element);
         }
+
+        requestFullScreen(elem);
     }
-}
+}

+ 99 - 95
inspector/src/tools/LabelTool.ts

@@ -1,127 +1,131 @@
-module INSPECTOR {
+import { AbstractTool } from "./AbstractTool";
+import { Nullable, Scene, AbstractMesh } from "babylonjs";
+import { Inspector } from "../Inspector";
 
-    export class LabelTool extends AbstractTool {
+import * as GUI from "babylonjs-gui";
+import { Helpers } from "../helpers/Helpers";
 
-        /** True if label are displayed, false otherwise */
-        private _isDisplayed: boolean = false;
-        private _advancedTexture: BABYLON.Nullable<BABYLON.GUI.AdvancedDynamicTexture> = null;
-        private _labelInitialized: boolean = false;
-        private _scene: BABYLON.Nullable<BABYLON.Scene> = null;
-        private _guiLoaded: boolean = false;
+export class LabelTool extends AbstractTool {
 
-        constructor(parent: HTMLElement, inspector: Inspector) {
-            super('fa', 'fa-tags', parent, inspector, 'Display mesh names on the canvas');
+    /** True if label are displayed, false otherwise */
+    private _isDisplayed: boolean = false;
+    private _advancedTexture: Nullable<GUI.AdvancedDynamicTexture> = null;
+    private _labelInitialized: boolean = false;
+    private _scene: Nullable<Scene> = null;
+    private _guiLoaded: boolean = false;
 
-            this._scene = inspector.scene;
-        }
+    constructor(parent: HTMLElement, inspector: Inspector) {
+        super('fa', 'fa-tags', parent, inspector, 'Display mesh names on the canvas');
+
+        this._scene = inspector.scene;
+    }
 
-        public dispose() {
+    public dispose() {
 
-            if (this._advancedTexture) {
-                this._advancedTexture.dispose();
-            }
+        if (this._advancedTexture) {
+            this._advancedTexture.dispose();
         }
+    }
 
-        private _checkGUILoaded(): boolean {
-            if (this._guiLoaded === true) {
-                return true;
-            }
-            if (BABYLON.GUI) {
-                this._guiLoaded = true;
-            }
-            return this._guiLoaded;
+    private _checkGUILoaded(): boolean {
+        if (this._guiLoaded === true) {
+            return true;
+        }
+        if (GUI) {
+            this._guiLoaded = true;
         }
+        return this._guiLoaded;
+    }
 
-        private _initializeLabels() {
-            // Check if the label are already initialized and quit if it's the case
-            if (this._labelInitialized || !this._scene) {
-                return;
-            }
+    private _initializeLabels() {
+        // Check if the label are already initialized and quit if it's the case
+        if (this._labelInitialized || !this._scene) {
+            return;
+        }
 
-            // Can't initialize them if the GUI lib is not loaded yet
-            if (!this._checkGUILoaded()) {
-                return;
-            }
+        // Can't initialize them if the GUI lib is not loaded yet
+        if (!this._checkGUILoaded()) {
+            return;
+        }
 
-            // Create the canvas that will be used to display the labels
-            this._advancedTexture = BABYLON.GUI.AdvancedDynamicTexture.CreateFullscreenUI("UI");
+        // Create the canvas that will be used to display the labels
+        this._advancedTexture = GUI.AdvancedDynamicTexture.CreateFullscreenUI("UI");
 
-            // Create label for all the Meshes, Lights and Cameras
-            // Those that will be created/removed after this method is called will be taken care by the event handlers added below
+        // Create label for all the Meshes, Lights and Cameras
+        // Those that will be created/removed after this method is called will be taken care by the event handlers added below
 
-            for (let m of this._scene.meshes) {
-                this._createLabel(m);
-            }
+        for (let m of this._scene.meshes) {
+            this._createLabel(m);
+        }
 
-            this._scene.onNewMeshAddedObservable.add((m, s) => {
-                this._createLabel(m);
-            });
+        this._scene.onNewMeshAddedObservable.add((m, s) => {
+            this._createLabel(m);
+        });
 
-            this._scene.onMeshRemovedObservable.add((m, s) => {
-                this._removeLabel(m);
-            });
+        this._scene.onMeshRemovedObservable.add((m, s) => {
+            this._removeLabel(m);
+        });
 
-            this._labelInitialized = true;
-        }
+        this._labelInitialized = true;
+    }
 
-        private _createLabel(mesh: BABYLON.AbstractMesh) {
-            // Don't create label for "system nodes" (starting and ending with ###)
-            let name = mesh.name;
+    private _createLabel(mesh: AbstractMesh) {
+        // Don't create label for "system nodes" (starting and ending with ###)
+        let name = mesh.name;
 
-            if (Helpers.IsSystemName(name)) {
-                return;
-            }
+        if (Helpers.IsSystemName(name)) {
+            return;
+        }
 
-            if (mesh && this._advancedTexture) {
-                let rect1 = new BABYLON.GUI.Rectangle();
-                rect1.width = 4 + 10 * name.length + "px";
-                rect1.height = "22px";
-                rect1.background = "rgba(0,0,0,0.6)";
-                rect1.color = "black";
-                this._advancedTexture.addControl(rect1);
+        if (mesh && this._advancedTexture) {
+            let rect1 = new GUI.Rectangle();
+            rect1.width = 4 + 10 * name.length + "px";
+            rect1.height = "22px";
+            rect1.background = "rgba(0,0,0,0.6)";
+            rect1.color = "black";
+            this._advancedTexture.addControl(rect1);
 
-                let label = new BABYLON.GUI.TextBlock();
-                label.text = name;
-                label.fontSize = 12;
-                rect1.addControl(label);
+            let label = new GUI.TextBlock();
+            label.text = name;
+            label.fontSize = 12;
+            rect1.addControl(label);
 
-                rect1.linkWithMesh(mesh);
-            }
+            rect1.linkWithMesh(mesh);
         }
+    }
 
-        private _removeLabel(mesh: BABYLON.AbstractMesh) {
-            if (!this._advancedTexture) {
-                return;
-            }
-            for (let g of this._advancedTexture._rootContainer.children) {
-                let ed = g._linkedMesh;
-                if (ed === mesh) {
-                    this._advancedTexture.removeControl(g);
-                    break;
-                }
+    private _removeLabel(mesh: AbstractMesh) {
+        if (!this._advancedTexture) {
+            return;
+        }
+        for (let g of this._advancedTexture._rootContainer.children) {
+            let ed = g._linkedMesh;
+            if (ed === mesh) {
+                this._advancedTexture.removeControl(g);
+                break;
             }
         }
+    }
 
-        // Action : Display/hide mesh names on the canvas
-        public action() {
-            // Don't toggle if the script is not loaded
-            if (!this._checkGUILoaded() || !this._advancedTexture) {
-                return;
-            }
+    // Action : Display/hide mesh names on the canvas
+    public action() {
+        // Don't toggle if the script is not loaded
+        if (!this._checkGUILoaded() || !this._advancedTexture) {
+            return;
+        }
 
-            // Toggle the label display state
-            this._isDisplayed = !this._isDisplayed;
+        // Toggle the label display state
+        this._isDisplayed = !this._isDisplayed;
 
-            // Check if we have to display the labels
-            if (this._isDisplayed) {
-                this._initializeLabels();
-                this._advancedTexture._rootContainer.isVisible = true;
-            }
+        // Check if we have to display the labels
+        if (this._isDisplayed) {
+            this._initializeLabels();
+            this._advancedTexture._rootContainer.isVisible = true;
+        }
 
-            // Or to hide them
-            else {
-                this._advancedTexture._rootContainer.isVisible = false;
-            }
+        // Or to hide them
+        else {
+            this._advancedTexture._rootContainer.isVisible = false;
         }
     }
-}
+}

+ 21 - 19
inspector/src/tools/PauseScheduleTool.ts

@@ -1,23 +1,25 @@
-module INSPECTOR {
-     
-    export class PauseScheduleTool extends AbstractTool {
-        
-        private _isPause : boolean = false;
+import { AbstractTool } from "./AbstractTool";
+import { Inspector } from "../Inspector";
+import { Scheduler } from "../scheduler/Scheduler";
 
-        constructor(parent:HTMLElement, inspector:Inspector) {
-            super('fa', 'fa-pause', parent, inspector, 'Pause the automatic update of properties');
-        }
 
-        // Action : refresh the whole panel
-        public action() {
-            if (this._isPause) {
-                Scheduler.getInstance().pause = false;
-                this._updateIcon('fa-pause');
-            } else {
-                Scheduler.getInstance().pause = true;
-                this._updateIcon('fa-play');
-            }
-            this._isPause = !this._isPause;
+export class PauseScheduleTool extends AbstractTool {
+
+    private _isPause: boolean = false;
+
+    constructor(parent: HTMLElement, inspector: Inspector) {
+        super('fa', 'fa-pause', parent, inspector, 'Pause the automatic update of properties');
+    }
+
+    // Action : refresh the whole panel
+    public action() {
+        if (this._isPause) {
+            Scheduler.getInstance().pause = false;
+            this._updateIcon('fa-pause');
+        } else {
+            Scheduler.getInstance().pause = true;
+            this._updateIcon('fa-play');
         }
+        this._isPause = !this._isPause;
     }
-}
+}

+ 52 - 50
inspector/src/tools/PickTool.ts

@@ -1,55 +1,57 @@
-module INSPECTOR {
-     
-    export class PickTool extends AbstractTool {
-        
-        private _isActive : boolean = false;
-        private _pickHandler: (evt: Event) => void;
-
-        constructor(parent:HTMLElement, inspector:Inspector) {
-            super('fa', 'fa-mouse-pointer', parent, inspector, 'Select a mesh in the scene');
-            
-            // Create handler
-            this._pickHandler = this._pickMesh.bind(this);
-        }
+import { AbstractTool } from "./AbstractTool";
+import { Inspector } from "../Inspector";
+import { AbstractMesh } from "babylonjs";
 
-        // Action : find the corresponding tree item in the correct tab and display it
-        public action() {
-            if (this._isActive) {
-                this._deactivate();
-            } else {                 
-                this.toHtml().classList.add('active');            
-                // Add event handler : pick on a mesh in the scene
-                let canvas = <HTMLElement>this._inspector.scene.getEngine().getRenderingCanvas();
-                canvas.addEventListener('click', this._pickHandler);
-                this._isActive = true;
-            }
-        }
-        
-        /** Deactivate this tool */
-        private _deactivate() {
-            this.toHtml().classList.remove('active');            
-            // Remove event handler
+
+export class PickTool extends AbstractTool {
+
+    private _isActive: boolean = false;
+    private _pickHandler: (evt: Event) => void;
+
+    constructor(parent: HTMLElement, inspector: Inspector) {
+        super('fa', 'fa-mouse-pointer', parent, inspector, 'Select a mesh in the scene');
+
+        // Create handler
+        this._pickHandler = this._pickMesh.bind(this);
+    }
+
+    // Action : find the corresponding tree item in the correct tab and display it
+    public action() {
+        if (this._isActive) {
+            this._deactivate();
+        } else {
+            this.toHtml().classList.add('active');
+            // Add event handler : pick on a mesh in the scene
             let canvas = <HTMLElement>this._inspector.scene.getEngine().getRenderingCanvas();
-            canvas.removeEventListener('click', this._pickHandler);
-            this._isActive = false;
+            canvas.addEventListener('click', this._pickHandler);
+            this._isActive = true;
         }
-        
-        /** Pick a mesh in the scene */
-        private _pickMesh(evt: PointerEvent) {
-            let pos = this._updatePointerPosition(evt);
-            let pi = this._inspector.scene.pick(pos.x, pos.y, (mesh:BABYLON.AbstractMesh) => {return true});
-            
-            if (pi && pi.pickedMesh) {
-                this._inspector.displayObjectDetails(pi.pickedMesh);
-            }
-            this._deactivate();
+    }
+
+    /** Deactivate this tool */
+    private _deactivate() {
+        this.toHtml().classList.remove('active');
+        // Remove event handler
+        let canvas = <HTMLElement>this._inspector.scene.getEngine().getRenderingCanvas();
+        canvas.removeEventListener('click', this._pickHandler);
+        this._isActive = false;
+    }
+
+    /** Pick a mesh in the scene */
+    private _pickMesh(evt: PointerEvent) {
+        let pos = this._updatePointerPosition(evt);
+        let pi = this._inspector.scene.pick(pos.x, pos.y, (mesh: AbstractMesh) => { return true });
+
+        if (pi && pi.pickedMesh) {
+            this._inspector.displayObjectDetails(pi.pickedMesh);
         }
-        
-        private _updatePointerPosition(evt: PointerEvent) : {x:number, y:number}{
-            let canvasRect = <ClientRect>this._inspector.scene.getEngine().getRenderingCanvasClientRect();
-            let pointerX = evt.clientX - canvasRect.left;
-            let pointerY = evt.clientY - canvasRect.top;
-            return {x:pointerX, y:pointerY};
-        };
+        this._deactivate();
     }
-}
+
+    private _updatePointerPosition(evt: PointerEvent): { x: number, y: number } {
+        let canvasRect = <ClientRect>this._inspector.scene.getEngine().getRenderingCanvasClientRect();
+        let pointerX = evt.clientX - canvasRect.left;
+        let pointerY = evt.clientY - canvasRect.top;
+        return { x: pointerX, y: pointerY };
+    };
+}

+ 14 - 13
inspector/src/tools/PopupTool.ts

@@ -1,14 +1,15 @@
-module INSPECTOR {
-     
-    export class PopupTool extends AbstractTool {
-
-        constructor(parent:HTMLElement, inspector:Inspector) {
-            super('fas', 'fa-external-link-alt', parent, inspector, 'Open the inspector in a popup');
-        }
-
-        // Action : refresh the whole panel
-        public action() {
-            this._inspector.openPopup();
-        }
+import { AbstractTool } from "./AbstractTool";
+import { Inspector } from "../Inspector";
+
+
+export class PopupTool extends AbstractTool {
+
+    constructor(parent: HTMLElement, inspector: Inspector) {
+        super('fas', 'fa-external-link-alt', parent, inspector, 'Open the inspector in a popup');
+    }
+
+    // Action : refresh the whole panel
+    public action() {
+        this._inspector.openPopup();
     }
-}
+}

+ 14 - 13
inspector/src/tools/RefreshTool.ts

@@ -1,14 +1,15 @@
-module INSPECTOR {
-     
-    export class RefreshTool extends AbstractTool {
-
-        constructor(parent:HTMLElement, inspector:Inspector) {
-            super('fa', 'fa-sync', parent, inspector, 'Refresh the current tab');
-        }
-
-        // Action : refresh the whole panel
-        public action() {
-            this._inspector.refresh();
-        }
+import { AbstractTool } from "./AbstractTool";
+import { Inspector } from "../Inspector";
+
+
+export class RefreshTool extends AbstractTool {
+
+    constructor(parent: HTMLElement, inspector: Inspector) {
+        super('fa', 'fa-sync', parent, inspector, 'Refresh the current tab');
+    }
+
+    // Action : refresh the whole panel
+    public action() {
+        this._inspector.refresh();
     }
-}
+}

+ 61 - 51
inspector/src/tools/Toolbar.ts

@@ -1,59 +1,69 @@
- module INSPECTOR {
+import { BasicElement } from "../gui/BasicElement";
+import { Inspector } from "../Inspector";
+import { AbstractTool } from "./AbstractTool";
+import { RefreshTool } from "./RefreshTool";
+import { LabelTool } from "./LabelTool";
+import { PickTool } from "./PickTool";
+import { Helpers } from "../helpers/Helpers";
+import { PopupTool } from "./PopupTool";
+import { FullscreenTool } from "./FullscreenTool";
+import { PauseScheduleTool } from "./PauseScheduleTool";
+import { DisposeTool } from "./DisposeTool";
 
-    export class Toolbar extends BasicElement {
 
-        private _inspector: Inspector;
-        private _tools : Array<AbstractTool> = []
+export class Toolbar extends BasicElement {
 
-        constructor (inspector:Inspector) {
-            super();
-            this._inspector = inspector;
-            this._build(); 
+    private _inspector: Inspector;
+    private _tools: Array<AbstractTool> = []
 
-            this._addTools();
-        }
-        
-        // A toolbar cannot be updated
-        public update() {};
-        
-        protected _build() {            
-            this._div.className = 'toolbar';
-        };
-
-        private _addTools() {
-            // Refresh
-            this._tools.push(new RefreshTool(this._div, this._inspector));  
-            // Display labels
-            this._tools.push(new LabelTool(this._div, this._inspector));          
-            // Pick object
-            this._tools.push(new PickTool(this._div, this._inspector));
-            
-            // Add the popup mode only if the inspector is not in popup mode and if the brower is not edge
-            // Edge is 
-            if (!this._inspector.popupMode && !Helpers.IsBrowserEdge()) {
-                this._tools.push(new PopupTool(this._div, this._inspector));
-            }
-            // FullScreen
-            this._tools.push(new FullscreenTool(this._div, this._inspector));
-
-            // Pause schedule
-            this._tools.push(new PauseScheduleTool(this._div, this._inspector));
-            
-            // Pause schedule
-            this._tools.push(new DisposeTool(this._div, this._inspector));
+    constructor(inspector: Inspector) {
+        super();
+        this._inspector = inspector;
+        this._build();
+
+        this._addTools();
+    }
+
+    // A toolbar cannot be updated
+    public update() { };
+
+    protected _build() {
+        this._div.className = 'toolbar';
+    };
+
+    private _addTools() {
+        // Refresh
+        this._tools.push(new RefreshTool(this._div, this._inspector));
+        // Display labels
+        this._tools.push(new LabelTool(this._div, this._inspector));
+        // Pick object
+        this._tools.push(new PickTool(this._div, this._inspector));
+
+        // Add the popup mode only if the inspector is not in popup mode and if the brower is not edge
+        // Edge is 
+        if (!this._inspector.popupMode && !Helpers.IsBrowserEdge()) {
+            this._tools.push(new PopupTool(this._div, this._inspector));
         }
+        // FullScreen
+        this._tools.push(new FullscreenTool(this._div, this._inspector));
+
+        // Pause schedule
+        this._tools.push(new PauseScheduleTool(this._div, this._inspector));
 
-        /** 
-         * Returns the total width in pixel of the tabbar, 
-         * that corresponds to the sum of the width of each tab + toolbar width
-        */
-        public getPixelWidth() : number {
-            let sum = 0;
-            for (let tool of this._tools) {
-                sum += tool.getPixelWidth();
-            }
-            
-            return sum;
+        // Pause schedule
+        this._tools.push(new DisposeTool(this._div, this._inspector));
+    }
+
+    /** 
+     * Returns the total width in pixel of the tabbar, 
+     * that corresponds to the sum of the width of each tab + toolbar width
+    */
+    public getPixelWidth(): number {
+        let sum = 0;
+        for (let tool of this._tools) {
+            sum += tool.getPixelWidth();
         }
+
+        return sum;
     }
- }
+}

+ 160 - 152
inspector/src/tree/TreeItem.ts

@@ -1,189 +1,197 @@
-module INSPECTOR {
+import { BasicElement } from "../gui/BasicElement";
+import { Tab } from "../tabs/Tab";
+import { Adapter } from "../adapters/Adapter";
+import { AbstractTreeTool } from "../treetools/AbstractTreeTool";
+import { MeshAdapter } from "../adapters/MeshAdapter";
+import { TransformNode, AbstractMesh } from "babylonjs";
+import { Inspector } from "../Inspector";
+import { Helpers } from "../helpers/Helpers";
+import { PropertyLine } from "../details/PropertyLine";
 
-    export class TreeItem extends BasicElement {
 
-        // Reference to the tab
-        private _tab: Tab;
-        // The object this item is linked to (should be a primitive or a canvas) TODO should be superclass of all primitives
-        private _adapter: Adapter;
-        private _tools: Array<AbstractTreeTool>;
-        public children: Array<TreeItem> = [];
-        // Div element that contains all children of this node.
-        private _lineContent: HTMLElement;
+export class TreeItem extends BasicElement {
 
-        constructor(tab: Tab, obj: Adapter) {
-            super();
-            this._tab = tab;
-            this._adapter = obj;
+    // Reference to the tab
+    private _tab: Tab;
+    // The object this item is linked to (should be a primitive or a canvas) TODO should be superclass of all primitives
+    private _adapter: Adapter;
+    private _tools: Array<AbstractTreeTool>;
+    public children: Array<TreeItem> = [];
+    // Div element that contains all children of this node.
+    private _lineContent: HTMLElement;
 
-            this._tools = this._adapter.getTools();
+    constructor(tab: Tab, obj: Adapter) {
+        super();
+        this._tab = tab;
+        this._adapter = obj;
 
-            this._build();
+        this._tools = this._adapter.getTools();
 
-        }
+        this._build();
 
-        /** Returns the item ID == its adapter ID */
-        public get id(): string {
-            return this._adapter.id();
-        }
+    }
 
-        /** Add the given item as a child of this one */
-        public add(child: TreeItem) {
-            this.children.push(child);
-            this.update();
-        }
+    /** Returns the item ID == its adapter ID */
+    public get id(): string {
+        return this._adapter.id();
+    }
 
-        /**
-         * Returns the original adapter
-         */
-        public get adapter(): Adapter {
-            return this._adapter;
-        }
+    /** Add the given item as a child of this one */
+    public add(child: TreeItem) {
+        this.children.push(child);
+        this.update();
+    }
 
-        /**
-         * Function used to compare this item to another tree item.
-         * Returns the alphabetical sort of the adapter ID
-         */
-        public compareTo(item: TreeItem): number {
-            let str1 = this.id;
-            let str2 = item.id;
-            return str1.localeCompare(str2, [], { numeric: true });
-        }
+    /**
+     * Returns the original adapter
+     */
+    public get adapter(): Adapter {
+        return this._adapter;
+    }
 
-        /** Returns true if the given obj correspond to the adapter linked to this tree item */
-        public correspondsTo(obj: any): boolean {
-            return this._adapter.correspondsTo(obj);
-        }
+    /**
+     * Function used to compare this item to another tree item.
+     * Returns the alphabetical sort of the adapter ID
+     */
+    public compareTo(item: TreeItem): number {
+        let str1 = this.id;
+        let str2 = item.id;
+        return str1.localeCompare(str2, [], { numeric: true });
+    }
 
-        /** hide all children of this item */
-        public fold() {
-            // Do nothing id no children
-            if (this.children.length > 0) {
-                for (let elem of this.children) {
-                    elem.toHtml().style.display = 'none';
-                }
-                this._div.classList.add('folded');
-                this._div.classList.remove('unfolded');
+    /** Returns true if the given obj correspond to the adapter linked to this tree item */
+    public correspondsTo(obj: any): boolean {
+        return this._adapter.correspondsTo(obj);
+    }
+
+    /** hide all children of this item */
+    public fold() {
+        // Do nothing id no children
+        if (this.children.length > 0) {
+            for (let elem of this.children) {
+                elem.toHtml().style.display = 'none';
             }
+            this._div.classList.add('folded');
+            this._div.classList.remove('unfolded');
         }
-        /** Show all children of this item */
-        public unfold() {
-            // Do nothing id no children
-            if (this.children.length > 0) {
-                for (let elem of this.children) {
-                    elem.toHtml().style.display = 'block';
-                }
-                this._div.classList.add('unfolded');
-                this._div.classList.remove('folded');
+    }
+    /** Show all children of this item */
+    public unfold() {
+        // Do nothing id no children
+        if (this.children.length > 0) {
+            for (let elem of this.children) {
+                elem.toHtml().style.display = 'block';
             }
+            this._div.classList.add('unfolded');
+            this._div.classList.remove('folded');
         }
+    }
 
-        /** Build the HTML of this item */
-        protected _build() {
-
-            /**
-             *  Hide the debug objects :
-             * - Axis : xline, yline, zline
-             * */
-            let adapterId = this._adapter.id();
-            if (adapterId == "xline"
-                || adapterId == "yline"
-                || adapterId == "zline") {
-                this._div.className = "line_invisible";
-            }
-            else this._div.className = 'line';
-
-            // special class for transform node ONLY
-            if (this.adapter instanceof MeshAdapter) {
-                let obj = this.adapter.object;
-                if (obj instanceof BABYLON.TransformNode && !(obj instanceof BABYLON.AbstractMesh)) {
-                    this._div.className += ' transformNode';
-                }
-            }
+    /** Build the HTML of this item */
+    protected _build() {
 
+        /**
+         *  Hide the debug objects :
+         * - Axis : xline, yline, zline
+         * */
+        let adapterId = this._adapter.id();
+        if (adapterId == "xline"
+            || adapterId == "yline"
+            || adapterId == "zline") {
+            this._div.className = "line_invisible";
+        }
+        else this._div.className = 'line';
 
-            for (let tool of this._tools) {
-                this._div.appendChild(tool.toHtml());
+        // special class for transform node ONLY
+        if (this.adapter instanceof MeshAdapter) {
+            let obj = this.adapter.object;
+            if (obj instanceof TransformNode && !(obj instanceof AbstractMesh)) {
+                this._div.className += ' transformNode';
             }
+        }
 
 
-            // Id
-            let text = Inspector.DOCUMENT.createElement('span');
-            text.textContent = this._adapter.id();
-            this._div.appendChild(text);
+        for (let tool of this._tools) {
+            this._div.appendChild(tool.toHtml());
+        }
 
-            // Type
-            let type = Inspector.DOCUMENT.createElement('span');
-            type.className = 'property-type';
-            if (this._adapter.type() !== 'type_not_defined') {
-                type.textContent = ' - ' + this._adapter.type();
-            }
-            this._div.appendChild(type);
 
-            this._lineContent = Helpers.CreateDiv('line-content', this._div);
+        // Id
+        let text = Inspector.DOCUMENT.createElement('span');
+        text.textContent = this._adapter.id();
+        this._div.appendChild(text);
 
-            this._addEvent();
+        // Type
+        let type = Inspector.DOCUMENT.createElement('span');
+        type.className = 'property-type';
+        if (this._adapter.type() !== 'type_not_defined') {
+            type.textContent = ' - ' + this._adapter.type();
         }
+        this._div.appendChild(type);
 
-        /**
-         * Returns one HTML element (.details) containing all  details of this primitive
-         */
-        public getDetails(): Array<PropertyLine> {
-            return this._adapter.getProperties();
-        }
+        this._lineContent = Helpers.CreateDiv('line-content', this._div);
 
-        public update() {
-            // Clean division holding all children
-            Helpers.CleanDiv(this._lineContent);
+        this._addEvent();
+    }
 
-            for (let child of this.children) {
-                let elem = child.toHtml();
-                this._lineContent.appendChild(elem);
-            }
-            if (this.children.length > 0) {
-                // Check if folded or not
-                if (!this._div.classList.contains('folded') && !this._div.classList.contains('unfolded')) {
-                    this._div.classList.add('folded');
-                }
-            }
-            this.fold();
-        }
+    /**
+     * Returns one HTML element (.details) containing all  details of this primitive
+     */
+    public getDetails(): Array<PropertyLine> {
+        return this._adapter.getProperties();
+    }
 
-        /**
-         * Add an event listener on the item : 
-         * - one click display details
-         */
-        protected _addEvent() {
-            this._div.addEventListener('click', (e) => {
-                this._tab.select(this);
-                // Fold/unfold the tree
-                if (this._isFolded()) {
-                    this.unfold();
-                } else {
-                    this.fold();
-                }
-                e.stopPropagation();
-            });
-        }
+    public update() {
+        // Clean division holding all children
+        Helpers.CleanDiv(this._lineContent);
 
-        /** Returns true if the node is folded, false otherwise */
-        private _isFolded(): boolean {
-            return !this._div.classList.contains('unfolded');
+        for (let child of this.children) {
+            let elem = child.toHtml();
+            this._lineContent.appendChild(elem);
         }
-
-        /** Set this item as active (background lighter) in the tree panel */
-        public active(b: boolean) {
-            this._div.classList.remove('active');
-            for (let child of this.children) {
-                child.active(false);
-            }
-            if (b) {
-                this._div.classList.add('active');
+        if (this.children.length > 0) {
+            // Check if folded or not
+            if (!this._div.classList.contains('folded') && !this._div.classList.contains('unfolded')) {
+                this._div.classList.add('folded');
             }
         }
+        this.fold();
+    }
+
+    /**
+     * Add an event listener on the item : 
+     * - one click display details
+     */
+    protected _addEvent() {
+        this._div.addEventListener('click', (e) => {
+            this._tab.select(this);
+            // Fold/unfold the tree
+            if (this._isFolded()) {
+                this.unfold();
+            } else {
+                this.fold();
+            }
+            e.stopPropagation();
+        });
+    }
 
-        public getDiv() {
-            return this._div;
+    /** Returns true if the node is folded, false otherwise */
+    private _isFolded(): boolean {
+        return !this._div.classList.contains('unfolded');
+    }
+
+    /** Set this item as active (background lighter) in the tree panel */
+    public active(b: boolean) {
+        this._div.classList.remove('active');
+        for (let child of this.children) {
+            child.active(false);
+        }
+        if (b) {
+            this._div.classList.add('active');
         }
     }
-}
+
+    public getDiv() {
+        return this._div;
+    }
+}

+ 29 - 29
inspector/src/treetools/AbstractTreeTool.ts

@@ -1,34 +1,34 @@
- module INSPECTOR {
-     
-    export abstract class AbstractTreeTool {
-        protected _elem: HTMLElement;
-        /** Is the tool enabled ? */
-        protected _on  : boolean = false;
-        
-        constructor() {
-            this._elem = Inspector.DOCUMENT.createElement('i');
-            this._elem.className = 'treeTool fa';
-            this._addEvents();
-        }    
+import { Inspector } from "../Inspector";
 
-        public toHtml() : HTMLElement {
-            return this._elem;
-        }
 
-        protected _addEvents() {
-            this._elem.addEventListener('click', (e) => {
-                this.action();
-                e.stopPropagation();
-            });
-        }
+export abstract class AbstractTreeTool {
+    protected _elem: HTMLElement;
+    /** Is the tool enabled ? */
+    protected _on: boolean = false;
 
-        /**
-         * Action launched when clicked on this element
-         * Should be overrided
-         */
-        protected action() {
-            this._on = !this._on;
-        }
+    constructor() {
+        this._elem = Inspector.DOCUMENT.createElement('i');
+        this._elem.className = 'treeTool fa';
+        this._addEvents();
+    }
+
+    public toHtml(): HTMLElement {
+        return this._elem;
+    }
 
+    protected _addEvents() {
+        this._elem.addEventListener('click', (e) => {
+            this.action();
+            e.stopPropagation();
+        });
     }
- }
+
+    /**
+     * Action launched when clicked on this element
+     * Should be overrided
+     */
+    protected action() {
+        this._on = !this._on;
+    }
+
+}

+ 35 - 36
inspector/src/treetools/BoundingBox.ts

@@ -1,43 +1,42 @@
-module INSPECTOR{
+import { AbstractTreeTool } from "./AbstractTreeTool";
 
-    /** Any object implementing this interface should 
-     * provide methods to toggle its bounding box
-     */
-    export interface IToolBoundingBox {
-        isBoxVisible   : () => boolean,
-        setBoxVisible  : (b:boolean) => void;
-    }
-    /**
-     * Checkbox to display/hide the primitive
-     */
-    export class BoundingBox extends AbstractTreeTool{
+/** Any object implementing this interface should 
+ * provide methods to toggle its bounding box
+ */
+export interface IToolBoundingBox {
+    isBoxVisible: () => boolean,
+    setBoxVisible: (b: boolean) => void;
+}
+/**
+ * Checkbox to display/hide the primitive
+ */
+export class BoundingBox extends AbstractTreeTool {
 
-        private _obj : IToolBoundingBox;
+    private _obj: IToolBoundingBox;
 
-        constructor(obj:IToolBoundingBox) {
-            super (); 
-            this._obj = obj;
-            this._elem.classList.add('fa-cube');
-            this._on = this._obj.isBoxVisible();
-            this._check();
-        }
+    constructor(obj: IToolBoundingBox) {
+        super();
+        this._obj = obj;
+        this._elem.classList.add('fa-cube');
+        this._on = this._obj.isBoxVisible();
+        this._check();
+    }
 
-        // For a checkbox, set visible/invisible the corresponding prim
-        protected action() {     
-            super.action();
-            // update object and gui according to the new status
-            this._check();
-        }
+    // For a checkbox, set visible/invisible the corresponding prim
+    protected action() {
+        super.action();
+        // update object and gui according to the new status
+        this._check();
+    }
 
-        private _check() {
-             if (this._on) {
-                // set icon eye
-                this._elem.classList.add('active');
-            }else {
-                // set icon eye-slash
-                this._elem.classList.remove('active');
-            }
-            this._obj.setBoxVisible(this._on);
+    private _check() {
+        if (this._on) {
+            // set icon eye
+            this._elem.classList.add('active');
+        } else {
+            // set icon eye-slash
+            this._elem.classList.remove('active');
         }
+        this._obj.setBoxVisible(this._on);
     }
-}
+}

+ 47 - 47
inspector/src/treetools/CameraPOV.ts

@@ -1,55 +1,55 @@
-module INSPECTOR {
-
-    export interface ICameraPOV {
-        setPOV: () => void,
-        getCurrentActiveCamera: () => string,
-        id: () => string
+import { AbstractTreeTool } from "./AbstractTreeTool";
+import { Inspector } from "../Inspector";
+
+
+export interface ICameraPOV {
+    setPOV: () => void,
+    getCurrentActiveCamera: () => string,
+    id: () => string
+}
+
+/**
+ * 
+ */
+export class CameraPOV extends AbstractTreeTool {
+    private cameraPOV: ICameraPOV;
+
+    constructor(camera: ICameraPOV) {
+        super();
+        this.cameraPOV = camera;
+
+        // Setting the id of the line with the name of the camera
+        this._elem.id = this.cameraPOV.id();
+
+        // Put the right icon 
+        if (this._elem.id == this.cameraPOV.getCurrentActiveCamera()) {
+            this._elem.classList.add('fa-check-circle');
+        } else {
+            this._elem.classList.add('fa-circle');
+        }
     }
 
-    /**
-     * 
-     */
-    export class CameraPOV extends AbstractTreeTool {
-        private cameraPOV: ICameraPOV;
-
-        constructor(camera: ICameraPOV) {
-            super();
-            this.cameraPOV = camera;
-
-            // Setting the id of the line with the name of the camera
-            this._elem.id = this.cameraPOV.id();
-
-            // Put the right icon 
-            if(this._elem.id == this.cameraPOV.getCurrentActiveCamera()){
-                this._elem.classList.add('fa-check-circle');
-            }else{
-                this._elem.classList.add('fa-circle');
-            }
-        }
+    protected action() {
+        super.action();
+        this._gotoPOV();
+    }
 
-        protected action() {
-            super.action();
-            this._gotoPOV();
+    private _gotoPOV() {
+        // Uncheck all the radio buttons
+        let actives = Inspector.DOCUMENT.querySelectorAll(".fa-check-circle");
+        for (let i = 0; i < actives.length; i++) {
+            actives[i].classList.remove('fa-check-circle');
+            actives[i].classList.add('fa-circle');
         }
 
-        private _gotoPOV() {
-            // Uncheck all the radio buttons
-            let actives = Inspector.DOCUMENT.querySelectorAll(".fa-check-circle");
-            for (let i = 0; i < actives.length; i++) {
-                actives[i].classList.remove('fa-check-circle');
-                actives[i].classList.add('fa-circle');
-            }
-            
-            // setting the point off view to the right camera
-            this.cameraPOV.setPOV();
-
-            // Check the right radio button
-            if(this._elem.id == this.cameraPOV.getCurrentActiveCamera())
-            {
-                this._elem.classList.remove('fa-circle');
-                this._elem.classList.add('fa-check-circle');
-            }
+        // setting the point off view to the right camera
+        this.cameraPOV.setPOV();
 
+        // Check the right radio button
+        if (this._elem.id == this.cameraPOV.getCurrentActiveCamera()) {
+            this._elem.classList.remove('fa-circle');
+            this._elem.classList.add('fa-check-circle');
         }
+
     }
-}
+}

+ 40 - 41
inspector/src/treetools/Checkbox.ts

@@ -1,49 +1,48 @@
-module INSPECTOR{
+import { AbstractTreeTool } from "./AbstractTreeTool";
 
-    /** Any object implementing this interface should 
-     * provide methods to toggle its visibility
-     */
-    export interface IToolVisible {
-        isVisible   : () => boolean,
-        setVisible  : (b:boolean) => void;
+/** Any object implementing this interface should 
+ * provide methods to toggle its visibility
+ */
+export interface IToolVisible {
+    isVisible: () => boolean,
+    setVisible: (b: boolean) => void;
+}
+/**
+ * Checkbox to display/hide the primitive
+ */
+export class Checkbox extends AbstractTreeTool {
+
+    private _obj: IToolVisible;
+
+    constructor(obj: IToolVisible) {
+        super();
+        this._obj = obj;
+        this._elem.classList.add('fa-eye');
+        this._on = this._obj.isVisible();
+        this._check(true);
     }
-    /**
-     * Checkbox to display/hide the primitive
-     */
-    export class Checkbox extends AbstractTreeTool{
 
-        private _obj : IToolVisible;
+    // For a checkbox, set visible/invisible the corresponding prim
+    protected action() {
+        super.action();
+        // update object and gui according to the new status
+        this._check();
+    }
 
-        constructor(obj:IToolVisible) {
-            super (); 
-            this._obj = obj;
+    private _check(dontEnable?: boolean) {
+        if (this._on) {
+            // set icon eye
             this._elem.classList.add('fa-eye');
-            this._on = this._obj.isVisible();
-            this._check(true);
+            this._elem.classList.add('active');
+            this._elem.classList.remove('fa-eye-slash');
+        } else {
+            // set icon eye-slash
+            this._elem.classList.remove('fa-eye');
+            this._elem.classList.remove('active');
+            this._elem.classList.add('fa-eye-slash');
         }
-
-        // For a checkbox, set visible/invisible the corresponding prim
-        protected action() {     
-            super.action();
-            // update object and gui according to the new status
-            this._check();
-        }
-
-        private _check(dontEnable?:boolean) {
-             if (this._on) {
-                // set icon eye
-                this._elem.classList.add('fa-eye');
-                this._elem.classList.add('active');
-                this._elem.classList.remove('fa-eye-slash');
-            }else {
-                // set icon eye-slash
-                this._elem.classList.remove('fa-eye');
-                this._elem.classList.remove('active');
-                this._elem.classList.add('fa-eye-slash');
-            }
-            if (!dontEnable) {
-                this._obj.setVisible(this._on);
-            }
+        if (!dontEnable) {
+            this._obj.setVisible(this._on);
         }
     }
-}
+}

+ 25 - 25
inspector/src/treetools/DebugArea.ts

@@ -1,31 +1,31 @@
-module INSPECTOR {
-    /** Any object implementing this interface should 
-     * provide methods to toggle a debug area
-     */
-    export interface IToolDebug {
-        debug  : (b:boolean) => void;
-    }
+import { AbstractTreeTool } from "./AbstractTreeTool";
 
-    export class DebugArea extends AbstractTreeTool {
+/** Any object implementing this interface should 
+ * provide methods to toggle a debug area
+ */
+export interface IToolDebug {
+    debug: (b: boolean) => void;
+}
 
-        private _obj : IToolDebug;
+export class DebugArea extends AbstractTreeTool {
 
-        constructor(obj:IToolDebug) {
-            super();
-            this._obj = obj;
-            this._elem.classList.add('fa-wrench');
-        }
+    private _obj: IToolDebug;
+
+    constructor(obj: IToolDebug) {
+        super();
+        this._obj = obj;
+        this._elem.classList.add('fa-wrench');
+    }
 
-        protected action() {     
-            super.action(); 
-            if (this._on) {
-                // set icon activated
-                this._elem.classList.add('active');
-            }else {
-                // set icon deactivated
-                this._elem.classList.remove('active');
-            }
-            this._obj.debug(this._on);
+    protected action() {
+        super.action();
+        if (this._on) {
+            // set icon activated
+            this._elem.classList.add('active');
+        } else {
+            // set icon deactivated
+            this._elem.classList.remove('active');
         }
+        this._obj.debug(this._on);
     }
-}
+}

+ 23 - 23
inspector/src/treetools/Info.ts

@@ -1,29 +1,29 @@
-module INSPECTOR{
+import { AbstractTreeTool } from "./AbstractTreeTool";
+import { Tooltip } from "../gui/Tooltip";
 
-    /** Any object implementing this interface should 
-     * provide methods to retrieve its info
-     */
-    export interface IToolInfo {
-        getInfo  : () => string;
-    }
-    /**
-     * Checkbox to display/hide the primitive
-     */
-    export class Info extends AbstractTreeTool{
+/** Any object implementing this interface should 
+ * provide methods to retrieve its info
+ */
+export interface IToolInfo {
+    getInfo: () => string;
+}
+/**
+ * Checkbox to display/hide the primitive
+ */
+export class Info extends AbstractTreeTool {
 
-        private _obj: IToolInfo;
+    private _obj: IToolInfo;
 
-        constructor(obj:IToolInfo) {
-            super (); 
-            this._obj = obj;
-            this._elem.classList.add('fa-info-circle');
+    constructor(obj: IToolInfo) {
+        super();
+        this._obj = obj;
+        this._elem.classList.add('fa-info-circle');
 
-            new Tooltip(this._elem, this._obj.getInfo(), this._elem);
-        }
+        new Tooltip(this._elem, this._obj.getInfo(), this._elem);
+    }
 
-        // Nothing to do on click
-        protected action() {     
-            super.action();
-        }
+    // Nothing to do on click
+    protected action() {
+        super.action();
     }
-}
+}

+ 32 - 32
inspector/src/treetools/SoundInteractions.ts

@@ -1,40 +1,40 @@
-module INSPECTOR {
+import { AbstractTreeTool } from "./AbstractTreeTool";
 
-    export interface ISoundInteractions {
-        setPlaying: (callback: Function) => void;
-    }
 
-    /**
-     * 
-     */
-    export class SoundInteractions extends AbstractTreeTool {
-        private playSound: ISoundInteractions;
+export interface ISoundInteractions {
+    setPlaying: (callback: Function) => void;
+}
 
-        constructor(playSound: ISoundInteractions) {
-            super();
-            this.playSound = playSound;
-            this._elem.classList.add('fa-play');
-        }
+/**
+ * 
+ */
+export class SoundInteractions extends AbstractTreeTool {
+    private playSound: ISoundInteractions;
 
-        protected action() {
-            super.action();
-            this._playSound();
-        }
+    constructor(playSound: ISoundInteractions) {
+        super();
+        this.playSound = playSound;
+        this._elem.classList.add('fa-play');
+    }
 
-        private _playSound() {
+    protected action() {
+        super.action();
+        this._playSound();
+    }
+
+    private _playSound() {
 
-            if (this._elem.classList.contains('fa-play')) {
-                this._elem.classList.remove('fa-play');
-                this._elem.classList.add('fa-pause');
-            }
-            else {
-                this._elem.classList.remove('fa-pause');
-                this._elem.classList.add('fa-play');
-            }
-            this.playSound.setPlaying(() => {
-                this._elem.classList.remove('fa-pause');
-                this._elem.classList.add('fa-play');
-            });
+        if (this._elem.classList.contains('fa-play')) {
+            this._elem.classList.remove('fa-play');
+            this._elem.classList.add('fa-pause');
         }
+        else {
+            this._elem.classList.remove('fa-pause');
+            this._elem.classList.add('fa-play');
+        }
+        this.playSound.setPlaying(() => {
+            this._elem.classList.remove('fa-pause');
+            this._elem.classList.add('fa-play');
+        });
     }
-}
+}

+ 0 - 13
inspector/src/tsconfig.json

@@ -1,13 +0,0 @@
-{
-    "compilerOptions": {
-        "experimentalDecorators": true,
-        "module": "commonjs",
-        "target": "es5",
-        "noImplicitAny": true,
-        "noImplicitReturns": true,
-        "noImplicitThis": true,
-        "noUnusedLocals": true,
-        "strictNullChecks": true,
-        "lib": ["dom", "es2015.promise", "es5"]
-    }
-}

+ 34 - 0
inspector/tsconfig.json

@@ -0,0 +1,34 @@
+{
+    "compilerOptions": {
+        "experimentalDecorators": true,
+        "module": "commonjs",
+        "target": "es5",
+        "noImplicitAny": true,
+        "noImplicitReturns": true,
+        "noImplicitThis": true,
+        "noUnusedLocals": true,
+        "strictNullChecks": true,
+        "declaration": true,
+        "sourceMap": true,
+        "lib": [
+            "es5",
+            "dom",
+            "es2015.promise",
+            "es2015.collection",
+            "es2015.iterable"
+        ],
+        "skipDefaultLibCheck": true,
+        "skipLibCheck": true,
+        "baseUrl": "./src/",
+        "rootDir": "./src/",
+        "paths": {
+            "babylonjs": [
+                "../../dist/preview release/babylon.d.ts"
+            ],
+            "babylonjs-gui": [
+                "../../dist/preview release/gui/babylon.gui.module.d.ts"
+            ]
+        },
+        "outDir": "./build"
+    }
+}