Pārlūkot izejas kodu

Merge New Inspector

sebastien 6 gadi atpakaļ
vecāks
revīzija
98c2594bef
100 mainītis faili ar 68882 papildinājumiem un 27312 dzēšanām
  1. 4 0
      .gitignore
  2. 13217 10412
      Playground/babylon.d.txt
  3. 3 2
      Playground/css/index.css
  4. 370 370
      Playground/index-local.html
  5. 7 30
      Playground/js/index.js
  6. 3 587
      Playground/js/libs/split.js
  7. 6 4
      Tools/DevLoader/BabylonLoader.js
  8. 8 8
      Tools/Gulp/config.json
  9. 10323 10292
      dist/preview release/babylon.d.ts
  10. 1 1
      dist/preview release/babylon.js
  11. 70 86
      dist/preview release/babylon.max.js
  12. 70 86
      dist/preview release/babylon.no-module.max.js
  13. 1 1
      dist/preview release/babylon.worker.js
  14. 70 86
      dist/preview release/es6.js
  15. 61 1
      dist/preview release/gui/babylon.gui.d.ts
  16. 1 1
      dist/preview release/gui/babylon.gui.js
  17. 1 1
      dist/preview release/gui/babylon.gui.min.js
  18. 1 1
      dist/preview release/gui/babylon.gui.min.js.map
  19. 122 2
      dist/preview release/gui/babylon.gui.module.d.ts
  20. 36120 1
      dist/preview release/inspector/babylon.inspector.bundle.js
  21. 1 1
      dist/preview release/inspector/babylon.inspector.bundle.js.map
  22. 12 967
      dist/preview release/inspector/babylon.inspector.d.ts
  23. 30 2342
      dist/preview release/inspector/babylon.inspector.module.d.ts
  24. 1 1
      dist/preview release/inspector/readme.md
  25. 253 0
      dist/preview release/materialsLibrary/babylon.gridMaterial.js
  26. 1 0
      dist/preview release/materialsLibrary/babylon.gridMaterial.min.js
  27. 5061 0
      dist/preview release/materialsLibrary/babylonjs.materials.js
  28. 1 0
      dist/preview release/materialsLibrary/babylonjs.materials.min.js
  29. 1 1
      dist/preview release/viewer/babylon.viewer.js
  30. 1 1
      dist/preview release/viewer/babylon.viewer.max.js
  31. 1 0
      dist/preview release/what's new.md
  32. 40 0
      gui/src/2D/advancedDynamicTexture.ts
  33. 22 10
      gui/src/2D/controls/colorpicker.ts
  34. 21 0
      gui/src/2D/controls/container.ts
  35. 70 1
      gui/src/2D/controls/control.ts
  36. 59 11
      gui/src/2D/controls/grid.ts
  37. 25 23
      gui/src/2D/controls/inputText.ts
  38. 8 0
      gui/src/3D/controls/control3D.ts
  39. 1 3
      gui/webpack.config.js
  40. 5 4
      inspector/index.html
  41. 3 9
      inspector/legacy/legacy.ts
  42. 0 156
      inspector/sass/_detailPanel.scss
  43. 0 18
      inspector/sass/_resizeBar.scss
  44. 0 19
      inspector/sass/_searchbar.scss
  45. 0 74
      inspector/sass/_slider.scss
  46. 0 92
      inspector/sass/_tabPanel.scss
  47. 0 60
      inspector/sass/_tabbar.scss
  48. 0 31
      inspector/sass/_toolbar.scss
  49. 0 14
      inspector/sass/_tooltip.scss
  50. 0 73
      inspector/sass/_tree.scss
  51. 0 16
      inspector/sass/_treeTool.scss
  52. 0 28
      inspector/sass/defines.scss
  53. 0 105
      inspector/sass/main.scss
  54. 0 51
      inspector/sass/tabs/_consoleTab.scss
  55. 0 92
      inspector/sass/tabs/_gltfTab.scss
  56. 0 53
      inspector/sass/tabs/_shaderTab.scss
  57. 0 52
      inspector/sass/tabs/_statsTab.scss
  58. 0 80
      inspector/sass/tabs/_toolsTab.scss
  59. BIN
      inspector/screens/tab_mesh.jpg
  60. BIN
      inspector/screens/tools.jpg
  61. 0 441
      inspector/src/Inspector.ts
  62. 0 43
      inspector/src/adapters/Adapter.ts
  63. 0 56
      inspector/src/adapters/CameraAdapter.ts
  64. 0 48
      inspector/src/adapters/GUIAdapter.ts
  65. 0 51
      inspector/src/adapters/LightAdapter.ts
  66. 0 37
      inspector/src/adapters/MaterialAdapter.ts
  67. 0 116
      inspector/src/adapters/MeshAdapter.ts
  68. 0 59
      inspector/src/adapters/PhysicsImpostorAdapter.ts
  69. 0 52
      inspector/src/adapters/SoundAdapter.ts
  70. 0 40
      inspector/src/adapters/TextureAdapter.ts
  71. 0 9
      inspector/src/adapters/index.ts
  72. 753 0
      inspector/src/components/actionTabs/actionTabs.scss
  73. 133 0
      inspector/src/components/actionTabs/actionTabsComponent.tsx
  74. 59 0
      inspector/src/components/actionTabs/lineContainerComponent.tsx
  75. 31 0
      inspector/src/components/actionTabs/lines/booleanLineComponent.tsx
  76. 21 0
      inspector/src/components/actionTabs/lines/buttonLineComponent.tsx
  77. 79 0
      inspector/src/components/actionTabs/lines/checkBoxLineComponent.tsx
  78. 61 0
      inspector/src/components/actionTabs/lines/color3LineComponent.tsx
  79. 30 0
      inspector/src/components/actionTabs/lines/fileButtonLineComponent.tsx
  80. 87 0
      inspector/src/components/actionTabs/lines/floatLineComponent.tsx
  81. 22 0
      inspector/src/components/actionTabs/lines/messageLineComponent.tsx
  82. 63 0
      inspector/src/components/actionTabs/lines/numericInputComponent.tsx
  83. 96 0
      inspector/src/components/actionTabs/lines/optionsLineComponent.tsx
  84. 113 0
      inspector/src/components/actionTabs/lines/quaternionLineComponent.tsx
  85. 50 0
      inspector/src/components/actionTabs/lines/radioLineComponent.tsx
  86. 64 0
      inspector/src/components/actionTabs/lines/sliderLineComponent.tsx
  87. 69 0
      inspector/src/components/actionTabs/lines/textInputLineComponent.tsx
  88. 48 0
      inspector/src/components/actionTabs/lines/textLineComponent.tsx
  89. 177 0
      inspector/src/components/actionTabs/lines/textureLineComponent.tsx
  90. 135 0
      inspector/src/components/actionTabs/lines/textureLinkLineComponent.tsx
  91. 31 0
      inspector/src/components/actionTabs/lines/valueLineComponent.tsx
  92. 110 0
      inspector/src/components/actionTabs/lines/vector3LineComponent.tsx
  93. 27 0
      inspector/src/components/actionTabs/paneComponent.tsx
  94. 116 0
      inspector/src/components/actionTabs/tabs/debugTabComponent.tsx
  95. 144 0
      inspector/src/components/actionTabs/tabs/propertyGridTabComponent.tsx
  96. 70 0
      inspector/src/components/actionTabs/tabs/propertyGrids/cameras/arcRotateCameraPropertyGridComponent.tsx
  97. 63 0
      inspector/src/components/actionTabs/tabs/propertyGrids/cameras/commonCameraPropertyGridComponent.tsx
  98. 52 0
      inspector/src/components/actionTabs/tabs/propertyGrids/cameras/freeCameraPropertyGridComponent.tsx
  99. 102 0
      inspector/src/components/actionTabs/tabs/propertyGrids/cameras/propertyGridTabComponent.tsx
  100. 0 0
      inspector/src/components/actionTabs/tabs/propertyGrids/fogPropertyGridComponent.tsx

+ 4 - 0
.gitignore

@@ -191,3 +191,7 @@ Viewer/tests/Lib/**/*.js
 Viewer/tests/commons/**/*.js
 .sass-cache/
 gui/dist/
+/Viewer/tests/tsc
+/Viewer/tests/tsc.cmd
+/Viewer/tests/tsserver
+/Viewer/tests/tsserver.cmd

Failā izmaiņas netiks attēlotas, jo tās ir par lielu
+ 13217 - 10412
Playground/babylon.d.txt


+ 3 - 2
Playground/css/index.css

@@ -246,6 +246,8 @@ body {
     width: 100%;
     height: 100%;
     touch-action: none;
+    display: block;
+    font-size: 0;
 }
 #fpsLabel {
     position: absolute;
@@ -472,7 +474,6 @@ body {
     padding:20px;
     border-radius: 5px;
     color:white;
-    font-family: 'Inconsolata';
 }
 #errorZone button {
     position:absolute;
@@ -508,7 +509,7 @@ body {
 .navbarBottom #statusBar {
     line-height:30px;
     color: #E74C3C;
-    font-family: 'Inconsolata';
+    font-size: 14px;
     padding-left:20px;
 }
 

+ 370 - 370
Playground/index-local.html

@@ -1,455 +1,455 @@
 <!DOCTYPE html>
 <html>
 
-    <head>
-        <title>Babylon.js Playground</title>
-        <meta charset='utf-8' />
-        <meta name="viewport" content="width=device-width, user-scalable=no">
-        <script src="https://code.jquery.com/pep/0.4.2/pep.min.js"></script>
-        <!--For canvas/code separator-->
-        <script src="js/libs/split.js"></script>
-
-        <script src="https://cdnjs.cloudflare.com/ajax/libs/dat-gui/0.6.2/dat.gui.min.js"></script>
-        <!-- jszip -->
-        <script src="js/libs/jszip.min.js"></script>
-        <script src="js/libs/fileSaver.js"></script>
-        <!-- Dependencies -->
-        <script src="../dist/preview%20release/cannon.js"></script>
-        <script src="../dist/preview%20release/Oimo.js"></script>
-        <script src="../dist/preview%20release/gltf_validator.js"></script>
-        <script src="../dist/preview%20release/earcut.min.js"></script>
-        <!-- Monaco -->
-
-        <!-- Babylon.js -->
-        <script src="../tools/DevLoader/BabylonLoader.js"></script>
-
-        <link href="css/index.css" rel="stylesheet" />
-    </head>
-
-    <body>
-        <div class="navbar navBar1600">
-            <div class="title">
-                Babylon.js Playground
-            </div>
-            <div class="version" id="mainTitle">
-            </div>
+<head>
+    <title>Babylon.js Playground</title>
+    <meta charset='utf-8' />
+    <meta name="viewport" content="width=device-width, user-scalable=no">
+    <script src="https://code.jquery.com/pep/0.4.2/pep.min.js"></script>
+    <!--For canvas/code separator-->
+    <script src="js/libs/split.js"></script>
+
+    <script src="https://cdnjs.cloudflare.com/ajax/libs/dat-gui/0.6.2/dat.gui.min.js"></script>
+    <!-- jszip -->
+    <script src="js/libs/jszip.min.js"></script>
+    <script src="js/libs/fileSaver.js"></script>
+    <!-- Dependencies -->
+    <script src="../dist/preview%20release/cannon.js"></script>
+    <script src="../dist/preview%20release/Oimo.js"></script>
+    <script src="../dist/preview%20release/gltf_validator.js"></script>
+    <script src="../dist/preview%20release/earcut.min.js"></script>
+    <!-- Monaco -->
+
+    <!-- Babylon.js -->
+    <script src="../tools/DevLoader/BabylonLoader.js"></script>
+
+    <link href="css/index.css" rel="stylesheet" />
+</head>
+
+<body>
+    <div class="navbar navBar1600">
+        <div class="title">
+            Babylon.js Playground
+        </div>
+        <div class="version" id="mainTitle">
+        </div>
 
-            <div class="category">
-                <div class="button run" id="runButton1600">Run
-                    <i class="fa fa-play" aria-hidden="true"></i>
-                </div>
+        <div class="category">
+            <div class="button run" id="runButton1600">Run
+                <i class="fa fa-play" aria-hidden="true"></i>
             </div>
+        </div>
 
 
-            <div class="category">
-                <div class="button" id="newButton1600">New
-                    <i class="fa fa-file" aria-hidden="true"></i>
-                </div>
-                <div class="button removeOnPhone" id="clearButton1600">Clear
-                    <i class="fa fa-trash" aria-hidden="true"></i>
-                </div>
+        <div class="category">
+            <div class="button" id="newButton1600">New
+                <i class="fa fa-file" aria-hidden="true"></i>
+            </div>
+            <div class="button removeOnPhone" id="clearButton1600">Clear
+                <i class="fa fa-trash" aria-hidden="true"></i>
             </div>
+        </div>
 
-            <div class="category">
-                <div class="button" id="saveButton1600">Save
-                    <i class="fa fa-floppy-o" aria-hidden="true"></i>
-                </div>
-                <div class="button removeOnPhone" id="zipButton1600">Zip
-                    <i class="fa fa-download" aria-hidden="true"></i>
-                </div>
+        <div class="category">
+            <div class="button" id="saveButton1600">Save
+                <i class="fa fa-floppy-o" aria-hidden="true"></i>
+            </div>
+            <div class="button removeOnPhone" id="zipButton1600">Zip
+                <i class="fa fa-download" aria-hidden="true"></i>
             </div>
+        </div>
 
-            <div class="category">
-                <div class="button select">Settings
-                    <div class="toDisplay">
-                        <div class="option subSelect">Theme
-                            <i class="fa fa-chevron-right" aria-hidden="true"></i>
-                            <div class="toDisplaySub">
-                                <div class="option" id="darkTheme1600">Dark</div>
-                                <div class="option" id="lightTheme1600">Light</div>
-                            </div>
+        <div class="category">
+            <div class="button select">Settings
+                <div class="toDisplay">
+                    <div class="option subSelect">Theme
+                        <i class="fa fa-chevron-right" aria-hidden="true"></i>
+                        <div class="toDisplaySub">
+                            <div class="option" id="darkTheme1600">Dark</div>
+                            <div class="option" id="lightTheme1600">Light</div>
                         </div>
-                        <div class="option subSelect">
-                            <span id="currentFontSize1600">Font: 14</span>
-                            <i class="fa fa-chevron-right" aria-hidden="true"></i>
-                            <div class="toDisplaySub">
-                                <div class="option" onclick="setFontSize(12);">12</div>
-                                <div class="option" onclick="setFontSize(14);">14</div>
-                                <div class="option" onclick="setFontSize(16);">16</div>
-                                <div class="option" onclick="setFontSize(18);">18</div>
-                                <div class="option" onclick="setFontSize(20);">20</div>
-                                <div class="option" onclick="setFontSize(22);">22</div>
-                            </div>
-                        </div>
-                        <div class="option" id="safemodeToggle1600">Safe mode
-                            <i class="far fa-square" aria-hidden="true"></i>
-                        </div>
-                        <div class="option checked" id="editorButton1600">Editor
-                            <i class="fa fa-check-square" aria-hidden="true"></i>
-                        </div>
-                        <div class="option" id="fullscreenButton1600">Fullscreen</div>
-                        <div class="option" id="editorFullscreenButton1600">Editor Fullscreen</div>
-                        <div class="option" id="formatButton1600">Format code</div>
-                        <div class="option" id="minimapToggle1600">Minimap
-                            <i class="far fa-square" aria-hidden="true"></i>
+                    </div>
+                    <div class="option subSelect">
+                        <span id="currentFontSize1600">Font: 14</span>
+                        <i class="fa fa-chevron-right" aria-hidden="true"></i>
+                        <div class="toDisplaySub">
+                            <div class="option" onclick="setFontSize(12);">12</div>
+                            <div class="option" onclick="setFontSize(14);">14</div>
+                            <div class="option" onclick="setFontSize(16);">16</div>
+                            <div class="option" onclick="setFontSize(18);">18</div>
+                            <div class="option" onclick="setFontSize(20);">20</div>
+                            <div class="option" onclick="setFontSize(22);">22</div>
                         </div>
                     </div>
+                    <div class="option" id="safemodeToggle1600">Safe mode
+                        <i class="far fa-square" aria-hidden="true"></i>
+                    </div>
+                    <div class="option checked" id="editorButton1600">Editor
+                        <i class="fa fa-check-square" aria-hidden="true"></i>
+                    </div>
+                    <div class="option" id="fullscreenButton1600">Fullscreen</div>
+                    <div class="option" id="editorFullscreenButton1600">Editor Fullscreen</div>
+                    <div class="option" id="formatButton1600">Format code</div>
+                    <div class="option" id="minimapToggle1600">Minimap
+                        <i class="far fa-square" aria-hidden="true"></i>
+                    </div>
                 </div>
-
-                <div class="button uncheck" id="debugButton1600">Inspector</div>
-                <div class="button" id="metadataButton1600">Metadata</div>
             </div>
 
+            <div class="button uncheck" id="debugButton1600">Inspector</div>
+            <div class="button" id="metadataButton1600">Metadata</div>
+        </div>
 
 
-            <div class="category right">
-                <div class="button select">
-                    <span id="currentVersion1600">Version: Latest</span>
-                    <div class="toDisplay">
-                        <div class="option" onclick="setVersion('latest');">Latest</div>
-                        <div class="option" onclick="setVersion('2.5');">2.5</div>
-                    </div>
-                </div>
-                <div class="button select">
-                    <span class="examplesButton">Examples</span>
+
+        <div class="category right">
+            <div class="button select">
+                <span id="currentVersion1600">Version: Latest</span>
+                <div class="toDisplay">
+                    <div class="option" onclick="setVersion('latest');">Latest</div>
+                    <div class="option" onclick="setVersion('2.5');">2.5</div>
                 </div>
             </div>
+            <div class="button select">
+                <span class="examplesButton">Examples</span>
+            </div>
         </div>
+    </div>
 
-        <div class="navbar navBar1475">
-            <div class="title">
-                Babylon.js Playground
-            </div>
-            <div class="version" id="mainTitle">
-            </div>
+    <div class="navbar navBar1475">
+        <div class="title">
+            Babylon.js Playground
+        </div>
+        <div class="version" id="mainTitle">
+        </div>
 
-            <div class="category">
-                <div class="button run" id="runButton1475">Run
-                    <i class="fa fa-play" aria-hidden="true"></i>
-                </div>
+        <div class="category">
+            <div class="button run" id="runButton1475">Run
+                <i class="fa fa-play" aria-hidden="true"></i>
             </div>
+        </div>
 
 
-            <div class="category">
-                <div class="button" id="newButton1475">New
-                    <i class="fa fa-file" aria-hidden="true"></i>
-                </div>
-                <div class="button removeOnPhone" id="clearButton1475">Clear
-                    <i class="fa fa-trash" aria-hidden="true"></i>
-                </div>
+        <div class="category">
+            <div class="button" id="newButton1475">New
+                <i class="fa fa-file" aria-hidden="true"></i>
+            </div>
+            <div class="button removeOnPhone" id="clearButton1475">Clear
+                <i class="fa fa-trash" aria-hidden="true"></i>
             </div>
+        </div>
 
-            <div class="category">
-                <div class="button" id="saveButton1475">Save
-                    <i class="fa fa-floppy-o" aria-hidden="true"></i>
-                </div>
-                <div class="button removeOnPhone" id="zipButton1475">Zip
-                    <i class="fa fa-download" aria-hidden="true"></i>
-                </div>
+        <div class="category">
+            <div class="button" id="saveButton1475">Save
+                <i class="fa fa-floppy-o" aria-hidden="true"></i>
+            </div>
+            <div class="button removeOnPhone" id="zipButton1475">Zip
+                <i class="fa fa-download" aria-hidden="true"></i>
             </div>
+        </div>
 
-            <div class="category">
-                <div class="button select">Settings
-                    <div class="toDisplay">
-                        <div class="option subSelect">Theme
-                            <i class="fa fa-chevron-right" aria-hidden="true"></i>
-                            <div class="toDisplaySub">
-                                <div class="option" id="darkTheme1475">Dark</div>
-                                <div class="option" id="lightTheme1475">Light</div>
-                            </div>
+        <div class="category">
+            <div class="button select">Settings
+                <div class="toDisplay">
+                    <div class="option subSelect">Theme
+                        <i class="fa fa-chevron-right" aria-hidden="true"></i>
+                        <div class="toDisplaySub">
+                            <div class="option" id="darkTheme1475">Dark</div>
+                            <div class="option" id="lightTheme1475">Light</div>
                         </div>
-                        <div class="option subSelect">
-                            <span id="currentFontSize1475">Font: 14</span>
-                            <i class="fa fa-chevron-right" aria-hidden="true"></i>
-                            <div class="toDisplaySub">
-                                <div class="option" onclick="setFontSize(12);">12</div>
-                                <div class="option" onclick="setFontSize(14);">14</div>
-                                <div class="option" onclick="setFontSize(16);">16</div>
-                                <div class="option" onclick="setFontSize(18);">18</div>
-                                <div class="option" onclick="setFontSize(20);">20</div>
-                                <div class="option" onclick="setFontSize(22);">22</div>
-                            </div>
-                        </div>
-                        <div class="option" id='safemodeToggle1475'>Safe mode
-                            <i class="far fa-square" aria-hidden="true"></i>
-                        </div>
-                        <div class="option checked" id="editorButton1475">Editor
-                            <i class="fa fa-check-square" aria-hidden="true"></i>
-                        </div>
-                        <div class="option" id="fullscreenButton1475">Fullscreen</div>
-                        <div class="option" id="editorFullscreenButton1475">Editor Fullscreen</div>
-                        <div class="option" id="formatButton1475">Format code</div>
-                        <div class="option" id="minimapToggle1475">Minimap
-                            <i class="far fa-square" aria-hidden="true"></i>
+                    </div>
+                    <div class="option subSelect">
+                        <span id="currentFontSize1475">Font: 14</span>
+                        <i class="fa fa-chevron-right" aria-hidden="true"></i>
+                        <div class="toDisplaySub">
+                            <div class="option" onclick="setFontSize(12);">12</div>
+                            <div class="option" onclick="setFontSize(14);">14</div>
+                            <div class="option" onclick="setFontSize(16);">16</div>
+                            <div class="option" onclick="setFontSize(18);">18</div>
+                            <div class="option" onclick="setFontSize(20);">20</div>
+                            <div class="option" onclick="setFontSize(22);">22</div>
                         </div>
-                        <div class="option" id="debugButton1475">Inspector</div>
-                        <div class="option" id="metadataButton1475">Metadata</div>
-                        <div class="option subSelect">
-                            <span id="currentVersion1475">Vers. : Latest</span>
-                            <i class="fa fa-chevron-right" aria-hidden="true"></i>
-                            <div class="toDisplaySub">
-                                <div class="option" onclick="setVersion('latest');">Latest</div>
-                                <div class="option" onclick="setVersion('2.5');">2.5</div>
-                            </div>
+                    </div>
+                    <div class="option" id='safemodeToggle1475'>Safe mode
+                        <i class="far fa-square" aria-hidden="true"></i>
+                    </div>
+                    <div class="option checked" id="editorButton1475">Editor
+                        <i class="fa fa-check-square" aria-hidden="true"></i>
+                    </div>
+                    <div class="option" id="fullscreenButton1475">Fullscreen</div>
+                    <div class="option" id="editorFullscreenButton1475">Editor Fullscreen</div>
+                    <div class="option" id="formatButton1475">Format code</div>
+                    <div class="option" id="minimapToggle1475">Minimap
+                        <i class="far fa-square" aria-hidden="true"></i>
+                    </div>
+                    <div class="option" id="debugButton1475">Inspector</div>
+                    <div class="option" id="metadataButton1475">Metadata</div>
+                    <div class="option subSelect">
+                        <span id="currentVersion1475">Vers. : Latest</span>
+                        <i class="fa fa-chevron-right" aria-hidden="true"></i>
+                        <div class="toDisplaySub">
+                            <div class="option" onclick="setVersion('latest');">Latest</div>
+                            <div class="option" onclick="setVersion('2.5');">2.5</div>
                         </div>
                     </div>
                 </div>
             </div>
+        </div>
 
-            <div class="category right">
-                <div class="button select">
-                    <span class="examplesButton">Examples</span>
-                </div>
+        <div class="category right">
+            <div class="button select">
+                <span class="examplesButton">Examples</span>
             </div>
         </div>
+    </div>
 
-        <div class="navbar navBar1030">
-            <div class="category">
-                <div class="button run" id="runButton1030">Run
-                    <i class="fa fa-play" aria-hidden="true"></i>
-                </div>
+    <div class="navbar navBar1030">
+        <div class="category">
+            <div class="button run" id="runButton1030">Run
+                <i class="fa fa-play" aria-hidden="true"></i>
             </div>
+        </div>
 
 
-            <div class="category">
-                <div class="button" id="newButton1030">New
-                    <i class="fa fa-file" aria-hidden="true"></i>
-                </div>
-                <div class="button removeOnPhone" id="clearButton1030">Clear
-                    <i class="fa fa-trash" aria-hidden="true"></i>
-                </div>
+        <div class="category">
+            <div class="button" id="newButton1030">New
+                <i class="fa fa-file" aria-hidden="true"></i>
+            </div>
+            <div class="button removeOnPhone" id="clearButton1030">Clear
+                <i class="fa fa-trash" aria-hidden="true"></i>
             </div>
+        </div>
 
-            <div class="category">
-                <div class="button" id="saveButton1030">Save
-                    <i class="fa fa-floppy-o" aria-hidden="true"></i>
-                </div>
-                <div class="button removeOnPhone" id="zipButton1030">Zip
-                    <i class="fa fa-download" aria-hidden="true"></i>
-                </div>
+        <div class="category">
+            <div class="button" id="saveButton1030">Save
+                <i class="fa fa-floppy-o" aria-hidden="true"></i>
+            </div>
+            <div class="button removeOnPhone" id="zipButton1030">Zip
+                <i class="fa fa-download" aria-hidden="true"></i>
             </div>
+        </div>
 
-            <div class="category">
-                <div class="button select">Settings
-                    <div class="toDisplay">
-                        <div class="option subSelect">Theme
-                            <i class="fa fa-chevron-right" aria-hidden="true"></i>
-                            <div class="toDisplaySub">
-                                <div class="option" id="darkTheme1030">Dark</div>
-                                <div class="option" id="lightTheme1030">Light</div>
-                            </div>
+        <div class="category">
+            <div class="button select">Settings
+                <div class="toDisplay">
+                    <div class="option subSelect">Theme
+                        <i class="fa fa-chevron-right" aria-hidden="true"></i>
+                        <div class="toDisplaySub">
+                            <div class="option" id="darkTheme1030">Dark</div>
+                            <div class="option" id="lightTheme1030">Light</div>
                         </div>
-                        <div class="option subSelect">
-                            <span id="currentFontSize1030">Font: 14</span>
-                            <i class="fa fa-chevron-right" aria-hidden="true"></i>
-                            <div class="toDisplaySub">
-                                <div class="option" onclick="setFontSize(12);">12</div>
-                                <div class="option" onclick="setFontSize(14);">14</div>
-                                <div class="option" onclick="setFontSize(16);">16</div>
-                                <div class="option" onclick="setFontSize(18);">18</div>
-                                <div class="option" onclick="setFontSize(20);">20</div>
-                                <div class="option" onclick="setFontSize(22);">22</div>
-                            </div>
-                        </div>
-                        <div class="option" id="safemodeToggle1030">Safe mode
-                            <i class="far fa-square" aria-hidden="true"></i>
-                        </div>
-                        <div class="option checked" id="editorButton1030">Editor
-                            <i class="fa fa-check-square" aria-hidden="true"></i>
-                        </div>
-                        <div class="option" id="fullscreenButton1030">Fullscreen</div>
-                        <div class="option" id="editorFullscreenButton1030">Editor Fullscreen</div>
-                        <div class="option" id="formatButton1030">Format code</div>
-                        <div class="option" id="minimapToggle1030">Minimap
-                            <i class="far fa-square" aria-hidden="true"></i>
+                    </div>
+                    <div class="option subSelect">
+                        <span id="currentFontSize1030">Font: 14</span>
+                        <i class="fa fa-chevron-right" aria-hidden="true"></i>
+                        <div class="toDisplaySub">
+                            <div class="option" onclick="setFontSize(12);">12</div>
+                            <div class="option" onclick="setFontSize(14);">14</div>
+                            <div class="option" onclick="setFontSize(16);">16</div>
+                            <div class="option" onclick="setFontSize(18);">18</div>
+                            <div class="option" onclick="setFontSize(20);">20</div>
+                            <div class="option" onclick="setFontSize(22);">22</div>
                         </div>
-                        <div class="option" id="debugButton1030">Inspector</div>
-                        <div class="option" id="metadataButton1030">Metadata</div>
-                        <div class="option subSelect">
-                            <span id="currentVersion1030">Vers. : Latest</span>
-                            <i class="fa fa-chevron-right" aria-hidden="true"></i>
-                            <div class="toDisplaySub">
-                                <div class="option" onclick="setVersion('latest');">Latest</div>
-                                <div class="option" onclick="setVersion('2.5');">2.5</div>
-                            </div>
+                    </div>
+                    <div class="option" id="safemodeToggle1030">Safe mode
+                        <i class="far fa-square" aria-hidden="true"></i>
+                    </div>
+                    <div class="option checked" id="editorButton1030">Editor
+                        <i class="fa fa-check-square" aria-hidden="true"></i>
+                    </div>
+                    <div class="option" id="fullscreenButton1030">Fullscreen</div>
+                    <div class="option" id="editorFullscreenButton1030">Editor Fullscreen</div>
+                    <div class="option" id="formatButton1030">Format code</div>
+                    <div class="option" id="minimapToggle1030">Minimap
+                        <i class="far fa-square" aria-hidden="true"></i>
+                    </div>
+                    <div class="option" id="debugButton1030">Inspector</div>
+                    <div class="option" id="metadataButton1030">Metadata</div>
+                    <div class="option subSelect">
+                        <span id="currentVersion1030">Vers. : Latest</span>
+                        <i class="fa fa-chevron-right" aria-hidden="true"></i>
+                        <div class="toDisplaySub">
+                            <div class="option" onclick="setVersion('latest');">Latest</div>
+                            <div class="option" onclick="setVersion('2.5');">2.5</div>
                         </div>
                     </div>
                 </div>
             </div>
+        </div>
 
-            <div class="category right">
-                <div class="button select">
-                    <span class="examplesButton">Examples</span>
-                </div>
+        <div class="category right">
+            <div class="button select">
+                <span class="examplesButton">Examples</span>
             </div>
         </div>
-
-        <div class="navbar navBar750">
-            <div class="category">
-                <div class="button select">File
-                    <div class="toDisplay">
-                        <div class="option" id="runButton750">Run
-                            <i class="fa fa-play" aria-hidden="true"></i>
-                        </div>
-                        <div class="option" id="newButton750">New
-                            <i class="fa fa-file" aria-hidden="true"></i>
-                        </div>
-                        <div class="option" id="clearButton750">Clear
-                            <i class="fa fa-trash" aria-hidden="true"></i>
-                        </div>
-                        <div class="option" id="saveButton750">Save
-                            <i class="fa fa-floppy-o" aria-hidden="true"></i>
-                        </div>
-                        <div class="option" id="zipButton750">Zip
-                            <i class="fa fa-download" aria-hidden="true"></i>
-                        </div>
+    </div>
+
+    <div class="navbar navBar750">
+        <div class="category">
+            <div class="button select">File
+                <div class="toDisplay">
+                    <div class="option" id="runButton750">Run
+                        <i class="fa fa-play" aria-hidden="true"></i>
+                    </div>
+                    <div class="option" id="newButton750">New
+                        <i class="fa fa-file" aria-hidden="true"></i>
+                    </div>
+                    <div class="option" id="clearButton750">Clear
+                        <i class="fa fa-trash" aria-hidden="true"></i>
+                    </div>
+                    <div class="option" id="saveButton750">Save
+                        <i class="fa fa-floppy-o" aria-hidden="true"></i>
+                    </div>
+                    <div class="option" id="zipButton750">Zip
+                        <i class="fa fa-download" aria-hidden="true"></i>
                     </div>
                 </div>
             </div>
+        </div>
 
-            <div class="category">
-                <div class="button select">Settings
-                    <div class="toDisplay">
-                        <div class="option subSelect">Theme
-                            <i class="fa fa-chevron-right" aria-hidden="true"></i>
-                            <div class="toDisplaySub">
-                                <div class="option" id="darkTheme750">Dark</div>
-                                <div class="option" id="lightTheme750">Light</div>
-                            </div>
-                        </div>
-                        <div class="option subSelect">
-                            <span id="currentFontSize750">Font: 14</span>
-                            <i class="fa fa-chevron-right" aria-hidden="true"></i>
-                            <div class="toDisplaySub">
-                                <div class="option" onclick="setFontSize(12);">12</div>
-                                <div class="option" onclick="setFontSize(14);">14</div>
-                                <div class="option" onclick="setFontSize(16);">16</div>
-                                <div class="option" onclick="setFontSize(18);">18</div>
-                                <div class="option" onclick="setFontSize(20);">20</div>
-                                <div class="option" onclick="setFontSize(22);">22</div>
-                            </div>
-                        </div>
-                        <div class="option" id="safemodeToggle750">Safe mode
-                            <i class="far fa-square" aria-hidden="true"></i>
-                        </div>
-                        <div style="display:none;" class="option checked" id="editorButton750">Editor
-                            <i class="fa fa-check-square" aria-hidden="true"></i>
+        <div class="category">
+            <div class="button select">Settings
+                <div class="toDisplay">
+                    <div class="option subSelect">Theme
+                        <i class="fa fa-chevron-right" aria-hidden="true"></i>
+                        <div class="toDisplaySub">
+                            <div class="option" id="darkTheme750">Dark</div>
+                            <div class="option" id="lightTheme750">Light</div>
                         </div>
-                        <div class="option" id="fullscreenButton750">Fullscreen</div>
-                        <div class="option" id="editorFullscreenButton750">Editor Fullscreen</div>
-                        <div class="option" id="formatButton750">Format code</div>
-                        <div class="option" id="minimapToggle750">Minimap
-                            <i class="far fa-square" aria-hidden="true"></i>
+                    </div>
+                    <div class="option subSelect">
+                        <span id="currentFontSize750">Font: 14</span>
+                        <i class="fa fa-chevron-right" aria-hidden="true"></i>
+                        <div class="toDisplaySub">
+                            <div class="option" onclick="setFontSize(12);">12</div>
+                            <div class="option" onclick="setFontSize(14);">14</div>
+                            <div class="option" onclick="setFontSize(16);">16</div>
+                            <div class="option" onclick="setFontSize(18);">18</div>
+                            <div class="option" onclick="setFontSize(20);">20</div>
+                            <div class="option" onclick="setFontSize(22);">22</div>
                         </div>
-                        <div class="option" id="debugButton750">Inspector</div>
-                        <div class="option" id="metadataButton750">Metadata</div>
-                        <div class="option subSelect">
-                            <span id="currentVersion750">Vers. : Latest</span>
-                            <i class="fa fa-chevron-right" aria-hidden="true"></i>
-                            <div class="toDisplaySub">
-                                <div class="option" onclick="setVersion('latest');">Latest</div>
-                                <div class="option" onclick="setVersion('2.5');">2.5</div>
-                            </div>
+                    </div>
+                    <div class="option" id="safemodeToggle750">Safe mode
+                        <i class="far fa-square" aria-hidden="true"></i>
+                    </div>
+                    <div style="display:none;" class="option checked" id="editorButton750">Editor
+                        <i class="fa fa-check-square" aria-hidden="true"></i>
+                    </div>
+                    <div class="option" id="fullscreenButton750">Fullscreen</div>
+                    <div class="option" id="editorFullscreenButton750">Editor Fullscreen</div>
+                    <div class="option" id="formatButton750">Format code</div>
+                    <div class="option" id="minimapToggle750">Minimap
+                        <i class="far fa-square" aria-hidden="true"></i>
+                    </div>
+                    <div class="option" id="debugButton750">Inspector</div>
+                    <div class="option" id="metadataButton750">Metadata</div>
+                    <div class="option subSelect">
+                        <span id="currentVersion750">Vers. : Latest</span>
+                        <i class="fa fa-chevron-right" aria-hidden="true"></i>
+                        <div class="toDisplaySub">
+                            <div class="option" onclick="setVersion('latest');">Latest</div>
+                            <div class="option" onclick="setVersion('2.5');">2.5</div>
                         </div>
                     </div>
                 </div>
             </div>
+        </div>
 
-            <div class="category right">
-                <div class="button select">
-                    <span class="examplesButton">Examples</span>
-                </div>
+        <div class="category right">
+            <div class="button select">
+                <span class="examplesButton">Examples</span>
             </div>
         </div>
+    </div>
 
-        <div class="wrapper">
-            <div id="jsEditor"></div>
-            <div id="canvasZone">
-                <canvas touch-action="none" id="renderCanvas"></canvas>
-            </div>
+    <div class="wrapper">
+        <div id="jsEditor"></div>
+        <div id="canvasZone">
+            <canvas touch-action="none" id="renderCanvas"></canvas>
         </div>
-        <div id="exampleList">
-            <div id="exampleBanner">
-                <h1>Examples</h1>
-            </div>
-            <div class="horizontalSeparator"></div>
-            <input id="filterBar" type="text" placeholder="Filter examples...">
-            <img id="filterBarClear" src="https://d33wubrfki0l68.cloudfront.net/17ca450bae302631f4857cd8c3992234ec5dd9a7/057f9/img/ui/clear_button.png">
+    </div>
+    <div id="exampleList">
+        <div id="exampleBanner">
+            <h1>Examples</h1>
         </div>
+        <div class="horizontalSeparator"></div>
+        <input id="filterBar" type="text" placeholder="Filter examples...">
+        <img id="filterBarClear" src="https://d33wubrfki0l68.cloudfront.net/17ca450bae302631f4857cd8c3992234ec5dd9a7/057f9/img/ui/clear_button.png">
+    </div>
 
-        <span class="label" id="fpsLabel">FPS</span>
+    <span class="label" id="fpsLabel">FPS</span>
 
-        <div id="errorZone">
-        </div>
+    <div id="errorZone">
+    </div>
 
-        <div class="navbarBottom">
-            <div id="statusBar"></div>
-            <div class="links">
-                <div class='link'>
-                    <a target='_new' href="https://www.netlify.com/">Deployed by Netlify</a>
-                </div>
-                <div class='link'>
-                    <a target='_new' href="http://www.html5gamedevs.com/forum/16-babylonjs/">Forum</a>
-                </div>
-                <div class='link'>
-                    <a target='_new' href="https://www.babylonjs.com/sandbox">Sandbox</a>
-                </div>
-                <div class='link'>
-                    <a target='_new' href="https://doc.babylonjs.com">Documentation</a>
-                </div>
-                <div class='link'>
-                    <a target='_new' href="https://doc.babylonjs.com/playground">Search</a>
-                </div>
+    <div class="navbarBottom">
+        <div id="statusBar"></div>
+        <div class="links">
+            <div class='link'>
+                <a target='_new' href="https://www.netlify.com/">Deployed by Netlify</a>
+            </div>
+            <div class='link'>
+                <a target='_new' href="http://www.html5gamedevs.com/forum/16-babylonjs/">Forum</a>
+            </div>
+            <div class='link'>
+                <a target='_new' href="https://www.babylonjs.com/sandbox">Sandbox</a>
+            </div>
+            <div class='link'>
+                <a target='_new' href="https://doc.babylonjs.com">Documentation</a>
+            </div>
+            <div class='link'>
+                <a target='_new' href="https://doc.babylonjs.com/playground">Search</a>
             </div>
         </div>
+    </div>
 
-        <div id="saveLayer" class="save-layer">
-            <div class="save-form">
-                <label for="saveFormTitle">TITLE</label>
-                <div class="separator"></div>
-                <input type="text" maxlength="120" id="saveFormTitle" class="save-form-title">
+    <div id="saveLayer" class="save-layer">
+        <div class="save-form">
+            <label for="saveFormTitle">TITLE</label>
+            <div class="separator"></div>
+            <input type="text" maxlength="120" id="saveFormTitle" class="save-form-title">
 
-                <label for="saveFormDescription">DESCRIPTION</label>
-                <div class="separator"></div>
-                <textarea id="saveFormDescription" rows="4" cols="10"></textarea>
+            <label for="saveFormDescription">DESCRIPTION</label>
+            <div class="separator"></div>
+            <textarea id="saveFormDescription" rows="4" cols="10"></textarea>
 
-                <label for="saveFormTags">TAGS (separated by comma)</label>
-                <div class="separator"></div>
-                <textarea id="saveFormTags" rows="4" cols="10"></textarea>
+            <label for="saveFormTags">TAGS (separated by comma)</label>
+            <div class="separator"></div>
+            <textarea id="saveFormTags" rows="4" cols="10"></textarea>
 
-                <div class="save-form-buttons" id="saveFormButtons">
+            <div class="save-form-buttons" id="saveFormButtons">
 
-                    <div id="saveFormButtonOk" class="button">OK</div>
-                    <div id="saveFormButtonCancel" class="button">Cancel</div>
-                </div>
+                <div id="saveFormButtonOk" class="button">OK</div>
+                <div id="saveFormButtonCancel" class="button">Cancel</div>
             </div>
         </div>
-
-        <div id="waitDiv">
-            <span id="waitTitle">Babylon.js Playground
-                <BR>
-                <BR>
-                <BR>
-            </span>
-            <img src="waitlogo.png" id="waitLogo" />
-        </div>
-
-        <script src="https://code.jquery.com/jquery.js"></script>
-
-        <script src="js/actions.js"></script>
-        <script src="js/pbt.js"></script>
-        <script>
-            BABYLONDEVTOOLS.Loader
-                .require('node_modules/monaco-editor/min/vs/loader.js')
-                .require('js/index.js')
-                .load(function () {
-                    BABYLON.DracoCompression.Configuration.decoder = {
-                        wasmUrl: "../dist/preview%20release/draco_wasm_wrapper_gltf.js",
-                        wasmBinaryUrl: "../dist/preview%20release/draco_decoder_gltf.wasm",
-                        fallbackUrl: "../dist/preview%20release/draco_decoder_gltf.js"
-                    };
-                });
-        </script>
-    </body>
-
-</html>
+    </div>
+
+    <div id="waitDiv">
+        <span id="waitTitle">Babylon.js Playground
+            <BR>
+            <BR>
+            <BR>
+        </span>
+        <img src="waitlogo.png" id="waitLogo" />
+    </div>
+
+    <script src="https://code.jquery.com/jquery.js"></script>
+
+    <script src="js/actions.js"></script>
+    <script src="js/pbt.js"></script>
+    <script>
+        BABYLONDEVTOOLS.Loader
+            .require('node_modules/monaco-editor/min/vs/loader.js')
+            .require('js/index.js')
+            .load(function() {
+                BABYLON.DracoCompression.Configuration.decoder = {
+                    wasmUrl: "../dist/preview%20release/draco_wasm_wrapper_gltf.js",
+                    wasmBinaryUrl: "../dist/preview%20release/draco_decoder_gltf.wasm",
+                    fallbackUrl: "../dist/preview%20release/draco_decoder_gltf.js"
+                };
+            });
+    </script>
+</body>
+
+</html>

+ 7 - 30
Playground/js/index.js

@@ -498,29 +498,11 @@ function showError(errorMessage, errorEvent) {
                 }
 
                 var showInspector = false;
-                var showDebugLayer = false;
-                var initialTabIndex = 0;
                 showBJSPGMenu();
                 jsEditor.updateOptions({ readOnly: false });
 
-                if (document.getElementsByClassName('insp-wrapper').length > 0) {
-                    for (var i = 0; i < engine.scenes.length; i++) {
-                        if (engine.scenes[i]._debugLayer) {
-                            //TODO: once inspector is updated on netlify, use getActiveTabIndex instead of the following loop
-                            //initialTabIndex = engine.scenes[i]._debugLayer._inspector.getActiveTabIndex();
-                            var tabs = engine.scenes[i]._debugLayer._inspector._tabbar._tabs;
-                            for (var j = 0; j < tabs.length; j++) {
-                                if (tabs[j].isActive()) {
-                                    initialTabIndex = j;
-                                    break;
-                                }
-                            }
-                            break;
-                        }
-                    }
+                if (BABYLON.Engine.LastCreatedScene && BABYLON.Engine.LastCreatedScene.debugLayer.isVisible()) {
                     showInspector = true;
-                } else if (document.getElementById('DebugLayer')) {
-                    showDebugLayer = true;
                 }
 
                 if (engine) {
@@ -644,12 +626,9 @@ function showError(errorMessage, errorEvent) {
 
                     if (scene) {
                         if (showInspector) {
-                            scene.debugLayer.show({ initialTab: initialTabIndex });
-                            scene.executeWhenReady(function() {
-                                scene.debugLayer._inspector.refresh();
-                            })
-                        } else if (showDebugLayer) {
-                            scene.debugLayer.show();
+                            if (!scene.debugLayer.isVisible()) {
+                                scene.debugLayer.show({ embedMode: true });
+                            }
                         }
                     }
                 });
@@ -905,8 +884,7 @@ function showError(errorMessage, errorEvent) {
             engine.resize();
 
             if (scene.debugLayer.isVisible()) {
-                scene.debugLayer.hide();  // Because when you close it with the cross, it doesn't call hide(), so you have to do it in code
-                scene.debugLayer.show();
+                scene.debugLayer.show({ embedMode: true });
             }
         }
 
@@ -969,12 +947,11 @@ function showError(errorMessage, errorEvent) {
         var toggleDebug = function() {
             // Always showing the debug layer, because you can close it by itself
             var scene = engine.scenes[0];
-            if (document.getElementsByClassName("insp-right-panel")[0]) {
+            if (scene.debugLayer.isVisible()) {
                 scene.debugLayer.hide();
             }
             else {
-                scene.debugLayer.hide(); // Because when you close it with the cross, it doesn't call hide(), so you have to do it in code
-                scene.debugLayer.show();
+                scene.debugLayer.show({ embedMode: true });
             }
         }
 

Failā izmaiņas netiks attēlotas, jo tās ir par lielu
+ 3 - 587
Playground/js/libs/split.js


+ 6 - 4
Tools/DevLoader/BabylonLoader.js

@@ -31,6 +31,7 @@ var BABYLONDEVTOOLS;
         var callback;
         var dependencies;
         var useDist;
+        var testMode;
         var min;
         var babylonJSPath;
 
@@ -91,6 +92,11 @@ var BABYLONDEVTOOLS;
             return this;
         }
 
+        Loader.prototype.testMode = function() {
+            testMode = true;
+            return this;
+        }
+
         Loader.prototype.useDist = function() {
             useDist = true;
             return this;
@@ -197,10 +203,6 @@ var BABYLONDEVTOOLS;
             }
             getJson('/Tools/Gulp/config.json',
                 function(data) {
-                    if (!min) {
-                        self.loadScript('/dist/preview release/split.js');
-                    }
-
                     self.loadBJSScripts(data);
                     if (dependencies) {
                         self.loadScripts(dependencies);

+ 8 - 8
Tools/Gulp/config.json

@@ -69,7 +69,7 @@
                 "main": "../../dist/preview release/build/index.d.ts",
                 "out": "../babylon.module.d.ts",
                 "baseDir": "../../dist/preview release/build/",
-                "headerText": "BabylonJS"
+                "headerText": "Babylon.js"
             },
             "processDeclaration": {
                 "filename": "babylon.module.d.ts",
@@ -179,7 +179,7 @@
                 "main": "../../dist/preview release/materialsLibrary/build/src/index.d.ts",
                 "out": "../babylonjs.materials.module.d.ts",
                 "baseDir": "../../dist/preview release/materialsLibrary/build/",
-                "headerText": "BabylonJS Materials"
+                "headerText": "Babylon.js Materials"
             },
             "processDeclaration": {
                 "filename": "babylonjs.materials.module.d.ts",
@@ -220,7 +220,7 @@
                 "main": "../../dist/preview release/postProcessesLibrary/build/src/index.d.ts",
                 "out": "../babylonjs.postProcess.module.d.ts",
                 "baseDir": "../../dist/preview release/postProcessesLibrary/build/",
-                "headerText": "BabylonJS Postprocess library"
+                "headerText": "Babylon.js Postprocess library"
             },
             "processDeclaration": {
                 "filename": "babylonjs.postProcess.module.d.ts",
@@ -301,7 +301,7 @@
                 "main": "../../dist/preview release/proceduralTexturesLibrary/build/src/index.d.ts",
                 "out": "../babylonjs.proceduralTextures.module.d.ts",
                 "baseDir": "../../dist/preview release/proceduralTexturesLibrary/build/",
-                "headerText": "BabylonJS Procedural Textures"
+                "headerText": "Babylon.js Procedural Textures"
             },
             "processDeclaration": {
                 "filename": "babylonjs.proceduralTextures.module.d.ts",
@@ -357,7 +357,7 @@
                 "main": "../../dist/preview release/loaders/build/src/index.d.ts",
                 "out": "../babylonjs.loaders.module.d.ts",
                 "baseDir": "../../dist/preview release/loaders/build/",
-                "headerText": "BabylonJS Loaders"
+                "headerText": "Babylon.js Loaders"
             },
             "processDeclaration": {
                 "filename": "babylonjs.loaders.module.d.ts",
@@ -415,7 +415,7 @@
                 "main": "../../dist/preview release/serializers/build/src/index.d.ts",
                 "out": "../babylonjs.serializers.module.d.ts",
                 "baseDir": "../../dist/preview release/serializers/build/",
-                "headerText": "BabylonJS serializers"
+                "headerText": "Babylon.js serializers"
             },
             "processDeclaration": {
                 "filename": "babylonjs.serializers.module.d.ts",
@@ -465,7 +465,7 @@
                 "main": "../../dist/preview release/gui/build/src/index.d.ts",
                 "out": "../babylon.gui.module.d.ts",
                 "baseDir": "../../dist/preview release/gui/build/",
-                "headerText": "BabylonJS GUI"
+                "headerText": "Babylon.js GUI"
             },
             "processDeclaration": {
                 "filename": "babylon.gui.module.d.ts",
@@ -497,7 +497,7 @@
                 "main": "../../dist/preview release/inspector/build/src/index.d.ts",
                 "out": "../babylon.inspector.module.d.ts",
                 "baseDir": "../../dist/preview release/inspector/build/",
-                "headerText": "BabylonJS Inspector"
+                "headerText": "Babylon.js Inspector"
             },
             "processDeclaration": {
                 "filename": "babylon.inspector.module.d.ts",

Failā izmaiņas netiks attēlotas, jo tās ir par lielu
+ 10323 - 10292
dist/preview release/babylon.d.ts


Failā izmaiņas netiks attēlotas, jo tās ir par lielu
+ 1 - 1
dist/preview release/babylon.js


+ 70 - 86
dist/preview release/babylon.max.js

@@ -23061,7 +23061,7 @@ var BABYLON;
              * falling off base on range or angle.
              * This can be set to any values in Light.FALLOFF_x.
              *
-             * Note: This is only usefull for PBR Materials at the moment. This could be extended if required to
+             * Note: This is only useful for PBR Materials at the moment. This could be extended if required to
              * other types of materials.
              */
             _this.falloffType = Light.FALLOFF_DEFAULT;
@@ -23836,7 +23836,7 @@ var BABYLON;
             _this.mode = Camera.PERSPECTIVE_CAMERA;
             /**
              * Define wether the camera is intermediate.
-             * This is usefull to not present the output directly to the screen in case of rig without post process for instance
+             * This is useful to not present the output directly to the screen in case of rig without post process for instance
              */
             _this.isIntermediate = false;
             /**
@@ -23855,7 +23855,7 @@ var BABYLON;
             _this.fovMode = Camera.FOVMODE_VERTICAL_FIXED;
             /**
              * Rig mode of the camera.
-             * This is usefull to create the camera with two "eyes" instead of one to create VR or stereoscopic scenes.
+             * This is useful to create the camera with two "eyes" instead of one to create VR or stereoscopic scenes.
              * This is normally controlled byt the camera themselves as internal use.
              */
             _this.cameraRigMode = Camera.RIG_MODE_NONE;
@@ -23947,7 +23947,7 @@ var BABYLON;
             return "Camera";
         };
         /**
-         * Gets a string representation of the camera usefull for debug purpose.
+         * Gets a string representation of the camera useful for debug purpose.
          * @param fullDetails Defines that a more verboe level of logging is required
          * @returns the string representation
          */
@@ -31731,8 +31731,7 @@ var BABYLON;
             this._cachedSize = BABYLON.Size.Zero();
             this._scene = scene || BABYLON.Engine.LastCreatedScene;
             if (this._scene) {
-                this._scene.textures.push(this);
-                this._scene.onNewTextureAddedObservable.notifyObservers(this);
+                this._scene.addTexture(this);
                 this.uniqueId = this._scene.getUniqueId();
             }
             this._uid = null;
@@ -32698,7 +32697,7 @@ var BABYLON;
             return serializationObject;
         };
         /**
-         * Get the current class name of the texture usefull for serialization or dynamic coding.
+         * Get the current class name of the texture useful for serialization or dynamic coding.
          * @returns "Texture"
          */
         Texture.prototype.getClassName = function () {
@@ -34700,7 +34699,7 @@ var BABYLON;
          * @param onSuccess is an optional Javascript function to be called just after the mesh is modified. It is passed the modified mesh and must return nothing.
          * @param uvOffset is an optional vector2 used to offset UV.
          * @param uvScale is an optional vector2 used to scale UV.
-         * @param forceUpdate defines whether or not to force an update of the generated buffers. This is usefull to apply on a deserialized model for instance.
+         * @param forceUpdate defines whether or not to force an update of the generated buffers. This is useful to apply on a deserialized model for instance.
          * @returns the Mesh.
          */
         Mesh.prototype.applyDisplacementMap = function (url, minHeight, maxHeight, onSuccess, uvOffset, uvScale, forceUpdate) {
@@ -34740,7 +34739,7 @@ var BABYLON;
          * @param onSuccess is an optional Javascript function to be called just after the mesh is modified. It is passed the modified mesh and must return nothing.
          * @param uvOffset is an optional vector2 used to offset UV.
          * @param uvScale is an optional vector2 used to scale UV.
-         * @param forceUpdate defines whether or not to force an update of the generated buffers. This is usefull to apply on a deserialized model for instance.
+         * @param forceUpdate defines whether or not to force an update of the generated buffers. This is useful to apply on a deserialized model for instance.
          * @returns the Mesh.
          */
         Mesh.prototype.applyDisplacementMapFromBuffer = function (buffer, heightMapWidth, heightMapHeight, minHeight, maxHeight, uvOffset, uvScale, forceUpdate) {
@@ -44119,7 +44118,7 @@ var BABYLON;
             _this.indexOfRefraction = 0.98;
             /**
              * Invert the refraction texture alongside the y axis.
-             * It can be usefull with procedural textures or probe for instance.
+             * It can be useful with procedural textures or probe for instance.
              * @see http://doc.babylonjs.com/how_to/reflect#how-to-obtain-reflections-and-refractions
              */
             _this.invertRefractionY = true;
@@ -46254,7 +46253,7 @@ var BABYLON;
              */
             _this._indexOfRefraction = 0.66;
             /**
-             * Controls if refraction needs to be inverted on Y. This could be usefull for procedural texture.
+             * Controls if refraction needs to be inverted on Y. This could be useful for procedural texture.
              */
             _this._invertRefractionY = false;
             /**
@@ -47790,7 +47789,7 @@ var BABYLON;
              */
             _this.indexOfRefraction = 0.66;
             /**
-             * Controls if refraction needs to be inverted on Y. This could be usefull for procedural texture.
+             * Controls if refraction needs to be inverted on Y. This could be useful for procedural texture.
              */
             _this.invertRefractionY = false;
             /**
@@ -49808,7 +49807,7 @@ var BABYLON;
         return function () { return new BABYLON.UniversalCamera(name, BABYLON.Vector3.Zero(), scene); };
     });
     /**
-     * This represents a free type of camera. It can be usefull in First Person Shooter game for instance.
+     * This represents a free type of camera. It can be useful in First Person Shooter game for instance.
      * Please consider using the new UniversalCamera instead as it adds more functionality like the gamepad.
      * @see http://doc.babylonjs.com/features/cameras#universal-camera
      */
@@ -49816,7 +49815,7 @@ var BABYLON;
         __extends(FreeCamera, _super);
         /**
          * Instantiates a Free Camera.
-         * This represents a free type of camera. It can be usefull in First Person Shooter game for instance.
+         * This represents a free type of camera. It can be useful in First Person Shooter game for instance.
          * Please consider using the new UniversalCamera instead as it adds more functionality like touch to this camera.
          * @see http://doc.babylonjs.com/features/cameras#universal-camera
          * @param name Define the name of the camera in the scene
@@ -66795,6 +66794,17 @@ var BABYLON;
 
 //# sourceMappingURL=babylon.rayHelper.js.map
 
+var __assign = (this && this.__assign) || function () {
+    __assign = Object.assign || function(t) {
+        for (var s, i = 1, n = arguments.length; i < n; i++) {
+            s = arguments[i];
+            for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
+                t[p] = s[p];
+        }
+        return t;
+    };
+    return __assign.apply(this, arguments);
+};
 var BABYLON;
 (function (BABYLON) {
     Object.defineProperty(BABYLON.Scene.prototype, "debugLayer", {
@@ -66837,64 +66847,31 @@ var BABYLON;
         }
         /** Creates the inspector window. */
         DebugLayer.prototype._createInspector = function (config) {
-            if (config === void 0) { config = {}; }
-            var popup = config.popup || false;
-            var initialTab = config.initialTab || 0;
-            var parentElement = config.parentElement || null;
-            if (!this._inspector) {
-                this.BJSINSPECTOR = this.BJSINSPECTOR || typeof INSPECTOR !== 'undefined' ? INSPECTOR : undefined;
-                this._inspector = new this.BJSINSPECTOR.Inspector(this._scene, popup, initialTab, parentElement, config.newColors);
-            } // else nothing to do as instance is already created
+            if (this.isVisible()) {
+                return;
+            }
+            var userOptions = __assign({ overlay: false, showExplorer: true, showInspector: true, embedMode: false, handleResize: true, enablePopup: true }, config);
+            this.BJSINSPECTOR = this.BJSINSPECTOR || typeof INSPECTOR !== 'undefined' ? INSPECTOR : undefined;
+            this.BJSINSPECTOR.Inspector.Show(this._scene, userOptions);
         };
         /**
          * Get if the inspector is visible or not.
          * @returns true if visible otherwise, false
          */
         DebugLayer.prototype.isVisible = function () {
-            if (!this._inspector) {
-                return false;
-            }
-            return true;
+            return this.BJSINSPECTOR.Inspector.IsVisible;
         };
         /**
          * Hide the inspector and close its window.
          */
         DebugLayer.prototype.hide = function () {
-            if (this._inspector) {
-                try {
-                    this._inspector.dispose();
-                }
-                catch (e) {
-                    // If the inspector has been removed directly from the inspector tool
-                }
-                this.onPropertyChangedObservable.clear();
-                this._inspector = null;
-            }
+            this.BJSINSPECTOR.Inspector.Hide();
         };
         /**
-        *
-        * Launch the debugLayer.
-        *
-        * initialTab:
-        * | Value | Tab Name |
-        * | --- | --- |
-        * | 0 | Scene |
-        * | 1 | Console |
-        * | 2 | Stats |
-        * | 3 | Textures |
-        * | 4 | Mesh |
-        * | 5 | Light |
-        * | 6 | Material |
-        * | 7 | GLTF |
-        * | 8 | GUI |
-        * | 9 | Physics |
-        * | 10 | Camera |
-        * | 11 | Audio |
-        *
-        * @param config Define the configuration of the inspector
-        */
+          * Launch the debugLayer.
+          * @param config Define the configuration of the inspector
+          */
         DebugLayer.prototype.show = function (config) {
-            if (config === void 0) { config = {}; }
             if (typeof this.BJSINSPECTOR == 'undefined') {
                 // Load inspector and add it to the DOM
                 BABYLON.Tools.LoadScript(DebugLayer.InspectorURL, this._createInspector.bind(this, config));
@@ -66905,13 +66882,6 @@ var BABYLON;
             }
         };
         /**
-         * Gets the active tab
-         * @return the index of the active tab or -1 if the inspector is hidden
-         */
-        DebugLayer.prototype.getActiveTab = function () {
-            return this._inspector ? this._inspector.getActiveTabIndex() : -1;
-        };
-        /**
          * Define the url to get the inspector script from.
          * By default it uses the babylonjs CDN.
          * @ignoreNaming
@@ -73830,13 +73800,18 @@ var BABYLON;
          */
         CubeTexture.prototype.clone = function () {
             var _this = this;
-            return BABYLON.SerializationHelper.Clone(function () {
-                var scene = _this.getScene();
+            var scene = this.getScene();
+            var uniqueId = 0;
+            var newCubeTexture = BABYLON.SerializationHelper.Clone(function () {
                 if (!scene) {
                     return _this;
                 }
-                return new CubeTexture(_this.url, scene, _this._extensions, _this._noMipmap, _this._files);
+                var cubeTexture = new CubeTexture(_this.url, scene, _this._extensions, _this._noMipmap, _this._files);
+                uniqueId = cubeTexture.uniqueId;
+                return cubeTexture;
             }, this);
+            newCubeTexture.uniqueId = uniqueId;
+            return newCubeTexture;
         };
         __decorate([
             BABYLON.serialize("rotationY")
@@ -74264,7 +74239,7 @@ var BABYLON;
         });
         /**
          * Resets the refresh counter of the texture and start bak from scratch.
-         * Could be usefull to regenerate the texture if it is setup to render only once.
+         * Could be useful to regenerate the texture if it is setup to render only once.
          */
         RenderTargetTexture.prototype.resetRefreshCounter = function () {
             this._currentRefreshId = -1;
@@ -75351,6 +75326,13 @@ var BABYLON;
             _this._context = _this._canvas.getContext("2d");
             return _this;
         }
+        /**
+         * Get the current class name of the texture useful for serialization or dynamic coding.
+         * @returns "DynamicTexture"
+         */
+        DynamicTexture.prototype.getClassName = function () {
+            return "DynamicTexture";
+        };
         Object.defineProperty(DynamicTexture.prototype, "canRescale", {
             /**
              * Gets the current state of canRescale
@@ -76913,9 +76895,9 @@ var BABYLON;
          * Documentation : https://doc.babylonjs.com/babylon101/shadows
          * @param mapSize The size of the texture what stores the shadows. Example : 1024.
          * @param light The light object generating the shadows.
-         * @param useFullFloatFirst By default the generator will try to use half float textures but if you need precision (for self shadowing for instance), you can use this option to enforce full float texture.
+         * @param usefulFloatFirst By default the generator will try to use half float textures but if you need precision (for self shadowing for instance), you can use this option to enforce full float texture.
          */
-        function ShadowGenerator(mapSize, light, useFullFloatFirst) {
+        function ShadowGenerator(mapSize, light, usefulFloatFirst) {
             this._bias = 0.00005;
             this._normalBias = 0;
             this._blurBoxOffset = 1;
@@ -76958,7 +76940,7 @@ var BABYLON;
             }
             // Texture type fallback from float to int if not supported.
             var caps = this._scene.getEngine().getCaps();
-            if (!useFullFloatFirst) {
+            if (!usefulFloatFirst) {
                 if (caps.textureHalfFloatRender && caps.textureHalfFloatLinearFiltering) {
                     this._textureType = BABYLON.Engine.TEXTURETYPE_HALF_FLOAT;
                 }
@@ -77018,14 +77000,14 @@ var BABYLON;
         Object.defineProperty(ShadowGenerator.prototype, "blurBoxOffset", {
             /**
              * Gets the blur box offset: offset applied during the blur pass.
-             * Only usefull if useKernelBlur = false
+             * Only useful if useKernelBlur = false
              */
             get: function () {
                 return this._blurBoxOffset;
             },
             /**
              * Sets the blur box offset: offset applied during the blur pass.
-             * Only usefull if useKernelBlur = false
+             * Only useful if useKernelBlur = false
              */
             set: function (value) {
                 if (this._blurBoxOffset === value) {
@@ -77062,14 +77044,14 @@ var BABYLON;
         Object.defineProperty(ShadowGenerator.prototype, "blurKernel", {
             /**
              * Gets the blur kernel: kernel size of the blur pass.
-             * Only usefull if useKernelBlur = true
+             * Only useful if useKernelBlur = true
              */
             get: function () {
                 return this._blurKernel;
             },
             /**
              * Sets the blur kernel: kernel size of the blur pass.
-             * Only usefull if useKernelBlur = true
+             * Only useful if useKernelBlur = true
              */
             set: function (value) {
                 if (this._blurKernel === value) {
@@ -77084,14 +77066,14 @@ var BABYLON;
         Object.defineProperty(ShadowGenerator.prototype, "useKernelBlur", {
             /**
              * Gets whether the blur pass is a kernel blur (if true) or box blur.
-             * Only usefull in filtered mode (useBlurExponentialShadowMap...)
+             * Only useful in filtered mode (useBlurExponentialShadowMap...)
              */
             get: function () {
                 return this._useKernelBlur;
             },
             /**
              * Sets whether the blur pass is a kernel blur (if true) or box blur.
-             * Only usefull in filtered mode (useBlurExponentialShadowMap...)
+             * Only useful in filtered mode (useBlurExponentialShadowMap...)
              */
             set: function (value) {
                 if (this._useKernelBlur === value) {
@@ -78414,7 +78396,9 @@ var BABYLON;
                 if (!_this._loadingDiv) {
                     return;
                 }
-                document.body.removeChild(_this._loadingDiv);
+                if (_this._loadingDiv.parentElement) {
+                    _this._loadingDiv.parentElement.removeChild(_this._loadingDiv);
+                }
                 window.removeEventListener("resize", _this._resizeLoadingUI);
                 _this._loadingDiv = null;
             };
@@ -81644,7 +81628,7 @@ var BABYLON;
         };
         /**
          * Resets the refresh counter of the texture and start bak from scratch.
-         * Could be usefull to regenerate the texture if it is setup to render only once.
+         * Could be useful to regenerate the texture if it is setup to render only once.
          */
         ProceduralTexture.prototype.resetRefreshCounter = function () {
             this._currentRefreshId = -1;
@@ -85898,7 +85882,7 @@ var BABYLON;
         delete this._depthRenderer[camera.id];
     };
     /**
-     * Defines the Depth Renderer scene component responsible to manage a depth buffer usefull
+     * Defines the Depth Renderer scene component responsible to manage a depth buffer useful
      * in several rendering techniques.
      */
     var DepthRendererSceneComponent = /** @class */ (function () {
@@ -95499,7 +95483,7 @@ var BABYLON;
 var BABYLON;
 (function (BABYLON) {
     /**
-     * Helper class usefull to convert panorama picture to their cubemap representation in 6 faces.
+     * Helper class useful to convert panorama picture to their cubemap representation in 6 faces.
      */
     var PanoramaToCubeMapTools = /** @class */ (function () {
         function PanoramaToCubeMapTools() {
@@ -110266,7 +110250,7 @@ var BABYLON;
         return function () { return new VirtualJoysticksCamera(name, BABYLON.Vector3.Zero(), scene); };
     });
     /**
-     * This represents a free type of camera. It can be usefull in First Person Shooter game for instance.
+     * This represents a free type of camera. It can be useful in First Person Shooter game for instance.
      * It is identical to the Free Camera and simply adds by default a virtual joystick.
      * Virtual Joysticks are on-screen 2D graphics that are used to control the camera or other scene items.
      * @see http://doc.babylonjs.com/features/cameras#virtual-joysticks-camera
@@ -110274,7 +110258,7 @@ var BABYLON;
     var VirtualJoysticksCamera = /** @class */ (function (_super) {
         __extends(VirtualJoysticksCamera, _super);
         /**
-         * Intantiates a VirtualJoysticksCamera. It can be usefull in First Person Shooter game for instance.
+         * Intantiates a VirtualJoysticksCamera. It can be useful in First Person Shooter game for instance.
          * It is identical to the Free Camera and simply adds by default a virtual joystick.
          * Virtual Joysticks are on-screen 2D graphics that are used to control the camera or other scene items.
          * @see http://doc.babylonjs.com/features/cameras#virtual-joysticks-camera
@@ -115843,14 +115827,14 @@ var BABYLON;
 (function (BABYLON) {
     /**
      * This represents a full screen 2d layer.
-     * This can be usefull to display a picture in the  background of your scene for instance.
+     * This can be useful to display a picture in the  background of your scene for instance.
      * @see https://www.babylonjs-playground.com/#08A2BS#1
      */
     var Layer = /** @class */ (function () {
         /**
          * Instantiates a new layer.
          * This represents a full screen 2d layer.
-         * This can be usefull to display a picture in the  background of your scene for instance.
+         * This can be useful to display a picture in the  background of your scene for instance.
          * @see https://www.babylonjs-playground.com/#08A2BS#1
          * @param name Define the name of the layer in the scene
          * @param imgUrl Define the url of the texture to display in the layer

+ 70 - 86
dist/preview release/babylon.no-module.max.js

@@ -23028,7 +23028,7 @@ var BABYLON;
              * falling off base on range or angle.
              * This can be set to any values in Light.FALLOFF_x.
              *
-             * Note: This is only usefull for PBR Materials at the moment. This could be extended if required to
+             * Note: This is only useful for PBR Materials at the moment. This could be extended if required to
              * other types of materials.
              */
             _this.falloffType = Light.FALLOFF_DEFAULT;
@@ -23803,7 +23803,7 @@ var BABYLON;
             _this.mode = Camera.PERSPECTIVE_CAMERA;
             /**
              * Define wether the camera is intermediate.
-             * This is usefull to not present the output directly to the screen in case of rig without post process for instance
+             * This is useful to not present the output directly to the screen in case of rig without post process for instance
              */
             _this.isIntermediate = false;
             /**
@@ -23822,7 +23822,7 @@ var BABYLON;
             _this.fovMode = Camera.FOVMODE_VERTICAL_FIXED;
             /**
              * Rig mode of the camera.
-             * This is usefull to create the camera with two "eyes" instead of one to create VR or stereoscopic scenes.
+             * This is useful to create the camera with two "eyes" instead of one to create VR or stereoscopic scenes.
              * This is normally controlled byt the camera themselves as internal use.
              */
             _this.cameraRigMode = Camera.RIG_MODE_NONE;
@@ -23914,7 +23914,7 @@ var BABYLON;
             return "Camera";
         };
         /**
-         * Gets a string representation of the camera usefull for debug purpose.
+         * Gets a string representation of the camera useful for debug purpose.
          * @param fullDetails Defines that a more verboe level of logging is required
          * @returns the string representation
          */
@@ -31698,8 +31698,7 @@ var BABYLON;
             this._cachedSize = BABYLON.Size.Zero();
             this._scene = scene || BABYLON.Engine.LastCreatedScene;
             if (this._scene) {
-                this._scene.textures.push(this);
-                this._scene.onNewTextureAddedObservable.notifyObservers(this);
+                this._scene.addTexture(this);
                 this.uniqueId = this._scene.getUniqueId();
             }
             this._uid = null;
@@ -32665,7 +32664,7 @@ var BABYLON;
             return serializationObject;
         };
         /**
-         * Get the current class name of the texture usefull for serialization or dynamic coding.
+         * Get the current class name of the texture useful for serialization or dynamic coding.
          * @returns "Texture"
          */
         Texture.prototype.getClassName = function () {
@@ -34667,7 +34666,7 @@ var BABYLON;
          * @param onSuccess is an optional Javascript function to be called just after the mesh is modified. It is passed the modified mesh and must return nothing.
          * @param uvOffset is an optional vector2 used to offset UV.
          * @param uvScale is an optional vector2 used to scale UV.
-         * @param forceUpdate defines whether or not to force an update of the generated buffers. This is usefull to apply on a deserialized model for instance.
+         * @param forceUpdate defines whether or not to force an update of the generated buffers. This is useful to apply on a deserialized model for instance.
          * @returns the Mesh.
          */
         Mesh.prototype.applyDisplacementMap = function (url, minHeight, maxHeight, onSuccess, uvOffset, uvScale, forceUpdate) {
@@ -34707,7 +34706,7 @@ var BABYLON;
          * @param onSuccess is an optional Javascript function to be called just after the mesh is modified. It is passed the modified mesh and must return nothing.
          * @param uvOffset is an optional vector2 used to offset UV.
          * @param uvScale is an optional vector2 used to scale UV.
-         * @param forceUpdate defines whether or not to force an update of the generated buffers. This is usefull to apply on a deserialized model for instance.
+         * @param forceUpdate defines whether or not to force an update of the generated buffers. This is useful to apply on a deserialized model for instance.
          * @returns the Mesh.
          */
         Mesh.prototype.applyDisplacementMapFromBuffer = function (buffer, heightMapWidth, heightMapHeight, minHeight, maxHeight, uvOffset, uvScale, forceUpdate) {
@@ -44086,7 +44085,7 @@ var BABYLON;
             _this.indexOfRefraction = 0.98;
             /**
              * Invert the refraction texture alongside the y axis.
-             * It can be usefull with procedural textures or probe for instance.
+             * It can be useful with procedural textures or probe for instance.
              * @see http://doc.babylonjs.com/how_to/reflect#how-to-obtain-reflections-and-refractions
              */
             _this.invertRefractionY = true;
@@ -46221,7 +46220,7 @@ var BABYLON;
              */
             _this._indexOfRefraction = 0.66;
             /**
-             * Controls if refraction needs to be inverted on Y. This could be usefull for procedural texture.
+             * Controls if refraction needs to be inverted on Y. This could be useful for procedural texture.
              */
             _this._invertRefractionY = false;
             /**
@@ -47757,7 +47756,7 @@ var BABYLON;
              */
             _this.indexOfRefraction = 0.66;
             /**
-             * Controls if refraction needs to be inverted on Y. This could be usefull for procedural texture.
+             * Controls if refraction needs to be inverted on Y. This could be useful for procedural texture.
              */
             _this.invertRefractionY = false;
             /**
@@ -49775,7 +49774,7 @@ var BABYLON;
         return function () { return new BABYLON.UniversalCamera(name, BABYLON.Vector3.Zero(), scene); };
     });
     /**
-     * This represents a free type of camera. It can be usefull in First Person Shooter game for instance.
+     * This represents a free type of camera. It can be useful in First Person Shooter game for instance.
      * Please consider using the new UniversalCamera instead as it adds more functionality like the gamepad.
      * @see http://doc.babylonjs.com/features/cameras#universal-camera
      */
@@ -49783,7 +49782,7 @@ var BABYLON;
         __extends(FreeCamera, _super);
         /**
          * Instantiates a Free Camera.
-         * This represents a free type of camera. It can be usefull in First Person Shooter game for instance.
+         * This represents a free type of camera. It can be useful in First Person Shooter game for instance.
          * Please consider using the new UniversalCamera instead as it adds more functionality like touch to this camera.
          * @see http://doc.babylonjs.com/features/cameras#universal-camera
          * @param name Define the name of the camera in the scene
@@ -66762,6 +66761,17 @@ var BABYLON;
 
 //# sourceMappingURL=rayHelper.js.map
 
+var __assign = (this && this.__assign) || function () {
+    __assign = Object.assign || function(t) {
+        for (var s, i = 1, n = arguments.length; i < n; i++) {
+            s = arguments[i];
+            for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
+                t[p] = s[p];
+        }
+        return t;
+    };
+    return __assign.apply(this, arguments);
+};
 var BABYLON;
 (function (BABYLON) {
     Object.defineProperty(BABYLON.Scene.prototype, "debugLayer", {
@@ -66804,64 +66814,31 @@ var BABYLON;
         }
         /** Creates the inspector window. */
         DebugLayer.prototype._createInspector = function (config) {
-            if (config === void 0) { config = {}; }
-            var popup = config.popup || false;
-            var initialTab = config.initialTab || 0;
-            var parentElement = config.parentElement || null;
-            if (!this._inspector) {
-                this.BJSINSPECTOR = this.BJSINSPECTOR || typeof INSPECTOR !== 'undefined' ? INSPECTOR : undefined;
-                this._inspector = new this.BJSINSPECTOR.Inspector(this._scene, popup, initialTab, parentElement, config.newColors);
-            } // else nothing to do as instance is already created
+            if (this.isVisible()) {
+                return;
+            }
+            var userOptions = __assign({ overlay: false, showExplorer: true, showInspector: true, embedMode: false, handleResize: true, enablePopup: true }, config);
+            this.BJSINSPECTOR = this.BJSINSPECTOR || typeof INSPECTOR !== 'undefined' ? INSPECTOR : undefined;
+            this.BJSINSPECTOR.Inspector.Show(this._scene, userOptions);
         };
         /**
          * Get if the inspector is visible or not.
          * @returns true if visible otherwise, false
          */
         DebugLayer.prototype.isVisible = function () {
-            if (!this._inspector) {
-                return false;
-            }
-            return true;
+            return this.BJSINSPECTOR.Inspector.IsVisible;
         };
         /**
          * Hide the inspector and close its window.
          */
         DebugLayer.prototype.hide = function () {
-            if (this._inspector) {
-                try {
-                    this._inspector.dispose();
-                }
-                catch (e) {
-                    // If the inspector has been removed directly from the inspector tool
-                }
-                this.onPropertyChangedObservable.clear();
-                this._inspector = null;
-            }
+            this.BJSINSPECTOR.Inspector.Hide();
         };
         /**
-        *
-        * Launch the debugLayer.
-        *
-        * initialTab:
-        * | Value | Tab Name |
-        * | --- | --- |
-        * | 0 | Scene |
-        * | 1 | Console |
-        * | 2 | Stats |
-        * | 3 | Textures |
-        * | 4 | Mesh |
-        * | 5 | Light |
-        * | 6 | Material |
-        * | 7 | GLTF |
-        * | 8 | GUI |
-        * | 9 | Physics |
-        * | 10 | Camera |
-        * | 11 | Audio |
-        *
-        * @param config Define the configuration of the inspector
-        */
+          * Launch the debugLayer.
+          * @param config Define the configuration of the inspector
+          */
         DebugLayer.prototype.show = function (config) {
-            if (config === void 0) { config = {}; }
             if (typeof this.BJSINSPECTOR == 'undefined') {
                 // Load inspector and add it to the DOM
                 BABYLON.Tools.LoadScript(DebugLayer.InspectorURL, this._createInspector.bind(this, config));
@@ -66872,13 +66849,6 @@ var BABYLON;
             }
         };
         /**
-         * Gets the active tab
-         * @return the index of the active tab or -1 if the inspector is hidden
-         */
-        DebugLayer.prototype.getActiveTab = function () {
-            return this._inspector ? this._inspector.getActiveTabIndex() : -1;
-        };
-        /**
          * Define the url to get the inspector script from.
          * By default it uses the babylonjs CDN.
          * @ignoreNaming
@@ -73797,13 +73767,18 @@ var BABYLON;
          */
         CubeTexture.prototype.clone = function () {
             var _this = this;
-            return BABYLON.SerializationHelper.Clone(function () {
-                var scene = _this.getScene();
+            var scene = this.getScene();
+            var uniqueId = 0;
+            var newCubeTexture = BABYLON.SerializationHelper.Clone(function () {
                 if (!scene) {
                     return _this;
                 }
-                return new CubeTexture(_this.url, scene, _this._extensions, _this._noMipmap, _this._files);
+                var cubeTexture = new CubeTexture(_this.url, scene, _this._extensions, _this._noMipmap, _this._files);
+                uniqueId = cubeTexture.uniqueId;
+                return cubeTexture;
             }, this);
+            newCubeTexture.uniqueId = uniqueId;
+            return newCubeTexture;
         };
         __decorate([
             BABYLON.serialize("rotationY")
@@ -74231,7 +74206,7 @@ var BABYLON;
         });
         /**
          * Resets the refresh counter of the texture and start bak from scratch.
-         * Could be usefull to regenerate the texture if it is setup to render only once.
+         * Could be useful to regenerate the texture if it is setup to render only once.
          */
         RenderTargetTexture.prototype.resetRefreshCounter = function () {
             this._currentRefreshId = -1;
@@ -75318,6 +75293,13 @@ var BABYLON;
             _this._context = _this._canvas.getContext("2d");
             return _this;
         }
+        /**
+         * Get the current class name of the texture useful for serialization or dynamic coding.
+         * @returns "DynamicTexture"
+         */
+        DynamicTexture.prototype.getClassName = function () {
+            return "DynamicTexture";
+        };
         Object.defineProperty(DynamicTexture.prototype, "canRescale", {
             /**
              * Gets the current state of canRescale
@@ -76880,9 +76862,9 @@ var BABYLON;
          * Documentation : https://doc.babylonjs.com/babylon101/shadows
          * @param mapSize The size of the texture what stores the shadows. Example : 1024.
          * @param light The light object generating the shadows.
-         * @param useFullFloatFirst By default the generator will try to use half float textures but if you need precision (for self shadowing for instance), you can use this option to enforce full float texture.
+         * @param usefulFloatFirst By default the generator will try to use half float textures but if you need precision (for self shadowing for instance), you can use this option to enforce full float texture.
          */
-        function ShadowGenerator(mapSize, light, useFullFloatFirst) {
+        function ShadowGenerator(mapSize, light, usefulFloatFirst) {
             this._bias = 0.00005;
             this._normalBias = 0;
             this._blurBoxOffset = 1;
@@ -76925,7 +76907,7 @@ var BABYLON;
             }
             // Texture type fallback from float to int if not supported.
             var caps = this._scene.getEngine().getCaps();
-            if (!useFullFloatFirst) {
+            if (!usefulFloatFirst) {
                 if (caps.textureHalfFloatRender && caps.textureHalfFloatLinearFiltering) {
                     this._textureType = BABYLON.Engine.TEXTURETYPE_HALF_FLOAT;
                 }
@@ -76985,14 +76967,14 @@ var BABYLON;
         Object.defineProperty(ShadowGenerator.prototype, "blurBoxOffset", {
             /**
              * Gets the blur box offset: offset applied during the blur pass.
-             * Only usefull if useKernelBlur = false
+             * Only useful if useKernelBlur = false
              */
             get: function () {
                 return this._blurBoxOffset;
             },
             /**
              * Sets the blur box offset: offset applied during the blur pass.
-             * Only usefull if useKernelBlur = false
+             * Only useful if useKernelBlur = false
              */
             set: function (value) {
                 if (this._blurBoxOffset === value) {
@@ -77029,14 +77011,14 @@ var BABYLON;
         Object.defineProperty(ShadowGenerator.prototype, "blurKernel", {
             /**
              * Gets the blur kernel: kernel size of the blur pass.
-             * Only usefull if useKernelBlur = true
+             * Only useful if useKernelBlur = true
              */
             get: function () {
                 return this._blurKernel;
             },
             /**
              * Sets the blur kernel: kernel size of the blur pass.
-             * Only usefull if useKernelBlur = true
+             * Only useful if useKernelBlur = true
              */
             set: function (value) {
                 if (this._blurKernel === value) {
@@ -77051,14 +77033,14 @@ var BABYLON;
         Object.defineProperty(ShadowGenerator.prototype, "useKernelBlur", {
             /**
              * Gets whether the blur pass is a kernel blur (if true) or box blur.
-             * Only usefull in filtered mode (useBlurExponentialShadowMap...)
+             * Only useful in filtered mode (useBlurExponentialShadowMap...)
              */
             get: function () {
                 return this._useKernelBlur;
             },
             /**
              * Sets whether the blur pass is a kernel blur (if true) or box blur.
-             * Only usefull in filtered mode (useBlurExponentialShadowMap...)
+             * Only useful in filtered mode (useBlurExponentialShadowMap...)
              */
             set: function (value) {
                 if (this._useKernelBlur === value) {
@@ -78381,7 +78363,9 @@ var BABYLON;
                 if (!_this._loadingDiv) {
                     return;
                 }
-                document.body.removeChild(_this._loadingDiv);
+                if (_this._loadingDiv.parentElement) {
+                    _this._loadingDiv.parentElement.removeChild(_this._loadingDiv);
+                }
                 window.removeEventListener("resize", _this._resizeLoadingUI);
                 _this._loadingDiv = null;
             };
@@ -81611,7 +81595,7 @@ var BABYLON;
         };
         /**
          * Resets the refresh counter of the texture and start bak from scratch.
-         * Could be usefull to regenerate the texture if it is setup to render only once.
+         * Could be useful to regenerate the texture if it is setup to render only once.
          */
         ProceduralTexture.prototype.resetRefreshCounter = function () {
             this._currentRefreshId = -1;
@@ -85865,7 +85849,7 @@ var BABYLON;
         delete this._depthRenderer[camera.id];
     };
     /**
-     * Defines the Depth Renderer scene component responsible to manage a depth buffer usefull
+     * Defines the Depth Renderer scene component responsible to manage a depth buffer useful
      * in several rendering techniques.
      */
     var DepthRendererSceneComponent = /** @class */ (function () {
@@ -95466,7 +95450,7 @@ var BABYLON;
 var BABYLON;
 (function (BABYLON) {
     /**
-     * Helper class usefull to convert panorama picture to their cubemap representation in 6 faces.
+     * Helper class useful to convert panorama picture to their cubemap representation in 6 faces.
      */
     var PanoramaToCubeMapTools = /** @class */ (function () {
         function PanoramaToCubeMapTools() {
@@ -110233,7 +110217,7 @@ var BABYLON;
         return function () { return new VirtualJoysticksCamera(name, BABYLON.Vector3.Zero(), scene); };
     });
     /**
-     * This represents a free type of camera. It can be usefull in First Person Shooter game for instance.
+     * This represents a free type of camera. It can be useful in First Person Shooter game for instance.
      * It is identical to the Free Camera and simply adds by default a virtual joystick.
      * Virtual Joysticks are on-screen 2D graphics that are used to control the camera or other scene items.
      * @see http://doc.babylonjs.com/features/cameras#virtual-joysticks-camera
@@ -110241,7 +110225,7 @@ var BABYLON;
     var VirtualJoysticksCamera = /** @class */ (function (_super) {
         __extends(VirtualJoysticksCamera, _super);
         /**
-         * Intantiates a VirtualJoysticksCamera. It can be usefull in First Person Shooter game for instance.
+         * Intantiates a VirtualJoysticksCamera. It can be useful in First Person Shooter game for instance.
          * It is identical to the Free Camera and simply adds by default a virtual joystick.
          * Virtual Joysticks are on-screen 2D graphics that are used to control the camera or other scene items.
          * @see http://doc.babylonjs.com/features/cameras#virtual-joysticks-camera
@@ -115810,14 +115794,14 @@ var BABYLON;
 (function (BABYLON) {
     /**
      * This represents a full screen 2d layer.
-     * This can be usefull to display a picture in the  background of your scene for instance.
+     * This can be useful to display a picture in the  background of your scene for instance.
      * @see https://www.babylonjs-playground.com/#08A2BS#1
      */
     var Layer = /** @class */ (function () {
         /**
          * Instantiates a new layer.
          * This represents a full screen 2d layer.
-         * This can be usefull to display a picture in the  background of your scene for instance.
+         * This can be useful to display a picture in the  background of your scene for instance.
          * @see https://www.babylonjs-playground.com/#08A2BS#1
          * @param name Define the name of the layer in the scene
          * @param imgUrl Define the url of the texture to display in the layer

Failā izmaiņas netiks attēlotas, jo tās ir par lielu
+ 1 - 1
dist/preview release/babylon.worker.js


+ 70 - 86
dist/preview release/es6.js

@@ -23028,7 +23028,7 @@ var BABYLON;
              * falling off base on range or angle.
              * This can be set to any values in Light.FALLOFF_x.
              *
-             * Note: This is only usefull for PBR Materials at the moment. This could be extended if required to
+             * Note: This is only useful for PBR Materials at the moment. This could be extended if required to
              * other types of materials.
              */
             _this.falloffType = Light.FALLOFF_DEFAULT;
@@ -23803,7 +23803,7 @@ var BABYLON;
             _this.mode = Camera.PERSPECTIVE_CAMERA;
             /**
              * Define wether the camera is intermediate.
-             * This is usefull to not present the output directly to the screen in case of rig without post process for instance
+             * This is useful to not present the output directly to the screen in case of rig without post process for instance
              */
             _this.isIntermediate = false;
             /**
@@ -23822,7 +23822,7 @@ var BABYLON;
             _this.fovMode = Camera.FOVMODE_VERTICAL_FIXED;
             /**
              * Rig mode of the camera.
-             * This is usefull to create the camera with two "eyes" instead of one to create VR or stereoscopic scenes.
+             * This is useful to create the camera with two "eyes" instead of one to create VR or stereoscopic scenes.
              * This is normally controlled byt the camera themselves as internal use.
              */
             _this.cameraRigMode = Camera.RIG_MODE_NONE;
@@ -23914,7 +23914,7 @@ var BABYLON;
             return "Camera";
         };
         /**
-         * Gets a string representation of the camera usefull for debug purpose.
+         * Gets a string representation of the camera useful for debug purpose.
          * @param fullDetails Defines that a more verboe level of logging is required
          * @returns the string representation
          */
@@ -31698,8 +31698,7 @@ var BABYLON;
             this._cachedSize = BABYLON.Size.Zero();
             this._scene = scene || BABYLON.Engine.LastCreatedScene;
             if (this._scene) {
-                this._scene.textures.push(this);
-                this._scene.onNewTextureAddedObservable.notifyObservers(this);
+                this._scene.addTexture(this);
                 this.uniqueId = this._scene.getUniqueId();
             }
             this._uid = null;
@@ -32665,7 +32664,7 @@ var BABYLON;
             return serializationObject;
         };
         /**
-         * Get the current class name of the texture usefull for serialization or dynamic coding.
+         * Get the current class name of the texture useful for serialization or dynamic coding.
          * @returns "Texture"
          */
         Texture.prototype.getClassName = function () {
@@ -34667,7 +34666,7 @@ var BABYLON;
          * @param onSuccess is an optional Javascript function to be called just after the mesh is modified. It is passed the modified mesh and must return nothing.
          * @param uvOffset is an optional vector2 used to offset UV.
          * @param uvScale is an optional vector2 used to scale UV.
-         * @param forceUpdate defines whether or not to force an update of the generated buffers. This is usefull to apply on a deserialized model for instance.
+         * @param forceUpdate defines whether or not to force an update of the generated buffers. This is useful to apply on a deserialized model for instance.
          * @returns the Mesh.
          */
         Mesh.prototype.applyDisplacementMap = function (url, minHeight, maxHeight, onSuccess, uvOffset, uvScale, forceUpdate) {
@@ -34707,7 +34706,7 @@ var BABYLON;
          * @param onSuccess is an optional Javascript function to be called just after the mesh is modified. It is passed the modified mesh and must return nothing.
          * @param uvOffset is an optional vector2 used to offset UV.
          * @param uvScale is an optional vector2 used to scale UV.
-         * @param forceUpdate defines whether or not to force an update of the generated buffers. This is usefull to apply on a deserialized model for instance.
+         * @param forceUpdate defines whether or not to force an update of the generated buffers. This is useful to apply on a deserialized model for instance.
          * @returns the Mesh.
          */
         Mesh.prototype.applyDisplacementMapFromBuffer = function (buffer, heightMapWidth, heightMapHeight, minHeight, maxHeight, uvOffset, uvScale, forceUpdate) {
@@ -44086,7 +44085,7 @@ var BABYLON;
             _this.indexOfRefraction = 0.98;
             /**
              * Invert the refraction texture alongside the y axis.
-             * It can be usefull with procedural textures or probe for instance.
+             * It can be useful with procedural textures or probe for instance.
              * @see http://doc.babylonjs.com/how_to/reflect#how-to-obtain-reflections-and-refractions
              */
             _this.invertRefractionY = true;
@@ -46221,7 +46220,7 @@ var BABYLON;
              */
             _this._indexOfRefraction = 0.66;
             /**
-             * Controls if refraction needs to be inverted on Y. This could be usefull for procedural texture.
+             * Controls if refraction needs to be inverted on Y. This could be useful for procedural texture.
              */
             _this._invertRefractionY = false;
             /**
@@ -47757,7 +47756,7 @@ var BABYLON;
              */
             _this.indexOfRefraction = 0.66;
             /**
-             * Controls if refraction needs to be inverted on Y. This could be usefull for procedural texture.
+             * Controls if refraction needs to be inverted on Y. This could be useful for procedural texture.
              */
             _this.invertRefractionY = false;
             /**
@@ -49775,7 +49774,7 @@ var BABYLON;
         return function () { return new BABYLON.UniversalCamera(name, BABYLON.Vector3.Zero(), scene); };
     });
     /**
-     * This represents a free type of camera. It can be usefull in First Person Shooter game for instance.
+     * This represents a free type of camera. It can be useful in First Person Shooter game for instance.
      * Please consider using the new UniversalCamera instead as it adds more functionality like the gamepad.
      * @see http://doc.babylonjs.com/features/cameras#universal-camera
      */
@@ -49783,7 +49782,7 @@ var BABYLON;
         __extends(FreeCamera, _super);
         /**
          * Instantiates a Free Camera.
-         * This represents a free type of camera. It can be usefull in First Person Shooter game for instance.
+         * This represents a free type of camera. It can be useful in First Person Shooter game for instance.
          * Please consider using the new UniversalCamera instead as it adds more functionality like touch to this camera.
          * @see http://doc.babylonjs.com/features/cameras#universal-camera
          * @param name Define the name of the camera in the scene
@@ -66762,6 +66761,17 @@ var BABYLON;
 
 //# sourceMappingURL=rayHelper.js.map
 
+var __assign = (this && this.__assign) || function () {
+    __assign = Object.assign || function(t) {
+        for (var s, i = 1, n = arguments.length; i < n; i++) {
+            s = arguments[i];
+            for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
+                t[p] = s[p];
+        }
+        return t;
+    };
+    return __assign.apply(this, arguments);
+};
 var BABYLON;
 (function (BABYLON) {
     Object.defineProperty(BABYLON.Scene.prototype, "debugLayer", {
@@ -66804,64 +66814,31 @@ var BABYLON;
         }
         /** Creates the inspector window. */
         DebugLayer.prototype._createInspector = function (config) {
-            if (config === void 0) { config = {}; }
-            var popup = config.popup || false;
-            var initialTab = config.initialTab || 0;
-            var parentElement = config.parentElement || null;
-            if (!this._inspector) {
-                this.BJSINSPECTOR = this.BJSINSPECTOR || typeof INSPECTOR !== 'undefined' ? INSPECTOR : undefined;
-                this._inspector = new this.BJSINSPECTOR.Inspector(this._scene, popup, initialTab, parentElement, config.newColors);
-            } // else nothing to do as instance is already created
+            if (this.isVisible()) {
+                return;
+            }
+            var userOptions = __assign({ overlay: false, showExplorer: true, showInspector: true, embedMode: false, handleResize: true, enablePopup: true }, config);
+            this.BJSINSPECTOR = this.BJSINSPECTOR || typeof INSPECTOR !== 'undefined' ? INSPECTOR : undefined;
+            this.BJSINSPECTOR.Inspector.Show(this._scene, userOptions);
         };
         /**
          * Get if the inspector is visible or not.
          * @returns true if visible otherwise, false
          */
         DebugLayer.prototype.isVisible = function () {
-            if (!this._inspector) {
-                return false;
-            }
-            return true;
+            return this.BJSINSPECTOR.Inspector.IsVisible;
         };
         /**
          * Hide the inspector and close its window.
          */
         DebugLayer.prototype.hide = function () {
-            if (this._inspector) {
-                try {
-                    this._inspector.dispose();
-                }
-                catch (e) {
-                    // If the inspector has been removed directly from the inspector tool
-                }
-                this.onPropertyChangedObservable.clear();
-                this._inspector = null;
-            }
+            this.BJSINSPECTOR.Inspector.Hide();
         };
         /**
-        *
-        * Launch the debugLayer.
-        *
-        * initialTab:
-        * | Value | Tab Name |
-        * | --- | --- |
-        * | 0 | Scene |
-        * | 1 | Console |
-        * | 2 | Stats |
-        * | 3 | Textures |
-        * | 4 | Mesh |
-        * | 5 | Light |
-        * | 6 | Material |
-        * | 7 | GLTF |
-        * | 8 | GUI |
-        * | 9 | Physics |
-        * | 10 | Camera |
-        * | 11 | Audio |
-        *
-        * @param config Define the configuration of the inspector
-        */
+          * Launch the debugLayer.
+          * @param config Define the configuration of the inspector
+          */
         DebugLayer.prototype.show = function (config) {
-            if (config === void 0) { config = {}; }
             if (typeof this.BJSINSPECTOR == 'undefined') {
                 // Load inspector and add it to the DOM
                 BABYLON.Tools.LoadScript(DebugLayer.InspectorURL, this._createInspector.bind(this, config));
@@ -66872,13 +66849,6 @@ var BABYLON;
             }
         };
         /**
-         * Gets the active tab
-         * @return the index of the active tab or -1 if the inspector is hidden
-         */
-        DebugLayer.prototype.getActiveTab = function () {
-            return this._inspector ? this._inspector.getActiveTabIndex() : -1;
-        };
-        /**
          * Define the url to get the inspector script from.
          * By default it uses the babylonjs CDN.
          * @ignoreNaming
@@ -73797,13 +73767,18 @@ var BABYLON;
          */
         CubeTexture.prototype.clone = function () {
             var _this = this;
-            return BABYLON.SerializationHelper.Clone(function () {
-                var scene = _this.getScene();
+            var scene = this.getScene();
+            var uniqueId = 0;
+            var newCubeTexture = BABYLON.SerializationHelper.Clone(function () {
                 if (!scene) {
                     return _this;
                 }
-                return new CubeTexture(_this.url, scene, _this._extensions, _this._noMipmap, _this._files);
+                var cubeTexture = new CubeTexture(_this.url, scene, _this._extensions, _this._noMipmap, _this._files);
+                uniqueId = cubeTexture.uniqueId;
+                return cubeTexture;
             }, this);
+            newCubeTexture.uniqueId = uniqueId;
+            return newCubeTexture;
         };
         __decorate([
             BABYLON.serialize("rotationY")
@@ -74231,7 +74206,7 @@ var BABYLON;
         });
         /**
          * Resets the refresh counter of the texture and start bak from scratch.
-         * Could be usefull to regenerate the texture if it is setup to render only once.
+         * Could be useful to regenerate the texture if it is setup to render only once.
          */
         RenderTargetTexture.prototype.resetRefreshCounter = function () {
             this._currentRefreshId = -1;
@@ -75318,6 +75293,13 @@ var BABYLON;
             _this._context = _this._canvas.getContext("2d");
             return _this;
         }
+        /**
+         * Get the current class name of the texture useful for serialization or dynamic coding.
+         * @returns "DynamicTexture"
+         */
+        DynamicTexture.prototype.getClassName = function () {
+            return "DynamicTexture";
+        };
         Object.defineProperty(DynamicTexture.prototype, "canRescale", {
             /**
              * Gets the current state of canRescale
@@ -76880,9 +76862,9 @@ var BABYLON;
          * Documentation : https://doc.babylonjs.com/babylon101/shadows
          * @param mapSize The size of the texture what stores the shadows. Example : 1024.
          * @param light The light object generating the shadows.
-         * @param useFullFloatFirst By default the generator will try to use half float textures but if you need precision (for self shadowing for instance), you can use this option to enforce full float texture.
+         * @param usefulFloatFirst By default the generator will try to use half float textures but if you need precision (for self shadowing for instance), you can use this option to enforce full float texture.
          */
-        function ShadowGenerator(mapSize, light, useFullFloatFirst) {
+        function ShadowGenerator(mapSize, light, usefulFloatFirst) {
             this._bias = 0.00005;
             this._normalBias = 0;
             this._blurBoxOffset = 1;
@@ -76925,7 +76907,7 @@ var BABYLON;
             }
             // Texture type fallback from float to int if not supported.
             var caps = this._scene.getEngine().getCaps();
-            if (!useFullFloatFirst) {
+            if (!usefulFloatFirst) {
                 if (caps.textureHalfFloatRender && caps.textureHalfFloatLinearFiltering) {
                     this._textureType = BABYLON.Engine.TEXTURETYPE_HALF_FLOAT;
                 }
@@ -76985,14 +76967,14 @@ var BABYLON;
         Object.defineProperty(ShadowGenerator.prototype, "blurBoxOffset", {
             /**
              * Gets the blur box offset: offset applied during the blur pass.
-             * Only usefull if useKernelBlur = false
+             * Only useful if useKernelBlur = false
              */
             get: function () {
                 return this._blurBoxOffset;
             },
             /**
              * Sets the blur box offset: offset applied during the blur pass.
-             * Only usefull if useKernelBlur = false
+             * Only useful if useKernelBlur = false
              */
             set: function (value) {
                 if (this._blurBoxOffset === value) {
@@ -77029,14 +77011,14 @@ var BABYLON;
         Object.defineProperty(ShadowGenerator.prototype, "blurKernel", {
             /**
              * Gets the blur kernel: kernel size of the blur pass.
-             * Only usefull if useKernelBlur = true
+             * Only useful if useKernelBlur = true
              */
             get: function () {
                 return this._blurKernel;
             },
             /**
              * Sets the blur kernel: kernel size of the blur pass.
-             * Only usefull if useKernelBlur = true
+             * Only useful if useKernelBlur = true
              */
             set: function (value) {
                 if (this._blurKernel === value) {
@@ -77051,14 +77033,14 @@ var BABYLON;
         Object.defineProperty(ShadowGenerator.prototype, "useKernelBlur", {
             /**
              * Gets whether the blur pass is a kernel blur (if true) or box blur.
-             * Only usefull in filtered mode (useBlurExponentialShadowMap...)
+             * Only useful in filtered mode (useBlurExponentialShadowMap...)
              */
             get: function () {
                 return this._useKernelBlur;
             },
             /**
              * Sets whether the blur pass is a kernel blur (if true) or box blur.
-             * Only usefull in filtered mode (useBlurExponentialShadowMap...)
+             * Only useful in filtered mode (useBlurExponentialShadowMap...)
              */
             set: function (value) {
                 if (this._useKernelBlur === value) {
@@ -78381,7 +78363,9 @@ var BABYLON;
                 if (!_this._loadingDiv) {
                     return;
                 }
-                document.body.removeChild(_this._loadingDiv);
+                if (_this._loadingDiv.parentElement) {
+                    _this._loadingDiv.parentElement.removeChild(_this._loadingDiv);
+                }
                 window.removeEventListener("resize", _this._resizeLoadingUI);
                 _this._loadingDiv = null;
             };
@@ -81611,7 +81595,7 @@ var BABYLON;
         };
         /**
          * Resets the refresh counter of the texture and start bak from scratch.
-         * Could be usefull to regenerate the texture if it is setup to render only once.
+         * Could be useful to regenerate the texture if it is setup to render only once.
          */
         ProceduralTexture.prototype.resetRefreshCounter = function () {
             this._currentRefreshId = -1;
@@ -85865,7 +85849,7 @@ var BABYLON;
         delete this._depthRenderer[camera.id];
     };
     /**
-     * Defines the Depth Renderer scene component responsible to manage a depth buffer usefull
+     * Defines the Depth Renderer scene component responsible to manage a depth buffer useful
      * in several rendering techniques.
      */
     var DepthRendererSceneComponent = /** @class */ (function () {
@@ -95466,7 +95450,7 @@ var BABYLON;
 var BABYLON;
 (function (BABYLON) {
     /**
-     * Helper class usefull to convert panorama picture to their cubemap representation in 6 faces.
+     * Helper class useful to convert panorama picture to their cubemap representation in 6 faces.
      */
     var PanoramaToCubeMapTools = /** @class */ (function () {
         function PanoramaToCubeMapTools() {
@@ -110233,7 +110217,7 @@ var BABYLON;
         return function () { return new VirtualJoysticksCamera(name, BABYLON.Vector3.Zero(), scene); };
     });
     /**
-     * This represents a free type of camera. It can be usefull in First Person Shooter game for instance.
+     * This represents a free type of camera. It can be useful in First Person Shooter game for instance.
      * It is identical to the Free Camera and simply adds by default a virtual joystick.
      * Virtual Joysticks are on-screen 2D graphics that are used to control the camera or other scene items.
      * @see http://doc.babylonjs.com/features/cameras#virtual-joysticks-camera
@@ -110241,7 +110225,7 @@ var BABYLON;
     var VirtualJoysticksCamera = /** @class */ (function (_super) {
         __extends(VirtualJoysticksCamera, _super);
         /**
-         * Intantiates a VirtualJoysticksCamera. It can be usefull in First Person Shooter game for instance.
+         * Intantiates a VirtualJoysticksCamera. It can be useful in First Person Shooter game for instance.
          * It is identical to the Free Camera and simply adds by default a virtual joystick.
          * Virtual Joysticks are on-screen 2D graphics that are used to control the camera or other scene items.
          * @see http://doc.babylonjs.com/features/cameras#virtual-joysticks-camera
@@ -115810,14 +115794,14 @@ var BABYLON;
 (function (BABYLON) {
     /**
      * This represents a full screen 2d layer.
-     * This can be usefull to display a picture in the  background of your scene for instance.
+     * This can be useful to display a picture in the  background of your scene for instance.
      * @see https://www.babylonjs-playground.com/#08A2BS#1
      */
     var Layer = /** @class */ (function () {
         /**
          * Instantiates a new layer.
          * This represents a full screen 2d layer.
-         * This can be usefull to display a picture in the  background of your scene for instance.
+         * This can be useful to display a picture in the  background of your scene for instance.
          * @see https://www.babylonjs-playground.com/#08A2BS#1
          * @param name Define the name of the layer in the scene
          * @param imgUrl Define the url of the texture to display in the layer

+ 61 - 1
dist/preview release/gui/babylon.gui.d.ts

@@ -1,4 +1,4 @@
-/*BabylonJS GUI*/
+/*Babylon.js GUI*/
 // Dependencies for this module:
 //   ../../../../Tools/Gulp/babylonjs
 declare module BABYLON.GUI {
@@ -67,6 +67,10 @@ declare module BABYLON.GUI {
                 */
             onClipboardObservable: BABYLON.Observable<BABYLON.ClipboardInfo>;
             /**
+                * BABYLON.Observable event triggered each time a pointer down is intercepted by a control
+                */
+            onControlPickedObservable: BABYLON.Observable<Control>;
+            /**
                 * Gets or sets a boolean defining if alpha is stored as premultiplied
                 */
             premulAlpha: boolean;
@@ -108,6 +112,19 @@ declare module BABYLON.GUI {
                 */
             readonly rootContainer: Container;
             /**
+                * Returns an array containing the root container.
+                * This is mostly used to let the Inspector introspects the ADT
+                * @returns an array containing the rootContainer
+                */
+            getChildren(): Array<Container>;
+            /**
+                * Will return all controls that are inside this texture
+                * @param directDescendantsOnly defines if true only direct descendants of 'this' will be considered, if false direct and also indirect (children of children, an so on in a recursive manner) descendants of 'this' will be considered
+                * @param predicate defines an optional predicate that will be called on every evaluated child, the predicate must return true for a given child to be part of the result, otherwise it will be ignored
+                * @return all child controls
+                */
+            getDescendants(directDescendantsOnly?: boolean, predicate?: (control: Control) => boolean): Control[];
+            /**
                 * Gets or sets the current focused control
                 */
             focusedControl: BABYLON.Nullable<IFocusableControl>;
@@ -130,6 +147,11 @@ declare module BABYLON.GUI {
              */
             constructor(name: string, width: number | undefined, height: number | undefined, scene: BABYLON.Nullable<BABYLON.Scene>, generateMipMaps?: boolean, samplingMode?: number);
             /**
+                * Get the current class name of the texture useful for serialization or dynamic coding.
+                * @returns "AdvancedDynamicTexture"
+                */
+            getClassName(): string;
+            /**
                 * Function used to execute a function on all controls
                 * @param func defines the function to execute
                 * @param container defines the container where controls belong. If null the root container will be used
@@ -173,6 +195,8 @@ declare module BABYLON.GUI {
             /** @hidden */
             _changeCursor(cursor: string): void;
             /** @hidden */
+            _registerLastControlDown(control: Control, pointerId: number): void;
+            /** @hidden */
             _cleanControlAfterRemovalFromList(list: {
                     [pointerId: number]: Control;
             }, control: Control): void;
@@ -820,6 +844,8 @@ declare module BABYLON.GUI {
             /** @hidden */
             _draw(parentMeasure: Measure, context: CanvasRenderingContext2D): void;
             /** @hidden */
+            _getDescendants(results: Control[], directDescendantsOnly?: boolean, predicate?: (control: Control) => boolean): void;
+            /** @hidden */
             _processPicking(x: number, y: number, type: number, pointerId: number, buttonIndex: number): boolean;
             /** @hidden */
             protected _clipForChildren(context: CanvasRenderingContext2D): void;
@@ -882,6 +908,10 @@ declare module BABYLON.GUI {
             /** @hidden */
             _tag: any;
             /**
+                * Gets or sets the unique id of the node. Please note that this number will be updated when the control is added to a container
+                */
+            uniqueId: number;
+            /**
                 * Gets or sets an object used to store user defined information for the node
                 */
             metadata: any;
@@ -910,6 +940,11 @@ declare module BABYLON.GUI {
             /** Gets the control type name */
             readonly typeName: string;
             /**
+                * Get the current class name of the control.
+                * @returns current class name
+                */
+            getClassName(): string;
+            /**
              * An event triggered when the pointer move over the control.
              */
             onPointerMoveObservable: BABYLON.Observable<BABYLON.Vector2>;
@@ -953,6 +988,10 @@ declare module BABYLON.GUI {
             };
             /** Gets or sets alpha value for the control (1 means opaque and 0 means entirely transparent) */
             alpha: number;
+            /**
+                * Gets or sets a boolean indicating that we want to highlight the control (mostly for debugging purpose)
+                */
+            isHighlighted: boolean;
             /** Gets or sets a value indicating the scale factor on X axis (1 by default)
                 * @see http://doc.babylonjs.com/how_to/gui#rotation-and-scaling
              */
@@ -1164,6 +1203,15 @@ declare module BABYLON.GUI {
                 * @param scene defines the hosting scene
                 */
             moveToVector3(position: BABYLON.Vector3, scene: BABYLON.Scene): void;
+            /** @hidden */
+            _getDescendants(results: Control[], directDescendantsOnly?: boolean, predicate?: (control: Control) => boolean): void;
+            /**
+                * Will return all controls that have this control as ascendant
+                * @param directDescendantsOnly defines if true only direct descendants of 'this' will be considered, if false direct and also indirect (children of children, an so on in a recursive manner) descendants of 'this' will be considered
+                * @param predicate defines an optional predicate that will be called on every evaluated child, the predicate must return true for a given child to be part of the result, otherwise it will be ignored
+                * @return all child controls
+                */
+            getDescendants(directDescendantsOnly?: boolean, predicate?: (control: Control) => boolean): Control[];
             /**
                 * Link current control with a target mesh
                 * @param mesh defines the mesh to link with
@@ -1185,6 +1233,10 @@ declare module BABYLON.GUI {
             /** @hidden */
             protected _transform(context: CanvasRenderingContext2D): void;
             /** @hidden */
+            _renderHighlight(context: CanvasRenderingContext2D): void;
+            /** @hidden */
+            protected _renderHighlightSpecific(context: CanvasRenderingContext2D): void;
+            /** @hidden */
             protected _applyStates(context: CanvasRenderingContext2D): void;
             /** @hidden */
             protected _processMeasures(parentMeasure: Measure, context: CanvasRenderingContext2D): boolean;
@@ -1363,7 +1415,10 @@ declare module BABYLON.GUI {
                 */
             constructor(name?: string | undefined);
             protected _getTypeName(): string;
+            protected _getGridDefinitions(definitionCallback: (lefts: number[], tops: number[], widths: number[], heights: number[]) => void): void;
             protected _additionalProcessing(parentMeasure: Measure, context: CanvasRenderingContext2D): void;
+            _flagDescendantsAsMatrixDirty(): void;
+            protected _renderHighlightSpecific(context: CanvasRenderingContext2D): void;
             /** Releases associated resources */
             dispose(): void;
     }
@@ -2458,6 +2513,11 @@ declare module BABYLON.GUI {
                 * Gets a string representing the class name
                 */
             readonly typeName: string;
+            /**
+                * Get the current class name of the control.
+                * @returns current class name
+                */
+            getClassName(): string;
             protected _getTypeName(): string;
             /**
                 * Gets the transform node used by this control

Failā izmaiņas netiks attēlotas, jo tās ir par lielu
+ 1 - 1
dist/preview release/gui/babylon.gui.js


Failā izmaiņas netiks attēlotas, jo tās ir par lielu
+ 1 - 1
dist/preview release/gui/babylon.gui.min.js


Failā izmaiņas netiks attēlotas, jo tās ir par lielu
+ 1 - 1
dist/preview release/gui/babylon.gui.min.js.map


+ 122 - 2
dist/preview release/gui/babylon.gui.module.d.ts

@@ -1,4 +1,4 @@
-/*BabylonJS GUI*/
+/*Babylon.js GUI*/
 // Dependencies for this module:
 //   ../../../../Tools/Gulp/babylonjs
 
@@ -112,6 +112,10 @@ declare module 'babylonjs-gui/2D/advancedDynamicTexture' {
                 */
             onClipboardObservable: Observable<ClipboardInfo>;
             /**
+                * Observable event triggered each time a pointer down is intercepted by a control
+                */
+            onControlPickedObservable: Observable<Control>;
+            /**
                 * Gets or sets a boolean defining if alpha is stored as premultiplied
                 */
             premulAlpha: boolean;
@@ -153,6 +157,19 @@ declare module 'babylonjs-gui/2D/advancedDynamicTexture' {
                 */
             readonly rootContainer: Container;
             /**
+                * Returns an array containing the root container.
+                * This is mostly used to let the Inspector introspects the ADT
+                * @returns an array containing the rootContainer
+                */
+            getChildren(): Array<Container>;
+            /**
+                * Will return all controls that are inside this texture
+                * @param directDescendantsOnly defines if true only direct descendants of 'this' will be considered, if false direct and also indirect (children of children, an so on in a recursive manner) descendants of 'this' will be considered
+                * @param predicate defines an optional predicate that will be called on every evaluated child, the predicate must return true for a given child to be part of the result, otherwise it will be ignored
+                * @return all child controls
+                */
+            getDescendants(directDescendantsOnly?: boolean, predicate?: (control: Control) => boolean): Control[];
+            /**
                 * Gets or sets the current focused control
                 */
             focusedControl: Nullable<IFocusableControl>;
@@ -175,6 +192,11 @@ declare module 'babylonjs-gui/2D/advancedDynamicTexture' {
              */
             constructor(name: string, width: number | undefined, height: number | undefined, scene: Nullable<Scene>, generateMipMaps?: boolean, samplingMode?: number);
             /**
+                * Get the current class name of the texture useful for serialization or dynamic coding.
+                * @returns "AdvancedDynamicTexture"
+                */
+            getClassName(): string;
+            /**
                 * Function used to execute a function on all controls
                 * @param func defines the function to execute
                 * @param container defines the container where controls belong. If null the root container will be used
@@ -218,6 +240,8 @@ declare module 'babylonjs-gui/2D/advancedDynamicTexture' {
             /** @hidden */
             _changeCursor(cursor: string): void;
             /** @hidden */
+            _registerLastControlDown(control: Control, pointerId: number): void;
+            /** @hidden */
             _cleanControlAfterRemovalFromList(list: {
                     [pointerId: number]: Control;
             }, control: Control): void;
@@ -919,6 +943,8 @@ declare module 'babylonjs-gui/2D/controls/container' {
             /** @hidden */
             _draw(parentMeasure: Measure, context: CanvasRenderingContext2D): void;
             /** @hidden */
+            _getDescendants(results: Control[], directDescendantsOnly?: boolean, predicate?: (control: Control) => boolean): void;
+            /** @hidden */
             _processPicking(x: number, y: number, type: number, pointerId: number, buttonIndex: number): boolean;
             /** @hidden */
             protected _clipForChildren(context: CanvasRenderingContext2D): void;
@@ -989,6 +1015,10 @@ declare module 'babylonjs-gui/2D/controls/control' {
             /** @hidden */
             _tag: any;
             /**
+                * Gets or sets the unique id of the node. Please note that this number will be updated when the control is added to a container
+                */
+            uniqueId: number;
+            /**
                 * Gets or sets an object used to store user defined information for the node
                 */
             metadata: any;
@@ -1017,6 +1047,11 @@ declare module 'babylonjs-gui/2D/controls/control' {
             /** Gets the control type name */
             readonly typeName: string;
             /**
+                * Get the current class name of the control.
+                * @returns current class name
+                */
+            getClassName(): string;
+            /**
              * An event triggered when the pointer move over the control.
              */
             onPointerMoveObservable: Observable<Vector2>;
@@ -1060,6 +1095,10 @@ declare module 'babylonjs-gui/2D/controls/control' {
             };
             /** Gets or sets alpha value for the control (1 means opaque and 0 means entirely transparent) */
             alpha: number;
+            /**
+                * Gets or sets a boolean indicating that we want to highlight the control (mostly for debugging purpose)
+                */
+            isHighlighted: boolean;
             /** Gets or sets a value indicating the scale factor on X axis (1 by default)
                 * @see http://doc.babylonjs.com/how_to/gui#rotation-and-scaling
              */
@@ -1271,6 +1310,15 @@ declare module 'babylonjs-gui/2D/controls/control' {
                 * @param scene defines the hosting scene
                 */
             moveToVector3(position: Vector3, scene: Scene): void;
+            /** @hidden */
+            _getDescendants(results: Control[], directDescendantsOnly?: boolean, predicate?: (control: Control) => boolean): void;
+            /**
+                * Will return all controls that have this control as ascendant
+                * @param directDescendantsOnly defines if true only direct descendants of 'this' will be considered, if false direct and also indirect (children of children, an so on in a recursive manner) descendants of 'this' will be considered
+                * @param predicate defines an optional predicate that will be called on every evaluated child, the predicate must return true for a given child to be part of the result, otherwise it will be ignored
+                * @return all child controls
+                */
+            getDescendants(directDescendantsOnly?: boolean, predicate?: (control: Control) => boolean): Control[];
             /**
                 * Link current control with a target mesh
                 * @param mesh defines the mesh to link with
@@ -1292,6 +1340,10 @@ declare module 'babylonjs-gui/2D/controls/control' {
             /** @hidden */
             protected _transform(context: CanvasRenderingContext2D): void;
             /** @hidden */
+            _renderHighlight(context: CanvasRenderingContext2D): void;
+            /** @hidden */
+            protected _renderHighlightSpecific(context: CanvasRenderingContext2D): void;
+            /** @hidden */
             protected _applyStates(context: CanvasRenderingContext2D): void;
             /** @hidden */
             protected _processMeasures(parentMeasure: Measure, context: CanvasRenderingContext2D): boolean;
@@ -1478,7 +1530,10 @@ declare module 'babylonjs-gui/2D/controls/grid' {
                 */
             constructor(name?: string | undefined);
             protected _getTypeName(): string;
+            protected _getGridDefinitions(definitionCallback: (lefts: number[], tops: number[], widths: number[], heights: number[]) => void): void;
             protected _additionalProcessing(parentMeasure: Measure, context: CanvasRenderingContext2D): void;
+            _flagDescendantsAsMatrixDirty(): void;
+            protected _renderHighlightSpecific(context: CanvasRenderingContext2D): void;
             /** Releases associated resources */
             dispose(): void;
     }
@@ -2648,6 +2703,11 @@ declare module 'babylonjs-gui/3D/controls/control3D' {
                 * Gets a string representing the class name
                 */
             readonly typeName: string;
+            /**
+                * Get the current class name of the control.
+                * @returns current class name
+                */
+            getClassName(): string;
             protected _getTypeName(): string;
             /**
                 * Gets the transform node used by this control
@@ -2991,7 +3051,7 @@ declare module 'babylonjs-gui/3D/materials/fluentMaterial' {
 }
 
 
-/*BabylonJS GUI*/
+/*Babylon.js GUI*/
 // Dependencies for this module:
 //   ../../../../Tools/Gulp/babylonjs
 declare module BABYLON.GUI {
@@ -3060,6 +3120,10 @@ declare module BABYLON.GUI {
                 */
             onClipboardObservable: BABYLON.Observable<BABYLON.ClipboardInfo>;
             /**
+                * BABYLON.Observable event triggered each time a pointer down is intercepted by a control
+                */
+            onControlPickedObservable: BABYLON.Observable<Control>;
+            /**
                 * Gets or sets a boolean defining if alpha is stored as premultiplied
                 */
             premulAlpha: boolean;
@@ -3101,6 +3165,19 @@ declare module BABYLON.GUI {
                 */
             readonly rootContainer: Container;
             /**
+                * Returns an array containing the root container.
+                * This is mostly used to let the Inspector introspects the ADT
+                * @returns an array containing the rootContainer
+                */
+            getChildren(): Array<Container>;
+            /**
+                * Will return all controls that are inside this texture
+                * @param directDescendantsOnly defines if true only direct descendants of 'this' will be considered, if false direct and also indirect (children of children, an so on in a recursive manner) descendants of 'this' will be considered
+                * @param predicate defines an optional predicate that will be called on every evaluated child, the predicate must return true for a given child to be part of the result, otherwise it will be ignored
+                * @return all child controls
+                */
+            getDescendants(directDescendantsOnly?: boolean, predicate?: (control: Control) => boolean): Control[];
+            /**
                 * Gets or sets the current focused control
                 */
             focusedControl: BABYLON.Nullable<IFocusableControl>;
@@ -3123,6 +3200,11 @@ declare module BABYLON.GUI {
              */
             constructor(name: string, width: number | undefined, height: number | undefined, scene: BABYLON.Nullable<BABYLON.Scene>, generateMipMaps?: boolean, samplingMode?: number);
             /**
+                * Get the current class name of the texture useful for serialization or dynamic coding.
+                * @returns "AdvancedDynamicTexture"
+                */
+            getClassName(): string;
+            /**
                 * Function used to execute a function on all controls
                 * @param func defines the function to execute
                 * @param container defines the container where controls belong. If null the root container will be used
@@ -3166,6 +3248,8 @@ declare module BABYLON.GUI {
             /** @hidden */
             _changeCursor(cursor: string): void;
             /** @hidden */
+            _registerLastControlDown(control: Control, pointerId: number): void;
+            /** @hidden */
             _cleanControlAfterRemovalFromList(list: {
                     [pointerId: number]: Control;
             }, control: Control): void;
@@ -3813,6 +3897,8 @@ declare module BABYLON.GUI {
             /** @hidden */
             _draw(parentMeasure: Measure, context: CanvasRenderingContext2D): void;
             /** @hidden */
+            _getDescendants(results: Control[], directDescendantsOnly?: boolean, predicate?: (control: Control) => boolean): void;
+            /** @hidden */
             _processPicking(x: number, y: number, type: number, pointerId: number, buttonIndex: number): boolean;
             /** @hidden */
             protected _clipForChildren(context: CanvasRenderingContext2D): void;
@@ -3875,6 +3961,10 @@ declare module BABYLON.GUI {
             /** @hidden */
             _tag: any;
             /**
+                * Gets or sets the unique id of the node. Please note that this number will be updated when the control is added to a container
+                */
+            uniqueId: number;
+            /**
                 * Gets or sets an object used to store user defined information for the node
                 */
             metadata: any;
@@ -3903,6 +3993,11 @@ declare module BABYLON.GUI {
             /** Gets the control type name */
             readonly typeName: string;
             /**
+                * Get the current class name of the control.
+                * @returns current class name
+                */
+            getClassName(): string;
+            /**
              * An event triggered when the pointer move over the control.
              */
             onPointerMoveObservable: BABYLON.Observable<BABYLON.Vector2>;
@@ -3946,6 +4041,10 @@ declare module BABYLON.GUI {
             };
             /** Gets or sets alpha value for the control (1 means opaque and 0 means entirely transparent) */
             alpha: number;
+            /**
+                * Gets or sets a boolean indicating that we want to highlight the control (mostly for debugging purpose)
+                */
+            isHighlighted: boolean;
             /** Gets or sets a value indicating the scale factor on X axis (1 by default)
                 * @see http://doc.babylonjs.com/how_to/gui#rotation-and-scaling
              */
@@ -4157,6 +4256,15 @@ declare module BABYLON.GUI {
                 * @param scene defines the hosting scene
                 */
             moveToVector3(position: BABYLON.Vector3, scene: BABYLON.Scene): void;
+            /** @hidden */
+            _getDescendants(results: Control[], directDescendantsOnly?: boolean, predicate?: (control: Control) => boolean): void;
+            /**
+                * Will return all controls that have this control as ascendant
+                * @param directDescendantsOnly defines if true only direct descendants of 'this' will be considered, if false direct and also indirect (children of children, an so on in a recursive manner) descendants of 'this' will be considered
+                * @param predicate defines an optional predicate that will be called on every evaluated child, the predicate must return true for a given child to be part of the result, otherwise it will be ignored
+                * @return all child controls
+                */
+            getDescendants(directDescendantsOnly?: boolean, predicate?: (control: Control) => boolean): Control[];
             /**
                 * Link current control with a target mesh
                 * @param mesh defines the mesh to link with
@@ -4178,6 +4286,10 @@ declare module BABYLON.GUI {
             /** @hidden */
             protected _transform(context: CanvasRenderingContext2D): void;
             /** @hidden */
+            _renderHighlight(context: CanvasRenderingContext2D): void;
+            /** @hidden */
+            protected _renderHighlightSpecific(context: CanvasRenderingContext2D): void;
+            /** @hidden */
             protected _applyStates(context: CanvasRenderingContext2D): void;
             /** @hidden */
             protected _processMeasures(parentMeasure: Measure, context: CanvasRenderingContext2D): boolean;
@@ -4356,7 +4468,10 @@ declare module BABYLON.GUI {
                 */
             constructor(name?: string | undefined);
             protected _getTypeName(): string;
+            protected _getGridDefinitions(definitionCallback: (lefts: number[], tops: number[], widths: number[], heights: number[]) => void): void;
             protected _additionalProcessing(parentMeasure: Measure, context: CanvasRenderingContext2D): void;
+            _flagDescendantsAsMatrixDirty(): void;
+            protected _renderHighlightSpecific(context: CanvasRenderingContext2D): void;
             /** Releases associated resources */
             dispose(): void;
     }
@@ -5451,6 +5566,11 @@ declare module BABYLON.GUI {
                 * Gets a string representing the class name
                 */
             readonly typeName: string;
+            /**
+                * Get the current class name of the control.
+                * @returns current class name
+                */
+            getClassName(): string;
             protected _getTypeName(): string;
             /**
                 * Gets the transform node used by this control

Failā izmaiņas netiks attēlotas, jo tās ir par lielu
+ 36120 - 1
dist/preview release/inspector/babylon.inspector.bundle.js


Failā izmaiņas netiks attēlotas, jo tās ir par lielu
+ 1 - 1
dist/preview release/inspector/babylon.inspector.bundle.js.map


+ 12 - 967
dist/preview release/inspector/babylon.inspector.d.ts

@@ -1,978 +1,23 @@
-/*BabylonJS Inspector*/
+/*Babylon.js Inspector*/
 // Dependencies for this module:
 //   ../../../../Tools/Gulp/babylonjs
 declare module INSPECTOR {
 }
 declare module INSPECTOR {
-}
-declare module INSPECTOR {
-}
-declare module INSPECTOR {
-}
-declare module INSPECTOR {
-}
-declare module INSPECTOR {
-}
-declare module INSPECTOR {
-}
-declare module INSPECTOR {
-    export class Tools {
-        static LookForItem(item: any, selectedEntity: any): boolean;
-        static SortAndFilter(items: any[]): any[];
-    }
-}
-declare module INSPECTOR {
-}
-declare module INSPECTOR {
-}
-export declare class Inspector {
-        /** The HTML document relative to this inspector (the window or the popup depending on its mode) */
-        static DOCUMENT: HTMLDocument;
-        /** The HTML window. In popup mode, it's the popup itself. Otherwise, it's the current tab */
-        static WINDOW: Window;
-        onGUILoaded: BABYLON.Observable<any>;
-        static GUIObject: any;
-        /** The inspector is created with the given engine.
-            * If the parameter 'popup' is false, the inspector is created as a right panel on the main window.
-            * If the parameter 'popup' is true, the inspector is created in another popup.
-            */
-        constructor(scene: BABYLON.Scene, popup?: boolean, initialTab?: number | string, parentElement?: BABYLON.Nullable<HTMLElement>, newColors?: {
-                backgroundColor?: string;
-                backgroundColorLighter?: string;
-                backgroundColorLighter2?: string;
-                backgroundColorLighter3?: string;
-                color?: string;
-                colorTop?: string;
-                colorBot?: string;
-        });
-        readonly scene: BABYLON.Scene;
-        readonly 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
-            */
-        dispose(): void;
-        /** Open the inspector in a new popup
-            * Set 'firstTime' to true if there is no inspector created beforehands
-            */
-        openPopup(firstTime?: boolean): void;
-        getActiveTabIndex(): number;
-}
-declare module INSPECTOR {
-    export const PROPERTIES: {
-        /** Format the given object :
-          * If a format function exists, returns the result of this function.
-          * If this function doesn't exists, return the object type instead
-          */
-        format: (obj: any) => any;
-        'type_not_defined': {
-            properties: any[];
-            format: () => string;
-        };
-        'Vector2': {
-            type: typeof BABYLON.Vector2;
-            format: (vec: BABYLON.Vector2) => string;
-        };
-        'Vector3': {
-            type: typeof BABYLON.Vector3;
-            format: (vec: BABYLON.Vector3) => string;
-        };
-        'Color3': {
-            type: typeof BABYLON.Color3;
-            format: (color: BABYLON.Color3) => string;
-            slider: {
-                r: {
-                    min: number;
-                    max: number;
-                    step: number;
-                };
-                g: {
-                    min: number;
-                    max: number;
-                    step: number;
-                };
-                b: {
-                    min: number;
-                    max: number;
-                    step: number;
-                };
-            };
-        };
-        'Color4': {
-            type: typeof BABYLON.Color4;
-            format: (color: BABYLON.Color4) => string;
-            slider: {
-                r: {
-                    min: number;
-                    max: number;
-                    step: number;
-                };
-                g: {
-                    min: number;
-                    max: number;
-                    step: number;
-                };
-                b: {
-                    min: number;
-                    max: number;
-                    step: number;
-                };
-            };
-        };
-        'Quaternion': {
-            type: typeof BABYLON.Quaternion;
-        };
-        'Size': {
-            type: typeof BABYLON.Size;
-            format: (size: BABYLON.Size) => string;
-        };
-        'Texture': {
-            type: typeof BABYLON.Texture;
-            format: (tex: BABYLON.Texture) => string;
-        };
-        'RenderTargetTexture': {
-            type: typeof BABYLON.RenderTargetTexture;
-        };
-        'DynamicTexture': {
-            type: typeof BABYLON.DynamicTexture;
-        };
-        'BaseTexture': {
-            type: typeof BABYLON.BaseTexture;
-        };
-        'CubeTexture': {
-            type: typeof BABYLON.CubeTexture;
-        };
-        'HDRCubeTexture': {
-            type: typeof BABYLON.HDRCubeTexture;
-        };
-        'Sound': {
-            type: typeof BABYLON.Sound;
-        };
-        'ArcRotateCamera': {
-            type: typeof BABYLON.ArcRotateCamera;
-            slider: {
-                alpha: {
-                    min: number;
-                    max: number;
-                    step: number;
-                };
-                beta: {
-                    min: number;
-                    max: number;
-                    step: number;
-                };
-                fov: {
-                    min: number;
-                    max: number;
-                    step: number;
-                };
-            };
-        };
-        'FreeCamera': {
-            type: typeof BABYLON.FreeCamera;
-            slider: {
-                fov: {
-                    min: number;
-                    max: number;
-                    step: number;
-                };
-            };
-        };
-        'Scene': {
-            type: typeof BABYLON.Scene;
-        };
-        'TransformNode': {
-            type: typeof BABYLON.TransformNode;
-            format: (m: BABYLON.TransformNode) => string;
-        };
-        'AbstractMesh': {
-            type: typeof BABYLON.AbstractMesh;
-            format: (m: BABYLON.AbstractMesh) => string;
-        };
-        'Mesh': {
-            type: typeof BABYLON.Mesh;
-            format: (m: BABYLON.Mesh) => string;
-            slider: {
-                visibility: {
-                    min: number;
-                    max: number;
-                    step: number;
-                };
-            };
-        };
-        'StandardMaterial': {
-            type: typeof BABYLON.StandardMaterial;
-            format: (mat: BABYLON.StandardMaterial) => string;
-            slider: {
-                alpha: {
-                    min: number;
-                    max: number;
-                    step: number;
-                };
-            };
-        };
-        'PBRMaterial': {
-            type: typeof BABYLON.PBRMaterial;
-            slider: {
-                alpha: {
-                    min: number;
-                    max: number;
-                    step: number;
-                };
-            };
-        };
-        'PhysicsImpostor': {
-            type: typeof BABYLON.PhysicsImpostor;
-        };
-        'ImageProcessingConfiguration': {
-            type: typeof BABYLON.ImageProcessingConfiguration;
-        };
-        'ColorCurves': {
-            type: typeof BABYLON.ColorCurves;
-        };
-    };
-}
-declare module INSPECTOR {
-    export type GUITyping = any;
-    export let guiLoaded: boolean;
-    /**
-       * Function that add gui objects properties to the variable PROPERTIES
-       */
-    export function loadGUIProperties(GUI: GUITyping): void;
-}
-declare module INSPECTOR {
-    export abstract class Adapter {
-            protected _obj: any;
-            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 true if the given object correspond to this  */
-            correspondsTo(obj: any): boolean;
-            /** Returns the adapter unique name */
-            readonly name: string;
-            /**
-                * Returns the actual object used for this adapter
-                */
-            readonly object: any;
-            /** Returns the list of tools available for this adapter */
-            abstract getTools(): Array<AbstractTreeTool>;
-    }
-}
-declare module INSPECTOR {
-    export class CameraAdapter extends Adapter implements ICameraPOV {
-        constructor(obj: BABYLON.Camera);
-        /** 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>;
-        setPOV(): void;
-        getCurrentActiveCamera(): string;
-    }
-}
-declare module INSPECTOR {
-    export class GUIAdapter extends Adapter implements IToolVisible {
-        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;
-    }
-}
-declare module INSPECTOR {
-    export class LightAdapter extends Adapter implements IToolVisible {
-        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;
-    }
-}
-declare module INSPECTOR {
-    export 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>;
-    }
-}
-declare module INSPECTOR {
-    export class MeshAdapter extends Adapter implements IToolVisible, IToolDebug, IToolBoundingBox, IToolInfo {
-            constructor(mesh: BABYLON.Node);
-            /** 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(enable: boolean): void;
-            /** Returns some information about this mesh */
-            getInfo(): string;
-    }
-}
-declare module INSPECTOR {
-    export class PhysicsImpostorAdapter extends Adapter implements IToolVisible {
-        constructor(obj: BABYLON.PhysicsImpostor, viewer: 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;
+    export class Inspector {
+        static OnSelectionChangeObservable: BABYLON.Observable<string>;
+        static OnPropertyChangedObservable: BABYLON.Observable<PropertyChangedEvent>;
+        static readonly IsVisible: boolean;
+        static EarlyAttachToLoader(): void;
+        static Show(scene: BABYLON.Scene, userOptions: Partial<BABYLON.IInspectorOptions>): void;
+        static Hide(): void;
     }
 }
 declare module INSPECTOR {
-    export class SoundAdapter extends Adapter implements ISoundInteractions {
-        constructor(obj: BABYLON.Sound);
-        /** 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>;
-        setPlaying(callback: Function): void;
-    }
-}
-declare module INSPECTOR {
-    export class TextureAdapter extends Adapter {
-        constructor(obj: BABYLON.BaseTexture);
-        /** 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>;
-    }
-}
-declare module INSPECTOR {
-    export interface SortDirection {
-            [property: string]: number;
-    }
-    export class DetailPanel extends BasicElement {
-            constructor(dr?: Array<PropertyLine>);
-            details: Array<PropertyLine>;
-            protected _build(): void;
-            /** Updates the HTML of the detail panel */
-            update(_items?: Array<PropertyLine>): void;
-            /** Search an element by name  */
-            searchByName(searchName: string): void;
-            /**
-                * Removes all data in the detail panel but keep the header row
-                */
-            clean(): void;
-            /**
-                * Clean the rows only
-                */
-            cleanRow(): void;
-            /** Overrides basicelement.dispose */
-            dispose(): void;
-    }
-}
-declare module INSPECTOR {
-    /**
-      * A property is a link between a data (string) and an object.
-      */
-    export class Property {
-        constructor(prop: string, obj: any, parentObj?: any);
-        readonly name: string;
+    export class PropertyChangedEvent {
+        object: any;
+        property: string;
         value: any;
-        readonly type: string;
-        obj: any;
-    }
-}
-declare module INSPECTOR {
-    export 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, BABYLON.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).
-        *
-        */
-    export class PropertyLine {
-            constructor(prop: Property, parent?: BABYLON.Nullable<PropertyLine>, level?: number);
-            validateInput(value: any, forceupdate?: boolean): void;
-            /** 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;
-            readonly name: string;
-            readonly value: any;
-            readonly type: string;
-            /** Delete properly this property line.
-                * Removes itself from the scheduler.
-                * Dispose all viewer element (color, texture...)
-                */
-            dispose(): void;
-            /**
-                * Update the property division with the new property value.
-                * If this property is complex, update its child, otherwise update its text content
-                */
-            update(): void;
-            toHtml(): HTMLElement;
-            closeDetails(): void;
-    }
-}
-declare module INSPECTOR {
-    /**
-        * Represents a html div element.
-        * The div is built when an instance of BasicElement is created.
-        */
-    export abstract class BasicElement {
-            protected _div: HTMLDivElement;
-            constructor();
-            /**
-                * Returns the div element
-                */
-            toHtml(): HTMLDivElement;
-            /**
-                * Build the html element
-                */
-            protected _build(): void;
-            abstract update(data?: any): void;
-            /** Default dispose method if needed */
-            dispose(): void;
-    }
-}
-declare module INSPECTOR {
-    /**
-     * Display a very small div corresponding to the given color
-     */
-    export class ColorElement extends BasicElement {
-        constructor(color: BABYLON.Color4 | BABYLON.Color3);
-        update(color?: BABYLON.Color4 | BABYLON.Color3): void;
-    }
-}
-declare module INSPECTOR {
-    /**
-      * Represents a html div element.
-      * The div is built when an instance of BasicElement is created.
-      */
-    export class ColorPickerElement extends BasicElement {
-        protected _input: HTMLInputElement;
-        constructor(color: BABYLON.Color4 | BABYLON.Color3, propertyLine: PropertyLine);
-        update(color?: BABYLON.Color4 | BABYLON.Color3): void;
-    }
-}
-declare module INSPECTOR {
-    /**
-     * Display a very small div. A new canvas is created, with a new js scene, containing only the
-     * cube texture in a cube
-     */
-    export class CubeTextureElement extends BasicElement {
-        protected _scene: BABYLON.Scene;
-        protected _cube: BABYLON.Mesh;
-        protected _textureUrl: string;
-        /** The texture given as a parameter should be cube. */
-        constructor(tex: BABYLON.Texture);
-        update(tex?: BABYLON.Texture): void;
-        /** Creates the box  */
-        protected _populateScene(): void;
-        /** Removes properly the babylon engine */
-        dispose(): void;
-    }
-}
-declare module INSPECTOR {
-    /**
-     * Display a very small div. A new canvas is created, with a new js scene, containing only the
-     * cube texture in a cube
-     */
-    export class HDRCubeTextureElement extends CubeTextureElement {
-        /** The texture given as a parameter should be cube. */
-        constructor(tex: BABYLON.Texture);
-        /** Creates the box  */
-        protected _populateScene(): void;
-    }
-}
-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.
-      */
-    export class SearchBar extends BasicElement {
-        constructor(tab: PropertyTab);
-        /** Delete all characters typped in the input element */
-        reset(): void;
-        update(): void;
-    }
-    export class SearchBarDetails extends BasicElement {
-        constructor(tab: DetailPanel);
-        /** Delete all characters typped in the input element */
-        reset(): void;
-        update(): void;
-    }
-}
-declare module INSPECTOR {
-    /**
-     * Display a very small div corresponding to the given texture. On mouse over, display the full image
-     */
-    export class TextureElement extends BasicElement {
-        constructor(tex: BABYLON.Texture);
-        update(tex?: BABYLON.Texture): void;
-    }
-}
-declare module INSPECTOR {
-    /**
-      * Creates a tooltip for the parent of the given html element
-      */
-    export class Tooltip {
-        constructor(elem: HTMLElement, tip: string, attachTo?: BABYLON.Nullable<HTMLElement>);
-    }
-}
-declare module INSPECTOR {
-    export class Helpers {
-            /**
-                * Returns the type of the given object. First
-                * uses getClassName. If nothing is returned, used the type of the constructor
-                */
-            static GET_TYPE(obj: any): string;
-            /**
-                * Returns true if the user browser is edge.
-                */
-            static IsBrowserEdge(): boolean;
-            /**
-                * Returns true if the user browser is IE.
-                */
-            static IsBrowserIE(): boolean;
-            /** 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: number): number;
-            /**
-                * Useful function used to create a div
-                */
-            static CreateDiv(className?: BABYLON.Nullable<string>, parent?: HTMLElement, tooltip?: string): HTMLDivElement;
-            /**
-                * Useful function used to create a input
-                */
-            static CreateInput(className?: string, parent?: HTMLElement, tooltip?: string): HTMLInputElement;
-            static CreateElement(element: string, className?: BABYLON.Nullable<string>, parent?: HTMLElement, tooltip?: string): HTMLElement;
-            /**
-                * Removes all children of the given div.
-                */
-            static CleanDiv(div: HTMLElement): void;
-            /**
-                * Returns the true value of the given CSS Attribute from the given element (in percentage or in pixel, as it was specified in the css)
-                */
-            static Css(elem: HTMLElement, cssAttribute: string): string;
-            static LoadScript(): void;
-            static IsSystemName(name: string): boolean;
-            /**
-                * Return an array of PropertyLine for an obj
-                * @param obj
-                */
-            static GetAllLinesProperties(obj: any): Array<PropertyLine>;
-            /**
-                * Returns an array of string corresponding to tjhe list of properties of the object to be displayed
-                * @param obj
-                */
-            static GetAllLinesPropertiesAsString(obj: any, dontTakeThis?: Array<string>): Array<string>;
-            static Capitalize(str: string): string;
-    }
-}
-declare module INSPECTOR {
-    export class Scheduler {
-        /** Is this scheduler in pause ? */
-        pause: boolean;
-        /** All properties are refreshed every 250ms */
-        static REFRESH_TIME: number;
-        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;
-        dispose(): void;
-    }
-}
-declare module INSPECTOR {
-    export class CameraTab extends PropertyTab {
-        constructor(tabbar: TabBar, inspector: Inspector);
-        protected _getTree(): Array<TreeItem>;
-    }
-}
-declare module INSPECTOR {
-    /**
-      * The console tab will have two features :
-      * - hook all console.log call and display them in this panel (and in the browser console as well)
-      * - display all Babylon logs (called with Tools.Log...)
-      */
-    export class ConsoleTab extends Tab {
-        constructor(tabbar: TabBar, insp: Inspector);
-        /** Overrides super.dispose */
-        dispose(): void;
-        active(b: boolean): void;
-    }
-}
-declare module INSPECTOR {
-    export class GLTFTab extends Tab {
-        static readonly IsSupported: boolean;
-        /** @hidden */
-        static _Initialize(): void;
-        constructor(tabbar: TabBar, inspector: Inspector);
-        dispose(): void;
-        /** @hidden */
-        static _GetLoaderDefaultsAsync(): Promise<any>;
-    }
-}
-declare module INSPECTOR {
-    export class GUITab extends PropertyTab {
-        constructor(tabbar: TabBar, inspector: Inspector);
-        protected _getTree(): Array<TreeItem>;
-    }
-}
-declare module INSPECTOR {
-    export class LightTab extends PropertyTab {
-        constructor(tabbar: TabBar, inspector: Inspector);
-        protected _getTree(): Array<TreeItem>;
-    }
-}
-declare module INSPECTOR {
-    export class MaterialTab extends PropertyTab {
-        constructor(tabbar: TabBar, inspector: Inspector);
-        protected _getTree(): Array<TreeItem>;
-    }
-}
-declare module INSPECTOR {
-    export class MeshTab extends PropertyTab {
-        constructor(tabbar: TabBar, inspector: Inspector);
-        protected _getTree(): Array<TreeItem>;
-    }
-}
-declare module INSPECTOR {
-    export class PhysicsTab extends PropertyTab {
-        viewer: any;
-        constructor(tabbar: TabBar, inspector: Inspector);
-        protected _getTree(): Array<TreeItem>;
-    }
-}
-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
-      */
-    export abstract class PropertyTab extends Tab {
-        protected _inspector: Inspector;
-        /** The panel containing a list of items */
-        protected _treePanel: HTMLDivElement;
-        /** 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;
-        /** 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): BABYLON.Nullable<TreeItem>;
-        filter(filter: string): void;
-        /** Builds the tree panel */
-        protected abstract _getTree(): Array<TreeItem>;
-    }
-}
-declare module INSPECTOR {
-    export class SceneTab extends Tab {
-            constructor(tabbar: TabBar, insp: Inspector);
-            /** Overrides super.dispose */
-            dispose(): void;
-    }
-}
-declare module INSPECTOR {
-    export class SoundTab extends PropertyTab {
-        constructor(tabbar: TabBar, inspector: Inspector);
-        protected _getTree(): Array<TreeItem>;
-    }
-}
-declare module INSPECTOR {
-    export class StatsTab extends Tab {
-        constructor(tabbar: TabBar, insp: Inspector);
-        dispose(): void;
-        active(b: boolean): void;
-    }
-}
-declare module INSPECTOR {
-    export 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(): void;
-            /** Select an item in the tree */
-            select(item: TreeItem): void;
-            /**
-                * Returns the total width in pixel of this tab, 0 by default
-             */
-            getPixelWidth(): number;
-    }
-}
-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.
-        */
-    export class TabBar extends BasicElement {
-            constructor(inspector: Inspector, initialTab?: number | string);
-            update(): void;
-            protected _build(): void;
-            /** 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(): BABYLON.Nullable<Tab>;
-            getActiveTabIndex(): number;
-            getTabIndex(name: string): number;
-            readonly 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;
-    }
-}
-declare module INSPECTOR {
-    export class TextureTab extends Tab {
-        static DDSPreview: DDSPreview;
-        /** The panel containing a list of items */
-        protected _treePanel: HTMLElement;
-        protected _treeItems: Array<TreeItem>;
-        constructor(tabbar: TabBar, inspector: Inspector);
-        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;
-        /** Set the given item as active in the tree */
-        activateNode(item: TreeItem): void;
-    }
-    class DDSPreview {
-        canvas: HTMLCanvasElement | null;
-        constructor(AdapterItem: TextureAdapter);
-        insertPreview(AdapterItem: TextureAdapter): void;
-        dispose(): void;
-    }
-}
-declare module INSPECTOR {
-    export class ToolsTab extends Tab {
-        constructor(tabbar: TabBar, insp: Inspector);
-        dispose(): void;
-    }
-}
-declare module INSPECTOR {
-    export class TreeItem extends BasicElement {
-            children: Array<TreeItem>;
-            constructor(tab: Tab, obj: Adapter);
-            /** Returns the item ID == its adapter ID */
-            readonly id: string;
-            /** Add the given item as a child of this one */
-            add(child: TreeItem): void;
-            /**
-                * Returns the original adapter
-                */
-            readonly adapter: Adapter;
-            /**
-                * 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
-                */
-            protected _addEvent(): void;
-            /** Set this item as active (background lighter) in the tree panel */
-            active(b: boolean): void;
-            getDiv(): HTMLDivElement;
-    }
-}
-declare module INSPECTOR {
-    export 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;
-    }
-}
-declare module INSPECTOR {
-    /** Any object implementing this interface should
-        * provide methods to toggle its bounding box
-        */
-    export interface IToolBoundingBox {
-            isBoxVisible: () => boolean;
-            setBoxVisible: (b: boolean) => void;
-    }
-    /**
-        * Checkbox to display/hide the primitive
-        */
-    export class BoundingBox extends AbstractTreeTool {
-            constructor(obj: IToolBoundingBox);
-            protected action(): void;
-    }
-}
-declare module INSPECTOR {
-    export interface ICameraPOV {
-        setPOV: () => void;
-        getCurrentActiveCamera: () => string;
-        id: () => string;
-    }
-    /**
-      *
-      */
-    export class CameraPOV extends AbstractTreeTool {
-        constructor(camera: ICameraPOV);
-        protected action(): void;
-    }
-}
-declare module INSPECTOR {
-    /** Any object implementing this interface should
-        * provide methods to toggle its visibility
-        */
-    export interface IToolVisible {
-            isVisible: () => boolean;
-            setVisible: (b: boolean) => void;
-    }
-    /**
-        * Checkbox to display/hide the primitive
-        */
-    export class Checkbox extends AbstractTreeTool {
-            constructor(obj: IToolVisible);
-            protected action(): void;
-    }
-}
-declare module INSPECTOR {
-    /** Any object implementing this interface should
-      * provide methods to toggle a debug area
-      */
-    export interface IToolDebug {
-        debug: (b: boolean) => void;
-    }
-    export class DebugArea extends AbstractTreeTool {
-        constructor(obj: IToolDebug);
-        protected action(): void;
-    }
-}
-declare module INSPECTOR {
-    /** Any object implementing this interface should
-        * provide methods to retrieve its info
-        */
-    export interface IToolInfo {
-            getInfo: () => string;
-    }
-    /**
-        * Checkbox to display/hide the primitive
-        */
-    export class Info extends AbstractTreeTool {
-            constructor(obj: IToolInfo);
-            protected action(): void;
-    }
-}
-declare module INSPECTOR {
-    export interface ISoundInteractions {
-        setPlaying: (callback: Function) => void;
-    }
-    /**
-      *
-      */
-    export class SoundInteractions extends AbstractTreeTool {
-        constructor(playSound: ISoundInteractions);
-        protected action(): void;
+        initialValue: any;
     }
 }

Failā izmaiņas netiks attēlotas, jo tās ir par lielu
+ 30 - 2342
dist/preview release/inspector/babylon.inspector.module.d.ts


+ 1 - 1
dist/preview release/inspector/readme.md

@@ -1,7 +1,7 @@
 Babylon.js inspector module
 =====================
 
-For usage documentation please visit http://doc.babylonjs.com/how_to/debug_layer and search "inspector".
+For usage documentation please visit http://doc.babylonjs.com/how_to/debug_layer.
 
 # Installation instructions
 

Failā izmaiņas netiks attēlotas, jo tās ir par lielu
+ 253 - 0
dist/preview release/materialsLibrary/babylon.gridMaterial.js


Failā izmaiņas netiks attēlotas, jo tās ir par lielu
+ 1 - 0
dist/preview release/materialsLibrary/babylon.gridMaterial.min.js


Failā izmaiņas netiks attēlotas, jo tās ir par lielu
+ 5061 - 0
dist/preview release/materialsLibrary/babylonjs.materials.js


Failā izmaiņas netiks attēlotas, jo tās ir par lielu
+ 1 - 0
dist/preview release/materialsLibrary/babylonjs.materials.min.js


Failā izmaiņas netiks attēlotas, jo tās ir par lielu
+ 1 - 1
dist/preview release/viewer/babylon.viewer.js


Failā izmaiņas netiks attēlotas, jo tās ir par lielu
+ 1 - 1
dist/preview release/viewer/babylon.viewer.max.js


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

@@ -2,6 +2,7 @@
 
 ## Major updates
 
+- [Inspector v2.0](https://doc.babylonjs.com/features/playground_debuglayer). [Dev log](https://medium.com/@babylonjs/dev-log-creating-the-new-inspector-b15c50900205) ([Deltakosh](https://github.com/deltakosh))
 - Added support for [parallel shader compilation](https://www.khronos.org/registry/webgl/extensions/KHR_parallel_shader_compile/) ([Deltakosh](https://github.com/deltakosh))
 - Added FlyCamera for free navigation in 3D space, with a limited set of settings ([Phuein](https://github.com/phuein)) [@NEED DEMO]
 - Added [Object Based Motion Blur](http://doc.babylonjs.com/how_to/using_motionblurpostprocess) post-process ([julien-moreau](https://github.com/julien-moreau))

+ 40 - 0
gui/src/2D/advancedDynamicTexture.ts

@@ -84,6 +84,11 @@ export class AdvancedDynamicTexture extends DynamicTexture {
     public onClipboardObservable = new Observable<ClipboardInfo>();
 
     /**
+     * Observable event triggered each time a pointer down is intercepted by a control
+     */
+    public onControlPickedObservable = new Observable<Control>();
+
+    /**
      * Gets or sets a boolean defining if alpha is stored as premultiplied
      */
     public premulAlpha = false;
@@ -208,6 +213,25 @@ export class AdvancedDynamicTexture extends DynamicTexture {
     }
 
     /**
+     * Returns an array containing the root container.
+     * This is mostly used to let the Inspector introspects the ADT
+     * @returns an array containing the rootContainer
+     */
+    public getChildren(): Array<Container> {
+        return [this._rootContainer];
+    }
+
+    /**
+     * Will return all controls that are inside this texture
+     * @param directDescendantsOnly defines if true only direct descendants of 'this' will be considered, if false direct and also indirect (children of children, an so on in a recursive manner) descendants of 'this' will be considered
+     * @param predicate defines an optional predicate that will be called on every evaluated child, the predicate must return true for a given child to be part of the result, otherwise it will be ignored
+     * @return all child controls
+     */
+    public getDescendants(directDescendantsOnly?: boolean, predicate?: (control: Control) => boolean): Control[] {
+        return this._rootContainer.getDescendants(directDescendantsOnly, predicate);
+    }
+
+    /**
      * Gets or sets the current focused control
      */
     public get focusedControl(): Nullable<IFocusableControl> {
@@ -306,6 +330,14 @@ export class AdvancedDynamicTexture extends DynamicTexture {
     }
 
     /**
+     * Get the current class name of the texture useful for serialization or dynamic coding.
+     * @returns "AdvancedDynamicTexture"
+     */
+    public getClassName(): string {
+        return "AdvancedDynamicTexture";
+    }
+
+    /**
      * Function used to execute a function on all controls
      * @param func defines the function to execute
      * @param container defines the container where controls belong. If null the root container will be used
@@ -405,6 +437,7 @@ export class AdvancedDynamicTexture extends DynamicTexture {
 
         this._rootContainer.dispose();
         this.onClipboardObservable.clear();
+        this.onControlPickedObservable.clear();
 
         super.dispose();
     }
@@ -558,6 +591,13 @@ export class AdvancedDynamicTexture extends DynamicTexture {
         }
     }
 
+    /** @hidden */
+    public _registerLastControlDown(control: Control, pointerId: number) {
+        this._lastControlDown[pointerId] = control;
+
+        this.onControlPickedObservable.notifyObservers(control);
+    }
+
     private _doPicking(x: number, y: number, type: number, pointerId: number, buttonIndex: number): void {
         var scene = this.getScene();
 

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

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

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

@@ -270,6 +270,7 @@ export class Container extends Control {
             }
 
             this._localDraw(context);
+            this._renderHighlight(context);
 
             if (this.clipChildren) {
                 this._clipForChildren(context);
@@ -283,6 +284,7 @@ export class Container extends Control {
                     child._tempParentMeasure.copyFrom(this._measureForChildren);
 
                     child._draw(this._measureForChildren, context);
+                    child._renderHighlight(context);
 
                     if (child.onAfterDrawObservable.hasObservers()) {
                         child.onAfterDrawObservable.notifyObservers(child);
@@ -318,6 +320,25 @@ export class Container extends Control {
     }
 
     /** @hidden */
+    public _getDescendants(results: Control[], directDescendantsOnly: boolean = false, predicate?: (control: Control) => boolean): void {
+        if (!this.children) {
+            return;
+        }
+
+        for (var index = 0; index < this.children.length; index++) {
+            var item = this.children[index];
+
+            if (!predicate || predicate(item)) {
+                results.push(item);
+            }
+
+            if (!directDescendantsOnly) {
+                item._getDescendants(results, false, predicate);
+            }
+        }
+    }
+
+    /** @hidden */
     public _processPicking(x: number, y: number, type: number, pointerId: number, buttonIndex: number): boolean {
         if (!this.isVisible || this.notRenderable) {
             return false;

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

@@ -73,6 +73,7 @@ export class Control {
     private _cachedOffsetX: number;
     private _cachedOffsetY: number;
     private _isVisible = true;
+    private _isHighlighted = false;
     /** @hidden */
     public _linkedMesh: Nullable<AbstractMesh>;
     private _fontSet = false;
@@ -87,6 +88,11 @@ export class Control {
     public _tag: any;
 
     /**
+     * Gets or sets the unique id of the node. Please note that this number will be updated when the control is added to a container
+     */
+    public uniqueId: number;
+
+    /**
      * Gets or sets an object used to store user defined information for the node
      */
     public metadata: any = null;
@@ -126,6 +132,14 @@ export class Control {
     }
 
     /**
+     * Get the current class name of the control.
+     * @returns current class name
+     */
+    public getClassName(): string {
+        return this._getTypeName();
+    }
+
+    /**
     * An event triggered when the pointer move over the control.
     */
     public onPointerMoveObservable = new Observable<Vector2>();
@@ -193,6 +207,22 @@ export class Control {
         this._markAsDirty();
     }
 
+    /**
+     * Gets or sets a boolean indicating that we want to highlight the control (mostly for debugging purpose)
+     */
+    public get isHighlighted(): boolean {
+        return this._isHighlighted;
+    }
+
+    public set isHighlighted(value: boolean) {
+        if (this._isHighlighted === value) {
+            return;
+        }
+
+        this._isHighlighted = value;
+        this._markAsDirty();
+    }
+
     /** Gets or sets a value indicating the scale factor on X axis (1 by default)
      * @see http://doc.babylonjs.com/how_to/gui#rotation-and-scaling
     */
@@ -852,6 +882,25 @@ export class Control {
         this.notRenderable = false;
     }
 
+    /** @hidden */
+    public _getDescendants(results: Control[], directDescendantsOnly: boolean = false, predicate?: (control: Control) => boolean): void {
+        // Do nothing by default
+    }
+
+    /**
+     * Will return all controls that have this control as ascendant
+     * @param directDescendantsOnly defines if true only direct descendants of 'this' will be considered, if false direct and also indirect (children of children, an so on in a recursive manner) descendants of 'this' will be considered
+     * @param predicate defines an optional predicate that will be called on every evaluated child, the predicate must return true for a given child to be part of the result, otherwise it will be ignored
+     * @return all child controls
+     */
+    public getDescendants(directDescendantsOnly?: boolean, predicate?: (control: Control) => boolean): Control[] {
+        var results = new Array<Control>();
+
+        this._getDescendants(results, directDescendantsOnly, predicate);
+
+        return results;
+    }
+
     /**
      * Link current control with a target mesh
      * @param mesh defines the mesh to link with
@@ -946,6 +995,9 @@ export class Control {
     public _link(root: Nullable<Container>, host: AdvancedDynamicTexture): void {
         this._root = root;
         this._host = host;
+        if (this._host) {
+            this.uniqueId = this._host.getScene()!.getUniqueId();
+        }
     }
 
     /** @hidden */
@@ -982,6 +1034,23 @@ export class Control {
     }
 
     /** @hidden */
+    public _renderHighlight(context: CanvasRenderingContext2D): void {
+        if (!this.isHighlighted) {
+            return;
+        }
+
+        context.strokeStyle = "#4affff";
+        context.lineWidth = 2;
+
+        this._renderHighlightSpecific(context);
+    }
+
+    /** @hidden */
+    protected _renderHighlightSpecific(context: CanvasRenderingContext2D): void {
+        context.strokeRect(this._currentMeasure.left, this._currentMeasure.top, this._currentMeasure.width, this._currentMeasure.height);
+    }
+
+    /** @hidden */
     protected _applyStates(context: CanvasRenderingContext2D): void {
         if (this._isFontSizeInPercentage) {
             this._fontSet = true;
@@ -1378,7 +1447,7 @@ export class Control {
 
         if (type === PointerEventTypes.POINTERDOWN) {
             this._onPointerDown(this, this._dummyVector2, pointerId, buttonIndex);
-            this._host._lastControlDown[pointerId] = this;
+            this._host._registerLastControlDown(this, pointerId);
             this._host._lastPickedControl = this;
             return true;
         }

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

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

+ 25 - 23
gui/src/2D/controls/inputText.ts

@@ -268,10 +268,12 @@ export class InputText extends Control implements IFocusableControl {
     }
 
     public set text(value: string) {
-        if (this._text === value) {
+        let valueAsString = value.toString(); // Forcing convertion
+
+        if (this._text === valueAsString) {
             return;
         }
-        this._text = value;
+        this._text = valueAsString;
         this._markAsDirty();
 
         this.onTextChangedObservable.notifyObservers(this);
@@ -352,21 +354,21 @@ export class InputText extends Control implements IFocusableControl {
 
         this._onClipboardObserver = this._host.onClipboardObservable.add((clipboardInfo) => {
             // process clipboard event, can be configured.
-             switch (clipboardInfo.type){
-                 case ClipboardEventTypes.COPY:
-                         this._onCopyText(clipboardInfo.event);
-                         this.onTextCopyObservable.notifyObservers(this);
-                         break;
-                 case ClipboardEventTypes.CUT:
-                         this._onCutText(clipboardInfo.event);
-                         this.onTextCutObservable.notifyObservers(this);
-                         break;
-                 case ClipboardEventTypes.PASTE:
-                         this._onPasteText(clipboardInfo.event);
-                         this.onTextPasteObservable.notifyObservers(this);
-                         break;
-                 default: return;
-              }
+            switch (clipboardInfo.type) {
+                case ClipboardEventTypes.COPY:
+                    this._onCopyText(clipboardInfo.event);
+                    this.onTextCopyObservable.notifyObservers(this);
+                    break;
+                case ClipboardEventTypes.CUT:
+                    this._onCutText(clipboardInfo.event);
+                    this.onTextCutObservable.notifyObservers(this);
+                    break;
+                case ClipboardEventTypes.PASTE:
+                    this._onPasteText(clipboardInfo.event);
+                    this.onTextPasteObservable.notifyObservers(this);
+                    break;
+                default: return;
+            }
         });
 
         let scene = this._host.getScene();
@@ -433,7 +435,7 @@ export class InputText extends Control implements IFocusableControl {
                     if (this._isTextHighlightOn) {
                         this.text = this._text.slice(0, this._startHighlightIndex) + this._text.slice(this._endHighlightIndex);
                         this._isTextHighlightOn = false;
-                        this._cursorOffset =  this.text.length - this._startHighlightIndex;
+                        this._cursorOffset = this.text.length - this._startHighlightIndex;
                         this._blinkIsEven = false;
                         if (evt) {
                             evt.preventDefault();
@@ -468,7 +470,7 @@ export class InputText extends Control implements IFocusableControl {
                     }
                     return;
                 }
-                if (this._text && this._text.length > 0  && this._cursorOffset > 0) {
+                if (this._text && this._text.length > 0 && this._cursorOffset > 0) {
                     let deletePosition = this._text.length - this._cursorOffset;
                     this.text = this._text.slice(0, deletePosition) + this._text.slice(deletePosition + 1);
                     this._cursorOffset--;
@@ -561,7 +563,7 @@ export class InputText extends Control implements IFocusableControl {
         this._endHighlightIndex = this._startHighlightIndex;
         for (let rWord = /\w+/g, left = 1, right = 1; this._startHighlightIndex > 0 && this._endHighlightIndex < this._text.length && (left || right);) {
             right = (this._text[this._endHighlightIndex].search(rWord) !== -1) ? ++this._endHighlightIndex : 0;
-            left =  (this._text[this._startHighlightIndex - 1 ].search(rWord) !== -1) ? --this._startHighlightIndex : 0;
+            left = (this._text[this._startHighlightIndex - 1].search(rWord) !== -1) ? --this._startHighlightIndex : 0;
         }
         this.onTextHighlightObservable.notifyObservers(this);
         this._isTextHighlightOn = true;
@@ -598,7 +600,7 @@ export class InputText extends Control implements IFocusableControl {
         try {
             ev.clipboardData.setData("text/plain", this._highlightedText);
         }
-        catch {} //pass
+        catch { } //pass
         this._host.clipboardData = this._highlightedText;
     }
     /** @hidden */
@@ -648,7 +650,7 @@ export class InputText extends Control implements IFocusableControl {
             // Background
             if (this._isFocused) {
                 if (this._focusedBackground) {
-                    context.fillStyle = this._isEnabled ?  this._focusedBackground : this._disabledColor;
+                    context.fillStyle = this._isEnabled ? this._focusedBackground : this._disabledColor;
 
                     context.fillRect(this._currentMeasure.left, this._currentMeasure.top, this._currentMeasure.width, this._currentMeasure.height);
                 }
@@ -760,7 +762,7 @@ export class InputText extends Control implements IFocusableControl {
                     this._markAsDirty();
                 }, 500);
 
-                 //show the highlighted text
+                //show the highlighted text
                 if (this._isTextHighlightOn) {
                     clearTimeout(this._blinkTimeout);
                     let highlightCursorOffsetWidth = context.measureText(this.text.substring(this._startHighlightIndex)).width;

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

@@ -201,6 +201,14 @@ export class Control3D implements IDisposable, IBehaviorAware<Control3D> {
         return this._getTypeName();
     }
 
+    /**
+     * Get the current class name of the control.
+     * @returns current class name
+     */
+    public getClassName(): string {
+        return this._getTypeName();
+    }
+
     protected _getTypeName(): string {
         return "Control3D";
     }

+ 1 - 3
gui/webpack.config.js

@@ -1,6 +1,5 @@
 const path = require('path');
 const webpack = require('webpack');
-const DtsBundleWebpack = require('dts-bundle-webpack');
 const CleanWebpackPlugin = require('clean-webpack-plugin');
 
 module.exports = {
@@ -17,8 +16,7 @@ module.exports = {
             amd: "babylonjs-gui",
             commonjs: "babylonjs-gui"
         },
-        umdNamedDefine: true,
-        //devtoolModuleFilenameTemplate: "[absolute-resource-path]"
+        umdNamedDefine: true
     },
     resolve: {
         extensions: [".js", '.ts']

+ 5 - 4
inspector/index.html

@@ -17,18 +17,19 @@
             padding: 0;
             margin: 0
         }
-        
+
         #wrapper {
             width: 100%;
             height: 100%;
             display: flex;
             overflow: hidden;
         }
-        
+
         canvas {
             width: 100%;
+            height: 100%;
         }
-        
+
         #inspector {
             width: 25%;
         }
@@ -46,7 +47,7 @@
 
     <!--Starting the game-->
     <script>
-        BABYLONDEVTOOLS.Loader.require("test/index.js").load(function () {
+        BABYLONDEVTOOLS.Loader.require("test/index.js").load(function() {
             new Test('game-canvas');
         });
     </script>

+ 3 - 9
inspector/legacy/legacy.ts

@@ -1,15 +1,9 @@
-import * as INSPECTOR from "../src/index";
-
-/**
- * Legacy support, defining window.INSPECTOR (global variable).
- *
- * This is the entry point for the UMD module.
- * The entry point for a future ESM package should be index.ts
- */
+import { Inspector } from "../src/index";
 
 var globalObject = (typeof global !== 'undefined') ? global : ((typeof window !== 'undefined') ? window : undefined);
 if (typeof globalObject !== "undefined") {
-    (<any>globalObject).INSPECTOR = INSPECTOR;
+    (<any>globalObject).BABYLON = (<any>globalObject).BABYLON || {};
+    (<any>globalObject).BABYLON.Inspector = Inspector;
 }
 
 export * from "../src/index";

+ 0 - 156
inspector/sass/_detailPanel.scss

@@ -1,156 +0,0 @@
-// The main class of the detail panel
-.insp-details {
-  background-color: $background;
-  overflow-y: auto;
-  overflow-x: auto;
-  color:$color;
-  font-family: $font;
-
-  .details {
-      padding-left: 5px;
-  }
-
-  // Common defintion between header row and detail row
-  .base-row {      
-    display:flex;
-    width:100%;
-
-    .base-property {
-        padding: 2px 0 2px 0;
-        text-overflow: ellipsis;
-        white-space: nowrap;
-        overflow: hidden;
-    }
-    // Property name
-    .prop-name {
-        @extend .property-name;
-        @extend .base-property;
-        width:35%;
-    }
-    // property value
-    .prop-value {
-        @extend .base-property;
-        width:59%;
-        padding-left:5px;
-        &.clickable {
-            cursor:pointer;
-            &:hover {
-                background-color:$background-lighter2;
-            }
-            &:after {
-                font-family: $font-family-icons;
-                content: "\00a0 \00a0 \00a0 \f105"; // 4 space before + angle-right
-                font-weight: 900; // To display solid font family
-            }
-        }   
-    }
-    
-    // input {
-    //     border:0;
-    //     font-family: $font;
-    //     background-color: $background-lighter;
-    //     color:$color;
-    //     // Remove blue border on focus
-    //     &:focus {
-    //         outline:none;
-    //     }
-    // }
-  }
-  
-  // A line of details composed of name, type, value, id, flagId
-  .row {
-    @extend .base-row;
-    &:nth-child(even) {
-        background-color:$background-lighter;
-    }
-    &.unfolded {          
-        .prop-value.clickable:after {
-            font-family: $font-family-icons;
-            content: "\00a0 \00a0 \00a0 \f107"; // 4 space before + angle-down
-            font-weight: 900; // To display solid font family
-        }
-    }
-  }
-
-  
-  // Name, type, value, Id, FlagId
-  .header-row {
-    @extend .base-row;
-    background-color: $background-lighter; 
-    color           : $color;
-    width           : 100%;
-    max-width       : 100%;
-    
-    // Special definition for text color: the color is the default one
-    // All header columns
-    & > * {
-        color:$color !important;
-        padding:5px 0 5px 5px !important;
-        cursor: pointer;
-        &:hover {
-            background-color:$background-lighter2;
-        }
-    }
-
-    .header-col {
-        display:flex;
-        justify-content: space-between;
-        align-items: center;
-
-        .sort-direction {
-            margin-right:5px;
-        }
-    }
-  }
-  
-  // A div used to view a property in the property line (color, texture...)
-  .element-viewer {
-      position:relative;
-      width:10px;
-      height:10px;
-      display:inline-block;
-      margin-left:5px;
-  }
-
-  // The div displaying a color
-  .color-element {
-      @extend .element-viewer;
-      width: 20px;
-      height: 15px;
-  }
-
-  // The div displaying a texture element
-  .texture-element {
-      @extend .element-viewer;
-      color:$color-top;
-      margin-left:10px; 
-
-      .texture-viewer {
-          
-          color:$color;
-          position:absolute;
-          z-index:10;
-          bottom:0;
-          right:0;
-          display:block;
-          width:150px;
-          height:150px;
-          border: 1px solid $background-lighter3;
-          background-color: $background;
-          transform: translateX(100%) translateY(100%);
-          
-          display: none;
-          flex-direction: column;
-          justify-content: flex-start;
-          align-items: center;
-
-          .texture-viewer-img {
-              margin:10px 0 10px 0;
-              max-width:110px;
-              max-height:110px;
-          }
-      }
-  }
-   
-
-}

+ 0 - 18
inspector/sass/_resizeBar.scss

@@ -1,18 +0,0 @@
-.c2di-resize-bar-v {
-  height:100%;
-  width:$resizebar-width;
-  background-color: $background;
-  cursor: col-resize;
-  flex-shrink: 0;
-  border-left:1px solid $background-lighter;
-  border-right:1px solid $background-lighter;
-}
-.c2di-resize-bar-h {
-  width:100%;
-  height:$resizebar-width;
-  background-color: $background;
-  cursor: row-resize;
-  flex-shrink: 0;
-  border-top: 1px solid $background-lighter;
-  border-bottom: 1px solid $background-lighter;
-}

+ 0 - 19
inspector/sass/_searchbar.scss

@@ -1,19 +0,0 @@
-.searchbar {
-    
-    border       : 1px solid $background-lighter;
-    margin-bottom: 5px;
-    display      : flex;
-    align-items  : center;
-    color:darken($color, 10%);
-    
-    input {
-        background-color: $background;
-        border          : none;
-        width           : 100%;
-        outline         : none;
-        font-family     : $font;
-        color           : darken($color, 10%);
-        padding         : 3px 0 3px 10px;
-        margin          : 6px 0 6px 0;
-    }
-}

+ 0 - 74
inspector/sass/_slider.scss

@@ -1,74 +0,0 @@
-$thumb-height: 15px;
-
-input[type="range"] { 
-  margin: auto;
-  -webkit-appearance: none;
-  position: relative;
-  overflow: hidden;
-  height: $thumb-height;
-  width: 50%;
-  cursor: pointer;
-  border-radius: 0; /* iOS */
-}
-
-::-webkit-slider-runnable-track {
-  background: #ddd;
-}
-
-/*
-* 1. Set to 0 height and width, and remove border for a slider without a thumb
-*/
-::-webkit-slider-thumb {
-  -webkit-appearance: none;
-  width: 20px; /* 1 */
-  height: $thumb-height; /* 1 */
-  background: #fff;
-  box-shadow: -100vw 0 0 100vw dodgerblue;
-  border: 0px solid #999; /* 1 */
-}
-
-::-moz-range-track {
-  height: $thumb-height;
-  background: #ddd;
-}
-
-::-moz-range-thumb {
-  background: #fff;
-  height: $thumb-height;
-  width: 20px;
-  border: 0px solid #999;
-  border-radius: 0 !important;
-  box-shadow: -100vw 0 0 100vw dodgerblue;
-  box-sizing: border-box;
-}
-
-::-ms-fill-lower { 
-  background: dodgerblue;
-}
-
-::-ms-thumb { 
-  background: #fff;
-  border: 0px solid #999;
-  height: $thumb-height;
-  width: 20px;
-  box-sizing: border-box;
-}
-
-::-ms-ticks-after { 
-  display: none; 
-}
-
-::-ms-ticks-before { 
-  display: none; 
-}
-
-::-ms-track { 
-  background: #ddd;
-  color: transparent;
-  height: $thumb-height;
-  border: none;
-}
-
-::-ms-tooltip { 
-  display: none;
-}

+ 0 - 92
inspector/sass/_tabPanel.scss

@@ -1,92 +0,0 @@
-.tab-panel {
-    height:100%;
-
-    &.searchable {
-        height:calc(100% - #{$searchbar-height} - 10px);   
-    }  
-
-    .texture-image {
-        max-height:400px;
-    }
-    
-    .scene-actions {
-        overflow-y: auto;
-        padding-left: 5px;
-        
-        // Action title : Textures/Options/Viewer
-        .actions-title {
-            font-size     : 1.1em;
-            padding-bottom: 10px;
-            border-bottom : 1px solid $color-bot;
-            margin        : 10px 0 10px 0;
-        }
-
-        .defaut-action {            
-            height     : 20px;
-            line-height: 20px;
-            width      : 100%;
-            cursor     : pointer;   
-            
-            &:hover {
-                background-color:$background-lighter;
-            }
-            &:active {                
-                background-color: $background-lighter2;
-            }
-        }
-
-        // Radio button
-        .action-radio {
-            @extend .defaut-action;
-            &:before {
-                width      : 1em;
-                height     : 1em;
-                line-height: 1em;
-                display    : inline-block;
-                font-family: $font-family-icons;
-                content    : "\f111";
-                margin-right:10px;
-            }
-            // radio button active
-            &.active {
-                &:before {
-                    width      : 1em;
-                    height     : 1em;
-                    line-height: 1em;
-                    display    : inline-block;
-                    font-family: $font-family-icons;
-                    content    : "\f192";
-                    color      : $color-bot;
-                    margin-right:10px;
-                }
-            }
-        }
-
-        // Check button
-        .action {             
-            @extend .defaut-action;
-            &:before {
-                width      : 1em;
-                height     : 1em;
-                line-height: 1em;
-                display    : inline-block;
-                font-family: $font-family-icons;
-                content    : "\f0c8";
-                margin-right:10px;
-            }
-                
-            &.active {
-                &:before {
-                    width      : 1em;
-                    height     : 1em;
-                    line-height: 1em;
-                    display    : inline-block;
-                    font-family: $font-family-icons;
-                    content    : "\f14a";
-                    color      : $color-bot;
-                    margin-right:10px;
-                }
-            }
-        }
-    }
-}

+ 0 - 60
inspector/sass/_tabbar.scss

@@ -1,60 +0,0 @@
-.tabbar {
-    height:$tabbar-height;
-    
-    display:flex;
-    align-items: center;
-    border-bottom: 1px solid $background-lighter2;
-    width:100%;
-    overflow-x:auto;
-    overflow-y:hidden;
-    box-sizing: border-box;
-    
-    .tab {
-        height:calc(#{$tabbar-height} - 2px);
-        width:auto;
-        padding: 0 10px 0 10px;
-        color:$color;
-        line-height: $tabbar-height;
-        text-align: center;
-        cursor: pointer;
-        margin: 0 5px 0 5px;
-        box-sizing: border-box;
-       
-        // Hover on it
-        &:hover {
-            border-bottom: 1px solid $color-top;
-            background-color: $background-lighter;
-        }
-        // Clic on it
-        &:active {
-            background-color: $background-lighter2;
-        }
-        // tab selected
-        &.active {
-            border-bottom: 1px solid $color-top;
-        }
-    }
-
-    .more-tabs {
-        width           : $tabbar-height;
-        height          : $tabbar-height;
-        display         : flex;
-        justify-content : center;
-        align-items     : center;
-        cursor          : pointer;
-        position        : relative;
-        border-right    : 1px solid $background-lighter2;
-        &:hover {
-            background-color: $background-lighter2;
-        }
-        &:active {
-            color:$color-top;
-            background-color: $background-lighter3;
-        }
-        // This tool is activated
-        &.active {
-            color:$color-top;
-        }
-
-    }
-}

+ 0 - 31
inspector/sass/_toolbar.scss

@@ -1,31 +0,0 @@
-/**
- * The toolbar contains : 
- * - a refresh tool - refresh the whole panel
- * - a popup tool - Open the inspector in a new panel
- * ...
- */   
-.toolbar {   
-    display:flex;
-     
-    .tool {
-        width          : $tabbar-height;
-        height         : $tabbar-height;
-        display        : flex;
-        justify-content: center;
-        align-items    : center;
-        cursor         : pointer;
-        position       : relative;
-        border-right   : 1px solid $background-lighter2;
-        &:hover {
-            background-color: $background-lighter2;
-        }
-        &:active {
-            color:$color-top;
-            background-color: $background-lighter3;
-        }
-        // This tool is activated
-        &.active {
-            color:$color-top;
-        }
-    }
-}

+ 0 - 14
inspector/sass/_tooltip.scss

@@ -1,14 +0,0 @@
-// Tooltip used when hovering on divisions
-
-.tooltip {
-    position        : absolute;
-    top             : $tabbar-height;
-    right           : 0;
-    color           : $color-top;
-    display         : none;
-    z-index         : 4;
-    font-family     : $font;  
-    padding         : 2px;
-    background-color: $background;
-    border          : 1px solid $background-lighter3;
-}

+ 0 - 73
inspector/sass/_tree.scss

@@ -1,73 +0,0 @@
-
-// Color for a property type
-.property-type {
-  color:$color-bot;
-}
-
-.property-name {
-  color:$color-top;
-}
-
-.insp-tree {
-  overflow-y: auto;
-  overflow-x: hidden;
-  height    : calc(50% - #{$tabbar-height} - #{$searchbar-height});
-  
-    
-    .line {
-        padding:3px;
-        cursor:pointer;
-        // Hover
-        &:hover {
-            background-color:$background-lighter;
-        }
-        // Line active (selected)
-        &.active {
-            background-color:$background-lighter3;
-            .line-content {
-                background-color:$background;
-            }
-        }
-        // > before title names
-        &.unfolded:before{            
-            width      : 1em;
-            height     : 1em;
-            line-height: 1em;
-            display    : inline-block;
-            font-family: $font-family-icons;
-            content    : "\f107";
-            font-weight: 900;          
-        }
-        &.folded:before{            
-            width      : 1em;
-            height     : 1em;
-            line-height: 1em;
-            display    : inline-block;
-            font-family: $font-family-icons;
-            content    : "\f105";
-            font-weight: 900;
-        }
-        
-        &.unfolded.transformNode > span:first-of-type{
-            color:$color-top;
-        }
-        &.folded.transformNode > span:first-of-type{ 
-            color:$color-top;
-        }
-
-        // Sub lines
-        .line-content {
-            padding-left:15px;
-            &:hover { 
-                background-color:$background;
-            }
-            .line:hover:first-child {            
-                background-color:$background-lighter2;
-            }
-            
-        }
-    }
-    .line_invisible {
-        display: none;
-    }
-}

+ 0 - 16
inspector/sass/_treeTool.scss

@@ -1,16 +0,0 @@
-/**
- * A tool contained in the tree panel (available for each item of the tree)
- */
-.treeTool {
-    margin : 3px 8px 3px 3px;
-    cursor:pointer;
-    position:relative;
-   
-    &:hover {        
-        color:$color-bot;
-    }
-    
-    &.active {
-        color:$color-bot;
-    }
-}

+ 0 - 28
inspector/sass/defines.scss

@@ -1,28 +0,0 @@
-// @import url(https://maxcdn.bootstrapcdn.com/font-awesome/4.6.3/css/font-awesome.min.css);
-@import url(https://use.fontawesome.com/releases/v5.0.13/css/all.css);
-@import url(https://fonts.googleapis.com/css?family=Inconsolata);
-
-$font               : 'Inconsolata', sans-serif;
-
-// ------------- //
-// If you update these colors, you should also 
-// replace them in the class Inspector as well, 
-// as it's used for custom themes
-// ------------- //
-
-$color              : #ccc;
-$background         : #242424;
-$background-active  : #2c2c2c;
-$color-top          : #f29766;
-$color-bot          : #5db0d7;
-$color-error        : #fa371d;
-
-$background-lighter : lighten($color: $background, $amount         : 3%);
-$background-lighter2: lighten($color: $background-lighter, $amount : 5%);
-$background-lighter3: lighten($color: $background-lighter2, $amount: 5%);
-
-$resizebar-width    : 10px;
-$tabbar-height      : 50px;
-$searchbar-height   : 30px;
-
-$font-family-icons  : 'Font Awesome 5 Free', sans-serif;

+ 0 - 105
inspector/sass/main.scss

@@ -1,105 +0,0 @@
-
-
-.insp-wrapper {
-  // Import variables, color and font files
-  @import "defines";
-
-  // Style for resize bar
-  .gutter {
-    background-color: $background-lighter;
-    &.gutter-vertical:not(.blocked) {
-      cursor        : ns-resize;
-    }
-    &.gutter-horizontal:not(.blocked) {
-      cursor        : ew-resize;
-    }
-  }
-
-  user-select: none; 
-  display:flex;
-  font-size:0.9em;
-  font-family     : $font;
-  background-color: $background;
-
-  // The panel containing the two subpanel : tree and details
-  .insp-right-panel {
-    width: 750px;
-    overflow-y: auto;
-
-    &.popupmode {
-      width:100% !important;
-    }
-    
-    display:flex; 
-    flex-direction: column;
-    flex-shrink: 0;
-
-    // The tree panel
-    .top-panel {
-      width:100%;
-      height:100%;
-      position:relative;
-      background-color: $background;
-      color           : $color;
-      font-size       : 1em;
-      
-      // The div that will contain the tab div
-      .tab-panel-content {
-        width:100%;
-        height:calc(100% - #{$tabbar-height});   
-      }   
-
-      // The div displaying all invisible tabs (when the tabbar width is small)
-      .more-tabs-panel {
-          position:absolute;
-          z-index:10;
-          top:$tabbar-height;
-          right:0;
-          width:100px;
-          display:none;
-          flex-direction: column;
-          align-items: center;
-          justify-content: center;
-          border: 1px solid $background-lighter3;
-          background-color: $background;
-
-          .invisible-tab {
-            height     : 25px;
-            width      : 100%;
-            line-height: 25px;
-            text-align : center;
-            background-color: $background-lighter;
-            cursor:pointer;
-
-            // Hover on it
-            &:hover {
-              background-color: $background-lighter2;
-            }
-            // Clic on it
-            &:active {
-              background-color: $background-lighter3;
-            }
-          }
-
-      }
-    }
-  }
-
-  @import 'tooltip';
-
-  // All tools used on object in the tree
-  @import 'treeTool';
-  @import "tabPanel";
-  @import "tabs/shaderTab";
-  @import "tabs/consoleTab";
-  @import "tabs/statsTab";
-  @import "tabs/gltfTab";
-  @import "tabs/toolsTab";
-
-  @import "tree";
-  @import "detailPanel";
-  @import "tabbar";
-  @import "toolbar";
-  @import "searchbar";
-  @import "slider";
-}

+ 0 - 51
inspector/sass/tabs/_consoleTab.scss

@@ -1,51 +0,0 @@
-.tab-panel {
-
-    .console-panel {
-        min-height              : 100px;
-        user-select             : text;
-        box-sizing              : border-box;
-        padding                 : 0 15px;    
-        
-        .console-panel-title {
-            height              : 25px;
-            border-bottom       : 1px solid $background-lighter2;
-            text-transform      : uppercase;
-            line-height         : 25px;
-            margin-bottom       : 10px; 
-        }
-        
-        .console-panel-content {            
-            overflow-y              : auto;
-            overflow-x              : hidden;    
-            height                  : calc(100% - 30px);
-        }  
-
-        .defaut-line {
-            word-wrap: break-word;
-            padding: 3px 0 3px 5px;
-        }
-
-        .caller {
-            padding: 3px 0 3px 0;
-            color:darken($color-bot, 10%);
-        }
-
-        .log {  
-            @extend .defaut-line;
-            color:white;
-        }   
-        
-        .warn {
-            @extend .defaut-line;
-            color:orange;
-        }
-        .error {
-            @extend .defaut-line;
-            color:orangered; 
-        }
-        .object {
-            @extend .defaut-line;
-            color:$color-bot;
-        }
-    }
-}

+ 0 - 92
inspector/sass/tabs/_gltfTab.scss

@@ -1,92 +0,0 @@
-.tab-panel {
-    .gltf-actions {
-        overflow-y: auto;
-        padding-left: 5px;
-
-        .gltf-title {
-            font-size     : 1.1em;
-            padding-bottom: 10px;
-            border-bottom : 1px solid $color-bot;
-            margin        : 10px 0 10px 0;
-        }
-
-        .gltf-action {
-            height     : 20px;
-            line-height: 20px;
-            width      : 100%;
-            cursor     : pointer;
-            white-space: nowrap;
-
-            &:hover {
-                background-color: $background-lighter;
-            }
-        }
-
-        .gltf-icon {
-            width      : 1em;
-            height     : 1em;
-            line-height: 1em;
-            display    : inline-block;
-            font-family: $font-family-icons;
-            margin-right:10px;
-        }
-
-        .gltf-checkbox {
-            @extend .gltf-action;
-            &:before {
-                width      : 1em;
-                height     : 1em;
-                line-height: 1em;
-                display    : inline-block;
-                font-family: $font-family-icons;
-                content    : "\f0c8";
-                margin-right:10px;
-            }
-
-            &.active {
-                &:before {
-                    width      : 1em;
-                    height     : 1em;
-                    line-height: 1em;
-                    display    : inline-block;
-                    font-family: $font-family-icons;
-                    content    : "\f14a";
-                    color      : $color-bot;
-                    margin-right:10px;
-                }
-            }
-        }
-
-        .gltf-input {
-            background-color: $background-lighter;
-            border          : none;
-            outline         : none;
-            font-family     : $font;
-            color           : darken($color, 10%);
-            padding         : 5px;
-            margin          : 0px 6px 0px 0;
-
-            &:hover {
-                background-color:$background-lighter2;
-            }
-        }
-
-        .gltf-button {
-            background-color: $background-lighter;
-            border          : none;
-            outline         : none;
-            font-family     : $font;
-            color           : $color;
-            padding         : 5px 10px;
-            margin          : 0px 6px 0px 0;
-
-            &:hover {
-                background-color:$background-lighter2;
-            }
-
-            &:active {
-                background-color:$background-lighter3;
-            }
-        }
-    }
-}

+ 0 - 53
inspector/sass/tabs/_shaderTab.scss

@@ -1,53 +0,0 @@
-.tab-panel {
-
-    .shader-tree-panel {
-        height                  : 30px;
-        
-        // The combo box listing all shaders
-        select {
-            height              : 30px;
-            background-color    : transparent;
-            color               : #ccc;
-            height              : 30px;
-            width               : 100%;
-            max-width           : 300px;
-            padding-left        : 15px;
-            border              : 1px solid $background-lighter;
-            outline             : 1px solid $background-lighter3;
-            option {
-                padding         : 5px;
-                color           : darken($color: $color, $amount: 30%)
-            }
-        }
-        
-    }
-
-    .shader-panel {
-        min-height              : 100px;
-        user-select             : text;
-        box-sizing              : border-box;
-        padding                 : 0 15px;
-        
-        // Shader code style - the syntax highlightinh is done by highlight.js, loaded dynamically
-        pre {
-            margin              : 0;
-            white-space         : pre-wrap;
-            code {
-                // to cancel the background color from zenburn theme of highlight js
-                background-color: $background !important;
-                padding         : 0;
-                margin          : 0;                    
-            }            
-        }
-        
-        .shader-panel-title {
-            height              : 25px;
-            border-bottom       : 1px solid $background-lighter2;
-            text-transform      : uppercase;
-            line-height         : 25px;
-            margin-bottom       : 10px;
-        }
-        
-        
-    }
-}

+ 0 - 52
inspector/sass/tabs/_statsTab.scss

@@ -1,52 +0,0 @@
-.tab-panel {
-
-    &.stats-panel {
-        overflow-y      : auto;
-    }
-    
-    .stats-fps {
-        font-weight:600;
-        color:$color-top;
-    }
-
-    .stat-title1 {        
-        font-size       : 1.1em;
-        padding         : 10px;
-    }
-
-    .stat-title2 {
-        margin          : 10px 0 10px 0;
-        font-size       : 1.05em; 
-        border-bottom   : 1px solid $color-bot;
-        box-sizing      : border-box;
-    }
-
-    .stat-label {
-        display         : inline-block;
-        width           : 80%;
-        padding         : 2px;
-        background-color: $background-lighter;
-        border-bottom   : 1px solid $background;
-        border-top      : 1px solid $background;
-        height          : 30px;
-        line-height     : 30px;
-        box-sizing      : border-box;
-        
-    }
-    .stat-value {
-        display         : inline-block;
-        width           : 20%;
-        padding         : 2px;
-        background-color: $background-lighter;
-        border-top      : 1px solid $background;
-        border-bottom   : 1px solid $background;
-        height          : 30px;
-        line-height     : 30px;
-        box-sizing      : border-box;
-    }
-
-    .stat-infos {
-        width           : 100%;
-        padding         : 4px;
-    }
-}

+ 0 - 80
inspector/sass/tabs/_toolsTab.scss

@@ -1,80 +0,0 @@
-.tab-panel {
-
-    &.tools-panel {
-        overflow-y      : auto;
-    }
-
-    .tool-title1 {        
-        font-size       : 1.1em;
-        padding         : 10px;
-    }
-
-    .tool-title2 {
-        margin          : 10px 0 10px 0;
-        font-size       : 1.05em; 
-        border-bottom   : 1px solid $color-bot;
-        box-sizing      : border-box;
-    }
-
-    .tool-label {
-        background-color: $background-lighter;
-        border          : none;
-        outline         : none;
-        font-family     : $font;
-        color           : darken($color, 10%);
-        padding         : 5px;
-        margin          : 0px 6px 0px 0;
-    }
-
-    .tool-label-line {
-        @extend .tool-label;
-        width           : 100%;
-    }
-
-    .tool-label-error {
-        @extend .tool-label;
-        color           : $color-error;
-        width           : 100%;
-        background-color: none;
-    }
-
-    .tool-value {
-        display         : inline-block;
-        width           : 25%;
-        padding         : 2px;
-        background-color: $background-lighter;
-        border-top      : 1px solid $background;
-        border-bottom   : 1px solid $background;
-        height          : 30px;
-        line-height     : 30px;
-        box-sizing      : border-box;
-    }
-
-    .tool-infos {
-        width           : 100%;
-        padding         : 4px;
-    }
-
-    .tool-input {
-        background-color: $background-lighter;
-        border          : none;
-        outline         : none;
-        font-family     : $font;
-        color           : $color;
-        padding         : 5px 10px;
-        margin          : 0px 6px 0px 0;
-        width           : 100%;
-        border-top      : 1px solid $background;
-        border-bottom   : 1px solid $background;
-        text-align: left;
-
-        &:hover {
-            background-color:$background-lighter2;
-            cursor: pointer;
-        }
-
-        &:active {
-            background-color:$background-lighter3;
-        }
-    }
-}

BIN
inspector/screens/tab_mesh.jpg


BIN
inspector/screens/tools.jpg


+ 0 - 441
inspector/src/Inspector.ts

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

+ 0 - 43
inspector/src/adapters/Adapter.ts

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

+ 0 - 56
inspector/src/adapters/CameraAdapter.ts

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

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

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

+ 0 - 51
inspector/src/adapters/LightAdapter.ts

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

+ 0 - 37
inspector/src/adapters/MaterialAdapter.ts

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

+ 0 - 116
inspector/src/adapters/MeshAdapter.ts

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

+ 0 - 59
inspector/src/adapters/PhysicsImpostorAdapter.ts

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

+ 0 - 52
inspector/src/adapters/SoundAdapter.ts

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

+ 0 - 40
inspector/src/adapters/TextureAdapter.ts

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

+ 0 - 9
inspector/src/adapters/index.ts

@@ -1,9 +0,0 @@
-export * from './Adapter';
-export * from './CameraAdapter';
-export * from './GUIAdapter';
-export * from './LightAdapter';
-export * from './MaterialAdapter';
-export * from './MeshAdapter';
-export * from './PhysicsImpostorAdapter';
-export * from './SoundAdapter';
-export * from './TextureAdapter';

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

@@ -0,0 +1,753 @@
+#inspector-host {
+    position: absolute;
+    right: 0px;
+    top:0px;
+    bottom: 0px;
+}
+
+#actionTabs {
+    background: #333333;
+    height: 100%;
+    margin: 0;
+    padding: 0;
+    display: grid;
+    grid-template-rows: auto 1fr;
+    font: 14px "Arial";    
+    overflow: hidden;
+
+    #header {
+        height: 30px;
+        font-size: 16px;
+        color: white;
+        background: #222222;
+        grid-row: 1;
+        text-align: center;
+        display: grid;
+        grid-template-columns: 30px 1fr 50px;        
+        -webkit-user-select: none; 
+        -moz-user-select: none;   
+        -ms-user-select: none;    
+        user-select: none;                
+
+        #logo {
+            grid-column: 1; 
+            width: 24px;
+            height: 24px;
+            display: flex;
+            align-self: center;   
+            justify-self: center;
+        }        
+
+        #back {
+            grid-column: 1; 
+            display: grid;
+            align-self: center;   
+            justify-self: center;
+            cursor: pointer;
+        }              
+
+        #title {
+            grid-column: 2; 
+            display: grid;
+            align-items: center;   
+            text-align: center;
+        }
+
+        #commands {
+            grid-column: 3; 
+            display: grid;
+            align-items: center;  
+            grid-template-columns: 1fr 1fr;   
+            
+            .expand {
+                grid-column: 1;
+                display: grid;
+                align-items: center;   
+                justify-items: center;
+                cursor: pointer;     
+            }
+
+            .close {
+                grid-column: 2;
+                display: grid;
+                align-items: center;   
+                justify-items: center;
+                cursor: pointer;     
+            }        
+        }
+    }
+
+    .tabs {
+        display: grid;
+        grid-row: 2;
+        grid-template-rows: 40px 1fr;
+        font: 14px "Arial";
+        overflow: hidden;
+
+        .labels {
+            grid-row: 1;
+            display: flex;
+            align-items: center;
+            justify-items: center;
+            border-bottom: 1px solid #ffffff; 
+            margin: 0;
+            padding: 0;         
+
+            .label {
+                font-size: 24px;
+                color: white;
+                width: 40px;
+                display: flex;
+                align-content: center;
+                justify-content: center;
+                border: 1px solid transparent;            
+                border-bottom: none;    
+                background: #333333;
+                padding: 5px;  
+                height: 28px;
+                cursor: pointer;
+
+                &.active {
+                    border-color: #ffffff;  
+                    border-bottom: 2px solid transparent;           
+                    margin-bottom: -2px;
+                }
+            }
+        }
+
+        .panes {
+            grid-row: 2;
+
+            display: grid;
+            grid-template-rows: 1fr;
+
+            overflow: hidden;
+
+            .infoMessage {
+                opacity: 0.5;
+                color: white;
+                margin: 15px 5px 0px 5px;
+                                
+            }
+
+            .pane {
+                color: white;
+
+                overflow-x: hidden;
+                overflow-y: auto;
+
+                -webkit-user-select: none; 
+                -moz-user-select: none;   
+                -ms-user-select: none;    
+                user-select: none;     
+                
+                .textureLinkLine {
+                    display: grid;
+                    grid-template-columns: auto 1fr;
+
+                    .debug {
+                        grid-column: 1;
+                        margin-left: 5px;
+                        display: grid;
+                        align-items: center; 
+                        justify-items: center;                          
+                        cursor: pointer;
+                        opacity: 0.5;
+
+                        &.selected {
+                            opacity: 1.0;
+                        }
+                    }
+
+                    .textLine {
+                        grid-column: 2;
+                    }
+                }
+
+                .messageLine {
+                    text-align: center;
+                    font-size: 12px;
+                    font-style: italic;
+                    opacity: 0.6;
+                }
+
+                .textLine {
+                    padding-left: 5px;
+                    height: 30px;
+                    display: grid;
+                    grid-template-columns: 1fr auto;
+
+                    .label {
+                        grid-column: 1;
+                        display: flex;
+                        align-items: center;
+                    }
+
+                    .link-value {
+                        grid-column: 2;
+                        white-space: nowrap;
+                        text-overflow: ellipsis;
+                        overflow: hidden;
+                        text-align: end;
+                        opacity: 0.8;
+                        margin:5px;
+                        margin-top: 6px;
+                        max-width: 200px;
+                        text-decoration: underline;
+                        cursor: pointer;
+                    }
+
+                    .value {
+                        grid-column: 2;
+                        white-space: nowrap;
+                        text-overflow: ellipsis;
+                        overflow: hidden;
+                        text-align: end;
+                        opacity: 0.8;
+                        margin:5px;
+                        margin-top: 6px;
+                        max-width: 200px;
+
+                        &.check {
+                            color: green;
+                        }
+
+                        &.uncheck {
+                            color: red;
+                        }  
+                    }
+                }
+
+                .textInputLine {
+                    padding-left: 5px;
+                    height: 30px;
+                    display: grid;
+                    grid-template-columns: 1fr 120px;
+
+                    .label {
+                        grid-column: 1;
+                        display: flex;
+                        align-items: center;
+                    }
+
+                    .value {                        
+                        display: flex;
+                        align-items: center;
+                        grid-column: 2;
+                        
+                        input {
+                            width: 110px;
+                        }
+                    }
+                }
+
+                .buttonLine {
+                    height: 30px;
+                    display: grid;
+                    align-items: center;
+                    justify-items: stretch;
+
+                    input[type="file"] {
+                        display: none;
+                    }
+
+                    .file-upload {
+                        background: transparent;
+                        border: 1px solid rgb(51, 122, 183);
+                        margin: 0px 10px;
+                        color:white;
+                        padding: 4px 5px;
+                        opacity: 0.9;
+                        cursor: pointer;
+                        text-align: center;
+                    }
+
+                    .file-upload:hover {
+                        opacity: 1.0;
+                    }
+
+                    .file-upload:active {
+                        transform: scale(0.98);
+                        transform-origin: 0.5 0.5;
+                    }
+
+                    button {
+                        background: #222222;
+                        border: 0px;
+                        color:white;
+                        padding: 4px 5px;
+                        opacity: 0.9;
+                        width: 100%;
+                        height: 28px;
+                    }
+
+                    button:hover {
+                        opacity: 1.0;
+                    }
+
+                    button:active {
+                        background: #282828;
+                    }   
+                    
+                    button:focus {
+                        border: 0px;
+                        outline: 0px;
+                    }  
+                }
+
+                .radioLine {
+                    padding-left: 5px;
+                    height: 30px;
+                    display: grid;
+                    grid-template-columns: 1fr 30px;
+
+                    .label {
+                        grid-column: 1;
+                        display: flex;
+                        align-items: center;
+                    }
+
+                    .radioContainer {
+                        display: flex;
+                        align-items: center;
+
+                        .radio {
+                            grid-column: 2;                        
+                            display: none;
+
+                            &:checked + label:before {
+                                border-color: rgb(51, 122, 183);
+                            }
+                            &:checked + label:after {
+                                transform: scale(1);
+                            }                        
+                        }
+
+                        .labelForRadio {
+                            display: inline-block;
+                            height: 14px;
+                            position: relative;
+                            padding: 0 24px;
+                            margin-bottom: 0;
+                            cursor: pointer;
+                            vertical-align: bottom;
+                            &:before, &:after {
+                                position: absolute;            
+                                content: '';  
+                                border-radius: 50%;
+                                transition: all .3s ease;
+                                transition-property: transform, border-color;
+                            }
+                            &:before {
+                                left: 0px;
+                                top: 0;
+                                width: 16px;
+                                height: 16px;
+                                border: 2px solid white;
+                            }
+                            &:after {
+                                top: 6px;
+                                left: 6px;
+                                width: 8px;
+                                height: 8px;
+                                transform: scale(0);
+                                background:rgb(51, 122, 183);
+                            }
+                        }
+                    }
+                }
+
+                .vector3Line {
+                    padding-left: 5px;                    
+                    display: grid;
+
+                    .firstLine {
+                        display: grid;
+                        grid-template-columns: 1fr auto 20px;
+                        height: 30px;
+
+                        .label {
+                            grid-column: 1;
+                            display: flex;
+                            align-items: center;
+                        }
+
+                        .vector {
+                            grid-column: 2;
+                            display: flex;
+                            align-items: center;
+                            text-align: right;
+                            opacity: 0.8;
+                        }
+
+                        .expand {
+                            grid-column: 3;
+                            display: grid;
+                            align-items: center;
+                            justify-items: center;
+                            cursor: pointer;
+                        }
+                    }
+
+                    .secondLine {
+                        display: grid;
+                        padding-right: 5px;  
+                        border-left: 1px solid rgb(51, 122, 183);
+
+                        .numeric {
+                            display: grid;
+                            grid-template-columns: 1fr auto;
+                        }
+
+                        .numeric-label {
+                            text-align: right;
+                            grid-column: 1;
+                            display: flex;
+                            align-items: center;                            
+                            justify-self: right;
+                            margin-right: 10px;                          
+                        }
+
+                        .numeric-value {
+                            width: 120px;
+                            grid-column: 2;
+                            display: flex;
+                            align-items: center;  
+                            border: 1px solid  rgb(51, 122, 183);
+                        }                        
+                    }
+                }
+
+                .checkBoxLine {
+                    padding-left: 5px;
+                    height: 30px;
+                    display: grid;
+                    grid-template-columns: 1fr auto;
+
+
+                    .label {
+                        grid-column: 1;
+                        display: flex;
+                        align-items: center;
+                    }
+
+                    .checkBox {
+                        grid-column: 2;
+                        
+                        display: flex;
+                        align-items: center;
+
+                        .lbl {
+                            position: relative;
+                            display: block;
+                            height: 14px;
+                            width: 34px;
+                            margin-right: 5px;
+                            background: #898989;
+                            border-radius: 100px;
+                            cursor: pointer;
+                            transition: all 0.3s ease;
+                        }
+
+                        .lbl:after {
+                            position: absolute;
+                            left: 3px;
+                            top: 2px;
+                            display: block;
+                            width: 10px;
+                            height: 10px;
+                            border-radius: 100px;
+                            background: #fff;
+                            box-shadow: 0px 3px 3px rgba(0,0,0,0.05);
+                            content: '';
+                            transition: all 0.15s ease;
+                        }
+
+                        .lbl:active:after { 
+                            transform: scale(1.15, 0.85); 
+                        }
+
+                        .cbx:checked ~ label { 
+                            background: rgb(51, 122, 183);
+                        }
+
+                        .cbx:checked ~ label:after {
+                            left: 20px;
+                            background: rgb(22, 73, 117);
+                        }
+
+                        .hidden { 
+                            display: none; 
+                        }               
+                    }                    
+                }                   
+
+                .textureLine {                   
+                    display: grid;
+                    grid-template-rows: 30px auto;
+
+                    .control {
+                        margin-top: 2px;
+                        grid-row: 1;
+                        display: grid;
+                        grid-template-columns: 1fr 40px 40px 40px 40px 40px 1fr;
+
+                        .red {
+                            grid-column: 2;
+                        }
+
+                        .green {
+                            grid-column: 3;
+                        }
+
+                        .blue {
+                            grid-column: 4;
+                        }
+
+                        .alpha {
+                            grid-column: 5;
+                        }                        
+
+                        .all {
+                            grid-column: 6;
+                        }                        
+                    }
+
+                    .control3D {
+                        margin-top: 2px;
+                        grid-row: 1;
+                        display: grid;
+                        grid-template-columns: 1fr 40px 40px 40px 40px 40px 40px 1fr;
+
+                        .px {
+                            grid-column: 2;
+                        }
+
+                        .nx {
+                            grid-column: 3;
+                        }
+
+                        .py {
+                            grid-column: 4;
+                        }
+
+                        .ny {
+                            grid-column: 5;
+                        }   
+
+                        .pz {
+                            grid-column: 6;
+                        }
+
+                        .nz {
+                            grid-column: 7;
+                        }                     
+                    }                    
+
+                    .command {
+                        border: 0px;
+                        background:transparent;
+                        color: white;
+                    }
+
+                    .selected {
+                        border: 1px solid rgb(51, 122, 183);
+                    }
+
+                    .preview {
+                        grid-row: 2;
+                        display: grid;
+                        align-self: center;
+                        justify-self: center;
+                        height: 256px;
+                        width: 256px;
+                        margin-top: 5px;
+                        margin-bottom: 5px;
+                    }
+                }
+
+                .gltf-extension-property {
+                    margin-left: 30px;
+                    border-left: 1px solid rgb(51, 122, 183);
+                }
+
+                .floatLine {
+                    padding-left: 5px;
+                    height: 30px;
+                    display: grid;
+                    grid-template-columns: 1fr 120px;
+
+
+                    .label {
+                        grid-column: 1;
+                        display: flex;
+                        align-items: center;
+                    }
+
+                    .value {
+                        grid-column: 2;
+                        
+                        display: flex;
+                        align-items: center;
+                        
+                        input {
+                            width: 110px;
+                        }
+                    }
+                }
+
+                .sliderLine {
+                    padding-left: 5px;
+                    height: 30px;
+                    display: grid;
+                    grid-template-columns: 1fr auto;
+
+                    .label {
+                        grid-column: 1;
+                        display: flex;
+                        align-items: center;
+                    }
+
+                    .slider {
+                        grid-column: 2;
+                        margin-right: 5px;
+                        
+                        display: flex;
+                        align-items: center;
+
+                        .range {
+                            -webkit-appearance: none;
+                            width: 120px;
+                            height: 6px;
+                            background: #d3d3d3;
+                            border-radius: 5px;
+                            outline: none;
+                            opacity: 0.7;
+                            -webkit-transition: .2s;
+                            transition: opacity .2s;
+                        }
+                        
+                        .range:hover {
+                            opacity: 1;
+                        }
+                        
+                        .range::-webkit-slider-thumb {
+                            -webkit-appearance: none;
+                            appearance: none;
+                            width: 14px;
+                            height: 14px;
+                            border-radius: 50%;
+                            background: rgb(51, 122, 183);
+                            cursor: pointer;
+                        }
+                        
+                        .range::-moz-range-thumb {
+                            width: 14px;
+                            height: 14px;
+                            border-radius: 50%;
+                            background: rgb(51, 122, 183);
+                            cursor: pointer;
+                        }
+                    }                    
+                }       
+                
+                .color3Line {
+                    padding-left: 5px;
+                    height: 30px;
+                    display: grid;
+                    grid-template-columns: 1fr auto;
+
+
+                    .label {
+                        grid-column: 1;
+                        display: flex;
+                        align-items: center;
+                    }
+
+                    .color3 {
+                        grid-column: 2;
+                        
+                        display: flex;
+                        align-items: center;   
+
+                        input[type="color"] {
+                            -webkit-appearance: none;
+                            border: none;
+                            padding: 0;
+                            width: 20px;
+                            height: 20px;
+                        }
+                        input[type="color"]::-webkit-color-swatch-wrapper {
+                            padding: 0;
+                        }
+                        input[type="color"]::-webkit-color-swatch {
+                            border: none;
+                        }
+                        
+                        input {
+                            margin-right: 5px;
+                        }
+                    }                    
+                }     
+                
+                .listLine {
+                    padding-left: 5px;
+                    height: 30px;
+                    display: grid;
+                    grid-template-columns: 1fr auto;
+
+
+                    .label {
+                        grid-column: 1;
+                        display: flex;
+                        align-items: center;
+                    }
+
+                    .options {
+                        grid-column: 2;
+                        
+                        display: flex;
+                        align-items: center;   
+                        margin-right: 5px;
+                    }                    
+                }                   
+
+                .paneContainer {
+                    margin-top: 3px;
+                    
+                    .header {
+                        display: grid;
+                        grid-template-columns: 1fr auto;
+                        background: #555555;    
+                        height: 30px;   
+                        padding-right: 5px;                        
+                        cursor: pointer;
+                        
+                        .title {
+                            margin-left: 5px;
+                            grid-column: 1;
+                            display: flex;
+                            align-items: center;
+                        }
+
+                        .collapse {
+                            grid-column: 2;
+                            display: flex;
+                            align-items: center;  
+                            justify-items: center;
+                            transform-origin: center;
+
+                            &.closed {
+                                transform: rotate(180deg);
+                            }
+                        }                        
+                    }
+
+                    .paneList > div:not(:last-child) {
+                        border-bottom: 0.5px solid rgba(255, 255, 255, 0.1);
+                    }
+                }
+            }
+        }
+    }
+}

+ 133 - 0
inspector/src/components/actionTabs/actionTabsComponent.tsx

@@ -0,0 +1,133 @@
+import * as React from "react";
+import { Observer, Scene, Nullable } from "babylonjs";
+import { TabsComponent } from "./tabsComponent";
+import { faFileAlt, faWrench, faBug, faChartBar } from '@fortawesome/free-solid-svg-icons';
+import { StatisticsTabComponent } from "./tabs/statisticsTabComponent";
+import { DebugTabComponent } from "./tabs/debugTabComponent";
+import Resizable from "re-resizable";
+import { PropertyGridTabComponent } from "./tabs/propertyGridTabComponent";
+import { HeaderComponent } from "../headerComponent";
+import { ToolsTabComponent } from "./tabs/toolsTabComponent";
+import { GlobalState } from "components/globalState";
+
+require("./actionTabs.scss");
+
+interface IActionTabsComponentProps {
+    scene: Scene,
+    noCommands?: boolean,
+    noHeader?: boolean,
+    noExpand?: boolean,
+    popupMode?: boolean,
+    onPopup?: () => void,
+    onClose?: () => void,
+    globalState: GlobalState
+}
+
+export class ActionTabsComponent extends React.Component<IActionTabsComponentProps, { selectedEntity: any, selectedIndex: number }> {
+    private _onSelectionChangeObserver: Nullable<Observer<any>>;
+    private _onTabChangedObserver: Nullable<Observer<any>>;
+    private _once = true;
+
+    constructor(props: IActionTabsComponentProps) {
+        super(props);
+
+        let initialIndex = 0;
+
+        const validationResutls = this.props.globalState.validationResults;
+        if (validationResutls) {
+            if (validationResutls.issues.numErrors || validationResutls.issues.numWarnings) {
+                initialIndex = 3;
+            }
+        }
+
+        this.state = { selectedEntity: null, selectedIndex: initialIndex }
+    }
+
+    componentWillMount() {
+        this._onSelectionChangeObserver = this.props.globalState.onSelectionChangedObservable.add((entity) => {
+            this.setState({ selectedEntity: entity, selectedIndex: 0 });
+        });
+
+        this._onTabChangedObserver = this.props.globalState.onTabChangedObservable.add(index => {
+            this.setState({ selectedIndex: index });
+        });
+    }
+
+    componentWillUnmount() {
+        if (this._onSelectionChangeObserver) {
+            this.props.globalState.onSelectionChangedObservable.remove(this._onSelectionChangeObserver);
+        }
+
+        if (this._onTabChangedObserver) {
+            this.props.globalState.onTabChangedObservable.remove(this._onTabChangedObserver);
+        }
+    }
+
+    changeSelectedTab(index: number) {
+        this.props.globalState.onTabChangedObservable.notifyObservers(index);
+    }
+
+    renderContent() {
+        return (
+            <TabsComponent selectedIndex={this.state.selectedIndex} onSelectedIndexChange={(value) => this.changeSelectedTab(value)}>
+                <PropertyGridTabComponent
+                    title="Properties" icon={faFileAlt} scene={this.props.scene} selectedEntity={this.state.selectedEntity}
+                    onSelectionChangedObservable={this.props.globalState.onSelectionChangedObservable}
+                    onPropertyChangedObservable={this.props.globalState.onPropertyChangedObservable} />
+                <DebugTabComponent title="Debug" icon={faBug} scene={this.props.scene} />
+                <StatisticsTabComponent title="Statistics" icon={faChartBar} scene={this.props.scene} />
+                <ToolsTabComponent title="Tools" icon={faWrench} scene={this.props.scene} globalState={this.props.globalState} />
+            </TabsComponent>
+        )
+    }
+
+    onClose() {
+        if (!this.props.onClose) {
+            return;
+        }
+        this.props.onClose();
+    }
+
+    onPopup() {
+        if (!this.props.onPopup) {
+            return;
+        }
+        this.props.onPopup();
+    }
+
+    render() {
+        if (this.props.popupMode) {
+            return (
+                <div id="actionTabs">
+                    {
+                        !this.props.noHeader &&
+                        <HeaderComponent title="INSPECTOR" handleBack={true} noCommands={this.props.noCommands} onClose={() => this.onClose()} onPopup={() => this.onPopup()} onSelectionChangedObservable={this.props.globalState.onSelectionChangedObservable} />
+                    }
+                    {this.renderContent()}
+                </div>
+            );
+        }
+
+        if (this._once) {
+            this._once = false;
+            // A bit hacky but no other way to force the initial width to 300px and not auto
+            setTimeout(() => {
+                const element = document.getElementById("actionTabs");
+                if (!element) {
+                    return;
+                }
+                element.style.width = "300px";
+            }, 150);
+        }
+
+        return (
+            <Resizable id="actionTabs" minWidth={300} maxWidth={600} size={{ height: "100%" }} minHeight="100%" enable={{ top: false, right: false, bottom: false, left: true, topRight: false, bottomRight: false, bottomLeft: false, topLeft: false }}>
+                {
+                    !this.props.noHeader &&
+                    <HeaderComponent title="INSPECTOR" handleBack={true} noExpand={this.props.noExpand} noCommands={this.props.noCommands} onClose={() => this.onClose()} onPopup={() => this.onPopup()} onSelectionChangedObservable={this.props.globalState.onSelectionChangedObservable} />
+                }
+                {this.renderContent()}
+            </Resizable>
+        );
+    }
+}

+ 59 - 0
inspector/src/components/actionTabs/lineContainerComponent.tsx

@@ -0,0 +1,59 @@
+import * as React from "react";
+import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
+import { faChevronDown } from '@fortawesome/free-solid-svg-icons';
+
+interface ILineContainerComponentProps {
+    title: string,
+    children: any[] | any,
+    closed?: boolean
+}
+
+export class LineContainerComponent extends React.Component<ILineContainerComponentProps, { isExpanded: boolean }> {
+    constructor(props: ILineContainerComponentProps) {
+        super(props);
+
+        this.state = { isExpanded: !this.props.closed };
+    }
+
+    switchExpandedState(): void {
+        this.setState({ isExpanded: !this.state.isExpanded });
+    }
+
+    renderHeader() {
+        const className = this.state.isExpanded ? "collapse" : "collapse closed";
+
+        return (
+            <div className="header" onClick={() => this.switchExpandedState()}>
+                <div className="title">
+                    {this.props.title}
+                </div>
+                <div className={className}>
+                    <FontAwesomeIcon icon={faChevronDown} />
+                </div>
+            </div>
+        )
+    }
+
+    render() {
+        if (!this.state.isExpanded) {
+            return (
+                <div className="paneContainer">
+                    {
+                        this.renderHeader()
+                    }
+                </div>
+            )
+        }
+
+        return (
+            <div className="paneContainer">
+                {
+                    this.renderHeader()
+                }
+                <div className="paneList">
+                    {this.props.children}
+                </div >
+            </div>
+        );
+    }
+}

+ 31 - 0
inspector/src/components/actionTabs/lines/booleanLineComponent.tsx

@@ -0,0 +1,31 @@
+import * as React from "react";
+import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
+import { faCheck, faTimesCircle } from "@fortawesome/free-solid-svg-icons";
+
+export interface IBooleanLineComponentProps {
+    label: string,
+    value: boolean
+}
+
+export class BooleanLineComponent extends React.Component<IBooleanLineComponentProps> {
+    constructor(props: IBooleanLineComponentProps) {
+        super(props);
+    }
+
+    render() {
+
+        const check = this.props.value ? <FontAwesomeIcon icon={faCheck} /> : <FontAwesomeIcon icon={faTimesCircle} />
+        const className = this.props.value ? "value check" : "value uncheck";
+
+        return (
+            <div className="textLine">
+                <div className="label">
+                    {this.props.label}
+                </div>
+                <div className={className}>
+                    {check}
+                </div>
+            </div>
+        );
+    }
+}

+ 21 - 0
inspector/src/components/actionTabs/lines/buttonLineComponent.tsx

@@ -0,0 +1,21 @@
+import * as React from "react";
+
+export interface IButtonLineComponentProps {
+    label: string,
+    onClick: () => void
+}
+
+export class ButtonLineComponent extends React.Component<IButtonLineComponentProps> {
+    constructor(props: IButtonLineComponentProps) {
+        super(props);
+    }
+
+    render() {
+
+        return (
+            <div className="buttonLine">
+                <button onClick={() => this.props.onClick()}>{this.props.label}</button>
+            </div>
+        );
+    }
+}

+ 79 - 0
inspector/src/components/actionTabs/lines/checkBoxLineComponent.tsx

@@ -0,0 +1,79 @@
+import * as React from "react";
+import { Observable } from "babylonjs";
+import { PropertyChangedEvent } from "../../propertyChangedEvent";
+
+export interface ICheckBoxLineComponentProps {
+    label: string,
+    target?: any,
+    propertyName?: string,
+    isSelected?: () => boolean,
+    onSelect?: (value: boolean) => void,
+    onPropertyChangedObservable?: Observable<PropertyChangedEvent>
+}
+
+export class CheckBoxLineComponent extends React.Component<ICheckBoxLineComponentProps, { isSelected: boolean }> {
+    private static _UniqueIdSeed = 0;
+    private _uniqueId: number;
+    private _localChange = false;
+    constructor(props: ICheckBoxLineComponentProps) {
+        super(props);
+
+        this._uniqueId = CheckBoxLineComponent._UniqueIdSeed++;
+
+        if (this.props.isSelected) {
+            this.state = { isSelected: this.props.isSelected() };
+        } else {
+            this.state = { isSelected: this.props.target[this.props.propertyName!] };
+        }
+    }
+
+    shouldComponentUpdate(nextProps: ICheckBoxLineComponentProps, nextState: { isSelected: boolean }) {
+        var currentState: boolean;
+
+        if (this.props.isSelected) {
+            currentState = nextProps.isSelected!();
+        } else {
+            currentState = nextProps.target[nextProps.propertyName!];
+        }
+
+        if (currentState !== nextState.isSelected || this._localChange) {
+            nextState.isSelected = currentState;
+            this._localChange = false;
+            return true;
+        }
+        return false;
+    }
+
+    onChange() {
+        this._localChange = true;
+        if (this.props.onSelect) {
+            this.props.onSelect(!this.state.isSelected);
+        } else {
+            if (this.props.onPropertyChangedObservable) {
+                this.props.onPropertyChangedObservable.notifyObservers({
+                    object: this.props.target,
+                    property: this.props.propertyName!,
+                    value: !this.state.isSelected,
+                    initialValue: this.state.isSelected
+                });
+            }
+
+            this.props.target[this.props.propertyName!] = !this.state.isSelected;
+        }
+        this.setState({ isSelected: !this.state.isSelected });
+    }
+
+    render() {
+        return (
+            <div className="checkBoxLine">
+                <div className="label">
+                    {this.props.label}
+                </div>
+                <div className="checkBox">
+                    <input type="checkbox" id={"checkbox" + this._uniqueId} className="cbx hidden" checked={this.state.isSelected} onChange={() => this.onChange()} />
+                    <label htmlFor={"checkbox" + this._uniqueId} className="lbl"></label>
+                </div>
+            </div>
+        );
+    }
+}

+ 61 - 0
inspector/src/components/actionTabs/lines/color3LineComponent.tsx

@@ -0,0 +1,61 @@
+import * as React from "react";
+import { Observable, Color3 } from "babylonjs";
+import { PropertyChangedEvent } from "../../propertyChangedEvent";
+
+export interface IColor3LineComponentProps {
+    label: string,
+    target: any,
+    propertyName: string,
+    onPropertyChangedObservable?: Observable<PropertyChangedEvent>
+}
+
+export class Color3LineComponent extends React.Component<IColor3LineComponentProps, { color: Color3 }> {
+    private _localChange = false;
+    constructor(props: IColor3LineComponentProps) {
+        super(props);
+
+        this.state = { color: this.props.target[this.props.propertyName] };
+    }
+
+    shouldComponentUpdate(nextProps: IColor3LineComponentProps, nextState: { color: Color3 }) {
+        const currentState = nextProps.target[nextProps.propertyName];
+
+        if (!currentState.equals(nextState.color) || this._localChange) {
+            nextState.color = currentState;
+            this._localChange = false;
+            return true;
+        }
+        return false;
+    }
+
+    onChange(newValue: string) {
+        this._localChange = true;
+        const newColor = BABYLON.Color3.FromHexString(newValue);
+
+        if (this.props.onPropertyChangedObservable) {
+            this.props.onPropertyChangedObservable.notifyObservers({
+                object: this.props.target,
+                property: this.props.propertyName,
+                value: newColor,
+                initialValue: this.state.color
+            });
+        }
+
+        this.props.target[this.props.propertyName] = newColor;
+
+        this.setState({ color: newColor });
+    }
+
+    render() {
+        return (
+            <div className="color3Line">
+                <div className="label">
+                    {this.props.label}
+                </div>
+                <div className="color3">
+                    <input type="color" value={this.state.color.toHexString()} onChange={(evt) => this.onChange(evt.target.value)} />
+                </div>
+            </div>
+        );
+    }
+}

+ 30 - 0
inspector/src/components/actionTabs/lines/fileButtonLineComponent.tsx

@@ -0,0 +1,30 @@
+import * as React from "react";
+
+interface IFileButtonLineComponentProps {
+    label: string,
+    onClick: (file: File) => void
+}
+
+export class FileButtonLineComponent extends React.Component<IFileButtonLineComponentProps> {
+    constructor(props: IFileButtonLineComponentProps) {
+        super(props);
+    }
+
+    onChange(evt: any) {
+        var files: File[] = evt.target.files;
+        if (files && files.length) {
+            this.props.onClick(files[0]);
+        }
+    }
+
+    render() {
+        return (
+            <div className="buttonLine">
+                <label htmlFor="file-upload" className="file-upload">
+                    {this.props.label}
+                </label>
+                <input id="file-upload" type="file" accept=".dds, .env" onChange={evt => this.onChange(evt)} />
+            </div>
+        );
+    }
+}

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

@@ -0,0 +1,87 @@
+import * as React from "react";
+import { Observable } from "babylonjs";
+import { PropertyChangedEvent } from "../../propertyChangedEvent";
+
+interface IFloatLineComponentProps {
+    label: string,
+    target: any,
+    propertyName: string,
+    step?: number,
+    onPropertyChangedObservable?: Observable<PropertyChangedEvent>,
+    additionalClass?: string
+}
+
+export class FloatLineComponent extends React.Component<IFloatLineComponentProps, { value: string }> {
+    private _localChange = false;
+    private _store: number;
+
+    constructor(props: IFloatLineComponentProps) {
+        super(props);
+
+        let currentValue = this.props.target[this.props.propertyName];
+        this.state = { value: currentValue ? currentValue.toFixed(3) : "0" }
+        this._store = currentValue;
+    }
+
+    shouldComponentUpdate(nextProps: IFloatLineComponentProps, nextState: { value: string }) {
+        if (this._localChange) {
+            this._localChange = false;
+            return true;
+        }
+
+        const newValue = nextProps.target[nextProps.propertyName];
+        if (newValue && newValue !== nextState.value) {
+            nextState.value = newValue.toFixed(3);
+            return true;
+        }
+        return false;
+    }
+
+    raiseOnPropertyChanged(newValue: number, previousValue: number) {
+        if (!this.props.onPropertyChangedObservable) {
+            return;
+        }
+        this.props.onPropertyChangedObservable.notifyObservers({
+            object: this.props.target,
+            property: this.props.propertyName,
+            value: newValue,
+            initialValue: previousValue
+        });
+    }
+
+    updateValue(valueString: string) {
+
+        if (/[^0-9\.\-]/g.test(valueString)) {
+            return;
+        }
+
+        let valueAsNumber = parseFloat(valueString);
+
+        this._localChange = true;
+        this.setState({ value: valueString });
+
+        if (isNaN(valueAsNumber)) {
+            return;
+        }
+
+        this.raiseOnPropertyChanged(valueAsNumber, this._store);
+        this.props.target[this.props.propertyName] = valueAsNumber;
+
+        this._store = valueAsNumber;
+    }
+
+    render() {
+
+        const step = this.props.step !== undefined ? this.props.step : 0.1;
+        return (
+            <div className={this.props.additionalClass ? this.props.additionalClass + " floatLine" : "floatLine"}>
+                <div className="label">
+                    {this.props.label}
+                </div>
+                <div className="value">
+                    <input className="numeric-input" value={this.state.value} onChange={evt => this.updateValue(evt.target.value)} step={step} />
+                </div>
+            </div>
+        );
+    }
+}

+ 22 - 0
inspector/src/components/actionTabs/lines/messageLineComponent.tsx

@@ -0,0 +1,22 @@
+import * as React from "react";
+
+interface IMessageLineComponentProps {
+    text: string,
+    color?: string,
+}
+
+export class MessageLineComponent extends React.Component<IMessageLineComponentProps> {
+    constructor(props: IMessageLineComponentProps) {
+        super(props);
+    }
+
+    render() {
+        return (
+            <div className="messageLine">
+                <div className="value" title={this.props.text} style={{ color: this.props.color ? this.props.color : "" }}>
+                    {this.props.text}
+                </div>
+            </div>
+        );
+    }
+}

+ 63 - 0
inspector/src/components/actionTabs/lines/numericInputComponent.tsx

@@ -0,0 +1,63 @@
+import * as React from "react";
+
+interface INumericInputComponentProps {
+    label: string,
+    value: number,
+    onChange: (value: number) => void
+}
+
+export class NumericInputComponent extends React.Component<INumericInputComponentProps, { value: string }> {
+    private _localChange = false;
+    constructor(props: INumericInputComponentProps) {
+        super(props);
+
+        this.state = { value: this.props.value.toFixed(3) }
+    }
+
+    shouldComponentUpdate(nextProps: INumericInputComponentProps, nextState: { value: string }) {
+        if (this._localChange) {
+            this._localChange = false;
+            return true;
+        }
+
+        if (nextProps.value.toString() !== nextState.value) {
+            nextState.value = nextProps.value.toFixed(3);
+            return true;
+        }
+        return false;
+    }
+
+    updateValue(evt: any) {
+        let value = evt.target.value;
+
+        if (/[^0-9\.\-]/g.test(value)) {
+            return;
+        }
+
+        let valueAsNumber = parseFloat(value);
+
+        this._localChange = true;
+        this.setState({ value: value });
+
+        if (isNaN(valueAsNumber)) {
+            return;
+        }
+
+        this.props.onChange(valueAsNumber);
+    }
+
+
+    render() {
+        return (
+            <div className="numeric">
+                {
+                    this.props.label &&
+                    <div className="numeric-label">
+                        {`${this.props.label}: `}
+                    </div>
+                }
+                <input className="numeric-input" value={this.state.value} onChange={evt => this.updateValue(evt)} />
+            </div>
+        )
+    }
+}

+ 96 - 0
inspector/src/components/actionTabs/lines/optionsLineComponent.tsx

@@ -0,0 +1,96 @@
+import * as React from "react";
+import { Observable } from "babylonjs";
+import { PropertyChangedEvent } from "../../propertyChangedEvent";
+
+class ListLineOption {
+    public label: string;
+    public value: number;
+}
+
+interface IOptionsLineComponentProps {
+    label: string,
+    target: any,
+    propertyName: string,
+    options: ListLineOption[],
+    noDirectUpdate?: boolean,
+    onSelect?: (value: number) => void,
+    onPropertyChangedObservable?: Observable<PropertyChangedEvent>
+}
+
+export class OptionsLineComponent extends React.Component<IOptionsLineComponentProps, { value: number }> {
+    private _localChange = false;
+
+    constructor(props: IOptionsLineComponentProps) {
+        super(props);
+
+        this.state = { value: 0 };
+    }
+
+    shouldComponentUpdate(nextProps: IOptionsLineComponentProps, nextState: { value: number }) {
+        if (this._localChange) {
+            this._localChange = false;
+            return true;
+        }
+
+        const newValue = nextProps.target[nextProps.propertyName];
+        if (newValue !== nextState.value) {
+            nextState.value = newValue;
+            return true;
+        }
+        return false;
+    }
+
+    raiseOnPropertyChanged(newValue: number, previousValue: number) {
+        if (!this.props.onPropertyChangedObservable) {
+            return;
+        }
+
+        this.props.onPropertyChangedObservable.notifyObservers({
+            object: this.props.target,
+            property: this.props.propertyName,
+            value: newValue,
+            initialValue: previousValue
+        });
+    }
+
+    updateValue(valueString: string) {
+        const value = parseInt(valueString);
+        this._localChange = true;
+
+        const store = this.state.value;
+        if (!this.props.noDirectUpdate) {
+            this.props.target[this.props.propertyName] = value;
+        }
+        this.setState({ value: value });
+
+        this.raiseOnPropertyChanged(value, store);
+
+        if (this.props.onSelect) {
+            this.props.onSelect(value);
+        }
+    }
+
+    render() {
+        var currentValue = this.props.target[this.props.propertyName];
+
+        return (
+            <div className="listLine">
+                <div className="label">
+                    {this.props.label}
+
+                </div>
+                <div className="options">
+                    <select onChange={evt => this.updateValue(evt.target.value)} defaultValue={currentValue}>
+                        {
+                            this.props.options.map(option => {
+                                return (
+                                    <option key={option.label} value={option.value}>{option.label}</option>
+                                )
+                            })
+                        }
+                    </select>
+                </div>
+            </div>
+        );
+    }
+}

+ 113 - 0
inspector/src/components/actionTabs/lines/quaternionLineComponent.tsx

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

+ 50 - 0
inspector/src/components/actionTabs/lines/radioLineComponent.tsx

@@ -0,0 +1,50 @@
+import * as React from "react";
+import { Observer, Observable, Nullable } from "babylonjs";
+
+interface IRadioButtonLineComponentProps {
+    onSelectionChangedObservable: Observable<RadioButtonLineComponent>,
+    label: string,
+    isSelected: () => boolean,
+    onSelect: () => void
+}
+
+export class RadioButtonLineComponent extends React.Component<IRadioButtonLineComponentProps, { isSelected: boolean }> {
+    private _onSelectionChangedObserver: Nullable<Observer<RadioButtonLineComponent>>;
+
+    constructor(props: IRadioButtonLineComponentProps) {
+        super(props);
+
+        this.state = { isSelected: this.props.isSelected() };
+    }
+
+    componentWillMount() {
+        this._onSelectionChangedObserver = this.props.onSelectionChangedObservable.add((value) => {
+            this.setState({ isSelected: value === this });
+        });
+    }
+
+    componentWillUnmount() {
+        if (this._onSelectionChangedObserver) {
+            this.props.onSelectionChangedObservable.remove(this._onSelectionChangedObserver);
+        }
+    }
+
+    onChange() {
+        this.props.onSelect();
+        this.props.onSelectionChangedObservable.notifyObservers(this);
+    }
+
+    render() {
+        return (
+            <div className="radioLine">
+                <div className="label">
+                    {this.props.label}
+                </div>
+                <div className="radioContainer">
+                    <input id={this.props.label} className="radio" type="radio" checked={this.state.isSelected} onChange={() => this.onChange()} />
+                    <label htmlFor={this.props.label} className="labelForRadio" />
+                </div>
+            </div>
+        );
+    }
+}

+ 64 - 0
inspector/src/components/actionTabs/lines/sliderLineComponent.tsx

@@ -0,0 +1,64 @@
+import * as React from "react";
+import { Observable } from "babylonjs";
+import { PropertyChangedEvent } from "../../propertyChangedEvent";
+
+interface ISliderLineComponentProps {
+    label: string,
+    target: any,
+    propertyName: string,
+    minimum: number,
+    maximum: number,
+    step: number,
+    onPropertyChangedObservable?: Observable<PropertyChangedEvent>
+}
+
+export class SliderLineComponent extends React.Component<ISliderLineComponentProps, { value: number }> {
+    private _localChange = false;
+    constructor(props: ISliderLineComponentProps) {
+        super(props);
+
+        this.state = { value: this.props.target[this.props.propertyName] };
+    }
+
+    shouldComponentUpdate(nextProps: ISliderLineComponentProps, nextState: { value: number }) {
+        const currentState = nextProps.target[nextProps.propertyName];
+
+        if (currentState !== nextState.value || this._localChange) {
+            nextState.value = currentState;
+            this._localChange = false;
+            return true;
+        }
+        return false;
+    }
+
+    onChange(newValueString: any) {
+        this._localChange = true;
+        const newValue = parseFloat(newValueString);
+
+        if (this.props.onPropertyChangedObservable) {
+            this.props.onPropertyChangedObservable.notifyObservers({
+                object: this.props.target,
+                property: this.props.propertyName,
+                value: newValue,
+                initialValue: this.state.value
+            });
+        }
+
+        this.props.target[this.props.propertyName] = newValue;
+
+        this.setState({ value: newValue });
+    }
+
+    render() {
+        return (
+            <div className="sliderLine">
+                <div className="label">
+                    {this.props.label}
+                </div>
+                <div className="slider">
+                    {this.state.value ? this.state.value.toFixed(2) : "0"}&nbsp;<input className="range" type="range" step={this.props.step} min={this.props.minimum} max={this.props.maximum} value={this.state.value} onChange={evt => this.onChange(evt.target.value)} />
+                </div>
+            </div>
+        );
+    }
+}

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

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

+ 48 - 0
inspector/src/components/actionTabs/lines/textLineComponent.tsx

@@ -0,0 +1,48 @@
+import * as React from "react";
+
+interface ITextLineComponentProps {
+    label: string,
+    value: string,
+    color?: string,
+    onLink?: () => void
+}
+
+export class TextLineComponent extends React.Component<ITextLineComponentProps> {
+    constructor(props: ITextLineComponentProps) {
+        super(props);
+    }
+
+    onLink() {
+        if (!this.props.onLink) {
+            return;
+        }
+
+        this.props.onLink();
+    }
+
+    renderContent() {
+        if (this.props.onLink) {
+            return (
+                <div className="link-value" title={this.props.value} onClick={() => this.onLink()}>
+                    {this.props.value || "no name"}
+                </div>
+            )
+        }
+        return (
+            <div className="value" title={this.props.value} style={{ color: this.props.color ? this.props.color : "" }}>
+                {this.props.value || "no name"}
+            </div>
+        )
+    }
+
+    render() {
+        return (
+            <div className="textLine">
+                <div className="label">
+                    {this.props.label}
+                </div>
+                {this.renderContent()}
+            </div>
+        );
+    }
+}

+ 177 - 0
inspector/src/components/actionTabs/lines/textureLineComponent.tsx

@@ -0,0 +1,177 @@
+import * as React from "react";
+import { Texture, PostProcess } from "babylonjs";
+
+interface ITextureLineComponentProps {
+    texture: Texture,
+    width: number,
+    height: number
+}
+
+export class TextureLineComponent extends React.Component<ITextureLineComponentProps, { displayRed: boolean, displayGreen: boolean, displayBlue: boolean, displayAlpha: boolean, face: number }> {
+    constructor(props: ITextureLineComponentProps) {
+        super(props);
+
+        this.state = {
+            displayRed: true,
+            displayGreen: true,
+            displayBlue: true,
+            displayAlpha: true,
+            face: 0
+        }
+    }
+
+    componentDidMount() {
+        this.updatePreview();
+    }
+
+    componentDidUpdate() {
+        this.updatePreview();
+    }
+
+    updatePreview() {
+        var texture = this.props.texture;
+        var scene = texture.getScene()!;
+        var engine = scene.getEngine();
+        var size = texture.getSize();
+        var ratio = size.width / size.height
+        var width = this.props.width;
+        var height = (width / ratio) | 0;
+
+        let passPostProcess: PostProcess;
+
+        if (!texture.isCube) {
+            passPostProcess = new BABYLON.PassPostProcess("pass", 1, null, BABYLON.Texture.NEAREST_SAMPLINGMODE, engine, false, BABYLON.Engine.TEXTURETYPE_UNSIGNED_INT);
+        } else {
+            var passCubePostProcess = new BABYLON.PassCubePostProcess("pass", 1, null, BABYLON.Texture.NEAREST_SAMPLINGMODE, engine, false, BABYLON.Engine.TEXTURETYPE_UNSIGNED_INT);
+            passCubePostProcess.face = this.state.face;
+
+            passPostProcess = passCubePostProcess;
+        }
+
+        if (!passPostProcess.getEffect().isReady()) {
+            // Try again later
+            passPostProcess.dispose();
+
+            setTimeout(() => this.updatePreview(), 250);
+
+            return;
+        }
+
+        const previewCanvas = this.refs.canvas as HTMLCanvasElement;
+
+        let rtt = new BABYLON.RenderTargetTexture(
+            "temp",
+            { width: width, height: height },
+            scene, false);
+
+        passPostProcess.onApply = function(effect) {
+            effect.setTexture("textureSampler", texture);
+        };
+
+        let internalTexture = rtt.getInternalTexture();
+
+        if (internalTexture) {
+            scene.postProcessManager.directRender([passPostProcess], internalTexture);
+
+            // Read the contents of the framebuffer
+            var numberOfChannelsByLine = width * 4;
+            var halfHeight = height / 2;
+
+            //Reading datas from WebGL
+            var data = engine.readPixels(0, 0, width, height);
+
+            if (!texture.isCube) {
+                if (!this.state.displayRed || !this.state.displayGreen || !this.state.displayBlue) {
+                    for (var i = 0; i < width * height * 4; i += 4) {
+
+                        if (!this.state.displayRed) {
+                            data[i] = 0;
+                        }
+
+                        if (!this.state.displayGreen) {
+                            data[i + 1] = 0;
+                        }
+
+                        if (!this.state.displayBlue) {
+                            data[i + 2] = 0;
+                        }
+
+                        if (this.state.displayAlpha) {
+                            var alpha = data[i + 2];
+                            data[i] = alpha;
+                            data[i + 1] = alpha;
+                            data[i + 2] = alpha;
+                            data[i + 2] = 0;
+                        }
+                    }
+                }
+            }
+
+            //To flip image on Y axis.
+            if (texture.invertY || texture.isCube) {
+                for (var i = 0; i < halfHeight; i++) {
+                    for (var j = 0; j < numberOfChannelsByLine; j++) {
+                        var currentCell = j + i * numberOfChannelsByLine;
+                        var targetLine = height - i - 1;
+                        var targetCell = j + targetLine * numberOfChannelsByLine;
+
+                        var temp = data[currentCell];
+                        data[currentCell] = data[targetCell];
+                        data[targetCell] = temp;
+                    }
+                }
+            }
+
+            previewCanvas.width = width;
+            previewCanvas.height = height;
+            var context = previewCanvas.getContext('2d');
+
+            if (context) {
+                // Copy the pixels to the preview canvas
+                var imageData = context.createImageData(width, height);
+                var castData = imageData.data;
+                castData.set(data);
+                context.putImageData(imageData, 0, 0);
+            }
+
+            // Unbind
+            engine.unBindFramebuffer(internalTexture);
+        }
+
+        rtt.dispose();
+        passPostProcess.dispose();
+
+        previewCanvas.style.height = height + "px";
+    }
+
+    render() {
+        var texture = this.props.texture;
+
+        return (
+            <div className="textureLine">
+                {
+                    texture.isCube &&
+                    <div className="control3D">
+                        <button className={this.state.face === 0 ? "px command selected" : "px command"} onClick={() => this.setState({ face: 0 })}>PX</button>
+                        <button className={this.state.face === 1 ? "nx command selected" : "nx command"} onClick={() => this.setState({ face: 1 })}>NX</button>
+                        <button className={this.state.face === 2 ? "py command selected" : "py command"} onClick={() => this.setState({ face: 2 })}>PY</button>
+                        <button className={this.state.face === 3 ? "ny command selected" : "ny command"} onClick={() => this.setState({ face: 3 })}>NY</button>
+                        <button className={this.state.face === 4 ? "pz command selected" : "pz command"} onClick={() => this.setState({ face: 4 })}>PZ</button>
+                        <button className={this.state.face === 5 ? "nz command selected" : "nz command"} onClick={() => this.setState({ face: 5 })}>NZ</button>
+                    </div>
+                }
+                {
+                    !texture.isCube &&
+                    <div className="control">
+                        <button className={this.state.displayRed && !this.state.displayGreen ? "red command selected" : "red command"} onClick={() => this.setState({ displayRed: true, displayGreen: false, displayBlue: false, displayAlpha: false })}>R</button>
+                        <button className={this.state.displayGreen && !this.state.displayBlue ? "green command selected" : "green command"} onClick={() => this.setState({ displayRed: false, displayGreen: true, displayBlue: false, displayAlpha: false })}>G</button>
+                        <button className={this.state.displayBlue && !this.state.displayAlpha ? "blue command selected" : "blue command"} onClick={() => this.setState({ displayRed: false, displayGreen: false, displayBlue: true, displayAlpha: false })}>B</button>
+                        <button className={this.state.displayAlpha && !this.state.displayRed ? "alpha command selected" : "alpha command"} onClick={() => this.setState({ displayRed: false, displayGreen: false, displayBlue: false, displayAlpha: true })}>A</button>
+                        <button className={this.state.displayRed && this.state.displayGreen ? "all command selected" : "all command"} onClick={() => this.setState({ displayRed: true, displayGreen: true, displayBlue: true, displayAlpha: true })}>ALL</button>
+                    </div>
+                }
+                <canvas ref="canvas" className="preview" />
+            </div>
+        );
+    }
+}

+ 135 - 0
inspector/src/components/actionTabs/lines/textureLinkLineComponent.tsx

@@ -0,0 +1,135 @@
+import * as React from "react";
+import { BaseTexture, Observable, Material, Observer, Nullable } from "babylonjs";
+import { TextLineComponent } from "./textLineComponent";
+import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
+import { faWrench } from '@fortawesome/free-solid-svg-icons';
+
+export interface ITextureLinkLineComponentProps {
+    label: string,
+    texture: Nullable<BaseTexture>,
+    material?: Material,
+    onSelectionChangedObservable?: Observable<any>,
+    onDebugSelectionChangeObservable?: Observable<BaseTexture>
+}
+
+export class TextureLinkLineComponent extends React.Component<ITextureLinkLineComponentProps, { isDebugSelected: boolean }> {
+    private _onDebugSelectionChangeObserver: Nullable<Observer<BaseTexture>>;
+
+    constructor(props: ITextureLinkLineComponentProps) {
+        super(props);
+
+        const material = this.props.material;
+        const texture = this.props.texture;
+
+        this.state = { isDebugSelected: material && material.metadata && material.metadata.debugTexture === texture };
+    }
+
+
+    componentWillMount() {
+        if (!this.props.onDebugSelectionChangeObservable) {
+            return;
+        }
+        this._onDebugSelectionChangeObserver = this.props.onDebugSelectionChangeObservable.add((texture) => {
+            if (this.props.texture !== texture) {
+                this.setState({ isDebugSelected: false });
+            }
+        });
+    }
+
+    componentWillUnmount() {
+        if (this.props.onDebugSelectionChangeObservable && this._onDebugSelectionChangeObserver) {
+            this.props.onDebugSelectionChangeObservable.remove(this._onDebugSelectionChangeObserver);
+        }
+    }
+
+    debugTexture() {
+        const texture = this.props.texture;
+        const material = this.props.material;
+
+        if (!material) {
+            return;
+        }
+        const scene = material.getScene();
+
+        if (material.metadata && material.metadata.debugTexture === texture) {
+            const debugMaterial = material.metadata.debugMaterial;
+
+            for (var mesh of scene.meshes) {
+                if (mesh.material === debugMaterial) {
+                    mesh.material = material;
+                }
+            }
+            debugMaterial.dispose();
+            material.metadata.debugTexture = null;
+            material.metadata.debugMaterial = null;
+
+            this.setState({ isDebugSelected: false });
+            return;
+        }
+
+        let checkMaterial = material;
+        let needToDisposeCheckMaterial = false;
+        if (material.metadata && material.metadata.debugTexture) {
+            checkMaterial = material.metadata.debugMaterial;
+            needToDisposeCheckMaterial = true;
+        }
+
+        var debugMaterial = new BABYLON.StandardMaterial("debugMaterial", scene);
+        debugMaterial.disableLighting = true;
+        debugMaterial.sideOrientation = material.sideOrientation;
+        debugMaterial.emissiveTexture = texture!;
+        debugMaterial.forceDepthWrite = true;
+        debugMaterial.metadata = { hidden: true };
+
+        for (var mesh of scene.meshes) {
+            if (mesh.material === checkMaterial) {
+                mesh.material = debugMaterial;
+            }
+        }
+
+        if (!material.metadata) {
+            material.metadata = {};
+        }
+
+        material.metadata.debugTexture = texture;
+        material.metadata.debugMaterial = debugMaterial;
+
+        if (this.props.onDebugSelectionChangeObservable) {
+            this.props.onDebugSelectionChangeObservable.notifyObservers(texture!);
+        }
+
+        if (needToDisposeCheckMaterial) {
+            checkMaterial.dispose();
+        }
+
+        this.setState({ isDebugSelected: true });
+    }
+
+    onLink() {
+        if (!this.props.onSelectionChangedObservable) {
+            return;
+        }
+
+        const texture = this.props.texture;
+        this.props.onSelectionChangedObservable.notifyObservers(texture!);
+    }
+
+    render() {
+        const texture = this.props.texture;
+
+        if (!texture) {
+            return null;
+        }
+        return (
+            <div className="textureLinkLine">
+                {
+                    !texture.isCube && this.props.material &&
+                    <div className={this.state.isDebugSelected ? "debug selected" : "debug"} onClick={() => this.debugTexture()} title="Render as main texture">
+                        <FontAwesomeIcon icon={faWrench} />
+                    </div>
+                }
+                <TextLineComponent label={this.props.label} value={texture.name} onLink={() => this.onLink()} />
+            </div>
+        );
+    }
+}

+ 31 - 0
inspector/src/components/actionTabs/lines/valueLineComponent.tsx

@@ -0,0 +1,31 @@
+import * as React from "react";
+
+interface IValueLineComponentProps {
+    label: string,
+    value: number,
+    color?: string,
+    fractionDigits?: number,
+    units?: string
+}
+
+export class ValueLineComponent extends React.Component<IValueLineComponentProps> {
+    constructor(props: IValueLineComponentProps) {
+        super(props);
+    }
+
+    render() {
+        const digits = this.props.fractionDigits !== undefined ? this.props.fractionDigits : 2;
+        const value = this.props.value.toFixed(digits) + (this.props.units ? " " + this.props.units : "");
+
+        return (
+            <div className="textLine">
+                <div className="label">
+                    {this.props.label}
+                </div>
+                <div className="value" style={{ color: this.props.color ? this.props.color : "" }}>
+                    {value}
+                </div>
+            </div>
+        );
+    }
+}

+ 110 - 0
inspector/src/components/actionTabs/lines/vector3LineComponent.tsx

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

+ 27 - 0
inspector/src/components/actionTabs/paneComponent.tsx

@@ -0,0 +1,27 @@
+import * as React from "react";
+import { IconDefinition } from '@fortawesome/free-solid-svg-icons';
+import { Scene, Observable } from "babylonjs";
+import { PropertyChangedEvent } from "../propertyChangedEvent";
+import { GlobalState } from "components/globalState";
+
+export interface IPaneComponentProps {
+    title: string,
+    icon: IconDefinition, scene: Scene,
+    selectedEntity?: any,
+    onSelectionChangedObservable?: Observable<any>,
+    onPropertyChangedObservable?: Observable<PropertyChangedEvent>,
+    globalState?: GlobalState
+}
+
+export class PaneComponent extends React.Component<IPaneComponentProps, { tag: any }> {
+    constructor(props: IPaneComponentProps) {
+        super(props);
+    }
+
+    render(): JSX.Element | null {
+        return (
+            <div className="pane">
+            </div>
+        );
+    }
+}

+ 116 - 0
inspector/src/components/actionTabs/tabs/debugTabComponent.tsx

@@ -0,0 +1,116 @@
+import * as React from "react";
+import { PaneComponent, IPaneComponentProps } from "../paneComponent";
+import { LineContainerComponent } from "../lineContainerComponent";
+import { CheckBoxLineComponent } from "../lines/checkBoxLineComponent";
+import { GridPropertyGridComponent } from "./propertyGrids/gridPropertyGridComponent";
+
+export class DebugTabComponent extends PaneComponent {
+    private _skeletonViewersEnabled = false;
+    private _skeletonViewers = new Array<BABYLON.Debug.SkeletonViewer>();
+
+    constructor(props: IPaneComponentProps) {
+        super(props);
+    }
+
+
+    componentWillMount() {
+        const scene = this.props.scene;
+
+        if (!scene) {
+            return;
+        }
+
+        for (var mesh of scene.meshes) {
+            if (mesh.skeleton && mesh.metadata && mesh.metadata.skeletonViewer) {
+                this._skeletonViewers.push(mesh.metadata.skeletonViewer);
+            }
+        }
+
+        this._skeletonViewersEnabled = (this._skeletonViewers.length > 0);
+    }
+
+    componentWillUnmount() {
+    }
+
+    switchSkeletonViewers() {
+        this._skeletonViewersEnabled = !this._skeletonViewersEnabled;
+        const scene = this.props.scene;
+
+        if (this._skeletonViewersEnabled) {
+            for (var mesh of scene.meshes) {
+                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, scene, true, 0, BABYLON.UtilityLayerRenderer.DefaultUtilityLayer);
+                    viewer.isEnabled = true;
+                    this._skeletonViewers.push(viewer);
+                    if (!mesh.metadata) {
+                        mesh.metadata = {};
+                    }
+                    mesh.metadata.skeletonViewer = viewer;
+                }
+            }
+        } else {
+            for (var index = 0; index < this._skeletonViewers.length; index++) {
+                this._skeletonViewers[index].mesh.metadata.skeletonViewer = null;
+                this._skeletonViewers[index].dispose();
+            }
+            this._skeletonViewers = [];
+
+        }
+    }
+
+    render() {
+        const scene = this.props.scene;
+
+        if (!scene) {
+            return null;
+        }
+
+        return (
+            <div className="pane">
+                <LineContainerComponent title="HELPERS">
+                    <GridPropertyGridComponent scene={scene} />
+                    <CheckBoxLineComponent label="Bones" isSelected={() => this._skeletonViewersEnabled} onSelect={() => this.switchSkeletonViewers()} />
+                </LineContainerComponent>
+                <LineContainerComponent title="TEXTURE CHANNELS">
+                    <CheckBoxLineComponent label="Diffuse" isSelected={() => BABYLON.StandardMaterial.DiffuseTextureEnabled} onSelect={() => BABYLON.StandardMaterial.DiffuseTextureEnabled = !BABYLON.StandardMaterial.DiffuseTextureEnabled} />
+                    <CheckBoxLineComponent label="Ambient" isSelected={() => BABYLON.StandardMaterial.AmbientTextureEnabled} onSelect={() => BABYLON.StandardMaterial.AmbientTextureEnabled = !BABYLON.StandardMaterial.AmbientTextureEnabled} />
+                    <CheckBoxLineComponent label="Specular" isSelected={() => BABYLON.StandardMaterial.SpecularTextureEnabled} onSelect={() => BABYLON.StandardMaterial.SpecularTextureEnabled = !BABYLON.StandardMaterial.SpecularTextureEnabled} />
+                    <CheckBoxLineComponent label="Emissive" isSelected={() => BABYLON.StandardMaterial.EmissiveTextureEnabled} onSelect={() => BABYLON.StandardMaterial.EmissiveTextureEnabled = !BABYLON.StandardMaterial.EmissiveTextureEnabled} />
+                    <CheckBoxLineComponent label="Bump" isSelected={() => BABYLON.StandardMaterial.BumpTextureEnabled} onSelect={() => BABYLON.StandardMaterial.BumpTextureEnabled = !BABYLON.StandardMaterial.BumpTextureEnabled} />
+                    <CheckBoxLineComponent label="Opacity" isSelected={() => BABYLON.StandardMaterial.OpacityTextureEnabled} onSelect={() => BABYLON.StandardMaterial.OpacityTextureEnabled = !BABYLON.StandardMaterial.OpacityTextureEnabled} />
+                    <CheckBoxLineComponent label="Reflection" isSelected={() => BABYLON.StandardMaterial.ReflectionTextureEnabled} onSelect={() => BABYLON.StandardMaterial.ReflectionTextureEnabled = !BABYLON.StandardMaterial.ReflectionTextureEnabled} />
+                    <CheckBoxLineComponent label="Refraction" isSelected={() => BABYLON.StandardMaterial.RefractionTextureEnabled} onSelect={() => BABYLON.StandardMaterial.RefractionTextureEnabled = !BABYLON.StandardMaterial.RefractionTextureEnabled} />
+                    <CheckBoxLineComponent label="ColorGrading" isSelected={() => BABYLON.StandardMaterial.ColorGradingTextureEnabled} onSelect={() => BABYLON.StandardMaterial.ColorGradingTextureEnabled = !BABYLON.StandardMaterial.ColorGradingTextureEnabled} />
+                    <CheckBoxLineComponent label="Lightmap" isSelected={() => BABYLON.StandardMaterial.LightmapTextureEnabled} onSelect={() => BABYLON.StandardMaterial.LightmapTextureEnabled = !BABYLON.StandardMaterial.LightmapTextureEnabled} />
+                    <CheckBoxLineComponent label="Fresnel" isSelected={() => BABYLON.StandardMaterial.FresnelEnabled} onSelect={() => BABYLON.StandardMaterial.FresnelEnabled = !BABYLON.StandardMaterial.FresnelEnabled} />
+                </LineContainerComponent>
+                <LineContainerComponent title="FEATURES">
+                    <CheckBoxLineComponent label="Animations" isSelected={() => scene.animationsEnabled} onSelect={() => scene.animationsEnabled = !scene.animationsEnabled} />
+                    <CheckBoxLineComponent label="Collisions" isSelected={() => scene.collisionsEnabled} onSelect={() => scene.collisionsEnabled = !scene.collisionsEnabled} />
+                    <CheckBoxLineComponent label="Fog" isSelected={() => scene.fogEnabled} onSelect={() => scene.fogEnabled = !scene.fogEnabled} />
+                    <CheckBoxLineComponent label="Lens flares" isSelected={() => scene.lensFlaresEnabled} onSelect={() => scene.lensFlaresEnabled = !scene.lensFlaresEnabled} />
+                    <CheckBoxLineComponent label="Lights" isSelected={() => scene.lightsEnabled} onSelect={() => scene.lightsEnabled = !scene.lightsEnabled} />
+                    <CheckBoxLineComponent label="Particles" isSelected={() => scene.particlesEnabled} onSelect={() => scene.particlesEnabled = !scene.particlesEnabled} />
+                    <CheckBoxLineComponent label="Post-processes" isSelected={() => scene.postProcessesEnabled} onSelect={() => scene.postProcessesEnabled = !scene.postProcessesEnabled} />
+                    <CheckBoxLineComponent label="Probes" isSelected={() => scene.probesEnabled} onSelect={() => scene.probesEnabled = !scene.probesEnabled} />
+                    <CheckBoxLineComponent label="Textures" isSelected={() => scene.texturesEnabled} onSelect={() => scene.texturesEnabled = !scene.texturesEnabled} />
+                    <CheckBoxLineComponent label="Procedural textures" isSelected={() => scene.proceduralTexturesEnabled} onSelect={() => scene.proceduralTexturesEnabled = !scene.proceduralTexturesEnabled} />
+                    <CheckBoxLineComponent label="Render targets" isSelected={() => scene.renderTargetsEnabled} onSelect={() => scene.renderTargetsEnabled = !scene.renderTargetsEnabled} />
+                    <CheckBoxLineComponent label="Shadows" isSelected={() => scene.shadowsEnabled} onSelect={() => scene.shadowsEnabled = !scene.shadowsEnabled} />
+                    <CheckBoxLineComponent label="Skeletons" isSelected={() => scene.skeletonsEnabled} onSelect={() => scene.skeletonsEnabled = !scene.skeletonsEnabled} />
+                    <CheckBoxLineComponent label="Sprites" isSelected={() => scene.spritesEnabled} onSelect={() => scene.spritesEnabled = !scene.spritesEnabled} />
+                </LineContainerComponent>
+            </div>
+        );
+    }
+}

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

@@ -0,0 +1,144 @@
+import * as React from "react";
+import { PaneComponent, IPaneComponentProps } from "../paneComponent";
+import { Mesh, TransformNode, Material, StandardMaterial, Texture, PBRMaterial, Scene, FreeCamera, ArcRotateCamera, HemisphericLight, PointLight, BackgroundMaterial } from "babylonjs";
+import { MaterialPropertyGridComponent } from "./propertyGrids/materials/materialPropertyGridComponent";
+import { StandardMaterialPropertyGridComponent } from "./propertyGrids/materials/standardMaterialPropertyGridComponent";
+import { TexturePropertyGridComponent } from "./propertyGrids/materials/texturePropertyGridComponent";
+import { PBRMaterialPropertyGridComponent } from "./propertyGrids/materials/pbrMaterialPropertyGridComponent";
+import { ScenePropertyGridComponent } from "./propertyGrids/scenePropertyGridComponent";
+import { HemisphericLightPropertyGridComponent } from "./propertyGrids/lights/hemisphericLightPropertyGridComponent";
+import { PointLightPropertyGridComponent } from "./propertyGrids/lights/pointLightPropertyGridComponent";
+import { FreeCameraPropertyGridComponent } from "./propertyGrids/cameras/freeCameraPropertyGridComponent";
+import { ArcRotateCameraPropertyGridComponent } from "./propertyGrids/cameras/arcRotateCameraPropertyGridComponent";
+import { MeshPropertyGridComponent } from "./propertyGrids/meshes/meshPropertyGridComponent";
+import { TransformNodePropertyGridComponent } from "./propertyGrids/meshes/transformNodePropertyGridComponent";
+import { BackgroundMaterialPropertyGridComponent } from "./propertyGrids/materials/backgroundMaterialPropertyGridComponent";
+import { Control } from "babylonjs-gui/2D/controls/control";
+import { ControlPropertyGridComponent } from "./propertyGrids/gui/controlPropertyGridComponent";
+import { TextBlockPropertyGridComponent } from "./propertyGrids/gui/textBlockPropertyGridComponent";
+import { TextBlock } from "babylonjs-gui/2D/controls/textBlock";
+import { InputText } from "babylonjs-gui/2D/controls/inputText";
+import { InputTextPropertyGridComponent } from "./propertyGrids/gui/inputTextPropertyGridComponent";
+import { ColorPicker } from "babylonjs-gui";
+import { ColorPickerPropertyGridComponent } from "./propertyGrids/gui/colorPickerPropertyGridComponent";
+
+export class PropertyGridTabComponent extends PaneComponent {
+    constructor(props: IPaneComponentProps) {
+        super(props);
+    }
+
+    render() {
+        const entity = this.props.selectedEntity;
+
+        if (!entity) {
+            return (
+                <div className="infoMessage">
+                    Please select an entity in the scene explorer.
+                </div>
+            );
+        }
+
+        if (entity.getClassName) {
+            const className = entity.getClassName();
+
+            if (className.indexOf("Mesh") !== -1) {
+                const mesh = entity as Mesh;
+                if (mesh.getTotalVertices() > 0) {
+                    return (<MeshPropertyGridComponent mesh={mesh}
+                        onSelectionChangedObservable={this.props.onSelectionChangedObservable}
+                        onPropertyChangedObservable={this.props.onPropertyChangedObservable} />);
+                }
+            }
+
+            if (className.indexOf("FreeCamera") !== -1) {
+                const freeCamera = entity as FreeCamera;
+                return (<FreeCameraPropertyGridComponent camera={freeCamera} onPropertyChangedObservable={this.props.onPropertyChangedObservable} />);
+            }
+
+            if (className.indexOf("ArcRotateCamera") !== -1) {
+                const arcRotateCamera = entity as ArcRotateCamera;
+                return (<ArcRotateCameraPropertyGridComponent camera={arcRotateCamera} onPropertyChangedObservable={this.props.onPropertyChangedObservable} />);
+            }
+
+            if (className === "HemisphericLight") {
+                const hemisphericLight = entity as HemisphericLight;
+                return (<HemisphericLightPropertyGridComponent
+                    light={hemisphericLight}
+                    onPropertyChangedObservable={this.props.onPropertyChangedObservable} />);
+            }
+
+            if (className === "PointLight") {
+                const pointLight = entity as PointLight;
+                return (<PointLightPropertyGridComponent
+                    light={pointLight}
+                    onPropertyChangedObservable={this.props.onPropertyChangedObservable} />);
+            }
+
+            if (className.indexOf("TransformNode") !== -1 || className.indexOf("Mesh") !== -1) {
+                const transformNode = entity as TransformNode;
+                return (<TransformNodePropertyGridComponent transformNode={transformNode} onPropertyChangedObservable={this.props.onPropertyChangedObservable} />);
+            }
+
+            if (className === "StandardMaterial") {
+                const material = entity as StandardMaterial;
+                return (<StandardMaterialPropertyGridComponent
+                    material={material}
+                    onSelectionChangedObservable={this.props.onSelectionChangedObservable}
+                    onPropertyChangedObservable={this.props.onPropertyChangedObservable} />);
+            }
+
+            if (className === "PBRMaterial") {
+                const material = entity as PBRMaterial;
+                return (<PBRMaterialPropertyGridComponent
+                    material={material}
+                    onSelectionChangedObservable={this.props.onSelectionChangedObservable}
+                    onPropertyChangedObservable={this.props.onPropertyChangedObservable} />);
+            }
+
+            if (className === "BackgroundMaterial") {
+                const material = entity as BackgroundMaterial;
+                return (<BackgroundMaterialPropertyGridComponent
+                    material={material}
+                    onSelectionChangedObservable={this.props.onSelectionChangedObservable}
+                    onPropertyChangedObservable={this.props.onPropertyChangedObservable} />);
+            }
+
+            if (className.indexOf("Material") !== -1) {
+                const material = entity as Material;
+                return (<MaterialPropertyGridComponent material={material} onPropertyChangedObservable={this.props.onPropertyChangedObservable} />);
+            }
+
+            if (className.indexOf("Texture") !== -1) {
+                const texture = entity as Texture;
+                return (<TexturePropertyGridComponent texture={texture} onPropertyChangedObservable={this.props.onPropertyChangedObservable} />);
+            }
+
+            if (className === "TextBlock") {
+                const textBlock = entity as TextBlock;
+                return (<TextBlockPropertyGridComponent textBlock={textBlock} onPropertyChangedObservable={this.props.onPropertyChangedObservable} />);
+            }
+
+            if (className === "InputText") {
+                const inputText = entity as InputText;
+                return (<InputTextPropertyGridComponent inputText={inputText} onPropertyChangedObservable={this.props.onPropertyChangedObservable} />);
+            }
+
+            if (className === "ColorPicker") {
+                const colorPicker = entity as ColorPicker;
+                return (<ColorPickerPropertyGridComponent colorPicker={colorPicker} onPropertyChangedObservable={this.props.onPropertyChangedObservable} />);
+            }
+
+            if (entity._host) {
+                const control = entity as Control;
+                return (<ControlPropertyGridComponent control={control} onPropertyChangedObservable={this.props.onPropertyChangedObservable} />);
+            }
+        } else if (entity.transformNodes) {
+            const scene = entity as Scene;
+            return (<ScenePropertyGridComponent scene={scene}
+                onSelectionChangedObservable={this.props.onSelectionChangedObservable}
+                onPropertyChangedObservable={this.props.onPropertyChangedObservable} />);
+        }
+
+        return null;
+    }
+}

+ 70 - 0
inspector/src/components/actionTabs/tabs/propertyGrids/cameras/arcRotateCameraPropertyGridComponent.tsx

@@ -0,0 +1,70 @@
+import * as React from "react";
+import { Observable, ArcRotateCamera } from "babylonjs";
+import { PropertyChangedEvent } from "../../../../propertyChangedEvent";
+import { CommonCameraPropertyGridComponent } from "./commonCameraPropertyGridComponent";
+import { LineContainerComponent } from "../../../lineContainerComponent";
+import { CheckBoxLineComponent } from "../../../lines/checkBoxLineComponent";
+import { FloatLineComponent } from "../../../lines/floatLineComponent";
+import { SliderLineComponent } from "../../../lines/sliderLineComponent";
+import { Vector3LineComponent } from "../../../lines/vector3LineComponent";
+
+interface IArcRotateCameraPropertyGridComponentProps {
+    camera: ArcRotateCamera,
+    onPropertyChangedObservable?: Observable<PropertyChangedEvent>
+}
+
+export class ArcRotateCameraPropertyGridComponent extends React.Component<IArcRotateCameraPropertyGridComponentProps> {
+    private _timerIntervalId: number;
+
+    constructor(props: IArcRotateCameraPropertyGridComponentProps) {
+        super(props);
+    }
+
+    componentWillMount() {
+        this._timerIntervalId = window.setInterval(() => this.forceUpdate(), 500);
+    }
+
+    componentWillUnmount() {
+        window.clearInterval(this._timerIntervalId);
+    }
+
+    render() {
+        const camera = this.props.camera;
+
+        return (
+            <div className="pane">
+                <CommonCameraPropertyGridComponent camera={camera} onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
+                <LineContainerComponent title="TRANSFORMS">
+                    <SliderLineComponent label="Alpha" target={camera} propertyName="alpha" minimum={camera.lowerAlphaLimit || 0} maximum={camera.upperAlphaLimit || 2 * Math.PI} step={0.01} onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
+                    <SliderLineComponent label="Beta" target={camera} propertyName="beta" minimum={camera.lowerAlphaLimit || 0} maximum={camera.upperBetaLimit || 2 * Math.PI} step={0.01} onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
+                    <FloatLineComponent label="Radius" target={camera} propertyName="radius" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
+                </LineContainerComponent>
+                <LineContainerComponent title="CONTROLS" closed={true}>
+                    <FloatLineComponent label="Angular sensitivity X" target={camera} propertyName="angularSensibilityX" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
+                    <FloatLineComponent label="Angular sensitivity Y" target={camera} propertyName="angularSensibilityY" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
+                    <FloatLineComponent label="Panning sensitivity" target={camera} propertyName="panningSensibility" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
+                    <FloatLineComponent label="Pinch delta percentage" target={camera} propertyName="pinchDeltaPercentage" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
+                    <FloatLineComponent label="Wheel delta percentage" target={camera} propertyName="wheelDeltaPercentage" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
+                    <FloatLineComponent label="Speed" target={camera} propertyName="speed" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
+                </LineContainerComponent>
+                <LineContainerComponent title="COLLISIONS" closed={true}>
+                    <CheckBoxLineComponent label="Check collisions" target={camera} propertyName="checkCollisions" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
+                    <Vector3LineComponent label="Collision radius" target={camera} propertyName="collisionRadius" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
+                </LineContainerComponent>
+                <LineContainerComponent title="LIMITS" closed={true}>
+                    <FloatLineComponent label="Lower alpha limit" target={camera} propertyName="lowerAlphaLimit" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
+                    <FloatLineComponent label="Upper alpha limit" target={camera} propertyName="upperAlphaLimit" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
+                    <FloatLineComponent label="Lower beta limit" target={camera} propertyName="lowerBetaLimit" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
+                    <FloatLineComponent label="Upper beta limit" target={camera} propertyName="upperBetaLimit" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
+                    <FloatLineComponent label="Lower radius limit" target={camera} propertyName="lowerRadiusLimit" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
+                    <FloatLineComponent label="Upper radius limit" target={camera} propertyName="upperRadiusLimit" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
+                </LineContainerComponent>
+                <LineContainerComponent title="BEHAVIORS" closed={true}>
+                    <CheckBoxLineComponent label="Auto rotation" target={camera} propertyName="useAutoRotationBehavior" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
+                    <CheckBoxLineComponent label="Bouncing" target={camera} propertyName="useBouncingBehavior" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
+                    <CheckBoxLineComponent label="Framing" target={camera} propertyName="useFramingBehavior" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
+                </LineContainerComponent>
+            </div>
+        );
+    }
+}

+ 63 - 0
inspector/src/components/actionTabs/tabs/propertyGrids/cameras/commonCameraPropertyGridComponent.tsx

@@ -0,0 +1,63 @@
+import * as React from "react";
+import { Camera, Observable } from "babylonjs";
+import { PropertyChangedEvent } from "../../../../propertyChangedEvent";
+import { SliderLineComponent } from "../../../lines/sliderLineComponent";
+import { LineContainerComponent } from "../../../lineContainerComponent";
+import { FloatLineComponent } from "../../../lines/floatLineComponent";
+import { TextLineComponent } from "../../../lines/textLineComponent";
+import { OptionsLineComponent } from "../../../lines/optionsLineComponent";
+
+interface ICommonCameraPropertyGridComponentProps {
+    camera: Camera,
+    onPropertyChangedObservable?: Observable<PropertyChangedEvent>
+}
+
+export class CommonCameraPropertyGridComponent extends React.Component<ICommonCameraPropertyGridComponentProps, { mode: number }> {
+    constructor(props: ICommonCameraPropertyGridComponentProps) {
+        super(props);
+
+        this.state = { mode: this.props.camera.mode };
+    }
+
+    render() {
+        const camera = this.props.camera;
+
+        var modeOptions = [
+            { label: "Perspective", value: BABYLON.Camera.PERSPECTIVE_CAMERA },
+            { label: "Orthographic", value: BABYLON.Camera.ORTHOGRAPHIC_CAMERA }
+        ];
+
+        return (
+            <LineContainerComponent title="GENERAL">
+                <TextLineComponent label="ID" value={camera.id} />
+                <TextLineComponent label="Unique ID" value={camera.uniqueId.toString()} />
+                <TextLineComponent label="Class" value={camera.getClassName()} />
+                <FloatLineComponent label="Near plane" target={camera} propertyName="minZ" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
+                <FloatLineComponent label="Far plane" target={camera} propertyName="maxZ" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
+                <SliderLineComponent label="Inertia" target={camera} propertyName="inertia" minimum={0} maximum={1} step={0.01} onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
+                <OptionsLineComponent label="Mode" options={modeOptions} target={camera} propertyName="mode" onPropertyChangedObservable={this.props.onPropertyChangedObservable} onSelect={value => this.setState({ mode: value })} />
+                {
+                    camera.mode === BABYLON.Camera.PERSPECTIVE_CAMERA &&
+                    <SliderLineComponent label="Field of view" target={camera} propertyName="fov" minimum={0.1} maximum={Math.PI} step={0.1} onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
+                }
+                {
+                    camera.mode === BABYLON.Camera.ORTHOGRAPHIC_CAMERA &&
+                    <FloatLineComponent label="Left" target={camera} propertyName="orthoLeft" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
+                }
+                {
+                    camera.mode === BABYLON.Camera.ORTHOGRAPHIC_CAMERA &&
+                    <FloatLineComponent label="Top" target={camera} propertyName="orthoTop" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
+                }
+                {
+                    camera.mode === BABYLON.Camera.ORTHOGRAPHIC_CAMERA &&
+                    <FloatLineComponent label="Right" target={camera} propertyName="orthoRight" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
+                }
+                {
+                    camera.mode === BABYLON.Camera.ORTHOGRAPHIC_CAMERA &&
+                    <FloatLineComponent label="Bottom" target={camera} propertyName="orthoBottom" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
+                }
+
+            </LineContainerComponent>
+        );
+    }
+}

+ 52 - 0
inspector/src/components/actionTabs/tabs/propertyGrids/cameras/freeCameraPropertyGridComponent.tsx

@@ -0,0 +1,52 @@
+import * as React from "react";
+import { Observable, FreeCamera } from "babylonjs";
+import { CommonCameraPropertyGridComponent } from "./commonCameraPropertyGridComponent";
+import { PropertyChangedEvent } from "../../../../propertyChangedEvent";
+import { LineContainerComponent } from "../../../lineContainerComponent";
+import { Vector3LineComponent } from "../../../lines/vector3LineComponent";
+import { FloatLineComponent } from "../../../lines/floatLineComponent";
+import { CheckBoxLineComponent } from "../../../lines/checkBoxLineComponent";
+
+interface IFreeCameraPropertyGridComponentProps {
+    camera: FreeCamera,
+    onPropertyChangedObservable?: Observable<PropertyChangedEvent>
+}
+
+export class FreeCameraPropertyGridComponent extends React.Component<IFreeCameraPropertyGridComponentProps> {
+    private _timerIntervalId: number;
+
+    constructor(props: IFreeCameraPropertyGridComponentProps) {
+        super(props);
+    }
+
+    componentWillMount() {
+        this._timerIntervalId = window.setInterval(() => this.forceUpdate(), 500);
+    }
+
+    componentWillUnmount() {
+        window.clearInterval(this._timerIntervalId);
+    }
+
+    render() {
+        const camera = this.props.camera;
+
+        return (
+            <div className="pane">
+                <CommonCameraPropertyGridComponent camera={camera} onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
+                <LineContainerComponent title="TRANSFORMS">
+                    <Vector3LineComponent label="Position" target={camera} propertyName="position" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
+                </LineContainerComponent>
+                <LineContainerComponent title="CONTROLS" closed={true}>
+                    <FloatLineComponent label="Angular sensitivity" target={camera} propertyName="angularSensibility" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
+                    <FloatLineComponent label="Speed" target={camera} propertyName="speed" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
+                </LineContainerComponent>
+                <LineContainerComponent title="COLLISIONS" closed={true}>
+                    <CheckBoxLineComponent label="Check collisions" target={camera} propertyName="checkCollisions" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
+                    <CheckBoxLineComponent label="Apply gravity" target={camera} propertyName="applYGravity" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
+                    <Vector3LineComponent label="Ellipsoid" target={camera} propertyName="ellipsoid" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
+                    <Vector3LineComponent label="Ellipsoid offset" target={camera} propertyName="ellipsoidOffset" onPropertyChangedObservable={this.props.onPropertyChangedObservable} />
+                </LineContainerComponent>
+            </div>
+        );
+    }
+}

+ 102 - 0
inspector/src/components/actionTabs/tabs/propertyGrids/cameras/propertyGridTabComponent.tsx

@@ -0,0 +1,102 @@
+import * as React from "react";
+import { PaneComponent, IPaneComponentProps } from "../../../paneComponent";
+import { Mesh, TransformNode, Material, StandardMaterial, Texture, PBRMaterial, Scene, FreeCamera, ArcRotateCamera, HemisphericLight, PointLight } from "babylonjs";
+import { MaterialPropertyGridComponent } from "../materials/materialPropertyGridComponent";
+import { StandardMaterialPropertyGridComponent } from "../materials/standardMaterialPropertyGridComponent";
+import { TexturePropertyGridComponent } from "../materials/texturePropertyGridComponent";
+import { PBRMaterialPropertyGridComponent } from "../materials/pbrMaterialPropertyGridComponent";
+import { ScenePropertyGridComponent } from "../scenePropertyGridComponent";
+import { HemisphericLightPropertyGridComponent } from "../lights/hemisphericLightPropertyGridComponent";
+import { PointLightPropertyGridComponent } from "../lights/pointLightPropertyGridComponent";
+import { FreeCameraPropertyGridComponent } from "./freeCameraPropertyGridComponent";
+import { ArcRotateCameraPropertyGridComponent } from "./arcRotateCameraPropertyGridComponent";
+import { MeshPropertyGridComponent } from "../meshes/meshPropertyGridComponent";
+import { TransformNodePropertyGridComponent } from "../meshes/transformNodePropertyGridComponent";
+
+export class PropertyGridTabComponent extends PaneComponent {
+    constructor(props: IPaneComponentProps) {
+        super(props);
+    }
+
+    render() {
+        const entity = this.props.selectedEntity;
+
+        if (!entity) {
+            return null;
+        }
+
+        if (entity.getClassName) {
+            const className = entity.getClassName();
+
+            if (className.indexOf("Mesh") !== -1) {
+                const mesh = entity as Mesh;
+                if (mesh.getTotalVertices() > 0) {
+                    return (<MeshPropertyGridComponent mesh={mesh}
+                        onSelectionChangedObservable={this.props.onSelectionChangedObservable}
+                        onPropertyChangedObservable={this.props.onPropertyChangedObservable} />);
+                }
+            }
+
+            if (className.indexOf("FreeCamera") !== -1) {
+                const freeCamera = entity as FreeCamera;
+                return (<FreeCameraPropertyGridComponent camera={freeCamera} onPropertyChangedObservable={this.props.onPropertyChangedObservable} />);
+            }
+
+            if (className.indexOf("ArcRotateCamera") !== -1) {
+                const arcRotateCamera = entity as ArcRotateCamera;
+                return (<ArcRotateCameraPropertyGridComponent camera={arcRotateCamera} onPropertyChangedObservable={this.props.onPropertyChangedObservable} />);
+            }
+
+            if (className === "HemisphericLight") {
+                const hemisphericLight = entity as HemisphericLight;
+                return (<HemisphericLightPropertyGridComponent
+                    light={hemisphericLight}
+                    onPropertyChangedObservable={this.props.onPropertyChangedObservable} />);
+            }
+
+            if (className === "PointLight") {
+                const pointLight = entity as PointLight;
+                return (<PointLightPropertyGridComponent
+                    light={pointLight}
+                    onPropertyChangedObservable={this.props.onPropertyChangedObservable} />);
+            }
+
+            if (className.indexOf("TransformNode") !== -1 || className.indexOf("Mesh") !== -1) {
+                const transformNode = entity as TransformNode;
+                return (<TransformNodePropertyGridComponent transformNode={transformNode} onPropertyChangedObservable={this.props.onPropertyChangedObservable} />);
+            }
+
+            if (className === "StandardMaterial") {
+                const material = entity as StandardMaterial;
+                return (<StandardMaterialPropertyGridComponent
+                    material={material}
+                    onSelectionChangedObservable={this.props.onSelectionChangedObservable}
+                    onPropertyChangedObservable={this.props.onPropertyChangedObservable} />);
+            }
+
+            if (className === "PBRMaterial") {
+                const material = entity as PBRMaterial;
+                return (<PBRMaterialPropertyGridComponent
+                    material={material}
+                    onSelectionChangedObservable={this.props.onSelectionChangedObservable}
+                    onPropertyChangedObservable={this.props.onPropertyChangedObservable} />);
+            }
+
+            if (className.indexOf("Material") !== -1) {
+                const material = entity as Material;
+                return (<MaterialPropertyGridComponent material={material} onPropertyChangedObservable={this.props.onPropertyChangedObservable} />);
+            }
+
+            if (className.indexOf("Texture") !== -1) {
+                const texture = entity as Texture;
+                return (<TexturePropertyGridComponent texture={texture} onPropertyChangedObservable={this.props.onPropertyChangedObservable} />);
+            }
+
+        } else if (entity.transformNodes) {
+            const scene = entity as Scene;
+            return (<ScenePropertyGridComponent scene={scene} onPropertyChangedObservable={this.props.onPropertyChangedObservable} />);
+        }
+
+        return null;
+    }
+}

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


Daži faili netika attēloti, jo izmaiņu fails ir pārāk liels