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

First version of the inspector

Temechon пре 8 година
родитељ
комит
3cfeca2491
100 измењених фајлова са 74506 додато и 0 уклоњено
  1. 8 0
      inspector/.gitignore
  2. 151 0
      inspector/Gruntfile.js
  3. 48 0
      inspector/README.md
  4. 0 0
      inspector/dist/.baseDir.d.ts
  5. 2 0
      inspector/dist/.baseDir.js
  6. 44 0
      inspector/dist/inspector/Inspector.d.ts
  7. 159 0
      inspector/dist/inspector/Inspector.js
  8. 26 0
      inspector/dist/inspector/adapters/Adapter.d.ts
  9. 36 0
      inspector/dist/inspector/adapters/Adapter.js
  10. 18 0
      inspector/dist/inspector/adapters/Canvas2DAdapter.d.ts
  11. 72 0
      inspector/dist/inspector/adapters/Canvas2DAdapter.js
  12. 18 0
      inspector/dist/inspector/adapters/LightAdapter.d.ts
  13. 68 0
      inspector/dist/inspector/adapters/LightAdapter.js
  14. 17 0
      inspector/dist/inspector/adapters/MaterialAdapter.d.ts
  15. 57 0
      inspector/dist/inspector/adapters/MaterialAdapter.js
  16. 27 0
      inspector/dist/inspector/adapters/MeshAdapter.d.ts
  17. 120 0
      inspector/dist/inspector/adapters/MeshAdapter.js
  18. 31 0
      inspector/dist/inspector/details/DetailPanel.d.ts
  19. 149 0
      inspector/dist/inspector/details/DetailPanel.js
  20. 16 0
      inspector/dist/inspector/details/Property.d.ts
  21. 49 0
      inspector/dist/inspector/details/Property.js
  22. 99 0
      inspector/dist/inspector/details/PropertyLine.d.ts
  23. 327 0
      inspector/dist/inspector/details/PropertyLine.js
  24. 21 0
      inspector/dist/inspector/gui/BasicElement.d.ts
  25. 29 0
      inspector/dist/inspector/gui/BasicElement.js
  26. 10 0
      inspector/dist/inspector/gui/ColorElement.d.ts
  27. 43 0
      inspector/dist/inspector/gui/ColorElement.js
  28. 26 0
      inspector/dist/inspector/gui/CubeTextureElement.d.ts
  29. 110 0
      inspector/dist/inspector/gui/CubeTextureElement.js
  30. 12 0
      inspector/dist/inspector/gui/HDRCubeTextureElement.d.ts
  31. 39 0
      inspector/dist/inspector/gui/HDRCubeTextureElement.js
  32. 14 0
      inspector/dist/inspector/gui/SearchBar.d.ts
  33. 42 0
      inspector/dist/inspector/gui/SearchBar.js
  34. 12 0
      inspector/dist/inspector/gui/TextureElement.d.ts
  35. 40 0
      inspector/dist/inspector/gui/TextureElement.js
  36. 12 0
      inspector/dist/inspector/gui/Tooltip.d.ts
  37. 21 0
      inspector/dist/inspector/gui/Tooltip.js
  38. 27 0
      inspector/dist/inspector/helpers/Helpers.d.ts
  39. 102 0
      inspector/dist/inspector/helpers/Helpers.js
  40. 59 0
      inspector/dist/inspector/properties.d.ts
  41. 155 0
      inspector/dist/inspector/properties.js
  42. 20 0
      inspector/dist/inspector/scheduler/Scheduler.d.ts
  43. 44 0
      inspector/dist/inspector/scheduler/Scheduler.js
  44. 6 0
      inspector/dist/inspector/tabs/Canvas2DTab.d.ts
  45. 53 0
      inspector/dist/inspector/tabs/Canvas2DTab.js
  46. 6 0
      inspector/dist/inspector/tabs/LightTab.d.ts
  47. 28 0
      inspector/dist/inspector/tabs/LightTab.js
  48. 6 0
      inspector/dist/inspector/tabs/MaterialTab.d.ts
  49. 28 0
      inspector/dist/inspector/tabs/MaterialTab.js
  50. 6 0
      inspector/dist/inspector/tabs/MeshTab.d.ts
  51. 34 0
      inspector/dist/inspector/tabs/MeshTab.js
  52. 34 0
      inspector/dist/inspector/tabs/PropertyTab.d.ts
  53. 125 0
      inspector/dist/inspector/tabs/PropertyTab.js
  54. 21 0
      inspector/dist/inspector/tabs/SceneTab.d.ts
  55. 176 0
      inspector/dist/inspector/tabs/SceneTab.js
  56. 17 0
      inspector/dist/inspector/tabs/ShaderTab.d.ts
  57. 154 0
      inspector/dist/inspector/tabs/ShaderTab.js
  58. 25 0
      inspector/dist/inspector/tabs/Tab.d.ts
  59. 63 0
      inspector/dist/inspector/tabs/Tab.js
  60. 48 0
      inspector/dist/inspector/tabs/TabBar.d.ts
  61. 181 0
      inspector/dist/inspector/tabs/TabBar.js
  62. 17 0
      inspector/dist/inspector/tools/AbstractTool.d.ts
  63. 37 0
      inspector/dist/inspector/tools/AbstractTool.js
  64. 7 0
      inspector/dist/inspector/tools/PauseScheduleTool.d.ts
  65. 30 0
      inspector/dist/inspector/tools/PauseScheduleTool.js
  66. 13 0
      inspector/dist/inspector/tools/PickTool.d.ts
  67. 56 0
      inspector/dist/inspector/tools/PickTool.js
  68. 6 0
      inspector/dist/inspector/tools/PopupTool.d.ts
  69. 21 0
      inspector/dist/inspector/tools/PopupTool.js
  70. 6 0
      inspector/dist/inspector/tools/RefreshTool.d.ts
  71. 21 0
      inspector/dist/inspector/tools/RefreshTool.js
  72. 15 0
      inspector/dist/inspector/tools/Toolbar.d.ts
  73. 52 0
      inspector/dist/inspector/tools/Toolbar.js
  74. 44 0
      inspector/dist/inspector/tree/TreeItem.d.ts
  75. 168 0
      inspector/dist/inspector/tree/TreeItem.js
  76. 15 0
      inspector/dist/inspector/treetools/AbstractTreeTool.d.ts
  77. 32 0
      inspector/dist/inspector/treetools/AbstractTreeTool.js
  78. 18 0
      inspector/dist/inspector/treetools/BoundingBox.d.ts
  79. 41 0
      inspector/dist/inspector/treetools/BoundingBox.js
  80. 18 0
      inspector/dist/inspector/treetools/Checkbox.d.ts
  81. 45 0
      inspector/dist/inspector/treetools/Checkbox.js
  82. 13 0
      inspector/dist/inspector/treetools/DebugArea.d.ts
  83. 31 0
      inspector/dist/inspector/treetools/DebugArea.js
  84. 17 0
      inspector/dist/inspector/treetools/Info.d.ts
  85. 27 0
      inspector/dist/inspector/treetools/Info.js
  86. 15033 0
      inspector/dist/libs/babylon.canvas2d.max.js
  87. 54626 0
      inspector/dist/libs/babylon.max.js
  88. 1 0
      inspector/dist/libs/main.css
  89. 560 0
      inspector/dist/libs/split.js
  90. 12 0
      inspector/dist/test/Test.d.ts
  91. 133 0
      inspector/dist/test/Test.js
  92. BIN
      inspector/dist/test/assets/albedo.png
  93. BIN
      inspector/dist/test/assets/reflectivity.png
  94. BIN
      inspector/dist/test/assets/room.hdr
  95. BIN
      inspector/dist/test/assets/skybox/snow_nx.jpg
  96. BIN
      inspector/dist/test/assets/skybox/snow_ny.jpg
  97. BIN
      inspector/dist/test/assets/skybox/snow_nz.jpg
  98. BIN
      inspector/dist/test/assets/skybox/snow_px.jpg
  99. BIN
      inspector/dist/test/assets/skybox/snow_py.jpg
  100. 0 0
      inspector/dist/test/assets/skybox/snow_pz.jpg

+ 8 - 0
inspector/.gitignore

@@ -0,0 +1,8 @@
+.idea
+node_modules
+.tmp
+*.map
+.tscache
+.history
+.vscode
+yarn.lock

+ 151 - 0
inspector/Gruntfile.js

@@ -0,0 +1,151 @@
+module.exports = function (grunt) {
+    
+    // load all grunt tasks
+    require('jit-grunt')(grunt);    
+
+    grunt.initConfig({
+        
+        clean: {
+            init: ['dist/libs/inspector.js', 'dist/libs/main.css', 'dist/inspector.js', 'dist/inspector.d.ts'],
+            compilation: ['dist/inspector/', 'dist/libs/inspector.js', 'dist/libs/main.css']
+        },
+
+        // Compilation from TypeScript to ES5²
+        ts: {
+            inspector: {
+                src : ['ts/**/*.ts', 'ts/typings/**/*'],
+                outDir: "dist",
+                options:{
+                    module: 'amd',
+                    target: 'es5',
+                    declaration: true,
+                    sourceMap:true,
+                    removeComments:false
+                }
+            }
+        },
+        // Concat definition files 
+        concat: {
+            inspector: {
+                files: {
+                    'dist/inspector.d.ts': ['dist/inspector/**/*.d.ts']
+                },
+            },
+        },
+        // Watches content related changes
+        watch : {
+            inspector : {
+                files: ['ts/inspector/**/*.ts'],
+                tasks: ['ts']
+            },
+            test : {
+                files: ['ts/test/**/*.ts'],
+                tasks: ['ts']
+            },
+            sass : {
+                files: ['sass/**/*.scss'],
+                tasks: ['sass','postcss']
+            }
+        },
+        // Sass compilation. Produce an extended css file in css folder
+        sass : {
+            options: {
+                sourcemap:'none',
+                style: 'expanded'
+            },
+            dist : {
+                files: {
+                    'dist/libs/main.css': 'sass/main.scss'
+                }
+            }
+        },
+        // Auto prefixer css
+        postcss : {
+            dist: {
+                options: {
+                    processors: [
+                        require('autoprefixer')({browsers: 'last 2 versions'}),
+                        require('cssnano')()
+                    ]
+                },
+                src: 'dist/libs/main.css'
+            }
+        },
+        // Build dist version
+        uglify : {
+            dist: {
+                options: {
+                    compress:false,
+                    beautify: true
+                },
+                files: {
+                    'dist/libs/inspector.js': [
+                        'dist/inspector/gui/BasicElement.js',
+                        'dist/inspector/gui/CubeTextureElement.js',
+                        'dist/inspector/adapters/Adapter.js',
+                        'dist/inspector/tabs/Tab.js',
+                        'dist/inspector/tabs/PropertyTab.js',
+                        'dist/inspector/tools/AbstractTool.js',
+                        'dist/inspector/treeTools/AbstractTreeTool.js',
+                        'dist/inspector/**/*.js']
+                }
+            }
+        },
+        //Server creation
+        connect: {
+            server: {
+                options: {
+                    port: 3000,
+                    base: '.'
+                }
+            },
+            test: {
+                options: {
+                    port: 3000,
+                    base: '.',
+                    keepalive:true
+                }
+            }
+        },
+        // Open default browser
+        open: {
+            local: {
+                path: 'http://localhost:3000/dist/test'
+            }
+        },
+        webpack: {
+            inspector: require("./webpack.config.js")
+        }
+    }); 
+
+    grunt.registerTask('default', 'Compile and watch source files', [
+        'dev',
+        'connect:server',
+        'open',
+        'watch'
+    ]);
+
+    grunt.registerTask('dev', 'build dev version', [
+        'clean:init',
+        'ts',
+        'sass',
+        'postcss', 
+    ]);
+
+    grunt.registerTask('test', 'test dist version', [
+        'open',
+        'connect:test'
+    ]);
+
+    // Compilation and webpack
+    grunt.registerTask('dist', 'build dist version', [
+        'dev',
+        'uglify',
+        'concat',
+        'webpack',
+        'clean:compilation'
+    ]);
+
+};
+
+

+ 48 - 0
inspector/README.md

@@ -0,0 +1,48 @@
+# Babylon.js Inspector
+
+An extension to easily debug your Babylon.js application, made with HTML/CSS.
+This extension replaces the old limited debug layer.
+
+## Usage
+### Online method
+Call the method `show` of the scene debugLayer: 
+```
+scene.debugLayer.show();
+```
+This method will retrieve dynamically the library `inspector.js`, download it and add
+it to the html page.
+
+### Offline method
+If you don't have access to internet, the inspector should be imported manually in your HTML page :
+```
+<script src="inspector.js" />
+``` 
+Then, call the method `show` of the scene debugLayer: 
+```
+scene.debugLayer.show();
+```
+
+A right panel will be created containing the Babylon.js inspector.
+
+## Features
+
+### Tools
+![](../screens.jpg)
+Several tools are available (from left to right) : 
+* Refresh
+
+## Contribute
+
+```
+npm install
+grunt
+```
+
+## Create the lib from source
+
+```
+grunt dist
+```
+The library will be in the `dist` folder.
+
+

+ 0 - 0
inspector/dist/.baseDir.d.ts


+ 2 - 0
inspector/dist/.baseDir.js

@@ -0,0 +1,2 @@
+// Ignore this file. See https://github.com/grunt-ts/grunt-ts/issues/77 
+//# sourceMappingURL=.baseDir.js.map

+ 44 - 0
inspector/dist/inspector/Inspector.d.ts

@@ -0,0 +1,44 @@
+declare module INSPECTOR {
+    class Inspector {
+        private _c2diwrapper;
+        /** The panel displayed at the top of the inspector */
+        private _topPanel;
+        /** The div containing the content of the active tab */
+        private _tabPanel;
+        /** The panel containing the list if items */
+        /** The list if tree items displayed in the tree panel. */
+        private _items;
+        private _tabbar;
+        private _scene;
+        /** The HTML document relative to this inspector (the window or the popup depending on its mode) */
+        static DOCUMENT: HTMLDocument;
+        /** True if the inspector is built as a popup tab */
+        private _popupMode;
+        /** The original canvas size, before applying the inspector*/
+        private _canvasSize;
+        /** The inspector is created with the given engine.
+         * If a HTML parent is not given as a parameter, the inspector is created as a right panel on the main window.
+         * If a HTML parent is given, the inspector is created in this element, taking full size of its parent.
+         */
+        constructor(scene: BABYLON.Scene, parent?: HTMLElement);
+        /** Build the inspector panel in the given HTML element */
+        private _buildInspector(parent);
+        scene: BABYLON.Scene;
+        popupMode: boolean;
+        /**
+         * Filter the list of item present in the tree.
+         * All item returned should have the given filter contained in the item id.
+        */
+        filterItem(filter: string): void;
+        /** Display the mesh tab on the given object */
+        displayObjectDetails(mesh: BABYLON.AbstractMesh): void;
+        /** Clean the whole tree of item and rebuilds it */
+        refresh(): void;
+        /** Remove the inspector panel when it's built as a right panel:
+         * remove the right panel and remove the wrapper
+         */
+        private _disposeInspector();
+        /** Open the inspector in a new popup */
+        openPopup(): void;
+    }
+}

+ 159 - 0
inspector/dist/inspector/Inspector.js

@@ -0,0 +1,159 @@
+var INSPECTOR;
+(function (INSPECTOR) {
+    var Inspector = (function () {
+        /** The inspector is created with the given engine.
+         * If a HTML parent is not given as a parameter, the inspector is created as a right panel on the main window.
+         * If a HTML parent is given, the inspector is created in this element, taking full size of its parent.
+         */
+        function Inspector(scene, parent) {
+            var _this = this;
+            /** True if the inspector is built as a popup tab */
+            this._popupMode = false;
+            // get canvas parent only if needed.
+            this._scene = scene;
+            // Save HTML document
+            Inspector.DOCUMENT = window.document;
+            // POPUP MODE if parent is defined
+            if (parent) {
+                // Build the inspector in the given parent
+                this._buildInspector(parent);
+            }
+            else {
+                // Get canvas and its DOM parent
+                var canvas = this._scene.getEngine().getRenderingCanvas();
+                var canvasParent = canvas.parentElement;
+                // resize canvas
+                // canvas.style.width = 'calc(100% - 750px - 12px)';
+                // get canvas style                
+                var canvasStyle = window.getComputedStyle(canvas);
+                this._canvasSize = { width: canvasStyle.width, height: canvasStyle.height };
+                // Create c2di wrapper
+                this._c2diwrapper = INSPECTOR.Helpers.CreateDiv('insp-wrapper', canvasParent);
+                this._c2diwrapper.style.width = this._canvasSize.width;
+                this._c2diwrapper.style.height = this._canvasSize.height;
+                // Add canvas to the wrapper
+                this._c2diwrapper.appendChild(canvas);
+                // add inspector     
+                var inspector = INSPECTOR.Helpers.CreateDiv('insp-right-panel', this._c2diwrapper);
+                // Add split bar
+                Split([canvas, inspector], {
+                    direction: 'horizontal',
+                    onDrag: function () {
+                        INSPECTOR.Helpers.SEND_EVENT('resize');
+                        if (_this._tabbar) {
+                            _this._tabbar.updateWidth();
+                        }
+                    }
+                });
+                // Build the inspector
+                this._buildInspector(inspector);
+                // Send resize event to the window
+                INSPECTOR.Helpers.SEND_EVENT('resize');
+            }
+            // Refresh the inspector
+            this.refresh();
+        }
+        /** Build the inspector panel in the given HTML element */
+        Inspector.prototype._buildInspector = function (parent) {
+            // tabbar
+            this._tabbar = new INSPECTOR.TabBar(this);
+            // Top panel
+            this._topPanel = INSPECTOR.Helpers.CreateDiv('top-panel', parent);
+            // Add tabbar
+            this._topPanel.appendChild(this._tabbar.toHtml());
+            this._tabbar.updateWidth();
+            // Tab panel
+            this._tabPanel = INSPECTOR.Helpers.CreateDiv('tab-panel-content', this._topPanel);
+        };
+        Object.defineProperty(Inspector.prototype, "scene", {
+            get: function () {
+                return this._scene;
+            },
+            enumerable: true,
+            configurable: true
+        });
+        Object.defineProperty(Inspector.prototype, "popupMode", {
+            get: function () {
+                return this._popupMode;
+            },
+            enumerable: true,
+            configurable: true
+        });
+        /**
+         * Filter the list of item present in the tree.
+         * All item returned should have the given filter contained in the item id.
+        */
+        Inspector.prototype.filterItem = function (filter) {
+            this._tabbar.getActiveTab().filter(filter);
+        };
+        /** Display the mesh tab on the given object */
+        Inspector.prototype.displayObjectDetails = function (mesh) {
+            this._tabbar.switchMeshTab(mesh);
+        };
+        /** Clean the whole tree of item and rebuilds it */
+        Inspector.prototype.refresh = function () {
+            // Clean top panel
+            INSPECTOR.Helpers.CleanDiv(this._tabPanel);
+            // Get the active tab and its items
+            var activeTab = this._tabbar.getActiveTab();
+            activeTab.update();
+            this._tabPanel.appendChild(activeTab.getPanel());
+            INSPECTOR.Helpers.SEND_EVENT('resize');
+        };
+        /** Remove the inspector panel when it's built as a right panel:
+         * remove the right panel and remove the wrapper
+         */
+        Inspector.prototype._disposeInspector = function () {
+            if (!this._popupMode) {
+                // Get canvas
+                var canvas = this._scene.getEngine().getRenderingCanvas();
+                // restore canvas size
+                canvas.style.width = this._canvasSize.width;
+                canvas.style.height = this._canvasSize.height;
+                // Get parent of the wrapper           
+                var canvasParent = canvas.parentElement.parentElement;
+                canvasParent.appendChild(canvas);
+                // Remove wrapper
+                INSPECTOR.Helpers.CleanDiv(this._c2diwrapper);
+                this._c2diwrapper.remove();
+                // Send resize event to the window
+                INSPECTOR.Helpers.SEND_EVENT('resize');
+            }
+        };
+        /** Open the inspector in a new popup */
+        Inspector.prototype.openPopup = function () {
+            // Create popup
+            var popup = window.open('', 'Babylon.js INSPECTOR', 'toolbar=no,resizable=yes,menubar=no,width=750,height=1000');
+            popup.document.title = 'Babylon.js INSPECTOR';
+            // Get the inspector style      
+            var styles = Inspector.DOCUMENT.querySelectorAll('style');
+            for (var s = 0; s < styles.length; s++) {
+                popup.document.body.appendChild(styles[s].cloneNode(true));
+            }
+            var links = document.querySelectorAll('link');
+            for (var l = 0; l < links.length; l++) {
+                var link = popup.document.createElement("link");
+                link.rel = "stylesheet";
+                link.href = links[l].href;
+                popup.document.head.appendChild(link);
+            }
+            // Dispose the right panel
+            this._disposeInspector();
+            // set the mode as popup
+            this._popupMode = true;
+            // Save the HTML document
+            Inspector.DOCUMENT = popup.document;
+            // Build the inspector wrapper
+            this._c2diwrapper = INSPECTOR.Helpers.CreateDiv('insp-wrapper', popup.document.body);
+            // add inspector     
+            var inspector = INSPECTOR.Helpers.CreateDiv('insp-right-panel', this._c2diwrapper);
+            // and build it in the popup  
+            this._buildInspector(inspector);
+            // Rebuild it
+            this.refresh();
+        };
+        return Inspector;
+    }());
+    INSPECTOR.Inspector = Inspector;
+})(INSPECTOR || (INSPECTOR = {}));
+//# sourceMappingURL=Inspector.js.map

+ 26 - 0
inspector/dist/inspector/adapters/Adapter.d.ts

@@ -0,0 +1,26 @@
+declare module INSPECTOR {
+    interface IHighlight {
+        highlight: (b: boolean) => void;
+    }
+    abstract class Adapter implements IHighlight {
+        protected _obj: any;
+        private static _name;
+        constructor(obj: any);
+        /** Returns the name displayed in the tree */
+        abstract id(): string;
+        /** Returns the type of this object - displayed in the tree */
+        abstract type(): string;
+        /** Returns the list of properties to be displayed for this adapter */
+        abstract getProperties(): Array<PropertyLine>;
+        /** Returns the actual object behind this adapter */
+        actualObject: any;
+        /** Returns true if the given object correspond to this  */
+        correspondsTo(obj: any): boolean;
+        /** Returns the adapter unique name */
+        name: string;
+        /** Returns the list of tools available for this adapter */
+        abstract getTools(): Array<AbstractTreeTool>;
+        /** Should be overriden in subclasses */
+        highlight(b: boolean): void;
+    }
+}

+ 36 - 0
inspector/dist/inspector/adapters/Adapter.js

@@ -0,0 +1,36 @@
+var INSPECTOR;
+(function (INSPECTOR) {
+    var Adapter = (function () {
+        function Adapter(obj) {
+            this._obj = obj;
+        }
+        Object.defineProperty(Adapter.prototype, "actualObject", {
+            /** Returns the actual object behind this adapter */
+            get: function () {
+                return this._obj;
+            },
+            enumerable: true,
+            configurable: true
+        });
+        /** Returns true if the given object correspond to this  */
+        Adapter.prototype.correspondsTo = function (obj) {
+            return obj === this._obj;
+        };
+        Object.defineProperty(Adapter.prototype, "name", {
+            /** Returns the adapter unique name */
+            get: function () {
+                return Adapter._name;
+            },
+            enumerable: true,
+            configurable: true
+        });
+        /** Should be overriden in subclasses */
+        Adapter.prototype.highlight = function (b) { };
+        ;
+        // a unique name for this adapter, to retrieve its own key in the local storage
+        Adapter._name = BABYLON.Geometry.RandomId();
+        return Adapter;
+    }());
+    INSPECTOR.Adapter = Adapter;
+})(INSPECTOR || (INSPECTOR = {}));
+//# sourceMappingURL=Adapter.js.map

+ 18 - 0
inspector/dist/inspector/adapters/Canvas2DAdapter.d.ts

@@ -0,0 +1,18 @@
+declare module INSPECTOR {
+    class Canvas2DAdapter extends Adapter implements IToolVisible, IToolDebug {
+        constructor(obj: any);
+        /** Returns the name displayed in the tree */
+        id(): string;
+        /** Returns the type of this object - displayed in the tree */
+        type(): string;
+        /** Returns the list of properties to be displayed for this adapter */
+        getProperties(): Array<PropertyLine>;
+        getTools(): Array<AbstractTreeTool>;
+        setVisible(b: boolean): void;
+        isVisible(): boolean;
+        /** Overrides super */
+        debug(b: boolean): void;
+        /** Overrides super.highlight */
+        highlight(b: boolean): void;
+    }
+}

+ 72 - 0
inspector/dist/inspector/adapters/Canvas2DAdapter.js

@@ -0,0 +1,72 @@
+var __extends = (this && this.__extends) || function (d, b) {
+    for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
+    function __() { this.constructor = d; }
+    d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
+};
+var INSPECTOR;
+(function (INSPECTOR) {
+    var Canvas2DAdapter = (function (_super) {
+        __extends(Canvas2DAdapter, _super);
+        function Canvas2DAdapter(obj) {
+            _super.call(this, obj);
+        }
+        /** Returns the name displayed in the tree */
+        Canvas2DAdapter.prototype.id = function () {
+            var str = '';
+            if (this._obj.id) {
+                str = this._obj.id;
+            } // otherwise nothing displayed        
+            return str;
+        };
+        /** Returns the type of this object - displayed in the tree */
+        Canvas2DAdapter.prototype.type = function () {
+            return INSPECTOR.Helpers.GET_TYPE(this._obj);
+        };
+        /** Returns the list of properties to be displayed for this adapter */
+        Canvas2DAdapter.prototype.getProperties = function () {
+            var _this = this;
+            var propertiesLines = [];
+            if (this._obj.propDic) {
+                var dico = this._obj.propDic;
+                dico.forEach(function (name, propInfo) {
+                    var property = new INSPECTOR.Property(name, _this.actualObject);
+                    propertiesLines.push(new INSPECTOR.PropertyLine(property));
+                });
+            }
+            // TODO REMOVE THIS WHEN PROPERTIES WILL BE DECORATED
+            var toAddDirty = [
+                'actualZOffset', 'isSizeAuto', 'layoutArea', 'layoutAreaPos', 'contentArea',
+                'marginOffset', 'paddingOffset', 'isPickable', 'isContainer', 'boundingInfo',
+                'levelBoundingInfo', 'isSizedByContent', 'isPositionAuto', 'actualScale', 'layoutBoundingInfo'];
+            for (var _i = 0, toAddDirty_1 = toAddDirty; _i < toAddDirty_1.length; _i++) {
+                var dirty = toAddDirty_1[_i];
+                var infos = new INSPECTOR.Property(dirty, this.actualObject);
+                propertiesLines.push(new INSPECTOR.PropertyLine(infos));
+            }
+            return propertiesLines;
+        };
+        Canvas2DAdapter.prototype.getTools = function () {
+            var tools = [];
+            tools.push(new INSPECTOR.Checkbox(this));
+            tools.push(new INSPECTOR.DebugArea(this));
+            return tools;
+        };
+        /// TOOLS ///
+        Canvas2DAdapter.prototype.setVisible = function (b) {
+            this._obj.levelVisible = b;
+        };
+        Canvas2DAdapter.prototype.isVisible = function () {
+            return this._obj.levelVisible;
+        };
+        /** Overrides super */
+        Canvas2DAdapter.prototype.debug = function (b) {
+            this._obj["displayDebugAreas"] = b;
+        };
+        /** Overrides super.highlight */
+        Canvas2DAdapter.prototype.highlight = function (b) {
+        };
+        return Canvas2DAdapter;
+    }(INSPECTOR.Adapter));
+    INSPECTOR.Canvas2DAdapter = Canvas2DAdapter;
+})(INSPECTOR || (INSPECTOR = {}));
+//# sourceMappingURL=Canvas2DAdapter.js.map

+ 18 - 0
inspector/dist/inspector/adapters/LightAdapter.d.ts

@@ -0,0 +1,18 @@
+declare module INSPECTOR {
+    class LightAdapter extends Adapter implements IToolVisible {
+        private static _PROPERTIES;
+        constructor(obj: BABYLON.Light);
+        /** Returns the name displayed in the tree */
+        id(): string;
+        /** Returns the type of this object - displayed in the tree */
+        type(): string;
+        /** Returns the list of properties to be displayed for this adapter */
+        getProperties(): Array<PropertyLine>;
+        getTools(): Array<AbstractTreeTool>;
+        setVisible(b: boolean): void;
+        isVisible(): boolean;
+        /** Returns some information about this mesh */
+        /** Overrides super.highlight */
+        highlight(b: boolean): void;
+    }
+}

+ 68 - 0
inspector/dist/inspector/adapters/LightAdapter.js

@@ -0,0 +1,68 @@
+var __extends = (this && this.__extends) || function (d, b) {
+    for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
+    function __() { this.constructor = d; }
+    d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
+};
+var INSPECTOR;
+(function (INSPECTOR) {
+    var LightAdapter = (function (_super) {
+        __extends(LightAdapter, _super);
+        function LightAdapter(obj) {
+            _super.call(this, obj);
+        }
+        /** Returns the name displayed in the tree */
+        LightAdapter.prototype.id = function () {
+            var str = '';
+            if (this._obj.name) {
+                str = this._obj.name;
+            } // otherwise nothing displayed        
+            return str;
+        };
+        /** Returns the type of this object - displayed in the tree */
+        LightAdapter.prototype.type = function () {
+            return INSPECTOR.Helpers.GET_TYPE(this._obj);
+        };
+        /** Returns the list of properties to be displayed for this adapter */
+        LightAdapter.prototype.getProperties = function () {
+            var propertiesLines = [];
+            for (var _i = 0, _a = LightAdapter._PROPERTIES; _i < _a.length; _i++) {
+                var dirty = _a[_i];
+                var infos = new INSPECTOR.Property(dirty, this._obj);
+                propertiesLines.push(new INSPECTOR.PropertyLine(infos));
+            }
+            return propertiesLines;
+        };
+        LightAdapter.prototype.getTools = function () {
+            var tools = [];
+            tools.push(new INSPECTOR.Checkbox(this));
+            return tools;
+        };
+        LightAdapter.prototype.setVisible = function (b) {
+            this._obj.setEnabled(b);
+        };
+        LightAdapter.prototype.isVisible = function () {
+            return this._obj.isEnabled();
+        };
+        /** Returns some information about this mesh */
+        // public getInfo() : string {
+        //     return `${(this._obj as BABYLON.AbstractMesh).getTotalVertices()} vertices`;
+        // }
+        /** Overrides super.highlight */
+        LightAdapter.prototype.highlight = function (b) {
+            this.actualObject.renderOutline = b;
+            this.actualObject.outlineWidth = 0.25;
+            this.actualObject.outlineColor = BABYLON.Color3.Yellow();
+        };
+        LightAdapter._PROPERTIES = [
+            'position',
+            'diffuse',
+            'intensity',
+            'radius',
+            'range',
+            'specular'
+        ];
+        return LightAdapter;
+    }(INSPECTOR.Adapter));
+    INSPECTOR.LightAdapter = LightAdapter;
+})(INSPECTOR || (INSPECTOR = {}));
+//# sourceMappingURL=LightAdapter.js.map

+ 17 - 0
inspector/dist/inspector/adapters/MaterialAdapter.d.ts

@@ -0,0 +1,17 @@
+declare module INSPECTOR {
+    class MaterialAdapter extends Adapter {
+        constructor(obj: BABYLON.Material);
+        /** Returns the name displayed in the tree */
+        id(): string;
+        /** Returns the type of this object - displayed in the tree */
+        type(): string;
+        /** Returns the list of properties to be displayed for this adapter */
+        getProperties(): Array<PropertyLine>;
+        /** No tools for a material adapter */
+        getTools(): Array<AbstractTreeTool>;
+        /** Overrides super.highlight.
+         * Highlighting a material outlines all meshes linked to this material
+         */
+        highlight(b: boolean): void;
+    }
+}

+ 57 - 0
inspector/dist/inspector/adapters/MaterialAdapter.js

@@ -0,0 +1,57 @@
+var __extends = (this && this.__extends) || function (d, b) {
+    for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
+    function __() { this.constructor = d; }
+    d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
+};
+var INSPECTOR;
+(function (INSPECTOR) {
+    var MaterialAdapter = (function (_super) {
+        __extends(MaterialAdapter, _super);
+        function MaterialAdapter(obj) {
+            _super.call(this, obj);
+        }
+        /** Returns the name displayed in the tree */
+        MaterialAdapter.prototype.id = function () {
+            var str = '';
+            if (this._obj.name) {
+                str = this._obj.name;
+            } // otherwise nothing displayed        
+            return str;
+        };
+        /** Returns the type of this object - displayed in the tree */
+        MaterialAdapter.prototype.type = function () {
+            return INSPECTOR.Helpers.GET_TYPE(this._obj);
+        };
+        /** Returns the list of properties to be displayed for this adapter */
+        MaterialAdapter.prototype.getProperties = function () {
+            var propertiesLines = [];
+            var propToDisplay = INSPECTOR.PROPERTIES[this.type()].properties;
+            for (var _i = 0, propToDisplay_1 = propToDisplay; _i < propToDisplay_1.length; _i++) {
+                var dirty = propToDisplay_1[_i];
+                var infos = new INSPECTOR.Property(dirty, this._obj);
+                propertiesLines.push(new INSPECTOR.PropertyLine(infos));
+            }
+            return propertiesLines;
+        };
+        /** No tools for a material adapter */
+        MaterialAdapter.prototype.getTools = function () {
+            return [];
+        };
+        /** Overrides super.highlight.
+         * Highlighting a material outlines all meshes linked to this material
+         */
+        MaterialAdapter.prototype.highlight = function (b) {
+            var material = this.actualObject;
+            var meshes = material.getBindedMeshes();
+            for (var _i = 0, meshes_1 = meshes; _i < meshes_1.length; _i++) {
+                var mesh = meshes_1[_i];
+                mesh.renderOutline = b;
+                mesh.outlineWidth = 0.25;
+                mesh.outlineColor = BABYLON.Color3.Yellow();
+            }
+        };
+        return MaterialAdapter;
+    }(INSPECTOR.Adapter));
+    INSPECTOR.MaterialAdapter = MaterialAdapter;
+})(INSPECTOR || (INSPECTOR = {}));
+//# sourceMappingURL=MaterialAdapter.js.map

+ 27 - 0
inspector/dist/inspector/adapters/MeshAdapter.d.ts

@@ -0,0 +1,27 @@
+declare module INSPECTOR {
+    class MeshAdapter extends Adapter implements IToolVisible, IToolDebug, IToolBoundingBox, IToolInfo {
+        /** Keep track of the axis of the actual object */
+        private _axis;
+        constructor(obj: BABYLON.AbstractMesh);
+        /** Returns the name displayed in the tree */
+        id(): string;
+        /** Returns the type of this object - displayed in the tree */
+        type(): string;
+        /** Returns the list of properties to be displayed for this adapter */
+        getProperties(): Array<PropertyLine>;
+        getTools(): Array<AbstractTreeTool>;
+        setVisible(b: boolean): void;
+        isVisible(): boolean;
+        isBoxVisible(): boolean;
+        setBoxVisible(b: boolean): boolean;
+        debug(b: boolean): void;
+        /** Returns some information about this mesh */
+        getInfo(): string;
+        /** Overrides super.highlight */
+        highlight(b: boolean): void;
+        /** 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();
+    }
+}

+ 120 - 0
inspector/dist/inspector/adapters/MeshAdapter.js

@@ -0,0 +1,120 @@
+var __extends = (this && this.__extends) || function (d, b) {
+    for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
+    function __() { this.constructor = d; }
+    d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
+};
+var INSPECTOR;
+(function (INSPECTOR) {
+    var MeshAdapter = (function (_super) {
+        __extends(MeshAdapter, _super);
+        function MeshAdapter(obj) {
+            _super.call(this, obj);
+            /** Keep track of the axis of the actual object */
+            this._axis = [];
+        }
+        /** Returns the name displayed in the tree */
+        MeshAdapter.prototype.id = function () {
+            var str = '';
+            if (this._obj.name) {
+                str = this._obj.name;
+            } // otherwise nothing displayed        
+            return str;
+        };
+        /** Returns the type of this object - displayed in the tree */
+        MeshAdapter.prototype.type = function () {
+            return INSPECTOR.Helpers.GET_TYPE(this._obj);
+        };
+        /** Returns the list of properties to be displayed for this adapter */
+        MeshAdapter.prototype.getProperties = function () {
+            var propertiesLines = [];
+            for (var _i = 0, _a = INSPECTOR.PROPERTIES['Mesh'].properties; _i < _a.length; _i++) {
+                var dirty = _a[_i];
+                var infos = new INSPECTOR.Property(dirty, this._obj);
+                propertiesLines.push(new INSPECTOR.PropertyLine(infos));
+            }
+            return propertiesLines;
+        };
+        MeshAdapter.prototype.getTools = function () {
+            var tools = [];
+            tools.push(new INSPECTOR.Checkbox(this));
+            tools.push(new INSPECTOR.DebugArea(this));
+            tools.push(new INSPECTOR.BoundingBox(this));
+            tools.push(new INSPECTOR.Info(this));
+            return tools;
+        };
+        MeshAdapter.prototype.setVisible = function (b) {
+            this._obj.setEnabled(b);
+            this._obj.isVisible = b;
+        };
+        MeshAdapter.prototype.isVisible = function () {
+            return this._obj.isEnabled() && this._obj.isVisible;
+        };
+        MeshAdapter.prototype.isBoxVisible = function () {
+            return this._obj.showBoundingBox;
+        };
+        MeshAdapter.prototype.setBoxVisible = function (b) {
+            return this._obj.showBoundingBox = b;
+        };
+        MeshAdapter.prototype.debug = function (b) {
+            // Draw axis the first time
+            if (this._axis.length == 0) {
+                this._drawAxis();
+            }
+            // Display or hide axis
+            for (var _i = 0, _a = this._axis; _i < _a.length; _i++) {
+                var ax = _a[_i];
+                ax.setEnabled(b);
+            }
+        };
+        /** Returns some information about this mesh */
+        MeshAdapter.prototype.getInfo = function () {
+            return this._obj.getTotalVertices() + " vertices";
+        };
+        /** Overrides super.highlight */
+        MeshAdapter.prototype.highlight = function (b) {
+            this.actualObject.renderOutline = b;
+            this.actualObject.outlineWidth = 0.25;
+            this.actualObject.outlineColor = BABYLON.Color3.Yellow();
+        };
+        /** 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
+         */
+        MeshAdapter.prototype._drawAxis = function () {
+            var _this = this;
+            this._obj.computeWorldMatrix();
+            var m = this._obj.getWorldMatrix();
+            // Axis
+            var x = new BABYLON.Vector3(8, 0, 0);
+            var y = new BABYLON.Vector3(0, 8, 0);
+            var z = new BABYLON.Vector3(0, 0, 8);
+            // Draw an axis of the given color
+            var _drawAxis = function (color, start, end) {
+                var axis = BABYLON.Mesh.CreateLines("###axis###", [
+                    start,
+                    end
+                ], _this._obj.getScene());
+                axis.color = color;
+                axis.renderingGroupId = 1;
+                return axis;
+            };
+            // X axis
+            var xAxis = _drawAxis(BABYLON.Color3.Red(), this._obj.getAbsolutePosition(), BABYLON.Vector3.TransformCoordinates(x, m));
+            xAxis.position.subtractInPlace(this._obj.position);
+            xAxis.parent = this._obj;
+            this._axis.push(xAxis);
+            // Y axis        
+            var yAxis = _drawAxis(BABYLON.Color3.Green(), this._obj.getAbsolutePosition(), BABYLON.Vector3.TransformCoordinates(y, m));
+            yAxis.parent = this._obj;
+            yAxis.position.subtractInPlace(this._obj.position);
+            this._axis.push(yAxis);
+            // Z axis
+            var zAxis = _drawAxis(BABYLON.Color3.Blue(), this._obj.getAbsolutePosition(), BABYLON.Vector3.TransformCoordinates(z, m));
+            zAxis.parent = this._obj;
+            zAxis.position.subtractInPlace(this._obj.position);
+            this._axis.push(zAxis);
+        };
+        return MeshAdapter;
+    }(INSPECTOR.Adapter));
+    INSPECTOR.MeshAdapter = MeshAdapter;
+})(INSPECTOR || (INSPECTOR = {}));
+//# sourceMappingURL=MeshAdapter.js.map

+ 31 - 0
inspector/dist/inspector/details/DetailPanel.d.ts

@@ -0,0 +1,31 @@
+declare module INSPECTOR {
+    interface SortDirection {
+        [property: string]: number;
+    }
+    class DetailPanel extends BasicElement {
+        private _headerRow;
+        private _detailRows;
+        private _sortDirection;
+        constructor(dr?: Array<PropertyLine>);
+        details: Array<PropertyLine>;
+        protected _build(): void;
+        /** Updates the HTML of the detail panel */
+        update(): void;
+        /** Add all lines in the html div. Does not sort them! */
+        private _addDetails();
+        /**
+         * Sort the details row by comparing the given property of each row
+         */
+        private _sortDetails(property, _direction?);
+        /**
+         * Removes all data in the detail panel but keep the header row
+         */
+        clean(): void;
+        /** Overrides basicelement.dispose */
+        dispose(): void;
+        /**
+         * Creates the header row : name, value, id
+         */
+        private _createHeaderRow();
+    }
+}

+ 149 - 0
inspector/dist/inspector/details/DetailPanel.js

@@ -0,0 +1,149 @@
+var __extends = (this && this.__extends) || function (d, b) {
+    for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
+    function __() { this.constructor = d; }
+    d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
+};
+var INSPECTOR;
+(function (INSPECTOR) {
+    var DetailPanel = (function (_super) {
+        __extends(DetailPanel, _super);
+        function DetailPanel(dr) {
+            _super.call(this);
+            // Contains all details rows that belongs to the item above
+            this._detailRows = [];
+            // Store the sort direction of each header column
+            this._sortDirection = {};
+            this._build();
+            if (dr) {
+                this._detailRows = dr;
+                this.update();
+            }
+        }
+        Object.defineProperty(DetailPanel.prototype, "details", {
+            set: function (detailsRow) {
+                this.clean();
+                this._detailRows = detailsRow;
+                // Refresh HTML
+                this.update();
+            },
+            enumerable: true,
+            configurable: true
+        });
+        DetailPanel.prototype._build = function () {
+            var _this = this;
+            this._div.className = 'insp-details';
+            this._div.id = 'insp-details';
+            // Create header row
+            this._createHeaderRow();
+            this._div.appendChild(this._headerRow);
+            window.addEventListener('resize', function (e) {
+                // adapt the header row max width according to its parent size;
+                _this._headerRow.style.maxWidth = _this._headerRow.parentElement.clientWidth + 'px';
+            });
+        };
+        /** Updates the HTML of the detail panel */
+        DetailPanel.prototype.update = function () {
+            this._sortDetails('name', 1);
+            this._addDetails();
+        };
+        /** Add all lines in the html div. Does not sort them! */
+        DetailPanel.prototype._addDetails = function () {
+            var details = INSPECTOR.Helpers.CreateDiv('details', this._div);
+            for (var _i = 0, _a = this._detailRows; _i < _a.length; _i++) {
+                var row = _a[_i];
+                details.appendChild(row.toHtml());
+            }
+        };
+        /**
+         * Sort the details row by comparing the given property of each row
+         */
+        DetailPanel.prototype._sortDetails = function (property, _direction) {
+            // Clean header
+            var elems = INSPECTOR.Inspector.DOCUMENT.querySelectorAll('.sort-direction');
+            for (var 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;
+            }
+            var direction = this._sortDirection[property];
+            if (direction == 1) {
+                this._headerRow.querySelector("#sort-direction-" + property).classList.remove('fa-chevron-down');
+                this._headerRow.querySelector("#sort-direction-" + property).classList.add('fa-chevron-up');
+            }
+            else {
+                this._headerRow.querySelector("#sort-direction-" + property).classList.remove('fa-chevron-up');
+                this._headerRow.querySelector("#sort-direction-" + property).classList.add('fa-chevron-down');
+            }
+            var isString = function (s) {
+                return typeof (s) === 'string' || s instanceof String;
+            };
+            this._detailRows.sort(function (detail1, detail2) {
+                var str1 = String(detail1[property]);
+                var 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;
+            });
+        };
+        /**
+         * Removes all data in the detail panel but keep the header row
+         */
+        DetailPanel.prototype.clean = function () {
+            // Delete all details row
+            for (var _i = 0, _a = this._detailRows; _i < _a.length; _i++) {
+                var pline = _a[_i];
+                pline.dispose();
+            }
+            INSPECTOR.Helpers.CleanDiv(this._div);
+            // Header row
+            this._div.appendChild(this._headerRow);
+        };
+        /** Overrides basicelement.dispose */
+        DetailPanel.prototype.dispose = function () {
+            // Delete all details row
+            for (var _i = 0, _a = this._detailRows; _i < _a.length; _i++) {
+                var pline = _a[_i];
+                pline.dispose();
+            }
+        };
+        /**
+         * Creates the header row : name, value, id
+         */
+        DetailPanel.prototype._createHeaderRow = function () {
+            var _this = this;
+            this._headerRow = INSPECTOR.Helpers.CreateDiv('header-row');
+            var createDiv = function (name, cssClass) {
+                var div = INSPECTOR.Helpers.CreateDiv(cssClass + ' header-col');
+                // Column title - first letter in uppercase
+                var spanName = INSPECTOR.Inspector.DOCUMENT.createElement('span');
+                spanName.textContent = name.charAt(0).toUpperCase() + name.slice(1);
+                // sort direction
+                var spanDirection = INSPECTOR.Inspector.DOCUMENT.createElement('i');
+                spanDirection.className = 'sort-direction fa';
+                spanDirection.id = 'sort-direction-' + name;
+                div.appendChild(spanName);
+                div.appendChild(spanDirection);
+                div.addEventListener('click', function (e) {
+                    _this._sortDetails(name);
+                    _this._addDetails();
+                });
+                return div;
+            };
+            this._headerRow.appendChild(createDiv('name', 'prop-name'));
+            this._headerRow.appendChild(createDiv('value', 'prop-value'));
+        };
+        return DetailPanel;
+    }(INSPECTOR.BasicElement));
+    INSPECTOR.DetailPanel = DetailPanel;
+})(INSPECTOR || (INSPECTOR = {}));
+//# sourceMappingURL=DetailPanel.js.map

+ 16 - 0
inspector/dist/inspector/details/Property.d.ts

@@ -0,0 +1,16 @@
+declare module INSPECTOR {
+    /**
+     * A property is a link between a data (string) and an object.
+     */
+    class Property {
+        /** The property name */
+        private _property;
+        /** The obj this property refers to */
+        private _obj;
+        constructor(prop: string, obj: any);
+        name: string;
+        value: any;
+        type: string;
+        obj: any;
+    }
+}

+ 49 - 0
inspector/dist/inspector/details/Property.js

@@ -0,0 +1,49 @@
+var INSPECTOR;
+(function (INSPECTOR) {
+    /**
+     * A property is a link between a data (string) and an object.
+     */
+    var Property = (function () {
+        function Property(prop, obj) {
+            this._property = prop;
+            this._obj = obj;
+        }
+        Object.defineProperty(Property.prototype, "name", {
+            get: function () {
+                return this._property;
+            },
+            enumerable: true,
+            configurable: true
+        });
+        Object.defineProperty(Property.prototype, "value", {
+            get: function () {
+                return this._obj[this._property];
+            },
+            set: function (newValue) {
+                this._obj[this._property] = newValue;
+            },
+            enumerable: true,
+            configurable: true
+        });
+        Object.defineProperty(Property.prototype, "type", {
+            get: function () {
+                return INSPECTOR.Helpers.GET_TYPE(this.value);
+            },
+            enumerable: true,
+            configurable: true
+        });
+        Object.defineProperty(Property.prototype, "obj", {
+            get: function () {
+                return this._obj;
+            },
+            set: function (newObj) {
+                this._obj = newObj;
+            },
+            enumerable: true,
+            configurable: true
+        });
+        return Property;
+    }());
+    INSPECTOR.Property = Property;
+})(INSPECTOR || (INSPECTOR = {}));
+//# sourceMappingURL=Property.js.map

+ 99 - 0
inspector/dist/inspector/details/PropertyLine.d.ts

@@ -0,0 +1,99 @@
+declare module INSPECTOR {
+    class PropertyFormatter {
+        /**
+         * Format the value of the given property of the given object.
+         */
+        static format(obj: any, prop: string): string;
+    }
+    /**
+     * A property line represents a line in the detail panel. This line is composed of :
+     * - a name (the property name)
+     * - a value if this property is of a type 'simple' : string, number, boolean, color, texture
+     * - the type of the value if this property is of a complex type (Vector2, Size, ...)
+     * - a ID if defined (otherwise an empty string is displayed)
+     * The original object is sent to the value object who will update it at will.
+     *
+     * A property line can contain OTHER property line objects in the case of a complex type.
+     * If this instance has no link to other instances, its type is ALWAYS a simple one (see above).
+     *
+     */
+    class PropertyLine {
+        private _property;
+        private _div;
+        private _valueDiv;
+        private _children;
+        private static _SIMPLE_TYPE;
+        private static _MARGIN_LEFT;
+        private _level;
+        /** The list of viewer element displayed at the end of the line (color, texture...) */
+        private _elements;
+        /** The property parent of this one. Used to update the value of this property and to retrieve the correct object */
+        private _parent;
+        /** The input element to display if this property is 'simple' in order to update it */
+        private _input;
+        /** Display input handler (stored to be removed afterwards) */
+        private _displayInputHandler;
+        /** Handler used to validate the input by pressing 'enter' */
+        private _validateInputHandler;
+        constructor(prop: Property, parent?: PropertyLine, level?: number);
+        /**
+         * Init the input element and al its handler :
+         * - a click in the window remove the input and restore the old property value
+         * - enters updates the property
+         */
+        private _initInput();
+        /**
+         * On enter : validates the new value and removes the input
+         * On escape : removes the input
+         */
+        private _validateInput(e);
+        /** Removes the input without validating the new value */
+        private _removeInputWithoutValidating();
+        /** Replaces the default display with an input */
+        private _displayInput(e);
+        /** Retrieve the correct object from its parent.
+         * If no parent exists, returns the property value.
+         * This method is used at each update in case the property object is removed from the original object
+         * (example : mesh.position = new BABYLON.Vector3 ; the original vector3 object is deleted from the mesh).
+        */
+        updateObject(): any;
+        name: string;
+        value: any;
+        type: string;
+        /**
+         * Creates elements that wil be displayed on a property line, depending on the
+         * type of the property.
+         */
+        private _createElements();
+        private _displayValueContent();
+        /** Delete properly this property line.
+         * Removes itself from the scheduler.
+         * Dispose all viewer element (color, texture...)
+         */
+        dispose(): void;
+        /** Updates the content of _valueDiv with the value of the property,
+         * and all HTML element correpsonding to this type.
+         * Elements are updated as well
+         */
+        private _updateValue();
+        /**
+         * Update the property division with the new property value.
+         * If this property is complex, update its child, otherwise update its text content
+         */
+        update(): void;
+        /**
+         * Returns true if the given instance is a simple type
+         */
+        private static _IS_TYPE_SIMPLE(inst);
+        /**
+         * Returns true if the type of this property is simple, false otherwise.
+         * Returns true if the value is null
+         */
+        private _isSimple();
+        toHtml(): HTMLElement;
+        /**
+         * Add sub properties in case of a complex type
+         */
+        private _addDetails();
+    }
+}

+ 327 - 0
inspector/dist/inspector/details/PropertyLine.js

@@ -0,0 +1,327 @@
+var INSPECTOR;
+(function (INSPECTOR) {
+    var PropertyFormatter = (function () {
+        function PropertyFormatter() {
+        }
+        /**
+         * Format the value of the given property of the given object.
+         */
+        PropertyFormatter.format = function (obj, prop) {
+            // Get original value;
+            var value = obj[prop];
+            // PrimitiveAlignment
+            if (obj instanceof BABYLON.PrimitiveAlignment) {
+                if (prop === 'horizontal') {
+                    switch (value) {
+                        case BABYLON.PrimitiveAlignment.AlignLeft:
+                            return 'left';
+                        case BABYLON.PrimitiveAlignment.AlignRight:
+                            return 'right';
+                        case BABYLON.PrimitiveAlignment.AlignCenter:
+                            return 'center';
+                        case BABYLON.PrimitiveAlignment.AlignStretch:
+                            return 'stretch';
+                    }
+                }
+                else if (prop === 'vertical') {
+                    switch (value) {
+                        case BABYLON.PrimitiveAlignment.AlignTop:
+                            return 'top';
+                        case BABYLON.PrimitiveAlignment.AlignBottom:
+                            return 'bottom';
+                        case BABYLON.PrimitiveAlignment.AlignCenter:
+                            return 'center';
+                        case BABYLON.PrimitiveAlignment.AlignStretch:
+                            return 'stretch';
+                    }
+                }
+            }
+            return value;
+        };
+        return PropertyFormatter;
+    }());
+    INSPECTOR.PropertyFormatter = PropertyFormatter;
+    /**
+     * A property line represents a line in the detail panel. This line is composed of :
+     * - a name (the property name)
+     * - a value if this property is of a type 'simple' : string, number, boolean, color, texture
+     * - the type of the value if this property is of a complex type (Vector2, Size, ...)
+     * - a ID if defined (otherwise an empty string is displayed)
+     * The original object is sent to the value object who will update it at will.
+     *
+     * A property line can contain OTHER property line objects in the case of a complex type.
+     * If this instance has no link to other instances, its type is ALWAYS a simple one (see above).
+     *
+     */
+    var PropertyLine = (function () {
+        function PropertyLine(prop, parent, level) {
+            if (level === void 0) { level = 0; }
+            // If the type is complex, this property will have child to update
+            this._children = [];
+            /** The list of viewer element displayed at the end of the line (color, texture...) */
+            this._elements = [];
+            this._property = prop;
+            this._level = level;
+            this._parent = parent;
+            this._div = INSPECTOR.Helpers.CreateDiv('row');
+            this._div.style.marginLeft = this._level + "px";
+            // Property name
+            var propName = INSPECTOR.Helpers.CreateDiv('prop-name', this._div);
+            propName.textContent = "" + this.name;
+            // Value
+            this._valueDiv = INSPECTOR.Helpers.CreateDiv('prop-value', this._div);
+            this._valueDiv.textContent = this._displayValueContent() || '-'; // Init value text node
+            this._createElements();
+            for (var _i = 0, _a = this._elements; _i < _a.length; _i++) {
+                var elem = _a[_i];
+                this._valueDiv.appendChild(elem.toHtml());
+            }
+            this._updateValue();
+            // If the property type is not simple, add click event to unfold its children
+            if (!this._isSimple()) {
+                this._valueDiv.classList.add('clickable');
+                this._valueDiv.addEventListener('click', this._addDetails.bind(this));
+            }
+            else {
+                this._initInput();
+                this._valueDiv.addEventListener('click', this._displayInputHandler);
+                this._input.addEventListener('keypress', this._validateInputHandler);
+            }
+            // Add this property to the scheduler
+            INSPECTOR.Scheduler.getInstance().add(this);
+        }
+        /**
+         * Init the input element and al its handler :
+         * - a click in the window remove the input and restore the old property value
+         * - enters updates the property
+         */
+        PropertyLine.prototype._initInput = function () {
+            // Create the input element
+            this._input = document.createElement('input');
+            this._input.setAttribute('type', 'text');
+            // if the property is 'simple', add an event listener to create an input
+            this._displayInputHandler = this._displayInput.bind(this);
+            this._validateInputHandler = this._validateInput.bind(this);
+        };
+        /**
+         * On enter : validates the new value and removes the input
+         * On escape : removes the input
+         */
+        PropertyLine.prototype._validateInput = function (e) {
+            if (e.keyCode == 13) {
+                // Enter : validate the new value
+                var newValue = this._input.value;
+                this.updateObject();
+                this._property.value = newValue;
+                // Remove input
+                this.update();
+            }
+            else if (e.keyCode == 27) {
+                // Esc : remove input
+                this.update();
+            }
+        };
+        /** Removes the input without validating the new value */
+        PropertyLine.prototype._removeInputWithoutValidating = function () {
+            INSPECTOR.Helpers.CleanDiv(this._valueDiv);
+            this._valueDiv.addEventListener('click', this._displayInputHandler);
+        };
+        /** Replaces the default display with an input */
+        PropertyLine.prototype._displayInput = function (e) {
+            // Remove the displayInput event listener
+            this._valueDiv.removeEventListener('click', this._displayInputHandler);
+            // Removes the input on a click in the window
+            // window.addEventListener('click', this._removeInputHandler);
+            // Set input value
+            var valueTxt = this._valueDiv.textContent;
+            this._valueDiv.textContent = "";
+            this._input.value = valueTxt;
+            this._valueDiv.appendChild(this._input);
+        };
+        /** Retrieve the correct object from its parent.
+         * If no parent exists, returns the property value.
+         * This method is used at each update in case the property object is removed from the original object
+         * (example : mesh.position = new BABYLON.Vector3 ; the original vector3 object is deleted from the mesh).
+        */
+        PropertyLine.prototype.updateObject = function () {
+            if (!this._parent) {
+                return this._property.value;
+            }
+            else {
+                this._property.obj = this._parent.updateObject();
+            }
+        };
+        Object.defineProperty(PropertyLine.prototype, "name", {
+            // Returns the property name
+            get: function () {
+                return this._property.name;
+            },
+            enumerable: true,
+            configurable: true
+        });
+        Object.defineProperty(PropertyLine.prototype, "value", {
+            // Returns the value of the property
+            get: function () {
+                return PropertyFormatter.format(this._property.obj, this._property.name);
+            },
+            enumerable: true,
+            configurable: true
+        });
+        Object.defineProperty(PropertyLine.prototype, "type", {
+            // Returns the type of the property
+            get: function () {
+                return this._property.type;
+            },
+            enumerable: true,
+            configurable: true
+        });
+        /**
+         * Creates elements that wil be displayed on a property line, depending on the
+         * type of the property.
+         */
+        PropertyLine.prototype._createElements = function () {
+            // Colors
+            if (this.type == 'Color3' || this.type == 'Color4') {
+                this._elements.push(new INSPECTOR.ColorElement(this.value));
+            }
+            // Texture
+            if (this.type == 'Texture') {
+                this._elements.push(new INSPECTOR.TextureElement(this.value));
+            }
+            // HDR Texture
+            if (this.type == 'HDRCubeTexture') {
+                this._elements.push(new INSPECTOR.HDRCubeTextureElement(this.value));
+            }
+            if (this.type == 'CubeTexture') {
+                this._elements.push(new INSPECTOR.CubeTextureElement(this.value));
+            }
+        };
+        // Returns the text displayed on the left of the property name : 
+        // - If the type is simple, display its value
+        // - If the type is complex, but instance of Vector2, Size, display the type and its tostring
+        // - If the type is another one, display the Type
+        PropertyLine.prototype._displayValueContent = function () {
+            var value = this.value;
+            // If the value is a number, truncate it if needed
+            if (typeof value === 'number') {
+                return INSPECTOR.Helpers.Trunc(value);
+            }
+            // If it's a string or a boolean, display its value
+            if (typeof value === 'string' || typeof value === 'boolean') {
+                return value;
+            }
+            return INSPECTOR.PROPERTIES.format(value);
+        };
+        /** Delete properly this property line.
+         * Removes itself from the scheduler.
+         * Dispose all viewer element (color, texture...)
+         */
+        PropertyLine.prototype.dispose = function () {
+            // console.log('delete properties', this.name);
+            INSPECTOR.Scheduler.getInstance().remove(this);
+            for (var _i = 0, _a = this._children; _i < _a.length; _i++) {
+                var child = _a[_i];
+                // console.log('delete properties', child.name);
+                INSPECTOR.Scheduler.getInstance().remove(child);
+            }
+            for (var _b = 0, _c = this._elements; _b < _c.length; _b++) {
+                var elem = _c[_b];
+                elem.dispose();
+            }
+            this._elements = [];
+        };
+        /** Updates the content of _valueDiv with the value of the property,
+         * and all HTML element correpsonding to this type.
+         * Elements are updated as well
+         */
+        PropertyLine.prototype._updateValue = function () {
+            // Update the property object first
+            this.updateObject();
+            // Then update its value
+            this._valueDiv.textContent = " ";
+            this._valueDiv.childNodes[0].nodeValue = this._displayValueContent();
+            for (var _i = 0, _a = this._elements; _i < _a.length; _i++) {
+                var elem = _a[_i];
+                elem.update(this.value);
+            }
+        };
+        /**
+         * Update the property division with the new property value.
+         * If this property is complex, update its child, otherwise update its text content
+         */
+        PropertyLine.prototype.update = function () {
+            this._removeInputWithoutValidating();
+            this._updateValue();
+        };
+        /**
+         * Returns true if the given instance is a simple type
+         */
+        PropertyLine._IS_TYPE_SIMPLE = function (inst) {
+            var type = INSPECTOR.Helpers.GET_TYPE(inst);
+            return PropertyLine._SIMPLE_TYPE.indexOf(type) != -1;
+        };
+        /**
+         * Returns true if the type of this property is simple, false otherwise.
+         * Returns true if the value is null
+         */
+        PropertyLine.prototype._isSimple = function () {
+            if (this.value != null) {
+                if (PropertyLine._SIMPLE_TYPE.indexOf(this.type) == -1) {
+                    // complex type : return the type name
+                    return false;
+                }
+                else {
+                    // simple type : return value
+                    return true;
+                }
+            }
+            else {
+                return true;
+            }
+        };
+        PropertyLine.prototype.toHtml = function () {
+            return this._div;
+        };
+        /**
+         * Add sub properties in case of a complex type
+         */
+        PropertyLine.prototype._addDetails = function () {
+            if (this._div.classList.contains('unfolded')) {
+                // Remove class unfolded
+                this._div.classList.remove('unfolded');
+                // remove html children
+                for (var _i = 0, _a = this._children; _i < _a.length; _i++) {
+                    var child = _a[_i];
+                    this._div.parentNode.removeChild(child.toHtml());
+                }
+            }
+            else {
+                // if children does not exists, generate it
+                this._div.classList.toggle('unfolded');
+                if (this._children.length == 0) {
+                    var objToDetail = this.value;
+                    var propToDisplay = INSPECTOR.PROPERTIES[INSPECTOR.Helpers.GET_TYPE(objToDetail)].properties.reverse();
+                    var propertyLine = null;
+                    for (var _b = 0, propToDisplay_1 = propToDisplay; _b < propToDisplay_1.length; _b++) {
+                        var prop = propToDisplay_1[_b];
+                        var infos = new INSPECTOR.Property(prop, this._property.value);
+                        var child = new PropertyLine(infos, this, this._level + PropertyLine._MARGIN_LEFT);
+                        this._children.push(child);
+                    }
+                }
+                // otherwise display it                    
+                for (var _c = 0, _d = this._children; _c < _d.length; _c++) {
+                    var child = _d[_c];
+                    this._div.parentNode.insertBefore(child.toHtml(), this._div.nextSibling);
+                }
+            }
+        };
+        // Array representing the simple type. All others are considered 'complex'
+        PropertyLine._SIMPLE_TYPE = ['number', 'string', 'boolean'];
+        // The number of pixel at each children step
+        PropertyLine._MARGIN_LEFT = 15;
+        return PropertyLine;
+    }());
+    INSPECTOR.PropertyLine = PropertyLine;
+})(INSPECTOR || (INSPECTOR = {}));
+//# sourceMappingURL=PropertyLine.js.map

+ 21 - 0
inspector/dist/inspector/gui/BasicElement.d.ts

@@ -0,0 +1,21 @@
+declare module INSPECTOR {
+    /**
+     * Represents a html div element.
+     * The div is built when an instance of BasicElement is created.
+     */
+    abstract class BasicElement {
+        protected _div: HTMLElement;
+        constructor();
+        /**
+         * Returns the div element
+         */
+        toHtml(): HTMLElement;
+        /**
+         * Build the html element
+         */
+        protected _build(): void;
+        abstract update(data?: any): any;
+        /** Default dispose method if needed */
+        dispose(): void;
+    }
+}

+ 29 - 0
inspector/dist/inspector/gui/BasicElement.js

@@ -0,0 +1,29 @@
+var INSPECTOR;
+(function (INSPECTOR) {
+    /**
+     * Represents a html div element.
+     * The div is built when an instance of BasicElement is created.
+     */
+    var BasicElement = (function () {
+        function BasicElement() {
+            this._div = INSPECTOR.Helpers.CreateDiv();
+        }
+        /**
+         * Returns the div element
+         */
+        BasicElement.prototype.toHtml = function () {
+            return this._div;
+        };
+        /**
+         * Build the html element
+         */
+        BasicElement.prototype._build = function () { };
+        ;
+        /** Default dispose method if needed */
+        BasicElement.prototype.dispose = function () { };
+        ;
+        return BasicElement;
+    }());
+    INSPECTOR.BasicElement = BasicElement;
+})(INSPECTOR || (INSPECTOR = {}));
+//# sourceMappingURL=BasicElement.js.map

+ 10 - 0
inspector/dist/inspector/gui/ColorElement.d.ts

@@ -0,0 +1,10 @@
+declare module INSPECTOR {
+    /**
+    * Display a very small div corresponding to the given color
+    */
+    class ColorElement extends BasicElement {
+        constructor(color: BABYLON.Color4 | BABYLON.Color3);
+        update(color?: BABYLON.Color4 | BABYLON.Color3): void;
+        private _toRgba(color);
+    }
+}

+ 43 - 0
inspector/dist/inspector/gui/ColorElement.js

@@ -0,0 +1,43 @@
+var __extends = (this && this.__extends) || function (d, b) {
+    for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
+    function __() { this.constructor = d; }
+    d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
+};
+var INSPECTOR;
+(function (INSPECTOR) {
+    /**
+    * Display a very small div corresponding to the given color
+    */
+    var ColorElement = (function (_super) {
+        __extends(ColorElement, _super);
+        // The color as hexadecimal string
+        function ColorElement(color) {
+            _super.call(this);
+            this._div.className = 'color-element';
+            this._div.style.backgroundColor = this._toRgba(color);
+        }
+        ColorElement.prototype.update = function (color) {
+            if (color) {
+                this._div.style.backgroundColor = this._toRgba(color);
+            }
+        };
+        ColorElement.prototype._toRgba = function (color) {
+            if (color) {
+                var r = (color.r * 255) | 0;
+                var g = (color.g * 255) | 0;
+                var b = (color.b * 255) | 0;
+                var a = 1;
+                if (color instanceof BABYLON.Color4) {
+                    var a_1 = color.a;
+                }
+                return "rgba(" + r + ", " + g + ", " + b + ", " + a + ")";
+            }
+            else {
+                return '';
+            }
+        };
+        return ColorElement;
+    }(INSPECTOR.BasicElement));
+    INSPECTOR.ColorElement = ColorElement;
+})(INSPECTOR || (INSPECTOR = {}));
+//# sourceMappingURL=ColorElement.js.map

+ 26 - 0
inspector/dist/inspector/gui/CubeTextureElement.d.ts

@@ -0,0 +1,26 @@
+declare 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
+    */
+    class CubeTextureElement extends BasicElement {
+        /** The big div displaying the full image */
+        private _textureDiv;
+        private _engine;
+        protected _scene: BABYLON.Scene;
+        protected _cube: BABYLON.Mesh;
+        private _canvas;
+        protected _textureUrl: string;
+        private _pause;
+        /** The texture given as a parameter should be cube. */
+        constructor(tex: BABYLON.Texture);
+        update(tex?: BABYLON.Texture): void;
+        /** Creates the box  */
+        protected _populateScene(): void;
+        /** Init the babylon engine */
+        private _initEngine();
+        private _showViewer(mode);
+        /** Removes properly the babylon engine */
+        dispose(): void;
+    }
+}

+ 110 - 0
inspector/dist/inspector/gui/CubeTextureElement.js

@@ -0,0 +1,110 @@
+var __extends = (this && this.__extends) || function (d, b) {
+    for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
+    function __() { this.constructor = d; }
+    d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
+};
+var INSPECTOR;
+(function (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
+    */
+    var CubeTextureElement = (function (_super) {
+        __extends(CubeTextureElement, _super);
+        /** The texture given as a parameter should be cube. */
+        function CubeTextureElement(tex) {
+            _super.call(this);
+            // On pause the engine will not render anything
+            this._pause = false;
+            this._div.className = 'fa fa-search texture-element';
+            // Create the texture viewer
+            this._textureDiv = INSPECTOR.Helpers.CreateDiv('texture-viewer', this._div);
+            // canvas
+            this._canvas = INSPECTOR.Helpers.CreateElement('canvas', 'texture-viewer-img', this._textureDiv);
+            if (tex) {
+                this._textureUrl = tex.name;
+            }
+            this._div.addEventListener('mouseover', this._showViewer.bind(this, 'flex'));
+            this._div.addEventListener('mouseout', this._showViewer.bind(this, 'none'));
+        }
+        CubeTextureElement.prototype.update = function (tex) {
+            if (tex && tex.url === this._textureUrl) {
+            }
+            else {
+                if (tex) {
+                    this._textureUrl = tex.name;
+                }
+                if (this._engine) {
+                    // Dispose old material and cube
+                    this._cube.material.dispose(true, true);
+                    this._cube.dispose();
+                }
+                else {
+                    this._initEngine();
+                }
+                // and create it again
+                this._populateScene();
+            }
+        };
+        /** Creates the box  */
+        CubeTextureElement.prototype._populateScene = function () {
+            var _this = this;
+            // Create the hdr texture
+            var hdrTexture = new BABYLON.CubeTexture(this._textureUrl, this._scene);
+            hdrTexture.coordinatesMode = BABYLON.Texture.SKYBOX_MODE;
+            this._cube = BABYLON.Mesh.CreateBox("hdrSkyBox", 10.0, this._scene);
+            var 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(function () {
+                _this._cube.rotation.y += 0.01;
+            });
+        };
+        /** Init the babylon engine */
+        CubeTextureElement.prototype._initEngine = function () {
+            var _this = this;
+            this._engine = new BABYLON.Engine(this._canvas);
+            this._scene = new BABYLON.Scene(this._engine);
+            this._scene.clearColor = new BABYLON.Color4(0, 0, 0, 0);
+            var cam = new BABYLON.FreeCamera('cam', new BABYLON.Vector3(0, 0, -20), this._scene);
+            var light = new BABYLON.HemisphericLight('', new BABYLON.Vector3(0, 1, 0), this._scene);
+            this._engine.runRenderLoop(function () {
+                if (!_this._pause) {
+                    _this._scene.render();
+                }
+            });
+            this._canvas.setAttribute('width', '110');
+            this._canvas.setAttribute('height', '110');
+        };
+        CubeTextureElement.prototype._showViewer = function (mode) {
+            // 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 */
+        CubeTextureElement.prototype.dispose = function () {
+            if (this._engine) {
+                this._engine.dispose();
+                this._engine = null;
+            }
+        };
+        return CubeTextureElement;
+    }(INSPECTOR.BasicElement));
+    INSPECTOR.CubeTextureElement = CubeTextureElement;
+})(INSPECTOR || (INSPECTOR = {}));
+//# sourceMappingURL=CubeTextureElement.js.map

+ 12 - 0
inspector/dist/inspector/gui/HDRCubeTextureElement.d.ts

@@ -0,0 +1,12 @@
+declare 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
+    */
+    class HDRCubeTextureElement extends CubeTextureElement {
+        /** The texture given as a parameter should be cube. */
+        constructor(tex: BABYLON.Texture);
+        /** Creates the box  */
+        protected _populateScene(): void;
+    }
+}

+ 39 - 0
inspector/dist/inspector/gui/HDRCubeTextureElement.js

@@ -0,0 +1,39 @@
+var __extends = (this && this.__extends) || function (d, b) {
+    for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
+    function __() { this.constructor = d; }
+    d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
+};
+var INSPECTOR;
+(function (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
+    */
+    var HDRCubeTextureElement = (function (_super) {
+        __extends(HDRCubeTextureElement, _super);
+        /** The texture given as a parameter should be cube. */
+        function HDRCubeTextureElement(tex) {
+            _super.call(this, tex);
+        }
+        /** Creates the box  */
+        HDRCubeTextureElement.prototype._populateScene = function () {
+            var _this = this;
+            // Create the hdr texture
+            var 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);
+            var 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(function () {
+                _this._cube.rotation.y += 0.01;
+            });
+        };
+        return HDRCubeTextureElement;
+    }(INSPECTOR.CubeTextureElement));
+    INSPECTOR.HDRCubeTextureElement = HDRCubeTextureElement;
+})(INSPECTOR || (INSPECTOR = {}));
+//# sourceMappingURL=HDRCubeTextureElement.js.map

+ 14 - 0
inspector/dist/inspector/gui/SearchBar.d.ts

@@ -0,0 +1,14 @@
+declare 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.
+     */
+    class SearchBar extends BasicElement {
+        private _tab;
+        private _inputElement;
+        constructor(tab: PropertyTab);
+        /** Delete all characters typped in the input element */
+        reset(): void;
+        update(): void;
+    }
+}

+ 42 - 0
inspector/dist/inspector/gui/SearchBar.js

@@ -0,0 +1,42 @@
+var __extends = (this && this.__extends) || function (d, b) {
+    for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
+    function __() { this.constructor = d; }
+    d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
+};
+var INSPECTOR;
+(function (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.
+     */
+    var SearchBar = (function (_super) {
+        __extends(SearchBar, _super);
+        function SearchBar(tab) {
+            var _this = this;
+            _super.call(this);
+            this._tab = tab;
+            this._div.classList.add('searchbar');
+            var filter = INSPECTOR.Inspector.DOCUMENT.createElement('i');
+            filter.className = 'fa fa-search';
+            this._div.appendChild(filter);
+            // Create input
+            this._inputElement = INSPECTOR.Inspector.DOCUMENT.createElement('input');
+            this._inputElement.placeholder = 'Filter by name...';
+            this._div.appendChild(this._inputElement);
+            this._inputElement.addEventListener('keyup', function (evt) {
+                var filter = _this._inputElement.value;
+                _this._tab.filter(filter);
+            });
+        }
+        /** Delete all characters typped in the input element */
+        SearchBar.prototype.reset = function () {
+            this._inputElement.value = '';
+        };
+        SearchBar.prototype.update = function () {
+            // Nothing to update
+        };
+        return SearchBar;
+    }(INSPECTOR.BasicElement));
+    INSPECTOR.SearchBar = SearchBar;
+})(INSPECTOR || (INSPECTOR = {}));
+//# sourceMappingURL=SearchBar.js.map

+ 12 - 0
inspector/dist/inspector/gui/TextureElement.d.ts

@@ -0,0 +1,12 @@
+declare module INSPECTOR {
+    /**
+    * Display a very small div corresponding to the given texture. On mouse over, display the full image
+    */
+    class TextureElement extends BasicElement {
+        /** The big div displaying the full image */
+        private _textureDiv;
+        constructor(tex: BABYLON.Texture);
+        update(tex?: BABYLON.Texture): void;
+        private _showViewer(mode);
+    }
+}

+ 40 - 0
inspector/dist/inspector/gui/TextureElement.js

@@ -0,0 +1,40 @@
+var __extends = (this && this.__extends) || function (d, b) {
+    for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
+    function __() { this.constructor = d; }
+    d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
+};
+var INSPECTOR;
+(function (INSPECTOR) {
+    /**
+    * Display a very small div corresponding to the given texture. On mouse over, display the full image
+    */
+    var TextureElement = (function (_super) {
+        __extends(TextureElement, _super);
+        function TextureElement(tex) {
+            _super.call(this);
+            this._div.className = 'fa fa-search texture-element';
+            // Create the texture viewer
+            this._textureDiv = INSPECTOR.Helpers.CreateDiv('texture-viewer', this._div);
+            // Img
+            var imgDiv = INSPECTOR.Helpers.CreateDiv('texture-viewer-img', this._textureDiv);
+            // Texture size
+            var sizeDiv = INSPECTOR.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'));
+        }
+        TextureElement.prototype.update = function (tex) {
+        };
+        TextureElement.prototype._showViewer = function (mode) {
+            this._textureDiv.style.display = mode;
+        };
+        return TextureElement;
+    }(INSPECTOR.BasicElement));
+    INSPECTOR.TextureElement = TextureElement;
+})(INSPECTOR || (INSPECTOR = {}));
+//# sourceMappingURL=TextureElement.js.map

+ 12 - 0
inspector/dist/inspector/gui/Tooltip.d.ts

@@ -0,0 +1,12 @@
+declare module INSPECTOR {
+    /**
+     * Creates a tooltip for the given html element
+     */
+    class Tooltip {
+        /** The tooltip is displayed for this element */
+        private _elem;
+        /** The tooltip div */
+        private _infoDiv;
+        constructor(elem: HTMLElement, tip: string);
+    }
+}

+ 21 - 0
inspector/dist/inspector/gui/Tooltip.js

@@ -0,0 +1,21 @@
+var INSPECTOR;
+(function (INSPECTOR) {
+    /**
+     * Creates a tooltip for the given html element
+     */
+    var Tooltip = (function () {
+        function Tooltip(elem, tip) {
+            var _this = this;
+            this._elem = elem;
+            this._infoDiv = INSPECTOR.Helpers.CreateDiv('tooltip', this._elem);
+            this._elem.addEventListener('mouseover', function () {
+                _this._infoDiv.textContent = tip;
+                _this._infoDiv.style.display = 'block';
+            });
+            this._elem.addEventListener('mouseout', function () { _this._infoDiv.style.display = 'none'; });
+        }
+        return Tooltip;
+    }());
+    INSPECTOR.Tooltip = Tooltip;
+})(INSPECTOR || (INSPECTOR = {}));
+//# sourceMappingURL=Tooltip.js.map

+ 27 - 0
inspector/dist/inspector/helpers/Helpers.d.ts

@@ -0,0 +1,27 @@
+declare module INSPECTOR {
+    class Helpers {
+        /**
+         * Returns the type of the given object. First
+         * uses getClassName. If nothing is returned, used the type of the constructor
+         */
+        static GET_TYPE(obj: any): string;
+        /**
+         * Returns the name of a function (workaround to get object type for IE11)
+         */
+        private static _GetFnName(fn);
+        /** Send the event which name is given in parameter to the window */
+        static SEND_EVENT(eventName: string): void;
+        /** Returns the given number with 2 decimal number max if a decimal part exists */
+        static Trunc(nb: any): number;
+        /**
+         * Useful function used to create a div
+         */
+        static CreateDiv(className?: string, parent?: HTMLElement): HTMLElement;
+        static CreateElement(element: string, className?: string, parent?: HTMLElement): HTMLElement;
+        /**
+         * Removes all children of the given div.
+         */
+        static CleanDiv(div: HTMLElement): void;
+        static LoadScript(): void;
+    }
+}

+ 102 - 0
inspector/dist/inspector/helpers/Helpers.js

@@ -0,0 +1,102 @@
+var INSPECTOR;
+(function (INSPECTOR) {
+    var Helpers = (function () {
+        function Helpers() {
+        }
+        /**
+         * Returns the type of the given object. First
+         * uses getClassName. If nothing is returned, used the type of the constructor
+         */
+        Helpers.GET_TYPE = function (obj) {
+            if (obj != null && obj != undefined) {
+                var 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);
+                    }
+                }
+                return classname;
+            }
+            else {
+                return '';
+            }
+        };
+        /**
+         * Returns the name of a function (workaround to get object type for IE11)
+         */
+        Helpers._GetFnName = function (fn) {
+            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 */
+        Helpers.SEND_EVENT = function (eventName) {
+            var event;
+            if (INSPECTOR.Inspector.DOCUMENT.createEvent) {
+                event = INSPECTOR.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 */
+        Helpers.Trunc = function (nb) {
+            if (Math.round(nb) !== nb) {
+                return nb.toFixed(2);
+            }
+            return nb;
+        };
+        ;
+        /**
+         * Useful function used to create a div
+         */
+        Helpers.CreateDiv = function (className, parent) {
+            return Helpers.CreateElement('div', className, parent);
+        };
+        Helpers.CreateElement = function (element, className, parent) {
+            var elem = INSPECTOR.Inspector.DOCUMENT.createElement(element);
+            if (className) {
+                elem.className = className;
+            }
+            if (parent) {
+                parent.appendChild(elem);
+            }
+            return elem;
+        };
+        /**
+         * Removes all children of the given div.
+         */
+        Helpers.CleanDiv = function (div) {
+            while (div.firstChild) {
+                div.removeChild(div.firstChild);
+            }
+        };
+        Helpers.LoadScript = function () {
+            BABYLON.Tools.LoadFile("https://cdnjs.cloudflare.com/ajax/libs/highlight.js/9.7.0/highlight.min.js", function (elem) {
+                var script = Helpers.CreateElement('script', '', INSPECTOR.Inspector.DOCUMENT.body);
+                script.textContent = elem;
+                // Load glsl detection
+                BABYLON.Tools.LoadFile("https://cdnjs.cloudflare.com/ajax/libs/highlight.js/9.7.0/languages/glsl.min.js", function (elem) {
+                    var script = Helpers.CreateElement('script', '', INSPECTOR.Inspector.DOCUMENT.body);
+                    script.textContent = elem;
+                    // Load css style
+                    BABYLON.Tools.LoadFile("https://cdnjs.cloudflare.com/ajax/libs/highlight.js/9.7.0/styles/zenburn.min.css", function (elem) {
+                        var style = Helpers.CreateElement('style', '', INSPECTOR.Inspector.DOCUMENT.body);
+                        style.textContent = elem;
+                    });
+                }, null, null, null, function () {
+                    console.log("erreur");
+                });
+            }, null, null, null, function () {
+                console.log("erreur");
+            });
+        };
+        return Helpers;
+    }());
+    INSPECTOR.Helpers = Helpers;
+})(INSPECTOR || (INSPECTOR = {}));
+//# sourceMappingURL=Helpers.js.map

+ 59 - 0
inspector/dist/inspector/properties.d.ts

@@ -0,0 +1,59 @@
+declare module INSPECTOR {
+    const PROPERTIES: {
+        format: (obj: any) => any;
+        'Vector2': {
+            properties: string[];
+            format: (vec: BABYLON.Vector2) => string;
+        };
+        'Vector3': {
+            properties: string[];
+            format: (vec: BABYLON.Vector3) => string;
+        };
+        'Color3': {
+            properties: string[];
+            format: (color: BABYLON.Color3) => string;
+        };
+        'Quaternion': {
+            properties: string[];
+        };
+        'Size': {
+            properties: string[];
+            format: (size: BABYLON.Size) => string;
+        };
+        'Texture': {
+            properties: string[];
+        };
+        'ArcRotateCamera': {
+            properties: string[];
+        };
+        'Scene': {
+            properties: string[];
+        };
+        'Mesh': {
+            properties: string[];
+            format: (m: BABYLON.Mesh) => string;
+        };
+        'StandardMaterial': {
+            properties: string[];
+            format: (mat: BABYLON.StandardMaterial) => string;
+        };
+        'PrimitiveAlignment': {
+            properties: string[];
+        };
+        'PrimitiveThickness': {
+            properties: string[];
+        };
+        'BoundingInfo2D': {
+            properties: string[];
+        };
+        'SolidColorBrush2D': {
+            properties: string[];
+        };
+        'GradientColorBrush2D': {
+            properties: string[];
+        };
+        'PBRMaterial': {
+            properties: string[];
+        };
+    };
+}

+ 155 - 0
inspector/dist/inspector/properties.js

@@ -0,0 +1,155 @@
+var INSPECTOR;
+(function (INSPECTOR) {
+    INSPECTOR.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: function (obj) {
+            var type = INSPECTOR.Helpers.GET_TYPE(obj) || 'default';
+            if (INSPECTOR.PROPERTIES[type] && INSPECTOR.PROPERTIES[type].format) {
+                return INSPECTOR.PROPERTIES[type].format(obj);
+            }
+            else {
+                return INSPECTOR.Helpers.GET_TYPE(obj);
+            }
+        },
+        'Vector2': {
+            properties: ['x', 'y'],
+            format: function (vec) { return "x:" + INSPECTOR.Helpers.Trunc(vec.x) + ", y:" + INSPECTOR.Helpers.Trunc(vec.y); }
+        },
+        'Vector3': {
+            properties: ['x', 'y', 'z'],
+            format: function (vec) { return "x:" + INSPECTOR.Helpers.Trunc(vec.x) + ", y:" + INSPECTOR.Helpers.Trunc(vec.y) + ", z:" + INSPECTOR.Helpers.Trunc(vec.z); }
+        },
+        'Color3': {
+            properties: ['r', 'g', 'b'],
+            format: function (color) { return "R:" + color.r + ", G:" + color.g + ", B:" + color.b; }
+        },
+        'Quaternion': {
+            properties: ['x', 'y', 'z', 'w']
+        },
+        'Size': {
+            properties: ['width', 'height'],
+            format: function (size) { return "Size - w:" + INSPECTOR.Helpers.Trunc(size.width) + ", h:" + INSPECTOR.Helpers.Trunc(size.height); }
+        },
+        'Texture': {
+            properties: [
+                'hasAlpha',
+                'level',
+                'name',
+                'wrapU',
+                'wrapV',
+                'uScale',
+                'vScale',
+                'uAng',
+                'vAng',
+                'wAng',
+                'uOffset',
+                'vOffset'
+            ],
+        },
+        'ArcRotateCamera': {
+            properties: ['alpha', 'beta', 'radius']
+        },
+        'Scene': {
+            properties: ['actionManager', 'activeCamera', 'ambientColor', 'clearColor']
+        },
+        'Mesh': {
+            properties: [
+                'name',
+                'position',
+                'rotation',
+                'rotationQuaternion',
+                'absolutePosition',
+                'material'
+            ],
+            format: function (m) { return m.name; }
+        },
+        'StandardMaterial': {
+            properties: [
+                'name',
+                'alpha',
+                'alphaMode',
+                'wireframe',
+                'isFrozen',
+                'zOffset',
+                'ambientColor',
+                'emissiveColor',
+                'diffuseColor',
+                'specularColor',
+                'specularPower',
+                'useAlphaFromDiffuseTexture',
+                'linkEmissiveWithDiffuse',
+                'useSpecularOverAlpha',
+                'diffuseFresnelParameters',
+                'opacityFresnelParameters',
+                'reflectionFresnelParameters',
+                'refractionFresnelParameters',
+                'emissiveFresnelParameters',
+                'diffuseTexture',
+                'emissiveTexture',
+                'specularTexture',
+                'ambientTexture',
+                'bumpTexture',
+                'lightMapTexture',
+                'opacityTexture',
+                'reflectionTexture',
+                'refractionTexture'
+            ],
+            format: function (mat) { return mat.name; }
+        },
+        'PrimitiveAlignment': {
+            properties: ['horizontal', 'vertical']
+        },
+        'PrimitiveThickness': {
+            properties: ['topPixels', 'leftPixels', 'rightPixels', 'bottomPixels']
+        },
+        'BoundingInfo2D': {
+            properties: ['radius', 'center', 'extent']
+        },
+        'SolidColorBrush2D': {
+            properties: ['color']
+        },
+        'GradientColorBrush2D': {
+            properties: ['color1', 'color2', 'translation', 'rotation', 'scale']
+        },
+        'PBRMaterial': {
+            properties: [
+                'name',
+                'albedoColor',
+                'albedoTexture',
+                'opacityTexture',
+                'reflectionTexture',
+                'emissiveTexture',
+                'bumpTexture',
+                'lightmapTexture',
+                'opacityFresnelParameters',
+                'emissiveFresnelParameters',
+                'linkEmissiveWithAlbedo',
+                'useLightmapAsShadowmap',
+                'useAlphaFromAlbedoTexture',
+                'useSpecularOverAlpha',
+                'useAutoMicroSurfaceFromReflectivityMap',
+                'useLogarithmicDepth',
+                'reflectivityColor',
+                'reflectivityTexture',
+                'reflectionTexture',
+                'reflectionColor',
+                'alpha',
+                'linkRefractionWithTransparency',
+                'indexOfRefraction',
+                'microSurface',
+                'useMicroSurfaceFromReflectivityMapAlpha',
+                'directIntensity',
+                'emissiveIntensity',
+                'specularIntensity',
+                'environmentIntensity',
+                'cameraExposure',
+                'cameraContrast',
+                'cameraColorGradingTexture',
+                'cameraColorCurves'
+            ]
+        }
+    };
+})(INSPECTOR || (INSPECTOR = {}));
+//# sourceMappingURL=properties.js.map

+ 20 - 0
inspector/dist/inspector/scheduler/Scheduler.d.ts

@@ -0,0 +1,20 @@
+declare module INSPECTOR {
+    class Scheduler {
+        private static _instance;
+        /** The number of the set interval */
+        private _timer;
+        /** Is this scheduler in pause ? */
+        pause: boolean;
+        /** All properties are refreshed every 250ms */
+        static REFRESH_TIME: number;
+        /** The list of data to update */
+        private _updatableProperties;
+        constructor();
+        static getInstance(): Scheduler;
+        /** Add a property line to be updated every X ms */
+        add(prop: PropertyLine): void;
+        /** Removes the given property from the list of properties to update */
+        remove(prop: PropertyLine): void;
+        private _update();
+    }
+}

+ 44 - 0
inspector/dist/inspector/scheduler/Scheduler.js

@@ -0,0 +1,44 @@
+var INSPECTOR;
+(function (INSPECTOR) {
+    var Scheduler = (function () {
+        function Scheduler() {
+            /** Is this scheduler in pause ? */
+            this.pause = false;
+            /** The list of data to update */
+            this._updatableProperties = [];
+            this._timer = setInterval(this._update.bind(this), Scheduler.REFRESH_TIME);
+        }
+        Scheduler.getInstance = function () {
+            if (!Scheduler._instance) {
+                Scheduler._instance = new Scheduler();
+                console.log('create ');
+            }
+            return Scheduler._instance;
+        };
+        /** Add a property line to be updated every X ms */
+        Scheduler.prototype.add = function (prop) {
+            this._updatableProperties.push(prop);
+        };
+        /** Removes the given property from the list of properties to update */
+        Scheduler.prototype.remove = function (prop) {
+            var index = this._updatableProperties.indexOf(prop);
+            if (index != -1) {
+                this._updatableProperties.splice(index, 1);
+            }
+        };
+        Scheduler.prototype._update = function () {
+            // If not in pause, update 
+            if (!this.pause) {
+                for (var _i = 0, _a = this._updatableProperties; _i < _a.length; _i++) {
+                    var prop = _a[_i];
+                    prop.update();
+                }
+            }
+        };
+        /** All properties are refreshed every 250ms */
+        Scheduler.REFRESH_TIME = 250;
+        return Scheduler;
+    }());
+    INSPECTOR.Scheduler = Scheduler;
+})(INSPECTOR || (INSPECTOR = {}));
+//# sourceMappingURL=Scheduler.js.map

+ 6 - 0
inspector/dist/inspector/tabs/Canvas2DTab.d.ts

@@ -0,0 +1,6 @@
+declare module INSPECTOR {
+    class Canvas2DTab extends PropertyTab {
+        constructor(tabbar: TabBar, inspector: Inspector);
+        protected _getTree(): Array<TreeItem>;
+    }
+}

+ 53 - 0
inspector/dist/inspector/tabs/Canvas2DTab.js

@@ -0,0 +1,53 @@
+var __extends = (this && this.__extends) || function (d, b) {
+    for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
+    function __() { this.constructor = d; }
+    d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
+};
+var INSPECTOR;
+(function (INSPECTOR) {
+    var Canvas2DTab = (function (_super) {
+        __extends(Canvas2DTab, _super);
+        function Canvas2DTab(tabbar, inspector) {
+            _super.call(this, tabbar, 'Canvas2D', inspector);
+        }
+        /* Overrides */
+        Canvas2DTab.prototype._getTree = function () {
+            var _this = this;
+            var arr = [];
+            // get all canvas2D
+            var instances = BABYLON.Canvas2D.instances || [];
+            // Returns true if the id of the given object starts and ends with '###'
+            var shouldExcludeThisPrim = function (obj) {
+                return (obj.id && obj.id.indexOf('###') == 0 && obj.id.lastIndexOf('###', 0) === 0);
+            };
+            // Recursive method building the tree panel
+            var createNode = function (obj) {
+                if (obj.children && obj.children.length > 0) {
+                    var node = new INSPECTOR.TreeItem(_this, new INSPECTOR.Canvas2DAdapter(obj));
+                    for (var _i = 0, _a = obj.children; _i < _a.length; _i++) {
+                        var child = _a[_i];
+                        if (!shouldExcludeThisPrim(child)) {
+                            var n = createNode(child);
+                            node.add(n);
+                        }
+                    }
+                    node.update();
+                    return node;
+                }
+                else {
+                    return new INSPECTOR.TreeItem(_this, new INSPECTOR.Canvas2DAdapter(obj));
+                }
+            };
+            for (var _i = 0, instances_1 = instances; _i < instances_1.length; _i++) {
+                var inst = instances_1[_i];
+                var c2d = inst;
+                var nodes = createNode(c2d);
+                arr.push(nodes);
+            }
+            return arr;
+        };
+        return Canvas2DTab;
+    }(INSPECTOR.PropertyTab));
+    INSPECTOR.Canvas2DTab = Canvas2DTab;
+})(INSPECTOR || (INSPECTOR = {}));
+//# sourceMappingURL=Canvas2DTab.js.map

+ 6 - 0
inspector/dist/inspector/tabs/LightTab.d.ts

@@ -0,0 +1,6 @@
+declare module INSPECTOR {
+    class LightTab extends PropertyTab {
+        constructor(tabbar: TabBar, inspector: Inspector);
+        protected _getTree(): Array<TreeItem>;
+    }
+}

+ 28 - 0
inspector/dist/inspector/tabs/LightTab.js

@@ -0,0 +1,28 @@
+var __extends = (this && this.__extends) || function (d, b) {
+    for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
+    function __() { this.constructor = d; }
+    d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
+};
+var INSPECTOR;
+(function (INSPECTOR) {
+    var LightTab = (function (_super) {
+        __extends(LightTab, _super);
+        function LightTab(tabbar, inspector) {
+            _super.call(this, tabbar, 'Light', inspector);
+        }
+        /* Overrides super */
+        LightTab.prototype._getTree = function () {
+            var arr = [];
+            // get all lights from the first scene
+            var instances = this._inspector.scene;
+            for (var _i = 0, _a = instances.lights; _i < _a.length; _i++) {
+                var light = _a[_i];
+                arr.push(new INSPECTOR.TreeItem(this, new INSPECTOR.LightAdapter(light)));
+            }
+            return arr;
+        };
+        return LightTab;
+    }(INSPECTOR.PropertyTab));
+    INSPECTOR.LightTab = LightTab;
+})(INSPECTOR || (INSPECTOR = {}));
+//# sourceMappingURL=LightTab.js.map

+ 6 - 0
inspector/dist/inspector/tabs/MaterialTab.d.ts

@@ -0,0 +1,6 @@
+declare module INSPECTOR {
+    class MaterialTab extends PropertyTab {
+        constructor(tabbar: TabBar, inspector: Inspector);
+        protected _getTree(): Array<TreeItem>;
+    }
+}

+ 28 - 0
inspector/dist/inspector/tabs/MaterialTab.js

@@ -0,0 +1,28 @@
+var __extends = (this && this.__extends) || function (d, b) {
+    for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
+    function __() { this.constructor = d; }
+    d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
+};
+var INSPECTOR;
+(function (INSPECTOR) {
+    var MaterialTab = (function (_super) {
+        __extends(MaterialTab, _super);
+        function MaterialTab(tabbar, inspector) {
+            _super.call(this, tabbar, 'Material', inspector);
+        }
+        /* Overrides super */
+        MaterialTab.prototype._getTree = function () {
+            var arr = [];
+            // get all meshes from the first scene
+            var instances = this._inspector.scene;
+            for (var _i = 0, _a = instances.materials; _i < _a.length; _i++) {
+                var mat = _a[_i];
+                arr.push(new INSPECTOR.TreeItem(this, new INSPECTOR.MaterialAdapter(mat)));
+            }
+            return arr;
+        };
+        return MaterialTab;
+    }(INSPECTOR.PropertyTab));
+    INSPECTOR.MaterialTab = MaterialTab;
+})(INSPECTOR || (INSPECTOR = {}));
+//# sourceMappingURL=MaterialTab.js.map

+ 6 - 0
inspector/dist/inspector/tabs/MeshTab.d.ts

@@ -0,0 +1,6 @@
+declare module INSPECTOR {
+    class MeshTab extends PropertyTab {
+        constructor(tabbar: TabBar, inspector: Inspector);
+        protected _getTree(): Array<TreeItem>;
+    }
+}

+ 34 - 0
inspector/dist/inspector/tabs/MeshTab.js

@@ -0,0 +1,34 @@
+var __extends = (this && this.__extends) || function (d, b) {
+    for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
+    function __() { this.constructor = d; }
+    d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
+};
+var INSPECTOR;
+(function (INSPECTOR) {
+    var MeshTab = (function (_super) {
+        __extends(MeshTab, _super);
+        function MeshTab(tabbar, inspector) {
+            _super.call(this, tabbar, 'Mesh', inspector);
+        }
+        /* Overrides super */
+        MeshTab.prototype._getTree = function () {
+            var arr = [];
+            // Returns true if the id of the given object starts and ends with '###'
+            var shouldExcludeThisMesh = function (obj) {
+                return (obj.name && obj.name.indexOf('###') == 0 && obj.name.lastIndexOf('###', 0) === 0);
+            };
+            // get all meshes from the first scene
+            var instances = this._inspector.scene;
+            for (var _i = 0, _a = instances.meshes; _i < _a.length; _i++) {
+                var mesh = _a[_i];
+                if (!shouldExcludeThisMesh(mesh)) {
+                    arr.push(new INSPECTOR.TreeItem(this, new INSPECTOR.MeshAdapter(mesh)));
+                }
+            }
+            return arr;
+        };
+        return MeshTab;
+    }(INSPECTOR.PropertyTab));
+    INSPECTOR.MeshTab = MeshTab;
+})(INSPECTOR || (INSPECTOR = {}));
+//# sourceMappingURL=MeshTab.js.map

+ 34 - 0
inspector/dist/inspector/tabs/PropertyTab.d.ts

@@ -0,0 +1,34 @@
+declare 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
+     */
+    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);
+        /** Overrides dispose */
+        dispose(): void;
+        update(_items?: Array<TreeItem>): void;
+        /** Display the details of the given item */
+        displayDetails(item: TreeItem): void;
+        /** Select an item in the tree */
+        select(item: TreeItem): void;
+        /** Highlight the given node, and downplay all others */
+        highlightNode(item?: TreeItem): void;
+        /** Set the given item as active in the tree */
+        activateNode(item: TreeItem): void;
+        /** Returns the treeitem corersponding to the given obj, null if not found */
+        getItemFor(_obj: any): TreeItem;
+        filter(filter: string): void;
+        /** Builds the tree panel */
+        protected abstract _getTree(): Array<TreeItem>;
+    }
+}

+ 125 - 0
inspector/dist/inspector/tabs/PropertyTab.js

@@ -0,0 +1,125 @@
+var __extends = (this && this.__extends) || function (d, b) {
+    for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
+    function __() { this.constructor = d; }
+    d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
+};
+var INSPECTOR;
+(function (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
+     */
+    var PropertyTab = (function (_super) {
+        __extends(PropertyTab, _super);
+        function PropertyTab(tabbar, name, insp) {
+            _super.call(this, tabbar, name);
+            this._treeItems = [];
+            this._inspector = insp;
+            // Build the properties panel : a div that will contains the tree and the detail panel
+            this._panel = INSPECTOR.Helpers.CreateDiv('tab-panel');
+            // Search bar
+            this._searchBar = new INSPECTOR.SearchBar(this);
+            // Add searchbar
+            this._panel.appendChild(this._searchBar.toHtml());
+            // Build the treepanel
+            this._treePanel = INSPECTOR.Helpers.CreateDiv('insp-tree', this._panel);
+            // Build the detail panel
+            this._detailsPanel = new INSPECTOR.DetailPanel();
+            this._panel.appendChild(this._detailsPanel.toHtml());
+            Split([this._treePanel, this._detailsPanel.toHtml()], { direction: 'vertical' });
+            this.update();
+        }
+        /** Overrides dispose */
+        PropertyTab.prototype.dispose = function () {
+            this._detailsPanel.dispose();
+        };
+        PropertyTab.prototype.update = function (_items) {
+            var items;
+            if (_items) {
+                items = _items;
+            }
+            else {
+                // Rebuild the tree
+                this._treeItems = this._getTree();
+                items = this._treeItems;
+            }
+            // Clean the tree
+            INSPECTOR.Helpers.CleanDiv(this._treePanel);
+            // Clean the detail properties
+            this._detailsPanel.clean();
+            // Sort items alphabetically
+            items.sort(function (item1, item2) {
+                return item1.compareTo(item2);
+            });
+            // Display items
+            for (var _i = 0, items_1 = items; _i < items_1.length; _i++) {
+                var item = items_1[_i];
+                this._treePanel.appendChild(item.toHtml());
+            }
+        };
+        /** Display the details of the given item */
+        PropertyTab.prototype.displayDetails = function (item) {
+            // Remove active state on all items
+            this.activateNode(item);
+            // Update the detail panel
+            this._detailsPanel.details = item.getDetails();
+        };
+        /** Select an item in the tree */
+        PropertyTab.prototype.select = function (item) {
+            // Remove the node highlight
+            this.highlightNode();
+            // Active the node
+            this.activateNode(item);
+            // Display its details
+            this.displayDetails(item);
+        };
+        /** Highlight the given node, and downplay all others */
+        PropertyTab.prototype.highlightNode = function (item) {
+            if (this._treeItems) {
+                for (var _i = 0, _a = this._treeItems; _i < _a.length; _i++) {
+                    var node = _a[_i];
+                    node.highlight(false);
+                }
+            }
+            if (item) {
+                item.highlight(true);
+            }
+        };
+        /** Set the given item as active in the tree */
+        PropertyTab.prototype.activateNode = function (item) {
+            if (this._treeItems) {
+                for (var _i = 0, _a = this._treeItems; _i < _a.length; _i++) {
+                    var node = _a[_i];
+                    node.active(false);
+                }
+            }
+            item.active(true);
+        };
+        /** Returns the treeitem corersponding to the given obj, null if not found */
+        PropertyTab.prototype.getItemFor = function (_obj) {
+            var obj = _obj;
+            for (var _i = 0, _a = this._treeItems; _i < _a.length; _i++) {
+                var item = _a[_i];
+                if (item.correspondsTo(obj)) {
+                    return item;
+                }
+            }
+            return null;
+        };
+        PropertyTab.prototype.filter = function (filter) {
+            var items = [];
+            for (var _i = 0, _a = this._treeItems; _i < _a.length; _i++) {
+                var item = _a[_i];
+                if (item.id.toLowerCase().indexOf(filter.toLowerCase()) != -1) {
+                    items.push(item);
+                }
+            }
+            this.update(items);
+        };
+        return PropertyTab;
+    }(INSPECTOR.Tab));
+    INSPECTOR.PropertyTab = PropertyTab;
+})(INSPECTOR || (INSPECTOR = {}));
+//# sourceMappingURL=PropertyTab.js.map

+ 21 - 0
inspector/dist/inspector/tabs/SceneTab.d.ts

@@ -0,0 +1,21 @@
+declare module INSPECTOR {
+    class SceneTab extends Tab {
+        private _inspector;
+        /** The list of  channels/options that can be activated/deactivated */
+        private _actions;
+        /** The list of skeleton viewer */
+        private _skeletonViewers;
+        /** The detail of the scene */
+        private _detailsPanel;
+        constructor(tabbar: TabBar, insp: Inspector);
+        /** Overrides super.dispose */
+        dispose(): void;
+        /** generates a div which correspond to an option that can be activated/deactivated */
+        private _generateActionLine(name, initValue, action);
+        /**
+         * Add a click action for all given elements :
+         * the clicked element is set as active, all others elements are deactivated
+         */
+        private _generateRadioAction(arr);
+    }
+}

+ 176 - 0
inspector/dist/inspector/tabs/SceneTab.js

@@ -0,0 +1,176 @@
+var __extends = (this && this.__extends) || function (d, b) {
+    for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
+    function __() { this.constructor = d; }
+    d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
+};
+var INSPECTOR;
+(function (INSPECTOR) {
+    var SceneTab = (function (_super) {
+        __extends(SceneTab, _super);
+        function SceneTab(tabbar, insp) {
+            var _this = this;
+            _super.call(this, tabbar, 'Scene');
+            /** The list of skeleton viewer */
+            this._skeletonViewers = [];
+            this._inspector = insp;
+            // Build the properties panel : a div that will contains the tree and the detail panel
+            this._panel = INSPECTOR.Helpers.CreateDiv('tab-panel');
+            this._actions = INSPECTOR.Helpers.CreateDiv('scene-actions', this._panel);
+            this._detailsPanel = new INSPECTOR.DetailPanel();
+            this._panel.appendChild(this._detailsPanel.toHtml());
+            // build propertiesline
+            var details = [];
+            for (var _i = 0, _a = INSPECTOR.PROPERTIES['Scene'].properties; _i < _a.length; _i++) {
+                var prop = _a[_i];
+                details.push(new INSPECTOR.PropertyLine(new INSPECTOR.Property(prop, this._inspector.scene)));
+            }
+            this._detailsPanel.details = details;
+            Split([this._actions, this._detailsPanel.toHtml()], {
+                sizes: [50, 50],
+                direction: 'vertical'
+            });
+            // Build actions
+            {
+                // Rendering mode
+                var title = INSPECTOR.Helpers.CreateDiv('actions-title', this._actions);
+                title.textContent = 'Rendering mode';
+                var point = INSPECTOR.Helpers.CreateDiv('action-radio', this._actions);
+                var wireframe = INSPECTOR.Helpers.CreateDiv('action-radio', this._actions);
+                var solid = INSPECTOR.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', function () { _this._inspector.scene.forcePointsCloud = true; _this._inspector.scene.forceWireframe = false; });
+                wireframe.addEventListener('click', function () { _this._inspector.scene.forcePointsCloud = false; _this._inspector.scene.forceWireframe = true; });
+                solid.addEventListener('click', function () { _this._inspector.scene.forcePointsCloud = false; _this._inspector.scene.forceWireframe = false; });
+                // Textures
+                title = INSPECTOR.Helpers.CreateDiv('actions-title', this._actions);
+                title.textContent = 'Textures channels';
+                this._generateActionLine('Diffuse Texture', BABYLON.StandardMaterial.DiffuseTextureEnabled, function (b) { BABYLON.StandardMaterial.DiffuseTextureEnabled = b; });
+                this._generateActionLine('Ambient Texture', BABYLON.StandardMaterial.AmbientTextureEnabled, function (b) { BABYLON.StandardMaterial.AmbientTextureEnabled = b; });
+                this._generateActionLine('Specular Texture', BABYLON.StandardMaterial.SpecularTextureEnabled, function (b) { BABYLON.StandardMaterial.SpecularTextureEnabled = b; });
+                this._generateActionLine('Emissive Texture', BABYLON.StandardMaterial.EmissiveTextureEnabled, function (b) { BABYLON.StandardMaterial.EmissiveTextureEnabled = b; });
+                this._generateActionLine('Bump Texture', BABYLON.StandardMaterial.BumpTextureEnabled, function (b) { BABYLON.StandardMaterial.BumpTextureEnabled = b; });
+                this._generateActionLine('Opacity Texture', BABYLON.StandardMaterial.OpacityTextureEnabled, function (b) { BABYLON.StandardMaterial.OpacityTextureEnabled = b; });
+                this._generateActionLine('Reflection Texture', BABYLON.StandardMaterial.ReflectionTextureEnabled, function (b) { BABYLON.StandardMaterial.ReflectionTextureEnabled = b; });
+                this._generateActionLine('Refraction Texture', BABYLON.StandardMaterial.RefractionTextureEnabled, function (b) { BABYLON.StandardMaterial.RefractionTextureEnabled = b; });
+                this._generateActionLine('ColorGrading', BABYLON.StandardMaterial.ColorGradingTextureEnabled, function (b) { BABYLON.StandardMaterial.ColorGradingTextureEnabled = b; });
+                this._generateActionLine('Lightmap Texture', BABYLON.StandardMaterial.LightmapTextureEnabled, function (b) { BABYLON.StandardMaterial.LightmapTextureEnabled = b; });
+                this._generateActionLine('Fresnel', BABYLON.StandardMaterial.FresnelEnabled, function (b) { BABYLON.StandardMaterial.FresnelEnabled = b; });
+                // Options
+                title = INSPECTOR.Helpers.CreateDiv('actions-title', this._actions);
+                title.textContent = 'Options';
+                this._generateActionLine('Animations', this._inspector.scene.animationsEnabled, function (b) { _this._inspector.scene.animationsEnabled = b; });
+                this._generateActionLine('Collisions', this._inspector.scene.collisionsEnabled, function (b) { _this._inspector.scene.collisionsEnabled = b; });
+                this._generateActionLine('Fog', this._inspector.scene.fogEnabled, function (b) { _this._inspector.scene.fogEnabled = b; });
+                this._generateActionLine('Lens flares', this._inspector.scene.lensFlaresEnabled, function (b) { _this._inspector.scene.lensFlaresEnabled = b; });
+                this._generateActionLine('Lights', this._inspector.scene.lightsEnabled, function (b) { _this._inspector.scene.lightsEnabled = b; });
+                this._generateActionLine('Particles', this._inspector.scene.particlesEnabled, function (b) { _this._inspector.scene.particlesEnabled = b; });
+                this._generateActionLine('Post-processes', this._inspector.scene.postProcessesEnabled, function (b) { _this._inspector.scene.postProcessesEnabled = b; });
+                this._generateActionLine('Probes', this._inspector.scene.probesEnabled, function (b) { _this._inspector.scene.probesEnabled = b; });
+                this._generateActionLine('Procedural textures', this._inspector.scene.proceduralTexturesEnabled, function (b) { _this._inspector.scene.proceduralTexturesEnabled = b; });
+                this._generateActionLine('Render targets', this._inspector.scene.renderTargetsEnabled, function (b) { _this._inspector.scene.renderTargetsEnabled = b; });
+                this._generateActionLine('Shadows', this._inspector.scene.shadowsEnabled, function (b) { _this._inspector.scene.shadowsEnabled = b; });
+                this._generateActionLine('Skeletons', this._inspector.scene.skeletonsEnabled, function (b) { _this._inspector.scene.skeletonsEnabled = b; });
+                this._generateActionLine('Sprites', this._inspector.scene.spritesEnabled, function (b) { _this._inspector.scene.spritesEnabled = b; });
+                this._generateActionLine('Textures', this._inspector.scene.texturesEnabled, function (b) { _this._inspector.scene.texturesEnabled = b; });
+                // Audio
+                title = INSPECTOR.Helpers.CreateDiv('actions-title', this._actions);
+                title.textContent = 'Audio';
+                var headphones = INSPECTOR.Helpers.CreateDiv('action-radio', this._actions);
+                var normalSpeaker = INSPECTOR.Helpers.CreateDiv('action-radio', this._actions);
+                this._generateActionLine('Disable audio', !this._inspector.scene.audioEnabled, function (b) { _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', function () { _this._inspector.scene.headphone = true; });
+                normalSpeaker.addEventListener('click', function () { _this._inspector.scene.headphone = false; });
+                // Viewers
+                title = INSPECTOR.Helpers.CreateDiv('actions-title', this._actions);
+                title.textContent = 'Viewer';
+                this._generateActionLine('Skeletons', false, function (b) {
+                    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;
+                                }
+                                var viewer = new BABYLON.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 = [];
+                    }
+                });
+            }
+        }
+        /** Overrides super.dispose */
+        SceneTab.prototype.dispose = function () {
+            this._detailsPanel.dispose();
+        };
+        /** generates a div which correspond to an option that can be activated/deactivated */
+        SceneTab.prototype._generateActionLine = function (name, initValue, action) {
+            var div = INSPECTOR.Helpers.CreateDiv('scene-actions', this._actions);
+            div.textContent = name;
+            div.classList.add('action');
+            if (initValue) {
+                div.classList.add('active');
+            }
+            div.addEventListener('click', function (e) {
+                div.classList.toggle('active');
+                var 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
+         */
+        SceneTab.prototype._generateRadioAction = function (arr) {
+            var active = function (elem, evt) {
+                for (var _i = 0, arr_1 = arr; _i < arr_1.length; _i++) {
+                    var e = arr_1[_i];
+                    e.classList.remove('active');
+                }
+                elem.classList.add('active');
+            };
+            for (var _i = 0, arr_2 = arr; _i < arr_2.length; _i++) {
+                var elem = arr_2[_i];
+                elem.addEventListener('click', active.bind(this, elem));
+            }
+        };
+        return SceneTab;
+    }(INSPECTOR.Tab));
+    INSPECTOR.SceneTab = SceneTab;
+})(INSPECTOR || (INSPECTOR = {}));
+//# sourceMappingURL=SceneTab.js.map

+ 17 - 0
inspector/dist/inspector/tabs/ShaderTab.d.ts

@@ -0,0 +1,17 @@
+declare module INSPECTOR {
+    class ShaderTab extends Tab {
+        private _inspector;
+        private _vertexPanel;
+        private _fragmentPanel;
+        constructor(tabbar: TabBar, insp: Inspector);
+        private _selectShader(event);
+        /** Overrides super.dispose */
+        dispose(): void;
+        /** Returns the position of the first { and the corresponding } */
+        private _getBracket(str);
+        /**
+         * Beautify the given string : correct indentation
+         */
+        private _beautify(glsl, level?);
+    }
+}

+ 154 - 0
inspector/dist/inspector/tabs/ShaderTab.js

@@ -0,0 +1,154 @@
+var __extends = (this && this.__extends) || function (d, b) {
+    for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
+    function __() { this.constructor = d; }
+    d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
+};
+var INSPECTOR;
+(function (INSPECTOR) {
+    var ShaderTab = (function (_super) {
+        __extends(ShaderTab, _super);
+        function ShaderTab(tabbar, insp) {
+            _super.call(this, tabbar, 'Shader');
+            this._inspector = insp;
+            // Build the shaders panel : a div that will contains the shaders tree and both shaders panels
+            this._panel = INSPECTOR.Helpers.CreateDiv('tab-panel');
+            var shaderPanel = INSPECTOR.Helpers.CreateDiv('shader-tree-panel');
+            this._vertexPanel = INSPECTOR.Helpers.CreateDiv('shader-panel');
+            this._fragmentPanel = INSPECTOR.Helpers.CreateDiv('shader-panel');
+            this._panel.appendChild(shaderPanel);
+            this._panel.appendChild(this._vertexPanel);
+            this._panel.appendChild(this._fragmentPanel);
+            INSPECTOR.Helpers.LoadScript();
+            Split([this._vertexPanel, this._fragmentPanel], {
+                sizes: [50, 50],
+                direction: 'vertical' });
+            var comboBox = INSPECTOR.Helpers.CreateElement('select', '', shaderPanel);
+            comboBox.addEventListener('change', this._selectShader.bind(this));
+            var option = INSPECTOR.Helpers.CreateElement('option', '', comboBox);
+            option.textContent = 'Select a shader';
+            option.setAttribute('value', "");
+            option.setAttribute('disabled', 'true');
+            option.setAttribute('selected', 'true');
+            // Build shaders combobox
+            for (var _i = 0, _a = this._inspector.scene.materials; _i < _a.length; _i++) {
+                var mat = _a[_i];
+                if (mat instanceof BABYLON.ShaderMaterial) {
+                    var option_1 = INSPECTOR.Helpers.CreateElement('option', '', comboBox);
+                    option_1.setAttribute('value', mat.id);
+                    option_1.textContent = mat.name + " - " + mat.id;
+                }
+            }
+        }
+        ShaderTab.prototype._selectShader = function (event) {
+            var id = event.target.value;
+            var mat = this._inspector.scene.getMaterialByID(id);
+            // Clean shader panel
+            INSPECTOR.Helpers.CleanDiv(this._vertexPanel);
+            // add the title - vertex shader
+            var title = INSPECTOR.Helpers.CreateDiv('shader-panel-title', this._vertexPanel);
+            title.textContent = 'Vertex shader';
+            // add code
+            var code = INSPECTOR.Helpers.CreateElement('code', 'glsl', INSPECTOR.Helpers.CreateElement('pre', '', this._vertexPanel));
+            code.textContent = this._beautify(mat.getEffect().getVertexShaderSource());
+            INSPECTOR.Helpers.CleanDiv(this._fragmentPanel);
+            // add the title - fragment shader
+            title = INSPECTOR.Helpers.CreateDiv('shader-panel-title', this._fragmentPanel);
+            title.textContent = 'Frgament shader';
+            // add code
+            code = INSPECTOR.Helpers.CreateElement('code', 'glsl', INSPECTOR.Helpers.CreateElement('pre', '', this._fragmentPanel));
+            code.textContent = this._beautify(mat.getEffect().getFragmentShaderSource());
+            // Init the syntax highlighting
+            var styleInit = INSPECTOR.Helpers.CreateElement('script', '', INSPECTOR.Inspector.DOCUMENT.body);
+            styleInit.textContent = 'hljs.initHighlighting();';
+        };
+        /** Overrides super.dispose */
+        ShaderTab.prototype.dispose = function () {
+        };
+        /** Returns the position of the first { and the corresponding } */
+        ShaderTab.prototype._getBracket = function (str) {
+            var fb = str.indexOf('{');
+            var arr = str.substr(fb + 1).split('');
+            var counter = 1;
+            var currentPosInString = fb;
+            var lastBracketIndex = 0;
+            for (var _i = 0, arr_1 = arr; _i < arr_1.length; _i++) {
+                var char = arr_1[_i];
+                currentPosInString++;
+                if (char === '{') {
+                    counter++;
+                }
+                if (char === '}') {
+                    counter--;
+                }
+                if (counter == 0) {
+                    lastBracketIndex = currentPosInString;
+                    break;
+                }
+            }
+            return { firstBracket: fb, lastBracket: lastBracketIndex };
+        };
+        /**
+         * Beautify the given string : correct indentation
+         */
+        ShaderTab.prototype._beautify = function (glsl, level) {
+            if (level === void 0) { level = 0; }
+            // return condition : no brackets at all
+            var brackets = this._getBracket(glsl);
+            var firstBracket = brackets.firstBracket;
+            var lastBracket = brackets.lastBracket;
+            var spaces = "";
+            for (var i = 0; i < level; i++) {
+                spaces += "    "; // 4 spaces
+            }
+            // If no brackets, return the indented string
+            if (firstBracket == -1) {
+                glsl = spaces + glsl; // indent first line
+                glsl = glsl
+                    .replace(/;./g, function (x) { return '\n' + x.substr(1); }); // new line after ;  except the last one
+                glsl = glsl.replace(/=/g, " = "); // space around =
+                glsl = glsl.replace(/\n/g, "\n" + spaces); // indentation
+                return glsl;
+            }
+            else {
+                // if brackets, beautify the inside                                 
+                // let insideWithBrackets = glsl.substr(firstBracket, lastBracket-firstBracket+1);
+                var left = glsl.substr(0, firstBracket);
+                var right = glsl.substr(lastBracket + 1, glsl.length);
+                var inside = glsl.substr(firstBracket + 1, lastBracket - firstBracket - 1);
+                inside = this._beautify(inside, level + 1);
+                return this._beautify(left, level) + '{\n' + inside + '\n' + spaces + '}\n' + this._beautify(right, level);
+            }
+            // // Replace bracket with @1 and @2 with correct indentation
+            // let newInside          = "@1\n\t" + inside + "\n@2";
+            // newInside              = newInside.replace(/;\n/g, ";\n\t");
+            // glsl                   = glsl.replace(insideWithBrackets, newInside);
+            // firstBracket       = glsl.indexOf('{');
+            // lastBracket        = glsl.lastIndexOf('}');
+            // }
+            // console.log(glsl);
+            // let regex = /(\{(?:\{??[^\{]*?}))+/gmi;
+            // let tmp = glsl;
+            // let m;
+            // while ((m = regex.exec(tmp)) !== null) {
+            //     // This is necessary to avoid infinite loops with zero-width matches
+            //     if (m.index === regex.lastIndex) {
+            //         regex.lastIndex++;
+            //     }                
+            //     // The result can be accessed through the `m`-variable.
+            //     m.forEach((match, groupIndex) => {
+            //         // Remove the first and the last bracket only
+            //         let matchWithoutBrackets = match.replace(/{/, "").replace(/}/, "");
+            //         // Indent the content inside brackets with tabs
+            //         glsl = glsl.replace(match, `{\n\t${matchWithoutBrackets}\n}\n`);
+            //         // removes the match from tmp
+            //         tmp = tmp.replace(match, "");
+            //         // and continue
+            //     });
+            // }
+            // return 
+        };
+        return ShaderTab;
+    }(INSPECTOR.Tab));
+    INSPECTOR.ShaderTab = ShaderTab;
+})(INSPECTOR || (INSPECTOR = {}));
+//# sourceMappingURL=ShaderTab.js.map

+ 25 - 0
inspector/dist/inspector/tabs/Tab.d.ts

@@ -0,0 +1,25 @@
+declare module INSPECTOR {
+    abstract class Tab extends BasicElement {
+        protected _tabbar: TabBar;
+        name: string;
+        protected _isActive: boolean;
+        protected _panel: HTMLDivElement;
+        constructor(tabbar: TabBar, name: string);
+        /** True if the tab is active, false otherwise */
+        isActive(): boolean;
+        protected _build(): void;
+        /** Set this tab as active or not, depending on the current state */
+        active(b: boolean): void;
+        update(): void;
+        /** Creates the tab panel for this tab. */
+        getPanel(): HTMLElement;
+        /** Add this in the propertytab with the searchbar */
+        filter(str: string): void;
+        /** Dispose properly this tab */
+        abstract dispose(): any;
+        /**
+         * Returns the total width in pixel of this tab, 0 by default
+        */
+        getPixelWidth(): number;
+    }
+}

+ 63 - 0
inspector/dist/inspector/tabs/Tab.js

@@ -0,0 +1,63 @@
+var __extends = (this && this.__extends) || function (d, b) {
+    for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
+    function __() { this.constructor = d; }
+    d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
+};
+var INSPECTOR;
+(function (INSPECTOR) {
+    var Tab = (function (_super) {
+        __extends(Tab, _super);
+        function Tab(tabbar, name) {
+            _super.call(this);
+            this._isActive = false;
+            this._tabbar = tabbar;
+            this.name = name;
+            this._build();
+        }
+        /** True if the tab is active, false otherwise */
+        Tab.prototype.isActive = function () {
+            return this._isActive;
+        };
+        Tab.prototype._build = function () {
+            var _this = this;
+            this._div.className = 'tab';
+            this._div.textContent = this.name;
+            this._div.addEventListener('click', function (evt) {
+                // Set this tab as active
+                _this._tabbar.switchTab(_this);
+            });
+        };
+        /** Set this tab as active or not, depending on the current state */
+        Tab.prototype.active = function (b) {
+            if (b) {
+                this._div.classList.add('active');
+            }
+            else {
+                this._div.classList.remove('active');
+            }
+            this._isActive = b;
+        };
+        Tab.prototype.update = function () {
+            // Nothing for the moment
+        };
+        /** Creates the tab panel for this tab. */
+        Tab.prototype.getPanel = function () {
+            return this._panel;
+        };
+        /** Add this in the propertytab with the searchbar */
+        Tab.prototype.filter = function (str) { };
+        ;
+        /**
+         * Returns the total width in pixel of this tab, 0 by default
+        */
+        Tab.prototype.getPixelWidth = function () {
+            var style = window.getComputedStyle(this._div);
+            var left = parseFloat(style.marginLeft.substr(0, style.marginLeft.length - 2)) || 0;
+            var right = parseFloat(style.marginRight.substr(0, style.marginRight.length - 2)) || 0;
+            return (this._div.clientWidth || 0) + left + right;
+        };
+        return Tab;
+    }(INSPECTOR.BasicElement));
+    INSPECTOR.Tab = Tab;
+})(INSPECTOR || (INSPECTOR = {}));
+//# sourceMappingURL=Tab.js.map

+ 48 - 0
inspector/dist/inspector/tabs/TabBar.d.ts

@@ -0,0 +1,48 @@
+declare 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.
+     */
+    class TabBar extends BasicElement {
+        private _tabs;
+        private _inspector;
+        /** The tab displaying all meshes */
+        private _meshTab;
+        /** The toolbar */
+        private _toolBar;
+        /** The icon displayed at the end of the toolbar displaying a combo box of tabs not displayed */
+        private _moreTabsIcon;
+        /** The panel displayed when the 'more-tab' icon is selected */
+        private _moreTabsPanel;
+        /** The list of tab displayed by clicking on the remainingIcon */
+        private _invisibleTabs;
+        /** The list of tabs visible, displayed in the tab bar */
+        private _visibleTabs;
+        constructor(inspector: Inspector);
+        update(): void;
+        protected _build(): void;
+        /**
+         * Add a tab to the 'more-tabs' panel, displayed by clicking on the
+         * 'more-tabs' icon
+         */
+        private _addInvisibleTabToPanel(tab);
+        /** Dispose the current tab, set the given tab as active, and refresh the treeview */
+        switchTab(tab: Tab): void;
+        /** Display the mesh tab.
+         * If a parameter is given, the given mesh details are displayed
+         */
+        switchMeshTab(mesh?: BABYLON.AbstractMesh): void;
+        /** Returns the active tab */
+        getActiveTab(): Tab;
+        inspector: Inspector;
+        /**
+         * Returns the total width in pixel of the tabbar,
+         * that corresponds to the sum of the width of each visible tab + toolbar width
+        */
+        getPixelWidth(): number;
+        /** Display the remaining icon or not depending on the tabbar width.
+         * This function should be called each time the inspector width is updated
+         */
+        updateWidth(): void;
+    }
+}

+ 181 - 0
inspector/dist/inspector/tabs/TabBar.js

@@ -0,0 +1,181 @@
+var __extends = (this && this.__extends) || function (d, b) {
+    for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
+    function __() { this.constructor = d; }
+    d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
+};
+var INSPECTOR;
+(function (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.
+     */
+    var TabBar = (function (_super) {
+        __extends(TabBar, _super);
+        function TabBar(inspector) {
+            _super.call(this);
+            // The list of available tabs
+            this._tabs = [];
+            /** The list of tab displayed by clicking on the remainingIcon */
+            this._invisibleTabs = [];
+            /** The list of tabs visible, displayed in the tab bar */
+            this._visibleTabs = [];
+            this._inspector = inspector;
+            this._tabs.push(new INSPECTOR.SceneTab(this, this._inspector));
+            this._meshTab = new INSPECTOR.MeshTab(this, this._inspector);
+            this._tabs.push(this._meshTab);
+            this._tabs.push(new INSPECTOR.ShaderTab(this, this._inspector));
+            this._tabs.push(new INSPECTOR.LightTab(this, this._inspector));
+            this._tabs.push(new INSPECTOR.Canvas2DTab(this, this._inspector));
+            this._tabs.push(new INSPECTOR.MaterialTab(this, this._inspector));
+            this._toolBar = new INSPECTOR.Toolbar(this._inspector);
+            this._build();
+            // Active the first tab
+            this._tabs[0].active(true);
+            // set all tab as visible
+            for (var _i = 0, _a = this._tabs; _i < _a.length; _i++) {
+                var tab = _a[_i];
+                this._visibleTabs.push(tab);
+            }
+        }
+        // No update
+        TabBar.prototype.update = function () { };
+        TabBar.prototype._build = function () {
+            var _this = this;
+            this._div.className = 'tabbar';
+            this._div.appendChild(this._toolBar.toHtml());
+            for (var _i = 0, _a = this._tabs; _i < _a.length; _i++) {
+                var tab = _a[_i];
+                this._div.appendChild(tab.toHtml());
+            }
+            this._moreTabsIcon = INSPECTOR.Helpers.CreateElement('i', 'fa fa-angle-double-right more-tabs');
+            this._moreTabsPanel = INSPECTOR.Helpers.CreateDiv('more-tabs-panel');
+            this._moreTabsIcon.addEventListener('click', function () {
+                // 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
+                    var topPanel = _this._div.parentNode;
+                    if (!topPanel.contains(_this._moreTabsPanel)) {
+                        topPanel.appendChild(_this._moreTabsPanel);
+                    }
+                    // Clean the 'more-tabs-panel'
+                    INSPECTOR.Helpers.CleanDiv(_this._moreTabsPanel);
+                    // Add each invisible tabs to this panel
+                    for (var _i = 0, _a = _this._invisibleTabs; _i < _a.length; _i++) {
+                        var tab = _a[_i];
+                        _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
+         */
+        TabBar.prototype._addInvisibleTabToPanel = function (tab) {
+            var _this = this;
+            var div = INSPECTOR.Helpers.CreateDiv('invisible-tab', this._moreTabsPanel);
+            div.textContent = tab.name;
+            div.addEventListener('click', function () {
+                _this._moreTabsPanel.style.display = 'none';
+                _this.switchTab(tab);
+            });
+        };
+        /** Dispose the current tab, set the given tab as active, and refresh the treeview */
+        TabBar.prototype.switchTab = function (tab) {
+            // Dispose the active tab
+            this.getActiveTab().dispose();
+            // Deactivate all tabs
+            for (var _i = 0, _a = this._tabs; _i < _a.length; _i++) {
+                var t = _a[_i];
+                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
+         */
+        TabBar.prototype.switchMeshTab = function (mesh) {
+            this.switchTab(this._meshTab);
+            if (mesh) {
+                var item = this._meshTab.getItemFor(mesh);
+                this._meshTab.select(item);
+            }
+        };
+        /** Returns the active tab */
+        TabBar.prototype.getActiveTab = function () {
+            for (var _i = 0, _a = this._tabs; _i < _a.length; _i++) {
+                var tab = _a[_i];
+                if (tab.isActive()) {
+                    return tab;
+                }
+            }
+        };
+        Object.defineProperty(TabBar.prototype, "inspector", {
+            get: function () {
+                return this._inspector;
+            },
+            enumerable: true,
+            configurable: true
+        });
+        /**
+         * Returns the total width in pixel of the tabbar,
+         * that corresponds to the sum of the width of each visible tab + toolbar width
+        */
+        TabBar.prototype.getPixelWidth = function () {
+            var sum = 0;
+            for (var _i = 0, _a = this._visibleTabs; _i < _a.length; _i++) {
+                var tab = _a[_i];
+                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
+         */
+        TabBar.prototype.updateWidth = function () {
+            var parentSize = this._div.parentElement.clientWidth;
+            var lastTabWidth = 75;
+            var 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
+                var 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;
+            }
+            // 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) {
+                    var lastTab = this._invisibleTabs.pop();
+                    this._div.appendChild(lastTab.toHtml());
+                    this._visibleTabs.push(lastTab);
+                    // Update more-tab icon in last position if needed
+                    this._div.removeChild(this._moreTabsIcon);
+                }
+            }
+            if (this._invisibleTabs.length > 0 && !this._div.contains(this._moreTabsIcon)) {
+                this._div.appendChild(this._moreTabsIcon);
+            }
+        };
+        return TabBar;
+    }(INSPECTOR.BasicElement));
+    INSPECTOR.TabBar = TabBar;
+})(INSPECTOR || (INSPECTOR = {}));
+//# sourceMappingURL=TabBar.js.map

+ 17 - 0
inspector/dist/inspector/tools/AbstractTool.d.ts

@@ -0,0 +1,17 @@
+declare module INSPECTOR {
+    abstract class AbstractTool {
+        private _elem;
+        protected _inspector: Inspector;
+        constructor(icon: string, parent: HTMLElement, inspector: Inspector, tooltip: string);
+        toHtml(): HTMLElement;
+        /**
+         * Returns the total width in pixel of this tool, 0 by default
+        */
+        getPixelWidth(): number;
+        /**
+         * Updates the icon of this tool with the given string
+         */
+        protected _updateIcon(icon: string): void;
+        abstract action(): any;
+    }
+}

+ 37 - 0
inspector/dist/inspector/tools/AbstractTool.js

@@ -0,0 +1,37 @@
+var INSPECTOR;
+(function (INSPECTOR) {
+    var AbstractTool = (function () {
+        function AbstractTool(icon, parent, inspector, tooltip) {
+            var _this = this;
+            this._inspector = inspector;
+            this._elem = INSPECTOR.Inspector.DOCUMENT.createElement('i');
+            this._elem.className = "tool fa " + icon;
+            parent.appendChild(this._elem);
+            this._elem.addEventListener('click', function (e) {
+                _this.action();
+            });
+            new INSPECTOR.Tooltip(this._elem, tooltip);
+        }
+        AbstractTool.prototype.toHtml = function () {
+            return this._elem;
+        };
+        /**
+         * Returns the total width in pixel of this tool, 0 by default
+        */
+        AbstractTool.prototype.getPixelWidth = function () {
+            var style = window.getComputedStyle(this._elem);
+            var left = parseFloat(style.marginLeft.substr(0, style.marginLeft.length - 2)) || 0;
+            var right = parseFloat(style.marginRight.substr(0, style.marginRight.length - 2)) || 0;
+            return (this._elem.clientWidth || 0) + left + right;
+        };
+        /**
+         * Updates the icon of this tool with the given string
+         */
+        AbstractTool.prototype._updateIcon = function (icon) {
+            this._elem.className = "tool fa " + icon;
+        };
+        return AbstractTool;
+    }());
+    INSPECTOR.AbstractTool = AbstractTool;
+})(INSPECTOR || (INSPECTOR = {}));
+//# sourceMappingURL=AbstractTool.js.map

+ 7 - 0
inspector/dist/inspector/tools/PauseScheduleTool.d.ts

@@ -0,0 +1,7 @@
+declare module INSPECTOR {
+    class PauseScheduleTool extends AbstractTool {
+        private _isPause;
+        constructor(parent: HTMLElement, inspector: Inspector);
+        action(): void;
+    }
+}

+ 30 - 0
inspector/dist/inspector/tools/PauseScheduleTool.js

@@ -0,0 +1,30 @@
+var __extends = (this && this.__extends) || function (d, b) {
+    for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
+    function __() { this.constructor = d; }
+    d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
+};
+var INSPECTOR;
+(function (INSPECTOR) {
+    var PauseScheduleTool = (function (_super) {
+        __extends(PauseScheduleTool, _super);
+        function PauseScheduleTool(parent, inspector) {
+            _super.call(this, 'fa-pause', parent, inspector, 'Pause the automatic update of properties');
+            this._isPause = false;
+        }
+        // Action : refresh the whole panel
+        PauseScheduleTool.prototype.action = function () {
+            if (this._isPause) {
+                INSPECTOR.Scheduler.getInstance().pause = false;
+                this._updateIcon('fa-pause');
+            }
+            else {
+                INSPECTOR.Scheduler.getInstance().pause = true;
+                this._updateIcon('fa-play');
+            }
+            this._isPause = !this._isPause;
+        };
+        return PauseScheduleTool;
+    }(INSPECTOR.AbstractTool));
+    INSPECTOR.PauseScheduleTool = PauseScheduleTool;
+})(INSPECTOR || (INSPECTOR = {}));
+//# sourceMappingURL=PauseScheduleTool.js.map

+ 13 - 0
inspector/dist/inspector/tools/PickTool.d.ts

@@ -0,0 +1,13 @@
+declare module INSPECTOR {
+    class PickTool extends AbstractTool {
+        private _isActive;
+        private _pickHandler;
+        constructor(parent: HTMLElement, inspector: Inspector);
+        action(): void;
+        /** Deactivate this tool */
+        private _deactivate();
+        /** Pick a mesh in the scene */
+        private _pickMesh(evt);
+        private _updatePointerPosition(evt);
+    }
+}

+ 56 - 0
inspector/dist/inspector/tools/PickTool.js

@@ -0,0 +1,56 @@
+var __extends = (this && this.__extends) || function (d, b) {
+    for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
+    function __() { this.constructor = d; }
+    d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
+};
+var INSPECTOR;
+(function (INSPECTOR) {
+    var PickTool = (function (_super) {
+        __extends(PickTool, _super);
+        function PickTool(parent, inspector) {
+            _super.call(this, 'fa-mouse-pointer', parent, inspector, 'Pick a mesh in the scene to display its details');
+            this._isActive = false;
+            // Create handler
+            this._pickHandler = this._pickMesh.bind(this);
+        }
+        // Action : find the corresponding tree item in the correct tab and display it
+        PickTool.prototype.action = function () {
+            if (this._isActive) {
+                this._deactivate();
+            }
+            else {
+                this.toHtml().classList.add('active');
+                // Add event handler : pick on a mesh in the scene
+                this._inspector.scene.getEngine().getRenderingCanvas().addEventListener('click', this._pickHandler);
+                this._isActive = true;
+            }
+        };
+        /** Deactivate this tool */
+        PickTool.prototype._deactivate = function () {
+            this.toHtml().classList.remove('active');
+            // Remove event handler
+            this._inspector.scene.getEngine().getRenderingCanvas().removeEventListener('click', this._pickHandler);
+            this._isActive = false;
+        };
+        /** Pick a mesh in the scene */
+        PickTool.prototype._pickMesh = function (evt) {
+            var pos = this._updatePointerPosition(evt);
+            var pi = this._inspector.scene.pick(pos.x, pos.y, function (mesh) { return true; });
+            if (pi.pickedMesh) {
+                console.log(pi.pickedMesh.name);
+                this._inspector.displayObjectDetails(pi.pickedMesh);
+            }
+            this._deactivate();
+        };
+        PickTool.prototype._updatePointerPosition = function (evt) {
+            var canvasRect = this._inspector.scene.getEngine().getRenderingCanvasClientRect();
+            var pointerX = evt.clientX - canvasRect.left;
+            var pointerY = evt.clientY - canvasRect.top;
+            return { x: pointerX, y: pointerY };
+        };
+        ;
+        return PickTool;
+    }(INSPECTOR.AbstractTool));
+    INSPECTOR.PickTool = PickTool;
+})(INSPECTOR || (INSPECTOR = {}));
+//# sourceMappingURL=PickTool.js.map

+ 6 - 0
inspector/dist/inspector/tools/PopupTool.d.ts

@@ -0,0 +1,6 @@
+declare module INSPECTOR {
+    class PopupTool extends AbstractTool {
+        constructor(parent: HTMLElement, inspector: Inspector);
+        action(): void;
+    }
+}

+ 21 - 0
inspector/dist/inspector/tools/PopupTool.js

@@ -0,0 +1,21 @@
+var __extends = (this && this.__extends) || function (d, b) {
+    for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
+    function __() { this.constructor = d; }
+    d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
+};
+var INSPECTOR;
+(function (INSPECTOR) {
+    var PopupTool = (function (_super) {
+        __extends(PopupTool, _super);
+        function PopupTool(parent, inspector) {
+            _super.call(this, 'fa-external-link', parent, inspector, 'Creates the inspector in an external popup');
+        }
+        // Action : refresh the whole panel
+        PopupTool.prototype.action = function () {
+            this._inspector.openPopup();
+        };
+        return PopupTool;
+    }(INSPECTOR.AbstractTool));
+    INSPECTOR.PopupTool = PopupTool;
+})(INSPECTOR || (INSPECTOR = {}));
+//# sourceMappingURL=PopupTool.js.map

+ 6 - 0
inspector/dist/inspector/tools/RefreshTool.d.ts

@@ -0,0 +1,6 @@
+declare module INSPECTOR {
+    class RefreshTool extends AbstractTool {
+        constructor(parent: HTMLElement, inspector: Inspector);
+        action(): void;
+    }
+}

+ 21 - 0
inspector/dist/inspector/tools/RefreshTool.js

@@ -0,0 +1,21 @@
+var __extends = (this && this.__extends) || function (d, b) {
+    for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
+    function __() { this.constructor = d; }
+    d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
+};
+var INSPECTOR;
+(function (INSPECTOR) {
+    var RefreshTool = (function (_super) {
+        __extends(RefreshTool, _super);
+        function RefreshTool(parent, inspector) {
+            _super.call(this, 'fa-refresh', parent, inspector, 'Refresh the current tab');
+        }
+        // Action : refresh the whole panel
+        RefreshTool.prototype.action = function () {
+            this._inspector.refresh();
+        };
+        return RefreshTool;
+    }(INSPECTOR.AbstractTool));
+    INSPECTOR.RefreshTool = RefreshTool;
+})(INSPECTOR || (INSPECTOR = {}));
+//# sourceMappingURL=RefreshTool.js.map

+ 15 - 0
inspector/dist/inspector/tools/Toolbar.d.ts

@@ -0,0 +1,15 @@
+declare module INSPECTOR {
+    class Toolbar extends BasicElement {
+        private _inspector;
+        private _tools;
+        constructor(inspector: Inspector);
+        update(): void;
+        protected _build(): void;
+        private _addTools();
+        /**
+         * Returns the total width in pixel of the tabbar,
+         * that corresponds to the sum of the width of each tab + toolbar width
+        */
+        getPixelWidth(): number;
+    }
+}

+ 52 - 0
inspector/dist/inspector/tools/Toolbar.js

@@ -0,0 +1,52 @@
+var __extends = (this && this.__extends) || function (d, b) {
+    for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
+    function __() { this.constructor = d; }
+    d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
+};
+var INSPECTOR;
+(function (INSPECTOR) {
+    var Toolbar = (function (_super) {
+        __extends(Toolbar, _super);
+        function Toolbar(inspector) {
+            _super.call(this);
+            this._tools = [];
+            this._inspector = inspector;
+            this._build();
+            this._addTools();
+        }
+        // A toolbar cannot be updated
+        Toolbar.prototype.update = function () { };
+        ;
+        Toolbar.prototype._build = function () {
+            this._div.className = 'toolbar';
+        };
+        ;
+        Toolbar.prototype._addTools = function () {
+            // Refresh
+            this._tools.push(new INSPECTOR.RefreshTool(this._div, this._inspector));
+            // Pick object
+            this._tools.push(new INSPECTOR.PickTool(this._div, this._inspector));
+            // Add the popup mode only if the inspector is not in popup mode
+            if (!this._inspector.popupMode) {
+                this._tools.push(new INSPECTOR.PopupTool(this._div, this._inspector));
+            }
+            // Pause schedule
+            this._tools.push(new INSPECTOR.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
+        */
+        Toolbar.prototype.getPixelWidth = function () {
+            var sum = 0;
+            for (var _i = 0, _a = this._tools; _i < _a.length; _i++) {
+                var tool = _a[_i];
+                sum += tool.getPixelWidth();
+            }
+            return sum;
+        };
+        return Toolbar;
+    }(INSPECTOR.BasicElement));
+    INSPECTOR.Toolbar = Toolbar;
+})(INSPECTOR || (INSPECTOR = {}));
+//# sourceMappingURL=Toolbar.js.map

+ 44 - 0
inspector/dist/inspector/tree/TreeItem.d.ts

@@ -0,0 +1,44 @@
+declare module INSPECTOR {
+    class TreeItem extends BasicElement {
+        private _tab;
+        private _adapter;
+        private _tools;
+        private _children;
+        private _lineContent;
+        constructor(tab: PropertyTab, obj: Adapter);
+        /** Returns the item ID == its adapter ID */
+        id: string;
+        /** Add the given item as a child of this one */
+        add(child: TreeItem): void;
+        /**
+         * Function used to compare this item to another tree item.
+         * Returns the alphabetical sort of the adapter ID
+         */
+        compareTo(item: TreeItem): number;
+        /** Returns true if the given obj correspond to the adapter linked to this tree item */
+        correspondsTo(obj: any): boolean;
+        /** hide all children of this item */
+        fold(): void;
+        /** Show all children of this item */
+        unfold(): void;
+        /** Build the HTML of this item */
+        protected _build(): void;
+        /**
+         * Returns one HTML element (.details) containing all  details of this primitive
+         */
+        getDetails(): Array<PropertyLine>;
+        update(): void;
+        /**
+         * Add an event listener on the item :
+         * - one click display details
+         * - on mouse hover the item is highlighted
+         */
+        protected _addEvent(): void;
+        /** Highlight or downplay this node */
+        highlight(b: boolean): void;
+        /** Returns true if the node is folded, false otherwise */
+        private _isFolded();
+        /** Set this item as active (background lighter) in the tree panel */
+        active(b: boolean): void;
+    }
+}

+ 168 - 0
inspector/dist/inspector/tree/TreeItem.js

@@ -0,0 +1,168 @@
+var __extends = (this && this.__extends) || function (d, b) {
+    for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
+    function __() { this.constructor = d; }
+    d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
+};
+var INSPECTOR;
+(function (INSPECTOR) {
+    var TreeItem = (function (_super) {
+        __extends(TreeItem, _super);
+        function TreeItem(tab, obj) {
+            _super.call(this);
+            this._children = [];
+            this._tab = tab;
+            this._adapter = obj;
+            this._tools = this._adapter.getTools();
+            this._build();
+        }
+        Object.defineProperty(TreeItem.prototype, "id", {
+            /** Returns the item ID == its adapter ID */
+            get: function () {
+                return this._adapter.id();
+            },
+            enumerable: true,
+            configurable: true
+        });
+        /** Add the given item as a child of this one */
+        TreeItem.prototype.add = function (child) {
+            this._children.push(child);
+            this.update();
+        };
+        /**
+         * Function used to compare this item to another tree item.
+         * Returns the alphabetical sort of the adapter ID
+         */
+        TreeItem.prototype.compareTo = function (item) {
+            var str1 = this.id;
+            var str2 = item.id;
+            return str1.localeCompare(str2, [], { numeric: true });
+        };
+        /** Returns true if the given obj correspond to the adapter linked to this tree item */
+        TreeItem.prototype.correspondsTo = function (obj) {
+            return this._adapter.correspondsTo(obj);
+        };
+        /** hide all children of this item */
+        TreeItem.prototype.fold = function () {
+            // Do nothing id no children
+            if (this._children.length > 0) {
+                for (var _i = 0, _a = this._children; _i < _a.length; _i++) {
+                    var elem = _a[_i];
+                    elem.toHtml().style.display = 'none';
+                }
+                this._div.classList.add('folded');
+                this._div.classList.remove('unfolded');
+            }
+        };
+        /** Show all children of this item */
+        TreeItem.prototype.unfold = function () {
+            // Do nothing id no children
+            if (this._children.length > 0) {
+                for (var _i = 0, _a = this._children; _i < _a.length; _i++) {
+                    var elem = _a[_i];
+                    elem.toHtml().style.display = 'block';
+                }
+                this._div.classList.add('unfolded');
+                this._div.classList.remove('folded');
+            }
+        };
+        /** Build the HTML of this item */
+        TreeItem.prototype._build = function () {
+            this._div.className = 'line';
+            for (var _i = 0, _a = this._tools; _i < _a.length; _i++) {
+                var tool = _a[_i];
+                this._div.appendChild(tool.toHtml());
+            }
+            // Id
+            var text = INSPECTOR.Inspector.DOCUMENT.createElement('span');
+            text.textContent = this._adapter.id();
+            this._div.appendChild(text);
+            // Type
+            var type = INSPECTOR.Inspector.DOCUMENT.createElement('span');
+            type.className = 'property-type';
+            type.textContent = ' - ' + this._adapter.type();
+            this._div.appendChild(type);
+            this._lineContent = INSPECTOR.Helpers.CreateDiv('line-content', this._div);
+            this._addEvent();
+        };
+        /**
+         * Returns one HTML element (.details) containing all  details of this primitive
+         */
+        TreeItem.prototype.getDetails = function () {
+            return this._adapter.getProperties();
+        };
+        TreeItem.prototype.update = function () {
+            // Clean division holding all children
+            INSPECTOR.Helpers.CleanDiv(this._lineContent);
+            for (var _i = 0, _a = this._children; _i < _a.length; _i++) {
+                var child = _a[_i];
+                var 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();
+        };
+        /**
+         * Add an event listener on the item :
+         * - one click display details
+         * - on mouse hover the item is highlighted
+         */
+        TreeItem.prototype._addEvent = function () {
+            var _this = this;
+            this._div.addEventListener('click', function (e) {
+                _this._tab.select(_this);
+                // Fold/unfold the tree
+                if (_this._isFolded()) {
+                    _this.unfold();
+                }
+                else {
+                    _this.fold();
+                }
+                e.stopPropagation();
+            });
+            // Highlight on mouse over
+            this._div.addEventListener('mouseover', function (e) {
+                _this._tab.highlightNode(_this);
+                e.stopPropagation();
+            });
+            // Remove highlight on mouse out
+            this._div.addEventListener('mouseout', function (e) {
+                _this._tab.highlightNode();
+            });
+        };
+        /** Highlight or downplay this node */
+        TreeItem.prototype.highlight = function (b) {
+            // Remove highlight for all children 
+            if (!b) {
+                for (var _i = 0, _a = this._children; _i < _a.length; _i++) {
+                    var child = _a[_i];
+                    child._adapter.highlight(b);
+                }
+            }
+            // Highlight this node
+            this._adapter.highlight(b);
+        };
+        /** Returns true if the node is folded, false otherwise */
+        TreeItem.prototype._isFolded = function () {
+            return !this._div.classList.contains('unfolded');
+        };
+        /** Set this item as active (background lighter) in the tree panel */
+        TreeItem.prototype.active = function (b) {
+            this._div.classList.remove('active');
+            for (var _i = 0, _a = this._children; _i < _a.length; _i++) {
+                var child = _a[_i];
+                child.active(false);
+            }
+            if (b) {
+                this._div.classList.add('active');
+            }
+        };
+        return TreeItem;
+    }(INSPECTOR.BasicElement));
+    INSPECTOR.TreeItem = TreeItem;
+})(INSPECTOR || (INSPECTOR = {}));
+//# sourceMappingURL=TreeItem.js.map

+ 15 - 0
inspector/dist/inspector/treetools/AbstractTreeTool.d.ts

@@ -0,0 +1,15 @@
+declare module INSPECTOR {
+    abstract class AbstractTreeTool {
+        protected _elem: HTMLElement;
+        /** Is the tool enabled ? */
+        protected _on: boolean;
+        constructor();
+        toHtml(): HTMLElement;
+        protected _addEvents(): void;
+        /**
+         * Action launched when clicked on this element
+         * Should be overrided
+         */
+        protected action(): void;
+    }
+}

+ 32 - 0
inspector/dist/inspector/treetools/AbstractTreeTool.js

@@ -0,0 +1,32 @@
+var INSPECTOR;
+(function (INSPECTOR) {
+    var AbstractTreeTool = (function () {
+        function AbstractTreeTool() {
+            /** Is the tool enabled ? */
+            this._on = false;
+            this._elem = INSPECTOR.Inspector.DOCUMENT.createElement('i');
+            this._elem.className = 'treeTool fa';
+            this._addEvents();
+        }
+        AbstractTreeTool.prototype.toHtml = function () {
+            return this._elem;
+        };
+        AbstractTreeTool.prototype._addEvents = function () {
+            var _this = this;
+            this._elem.addEventListener('click', function (e) {
+                _this.action();
+                e.stopPropagation();
+            });
+        };
+        /**
+         * Action launched when clicked on this element
+         * Should be overrided
+         */
+        AbstractTreeTool.prototype.action = function () {
+            this._on = !this._on;
+        };
+        return AbstractTreeTool;
+    }());
+    INSPECTOR.AbstractTreeTool = AbstractTreeTool;
+})(INSPECTOR || (INSPECTOR = {}));
+//# sourceMappingURL=AbstractTreeTool.js.map

+ 18 - 0
inspector/dist/inspector/treetools/BoundingBox.d.ts

@@ -0,0 +1,18 @@
+declare module INSPECTOR {
+    /** Any object implementing this interface should
+     * provide methods to toggle its bounding box
+     */
+    interface IToolBoundingBox {
+        isBoxVisible: () => boolean;
+        setBoxVisible: (b: boolean) => void;
+    }
+    /**
+     * Checkbox to display/hide the primitive
+     */
+    class BoundingBox extends AbstractTreeTool {
+        private _obj;
+        constructor(obj: IToolBoundingBox);
+        protected action(): void;
+        private _check();
+    }
+}

+ 41 - 0
inspector/dist/inspector/treetools/BoundingBox.js

@@ -0,0 +1,41 @@
+var __extends = (this && this.__extends) || function (d, b) {
+    for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
+    function __() { this.constructor = d; }
+    d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
+};
+var INSPECTOR;
+(function (INSPECTOR) {
+    /**
+     * Checkbox to display/hide the primitive
+     */
+    var BoundingBox = (function (_super) {
+        __extends(BoundingBox, _super);
+        function BoundingBox(obj) {
+            _super.call(this);
+            this._obj = obj;
+            this._elem.classList.add('fa-square-o');
+            this._on = this._obj.isBoxVisible();
+            this._check();
+        }
+        // For a checkbox, set visible/invisible the corresponding prim
+        BoundingBox.prototype.action = function () {
+            _super.prototype.action.call(this);
+            // update object and gui according to the new status
+            this._check();
+        };
+        BoundingBox.prototype._check = function () {
+            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);
+        };
+        return BoundingBox;
+    }(INSPECTOR.AbstractTreeTool));
+    INSPECTOR.BoundingBox = BoundingBox;
+})(INSPECTOR || (INSPECTOR = {}));
+//# sourceMappingURL=BoundingBox.js.map

+ 18 - 0
inspector/dist/inspector/treetools/Checkbox.d.ts

@@ -0,0 +1,18 @@
+declare module INSPECTOR {
+    /** Any object implementing this interface should
+     * provide methods to toggle its visibility
+     */
+    interface IToolVisible {
+        isVisible: () => boolean;
+        setVisible: (b: boolean) => void;
+    }
+    /**
+     * Checkbox to display/hide the primitive
+     */
+    class Checkbox extends AbstractTreeTool {
+        private _obj;
+        constructor(obj: IToolVisible);
+        protected action(): void;
+        private _check();
+    }
+}

+ 45 - 0
inspector/dist/inspector/treetools/Checkbox.js

@@ -0,0 +1,45 @@
+var __extends = (this && this.__extends) || function (d, b) {
+    for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
+    function __() { this.constructor = d; }
+    d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
+};
+var INSPECTOR;
+(function (INSPECTOR) {
+    /**
+     * Checkbox to display/hide the primitive
+     */
+    var Checkbox = (function (_super) {
+        __extends(Checkbox, _super);
+        function Checkbox(obj) {
+            _super.call(this);
+            this._obj = obj;
+            this._elem.classList.add('fa-eye');
+            this._on = this._obj.isVisible();
+            this._check();
+        }
+        // For a checkbox, set visible/invisible the corresponding prim
+        Checkbox.prototype.action = function () {
+            _super.prototype.action.call(this);
+            // update object and gui according to the new status
+            this._check();
+        };
+        Checkbox.prototype._check = function () {
+            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');
+            }
+            this._obj.setVisible(this._on);
+        };
+        return Checkbox;
+    }(INSPECTOR.AbstractTreeTool));
+    INSPECTOR.Checkbox = Checkbox;
+})(INSPECTOR || (INSPECTOR = {}));
+//# sourceMappingURL=Checkbox.js.map

+ 13 - 0
inspector/dist/inspector/treetools/DebugArea.d.ts

@@ -0,0 +1,13 @@
+declare module INSPECTOR {
+    /** Any object implementing this interface should
+     * provide methods to toggle a debug area
+     */
+    interface IToolDebug {
+        debug: (b: boolean) => void;
+    }
+    class DebugArea extends AbstractTreeTool {
+        private _obj;
+        constructor(obj: IToolDebug);
+        protected action(): void;
+    }
+}

+ 31 - 0
inspector/dist/inspector/treetools/DebugArea.js

@@ -0,0 +1,31 @@
+var __extends = (this && this.__extends) || function (d, b) {
+    for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
+    function __() { this.constructor = d; }
+    d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
+};
+var INSPECTOR;
+(function (INSPECTOR) {
+    var DebugArea = (function (_super) {
+        __extends(DebugArea, _super);
+        function DebugArea(obj) {
+            _super.call(this);
+            this._obj = obj;
+            this._elem.classList.add('fa-wrench');
+        }
+        DebugArea.prototype.action = function () {
+            _super.prototype.action.call(this);
+            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);
+        };
+        return DebugArea;
+    }(INSPECTOR.AbstractTreeTool));
+    INSPECTOR.DebugArea = DebugArea;
+})(INSPECTOR || (INSPECTOR = {}));
+//# sourceMappingURL=DebugArea.js.map

+ 17 - 0
inspector/dist/inspector/treetools/Info.d.ts

@@ -0,0 +1,17 @@
+declare module INSPECTOR {
+    /** Any object implementing this interface should
+     * provide methods to retrieve its info
+     */
+    interface IToolInfo {
+        getInfo: () => string;
+    }
+    /**
+     * Checkbox to display/hide the primitive
+     */
+    class Info extends AbstractTreeTool {
+        private _obj;
+        private _tooltip;
+        constructor(obj: IToolInfo);
+        protected action(): void;
+    }
+}

+ 27 - 0
inspector/dist/inspector/treetools/Info.js

@@ -0,0 +1,27 @@
+var __extends = (this && this.__extends) || function (d, b) {
+    for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
+    function __() { this.constructor = d; }
+    d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
+};
+var INSPECTOR;
+(function (INSPECTOR) {
+    /**
+     * Checkbox to display/hide the primitive
+     */
+    var Info = (function (_super) {
+        __extends(Info, _super);
+        function Info(obj) {
+            _super.call(this);
+            this._obj = obj;
+            this._elem.classList.add('fa-info-circle');
+            this._tooltip = new INSPECTOR.Tooltip(this._elem, this._obj.getInfo());
+        }
+        // Nothing to do on click
+        Info.prototype.action = function () {
+            _super.prototype.action.call(this);
+        };
+        return Info;
+    }(INSPECTOR.AbstractTreeTool));
+    INSPECTOR.Info = Info;
+})(INSPECTOR || (INSPECTOR = {}));
+//# sourceMappingURL=Info.js.map

Разлика између датотеке није приказан због своје велике величине
+ 15033 - 0
inspector/dist/libs/babylon.canvas2d.max.js


Разлика између датотеке није приказан због своје велике величине
+ 54626 - 0
inspector/dist/libs/babylon.max.js


Разлика између датотеке није приказан због своје велике величине
+ 1 - 0
inspector/dist/libs/main.css


+ 560 - 0
inspector/dist/libs/split.js

@@ -0,0 +1,560 @@
+// The programming goals of Split.js are to deliver readable, understandable and
+// maintainable code, while at the same time manually optimizing for tiny minified file size,
+// browser compatibility without additional requirements, graceful fallback (IE8 is supported)
+// and very few assumptions about the user's page layout.
+//
+// Make sure all browsers handle this JS library correctly with ES5.
+// More information here: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Strict_mode
+'use strict';
+
+// A wrapper function that does a couple things:
+//
+// 1. Doesn't pollute the global namespace. This is important for a library.
+// 2. Allows us to mount the library in different module systems, as well as
+//    directly in the browser.
+(function() {
+
+// Save the global `this` for use later. In this case, since the library only
+// runs in the browser, it will refer to `window`. Also, figure out if we're in IE8
+// or not. IE8 will still render correctly, but will be static instead of draggable.
+//
+// Save a couple long function names that are used frequently.
+// This optimization saves around 400 bytes.
+var global = this
+  , isIE8 = global.attachEvent && !global[addEventListener]
+  , document = global.document
+  , addEventListener = 'addEventListener'
+  , removeEventListener = 'removeEventListener'
+  , getBoundingClientRect = 'getBoundingClientRect'
+
+  // This library only needs two helper functions:
+  //
+  // The first determines which prefixes of CSS calc we need.
+  // We only need to do this once on startup, when this anonymous function is called.
+  // 
+  // Tests -webkit, -moz and -o prefixes. Modified from StackOverflow:
+  // http://stackoverflow.com/questions/16625140/js-feature-detection-to-detect-the-usage-of-webkit-calc-over-calc/16625167#16625167
+  , calc = (function () {
+        var el
+          , prefixes = ["", "-webkit-", "-moz-", "-o-"]
+
+        for (var i = 0; i < prefixes.length; i++) {
+            el = document.createElement('div')
+            el.style.cssText = "width:" + prefixes[i] + "calc(9px)"
+
+            if (el.style.length) {
+                return prefixes[i] + "calc"
+            }
+        }
+    })()
+
+  // The second helper function allows elements and string selectors to be used
+  // interchangeably. In either case an element is returned. This allows us to
+  // do `Split(elem1, elem2)` as well as `Split('#id1', '#id2')`.
+  , elementOrSelector = function (el) {
+        if (typeof el === 'string' || el instanceof String) {
+            return document.querySelector(el)
+        } else {
+            return el
+        }
+    }
+
+  // The main function to initialize a split. Split.js thinks about each pair
+  // of elements as an independant pair. Dragging the gutter between two elements
+  // only changes the dimensions of elements in that pair. This is key to understanding
+  // how the following functions operate, since each function is bound to a pair.
+  // 
+  // A pair object is shaped like this:
+  // 
+  // {
+  //     a: DOM element,
+  //     b: DOM element,
+  //     aMin: Number,
+  //     bMin: Number,
+  //     dragging: Boolean,
+  //     parent: DOM element,
+  //     isFirst: Boolean,
+  //     isLast: Boolean,
+  //     direction: 'horizontal' | 'vertical'
+  // }
+  //
+  // The basic sequence:
+  // 
+  // 1. Set defaults to something sane. `options` doesn't have to be passed at all.
+  // 2. Initialize a bunch of strings based on the direction we're splitting.
+  //    A lot of the behavior in the rest of the library is paramatized down to
+  //    rely on CSS strings and classes.
+  // 3. Define the dragging helper functions, and a few helpers to go with them.
+  // 4. Define a few more functions that "balance" the entire split instance.
+  //    Split.js tries it's best to cope with min sizes that don't add up.
+  // 5. Loop through the elements while pairing them off. Every pair gets an
+  //    `pair` object, a gutter, and special isFirst/isLast properties.
+  // 6. Actually size the pair elements, insert gutters and attach event listeners.
+  // 7. Balance all of the pairs to accomodate min sizes as best as possible.
+  , Split = function (ids, options) {
+    var dimension
+      , i
+      , clientDimension
+      , clientAxis
+      , position
+      , gutterClass
+      , paddingA
+      , paddingB
+      , pairs = []
+
+    // 1. Set defaults to something sane. `options` doesn't have to be passed at all,
+    // so create an options object if none exists. Pixel values 10, 100 and 30 are
+    // arbitrary but feel natural.
+    options = typeof options !== 'undefined' ?  options : {}
+
+    if (typeof options.gutterSize === 'undefined') options.gutterSize = 10
+    if (typeof options.minSize === 'undefined') options.minSize = 100
+    if (typeof options.snapOffset === 'undefined') options.snapOffset = 30
+    if (typeof options.direction === 'undefined') options.direction = 'horizontal'
+
+    // 2. Initialize a bunch of strings based on the direction we're splitting.
+    // A lot of the behavior in the rest of the library is paramatized down to
+    // rely on CSS strings and classes.
+    if (options.direction == 'horizontal') {
+        dimension = 'width'
+        clientDimension = 'clientWidth'
+        clientAxis = 'clientX'
+        position = 'left'
+        gutterClass = 'gutter gutter-horizontal'
+        paddingA = 'paddingLeft'
+        paddingB = 'paddingRight'
+        if (!options.cursor) options.cursor = 'ew-resize'
+    } else if (options.direction == 'vertical') {
+        dimension = 'height'
+        clientDimension = 'clientHeight'
+        clientAxis = 'clientY'
+        position = 'top'
+        gutterClass = 'gutter gutter-vertical'
+        paddingA = 'paddingTop'
+        paddingB = 'paddingBottom'
+        if (!options.cursor) options.cursor = 'ns-resize'
+    }
+
+    // 3. Define the dragging helper functions, and a few helpers to go with them.
+    // Each helper is bound to a pair object that contains it's metadata. This
+    // also makes it easy to store references to listeners that that will be
+    // added and removed.
+    // 
+    // Even though there are no other functions contained in them, aliasing
+    // this to self saves 50 bytes or so since it's used so frequently.
+    //
+    // The pair object saves metadata like dragging state, position and
+    // event listener references.
+    //
+    // startDragging calls `calculateSizes` to store the inital size in the pair object.
+    // It also adds event listeners for mouse/touch events,
+    // and prevents selection while dragging so avoid the selecting text.
+    var startDragging = function (e) {
+            // Alias frequently used variables to save space. 200 bytes.
+            var self = this
+              , a = self.a
+              , b = self.b
+
+            // Call the onDragStart callback.
+            if (!self.dragging && options.onDragStart) {
+                options.onDragStart()
+            }
+
+            // Don't actually drag the element. We emulate that in the drag function.
+            e.preventDefault()
+
+            // Set the dragging property of the pair object.
+            self.dragging = true
+
+            // Create two event listeners bound to the same pair object and store
+            // them in the pair object.
+            self.move = drag.bind(self)
+            self.stop = stopDragging.bind(self)
+
+            // All the binding. `window` gets the stop events in case we drag out of the elements.
+            global[addEventListener]('mouseup', self.stop)
+            global[addEventListener]('touchend', self.stop)
+            global[addEventListener]('touchcancel', self.stop)
+
+            self.parent[addEventListener]('mousemove', self.move)
+            self.parent[addEventListener]('touchmove', self.move)
+
+            // Disable selection. Disable!
+            a[addEventListener]('selectstart', noop)
+            a[addEventListener]('dragstart', noop)
+            b[addEventListener]('selectstart', noop)
+            b[addEventListener]('dragstart', noop)
+
+            a.style.userSelect = 'none'
+            a.style.webkitUserSelect = 'none'
+            a.style.MozUserSelect = 'none'
+            a.style.pointerEvents = 'none'
+
+            b.style.userSelect = 'none'
+            b.style.webkitUserSelect = 'none'
+            b.style.MozUserSelect = 'none'
+            b.style.pointerEvents = 'none'
+
+            // Set the cursor, both on the gutter and the parent element.
+            // Doing only a, b and gutter causes flickering.
+            self.gutter.style.cursor = options.cursor
+            self.parent.style.cursor = options.cursor
+
+            // Cache the initial sizes of the pair.
+            calculateSizes.call(self)
+        }
+
+      // stopDragging is very similar to startDragging in reverse.
+      , stopDragging = function () {
+            var self = this
+              , a = self.a
+              , b = self.b
+
+            if (self.dragging && options.onDragEnd) {
+                options.onDragEnd()
+            }
+
+            self.dragging = false
+
+            // Remove the stored event listeners. This is why we store them.
+            global[removeEventListener]('mouseup', self.stop)
+            global[removeEventListener]('touchend', self.stop)
+            global[removeEventListener]('touchcancel', self.stop)
+
+            self.parent[removeEventListener]('mousemove', self.move)
+            self.parent[removeEventListener]('touchmove', self.move)
+
+            // Delete them once they are removed. I think this makes a difference
+            // in memory usage with a lot of splits on one page. But I don't know for sure.
+            delete self.stop
+            delete self.move
+
+            a[removeEventListener]('selectstart', noop)
+            a[removeEventListener]('dragstart', noop)
+            b[removeEventListener]('selectstart', noop)
+            b[removeEventListener]('dragstart', noop)
+
+            a.style.userSelect = ''
+            a.style.webkitUserSelect = ''
+            a.style.MozUserSelect = ''
+            a.style.pointerEvents = ''
+
+            b.style.userSelect = ''
+            b.style.webkitUserSelect = ''
+            b.style.MozUserSelect = ''
+            b.style.pointerEvents = ''
+
+            self.gutter.style.cursor = ''
+            self.parent.style.cursor = ''
+        }
+
+      // drag, where all the magic happens. The logic is really quite simple:
+      // 
+      // 1. Ignore if the pair is not dragging.
+      // 2. Get the offset of the event.
+      // 3. Snap offset to min if within snappable range (within min + snapOffset).
+      // 4. Actually adjust each element in the pair to offset.
+      // 
+      // ---------------------------------------------------------------------
+      // |    | <- this.aMin               ||              this.bMin -> |    |
+      // |    |  | <- this.snapOffset      ||     this.snapOffset -> |  |    |
+      // |    |  |                         ||                        |  |    |
+      // |    |  |                         ||                        |  |    |
+      // ---------------------------------------------------------------------
+      // | <- this.start                                        this.size -> |
+      , drag = function (e) {
+            var offset
+
+            if (!this.dragging) return
+
+            // Get the offset of the event from the first side of the
+            // pair `this.start`. Supports touch events, but not multitouch, so only the first
+            // finger `touches[0]` is counted.
+            if ('touches' in e) {
+                offset = e.touches[0][clientAxis] - this.start
+            } else {
+                offset = e[clientAxis] - this.start
+            }
+
+            // If within snapOffset of min or max, set offset to min or max.
+            // snapOffset buffers aMin and bMin, so logic is opposite for both.
+            // Include the appropriate gutter sizes to prevent overflows.
+            if (offset <= this.aMin + options.snapOffset + this.aGutterSize) {
+                offset = this.aMin + this.aGutterSize
+            } else if (offset >= this.size - (this.bMin + options.snapOffset + this.bGutterSize)) {
+                offset = this.size - (this.bMin + this.bGutterSize)
+            }
+
+            // Actually adjust the size.
+            adjust.call(this, offset)
+
+            // Call the drag callback continously. Don't do anything too intensive
+            // in this callback.
+            if (options.onDrag) {
+                options.onDrag()
+            }
+        }
+
+      // Cache some important sizes when drag starts, so we don't have to do that
+      // continously:
+      // 
+      // `size`: The total size of the pair. First element + second element + first gutter + second gutter.
+      // `percentage`: The percentage between 0-100 that the pair occupies in the parent.
+      // `start`: The leading side of the first element.
+      //
+      // ------------------------------------------------ - - - - - - - - - - -
+      // |      aGutterSize -> |||                      |                     |
+      // |                     |||                      |                     |
+      // |                     |||                      |                     |
+      // |                     ||| <- bGutterSize       |                     |
+      // ------------------------------------------------ - - - - - - - - - - -
+      // | <- start                             size -> |       parentSize -> |
+      , calculateSizes = function () {
+            // Figure out the parent size minus padding.
+            var computedStyle = global.getComputedStyle(this.parent)
+              , parentSize = this.parent[clientDimension] - parseFloat(computedStyle[paddingA]) - parseFloat(computedStyle[paddingB])
+
+            this.size = this.a[getBoundingClientRect]()[dimension] + this.b[getBoundingClientRect]()[dimension] + this.aGutterSize + this.bGutterSize
+            this.percentage = Math.min(this.size / parentSize * 100, 100)
+            this.start = this.a[getBoundingClientRect]()[position]
+        }
+
+      // Actually adjust the size of elements `a` and `b` to `offset` while dragging.
+      // calc is used to allow calc(percentage + gutterpx) on the whole split instance,
+      // which allows the viewport to be resized without additional logic.
+      // Element a's size is the same as offset. b's size is total size - a size.
+      // Both sizes are calculated from the initial parent percentage, then the gutter size is subtracted.
+      , adjust = function (offset) {
+            this.a.style[dimension] = calc + '(' + (offset / this.size * this.percentage) + '% - ' + this.aGutterSize + 'px)'
+            this.b.style[dimension] = calc + '(' + (this.percentage - (offset / this.size * this.percentage)) + '% - ' + this.bGutterSize + 'px)'
+        }
+
+      // 4. Define a few more functions that "balance" the entire split instance.
+      // Split.js tries it's best to cope with min sizes that don't add up.
+      // At some point this should go away since it breaks out of the calc(% - px) model.
+      // Maybe it's a user error if you pass uncomputable minSizes.
+      , fitMin = function () {
+            var self = this
+              , a = self.a
+              , b = self.b
+
+            if (a[getBoundingClientRect]()[dimension] < self.aMin) {
+                a.style[dimension] = (self.aMin - self.aGutterSize) + 'px'
+                b.style[dimension] = (self.size - self.aMin - self.aGutterSize) + 'px'
+            } else if (b[getBoundingClientRect]()[dimension] < self.bMin) {
+                a.style[dimension] = (self.size - self.bMin - self.bGutterSize) + 'px'
+                b.style[dimension] = (self.bMin - self.bGutterSize) + 'px'
+            }
+        }
+      , fitMinReverse = function () {
+            var self = this
+              , a = self.a
+              , b = self.b
+
+            if (b[getBoundingClientRect]()[dimension] < self.bMin) {
+                a.style[dimension] = (self.size - self.bMin - self.bGutterSize) + 'px'
+                b.style[dimension] = (self.bMin - self.bGutterSize) + 'px'
+            } else if (a[getBoundingClientRect]()[dimension] < self.aMin) {
+                a.style[dimension] = (self.aMin - self.aGutterSize) + 'px'
+                b.style[dimension] = (self.size - self.aMin - self.aGutterSize) + 'px'
+            }
+        }
+      , balancePairs = function (pairs) {
+            for (var i = 0; i < pairs.length; i++) {
+                calculateSizes.call(pairs[i])
+                fitMin.call(pairs[i])
+            }
+
+            for (i = pairs.length - 1; i >= 0; i--) {
+                calculateSizes.call(pairs[i])
+                fitMinReverse.call(pairs[i])
+            }
+        }
+      , setElementSize = function (el, size, gutterSize) {
+            // Split.js allows setting sizes via numbers (ideally), or if you must,
+            // by string, like '300px'. This is less than ideal, because it breaks
+            // the fluid layout that `calc(% - px)` provides. You're on your own if you do that,
+            // make sure you calculate the gutter size by hand.
+            if (typeof size !== 'string' && !(size instanceof String)) {
+                if (!isIE8) {
+                    size = calc + '(' + size + '% - ' + gutterSize + 'px)'
+                } else {
+                    size = options.sizes[i] + '%'
+                }
+            }
+
+            el.style[dimension] = size
+        }
+
+      // No-op function to prevent default. Used to prevent selection.
+      , noop = function () { return false }
+
+      // All DOM elements in the split should have a common parent. We can grab
+      // the first elements parent and hope users read the docs because the
+      // behavior will be whacky otherwise.
+      , parent = elementOrSelector(ids[0]).parentNode
+
+    // Set default options.sizes to equal percentages of the parent element.
+    if (!options.sizes) {
+        var percent = 100 / ids.length
+
+        options.sizes = []
+
+        for (i = 0; i < ids.length; i++) {
+            options.sizes.push(percent)
+        }
+    }
+
+    // Standardize minSize to an array if it isn't already. This allows minSize
+    // to be passed as a number.
+    if (!Array.isArray(options.minSize)) {
+        var minSizes = []
+
+        for (i = 0; i < ids.length; i++) {
+            minSizes.push(options.minSize)
+        }
+
+        options.minSize = minSizes
+    }
+
+    // 5. Loop through the elements while pairing them off. Every pair gets a
+    // `pair` object, a gutter, and isFirst/isLast properties.
+    //
+    // Basic logic:
+    //
+    // - Starting with the second element `i > 0`, create `pair` objects with
+    //   `a = ids[i - 1]` and `b = ids[i]`
+    // - Set gutter sizes based on the _pair_ being first/last. The first and last
+    //   pair have gutterSize / 2, since they only have one half gutter, and not two.
+    // - Create gutter elements and add event listeners.
+    // - Set the size of the elements, minus the gutter sizes.
+    //
+    // -----------------------------------------------------------------------
+    // |     i=0     |         i=1         |        i=2       |      i=3     |
+    // |             |       isFirst       |                  |     isLast   |
+    // |           pair 0                pair 1             pair 2           |
+    // |             |                     |                  |              |
+    // -----------------------------------------------------------------------
+    for (i = 0; i < ids.length; i++) {
+        var el = elementOrSelector(ids[i])
+          , isFirstPair = (i == 1)
+          , isLastPair = (i == ids.length - 1)
+          , size = options.sizes[i]
+          , gutterSize = options.gutterSize
+          , pair
+
+        if (i > 0) {
+            // Create the pair object with it's metadata.
+            pair = {
+                a: elementOrSelector(ids[i - 1]),
+                b: el,
+                aMin: options.minSize[i - 1],
+                bMin: options.minSize[i],
+                dragging: false,
+                parent: parent,
+                isFirst: isFirstPair,
+                isLast: isLastPair,
+                direction: options.direction
+            }
+
+            // For first and last pairs, first and last gutter width is half.
+            pair.aGutterSize = options.gutterSize
+            pair.bGutterSize = options.gutterSize
+
+            if (isFirstPair) {
+                pair.aGutterSize = options.gutterSize / 2
+            }
+
+            if (isLastPair) {
+                pair.bGutterSize = options.gutterSize / 2
+            }
+        }
+
+        // Determine the size of the current element. IE8 is supported by
+        // staticly assigning sizes without draggable gutters. Assigns a string
+        // to `size`.
+        // 
+        // IE9 and above
+        if (!isIE8) {
+            // Create gutter elements for each pair.
+            if (i > 0) {
+                var gutter = document.createElement('div')
+
+                gutter.className = gutterClass
+                gutter.style[dimension] = options.gutterSize + 'px'
+
+                gutter[addEventListener]('mousedown', startDragging.bind(pair))
+                gutter[addEventListener]('touchstart', startDragging.bind(pair))
+
+                parent.insertBefore(gutter, el)
+
+                pair.gutter = gutter
+            }
+
+            // Half-size gutters for first and last elements.
+            if (i === 0 || i == ids.length - 1) {
+                gutterSize = options.gutterSize / 2
+            }
+        }
+
+        // Set the element size to our determined size.
+        setElementSize(el, size, gutterSize)
+
+        // After the first iteration, and we have a pair object, append it to the
+        // list of pairs.
+        if (i > 0) {
+            pairs.push(pair)
+        }
+    }
+
+    // Balance the pairs to try to accomodate min sizes.
+    //balancePairs(pairs)
+
+    return {
+        setSizes: function (sizes) {
+            for (var i = 0; i < sizes.length; i++) {
+                if (i > 0) {
+                    var pair = pairs[i - 1]
+
+                    setElementSize(pair.a, sizes[i - 1], pair.aGutterSize)
+                    setElementSize(pair.b, sizes[i], pair.bGutterSize)
+                }
+            }
+        },
+        collapse: function (i) {
+            var pair
+
+            if (i === pairs.length) {
+                pair = pairs[i - 1]
+
+                calculateSizes.call(pair)
+                adjust.call(pair, pair.size - pair.bGutterSize)
+            } else {
+                pair = pairs[i]
+
+                calculateSizes.call(pair)
+                adjust.call(pair, pair.aGutterSize)
+            }
+        },
+        destroy: function () {
+            for (var i = 0; i < pairs.length; i++) {
+                pairs[i].parent.removeChild(pairs[i].gutter)
+                pairs[i].a.style[dimension] = ''
+                pairs[i].b.style[dimension] = ''
+            }
+        }
+    }
+}
+
+// Play nicely with module systems, and the browser too if you include it raw.
+if (typeof exports !== 'undefined') {
+    if (typeof module !== 'undefined' && module.exports) {
+        exports = module.exports = Split
+    }
+    exports.Split = Split
+} else {
+    global.Split = Split
+}
+
+// Call our wrapper function with the current global. In this case, `window`.
+}).call(window);

+ 12 - 0
inspector/dist/test/Test.d.ts

@@ -0,0 +1,12 @@
+declare class Test {
+    private engine;
+    scene: BABYLON.Scene;
+    constructor(canvasId: string);
+    private _run();
+    private _initScene();
+    private _initGame();
+    /**
+     * Create the canvas2D
+     */
+    private _createCanvas();
+}

+ 133 - 0
inspector/dist/test/Test.js

@@ -0,0 +1,133 @@
+var Test = (function () {
+    function Test(canvasId) {
+        var _this = this;
+        var canvas = document.getElementById(canvasId);
+        this.engine = new BABYLON.Engine(canvas, true);
+        this.scene = null;
+        window.addEventListener("resize", function () {
+            _this.engine.resize();
+        });
+        this._run();
+    }
+    Test.prototype._run = function () {
+        var _this = this;
+        this._initScene();
+        // new INSPECTOR.Inspector(this.scene); 
+        BABYLON.DebugLayer.InspectorURL = 'http://localhost:3000/dist/libs/inspector.js';
+        this.scene.debugLayer.show();
+        this.scene.executeWhenReady(function () {
+            _this._initGame();
+            _this.engine.runRenderLoop(function () {
+                _this.scene.render();
+            });
+        });
+    };
+    Test.prototype._initScene = function () {
+        var scene = new BABYLON.Scene(this.engine);
+        var camera = new BABYLON.ArcRotateCamera("Camera", -Math.PI / 4, Math.PI / 2.5, 200, BABYLON.Vector3.Zero(), scene);
+        camera.attachControl(this.engine.getRenderingCanvas(), true);
+        camera.minZ = 0.1;
+        // Lights
+        var light0 = new BABYLON.PointLight("Omni0", new BABYLON.Vector3(0, 10, 0), scene);
+        var light1 = new BABYLON.PointLight("Omni1", new BABYLON.Vector3(0, -10, 0), scene);
+        var light2 = new BABYLON.PointLight("Omni2", new BABYLON.Vector3(10, 0, 0), scene);
+        var light3 = new BABYLON.DirectionalLight("Dir0", new BABYLON.Vector3(1, -1, 0), scene);
+        var material = new BABYLON.StandardMaterial("kosh", scene);
+        var sphere = BABYLON.Mesh.CreateSphere("Sphere", 16, 3, scene);
+        // Creating light sphere
+        var lightSphere0 = BABYLON.Mesh.CreateSphere("Sphere0", 16, 0.5, scene);
+        var lightSphere1 = BABYLON.Mesh.CreateSphere("Sphere1", 16, 0.5, scene);
+        var lightSphere2 = BABYLON.Mesh.CreateSphere("Sphere2", 16, 0.5, scene);
+        lightSphere0.material = new BABYLON.StandardMaterial("red", scene);
+        lightSphere0.material.diffuseColor = new BABYLON.Color3(0, 0, 0);
+        lightSphere0.material.specularColor = new BABYLON.Color3(0, 0, 0);
+        lightSphere0.material.emissiveColor = new BABYLON.Color3(1, 0, 0);
+        lightSphere1.material = new BABYLON.StandardMaterial("green", scene);
+        lightSphere1.material.diffuseColor = new BABYLON.Color3(0, 0, 0);
+        lightSphere1.material.specularColor = new BABYLON.Color3(0, 0, 0);
+        lightSphere1.material.emissiveColor = new BABYLON.Color3(0, 1, 0);
+        lightSphere2.material = new BABYLON.StandardMaterial("blue", scene);
+        lightSphere2.material.diffuseColor = new BABYLON.Color3(0, 0, 0);
+        lightSphere2.material.specularColor = new BABYLON.Color3(0, 0, 0);
+        lightSphere2.material.emissiveColor = new BABYLON.Color3(0, 0, 1);
+        // Sphere material
+        material.diffuseColor = new BABYLON.Color3(1, 1, 1);
+        sphere.material = material;
+        // Lights colors
+        light0.diffuse = new BABYLON.Color3(1, 0, 0);
+        light0.specular = new BABYLON.Color3(1, 0, 0);
+        light1.diffuse = new BABYLON.Color3(0, 1, 0);
+        light1.specular = new BABYLON.Color3(0, 1, 0);
+        light2.diffuse = new BABYLON.Color3(0, 0, 1);
+        light2.specular = new BABYLON.Color3(0, 0, 1);
+        light3.diffuse = new BABYLON.Color3(1, 1, 1);
+        light3.specular = new BABYLON.Color3(1, 1, 1);
+        BABYLON.Effect.ShadersStore["customVertexShader"] = 'precision highp float;attribute vec3 position;attribute vec2 uv;uniform mat4 worldViewProjection;varying vec2 vUV;varying vec3 vPos;void main(){gl_Position=worldViewProjection*vec4(position,1.),vPos=gl_Position.xyz;if(position.x >2.0) {gl_Position.x = 2.0;} else { gl_Position.y = 1.0;}}';
+        BABYLON.Effect.ShadersStore["customFragmentShader"] = 'precision highp float;varying vec3 vPos;uniform vec3 color;void main(){gl_FragColor=vec4(mix(color,vPos,.05),1.);}';
+        var shaderMaterial = new BABYLON.ShaderMaterial("shader", scene, {
+            vertex: "custom",
+            fragment: "custom",
+        }, {
+            attributes: ["position", "normal", "uv"],
+            uniforms: ["world", "worldView", "worldViewProjection", "view", "projection"]
+        });
+        sphere.material = shaderMaterial;
+        // Animations
+        var alpha = 0;
+        scene.beforeRender = function () {
+            light0.position = new BABYLON.Vector3(10 * Math.sin(alpha), 0, 10 * Math.cos(alpha));
+            light1.position = new BABYLON.Vector3(10 * Math.sin(alpha), 0, -10 * Math.cos(alpha));
+            light2.position = new BABYLON.Vector3(10 * Math.cos(alpha), 0, 10 * Math.sin(alpha));
+            lightSphere0.position = light0.position;
+            lightSphere1.position = light1.position;
+            lightSphere2.position = light2.position;
+            alpha += 0.01;
+        };
+        this.scene = scene;
+    };
+    Test.prototype._initGame = function () {
+        this._createCanvas();
+    };
+    /**
+     * Create the canvas2D
+     */
+    Test.prototype._createCanvas = function () {
+        var canvas = new BABYLON.ScreenSpaceCanvas2D(this.scene, {
+            id: "Hello world SC",
+            size: new BABYLON.Size(300, 100),
+            backgroundFill: "#4040408F",
+            backgroundRoundRadius: 50,
+            children: [
+                new BABYLON.Text2D("Hello World!", {
+                    id: "text",
+                    marginAlignment: "h: center, v:center",
+                    fontName: "20pt Arial",
+                })
+            ]
+        });
+        var infoCanvas = new BABYLON.ScreenSpaceCanvas2D(this.scene, { id: "PINK CUBE SC", size: new BABYLON.Size(500, 500) });
+        var text2 = new BABYLON.Text2D("UnbindTime", { parent: infoCanvas, id: "Text", marginAlignment: "h: left, v: bottom", fontName: "10pt Arial" });
+        canvas = new BABYLON.WorldSpaceCanvas2D(this.scene, new BABYLON.Size(150, 150), {
+            id: "WorldSpaceCanvas",
+            worldPosition: new BABYLON.Vector3(0, 0, 0),
+            worldRotation: BABYLON.Quaternion.RotationYawPitchRoll(Math.PI / 4, Math.PI / 4, 0),
+            enableInteraction: true,
+            backgroundFill: "#C0C0C040",
+            backgroundRoundRadius: 20,
+            children: [
+                new BABYLON.Text2D("World Space Canvas", { fontName: "8pt Arial", marginAlignment: "h: center, v: bottom", fontSuperSample: true })
+            ]
+        });
+        var rect = new BABYLON.Rectangle2D({ parent: canvas, x: 45, y: 45, width: 30, height: 30, fill: null, border: BABYLON.Canvas2D.GetGradientColorBrush(new BABYLON.Color4(0.9, 0.3, 0.9, 1), new BABYLON.Color4(1.0, 1.0, 1.0, 1)), borderThickness: 2 });
+        var buttonRect = new BABYLON.Rectangle2D({ parent: canvas, id: "button", x: 12, y: 12, width: 50, height: 15, fill: "#40C040FF", roundRadius: 2, children: [new BABYLON.Text2D("Click Me!", { fontName: "8pt Arial", marginAlignment: "h: center, v: center", fontSuperSample: true })] });
+        var button2Rect = new BABYLON.Rectangle2D({ parent: canvas, id: "button2", x: 70, y: 12, width: 40, height: 15, fill: "#4040C0FF", roundRadius: 2, isVisible: false, children: [new BABYLON.Text2D("Great!", { fontName: "8pt Arial", marginAlignment: "h: center, v: center", fontSuperSample: true })] });
+        ;
+        buttonRect.pointerEventObservable.add(function (d, s) {
+            button2Rect.levelVisible = !button2Rect.levelVisible;
+        }, BABYLON.PrimitivePointerInfo.PointerUp);
+        var insideRect = new BABYLON.Rectangle2D({ parent: rect, width: 10, height: 10, marginAlignment: "h: center, v: center", fill: "#0040F0FF" });
+        insideRect.roundRadius = 2;
+    };
+    return Test;
+}());
+//# sourceMappingURL=Test.js.map

BIN
inspector/dist/test/assets/albedo.png


BIN
inspector/dist/test/assets/reflectivity.png


BIN
inspector/dist/test/assets/room.hdr


BIN
inspector/dist/test/assets/skybox/snow_nx.jpg


BIN
inspector/dist/test/assets/skybox/snow_ny.jpg


BIN
inspector/dist/test/assets/skybox/snow_nz.jpg


BIN
inspector/dist/test/assets/skybox/snow_px.jpg


BIN
inspector/dist/test/assets/skybox/snow_py.jpg


+ 0 - 0
inspector/dist/test/assets/skybox/snow_pz.jpg


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