소스 검색

Merge branch 'master' into utilityLayerFixes

Trevor Baron 7 년 전
부모
커밋
bdec2f7767
100개의 변경된 파일19362개의 추가작업 그리고 18519개의 파일을 삭제
  1. 6 0
      .gitignore
  2. 1 1
      .vscode/tasks.json
  3. 1463 1470
      Playground/babylon.d.txt
  4. 79 0
      Playground/css/color_ts.css
  5. 421 419
      Playground/debug.html
  6. 5 1
      Playground/index-local.html
  7. 11 10
      Playground/index.html
  8. 11 3
      Playground/js/index.js
  9. 24 0
      Playground/ts.html
  10. 31 24
      Tools/DevLoader/BabylonLoader.js
  11. 93 151
      Tools/Gulp/config.json
  12. 94 33
      Tools/Gulp/gulpfile.js
  13. 2 1
      Tools/Gulp/package.json
  14. 44 19
      Tools/Gulp/processViewerDeclaration.js
  15. 6 3
      Tools/Publisher/index.js
  16. 139 0
      Tools/WebpackShaderLoader/index.js
  17. 6 4
      Viewer/package.json
  18. 3 1
      Viewer/src/configuration/types/default.ts
  19. 62 0
      Viewer/src/templating/plugins/printButton.ts
  20. 2 0
      Viewer/src/viewer/defaultViewer.ts
  21. 2 1
      Viewer/tests/unit/tsconfig.json
  22. 4 2
      Viewer/tests/unit/webpack.config.js
  23. 1 1
      Viewer/tsconfig-gulp.json
  24. 2 2
      Viewer/tsconfig.json
  25. 4 2
      Viewer/webpack.assets.config.js
  26. 4 3
      Viewer/webpack.config.js
  27. 9 10
      Viewer/webpack.gulp.config.js
  28. 8115 8114
      dist/preview release/babylon.d.ts
  29. 47 47
      dist/preview release/babylon.js
  30. 23 18
      dist/preview release/babylon.max.js
  31. 23 18
      dist/preview release/babylon.no-module.max.js
  32. 47 47
      dist/preview release/babylon.worker.js
  33. 23 18
      dist/preview release/es6.js
  34. 1 2
      dist/preview release/gui/package.json
  35. 3 0
      dist/preview release/inspector/package.json
  36. 1 0
      dist/preview release/loaders/babylon.objFileLoader.d.ts
  37. 37 1
      dist/preview release/loaders/babylon.objFileLoader.js
  38. 1 1
      dist/preview release/loaders/babylon.objFileLoader.min.js
  39. 1 0
      dist/preview release/loaders/babylonjs.loaders.d.ts
  40. 37 1
      dist/preview release/loaders/babylonjs.loaders.js
  41. 4 4
      dist/preview release/loaders/babylonjs.loaders.min.js
  42. 1 0
      dist/preview release/loaders/babylonjs.loaders.module.d.ts
  43. 77 43
      dist/preview release/viewer/babylon.viewer.d.ts
  44. 58 58
      dist/preview release/viewer/babylon.viewer.js
  45. 290 195
      dist/preview release/viewer/babylon.viewer.max.js
  46. 77 43
      dist/preview release/viewer/babylon.viewer.module.d.ts
  47. 6 2
      dist/preview release/what's new.md
  48. 41 0
      gui/package.json
  49. 3 3
      gui/readme.md
  50. 587 589
      gui/src/2D/advancedDynamicTexture.ts
  51. 182 180
      gui/src/2D/controls/button.ts
  52. 118 118
      gui/src/2D/controls/checkbox.ts
  53. 354 356
      gui/src/2D/controls/colorpicker.ts
  54. 261 260
      gui/src/2D/controls/container.ts
  55. 1135 1159
      gui/src/2D/controls/control.ts
  56. 71 71
      gui/src/2D/controls/ellipse.ts
  57. 277 276
      gui/src/2D/controls/grid.ts
  58. 279 279
      gui/src/2D/controls/image.ts
  59. 19 0
      gui/src/2D/controls/index.ts
  60. 10 12
      gui/src/2D/controls/inputPassword.ts
  61. 426 424
      gui/src/2D/controls/inputText.ts
  62. 216 215
      gui/src/2D/controls/line.ts
  63. 187 186
      gui/src/2D/controls/multiLine.ts
  64. 136 136
      gui/src/2D/controls/radioButton.ts
  65. 117 118
      gui/src/2D/controls/rectangle.ts
  66. 359 358
      gui/src/2D/controls/slider.ts
  67. 127 127
      gui/src/2D/controls/stackPanel.ts
  68. 53 0
      gui/src/2D/controls/statics.ts
  69. 329 328
      gui/src/2D/controls/textBlock.ts
  70. 199 196
      gui/src/2D/controls/virtualKeyboard.ts
  71. 8 0
      gui/src/2D/index.ts
  72. 184 186
      gui/src/2D/math2D.ts
  73. 57 60
      gui/src/2D/measure.ts
  74. 106 106
      gui/src/2D/multiLinePoint.ts
  75. 79 79
      gui/src/2D/style.ts
  76. 135 137
      gui/src/2D/valueAndUnit.ts
  77. 17 18
      gui/src/3D/controls/abstractButton3D.ts
  78. 135 134
      gui/src/3D/controls/button3D.ts
  79. 121 122
      gui/src/3D/controls/container3D.ts
  80. 346 345
      gui/src/3D/controls/control3D.ts
  81. 48 48
      gui/src/3D/controls/cylinderPanel.ts
  82. 210 206
      gui/src/3D/controls/holographicButton.ts
  83. 12 0
      gui/src/3D/controls/index.ts
  84. 50 51
      gui/src/3D/controls/meshButton3D.ts
  85. 29 28
      gui/src/3D/controls/planePanel.ts
  86. 91 95
      gui/src/3D/controls/scatterPanel.ts
  87. 49 49
      gui/src/3D/controls/spherePanel.ts
  88. 87 88
      gui/src/3D/controls/stackPanel3D.ts
  89. 155 161
      gui/src/3D/controls/volumeBasedPanel.ts
  90. 180 181
      gui/src/3D/gui3DManager.ts
  91. 5 0
      gui/src/3D/index.ts
  92. 237 235
      gui/src/3D/materials/fluentMaterial.ts
  93. 1 0
      gui/src/3D/materials/index.ts
  94. 12 0
      gui/src/3D/materials/shaders/fluent.ts
  95. 12 14
      gui/src/3D/vector3WithInfo.ts
  96. 2 0
      gui/src/index.ts
  97. 0 12
      gui/src/tsconfig.json
  98. 31 0
      gui/tsconfig.json
  99. 76 0
      gui/webpack.config.js
  100. 0 0
      inspector/package.json

+ 6 - 0
.gitignore

@@ -13,6 +13,7 @@ TestResults
 *.user
 *.user
 *.sln.docstates
 *.sln.docstates
 *.map
 *.map
+!dist/**/*.map
 
 
 # javascript files
 # javascript files
 src/**/*.js
 src/**/*.js
@@ -161,8 +162,12 @@ node_modules
 *.js.fx
 *.js.fx
 *.d.ts
 *.d.ts
 !dist/**/*.d.ts
 !dist/**/*.d.ts
+!dist/**/*.js.map
 !lib.d.ts
 !lib.d.ts
 
 
+# Split declaration file
+!ISplit.d.ts
+
 # local dev
 # local dev
 localDev/src/*
 localDev/src/*
 /dist/preview release/babylon.custom.js
 /dist/preview release/babylon.custom.js
@@ -183,3 +188,4 @@ Viewer/tests/unit/src/**/*.js
 Viewer/tests/Lib/**/*.js
 Viewer/tests/Lib/**/*.js
 Viewer/tests/commons/**/*.js
 Viewer/tests/commons/**/*.js
 .sass-cache/
 .sass-cache/
+gui/dist/

+ 1 - 1
.vscode/tasks.json

@@ -66,7 +66,7 @@
                     "background": {
                     "background": {
                         "activeOnStart": true,
                         "activeOnStart": true,
                         "beginsPattern": "Project is running at",
                         "beginsPattern": "Project is running at",
-                        "endsPattern": "webpack: Compiled successfully."
+                        "endsPattern": "Compiled successfully."
                     }
                     }
                 }
                 }
             ],
             ],

파일 크기가 너무 크기때문에 변경 상태를 표시하지 않습니다.
+ 1463 - 1470
Playground/babylon.d.txt


+ 79 - 0
Playground/css/color_ts.css

@@ -0,0 +1,79 @@
+@import url("https://fonts.googleapis.com/css?family=Montserrat:300,400");
+@import url("https://maxcdn.bootstrapcdn.com/font-awesome/4.6.3/css/font-awesome.min.css");
+#waitTitle {
+    color: rgb(208, 23, 211);
+}
+#exampleList #exampleBanner h1 {
+    color: #ae00ef;
+}
+#exampleList .horizontalSeparator {
+    border-top: 1px solid #ae00ef;
+}
+#exampleList .categoryContainer .itemLine .itemContent .itemLineDocLink {
+    color: #ae00ef;
+}
+#exampleList .categoryContainer .itemLine .itemContent .itemLinePGLink {
+    color: #ae00ef;
+}
+
+#fpsLabel {
+    background-color: #9147c9;
+}
+.navbar .title {
+    color: #bb47c9;
+}
+.navbar .version {
+    color: #9147c9;
+}
+
+.button {
+    background-color: #9147c9;
+}
+.button:hover {
+    background-color: #bb47c9;
+}
+.navbar .button.run {
+    background-color: #bb47c9;
+}
+.navbar .select .toDisplay {
+    border: 1px solid #9147c9;
+}
+.navbar .select .subSelect .toDisplaySub {
+    border: 1px solid #9147c9;
+}
+
+.navbar .select .toDisplay .option {
+    font-size: 0.9em;
+    height: 35px;
+    line-height: 35px;
+    padding: 0px 5px 0px 5px;
+    text-align: center;
+    border-bottom : 1px solid rgba(0,0,0,0.1);
+}
+
+.navbar .select .toDisplay .option.light:hover {
+    cursor: pointer;
+    background-color: #d9d9d9;
+}
+
+
+.navbar .select .toDisplay .option.dark {
+    background-color: #333;
+    color: white;
+}
+.navbar .select .toDisplay .option.light {
+    background-color: white;
+    color: #9147c9;
+}
+.navbar .select .toDisplayBig {
+    border: 1px solid #9147c9;
+}
+
+.navbar .select .toDisplayBig.light {    
+    color: #bb47c9;
+}
+.navbar .select .toDisplayBig a.light {
+    color: #9147c9;
+}
+
+

+ 421 - 419
Playground/debug.html

@@ -1,510 +1,512 @@
 <!DOCTYPE html>
 <!DOCTYPE html>
 <html>
 <html>
 
 
-<head>
-    <title>Babylon.js Playground</title>
-    <meta charset='utf-8' />
-    <meta name="viewport" content="width=device-width, user-scalable=no">
-    <link rel="shortcut icon" href="https://www.babylonjs.com/img/favicon/favicon.ico">
-    <link rel="apple-touch-icon" sizes="57x57" href="https://www.babylonjs.com/img/favicon/apple-icon-57x57.png">
-    <link rel="apple-touch-icon" sizes="60x60" href="https://www.babylonjs.com/img/favicon/apple-icon-60x60.png">
-    <link rel="apple-touch-icon" sizes="72x72" href="https://www.babylonjs.com/img/favicon/apple-icon-72x72.png">
-    <link rel="apple-touch-icon" sizes="76x76" href="https://www.babylonjs.com/img/favicon/apple-icon-76x76.png">
-    <link rel="apple-touch-icon" sizes="114x114" href="https://www.babylonjs.com/img/favicon/apple-icon-114x114.png">
-    <link rel="apple-touch-icon" sizes="120x120" href="https://www.babylonjs.com/img/favicon/apple-icon-120x120.png">
-    <link rel="apple-touch-icon" sizes="144x144" href="https://www.babylonjs.com/img/favicon/apple-icon-144x144.png">
-    <link rel="apple-touch-icon" sizes="152x152" href="https://www.babylonjs.com/img/favicon/apple-icon-152x152.png">
-    <link rel="apple-touch-icon" sizes="180x180" href="https://www.babylonjs.com/img/favicon/apple-icon-180x180.png">
-    <link rel="icon" type="image/png" sizes="192x192" href="https://www.babylonjs.com/img/favicon/android-icon-192x192.png">
-    <link rel="icon" type="image/png" sizes="32x32" href="https://www.babylonjs.com/img/favicon/favicon-32x32.png">
-    <link rel="icon" type="image/png" sizes="96x96" href="https://www.babylonjs.com/img/favicon/favicon-96x96.png">
-    <link rel="icon" type="image/png" sizes="16x16" href="https://www.babylonjs.com/img/favicon/favicon-16x16.png">
-    <link rel="manifest" href="https://www.babylonjs.com/img/favicon/manifest.json">
-    <meta name="msapplication-TileColor" content="#ffffff">
-    <meta name="msapplication-TileImage" content="https://www.babylonjs.com/img/favicon/ms-icon-144x144.png">
-    <meta name="msapplication-config" content="https://www.babylonjs.com/img/favicon/browserconfig.xml">
-    <meta name="theme-color" content="#ffffff">
-
-    <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>
-    <!-- Monaco -->
-    <script src="node_modules/monaco-editor/min/vs/loader.js"></script>
-    <!-- Babylon.js -->
-    <script src="https://preview.babylonjs.com/cannon.js"></script>
-    <script src="https://preview.babylonjs.com/Oimo.js"></script>
-    <script src="https://preview.babylonjs.com/babylon.max.js"></script>
-    <script src="https://preview.babylonjs.com/inspector/babylon.inspector.bundle.js"></script>
-
-    <script src="https://preview.babylonjs.com/materialsLibrary/babylon.fireMaterial.min.js"></script>
-    <script src="https://preview.babylonjs.com/materialsLibrary/babylon.waterMaterial.min.js"></script>
-    <script src="https://preview.babylonjs.com/materialsLibrary/babylon.lavaMaterial.min.js"></script>
-    <script src="https://preview.babylonjs.com/materialsLibrary/babylon.normalMaterial.min.js"></script>
-    <script src="https://preview.babylonjs.com/materialsLibrary/babylon.skyMaterial.min.js"></script>
-    <script src="https://preview.babylonjs.com/materialsLibrary/babylon.triPlanarMaterial.min.js"></script>
-    <script src="https://preview.babylonjs.com/materialsLibrary/babylon.terrainMaterial.min.js"></script>
-    <script src="https://preview.babylonjs.com/materialsLibrary/babylon.gradientMaterial.min.js"></script>
-    <script src="https://preview.babylonjs.com/materialsLibrary/babylon.furMaterial.min.js"></script>
-    <script src="https://preview.babylonjs.com/materialsLibrary/babylon.gridMaterial.min.js"></script>
-    <script src="https://preview.babylonjs.com/materialsLibrary/babylon.shadowOnlyMaterial.min.js"></script>
-    <script src="https://preview.babylonjs.com/materialsLibrary/babylon.customMaterial.min.js"></script>
-    <script src="https://preview.babylonjs.com/materialsLibrary/babylon.cellMaterial.min.js"></script>
-
-    <script src="https://preview.babylonjs.com/proceduralTexturesLibrary/babylon.brickProceduralTexture.min.js"></script>
-    <script src="https://preview.babylonjs.com/proceduralTexturesLibrary/babylon.cloudProceduralTexture.min.js"></script>
-    <script src="https://preview.babylonjs.com/proceduralTexturesLibrary/babylon.fireProceduralTexture.min.js"></script>
-    <script src="https://preview.babylonjs.com/proceduralTexturesLibrary/babylon.grassProceduralTexture.min.js"></script>
-    <script src="https://preview.babylonjs.com/proceduralTexturesLibrary/babylon.marbleProceduralTexture.min.js"></script>
-    <script src="https://preview.babylonjs.com/proceduralTexturesLibrary/babylon.roadProceduralTexture.min.js"></script>
-    <script src="https://preview.babylonjs.com/proceduralTexturesLibrary/babylon.starfieldProceduralTexture.min.js"></script>
-    <script src="https://preview.babylonjs.com/proceduralTexturesLibrary/babylon.woodProceduralTexture.min.js"></script>
-
-    <script src="https://preview.babylonjs.com/postProcessesLibrary/babylon.asciiArtPostProcess.min.js"></script>
-    <script src="https://preview.babylonjs.com/postProcessesLibrary/babylon.digitalRainPostProcess.min.js"></script>
-
-    <script src="https://preview.babylonjs.com/loaders/babylon.glTFFileLoader.js"></script>
-    <script src="https://preview.babylonjs.com/loaders/babylon.objFileLoader.js"></script>
-    <script src="https://preview.babylonjs.com/loaders/babylon.stlFileLoader.js"></script>
-
-    <script src="https://preview.babylonjs.com/gui/babylon.gui.js"></script>
-
-    <script src="https://preview.babylonjs.com/serializers/babylonjs.serializers.min.js"></script>
-
-    <script src="https://rawgit.com/BabylonJS/Extensions/master/ClonerSystem/src/babylonx.cloner.js"></script>
-    <script src="https://rawgit.com/BabylonJS/Extensions/master/CompoundShader/src/babylonx.CompoundShader.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">
-            v3.0-alpha
-        </div>
-
-        <div class="category">
-            <div class="button run" id="runButton1600">Run
-                <i class="fa fa-play" aria-hidden="true"></i>
+    <head>
+        <title>Babylon.js Playground</title>
+        <meta charset='utf-8' />
+        <meta name="viewport" content="width=device-width, user-scalable=no">
+        <link rel="shortcut icon" href="https://www.babylonjs.com/img/favicon/favicon.ico">
+        <link rel="apple-touch-icon" sizes="57x57" href="https://www.babylonjs.com/img/favicon/apple-icon-57x57.png">
+        <link rel="apple-touch-icon" sizes="60x60" href="https://www.babylonjs.com/img/favicon/apple-icon-60x60.png">
+        <link rel="apple-touch-icon" sizes="72x72" href="https://www.babylonjs.com/img/favicon/apple-icon-72x72.png">
+        <link rel="apple-touch-icon" sizes="76x76" href="https://www.babylonjs.com/img/favicon/apple-icon-76x76.png">
+        <link rel="apple-touch-icon" sizes="114x114" href="https://www.babylonjs.com/img/favicon/apple-icon-114x114.png">
+        <link rel="apple-touch-icon" sizes="120x120" href="https://www.babylonjs.com/img/favicon/apple-icon-120x120.png">
+        <link rel="apple-touch-icon" sizes="144x144" href="https://www.babylonjs.com/img/favicon/apple-icon-144x144.png">
+        <link rel="apple-touch-icon" sizes="152x152" href="https://www.babylonjs.com/img/favicon/apple-icon-152x152.png">
+        <link rel="apple-touch-icon" sizes="180x180" href="https://www.babylonjs.com/img/favicon/apple-icon-180x180.png">
+        <link rel="icon" type="image/png" sizes="192x192" href="https://www.babylonjs.com/img/favicon/android-icon-192x192.png">
+        <link rel="icon" type="image/png" sizes="32x32" href="https://www.babylonjs.com/img/favicon/favicon-32x32.png">
+        <link rel="icon" type="image/png" sizes="96x96" href="https://www.babylonjs.com/img/favicon/favicon-96x96.png">
+        <link rel="icon" type="image/png" sizes="16x16" href="https://www.babylonjs.com/img/favicon/favicon-16x16.png">
+        <link rel="manifest" href="https://www.babylonjs.com/img/favicon/manifest.json">
+        <meta name="msapplication-TileColor" content="#ffffff">
+        <meta name="msapplication-TileImage" content="https://www.babylonjs.com/img/favicon/ms-icon-144x144.png">
+        <meta name="msapplication-config" content="https://www.babylonjs.com/img/favicon/browserconfig.xml">
+        <meta name="theme-color" content="#ffffff">
+
+        <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>
+
+        <!-- Babylon.js -->
+        <script src="https://preview.babylonjs.com/cannon.js"></script>
+        <script src="https://preview.babylonjs.com/Oimo.js"></script>
+        <script src="https://preview.babylonjs.com/babylon.max.js"></script>
+        <script src="https://preview.babylonjs.com/inspector/babylon.inspector.bundle.js"></script>
+
+        <script src="https://preview.babylonjs.com/materialsLibrary/babylon.fireMaterial.min.js"></script>
+        <script src="https://preview.babylonjs.com/materialsLibrary/babylon.waterMaterial.min.js"></script>
+        <script src="https://preview.babylonjs.com/materialsLibrary/babylon.lavaMaterial.min.js"></script>
+        <script src="https://preview.babylonjs.com/materialsLibrary/babylon.normalMaterial.min.js"></script>
+        <script src="https://preview.babylonjs.com/materialsLibrary/babylon.skyMaterial.min.js"></script>
+        <script src="https://preview.babylonjs.com/materialsLibrary/babylon.triPlanarMaterial.min.js"></script>
+        <script src="https://preview.babylonjs.com/materialsLibrary/babylon.terrainMaterial.min.js"></script>
+        <script src="https://preview.babylonjs.com/materialsLibrary/babylon.gradientMaterial.min.js"></script>
+        <script src="https://preview.babylonjs.com/materialsLibrary/babylon.furMaterial.min.js"></script>
+        <script src="https://preview.babylonjs.com/materialsLibrary/babylon.gridMaterial.min.js"></script>
+        <script src="https://preview.babylonjs.com/materialsLibrary/babylon.shadowOnlyMaterial.min.js"></script>
+        <script src="https://preview.babylonjs.com/materialsLibrary/babylon.customMaterial.min.js"></script>
+        <script src="https://preview.babylonjs.com/materialsLibrary/babylon.cellMaterial.min.js"></script>
+
+        <script src="https://preview.babylonjs.com/proceduralTexturesLibrary/babylon.brickProceduralTexture.min.js"></script>
+        <script src="https://preview.babylonjs.com/proceduralTexturesLibrary/babylon.cloudProceduralTexture.min.js"></script>
+        <script src="https://preview.babylonjs.com/proceduralTexturesLibrary/babylon.fireProceduralTexture.min.js"></script>
+        <script src="https://preview.babylonjs.com/proceduralTexturesLibrary/babylon.grassProceduralTexture.min.js"></script>
+        <script src="https://preview.babylonjs.com/proceduralTexturesLibrary/babylon.marbleProceduralTexture.min.js"></script>
+        <script src="https://preview.babylonjs.com/proceduralTexturesLibrary/babylon.roadProceduralTexture.min.js"></script>
+        <script src="https://preview.babylonjs.com/proceduralTexturesLibrary/babylon.starfieldProceduralTexture.min.js"></script>
+        <script src="https://preview.babylonjs.com/proceduralTexturesLibrary/babylon.woodProceduralTexture.min.js"></script>
+
+        <script src="https://preview.babylonjs.com/postProcessesLibrary/babylon.asciiArtPostProcess.min.js"></script>
+        <script src="https://preview.babylonjs.com/postProcessesLibrary/babylon.digitalRainPostProcess.min.js"></script>
+
+        <script src="https://preview.babylonjs.com/loaders/babylon.glTFFileLoader.js"></script>
+        <script src="https://preview.babylonjs.com/loaders/babylon.objFileLoader.js"></script>
+        <script src="https://preview.babylonjs.com/loaders/babylon.stlFileLoader.js"></script>
+
+        <script src="https://preview.babylonjs.com/gui/babylon.gui.js"></script>
+
+        <script src="https://preview.babylonjs.com/serializers/babylonjs.serializers.min.js"></script>
+
+        <script src="https://rawgit.com/BabylonJS/Extensions/master/ClonerSystem/src/babylonx.cloner.js"></script>
+        <script src="https://rawgit.com/BabylonJS/Extensions/master/CompoundShader/src/babylonx.CompoundShader.js"></script>
+        <link href="css/index.css" rel="stylesheet" />
+
+        <!-- Monaco -->
+        <script src="node_modules/monaco-editor/min/vs/loader.js"></script>
+
+    </head>
+
+    <body>
+        <div class="navbar navBar1600">
+            <div class="title">
+                Babylon.js Playground
+            </div>
+            <div class="version" id="mainTitle">
+                v3.0-alpha
+            </div>
+
+            <div class="category">
+                <div class="button run" id="runButton1600">Run
+                    <i class="fa fa-play" aria-hidden="true"></i>
+                </div>
             </div>
             </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 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>
-        </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 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>
-        </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 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>
                         </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 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="fa fa-square-o" 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="fa fa-square-o" aria-hidden="true"></i>
                         </div>
                         </div>
-                    </div>
-                    <div class="option" id="safemodeToggle1600">Safe mode
-                        <i class="fa fa-square-o" 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="fa fa-square-o" aria-hidden="true"></i>
                     </div>
                     </div>
                 </div>
                 </div>
-            </div>
 
 
-            <div class="button uncheck" id="debugButton1600">Inspector
-                <i class="fa fa-square-o" aria-hidden="true"></i>
+                <div class="button uncheck" id="debugButton1600">Inspector
+                    <i class="fa fa-square-o" aria-hidden="true"></i>
+                </div>
+                <div class="button" id="metadataButton1600">Metadata</div>
             </div>
             </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 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="button select">
-                <span class="examplesButton">Examples</span>
             </div>
             </div>
         </div>
         </div>
-    </div>
 
 
-    <div class="navbar navBar1475">
-        <div class="title">
-            Babylon.js Playground
-        </div>
-        <div class="version" id="mainTitle">
-            v3.0-alpha
-        </div>
+        <div class="navbar navBar1475">
+            <div class="title">
+                Babylon.js Playground
+            </div>
+            <div class="version" id="mainTitle">
+                v3.0-alpha
+            </div>
 
 
-        <div class="category">
-            <div class="button run" id="runButton1475">Run
-                <i class="fa fa-play" aria-hidden="true"></i>
+            <div class="category">
+                <div class="button run" id="runButton1475">Run
+                    <i class="fa fa-play" aria-hidden="true"></i>
+                </div>
             </div>
             </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 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>
-        </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 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>
-        </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 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>
                         </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 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>
-                    </div>
-                    <div class="option" id='safemodeToggle1475'>Safe mode
-                        <i class="fa fa-square-o" 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="fa fa-square-o" aria-hidden="true"></i>
-                    </div>
-                    <div class="option" id="debugButton1475">Inspector
-                        <i class="fa fa-square-o" aria-hidden="true"></i>
-                    </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 class="option" id='safemodeToggle1475'>Safe mode
+                            <i class="fa fa-square-o" 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="fa fa-square-o" aria-hidden="true"></i>
+                        </div>
+                        <div class="option" id="debugButton1475">Inspector
+                            <i class="fa fa-square-o" aria-hidden="true"></i>
+                        </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>
                 </div>
             </div>
             </div>
-        </div>
 
 
-        <div class="category right">
-            <div class="button select">
-                <span class="examplesButton">Examples</span>
+            <div class="category right">
+                <div class="button select">
+                    <span class="examplesButton">Examples</span>
+                </div>
             </div>
             </div>
         </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 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>
-        </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 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>
-        </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 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>
-        </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 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>
                         </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 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>
-                    </div>
-                    <div class="option" id="safemodeToggle1030">Safe mode
-                        <i class="fa fa-square-o" 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="fa fa-square-o" aria-hidden="true"></i>
-                    </div>
-                    <div class="option" id="debugButton1030">Inspector
-                        <i class="fa fa-square-o" aria-hidden="true"></i>
-                    </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 class="option" id="safemodeToggle1030">Safe mode
+                            <i class="fa fa-square-o" 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="fa fa-square-o" aria-hidden="true"></i>
+                        </div>
+                        <div class="option" id="debugButton1030">Inspector
+                            <i class="fa fa-square-o" aria-hidden="true"></i>
+                        </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>
                 </div>
             </div>
             </div>
-        </div>
 
 
-        <div class="category right">
-            <div class="button select">
-                <span class="examplesButton">Examples</span>
+            <div class="category right">
+                <div class="button select">
+                    <span class="examplesButton">Examples</span>
+                </div>
             </div>
             </div>
         </div>
         </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 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>
             </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 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>
-                    </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 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>
-                    </div>
-                    <div class="option" id="safemodeToggle750">Safe mode
-                        <i class="fa fa-square-o" 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="fa fa-square-o" aria-hidden="true"></i>
-                    </div>
-                    <div class="option" id="debugButton750">Inspector
-                        <i class="fa fa-square-o" aria-hidden="true"></i>
-                    </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 class="option" id="safemodeToggle750">Safe mode
+                            <i class="fa fa-square-o" 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="fa fa-square-o" aria-hidden="true"></i>
+                        </div>
+                        <div class="option" id="debugButton750">Inspector
+                            <i class="fa fa-square-o" aria-hidden="true"></i>
+                        </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>
                 </div>
             </div>
             </div>
-        </div>
 
 
-        <div class="category right">
-            <div class="button select">
-                <span class="examplesButton">Examples</span>
+            <div class="category right">
+                <div class="button select">
+                    <span class="examplesButton">Examples</span>
+                </div>
             </div>
             </div>
         </div>
         </div>
-    </div>
 
 
-    <div class="wrapper">
-        <div id="jsEditor"></div>
-        <div id="canvasZone">
-            <canvas touch-action="none" id="renderCanvas"></canvas>
+        <div class="wrapper">
+            <div id="jsEditor"></div>
+            <div id="canvasZone">
+                <canvas touch-action="none" id="renderCanvas"></canvas>
+            </div>
         </div>
         </div>
-    </div>
-    <div id="exampleList">
-        <div id="exampleBanner">
-            <h1>Examples</h1>
+        <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>
-        <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 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>
         </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 id="saveFormButtonOk" class="button">OK</div>
+                    <div id="saveFormButtonCancel" class="button">Cancel</div>
+                </div>
             </div>
             </div>
         </div>
         </div>
-    </div>
 
 
-    <script src="https://code.jquery.com/jquery.js"></script>
+        <script src="https://code.jquery.com/jquery.js"></script>
 
 
-    <script src="js/actions.js"></script>
-    <script src="js/pbt.js"></script>
-    <script src="js/index.js"></script>
+        <script src="js/actions.js"></script>
+        <script src="js/pbt.js"></script>
+        <script src="js/index.js"></script>
 
 
-    <!-- Global site tag (gtag.js) - Google Analytics -->
-    <script async src="https://www.googletagmanager.com/gtag/js?id=UA-41767310-2"></script>
-    <script>
-    window.dataLayer = window.dataLayer || [];
-    function gtag(){dataLayer.push(arguments);}
-    gtag('js', new Date());
+        <!-- Global site tag (gtag.js) - Google Analytics -->
+        <script async src="https://www.googletagmanager.com/gtag/js?id=UA-41767310-2"></script>
+        <script>
+            window.dataLayer = window.dataLayer || [];
+            function gtag() { dataLayer.push(arguments); }
+            gtag('js', new Date());
 
 
-    gtag('config', 'UA-41767310-2');
-    </script>    
-</body>
+            gtag('config', 'UA-41767310-2');
+        </script>
+    </body>
 
 
 </html>
 </html>

+ 5 - 1
Playground/index-local.html

@@ -18,7 +18,7 @@
         <script src="../dist/preview%20release/Oimo.js"></script>
         <script src="../dist/preview%20release/Oimo.js"></script>
         <script src="../dist/preview%20release/earcut.min.js"></script>
         <script src="../dist/preview%20release/earcut.min.js"></script>
         <!-- Monaco -->
         <!-- Monaco -->
-        <script src="node_modules/monaco-editor/min/vs/loader.js"></script>
+
         <!-- Babylon.js -->
         <!-- Babylon.js -->
         <script src="../tools/DevLoader/BabylonLoader.js"></script>
         <script src="../tools/DevLoader/BabylonLoader.js"></script>
 
 
@@ -454,6 +454,10 @@
                         wasmBinaryUrl: "../dist/preview%20release/draco_decoder_gltf.wasm",
                         wasmBinaryUrl: "../dist/preview%20release/draco_decoder_gltf.wasm",
                         fallbackUrl: "../dist/preview%20release/draco_decoder_gltf.js"
                         fallbackUrl: "../dist/preview%20release/draco_decoder_gltf.js"
                     };
                     };
+                    var script = document.createElement('script');
+                    script.type = 'text/javascript';
+                    script.src = "node_modules/monaco-editor/min/vs/loader.js";
+                    document.head.appendChild(script);
                 });
                 });
         </script>
         </script>
     </body>
     </body>

+ 11 - 10
Playground/index.html

@@ -37,8 +37,6 @@
         <script src="https://preview.babylonjs.com/cannon.js"></script>
         <script src="https://preview.babylonjs.com/cannon.js"></script>
         <script src="https://preview.babylonjs.com/Oimo.js"></script>
         <script src="https://preview.babylonjs.com/Oimo.js"></script>
         <script src="https://preview.babylonjs.com/earcut.min.js"></script>
         <script src="https://preview.babylonjs.com/earcut.min.js"></script>
-        <!-- Monaco -->
-        <script src="node_modules/monaco-editor/min/vs/loader.js"></script>
         <!-- Babylon.js -->
         <!-- Babylon.js -->
         <script src="https://preview.babylonjs.com/babylon.js"></script>
         <script src="https://preview.babylonjs.com/babylon.js"></script>
         <script src="https://preview.babylonjs.com/inspector/babylon.inspector.bundle.js"></script>
         <script src="https://preview.babylonjs.com/inspector/babylon.inspector.bundle.js"></script>
@@ -48,13 +46,16 @@
         <script src="https://preview.babylonjs.com/loaders/babylonjs.loaders.js"></script>
         <script src="https://preview.babylonjs.com/loaders/babylonjs.loaders.js"></script>
         <script src="https://preview.babylonjs.com/serializers/babylonjs.serializers.min.js"></script>
         <script src="https://preview.babylonjs.com/serializers/babylonjs.serializers.min.js"></script>
         <script src="https://preview.babylonjs.com/gui/babylon.gui.min.js"></script>
         <script src="https://preview.babylonjs.com/gui/babylon.gui.min.js"></script>
+        <!-- Monaco -->
+        <script src="node_modules/monaco-editor/min/vs/loader.js"></script>
+
 
 
         <!-- Extensions -->
         <!-- Extensions -->
         <script src="https://rawgit.com/BabylonJS/Extensions/master/ClonerSystem/src/babylonx.cloner.js" async></script>
         <script src="https://rawgit.com/BabylonJS/Extensions/master/ClonerSystem/src/babylonx.cloner.js" async></script>
         <script src="https://rawgit.com/BabylonJS/Extensions/master/CompoundShader/src/babylonx.CompoundShader.js" async></script>
         <script src="https://rawgit.com/BabylonJS/Extensions/master/CompoundShader/src/babylonx.CompoundShader.js" async></script>
         <script src="https://www.babylontoolkit.com/playground/scripts/babylon.navmesh.js"></script>
         <script src="https://www.babylontoolkit.com/playground/scripts/babylon.navmesh.js"></script>
         <script src="https://www.babylontoolkit.com/playground/scripts/babylon.manager.js"></script>
         <script src="https://www.babylontoolkit.com/playground/scripts/babylon.manager.js"></script>
-                               
+
         <link href="css/index.css" rel="stylesheet" />
         <link href="css/index.css" rel="stylesheet" />
     </head>
     </head>
 
 
@@ -408,7 +409,7 @@
                 <canvas touch-action="none" id="renderCanvas"></canvas>
                 <canvas touch-action="none" id="renderCanvas"></canvas>
             </div>
             </div>
         </div>
         </div>
-        <div id="exampleList">
+        <div id="exampleList" class = "javascript">
             <div id="exampleBanner">
             <div id="exampleBanner">
                 <h1>Examples</h1>
                 <h1>Examples</h1>
             </div>
             </div>
@@ -479,16 +480,16 @@
         <script src="js/actions.js"></script>
         <script src="js/actions.js"></script>
         <script src="js/pbt.js"></script>
         <script src="js/pbt.js"></script>
         <script src="js/index.js"></script>
         <script src="js/index.js"></script>
-        
+
         <!-- Global site tag (gtag.js) - Google Analytics -->
         <!-- Global site tag (gtag.js) - Google Analytics -->
         <script async src="https://www.googletagmanager.com/gtag/js?id=UA-41767310-2"></script>
         <script async src="https://www.googletagmanager.com/gtag/js?id=UA-41767310-2"></script>
         <script>
         <script>
-        window.dataLayer = window.dataLayer || [];
-        function gtag(){dataLayer.push(arguments);}
-        gtag('js', new Date());
+            window.dataLayer = window.dataLayer || [];
+            function gtag() { dataLayer.push(arguments); }
+            gtag('js', new Date());
 
 
-        gtag('config', 'UA-41767310-2');
-        </script>        
+            gtag('config', 'UA-41767310-2');
+        </script>
     </body>
     </body>
 
 
 </html>
 </html>

+ 11 - 3
Playground/js/index.js

@@ -241,9 +241,17 @@ function showError(errorMessage, errorEvent) {
         };
         };
 
 
         var loadScriptsList = function () {
         var loadScriptsList = function () {
-            var xhr = new XMLHttpRequest();
 
 
-            xhr.open('GET', 'https://raw.githubusercontent.com/BabylonJS/Documentation/master/examples/list.json', true);
+            var exampleList = document.getElementById("exampleList");
+           
+            var xhr = new XMLHttpRequest();
+            //Open Typescript or Javascript examples
+            if(exampleList.className != 'typescript') {
+                xhr.open('GET', 'https://raw.githubusercontent.com/BabylonJS/Documentation/master/examples/list.json', true);
+            }
+            else {
+                xhr.open('GET', 'https://raw.githubusercontent.com/BabylonJS/Documentation/master/examples/list_ts.json', true);
+            }
 
 
             xhr.onreadystatechange = function () {
             xhr.onreadystatechange = function () {
                 if (xhr.readyState === 4) {
                 if (xhr.readyState === 4) {
@@ -257,7 +265,7 @@ function showError(errorMessage, errorEvent) {
                         }
                         }
                         scripts.sort(sortScriptsList);
                         scripts.sort(sortScriptsList);
 
 
-                        var exampleList = document.getElementById("exampleList");
+                                                
 
 
                         if (exampleList) {
                         if (exampleList) {
                             for (var i = 0; i < scripts.length; i++) {
                             for (var i = 0; i < scripts.length; i++) {

+ 24 - 0
Playground/ts.html

@@ -56,6 +56,7 @@
         <script src="https://www.babylontoolkit.com/playground/scripts/babylon.manager.js"></script>
         <script src="https://www.babylontoolkit.com/playground/scripts/babylon.manager.js"></script>
                                
                                
         <link href="css/index.css" rel="stylesheet" />
         <link href="css/index.css" rel="stylesheet" />
+        <link href="css/color_ts.css" rel="stylesheet" />
     </head>
     </head>
 
 
     <body>
     <body>
@@ -144,6 +145,9 @@
                         <div class="option" onclick="setVersion('stable');">Stable</div>
                         <div class="option" onclick="setVersion('stable');">Stable</div>
                     </div>
                     </div>
                 </div>
                 </div>
+                <div class="button select">
+                    <span class="examplesButton">Examples</span>
+                </div>
             </div>
             </div>
         </div>
         </div>
 
 
@@ -228,6 +232,12 @@
                     </div>
                     </div>
                 </div>
                 </div>
             </div>
             </div>
+
+            <div class="category right">
+                <div class="button select">
+                    <span class="examplesButton">Examples</span>
+                </div>
+            </div>
         </div>
         </div>
 
 
         <div class="navbar navBar1030">
         <div class="navbar navBar1030">
@@ -305,6 +315,12 @@
                     </div>
                     </div>
                 </div>
                 </div>
             </div>
             </div>
+
+            <div class="category right">
+                <div class="button select">
+                    <span class="examplesButton">Examples</span>
+                </div>
+            </div>
         </div>
         </div>
 
 
         <div class="navbar navBar750">
         <div class="navbar navBar750">
@@ -387,6 +403,14 @@
                 <canvas touch-action="none" id="renderCanvas"></canvas>
                 <canvas touch-action="none" id="renderCanvas"></canvas>
             </div>
             </div>
         </div>
         </div>
+        <div id="exampleList" class = "typescript">
+            <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>
 
 

+ 31 - 24
Tools/DevLoader/BabylonLoader.js

@@ -141,36 +141,44 @@ var BABYLONDEVTOOLS;
         }
         }
 
 
         Loader.prototype.loadLibrary = function (library, module) {
         Loader.prototype.loadLibrary = function (library, module) {
+            if (library.preventLoadLibrary) {
+                return;
+            }
+
             if (!useDist) {
             if (!useDist) {
-                var i = 0;
-                for (; i < library.files.length; i++) {
-                    var file = library.files[i];
-                    if (file.indexOf('lib.d.ts') > 0) {
-                        continue;
-                    }
+                if (library.useOutputForDebugging) {
+                    this.loadScript(babylonJSPath + '/.temp' + module.build.distOutputDirectory + library.output);
+                } else {
+                    var i = 0;
+                    for (; i < library.files.length; i++) {
+                        var file = library.files[i];
+                        if (file.indexOf('lib.d.ts') > 0) {
+                            continue;
+                        }
 
 
-                    file = file.replace('.ts', '.js');
-                    file = file.replace('../', '');
-                    file = babylonJSPath + '/' + file;
-                    this.loadScript(file);
-                }
+                        file = file.replace('.ts', '.js');
+                        file = file.replace('../', '');
+                        file = babylonJSPath + '/' + file;
+                        this.loadScript(file);
+                    }
 
 
-                if (library.shaderFiles && library.shaderFiles.length > 0) {
-                    var shaderFile = library.shaderFiles[0];
-                    var endDirectoryIndex = shaderFile.lastIndexOf('/');
-                    shaderFile = shaderFile.substring(0, endDirectoryIndex + 1);
-                    shaderFile += library.output.replace('.js', '.js.fx');
-                    this.loadScript(shaderFile);
-                    if (library.shadersIncludeFiles) {
-                        var includeShaderFile = shaderFile.replace('.js.fx', '.js.include.fx');
-                        this.loadScript(includeShaderFile);
+                    if (library.shaderFiles && library.shaderFiles.length > 0) {
+                        var shaderFile = library.shaderFiles[0];
+                        var endDirectoryIndex = shaderFile.lastIndexOf('/');
+                        shaderFile = shaderFile.substring(0, endDirectoryIndex + 1);
+                        shaderFile += library.output.replace('.js', '.js.fx');
+                        this.loadScript(shaderFile);
+                        if (library.shadersIncludeFiles) {
+                            var includeShaderFile = shaderFile.replace('.js.fx', '.js.include.fx');
+                            this.loadScript(includeShaderFile);
+                        }
                     }
                     }
                 }
                 }
             }
             }
             else if (min) {
             else if (min) {
                 if (library.webpack) {
                 if (library.webpack) {
                     if (module.build.distOutputDirectory)
                     if (module.build.distOutputDirectory)
-                        this.loadScript(babylonJSPath + '/dist/preview release' + module.build.distOutputDirectory + library.output.replace('.js', '.bundle.js'));
+                        this.loadScript(babylonJSPath + '/dist/preview release' + module.build.distOutputDirectory + library.output);
                 }
                 }
                 else {
                 else {
                     this.loadScript(babylonJSPath + '/dist/preview release' + module.build.distOutputDirectory + library.output.replace('.js', '.min.js'));
                     this.loadScript(babylonJSPath + '/dist/preview release' + module.build.distOutputDirectory + library.output.replace('.js', '.min.js'));
@@ -181,6 +189,7 @@ var BABYLONDEVTOOLS;
                     this.loadScript(babylonJSPath + '/dist/preview release' + module.build.distOutputDirectory + library.output);
                     this.loadScript(babylonJSPath + '/dist/preview release' + module.build.distOutputDirectory + library.output);
             }
             }
 
 
+            // Currently not being used
             if (!min && library.sassFiles && library.sassFiles.length > 0) {
             if (!min && library.sassFiles && library.sassFiles.length > 0) {
                 var cssFile = library.output.replace('.js', '.css');
                 var cssFile = library.output.replace('.js', '.css');
                 cssFile = babylonJSPath + '/dist/preview release' + module.build.distOutputDirectory + cssFile;
                 cssFile = babylonJSPath + '/dist/preview release' + module.build.distOutputDirectory + cssFile;
@@ -242,10 +251,8 @@ var BABYLONDEVTOOLS;
 
 
             // Modules
             // Modules
             if (loadModules) {
             if (loadModules) {
+
                 for (var i = 0; i < settings.modules.length; i++) {
                 for (var i = 0; i < settings.modules.length; i++) {
-                    if (settings.modules[i] === "viewer") {
-                        continue;
-                    }
                     this.loadModule(settings[settings.modules[i]]);
                     this.loadModule(settings[settings.modules[i]]);
                 }
                 }
             }
             }

+ 93 - 151
Tools/Gulp/config.json

@@ -8,6 +8,7 @@
         "declarationModuleFilename": "babylon.module.d.ts",
         "declarationModuleFilename": "babylon.module.d.ts",
         "outputDirectory": "../../dist/preview release",
         "outputDirectory": "../../dist/preview release",
         "playgroundDirectory": "../../Playground/",
         "playgroundDirectory": "../../Playground/",
+        "tempDirectory": "../../.temp/",
         "intellisenseFile": "babylon.d.txt",
         "intellisenseFile": "babylon.d.txt",
         "intellisenseSources": [
         "intellisenseSources": [
             "../../dist/preview release/babylon.d.ts",
             "../../dist/preview release/babylon.d.ts",
@@ -136,7 +137,7 @@
             "picking",
             "picking",
             "backgroundMaterial",
             "backgroundMaterial",
             "videoDome"
             "videoDome"
-        ]      
+        ]
     },
     },
     "workloads": {
     "workloads": {
         "core": {
         "core": {
@@ -227,7 +228,7 @@
                 "fresnelFunction",
                 "fresnelFunction",
                 "reflectionFunction",
                 "reflectionFunction",
                 "imageProcessingDeclaration",
                 "imageProcessingDeclaration",
-                "imageProcessingFunctions",                
+                "imageProcessingFunctions",
                 "bumpFragmentFunctions",
                 "bumpFragmentFunctions",
                 "clipPlaneFragmentDeclaration",
                 "clipPlaneFragmentDeclaration",
                 "fogFragmentDeclaration",
                 "fogFragmentDeclaration",
@@ -246,7 +247,7 @@
                 "core",
                 "core",
                 "debug"
                 "debug"
             ]
             ]
-        },          
+        },
         "occlusionQuery": {
         "occlusionQuery": {
             "files": [
             "files": [
                 "../../src/Engine/Extensions/babylon.engine.occlusionQuery.js"
                 "../../src/Engine/Extensions/babylon.engine.occlusionQuery.js"
@@ -255,7 +256,7 @@
                 "core",
                 "core",
                 "debug"
                 "debug"
             ]
             ]
-        },          
+        },
         "behaviors": {
         "behaviors": {
             "files": [
             "files": [
                 "../../src/Behaviors/babylon.behavior.js"
                 "../../src/Behaviors/babylon.behavior.js"
@@ -263,7 +264,7 @@
             "dependUpon": [
             "dependUpon": [
                 "core"
                 "core"
             ]
             ]
-        },   
+        },
         "imageProcessing": {
         "imageProcessing": {
             "files": [
             "files": [
                 "../../src/Materials/babylon.imageProcessingConfiguration.js",
                 "../../src/Materials/babylon.imageProcessingConfiguration.js",
@@ -273,8 +274,8 @@
             "dependUpon": [
             "dependUpon": [
                 "core"
                 "core"
             ]
             ]
-        },  
-        "noise" : {
+        },
+        "noise": {
             "files": [
             "files": [
                 "../../src/Materials/Textures/Procedurals/babylon.noiseProceduralTexture.js"
                 "../../src/Materials/Textures/Procedurals/babylon.noiseProceduralTexture.js"
             ],
             ],
@@ -285,7 +286,7 @@
             "shaders": [
             "shaders": [
                 "noise.fragment"
                 "noise.fragment"
             ]
             ]
-        },      
+        },
         "particles": {
         "particles": {
             "files": [
             "files": [
                 "../../src/Particles/babylon.particle.js",
                 "../../src/Particles/babylon.particle.js",
@@ -1083,7 +1084,7 @@
             ]
             ]
         },
         },
         "textureFormats": {
         "textureFormats": {
-            "files": [ ],
+            "files": [],
             "dependUpon": [
             "dependUpon": [
                 "dds",
                 "dds",
                 "tga",
                 "tga",
@@ -1208,7 +1209,7 @@
             "shaders": [
             "shaders": [
                 "anaglyph.fragment"
                 "anaglyph.fragment"
             ]
             ]
-        },       
+        },
         "stereoscopic": {
         "stereoscopic": {
             "files": [
             "files": [
                 "../../src/PostProcess/babylon.stereoscopicInterlacePostProcess.js",
                 "../../src/PostProcess/babylon.stereoscopicInterlacePostProcess.js",
@@ -1226,7 +1227,7 @@
             "shaders": [
             "shaders": [
                 "stereoscopicInterlace.fragment"
                 "stereoscopicInterlace.fragment"
             ]
             ]
-        },           
+        },
         "vr": {
         "vr": {
             "files": [
             "files": [
                 "../../src/PostProcess/babylon.vrDistortionCorrectionPostProcess.js",
                 "../../src/PostProcess/babylon.vrDistortionCorrectionPostProcess.js",
@@ -1409,8 +1410,8 @@
         "proceduralTexturesLibrary",
         "proceduralTexturesLibrary",
         "loaders",
         "loaders",
         "serializers",
         "serializers",
-        "inspector",
         "gui",
         "gui",
+        "inspector",
         "viewer",
         "viewer",
         "viewer-assets"
         "viewer-assets"
     ],
     ],
@@ -1844,146 +1845,72 @@
     "gui": {
     "gui": {
         "libraries": [
         "libraries": [
             {
             {
-                "files": [
-                    "../../gui/src/2D/style.ts",
-                    "../../gui/src/2D/valueAndUnit.ts",
-                    "../../gui/src/2D/advancedDynamicTexture.ts",
-                    "../../gui/src/2D/measure.ts",
-                    "../../gui/src/2D/math2D.ts",
-                    "../../gui/src/2D/multiLinePoint.ts",
-                    "../../gui/src/2D/controls/control.ts",
-                    "../../gui/src/2D/controls/container.ts",
-                    "../../gui/src/2D/controls/stackPanel.ts",
-                    "../../gui/src/2D/controls/rectangle.ts",
-                    "../../gui/src/2D/controls/ellipse.ts",
-                    "../../gui/src/2D/controls/line.ts",
-                    "../../gui/src/2D/controls/slider.ts",
-                    "../../gui/src/2D/controls/checkbox.ts",
-                    "../../gui/src/2D/controls/radioButton.ts",
-                    "../../gui/src/2D/controls/textBlock.ts",
-                    "../../gui/src/2D/controls/image.ts",
-                    "../../gui/src/2D/controls/button.ts",
-                    "../../gui/src/2D/controls/colorpicker.ts",
-                    "../../gui/src/2D/controls/inputText.ts",
-                    "../../gui/src/2D/controls/inputPassword.ts",
-                    "../../gui/src/2D/controls/virtualKeyboard.ts",
-                    "../../gui/src/2D/controls/multiLine.ts",
-                    "../../gui/src/2D/controls/grid.ts",                    
-                    "../../gui/src/3D/gui3DManager.ts",
-                    "../../gui/src/3D/materials/fluentMaterial.ts",
-                    "../../gui/src/3D/vector3WithInfo.ts",
-                    "../../gui/src/3D/controls/control3D.ts",
-                    "../../gui/src/3D/controls/container3D.ts",
-                    "../../gui/src/3D/controls/abstractButton3D.ts",
-                    "../../gui/src/3D/controls/button3D.ts",
-                    "../../gui/src/3D/controls/meshButton3D.ts",
-                    "../../gui/src/3D/controls/holographicButton.ts",
-                    "../../gui/src/3D/controls/stackPanel3D.ts",
-                    "../../gui/src/3D/controls/volumeBasedPanel.ts",
-                    "../../gui/src/3D/controls/spherePanel.ts",
-                    "../../gui/src/3D/controls/planePanel.ts",
-                    "../../gui/src/3D/controls/scatterPanel.ts",
-                    "../../gui/src/3D/controls/cylinderPanel.ts"
-                ],
-                "shaderFiles": [
-                    "../../gui/src/3D/materials/shaders/fluent.vertex.fx",
-                    "../../gui/src/3D/materials/shaders/fluent.fragment.fx"
-                ],
-                "output": "babylon.gui.js",
-                "buildAsModule": true,
-                "moduleName": "babylonjs-gui",
-                "moduleDeclaration": {
-                    "name": "GUI",
-                    "module": "babylonjs-gui"
-                }
+                "files": [],
+                "noBundleInName": true,
+                "output": "babylon.gui.min.js",
+                "webpack": "../../gui/webpack.config.js",
+                "bundle": "true",
+                "babylonIncluded": false,
+                "useOutputForDebugging": true
             }
             }
         ],
         ],
         "build": {
         "build": {
-            "srcOutputDirectory": "../../gui/",
-            "distOutputDirectory": "/gui/"
+            "srcOutputDirectory": "../../gui/src/",
+            "distOutputDirectory": "/gui/",
+            "dtsBundle": {
+                "name": "babylonjs-gui",
+                "main": "../../dist/preview release/gui/build/index.d.ts",
+                "out": "../babylon.gui.module.d.ts",
+                "baseDir": "../../dist/preview release/gui/build/",
+                "headerText": "BabylonJS GUI"
+            },
+            "processDeclaration": {
+                "filename": "babylon.gui.module.d.ts",
+                "packageName": "babylonjs-gui",
+                "moduleName": "BABYLON.GUI",
+                "importsToRemove": [],
+                "classMap": {
+                    "babylonjs": "BABYLON",
+                    "babylonjs-loaders": "BABYLON",
+                    "babylonjs-serializers": "BABYLON"
+                }
+            }
         }
         }
     },
     },
     "inspector": {
     "inspector": {
         "libraries": [
         "libraries": [
             {
             {
-                "files": [
-                    "../../inspector/src/Inspector.ts",
-                    "../../inspector/src/properties.ts",
-                    "../../inspector/src/properties_gui.ts",
-                    "../../inspector/src/gui/BasicElement.ts",
-                    "../../inspector/src/adapters/Adapter.ts",
-                    "../../inspector/src/adapters/CameraAdapter.ts",
-                    "../../inspector/src/adapters/PhysicsImpostorAdapter.ts",
-                    "../../inspector/src/adapters/GUIAdapter.ts",
-                    "../../inspector/src/adapters/SoundAdapter.ts",
-                    "../../inspector/src/adapters/TextureAdapter.ts",
-                    "../../inspector/src/adapters/LightAdapter.ts",
-                    "../../inspector/src/adapters/MaterialAdapter.ts",
-                    "../../inspector/src/adapters/MeshAdapter.ts",
-                    "../../inspector/src/adapters/PhysicsImpostorAdapter.ts",
-                    "../../inspector/src/details/DetailPanel.ts",
-                    "../../inspector/src/details/Property.ts",
-                    "../../inspector/src/details/PropertyLine.ts",
-                    "../../inspector/src/gui/ColorElement.ts",
-                    "../../inspector/src/gui/ColorPickerElement.ts",
-                    "../../inspector/src/gui/CubeTextureElement.ts",
-                    "../../inspector/src/gui/HDRCubeTextureElement.ts",
-                    "../../inspector/src/gui/SearchBar.ts",
-                    "../../inspector/src/gui/TextureElement.ts",
-                    "../../inspector/src/gui/Tooltip.ts",
-                    "../../inspector/src/helpers/Helpers.ts",
-                    "../../inspector/src/scheduler/Scheduler.ts",
-                    "../../inspector/src/tabs/Tab.ts",
-                    "../../inspector/src/tabs/PropertyTab.ts",
-                    "../../inspector/src/tabs/CameraTab.ts",
-                    "../../inspector/src/tabs/GUITab.ts",
-                    "../../inspector/src/tabs/PhysicsTab.ts",
-                    "../../inspector/src/tabs/SoundTab.ts",
-                    "../../inspector/src/tabs/TextureTab.ts",
-                    "../../inspector/src/tabs/LightTab.ts",
-                    "../../inspector/src/tabs/MaterialTab.ts",
-                    "../../inspector/src/tabs/MeshTab.ts",
-                    "../../inspector/src/tabs/SceneTab.ts",
-                    "../../inspector/src/tabs/ConsoleTab.ts",
-                    "../../inspector/src/tabs/StatsTab.ts",
-                    "../../inspector/src/tabs/GLTFTab.ts",
-                    "../../inspector/src/tabs/ToolsTab.ts",
-                    "../../inspector/src/tabs/TabBar.ts",
-                    "../../inspector/src/tools/AbstractTool.ts",
-                    "../../inspector/src/tools/PauseScheduleTool.ts",
-                    "../../inspector/src/tools/PickTool.ts",
-                    "../../inspector/src/tools/PopupTool.ts",
-                    "../../inspector/src/tools/RefreshTool.ts",
-                    "../../inspector/src/tools/LabelTool.ts",
-                    "../../inspector/src/tools/Toolbar.ts",
-                    "../../inspector/src/tools/DisposeTool.ts",
-                    "../../inspector/src/tools/FullscreenTool.ts",
-                    "../../inspector/src/tree/TreeItem.ts",
-                    "../../inspector/src/treetools/AbstractTreeTool.ts",
-                    "../../inspector/src/treetools/BoundingBox.ts",
-                    "../../inspector/src/treetools/CameraPOV.ts",
-                    "../../inspector/src/treetools/SoundInteractions.ts",
-                    "../../inspector/src/treetools/Checkbox.ts",
-                    "../../inspector/src/treetools/DebugArea.ts",
-                    "../../inspector/src/treetools/Info.ts",
-                    "../../inspector/src/lib.d.ts"
-                ],
-                "sassFiles": [
-                    "../../inspector/sass/**/*.scss"
-                ],
-                "output": "babylon.inspector.js",
+                "files": [],
+                "sassFiles": [],
+                "output": "babylon.inspector.bundle.js",
                 "webpack": "../../inspector/webpack.config.js",
                 "webpack": "../../inspector/webpack.config.js",
                 "bundle": "true",
                 "bundle": "true",
-                "moduleDeclaration": {
-                    "name": "INSPECTOR",
-                    "module": "babylonjs-inspector"
-                },
-                "extendsRoot": true
+                "extendsRoot": true,
+                "useOutputForDebugging": true
             }
             }
         ],
         ],
         "build": {
         "build": {
-            "srcOutputDirectory": "../../inspector/",
-            "distOutputDirectory": "/inspector/"
+            "srcOutputDirectory": "../../inspector/src/",
+            "distOutputDirectory": "/inspector/",
+            "dtsBundle": {
+                "name": "babylonjs-inspector",
+                "main": "../../dist/preview release/inspector/build/index.d.ts",
+                "out": "../babylon.inspector.module.d.ts",
+                "baseDir": "../../dist/preview release/inspector/build/",
+                "headerText": "BabylonJS Inspector"
+            },
+            "processDeclaration": {
+                "filename": "babylon.inspector.module.d.ts",
+                "packageName": "babylonjs-inspector",
+                "moduleName": "INSPECTOR",
+                "importsToRemove": [],
+                "classMap": {
+                    "babylonjs": "BABYLON",
+                    "babylonjs-loaders": "BABYLON",
+                    "babylonjs-serializers": "BABYLON",
+                    "babylonjs-gui": "BABYLON.GUI"
+                }
+            }
         }
         }
     },
     },
     "viewer": {
     "viewer": {
@@ -1998,18 +1925,32 @@
                     "name": "BabylonViewer",
                     "name": "BabylonViewer",
                     "module": "babylonjs-viewer"
                     "module": "babylonjs-viewer"
                 },
                 },
-                "babylonIncluded": true
+                "babylonIncluded": true,
+                "noWatch": true,
+                "preventLoadLibrary": true
             }
             }
         ],
         ],
         "build": {
         "build": {
             "srcOutputDirectory": "../../Viewer/",
             "srcOutputDirectory": "../../Viewer/",
+            "distOutputDirectory": "/viewer/",
             "dtsBundle": {
             "dtsBundle": {
                 "name": "babylonjs-viewer",
                 "name": "babylonjs-viewer",
-                "main": "../../Viewer/dist/build/src/index.d.ts",
-                "out": "../../../../dist/preview release/viewer/babylon.viewer.module.d.ts",
-                "legacyDeclaration": true,
+                "main": "../../dist/preview release/viewer/build/src/index.d.ts",
+                "out": "../../babylon.viewer.module.d.ts",
                 "prependText": "/// <reference path=\"./babylon.d.ts\"/>\n/// <reference path=\"./babylon.glTF2Interface.d.ts\"/>\n/// <reference path=\"./babylonjs.loaders.d.ts\"/>\ndeclare module \"babylonjs-loaders\"{ export=BABYLON;}\n"
                 "prependText": "/// <reference path=\"./babylon.d.ts\"/>\n/// <reference path=\"./babylon.glTF2Interface.d.ts\"/>\n/// <reference path=\"./babylonjs.loaders.d.ts\"/>\ndeclare module \"babylonjs-loaders\"{ export=BABYLON;}\n"
             },
             },
+            "processDeclaration": {
+                "packageName": "babylonjs-viewer",
+                "moduleName": "BabylonViewer",
+                "importsToRemove": [
+                    "pep",
+                    "babylonjs-loaders"
+                ],
+                "classMap": {
+                    "babylonjs": "BABYLON",
+                    "babylonjs-loaders": "BABYLON"
+                }
+            },
             "outputs": [
             "outputs": [
                 {
                 {
                     "destination": [
                     "destination": [
@@ -2026,8 +1967,7 @@
                                 "glTF2Interface/babylon.glTF2Interface.d.ts"
                                 "glTF2Interface/babylon.glTF2Interface.d.ts"
                             ]
                             ]
                         }
                         }
-                    ],
-                    "minified": true
+                    ]
                 },
                 },
                 {
                 {
                     "destination": [
                     "destination": [
@@ -2056,23 +1996,25 @@
                     "name": "BabylonViewerAssets",
                     "name": "BabylonViewerAssets",
                     "module": "babylonjs-viewer-assets"
                     "module": "babylonjs-viewer-assets"
                 },
                 },
-                "babylonIncluded": true
+                "babylonIncluded": true,
+                "noWatch": true,
+                "preventLoadLibrary": true
             }
             }
         ],
         ],
         "build": {
         "build": {
             "srcOutputDirectory": "../../Viewer/",
             "srcOutputDirectory": "../../Viewer/",
+            "distOutputDirectory": "/viewer/",
             "dtsBundle": {
             "dtsBundle": {
                 "name": "babylonjs-viewer-assets",
                 "name": "babylonjs-viewer-assets",
-                "baseDir": "../../Viewer/dist/build/src/assets/",
-                "main": "../../Viewer/dist/build/src/assets/index.d.ts",
-                "out": "../../../build/assets/babylon.viewer.assets.module.d.ts"
+                "main": "../../dist/preview release/viewer/build/src/assets/index.d.ts",
+                "out": "../../../../../../Viewer/build/assets/babylon.viewer.assets.module.d.ts"
             },
             },
             "outputs": [
             "outputs": [
                 {
                 {
                     "destination": [
                     "destination": [
                         {
                         {
                             "filename": "babylon.viewer.assets.js",
                             "filename": "babylon.viewer.assets.js",
-                            "outputDirectory": "/../../Viewer/dist/build/assets/"
+                            "outputDirectory": "/../../Viewer/build/assets/"
                         }
                         }
                     ],
                     ],
                     "minified": true
                     "minified": true
@@ -2080,4 +2022,4 @@
             ]
             ]
         }
         }
     }
     }
-}
+}

+ 94 - 33
Tools/Gulp/gulpfile.js

@@ -16,7 +16,6 @@ var merge2 = require("merge2");
 var concat = require("gulp-concat");
 var concat = require("gulp-concat");
 var rename = require("gulp-rename");
 var rename = require("gulp-rename");
 var cleants = require("gulp-clean-ts-extends");
 var cleants = require("gulp-clean-ts-extends");
-var changedInPlace = require("gulp-changed-in-place");
 var runSequence = require("run-sequence");
 var runSequence = require("run-sequence");
 var replace = require("gulp-replace");
 var replace = require("gulp-replace");
 var uncommentShader = require("./gulp-removeShaderComments");
 var uncommentShader = require("./gulp-removeShaderComments");
@@ -25,17 +24,17 @@ var optimisejs = require("gulp-optimize-js");
 var webserver = require("gulp-webserver");
 var webserver = require("gulp-webserver");
 var path = require("path");
 var path = require("path");
 var sass = require("gulp-sass");
 var sass = require("gulp-sass");
-var webpack = require("webpack-stream");
+const webpack = require('webpack');
+var webpackStream = require("webpack-stream");
 var typedoc = require("gulp-typedoc");
 var typedoc = require("gulp-typedoc");
 var validateTypedoc = require("./gulp-validateTypedoc");
 var validateTypedoc = require("./gulp-validateTypedoc");
-var request = require('request');
 var fs = require("fs");
 var fs = require("fs");
 var dtsBundle = require('dts-bundle');
 var dtsBundle = require('dts-bundle');
 const through = require('through2');
 const through = require('through2');
 var karmaServer = require('karma').Server;
 var karmaServer = require('karma').Server;
 
 
 //viewer declaration
 //viewer declaration
-var processViewerDeclaration = require('./processViewerDeclaration');
+var processDeclaration = require('./processViewerDeclaration');
 
 
 var config = require("./config.json");
 var config = require("./config.json");
 
 
@@ -448,7 +447,7 @@ var buildExternalLibrary = function (library, settings, watch) {
 
 
         if (library.webpack) {
         if (library.webpack) {
             let sequence = [waitAll];
             let sequence = [waitAll];
-            let wpBuild = webpack(require(library.webpack));
+            let wpBuild = webpackStream(require(library.webpack), webpack);
             if (settings.build.outputs) {
             if (settings.build.outputs) {
                 //shoud dtsBundle create the declaration?
                 //shoud dtsBundle create the declaration?
                 if (settings.build.dtsBundle) {
                 if (settings.build.dtsBundle) {
@@ -459,7 +458,7 @@ var buildExternalLibrary = function (library, settings, watch) {
                             if (isdts) this.push(file);
                             if (isdts) this.push(file);
                             cb();
                             cb();
                         }))
                         }))
-                        .pipe(gulp.dest('.'));
+                        .pipe(gulp.dest(outputDirectory));
                     // dts-bundle does NOT support (gulp) streams, so files have to be saved and reloaded, 
                     // dts-bundle does NOT support (gulp) streams, so files have to be saved and reloaded, 
                     // until I fix it
                     // until I fix it
                     event.on("end", function () {
                     event.on("end", function () {
@@ -471,8 +470,8 @@ var buildExternalLibrary = function (library, settings, watch) {
                             if (err) throw err;
                             if (err) throw err;
                             data = (settings.build.dtsBundle.prependText || "") + '\n' + data.toString();
                             data = (settings.build.dtsBundle.prependText || "") + '\n' + data.toString();
                             fs.writeFile(fileLocation, data);
                             fs.writeFile(fileLocation, data);
-                            if (settings.build.dtsBundle.legacyDeclaration) {
-                                var newData = processViewerDeclaration(data);
+                            if (settings.build.processDeclaration) {
+                                var newData = processDeclaration(data, settings.build.processDeclaration);
                                 fs.writeFile(fileLocation.replace('.module', ''), newData);
                                 fs.writeFile(fileLocation.replace('.module', ''), newData);
                             }
                             }
                         });
                         });
@@ -541,14 +540,50 @@ var buildExternalLibrary = function (library, settings, watch) {
                 sequence.push(build);
                 sequence.push(build);
 
 
             } else {
             } else {
+
+                let buildEvent = wpBuild
+                    .pipe(gulp.dest(outputDirectory))
+                    //back-compat
+                    .pipe(through.obj(function (file, enc, cb) {
+                        // only js files
+                        const isjs = /\.js$/.test(file.path);
+                        if (isjs) this.push(file);
+                        cb();
+                    }))
+                    .pipe(rename(library.output.replace(".js", ".max.js")))
+                    .pipe(rename(library.output.replace(".min.max.", ".")))
+                    .pipe(rename(library.output.replace(".bundle.max.", ".")))
+                    .pipe(gulp.dest(outputDirectory));
                 sequence.push(
                 sequence.push(
-                    wpBuild
-                        .pipe(rename(library.output.replace(".js", library.noBundleInName ? '.js' : ".bundle.js")))
-                        .pipe(addModuleExports(library.moduleDeclaration, { subModule: false, extendsRoot: library.extendsRoot, externalUsingBabylon: true }))
-                        .pipe(uglify())
-                        .pipe(optimisejs())
-                        .pipe(gulp.dest(outputDirectory))
-                )
+                    buildEvent
+                );
+                if (settings.build.dtsBundle || settings.build.processDeclaration) {
+                    buildEvent.on("end", function () {
+                        if (settings.build.dtsBundle) {
+                            dtsBundle.bundle(settings.build.dtsBundle);
+                        } if (settings.build.processDeclaration) {
+                            let fileLocation = path.join(outputDirectory, settings.build.processDeclaration.filename);
+                            fs.readFile(fileLocation, function (err, data) {
+                                if (err) throw err;
+                                var newData = processDeclaration(data, settings.build.processDeclaration);
+                                fs.writeFile(fileLocation.replace('.module', ''), newData);
+                            });
+                        }
+                    });
+                }
+                /*if (settings.build.processDeclaration) {
+                    sequence.push(
+                        wpBuild
+                            .pipe(through.obj(function (file, enc, cb) {
+                                // only js files
+                                const isDts = /\.d.ts$/.test(file.path);
+                                file.contents = new Buffer(processDeclaration(file.contents, settings.build.processDeclaration));
+                                if (isDts) this.push(file);
+                                cb();
+                            }))
+                            .pipe(gulp.dest(outputDirectory))
+                    )
+                }*/
             }
             }
 
 
             return merge2(sequence);
             return merge2(sequence);
@@ -600,7 +635,7 @@ gulp.task("build-custom", function (cb) {
  * Do it all.
  * Do it all.
  */
  */
 gulp.task("typescript-all", function (cb) {
 gulp.task("typescript-all", function (cb) {
-    runSequence("typescript", "typescript-libraries", cb);
+    runSequence("typescript", "typescript-libraries", "netlify-cleanup", cb);
 });
 });
 
 
 /**
 /**
@@ -623,22 +658,35 @@ gulp.task("watch", ["srcTscWatch"], function () {
     var tasks = [];
     var tasks = [];
 
 
     config.modules.map(function (module) {
     config.modules.map(function (module) {
+
         config[module].libraries.map(function (library) {
         config[module].libraries.map(function (library) {
-            tasks.push(gulp.watch(library.files, { interval: interval }, function () {
-                console.log(library.output);
-                return buildExternalLibrary(library, config[module], true)
-                    .pipe(debug());
-            }));
-            tasks.push(gulp.watch(library.shaderFiles, { interval: interval }, function () {
-                console.log(library.output);
-                return buildExternalLibrary(library, config[module], true)
-                    .pipe(debug())
-            }));
-            tasks.push(gulp.watch(library.sassFiles, { interval: interval }, function () {
-                console.log(library.output);
-                return buildExternalLibrary(library, config[module], true)
-                    .pipe(debug())
-            }));
+            if (library.webpack) {
+                if (library.noWatch) return;
+                var outputDirectory = config.build.tempDirectory + config[module].build.distOutputDirectory;
+                let wpconfig = require(library.webpack);
+                wpconfig.watch = true;
+                // dev mode and absolute path sourcemaps for debugging
+                wpconfig.mode = "development";
+                wpconfig.output.devtoolModuleFilenameTemplate = "[absolute-resource-path]";
+                //config.stats = "minimal";
+                tasks.push(webpackStream(wpconfig, webpack).pipe(gulp.dest(outputDirectory)))
+            } else {
+                tasks.push(gulp.watch(library.files, { interval: interval }, function () {
+                    console.log(library.output);
+                    return buildExternalLibrary(library, config[module], true)
+                        .pipe(debug());
+                }));
+                tasks.push(gulp.watch(library.shaderFiles, { interval: interval }, function () {
+                    console.log(library.output);
+                    return buildExternalLibrary(library, config[module], true)
+                        .pipe(debug())
+                }));
+                tasks.push(gulp.watch(library.sassFiles, { interval: interval }, function () {
+                    console.log(library.output);
+                    return buildExternalLibrary(library, config[module], true)
+                        .pipe(debug())
+                }));
+            }
         });
         });
     });
     });
 
 
@@ -696,6 +744,19 @@ gulp.task("clean-JS-MAP", function () {
     ], { force: true });
     ], { force: true });
 });
 });
 
 
+gulp.task("netlify-cleanup", function () {
+    //set by netlify
+    if (process.env.REPOSITORY_URL) {
+        return del([
+            "../../inspector/node_modules/**/*", "../../gui/node_modules/**/*",
+            "../../Viewer/node_modules/**/*"
+        ], { force: true });
+    }
+    else {
+        return true;
+    }
+})
+
 // this is needed for the modules for the declaration files.
 // this is needed for the modules for the declaration files.
 gulp.task("modules-compile", function () {
 gulp.task("modules-compile", function () {
     var tsResult = gulp.src(config.typescript)
     var tsResult = gulp.src(config.typescript)
@@ -1131,7 +1192,7 @@ gulp.task("tests-viewer-validation-browserstack", ["tests-viewer-validation-tran
  */
  */
 gulp.task("tests-viewer-validation-transpile", function (done) {
 gulp.task("tests-viewer-validation-transpile", function (done) {
 
 
-    let wpBuild = webpack(require('../../Viewer//webpack.gulp.config.js'));
+    let wpBuild = webpackStream(require('../../Viewer/webpack.gulp.config.js'), webpack);
 
 
     // clean the built directory
     // clean the built directory
     rmDir("../../Viewer/tests/build/");
     rmDir("../../Viewer/tests/build/");
@@ -1150,7 +1211,7 @@ gulp.task("tests-viewer-validation-transpile", function (done) {
  */
  */
 gulp.task("tests-viewer-transpile", function (done) {
 gulp.task("tests-viewer-transpile", function (done) {
 
 
-    let wpBuild = webpack(require('../../Viewer/tests/unit/webpack.config.js'));
+    let wpBuild = webpackStream(require('../../Viewer/tests/unit/webpack.config.js'), webpack);
 
 
     // clean the built directory
     // clean the built directory
     rmDir("../../Viewer/tests/build/");
     rmDir("../../Viewer/tests/build/");

+ 2 - 1
Tools/Gulp/package.json

@@ -59,10 +59,11 @@
         "ts-loader": "^2.3.7",
         "ts-loader": "^2.3.7",
         "typedoc": "^0.9.0",
         "typedoc": "^0.9.0",
         "typescript": "~2.8.1",
         "typescript": "~2.8.1",
+        "webpack": "^4.16.0",
         "webpack-stream": "^4.0.1"
         "webpack-stream": "^4.0.1"
     },
     },
     "scripts": {
     "scripts": {
-        "install": "npm --prefix ../../Playground/ install ../../Playground/ && npm --prefix ../../tests/unit/ install ../../tests/unit/ && npm --prefix ../../Viewer/tests/ install ../../Viewer/tests/ && cd ../../Viewer && npm install && cd ../Tools/Gulp/ && gulp deployLocalDev"
+        "install": "cd ../../gui && npm install && cd ../Tools/Gulp/ &&  cd ../../inspector && npm install && cd ../Tools/Gulp/ && npm --prefix ../../Playground/ install ../../Playground/ && npm --prefix ../../tests/unit/ install ../../tests/unit/ && npm --prefix ../../Viewer/tests/ install ../../Viewer/tests/ && cd ../../Viewer && npm install && cd ../Tools/Gulp/ && gulp deployLocalDev"
     },
     },
     "dependencies": {
     "dependencies": {
         "dts-bundle": "^0.7.3",
         "dts-bundle": "^0.7.3",

+ 44 - 19
Tools/Gulp/processViewerDeclaration.js

@@ -1,4 +1,13 @@
-module.exports = function (data) {
+module.exports = function (data, options) {
+
+    /*
+    {
+        packageName: string,
+        moduleName: string,
+        importsToRemove: Array<string>,
+        classMap
+    }
+    */
 
 
     var str = "" + data;
     var str = "" + data;
 
 
@@ -6,35 +15,51 @@ module.exports = function (data) {
     // str = str.replace(/declare module 'babylonjs-viewer\/' {((?!(declare))(.|\n))*\n}/g, '');
     // str = str.replace(/declare module 'babylonjs-viewer\/' {((?!(declare))(.|\n))*\n}/g, '');
 
 
     let lines = str.split('\n');
     let lines = str.split('\n');
-    var firstIndex = lines.findIndex((line => { return line.indexOf("'babylonjs-viewer/'") !== -1 }));
+    var firstIndex = lines.findIndex((line => { return line.indexOf(`'${options.packageName}/'`) !== -1 }));
     var lastIndex = lines.findIndex(((line, idx) => { return line.trim() === '}' && idx > firstIndex }));
     var lastIndex = lines.findIndex(((line, idx) => { return line.trim() === '}' && idx > firstIndex }));
     lines.splice(firstIndex, lastIndex - firstIndex + 1);
     lines.splice(firstIndex, lastIndex - firstIndex + 1);
     str = lines.join('\n');
     str = lines.join('\n');
 
 
-    str = str.replace(/declare module (.*) {/g, 'declare module BabylonViewer {').replace("import * as BABYLON from 'babylonjs';", "");
-    str = str.replace(/import {(.*)} from ['"]babylonjs-viewer(.*)['"];/g, '').replace(/import 'babylonjs-loaders';/, '').replace(/import 'pep';/, '');
+    str = str.replace(/declare module (.*) {/g, `declare module ${options.moduleName} {`);
+
+    str = str.replace("import * as BABYLON from 'babylonjs';", "");
+    let regexp = new RegExp(`import {(.*)} from ['"]${options.packageName}(.*)['"];`, 'g');
+    str = str.replace(regexp, '');
+
+    if (options.importsToRemove) {
+        while (options.importsToRemove.length) {
+            let remove = options.importsToRemove.pop();
+            str = str.replace(new RegExp(`import '${remove}';`), '');
+        }
+    }
 
 
     //find all used BABYLON and BABYLON-Loaders classes:
     //find all used BABYLON and BABYLON-Loaders classes:
 
 
-    var babylonRegex = /import {(.*)} from ['"](babylonjs|babylonjs-loaders)['"];/g
+    if ((options.classMap)) {
+        Object.keys(options.classMap).forEach(package => {
+            var babylonRegex = new RegExp(`import {(.*)} from ['"](${package})['"];`, "g");
 
 
-    var match = babylonRegex.exec(str);
-    let classes = new Set();
-    while (match != null) {
-        if (match[1]) {
-            match[1].split(",").forEach(element => {
-                classes.add(element.trim());
+            var match = babylonRegex.exec(str);
+            let classes = new Set();
+            while (match != null) {
+                if (match[1]) {
+                    match[1].split(",").forEach(element => {
+                        classes.add(element.trim());
+                    });
+                }
+                match = babylonRegex.exec(str);
+            }
+            str = str.replace(babylonRegex, '');
+            classes.forEach(cls => {
+                let rg = new RegExp(`([ <])(${cls})([^\\w])`, "g")
+                str = str.replace(rg, `$1${options.classMap[package]}.$2$3`);
             });
             });
-        }
-        match = babylonRegex.exec(str);
+        })
     }
     }
-    str = str.replace(babylonRegex, '');
-    classes.forEach(cls => {
-        let rg = new RegExp(`([ <])(${cls})([^\\w])`, "g")
-        str = str.replace(rg, "$1BABYLON.$2$3");
-    });
 
 
-    str = str.replace(/export {(.*)};/g, '')
+    str = str.replace(/export {(.*)};/g, '');
+
+    str = str.split("\n").filter(line => line.trim()).filter(line => line.indexOf("export * from") === -1).join("\n");
 
 
     return str;
     return str;
 }
 }

+ 6 - 3
Tools/Publisher/index.js

@@ -56,7 +56,7 @@ let packages = [
     },
     },
     {
     {
         name: 'viewer-assets',
         name: 'viewer-assets',
-        path: basePath + '/../../Viewer/dist/build/assets/',
+        path: basePath + '/../../Viewer/build/assets/',
         required: [
         required: [
             basePath + '/../../Viewer/assets/readme.md',
             basePath + '/../../Viewer/assets/readme.md',
             basePath + '/../../Viewer/assets/package.json',
             basePath + '/../../Viewer/assets/package.json',
@@ -215,7 +215,7 @@ function processCore(package, version) {
 
 
 function processViewer(package, version) {
 function processViewer(package, version) {
 
 
-    let buildPath = package.path + "dist/build/src/";
+    let buildPath = package.path + "build/src/";
     let projectPath = '../../Viewer';
     let projectPath = '../../Viewer';
 
 
     if (package.required) {
     if (package.required) {
@@ -257,7 +257,10 @@ function publish(version, packageName, basePath) {
 
 
     //publish the respected package
     //publish the respected package
     console.log("executing " + 'npm publish \"' + basePath + "\"" + ' ' + tagDef);
     console.log("executing " + 'npm publish \"' + basePath + "\"" + ' ' + tagDef);
-    shelljs.exec('npm publish \"' + basePath + "\"" + ' ' + tagDef);
+    if (process.argv.indexOf('--no-publish') === -1) {
+        shelljs.exec('npm publish \"' + basePath + "\"" + ' ' + tagDef);
+    }
+
 }
 }
 
 
 function getFiles(dir, files_) {
 function getFiles(dir, files_) {

+ 139 - 0
Tools/WebpackShaderLoader/index.js

@@ -0,0 +1,139 @@
+//modified https://github.com/grieve/webpack-glsl-loader/blob/master/index.js
+'use strict';
+
+var fs = require('fs');
+var path = require('path');
+
+
+function parse(loader, source, context, cb) {
+    var imports = [];
+    var importPattern = /@import ([.\/\w_-]+);/gi;
+    var match = importPattern.exec(source);
+
+    while (match != null) {
+        imports.push({
+            key: match[1],
+            target: match[0],
+            content: ''
+        });
+        match = importPattern.exec(source);
+    }
+
+    source = uncomment(source);
+
+    processImports(loader, source, context, imports, cb);
+}
+
+var singleComment = 1;
+var multiComment = 2;
+
+function uncomment(str) {
+
+    var currentChar;
+    var nextChar;
+    var insideString = false;
+    var insideComment = 0;
+    var offset = 0;
+    var ret = '';
+
+    str = str.replace(/\r\n/g, '\n');
+    str = str.replace(/[ \f\t\v]+/g, ' ');
+    str = str.replace(/^\s*\n/gm, '');
+    str = str.replace(/ \+ /g, '+');
+    str = str.replace(/ \- /g, '-');
+    str = str.replace(/ \/ /g, '/');
+    str = str.replace(/ \* /g, '*');
+    str = str.replace(/ > /g, '>');
+    str = str.replace(/ < /g, '<');
+    str = str.replace(/ >= /g, '>=');
+    str = str.replace(/ <= /g, '<=');
+    str = str.replace(/ \+= /g, '+=');
+    str = str.replace(/ \-= /g, '-=');
+    str = str.replace(/ \/= /g, '/=');
+    str = str.replace(/ \*= /g, '*=');
+    str = str.replace(/ = /g, '=');
+    str = str.replace(/, /g, ',');
+    str = str.replace(/\n\n/g, '\n');
+    str = str.replace(/\n /g, '\n');
+
+    for (var i = 0; i < str.length; i++) {
+        currentChar = str[i];
+        nextChar = str[i + 1];
+
+        if (!insideComment && currentChar === '"') {
+            var escaped = str[i - 1] === '\\' && str[i - 2] !== '\\';
+            if (!escaped) {
+                insideString = !insideString;
+            }
+        }
+
+        if (insideString) {
+            continue;
+        }
+
+        if (!insideComment && currentChar + nextChar === '//') {
+            ret += str.slice(offset, i);
+            offset = i;
+            insideComment = singleComment;
+            i++;
+        } else if (insideComment === singleComment && currentChar === '\n') {
+            insideComment = 0;
+            offset = i;
+        } else if (!insideComment && currentChar + nextChar === '/*') {
+            ret += str.slice(offset, i);
+            offset = i;
+            insideComment = multiComment;
+            i++;
+            continue;
+        } else if (insideComment === multiComment && currentChar + nextChar === '*/') {
+            i++;
+            insideComment = 0;
+            offset = i + 1;
+            continue;
+        }
+    }
+
+    return ret + (insideComment ? '' : str.substr(offset));
+}
+
+function processImports(loader, source, context, imports, cb) {
+    if (imports.length === 0) {
+        return cb(null, source);
+    }
+
+    var imp = imports.pop();
+
+    loader.resolve(context, imp.key + '.fx', function (err, resolved) {
+        if (err) {
+            return cb(err);
+        }
+
+        loader.addDependency(resolved);
+        fs.readFile(resolved, 'utf-8', function (err, src) {
+            if (err) {
+                return cb(err);
+            }
+
+            parse(loader, src, path.dirname(resolved), function (err, bld) {
+                if (err) {
+                    return cb(err);
+                }
+
+                source = source.replace(imp.target, bld);
+                processImports(loader, source, context, imports, cb);
+            });
+        });
+    });
+}
+
+module.exports = function (source) {
+    this.cacheable();
+    var cb = this.async();
+    parse(this, source, this.context, function (err, bld) {
+        if (err) {
+            return cb(err);
+        }
+
+        cb(null, 'module.exports = ' + JSON.stringify(bld));
+    });
+};

+ 6 - 4
Viewer/package.json

@@ -27,15 +27,17 @@
         "@types/node": "^8.9.4",
         "@types/node": "^8.9.4",
         "base64-font-loader": "0.0.4",
         "base64-font-loader": "0.0.4",
         "base64-image-loader": "^1.2.1",
         "base64-image-loader": "^1.2.1",
+        "base64-inline-loader": "^1.1.1",
         "deepmerge": "^2.1.1",
         "deepmerge": "^2.1.1",
         "handlebars": "^4.0.11",
         "handlebars": "^4.0.11",
         "html-loader": "^0.5.5",
         "html-loader": "^0.5.5",
         "json-loader": "^0.5.7",
         "json-loader": "^0.5.7",
-        "ts-loader": "^2.3.7",
-        "typescript": "^2.7.2",
+        "ts-loader": "^4.4.0",
+        "typescript": "^2.9.2",
         "uglifyjs-webpack-plugin": "^1.2.2",
         "uglifyjs-webpack-plugin": "^1.2.2",
-        "webpack": "^3.11.0",
-        "webpack-dev-server": "^2.11.2"
+        "webpack": "^4.16.0",
+        "webpack-cli": "^3.0.8",
+        "webpack-dev-server": "^3.1.4"
     },
     },
     "dependencies": {
     "dependencies": {
         "pepjs": "^0.4.3"
         "pepjs": "^0.4.3"

+ 3 - 1
Viewer/src/configuration/types/default.ts

@@ -51,12 +51,14 @@ export let defaultConfiguration: ViewerConfiguration = {
                 hideHelp: true,
                 hideHelp: true,
                 hideHd: true,
                 hideHd: true,
                 hideVr: true,
                 hideVr: true,
+                hidePrint: true,
                 disableOnFullscreen: false,
                 disableOnFullscreen: false,
                 text: {
                 text: {
                     hdButton: "Toggle HD",
                     hdButton: "Toggle HD",
                     fullscreenButton: "Fullscreen",
                     fullscreenButton: "Fullscreen",
                     helpButton: "Help",
                     helpButton: "Help",
-                    vrButton: "Toggle VR"
+                    vrButton: "Toggle VR",
+                    printButton: "Print model in 3D"
                 }
                 }
             },
             },
             events: {
             events: {

+ 62 - 0
Viewer/src/templating/plugins/printButton.ts

@@ -0,0 +1,62 @@
+import { AbstractViewerNavbarButton } from "../viewerTemplatePlugin";
+import { DefaultViewer } from "../../viewer/defaultViewer";
+import { EventCallback } from "../templateManager";
+import { Tools } from "babylonjs";
+
+export class PrintButtonPlugin extends AbstractViewerNavbarButton {
+
+    private _currentModelUrl: string;
+
+    constructor(private _viewer: DefaultViewer) {
+        super("print", "print-button", PrintButtonPlugin.HtmlTemplate);
+
+        this._viewer.onModelLoadedObservable.add((model) => {
+            this._currentModelUrl = "";
+            if (model.configuration.url) {
+                let filename = Tools.GetFilename(model.configuration.url) || model.configuration.url;
+                let baseUrl = model.configuration.root || Tools.GetFolderPath(model.configuration.url);
+
+                //gltf, obj, stl
+                let extension = model.configuration.loader || filename.split(".").pop() || "";
+                let printable = false;
+                // not using .some sue to IE11
+                ["gltf", "glb", "obj", "stl"].forEach(ext => {
+                    if (extension.indexOf(ext) !== -1) {
+                        printable = true;
+                    }
+                })
+                if (printable) {
+                    this._currentModelUrl = baseUrl + filename;
+                }
+            }
+        })
+    }
+
+    onEvent(event: EventCallback): void {
+        if (this._currentModelUrl) {
+            let printUrl = this._currentModelUrl.replace(/https?:\/\//, "com.microsoft.print3d://");
+            window.open(printUrl);
+        }
+    }
+
+    protected static HtmlTemplate: string = `
+{{#unless hidePrint}}
+<style>
+
+/* Show only if it's a windows 10 printer  */
+.print-icon.not-win-10 {
+    display: none;
+}
+
+.print-icon:after {
+    font-size: 16px;
+    content: "\\E914";
+}
+
+</style>
+<button class="print-button ${window.navigator.userAgent.indexOf("Windows NT 10.0") === -1 ? "no-win-10" : ""}" title="{{text.printButton}}">
+     <span class="icon print-icon"></span>
+ </button>
+ {{/unless}}
+`;
+}

+ 2 - 0
Viewer/src/viewer/defaultViewer.ts

@@ -8,6 +8,7 @@ import { ViewerModel } from '../model/viewerModel';
 import { IModelAnimation, AnimationState } from '../model/modelAnimation';
 import { IModelAnimation, AnimationState } from '../model/modelAnimation';
 import { IViewerTemplatePlugin } from '../templating/viewerTemplatePlugin';
 import { IViewerTemplatePlugin } from '../templating/viewerTemplatePlugin';
 import { HDButtonPlugin } from '../templating/plugins/hdButtonPlugin';
 import { HDButtonPlugin } from '../templating/plugins/hdButtonPlugin';
+import { PrintButtonPlugin } from '../templating/plugins/printButton';
 
 
 /**
 /**
  * The Default viewer is the default implementation of the AbstractViewer.
  * The Default viewer is the default implementation of the AbstractViewer.
@@ -148,6 +149,7 @@ export class DefaultViewer extends AbstractViewer {
             }
             }
 
 
             this.registerTemplatePlugin(new HDButtonPlugin(this));
             this.registerTemplatePlugin(new HDButtonPlugin(this));
+            this.registerTemplatePlugin(new PrintButtonPlugin(this));
         }
         }
     }
     }
 
 

+ 2 - 1
Viewer/tests/unit/tsconfig.json

@@ -20,7 +20,7 @@
         "skipDefaultLibCheck": true,
         "skipDefaultLibCheck": true,
         "skipLibCheck": true,
         "skipLibCheck": true,
         "baseUrl": "./src/",
         "baseUrl": "./src/",
-        "rootDir": "./",
+        "rootDir": "../../",
         "paths": {
         "paths": {
             "babylonjs": [
             "babylonjs": [
                 "../../../../dist/preview release/babylon.d.ts"
                 "../../../../dist/preview release/babylon.d.ts"
@@ -35,6 +35,7 @@
                 "../../src/assets/"
                 "../../src/assets/"
             ]
             ]
         },
         },
+        "outDir": "./build"
     },
     },
     "include": [
     "include": [
         "./src/**/*.ts"
         "./src/**/*.ts"

+ 4 - 2
Viewer/tests/unit/webpack.config.js

@@ -1,6 +1,7 @@
 const path = require('path');
 const path = require('path');
 
 
 module.exports = {
 module.exports = {
+    context: __dirname,
     entry: {
     entry: {
         'test': __dirname + '/src/index.ts'
         'test': __dirname + '/src/index.ts'
     },
     },
@@ -24,9 +25,10 @@ module.exports = {
         oimo: 'OIMO',
         oimo: 'OIMO',
         "earcut": true
         "earcut": true
     },
     },
+    mode: "development",
     devtool: 'source-map',
     devtool: 'source-map',
     module: {
     module: {
-        loaders: [{
+        rules: [{
             test: /\.tsx?$/,
             test: /\.tsx?$/,
             loader: 'ts-loader',
             loader: 'ts-loader',
             exclude: /node_modules/
             exclude: /node_modules/
@@ -46,7 +48,7 @@ module.exports = {
         },
         },
         {
         {
             test: /\.(woff|ttf|eot|svg)(\?v=[0-9]\.[0-9]\.[0-9])?$/,
             test: /\.(woff|ttf|eot|svg)(\?v=[0-9]\.[0-9]\.[0-9])?$/,
-            loader: 'base64-font-loader'
+            loader: 'base64-inline-loader?limit=1000&name=[name].[ext]'
         }]
         }]
     },
     },
     devServer: {
     devServer: {

+ 1 - 1
Viewer/tsconfig-gulp.json

@@ -41,7 +41,7 @@
                 "./assets/"
                 "./assets/"
             ]
             ]
         },
         },
-        "outDir": "./dist/build"
+        "outDir": "./build"
     },
     },
     "exclude": [
     "exclude": [
         "node_modules",
         "node_modules",

+ 2 - 2
Viewer/tsconfig.json

@@ -1,6 +1,6 @@
 {
 {
     "compilerOptions": {
     "compilerOptions": {
-        "target": "es2015",
+        "target": "es5",
         "module": "commonjs",
         "module": "commonjs",
         "declaration": true,
         "declaration": true,
         "experimentalDecorators": true,
         "experimentalDecorators": true,
@@ -44,6 +44,6 @@
                 "./assets/*"
                 "./assets/*"
             ]
             ]
         },
         },
-        "outDir": "./dist/build"
+        "outDir": "./build"
     }
     }
 }
 }

+ 4 - 2
Viewer/webpack.assets.config.js

@@ -1,4 +1,5 @@
 module.exports = {
 module.exports = {
+    context: __dirname,
     entry: [
     entry: [
         __dirname + '/src/assets/index.ts'
         __dirname + '/src/assets/index.ts'
     ],
     ],
@@ -10,8 +11,9 @@ module.exports = {
     resolve: {
     resolve: {
         extensions: ['.ts']
         extensions: ['.ts']
     },
     },
+    mode: "production",
     module: {
     module: {
-        loaders: [{
+        rules: [{
             test: /\.tsx?$/,
             test: /\.tsx?$/,
             use: {
             use: {
                 loader: 'ts-loader',
                 loader: 'ts-loader',
@@ -36,7 +38,7 @@ module.exports = {
         },
         },
         {
         {
             test: /\.(woff|ttf|eot|svg)(\?v=[0-9]\.[0-9]\.[0-9])?$/,
             test: /\.(woff|ttf|eot|svg)(\?v=[0-9]\.[0-9]\.[0-9])?$/,
-            loader: 'base64-font-loader'
+            loader: 'base64-inline-loader?limit=1000&name=[name].[ext]'
         }]
         }]
     }
     }
 }
 }

+ 4 - 3
Viewer/webpack.config.js

@@ -54,7 +54,7 @@ module.exports = /*[
             libraryTarget: 'umd',
             libraryTarget: 'umd',
             library: 'BabylonViewer',
             library: 'BabylonViewer',
             umdNamedDefine: true,
             umdNamedDefine: true,
-            devtoolModuleFilenameTemplate: '[relative-resource-path]'
+            devtoolModuleFilenameTemplate: '[absolute-resource-path]'
         },
         },
         resolve: {
         resolve: {
             extensions: ['.ts', '.js'],
             extensions: ['.ts', '.js'],
@@ -71,6 +71,7 @@ module.exports = /*[
             oimo: 'OIMO',
             oimo: 'OIMO',
             earcut: true
             earcut: true
         },
         },
+        mode: "development",
         devtool: 'source-map',
         devtool: 'source-map',
         plugins: [
         plugins: [
             new webpack.WatchIgnorePlugin([
             new webpack.WatchIgnorePlugin([
@@ -78,7 +79,7 @@ module.exports = /*[
             ])
             ])
         ],
         ],
         module: {
         module: {
-            loaders: [{
+            rules: [{
                 test: /\.tsx?$/,
                 test: /\.tsx?$/,
                 loader: 'ts-loader',
                 loader: 'ts-loader',
                 exclude: /node_modules/
                 exclude: /node_modules/
@@ -98,7 +99,7 @@ module.exports = /*[
             },
             },
             {
             {
                 test: /\.(woff|ttf|eot|svg)(\?v=[0-9]\.[0-9]\.[0-9])?$/,
                 test: /\.(woff|ttf|eot|svg)(\?v=[0-9]\.[0-9]\.[0-9])?$/,
-                loader: 'base64-font-loader'
+                loader: 'base64-inline-loader?limit=1000&name=[name].[ext]'
             }]
             }]
         },
         },
         devServer: {
         devServer: {

+ 9 - 10
Viewer/webpack.gulp.config.js

@@ -1,7 +1,10 @@
+const path = require('path');
+const webpack = require('webpack');
+
 module.exports = {
 module.exports = {
-    //context: __dirname,
+    context: __dirname,
     entry: [
     entry: [
-        __dirname + '/src/index.ts'
+        path.resolve(__dirname, './src/index.ts')
     ],
     ],
     output: {
     output: {
         libraryTarget: 'var',
         libraryTarget: 'var',
@@ -22,15 +25,11 @@ module.exports = {
             "babylonjs-viewer-assets": __dirname + '/src/assets/index.ts'
             "babylonjs-viewer-assets": __dirname + '/src/assets/index.ts'
         }
         }
     },
     },
+    mode: "production",
     module: {
     module: {
-        loaders: [{
+        rules: [{
             test: /\.tsx?$/,
             test: /\.tsx?$/,
-            use: {
-                loader: 'ts-loader',
-                options: {
-                    configFile: 'tsconfig-gulp.json'
-                }
-            },
+            loader: 'ts-loader',
             exclude: /node_modules/
             exclude: /node_modules/
         },
         },
         {
         {
@@ -48,7 +47,7 @@ module.exports = {
         },
         },
         {
         {
             test: /\.(woff|ttf|eot|svg)(\?v=[0-9]\.[0-9]\.[0-9])?$/,
             test: /\.(woff|ttf|eot|svg)(\?v=[0-9]\.[0-9]\.[0-9])?$/,
-            loader: 'base64-font-loader'
+            loader: 'base64-inline-loader?limit=1000&name=[name].[ext]'
         }]
         }]
     }
     }
 }
 }

파일 크기가 너무 크기때문에 변경 상태를 표시하지 않습니다.
+ 8115 - 8114
dist/preview release/babylon.d.ts


파일 크기가 너무 크기때문에 변경 상태를 표시하지 않습니다.
+ 47 - 47
dist/preview release/babylon.js


+ 23 - 18
dist/preview release/babylon.max.js

@@ -15760,7 +15760,6 @@ var BABYLON;
             var gl = this._gl;
             var gl = this._gl;
             var texture = new BABYLON.InternalTexture(this, BABYLON.InternalTexture.DATASOURCE_CUBERAW);
             var texture = new BABYLON.InternalTexture(this, BABYLON.InternalTexture.DATASOURCE_CUBERAW);
             texture.isCube = true;
             texture.isCube = true;
-            texture.generateMipMaps = generateMipMaps;
             texture.format = format;
             texture.format = format;
             texture.type = type;
             texture.type = type;
             if (!this._doNotHandleContextLost) {
             if (!this._doNotHandleContextLost) {
@@ -15771,6 +15770,25 @@ var BABYLON;
             if (internalFormat === gl.RGB) {
             if (internalFormat === gl.RGB) {
                 internalFormat = gl.RGBA;
                 internalFormat = gl.RGBA;
             }
             }
+            // Mipmap generation needs a sized internal format that is both color-renderable and texture-filterable
+            if (textureType === gl.FLOAT && !this._caps.textureFloatLinearFiltering) {
+                generateMipMaps = false;
+                samplingMode = Engine.TEXTURE_NEAREST_SAMPLINGMODE;
+                BABYLON.Tools.Warn("Float texture filtering is not supported. Mipmap generation and sampling mode are forced to false and TEXTURE_NEAREST_SAMPLINGMODE, respectively.");
+            }
+            else if (textureType === this._gl.HALF_FLOAT_OES && !this._caps.textureHalfFloatLinearFiltering) {
+                generateMipMaps = false;
+                samplingMode = Engine.TEXTURE_NEAREST_SAMPLINGMODE;
+                BABYLON.Tools.Warn("Half float texture filtering is not supported. Mipmap generation and sampling mode are forced to false and TEXTURE_NEAREST_SAMPLINGMODE, respectively.");
+            }
+            else if (textureType === gl.FLOAT && !this._caps.textureFloatRender) {
+                generateMipMaps = false;
+                BABYLON.Tools.Warn("Render to float textures is not supported. Mipmap generation forced to false.");
+            }
+            else if (textureType === gl.HALF_FLOAT && !this._caps.colorBufferFloat) {
+                generateMipMaps = false;
+                BABYLON.Tools.Warn("Render to half float textures is not supported. Mipmap generation forced to false.");
+            }
             var width = size;
             var width = size;
             var height = width;
             var height = width;
             texture.width = width;
             texture.width = width;
@@ -15789,22 +15807,13 @@ var BABYLON;
             if (data && generateMipMaps) {
             if (data && generateMipMaps) {
                 this._gl.generateMipmap(this._gl.TEXTURE_CUBE_MAP);
                 this._gl.generateMipmap(this._gl.TEXTURE_CUBE_MAP);
             }
             }
-            if (textureType === gl.FLOAT && !this._caps.textureFloatLinearFiltering) {
-                gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
-                gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
-            }
-            else if (textureType === this._gl.HALF_FLOAT_OES && !this._caps.textureHalfFloatLinearFiltering) {
-                gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
-                gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
-            }
-            else {
-                var filters = this._getSamplingParameters(samplingMode, generateMipMaps);
-                gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_MAG_FILTER, filters.mag);
-                gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_MIN_FILTER, filters.min);
-            }
+            var filters = this._getSamplingParameters(samplingMode, generateMipMaps);
+            gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_MAG_FILTER, filters.mag);
+            gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_MIN_FILTER, filters.min);
             gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
             gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
             gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
             gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
             this._bindTextureDirectly(gl.TEXTURE_CUBE_MAP, null);
             this._bindTextureDirectly(gl.TEXTURE_CUBE_MAP, null);
+            texture.generateMipMaps = generateMipMaps;
             return texture;
             return texture;
         };
         };
         /**
         /**
@@ -15871,10 +15880,6 @@ var BABYLON;
                     _this._bindTextureDirectly(gl.TEXTURE_CUBE_MAP, null);
                     _this._bindTextureDirectly(gl.TEXTURE_CUBE_MAP, null);
                 }
                 }
                 else {
                 else {
-                    texture.generateMipMaps = !noMipmap;
-                    if (type === Engine.TEXTURETYPE_FLOAT && !_this._caps.textureFloatLinearFiltering) {
-                        texture.generateMipMaps = false;
-                    }
                     _this.updateRawCubeTexture(texture, faceDataArrays, format, type, invertY);
                     _this.updateRawCubeTexture(texture, faceDataArrays, format, type, invertY);
                 }
                 }
                 texture.isReady = true;
                 texture.isReady = true;

+ 23 - 18
dist/preview release/babylon.no-module.max.js

@@ -15727,7 +15727,6 @@ var BABYLON;
             var gl = this._gl;
             var gl = this._gl;
             var texture = new BABYLON.InternalTexture(this, BABYLON.InternalTexture.DATASOURCE_CUBERAW);
             var texture = new BABYLON.InternalTexture(this, BABYLON.InternalTexture.DATASOURCE_CUBERAW);
             texture.isCube = true;
             texture.isCube = true;
-            texture.generateMipMaps = generateMipMaps;
             texture.format = format;
             texture.format = format;
             texture.type = type;
             texture.type = type;
             if (!this._doNotHandleContextLost) {
             if (!this._doNotHandleContextLost) {
@@ -15738,6 +15737,25 @@ var BABYLON;
             if (internalFormat === gl.RGB) {
             if (internalFormat === gl.RGB) {
                 internalFormat = gl.RGBA;
                 internalFormat = gl.RGBA;
             }
             }
+            // Mipmap generation needs a sized internal format that is both color-renderable and texture-filterable
+            if (textureType === gl.FLOAT && !this._caps.textureFloatLinearFiltering) {
+                generateMipMaps = false;
+                samplingMode = Engine.TEXTURE_NEAREST_SAMPLINGMODE;
+                BABYLON.Tools.Warn("Float texture filtering is not supported. Mipmap generation and sampling mode are forced to false and TEXTURE_NEAREST_SAMPLINGMODE, respectively.");
+            }
+            else if (textureType === this._gl.HALF_FLOAT_OES && !this._caps.textureHalfFloatLinearFiltering) {
+                generateMipMaps = false;
+                samplingMode = Engine.TEXTURE_NEAREST_SAMPLINGMODE;
+                BABYLON.Tools.Warn("Half float texture filtering is not supported. Mipmap generation and sampling mode are forced to false and TEXTURE_NEAREST_SAMPLINGMODE, respectively.");
+            }
+            else if (textureType === gl.FLOAT && !this._caps.textureFloatRender) {
+                generateMipMaps = false;
+                BABYLON.Tools.Warn("Render to float textures is not supported. Mipmap generation forced to false.");
+            }
+            else if (textureType === gl.HALF_FLOAT && !this._caps.colorBufferFloat) {
+                generateMipMaps = false;
+                BABYLON.Tools.Warn("Render to half float textures is not supported. Mipmap generation forced to false.");
+            }
             var width = size;
             var width = size;
             var height = width;
             var height = width;
             texture.width = width;
             texture.width = width;
@@ -15756,22 +15774,13 @@ var BABYLON;
             if (data && generateMipMaps) {
             if (data && generateMipMaps) {
                 this._gl.generateMipmap(this._gl.TEXTURE_CUBE_MAP);
                 this._gl.generateMipmap(this._gl.TEXTURE_CUBE_MAP);
             }
             }
-            if (textureType === gl.FLOAT && !this._caps.textureFloatLinearFiltering) {
-                gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
-                gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
-            }
-            else if (textureType === this._gl.HALF_FLOAT_OES && !this._caps.textureHalfFloatLinearFiltering) {
-                gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
-                gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
-            }
-            else {
-                var filters = this._getSamplingParameters(samplingMode, generateMipMaps);
-                gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_MAG_FILTER, filters.mag);
-                gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_MIN_FILTER, filters.min);
-            }
+            var filters = this._getSamplingParameters(samplingMode, generateMipMaps);
+            gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_MAG_FILTER, filters.mag);
+            gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_MIN_FILTER, filters.min);
             gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
             gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
             gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
             gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
             this._bindTextureDirectly(gl.TEXTURE_CUBE_MAP, null);
             this._bindTextureDirectly(gl.TEXTURE_CUBE_MAP, null);
+            texture.generateMipMaps = generateMipMaps;
             return texture;
             return texture;
         };
         };
         /**
         /**
@@ -15838,10 +15847,6 @@ var BABYLON;
                     _this._bindTextureDirectly(gl.TEXTURE_CUBE_MAP, null);
                     _this._bindTextureDirectly(gl.TEXTURE_CUBE_MAP, null);
                 }
                 }
                 else {
                 else {
-                    texture.generateMipMaps = !noMipmap;
-                    if (type === Engine.TEXTURETYPE_FLOAT && !_this._caps.textureFloatLinearFiltering) {
-                        texture.generateMipMaps = false;
-                    }
                     _this.updateRawCubeTexture(texture, faceDataArrays, format, type, invertY);
                     _this.updateRawCubeTexture(texture, faceDataArrays, format, type, invertY);
                 }
                 }
                 texture.isReady = true;
                 texture.isReady = true;

파일 크기가 너무 크기때문에 변경 상태를 표시하지 않습니다.
+ 47 - 47
dist/preview release/babylon.worker.js


+ 23 - 18
dist/preview release/es6.js

@@ -15727,7 +15727,6 @@ var BABYLON;
             var gl = this._gl;
             var gl = this._gl;
             var texture = new BABYLON.InternalTexture(this, BABYLON.InternalTexture.DATASOURCE_CUBERAW);
             var texture = new BABYLON.InternalTexture(this, BABYLON.InternalTexture.DATASOURCE_CUBERAW);
             texture.isCube = true;
             texture.isCube = true;
-            texture.generateMipMaps = generateMipMaps;
             texture.format = format;
             texture.format = format;
             texture.type = type;
             texture.type = type;
             if (!this._doNotHandleContextLost) {
             if (!this._doNotHandleContextLost) {
@@ -15738,6 +15737,25 @@ var BABYLON;
             if (internalFormat === gl.RGB) {
             if (internalFormat === gl.RGB) {
                 internalFormat = gl.RGBA;
                 internalFormat = gl.RGBA;
             }
             }
+            // Mipmap generation needs a sized internal format that is both color-renderable and texture-filterable
+            if (textureType === gl.FLOAT && !this._caps.textureFloatLinearFiltering) {
+                generateMipMaps = false;
+                samplingMode = Engine.TEXTURE_NEAREST_SAMPLINGMODE;
+                BABYLON.Tools.Warn("Float texture filtering is not supported. Mipmap generation and sampling mode are forced to false and TEXTURE_NEAREST_SAMPLINGMODE, respectively.");
+            }
+            else if (textureType === this._gl.HALF_FLOAT_OES && !this._caps.textureHalfFloatLinearFiltering) {
+                generateMipMaps = false;
+                samplingMode = Engine.TEXTURE_NEAREST_SAMPLINGMODE;
+                BABYLON.Tools.Warn("Half float texture filtering is not supported. Mipmap generation and sampling mode are forced to false and TEXTURE_NEAREST_SAMPLINGMODE, respectively.");
+            }
+            else if (textureType === gl.FLOAT && !this._caps.textureFloatRender) {
+                generateMipMaps = false;
+                BABYLON.Tools.Warn("Render to float textures is not supported. Mipmap generation forced to false.");
+            }
+            else if (textureType === gl.HALF_FLOAT && !this._caps.colorBufferFloat) {
+                generateMipMaps = false;
+                BABYLON.Tools.Warn("Render to half float textures is not supported. Mipmap generation forced to false.");
+            }
             var width = size;
             var width = size;
             var height = width;
             var height = width;
             texture.width = width;
             texture.width = width;
@@ -15756,22 +15774,13 @@ var BABYLON;
             if (data && generateMipMaps) {
             if (data && generateMipMaps) {
                 this._gl.generateMipmap(this._gl.TEXTURE_CUBE_MAP);
                 this._gl.generateMipmap(this._gl.TEXTURE_CUBE_MAP);
             }
             }
-            if (textureType === gl.FLOAT && !this._caps.textureFloatLinearFiltering) {
-                gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
-                gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
-            }
-            else if (textureType === this._gl.HALF_FLOAT_OES && !this._caps.textureHalfFloatLinearFiltering) {
-                gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
-                gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
-            }
-            else {
-                var filters = this._getSamplingParameters(samplingMode, generateMipMaps);
-                gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_MAG_FILTER, filters.mag);
-                gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_MIN_FILTER, filters.min);
-            }
+            var filters = this._getSamplingParameters(samplingMode, generateMipMaps);
+            gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_MAG_FILTER, filters.mag);
+            gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_MIN_FILTER, filters.min);
             gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
             gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
             gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
             gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
             this._bindTextureDirectly(gl.TEXTURE_CUBE_MAP, null);
             this._bindTextureDirectly(gl.TEXTURE_CUBE_MAP, null);
+            texture.generateMipMaps = generateMipMaps;
             return texture;
             return texture;
         };
         };
         /**
         /**
@@ -15838,10 +15847,6 @@ var BABYLON;
                     _this._bindTextureDirectly(gl.TEXTURE_CUBE_MAP, null);
                     _this._bindTextureDirectly(gl.TEXTURE_CUBE_MAP, null);
                 }
                 }
                 else {
                 else {
-                    texture.generateMipMaps = !noMipmap;
-                    if (type === Engine.TEXTURETYPE_FLOAT && !_this._caps.textureFloatLinearFiltering) {
-                        texture.generateMipMaps = false;
-                    }
                     _this.updateRawCubeTexture(texture, faceDataArrays, format, type, invertY);
                     _this.updateRawCubeTexture(texture, faceDataArrays, format, type, invertY);
                 }
                 }
                 texture.isReady = true;
                 texture.isReady = true;

+ 1 - 2
dist/preview release/gui/package.json

@@ -11,9 +11,8 @@
     },
     },
     "main": "babylon.gui.min.js",
     "main": "babylon.gui.min.js",
     "files": [
     "files": [
-        "babylon.gui.js",
         "babylon.gui.min.js",
         "babylon.gui.min.js",
-        "babylon.gui.d.ts",
+        "babylon.gui.min.js.map",
         "babylon.gui.module.d.ts",
         "babylon.gui.module.d.ts",
         "readme.md",
         "readme.md",
         "package.json"
         "package.json"

+ 3 - 0
dist/preview release/inspector/package.json

@@ -12,9 +12,12 @@
     "main": "babylon.inspector.bundle.js",
     "main": "babylon.inspector.bundle.js",
     "files": [
     "files": [
         "babylon.inspector.bundle.js",
         "babylon.inspector.bundle.js",
+        "babylon.inspector.bundle.js.map",
+        "babylon.inspector.module.d.ts",
         "readme.md",
         "readme.md",
         "package.json"
         "package.json"
     ],
     ],
+    "typings": "babylon.inspector.module.d.ts",
     "keywords": [
     "keywords": [
         "3D",
         "3D",
         "javascript",
         "javascript",

+ 1 - 0
dist/preview release/loaders/babylon.objFileLoader.d.ts

@@ -45,6 +45,7 @@ declare module BABYLON {
         facePattern2: RegExp;
         facePattern2: RegExp;
         facePattern3: RegExp;
         facePattern3: RegExp;
         facePattern4: RegExp;
         facePattern4: RegExp;
+        facePattern5: RegExp;
         /**
         /**
          * Calls synchronously the MTL file attached to this obj.
          * Calls synchronously the MTL file attached to this obj.
          * Load function or importMesh function don't enable to load 2 files in the same time asynchronously.
          * Load function or importMesh function don't enable to load 2 files in the same time asynchronously.

+ 37 - 1
dist/preview release/loaders/babylon.objFileLoader.js

@@ -231,6 +231,8 @@ var BABYLON;
             this.facePattern3 = /f\s+((([\d]{1,}\/[\d]{1,}\/[\d]{1,}[\s]?){3,})+)/;
             this.facePattern3 = /f\s+((([\d]{1,}\/[\d]{1,}\/[\d]{1,}[\s]?){3,})+)/;
             // f vertex//normal vertex//normal vertex//normal ...
             // f vertex//normal vertex//normal vertex//normal ...
             this.facePattern4 = /f\s+((([\d]{1,}\/\/[\d]{1,}[\s]?){3,})+)/;
             this.facePattern4 = /f\s+((([\d]{1,}\/\/[\d]{1,}[\s]?){3,})+)/;
+            // f -vertex/-uvs/-normal -vertex/-uvs/-normal -vertex/-uvs/-normal ...
+            this.facePattern5 = /f\s+(((-[\d]{1,}\/-[\d]{1,}\/-[\d]{1,}[\s]?){3,})+)/;
         }
         }
         /**
         /**
          * Calls synchronously the MTL file attached to this obj.
          * Calls synchronously the MTL file attached to this obj.
@@ -413,11 +415,12 @@ var BABYLON;
              * Create triangles from polygons by recursion
              * Create triangles from polygons by recursion
              * The best to understand how it works is to draw it in the same time you get the recursion.
              * The best to understand how it works is to draw it in the same time you get the recursion.
              * It is important to notice that a triangle is a polygon
              * It is important to notice that a triangle is a polygon
-             * We get 4 patterns of face defined in OBJ File :
+             * We get 5 patterns of face defined in OBJ File :
              * facePattern1 = ["1","2","3","4","5","6"]
              * facePattern1 = ["1","2","3","4","5","6"]
              * facePattern2 = ["1/1","2/2","3/3","4/4","5/5","6/6"]
              * facePattern2 = ["1/1","2/2","3/3","4/4","5/5","6/6"]
              * facePattern3 = ["1/1/1","2/2/2","3/3/3","4/4/4","5/5/5","6/6/6"]
              * facePattern3 = ["1/1/1","2/2/2","3/3/3","4/4/4","5/5/5","6/6/6"]
              * facePattern4 = ["1//1","2//2","3//3","4//4","5//5","6//6"]
              * facePattern4 = ["1//1","2//2","3//3","4//4","5//5","6//6"]
+             * facePattern5 = ["-1/-1/-1","-2/-2/-2","-3/-3/-3","-4/-4/-4","-5/-5/-5","-6/-6/-6"]
              * Each pattern is divided by the same method
              * Each pattern is divided by the same method
              * @param face Array[String] The indices of elements
              * @param face Array[String] The indices of elements
              * @param v Integer The variable to increment
              * @param v Integer The variable to increment
@@ -437,6 +440,7 @@ var BABYLON;
                 //Pattern2 => triangle = ["1/1","2/2","3/3","1/1","3/3","4/4"];
                 //Pattern2 => triangle = ["1/1","2/2","3/3","1/1","3/3","4/4"];
                 //Pattern3 => triangle = ["1/1/1","2/2/2","3/3/3","1/1/1","3/3/3","4/4/4"];
                 //Pattern3 => triangle = ["1/1/1","2/2/2","3/3/3","1/1/1","3/3/3","4/4/4"];
                 //Pattern4 => triangle = ["1//1","2//2","3//3","1//1","3//3","4//4"];
                 //Pattern4 => triangle = ["1//1","2//2","3//3","1//1","3//3","4//4"];
+                //Pattern5 => triangle = ["-1/-1/-1","-2/-2/-2","-3/-3/-3","-1/-1/-1","-3/-3/-3","-4/-4/-4"];
             };
             };
             /**
             /**
              * Create triangles and push the data for each polygon for the pattern 1
              * Create triangles and push the data for each polygon for the pattern 1
@@ -532,6 +536,31 @@ var BABYLON;
                 //Reset variable for the next line
                 //Reset variable for the next line
                 triangles = [];
                 triangles = [];
             };
             };
+            /**
+             * Create triangles and push the data for each polygon for the pattern 3
+             * In this pattern we get vertice positions, uvs and normals
+             * @param face
+             * @param v
+             */
+            var setDataForCurrentFaceWithPattern5 = function (face, v) {
+                //Get the indices of triangles for each polygon
+                getTriangles(face, v);
+                for (var k = 0; k < triangles.length; k++) {
+                    //triangle[k] = "-1/-1/-1"
+                    //Split the data for getting position, uv, and normals
+                    var point = triangles[k].split("/"); // ["-1", "-1", "-1"]
+                    // Set position indice
+                    var indicePositionFromObj = positions.length + parseInt(point[0]);
+                    // Set uv indice
+                    var indiceUvsFromObj = uvs.length + parseInt(point[1]);
+                    // Set normal indice
+                    var indiceNormalFromObj = normals.length + parseInt(point[2]);
+                    setData(indicePositionFromObj, indiceUvsFromObj, indiceNormalFromObj, positions[indicePositionFromObj], uvs[indiceUvsFromObj], normals[indiceNormalFromObj] //Set the vector for each component
+                    );
+                }
+                //Reset variable for the next line
+                triangles = [];
+            };
             var addPreviousObjMesh = function () {
             var addPreviousObjMesh = function () {
                 //Check if it is not the first mesh. Otherwise we don't have data.
                 //Check if it is not the first mesh. Otherwise we don't have data.
                 if (meshesFromObj.length > 0) {
                 if (meshesFromObj.length > 0) {
@@ -604,6 +633,13 @@ var BABYLON;
                     setDataForCurrentFaceWithPattern4(result[1].trim().split(" "), // ["1//1", "2//2", "3//3"]
                     setDataForCurrentFaceWithPattern4(result[1].trim().split(" "), // ["1//1", "2//2", "3//3"]
                     1);
                     1);
                 }
                 }
+                else if ((result = this.facePattern5.exec(line)) !== null) {
+                    //Value of result:
+                    //["f -1/-1/-1 -2/-2/-2 -3/-3/-3", "-1/-1/-1 -2/-2/-2 -3/-3/-3"...]
+                    //Set the data for this face
+                    setDataForCurrentFaceWithPattern5(result[1].trim().split(" "), // ["-1/-1/-1", "-2/-2/-2", "-3/-3/-3"]
+                    1);
+                }
                 else if ((result = this.facePattern2.exec(line)) !== null) {
                 else if ((result = this.facePattern2.exec(line)) !== null) {
                     //Value of result:
                     //Value of result:
                     //["f 1/1 2/2 3/3", "1/1 2/2 3/3"...]
                     //["f 1/1 2/2 3/3", "1/1 2/2 3/3"...]

파일 크기가 너무 크기때문에 변경 상태를 표시하지 않습니다.
+ 1 - 1
dist/preview release/loaders/babylon.objFileLoader.min.js


+ 1 - 0
dist/preview release/loaders/babylonjs.loaders.d.ts

@@ -63,6 +63,7 @@ declare module BABYLON {
         facePattern2: RegExp;
         facePattern2: RegExp;
         facePattern3: RegExp;
         facePattern3: RegExp;
         facePattern4: RegExp;
         facePattern4: RegExp;
+        facePattern5: RegExp;
         /**
         /**
          * Calls synchronously the MTL file attached to this obj.
          * Calls synchronously the MTL file attached to this obj.
          * Load function or importMesh function don't enable to load 2 files in the same time asynchronously.
          * Load function or importMesh function don't enable to load 2 files in the same time asynchronously.

+ 37 - 1
dist/preview release/loaders/babylonjs.loaders.js

@@ -430,6 +430,8 @@ var BABYLON;
             this.facePattern3 = /f\s+((([\d]{1,}\/[\d]{1,}\/[\d]{1,}[\s]?){3,})+)/;
             this.facePattern3 = /f\s+((([\d]{1,}\/[\d]{1,}\/[\d]{1,}[\s]?){3,})+)/;
             // f vertex//normal vertex//normal vertex//normal ...
             // f vertex//normal vertex//normal vertex//normal ...
             this.facePattern4 = /f\s+((([\d]{1,}\/\/[\d]{1,}[\s]?){3,})+)/;
             this.facePattern4 = /f\s+((([\d]{1,}\/\/[\d]{1,}[\s]?){3,})+)/;
+            // f -vertex/-uvs/-normal -vertex/-uvs/-normal -vertex/-uvs/-normal ...
+            this.facePattern5 = /f\s+(((-[\d]{1,}\/-[\d]{1,}\/-[\d]{1,}[\s]?){3,})+)/;
         }
         }
         /**
         /**
          * Calls synchronously the MTL file attached to this obj.
          * Calls synchronously the MTL file attached to this obj.
@@ -612,11 +614,12 @@ var BABYLON;
              * Create triangles from polygons by recursion
              * Create triangles from polygons by recursion
              * The best to understand how it works is to draw it in the same time you get the recursion.
              * The best to understand how it works is to draw it in the same time you get the recursion.
              * It is important to notice that a triangle is a polygon
              * It is important to notice that a triangle is a polygon
-             * We get 4 patterns of face defined in OBJ File :
+             * We get 5 patterns of face defined in OBJ File :
              * facePattern1 = ["1","2","3","4","5","6"]
              * facePattern1 = ["1","2","3","4","5","6"]
              * facePattern2 = ["1/1","2/2","3/3","4/4","5/5","6/6"]
              * facePattern2 = ["1/1","2/2","3/3","4/4","5/5","6/6"]
              * facePattern3 = ["1/1/1","2/2/2","3/3/3","4/4/4","5/5/5","6/6/6"]
              * facePattern3 = ["1/1/1","2/2/2","3/3/3","4/4/4","5/5/5","6/6/6"]
              * facePattern4 = ["1//1","2//2","3//3","4//4","5//5","6//6"]
              * facePattern4 = ["1//1","2//2","3//3","4//4","5//5","6//6"]
+             * facePattern5 = ["-1/-1/-1","-2/-2/-2","-3/-3/-3","-4/-4/-4","-5/-5/-5","-6/-6/-6"]
              * Each pattern is divided by the same method
              * Each pattern is divided by the same method
              * @param face Array[String] The indices of elements
              * @param face Array[String] The indices of elements
              * @param v Integer The variable to increment
              * @param v Integer The variable to increment
@@ -636,6 +639,7 @@ var BABYLON;
                 //Pattern2 => triangle = ["1/1","2/2","3/3","1/1","3/3","4/4"];
                 //Pattern2 => triangle = ["1/1","2/2","3/3","1/1","3/3","4/4"];
                 //Pattern3 => triangle = ["1/1/1","2/2/2","3/3/3","1/1/1","3/3/3","4/4/4"];
                 //Pattern3 => triangle = ["1/1/1","2/2/2","3/3/3","1/1/1","3/3/3","4/4/4"];
                 //Pattern4 => triangle = ["1//1","2//2","3//3","1//1","3//3","4//4"];
                 //Pattern4 => triangle = ["1//1","2//2","3//3","1//1","3//3","4//4"];
+                //Pattern5 => triangle = ["-1/-1/-1","-2/-2/-2","-3/-3/-3","-1/-1/-1","-3/-3/-3","-4/-4/-4"];
             };
             };
             /**
             /**
              * Create triangles and push the data for each polygon for the pattern 1
              * Create triangles and push the data for each polygon for the pattern 1
@@ -731,6 +735,31 @@ var BABYLON;
                 //Reset variable for the next line
                 //Reset variable for the next line
                 triangles = [];
                 triangles = [];
             };
             };
+            /**
+             * Create triangles and push the data for each polygon for the pattern 3
+             * In this pattern we get vertice positions, uvs and normals
+             * @param face
+             * @param v
+             */
+            var setDataForCurrentFaceWithPattern5 = function (face, v) {
+                //Get the indices of triangles for each polygon
+                getTriangles(face, v);
+                for (var k = 0; k < triangles.length; k++) {
+                    //triangle[k] = "-1/-1/-1"
+                    //Split the data for getting position, uv, and normals
+                    var point = triangles[k].split("/"); // ["-1", "-1", "-1"]
+                    // Set position indice
+                    var indicePositionFromObj = positions.length + parseInt(point[0]);
+                    // Set uv indice
+                    var indiceUvsFromObj = uvs.length + parseInt(point[1]);
+                    // Set normal indice
+                    var indiceNormalFromObj = normals.length + parseInt(point[2]);
+                    setData(indicePositionFromObj, indiceUvsFromObj, indiceNormalFromObj, positions[indicePositionFromObj], uvs[indiceUvsFromObj], normals[indiceNormalFromObj] //Set the vector for each component
+                    );
+                }
+                //Reset variable for the next line
+                triangles = [];
+            };
             var addPreviousObjMesh = function () {
             var addPreviousObjMesh = function () {
                 //Check if it is not the first mesh. Otherwise we don't have data.
                 //Check if it is not the first mesh. Otherwise we don't have data.
                 if (meshesFromObj.length > 0) {
                 if (meshesFromObj.length > 0) {
@@ -803,6 +832,13 @@ var BABYLON;
                     setDataForCurrentFaceWithPattern4(result[1].trim().split(" "), // ["1//1", "2//2", "3//3"]
                     setDataForCurrentFaceWithPattern4(result[1].trim().split(" "), // ["1//1", "2//2", "3//3"]
                     1);
                     1);
                 }
                 }
+                else if ((result = this.facePattern5.exec(line)) !== null) {
+                    //Value of result:
+                    //["f -1/-1/-1 -2/-2/-2 -3/-3/-3", "-1/-1/-1 -2/-2/-2 -3/-3/-3"...]
+                    //Set the data for this face
+                    setDataForCurrentFaceWithPattern5(result[1].trim().split(" "), // ["-1/-1/-1", "-2/-2/-2", "-3/-3/-3"]
+                    1);
+                }
                 else if ((result = this.facePattern2.exec(line)) !== null) {
                 else if ((result = this.facePattern2.exec(line)) !== null) {
                     //Value of result:
                     //Value of result:
                     //["f 1/1 2/2 3/3", "1/1 2/2 3/3"...]
                     //["f 1/1 2/2 3/3", "1/1 2/2 3/3"...]

파일 크기가 너무 크기때문에 변경 상태를 표시하지 않습니다.
+ 4 - 4
dist/preview release/loaders/babylonjs.loaders.min.js


+ 1 - 0
dist/preview release/loaders/babylonjs.loaders.module.d.ts

@@ -70,6 +70,7 @@ declare module BABYLON {
         facePattern2: RegExp;
         facePattern2: RegExp;
         facePattern3: RegExp;
         facePattern3: RegExp;
         facePattern4: RegExp;
         facePattern4: RegExp;
+        facePattern5: RegExp;
         /**
         /**
          * Calls synchronously the MTL file attached to this obj.
          * Calls synchronously the MTL file attached to this obj.
          * Load function or importMesh function don't enable to load 2 files in the same time asynchronously.
          * Load function or importMesh function don't enable to load 2 files in the same time asynchronously.

+ 77 - 43
dist/preview release/viewer/babylon.viewer.d.ts

@@ -1006,6 +1006,7 @@ declare module BabylonViewer {
 declare module BabylonViewer {
 declare module BabylonViewer {
     
     
     
     
+    
     export function getConfigurationKey(key: string, configObject: any): any;
     export function getConfigurationKey(key: string, configObject: any): any;
     export interface ViewerConfiguration {
     export interface ViewerConfiguration {
             version?: string;
             version?: string;
@@ -1054,6 +1055,7 @@ declare module BabylonViewer {
                     minecraft?: boolean;
                     minecraft?: boolean;
                     [propName: string]: boolean | undefined;
                     [propName: string]: boolean | undefined;
             };
             };
+            environmentMap?: IEnvironmentMapConfiguration;
             vr?: IVRConfiguration;
             vr?: IVRConfiguration;
             lab?: {
             lab?: {
                     flashlight?: boolean | {
                     flashlight?: boolean | {
@@ -1072,12 +1074,14 @@ declare module BabylonViewer {
                             };
                             };
                     };
                     };
                     hideLoadingDelay?: number;
                     hideLoadingDelay?: number;
+                    /** Deprecated */
                     assetsRootURL?: string;
                     assetsRootURL?: string;
                     environmentMainColor?: {
                     environmentMainColor?: {
                             r: number;
                             r: number;
                             g: number;
                             g: number;
                             b: number;
                             b: number;
                     };
                     };
+                    /** Deprecated */
                     environmentMap?: {
                     environmentMap?: {
                             /**
                             /**
                                 * Environment map texture path in relative to the asset folder.
                                 * Environment map texture path in relative to the asset folder.
@@ -1369,6 +1373,7 @@ declare module BabylonViewer {
     
     
     
     
     
     
+    
     /**
     /**
         * This interface describes the structure of the variable sent with the configuration observables of the scene manager.
         * This interface describes the structure of the variable sent with the configuration observables of the scene manager.
         * O - the type of object we are dealing with (Light, BABYLON.ArcRotateCamera, BABYLON.Scene, etc')
         * O - the type of object we are dealing with (Light, BABYLON.ArcRotateCamera, BABYLON.Scene, etc')
@@ -1514,6 +1519,7 @@ declare module BabylonViewer {
                 * @param modelConfiguration the configuration to use to reconfigure the models
                 * @param modelConfiguration the configuration to use to reconfigure the models
                 */
                 */
             protected _configureVR(vrConfig: IVRConfiguration): void;
             protected _configureVR(vrConfig: IVRConfiguration): void;
+            protected _configureEnvironmentMap(environmentMapConfiguration: IEnvironmentMapConfiguration): any;
             /**
             /**
                 * (Re) configure the camera. The camera will only be created once and from this point will only be reconfigured.
                 * (Re) configure the camera. The camera will only be created once and from this point will only be reconfigured.
                 * @param cameraConfig the new camera configuration
                 * @param cameraConfig the new camera configuration
@@ -1652,6 +1658,32 @@ declare module BabylonViewer {
     export * from 'babylonjs-viewer/configuration/interfaces/skyboxConfiguration';
     export * from 'babylonjs-viewer/configuration/interfaces/skyboxConfiguration';
     export * from 'babylonjs-viewer/configuration/interfaces/templateConfiguration';
     export * from 'babylonjs-viewer/configuration/interfaces/templateConfiguration';
     export * from 'babylonjs-viewer/configuration/interfaces/vrConfiguration';
     export * from 'babylonjs-viewer/configuration/interfaces/vrConfiguration';
+    export * from 'babylonjs-viewer/configuration/interfaces/environmentMapConfiguration';
+}
+
+declare module BabylonViewer {
+    export interface IEnvironmentMapConfiguration {
+            /**
+                * Environment map texture path in relative to the asset folder.
+                */
+            texture: string;
+            /**
+                * Default rotation to apply to the environment map.
+                */
+            rotationY: number;
+            /**
+                * Tint level of the main color on the environment map.
+                */
+            tintLevel: number;
+            /**
+                * The environment's main color.
+                */
+            mainColor?: {
+                    r?: number;
+                    g?: number;
+                    b?: number;
+            };
+    }
 }
 }
 
 
 declare module BabylonViewer {
 declare module BabylonViewer {
@@ -2110,49 +2142,51 @@ declare module BabylonViewer {
     
     
     
     
     export interface ISceneConfiguration {
     export interface ISceneConfiguration {
-        debug?: boolean;
-        clearColor?: {
-            r: number;
-            g: number;
-            b: number;
-            a: number;
-        };
-        mainColor?: {
-            r?: number;
-            g?: number;
-            b?: number;
-        };
-        imageProcessingConfiguration?: IImageProcessingConfiguration;
-        environmentTexture?: string;
-        colorGrading?: IColorGradingConfiguration;
-        environmentRotationY?: number;
-        /**
-          * Deprecated, please use default rendering pipeline
-          */
-        glow?: boolean | BABYLON.IGlowLayerOptions;
-        disableHdr?: boolean;
-        renderInBackground?: boolean;
-        disableCameraControl?: boolean;
-        animationPropertiesOverride?: {
-            [propName: string]: any;
-        };
-        defaultMaterial?: {
-            materialType: "standard" | "pbr";
-            [propName: string]: any;
-        };
-        flags?: {
-            shadowsEnabled?: boolean;
-            particlesEnabled?: boolean;
-            collisionsEnabled?: boolean;
-            lightsEnabled?: boolean;
-            texturesEnabled?: boolean;
-            lensFlaresEnabled?: boolean;
-            proceduralTexturesEnabled?: boolean;
-            renderTargetsEnabled?: boolean;
-            spritesEnabled?: boolean;
-            skeletonsEnabled?: boolean;
-            audioEnabled?: boolean;
-        };
+            debug?: boolean;
+            clearColor?: {
+                    r: number;
+                    g: number;
+                    b: number;
+                    a: number;
+            };
+            /** Deprecated, use environmentMap.mainColor instead. */
+            mainColor?: {
+                    r?: number;
+                    g?: number;
+                    b?: number;
+            };
+            imageProcessingConfiguration?: IImageProcessingConfiguration;
+            environmentTexture?: string;
+            colorGrading?: IColorGradingConfiguration;
+            environmentRotationY?: number;
+            /**
+                * Deprecated, please use default rendering pipeline
+                */
+            glow?: boolean | BABYLON.IGlowLayerOptions;
+            disableHdr?: boolean;
+            renderInBackground?: boolean;
+            disableCameraControl?: boolean;
+            animationPropertiesOverride?: {
+                    [propName: string]: any;
+            };
+            defaultMaterial?: {
+                    materialType: "standard" | "pbr";
+                    [propName: string]: any;
+            };
+            flags?: {
+                    shadowsEnabled?: boolean;
+                    particlesEnabled?: boolean;
+                    collisionsEnabled?: boolean;
+                    lightsEnabled?: boolean;
+                    texturesEnabled?: boolean;
+                    lensFlaresEnabled?: boolean;
+                    proceduralTexturesEnabled?: boolean;
+                    renderTargetsEnabled?: boolean;
+                    spritesEnabled?: boolean;
+                    skeletonsEnabled?: boolean;
+                    audioEnabled?: boolean;
+            };
+            assetsRootURL?: string;
     }
     }
 }
 }
 
 

파일 크기가 너무 크기때문에 변경 상태를 표시하지 않습니다.
+ 58 - 58
dist/preview release/viewer/babylon.viewer.js


파일 크기가 너무 크기때문에 변경 상태를 표시하지 않습니다.
+ 290 - 195
dist/preview release/viewer/babylon.viewer.max.js


+ 77 - 43
dist/preview release/viewer/babylon.viewer.module.d.ts

@@ -1006,6 +1006,7 @@ declare module 'babylonjs-viewer/configuration' {
 declare module 'babylonjs-viewer/configuration/configuration' {
 declare module 'babylonjs-viewer/configuration/configuration' {
     import { EngineOptions } from 'babylonjs';
     import { EngineOptions } from 'babylonjs';
     import { ICameraConfiguration, IDefaultRenderingPipelineConfiguration, IGroundConfiguration, ILightConfiguration, IModelConfiguration, IObserversConfiguration, ISceneConfiguration, ISceneOptimizerConfiguration, ISkyboxConfiguration, ITemplateConfiguration, IVRConfiguration } from 'babylonjs-viewer/configuration/interfaces';
     import { ICameraConfiguration, IDefaultRenderingPipelineConfiguration, IGroundConfiguration, ILightConfiguration, IModelConfiguration, IObserversConfiguration, ISceneConfiguration, ISceneOptimizerConfiguration, ISkyboxConfiguration, ITemplateConfiguration, IVRConfiguration } from 'babylonjs-viewer/configuration/interfaces';
+    import { IEnvironmentMapConfiguration } from 'babylonjs-viewer/configuration/interfaces/environmentMapConfiguration';
     export function getConfigurationKey(key: string, configObject: any): any;
     export function getConfigurationKey(key: string, configObject: any): any;
     export interface ViewerConfiguration {
     export interface ViewerConfiguration {
             version?: string;
             version?: string;
@@ -1054,6 +1055,7 @@ declare module 'babylonjs-viewer/configuration/configuration' {
                     minecraft?: boolean;
                     minecraft?: boolean;
                     [propName: string]: boolean | undefined;
                     [propName: string]: boolean | undefined;
             };
             };
+            environmentMap?: IEnvironmentMapConfiguration;
             vr?: IVRConfiguration;
             vr?: IVRConfiguration;
             lab?: {
             lab?: {
                     flashlight?: boolean | {
                     flashlight?: boolean | {
@@ -1072,12 +1074,14 @@ declare module 'babylonjs-viewer/configuration/configuration' {
                             };
                             };
                     };
                     };
                     hideLoadingDelay?: number;
                     hideLoadingDelay?: number;
+                    /** Deprecated */
                     assetsRootURL?: string;
                     assetsRootURL?: string;
                     environmentMainColor?: {
                     environmentMainColor?: {
                             r: number;
                             r: number;
                             g: number;
                             g: number;
                             b: number;
                             b: number;
                     };
                     };
+                    /** Deprecated */
                     environmentMap?: {
                     environmentMap?: {
                             /**
                             /**
                                 * Environment map texture path in relative to the asset folder.
                                 * Environment map texture path in relative to the asset folder.
@@ -1369,6 +1373,7 @@ declare module 'babylonjs-viewer/managers/sceneManager' {
     import { ViewerLabs } from 'babylonjs-viewer/labs/viewerLabs';
     import { ViewerLabs } from 'babylonjs-viewer/labs/viewerLabs';
     import { ObservablesManager } from 'babylonjs-viewer/managers/observablesManager';
     import { ObservablesManager } from 'babylonjs-viewer/managers/observablesManager';
     import { ConfigurationContainer } from 'babylonjs-viewer/configuration/configurationContainer';
     import { ConfigurationContainer } from 'babylonjs-viewer/configuration/configurationContainer';
+    import { IEnvironmentMapConfiguration } from 'babylonjs-viewer/configuration/interfaces/environmentMapConfiguration';
     /**
     /**
         * This interface describes the structure of the variable sent with the configuration observables of the scene manager.
         * This interface describes the structure of the variable sent with the configuration observables of the scene manager.
         * O - the type of object we are dealing with (Light, ArcRotateCamera, Scene, etc')
         * O - the type of object we are dealing with (Light, ArcRotateCamera, Scene, etc')
@@ -1514,6 +1519,7 @@ declare module 'babylonjs-viewer/managers/sceneManager' {
                 * @param modelConfiguration the configuration to use to reconfigure the models
                 * @param modelConfiguration the configuration to use to reconfigure the models
                 */
                 */
             protected _configureVR(vrConfig: IVRConfiguration): void;
             protected _configureVR(vrConfig: IVRConfiguration): void;
+            protected _configureEnvironmentMap(environmentMapConfiguration: IEnvironmentMapConfiguration): any;
             /**
             /**
                 * (Re) configure the camera. The camera will only be created once and from this point will only be reconfigured.
                 * (Re) configure the camera. The camera will only be created once and from this point will only be reconfigured.
                 * @param cameraConfig the new camera configuration
                 * @param cameraConfig the new camera configuration
@@ -1652,6 +1658,32 @@ declare module 'babylonjs-viewer/configuration/interfaces' {
     export * from 'babylonjs-viewer/configuration/interfaces/skyboxConfiguration';
     export * from 'babylonjs-viewer/configuration/interfaces/skyboxConfiguration';
     export * from 'babylonjs-viewer/configuration/interfaces/templateConfiguration';
     export * from 'babylonjs-viewer/configuration/interfaces/templateConfiguration';
     export * from 'babylonjs-viewer/configuration/interfaces/vrConfiguration';
     export * from 'babylonjs-viewer/configuration/interfaces/vrConfiguration';
+    export * from 'babylonjs-viewer/configuration/interfaces/environmentMapConfiguration';
+}
+
+declare module 'babylonjs-viewer/configuration/interfaces/environmentMapConfiguration' {
+    export interface IEnvironmentMapConfiguration {
+            /**
+                * Environment map texture path in relative to the asset folder.
+                */
+            texture: string;
+            /**
+                * Default rotation to apply to the environment map.
+                */
+            rotationY: number;
+            /**
+                * Tint level of the main color on the environment map.
+                */
+            tintLevel: number;
+            /**
+                * The environment's main color.
+                */
+            mainColor?: {
+                    r?: number;
+                    g?: number;
+                    b?: number;
+            };
+    }
 }
 }
 
 
 declare module 'babylonjs-viewer/templating/eventManager' {
 declare module 'babylonjs-viewer/templating/eventManager' {
@@ -2110,49 +2142,51 @@ declare module 'babylonjs-viewer/configuration/interfaces/sceneConfiguration' {
     import { IColorGradingConfiguration } from "babylonjs-viewer/configuration/interfaces/colorGradingConfiguration";
     import { IColorGradingConfiguration } from "babylonjs-viewer/configuration/interfaces/colorGradingConfiguration";
     import { IGlowLayerOptions } from "babylonjs";
     import { IGlowLayerOptions } from "babylonjs";
     export interface ISceneConfiguration {
     export interface ISceneConfiguration {
-        debug?: boolean;
-        clearColor?: {
-            r: number;
-            g: number;
-            b: number;
-            a: number;
-        };
-        mainColor?: {
-            r?: number;
-            g?: number;
-            b?: number;
-        };
-        imageProcessingConfiguration?: IImageProcessingConfiguration;
-        environmentTexture?: string;
-        colorGrading?: IColorGradingConfiguration;
-        environmentRotationY?: number;
-        /**
-          * Deprecated, please use default rendering pipeline
-          */
-        glow?: boolean | IGlowLayerOptions;
-        disableHdr?: boolean;
-        renderInBackground?: boolean;
-        disableCameraControl?: boolean;
-        animationPropertiesOverride?: {
-            [propName: string]: any;
-        };
-        defaultMaterial?: {
-            materialType: "standard" | "pbr";
-            [propName: string]: any;
-        };
-        flags?: {
-            shadowsEnabled?: boolean;
-            particlesEnabled?: boolean;
-            collisionsEnabled?: boolean;
-            lightsEnabled?: boolean;
-            texturesEnabled?: boolean;
-            lensFlaresEnabled?: boolean;
-            proceduralTexturesEnabled?: boolean;
-            renderTargetsEnabled?: boolean;
-            spritesEnabled?: boolean;
-            skeletonsEnabled?: boolean;
-            audioEnabled?: boolean;
-        };
+            debug?: boolean;
+            clearColor?: {
+                    r: number;
+                    g: number;
+                    b: number;
+                    a: number;
+            };
+            /** Deprecated, use environmentMap.mainColor instead. */
+            mainColor?: {
+                    r?: number;
+                    g?: number;
+                    b?: number;
+            };
+            imageProcessingConfiguration?: IImageProcessingConfiguration;
+            environmentTexture?: string;
+            colorGrading?: IColorGradingConfiguration;
+            environmentRotationY?: number;
+            /**
+                * Deprecated, please use default rendering pipeline
+                */
+            glow?: boolean | IGlowLayerOptions;
+            disableHdr?: boolean;
+            renderInBackground?: boolean;
+            disableCameraControl?: boolean;
+            animationPropertiesOverride?: {
+                    [propName: string]: any;
+            };
+            defaultMaterial?: {
+                    materialType: "standard" | "pbr";
+                    [propName: string]: any;
+            };
+            flags?: {
+                    shadowsEnabled?: boolean;
+                    particlesEnabled?: boolean;
+                    collisionsEnabled?: boolean;
+                    lightsEnabled?: boolean;
+                    texturesEnabled?: boolean;
+                    lensFlaresEnabled?: boolean;
+                    proceduralTexturesEnabled?: boolean;
+                    renderTargetsEnabled?: boolean;
+                    spritesEnabled?: boolean;
+                    skeletonsEnabled?: boolean;
+                    audioEnabled?: boolean;
+            };
+            assetsRootURL?: string;
     }
     }
 }
 }
 
 

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

@@ -7,7 +7,7 @@
 - New GUI 3D controls toolset. [Complete doc + demos](http://doc.babylonjs.com/how_to/gui3d) ([Deltakosh](https://github.com/deltakosh))
 - New GUI 3D controls toolset. [Complete doc + demos](http://doc.babylonjs.com/how_to/gui3d) ([Deltakosh](https://github.com/deltakosh))
 - Added [Environment Texture Tools](https://doc.babylonjs.com/how_to/physically_based_rendering#creating-a-compressed-environment-texture) to reduce the size of the usual .DDS file ([sebavan](http://www.github.com/sebavan))
 - Added [Environment Texture Tools](https://doc.babylonjs.com/how_to/physically_based_rendering#creating-a-compressed-environment-texture) to reduce the size of the usual .DDS file ([sebavan](http://www.github.com/sebavan))
 - New GUI control: the [Grid](http://doc.babylonjs.com/how_to/gui#grid) ([Deltakosh](https://github.com/deltakosh))
 - New GUI control: the [Grid](http://doc.babylonjs.com/how_to/gui#grid) ([Deltakosh](https://github.com/deltakosh))
-- Gizmo and GizmoManager classes used to manipulate meshes in a scene. Gizmo types include: position, rotation, scale and bounding box. [Doc](http://doc.babylonjs.com/how_to/gizmo) ([TrevorDev](https://github.com/TrevorDev))
+- Gizmo and GizmoManager classes used to manipulate meshes in a scene. Gizmo types include: position, scale, rotation and bounding box. [Doc](http://doc.babylonjs.com/how_to/gizmo) ([TrevorDev](https://github.com/TrevorDev))
 - New behaviors: PointerDragBehavior, SixDofDragBehavior and MultiPointerScaleBehavior to enable smooth drag and drop/scaling with mouse or 6dof controller on a mesh. [Doc](http://doc.babylonjs.com/how_to/meshbehavior) ([TrevorDev](https://github.com/TrevorDev))
 - New behaviors: PointerDragBehavior, SixDofDragBehavior and MultiPointerScaleBehavior to enable smooth drag and drop/scaling with mouse or 6dof controller on a mesh. [Doc](http://doc.babylonjs.com/how_to/meshbehavior) ([TrevorDev](https://github.com/TrevorDev))
 - Particle system improvements ([Deltakosh](https://github.com/deltakosh))
 - Particle system improvements ([Deltakosh](https://github.com/deltakosh))
   - Added a ParticleHelper class to create some pre-configured particle systems in a one-liner method style. [Doc](https://doc.babylonjs.com/How_To/ParticleHelper) ([Deltakosh](https://github.com/deltakosh)) / ([DevChris](https://github.com/yovanoc))
   - Added a ParticleHelper class to create some pre-configured particle systems in a one-liner method style. [Doc](https://doc.babylonjs.com/How_To/ParticleHelper) ([Deltakosh](https://github.com/deltakosh)) / ([DevChris](https://github.com/yovanoc))
@@ -24,10 +24,13 @@
   - Added support for size gradients. [Doc](https://doc.babylonjs.com/babylon101/particles#size)
   - Added support for size gradients. [Doc](https://doc.babylonjs.com/babylon101/particles#size)
   - Added support for life time gradients. [Doc](https://doc.babylonjs.com/babylon101/particles#lifetime)
   - Added support for life time gradients. [Doc](https://doc.babylonjs.com/babylon101/particles#lifetime)
   - Added support for angular speed gradients. [Doc](https://doc.babylonjs.com/babylon101/particles#rotation)
   - Added support for angular speed gradients. [Doc](https://doc.babylonjs.com/babylon101/particles#rotation)
+  - Added support for noise textures. [Doc](http://doc.babylonjs.com/babylon101/particles#noise-texture)
 - Added SceneComponent to help decoupling Scene from its components. ([sebavan](http://www.github.com/sebavan))
 - Added SceneComponent to help decoupling Scene from its components. ([sebavan](http://www.github.com/sebavan))
 - Playground can now be used with TypeScript directly!. [Demo](https://www.babylonjs-playground.com/ts.html) ([Deltakosh](https://github.com/deltakosh), [NasimiAsl](https://github.com/NasimiAsl))
 - Playground can now be used with TypeScript directly!. [Demo](https://www.babylonjs-playground.com/ts.html) ([Deltakosh](https://github.com/deltakosh), [NasimiAsl](https://github.com/NasimiAsl))
 - New GUI control: [InputPassword](https://doc.babylonjs.com/how_to/gui#inputpassword) ([theom](https://github.com/theom))
 - New GUI control: [InputPassword](https://doc.babylonjs.com/how_to/gui#inputpassword) ([theom](https://github.com/theom))
 - Added dead key support and before key add observable to InputText. [Doc](https://doc.babylonjs.com/how_to/gui#using-onbeforekeyaddobservable-for-extended-keyboard-layouts-and-input-masks)([theom](https://github.com/theom))
 - Added dead key support and before key add observable to InputText. [Doc](https://doc.babylonjs.com/how_to/gui#using-onbeforekeyaddobservable-for-extended-keyboard-layouts-and-input-masks)([theom](https://github.com/theom))
+- GUI and Inspector are now ES-Modules ([RaananW](https://github.com/RaananW))
+- Added support for noise procedural textures. [Doc](http://doc.babylonjs.com/how_to/how_to_use_procedural_textures#noise-procedural-texture) ([Deltakosh](https://github.com/deltakosh))
 
 
 ## Updates
 ## Updates
 
 
@@ -99,6 +102,7 @@
 - The default viewer has a plugin system with which new buttons can be added externally ([RaananW](https://github.com/RaananW))
 - The default viewer has a plugin system with which new buttons can be added externally ([RaananW](https://github.com/RaananW))
 - The extended configuration is now the default when not providing the "extended" parameter ([RaananW](https://github.com/RaananW))
 - The extended configuration is now the default when not providing the "extended" parameter ([RaananW](https://github.com/RaananW))
 - viewer.updateConfiguration also accepts a URL to download configuration remotely ([RaananW](https://github.com/RaananW))
 - viewer.updateConfiguration also accepts a URL to download configuration remotely ([RaananW](https://github.com/RaananW))
+- Viewer supports 3D printing on windows 10 ([RaananW](https://github.com/RaananW))
 - The viewer's environment map is using the new .env feature ([RaananW](https://github.com/RaananW))
 - The viewer's environment map is using the new .env feature ([RaananW](https://github.com/RaananW))
 
 
 ### Documentation
 ### Documentation
@@ -118,7 +122,7 @@
 - Parse geometry when load binary mesh ([SinhNQ](https://github.com/quocsinh))
 - Parse geometry when load binary mesh ([SinhNQ](https://github.com/quocsinh))
 - Removing observers during observable notify should not skip over valid observers ([TrevorDev](https://github.com/TrevorDev))
 - Removing observers during observable notify should not skip over valid observers ([TrevorDev](https://github.com/TrevorDev))
 - Initializing gamepadManager should register the gamepad update events ([TrevorDev](https://github.com/TrevorDev))
 - Initializing gamepadManager should register the gamepad update events ([TrevorDev](https://github.com/TrevorDev))
-- Do not generate mipmaps for HDRCubeTexture if OES_texture_float_linear isn't supported ([PeapBoy](https://github.com/NicolasBuecher))
+- Do not generate mipmaps for RawCubeTexture if OES_texture_float_linear and/or EXT_color_buffer_float extensions are not supported ([PeapBoy](https://github.com/NicolasBuecher))
 
 
 ### Core Engine
 ### Core Engine
 
 

+ 41 - 0
gui/package.json

@@ -0,0 +1,41 @@
+{
+    "name": "babylonjs-gui",
+    "version": "1.0.0",
+    "description": "The js GUI library is an extension you can use to generate interactive user interface.\r It is build on top of the DynamicTexture.",
+    "scripts": {
+        "start:server": "webpack-dev-server",
+        "start:watch": "webpack -w",
+        "build:dev": "webpack",
+        "build:prod": "webpack --mode=production",
+        "test": "echo \"Error: no test specified\" && exit 1"
+    },
+    "repository": {
+        "type": "git",
+        "url": "git+https://github.com/BabylonJS/Babylon.js.git"
+    },
+    "keywords": [
+        "3d",
+        "webgl",
+        "viewer"
+    ],
+    "license": "Apache2",
+    "bugs": {
+        "url": "https://github.com/BabylonJS/Babylon.js/issues"
+    },
+    "homepage": "https://github.com/BabylonJS/Babylon.js#readme",
+    "devDependencies": {
+        "@types/node": "^10.5.2",
+        "clean-webpack-plugin": "^0.1.19",
+        "ts-loader": "^4.0.0",
+        "typescript": "^2.9.2",
+        "webpack": "^4.16.0",
+        "webpack-cli": "^3.0.8",
+        "webpack-dev-server": "^3.1.4"
+    },
+    "peerDependencies": {
+        "babylonjs": ">3.2.0"
+    },
+    "dependencies": {
+        "dts-bundle-webpack": "^1.0.0"
+    }
+}

+ 3 - 3
gui/readme.md

@@ -1,6 +1,6 @@
-# Babylon.js GUI library
-The Babylon.js GUI library is an extension you can use to generate interactive user interface.
+# js GUI library
+The js GUI library is an extension you can use to generate interactive user interface.
 It is build on top of the DynamicTexture.
 It is build on top of the DynamicTexture.
 
 
 Documentation: http://doc.babylonjs.com/how_to/gui
 Documentation: http://doc.babylonjs.com/how_to/gui
-API: http://doc.babylonjs.com/api/modules/babylon.gui
+API: http://doc.babylonjs.com/api/modules/gui

파일 크기가 너무 크기때문에 변경 상태를 표시하지 않습니다.
+ 587 - 589
gui/src/2D/advancedDynamicTexture.ts


+ 182 - 180
gui/src/2D/controls/button.ts

@@ -1,207 +1,209 @@
-/// <reference path="../../../../dist/preview release/babylon.d.ts"/>
+import { Rectangle } from "./rectangle";
+import { Control } from "./control";
+import { TextBlock } from "./textBlock";
+import { Image } from "./image";
+import { Vector2 } from "babylonjs";
+
+/**
+ * Class used to create 2D buttons
+ */
+export class Button extends Rectangle {
+    /**
+     * Function called to generate a pointer enter animation
+     */
+    public pointerEnterAnimation: () => void;
+    /**
+     * Function called to generate a pointer out animation
+     */
+    public pointerOutAnimation: () => void;
+    /**
+     * Function called to generate a pointer down animation
+     */
+    public pointerDownAnimation: () => void;
+    /**
+     * Function called to generate a pointer up animation
+     */
+    public pointerUpAnimation: () => void;
 
 
-module BABYLON.GUI {
     /**
     /**
-     * Class used to create 2D buttons
+     * Creates a new Button
+     * @param name defines the name of the button
      */
      */
-    export class Button extends Rectangle {    
-        /**
-         * Function called to generate a pointer enter animation
-         */
-        public pointerEnterAnimation: () => void;
-        /**
-         * Function called to generate a pointer out animation
-         */        
-        public pointerOutAnimation: () => void;
-        /**
-         * Function called to generate a pointer down animation
-         */        
-        public pointerDownAnimation: () => void;
-        /**
-         * Function called to generate a pointer up animation
-         */        
-        public pointerUpAnimation: () => void;
-
-        /**
-         * Creates a new Button
-         * @param name defines the name of the button
-         */
-        constructor(public name?: string) {
-            super(name);
-          
-            this.thickness = 1;
-            this.isPointerBlocker = true;
-
-            this.pointerEnterAnimation = () => {
-                this.alpha -= 0.1;
-            }
-
-            this.pointerOutAnimation = () => {
-                this.alpha += 0.1;
-            }    
-
-            this.pointerDownAnimation = () => {
-                this.scaleX -= 0.05;
-                this.scaleY -= 0.05;
-            }
-
-            this.pointerUpAnimation = () => {
-                this.scaleX += 0.05;
-                this.scaleY += 0.05;
-            }                      
+    constructor(public name?: string) {
+        super(name);
+
+        this.thickness = 1;
+        this.isPointerBlocker = true;
+
+        this.pointerEnterAnimation = () => {
+            this.alpha -= 0.1;
         }
         }
 
 
-        protected _getTypeName(): string {
-            return "Button";
+        this.pointerOutAnimation = () => {
+            this.alpha += 0.1;
         }
         }
 
 
-        // While being a container, the button behaves like a control.
-        /** @hidden */
-        public _processPicking(x: number, y: number, type: number, pointerId:number, buttonIndex: number): boolean {
-            if (!this.isHitTestVisible || !this.isVisible || this.notRenderable) {
-                return false;
-            }
+        this.pointerDownAnimation = () => {
+            this.scaleX -= 0.05;
+            this.scaleY -= 0.05;
+        }
 
 
-            if (!super.contains(x, y)) {
-                return false;
-            }
+        this.pointerUpAnimation = () => {
+            this.scaleX += 0.05;
+            this.scaleY += 0.05;
+        }
+    }
 
 
-            this._processObservables(type, x, y, pointerId, buttonIndex);
+    protected _getTypeName(): string {
+        return "Button";
+    }
 
 
-            return true;
+    // While being a container, the button behaves like a control.
+    /** @hidden */
+    public _processPicking(x: number, y: number, type: number, pointerId: number, buttonIndex: number): boolean {
+        if (!this.isHitTestVisible || !this.isVisible || this.notRenderable) {
+            return false;
         }
         }
 
 
-        /** @hidden */
-        public _onPointerEnter(target: Control): boolean {
-            if (!super._onPointerEnter(target)) {
-                return false;
-            }
+        if (!super.contains(x, y)) {
+            return false;
+        }
 
 
-            if (this.pointerEnterAnimation) {
-                this.pointerEnterAnimation();
-            }
+        this._processObservables(type, x, y, pointerId, buttonIndex);
 
 
-            return true;
-        }
+        return true;
+    }
 
 
-        /** @hidden */
-        public _onPointerOut(target: Control): void {
-            if (this.pointerOutAnimation) {
-                this.pointerOutAnimation();
-            }
+    /** @hidden */
+    public _onPointerEnter(target: Control): boolean {
+        if (!super._onPointerEnter(target)) {
+            return false;
+        }
 
 
-            super._onPointerOut(target);
+        if (this.pointerEnterAnimation) {
+            this.pointerEnterAnimation();
         }
         }
 
 
-        /** @hidden */
-        public _onPointerDown(target: Control, coordinates: Vector2, pointerId:number, buttonIndex: number): boolean {
-            if (!super._onPointerDown(target, coordinates, pointerId, buttonIndex)) {
-                return false;
-            }
+        return true;
+    }
 
 
+    /** @hidden */
+    public _onPointerOut(target: Control): void {
+        if (this.pointerOutAnimation) {
+            this.pointerOutAnimation();
+        }
 
 
-            if (this.pointerDownAnimation) {
-                this.pointerDownAnimation();
-            }
+        super._onPointerOut(target);
+    }
 
 
-            return true;
+    /** @hidden */
+    public _onPointerDown(target: Control, coordinates: Vector2, pointerId: number, buttonIndex: number): boolean {
+        if (!super._onPointerDown(target, coordinates, pointerId, buttonIndex)) {
+            return false;
         }
         }
 
 
-        /** @hidden */
-        public _onPointerUp(target: Control, coordinates: Vector2, pointerId:number, buttonIndex: number, notifyClick: boolean): void {
-            if (this.pointerUpAnimation) {
-                this.pointerUpAnimation();
-            }
-
-            super._onPointerUp(target, coordinates, pointerId, buttonIndex, notifyClick);
-        }        
-
-        // Statics
-        /**
-         * Creates a new button made with an image and a text
-         * @param name defines the name of the button
-         * @param text defines the text of the button
-         * @param imageUrl defines the url of the image
-         * @returns a new Button
-         */
-        public static CreateImageButton(name: string, text: string, imageUrl: string): Button {
-            var result = new Button(name);
-
-            // Adding text
-            var textBlock = new BABYLON.GUI.TextBlock(name + "_button", text);
-            textBlock.textWrapping = true;
-            textBlock.textHorizontalAlignment = BABYLON.GUI.Control.HORIZONTAL_ALIGNMENT_CENTER;
-            textBlock.paddingLeft = "20%";
-            result.addControl(textBlock);   
-
-            // Adding image
-            var iconImage = new BABYLON.GUI.Image(name + "_icon", imageUrl);
-            iconImage.width = "20%";
-            iconImage.stretch = BABYLON.GUI.Image.STRETCH_UNIFORM;
-            iconImage.horizontalAlignment = BABYLON.GUI.Control.HORIZONTAL_ALIGNMENT_LEFT;
-            result.addControl(iconImage);            
-
-            return result;
-        }
 
 
-        /**
-         * Creates a new button made with an image
-         * @param name defines the name of the button
-         * @param imageUrl defines the url of the image
-         * @returns a new Button
-         */
-        public static CreateImageOnlyButton(name: string, imageUrl: string): Button {
-            var result = new Button(name);
-
-            // Adding image
-            var iconImage = new BABYLON.GUI.Image(name + "_icon", imageUrl);
-            iconImage.stretch = BABYLON.GUI.Image.STRETCH_FILL;
-            iconImage.horizontalAlignment = BABYLON.GUI.Control.HORIZONTAL_ALIGNMENT_LEFT;
-            result.addControl(iconImage);            
-
-            return result;
+        if (this.pointerDownAnimation) {
+            this.pointerDownAnimation();
         }
         }
 
 
-        /**
-         * Creates a new button made with a text
-         * @param name defines the name of the button
-         * @param text defines the text of the button
-         * @returns a new Button
-         */        
-        public static CreateSimpleButton(name: string, text: string): Button {
-            var result = new Button(name);
-
-            // Adding text
-            var textBlock = new BABYLON.GUI.TextBlock(name + "_button", text);
-            textBlock.textWrapping = true;
-            textBlock.textHorizontalAlignment = BABYLON.GUI.Control.HORIZONTAL_ALIGNMENT_CENTER;
-            result.addControl(textBlock);           
-
-            return result;
-        }
-        
-        /**
-         * Creates a new button made with an image and a centered text
-         * @param name defines the name of the button
-         * @param text defines the text of the button
-         * @param imageUrl defines the url of the image
-         * @returns a new Button
-         */        
-        public static CreateImageWithCenterTextButton(name: string, text: string, imageUrl: string): Button {
-            var result = new Button(name);
-
-            // Adding image
-            var iconImage = new BABYLON.GUI.Image(name + "_icon", imageUrl);
-            iconImage.stretch = BABYLON.GUI.Image.STRETCH_FILL;
-            result.addControl(iconImage);         
-            
-            // Adding text
-            var textBlock = new BABYLON.GUI.TextBlock(name + "_button", text);
-            textBlock.textWrapping = true;
-            textBlock.textHorizontalAlignment = BABYLON.GUI.Control.HORIZONTAL_ALIGNMENT_CENTER;
-            result.addControl(textBlock);   
-
-            return result;
+        return true;
+    }
+
+    /** @hidden */
+    public _onPointerUp(target: Control, coordinates: Vector2, pointerId: number, buttonIndex: number, notifyClick: boolean): void {
+        if (this.pointerUpAnimation) {
+            this.pointerUpAnimation();
         }
         }
-    }    
-}
+
+        super._onPointerUp(target, coordinates, pointerId, buttonIndex, notifyClick);
+    }
+
+    // Statics
+    /**
+     * Creates a new button made with an image and a text
+     * @param name defines the name of the button
+     * @param text defines the text of the button
+     * @param imageUrl defines the url of the image
+     * @returns a new Button
+     */
+    public static CreateImageButton(name: string, text: string, imageUrl: string): Button {
+        var result = new Button(name);
+
+        // Adding text
+        var textBlock = new TextBlock(name + "_button", text);
+        textBlock.textWrapping = true;
+        textBlock.textHorizontalAlignment = Control.HORIZONTAL_ALIGNMENT_CENTER;
+        textBlock.paddingLeft = "20%";
+        result.addControl(textBlock);
+
+        // Adding image
+        var iconImage = new Image(name + "_icon", imageUrl);
+        iconImage.width = "20%";
+        iconImage.stretch = Image.STRETCH_UNIFORM;
+        iconImage.horizontalAlignment = Control.HORIZONTAL_ALIGNMENT_LEFT;
+        result.addControl(iconImage);
+
+        return result;
+    }
+
+    /**
+     * Creates a new button made with an image
+     * @param name defines the name of the button
+     * @param imageUrl defines the url of the image
+     * @returns a new Button
+     */
+    public static CreateImageOnlyButton(name: string, imageUrl: string): Button {
+        var result = new Button(name);
+
+        // Adding image
+        var iconImage = new Image(name + "_icon", imageUrl);
+        iconImage.stretch = Image.STRETCH_FILL;
+        iconImage.horizontalAlignment = Control.HORIZONTAL_ALIGNMENT_LEFT;
+        result.addControl(iconImage);
+
+        return result;
+    }
+
+    /**
+     * Creates a new button made with a text
+     * @param name defines the name of the button
+     * @param text defines the text of the button
+     * @returns a new Button
+     */
+    public static CreateSimpleButton(name: string, text: string): Button {
+        var result = new Button(name);
+
+        // Adding text
+        var textBlock = new TextBlock(name + "_button", text);
+        textBlock.textWrapping = true;
+        textBlock.textHorizontalAlignment = Control.HORIZONTAL_ALIGNMENT_CENTER;
+        result.addControl(textBlock);
+
+        return result;
+    }
+
+    /**
+     * Creates a new button made with an image and a centered text
+     * @param name defines the name of the button
+     * @param text defines the text of the button
+     * @param imageUrl defines the url of the image
+     * @returns a new Button
+     */
+    public static CreateImageWithCenterTextButton(name: string, text: string, imageUrl: string): Button {
+        var result = new Button(name);
+
+        // Adding image
+        var iconImage = new Image(name + "_icon", imageUrl);
+        iconImage.stretch = Image.STRETCH_FILL;
+        result.addControl(iconImage);
+
+        // Adding text
+        var textBlock = new TextBlock(name + "_button", text);
+        textBlock.textWrapping = true;
+        textBlock.textHorizontalAlignment = Control.HORIZONTAL_ALIGNMENT_CENTER;
+        result.addControl(textBlock);
+
+        return result;
+    }
+}    

+ 118 - 118
gui/src/2D/controls/checkbox.ts

@@ -1,145 +1,145 @@
-/// <reference path="../../../../dist/preview release/babylon.d.ts"/>
+import { Control } from "./control";
+import { Measure } from "../measure";
+import { Observable, Vector2 } from "babylonjs";
+
+/**
+ * Class used to represent a 2D checkbox
+ */
+export class Checkbox extends Control {
+    private _isChecked = false;
+    private _background = "black";
+    private _checkSizeRatio = 0.8;
+    private _thickness = 1;
+
+    /** Gets or sets border thickness  */
+    public get thickness(): number {
+        return this._thickness;
+    }
+
+    public set thickness(value: number) {
+        if (this._thickness === value) {
+            return;
+        }
+
+        this._thickness = value;
+        this._markAsDirty();
+    }
 
 
-module BABYLON.GUI {
     /**
     /**
-     * Class used to represent a 2D checkbox
+     * Observable raised when isChecked property changes
      */
      */
-    export class Checkbox extends Control {
-        private _isChecked = false;
-        private _background = "black";   
-        private _checkSizeRatio = 0.8;
-        private _thickness = 1;
-        
-        /** Gets or sets border thickness  */
-        public get thickness(): number {
-            return this._thickness;
-        }
-
-        public set thickness(value: number) {
-            if (this._thickness === value) {
-                return;
-            }
+    public onIsCheckedChangedObservable = new Observable<boolean>();
 
 
-            this._thickness = value;
-            this._markAsDirty();
-        }           
+    /** Gets or sets a value indicating the ratio between overall size and check size */
+    public get checkSizeRatio(): number {
+        return this._checkSizeRatio;
+    }
 
 
-        /**
-         * Observable raised when isChecked property changes
-         */
-        public onIsCheckedChangedObservable = new Observable<boolean>();
+    public set checkSizeRatio(value: number) {
+        value = Math.max(Math.min(1, value), 0);
 
 
-        /** Gets or sets a value indicating the ratio between overall size and check size */
-        public get checkSizeRatio(): number {
-            return this._checkSizeRatio;
+        if (this._checkSizeRatio === value) {
+            return;
         }
         }
 
 
-        public set checkSizeRatio(value: number) {
-            value = Math.max(Math.min(1, value), 0);
+        this._checkSizeRatio = value;
+        this._markAsDirty();
+    }
 
 
-            if (this._checkSizeRatio === value) {
-                return;
-            }
-
-            this._checkSizeRatio = value;
-            this._markAsDirty();
-        }             
+    /** Gets or sets background color */
+    public get background(): string {
+        return this._background;
+    }
 
 
-        /** Gets or sets background color */
-        public get background(): string {
-            return this._background;
+    public set background(value: string) {
+        if (this._background === value) {
+            return;
         }
         }
 
 
-        public set background(value: string) {
-            if (this._background === value) {
-                return;
-            }
+        this._background = value;
+        this._markAsDirty();
+    }
 
 
-            this._background = value;
-            this._markAsDirty();
-        }     
+    /** Gets or sets a boolean indicating if the checkbox is checked or not */
+    public get isChecked(): boolean {
+        return this._isChecked;
+    }
 
 
-        /** Gets or sets a boolean indicating if the checkbox is checked or not */
-        public get isChecked(): boolean {
-            return this._isChecked;
+    public set isChecked(value: boolean) {
+        if (this._isChecked === value) {
+            return;
         }
         }
 
 
-        public set isChecked(value: boolean) {
-            if (this._isChecked === value) {
-                return;
-            }
+        this._isChecked = value;
+        this._markAsDirty();
 
 
-            this._isChecked = value;
-            this._markAsDirty();
+        this.onIsCheckedChangedObservable.notifyObservers(value);
+    }
 
 
-            this.onIsCheckedChangedObservable.notifyObservers(value);
-        }                             
+    /**
+     * Creates a new CheckBox
+     * @param name defines the control name
+     */
+    constructor(public name?: string) {
+        super(name);
+        this.isPointerBlocker = true;
+    }
+
+    protected _getTypeName(): string {
+        return "CheckBox";
+    }
+
+    /** @hidden */
+    public _draw(parentMeasure: Measure, context: CanvasRenderingContext2D): void {
+        context.save();
+
+        this._applyStates(context);
+        if (this._processMeasures(parentMeasure, context)) {
+            let actualWidth = this._currentMeasure.width - this._thickness;
+            let actualHeight = this._currentMeasure.height - this._thickness;
+
+            if (this.shadowBlur || this.shadowOffsetX || this.shadowOffsetY) {
+                context.shadowColor = this.shadowColor;
+                context.shadowBlur = this.shadowBlur;
+                context.shadowOffsetX = this.shadowOffsetX;
+                context.shadowOffsetY = this.shadowOffsetY;
+            }
 
 
-        /**
-         * Creates a new CheckBox
-         * @param name defines the control name
-         */
-        constructor(public name?: string) {
-            super(name);
-            this.isPointerBlocker = true;
-        }
+            context.fillStyle = this._background;
+            context.fillRect(this._currentMeasure.left + this._thickness / 2, this._currentMeasure.top + this._thickness / 2, actualWidth, actualHeight);
 
 
-        protected _getTypeName(): string {
-            return "CheckBox";
-        }
-        
-        /** @hidden */
-        public _draw(parentMeasure: Measure, context: CanvasRenderingContext2D): void {
-            context.save();
-
-            this._applyStates(context);
-            if (this._processMeasures(parentMeasure, context)) {
-                let actualWidth = this._currentMeasure.width - this._thickness;
-                let actualHeight = this._currentMeasure.height - this._thickness;
-
-                if(this.shadowBlur || this.shadowOffsetX || this.shadowOffsetY){
-                    context.shadowColor = this.shadowColor;
-                    context.shadowBlur = this.shadowBlur;
-                    context.shadowOffsetX = this.shadowOffsetX;
-                    context.shadowOffsetY = this.shadowOffsetY;
-                }
-                
-                context.fillStyle = this._background;
-                context.fillRect(this._currentMeasure.left + this._thickness / 2, this._currentMeasure.top + this._thickness / 2, actualWidth, actualHeight);   
-
-                if(this.shadowBlur || this.shadowOffsetX || this.shadowOffsetY){
-                    context.shadowBlur = 0;
-                    context.shadowOffsetX = 0;
-                    context.shadowOffsetY = 0;
-                }
-
-                if (this._isChecked) {
-                    context.fillStyle = this.color;
-                    let offsetWidth = actualWidth * this._checkSizeRatio;
-                    let offseHeight = actualHeight * this._checkSizeRatio;
-
-                    context.fillRect(this._currentMeasure.left + this._thickness / 2 + (actualWidth - offsetWidth) / 2, this._currentMeasure.top + this._thickness / 2 + (actualHeight - offseHeight) / 2, offsetWidth, offseHeight);
-                }
-
-                context.strokeStyle = this.color;
-                context.lineWidth = this._thickness;
-
-                context.strokeRect(this._currentMeasure.left + this._thickness / 2, this._currentMeasure.top + this._thickness / 2, actualWidth, actualHeight);                       
+            if (this.shadowBlur || this.shadowOffsetX || this.shadowOffsetY) {
+                context.shadowBlur = 0;
+                context.shadowOffsetX = 0;
+                context.shadowOffsetY = 0;
             }
             }
-            context.restore();
-        }
 
 
-        // Events
+            if (this._isChecked) {
+                context.fillStyle = this.color;
+                let offsetWidth = actualWidth * this._checkSizeRatio;
+                let offseHeight = actualHeight * this._checkSizeRatio;
 
 
-        /** @hidden */
-        public _onPointerDown(target: Control, coordinates: Vector2, pointerId:number, buttonIndex: number): boolean {
-            if (!super._onPointerDown(target, coordinates, pointerId, buttonIndex)) {
-                return false;
+                context.fillRect(this._currentMeasure.left + this._thickness / 2 + (actualWidth - offsetWidth) / 2, this._currentMeasure.top + this._thickness / 2 + (actualHeight - offseHeight) / 2, offsetWidth, offseHeight);
             }
             }
 
 
-            this.isChecked = !this.isChecked;
+            context.strokeStyle = this.color;
+            context.lineWidth = this._thickness;
 
 
-            return true;
+            context.strokeRect(this._currentMeasure.left + this._thickness / 2, this._currentMeasure.top + this._thickness / 2, actualWidth, actualHeight);
         }
         }
-    }    
-}
+        context.restore();
+    }
+
+    // Events
+
+    /** @hidden */
+    public _onPointerDown(target: Control, coordinates: Vector2, pointerId: number, buttonIndex: number): boolean {
+        if (!super._onPointerDown(target, coordinates, pointerId, buttonIndex)) {
+            return false;
+        }
+
+        this.isChecked = !this.isChecked;
+
+        return true;
+    }
+}   

+ 354 - 356
gui/src/2D/controls/colorpicker.ts

@@ -1,430 +1,428 @@
-/// <reference path="../../../../dist/preview release/babylon.d.ts"/>
-
-module BABYLON.GUI {
-    /** Class used to create color pickers */
-    export class ColorPicker extends Control {
-        private _colorWheelCanvas: HTMLCanvasElement;
-        
-        private _value: Color3 = Color3.Red();
-        private _tmpColor = new Color3();
-
-        private _pointerStartedOnSquare = false;
-        private _pointerStartedOnWheel = false;
-        
-        private _squareLeft = 0;
-        private _squareTop = 0;
-        private _squareSize = 0;
-
-        private _h = 360;
-        private _s = 1;
-        private _v = 1;
-        
-        /**
-         * Observable raised when the value changes
-         */
-        public onValueChangedObservable = new Observable<Color3>();
-
-        /** Gets or sets the color of the color picker */
-        public get value(): Color3 {
-            return this._value;
-        }
+import { Control } from "./control";
+import { Color3, Observable, Vector2 } from "babylonjs";
+import { Measure } from "../measure";
 
 
-        public set value(value: Color3) {
-            if (this._value.equals(value)) {
-                return;
-            }
+/** Class used to create color pickers */
+export class ColorPicker extends Control {
+    private _colorWheelCanvas: HTMLCanvasElement;
 
 
-            this._value.copyFrom(value);
+    private _value: Color3 = Color3.Red();
+    private _tmpColor = new Color3();
 
 
-            this._RGBtoHSV(this._value, this._tmpColor);
-            
-            this._h = this._tmpColor.r;
-            this._s = Math.max(this._tmpColor.g, 0.00001);
-            this._v = Math.max(this._tmpColor.b, 0.00001);
+    private _pointerStartedOnSquare = false;
+    private _pointerStartedOnWheel = false;
 
 
-            this._markAsDirty();
+    private _squareLeft = 0;
+    private _squareTop = 0;
+    private _squareSize = 0;
 
 
-            this.onValueChangedObservable.notifyObservers(this._value);
-        }
+    private _h = 360;
+    private _s = 1;
+    private _v = 1;
 
 
-        /** Gets or sets control width */
-        public set width(value: string | number ) {
-            if (this._width.toString(this._host) === value) {
-                return;
-            }
+    /**
+     * Observable raised when the value changes
+     */
+    public onValueChangedObservable = new Observable<Color3>();
 
 
-            if (this._width.fromString(value)) {
-                this._height.fromString(value);
-                this._markAsDirty();
-            }
+    /** Gets or sets the color of the color picker */
+    public get value(): Color3 {
+        return this._value;
+    }
+
+    public set value(value: Color3) {
+        if (this._value.equals(value)) {
+            return;
         }
         }
 
 
-        /** Gets or sets control height */
-        public set height(value: string | number ) {
-            if (this._height.toString(this._host) === value) {
-                return;
-            }
+        this._value.copyFrom(value);
 
 
-            if (this._height.fromString(value)) {
-                this._width.fromString(value);
-                this._markAsDirty();
-            }
-        }
+        this._RGBtoHSV(this._value, this._tmpColor);
 
 
-        /** Gets or sets control size */
-        public get size(): string | number {
-            return this.width;
-        }
+        this._h = this._tmpColor.r;
+        this._s = Math.max(this._tmpColor.g, 0.00001);
+        this._v = Math.max(this._tmpColor.b, 0.00001);
+
+        this._markAsDirty();
+
+        this.onValueChangedObservable.notifyObservers(this._value);
+    }
 
 
-        public set size(value: string | number){
-            this.width = value;
-        }              
-
-        /**
-         * Creates a new ColorPicker
-         * @param name defines the control name
-         */
-        constructor(public name?: string) {
-            super(name);
-            this.value = new BABYLON.Color3(.88, .1, .1);
-            this.size = "200px";
-            this.isPointerBlocker = true;
+    /** Gets or sets control width */
+    public set width(value: string | number) {
+        if (this._width.toString(this._host) === value) {
+            return;
         }
         }
 
 
-        protected _getTypeName(): string {
-            return "ColorPicker";
-        }        
+        if (this._width.fromString(value)) {
+            this._height.fromString(value);
+            this._markAsDirty();
+        }
+    }
 
 
-        private _updateSquareProps():void {
-            var radius = Math.min(this._currentMeasure.width, this._currentMeasure.height)*.5;
-            var wheelThickness = radius*.2;
-            var innerDiameter = (radius-wheelThickness)*2;
-            var squareSize = innerDiameter/(Math.sqrt(2));
-            var offset = radius - squareSize*.5;
+    /** Gets or sets control height */
+    public set height(value: string | number) {
+        if (this._height.toString(this._host) === value) {
+            return;
+        }
 
 
-            this._squareLeft = this._currentMeasure.left + offset;
-            this._squareTop = this._currentMeasure.top + offset;
-            this._squareSize = squareSize;
+        if (this._height.fromString(value)) {
+            this._width.fromString(value);
+            this._markAsDirty();
         }
         }
+    }
+
+    /** Gets or sets control size */
+    public get size(): string | number {
+        return this.width;
+    }
+
+    public set size(value: string | number) {
+        this.width = value;
+    }
+
+    /**
+     * Creates a new ColorPicker
+     * @param name defines the control name
+     */
+    constructor(public name?: string) {
+        super(name);
+        this.value = new Color3(.88, .1, .1);
+        this.size = "200px";
+        this.isPointerBlocker = true;
+    }
+
+    protected _getTypeName(): string {
+        return "ColorPicker";
+    }
+
+    private _updateSquareProps(): void {
+        var radius = Math.min(this._currentMeasure.width, this._currentMeasure.height) * .5;
+        var wheelThickness = radius * .2;
+        var innerDiameter = (radius - wheelThickness) * 2;
+        var squareSize = innerDiameter / (Math.sqrt(2));
+        var offset = radius - squareSize * .5;
+
+        this._squareLeft = this._currentMeasure.left + offset;
+        this._squareTop = this._currentMeasure.top + offset;
+        this._squareSize = squareSize;
+    }
+
+    private _drawGradientSquare(hueValue: number, left: number, top: number, width: number, height: number, context: CanvasRenderingContext2D) {
+        var lgh = context.createLinearGradient(left, top, width + left, top);
+        lgh.addColorStop(0, '#fff');
+        lgh.addColorStop(1, 'hsl(' + hueValue + ', 100%, 50%)');
+
+        context.fillStyle = lgh;
+        context.fillRect(left, top, width, height);
+
+        var lgv = context.createLinearGradient(left, top, left, height + top);
+        lgv.addColorStop(0, 'rgba(0,0,0,0)');
+        lgv.addColorStop(1, '#000');
+
+        context.fillStyle = lgv;
+        context.fillRect(left, top, width, height);
+    }
+
+    private _drawCircle(centerX: number, centerY: number, radius: number, context: CanvasRenderingContext2D) {
+        context.beginPath();
+        context.arc(centerX, centerY, radius + 1, 0, 2 * Math.PI, false);
+        context.lineWidth = 3;
+        context.strokeStyle = '#333333';
+        context.stroke();
+        context.beginPath();
+        context.arc(centerX, centerY, radius, 0, 2 * Math.PI, false);
+        context.lineWidth = 3;
+        context.strokeStyle = '#ffffff';
+        context.stroke();
+    }
+
+    private _createColorWheelCanvas(radius: number, thickness: number): HTMLCanvasElement {
+        var canvas = document.createElement("canvas");
+        canvas.width = radius * 2;
+        canvas.height = radius * 2;
+        var context = <CanvasRenderingContext2D>canvas.getContext("2d");
+        var image = context.getImageData(0, 0, radius * 2, radius * 2);
+        var data = image.data;
+
+        var color = this._tmpColor;
+        var maxDistSq = radius * radius;
+        var innerRadius = radius - thickness;
+        var minDistSq = innerRadius * innerRadius;
+
+        for (var x = -radius; x < radius; x++) {
+            for (var y = -radius; y < radius; y++) {
+
+                var distSq = x * x + y * y;
+
+                if (distSq > maxDistSq || distSq < minDistSq) {
+                    continue;
+                }
 
 
-        private _drawGradientSquare(hueValue:number, left:number, top:number, width:number, height:number, context: CanvasRenderingContext2D) {
-            var lgh = context.createLinearGradient(left, top, width+left, top);
-            lgh.addColorStop(0, '#fff');
-            lgh.addColorStop(1,  'hsl(' + hueValue + ', 100%, 50%)');
+                var dist = Math.sqrt(distSq);
+                var ang = Math.atan2(y, x);
 
 
-            context.fillStyle = lgh;
-            context.fillRect(left, top,  width, height);
+                this._HSVtoRGB(ang * 180 / Math.PI + 180, dist / radius, 1, color);
 
 
-            var lgv = context.createLinearGradient(left, top, left, height+top);
-            lgv.addColorStop(0, 'rgba(0,0,0,0)');
-            lgv.addColorStop(1,  '#000');
+                var index = ((x + radius) + ((y + radius) * 2 * radius)) * 4;
 
 
-            context.fillStyle = lgv;
-            context.fillRect(left, top, width, height);
-        }
+                data[index] = color.r * 255;
+                data[index + 1] = color.g * 255;
+                data[index + 2] = color.b * 255;
+                var alphaRatio = (dist - innerRadius) / (radius - innerRadius);
 
 
-        private _drawCircle(centerX:number, centerY:number, radius:number, context: CanvasRenderingContext2D) {
-            context.beginPath();
-            context.arc(centerX, centerY, radius+1, 0, 2 * Math.PI, false);
-            context.lineWidth = 3;
-            context.strokeStyle = '#333333';
-            context.stroke();
-            context.beginPath();
-            context.arc(centerX, centerY, radius, 0, 2 * Math.PI, false);
-            context.lineWidth = 3;
-            context.strokeStyle = '#ffffff';
-            context.stroke();
-        }
+                //apply less alpha to bigger color pickers
+                var alphaAmount = .2;
+                var maxAlpha = .2;
+                var minAlpha = .04;
+                var lowerRadius = 50;
+                var upperRadius = 150;
+
+                if (radius < lowerRadius) {
+                    alphaAmount = maxAlpha;
+                } else if (radius > upperRadius) {
+                    alphaAmount = minAlpha;
+                } else {
+                    alphaAmount = (minAlpha - maxAlpha) * (radius - lowerRadius) / (upperRadius - lowerRadius) + maxAlpha;
+                }
 
 
-        private _createColorWheelCanvas(radius:number, thickness:number): HTMLCanvasElement {
-            var canvas = document.createElement("canvas");
-            canvas.width = radius * 2;
-            canvas.height = radius * 2;
-            var context = <CanvasRenderingContext2D>canvas.getContext("2d");
-            var image = context.getImageData(0, 0, radius * 2, radius * 2);
-            var data = image.data;
-            
-            var color = this._tmpColor;
-            var maxDistSq = radius*radius;
-            var innerRadius = radius - thickness;
-            var minDistSq = innerRadius*innerRadius;
-
-            for (var x = -radius; x < radius; x++) {
-                for (var y = -radius; y < radius; y++) {
-                    
-                    var distSq = x*x + y*y;
-                    
-                    if (distSq > maxDistSq || distSq < minDistSq) {
-                        continue;
-                    }
-
-                    var dist = Math.sqrt(distSq);
-                    var ang = Math.atan2(y, x);
-                    
-                    this._HSVtoRGB(ang * 180/Math.PI + 180, dist/radius, 1, color);
-                    
-                    var index = ((x + radius) + ((y + radius)*2*radius)) * 4;
-                    
-                    data[index] = color.r*255;
-                    data[index + 1] = color.g*255;
-                    data[index + 2] = color.b*255;      
-                    var alphaRatio = (dist - innerRadius) / (radius - innerRadius);
-
-                    //apply less alpha to bigger color pickers
-                    var alphaAmount = .2;
-                    var maxAlpha = .2;
-                    var minAlpha = .04;
-                    var lowerRadius = 50;
-                    var upperRadius = 150;
-
-                    if(radius < lowerRadius){
-                        alphaAmount = maxAlpha;
-                    }else if(radius > upperRadius){
-                        alphaAmount = minAlpha;
-                    }else{
-                        alphaAmount = (minAlpha - maxAlpha)*(radius - lowerRadius)/(upperRadius - lowerRadius) + maxAlpha;
-                    }
-                    
-                    var alphaRatio = (dist - innerRadius) / (radius - innerRadius);
-
-                    if (alphaRatio < alphaAmount) {
-                        data[index + 3] = 255 * (alphaRatio / alphaAmount);
-                    } else if (alphaRatio > 1 - alphaAmount) {
-                        data[index + 3] = 255 * (1.0 - ((alphaRatio - (1 - alphaAmount)) / alphaAmount));
-                    } else {
-                        data[index + 3] = 255;
-                    }
+                var alphaRatio = (dist - innerRadius) / (radius - innerRadius);
 
 
+                if (alphaRatio < alphaAmount) {
+                    data[index + 3] = 255 * (alphaRatio / alphaAmount);
+                } else if (alphaRatio > 1 - alphaAmount) {
+                    data[index + 3] = 255 * (1.0 - ((alphaRatio - (1 - alphaAmount)) / alphaAmount));
+                } else {
+                    data[index + 3] = 255;
                 }
                 }
+
             }
             }
+        }
 
 
-            context.putImageData(image, 0, 0);
+        context.putImageData(image, 0, 0);
 
 
-            return canvas;
-        }
+        return canvas;
+    }
 
 
-        private _RGBtoHSV(color:Color3, result:Color3){
-            var r = color.r;
-            var g = color.g;
-            var b = color.b;
-
-            var max = Math.max(r, g, b);
-            var min = Math.min(r, g, b);
-            var h = 0;
-            var s = 0;
-            var v = max;
-            
-            var dm = max - min;
-            
-            if(max !== 0){
-                s = dm / max;
-            }
+    private _RGBtoHSV(color: Color3, result: Color3) {
+        var r = color.r;
+        var g = color.g;
+        var b = color.b;
+
+        var max = Math.max(r, g, b);
+        var min = Math.min(r, g, b);
+        var h = 0;
+        var s = 0;
+        var v = max;
+
+        var dm = max - min;
+
+        if (max !== 0) {
+            s = dm / max;
+        }
 
 
-            if(max != min) {
-                if(max == r){
-                    h = (g - b) / dm;
-                    if(g < b){
-                        h += 6;
-                    }
-                }else if(max == g){
-                    h = (b - r) / dm + 2;
-                }else if(max == b){
-                    h = (r - g) / dm + 4;
+        if (max != min) {
+            if (max == r) {
+                h = (g - b) / dm;
+                if (g < b) {
+                    h += 6;
                 }
                 }
-                h *= 60;
+            } else if (max == g) {
+                h = (b - r) / dm + 2;
+            } else if (max == b) {
+                h = (r - g) / dm + 4;
             }
             }
-            
-            result.r = h;
-            result.g = s;
-            result.b = v;
+            h *= 60;
         }
         }
 
 
-        private _HSVtoRGB(hue:number, saturation:number, value:number, result:Color3) {
-            var chroma = value * saturation;
-            var h = hue / 60;
-            var x = chroma * (1- Math.abs((h % 2) - 1));
-            var r = 0;
-            var g = 0;
-            var b = 0;
-
-            if (h >= 0 && h <= 1) {
-                r = chroma;
-                g = x;
-            } else if (h >= 1 && h <= 2) {
-                r = x;
-                g = chroma;
-            } else if (h >= 2 && h <= 3) {
-                g = chroma;
-                b = x;
-            } else if (h >= 3 && h <= 4) {
-                g = x;
-                b = chroma;
-            } else if (h >= 4 && h <= 5) {
-                r = x;
-                b = chroma;
-            } else if (h >= 5 && h <= 6) {
-                r = chroma;
-                b = x;
-            }
-            
-            var m = value - chroma;
-            result.set((r+m), (g+m), (b+m));            
+        result.r = h;
+        result.g = s;
+        result.b = v;
+    }
+
+    private _HSVtoRGB(hue: number, saturation: number, value: number, result: Color3) {
+        var chroma = value * saturation;
+        var h = hue / 60;
+        var x = chroma * (1 - Math.abs((h % 2) - 1));
+        var r = 0;
+        var g = 0;
+        var b = 0;
+
+        if (h >= 0 && h <= 1) {
+            r = chroma;
+            g = x;
+        } else if (h >= 1 && h <= 2) {
+            r = x;
+            g = chroma;
+        } else if (h >= 2 && h <= 3) {
+            g = chroma;
+            b = x;
+        } else if (h >= 3 && h <= 4) {
+            g = x;
+            b = chroma;
+        } else if (h >= 4 && h <= 5) {
+            r = x;
+            b = chroma;
+        } else if (h >= 5 && h <= 6) {
+            r = chroma;
+            b = x;
         }
         }
 
 
-        /** @hidden */
-        public _draw(parentMeasure: Measure, context: CanvasRenderingContext2D): void {
-            context.save();
+        var m = value - chroma;
+        result.set((r + m), (g + m), (b + m));
+    }
 
 
-            this._applyStates(context);
-            if (this._processMeasures(parentMeasure, context)) {
+    /** @hidden */
+    public _draw(parentMeasure: Measure, context: CanvasRenderingContext2D): void {
+        context.save();
 
 
-                var radius = Math.min(this._currentMeasure.width, this._currentMeasure.height)*.5;
-                var wheelThickness = radius*.2;
-                var left = this._currentMeasure.left;
-                var top = this._currentMeasure.top;
+        this._applyStates(context);
+        if (this._processMeasures(parentMeasure, context)) {
 
 
-                if(!this._colorWheelCanvas || this._colorWheelCanvas.width != radius*2){
-                    this._colorWheelCanvas = this._createColorWheelCanvas(radius, wheelThickness);
-                }
+            var radius = Math.min(this._currentMeasure.width, this._currentMeasure.height) * .5;
+            var wheelThickness = radius * .2;
+            var left = this._currentMeasure.left;
+            var top = this._currentMeasure.top;
 
 
-                this._updateSquareProps();
+            if (!this._colorWheelCanvas || this._colorWheelCanvas.width != radius * 2) {
+                this._colorWheelCanvas = this._createColorWheelCanvas(radius, wheelThickness);
+            }
 
 
-                if(this.shadowBlur || this.shadowOffsetX || this.shadowOffsetY){                
-                    context.shadowColor = this.shadowColor;
-                    context.shadowBlur = this.shadowBlur;
-                    context.shadowOffsetX = this.shadowOffsetX;
-                    context.shadowOffsetY = this.shadowOffsetY; 
-                    
-                    context.fillRect(this._squareLeft, this._squareTop, this._squareSize, this._squareSize);
-                }
+            this._updateSquareProps();
 
 
-                context.drawImage(this._colorWheelCanvas, left, top);
+            if (this.shadowBlur || this.shadowOffsetX || this.shadowOffsetY) {
+                context.shadowColor = this.shadowColor;
+                context.shadowBlur = this.shadowBlur;
+                context.shadowOffsetX = this.shadowOffsetX;
+                context.shadowOffsetY = this.shadowOffsetY;
 
 
-                if(this.shadowBlur || this.shadowOffsetX || this.shadowOffsetY){
-                    context.shadowBlur = 0;
-                    context.shadowOffsetX = 0;
-                    context.shadowOffsetY = 0;
-                }
+                context.fillRect(this._squareLeft, this._squareTop, this._squareSize, this._squareSize);
+            }
 
 
-                this._drawGradientSquare(this._h, 
-                                        this._squareLeft,
-                                        this._squareTop,
-                                        this._squareSize, 
-                                        this._squareSize,
-                                        context);
-                
-                var cx = this._squareLeft + this._squareSize*this._s;
-                var cy = this._squareTop + this._squareSize*(1 - this._v);
-                
-                this._drawCircle(cx, cy, radius*.04, context);
-
-                var dist = radius - wheelThickness*.5;
-                cx = left + radius + Math.cos((this._h-180)*Math.PI/180)*dist;
-                cy = top + radius + Math.sin((this._h-180)*Math.PI/180)*dist;
-                this._drawCircle(cx, cy, wheelThickness*.35, context);
+            context.drawImage(this._colorWheelCanvas, left, top);
 
 
+            if (this.shadowBlur || this.shadowOffsetX || this.shadowOffsetY) {
+                context.shadowBlur = 0;
+                context.shadowOffsetX = 0;
+                context.shadowOffsetY = 0;
             }
             }
-            context.restore();
-        }
 
 
-        // Events
-        private _pointerIsDown = false;
+            this._drawGradientSquare(this._h,
+                this._squareLeft,
+                this._squareTop,
+                this._squareSize,
+                this._squareSize,
+                context);
 
 
-        private _updateValueFromPointer(x: number, y:number): void {
-            if(this._pointerStartedOnWheel)
-            {
-                var radius = Math.min(this._currentMeasure.width, this._currentMeasure.height)*.5;
-                var centerX = radius + this._currentMeasure.left;
-                var centerY = radius + this._currentMeasure.top;
-                this._h = Math.atan2(y - centerY, x - centerX)*180/Math.PI + 180;
-            }
-            else if(this._pointerStartedOnSquare)
-            {
-                this._updateSquareProps();
-                this._s = (x - this._squareLeft) / this._squareSize;
-                this._v = 1 - (y - this._squareTop) / this._squareSize;
-                this._s = Math.min(this._s, 1);
-                this._s = Math.max(this._s, 0.00001);
-                this._v = Math.min(this._v, 1);
-                this._v = Math.max(this._v, 0.00001);
-            }
+            var cx = this._squareLeft + this._squareSize * this._s;
+            var cy = this._squareTop + this._squareSize * (1 - this._v);
+
+            this._drawCircle(cx, cy, radius * .04, context);
 
 
-            this._HSVtoRGB(this._h, this._s, this._v, this._tmpColor);
+            var dist = radius - wheelThickness * .5;
+            cx = left + radius + Math.cos((this._h - 180) * Math.PI / 180) * dist;
+            cy = top + radius + Math.sin((this._h - 180) * Math.PI / 180) * dist;
+            this._drawCircle(cx, cy, wheelThickness * .35, context);
 
 
-            this.value = this._tmpColor;
         }
         }
+        context.restore();
+    }
 
 
-        private _isPointOnSquare(coordinates: Vector2):boolean {
+    // Events
+    private _pointerIsDown = false;
+
+    private _updateValueFromPointer(x: number, y: number): void {
+        if (this._pointerStartedOnWheel) {
+            var radius = Math.min(this._currentMeasure.width, this._currentMeasure.height) * .5;
+            var centerX = radius + this._currentMeasure.left;
+            var centerY = radius + this._currentMeasure.top;
+            this._h = Math.atan2(y - centerY, x - centerX) * 180 / Math.PI + 180;
+        }
+        else if (this._pointerStartedOnSquare) {
             this._updateSquareProps();
             this._updateSquareProps();
+            this._s = (x - this._squareLeft) / this._squareSize;
+            this._v = 1 - (y - this._squareTop) / this._squareSize;
+            this._s = Math.min(this._s, 1);
+            this._s = Math.max(this._s, 0.00001);
+            this._v = Math.min(this._v, 1);
+            this._v = Math.max(this._v, 0.00001);
+        }
 
 
-            var left = this._squareLeft;
-            var top = this._squareTop;
-            var size = this._squareSize;
+        this._HSVtoRGB(this._h, this._s, this._v, this._tmpColor);
 
 
-            if(coordinates.x >= left && coordinates.x <= left + size &&
-               coordinates.y >= top && coordinates.y <= top + size){
-                return true;
-            }
+        this.value = this._tmpColor;
+    }
 
 
-            return false;
+    private _isPointOnSquare(coordinates: Vector2): 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) {
+            return true;
         }
         }
 
 
-        private _isPointOnWheel(coordinates: Vector2):boolean {
-            var radius = Math.min(this._currentMeasure.width, this._currentMeasure.height)*.5;
-            var centerX = radius + this._currentMeasure.left;
-            var centerY = radius + this._currentMeasure.top;
-            var wheelThickness = radius*.2;
-            var innerRadius = radius-wheelThickness;
-            var radiusSq = radius*radius;
-            var innerRadiusSq = innerRadius*innerRadius;
+        return false;
+    }
 
 
-            var dx = coordinates.x - centerX;
-            var dy = coordinates.y - centerY;
+    private _isPointOnWheel(coordinates: Vector2): boolean {
+        var radius = Math.min(this._currentMeasure.width, this._currentMeasure.height) * .5;
+        var centerX = radius + this._currentMeasure.left;
+        var centerY = radius + this._currentMeasure.top;
+        var wheelThickness = radius * .2;
+        var innerRadius = radius - wheelThickness;
+        var radiusSq = radius * radius;
+        var innerRadiusSq = innerRadius * innerRadius;
 
 
-            var distSq = dx*dx + dy*dy;
+        var dx = coordinates.x - centerX;
+        var dy = coordinates.y - centerY;
 
 
-            if(distSq <= radiusSq && distSq >= innerRadiusSq){
-                return true;
-            }
+        var distSq = dx * dx + dy * dy;
+
+        if (distSq <= radiusSq && distSq >= innerRadiusSq) {
+            return true;
+        }
 
 
+        return false;
+    }
+
+    public _onPointerDown(target: Control, coordinates: Vector2, pointerId: number, buttonIndex: number): boolean {
+        if (!super._onPointerDown(target, coordinates, pointerId, buttonIndex)) {
             return false;
             return false;
         }
         }
 
 
-        public _onPointerDown(target: Control, coordinates: Vector2, pointerId:number, buttonIndex: number): boolean {
-            if (!super._onPointerDown(target, coordinates, pointerId, buttonIndex)) {
-                return false;
-            }            
+        this._pointerIsDown = true;
 
 
-            this._pointerIsDown = true;
+        this._pointerStartedOnSquare = false;
+        this._pointerStartedOnWheel = false;
 
 
-            this._pointerStartedOnSquare = false;
-            this._pointerStartedOnWheel = false;
+        if (this._isPointOnSquare(coordinates)) {
+            this._pointerStartedOnSquare = true;
+        } else if (this._isPointOnWheel(coordinates)) {
+            this._pointerStartedOnWheel = true;
+        }
 
 
-            if(this._isPointOnSquare(coordinates)){
-                this._pointerStartedOnSquare = true;
-            }else if(this._isPointOnWheel(coordinates)){
-                this._pointerStartedOnWheel = true;
-            }
+        this._updateValueFromPointer(coordinates.x, coordinates.y);
+        this._host._capturingControl[pointerId] = this;
 
 
-            this._updateValueFromPointer(coordinates.x, coordinates.y);
-            this._host._capturingControl[pointerId] = this;
+        return true;
+    }
 
 
-            return true;
+    public _onPointerMove(target: Control, coordinates: Vector2): void {
+        if (this._pointerIsDown) {
+            this._updateValueFromPointer(coordinates.x, coordinates.y);
         }
         }
 
 
-        public _onPointerMove(target: Control, coordinates: Vector2): void {
-            if (this._pointerIsDown) {
-                this._updateValueFromPointer(coordinates.x, coordinates.y);
-            }
+        super._onPointerMove(target, coordinates);
+    }
 
 
-            super._onPointerMove(target, coordinates);
-        }
+    public _onPointerUp(target: Control, coordinates: Vector2, pointerId: number, buttonIndex: number, notifyClick: boolean): void {
+        this._pointerIsDown = false;
 
 
-        public _onPointerUp (target: Control, coordinates: Vector2, pointerId:number, buttonIndex: number, notifyClick: boolean): void {
-            this._pointerIsDown = false;
-            
-            delete this._host._capturingControl[pointerId];
-            super._onPointerUp(target, coordinates, pointerId, buttonIndex, notifyClick);
-        }     
-    }    
-}
+        delete this._host._capturingControl[pointerId];
+        super._onPointerUp(target, coordinates, pointerId, buttonIndex, notifyClick);
+    }
+}  

+ 261 - 260
gui/src/2D/controls/container.ts

@@ -1,339 +1,340 @@
-/// <reference path="../../../../dist/preview release/babylon.d.ts"/>
-
-module BABYLON.GUI {
-    /**
-     * Root class for 2D containers
-     * @see http://doc.babylonjs.com/how_to/gui#containers
-     */
-    export class Container extends Control {
-        /** @hidden */
-        protected _children = new Array<Control>();
-        /** @hidden */
-        protected _measureForChildren = Measure.Empty();  
-        /** @hidden */
-        protected _background: string;   
-        /** @hidden */
-        protected _adaptWidthToChildren = false;
-        /** @hidden */
-        protected _adaptHeightToChildren = false;
-
-        /** Gets or sets a boolean indicating if the container should try to adapt to its children height */
-        public get adaptHeightToChildren(): boolean {
-            return this._adaptHeightToChildren;
+import { Control } from "./control";
+import { Measure } from "../measure";
+import { Nullable } from "babylonjs";
+import { AdvancedDynamicTexture } from "../advancedDynamicTexture";
+
+/**
+ * Root class for 2D containers
+ * @see http://doc.babylonjs.com/how_to/gui#containers
+ */
+export class Container extends Control {
+    /** @hidden */
+    protected _children = new Array<Control>();
+    /** @hidden */
+    protected _measureForChildren = Measure.Empty();
+    /** @hidden */
+    protected _background: string;
+    /** @hidden */
+    protected _adaptWidthToChildren = false;
+    /** @hidden */
+    protected _adaptHeightToChildren = false;
+
+    /** Gets or sets a boolean indicating if the container should try to adapt to its children height */
+    public get adaptHeightToChildren(): boolean {
+        return this._adaptHeightToChildren;
+    }
+
+    public set adaptHeightToChildren(value: boolean) {
+        if (this._adaptHeightToChildren === value) {
+            return;
         }
         }
 
 
-        public set adaptHeightToChildren(value: boolean) {
-            if (this._adaptHeightToChildren === value) {
-                return;
-            }
-
-            this._adaptHeightToChildren = value;
-
-            if (value) {
-                this.height = "100%";
-            }
+        this._adaptHeightToChildren = value;
 
 
-            this._markAsDirty();
-        }       
-        
-        /** Gets or sets a boolean indicating if the container should try to adapt to its children width */
-        public get adaptWidthToChildren(): boolean {
-            return this._adaptWidthToChildren;
+        if (value) {
+            this.height = "100%";
         }
         }
 
 
-        public set adaptWidthToChildren(value: boolean) {
-            if (this._adaptWidthToChildren === value) {
-                return;
-            }
+        this._markAsDirty();
+    }
 
 
-            this._adaptWidthToChildren = value;
+    /** Gets or sets a boolean indicating if the container should try to adapt to its children width */
+    public get adaptWidthToChildren(): boolean {
+        return this._adaptWidthToChildren;
+    }
 
 
-            if (value) {
-                this.width = "100%";
-            }
+    public set adaptWidthToChildren(value: boolean) {
+        if (this._adaptWidthToChildren === value) {
+            return;
+        }
 
 
-            this._markAsDirty();
-        }           
+        this._adaptWidthToChildren = value;
 
 
-        /** Gets or sets background color */
-        public get background(): string {
-            return this._background;
+        if (value) {
+            this.width = "100%";
         }
         }
 
 
-        public set background(value: string) {
-            if (this._background === value) {
-                return;
-            }
+        this._markAsDirty();
+    }
+
+    /** Gets or sets background color */
+    public get background(): string {
+        return this._background;
+    }
 
 
-            this._background = value;
-            this._markAsDirty();
-        }  
-
-        /** Gets the list of children */
-        public get children(): Control[] {
-            return this._children;
-        }        
-
-        /**
-         * Creates a new Container
-         * @param name defines the name of the container
-         */
-        constructor(public name?: string) {
-            super(name);
+    public set background(value: string) {
+        if (this._background === value) {
+            return;
         }
         }
 
 
-        protected _getTypeName(): string {
-            return "Container";
-        }           
-
-        /**
-         * Gets a child using its name
-         * @param name defines the child name to look for
-         * @returns the child control if found
-         */
-        public getChildByName(name: string): Nullable<Control> {
-            for (var child of this.children) {
-                if (child.name === name) {
-                    return child;
-                }
-            }
+        this._background = value;
+        this._markAsDirty();
+    }
 
 
-            return null;
-        }       
-
-        /**
-         * Gets a child using its type and its name
-         * @param name defines the child name to look for
-         * @param type defines the child type to look for
-         * @returns the child control if found
-         */        
-        public getChildByType(name: string, type: string): Nullable<Control> {
-            for (var child of this.children) {
-                if (child.typeName === type) {
-                    return child;
-                }
-            }
+    /** Gets the list of children */
+    public get children(): Control[] {
+        return this._children;
+    }
 
 
-            return null;
-        }            
+    /**
+     * Creates a new Container
+     * @param name defines the name of the container
+     */
+    constructor(public name?: string) {
+        super(name);
+    }
 
 
-        /**
-         * Search for a specific control in children
-         * @param control defines the control to look for
-         * @returns true if the control is in child list
-         */
-        public containsControl(control: Control): boolean {
-            return this.children.indexOf(control) !== -1;
-        }
+    protected _getTypeName(): string {
+        return "Container";
+    }
 
 
-        /**
-         * Adds a new control to the current container
-         * @param control defines the control to add
-         * @returns the current container
-         */
-        public addControl(control: Nullable<Control>): Container {
-            if (!control) {
-                return this;
+    /**
+     * Gets a child using its name
+     * @param name defines the child name to look for
+     * @returns the child control if found
+     */
+    public getChildByName(name: string): Nullable<Control> {
+        for (var child of this.children) {
+            if (child.name === name) {
+                return child;
             }
             }
+        }
 
 
-           var index = this._children.indexOf(control);
+        return null;
+    }
 
 
-            if (index !== -1) {
-                return this;
+    /**
+     * Gets a child using its type and its name
+     * @param name defines the child name to look for
+     * @param type defines the child type to look for
+     * @returns the child control if found
+     */
+    public getChildByType(name: string, type: string): Nullable<Control> {
+        for (var child of this.children) {
+            if (child.typeName === type) {
+                return child;
             }
             }
-            control._link(this, this._host);
+        }
 
 
-            control._markAllAsDirty();
+        return null;
+    }
 
 
-            this._reOrderControl(control);
+    /**
+     * Search for a specific control in children
+     * @param control defines the control to look for
+     * @returns true if the control is in child list
+     */
+    public containsControl(control: Control): boolean {
+        return this.children.indexOf(control) !== -1;
+    }
 
 
-            this._markAsDirty();
+    /**
+     * Adds a new control to the current container
+     * @param control defines the control to add
+     * @returns the current container
+     */
+    public addControl(control: Nullable<Control>): Container {
+        if (!control) {
             return this;
             return this;
         }
         }
 
 
-        /**
-         * Removes a control from the current container
-         * @param control defines the control to remove
-         * @returns the current container
-         */        
-        public removeControl(control: Control): Container {
-            var index = this._children.indexOf(control);
+        var index = this._children.indexOf(control);
 
 
-            if (index !== -1) {
-                this._children.splice(index, 1);
+        if (index !== -1) {
+            return this;
+        }
+        control._link(this, this._host);
 
 
-                control.parent = null;
-            }
+        control._markAllAsDirty();
 
 
-            control.linkWithMesh(null);
+        this._reOrderControl(control);
 
 
-            if (this._host) {
-                this._host._cleanControlAfterRemoval(control);
-            }
+        this._markAsDirty();
+        return this;
+    }
 
 
-            this._markAsDirty();
-            return this;
+    /**
+     * Removes a control from the current container
+     * @param control defines the control to remove
+     * @returns the current container
+     */
+    public removeControl(control: Control): Container {
+        var index = this._children.indexOf(control);
+
+        if (index !== -1) {
+            this._children.splice(index, 1);
+
+            control.parent = null;
         }
         }
 
 
-        /** @hidden */
-        public _reOrderControl(control: Control): void {
-            this.removeControl(control);
+        control.linkWithMesh(null);
 
 
-            for (var index = 0; index < this._children.length; index++) {
-                if (this._children[index].zIndex > control.zIndex) {
-                    this._children.splice(index, 0, control);
-                    return;
-                }
-            }
+        if (this._host) {
+            this._host._cleanControlAfterRemoval(control);
+        }
 
 
-            this._children.push(control);
+        this._markAsDirty();
+        return this;
+    }
 
 
-            control.parent = this;
+    /** @hidden */
+    public _reOrderControl(control: Control): void {
+        this.removeControl(control);
 
 
-            this._markAsDirty();
+        for (var index = 0; index < this._children.length; index++) {
+            if (this._children[index].zIndex > control.zIndex) {
+                this._children.splice(index, 0, control);
+                return;
+            }
         }
         }
 
 
-        /** @hidden */       
-        public _markMatrixAsDirty(): void {
-            super._markMatrixAsDirty();
+        this._children.push(control);
 
 
-            for (var index = 0; index < this._children.length; index++) {
-                this._children[index]._markMatrixAsDirty();
-            }
+        control.parent = this;
+
+        this._markAsDirty();
+    }
+
+    /** @hidden */
+    public _markMatrixAsDirty(): void {
+        super._markMatrixAsDirty();
+
+        for (var index = 0; index < this._children.length; index++) {
+            this._children[index]._markMatrixAsDirty();
         }
         }
+    }
 
 
-        /** @hidden */ 
-        public _markAllAsDirty(): void {
-            super._markAllAsDirty();
+    /** @hidden */
+    public _markAllAsDirty(): void {
+        super._markAllAsDirty();
 
 
-            for (var index = 0; index < this._children.length; index++) {
-                this._children[index]._markAllAsDirty();
-            }
+        for (var index = 0; index < this._children.length; index++) {
+            this._children[index]._markAllAsDirty();
         }
         }
+    }
+
+    /** @hidden */
+    protected _localDraw(context: CanvasRenderingContext2D): void {
+        if (this._background) {
+            if (this.shadowBlur || this.shadowOffsetX || this.shadowOffsetY) {
+                context.shadowColor = this.shadowColor;
+                context.shadowBlur = this.shadowBlur;
+                context.shadowOffsetX = this.shadowOffsetX;
+                context.shadowOffsetY = this.shadowOffsetY;
+            }
 
 
-        /** @hidden */ 
-        protected _localDraw(context: CanvasRenderingContext2D): void {
-            if (this._background) {
-                if(this.shadowBlur || this.shadowOffsetX || this.shadowOffsetY){
-                    context.shadowColor = this.shadowColor;
-                    context.shadowBlur = this.shadowBlur;
-                    context.shadowOffsetX = this.shadowOffsetX;
-                    context.shadowOffsetY = this.shadowOffsetY;
-                }
-                
-                context.fillStyle = this._background;
-                context.fillRect(this._currentMeasure.left, this._currentMeasure.top, this._currentMeasure.width, this._currentMeasure.height);
-                
-                if(this.shadowBlur || this.shadowOffsetX || this.shadowOffsetY){
-                    context.shadowBlur = 0;
-                    context.shadowOffsetX = 0;
-                    context.shadowOffsetY = 0;
-                }
+            context.fillStyle = this._background;
+            context.fillRect(this._currentMeasure.left, this._currentMeasure.top, this._currentMeasure.width, this._currentMeasure.height);
+
+            if (this.shadowBlur || this.shadowOffsetX || this.shadowOffsetY) {
+                context.shadowBlur = 0;
+                context.shadowOffsetX = 0;
+                context.shadowOffsetY = 0;
             }
             }
         }
         }
+    }
 
 
-        /** @hidden */ 
-        public _link(root: Nullable<Container>, host: AdvancedDynamicTexture): void {
-            super._link(root, host);
+    /** @hidden */
+    public _link(root: Nullable<Container>, host: AdvancedDynamicTexture): void {
+        super._link(root, host);
 
 
-            for (var child of this._children) {
-                child._link(root, host);
-            }
+        for (var child of this._children) {
+            child._link(root, host);
         }
         }
+    }
 
 
-        /** @hidden */ 
-        public _draw(parentMeasure: Measure, context: CanvasRenderingContext2D): void {      
-            if (!this.isVisible || this.notRenderable) {
-                return;
-            }
-            context.save();
-           
-            this._applyStates(context);
+    /** @hidden */
+    public _draw(parentMeasure: Measure, context: CanvasRenderingContext2D): void {
+        if (!this.isVisible || this.notRenderable) {
+            return;
+        }
+        context.save();
 
 
-            if (this._processMeasures(parentMeasure, context)) {
-                this._localDraw(context);
+        this._applyStates(context);
 
 
-                this._clipForChildren(context);
+        if (this._processMeasures(parentMeasure, context)) {
+            this._localDraw(context);
 
 
-                let computedWidth = -1;
-                let computedHeight = -1;
+            this._clipForChildren(context);
 
 
-                for (var child of this._children) {
-                    if (child.isVisible && !child.notRenderable) {
-                        child._tempParentMeasure.copyFrom(this._measureForChildren);
-                        child._draw(this._measureForChildren, context);
+            let computedWidth = -1;
+            let computedHeight = -1;
 
 
-                        if (child.onAfterDrawObservable.hasObservers()) {
-                            child.onAfterDrawObservable.notifyObservers(child);
-                        }
+            for (var child of this._children) {
+                if (child.isVisible && !child.notRenderable) {
+                    child._tempParentMeasure.copyFrom(this._measureForChildren);
+                    child._draw(this._measureForChildren, context);
 
 
-                        if (this.adaptWidthToChildren && child._width.isPixel) {
-                            computedWidth = Math.max(computedWidth, child._currentMeasure.width);
-                        }
-                        if (this.adaptHeightToChildren && child._height.isPixel) {
-                            computedHeight = Math.max(computedHeight, child._currentMeasure.height);
-                        }                        
+                    if (child.onAfterDrawObservable.hasObservers()) {
+                        child.onAfterDrawObservable.notifyObservers(child);
                     }
                     }
-                }
 
 
-                if (this.adaptWidthToChildren && computedWidth >= 0) {
-                    this.width = computedWidth + "px";
+                    if (this.adaptWidthToChildren && child._width.isPixel) {
+                        computedWidth = Math.max(computedWidth, child._currentMeasure.width);
+                    }
+                    if (this.adaptHeightToChildren && child._height.isPixel) {
+                        computedHeight = Math.max(computedHeight, child._currentMeasure.height);
+                    }
                 }
                 }
-                if (this.adaptHeightToChildren && computedHeight >= 0) {
-                    this.height = computedHeight + "px";
-                }                
             }
             }
-            context.restore();
 
 
-            if (this.onAfterDrawObservable.hasObservers()) {
-                this.onAfterDrawObservable.notifyObservers(this);
+            if (this.adaptWidthToChildren && computedWidth >= 0) {
+                this.width = computedWidth + "px";
+            }
+            if (this.adaptHeightToChildren && computedHeight >= 0) {
+                this.height = computedHeight + "px";
             }
             }
         }
         }
+        context.restore();
 
 
-        /** @hidden */ 
-        public _processPicking(x: number, y: number, type: number, pointerId:number, buttonIndex: number): boolean {
-            if (!this.isVisible || this.notRenderable) {
-                return false;
-            }
+        if (this.onAfterDrawObservable.hasObservers()) {
+            this.onAfterDrawObservable.notifyObservers(this);
+        }
+    }
 
 
-            if (!super.contains(x, y)) {
-                return false;
-            }
+    /** @hidden */
+    public _processPicking(x: number, y: number, type: number, pointerId: number, buttonIndex: number): boolean {
+        if (!this.isVisible || this.notRenderable) {
+            return false;
+        }
 
 
-            // Checking backwards to pick closest first
-            for (var index = this._children.length - 1; index >= 0; index--) {
-                var child = this._children[index];
-                if (child._processPicking(x, y, type, pointerId, buttonIndex)) {
-                    return true;
-                }
-            }
+        if (!super.contains(x, y)) {
+            return false;
+        }
 
 
-            if (!this.isHitTestVisible) {
-                return false;
+        // Checking backwards to pick closest first
+        for (var index = this._children.length - 1; index >= 0; index--) {
+            var child = this._children[index];
+            if (child._processPicking(x, y, type, pointerId, buttonIndex)) {
+                return true;
             }
             }
-
-            return this._processObservables(type, x, y, pointerId, buttonIndex);
         }
         }
 
 
-        /** @hidden */ 
-        protected _clipForChildren(context: CanvasRenderingContext2D): void {
-            // DO nothing
+        if (!this.isHitTestVisible) {
+            return false;
         }
         }
 
 
-        /** @hidden */ 
-        protected _additionalProcessing(parentMeasure: Measure, context: CanvasRenderingContext2D): void {  
-            super._additionalProcessing(parentMeasure, context);
+        return this._processObservables(type, x, y, pointerId, buttonIndex);
+    }
 
 
-            this._measureForChildren.copyFrom(this._currentMeasure);
-        }
+    /** @hidden */
+    protected _clipForChildren(context: CanvasRenderingContext2D): void {
+        // DO nothing
+    }
 
 
-        /** Releases associated resources */
-        public dispose() {
-            super.dispose();
+    /** @hidden */
+    protected _additionalProcessing(parentMeasure: Measure, context: CanvasRenderingContext2D): void {
+        super._additionalProcessing(parentMeasure, context);
 
 
-            for (var control of this._children) {
-                control.dispose();
-            }
+        this._measureForChildren.copyFrom(this._currentMeasure);
+    }
+
+    /** Releases associated resources */
+    public dispose() {
+        super.dispose();
+
+        for (var control of this._children) {
+            control.dispose();
         }
         }
-    }    
-}
+    }
+}   

파일 크기가 너무 크기때문에 변경 상태를 표시하지 않습니다.
+ 1135 - 1159
gui/src/2D/controls/control.ts


+ 71 - 71
gui/src/2D/controls/ellipse.ts

@@ -1,87 +1,87 @@
-/// <reference path="../../../../dist/preview release/babylon.d.ts"/>
-
-module BABYLON.GUI {
-    /** Class used to create 2D ellipse containers */
-    export class Ellipse extends Container {
-        private _thickness = 1;       
-        
-        /** Gets or sets border thickness */
-        public get thickness(): number {
-            return this._thickness;
+import { Container } from "./container";
+import { Control } from "./control";
+import { Measure } from "../measure";
+
+/** Class used to create 2D ellipse containers */
+export class Ellipse extends Container {
+    private _thickness = 1;
+
+    /** Gets or sets border thickness */
+    public get thickness(): number {
+        return this._thickness;
+    }
+
+    public set thickness(value: number) {
+        if (this._thickness === value) {
+            return;
         }
         }
 
 
-        public set thickness(value: number) {
-            if (this._thickness === value) {
-                return;
-            }
-
-            this._thickness = value;
-            this._markAsDirty();
-        }                
-     
-        /**
-         * Creates a new Ellipse
-         * @param name defines the control name
-         */
-        constructor(public name?: string) {
-            super(name);
+        this._thickness = value;
+        this._markAsDirty();
+    }
+
+    /**
+     * Creates a new Ellipse
+     * @param name defines the control name
+     */
+    constructor(public name?: string) {
+        super(name);
+    }
+
+    protected _getTypeName(): string {
+        return "Ellipse";
+    }
+
+    protected _localDraw(context: CanvasRenderingContext2D): void {
+        context.save();
+
+        if (this.shadowBlur || this.shadowOffsetX || this.shadowOffsetY) {
+            context.shadowColor = this.shadowColor;
+            context.shadowBlur = this.shadowBlur;
+            context.shadowOffsetX = this.shadowOffsetX;
+            context.shadowOffsetY = this.shadowOffsetY;
         }
         }
 
 
-        protected _getTypeName(): string {
-            return "Ellipse";
-        }              
-
-        protected _localDraw(context: CanvasRenderingContext2D): void {
-            context.save();
+        Control.drawEllipse(this._currentMeasure.left + this._currentMeasure.width / 2, this._currentMeasure.top + this._currentMeasure.height / 2,
+            this._currentMeasure.width / 2 - this._thickness / 2, this._currentMeasure.height / 2 - this._thickness / 2, context);
 
 
-            if(this.shadowBlur || this.shadowOffsetX || this.shadowOffsetY){
-                context.shadowColor = this.shadowColor;
-                context.shadowBlur = this.shadowBlur;
-                context.shadowOffsetX = this.shadowOffsetX;
-                context.shadowOffsetY = this.shadowOffsetY;
-            }
+        if (this._background) {
+            context.fillStyle = this._background;
 
 
-            Control.drawEllipse(this._currentMeasure.left + this._currentMeasure.width / 2, this._currentMeasure.top + this._currentMeasure.height / 2, 
-                            this._currentMeasure.width / 2 - this._thickness / 2, this._currentMeasure.height / 2 - this._thickness / 2, context);
+            context.fill();
+        }
 
 
-            if (this._background) {
-                context.fillStyle = this._background;
+        if (this.shadowBlur || this.shadowOffsetX || this.shadowOffsetY) {
+            context.shadowBlur = 0;
+            context.shadowOffsetX = 0;
+            context.shadowOffsetY = 0;
+        }
 
 
-                context.fill();
+        if (this._thickness) {
+            if (this.color) {
+                context.strokeStyle = this.color;
             }
             }
+            context.lineWidth = this._thickness;
 
 
-            if(this.shadowBlur || this.shadowOffsetX || this.shadowOffsetY){
-                context.shadowBlur = 0;
-                context.shadowOffsetX = 0;
-                context.shadowOffsetY = 0;
-            }
+            context.stroke();
+        }
 
 
-            if (this._thickness) {
-                if (this.color) {
-                    context.strokeStyle = this.color;
-                }
-                context.lineWidth = this._thickness;
+        context.restore();
+    }
 
 
-                context.stroke();
-            }
-        
-            context.restore();
-        }
+    protected _additionalProcessing(parentMeasure: Measure, context: CanvasRenderingContext2D): void {
+        super._additionalProcessing(parentMeasure, context);
 
 
-        protected _additionalProcessing(parentMeasure: Measure, context: CanvasRenderingContext2D): void {  
-            super._additionalProcessing(parentMeasure, context);
+        this._measureForChildren.width -= 2 * this._thickness;
+        this._measureForChildren.height -= 2 * this._thickness;
+        this._measureForChildren.left += this._thickness;
+        this._measureForChildren.top += this._thickness;
+    }
 
 
-            this._measureForChildren.width -= 2 * this._thickness;
-            this._measureForChildren.height -= 2 * this._thickness;
-            this._measureForChildren.left += this._thickness;
-            this._measureForChildren.top += this._thickness;            
-        }
+    protected _clipForChildren(context: CanvasRenderingContext2D) {
 
 
-       protected _clipForChildren(context: CanvasRenderingContext2D) {
+        Control.drawEllipse(this._currentMeasure.left + this._currentMeasure.width / 2, this._currentMeasure.top + this._currentMeasure.height / 2, this._currentMeasure.width / 2, this._currentMeasure.height / 2, context);
 
 
-            Control.drawEllipse(this._currentMeasure.left + this._currentMeasure.width / 2, this._currentMeasure.top + this._currentMeasure.height / 2, this._currentMeasure.width / 2, this._currentMeasure.height / 2, context);
-            
-            context.clip();
-        }
-    }    
-}
+        context.clip();
+    }
+}   

+ 277 - 276
gui/src/2D/controls/grid.ts

@@ -1,350 +1,351 @@
-/// <reference path="../../../../dist/preview release/babylon.d.ts"/>
+import { Container } from "./container";
+import { ValueAndUnit } from "../valueAndUnit";
+import { Control } from "./control";
+import { Measure } from "../measure";
+
+/**
+ * Class used to create a 2D grid container
+ */
+export class Grid extends Container {
+    private _rowDefinitions = new Array<ValueAndUnit>();
+    private _columnDefinitions = new Array<ValueAndUnit>();
+    private _cells: { [key: string]: Container } = {};
+    private _childControls = new Array<Control>();
+
+    /** Gets the list of children */
+    public get children(): Control[] {
+        return this._childControls;
+    }
 
 
-module BABYLON.GUI {
     /**
     /**
-     * Class used to create a 2D grid container
+     * Adds a new row to the grid
+     * @param height defines the height of the row (either in pixel or a value between 0 and 1)
+     * @param isPixel defines if the height is expressed in pixel (or in percentage)
+     * @returns the current grid
      */
      */
-    export class Grid extends Container {
-        private _rowDefinitions = new Array<ValueAndUnit>();
-        private _columnDefinitions = new Array<ValueAndUnit>();
-        private _cells: {[key: string]:Container} = {};
-        private _childControls = new Array<Control>();
-
-        /** Gets the list of children */
-        public get children(): Control[] {
-            return this._childControls;
-        }             
-
-        /**
-         * Adds a new row to the grid
-         * @param height defines the height of the row (either in pixel or a value between 0 and 1)
-         * @param isPixel defines if the height is expressed in pixel (or in percentage)
-         * @returns the current grid
-         */
-        public addRowDefinition(height: number, isPixel = false): Grid {
-            this._rowDefinitions.push(new ValueAndUnit(height, isPixel ? ValueAndUnit.UNITMODE_PIXEL : ValueAndUnit.UNITMODE_PERCENTAGE));
-
-            this._markAsDirty();
+    public addRowDefinition(height: number, isPixel = false): Grid {
+        this._rowDefinitions.push(new ValueAndUnit(height, isPixel ? ValueAndUnit.UNITMODE_PIXEL : ValueAndUnit.UNITMODE_PERCENTAGE));
 
 
-            return this;
-        }
+        this._markAsDirty();
 
 
-        /**
-         * Adds a new column to the grid
-         * @param width defines the width of the column (either in pixel or a value between 0 and 1)
-         * @param isPixel defines if the width is expressed in pixel (or in percentage)
-         * @returns the current grid
-         */
-        public addColumnDefinition(width: number, isPixel = false): Grid {
-            this._columnDefinitions.push(new ValueAndUnit(width, isPixel ? ValueAndUnit.UNITMODE_PIXEL : ValueAndUnit.UNITMODE_PERCENTAGE));
-            
-            this._markAsDirty();
+        return this;
+    }
 
 
-            return this;
-        }     
-
-        /**
-         * Update a row definition
-         * @param index defines the index of the row to update
-         * @param height defines the height of the row (either in pixel or a value between 0 and 1)
-         * @param isPixel defines if the weight is expressed in pixel (or in percentage)
-         * @returns the current grid
-         */
-        public setRowDefinition(index: number, height: number, isPixel = false): Grid {
-            if (index < 0 || index >= this._rowDefinitions.length) {
-                return this;
-            }
+    /**
+     * Adds a new column to the grid
+     * @param width defines the width of the column (either in pixel or a value between 0 and 1)
+     * @param isPixel defines if the width is expressed in pixel (or in percentage)
+     * @returns the current grid
+     */
+    public addColumnDefinition(width: number, isPixel = false): Grid {
+        this._columnDefinitions.push(new ValueAndUnit(width, isPixel ? ValueAndUnit.UNITMODE_PIXEL : ValueAndUnit.UNITMODE_PERCENTAGE));
 
 
-            this._rowDefinitions[index] = new ValueAndUnit(height,isPixel ? ValueAndUnit.UNITMODE_PIXEL : ValueAndUnit.UNITMODE_PERCENTAGE);
+        this._markAsDirty();
 
 
-            this._markAsDirty();
+        return this;
+    }
 
 
+    /**
+     * Update a row definition
+     * @param index defines the index of the row to update
+     * @param height defines the height of the row (either in pixel or a value between 0 and 1)
+     * @param isPixel defines if the weight is expressed in pixel (or in percentage)
+     * @returns the current grid
+     */
+    public setRowDefinition(index: number, height: number, isPixel = false): Grid {
+        if (index < 0 || index >= this._rowDefinitions.length) {
             return this;
             return this;
         }
         }
 
 
-        /**
-         * Update a column definition
-         * @param index defines the index of the column to update
-         * @param width defines the width of the column (either in pixel or a value between 0 and 1)
-         * @param isPixel defines if the width is expressed in pixel (or in percentage)
-         * @returns the current grid
-         */
-        public setColumnDefinition(index: number, width: number, isPixel = false): Grid {
-            if (index < 0 || index >= this._columnDefinitions.length) {
-                return this;
-            }
+        this._rowDefinitions[index] = new ValueAndUnit(height, isPixel ? ValueAndUnit.UNITMODE_PIXEL : ValueAndUnit.UNITMODE_PERCENTAGE);
 
 
-            this._columnDefinitions[index] = new ValueAndUnit(width, isPixel ? ValueAndUnit.UNITMODE_PIXEL : ValueAndUnit.UNITMODE_PERCENTAGE);
+        this._markAsDirty();
 
 
-            this._markAsDirty();
+        return this;
+    }
 
 
+    /**
+     * Update a column definition
+     * @param index defines the index of the column to update
+     * @param width defines the width of the column (either in pixel or a value between 0 and 1)
+     * @param isPixel defines if the width is expressed in pixel (or in percentage)
+     * @returns the current grid
+     */
+    public setColumnDefinition(index: number, width: number, isPixel = false): Grid {
+        if (index < 0 || index >= this._columnDefinitions.length) {
             return this;
             return this;
-        }        
+        }
 
 
-        private _removeCell(cell: Container, key: string) {
-            if (!cell) {
-                return;
-            }
+        this._columnDefinitions[index] = new ValueAndUnit(width, isPixel ? ValueAndUnit.UNITMODE_PIXEL : ValueAndUnit.UNITMODE_PERCENTAGE);
+
+        this._markAsDirty();
+
+        return this;
+    }
+
+    private _removeCell(cell: Container, key: string) {
+        if (!cell) {
+            return;
+        }
 
 
-            super.removeControl(cell);
+        super.removeControl(cell);
 
 
-            for (var control of cell.children) {
-                let childIndex = this._childControls.indexOf(control);
+        for (var control of cell.children) {
+            let childIndex = this._childControls.indexOf(control);
 
 
-                if (childIndex !== -1) {
-                    this._childControls.splice(childIndex, 1);
-                }
+            if (childIndex !== -1) {
+                this._childControls.splice(childIndex, 1);
             }
             }
+        }
+
+        delete this._cells[key];
+    }
 
 
-            delete this._cells[key];
+    private _offsetCell(previousKey: string, key: string) {
+        if (!this._cells[key]) {
+            return;
         }
         }
 
 
-        private _offsetCell(previousKey: string, key: string) {
-            if (!this._cells[key]) {
-                return;
-            }
+        this._cells[previousKey] = this._cells[key];
 
 
-            this._cells[previousKey] = this._cells[key];
+        for (var control of this._cells[previousKey].children) {
+            control._tag = previousKey;
+        }
 
 
-            for (var control of this._cells[previousKey].children) {
-                control._tag = previousKey;
-            } 
+        delete this._cells[key];
+    }
 
 
-            delete this._cells[key];
+    /**
+     * Remove a column definition at specified index
+     * @param index defines the index of the column to remove
+     * @returns the current grid
+     */
+    public removeColumnDefinition(index: number): Grid {
+        if (index < 0 || index >= this._columnDefinitions.length) {
+            return this;
         }
         }
 
 
-        /**
-         * Remove a column definition at specified index
-         * @param index defines the index of the column to remove
-         * @returns the current grid
-         */
-        public removeColumnDefinition(index: number): Grid {
-            if (index < 0 || index >= this._columnDefinitions.length) {
-                return this;
-            }
+        for (var x = 0; x < this._rowDefinitions.length; x++) {
+            let key = `${x}:${index}`;
+            let cell = this._cells[key];
+
+            this._removeCell(cell, key);
+        }
 
 
-            for (var x = 0; x < this._rowDefinitions.length; x++) {
-                let key = `${x}:${index}`;
-                let cell = this._cells[key];
+        for (var x = 0; x < this._rowDefinitions.length; x++) {
+            for (var y = index + 1; y < this._columnDefinitions.length; y++) {
+                let previousKey = `${x}:${y - 1}`;
+                let key = `${x}:${y}`;
 
 
-                this._removeCell(cell, key);
+                this._offsetCell(previousKey, key);
             }
             }
+        }
 
 
-            for (var x = 0; x < this._rowDefinitions.length; x++) {
-                for (var y = index + 1; y < this._columnDefinitions.length; y++) {
-                    let previousKey = `${x}:${y - 1}`;
-                    let key = `${x}:${y}`;
+        this._columnDefinitions.splice(index, 1);
 
 
-                    this._offsetCell(previousKey, key);
-                }
-            }
-            
-            this._columnDefinitions.splice(index, 1);
+        this._markAsDirty();
 
 
-            this._markAsDirty();
+        return this;
+    }
 
 
+    /**
+     * Remove a row definition at specified index
+     * @param index defines the index of the row to remove
+     * @returns the current grid
+     */
+    public removeRowDefinition(index: number): Grid {
+        if (index < 0 || index >= this._rowDefinitions.length) {
             return this;
             return this;
         }
         }
 
 
-        /**
-         * Remove a row definition at specified index
-         * @param index defines the index of the row to remove
-         * @returns the current grid
-         */
-        public removeRowDefinition(index: number): Grid {
-            if (index < 0 || index >= this._rowDefinitions.length) {
-                return this;
-            }
+        for (var y = 0; y < this._columnDefinitions.length; y++) {
+            let key = `${index}:${y}`;
+            let cell = this._cells[key];
 
 
-            for (var y = 0; y < this._columnDefinitions.length; y++) {
-                let key = `${index}:${y}`;
-                let cell = this._cells[key];
+            this._removeCell(cell, key);
+        }
 
 
-                this._removeCell(cell, key);
+        for (var y = 0; y < this._columnDefinitions.length; y++) {
+            for (var x = index + 1; x < this._rowDefinitions.length; x++) {
+                let previousKey = `${x - 1}:${y}`;
+                let key = `${x}:${y}`;
+
+                this._offsetCell(previousKey, key);
             }
             }
+        }
 
 
-            for (var y = 0; y < this._columnDefinitions.length; y++) {
-                for (var x = index + 1; x < this._rowDefinitions.length; x++) {
-                    let previousKey = `${x - 1}:${y}`;
-                    let key = `${x}:${y}`;
+        this._rowDefinitions.splice(index, 1);
 
 
-                    this._offsetCell(previousKey, key);
-                }
-            }
-            
-            this._rowDefinitions.splice(index, 1);
+        this._markAsDirty();
 
 
-            this._markAsDirty();
+        return this;
+    }
 
 
-            return this;
+    /**
+     * Adds a new control to the current grid
+     * @param control defines the control to add
+     * @param row defines the row where to add the control (0 by default)
+     * @param column defines the column where to add the control (0 by default)
+     * @returns the current grid
+     */
+    public addControl(control: Control, row: number = 0, column: number = 0): Grid {
+        if (this._rowDefinitions.length === 0) {
+            // Add default row definition
+            this.addRowDefinition(1, false);
         }
         }
 
 
-        /**
-         * Adds a new control to the current grid
-         * @param control defines the control to add
-         * @param row defines the row where to add the control (0 by default)
-         * @param column defines the column where to add the control (0 by default)
-         * @returns the current grid
-         */
-        public addControl(control: Control, row: number = 0, column: number = 0): Grid {
-            if (this._rowDefinitions.length === 0) {
-                // Add default row definition
-                this.addRowDefinition(1, false);
-            }
+        if (this._columnDefinitions.length === 0) {
+            // Add default column definition
+            this.addColumnDefinition(1, false);
+        }
 
 
-            if (this._columnDefinitions.length === 0) {
-                // Add default column definition
-                this.addColumnDefinition(1, false);
-            }
+        let x = Math.min(row, this._rowDefinitions.length - 1);
+        let y = Math.min(column, this._columnDefinitions.length - 1);
+        let key = `${x}:${y}`;
+        let goodContainer = this._cells[key];
+
+        if (!goodContainer) {
+            goodContainer = new Container(key);
+            this._cells[key] = goodContainer;
+            goodContainer.horizontalAlignment = Control.HORIZONTAL_ALIGNMENT_LEFT;
+            goodContainer.verticalAlignment = Control.VERTICAL_ALIGNMENT_TOP;
+            super.addControl(goodContainer);
+        }
 
 
-            let x = Math.min(row, this._rowDefinitions.length - 1);
-            let y = Math.min(column, this._columnDefinitions.length - 1);
-            let key = `${x}:${y}`;
-            let goodContainer = this._cells[key];
-
-            if (!goodContainer) {
-                goodContainer = new Container(key);
-                this._cells[key] = goodContainer;
-                goodContainer.horizontalAlignment = Control.HORIZONTAL_ALIGNMENT_LEFT;
-                goodContainer.verticalAlignment = Control.VERTICAL_ALIGNMENT_TOP;
-                super.addControl(goodContainer);
-            }
+        goodContainer.addControl(control);
+        this._childControls.push(control);
+        control._tag = key;
 
 
-            goodContainer.addControl(control);
-            this._childControls.push(control);
-            control._tag = key;
+        this._markAsDirty();
 
 
-            this._markAsDirty();            
+        return this;
+    }
 
 
-            return this;
+    /**
+     * Removes a control from the current container
+     * @param control defines the control to remove
+     * @returns the current container
+     */
+    public removeControl(control: Control): Container {
+        var index = this._childControls.indexOf(control);
+
+        if (index !== -1) {
+            this._childControls.splice(index, 1);
         }
         }
 
 
-        /**
-         * Removes a control from the current container
-         * @param control defines the control to remove
-         * @returns the current container
-         */        
-        public removeControl(control: Control): Container {
-            var index = this._childControls.indexOf(control);
+        let cell = this._cells[control._tag];
 
 
-            if (index !== -1) {
-                this._childControls.splice(index, 1);
-            }
+        if (cell) {
+            cell.removeControl(control);
+        }
 
 
-            let cell = this._cells[control._tag];
+        this._markAsDirty();
+        return this;
+    }
 
 
-            if (cell) {
-                cell.removeControl(control);
-            }
+    /**
+     * Creates a new Grid
+     * @param name defines control name
+     */
+    constructor(public name?: string) {
+        super(name);
+    }
 
 
-            this._markAsDirty();
-            return this;
-        }        
-
-        /**
-         * Creates a new Grid
-         * @param name defines control name
-         */
-        constructor(public name?: string) {
-            super(name);
-        }
+    protected _getTypeName(): string {
+        return "Grid";
+    }
 
 
-        protected _getTypeName(): string {
-            return "Grid";
-        }   
-
-        protected _additionalProcessing(parentMeasure: Measure, context: CanvasRenderingContext2D): void {
-            let widths = [];
-            let heights = [];
-            let lefts = [];
-            let tops = [];
-
-            let availableWidth = this._currentMeasure.width;
-            let globalWidthPercentage = 0;
-            let availableHeight = this._currentMeasure.height;
-            let globalHeightPercentage = 0;
-
-            // Heights
-            let index = 0;
-            for (var value of this._rowDefinitions) {
-                if (value.isPixel) {
-                    let height = value.getValue(this._host);
-                    availableHeight -= height;
-                    heights[index] = height;
-                } else {
-                    globalHeightPercentage += value.internalValue;
-                }
-                index++;
+    protected _additionalProcessing(parentMeasure: Measure, context: CanvasRenderingContext2D): void {
+        let widths = [];
+        let heights = [];
+        let lefts = [];
+        let tops = [];
+
+        let availableWidth = this._currentMeasure.width;
+        let globalWidthPercentage = 0;
+        let availableHeight = this._currentMeasure.height;
+        let globalHeightPercentage = 0;
+
+        // Heights
+        let index = 0;
+        for (var value of this._rowDefinitions) {
+            if (value.isPixel) {
+                let height = value.getValue(this._host);
+                availableHeight -= height;
+                heights[index] = height;
+            } else {
+                globalHeightPercentage += value.internalValue;
             }
             }
+            index++;
+        }
 
 
-            let top = 0;
-            index = 0;
-            for (var value of this._rowDefinitions) {
-                tops.push(top);
-
-                if (!value.isPixel) {
-                    let height = (value.internalValue / globalHeightPercentage) * availableHeight;
-                    top += height;
-                    heights[index] = height;
-                } else {
-                    top += value.getValue(this._host);
-                }
-                index++;
+        let top = 0;
+        index = 0;
+        for (var value of this._rowDefinitions) {
+            tops.push(top);
+
+            if (!value.isPixel) {
+                let height = (value.internalValue / globalHeightPercentage) * availableHeight;
+                top += height;
+                heights[index] = height;
+            } else {
+                top += value.getValue(this._host);
             }
             }
+            index++;
+        }
 
 
-            // Widths
-            index = 0;
-            for (var value of this._columnDefinitions) {
-                if (value.isPixel) {
-                    let width = value.getValue(this._host);
-                    availableWidth -= width;
-                    widths[index] = width;
-                } else {
-                    globalWidthPercentage += value.internalValue;
-                }
-                index++;
+        // Widths
+        index = 0;
+        for (var value of this._columnDefinitions) {
+            if (value.isPixel) {
+                let width = value.getValue(this._host);
+                availableWidth -= width;
+                widths[index] = width;
+            } else {
+                globalWidthPercentage += value.internalValue;
             }
             }
+            index++;
+        }
 
 
-            let left = 0;
-            index = 0;
-            for (var value of this._columnDefinitions) {
-                lefts.push(left);
-                if (!value.isPixel) {
-                    let width = (value.internalValue / globalWidthPercentage) * availableWidth;
-                    left += width;
-                    widths[index] = width;
-                }  else {
-                    left += value.getValue(this._host);
-                }
-                index++;
-            }       
-            
-            // 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";
+        let left = 0;
+        index = 0;
+        for (var value of this._columnDefinitions) {
+            lefts.push(left);
+            if (!value.isPixel) {
+                let width = (value.internalValue / globalWidthPercentage) * availableWidth;
+                left += width;
+                widths[index] = width;
+            } else {
+                left += value.getValue(this._host);
             }
             }
+            index++;
+        }
 
 
-            super._additionalProcessing(parentMeasure, context);
+        // 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";
         }
         }
 
 
-        /** Releases associated resources */
-        public dispose() {
-            super.dispose();
+        super._additionalProcessing(parentMeasure, context);
+    }
+
+    /** Releases associated resources */
+    public dispose() {
+        super.dispose();
 
 
-            for (var control of this._childControls) {
-                control.dispose();
-            }
+        for (var control of this._childControls) {
+            control.dispose();
         }
         }
     }
     }
 }
 }

+ 279 - 279
gui/src/2D/controls/image.ts

@@ -1,351 +1,351 @@
-/// <reference path="../../../../dist/preview release/babylon.d.ts"/>
+import { Control } from "./control";
+import { Nullable, Tools } from "babylonjs";
+import { Measure } from "../measure";
+
+/**
+ * Class used to create 2D images
+ */
+class GUIImage extends Control {
+    private _domImage: HTMLImageElement;
+    private _imageWidth: number;
+    private _imageHeight: number;
+    private _loaded = false;
+    private _stretch = GUIImage.STRETCH_FILL;
+    private _source: Nullable<string>;
+    private _autoScale = false;
+
+    private _sourceLeft = 0;
+    private _sourceTop = 0;
+    private _sourceWidth = 0;
+    private _sourceHeight = 0;
+
+    private _cellWidth: number = 0;
+    private _cellHeight: number = 0;
+    private _cellId: number = -1;
 
 
-var DOMImage = Image;
-
-module BABYLON.GUI {
     /**
     /**
-     * Class used to create 2D images
+     * Gets or sets the left coordinate in the source image
      */
      */
-    export class Image extends Control {
-        private _domImage: HTMLImageElement;
-        private _imageWidth: number;
-        private _imageHeight: number;
-        private _loaded = false;
-        private _stretch = Image.STRETCH_FILL;
-        private _source: Nullable<string>;
-        private _autoScale = false;
-
-        private _sourceLeft = 0;
-        private _sourceTop = 0;
-        private _sourceWidth = 0;
-        private _sourceHeight = 0;
-
-        private _cellWidth: number = 0;
-        private _cellHeight: number = 0;
-        private _cellId: number = -1;
-
-        /**
-         * Gets or sets the left coordinate in the source image
-         */
-        public get sourceLeft(): number {
-            return this._sourceLeft;
+    public get sourceLeft(): number {
+        return this._sourceLeft;
+    }
+
+    public set sourceLeft(value: number) {
+        if (this._sourceLeft === value) {
+            return;
         }
         }
 
 
-        public set sourceLeft(value: number) {
-            if (this._sourceLeft === value) {
-                return;
-            }
+        this._sourceLeft = value;
 
 
-            this._sourceLeft = value;
+        this._markAsDirty();
+    }
 
 
-            this._markAsDirty();
-        }
+    /**
+     * Gets or sets the top coordinate in the source image
+     */
+    public get sourceTop(): number {
+        return this._sourceTop;
+    }
 
 
-        /**
-         * Gets or sets the top coordinate in the source image
-         */        
-        public get sourceTop(): number {
-            return this._sourceTop;
+    public set sourceTop(value: number) {
+        if (this._sourceTop === value) {
+            return;
         }
         }
 
 
-        public set sourceTop(value: number) {
-            if (this._sourceTop === value) {
-                return;
-            }
+        this._sourceTop = value;
 
 
-            this._sourceTop = value;
+        this._markAsDirty();
+    }
 
 
-            this._markAsDirty();
-        }
+    /**
+     * Gets or sets the width to capture in the source image
+     */
+    public get sourceWidth(): number {
+        return this._sourceWidth;
+    }
 
 
-        /**
-         * Gets or sets the width to capture in the source image
-         */        
-        public get sourceWidth(): number {
-            return this._sourceWidth;
+    public set sourceWidth(value: number) {
+        if (this._sourceWidth === value) {
+            return;
         }
         }
 
 
-        public set sourceWidth(value: number) {
-            if (this._sourceWidth === value) {
-                return;
-            }
+        this._sourceWidth = value;
 
 
-            this._sourceWidth = value;
+        this._markAsDirty();
+    }
 
 
-            this._markAsDirty();
-        }
+    /**
+     * Gets or sets the height to capture in the source image
+     */
+    public get sourceHeight(): number {
+        return this._sourceHeight;
+    }
 
 
-        /**
-         * Gets or sets the height to capture in the source image
-         */        
-        public get sourceHeight(): number {
-            return this._sourceHeight;
+    public set sourceHeight(value: number) {
+        if (this._sourceHeight === value) {
+            return;
         }
         }
 
 
-        public set sourceHeight(value: number) {
-            if (this._sourceHeight === value) {
-                return;
-            }
+        this._sourceHeight = value;
 
 
-            this._sourceHeight = value;
+        this._markAsDirty();
+    }
 
 
-            this._markAsDirty();
-        }
+    /** 
+     * Gets or sets a boolean indicating if the image can force its container to adapt its size 
+     * @see http://doc.babylonjs.com/how_to/gui#image
+     */
+    public get autoScale(): boolean {
+        return this._autoScale;
+    }
 
 
-        /** 
-         * Gets or sets a boolean indicating if the image can force its container to adapt its size 
-         * @see http://doc.babylonjs.com/how_to/gui#image
-         */
-        public get autoScale(): boolean {
-            return this._autoScale;
+    public set autoScale(value: boolean) {
+        if (this._autoScale === value) {
+            return;
         }
         }
 
 
-        public set autoScale(value: boolean) {
-            if (this._autoScale === value) {
-                return;
-            }
-
-            this._autoScale = value;
+        this._autoScale = value;
 
 
-            if (value && this._loaded) {
-                this.synchronizeSizeWithContent();
-            }
+        if (value && this._loaded) {
+            this.synchronizeSizeWithContent();
         }
         }
+    }
 
 
-        /** Gets or sets the streching mode used by the image */
-        public get stretch(): number {
-            return this._stretch;
-        }
+    /** Gets or sets the streching mode used by the image */
+    public get stretch(): number {
+        return this._stretch;
+    }
 
 
-        public set stretch(value: number) {
-            if (this._stretch === value) {
-                return;
-            }
+    public set stretch(value: number) {
+        if (this._stretch === value) {
+            return;
+        }
 
 
-            this._stretch = value;
+        this._stretch = value;
 
 
-            this._markAsDirty();
-        }
+        this._markAsDirty();
+    }
 
 
-        /**
-         * Gets or sets the internal DOM image used to render the control
-         */
-        public set domImage(value: HTMLImageElement) {
-            this._domImage = value;
-            this._loaded = false;
+    /**
+     * Gets or sets the internal DOM image used to render the control
+     */
+    public set domImage(value: HTMLImageElement) {
+        this._domImage = value;
+        this._loaded = false;
 
 
-            if (this._domImage.width) {
+        if (this._domImage.width) {
+            this._onImageLoaded();
+        } else {
+            this._domImage.onload = () => {
                 this._onImageLoaded();
                 this._onImageLoaded();
-            } else {
-                this._domImage.onload = () => {
-                    this._onImageLoaded();
-                }
             }
             }
         }
         }
+    }
 
 
-        public get domImage(): HTMLImageElement {
-            return this._domImage;
-        }
-
-        private _onImageLoaded(): void {
-            this._imageWidth = this._domImage.width;
-            this._imageHeight = this._domImage.height;
-            this._loaded = true;
+    public get domImage(): HTMLImageElement {
+        return this._domImage;
+    }
 
 
-            if (this._autoScale) {
-                this.synchronizeSizeWithContent();
-            }
+    private _onImageLoaded(): void {
+        this._imageWidth = this._domImage.width;
+        this._imageHeight = this._domImage.height;
+        this._loaded = true;
 
 
-            this._markAsDirty();
+        if (this._autoScale) {
+            this.synchronizeSizeWithContent();
         }
         }
 
 
-        /**
-         * Gets or sets image source url
-         */
-        public set source(value: Nullable<string>) {
-            if (this._source === value) {
-                return;
-            }
+        this._markAsDirty();
+    }
 
 
-            this._loaded = false;
-            this._source = value;
+    /**
+     * Gets or sets image source url
+     */
+    public set source(value: Nullable<string>) {
+        if (this._source === value) {
+            return;
+        }
 
 
-            this._domImage = new DOMImage();
+        this._loaded = false;
+        this._source = value;
 
 
-            this._domImage.onload = () => {
-                this._onImageLoaded();
-            }
-            if (value) {
-                Tools.SetCorsBehavior(value, this._domImage);
-                this._domImage.src = value;
-            }
-        }
+        this._domImage = new Image();
 
 
-        /** 
-         * Gets or sets the cell width to use when animation sheet is enabled 
-         * @see http://doc.babylonjs.com/how_to/gui#image
-         */
-        get cellWidth(): number {
-            return this._cellWidth;
+        this._domImage.onload = () => {
+            this._onImageLoaded();
         }
         }
-        set cellWidth(value: number) {
-            if(this._cellWidth === value){
-                return;
-            }
-            
-            this._cellWidth = value;
-            this._markAsDirty();
+        if (value) {
+            Tools.SetCorsBehavior(value, this._domImage);
+            this._domImage.src = value;
         }
         }
+    }
 
 
-        /** 
-         * Gets or sets the cell height to use when animation sheet is enabled 
-         * @see http://doc.babylonjs.com/how_to/gui#image
-         */
-        get cellHeight(): number {
-            return this._cellHeight;
-        }
-        set cellHeight(value: number) {
-            if(this._cellHeight === value){
-                return;
-            }
-            
-            this._cellHeight = value;
-            this._markAsDirty();
-        }
-    
-        /** 
-         * Gets or sets the cell id to use (this will turn on the animation sheet mode)
-         * @see http://doc.babylonjs.com/how_to/gui#image
-         */
-        get cellId(): number {
-            return this._cellId;
-        }
-        set cellId(value: number) {
-            if (this._cellId === value) {
-                 return;
-             }
-            
-            this._cellId = value;
-            this._markAsDirty();
+    /** 
+     * Gets or sets the cell width to use when animation sheet is enabled 
+     * @see http://doc.babylonjs.com/how_to/gui#image
+     */
+    get cellWidth(): number {
+        return this._cellWidth;
+    }
+    set cellWidth(value: number) {
+        if (this._cellWidth === value) {
+            return;
         }
         }
 
 
-        /**
-         * Creates a new Image
-         * @param name defines the control name
-         * @param url defines the image url
-         */
-        constructor(public name?: string, url: Nullable<string> = null) {
-            super(name);
+        this._cellWidth = value;
+        this._markAsDirty();
+    }
 
 
-            this.source = url;
+    /** 
+     * Gets or sets the cell height to use when animation sheet is enabled 
+     * @see http://doc.babylonjs.com/how_to/gui#image
+     */
+    get cellHeight(): number {
+        return this._cellHeight;
+    }
+    set cellHeight(value: number) {
+        if (this._cellHeight === value) {
+            return;
         }
         }
 
 
-        protected _getTypeName(): string {
-            return "Image";
+        this._cellHeight = value;
+        this._markAsDirty();
+    }
+
+    /** 
+     * Gets or sets the cell id to use (this will turn on the animation sheet mode)
+     * @see http://doc.babylonjs.com/how_to/gui#image
+     */
+    get cellId(): number {
+        return this._cellId;
+    }
+    set cellId(value: number) {
+        if (this._cellId === value) {
+            return;
         }
         }
 
 
-        /** Force the control to synchronize with its content */
-        public synchronizeSizeWithContent() {
-            if (!this._loaded) {
-                return;
-            }
+        this._cellId = value;
+        this._markAsDirty();
+    }
 
 
-            this.width = this._domImage.width + "px";
-            this.height = this._domImage.height + "px";
+    /**
+     * Creates a new Image
+     * @param name defines the control name
+     * @param url defines the image url
+     */
+    constructor(public name?: string, url: Nullable<string> = null) {
+        super(name);
+
+        this.source = url;
+    }
+
+    protected _getTypeName(): string {
+        return "Image";
+    }
+
+    /** Force the control to synchronize with its content */
+    public synchronizeSizeWithContent() {
+        if (!this._loaded) {
+            return;
         }
         }
 
 
-        public _draw(parentMeasure: Measure, context: CanvasRenderingContext2D): void {
-            context.save();
+        this.width = this._domImage.width + "px";
+        this.height = this._domImage.height + "px";
+    }
 
 
-            if(this.shadowBlur || this.shadowOffsetX || this.shadowOffsetY){
-                context.shadowColor = this.shadowColor;
-                context.shadowBlur = this.shadowBlur;
-                context.shadowOffsetX = this.shadowOffsetX;
-                context.shadowOffsetY = this.shadowOffsetY;
-            }
+    public _draw(parentMeasure: Measure, context: CanvasRenderingContext2D): void {
+        context.save();
 
 
-            let x, y, width, height;
-            if (this.cellId == -1) {
-                x = this._sourceLeft;
-                y = this._sourceTop;
+        if (this.shadowBlur || this.shadowOffsetX || this.shadowOffsetY) {
+            context.shadowColor = this.shadowColor;
+            context.shadowBlur = this.shadowBlur;
+            context.shadowOffsetX = this.shadowOffsetX;
+            context.shadowOffsetY = this.shadowOffsetY;
+        }
 
 
-                width = this._sourceWidth ? this._sourceWidth : this._imageWidth;
-                height = this._sourceHeight ? this._sourceHeight : this._imageHeight;
-            }
-            else {
-                let rowCount = this._domImage.naturalWidth / this.cellWidth;
-                let column = (this.cellId / rowCount) >> 0;
-                let row = this.cellId % rowCount;
-
-                x = this.cellWidth * row;
-                y = this.cellHeight * column;
-                width = this.cellWidth;
-                height = this.cellHeight;
-            }
+        let x, y, width, height;
+        if (this.cellId == -1) {
+            x = this._sourceLeft;
+            y = this._sourceTop;
 
 
-            this._applyStates(context);
-            if (this._processMeasures(parentMeasure, context)) {
-                if (this._loaded) {
-                    switch (this._stretch) {
-                        case Image.STRETCH_NONE:
-                            context.drawImage(this._domImage, x, y, width, height,
-                                this._currentMeasure.left, this._currentMeasure.top, this._currentMeasure.width, this._currentMeasure.height);
-                            break;
-                        case Image.STRETCH_FILL:
-                            context.drawImage(this._domImage, x, y, width, height,
-                                this._currentMeasure.left, this._currentMeasure.top, this._currentMeasure.width, this._currentMeasure.height);
-                            break;
-                        case Image.STRETCH_UNIFORM:
-                            var hRatio = this._currentMeasure.width / width;
-                            var vRatio = this._currentMeasure.height / height;
-                            var ratio = Math.min(hRatio, vRatio);
-                            var centerX = (this._currentMeasure.width - width * ratio) / 2;
-                            var centerY = (this._currentMeasure.height - height * ratio) / 2;
-
-                            context.drawImage(this._domImage, x, y, width, height,
-                                this._currentMeasure.left + centerX, this._currentMeasure.top + centerY, width * ratio, height * ratio);
-                            break;
-                        case Image.STRETCH_EXTEND:
-                            context.drawImage(this._domImage, x, y, width, height,
-                                this._currentMeasure.left, this._currentMeasure.top, this._currentMeasure.width, this._currentMeasure.height);
-                            if (this._autoScale) {
-                                this.synchronizeSizeWithContent();
-                            }
-                            if (this._root && this._root.parent) { // Will update root size if root is not the top root
-                                this._root.width = this.width;
-                                this._root.height = this.height;
-                            }
-                            break;
-                    }
+            width = this._sourceWidth ? this._sourceWidth : this._imageWidth;
+            height = this._sourceHeight ? this._sourceHeight : this._imageHeight;
+        }
+        else {
+            let rowCount = this._domImage.naturalWidth / this.cellWidth;
+            let column = (this.cellId / rowCount) >> 0;
+            let row = this.cellId % rowCount;
+
+            x = this.cellWidth * row;
+            y = this.cellHeight * column;
+            width = this.cellWidth;
+            height = this.cellHeight;
+        }
+
+        this._applyStates(context);
+        if (this._processMeasures(parentMeasure, context)) {
+            if (this._loaded) {
+                switch (this._stretch) {
+                    case GUIImage.STRETCH_NONE:
+                        context.drawImage(this._domImage, x, y, width, height,
+                            this._currentMeasure.left, this._currentMeasure.top, this._currentMeasure.width, this._currentMeasure.height);
+                        break;
+                    case GUIImage.STRETCH_FILL:
+                        context.drawImage(this._domImage, x, y, width, height,
+                            this._currentMeasure.left, this._currentMeasure.top, this._currentMeasure.width, this._currentMeasure.height);
+                        break;
+                    case GUIImage.STRETCH_UNIFORM:
+                        var hRatio = this._currentMeasure.width / width;
+                        var vRatio = this._currentMeasure.height / height;
+                        var ratio = Math.min(hRatio, vRatio);
+                        var centerX = (this._currentMeasure.width - width * ratio) / 2;
+                        var centerY = (this._currentMeasure.height - height * ratio) / 2;
+
+                        context.drawImage(this._domImage, x, y, width, height,
+                            this._currentMeasure.left + centerX, this._currentMeasure.top + centerY, width * ratio, height * ratio);
+                        break;
+                    case GUIImage.STRETCH_EXTEND:
+                        context.drawImage(this._domImage, x, y, width, height,
+                            this._currentMeasure.left, this._currentMeasure.top, this._currentMeasure.width, this._currentMeasure.height);
+                        if (this._autoScale) {
+                            this.synchronizeSizeWithContent();
+                        }
+                        if (this._root && this._root.parent) { // Will update root size if root is not the top root
+                            this._root.width = this.width;
+                            this._root.height = this.height;
+                        }
+                        break;
                 }
                 }
             }
             }
-            context.restore();
         }
         }
+        context.restore();
+    }
 
 
-        // Static
-        private static _STRETCH_NONE = 0;
-        private static _STRETCH_FILL = 1;
-        private static _STRETCH_UNIFORM = 2;
-        private static _STRETCH_EXTEND = 3;
+    // Static
+    private static _STRETCH_NONE = 0;
+    private static _STRETCH_FILL = 1;
+    private static _STRETCH_UNIFORM = 2;
+    private static _STRETCH_EXTEND = 3;
 
 
-        /** STRETCH_NONE */
-        public static get STRETCH_NONE(): number {
-            return Image._STRETCH_NONE;
-        }
+    /** STRETCH_NONE */
+    public static get STRETCH_NONE(): number {
+        return GUIImage._STRETCH_NONE;
+    }
 
 
-        /** STRETCH_FILL */
-        public static get STRETCH_FILL(): number {
-            return Image._STRETCH_FILL;
-        }
+    /** STRETCH_FILL */
+    public static get STRETCH_FILL(): number {
+        return GUIImage._STRETCH_FILL;
+    }
 
 
-        /** STRETCH_UNIFORM */
-        public static get STRETCH_UNIFORM(): number {
-            return Image._STRETCH_UNIFORM;
-        }
+    /** STRETCH_UNIFORM */
+    public static get STRETCH_UNIFORM(): number {
+        return GUIImage._STRETCH_UNIFORM;
+    }
 
 
-        /** STRETCH_EXTEND */
-        public static get STRETCH_EXTEND(): number {
-            return Image._STRETCH_EXTEND;
-        }
+    /** STRETCH_EXTEND */
+    public static get STRETCH_EXTEND(): number {
+        return GUIImage._STRETCH_EXTEND;
     }
     }
 }
 }
+
+export { GUIImage as Image };

+ 19 - 0
gui/src/2D/controls/index.ts

@@ -0,0 +1,19 @@
+export * from "./button";
+export * from "./checkbox";
+export * from "./colorpicker";
+export * from "./container";
+export * from "./control";
+export * from "./ellipse";
+export * from "./grid";
+export * from "./image";
+export * from "./inputText";
+export * from "./line";
+export * from "./multiLine";
+export * from "./radioButton";
+export * from "./stackPanel";
+export * from "./textBlock";
+export * from "./virtualKeyboard";
+export * from "./slider";
+export * from "./rectangle";
+
+export * from "./statics";

+ 10 - 12
gui/src/2D/controls/inputPassword.ts

@@ -1,16 +1,14 @@
-/// <reference path="../../../../dist/preview release/babylon.d.ts"/>
+import { InputText } from "./inputText";
 
 
-module BABYLON.GUI {
-    /**
-     * Class used to create a password control
-     */
-    export class InputPassword extends InputText {
-        protected _beforeRenderText(text: string): string {
-            let txt = "";
-            for (let i = 0; i < text.length; i++) {
-                txt += "\u2022";
-            }
-            return txt;
+/**
+ * Class used to create a password control
+ */
+export class InputPassword extends InputText {
+    protected _beforeRenderText(text: string): string {
+        let txt = "";
+        for (let i = 0; i < text.length; i++) {
+            txt += "\u2022";
         }
         }
+        return txt;
     }
     }
 }
 }

+ 426 - 424
gui/src/2D/controls/inputText.ts

@@ -1,536 +1,538 @@
-/// <reference path="../../../../dist/preview release/babylon.d.ts"/>
+import { Control } from "./control";
+import { IFocusableControl } from "../advancedDynamicTexture";
+import { ValueAndUnit } from "../valueAndUnit";
+import { Nullable, Observable, Vector2 } from "babylonjs";
+import { Measure } from "../measure";
+
+/**
+ * Class used to create input text control
+ */
+export class InputText extends Control implements IFocusableControl {
+    private _text = "";
+    private _placeholderText = "";
+    private _background = "#222222";
+    private _focusedBackground = "#000000";
+    private _placeholderColor = "gray";
+    private _thickness = 1;
+    private _margin = new ValueAndUnit(10, ValueAndUnit.UNITMODE_PIXEL);
+    private _autoStretchWidth = true;
+    private _maxWidth = new ValueAndUnit(1, ValueAndUnit.UNITMODE_PERCENTAGE, false);
+    private _isFocused = false;
+    private _blinkTimeout: number;
+    private _blinkIsEven = false;
+    private _cursorOffset = 0;
+    private _scrollLeft: Nullable<number>;
+    private _textWidth: number;
+    private _clickedCoordinate: Nullable<number>;
+    private _deadKey = false;
+    private _addKey = true;
+    private _currentKey = "";
+
+    /** Gets or sets a string representing the message displayed on mobile when the control gets the focus */
+    public promptMessage = "Please enter text:";
+
+    /** Observable raised when the text changes */
+    public onTextChangedObservable = new Observable<InputText>();
+    /** Observable raised just before an entered character is to be added */
+    public onBeforeKeyAddObservable = new Observable<InputText>();
+    /** Observable raised when the control gets the focus */
+    public onFocusObservable = new Observable<InputText>();
+    /** Observable raised when the control loses the focus */
+    public onBlurObservable = new Observable<InputText>();
+
+    /** Gets or sets the maximum width allowed by the control */
+    public get maxWidth(): string | number {
+        return this._maxWidth.toString(this._host);
+    }
 
 
-module BABYLON.GUI {
-    /**
-     * Class used to create input text control
-     */
-    export class InputText extends Control implements IFocusableControl {
-        private _text = "";
-        private _placeholderText = "";
-        private _background = "#222222";
-        private _focusedBackground = "#000000";
-        private _placeholderColor = "gray";
-        private _thickness = 1;
-        private _margin = new ValueAndUnit(10, ValueAndUnit.UNITMODE_PIXEL);
-        private _autoStretchWidth = true;
-        private _maxWidth = new ValueAndUnit(1, ValueAndUnit.UNITMODE_PERCENTAGE, false);
-        private _isFocused = false;
-        private _blinkTimeout: number;
-        private _blinkIsEven = false;
-        private _cursorOffset = 0;
-        private _scrollLeft: Nullable<number>;
-        private _textWidth: number;
-        private _clickedCoordinate: Nullable<number>;
-        private _deadKey = false;
-        private _addKey = true;
-        private _currentKey = "";
-
-        /** Gets or sets a string representing the message displayed on mobile when the control gets the focus */
-        public promptMessage = "Please enter text:";
-
-        /** Observable raised when the text changes */
-        public onTextChangedObservable = new Observable<InputText>();
-        /** Observable raised just before an entered character is to be added */
-        public onBeforeKeyAddObservable = new Observable<InputText>();
-        /** Observable raised when the control gets the focus */
-        public onFocusObservable = new Observable<InputText>();
-        /** Observable raised when the control loses the focus */
-        public onBlurObservable = new Observable<InputText>();
-
-        /** Gets or sets the maximum width allowed by the control */
-        public get maxWidth(): string | number {
-            return this._maxWidth.toString(this._host);
+    /** Gets the maximum width allowed by the control in pixels */
+    public get maxWidthInPixels(): number {
+        return this._maxWidth.getValueInPixel(this._host, this._cachedParentMeasure.width);
+    }
+
+    public set maxWidth(value: string | number) {
+        if (this._maxWidth.toString(this._host) === value) {
+            return;
         }
         }
 
 
-        /** Gets the maximum width allowed by the control in pixels */
-        public get maxWidthInPixels(): number {
-            return this._maxWidth.getValueInPixel(this._host, this._cachedParentMeasure.width);
+        if (this._maxWidth.fromString(value)) {
+            this._markAsDirty();
         }
         }
+    }
 
 
-        public set maxWidth(value: string | number) {
-            if (this._maxWidth.toString(this._host) === value) {
-                return;
-            }
+    /** Gets or sets control margin */
+    public get margin(): string {
+        return this._margin.toString(this._host);
+    }
 
 
-            if (this._maxWidth.fromString(value)) {
-                this._markAsDirty();
-            }
-        }
+    /** Gets control margin in pixels */
+    public get marginInPixels(): number {
+        return this._margin.getValueInPixel(this._host, this._cachedParentMeasure.width);
+    }
 
 
-        /** Gets or sets control margin */
-        public get margin(): string {
-            return this._margin.toString(this._host);
+    public set margin(value: string) {
+        if (this._margin.toString(this._host) === value) {
+            return;
         }
         }
 
 
-        /** Gets control margin in pixels */
-        public get marginInPixels(): number {
-            return this._margin.getValueInPixel(this._host, this._cachedParentMeasure.width);
+        if (this._margin.fromString(value)) {
+            this._markAsDirty();
         }
         }
+    }
 
 
-        public set margin(value: string) {
-            if (this._margin.toString(this._host) === value) {
-                return;
-            }
+    /** Gets or sets a boolean indicating if the control can auto stretch its width to adapt to the text */
+    public get autoStretchWidth(): boolean {
+        return this._autoStretchWidth;
+    }
 
 
-            if (this._margin.fromString(value)) {
-                this._markAsDirty();
-            }
+    public set autoStretchWidth(value: boolean) {
+        if (this._autoStretchWidth === value) {
+            return;
         }
         }
 
 
-        /** Gets or sets a boolean indicating if the control can auto stretch its width to adapt to the text */
-        public get autoStretchWidth(): boolean {
-            return this._autoStretchWidth;
-        }
+        this._autoStretchWidth = value;
+        this._markAsDirty();
+    }
 
 
-        public set autoStretchWidth(value: boolean) {
-            if (this._autoStretchWidth === value) {
-                return;
-            }
+    /** Gets or sets border thickness */
+    public get thickness(): number {
+        return this._thickness;
+    }
 
 
-            this._autoStretchWidth = value;
-            this._markAsDirty();
+    public set thickness(value: number) {
+        if (this._thickness === value) {
+            return;
         }
         }
 
 
-        /** Gets or sets border thickness */
-        public get thickness(): number {
-            return this._thickness;
-        }
+        this._thickness = value;
+        this._markAsDirty();
+    }
 
 
-        public set thickness(value: number) {
-            if (this._thickness === value) {
-                return;
-            }
+    /** Gets or sets the background color when focused */
+    public get focusedBackground(): string {
+        return this._focusedBackground;
+    }
 
 
-            this._thickness = value;
-            this._markAsDirty();
+    public set focusedBackground(value: string) {
+        if (this._focusedBackground === value) {
+            return;
         }
         }
 
 
-        /** Gets or sets the background color when focused */
-        public get focusedBackground(): string {
-            return this._focusedBackground;
-        }
+        this._focusedBackground = value;
+        this._markAsDirty();
+    }
 
 
-        public set focusedBackground(value: string) {
-            if (this._focusedBackground === value) {
-                return;
-            }
+    /** Gets or sets the background color */
+    public get background(): string {
+        return this._background;
+    }
 
 
-            this._focusedBackground = value;
-            this._markAsDirty();
+    public set background(value: string) {
+        if (this._background === value) {
+            return;
         }
         }
 
 
-        /** Gets or sets the background color */
-        public get background(): string {
-            return this._background;
-        }
+        this._background = value;
+        this._markAsDirty();
+    }
 
 
-        public set background(value: string) {
-            if (this._background === value) {
-                return;
-            }
+    /** Gets or sets the placeholder color */
+    public get placeholderColor(): string {
+        return this._placeholderColor;
+    }
 
 
-            this._background = value;
-            this._markAsDirty();
+    public set placeholderColor(value: string) {
+        if (this._placeholderColor === value) {
+            return;
         }
         }
 
 
-        /** Gets or sets the placeholder color */
-        public get placeholderColor(): string {
-            return this._placeholderColor;
-        }
+        this._placeholderColor = value;
+        this._markAsDirty();
+    }
 
 
-        public set placeholderColor(value: string) {
-            if (this._placeholderColor === value) {
-                return;
-            }
+    /** Gets or sets the text displayed when the control is empty */
+    public get placeholderText(): string {
+        return this._placeholderText;
+    }
 
 
-            this._placeholderColor = value;
-            this._markAsDirty();
+    public set placeholderText(value: string) {
+        if (this._placeholderText === value) {
+            return;
         }
         }
+        this._placeholderText = value;
+        this._markAsDirty();
+    }
 
 
-        /** Gets or sets the text displayed when the control is empty */
-        public get placeholderText(): string {
-            return this._placeholderText;
-        }
+    /** Gets or sets the dead key flag */
+    public get deadKey(): boolean {
+        return this._deadKey;
+    }
 
 
-        public set placeholderText(value: string) {
-            if (this._placeholderText === value) {
-                return;
-            }
-            this._placeholderText = value;
-            this._markAsDirty();
-        }
+    public set deadKey(flag: boolean) {
+        this._deadKey = flag;
+    }
 
 
-        /** Gets or sets the dead key flag */
-        public get deadKey(): boolean {
-            return this._deadKey;
-        }
+    /** Gets or sets if the current key should be added */
+    public get addKey(): boolean {
+        return this._addKey;
+    }
 
 
-        public set deadKey(flag: boolean) {
-            this._deadKey = flag;
-        }
+    public set addKey(flag: boolean) {
+        this._addKey = flag;
+    }
 
 
-        /** Gets or sets if the current key should be added */
-        public get addKey(): boolean {
-            return this._addKey;
-        }
+    /** Gets or sets the value of the current key being entered */
+    public get currentKey(): string {
+        return this._currentKey;
+    }
 
 
-        public set addKey(flag: boolean) {
-            this._addKey = flag;
-        }
+    public set currentKey(key: string) {
+        this._currentKey = key;
+    }
 
 
-        /** Gets or sets the value of the current key being entered */
-        public get currentKey(): string {
-            return this._currentKey;
-        }
+    /** Gets or sets the text displayed in the control */
+    public get text(): string {
+        return this._text;
+    }
 
 
-        public set currentKey(key: string) {
-            this._currentKey = key;
+    public set text(value: string) {
+        if (this._text === value) {
+            return;
         }
         }
+        this._text = value;
+        this._markAsDirty();
 
 
-        /** Gets or sets the text displayed in the control */
-        public get text(): string {
-            return this._text;
-        }
+        this.onTextChangedObservable.notifyObservers(this);
+    }
 
 
-        public set text(value: string) {
-            if (this._text === value) {
-                return;
-            }
-            this._text = value;
-            this._markAsDirty();
+    /** Gets or sets control width */
+    public get width(): string | number {
+        return this._width.toString(this._host);
+    }
 
 
-            this.onTextChangedObservable.notifyObservers(this);
+    public set width(value: string | number) {
+        if (this._width.toString(this._host) === value) {
+            return;
         }
         }
 
 
-        /** Gets or sets control width */
-        public get width(): string | number {
-            return this._width.toString(this._host);
+        if (this._width.fromString(value)) {
+            this._markAsDirty();
         }
         }
 
 
-        public set width(value: string | number) {
-            if (this._width.toString(this._host) === value) {
-                return;
-            }
-
-            if (this._width.fromString(value)) {
-                this._markAsDirty();
-            }
+        this.autoStretchWidth = false;
+    }
 
 
-            this.autoStretchWidth = false;
-        }
+    /**
+     * Creates a new InputText
+     * @param name defines the control name
+     * @param text defines the text of the control
+     */
+    constructor(public name?: string, text: string = "") {
+        super(name);
 
 
-        /**
-         * Creates a new InputText
-         * @param name defines the control name
-         * @param text defines the text of the control
-         */
-        constructor(public name?: string, text: string = "") {
-            super(name);
+        this.text = text;
+    }
 
 
-            this.text = text;
-        }
+    /** @hidden */
+    public onBlur(): void {
+        this._isFocused = false;
+        this._scrollLeft = null;
+        this._cursorOffset = 0;
+        clearTimeout(this._blinkTimeout);
+        this._markAsDirty();
 
 
-        /** @hidden */
-        public onBlur(): void {
-            this._isFocused = false;
-            this._scrollLeft = null;
-            this._cursorOffset = 0;
-            clearTimeout(this._blinkTimeout);
-            this._markAsDirty();
-
-            this.onBlurObservable.notifyObservers(this);
-        }
+        this.onBlurObservable.notifyObservers(this);
+    }
 
 
-        /** @hidden */
-        public onFocus(): void {
-            this._scrollLeft = null;
-            this._isFocused = true;
-            this._blinkIsEven = false;
-            this._cursorOffset = 0;
-            this._markAsDirty();
+    /** @hidden */
+    public onFocus(): void {
+        this._scrollLeft = null;
+        this._isFocused = true;
+        this._blinkIsEven = false;
+        this._cursorOffset = 0;
+        this._markAsDirty();
 
 
-            this.onFocusObservable.notifyObservers(this);
+        this.onFocusObservable.notifyObservers(this);
 
 
-            if (navigator.userAgent.indexOf("Mobile") !== -1) {
-                let value = prompt(this.promptMessage);
+        if (navigator.userAgent.indexOf("Mobile") !== -1) {
+            let value = prompt(this.promptMessage);
 
 
-                if (value !== null) {
-                    this.text = value;
-                }
-                this._host.focusedControl = null;
-                return;
+            if (value !== null) {
+                this.text = value;
             }
             }
+            this._host.focusedControl = null;
+            return;
         }
         }
+    }
 
 
-        protected _getTypeName(): string {
-            return "InputText";
-        }
+    protected _getTypeName(): string {
+        return "InputText";
+    }
 
 
-        /** @hidden */
-        public processKey(keyCode: number, key?: string) {
-            // Specific cases
-            switch (keyCode) {
-                case 32: //SPACE
-                    key = " "; //ie11 key for space is "Spacebar"
-                    break;
-                case 8: // BACKSPACE
-                    if (this._text && this._text.length > 0) {
-                        if (this._cursorOffset === 0) {
-                            this.text = this._text.substr(0, this._text.length - 1);
-                        } else {
-                            let deletePosition = this._text.length - this._cursorOffset;
-                            if (deletePosition > 0) {
-                                this.text = this._text.slice(0, deletePosition - 1) + this._text.slice(deletePosition);
-                            }
-                        }
-                    }
-                    return;
-                case 46: // DELETE
-                    if (this._text && this._text.length > 0) {
+    /** @hidden */
+    public processKey(keyCode: number, key?: string) {
+        // Specific cases
+        switch (keyCode) {
+            case 32: //SPACE
+                key = " "; //ie11 key for space is "Spacebar"
+                break;
+            case 8: // BACKSPACE
+                if (this._text && this._text.length > 0) {
+                    if (this._cursorOffset === 0) {
+                        this.text = this._text.substr(0, this._text.length - 1);
+                    } else {
                         let deletePosition = this._text.length - this._cursorOffset;
                         let deletePosition = this._text.length - this._cursorOffset;
-                        this.text = this._text.slice(0, deletePosition) + this._text.slice(deletePosition + 1);
-                        this._cursorOffset--;
-                    }
-                    return;
-                case 13: // RETURN
-                    this._host.focusedControl = null;
-                    return;
-                case 35: // END
-                    this._cursorOffset = 0;
-                    this._blinkIsEven = false;
-                    this._markAsDirty();
-                    return;
-                case 36: // HOME
-                    this._cursorOffset = this._text.length;
-                    this._blinkIsEven = false;
-                    this._markAsDirty();
-                    return;
-                case 37: // LEFT
-                    this._cursorOffset++;
-                    if (this._cursorOffset > this._text.length) {
-                        this._cursorOffset = this._text.length;
+                        if (deletePosition > 0) {
+                            this.text = this._text.slice(0, deletePosition - 1) + this._text.slice(deletePosition);
+                        }
                     }
                     }
-                    this._blinkIsEven = false;
-                    this._markAsDirty();
-                    return;
-                case 39: // RIGHT
+                }
+                return;
+            case 46: // DELETE
+                if (this._text && this._text.length > 0) {
+                    let deletePosition = this._text.length - this._cursorOffset;
+                    this.text = this._text.slice(0, deletePosition) + this._text.slice(deletePosition + 1);
                     this._cursorOffset--;
                     this._cursorOffset--;
-                    if (this._cursorOffset < 0) {
-                        this._cursorOffset = 0;
-                    }
-                    this._blinkIsEven = false;
-                    this._markAsDirty();
-                    return;
-                case 222: // Dead
-                    this.deadKey = true;
-                    return;
-            }
+                }
+                return;
+            case 13: // RETURN
+                this._host.focusedControl = null;
+                return;
+            case 35: // END
+                this._cursorOffset = 0;
+                this._blinkIsEven = false;
+                this._markAsDirty();
+                return;
+            case 36: // HOME
+                this._cursorOffset = this._text.length;
+                this._blinkIsEven = false;
+                this._markAsDirty();
+                return;
+            case 37: // LEFT
+                this._cursorOffset++;
+                if (this._cursorOffset > this._text.length) {
+                    this._cursorOffset = this._text.length;
+                }
+                this._blinkIsEven = false;
+                this._markAsDirty();
+                return;
+            case 39: // RIGHT
+                this._cursorOffset--;
+                if (this._cursorOffset < 0) {
+                    this._cursorOffset = 0;
+                }
+                this._blinkIsEven = false;
+                this._markAsDirty();
+                return;
+            case 222: // Dead
+                this.deadKey = true;
+                return;
+        }
 
 
-            // Printable characters
-            if (key &&
-                ((keyCode === -1) ||                     // Direct access
-                 (keyCode === 32) ||                     // Space
-                 (keyCode > 47 && keyCode < 58) ||       // Numbers
-                 (keyCode > 64 && keyCode < 91) ||       // Letters
-                 (keyCode > 185 && keyCode < 193) ||     // Special characters
-                 (keyCode > 218 && keyCode < 223) ||     // Special characters
-                 (keyCode > 95 && keyCode < 112))) {     // Numpad
-                this._currentKey = key;
-                this.onBeforeKeyAddObservable.notifyObservers(this);
-                key = this._currentKey;
-                if (this._addKey) {
-                    if (this._cursorOffset === 0) {
-                        this.text += key;
-                    } else {
-                        let insertPosition = this._text.length - this._cursorOffset;
+        // Printable characters
+        if (key &&
+            ((keyCode === -1) ||                     // Direct access
+                (keyCode === 32) ||                     // Space
+                (keyCode > 47 && keyCode < 58) ||       // Numbers
+                (keyCode > 64 && keyCode < 91) ||       // Letters
+                (keyCode > 185 && keyCode < 193) ||     // Special characters
+                (keyCode > 218 && keyCode < 223) ||     // Special characters
+                (keyCode > 95 && keyCode < 112))) {     // Numpad
+            this._currentKey = key;
+            this.onBeforeKeyAddObservable.notifyObservers(this);
+            key = this._currentKey;
+            if (this._addKey) {
+                if (this._cursorOffset === 0) {
+                    this.text += key;
+                } else {
+                    let insertPosition = this._text.length - this._cursorOffset;
 
 
-                        this.text = this._text.slice(0, insertPosition) + key + this._text.slice(insertPosition);
-                    }
+                    this.text = this._text.slice(0, insertPosition) + key + this._text.slice(insertPosition);
                 }
                 }
             }
             }
         }
         }
+    }
 
 
-        /** @hidden */
-        public processKeyboard(evt: KeyboardEvent): void {
-            this.processKey(evt.keyCode, evt.key);
-        }
-
-        public _draw(parentMeasure: Measure, context: CanvasRenderingContext2D): void {
-            context.save();
+    /** @hidden */
+    public processKeyboard(evt: KeyboardEvent): void {
+        this.processKey(evt.keyCode, evt.key);
+    }
 
 
-            this._applyStates(context);
-            if (this._processMeasures(parentMeasure, context)) {
+    public _draw(parentMeasure: Measure, context: CanvasRenderingContext2D): void {
+        context.save();
 
 
-                if (this.shadowBlur || this.shadowOffsetX || this.shadowOffsetY) {
-                    context.shadowColor = this.shadowColor;
-                    context.shadowBlur = this.shadowBlur;
-                    context.shadowOffsetX = this.shadowOffsetX;
-                    context.shadowOffsetY = this.shadowOffsetY;
-                }
+        this._applyStates(context);
+        if (this._processMeasures(parentMeasure, context)) {
 
 
-                // Background
-                if (this._isFocused) {
-                    if (this._focusedBackground) {
-                        context.fillStyle = this._focusedBackground;
+            if (this.shadowBlur || this.shadowOffsetX || this.shadowOffsetY) {
+                context.shadowColor = this.shadowColor;
+                context.shadowBlur = this.shadowBlur;
+                context.shadowOffsetX = this.shadowOffsetX;
+                context.shadowOffsetY = this.shadowOffsetY;
+            }
 
 
-                        context.fillRect(this._currentMeasure.left, this._currentMeasure.top, this._currentMeasure.width, this._currentMeasure.height);
-                    }
-                } else if (this._background) {
-                    context.fillStyle = this._background;
+            // Background
+            if (this._isFocused) {
+                if (this._focusedBackground) {
+                    context.fillStyle = this._focusedBackground;
 
 
                     context.fillRect(this._currentMeasure.left, this._currentMeasure.top, this._currentMeasure.width, this._currentMeasure.height);
                     context.fillRect(this._currentMeasure.left, this._currentMeasure.top, this._currentMeasure.width, this._currentMeasure.height);
                 }
                 }
+            } else if (this._background) {
+                context.fillStyle = this._background;
 
 
-                if (this.shadowBlur || this.shadowOffsetX || this.shadowOffsetY) {
-                    context.shadowBlur = 0;
-                    context.shadowOffsetX = 0;
-                    context.shadowOffsetY = 0;
-                }
+                context.fillRect(this._currentMeasure.left, this._currentMeasure.top, this._currentMeasure.width, this._currentMeasure.height);
+            }
 
 
-                if (!this._fontOffset) {
-                    this._fontOffset = Control._GetFontOffset(context.font);
-                }
+            if (this.shadowBlur || this.shadowOffsetX || this.shadowOffsetY) {
+                context.shadowBlur = 0;
+                context.shadowOffsetX = 0;
+                context.shadowOffsetY = 0;
+            }
 
 
-                // Text
-                let clipTextLeft = this._currentMeasure.left + this._margin.getValueInPixel(this._host, parentMeasure.width);
-                if (this.color) {
-                    context.fillStyle = this.color;
-                }
+            if (!this._fontOffset) {
+                this._fontOffset = Control._GetFontOffset(context.font);
+            }
 
 
-                let text = this._beforeRenderText(this._text);
+            // Text
+            let clipTextLeft = this._currentMeasure.left + this._margin.getValueInPixel(this._host, parentMeasure.width);
+            if (this.color) {
+                context.fillStyle = this.color;
+            }
 
 
-                if (!this._isFocused && !this._text && this._placeholderText) {
-                    text = this._placeholderText;
+            let text = this._beforeRenderText(this._text);
 
 
-                    if (this._placeholderColor) {
-                        context.fillStyle = this._placeholderColor;
-                    }
-                }
+            if (!this._isFocused && !this._text && this._placeholderText) {
+                text = this._placeholderText;
 
 
-                this._textWidth = context.measureText(text).width;
-                let marginWidth = this._margin.getValueInPixel(this._host, parentMeasure.width) * 2;
-                if (this._autoStretchWidth) {
-                    this.width = Math.min(this._maxWidth.getValueInPixel(this._host, parentMeasure.width), this._textWidth + marginWidth) + "px";
+                if (this._placeholderColor) {
+                    context.fillStyle = this._placeholderColor;
                 }
                 }
+            }
 
 
-                let rootY = this._fontOffset.ascent + (this._currentMeasure.height - this._fontOffset.height) / 2;
-                let availableWidth = this._width.getValueInPixel(this._host, parentMeasure.width) - marginWidth;
-                context.save();
-                context.beginPath();
-                context.rect(clipTextLeft, this._currentMeasure.top + (this._currentMeasure.height - this._fontOffset.height) / 2, availableWidth + 2, this._currentMeasure.height);
-                context.clip();
-
-                if (this._isFocused && this._textWidth > availableWidth) {
-                    let textLeft = clipTextLeft - this._textWidth + availableWidth;
-                    if (!this._scrollLeft) {
-                        this._scrollLeft = textLeft;
-                    }
-                } else {
-                    this._scrollLeft = clipTextLeft;
+            this._textWidth = context.measureText(text).width;
+            let marginWidth = this._margin.getValueInPixel(this._host, parentMeasure.width) * 2;
+            if (this._autoStretchWidth) {
+                this.width = Math.min(this._maxWidth.getValueInPixel(this._host, parentMeasure.width), this._textWidth + marginWidth) + "px";
+            }
+
+            let rootY = this._fontOffset.ascent + (this._currentMeasure.height - this._fontOffset.height) / 2;
+            let availableWidth = this._width.getValueInPixel(this._host, parentMeasure.width) - marginWidth;
+            context.save();
+            context.beginPath();
+            context.rect(clipTextLeft, this._currentMeasure.top + (this._currentMeasure.height - this._fontOffset.height) / 2, availableWidth + 2, this._currentMeasure.height);
+            context.clip();
+
+            if (this._isFocused && this._textWidth > availableWidth) {
+                let textLeft = clipTextLeft - this._textWidth + availableWidth;
+                if (!this._scrollLeft) {
+                    this._scrollLeft = textLeft;
                 }
                 }
+            } else {
+                this._scrollLeft = clipTextLeft;
+            }
 
 
-                context.fillText(text, this._scrollLeft, this._currentMeasure.top + rootY);
-
-                // Cursor
-                if (this._isFocused) {
-
-                    // Need to move cursor
-                    if (this._clickedCoordinate) {
-                        var rightPosition = this._scrollLeft + this._textWidth;
-                        var absoluteCursorPosition = rightPosition - this._clickedCoordinate;
-                        var currentSize = 0;
-                        this._cursorOffset = 0;
-                        var previousDist = 0;
-                        do {
-                            if (this._cursorOffset) {
-                                previousDist = Math.abs(absoluteCursorPosition - currentSize);
-                            }
-                            this._cursorOffset++;
-                            currentSize = context.measureText(text.substr(text.length - this._cursorOffset, this._cursorOffset)).width;
-
-                        } while (currentSize < absoluteCursorPosition && (text.length >= this._cursorOffset));
-
-                        // Find closest move
-                        if (Math.abs(absoluteCursorPosition - currentSize) > previousDist) {
-                            this._cursorOffset--;
-                        }
+            context.fillText(text, this._scrollLeft, this._currentMeasure.top + rootY);
 
 
-                        this._blinkIsEven = false;
-                        this._clickedCoordinate = null;
-                    }
+            // Cursor
+            if (this._isFocused) {
 
 
-                    // Render cursor
-                    if (!this._blinkIsEven) {
-                        let cursorOffsetText = this.text.substr(this._text.length - this._cursorOffset);
-                        let cursorOffsetWidth = context.measureText(cursorOffsetText).width;
-                        let cursorLeft = this._scrollLeft + this._textWidth - cursorOffsetWidth;
-
-                        if (cursorLeft < clipTextLeft) {
-                            this._scrollLeft += (clipTextLeft - cursorLeft);
-                            cursorLeft = clipTextLeft;
-                            this._markAsDirty();
-                        } else if (cursorLeft > clipTextLeft + availableWidth) {
-                            this._scrollLeft += (clipTextLeft + availableWidth - cursorLeft);
-                            cursorLeft = clipTextLeft + availableWidth;
-                            this._markAsDirty();
+                // Need to move cursor
+                if (this._clickedCoordinate) {
+                    var rightPosition = this._scrollLeft + this._textWidth;
+                    var absoluteCursorPosition = rightPosition - this._clickedCoordinate;
+                    var currentSize = 0;
+                    this._cursorOffset = 0;
+                    var previousDist = 0;
+                    do {
+                        if (this._cursorOffset) {
+                            previousDist = Math.abs(absoluteCursorPosition - currentSize);
                         }
                         }
-                        context.fillRect(cursorLeft, this._currentMeasure.top + (this._currentMeasure.height - this._fontOffset.height) / 2, 2, this._fontOffset.height);
+                        this._cursorOffset++;
+                        currentSize = context.measureText(text.substr(text.length - this._cursorOffset, this._cursorOffset)).width;
+
+                    } while (currentSize < absoluteCursorPosition && (text.length >= this._cursorOffset));
+
+                    // Find closest move
+                    if (Math.abs(absoluteCursorPosition - currentSize) > previousDist) {
+                        this._cursorOffset--;
                     }
                     }
 
 
-                    clearTimeout(this._blinkTimeout);
-                    this._blinkTimeout = setTimeout(() => {
-                        this._blinkIsEven = !this._blinkIsEven;
-                        this._markAsDirty();
-                    }, 500);
+                    this._blinkIsEven = false;
+                    this._clickedCoordinate = null;
                 }
                 }
 
 
-                context.restore();
+                // Render cursor
+                if (!this._blinkIsEven) {
+                    let cursorOffsetText = this.text.substr(this._text.length - this._cursorOffset);
+                    let cursorOffsetWidth = context.measureText(cursorOffsetText).width;
+                    let cursorLeft = this._scrollLeft + this._textWidth - cursorOffsetWidth;
 
 
-                // Border
-                if (this._thickness) {
-                    if (this.color) {
-                        context.strokeStyle = this.color;
+                    if (cursorLeft < clipTextLeft) {
+                        this._scrollLeft += (clipTextLeft - cursorLeft);
+                        cursorLeft = clipTextLeft;
+                        this._markAsDirty();
+                    } else if (cursorLeft > clipTextLeft + availableWidth) {
+                        this._scrollLeft += (clipTextLeft + availableWidth - cursorLeft);
+                        cursorLeft = clipTextLeft + availableWidth;
+                        this._markAsDirty();
                     }
                     }
-                    context.lineWidth = this._thickness;
-
-                    context.strokeRect(this._currentMeasure.left + this._thickness / 2, this._currentMeasure.top + this._thickness / 2,
-                        this._currentMeasure.width - this._thickness, this._currentMeasure.height - this._thickness);
+                    context.fillRect(cursorLeft, this._currentMeasure.top + (this._currentMeasure.height - this._fontOffset.height) / 2, 2, this._fontOffset.height);
                 }
                 }
+
+                clearTimeout(this._blinkTimeout);
+                this._blinkTimeout = <any>setTimeout(() => {
+                    this._blinkIsEven = !this._blinkIsEven;
+                    this._markAsDirty();
+                }, 500);
             }
             }
+
             context.restore();
             context.restore();
-        }
 
 
-        public _onPointerDown(target: Control, coordinates: Vector2, pointerId: number, buttonIndex: number): boolean {
-            if (!super._onPointerDown(target, coordinates, pointerId, buttonIndex)) {
-                return false;
-            }
+            // Border
+            if (this._thickness) {
+                if (this.color) {
+                    context.strokeStyle = this.color;
+                }
+                context.lineWidth = this._thickness;
 
 
-            this._clickedCoordinate = coordinates.x;
-            if (this._host.focusedControl === this) {
-                // Move cursor
-                clearTimeout(this._blinkTimeout);
-                this._markAsDirty();
-                return true;
+                context.strokeRect(this._currentMeasure.left + this._thickness / 2, this._currentMeasure.top + this._thickness / 2,
+                    this._currentMeasure.width - this._thickness, this._currentMeasure.height - this._thickness);
             }
             }
-            this._host.focusedControl = this;
-
-            return true;
         }
         }
+        context.restore();
+    }
 
 
-        public _onPointerUp(target: Control, coordinates: Vector2, pointerId: number, buttonIndex: number, notifyClick: boolean): void {
-            super._onPointerUp(target, coordinates, pointerId, buttonIndex, notifyClick);
+    public _onPointerDown(target: Control, coordinates: Vector2, pointerId: number, buttonIndex: number): boolean {
+        if (!super._onPointerDown(target, coordinates, pointerId, buttonIndex)) {
+            return false;
         }
         }
 
 
-        protected _beforeRenderText(text: string): string {
-            return text;
+        this._clickedCoordinate = coordinates.x;
+        if (this._host.focusedControl === this) {
+            // Move cursor
+            clearTimeout(this._blinkTimeout);
+            this._markAsDirty();
+            return true;
         }
         }
+        this._host.focusedControl = this;
+
+        return true;
+    }
 
 
-        public dispose() {
-            super.dispose();
+    public _onPointerUp(target: Control, coordinates: Vector2, pointerId: number, buttonIndex: number, notifyClick: boolean): void {
+        super._onPointerUp(target, coordinates, pointerId, buttonIndex, notifyClick);
+    }
 
 
-            this.onBlurObservable.clear();
-            this.onFocusObservable.clear();
-            this.onTextChangedObservable.clear();
-        }
+    protected _beforeRenderText(text: string): string {
+        return text;
+    }
+
+    public dispose() {
+        super.dispose();
+
+        this.onBlurObservable.clear();
+        this.onFocusObservable.clear();
+        this.onTextChangedObservable.clear();
     }
     }
 }
 }

+ 216 - 215
gui/src/2D/controls/line.ts

@@ -1,244 +1,245 @@
-/// <reference path="../../../../dist/preview release/babylon.d.ts"/>
-
-module BABYLON.GUI {
-    /** Class used to render 2D lines */
-    export class Line extends Control {
-        private _lineWidth = 1;
-        private _x1 = new ValueAndUnit(0);
-        private _y1 = new ValueAndUnit(0);
-        private _x2 = new ValueAndUnit(0);
-        private _y2 = new ValueAndUnit(0);
-        private _dash = new Array<number>();
-        private _connectedControl: Control;
-        private _connectedControlDirtyObserver: Nullable<Observer<Control>>;
-
-        /** Gets or sets the dash pattern */
-        public get dash(): Array<number> {
-            return this._dash;
-        }
-
-        public set dash(value: Array<number>) {
-            if (this._dash === value) {
-                return;
-            }
-
-            this._dash = value;
-            this._markAsDirty();
-        }     
-
-        /** Gets or sets the control connected with the line end */
-        public get connectedControl(): Control {
-            return this._connectedControl;
+import { Control } from "./control";
+import { ValueAndUnit } from "../valueAndUnit";
+import { Nullable, Observer, Vector3, Scene, Tools, Matrix } from "babylonjs";
+import { Measure } from "../measure";
+
+/** Class used to render 2D lines */
+export class Line extends Control {
+    private _lineWidth = 1;
+    private _x1 = new ValueAndUnit(0);
+    private _y1 = new ValueAndUnit(0);
+    private _x2 = new ValueAndUnit(0);
+    private _y2 = new ValueAndUnit(0);
+    private _dash = new Array<number>();
+    private _connectedControl: Control;
+    private _connectedControlDirtyObserver: Nullable<Observer<Control>>;
+
+    /** Gets or sets the dash pattern */
+    public get dash(): Array<number> {
+        return this._dash;
+    }
+
+    public set dash(value: Array<number>) {
+        if (this._dash === value) {
+            return;
         }
         }
 
 
-        public set connectedControl(value: Control) {
-            if (this._connectedControl === value) {
-                return;
-            }
+        this._dash = value;
+        this._markAsDirty();
+    }
 
 
-            if (this._connectedControlDirtyObserver && this._connectedControl) {
-                this._connectedControl.onDirtyObservable.remove(this._connectedControlDirtyObserver);
-                this._connectedControlDirtyObserver = null;
-            }
+    /** Gets or sets the control connected with the line end */
+    public get connectedControl(): Control {
+        return this._connectedControl;
+    }
 
 
-            if (value) {
-                this._connectedControlDirtyObserver = value.onDirtyObservable.add(() => this._markAsDirty());
-            }            
+    public set connectedControl(value: Control) {
+        if (this._connectedControl === value) {
+            return;
+        }
 
 
-            this._connectedControl = value;
-            this._markAsDirty();
-        }              
+        if (this._connectedControlDirtyObserver && this._connectedControl) {
+            this._connectedControl.onDirtyObservable.remove(this._connectedControlDirtyObserver);
+            this._connectedControlDirtyObserver = null;
+        }
 
 
-        /** Gets or sets start coordinates on X axis */
-        public get x1(): string | number  {
-            return this._x1.toString(this._host);
+        if (value) {
+            this._connectedControlDirtyObserver = value.onDirtyObservable.add(() => this._markAsDirty());
         }
         }
 
 
-        public set x1(value: string | number ) {
-            if (this._x1.toString(this._host) === value) {
-                return;
-            }
+        this._connectedControl = value;
+        this._markAsDirty();
+    }
 
 
-            if (this._x1.fromString(value)) {
-                this._markAsDirty();
-            }
-        }    
+    /** Gets or sets start coordinates on X axis */
+    public get x1(): string | number {
+        return this._x1.toString(this._host);
+    }
 
 
-        /** Gets or sets start coordinates on Y axis */        
-        public get y1(): string | number  {
-            return this._y1.toString(this._host);
+    public set x1(value: string | number) {
+        if (this._x1.toString(this._host) === value) {
+            return;
         }
         }
 
 
-        public set y1(value: string | number ) {
-            if (this._y1.toString(this._host) === value) {
-                return;
-            }
+        if (this._x1.fromString(value)) {
+            this._markAsDirty();
+        }
+    }
 
 
-            if (this._y1.fromString(value)) {
-                this._markAsDirty();
-            }
-        }     
+    /** Gets or sets start coordinates on Y axis */
+    public get y1(): string | number {
+        return this._y1.toString(this._host);
+    }
 
 
-        /** Gets or sets end coordinates on X axis */        
-        public get x2(): string | number  {
-            return this._x2.toString(this._host);
+    public set y1(value: string | number) {
+        if (this._y1.toString(this._host) === value) {
+            return;
         }
         }
 
 
-        public set x2(value: string | number ) {
-            if (this._x2.toString(this._host) === value) {
-                return;
-            }
+        if (this._y1.fromString(value)) {
+            this._markAsDirty();
+        }
+    }
 
 
-            if (this._x2.fromString(value)) {
-                this._markAsDirty();
-            }
-        }    
+    /** Gets or sets end coordinates on X axis */
+    public get x2(): string | number {
+        return this._x2.toString(this._host);
+    }
 
 
-        /** Gets or sets end coordinates on Y axis */        
-        public get y2(): string | number  {
-            return this._y2.toString(this._host);
+    public set x2(value: string | number) {
+        if (this._x2.toString(this._host) === value) {
+            return;
         }
         }
 
 
-        public set y2(value: string | number ) {
-            if (this._y2.toString(this._host) === value) {
-                return;
-            }
-
-            if (this._y2.fromString(value)) {
-                this._markAsDirty();
-            }
-        }                       
-        
-        /** Gets or sets line width */
-        public get lineWidth(): number {
-            return this._lineWidth;
+        if (this._x2.fromString(value)) {
+            this._markAsDirty();
         }
         }
+    }
 
 
-        public set lineWidth(value: number) {
-            if (this._lineWidth === value) {
-                return;
-            }
+    /** Gets or sets end coordinates on Y axis */
+    public get y2(): string | number {
+        return this._y2.toString(this._host);
+    }
 
 
-            this._lineWidth = value;
+    public set y2(value: string | number) {
+        if (this._y2.toString(this._host) === value) {
+            return;
+        }
+
+        if (this._y2.fromString(value)) {
             this._markAsDirty();
             this._markAsDirty();
-        }   
+        }
+    }
+
+    /** Gets or sets line width */
+    public get lineWidth(): number {
+        return this._lineWidth;
+    }
 
 
-        /** Gets or sets horizontal alignment */
-        public set horizontalAlignment(value: number) {
+    public set lineWidth(value: number) {
+        if (this._lineWidth === value) {
             return;
             return;
-        } 
+        }
+
+        this._lineWidth = value;
+        this._markAsDirty();
+    }
+
+    /** Gets or sets horizontal alignment */
+    public set horizontalAlignment(value: number) {
+        return;
+    }
+
+    /** Gets or sets vertical alignment */
+    public set verticalAlignment(value: number) {
+        return;
+    }
+
+    private get _effectiveX2(): number {
+        return (this._connectedControl ? this._connectedControl.centerX : 0) + this._x2.getValue(this._host);
+    }
+
+    private get _effectiveY2(): number {
+        return (this._connectedControl ? this._connectedControl.centerY : 0) + this._y2.getValue(this._host);
+    }
+
+    /**
+     * Creates a new Line
+     * @param name defines the control name
+     */
+    constructor(public name?: string) {
+        super(name);
+
+        this.isHitTestVisible = false;
+        this._horizontalAlignment = Control.HORIZONTAL_ALIGNMENT_LEFT;
+        this._verticalAlignment = Control.VERTICAL_ALIGNMENT_TOP;
+    }
+
+    protected _getTypeName(): string {
+        return "Line";
+    }
+
+    public _draw(parentMeasure: Measure, context: CanvasRenderingContext2D): void {
+        context.save();
+
+        if (this.shadowBlur || this.shadowOffsetX || this.shadowOffsetY) {
+            context.shadowColor = this.shadowColor;
+            context.shadowBlur = this.shadowBlur;
+            context.shadowOffsetX = this.shadowOffsetX;
+            context.shadowOffsetY = this.shadowOffsetY;
+        }
+
+        this._applyStates(context);
+        if (this._processMeasures(parentMeasure, context)) {
+            context.strokeStyle = this.color;
+            context.lineWidth = this._lineWidth;
+            context.setLineDash(this._dash);
+
+            context.beginPath();
+            context.moveTo(this._x1.getValue(this._host), this._y1.getValue(this._host));
+
+            context.lineTo(this._effectiveX2, this._effectiveY2);
 
 
-        /** Gets or sets vertical alignment */
-        public set verticalAlignment(value: number) {
+            context.stroke();
+        }
+
+        context.restore();
+    }
+
+    public _measure(): void {
+        // Width / Height
+        this._currentMeasure.width = Math.abs(this._x1.getValue(this._host) - this._effectiveX2) + this._lineWidth;
+        this._currentMeasure.height = Math.abs(this._y1.getValue(this._host) - this._effectiveY2) + this._lineWidth;
+    }
+
+    protected _computeAlignment(parentMeasure: Measure, context: CanvasRenderingContext2D): void {
+        this._currentMeasure.left = Math.min(this._x1.getValue(this._host), this._effectiveX2) - this._lineWidth / 2;
+        this._currentMeasure.top = Math.min(this._y1.getValue(this._host), this._effectiveY2) - this._lineWidth / 2;
+    }
+
+    /**
+     * Move one end of the line given 3D cartesian coordinates.
+     * @param position Targeted world position
+     * @param scene Scene
+     * @param end (opt) Set to true to assign x2 and y2 coordinates of the line. Default assign to x1 and y1.
+     */
+    public moveToVector3(position: Vector3, scene: Scene, end: boolean = false): void {
+        if (!this._host || this._root !== this._host._rootContainer) {
+            Tools.Error("Cannot move a control to a vector3 if the control is not at root level");
             return;
             return;
-        }    
+        }
+
+        var globalViewport = this._host._getGlobalViewport(scene);
+        var projectedPosition = Vector3.Project(position, Matrix.Identity(), scene.getTransformMatrix(), globalViewport);
 
 
-        private get _effectiveX2(): number {
-            return (this._connectedControl ? this._connectedControl.centerX : 0) + this._x2.getValue(this._host);
-        }   
-
-        private get _effectiveY2(): number {
-            return (this._connectedControl ? this._connectedControl.centerY : 0) + this._y2.getValue(this._host);
-        }           
-
-        /**
-         * Creates a new Line
-         * @param name defines the control name
-         */
-        constructor(public name?: string) {
-            super(name);
-
-            this.isHitTestVisible = false;
-            this._horizontalAlignment = Control.HORIZONTAL_ALIGNMENT_LEFT;
-            this._verticalAlignment = Control.VERTICAL_ALIGNMENT_TOP;            
-        }
-
-        protected _getTypeName(): string {
-            return "Line";
-        }              
-
-        public _draw(parentMeasure: Measure, context: CanvasRenderingContext2D): void {
-            context.save();
-
-            if(this.shadowBlur || this.shadowOffsetX || this.shadowOffsetY){
-                context.shadowColor = this.shadowColor;
-                context.shadowBlur = this.shadowBlur;
-                context.shadowOffsetX = this.shadowOffsetX;
-                context.shadowOffsetY = this.shadowOffsetY;
-            }
-
-            this._applyStates(context);
-            if (this._processMeasures(parentMeasure, context)) {
-                context.strokeStyle = this.color;
-                context.lineWidth = this._lineWidth;
-                context.setLineDash(this._dash);
-
-                context.beginPath();
-                context.moveTo(this._x1.getValue(this._host), this._y1.getValue(this._host));
-
-                context.lineTo(this._effectiveX2, this._effectiveY2);
-
-                context.stroke();
-            }
-
-            context.restore();
-        }
-
-        public _measure(): void {  
-            // Width / Height
-            this._currentMeasure.width = Math.abs(this._x1.getValue(this._host) - this._effectiveX2) + this._lineWidth;
-            this._currentMeasure.height = Math.abs(this._y1.getValue(this._host) - this._effectiveY2) + this._lineWidth;
-        }
-
-        protected _computeAlignment(parentMeasure: Measure, context: CanvasRenderingContext2D): void {          
-            this._currentMeasure.left = Math.min(this._x1.getValue(this._host), this._effectiveX2) - this._lineWidth / 2;
-            this._currentMeasure.top = Math.min(this._y1.getValue(this._host), this._effectiveY2) - this._lineWidth / 2;            
-        }
-
-        /**
-         * Move one end of the line given 3D cartesian coordinates.
-         * @param position Targeted world position
-         * @param scene Scene
-         * @param end (opt) Set to true to assign x2 and y2 coordinates of the line. Default assign to x1 and y1.
-         */
-        public moveToVector3(position: Vector3, scene: Scene, end: boolean = false): void {
-            if (!this._host || this._root !== this._host._rootContainer) {
-                Tools.Error("Cannot move a control to a vector3 if the control is not at root level");
-                return;
-            }
-
-            var globalViewport = this._host._getGlobalViewport(scene);
-            var projectedPosition = Vector3.Project(position, Matrix.Identity(), scene.getTransformMatrix(), globalViewport);
-
-            this._moveToProjectedPosition(projectedPosition, end)
-
-            if (projectedPosition.z < 0 || projectedPosition.z > 1) {
-                this.notRenderable = true;
-                return;
-            }
-            this.notRenderable = false;
-        }
-
-        /**
-         * Move one end of the line to a position in screen absolute space.
-         * @param projectedPosition Position in screen absolute space (X, Y)
-         * @param end (opt) Set to true to assign x2 and y2 coordinates of the line. Default assign to x1 and y1.
-         */
-        public _moveToProjectedPosition(projectedPosition: Vector3, end: boolean = false): void {
-            let x: string = (projectedPosition.x + this._linkOffsetX.getValue(this._host)) + "px";
-            let y: string = (projectedPosition.y + this._linkOffsetY.getValue(this._host)) + "px";
-
-            if (end) {
-                this.x2 = x;
-                this.y2 = y;
-                this._x2.ignoreAdaptiveScaling = true;
-                this._y2.ignoreAdaptiveScaling = true;
-            } else {
-                this.x1 = x;
-                this.y1 = y;
-                this._x1.ignoreAdaptiveScaling = true;
-                this._y1.ignoreAdaptiveScaling = true;
-            }
-        }
-    }    
-}
+        this._moveToProjectedPosition(projectedPosition, end)
+
+        if (projectedPosition.z < 0 || projectedPosition.z > 1) {
+            this.notRenderable = true;
+            return;
+        }
+        this.notRenderable = false;
+    }
+
+    /**
+     * Move one end of the line to a position in screen absolute space.
+     * @param projectedPosition Position in screen absolute space (X, Y)
+     * @param end (opt) Set to true to assign x2 and y2 coordinates of the line. Default assign to x1 and y1.
+     */
+    public _moveToProjectedPosition(projectedPosition: Vector3, end: boolean = false): void {
+        let x: string = (projectedPosition.x + this._linkOffsetX.getValue(this._host)) + "px";
+        let y: string = (projectedPosition.y + this._linkOffsetY.getValue(this._host)) + "px";
+
+        if (end) {
+            this.x2 = x;
+            this.y2 = y;
+            this._x2.ignoreAdaptiveScaling = true;
+            this._y2.ignoreAdaptiveScaling = true;
+        } else {
+            this.x1 = x;
+            this.y1 = y;
+            this._x1.ignoreAdaptiveScaling = true;
+            this._y1.ignoreAdaptiveScaling = true;
+        }
+    }
+}   

+ 187 - 186
gui/src/2D/controls/multiLine.ts

@@ -1,248 +1,249 @@
-/// <reference path="../../../../dist/preview release/babylon.d.ts"/>
+import { Control } from "./control";
+import { MultiLinePoint } from "../multiLinePoint";
+import { Nullable, AbstractMesh } from "babylonjs";
+import { Measure } from "../measure";
 
 
-module BABYLON.GUI {
+
+/**
+ * Class used to create multi line control
+ */
+export class MultiLine extends Control {
+
+    private _lineWidth: number = 1;
+    private _dash: number[];
+    private _points: Nullable<MultiLinePoint>[];
+
+    private _minX: Nullable<number>;
+    private _minY: Nullable<number>;
+    private _maxX: Nullable<number>;
+    private _maxY: Nullable<number>;
 
 
     /**
     /**
-     * Class used to create multi line control
+     * Creates a new MultiLine
+     * @param name defines the control name
      */
      */
-    export class MultiLine extends Control {
-
-        private _lineWidth: number = 1;
-        private _dash: number[];
-        private _points: Nullable<MultiLinePoint>[];
-
-        private _minX: Nullable<number>;
-        private _minY: Nullable<number>;
-        private _maxX: Nullable<number>;
-        private _maxY: Nullable<number>;
-
-        /**
-         * Creates a new MultiLine
-         * @param name defines the control name
-         */
-        constructor(public name?: string) {
-            super(name);
-
-            this.isHitTestVisible = false;
-            this._horizontalAlignment = Control.HORIZONTAL_ALIGNMENT_LEFT;
-            this._verticalAlignment = Control.VERTICAL_ALIGNMENT_TOP;
-
-            this._dash = [];
-            this._points = [];
-        }
+    constructor(public name?: string) {
+        super(name);
 
 
-        /** Gets or sets dash pattern */
-        public get dash(): Array<number> {
-            return this._dash;
-        }
+        this.isHitTestVisible = false;
+        this._horizontalAlignment = Control.HORIZONTAL_ALIGNMENT_LEFT;
+        this._verticalAlignment = Control.VERTICAL_ALIGNMENT_TOP;
 
 
-        public set dash(value: Array<number>) {
-            if (this._dash === value) {
-                return;
-            }
+        this._dash = [];
+        this._points = [];
+    }
+
+    /** Gets or sets dash pattern */
+    public get dash(): Array<number> {
+        return this._dash;
+    }
 
 
-            this._dash = value;
-            this._markAsDirty();
+    public set dash(value: Array<number>) {
+        if (this._dash === value) {
+            return;
         }
         }
 
 
-        /**
-         * Gets point stored at specified index
-         * @param index defines the index to look for
-         * @returns the requested point if found
-         */
-        public getAt(index: number): MultiLinePoint {
-            if (!this._points[index]) {
-                this._points[index] = new MultiLinePoint(this);
-            }
+        this._dash = value;
+        this._markAsDirty();
+    }
 
 
-            return this._points[index] as MultiLinePoint;
+    /**
+     * Gets point stored at specified index
+     * @param index defines the index to look for
+     * @returns the requested point if found
+     */
+    public getAt(index: number): MultiLinePoint {
+        if (!this._points[index]) {
+            this._points[index] = new MultiLinePoint(this);
         }
         }
 
 
-        /** Function called when a point is updated */
-        public onPointUpdate = (): void => {
-            this._markAsDirty();
-        }
+        return this._points[index] as MultiLinePoint;
+    }
 
 
-        /**
-         * Adds new points to the point collection
-         * @param items defines the list of items (mesh, control or 2d coordiantes) to add 
-         * @returns the list of created MultiLinePoint
-         */
-        public add(...items: (AbstractMesh | Control | { x: string | number, y: string | number })[]): MultiLinePoint[] {
-            return items.map(item => this.push(item));
-        }
+    /** Function called when a point is updated */
+    public onPointUpdate = (): void => {
+        this._markAsDirty();
+    }
 
 
-        /**
-         * Adds a new point to the point collection
-         * @param item defines the item (mesh, control or 2d coordiantes) to add 
-         * @returns the created MultiLinePoint
-         */
-        public push(item?: (AbstractMesh | Control | { x: string | number, y: string | number })): MultiLinePoint {
-            var point: MultiLinePoint = this.getAt(this._points.length);
+    /**
+     * Adds new points to the point collection
+     * @param items defines the list of items (mesh, control or 2d coordiantes) to add 
+     * @returns the list of created MultiLinePoint
+     */
+    public add(...items: (AbstractMesh | Control | { x: string | number, y: string | number })[]): MultiLinePoint[] {
+        return items.map(item => this.push(item));
+    }
 
 
-            if (item == null) return point;
+    /**
+     * Adds a new point to the point collection
+     * @param item defines the item (mesh, control or 2d coordiantes) to add 
+     * @returns the created MultiLinePoint
+     */
+    public push(item?: (AbstractMesh | Control | { x: string | number, y: string | number })): MultiLinePoint {
+        var point: MultiLinePoint = this.getAt(this._points.length);
 
 
-            if (item instanceof AbstractMesh) {
-                point.mesh = item;
-            }
-            else if (item instanceof Control) {
-                point.control = item;
-            }
-            else if (item.x != null && item.y != null) {
-                point.x = item.x;
-                point.y = item.y;
-            }
+        if (item == null) return point;
 
 
-            return point;
+        if (item instanceof AbstractMesh) {
+            point.mesh = item;
+        }
+        else if (item instanceof Control) {
+            point.control = item;
+        }
+        else if (item.x != null && item.y != null) {
+            point.x = item.x;
+            point.y = item.y;
         }
         }
 
 
-        /**
-         * Remove a specific value or point from the active point collection
-         * @param value defines the value or point to remove
-         */
-        public remove(value: number | MultiLinePoint): void {
-            var index: number;
-            
-            if (value instanceof MultiLinePoint) {
-                index = this._points.indexOf(value);
-
-                if (index === -1) {
-                    return;
-                }
-            }
-            else {
-                index = value;
-            }
-            
-            var point: Nullable<MultiLinePoint> = this._points[index];
+        return point;
+    }
 
 
-            if (!point) {
+    /**
+     * Remove a specific value or point from the active point collection
+     * @param value defines the value or point to remove
+     */
+    public remove(value: number | MultiLinePoint): void {
+        var index: number;
+
+        if (value instanceof MultiLinePoint) {
+            index = this._points.indexOf(value);
+
+            if (index === -1) {
                 return;
                 return;
             }
             }
+        }
+        else {
+            index = value;
+        }
 
 
-            point.dispose();
+        var point: Nullable<MultiLinePoint> = this._points[index];
 
 
-            this._points.splice(index, 1);
-        }
-        
-        /** Gets or sets line width */
-        public get lineWidth(): number {
-            return this._lineWidth;
+        if (!point) {
+            return;
         }
         }
 
 
-        public set lineWidth(value: number) {
-            if (this._lineWidth === value) {
-                return;
-            }
+        point.dispose();
 
 
-            this._lineWidth = value;
-            this._markAsDirty();
-        }   
+        this._points.splice(index, 1);
+    }
 
 
-        public set horizontalAlignment(value: number) {
-            return;
-        } 
+    /** Gets or sets line width */
+    public get lineWidth(): number {
+        return this._lineWidth;
+    }
 
 
-        public set verticalAlignment(value: number) {
+    public set lineWidth(value: number) {
+        if (this._lineWidth === value) {
             return;
             return;
         }
         }
 
 
-        protected _getTypeName(): string {
-            return "MultiLine";
-        }              
-
-        public _draw(parentMeasure: Measure, context: CanvasRenderingContext2D): void {
-            context.save();
-
-            if (this.shadowBlur || this.shadowOffsetX || this.shadowOffsetY){
-                context.shadowColor = this.shadowColor;
-                context.shadowBlur = this.shadowBlur;
-                context.shadowOffsetX = this.shadowOffsetX;
-                context.shadowOffsetY = this.shadowOffsetY;
-            }
+        this._lineWidth = value;
+        this._markAsDirty();
+    }
 
 
-            this._applyStates(context);
+    public set horizontalAlignment(value: number) {
+        return;
+    }
 
 
-            if (this._processMeasures(parentMeasure, context)) {
-                context.strokeStyle = this.color;
-                context.lineWidth = this._lineWidth;
-                context.setLineDash(this._dash);
+    public set verticalAlignment(value: number) {
+        return;
+    }
 
 
-                context.beginPath();
+    protected _getTypeName(): string {
+        return "MultiLine";
+    }
 
 
-                var first: boolean = true; //first index is not necessarily 0
+    public _draw(parentMeasure: Measure, context: CanvasRenderingContext2D): void {
+        context.save();
 
 
-                this._points.forEach(point => {
-                    if (!point) {
-                        return;
-                    }
+        if (this.shadowBlur || this.shadowOffsetX || this.shadowOffsetY) {
+            context.shadowColor = this.shadowColor;
+            context.shadowBlur = this.shadowBlur;
+            context.shadowOffsetX = this.shadowOffsetX;
+            context.shadowOffsetY = this.shadowOffsetY;
+        }
 
 
-                    if (first) {
-                        context.moveTo(point._point.x, point._point.y);
+        this._applyStates(context);
 
 
-                        first = false;
-                    }
-                    else {
-                        context.lineTo(point._point.x, point._point.y);
-                    }
-                });
+        if (this._processMeasures(parentMeasure, context)) {
+            context.strokeStyle = this.color;
+            context.lineWidth = this._lineWidth;
+            context.setLineDash(this._dash);
 
 
-                context.stroke();
-            }
+            context.beginPath();
 
 
-            context.restore();
-        }
+            var first: boolean = true; //first index is not necessarily 0
 
 
-        protected _additionalProcessing(parentMeasure: Measure, context: CanvasRenderingContext2D): void {
-            this._minX = null;
-            this._minY = null;
-            this._maxX = null;
-            this._maxY = null;
-            
-            this._points.forEach((point, index) => {
+            this._points.forEach(point => {
                 if (!point) {
                 if (!point) {
                     return;
                     return;
                 }
                 }
 
 
-                point.translate();
+                if (first) {
+                    context.moveTo(point._point.x, point._point.y);
 
 
-                if (this._minX == null || point._point.x < this._minX) this._minX = point._point.x;
-                if (this._minY == null || point._point.y < this._minY) this._minY = point._point.y;
-                if (this._maxX == null || point._point.x > this._maxX) this._maxX = point._point.x;
-                if (this._maxY == null || point._point.y > this._maxY) this._maxY = point._point.y;
+                    first = false;
+                }
+                else {
+                    context.lineTo(point._point.x, point._point.y);
+                }
             });
             });
 
 
-            if (this._minX == null) this._minX = 0;
-            if (this._minY == null) this._minY = 0;
-            if (this._maxX == null) this._maxX = 0;
-            if (this._maxY == null) this._maxY = 0;
+            context.stroke();
         }
         }
 
 
-        public _measure(): void {
-            if (this._minX == null || this._maxX == null || this._minY == null || this._maxY == null) {
+        context.restore();
+    }
+
+    protected _additionalProcessing(parentMeasure: Measure, context: CanvasRenderingContext2D): void {
+        this._minX = null;
+        this._minY = null;
+        this._maxX = null;
+        this._maxY = null;
+
+        this._points.forEach((point, index) => {
+            if (!point) {
                 return;
                 return;
             }
             }
 
 
-            this._currentMeasure.width = Math.abs(this._maxX - this._minX) + this._lineWidth;
-            this._currentMeasure.height = Math.abs(this._maxY - this._minY) + this._lineWidth;
+            point.translate();
+
+            if (this._minX == null || point._point.x < this._minX) this._minX = point._point.x;
+            if (this._minY == null || point._point.y < this._minY) this._minY = point._point.y;
+            if (this._maxX == null || point._point.x > this._maxX) this._maxX = point._point.x;
+            if (this._maxY == null || point._point.y > this._maxY) this._maxY = point._point.y;
+        });
+
+        if (this._minX == null) this._minX = 0;
+        if (this._minY == null) this._minY = 0;
+        if (this._maxX == null) this._maxX = 0;
+        if (this._maxY == null) this._maxY = 0;
+    }
+
+    public _measure(): void {
+        if (this._minX == null || this._maxX == null || this._minY == null || this._maxY == null) {
+            return;
         }
         }
 
 
-        protected _computeAlignment(parentMeasure: Measure, context: CanvasRenderingContext2D): void {
-            if (this._minX == null || this._minY == null) {
-                return;
-            }
+        this._currentMeasure.width = Math.abs(this._maxX - this._minX) + this._lineWidth;
+        this._currentMeasure.height = Math.abs(this._maxY - this._minY) + this._lineWidth;
+    }
 
 
-            this._currentMeasure.left = this._minX - this._lineWidth / 2;
-            this._currentMeasure.top = this._minY - this._lineWidth / 2;  
+    protected _computeAlignment(parentMeasure: Measure, context: CanvasRenderingContext2D): void {
+        if (this._minX == null || this._minY == null) {
+            return;
         }
         }
 
 
-        public dispose(): void {
-            while (this._points.length > 0) {
-                this.remove(this._points.length - 1);
-            }
+        this._currentMeasure.left = this._minX - this._lineWidth / 2;
+        this._currentMeasure.top = this._minY - this._lineWidth / 2;
+    }
 
 
-            super.dispose();
+    public dispose(): void {
+        while (this._points.length > 0) {
+            this.remove(this._points.length - 1);
         }
         }
 
 
-    }    
-}
+        super.dispose();
+    }
+
+}    

+ 136 - 136
gui/src/2D/controls/radioButton.ts

@@ -1,172 +1,172 @@
-/// <reference path="../../../../dist/preview release/babylon.d.ts"/>
-
-module BABYLON.GUI {
-    /**
-     * Class used to create radio button controls
-     */
-    export class RadioButton extends Control {
-        private _isChecked = false;
-        private _background = "black";   
-        private _checkSizeRatio = 0.8;
-        private _thickness = 1;
-        
-        /** Gets or sets border thickness */
-        public get thickness(): number {
-            return this._thickness;
+import { Control } from "./control";
+import { Observable, Vector2 } from "babylonjs";
+import { Measure } from "../measure";
+
+/**
+ * Class used to create radio button controls
+ */
+export class RadioButton extends Control {
+    private _isChecked = false;
+    private _background = "black";
+    private _checkSizeRatio = 0.8;
+    private _thickness = 1;
+
+    /** Gets or sets border thickness */
+    public get thickness(): number {
+        return this._thickness;
+    }
+
+    public set thickness(value: number) {
+        if (this._thickness === value) {
+            return;
         }
         }
 
 
-        public set thickness(value: number) {
-            if (this._thickness === value) {
-                return;
-            }
+        this._thickness = value;
+        this._markAsDirty();
+    }
 
 
-            this._thickness = value;
-            this._markAsDirty();
-        }           
+    /** Gets or sets group name */
+    public group = "";
 
 
-        /** Gets or sets group name */
-        public group = "";        
+    /** Observable raised when isChecked is changed */
+    public onIsCheckedChangedObservable = new Observable<boolean>();
 
 
-        /** Observable raised when isChecked is changed */
-        public onIsCheckedChangedObservable = new Observable<boolean>();
+    /** Gets or sets a value indicating the ratio between overall size and check size */
+    public get checkSizeRatio(): number {
+        return this._checkSizeRatio;
+    }
 
 
-        /** Gets or sets a value indicating the ratio between overall size and check size */
-        public get checkSizeRatio(): number {
-            return this._checkSizeRatio;
-        }
+    public set checkSizeRatio(value: number) {
+        value = Math.max(Math.min(1, value), 0);
 
 
-        public set checkSizeRatio(value: number) {
-            value = Math.max(Math.min(1, value), 0);
+        if (this._checkSizeRatio === value) {
+            return;
+        }
 
 
-            if (this._checkSizeRatio === value) {
-                return;
-            }
+        this._checkSizeRatio = value;
+        this._markAsDirty();
+    }
 
 
-            this._checkSizeRatio = value;
-            this._markAsDirty();
-        }             
+    /** Gets or sets background color */
+    public get background(): string {
+        return this._background;
+    }
 
 
-        /** Gets or sets background color */
-        public get background(): string {
-            return this._background;
+    public set background(value: string) {
+        if (this._background === value) {
+            return;
         }
         }
 
 
-        public set background(value: string) {
-            if (this._background === value) {
-                return;
-            }
+        this._background = value;
+        this._markAsDirty();
+    }
 
 
-            this._background = value;
-            this._markAsDirty();
-        }     
+    /** Gets or sets a boolean indicating if the checkbox is checked or not */
+    public get isChecked(): boolean {
+        return this._isChecked;
+    }
 
 
-        /** Gets or sets a boolean indicating if the checkbox is checked or not */
-        public get isChecked(): boolean {
-            return this._isChecked;
+    public set isChecked(value: boolean) {
+        if (this._isChecked === value) {
+            return;
         }
         }
 
 
-        public set isChecked(value: boolean) {
-            if (this._isChecked === value) {
-                return;
-            }
+        this._isChecked = value;
+        this._markAsDirty();
 
 
-            this._isChecked = value;
-            this._markAsDirty();
-
-            this.onIsCheckedChangedObservable.notifyObservers(value);
-
-            if (this._isChecked && this._host) {
-                // Update all controls from same group
-                this._host.executeOnAllControls((control) => {
-                    if (control === this) {
-                        return;
-                    }
-
-                    if ((<any>control).group === undefined) {
-                        return;
-                    }
-                    var childRadio = (<RadioButton>control);
-                    if (childRadio.group === this.group) {
-                        childRadio.isChecked = false;
-                    }
-                });
-            }
-        }                             
+        this.onIsCheckedChangedObservable.notifyObservers(value);
 
 
-        /**
-         * Creates a new RadioButton
-         * @param name defines the control name
-         */        
-        constructor(public name?: string) {
-            super(name);
+        if (this._isChecked && this._host) {
+            // Update all controls from same group
+            this._host.executeOnAllControls((control) => {
+                if (control === this) {
+                    return;
+                }
 
 
-            this.isPointerBlocker = true;
+                if ((<any>control).group === undefined) {
+                    return;
+                }
+                var childRadio = (<RadioButton>control);
+                if (childRadio.group === this.group) {
+                    childRadio.isChecked = false;
+                }
+            });
         }
         }
+    }
+
+    /**
+     * Creates a new RadioButton
+     * @param name defines the control name
+     */
+    constructor(public name?: string) {
+        super(name);
 
 
-        protected _getTypeName(): string {
-            return "RadioButton";
-        }              
+        this.isPointerBlocker = true;
+    }
 
 
-        public _draw(parentMeasure: Measure, context: CanvasRenderingContext2D): void {
-            context.save();
+    protected _getTypeName(): string {
+        return "RadioButton";
+    }
 
 
-            this._applyStates(context);
-            if (this._processMeasures(parentMeasure, context)) {
-                let actualWidth = this._currentMeasure.width - this._thickness;
-                let actualHeight = this._currentMeasure.height - this._thickness;
+    public _draw(parentMeasure: Measure, context: CanvasRenderingContext2D): void {
+        context.save();
 
 
-                if(this.shadowBlur || this.shadowOffsetX || this.shadowOffsetY){
-                    context.shadowColor = this.shadowColor;
-                    context.shadowBlur = this.shadowBlur;
-                    context.shadowOffsetX = this.shadowOffsetX;
-                    context.shadowOffsetY = this.shadowOffsetY;
-                }
-                
-                // Outer
-                Control.drawEllipse(this._currentMeasure.left + this._currentMeasure.width / 2, this._currentMeasure.top + this._currentMeasure.height / 2, 
-                            this._currentMeasure.width / 2 - this._thickness / 2, this._currentMeasure.height / 2 - this._thickness / 2, context);
-                
-                context.fillStyle = this._background;
-                context.fill();
+        this._applyStates(context);
+        if (this._processMeasures(parentMeasure, context)) {
+            let actualWidth = this._currentMeasure.width - this._thickness;
+            let actualHeight = this._currentMeasure.height - this._thickness;
 
 
-                if(this.shadowBlur || this.shadowOffsetX || this.shadowOffsetY){
-                    context.shadowBlur = 0;
-                    context.shadowOffsetX = 0;
-                    context.shadowOffsetY = 0;
-                }
+            if (this.shadowBlur || this.shadowOffsetX || this.shadowOffsetY) {
+                context.shadowColor = this.shadowColor;
+                context.shadowBlur = this.shadowBlur;
+                context.shadowOffsetX = this.shadowOffsetX;
+                context.shadowOffsetY = this.shadowOffsetY;
+            }
+
+            // Outer
+            Control.drawEllipse(this._currentMeasure.left + this._currentMeasure.width / 2, this._currentMeasure.top + this._currentMeasure.height / 2,
+                this._currentMeasure.width / 2 - this._thickness / 2, this._currentMeasure.height / 2 - this._thickness / 2, context);
 
 
-                context.strokeStyle = this.color;
-                context.lineWidth = this._thickness;
+            context.fillStyle = this._background;
+            context.fill();
 
 
-                context.stroke();
+            if (this.shadowBlur || this.shadowOffsetX || this.shadowOffsetY) {
+                context.shadowBlur = 0;
+                context.shadowOffsetX = 0;
+                context.shadowOffsetY = 0;
+            }
 
 
-                // Inner
-                if (this._isChecked) {
-                    context.fillStyle = this.color;
-                    let offsetWidth = actualWidth * this._checkSizeRatio;
-                    let offseHeight = actualHeight * this._checkSizeRatio;
+            context.strokeStyle = this.color;
+            context.lineWidth = this._thickness;
 
 
-                    Control.drawEllipse(this._currentMeasure.left + this._currentMeasure.width / 2, this._currentMeasure.top + this._currentMeasure.height / 2, 
-                                    offsetWidth / 2 - this._thickness / 2, offseHeight / 2  - this._thickness / 2, context);
+            context.stroke();
 
 
-                    context.fill();
-                }
+            // Inner
+            if (this._isChecked) {
+                context.fillStyle = this.color;
+                let offsetWidth = actualWidth * this._checkSizeRatio;
+                let offseHeight = actualHeight * this._checkSizeRatio;
 
 
+                Control.drawEllipse(this._currentMeasure.left + this._currentMeasure.width / 2, this._currentMeasure.top + this._currentMeasure.height / 2,
+                    offsetWidth / 2 - this._thickness / 2, offseHeight / 2 - this._thickness / 2, context);
+
+                context.fill();
             }
             }
-            context.restore();
+
         }
         }
+        context.restore();
+    }
 
 
-        // Events
-        public _onPointerDown(target: Control, coordinates: Vector2, pointerId:number, buttonIndex: number): boolean {
-            if (!super._onPointerDown(target, coordinates, pointerId, buttonIndex)) {
-                return false;
-            }
-            
-            if (!this.isChecked) {
-                this.isChecked = true;
-            }
+    // Events
+    public _onPointerDown(target: Control, coordinates: Vector2, pointerId: number, buttonIndex: number): boolean {
+        if (!super._onPointerDown(target, coordinates, pointerId, buttonIndex)) {
+            return false;
+        }
 
 
-            return true;
+        if (!this.isChecked) {
+            this.isChecked = true;
         }
         }
-    }    
-}
+
+        return true;
+    }
+}   

+ 117 - 118
gui/src/2D/controls/rectangle.ts

@@ -1,136 +1,135 @@
-/// <reference path="../../../../dist/preview release/babylon.d.ts"/>
-
-module BABYLON.GUI {
-    /** Class used to create rectangle container */
-    export class Rectangle extends Container {
-        private _thickness = 1;
-        private _cornerRadius = 0;
-        
-        /** Gets or sets border thickness */        
-        public get thickness(): number {
-            return this._thickness;
+import { Container } from "./container";
+import { Measure } from "../measure";
+
+/** Class used to create rectangle container */
+export class Rectangle extends Container {
+    private _thickness = 1;
+    private _cornerRadius = 0;
+
+    /** Gets or sets border thickness */
+    public get thickness(): number {
+        return this._thickness;
+    }
+
+    public set thickness(value: number) {
+        if (this._thickness === value) {
+            return;
         }
         }
 
 
-        public set thickness(value: number) {
-            if (this._thickness === value) {
-                return;
-            }
+        this._thickness = value;
+        this._markAsDirty();
+    }
 
 
-            this._thickness = value;
-            this._markAsDirty();
-        }   
-        
-        /** Gets or sets the corner radius angle */
-        public get cornerRadius(): number {
-            return this._cornerRadius;
-        }
+    /** Gets or sets the corner radius angle */
+    public get cornerRadius(): number {
+        return this._cornerRadius;
+    }
 
 
-        public set cornerRadius(value: number) {
-            if (value < 0) {
-                value = 0;
-            }
+    public set cornerRadius(value: number) {
+        if (value < 0) {
+            value = 0;
+        }
 
 
-            if (this._cornerRadius === value) {
-                return;
-            }
+        if (this._cornerRadius === value) {
+            return;
+        }
 
 
-            this._cornerRadius = value;
-            this._markAsDirty();
-        }   
-     
-        /**
-         * Creates a new Rectangle
-         * @param name defines the control name
-         */       
-        constructor(public name?: string) {
-            super(name);
+        this._cornerRadius = value;
+        this._markAsDirty();
+    }
+
+    /**
+     * Creates a new Rectangle
+     * @param name defines the control name
+     */
+    constructor(public name?: string) {
+        super(name);
+    }
+
+    protected _getTypeName(): string {
+        return "Rectangle";
+    }
+
+    protected _localDraw(context: CanvasRenderingContext2D): void {
+        context.save();
+
+        if (this.shadowBlur || this.shadowOffsetX || this.shadowOffsetY) {
+            context.shadowColor = this.shadowColor;
+            context.shadowBlur = this.shadowBlur;
+            context.shadowOffsetX = this.shadowOffsetX;
+            context.shadowOffsetY = this.shadowOffsetY;
         }
         }
 
 
-        protected _getTypeName(): string {
-            return "Rectangle";
-        }              
-
-        protected _localDraw(context: CanvasRenderingContext2D): void {
-            context.save();
-            
-            if(this.shadowBlur || this.shadowOffsetX || this.shadowOffsetY){
-                context.shadowColor = this.shadowColor;
-                context.shadowBlur = this.shadowBlur;
-                context.shadowOffsetX = this.shadowOffsetX;
-                context.shadowOffsetY = this.shadowOffsetY;
+        if (this._background) {
+            context.fillStyle = this._background;
+
+            if (this._cornerRadius) {
+                this._drawRoundedRect(context, this._thickness / 2);
+                context.fill();
+            } else {
+                context.fillRect(this._currentMeasure.left, this._currentMeasure.top, this._currentMeasure.width, this._currentMeasure.height);
             }
             }
+        }
 
 
-            if (this._background) {
-                context.fillStyle = this._background;
+        if (this._thickness) {
 
 
-                if (this._cornerRadius) {
-                    this._drawRoundedRect(context, this._thickness / 2);
-                    context.fill();
-                } else {
-                    context.fillRect(this._currentMeasure.left, this._currentMeasure.top, this._currentMeasure.width, this._currentMeasure.height);
-                }
+            if (this.shadowBlur || this.shadowOffsetX || this.shadowOffsetY) {
+                context.shadowBlur = 0;
+                context.shadowOffsetX = 0;
+                context.shadowOffsetY = 0;
             }
             }
 
 
-            if (this._thickness) {
-
-                if(this.shadowBlur || this.shadowOffsetX || this.shadowOffsetY){
-                    context.shadowBlur = 0;
-                    context.shadowOffsetX = 0;
-                    context.shadowOffsetY = 0;
-                }
-
-                if (this.color) {
-                    context.strokeStyle = this.color;
-                }
-                context.lineWidth = this._thickness;
-
-                if (this._cornerRadius) {
-                    this._drawRoundedRect(context, this._thickness / 2);
-                    context.stroke();
-                } else {                
-                    context.strokeRect(this._currentMeasure.left + this._thickness / 2, this._currentMeasure.top + this._thickness / 2, 
-                                       this._currentMeasure.width - this._thickness, this._currentMeasure.height - this._thickness);
-                }
+            if (this.color) {
+                context.strokeStyle = this.color;
             }
             }
+            context.lineWidth = this._thickness;
 
 
-            context.restore();
-        }
-
-        protected _additionalProcessing(parentMeasure: Measure, context: CanvasRenderingContext2D): void {  
-            super._additionalProcessing(parentMeasure, context);
-
-            this._measureForChildren.width -= 2 * this._thickness;
-            this._measureForChildren.height -= 2 * this._thickness;
-            this._measureForChildren.left += this._thickness;
-            this._measureForChildren.top += this._thickness;            
-        }
-
-        private _drawRoundedRect(context: CanvasRenderingContext2D, offset: number = 0): void {
-            var x = this._currentMeasure.left + offset;
-            var y = this._currentMeasure.top + offset;
-            var width = this._currentMeasure.width - offset * 2;
-            var height = this._currentMeasure.height - offset * 2;
-
-            var radius = Math.min(height / 2 - 2, Math.min(width / 2 - 2, this._cornerRadius));
-
-            context.beginPath();
-            context.moveTo(x + radius, y);
-            context.lineTo(x + width - radius, y);
-            context.quadraticCurveTo(x + width, y, x + width, y + radius);
-            context.lineTo(x + width, y + height - radius);
-            context.quadraticCurveTo(x + width, y + height, x + width - radius, y + height);
-            context.lineTo(x + radius, y + height);
-            context.quadraticCurveTo(x, y + height, x, y + height - radius);
-            context.lineTo(x, y + radius);
-            context.quadraticCurveTo(x, y, x + radius, y);
-            context.closePath();
-        } 
-
-        protected _clipForChildren(context: CanvasRenderingContext2D) {
             if (this._cornerRadius) {
             if (this._cornerRadius) {
-                this._drawRoundedRect(context, this._thickness);
-                context.clip();
+                this._drawRoundedRect(context, this._thickness / 2);
+                context.stroke();
+            } else {
+                context.strokeRect(this._currentMeasure.left + this._thickness / 2, this._currentMeasure.top + this._thickness / 2,
+                    this._currentMeasure.width - this._thickness, this._currentMeasure.height - this._thickness);
             }
             }
         }
         }
-    }    
-}
+
+        context.restore();
+    }
+
+    protected _additionalProcessing(parentMeasure: Measure, context: CanvasRenderingContext2D): void {
+        super._additionalProcessing(parentMeasure, context);
+
+        this._measureForChildren.width -= 2 * this._thickness;
+        this._measureForChildren.height -= 2 * this._thickness;
+        this._measureForChildren.left += this._thickness;
+        this._measureForChildren.top += this._thickness;
+    }
+
+    private _drawRoundedRect(context: CanvasRenderingContext2D, offset: number = 0): void {
+        var x = this._currentMeasure.left + offset;
+        var y = this._currentMeasure.top + offset;
+        var width = this._currentMeasure.width - offset * 2;
+        var height = this._currentMeasure.height - offset * 2;
+
+        var radius = Math.min(height / 2 - 2, Math.min(width / 2 - 2, this._cornerRadius));
+
+        context.beginPath();
+        context.moveTo(x + radius, y);
+        context.lineTo(x + width - radius, y);
+        context.quadraticCurveTo(x + width, y, x + width, y + radius);
+        context.lineTo(x + width, y + height - radius);
+        context.quadraticCurveTo(x + width, y + height, x + width - radius, y + height);
+        context.lineTo(x + radius, y + height);
+        context.quadraticCurveTo(x, y + height, x, y + height - radius);
+        context.lineTo(x, y + radius);
+        context.quadraticCurveTo(x, y, x + radius, y);
+        context.closePath();
+    }
+
+    protected _clipForChildren(context: CanvasRenderingContext2D) {
+        if (this._cornerRadius) {
+            this._drawRoundedRect(context, this._thickness);
+            context.clip();
+        }
+    }
+}    

+ 359 - 358
gui/src/2D/controls/slider.ts

@@ -1,463 +1,464 @@
-/// <reference path="../../../../dist/preview release/babylon.d.ts"/>
+import { Control } from "./control";
+import { ValueAndUnit } from "../valueAndUnit";
+import { Observable, Vector2 } from "babylonjs";
+import { Measure } from "../measure";
+
+/**
+ * Class used to create slider controls
+ */
+export class Slider extends Control {
+    private _thumbWidth = new ValueAndUnit(20, ValueAndUnit.UNITMODE_PIXEL, false);
+    private _minimum = 0;
+    private _maximum = 100;
+    private _value = 50;
+    private _isVertical = false;
+    private _background = "black";
+    private _borderColor = "white";
+    private _barOffset = new ValueAndUnit(5, ValueAndUnit.UNITMODE_PIXEL, false);
+    private _isThumbCircle = false;
+    private _isThumbClamped = false;
+
+    /** Observable raised when the sldier value changes */
+    public onValueChangedObservable = new Observable<number>();
+
+    /** Gets or sets border color */
+    public get borderColor(): string {
+        return this._borderColor;
+    }
 
 
-module BABYLON.GUI {
-    /**
-     * Class used to create slider controls
-     */
-    export class Slider extends Control {
-        private _thumbWidth = new ValueAndUnit(20, ValueAndUnit.UNITMODE_PIXEL, false);
-        private _minimum = 0;
-        private _maximum = 100;
-        private _value = 50;
-        private _isVertical = false;
-        private _background = "black";
-        private _borderColor = "white";
-        private _barOffset = new ValueAndUnit(5, ValueAndUnit.UNITMODE_PIXEL, false);
-        private _isThumbCircle = false;
-        private _isThumbClamped = false;
-
-        /** Observable raised when the sldier value changes */
-        public onValueChangedObservable = new Observable<number>();
-
-        /** Gets or sets border color */
-        public get borderColor(): string {
-            return this._borderColor;
+    public set borderColor(value: string) {
+        if (this._borderColor === value) {
+            return;
         }
         }
 
 
-        public set borderColor(value: string) {
-            if (this._borderColor === value) {
-                return;
-            }
+        this._borderColor = value;
+        this._markAsDirty();
+    }
 
 
-            this._borderColor = value;
-            this._markAsDirty();
-        }
+    /** Gets or sets background color */
+    public get background(): string {
+        return this._background;
+    }
 
 
-        /** Gets or sets background color */
-        public get background(): string {
-            return this._background;
+    public set background(value: string) {
+        if (this._background === value) {
+            return;
         }
         }
 
 
-        public set background(value: string) {
-            if (this._background === value) {
-                return;
-            }
+        this._background = value;
+        this._markAsDirty();
+    }
 
 
-            this._background = value;
-            this._markAsDirty();
-        }
+    /** Gets or sets main bar offset */
+    public get barOffset(): string | number {
+        return this._barOffset.toString(this._host);
+    }
 
 
-        /** Gets or sets main bar offset */
-        public get barOffset(): string | number {
-            return this._barOffset.toString(this._host);
+    /** Gets main bar offset in pixels*/
+    public get barOffsetInPixels(): number {
+        return this._barOffset.getValueInPixel(this._host, this._cachedParentMeasure.width);
+    }
+
+    public set barOffset(value: string | number) {
+        if (this._barOffset.toString(this._host) === value) {
+            return;
         }
         }
 
 
-        /** Gets main bar offset in pixels*/
-        public get barOffsetInPixels(): number {
-            return this._barOffset.getValueInPixel(this._host, this._cachedParentMeasure.width);
+        if (this._barOffset.fromString(value)) {
+            this._markAsDirty();
         }
         }
+    }
 
 
-        public set barOffset(value: string | number) {
-            if (this._barOffset.toString(this._host) === value) {
-                return;
-            }
+    /** Gets or sets thumb width */
+    public get thumbWidth(): string | number {
+        return this._thumbWidth.toString(this._host);
+    }
 
 
-            if (this._barOffset.fromString(value)) {
-                this._markAsDirty();
-            }
-        }
+    /** Gets thumb width in pixels */
+    public get thumbWidthInPixels(): number {
+        return this._thumbWidth.getValueInPixel(this._host, this._cachedParentMeasure.width);
+    }
 
 
-        /** Gets or sets thumb width */
-        public get thumbWidth(): string | number {
-            return this._thumbWidth.toString(this._host);
+    public set thumbWidth(value: string | number) {
+        if (this._thumbWidth.toString(this._host) === value) {
+            return;
         }
         }
 
 
-        /** Gets thumb width in pixels */       
-        public get thumbWidthInPixels(): number {
-            return this._thumbWidth.getValueInPixel(this._host, this._cachedParentMeasure.width);
+        if (this._thumbWidth.fromString(value)) {
+            this._markAsDirty();
         }
         }
+    }
 
 
-        public set thumbWidth(value: string | number) {
-            if (this._thumbWidth.toString(this._host) === value) {
-                return;
-            }
+    /** Gets or sets minimum value */
+    public get minimum(): number {
+        return this._minimum;
+    }
 
 
-            if (this._thumbWidth.fromString(value)) {
-                this._markAsDirty();
-            }
+    public set minimum(value: number) {
+        if (this._minimum === value) {
+            return;
         }
         }
 
 
-        /** Gets or sets minimum value */
-        public get minimum(): number {
-            return this._minimum;
-        }
+        this._minimum = value;
+        this._markAsDirty();
 
 
-        public set minimum(value: number) {
-            if (this._minimum === value) {
-                return;
-            }
+        this.value = Math.max(Math.min(this.value, this._maximum), this._minimum);
+    }
 
 
-            this._minimum = value;
-            this._markAsDirty();
+    /** Gets or sets maximum value */
+    public get maximum(): number {
+        return this._maximum;
+    }
 
 
-            this.value = Math.max(Math.min(this.value, this._maximum), this._minimum);
+    public set maximum(value: number) {
+        if (this._maximum === value) {
+            return;
         }
         }
 
 
-        /** Gets or sets maximum value */        
-        public get maximum(): number {
-            return this._maximum;
-        }
+        this._maximum = value;
+        this._markAsDirty();
 
 
-        public set maximum(value: number) {
-            if (this._maximum === value) {
-                return;
-            }
+        this.value = Math.max(Math.min(this.value, this._maximum), this._minimum);
+    }
 
 
-            this._maximum = value;
-            this._markAsDirty();
+    /** Gets or sets current value */
+    public get value(): number {
+        return this._value;
+    }
 
 
-            this.value = Math.max(Math.min(this.value, this._maximum), this._minimum);
-        }
+    public set value(value: number) {
+        value = Math.max(Math.min(value, this._maximum), this._minimum);
 
 
-        /** Gets or sets current value */
-        public get value(): number {
-            return this._value;
+        if (this._value === value) {
+            return;
         }
         }
 
 
-        public set value(value: number) {
-            value = Math.max(Math.min(value, this._maximum), this._minimum);
+        this._value = value;
+        this._markAsDirty();
+        this.onValueChangedObservable.notifyObservers(this._value);
+    }
 
 
-            if (this._value === value) {
-                return;
-            }
+    /**Gets or sets a boolean indicating if the slider should be vertical or horizontal */
+    public get isVertical(): boolean {
+        return this._isVertical;
+    }
 
 
-            this._value = value;
-            this._markAsDirty();
-            this.onValueChangedObservable.notifyObservers(this._value);
+    public set isVertical(value: boolean) {
+        if (this._isVertical === value) {
+            return;
         }
         }
 
 
-        /**Gets or sets a boolean indicating if the slider should be vertical or horizontal */
-        public get isVertical(): boolean {
-            return this._isVertical;
-        }
+        this._isVertical = value;
+        this._markAsDirty();
+    }
 
 
-        public set isVertical(value: boolean) {
-            if(this._isVertical === value){
-                return;
-            }
+    /** Gets or sets a boolean indicating if the thumb should be round or square */
+    public get isThumbCircle(): boolean {
+        return this._isThumbCircle;
+    }
 
 
-            this._isVertical = value;
-            this._markAsDirty();
+    public set isThumbCircle(value: boolean) {
+        if (this._isThumbCircle === value) {
+            return;
         }
         }
 
 
-        /** Gets or sets a boolean indicating if the thumb should be round or square */
-        public get isThumbCircle(): boolean {
-            return this._isThumbCircle;
-        }
+        this._isThumbCircle = value;
+        this._markAsDirty();
+    }
 
 
-        public set isThumbCircle(value: boolean) {
-            if (this._isThumbCircle === value) {
-                return;
-            }
+    /** Gets or sets a value indicating if the thumb can go over main bar extends */
+    public get isThumbClamped(): boolean {
+        return this._isThumbClamped;
+    }
 
 
-            this._isThumbCircle = value;
-            this._markAsDirty();
+    public set isThumbClamped(value: boolean) {
+        if (this._isThumbClamped === value) {
+            return;
         }
         }
 
 
-        /** Gets or sets a value indicating if the thumb can go over main bar extends */
-        public get isThumbClamped(): boolean {
-            return this._isThumbClamped;
-        }
+        this._isThumbClamped = value;
+        this._markAsDirty();
+    }
 
 
-        public set isThumbClamped(value: boolean) {
-            if (this._isThumbClamped === value) {
-                return;
-            }
+    /**
+     * Creates a new Slider
+     * @param name defines the control name
+     */
+    constructor(public name?: string) {
+        super(name);
 
 
-            this._isThumbClamped = value;
-            this._markAsDirty();
-        }
+        this.isPointerBlocker = true;
+    }
 
 
-       /**
-        * Creates a new Slider
-        * @param name defines the control name
-        */
-        constructor(public name?: string) {
-            super(name);
+    protected _getTypeName(): string {
+        return "Slider";
+    }
 
 
-            this.isPointerBlocker = true;
+    protected _getThumbThickness(type: string, backgroundLength: number): number {
+        var thumbThickness = 0;
+        switch (type) {
+            case "circle":
+                if (this._thumbWidth.isPixel) {
+                    thumbThickness = Math.max(this._thumbWidth.getValue(this._host), backgroundLength);
+                }
+                else {
+                    thumbThickness = backgroundLength * this._thumbWidth.getValue(this._host);
+                }
+                break;
+            case "rectangle":
+                if (this._thumbWidth.isPixel) {
+                    thumbThickness = Math.min(this._thumbWidth.getValue(this._host), backgroundLength);
+                }
+                else {
+                    thumbThickness = backgroundLength * this._thumbWidth.getValue(this._host);
+                }
         }
         }
+        return thumbThickness;
+    }
 
 
-        protected _getTypeName(): string {
-            return "Slider";
-        }
 
 
-        protected _getThumbThickness(type:string, backgroundLength:number): number {
-            var thumbThickness = 0;
-            switch(type) {
-                case "circle":
-                    if (this._thumbWidth.isPixel) {
-                        thumbThickness = Math.max(this._thumbWidth.getValue(this._host), backgroundLength);
-                    }
-                    else {
-                        thumbThickness = backgroundLength * this._thumbWidth.getValue(this._host);
-                    }
-                    break;
-                case "rectangle":
-                    if (this._thumbWidth.isPixel) {
-                        thumbThickness = Math.min(this._thumbWidth.getValue(this._host), backgroundLength);
-                    }
-                    else {
-                        thumbThickness = backgroundLength * this._thumbWidth.getValue(this._host);
-                    }
+    public _draw(parentMeasure: Measure, context: CanvasRenderingContext2D): void {
+        context.save();
+
+        this._applyStates(context);
+        if (this._processMeasures(parentMeasure, context)) {
+            // Main bar
+            var effectiveBarOffset = 0;
+            var type = this.isThumbCircle ? "circle" : "rectangle";
+            var left = this._currentMeasure.left;
+            var top = this._currentMeasure.top;
+            var width = this._currentMeasure.width;
+            var height = this._currentMeasure.height;
+
+            var backgroundBoxLength = Math.max(this._currentMeasure.width, this._currentMeasure.height);
+            var backgroundBoxThickness = Math.min(this._currentMeasure.width, this._currentMeasure.height);
+
+            var effectiveThumbThickness = this._getThumbThickness(type, backgroundBoxThickness);
+            backgroundBoxLength -= effectiveThumbThickness;
+
+            var radius = 0;
+
+
+            //throw error when height is less than width for vertical slider
+            if ((this._isVertical && this._currentMeasure.height < this._currentMeasure.width)) {
+                console.error("Height should be greater than width");
+                return;
+            }
+            if (this._barOffset.isPixel) {
+                effectiveBarOffset = Math.min(this._barOffset.getValue(this._host), backgroundBoxThickness);
+            }
+            else {
+                effectiveBarOffset = backgroundBoxThickness * this._barOffset.getValue(this._host);
             }
             }
-            return thumbThickness;
-        }
 
 
+            backgroundBoxThickness -= (effectiveBarOffset * 2);
 
 
-        public _draw(parentMeasure: Measure, context: CanvasRenderingContext2D): void {
-            context.save();
-
-            this._applyStates(context);
-            if (this._processMeasures(parentMeasure, context)) {
-                // Main bar
-                var effectiveBarOffset = 0;
-                var type = this.isThumbCircle ? "circle" : "rectangle";
-                var left = this._currentMeasure.left;
-                var top = this._currentMeasure.top;
-                var width = this._currentMeasure.width;
-                var height = this._currentMeasure.height;
-            
-                var backgroundBoxLength = Math.max(this._currentMeasure.width, this._currentMeasure.height);
-                var backgroundBoxThickness = Math.min(this._currentMeasure.width, this._currentMeasure.height);
-                
-                var effectiveThumbThickness = this._getThumbThickness(type, backgroundBoxThickness);
-                backgroundBoxLength -= effectiveThumbThickness;
-
-                var radius = 0;
-
-
-                //throw error when height is less than width for vertical slider
-                if ((this._isVertical && this._currentMeasure.height < this._currentMeasure.width)) {
-                    console.error("Height should be greater than width");
-                    return;
-                }
-                if (this._barOffset.isPixel) {
-                    effectiveBarOffset = Math.min(this._barOffset.getValue(this._host), backgroundBoxThickness);
+            if (this._isVertical) {
+                left += effectiveBarOffset;
+                if (!this.isThumbClamped) {
+                    top += (effectiveThumbThickness / 2);
                 }
                 }
-                else {
-                    effectiveBarOffset = backgroundBoxThickness * this._barOffset.getValue(this._host);
+
+                height = backgroundBoxLength;
+                width = backgroundBoxThickness;
+
+            }
+            else {
+                top += effectiveBarOffset;
+                if (!this.isThumbClamped) {
+                    left += (effectiveThumbThickness / 2);
                 }
                 }
+                height = backgroundBoxThickness;
+                width = backgroundBoxLength;
+            }
 
 
-                backgroundBoxThickness -= (effectiveBarOffset * 2);
+            if (this.isThumbClamped && this.isThumbCircle) {
+                if (this._isVertical)
+                    top += (effectiveThumbThickness / 2);
+                else
+                    left += (effectiveThumbThickness / 2);
 
 
-                if (this._isVertical) {
-                    left += effectiveBarOffset;
-                    if(!this.isThumbClamped) {
-                       top += (effectiveThumbThickness / 2);
-                    }
-    
-                    height = backgroundBoxLength;
-                    width = backgroundBoxThickness;
+                radius = backgroundBoxThickness / 2;
+            }
+            else {
+                radius = (effectiveThumbThickness - effectiveBarOffset) / 2;
+            }
+
+            if (this.shadowBlur || this.shadowOffsetX || this.shadowOffsetY) {
+                context.shadowColor = this.shadowColor;
+                context.shadowBlur = this.shadowBlur;
+                context.shadowOffsetX = this.shadowOffsetX;
+                context.shadowOffsetY = this.shadowOffsetY;
+            }
+
+            var thumbPosition = (this._isVertical) ? ((this._maximum - this._value) / (this._maximum - this._minimum)) * backgroundBoxLength : ((this._value - this._minimum) / (this._maximum - this._minimum)) * backgroundBoxLength;
+            context.fillStyle = this._background;
 
 
+            if (this._isVertical) {
+                if (this.isThumbClamped) {
+                    if (this.isThumbCircle) {
+                        context.beginPath();
+                        context.arc(left + backgroundBoxThickness / 2, top, radius, Math.PI, 2 * Math.PI);
+                        context.fill();
+                        context.fillRect(left, top, width, height);
+                    }
+                    else {
+                        context.fillRect(left, top, width, height + effectiveThumbThickness);
+                    }
                 }
                 }
                 else {
                 else {
-                    top += effectiveBarOffset;
-                    if(!this.isThumbClamped) {
-                       left += (effectiveThumbThickness / 2);
-                    }
-                    height = backgroundBoxThickness;
-                    width = backgroundBoxLength;
+                    context.fillRect(left, top, width, height);
                 }
                 }
-
-                if(this.isThumbClamped && this.isThumbCircle){
-                    if(this._isVertical)
-                        top += (effectiveThumbThickness / 2);
-                    else 
-                        left += (effectiveThumbThickness / 2);
-
-                    radius = backgroundBoxThickness / 2;
+            }
+            else {
+                if (this.isThumbClamped) {
+                    if (this.isThumbCircle) {
+                        context.beginPath();
+                        context.arc(left + backgroundBoxLength, top + (backgroundBoxThickness / 2), radius, 0, 2 * Math.PI);
+                        context.fill();
+                        context.fillRect(left, top, width, height);
+                    }
+                    else {
+                        context.fillRect(left, top, width + effectiveThumbThickness, height);
+                    }
                 }
                 }
-                else{
-                    radius = (effectiveThumbThickness- effectiveBarOffset) / 2;
+                else {
+                    context.fillRect(left, top, width, height);
                 }
                 }
+            }
 
 
-                if (this.shadowBlur || this.shadowOffsetX || this.shadowOffsetY) {
-                    context.shadowColor = this.shadowColor;
-                    context.shadowBlur = this.shadowBlur;
-                    context.shadowOffsetX = this.shadowOffsetX;
-                    context.shadowOffsetY = this.shadowOffsetY;
-                }
+            if (this.shadowBlur || this.shadowOffsetX || this.shadowOffsetY) {
+                context.shadowBlur = 0;
+                context.shadowOffsetX = 0;
+                context.shadowOffsetY = 0;
+            }
 
 
-                var thumbPosition = (this._isVertical) ? ((this._maximum - this._value) / (this._maximum - this._minimum)) * backgroundBoxLength : ((this._value - this._minimum) / (this._maximum - this._minimum)) * backgroundBoxLength;
-                context.fillStyle = this._background;
-                
-                if(this._isVertical){
-                    if (this.isThumbClamped) {
-                        if (this.isThumbCircle) {
-                            context.beginPath();
-                            context.arc(left + backgroundBoxThickness / 2, top, radius, Math.PI, 2 * Math.PI);
-                            context.fill();
-                            context.fillRect(left, top, width , height);
-                        }
-                        else {
-                            context.fillRect(left, top, width, height + effectiveThumbThickness);
-                        }
+            context.fillStyle = this.color;
+            if (this._isVertical) {
+                if (this.isThumbClamped) {
+                    if (this.isThumbCircle) {
+                        context.beginPath();
+                        context.arc(left + backgroundBoxThickness / 2, top + backgroundBoxLength, radius, 0, 2 * Math.PI);
+                        context.fill();
+                        context.fillRect(left, top + thumbPosition, width, height - thumbPosition);
                     }
                     }
                     else {
                     else {
-                        context.fillRect(left, top , width, height);
+                        context.fillRect(left, top + thumbPosition, width, this._currentMeasure.height - thumbPosition);
                     }
                     }
                 }
                 }
-                else{
-                    if (this.isThumbClamped) {
-                        if (this.isThumbCircle) {
-                            context.beginPath();
-                            context.arc(left + backgroundBoxLength , top + (backgroundBoxThickness/2), radius, 0,  2* Math.PI);
-                            context.fill();
-                            context.fillRect(left, top, width, height);
-                        }
-                        else {
-                            context.fillRect(left, top, width + effectiveThumbThickness, height);
-                        }
+                else {
+                    context.fillRect(left, top + thumbPosition, width, height - thumbPosition);
+                }
+            }
+            else {
+                if (this.isThumbClamped) {
+                    if (this.isThumbCircle) {
+                        context.beginPath();
+                        context.arc(left, top + backgroundBoxThickness / 2, radius, 0, 2 * Math.PI);
+                        context.fill();
+                        context.fillRect(left, top, thumbPosition, height);
                     }
                     }
                     else {
                     else {
-                        context.fillRect(left, top, width, height);
+                        context.fillRect(left, top, thumbPosition, height);
                     }
                     }
                 }
                 }
+                else {
+                    context.fillRect(left, top, thumbPosition, height);
+                }
+            }
+
 
 
+            if (this.shadowBlur || this.shadowOffsetX || this.shadowOffsetY) {
+                context.shadowColor = this.shadowColor;
+                context.shadowBlur = this.shadowBlur;
+                context.shadowOffsetX = this.shadowOffsetX;
+                context.shadowOffsetY = this.shadowOffsetY;
+            }
+            if (this._isThumbCircle) {
+                context.beginPath();
+                if (this._isVertical) {
+                    context.arc(left + backgroundBoxThickness / 2, top + thumbPosition, radius, 0, 2 * Math.PI);
+                }
+                else {
+                    context.arc(left + thumbPosition, top + (backgroundBoxThickness / 2), radius, 0, 2 * Math.PI);
+                }
+                context.fill();
                 if (this.shadowBlur || this.shadowOffsetX || this.shadowOffsetY) {
                 if (this.shadowBlur || this.shadowOffsetX || this.shadowOffsetY) {
                     context.shadowBlur = 0;
                     context.shadowBlur = 0;
                     context.shadowOffsetX = 0;
                     context.shadowOffsetX = 0;
                     context.shadowOffsetY = 0;
                     context.shadowOffsetY = 0;
                 }
                 }
-                
-                context.fillStyle = this.color;
-                if(this._isVertical){
-                    if (this.isThumbClamped) {
-                        if (this.isThumbCircle) {
-                            context.beginPath();
-                            context.arc(left + backgroundBoxThickness / 2, top + backgroundBoxLength, radius, 0, 2 * Math.PI);
-                            context.fill();
-                            context.fillRect(left, top + thumbPosition, width, height - thumbPosition);
-                        }
-                        else {
-                            context.fillRect(left, top + thumbPosition, width, this._currentMeasure.height - thumbPosition);
-                        }
-                    }
-                    else {
-                        context.fillRect(left, top + thumbPosition ,width,  height - thumbPosition);
-                    }
+                context.strokeStyle = this._borderColor;
+                context.stroke();
+            }
+            else {
+                if (this._isVertical) {
+                    context.fillRect(left - effectiveBarOffset, this._currentMeasure.top + thumbPosition, this._currentMeasure.width, effectiveThumbThickness);
                 }
                 }
-                else{
-                    if (this.isThumbClamped) {
-                        if (this.isThumbCircle) {
-                            context.beginPath();
-                            context.arc(left , top + backgroundBoxThickness/2 , radius, 0, 2 * Math.PI);
-                            context.fill();
-                            context.fillRect(left, top, thumbPosition, height);
-                        }
-                        else {
-                            context.fillRect(left, top, thumbPosition, height);
-                        }
-                    }
-                    else {
-                        context.fillRect(left , top, thumbPosition,  height);
-                    }
+                else {
+                    context.fillRect(this._currentMeasure.left + thumbPosition, this._currentMeasure.top, effectiveThumbThickness, this._currentMeasure.height);
                 }
                 }
-               
-               
                 if (this.shadowBlur || this.shadowOffsetX || this.shadowOffsetY) {
                 if (this.shadowBlur || this.shadowOffsetX || this.shadowOffsetY) {
-                    context.shadowColor = this.shadowColor;
-                    context.shadowBlur = this.shadowBlur;
-                    context.shadowOffsetX = this.shadowOffsetX;
-                    context.shadowOffsetY = this.shadowOffsetY;
+                    context.shadowBlur = 0;
+                    context.shadowOffsetX = 0;
+                    context.shadowOffsetY = 0;
                 }
                 }
-                if (this._isThumbCircle) {
-                    context.beginPath();
-                    if (this._isVertical) {
-                        context.arc(left + backgroundBoxThickness / 2, top + thumbPosition, radius, 0, 2 * Math.PI);
-                    }
-                    else {
-                        context.arc(left + thumbPosition, top + ( backgroundBoxThickness/2), radius, 0, 2 * Math.PI);
-                    }
-                    context.fill();
-                    if (this.shadowBlur || this.shadowOffsetX || this.shadowOffsetY) {
-                        context.shadowBlur = 0;
-                        context.shadowOffsetX = 0;
-                        context.shadowOffsetY = 0;
-                    }
-                    context.strokeStyle = this._borderColor;
-                    context.stroke();
+                context.strokeStyle = this._borderColor;
+                if (this._isVertical) {
+                    context.strokeRect(left - effectiveBarOffset, this._currentMeasure.top + thumbPosition, this._currentMeasure.width, effectiveThumbThickness);
                 }
                 }
                 else {
                 else {
-                    if (this._isVertical) {
-                        context.fillRect(left - effectiveBarOffset, this._currentMeasure.top + thumbPosition, this._currentMeasure.width, effectiveThumbThickness);
-                    }
-                    else {
-                        context.fillRect(this._currentMeasure.left + thumbPosition, this._currentMeasure.top, effectiveThumbThickness, this._currentMeasure.height);
-                    }
-                    if (this.shadowBlur || this.shadowOffsetX || this.shadowOffsetY) {
-                        context.shadowBlur = 0;
-                        context.shadowOffsetX = 0;
-                        context.shadowOffsetY = 0;
-                    }
-                    context.strokeStyle = this._borderColor;
-                    if (this._isVertical) {
-                        context.strokeRect(left - effectiveBarOffset, this._currentMeasure.top + thumbPosition, this._currentMeasure.width, effectiveThumbThickness);
-                    }
-                    else {
-                        context.strokeRect(this._currentMeasure.left + thumbPosition, this._currentMeasure.top, effectiveThumbThickness, this._currentMeasure.height);
-                    }
+                    context.strokeRect(this._currentMeasure.left + thumbPosition, this._currentMeasure.top, effectiveThumbThickness, this._currentMeasure.height);
                 }
                 }
             }
             }
-            context.restore();
         }
         }
+        context.restore();
+    }
 
 
 
 
-        // Events
-        private _pointerIsDown = false;
+    // Events
+    private _pointerIsDown = false;
 
 
-        private _updateValueFromPointer(x: number, y: number): void {
-            if (this.rotation != 0) {
-                this._invertTransformMatrix.transformCoordinates(x, y, this._transformedPosition);
-                x = this._transformedPosition.x;
-                y = this._transformedPosition.y;
-            }
-            
-            if(this._isVertical){
-                this.value = this._minimum + (1 - ((y - this._currentMeasure.top) / this._currentMeasure.height)) * (this._maximum - this._minimum);
-            }
-            else{
-                this.value = this._minimum + ((x - this._currentMeasure.left) / this._currentMeasure.width) * (this._maximum - this._minimum);
-            }
+    private _updateValueFromPointer(x: number, y: number): void {
+        if (this.rotation != 0) {
+            this._invertTransformMatrix.transformCoordinates(x, y, this._transformedPosition);
+            x = this._transformedPosition.x;
+            y = this._transformedPosition.y;
         }
         }
 
 
-        public _onPointerDown(target: Control, coordinates: Vector2, pointerId:number, buttonIndex: number): boolean {
-            if (!super._onPointerDown(target, coordinates, pointerId, buttonIndex)) {
-                return false;
-            }
+        if (this._isVertical) {
+            this.value = this._minimum + (1 - ((y - this._currentMeasure.top) / this._currentMeasure.height)) * (this._maximum - this._minimum);
+        }
+        else {
+            this.value = this._minimum + ((x - this._currentMeasure.left) / this._currentMeasure.width) * (this._maximum - this._minimum);
+        }
+    }
 
 
-            this._pointerIsDown = true;
+    public _onPointerDown(target: Control, coordinates: Vector2, pointerId: number, buttonIndex: number): boolean {
+        if (!super._onPointerDown(target, coordinates, pointerId, buttonIndex)) {
+            return false;
+        }
 
 
-            this._updateValueFromPointer(coordinates.x, coordinates.y);
-            this._host._capturingControl[pointerId] = this;
+        this._pointerIsDown = true;
 
 
-            return true;
-        }
+        this._updateValueFromPointer(coordinates.x, coordinates.y);
+        this._host._capturingControl[pointerId] = this;
 
 
-        public _onPointerMove(target: Control, coordinates: Vector2): void {
-            if (this._pointerIsDown) {
-                this._updateValueFromPointer(coordinates.x, coordinates.y);
-            }
+        return true;
+    }
 
 
-            super._onPointerMove(target, coordinates);
+    public _onPointerMove(target: Control, coordinates: Vector2): void {
+        if (this._pointerIsDown) {
+            this._updateValueFromPointer(coordinates.x, coordinates.y);
         }
         }
 
 
-        public _onPointerUp(target: Control, coordinates: Vector2, pointerId:number, buttonIndex: number, notifyClick: boolean): void {
-            this._pointerIsDown = false;
+        super._onPointerMove(target, coordinates);
+    }
 
 
-            delete this._host._capturingControl[pointerId];
-            super._onPointerUp(target, coordinates, pointerId, buttonIndex, notifyClick);
-        }
+    public _onPointerUp(target: Control, coordinates: Vector2, pointerId: number, buttonIndex: number, notifyClick: boolean): void {
+        this._pointerIsDown = false;
+
+        delete this._host._capturingControl[pointerId];
+        super._onPointerUp(target, coordinates, pointerId, buttonIndex, notifyClick);
     }
     }
 }
 }

+ 127 - 127
gui/src/2D/controls/stackPanel.ts

@@ -1,153 +1,153 @@
-/// <reference path="../../../../dist/preview release/babylon.d.ts"/>
+import { Container } from "./container";
+import { Measure } from "../measure";
+import { Control } from "./control";
+
+/**
+ * Class used to create a 2D stack panel container
+ */
+export class StackPanel extends Container {
+    private _isVertical = true;
+    private _manualWidth = false;
+    private _manualHeight = false;
+    private _doNotTrackManualChanges = false;
+    private _tempMeasureStore = Measure.Empty();
+
+    /** Gets or sets a boolean indicating if the stack panel is vertical or horizontal*/
+    public get isVertical(): boolean {
+        return this._isVertical;
+    }
+
+    public set isVertical(value: boolean) {
+        if (this._isVertical === value) {
+            return;
+        }
 
 
-module BABYLON.GUI {
-    /**
-     * Class used to create a 2D stack panel container
-     */
-    export class StackPanel extends Container {
-        private _isVertical = true;
-        private _manualWidth = false;
-        private _manualHeight = false;
-        private _doNotTrackManualChanges = false;
-        private _tempMeasureStore = Measure.Empty();
-
-        /** Gets or sets a boolean indicating if the stack panel is vertical or horizontal*/
-        public get isVertical(): boolean {
-            return this._isVertical;
+        this._isVertical = value;
+        this._markAsDirty();
+    }
+
+    /** Gets or sets panel width */
+    public set width(value: string | number) {
+        if (!this._doNotTrackManualChanges) {
+            this._manualWidth = true;
         }
         }
 
 
-        public set isVertical(value: boolean) {
-            if (this._isVertical === value) {
-                return;
-            }
+        if (this._width.toString(this._host) === value) {
+            return;
+        }
 
 
-            this._isVertical = value;
+        if (this._width.fromString(value)) {
             this._markAsDirty();
             this._markAsDirty();
         }
         }
-       
-        /** Gets or sets panel width */
-        public set width(value: string | number ) {
-            if (!this._doNotTrackManualChanges) {
-                this._manualWidth = true;
-            }
+    }
 
 
-            if (this._width.toString(this._host) === value) {
-                return;
-            }
+    public get width(): string | number {
+        return this._width.toString(this._host);
+    }
 
 
-            if (this._width.fromString(value)) {
-                this._markAsDirty();
-            }
+    /** Gets or sets panel height */
+    public set height(value: string | number) {
+        if (!this._doNotTrackManualChanges) {
+            this._manualHeight = true;
         }
         }
 
 
-        public get width(): string | number {
-            return this._width.toString(this._host);
-        }        
+        if (this._height.toString(this._host) === value) {
+            return;
+        }
 
 
-        /** Gets or sets panel height */
-        public set height(value: string | number ) {
-            if (!this._doNotTrackManualChanges) {
-                this._manualHeight = true;
-            }
+        if (this._height.fromString(value)) {
+            this._markAsDirty();
+        }
+    }
 
 
-            if (this._height.toString(this._host) === value) {
-                return;
-            }
+    public get height(): string | number {
+        return this._height.toString(this._host);
+    }
 
 
-            if (this._height.fromString(value)) {
-                this._markAsDirty();
+    /**
+     * Creates a new StackPanel
+     * @param name defines control name
+     */
+    constructor(public name?: string) {
+        super(name);
+    }
+
+    protected _getTypeName(): string {
+        return "StackPanel";
+    }
+
+    protected _preMeasure(parentMeasure: Measure, context: CanvasRenderingContext2D): void {
+        var stackWidth = 0;
+        var stackHeight = 0;
+        for (var child of this._children) {
+            this._tempMeasureStore.copyFrom(child._currentMeasure);
+            child._currentMeasure.copyFrom(parentMeasure);
+            child._measure();
+
+            if (this._isVertical) {
+                child.top = stackHeight + "px";
+                if (!child._top.ignoreAdaptiveScaling) {
+                    child._markAsDirty();
+                }
+                child._top.ignoreAdaptiveScaling = true;
+                stackHeight += child._currentMeasure.height;
+                if (child._currentMeasure.width > stackWidth) {
+                    stackWidth = child._currentMeasure.width;
+                }
+                child.verticalAlignment = Control.VERTICAL_ALIGNMENT_TOP;
+            } else {
+                child.left = stackWidth + "px";
+                if (!child._left.ignoreAdaptiveScaling) {
+                    child._markAsDirty();
+                }
+                child._left.ignoreAdaptiveScaling = true;
+                stackWidth += child._currentMeasure.width;
+                if (child._currentMeasure.height > stackHeight) {
+                    stackHeight = child._currentMeasure.height;
+                }
+                child.horizontalAlignment = Control.HORIZONTAL_ALIGNMENT_LEFT;
             }
             }
-        }        
-                
-        public get height(): string | number  {
-            return this._height.toString(this._host);
-        }
-    
-        /**
-         * Creates a new StackPanel
-         * @param name defines control name
-         */
-        constructor(public name?: string) {
-            super(name);
+
+            child._currentMeasure.copyFrom(this._tempMeasureStore);
         }
         }
 
 
-        protected _getTypeName(): string {
-            return "StackPanel";
-        }              
-
-        protected _preMeasure(parentMeasure: Measure, context: CanvasRenderingContext2D): void {
-            var stackWidth = 0;
-            var stackHeight = 0;
-            for (var child of this._children) {
-                this._tempMeasureStore.copyFrom(child._currentMeasure);
-                child._currentMeasure.copyFrom(parentMeasure);
-                child._measure();
-                
-                if (this._isVertical) {
-                    child.top = stackHeight + "px";
-                    if (!child._top.ignoreAdaptiveScaling) {
-                        child._markAsDirty();
-                    }
-                    child._top.ignoreAdaptiveScaling = true;
-                    stackHeight += child._currentMeasure.height;
-                    if(child._currentMeasure.width > stackWidth) {
-                        stackWidth = child._currentMeasure.width;                        
-                    }
-                    child.verticalAlignment = BABYLON.GUI.Control.VERTICAL_ALIGNMENT_TOP;
-                } else {
-                    child.left = stackWidth + "px";
-                    if (!child._left.ignoreAdaptiveScaling) {
-                        child._markAsDirty();
-                    }                    
-                    child._left.ignoreAdaptiveScaling = true;
-                    stackWidth += child._currentMeasure.width;
-                    if(child._currentMeasure.height > stackHeight) {
-                        stackHeight = child._currentMeasure.height;                        
-                    }
-                    child.horizontalAlignment = BABYLON.GUI.Control.HORIZONTAL_ALIGNMENT_LEFT;
-                }
+        this._doNotTrackManualChanges = true;
 
 
-                child._currentMeasure.copyFrom(this._tempMeasureStore);
-            }
-            
-            this._doNotTrackManualChanges = true;
+        // Let stack panel width and height default to stackHeight and stackWidth if dimensions are not specified.
+        // User can now define their own height and width for stack panel.
 
 
-            // Let stack panel width and height default to stackHeight and stackWidth if dimensions are not specified.
-            // User can now define their own height and width for stack panel.
+        let panelWidthChanged = false;
+        let panelHeightChanged = false;
 
 
-            let panelWidthChanged = false;
-            let panelHeightChanged = false;
+        let previousHeight = this.height;
+        let previousWidth = this.width;
 
 
-            let previousHeight = this.height;
-            let previousWidth = this.width;
+        if (!this._manualHeight) {
+            // do not specify height if strictly defined by user
+            this.height = stackHeight + "px";
+        }
+        if (!this._manualWidth) {
+            // do not specify width if strictly defined by user
+            this.width = stackWidth + "px";
+        }
 
 
-            if (!this._manualHeight) {
-                // do not specify height if strictly defined by user
-                this.height = stackHeight + "px";
-            }
-            if (!this._manualWidth) {
-                // do not specify width if strictly defined by user
-                this.width = stackWidth + "px";
-            }
+        panelWidthChanged = previousWidth !== this.width || !this._width.ignoreAdaptiveScaling;
+        panelHeightChanged = previousHeight !== this.height || !this._height.ignoreAdaptiveScaling;
 
 
-            panelWidthChanged = previousWidth !== this.width || !this._width.ignoreAdaptiveScaling;
-            panelHeightChanged = previousHeight !== this.height || !this._height.ignoreAdaptiveScaling;
+        if (panelHeightChanged) {
+            this._height.ignoreAdaptiveScaling = true;
+        }
 
 
-            if (panelHeightChanged) {
-                this._height.ignoreAdaptiveScaling = true;
-            }
+        if (panelWidthChanged) {
+            this._width.ignoreAdaptiveScaling = true;
+        }
 
 
-            if (panelWidthChanged) {
-                this._width.ignoreAdaptiveScaling = true;
-            }
+        this._doNotTrackManualChanges = false;
 
 
-            this._doNotTrackManualChanges = false;
+        if (panelWidthChanged || panelHeightChanged) {
+            this._markAllAsDirty();
+        }
 
 
-            if (panelWidthChanged || panelHeightChanged) {
-                this._markAllAsDirty();
-            }
-            
-            super._preMeasure(parentMeasure, context);
-        }    
-    }    
-}
+        super._preMeasure(parentMeasure, context);
+    }
+}  

+ 53 - 0
gui/src/2D/controls/statics.ts

@@ -0,0 +1,53 @@
+import { Control } from "./control";
+import { StackPanel } from "./stackPanel";
+import { TextBlock } from "./textBlock";
+
+/**
+ * Forcing an export so that this code will execute
+ * @hidden
+ */
+const name = "Statics";
+
+export { name };
+
+/**
+ * Creates a stack panel that can be used to render headers
+ * @param control defines the control to associate with the header
+ * @param text defines the text of the header
+ * @param size defines the size of the header
+ * @param options defines options used to configure the header
+ * @returns a new StackPanel
+ */
+Control.AddHeader = function (control: Control, text: string, size: string | number, options: { isHorizontal: boolean, controlFirst: boolean }): StackPanel {
+    let panel = new StackPanel("panel");
+    let isHorizontal = options ? options.isHorizontal : true;
+    let controlFirst = options ? options.controlFirst : true;
+
+    panel.isVertical = !isHorizontal;
+
+    let header = new TextBlock("header");
+    header.text = text;
+    header.textHorizontalAlignment = Control.HORIZONTAL_ALIGNMENT_LEFT;
+    if (isHorizontal) {
+        header.width = size;
+    } else {
+        header.height = size;
+    }
+
+    if (controlFirst) {
+        panel.addControl(control);
+        panel.addControl(header);
+        header.paddingLeft = "5px";
+    } else {
+        panel.addControl(header);
+        panel.addControl(control);
+        header.paddingRight = "5px";
+    }
+
+    header.shadowBlur = control.shadowBlur;
+    header.shadowColor = control.shadowColor;
+    header.shadowOffsetX = control.shadowOffsetX;
+    header.shadowOffsetY = control.shadowOffsetY;
+
+    return panel;
+}

+ 329 - 328
gui/src/2D/controls/textBlock.ts

@@ -1,414 +1,415 @@
-/// <reference path="../../../../dist/preview release/babylon.d.ts"/>
+import { Observable } from "babylonjs";
+import { Measure } from "../measure";
+import { ValueAndUnit } from "../valueAndUnit";
+import { Control } from "./control";
+
+/**
+ * Enum that determines the text-wrapping mode to use.
+ */
+export enum TextWrapping {
+    /**
+     * Clip the text when it's larger than Control.width; this is the default mode.
+     */
+    Clip = 0,
 
 
-module BABYLON.GUI {
     /**
     /**
-     * Enum that determines the text-wrapping mode to use.
+     * Wrap the text word-wise, i.e. try to add line-breaks at word boundary to fit within Control.width.
      */
      */
-    export enum TextWrapping {
-        /**
-         * Clip the text when it's larger than Control.width; this is the default mode.
-         */
-        Clip = 0,
+    WordWrap = 1,
 
 
-        /**
-         * Wrap the text word-wise, i.e. try to add line-breaks at word boundary to fit within Control.width.
-         */
-        WordWrap = 1,
+    /**
+     * Ellipsize the text, i.e. shrink with trailing … when text is larger than Control.width.
+     */
+    Ellipsis,
+}
+
+/**
+ * Class used to create text block control
+ */
+export class TextBlock extends Control {
+    private _text = "";
+    private _textWrapping = TextWrapping.Clip;
+    private _textHorizontalAlignment = Control.HORIZONTAL_ALIGNMENT_CENTER;
+    private _textVerticalAlignment = Control.VERTICAL_ALIGNMENT_CENTER;
+
+    private _lines: any[];
+    private _resizeToFit: boolean = false;
+    private _lineSpacing: ValueAndUnit = new ValueAndUnit(0);
+    private _outlineWidth: number = 0;
+    private _outlineColor: string = "white";
+    /**
+    * An event triggered after the text is changed
+    */
+    public onTextChangedObservable = new Observable<TextBlock>();
 
 
-        /**
-         * Ellipsize the text, i.e. shrink with trailing … when text is larger than Control.width.
-         */
-        Ellipsis,
+    /**
+    * An event triggered after the text was broken up into lines
+    */
+    public onLinesReadyObservable = new Observable<TextBlock>();
+
+    /**
+     * Return the line list (you may need to use the onLinesReadyObservable to make sure the list is ready)
+     */
+    public get lines(): any[] {
+        return this._lines;
     }
     }
 
 
     /**
     /**
-     * Class used to create text block control
+     * Gets or sets an boolean indicating that the TextBlock will be resized to fit container
      */
      */
-    export class TextBlock extends Control {
-        private _text = "";
-        private _textWrapping = TextWrapping.Clip;
-        private _textHorizontalAlignment = Control.HORIZONTAL_ALIGNMENT_CENTER;
-        private _textVerticalAlignment = Control.VERTICAL_ALIGNMENT_CENTER;
-
-        private _lines: any[];
-        private _resizeToFit: boolean = false;
-        private _lineSpacing: ValueAndUnit = new ValueAndUnit(0);
-        private _outlineWidth: number = 0;
-        private _outlineColor: string = "white";
-        /**
-        * An event triggered after the text is changed
-        */
-        public onTextChangedObservable = new Observable<TextBlock>();
+    public get resizeToFit(): boolean {
+        return this._resizeToFit;
+    }
 
 
-        /**
-        * An event triggered after the text was broken up into lines
-        */
-        public onLinesReadyObservable = new Observable<TextBlock>();
+    /**
+     * Gets or sets an boolean indicating that the TextBlock will be resized to fit container
+     */
+    public set resizeToFit(value: boolean) {
+        this._resizeToFit = value;
 
 
-        /**
-         * Return the line list (you may need to use the onLinesReadyObservable to make sure the list is ready)
-         */
-        public get lines(): any[] {
-            return this._lines;
-        }
-        
-        /**
-         * Gets or sets an boolean indicating that the TextBlock will be resized to fit container
-         */
-        public get resizeToFit(): boolean {
-            return this._resizeToFit;
+        if (this._resizeToFit) {
+            this._width.ignoreAdaptiveScaling = true;
+            this._height.ignoreAdaptiveScaling = true;
         }
         }
+    }
 
 
-        /**
-         * Gets or sets an boolean indicating that the TextBlock will be resized to fit container
-         */        
-        public set resizeToFit(value: boolean) {
-            this._resizeToFit = value;
-
-            if (this._resizeToFit) {
-                this._width.ignoreAdaptiveScaling = true;
-                this._height.ignoreAdaptiveScaling = true;
-            }
-        }
+    /**
+     * Gets or sets a boolean indicating if text must be wrapped
+     */
+    public get textWrapping(): TextWrapping | boolean {
+        return this._textWrapping;
+    }
 
 
-        /**
-         * Gets or sets a boolean indicating if text must be wrapped
-         */
-        public get textWrapping(): TextWrapping | boolean {
-            return this._textWrapping;
+    /**
+     * Gets or sets a boolean indicating if text must be wrapped
+     */
+    public set textWrapping(value: TextWrapping | boolean) {
+        if (this._textWrapping === value) {
+            return;
         }
         }
+        this._textWrapping = +value;
+        this._markAsDirty();
+    }
 
 
-        /**
-         * Gets or sets a boolean indicating if text must be wrapped
-         */        
-        public set textWrapping(value: TextWrapping | boolean) {
-            if (this._textWrapping === value) {
-                return;
-            }
-            this._textWrapping = +value;
-            this._markAsDirty();
-        }
+    /**
+     * Gets or sets text to display
+     */
+    public get text(): string {
+        return this._text;
+    }
 
 
-        /**
-         * Gets or sets text to display
-         */
-        public get text(): string {
-            return this._text;
+    /**
+     * Gets or sets text to display
+     */
+    public set text(value: string) {
+        if (this._text === value) {
+            return;
         }
         }
+        this._text = value;
+        this._markAsDirty();
 
 
-        /**
-         * Gets or sets text to display
-         */
-        public set text(value: string) {
-            if (this._text === value) {
-                return;
-            }
-            this._text = value;
-            this._markAsDirty();
+        this.onTextChangedObservable.notifyObservers(this);
+    }
 
 
-            this.onTextChangedObservable.notifyObservers(this);
-        }
+    /**
+     * Gets or sets text horizontal alignment (BABYLON.GUI.Control.HORIZONTAL_ALIGNMENT_CENTER by default)
+     */
+    public get textHorizontalAlignment(): number {
+        return this._textHorizontalAlignment;
+    }
 
 
-        /**
-         * Gets or sets text horizontal alignment (BABYLON.GUI.Control.HORIZONTAL_ALIGNMENT_CENTER by default)
-         */
-        public get textHorizontalAlignment(): number {
-            return this._textHorizontalAlignment;
+    /**
+     * Gets or sets text horizontal alignment (BABYLON.GUI.Control.HORIZONTAL_ALIGNMENT_CENTER by default)
+     */
+    public set textHorizontalAlignment(value: number) {
+        if (this._textHorizontalAlignment === value) {
+            return;
         }
         }
 
 
-        /**
-         * Gets or sets text horizontal alignment (BABYLON.GUI.Control.HORIZONTAL_ALIGNMENT_CENTER by default)
-         */        
-        public set textHorizontalAlignment(value: number) {
-            if (this._textHorizontalAlignment === value) {
-                return;
-            }
+        this._textHorizontalAlignment = value;
+        this._markAsDirty();
+    }
 
 
-            this._textHorizontalAlignment = value;
-            this._markAsDirty();
-        }
+    /**
+     * Gets or sets text vertical alignment (BABYLON.GUI.Control.VERTICAL_ALIGNMENT_CENTER by default)
+     */
+    public get textVerticalAlignment(): number {
+        return this._textVerticalAlignment;
+    }
 
 
-        /**
-         * Gets or sets text vertical alignment (BABYLON.GUI.Control.VERTICAL_ALIGNMENT_CENTER by default)
-         */        
-        public get textVerticalAlignment(): number {
-            return this._textVerticalAlignment;
+    /**
+     * Gets or sets text vertical alignment (BABYLON.GUI.Control.VERTICAL_ALIGNMENT_CENTER by default)
+     */
+    public set textVerticalAlignment(value: number) {
+        if (this._textVerticalAlignment === value) {
+            return;
         }
         }
 
 
-        /**
-         * Gets or sets text vertical alignment (BABYLON.GUI.Control.VERTICAL_ALIGNMENT_CENTER by default)
-         */           
-        public set textVerticalAlignment(value: number) {
-            if (this._textVerticalAlignment === value) {
-                return;
-            }
+        this._textVerticalAlignment = value;
+        this._markAsDirty();
+    }
 
 
-            this._textVerticalAlignment = value;
+    /**
+     * Gets or sets line spacing value
+     */
+    public set lineSpacing(value: string | number) {
+        if (this._lineSpacing.fromString(value)) {
             this._markAsDirty();
             this._markAsDirty();
         }
         }
+    }
 
 
-        /**
-         * Gets or sets line spacing value
-         */
-        public set lineSpacing(value: string | number) {
-            if (this._lineSpacing.fromString(value)) {
-                this._markAsDirty();
-            }
-        }
+    /**
+     * Gets or sets line spacing value
+     */
+    public get lineSpacing(): string | number {
+        return this._lineSpacing.toString(this._host);
+    }
 
 
-        /**
-         * Gets or sets line spacing value
-         */        
-        public get lineSpacing(): string | number {
-            return this._lineSpacing.toString(this._host);
-        }
+    /**
+     * Gets or sets outlineWidth of the text to display
+     */
+    public get outlineWidth(): number {
+        return this._outlineWidth;
+    }
 
 
-        /**
-         * Gets or sets outlineWidth of the text to display
-         */
-        public get outlineWidth(): number {
-            return this._outlineWidth;
+    /**
+     * Gets or sets outlineWidth of the text to display
+     */
+    public set outlineWidth(value: number) {
+        if (this._outlineWidth === value) {
+            return;
         }
         }
+        this._outlineWidth = value;
+        this._markAsDirty();
+    }
 
 
-        /**
-         * Gets or sets outlineWidth of the text to display
-         */
-        public set outlineWidth(value: number) {
-            if (this._outlineWidth === value) {
-                return;
-            }
-            this._outlineWidth = value;
-            this._markAsDirty();
-        }
+    /**
+     * Gets or sets outlineColor of the text to display
+     */
+    public get outlineColor(): string {
+        return this._outlineColor;
+    }
 
 
-        /**
-         * Gets or sets outlineColor of the text to display
-         */
-        public get outlineColor(): string {
-            return this._outlineColor;
+    /**
+     * Gets or sets outlineColor of the text to display
+     */
+    public set outlineColor(value: string) {
+        if (this._outlineColor === value) {
+            return;
         }
         }
+        this._outlineColor = value;
+        this._markAsDirty();
+    }
 
 
+    /**
+     * Creates a new TextBlock object
+     * @param name defines the name of the control
+     * @param text defines the text to display (emptry string by default)
+     */
+    constructor(
         /**
         /**
-         * Gets or sets outlineColor of the text to display
+         * Defines the name of the control
          */
          */
-        public set outlineColor(value: string) {
-            if (this._outlineColor === value) {
-                return;
-            }
-            this._outlineColor = value;
-            this._markAsDirty();
+        public name?: string,
+        text: string = "") {
+        super(name);
+
+        this.text = text;
+    }
+
+    protected _getTypeName(): string {
+        return "TextBlock";
+    }
+
+    private _drawText(text: string, textWidth: number, y: number, context: CanvasRenderingContext2D): void {
+        var width = this._currentMeasure.width;
+        var x = 0;
+        switch (this._textHorizontalAlignment) {
+            case Control.HORIZONTAL_ALIGNMENT_LEFT:
+                x = 0
+                break;
+            case Control.HORIZONTAL_ALIGNMENT_RIGHT:
+                x = width - textWidth;
+                break;
+            case Control.HORIZONTAL_ALIGNMENT_CENTER:
+                x = (width - textWidth) / 2;
+                break;
         }
         }
 
 
-        /**
-         * Creates a new TextBlock object
-         * @param name defines the name of the control
-         * @param text defines the text to display (emptry string by default)
-         */
-        constructor(
-            /**
-             * Defines the name of the control
-             */
-            public name?: string, 
-            text: string = "") {
-            super(name);
-
-            this.text = text;
+        if (this.shadowBlur || this.shadowOffsetX || this.shadowOffsetY) {
+            context.shadowColor = this.shadowColor;
+            context.shadowBlur = this.shadowBlur;
+            context.shadowOffsetX = this.shadowOffsetX;
+            context.shadowOffsetY = this.shadowOffsetY;
         }
         }
 
 
-        protected _getTypeName(): string {
-            return "TextBlock";
+        if (this.outlineWidth) {
+            context.strokeText(text, this._currentMeasure.left + x, y);
         }
         }
+        context.fillText(text, this._currentMeasure.left + x, y);
+    }
 
 
-        private _drawText(text: string, textWidth: number, y: number, context: CanvasRenderingContext2D): void {
-            var width = this._currentMeasure.width;
-            var x = 0;
-            switch (this._textHorizontalAlignment) {
-                case Control.HORIZONTAL_ALIGNMENT_LEFT:
-                    x = 0
-                    break;
-                case Control.HORIZONTAL_ALIGNMENT_RIGHT:
-                    x = width - textWidth;
-                    break;
-                case Control.HORIZONTAL_ALIGNMENT_CENTER:
-                    x = (width - textWidth) / 2;
-                    break;
-            }
+    /** @hidden */
+    public _draw(parentMeasure: Measure, context: CanvasRenderingContext2D): void {
+        context.save();
 
 
-            if (this.shadowBlur || this.shadowOffsetX || this.shadowOffsetY) {
-                context.shadowColor = this.shadowColor;
-                context.shadowBlur = this.shadowBlur;
-                context.shadowOffsetX = this.shadowOffsetX;
-                context.shadowOffsetY = this.shadowOffsetY;
-            }
+        this._applyStates(context);
 
 
-            if (this.outlineWidth) {
-                context.strokeText(text, this._currentMeasure.left + x, y);
-            }
-            context.fillText(text, this._currentMeasure.left + x, y);
+        if (this._processMeasures(parentMeasure, context)) {
+            // Render lines
+            this._renderLines(context);
         }
         }
+        context.restore();
+    }
 
 
-        /** @hidden */
-        public _draw(parentMeasure: Measure, context: CanvasRenderingContext2D): void {
-            context.save();
+    protected _applyStates(context: CanvasRenderingContext2D): void {
+        super._applyStates(context);
+        if (this.outlineWidth) {
+            context.lineWidth = this.outlineWidth;
+            context.strokeStyle = this.outlineColor;
+        }
+    }
 
 
-            this._applyStates(context);
+    protected _additionalProcessing(parentMeasure: Measure, context: CanvasRenderingContext2D): void {
+        this._lines = this._breakLines(this._currentMeasure.width, context);
+        this.onLinesReadyObservable.notifyObservers(this);
+    }
 
 
-            if (this._processMeasures(parentMeasure, context)) {
-                // Render lines
-                this._renderLines(context);
-            }
-            context.restore();
-        }
+    protected _breakLines(refWidth: number, context: CanvasRenderingContext2D): object[] {
+        var lines = [];
+        var _lines = this.text.split("\n");
 
 
-        protected _applyStates(context: CanvasRenderingContext2D): void {
-            super._applyStates(context);
-            if (this.outlineWidth) {
-                context.lineWidth = this.outlineWidth;
-                context.strokeStyle = this.outlineColor;
+        if (this._textWrapping === TextWrapping.Ellipsis && !this._resizeToFit) {
+            for (var _line of _lines) {
+                lines.push(this._parseLineEllipsis(_line, refWidth, context));
+            }
+        } else if (this._textWrapping === TextWrapping.WordWrap && !this._resizeToFit) {
+            for (var _line of _lines) {
+                lines.push(...this._parseLineWordWrap(_line, refWidth, context));
+            }
+        } else {
+            for (var _line of _lines) {
+                lines.push(this._parseLine(_line, context));
             }
             }
         }
         }
 
 
-        protected _additionalProcessing(parentMeasure: Measure, context: CanvasRenderingContext2D): void {
-            this._lines = this._breakLines(this._currentMeasure.width, context);
-            this.onLinesReadyObservable.notifyObservers(this);
-        }
+        return lines;
+    }
 
 
-        protected _breakLines(refWidth: number, context: CanvasRenderingContext2D): object[] {
-            var lines = [];
-            var _lines = this.text.split("\n");
+    protected _parseLine(line: string = '', context: CanvasRenderingContext2D): object {
+        return { text: line, width: context.measureText(line).width };
+    }
 
 
-            if (this._textWrapping === TextWrapping.Ellipsis && !this._resizeToFit) {
-                for (var _line of _lines) {
-                    lines.push(this._parseLineEllipsis(_line, refWidth, context));
-                }
-            } else if (this._textWrapping === TextWrapping.WordWrap && !this._resizeToFit) {
-                for (var _line of _lines) {
-                    lines.push(...this._parseLineWordWrap(_line, refWidth, context));
-                }
-            } else {
-                for (var _line of _lines) {
-                    lines.push(this._parseLine(_line, context));
-                }
-            }
+    protected _parseLineEllipsis(line: string = '', width: number,
+        context: CanvasRenderingContext2D): object {
+        var lineWidth = context.measureText(line).width;
 
 
-            return lines;
+        if (lineWidth > width) {
+            line += '…';
         }
         }
-
-        protected _parseLine(line: string = '', context: CanvasRenderingContext2D): object {
-            return { text: line, width: context.measureText(line).width };
+        while (line.length > 2 && lineWidth > width) {
+            line = line.slice(0, -2) + '…';
+            lineWidth = context.measureText(line).width;
         }
         }
 
 
-        protected _parseLineEllipsis(line: string = '', width: number,
-                                     context: CanvasRenderingContext2D): object {
-            var lineWidth = context.measureText(line).width;
+        return { text: line, width: lineWidth };
+    }
 
 
-            if (lineWidth > width) {
-                line += '…';
-            }
-            while (line.length > 2 && lineWidth > width) {
-                line = line.slice(0, -2) + '…';
+    protected _parseLineWordWrap(line: string = '', width: number,
+        context: CanvasRenderingContext2D): object[] {
+        var lines = [];
+        var words = line.split(' ');
+        var lineWidth = 0;
+
+        for (var n = 0; n < words.length; n++) {
+            var testLine = n > 0 ? line + " " + words[n] : words[0];
+            var metrics = context.measureText(testLine);
+            var testWidth = metrics.width;
+            if (testWidth > width && n > 0) {
+                lines.push({ text: line, width: lineWidth });
+                line = words[n];
                 lineWidth = context.measureText(line).width;
                 lineWidth = context.measureText(line).width;
             }
             }
-
-            return { text: line, width: lineWidth };
-        }
-
-        protected _parseLineWordWrap(line: string = '', width: number,
-                                     context: CanvasRenderingContext2D): object[] {
-            var lines = [];
-            var words = line.split(' ');
-            var lineWidth = 0;
-
-            for (var n = 0; n < words.length; n++) {
-                var testLine = n > 0 ? line + " " + words[n] : words[0];
-                var metrics = context.measureText(testLine);
-                var testWidth = metrics.width;
-                if (testWidth > width && n > 0) {
-                    lines.push({ text: line, width: lineWidth });
-                    line = words[n];
-                    lineWidth = context.measureText(line).width;
-                }
-                else {
-                    lineWidth = testWidth;
-                    line = testLine;
-                }
+            else {
+                lineWidth = testWidth;
+                line = testLine;
             }
             }
-            lines.push({ text: line, width: lineWidth });
-
-            return lines;
         }
         }
+        lines.push({ text: line, width: lineWidth });
 
 
-        protected _renderLines(context: CanvasRenderingContext2D): void {
-            var height = this._currentMeasure.height;
+        return lines;
+    }
 
 
-            if (!this._fontOffset) {
-                this._fontOffset = Control._GetFontOffset(context.font);
-            }
-            var rootY = 0;
-            switch (this._textVerticalAlignment) {
-                case Control.VERTICAL_ALIGNMENT_TOP:
-                    rootY = this._fontOffset.ascent;
-                    break;
-                case Control.VERTICAL_ALIGNMENT_BOTTOM:
-                    rootY = height - this._fontOffset.height * (this._lines.length - 1) - this._fontOffset.descent;
-                    break;
-                case Control.VERTICAL_ALIGNMENT_CENTER:
-                    rootY = this._fontOffset.ascent + (height - this._fontOffset.height * this._lines.length) / 2;
-                    break;
-            }
+    protected _renderLines(context: CanvasRenderingContext2D): void {
+        var height = this._currentMeasure.height;
 
 
-            rootY += this._currentMeasure.top;
+        if (!this._fontOffset) {
+            this._fontOffset = Control._GetFontOffset(context.font);
+        }
+        var rootY = 0;
+        switch (this._textVerticalAlignment) {
+            case Control.VERTICAL_ALIGNMENT_TOP:
+                rootY = this._fontOffset.ascent;
+                break;
+            case Control.VERTICAL_ALIGNMENT_BOTTOM:
+                rootY = height - this._fontOffset.height * (this._lines.length - 1) - this._fontOffset.descent;
+                break;
+            case Control.VERTICAL_ALIGNMENT_CENTER:
+                rootY = this._fontOffset.ascent + (height - this._fontOffset.height * this._lines.length) / 2;
+                break;
+        }
 
 
-            var maxLineWidth: number = 0;
+        rootY += this._currentMeasure.top;
 
 
-            for (let i = 0; i < this._lines.length; i++) {
-                const line = this._lines[i];
+        var maxLineWidth: number = 0;
 
 
-                if (i !== 0 && this._lineSpacing.internalValue !== 0) {
+        for (let i = 0; i < this._lines.length; i++) {
+            const line = this._lines[i];
 
 
-                    if (this._lineSpacing.isPixel) {
-                        rootY += this._lineSpacing.getValue(this._host);
-                    } else {                        
-                        rootY = rootY + (this._lineSpacing.getValue(this._host) * this._height.getValueInPixel(this._host,  this._cachedParentMeasure.height));
-                    }
+            if (i !== 0 && this._lineSpacing.internalValue !== 0) {
+
+                if (this._lineSpacing.isPixel) {
+                    rootY += this._lineSpacing.getValue(this._host);
+                } else {
+                    rootY = rootY + (this._lineSpacing.getValue(this._host) * this._height.getValueInPixel(this._host, this._cachedParentMeasure.height));
                 }
                 }
+            }
 
 
-                this._drawText(line.text, line.width, rootY, context);
-                rootY += this._fontOffset.height;
+            this._drawText(line.text, line.width, rootY, context);
+            rootY += this._fontOffset.height;
 
 
-                if (line.width > maxLineWidth) maxLineWidth = line.width;
-            }
+            if (line.width > maxLineWidth) maxLineWidth = line.width;
+        }
 
 
-            if (this._resizeToFit) {
-                this.width = this.paddingLeftInPixels + this.paddingRightInPixels + maxLineWidth + 'px';
-                this.height = this.paddingTopInPixels + this.paddingBottomInPixels + this._fontOffset.height * this._lines.length + 'px';
-            }
+        if (this._resizeToFit) {
+            this.width = this.paddingLeftInPixels + this.paddingRightInPixels + maxLineWidth + 'px';
+            this.height = this.paddingTopInPixels + this.paddingBottomInPixels + this._fontOffset.height * this._lines.length + 'px';
         }
         }
+    }
 
 
-        /**
-         * Given a width constraint applied on the text block, find the expected height
-         * @returns expected height
-         */
-        public computeExpectedHeight(): number {
-            if (this.text && this.widthInPixels) {
-                const context = document.createElement('canvas').getContext('2d');
-                if (context) {
-                    this._applyStates(context);
-                    if (!this._fontOffset) {
-                        this._fontOffset = Control._GetFontOffset(context.font);
-                    }
-                    const lines = this._lines ? this._lines : this._breakLines(
-                        this.widthInPixels - this.paddingLeftInPixels - this.paddingRightInPixels, context);
-                    return this.paddingTopInPixels + this.paddingBottomInPixels + this._fontOffset.height * lines.length;
+    /**
+     * Given a width constraint applied on the text block, find the expected height
+     * @returns expected height
+     */
+    public computeExpectedHeight(): number {
+        if (this.text && this.widthInPixels) {
+            const context = document.createElement('canvas').getContext('2d');
+            if (context) {
+                this._applyStates(context);
+                if (!this._fontOffset) {
+                    this._fontOffset = Control._GetFontOffset(context.font);
                 }
                 }
+                const lines = this._lines ? this._lines : this._breakLines(
+                    this.widthInPixels - this.paddingLeftInPixels - this.paddingRightInPixels, context);
+                return this.paddingTopInPixels + this.paddingBottomInPixels + this._fontOffset.height * lines.length;
             }
             }
-            return 0;
         }
         }
+        return 0;
+    }
 
 
-        dispose(): void {
-            super.dispose();
+    dispose(): void {
+        super.dispose();
 
 
-            this.onTextChangedObservable.clear();
-        }
+        this.onTextChangedObservable.clear();
     }
     }
-}
+}

+ 199 - 196
gui/src/2D/controls/virtualKeyboard.ts

@@ -1,238 +1,241 @@
-/// <reference path="../../../../dist/preview release/babylon.d.ts"/>
-
-module BABYLON.GUI {
+import { StackPanel } from "./stackPanel";
+import { Observable, Nullable, Observer } from "babylonjs";
+import { Button } from "./button";
+import { Container } from "./container";
+import { TextBlock } from "./textBlock";
+import { InputText } from "./inputText";
+
+
+/**
+ * Class used to store key control properties
+ */
+export class KeyPropertySet {
+    /** Width */
+    width?: string;
+    /** Height */
+    height?: string;
+    /** Left padding */
+    paddingLeft?: string;
+    /** Right padding */
+    paddingRight?: string;
+    /** Top padding */
+    paddingTop?: string;
+    /** Bottom padding */
+    paddingBottom?: string;
+    /** Foreground color */
+    color?: string;
+    /** Background color */
+    background?: string;
+}
 
 
-    /**
-     * Class used to store key control properties
-     */
-    export class KeyPropertySet {
-        /** Width */
-        width?: string;
-        /** Height */
-        height?: string;
-        /** Left padding */
-        paddingLeft?: string;
-        /** Right padding */
-        paddingRight?: string;
-        /** Top padding */
-        paddingTop?: string;
-        /** Bottom padding */
-        paddingBottom?: string;
-        /** Foreground color */
-        color?: string;
-        /** Background color */
-        background?: string;
+/**
+ * Class used to create virtual keyboard
+ */
+export class VirtualKeyboard extends StackPanel {
+    /** Observable raised when a key is pressed */
+    public onKeyPressObservable = new Observable<string>();
+
+    /** Gets or sets default key button width */
+    public defaultButtonWidth = "40px";
+    /** Gets or sets default key button height */
+    public defaultButtonHeight = "40px";
+
+    /** Gets or sets default key button left padding */
+    public defaultButtonPaddingLeft = "2px";
+    /** Gets or sets default key button right padding */
+    public defaultButtonPaddingRight = "2px";
+    /** Gets or sets default key button top padding */
+    public defaultButtonPaddingTop = "2px";
+    /** Gets or sets default key button bottom padding */
+    public defaultButtonPaddingBottom = "2px";
+
+    /** Gets or sets default key button foreground color */
+    public defaultButtonColor = "#DDD";
+    /** Gets or sets default key button background color */
+    public defaultButtonBackground = "#070707";
+
+    /** Gets or sets shift button foreground color */
+    public shiftButtonColor = "#7799FF";
+    /** Gets or sets shift button thickness*/
+    public selectedShiftThickness = 1;
+
+    /** Gets shift key state */
+    public shiftState = 0;
+
+    protected _getTypeName(): string {
+        return "VirtualKeyboard";
     }
     }
 
 
-    /**
-     * Class used to create virtual keyboard
-     */
-    export class VirtualKeyboard extends StackPanel {
-        /** Observable raised when a key is pressed */
-        public onKeyPressObservable = new Observable<string>();
-
-        /** Gets or sets default key button width */
-        public defaultButtonWidth = "40px";
-        /** Gets or sets default key button height */
-        public defaultButtonHeight = "40px";
-
-        /** Gets or sets default key button left padding */
-        public defaultButtonPaddingLeft = "2px";
-        /** Gets or sets default key button right padding */
-        public defaultButtonPaddingRight = "2px";
-        /** Gets or sets default key button top padding */
-        public defaultButtonPaddingTop = "2px";
-        /** Gets or sets default key button bottom padding */
-        public defaultButtonPaddingBottom = "2px";
-
-        /** Gets or sets default key button foreground color */
-        public defaultButtonColor = "#DDD";
-        /** Gets or sets default key button background color */
-        public defaultButtonBackground = "#070707";
-
-        /** Gets or sets shift button foreground color */
-        public shiftButtonColor = "#7799FF";
-        /** Gets or sets shift button thickness*/
-        public selectedShiftThickness = 1;
-
-        /** Gets shift key state */
-        public shiftState = 0;
-
-        protected _getTypeName(): string {
-            return "VirtualKeyboard";
-        }
+    private _createKey(key: string, propertySet: Nullable<KeyPropertySet>) {
+        var button = Button.CreateSimpleButton(key, key);
 
 
-        private _createKey(key: string, propertySet: Nullable<KeyPropertySet>) {
-            var button = Button.CreateSimpleButton(key, key);
+        button.width = propertySet && propertySet.width ? propertySet.width : this.defaultButtonWidth;
+        button.height = propertySet && propertySet.height ? propertySet.height : this.defaultButtonHeight;
+        button.color = propertySet && propertySet.color ? propertySet.color : this.defaultButtonColor;
+        button.background = propertySet && propertySet.background ? propertySet.background : this.defaultButtonBackground;
+        button.paddingLeft = propertySet && propertySet.paddingLeft ? propertySet.paddingLeft : this.defaultButtonPaddingLeft;
+        button.paddingRight = propertySet && propertySet.paddingRight ? propertySet.paddingRight : this.defaultButtonPaddingRight;
+        button.paddingTop = propertySet && propertySet.paddingTop ? propertySet.paddingTop : this.defaultButtonPaddingTop;
+        button.paddingBottom = propertySet && propertySet.paddingBottom ? propertySet.paddingBottom : this.defaultButtonPaddingBottom;
 
 
-            button.width = propertySet && propertySet.width ? propertySet.width : this.defaultButtonWidth;
-            button.height = propertySet && propertySet.height ? propertySet.height : this.defaultButtonHeight;
-            button.color = propertySet && propertySet.color ? propertySet.color : this.defaultButtonColor;
-            button.background = propertySet && propertySet.background ? propertySet.background : this.defaultButtonBackground;
-            button.paddingLeft = propertySet && propertySet.paddingLeft ? propertySet.paddingLeft : this.defaultButtonPaddingLeft;
-            button.paddingRight = propertySet && propertySet.paddingRight ? propertySet.paddingRight : this.defaultButtonPaddingRight;
-            button.paddingTop = propertySet && propertySet.paddingTop ? propertySet.paddingTop : this.defaultButtonPaddingTop;
-            button.paddingBottom = propertySet && propertySet.paddingBottom ? propertySet.paddingBottom : this.defaultButtonPaddingBottom;
+        button.thickness = 0;
+        button.isFocusInvisible = true;
 
 
-            button.thickness = 0;
-            button.isFocusInvisible = true;
+        button.shadowColor = this.shadowColor;
+        button.shadowBlur = this.shadowBlur;
+        button.shadowOffsetX = this.shadowOffsetX;
+        button.shadowOffsetY = this.shadowOffsetY;
 
 
-            button.shadowColor = this.shadowColor;
-            button.shadowBlur = this.shadowBlur;
-            button.shadowOffsetX = this.shadowOffsetX;
-            button.shadowOffsetY = this.shadowOffsetY;
+        button.onPointerUpObservable.add(() => {
+            this.onKeyPressObservable.notifyObservers(key);
+        });
 
 
-            button.onPointerUpObservable.add(() => {
-                this.onKeyPressObservable.notifyObservers(key);
-            });
+        return button;
+    }
 
 
-            return button;
-        }
+    /**
+     * Adds a new row of keys
+     * @param keys defines the list of keys to add
+     * @param propertySets defines the associated property sets
+     */
+    public addKeysRow(keys: Array<string>, propertySets?: Array<KeyPropertySet>): void {
+        let panel = new StackPanel();
+        panel.isVertical = false;
+        panel.isFocusInvisible = true;
 
 
-        /**
-         * Adds a new row of keys
-         * @param keys defines the list of keys to add
-         * @param propertySets defines the associated property sets
-         */
-        public addKeysRow(keys: Array<string>, propertySets?: Array<KeyPropertySet>): void {
-            let panel = new StackPanel();
-            panel.isVertical = false;
-            panel.isFocusInvisible = true;
-
-            for (var i = 0; i < keys.length; i++) {
-                let properties = null;
-
-                if (propertySets && propertySets.length === keys.length) {
-                    properties = propertySets[i];
-                }
+        for (var i = 0; i < keys.length; i++) {
+            let properties = null;
 
 
-                panel.addControl(this._createKey(keys[i], properties));
+            if (propertySets && propertySets.length === keys.length) {
+                properties = propertySets[i];
             }
             }
 
 
-            this.addControl(panel);
+            panel.addControl(this._createKey(keys[i], properties));
         }
         }
 
 
-        /**
-         * Set the shift key to a specific state
-         * @param shiftState defines the new shift state
-         */
-        public applyShiftState(shiftState: number): void {
-            if (!this.children) {
-                return;
-            }
+        this.addControl(panel);
+    }
 
 
-            for (var i = 0; i < this.children.length; i++) {
-                let row = this.children[i];
-                if (!row || !(<Container>row).children) {
-                    continue;
-                }
+    /**
+     * Set the shift key to a specific state
+     * @param shiftState defines the new shift state
+     */
+    public applyShiftState(shiftState: number): void {
+        if (!this.children) {
+            return;
+        }
 
 
-                let rowContainer = <Container>row;
-                for (var j = 0; j < rowContainer.children.length; j++) {
-                    let button = rowContainer.children[j] as Button;
+        for (var i = 0; i < this.children.length; i++) {
+            let row = this.children[i];
+            if (!row || !(<Container>row).children) {
+                continue;
+            }
 
 
-                    if (!button || !button.children[0]) {
-                        continue;
-                    }
+            let rowContainer = <Container>row;
+            for (var j = 0; j < rowContainer.children.length; j++) {
+                let button = rowContainer.children[j] as Button;
 
 
-                    let button_tblock = button.children[0] as TextBlock;
+                if (!button || !button.children[0]) {
+                    continue;
+                }
 
 
-                    if (button_tblock.text === "\u21E7") {
-                        button.color = (shiftState ? this.shiftButtonColor : this.defaultButtonColor);
-                        button.thickness = (shiftState > 1 ? this.selectedShiftThickness : 0);
-                    }
+                let button_tblock = button.children[0] as TextBlock;
 
 
-                    button_tblock.text = (shiftState > 0 ? button_tblock.text.toUpperCase() : button_tblock.text.toLowerCase());
+                if (button_tblock.text === "\u21E7") {
+                    button.color = (shiftState ? this.shiftButtonColor : this.defaultButtonColor);
+                    button.thickness = (shiftState > 1 ? this.selectedShiftThickness : 0);
                 }
                 }
-            }
-        }
-
-        private _connectedInputText: Nullable<InputText>;
-        private _onFocusObserver: Nullable<Observer<InputText>>;
-        private _onBlurObserver: Nullable<Observer<InputText>>;
-        private _onKeyPressObserver: Nullable<Observer<string>>;
 
 
-        /** Gets the input text control attached with the keyboard */
-        public get connectedInputText(): Nullable<InputText> {
-            return this._connectedInputText;
+                button_tblock.text = (shiftState > 0 ? button_tblock.text.toUpperCase() : button_tblock.text.toLowerCase());
+            }
         }
         }
+    }
 
 
-        /**
-         * Connects the keyboard with an input text control
-         * @param input defines the target control
-         */
-        public connect(input: InputText): void {
-            this.isVisible = false;
-            this._connectedInputText = input;
+    private _connectedInputText: Nullable<InputText>;
+    private _onFocusObserver: Nullable<Observer<InputText>>;
+    private _onBlurObserver: Nullable<Observer<InputText>>;
+    private _onKeyPressObserver: Nullable<Observer<string>>;
 
 
-            // Events hooking
-            this._onFocusObserver = input.onFocusObservable.add(() => {
-                this.isVisible = true;
-            });
+    /** Gets the input text control attached with the keyboard */
+    public get connectedInputText(): Nullable<InputText> {
+        return this._connectedInputText;
+    }
 
 
-            this._onBlurObserver = input.onBlurObservable.add(() => {
-                this.isVisible = false;
-            });
+    /**
+     * Connects the keyboard with an input text control
+     * @param input defines the target control
+     */
+    public connect(input: InputText): void {
+        this.isVisible = false;
+        this._connectedInputText = input;
 
 
-            this._onKeyPressObserver = this.onKeyPressObservable.add((key) => {
-                if (!this._connectedInputText) {
-                    return;
-                }
-                switch (key) {
-                    case "\u21E7":
-                        this.shiftState++;
-                        if (this.shiftState > 2) {
-                            this.shiftState = 0;
-                        }
-                        this.applyShiftState(this.shiftState);
-                        return;
-                    case "\u2190":
-                        this._connectedInputText.processKey(8);
-                        return;
-                    case "\u21B5":
-                        this._connectedInputText.processKey(13);
-                        return;
-                }
-                this._connectedInputText.processKey(-1, (this.shiftState ? key.toUpperCase() : key));
+        // Events hooking
+        this._onFocusObserver = input.onFocusObservable.add(() => {
+            this.isVisible = true;
+        });
 
 
-                if (this.shiftState === 1) {
-                    this.shiftState = 0;
-                    this.applyShiftState(this.shiftState);
-                }
-            });
-        }
+        this._onBlurObserver = input.onBlurObservable.add(() => {
+            this.isVisible = false;
+        });
 
 
-        /**
-         * Disconnects the keyboard from an input text control
-         */
-        public disconnect(): void {
+        this._onKeyPressObserver = this.onKeyPressObservable.add((key) => {
             if (!this._connectedInputText) {
             if (!this._connectedInputText) {
                 return;
                 return;
             }
             }
+            switch (key) {
+                case "\u21E7":
+                    this.shiftState++;
+                    if (this.shiftState > 2) {
+                        this.shiftState = 0;
+                    }
+                    this.applyShiftState(this.shiftState);
+                    return;
+                case "\u2190":
+                    this._connectedInputText.processKey(8);
+                    return;
+                case "\u21B5":
+                    this._connectedInputText.processKey(13);
+                    return;
+            }
+            this._connectedInputText.processKey(-1, (this.shiftState ? key.toUpperCase() : key));
 
 
-            this._connectedInputText.onFocusObservable.remove(this._onFocusObserver);
-            this._connectedInputText.onBlurObservable.remove(this._onBlurObserver);
-            this.onKeyPressObservable.remove(this._onKeyPressObserver);
+            if (this.shiftState === 1) {
+                this.shiftState = 0;
+                this.applyShiftState(this.shiftState);
+            }
+        });
+    }
 
 
-            this._connectedInputText = null;
+    /**
+     * Disconnects the keyboard from an input text control
+     */
+    public disconnect(): void {
+        if (!this._connectedInputText) {
+            return;
         }
         }
 
 
-        // Statics
+        this._connectedInputText.onFocusObservable.remove(this._onFocusObserver);
+        this._connectedInputText.onBlurObservable.remove(this._onBlurObserver);
+        this.onKeyPressObservable.remove(this._onKeyPressObserver);
 
 
-        /**
-         * Creates a new keyboard using a default layout
-         * @returns a new VirtualKeyboard
-         */
-        public static CreateDefaultLayout(): VirtualKeyboard {
-            let returnValue = new VirtualKeyboard();
+        this._connectedInputText = null;
+    }
 
 
-            returnValue.addKeysRow(["1", "2", "3", "4", "5", "6", "7", "8", "9", "0", "\u2190"]);
-            returnValue.addKeysRow(["q", "w", "e", "r", "t", "y", "u", "i", "o", "p"]);
-            returnValue.addKeysRow(["a", "s", "d", "f", "g", "h", "j", "k", "l", ";", "'", "\u21B5"]);
-            returnValue.addKeysRow(["\u21E7", "z", "x", "c", "v", "b", "n", "m", ",", ".", "/"]);
-            returnValue.addKeysRow([" "], [{ width: "200px" }]);
+    // Statics
 
 
-            return returnValue;
-        }
+    /**
+     * Creates a new keyboard using a default layout
+     * @returns a new VirtualKeyboard
+     */
+    public static CreateDefaultLayout(): VirtualKeyboard {
+        let returnValue = new VirtualKeyboard();
+
+        returnValue.addKeysRow(["1", "2", "3", "4", "5", "6", "7", "8", "9", "0", "\u2190"]);
+        returnValue.addKeysRow(["q", "w", "e", "r", "t", "y", "u", "i", "o", "p"]);
+        returnValue.addKeysRow(["a", "s", "d", "f", "g", "h", "j", "k", "l", ";", "'", "\u21B5"]);
+        returnValue.addKeysRow(["\u21E7", "z", "x", "c", "v", "b", "n", "m", ",", ".", "/"]);
+        returnValue.addKeysRow([" "], [{ width: "200px" }]);
+
+        return returnValue;
     }
     }
 }
 }

+ 8 - 0
gui/src/2D/index.ts

@@ -0,0 +1,8 @@
+export * from "./controls";
+
+export * from "./advancedDynamicTexture";
+export * from "./math2D";
+export * from "./measure";
+export * from "./multiLinePoint";
+export * from "./style";
+export * from "./valueAndUnit";

+ 184 - 186
gui/src/2D/math2D.ts

@@ -1,207 +1,205 @@
-/// <reference path="../../../dist/preview release/babylon.d.ts"/>
+import { Vector2, Epsilon, Nullable } from "babylonjs";
 
 
-module BABYLON.GUI {
+/**
+ * Class used to transport Vector2 information for pointer events
+ */
+export class Vector2WithInfo extends Vector2 {
     /**
     /**
-     * Class used to transport Vector2 information for pointer events
-     */    
-    export class Vector2WithInfo extends Vector2 {    
-        /**
-         * Creates a new Vector2WithInfo
-         * @param source defines the vector2 data to transport
-         * @param buttonIndex defines the current mouse button index
-         */    
-        public constructor(source: Vector2, 
-            /** defines the current mouse button index */
-            public buttonIndex: number = 0) {
-            super(source.x, source.y);
-        }
+     * Creates a new Vector2WithInfo
+     * @param source defines the vector2 data to transport
+     * @param buttonIndex defines the current mouse button index
+     */
+    public constructor(source: Vector2,
+        /** defines the current mouse button index */
+        public buttonIndex: number = 0) {
+        super(source.x, source.y);
     }
     }
+}
 
 
-    /** Class used to provide 2D matrix features */
-    export class Matrix2D {
-        /** Gets the internal array of 6 floats used to store matrix data */
-        public m = new Float32Array(6);
-
-        /**
-         * Creates a new matrix
-         * @param m00 defines value for (0, 0)
-         * @param m01 defines value for (0, 1) 
-         * @param m10 defines value for (1, 0) 
-         * @param m11 defines value for (1, 1) 
-         * @param m20 defines value for (2, 0) 
-         * @param m21 defines value for (2, 1) 
-         */
-        constructor(m00: number, m01: number, m10: number, m11: number, m20: number, m21: number) {
-            this.fromValues(m00, m01, m10, m11, m20, m21);
-        }
+/** Class used to provide 2D matrix features */
+export class Matrix2D {
+    /** Gets the internal array of 6 floats used to store matrix data */
+    public m = new Float32Array(6);
 
 
-        /**
-         * Fills the matrix from direct values
-         * @param m00 defines value for (0, 0)
-         * @param m01 defines value for (0, 1)
-         * @param m10 defines value for (1, 0)
-         * @param m11 defines value for (1, 1)
-         * @param m20 defines value for (2, 0)
-         * @param m21 defines value for (2, 1)
-         * @returns the current modified matrix
-         */
-        public fromValues(m00: number, m01: number, m10: number, m11: number, m20: number, m21: number): Matrix2D {
-            this.m[0] = m00; this.m[1] = m01; 
-            this.m[2] = m10; this.m[3] = m11;
-            this.m[4] = m20; this.m[5] = m21;
-            return this;
-        }
+    /**
+     * Creates a new matrix
+     * @param m00 defines value for (0, 0)
+     * @param m01 defines value for (0, 1) 
+     * @param m10 defines value for (1, 0) 
+     * @param m11 defines value for (1, 1) 
+     * @param m20 defines value for (2, 0) 
+     * @param m21 defines value for (2, 1) 
+     */
+    constructor(m00: number, m01: number, m10: number, m11: number, m20: number, m21: number) {
+        this.fromValues(m00, m01, m10, m11, m20, m21);
+    }
 
 
-        /** 
-         * Gets matrix determinant
-         * @returns the determinant
-         */
-        public determinant(): number {
-            return this.m[0] * this.m[3] - this.m[1] * this.m[2];
-        }
+    /**
+     * Fills the matrix from direct values
+     * @param m00 defines value for (0, 0)
+     * @param m01 defines value for (0, 1)
+     * @param m10 defines value for (1, 0)
+     * @param m11 defines value for (1, 1)
+     * @param m20 defines value for (2, 0)
+     * @param m21 defines value for (2, 1)
+     * @returns the current modified matrix
+     */
+    public fromValues(m00: number, m01: number, m10: number, m11: number, m20: number, m21: number): Matrix2D {
+        this.m[0] = m00; this.m[1] = m01;
+        this.m[2] = m10; this.m[3] = m11;
+        this.m[4] = m20; this.m[5] = m21;
+        return this;
+    }
 
 
-        /**
-         * Inverses the matrix and stores it in a target matrix
-         * @param result defines the target matrix
-         * @returns the current matrix
-         */
-        public invertToRef(result: Matrix2D): Matrix2D {
-            let l0 = this.m[0]; let l1 = this.m[1];
-            let l2 = this.m[2]; let l3 = this.m[3];
-            let l4 = this.m[4]; let l5 = this.m[5];
-
-            let det = this.determinant();
-            if (det < (Epsilon * Epsilon)) {
-                result.m[0] = 0;     result.m[1] = 0;
-                result.m[2] = 0;    result.m[3] = 0;
-                result.m[4] = 0;   result.m[5] = 0;
-                return this;
-            }
-
-            let detDiv = 1 / det;
-
-            let det4 = l2 * l5 - l3 * l4;
-            let det5 = l1 * l4 - l0 * l5;
-
-            result.m[0] = l3 * detDiv;     result.m[1] = -l1 * detDiv;
-            result.m[2] = -l2 * detDiv;    result.m[3] = l0 * detDiv;
-            result.m[4] = det4 * detDiv;   result.m[5] = det5 * detDiv;
+    /** 
+     * Gets matrix determinant
+     * @returns the determinant
+     */
+    public determinant(): number {
+        return this.m[0] * this.m[3] - this.m[1] * this.m[2];
+    }
 
 
+    /**
+     * Inverses the matrix and stores it in a target matrix
+     * @param result defines the target matrix
+     * @returns the current matrix
+     */
+    public invertToRef(result: Matrix2D): Matrix2D {
+        let l0 = this.m[0]; let l1 = this.m[1];
+        let l2 = this.m[2]; let l3 = this.m[3];
+        let l4 = this.m[4]; let l5 = this.m[5];
+
+        let det = this.determinant();
+        if (det < (Epsilon * Epsilon)) {
+            result.m[0] = 0; result.m[1] = 0;
+            result.m[2] = 0; result.m[3] = 0;
+            result.m[4] = 0; result.m[5] = 0;
             return this;
             return this;
         }
         }
 
 
-        /**
-         * Multiplies the current matrix with another one
-         * @param other defines the second operand
-         * @param result defines the target matrix 
-         * @returns the current matrix
-         */
-        public multiplyToRef(other: Matrix2D, result: Matrix2D): Matrix2D {
-            let l0 = this.m[0];     let l1 = this.m[1];
-            let l2 = this.m[2];     let l3 = this.m[3];
-            let l4 = this.m[4];     let l5 = this.m[5];
-
-            let r0 = other.m[0];    let r1 = other.m[1];
-            let r2 = other.m[2];    let r3 = other.m[3];
-            let r4 = other.m[4];    let r5 = other.m[5];
-
-            result.m[0] = l0 * r0 + l1 * r2;        result.m[1] = l0 * r1 + l1 * r3;
-            result.m[2] = l2 * r0 + l3 * r2;        result.m[3] = l2 * r1 + l3 * r3;
-            result.m[4] = l4 * r0 + l5 * r2 + r4;   result.m[5] = l4 * r1 + l5 * r3 + r5;
+        let detDiv = 1 / det;
 
 
-            return this;
-        }
+        let det4 = l2 * l5 - l3 * l4;
+        let det5 = l1 * l4 - l0 * l5;
 
 
-        /**
-         * Applies the current matrix to a set of 2 floats and stores the result in a vector2
-         * @param x defines the x coordinate to transform
-         * @param y defines the x coordinate to transform 
-         * @param result defines the target vector2 
-         * @returns the current matrix
-         */
-        public transformCoordinates(x: number, y: number, result: Vector2): Matrix2D {
-            result.x = x * this.m[0] + y * this.m[2] + this.m[4];
-            result.y = x * this.m[1] + y * this.m[3] + this.m[5];
+        result.m[0] = l3 * detDiv; result.m[1] = -l1 * detDiv;
+        result.m[2] = -l2 * detDiv; result.m[3] = l0 * detDiv;
+        result.m[4] = det4 * detDiv; result.m[5] = det5 * detDiv;
 
 
-            return this;
-        }
+        return this;
+    }
 
 
-        // Statics
-        /**
-         * Creates an identity matrix
-         * @returns a new matrix
-         */
-        public static Identity(): Matrix2D {
-            return new Matrix2D(1, 0, 0, 1, 0, 0);
-        }
+    /**
+     * Multiplies the current matrix with another one
+     * @param other defines the second operand
+     * @param result defines the target matrix 
+     * @returns the current matrix
+     */
+    public multiplyToRef(other: Matrix2D, result: Matrix2D): Matrix2D {
+        let l0 = this.m[0]; let l1 = this.m[1];
+        let l2 = this.m[2]; let l3 = this.m[3];
+        let l4 = this.m[4]; let l5 = this.m[5];
+
+        let r0 = other.m[0]; let r1 = other.m[1];
+        let r2 = other.m[2]; let r3 = other.m[3];
+        let r4 = other.m[4]; let r5 = other.m[5];
+
+        result.m[0] = l0 * r0 + l1 * r2; result.m[1] = l0 * r1 + l1 * r3;
+        result.m[2] = l2 * r0 + l3 * r2; result.m[3] = l2 * r1 + l3 * r3;
+        result.m[4] = l4 * r0 + l5 * r2 + r4; result.m[5] = l4 * r1 + l5 * r3 + r5;
+
+        return this;
+    }
 
 
-        /**
-         * Creates a translation matrix and stores it in a target matrix
-         * @param x defines the x coordinate of the translation
-         * @param y defines the y coordinate of the translation 
-         * @param result defines the target matrix
-         */
-        public static TranslationToRef(x: number, y: number, result: Matrix2D): void {
-            result.fromValues(1, 0, 0, 1, x, y);
-        }
+    /**
+     * Applies the current matrix to a set of 2 floats and stores the result in a vector2
+     * @param x defines the x coordinate to transform
+     * @param y defines the x coordinate to transform 
+     * @param result defines the target vector2 
+     * @returns the current matrix
+     */
+    public transformCoordinates(x: number, y: number, result: Vector2): Matrix2D {
+        result.x = x * this.m[0] + y * this.m[2] + this.m[4];
+        result.y = x * this.m[1] + y * this.m[3] + this.m[5];
+
+        return this;
+    }
 
 
-        /**
-         * Creates a scaling matrix and stores it in a target matrix
-         * @param x defines the x coordinate of the scaling
-         * @param y defines the y coordinate of the scaling 
-         * @param result defines the target matrix
-         */
-        public static ScalingToRef(x: number, y: number, result: Matrix2D): void {
-            result.fromValues(x, 0, 0, y,  0, 0);
-        }
+    // Statics
+    /**
+     * Creates an identity matrix
+     * @returns a new matrix
+     */
+    public static Identity(): Matrix2D {
+        return new Matrix2D(1, 0, 0, 1, 0, 0);
+    }
 
 
-        /**
-         * Creates a rotation matrix and stores it in a target matrix
-         * @param angle defines the rotation angle
-         * @param result defines the target matrix
-         */        
-        public static RotationToRef(angle: number, result: Matrix2D): void {
-            var s = Math.sin(angle);
-            var c = Math.cos(angle);
+    /**
+     * Creates a translation matrix and stores it in a target matrix
+     * @param x defines the x coordinate of the translation
+     * @param y defines the y coordinate of the translation 
+     * @param result defines the target matrix
+     */
+    public static TranslationToRef(x: number, y: number, result: Matrix2D): void {
+        result.fromValues(1, 0, 0, 1, x, y);
+    }
 
 
-            result.fromValues(c, s, -s, c,  0, 0);
-        }
+    /**
+     * Creates a scaling matrix and stores it in a target matrix
+     * @param x defines the x coordinate of the scaling
+     * @param y defines the y coordinate of the scaling 
+     * @param result defines the target matrix
+     */
+    public static ScalingToRef(x: number, y: number, result: Matrix2D): void {
+        result.fromValues(x, 0, 0, y, 0, 0);
+    }
+
+    /**
+     * Creates a rotation matrix and stores it in a target matrix
+     * @param angle defines the rotation angle
+     * @param result defines the target matrix
+     */
+    public static RotationToRef(angle: number, result: Matrix2D): void {
+        var s = Math.sin(angle);
+        var c = Math.cos(angle);
+
+        result.fromValues(c, s, -s, c, 0, 0);
+    }
 
 
-        private static _TempPreTranslationMatrix = Matrix2D.Identity();
-        private static _TempPostTranslationMatrix = Matrix2D.Identity();
-        private static _TempRotationMatrix = Matrix2D.Identity();
-        private static _TempScalingMatrix = Matrix2D.Identity();
-        private static _TempCompose0 = Matrix2D.Identity();
-        private static _TempCompose1 = Matrix2D.Identity();
-        private static _TempCompose2 = Matrix2D.Identity();
-
-        /**
-         * Composes a matrix from translation, rotation, scaling and parent matrix and stores it in a target matrix 
-         * @param tx defines the x coordinate of the translation
-         * @param ty defines the y coordinate of the translation 
-         * @param angle defines the rotation angle 
-         * @param scaleX defines the x coordinate of the scaling
-         * @param scaleY defines the y coordinate of the scaling 
-         * @param parentMatrix defines the parent matrix to multiply by (can be null)
-         * @param result defines the target matrix 
-         */
-        public static ComposeToRef(tx: number, ty: number, angle: number, scaleX: number, scaleY: number, parentMatrix: Nullable<Matrix2D>,  result: Matrix2D): void {
-            Matrix2D.TranslationToRef(tx, ty, Matrix2D._TempPreTranslationMatrix);
-
-            Matrix2D.ScalingToRef(scaleX, scaleY, Matrix2D._TempScalingMatrix);
-
-            Matrix2D.RotationToRef(angle, Matrix2D._TempRotationMatrix);
-
-            Matrix2D.TranslationToRef(-tx, -ty, Matrix2D._TempPostTranslationMatrix);
-
-            Matrix2D._TempPreTranslationMatrix.multiplyToRef(Matrix2D._TempScalingMatrix, Matrix2D._TempCompose0);
-            Matrix2D._TempCompose0.multiplyToRef(Matrix2D._TempRotationMatrix, Matrix2D._TempCompose1);
-            if (parentMatrix) {
-                Matrix2D._TempCompose1.multiplyToRef(Matrix2D._TempPostTranslationMatrix, Matrix2D._TempCompose2);
-                Matrix2D._TempCompose2.multiplyToRef(parentMatrix, result);
-            } else {
-                Matrix2D._TempCompose1.multiplyToRef(Matrix2D._TempPostTranslationMatrix, result);
-            }
+    private static _TempPreTranslationMatrix = Matrix2D.Identity();
+    private static _TempPostTranslationMatrix = Matrix2D.Identity();
+    private static _TempRotationMatrix = Matrix2D.Identity();
+    private static _TempScalingMatrix = Matrix2D.Identity();
+    private static _TempCompose0 = Matrix2D.Identity();
+    private static _TempCompose1 = Matrix2D.Identity();
+    private static _TempCompose2 = Matrix2D.Identity();
+
+    /**
+     * Composes a matrix from translation, rotation, scaling and parent matrix and stores it in a target matrix 
+     * @param tx defines the x coordinate of the translation
+     * @param ty defines the y coordinate of the translation 
+     * @param angle defines the rotation angle 
+     * @param scaleX defines the x coordinate of the scaling
+     * @param scaleY defines the y coordinate of the scaling 
+     * @param parentMatrix defines the parent matrix to multiply by (can be null)
+     * @param result defines the target matrix 
+     */
+    public static ComposeToRef(tx: number, ty: number, angle: number, scaleX: number, scaleY: number, parentMatrix: Nullable<Matrix2D>, result: Matrix2D): void {
+        Matrix2D.TranslationToRef(tx, ty, Matrix2D._TempPreTranslationMatrix);
+
+        Matrix2D.ScalingToRef(scaleX, scaleY, Matrix2D._TempScalingMatrix);
+
+        Matrix2D.RotationToRef(angle, Matrix2D._TempRotationMatrix);
+
+        Matrix2D.TranslationToRef(-tx, -ty, Matrix2D._TempPostTranslationMatrix);
+
+        Matrix2D._TempPreTranslationMatrix.multiplyToRef(Matrix2D._TempScalingMatrix, Matrix2D._TempCompose0);
+        Matrix2D._TempCompose0.multiplyToRef(Matrix2D._TempRotationMatrix, Matrix2D._TempCompose1);
+        if (parentMatrix) {
+            Matrix2D._TempCompose1.multiplyToRef(Matrix2D._TempPostTranslationMatrix, Matrix2D._TempCompose2);
+            Matrix2D._TempCompose2.multiplyToRef(parentMatrix, result);
+        } else {
+            Matrix2D._TempCompose1.multiplyToRef(Matrix2D._TempPostTranslationMatrix, result);
         }
         }
-    }    
-}
+    }
+}   

+ 57 - 60
gui/src/2D/measure.ts

@@ -1,72 +1,69 @@
-/// <reference path="../../../dist/preview release/babylon.d.ts"/>
 
 
-module BABYLON.GUI {
+/**
+ * Class used to store 2D control sizes
+ */
+export class Measure {
     /**
     /**
-     * Class used to store 2D control sizes
+     * Creates a new measure
+     * @param left defines left coordinate
+     * @param top defines top coordinate 
+     * @param width defines width dimension
+     * @param height defines height dimension
      */
      */
-    export class Measure {
-        /**
-         * Creates a new measure
-         * @param left defines left coordinate
-         * @param top defines top coordinate 
-         * @param width defines width dimension
-         * @param height defines height dimension
-         */
-        public constructor(
-            /** defines left coordinate */
-            public left: number, 
-            /** defines top coordinate  */
-            public top: number, 
-            /** defines width dimension  */
-            public width: number, 
-            /** defines height dimension */
-            public height: number) {
+    public constructor(
+        /** defines left coordinate */
+        public left: number,
+        /** defines top coordinate  */
+        public top: number,
+        /** defines width dimension  */
+        public width: number,
+        /** defines height dimension */
+        public height: number) {
 
 
-        }
-
-        /**
-         * Copy from another measure
-         * @param other defines the other measure to copy from
-         */
-        public copyFrom(other: Measure): void {
-            this.left = other.left;
-            this.top = other.top;
-            this.width = other.width;
-            this.height = other.height;
-        }
-
-        /**
-         * Check equality between this measure and another one
-         * @param other defines the other measures
-         * @returns true if both measures are equals
-         */
-        public isEqualsTo(other: Measure): boolean {
+    }
 
 
-            if (this.left !== other.left) {
-                return false;
-            }
+    /**
+     * Copy from another measure
+     * @param other defines the other measure to copy from
+     */
+    public copyFrom(other: Measure): void {
+        this.left = other.left;
+        this.top = other.top;
+        this.width = other.width;
+        this.height = other.height;
+    }
 
 
-            if (this.top !== other.top) {
-                return false;
-            }
+    /**
+     * Check equality between this measure and another one
+     * @param other defines the other measures
+     * @returns true if both measures are equals
+     */
+    public isEqualsTo(other: Measure): boolean {
 
 
-            if (this.width !== other.width) {
-                return false;
-            }
+        if (this.left !== other.left) {
+            return false;
+        }
 
 
-            if (this.height !== other.height) {
-                return false;
-            }
+        if (this.top !== other.top) {
+            return false;
+        }
 
 
-            return true;
+        if (this.width !== other.width) {
+            return false;
         }
         }
 
 
-        /**
-         * Creates an empty measure
-         * @returns a new measure
-         */
-        public static Empty(): Measure {
-            return new Measure(0, 0, 0, 0);
+        if (this.height !== other.height) {
+            return false;
         }
         }
-    }    
-}
+
+        return true;
+    }
+
+    /**
+     * Creates an empty measure
+     * @returns a new measure
+     */
+    public static Empty(): Measure {
+        return new Measure(0, 0, 0, 0);
+    }
+}   

+ 106 - 106
gui/src/2D/multiLinePoint.ts

@@ -1,150 +1,150 @@
-/// <reference path="../../../dist/preview release/babylon.d.ts"/>
+import { MultiLine } from "./controls/multiLine";
+import { ValueAndUnit } from "./valueAndUnit";
+import { Control } from "./controls/control";
+import { AbstractMesh, Nullable, Observer, Camera, Vector2 } from "babylonjs";
 
 
-module BABYLON.GUI {
 
 
-    /**
-     * Class used to store a point for a MultiLine object.
-     * The point can be pure 2D coordinates, a mesh or a control
-     */
-    export class MultiLinePoint {
+/**
+ * Class used to store a point for a MultiLine object.
+ * The point can be pure 2D coordinates, a mesh or a control
+ */
+export class MultiLinePoint {
+
+    private _multiLine: MultiLine;
+
+    private _x: ValueAndUnit;
+    private _y: ValueAndUnit;
+    private _control: Nullable<Control>;
+    private _mesh: Nullable<AbstractMesh>;
 
 
-        private _multiLine: MultiLine;
+    private _controlObserver: Nullable<Observer<Control>>;
+    private _meshObserver: Nullable<Observer<Camera>>;
 
 
-        private _x: ValueAndUnit;
-        private _y: ValueAndUnit;
-        private _control: Nullable<Control>;
-        private _mesh: Nullable<AbstractMesh>;
+    /** @hidden */
+    public _point: Vector2;
 
 
-        private _controlObserver: Nullable< Observer<Control> >;
-        private _meshObserver: Nullable< Observer<Camera> >;
+    /**
+     * Creates a new MultiLinePoint
+     * @param multiLine defines the source MultiLine object
+     */
+    constructor(multiLine: MultiLine) {
+        this._multiLine = multiLine;
 
 
-        /** @hidden */
-        public _point: Vector2;
+        this._x = new ValueAndUnit(0);
+        this._y = new ValueAndUnit(0);
 
 
-        /**
-         * Creates a new MultiLinePoint
-         * @param multiLine defines the source MultiLine object
-         */
-        constructor(multiLine: MultiLine) {
-            this._multiLine = multiLine;
+        this._point = new Vector2(0, 0);
+    }
 
 
-            this._x = new ValueAndUnit(0);
-            this._y = new ValueAndUnit(0);
+    /** Gets or sets x coordinate */
+    public get x(): string | number {
+        return this._x.toString(this._multiLine._host);
+    }
 
 
-            this._point = new Vector2(0, 0);
+    public set x(value: string | number) {
+        if (this._x.toString(this._multiLine._host) === value) {
+            return;
         }
         }
 
 
-        /** Gets or sets x coordinate */
-        public get x(): string | number {
-            return this._x.toString(this._multiLine._host);
+        if (this._x.fromString(value)) {
+            this._multiLine._markAsDirty();
         }
         }
+    }
 
 
-        public set x(value: string | number) {
-            if (this._x.toString(this._multiLine._host) === value) {
-                return;
-            }
+    /** Gets or sets y coordinate */
+    public get y(): string | number {
+        return this._y.toString(this._multiLine._host);
+    }
 
 
-            if (this._x.fromString(value)) {
-                this._multiLine._markAsDirty();
-            }
+    public set y(value: string | number) {
+        if (this._y.toString(this._multiLine._host) === value) {
+            return;
         }
         }
 
 
-        /** Gets or sets y coordinate */
-        public get y(): string | number {
-            return this._y.toString(this._multiLine._host);
+        if (this._y.fromString(value)) {
+            this._multiLine._markAsDirty();
         }
         }
+    }
 
 
-        public set y(value: string | number) {
-            if (this._y.toString(this._multiLine._host) === value) {
-                return;
-            }
+    /** Gets or sets the control associated with this point */
+    public get control(): Nullable<Control> {
+        return this._control;
+    }
 
 
-            if (this._y.fromString(value)) {
-                this._multiLine._markAsDirty();
-            }
+    public set control(value: Nullable<Control>) {
+        if (this._control === value) {
+            return;
         }
         }
 
 
-        /** Gets or sets the control associated with this point */
-        public get control(): Nullable<Control> {
-            return this._control;
-        }
+        if (this._control && this._controlObserver) {
+            this._control.onDirtyObservable.remove(this._controlObserver);
 
 
-        public set control(value: Nullable<Control>) {
-            if (this._control === value) {
-                return;
-            }
+            this._controlObserver = null;
+        }
 
 
-            if (this._control && this._controlObserver) {
-                this._control.onDirtyObservable.remove(this._controlObserver);
+        this._control = value;
 
 
-                this._controlObserver = null;
-            }
+        if (this._control) {
+            this._controlObserver = this._control.onDirtyObservable.add(this._multiLine.onPointUpdate);
+        }
 
 
-            this._control = value;
+        this._multiLine._markAsDirty();
+    }
 
 
-            if (this._control) {
-                this._controlObserver = this._control.onDirtyObservable.add(this._multiLine.onPointUpdate);
-            }
+    /** Gets or sets the mesh associated with this point */
+    public get mesh(): Nullable<AbstractMesh> {
+        return this._mesh;
+    }
 
 
-            this._multiLine._markAsDirty();
+    public set mesh(value: Nullable<AbstractMesh>) {
+        if (this._mesh === value) {
+            return;
         }
         }
 
 
-        /** Gets or sets the mesh associated with this point */
-        public get mesh(): Nullable<AbstractMesh> {
-            return this._mesh;
+        if (this._mesh && this._meshObserver) {
+            this._mesh.getScene().onAfterCameraRenderObservable.remove(this._meshObserver);
         }
         }
 
 
-        public set mesh(value: Nullable<AbstractMesh>) {
-            if (this._mesh === value) {
-                return;
-            }
-
-            if (this._mesh && this._meshObserver) {
-                this._mesh.getScene().onAfterCameraRenderObservable.remove(this._meshObserver);
-            }
+        this._mesh = value;
 
 
-            this._mesh = value;
+        if (this._mesh) {
+            this._meshObserver = this._mesh.getScene().onAfterCameraRenderObservable.add(this._multiLine.onPointUpdate);
+        }
 
 
-            if (this._mesh) {
-                this._meshObserver = this._mesh.getScene().onAfterCameraRenderObservable.add(this._multiLine.onPointUpdate);
-            }
+        this._multiLine._markAsDirty();
+    }
 
 
-            this._multiLine._markAsDirty();
-        }
+    /** 
+     * Gets a translation vector
+     * @returns the translation vector
+     */
+    public translate(): Vector2 {
+        this._point = this._translatePoint();
 
 
-        /** 
-         * Gets a translation vector
-         * @returns the translation vector
-         */
-        public translate(): Vector2 {
-            this._point = this._translatePoint();
+        return this._point;
+    }
 
 
-            return this._point;
+    private _translatePoint(): Vector2 {
+        if (this._mesh != null) {
+            return this._multiLine._host.getProjectedPosition(this._mesh.getBoundingInfo().boundingSphere.center, this._mesh.getWorldMatrix());
         }
         }
-
-        private _translatePoint(): Vector2 {
-            if (this._mesh != null) {
-                return this._multiLine._host.getProjectedPosition(this._mesh.getBoundingInfo().boundingSphere.center, this._mesh.getWorldMatrix());
-            }
-            else if (this._control != null) {
-                return new Vector2(this._control.centerX, this._control.centerY);
-            }
-            else {
-                var host: any = this._multiLine._host as any;
-
-                var xValue: number = this._x.getValueInPixel(host, Number(host._canvas.width));
-                var yValue: number = this._y.getValueInPixel(host, Number(host._canvas.height));
-                
-                return new Vector2(xValue, yValue);
-            }
+        else if (this._control != null) {
+            return new Vector2(this._control.centerX, this._control.centerY);
         }
         }
+        else {
+            var host: any = this._multiLine._host as any;
+
+            var xValue: number = this._x.getValueInPixel(host, Number(host._canvas.width));
+            var yValue: number = this._y.getValueInPixel(host, Number(host._canvas.height));
 
 
-        /** Release associated resources */
-        public dispose(): void {
-            this.control = null;
-            this.mesh = null;
+            return new Vector2(xValue, yValue);
         }
         }
+    }
 
 
+    /** Release associated resources */
+    public dispose(): void {
+        this.control = null;
+        this.mesh = null;
     }
     }
 
 
 }
 }

+ 79 - 79
gui/src/2D/style.ts

@@ -1,98 +1,98 @@
-/// <reference path="../../../dist/preview release/babylon.d.ts"/>
+import { IDisposable, Observable } from "babylonjs";
+import { AdvancedDynamicTexture } from "./advancedDynamicTexture";
+import { ValueAndUnit } from "./valueAndUnit";
+
+/**
+ * Define a style used by control to automatically setup properties based on a template.
+ * Only support font related properties so far
+ */
+export class Style implements IDisposable {
+    private _fontFamily = "Arial";
+    private _fontStyle = "";
+    private _fontWeight = "";
+    /** @hidden */
+    public _host: AdvancedDynamicTexture;
+    /** @hidden */
+    public _fontSize = new ValueAndUnit(18, ValueAndUnit.UNITMODE_PIXEL, false);
 
 
-module BABYLON.GUI {
     /**
     /**
-     * Define a style used by control to automatically setup properties based on a template.
-     * Only support font related properties so far
+     * Observable raised when the style values are changed
      */
      */
-    export class Style implements BABYLON.IDisposable {
-        private _fontFamily = "Arial";
-        private _fontStyle = "";       
-        private _fontWeight = "";     
-        /** @hidden */ 
-        public _host: AdvancedDynamicTexture;
-        /** @hidden */
-        public _fontSize = new ValueAndUnit(18, ValueAndUnit.UNITMODE_PIXEL, false);
-
-        /**
-         * Observable raised when the style values are changed
-         */
-        public onChangedObservable = new BABYLON.Observable<Style>();
-
-        /**
-         * Creates a new style object
-         * @param host defines the AdvancedDynamicTexture which hosts this style
-         */
-        public constructor(host: AdvancedDynamicTexture) {
-            this._host = host;
-        }
+    public onChangedObservable = new Observable<Style>();
 
 
-        /**
-         * Gets or sets the font size
-         */
-        public get fontSize(): string | number {
-            return this._fontSize.toString(this._host);
-        }
+    /**
+     * Creates a new style object
+     * @param host defines the AdvancedDynamicTexture which hosts this style
+     */
+    public constructor(host: AdvancedDynamicTexture) {
+        this._host = host;
+    }
 
 
-        public set fontSize(value: string | number) {
-            if (this._fontSize.toString(this._host) === value) {
-                return;
-            }
-
-            if (this._fontSize.fromString(value)) {
-                this.onChangedObservable.notifyObservers(this);
-            }
-        }        
-        
-        /**
-         * Gets or sets the font family
-         */
-        public get fontFamily(): string {
-            return this._fontFamily;
-        }
+    /**
+     * Gets or sets the font size
+     */
+    public get fontSize(): string | number {
+        return this._fontSize.toString(this._host);
+    }
 
 
-        public set fontFamily(value: string) {
-            if (this._fontFamily === value) {
-                return;
-            }
+    public set fontSize(value: string | number) {
+        if (this._fontSize.toString(this._host) === value) {
+            return;
+        }
 
 
-            this._fontFamily = value;
+        if (this._fontSize.fromString(value)) {
             this.onChangedObservable.notifyObservers(this);
             this.onChangedObservable.notifyObservers(this);
         }
         }
+    }
 
 
-        /**
-         * Gets or sets the font style 
-         */
-        public get fontStyle(): string {
-            return this._fontStyle;
+    /**
+     * Gets or sets the font family
+     */
+    public get fontFamily(): string {
+        return this._fontFamily;
+    }
+
+    public set fontFamily(value: string) {
+        if (this._fontFamily === value) {
+            return;
         }
         }
 
 
-        public set fontStyle(value: string) {
-            if (this._fontStyle === value) {
-                return;
-            }
+        this._fontFamily = value;
+        this.onChangedObservable.notifyObservers(this);
+    }
 
 
-            this._fontStyle = value;
-            this.onChangedObservable.notifyObservers(this);
-        }
+    /**
+     * Gets or sets the font style 
+     */
+    public get fontStyle(): string {
+        return this._fontStyle;
+    }
 
 
-        /** Gets or sets font weight */
-        public get fontWeight(): string {
-            return this._fontWeight;
+    public set fontStyle(value: string) {
+        if (this._fontStyle === value) {
+            return;
         }
         }
 
 
-        public set fontWeight(value: string) {
-            if (this._fontWeight === value) {
-                return;
-            }
+        this._fontStyle = value;
+        this.onChangedObservable.notifyObservers(this);
+    }
 
 
-            this._fontWeight = value;            
-            this.onChangedObservable.notifyObservers(this);
-        }          
+    /** Gets or sets font weight */
+    public get fontWeight(): string {
+        return this._fontWeight;
+    }
 
 
-        /** Dispose all associated resources */
-        public dispose() {
-            this.onChangedObservable.clear();
+    public set fontWeight(value: string) {
+        if (this._fontWeight === value) {
+            return;
         }
         }
-    }    
-}
+
+        this._fontWeight = value;
+        this.onChangedObservable.notifyObservers(this);
+    }
+
+    /** Dispose all associated resources */
+    public dispose() {
+        this.onChangedObservable.clear();
+    }
+}    

+ 135 - 137
gui/src/2D/valueAndUnit.ts

@@ -1,165 +1,163 @@
-/// <reference path="../../../dist/preview release/babylon.d.ts"/>
+import { AdvancedDynamicTexture } from "./advancedDynamicTexture";
 
 
-module BABYLON.GUI {
+/**
+ * Class used to specific a value and its associated unit
+ */
+export class ValueAndUnit {
+    private _value = 1;
     /**
     /**
-     * Class used to specific a value and its associated unit
+     * Gets or sets a value indicating that this value will not scale accordingly with adaptive scaling property
+     * @see http://doc.babylonjs.com/how_to/gui#adaptive-scaling
      */
      */
-    export class ValueAndUnit {
-        private _value = 1;
-        /**
-         * Gets or sets a value indicating that this value will not scale accordingly with adaptive scaling property
-         * @see http://doc.babylonjs.com/how_to/gui#adaptive-scaling
-         */
-        public ignoreAdaptiveScaling = false;
-
-        /**
-         * Creates a new ValueAndUnit
-         * @param value defines the value to store
-         * @param unit defines the unit to store
-         * @param negativeValueAllowed defines a boolean indicating if the value can be negative
-         */
-        public constructor(value: number, 
-            /** defines the unit to store */
-            public unit = ValueAndUnit.UNITMODE_PIXEL, 
-            /** defines a boolean indicating if the value can be negative */
-            public negativeValueAllowed = true) {
-            this._value = value;
-        }
+    public ignoreAdaptiveScaling = false;
 
 
-        /** Gets a boolean indicating if the value is a percentage */
-        public get isPercentage(): boolean {
-            return this.unit === ValueAndUnit.UNITMODE_PERCENTAGE;
-        }
+    /**
+     * Creates a new ValueAndUnit
+     * @param value defines the value to store
+     * @param unit defines the unit to store
+     * @param negativeValueAllowed defines a boolean indicating if the value can be negative
+     */
+    public constructor(value: number,
+        /** defines the unit to store */
+        public unit = ValueAndUnit.UNITMODE_PIXEL,
+        /** defines a boolean indicating if the value can be negative */
+        public negativeValueAllowed = true) {
+        this._value = value;
+    }
+
+    /** Gets a boolean indicating if the value is a percentage */
+    public get isPercentage(): boolean {
+        return this.unit === ValueAndUnit.UNITMODE_PERCENTAGE;
+    }
+
+    /** Gets a boolean indicating if the value is store as pixel */
+    public get isPixel(): boolean {
+        return this.unit === ValueAndUnit.UNITMODE_PIXEL;
+    }
+
+    /** Gets direct internal value */
+    public get internalValue(): number {
+        return this._value;
+    }
 
 
-        /** Gets a boolean indicating if the value is store as pixel */
-        public get isPixel(): boolean {
-            return this.unit === ValueAndUnit.UNITMODE_PIXEL;
+    /**
+     * Gets value as pixel
+     * @param host defines the root host
+     * @param refValue defines the reference value for percentages
+     * @returns the value as pixel
+     */
+    public getValueInPixel(host: AdvancedDynamicTexture, refValue: number): number {
+        if (this.isPixel) {
+            return this.getValue(host);
         }
         }
 
 
-        /** Gets direct internal value */
-        public get internalValue(): number {
-            return this._value;
-        }
+        return this.getValue(host) * refValue;
+    }
 
 
-        /**
-         * Gets value as pixel
-         * @param host defines the root host
-         * @param refValue defines the reference value for percentages
-         * @returns the value as pixel
-         */
-        public getValueInPixel(host: AdvancedDynamicTexture, refValue: number): number {
-            if (this.isPixel) {
-                return this.getValue(host);
+    /**
+     * Gets the value accordingly to its unit
+     * @param host  defines the root host
+     * @returns the value
+     */
+    public getValue(host: AdvancedDynamicTexture): number {
+        if (host && !this.ignoreAdaptiveScaling && this.unit !== ValueAndUnit.UNITMODE_PERCENTAGE) {
+            var width: number = 0;
+            var height: number = 0;
+
+            if (host.idealWidth) {
+                width = (this._value * host.getSize().width) / host.idealWidth;
             }
             }
 
 
-            return this.getValue(host) * refValue;
-        }
+            if (host.idealHeight) {
+                height = (this._value * host.getSize().height) / host.idealHeight;
+            }
 
 
-        /**
-         * Gets the value accordingly to its unit
-         * @param host  defines the root host
-         * @returns the value
-         */
-        public getValue(host: AdvancedDynamicTexture): number {
-            if (host && !this.ignoreAdaptiveScaling && this.unit !== ValueAndUnit.UNITMODE_PERCENTAGE) {
-                var width: number = 0;
-                var height: number = 0;
-
-                if (host.idealWidth) {
-                    width = (this._value * host.getSize().width) / host.idealWidth;
-                }
-                
-                if (host.idealHeight) {
-                    height = (this._value * host.getSize().height) / host.idealHeight;
-                }
-
-                if (host.useSmallestIdeal && host.idealWidth && host.idealHeight) {
-                    return window.innerWidth < window.innerHeight ? width : height;
-                }
-
-                if (host.idealWidth) { // horizontal
-                    return width;
-                }
-                
-                if (host.idealHeight) { // vertical
-                    return height;
-                }
+            if (host.useSmallestIdeal && host.idealWidth && host.idealHeight) {
+                return window.innerWidth < window.innerHeight ? width : height;
+            }
+
+            if (host.idealWidth) { // horizontal
+                return width;
             }
             }
-            return this._value;
-        }
 
 
-        /**
-         * Gets a string representation of the value
-         * @param host defines the root host
-         * @returns a string
-         */
-        public toString(host: AdvancedDynamicTexture): string {
-            switch (this.unit) {
-                case ValueAndUnit.UNITMODE_PERCENTAGE:
-                    return (this.getValue(host) * 100) + "%";
-                case ValueAndUnit.UNITMODE_PIXEL:
-                    return this.getValue(host) + "px";
+            if (host.idealHeight) { // vertical
+                return height;
             }
             }
+        }
+        return this._value;
+    }
 
 
-            return this.unit.toString();
+    /**
+     * Gets a string representation of the value
+     * @param host defines the root host
+     * @returns a string
+     */
+    public toString(host: AdvancedDynamicTexture): string {
+        switch (this.unit) {
+            case ValueAndUnit.UNITMODE_PERCENTAGE:
+                return (this.getValue(host) * 100) + "%";
+            case ValueAndUnit.UNITMODE_PIXEL:
+                return this.getValue(host) + "px";
         }
         }
 
 
-        /**
-         * Store a value parsed from a string
-         * @param source defines the source string
-         * @returns true if the value was successfully parsed
-         */
-        public fromString(source: string | number ): boolean {
-            var match = ValueAndUnit._Regex.exec(source.toString());
+        return this.unit.toString();
+    }
 
 
-            if (!match || match.length === 0) {
-                return false;
-            }
+    /**
+     * Store a value parsed from a string
+     * @param source defines the source string
+     * @returns true if the value was successfully parsed
+     */
+    public fromString(source: string | number): boolean {
+        var match = ValueAndUnit._Regex.exec(source.toString());
 
 
-            var sourceValue = parseFloat(match[1]);
-            var sourceUnit = this.unit;
+        if (!match || match.length === 0) {
+            return false;
+        }
 
 
-            if (!this.negativeValueAllowed) {
-                if (sourceValue < 0) {
-                    sourceValue = 0;
-                }
-            }
-            
-            if (match.length === 4) {
-                switch(match[3]) {
-                    case "px":
-                        sourceUnit = ValueAndUnit.UNITMODE_PIXEL;
-                        break;
-                    case "%":
-                        sourceUnit = ValueAndUnit.UNITMODE_PERCENTAGE;
-                        sourceValue /= 100.0;
-                        break;
-                }
-            }
+        var sourceValue = parseFloat(match[1]);
+        var sourceUnit = this.unit;
 
 
-            if (sourceValue === this._value && sourceUnit === this.unit) {
-                return false;
+        if (!this.negativeValueAllowed) {
+            if (sourceValue < 0) {
+                sourceValue = 0;
             }
             }
+        }
 
 
-            this._value = sourceValue;
-            this.unit = sourceUnit;
+        if (match.length === 4) {
+            switch (match[3]) {
+                case "px":
+                    sourceUnit = ValueAndUnit.UNITMODE_PIXEL;
+                    break;
+                case "%":
+                    sourceUnit = ValueAndUnit.UNITMODE_PERCENTAGE;
+                    sourceValue /= 100.0;
+                    break;
+            }
+        }
 
 
-            return true;
+        if (sourceValue === this._value && sourceUnit === this.unit) {
+            return false;
         }
         }
 
 
-        // Static
-        private static _Regex = /(^-?\d*(\.\d+)?)(%|px)?/;
-        private static _UNITMODE_PERCENTAGE = 0;
-        private static _UNITMODE_PIXEL = 1;
+        this._value = sourceValue;
+        this.unit = sourceUnit;
 
 
-        /** UNITMODE_PERCENTAGE */
-        public static get UNITMODE_PERCENTAGE(): number {
-            return ValueAndUnit._UNITMODE_PERCENTAGE;
-        }
+        return true;
+    }
+
+    // Static
+    private static _Regex = /(^-?\d*(\.\d+)?)(%|px)?/;
+    private static _UNITMODE_PERCENTAGE = 0;
+    private static _UNITMODE_PIXEL = 1;
+
+    /** UNITMODE_PERCENTAGE */
+    public static get UNITMODE_PERCENTAGE(): number {
+        return ValueAndUnit._UNITMODE_PERCENTAGE;
+    }
 
 
-        /** UNITMODE_PIXEL */
-        public static get UNITMODE_PIXEL(): number {
-            return ValueAndUnit._UNITMODE_PIXEL;
-        }   
-    }    
-}
+    /** UNITMODE_PIXEL */
+    public static get UNITMODE_PIXEL(): number {
+        return ValueAndUnit._UNITMODE_PIXEL;
+    }
+}  

+ 17 - 18
gui/src/3D/controls/abstractButton3D.ts

@@ -1,25 +1,24 @@
-/// <reference path="../../../../dist/preview release/babylon.d.ts"/>
+import { Control3D } from "./control3D";
+import { TransformNode, Scene } from "babylonjs";
 
 
-module BABYLON.GUI {
+/**
+ * Class used as a root to all buttons
+ */
+export class AbstractButton3D extends Control3D {
     /**
     /**
-     * Class used as a root to all buttons
+     * Creates a new button
+     * @param name defines the control name
      */
      */
-    export class AbstractButton3D extends Control3D {
-        /**
-         * Creates a new button
-         * @param name defines the control name
-         */
-        constructor(name?: string) {
-            super(name);
-        }
+    constructor(name?: string) {
+        super(name);
+    }
 
 
-        protected _getTypeName(): string {
-            return "AbstractButton3D";
-        }        
+    protected _getTypeName(): string {
+        return "AbstractButton3D";
+    }
 
 
-        // Mesh association
-        protected _createNode(scene: Scene): TransformNode {
-            return new TransformNode("button" + this.name);
-        }    
+    // Mesh association
+    protected _createNode(scene: Scene): TransformNode {
+        return new TransformNode("button" + this.name);
     }
     }
 }
 }

+ 135 - 134
gui/src/3D/controls/button3D.ts

@@ -1,177 +1,178 @@
-/// <reference path="../../../../dist/preview release/babylon.d.ts"/>
+import { AbstractButton3D } from "./abstractButton3D";
+import { Material, Nullable, int, Color3, StandardMaterial, Texture, Scene, TransformNode, Vector4, MeshBuilder, AbstractMesh } from "babylonjs";
+import { AdvancedDynamicTexture } from "../../2D/advancedDynamicTexture";
+import { Control } from "../../2D/controls/control";
+
+/**
+ * Class used to create a button in 3D
+ */
+export class Button3D extends AbstractButton3D {
+    /** @hidden */
+    protected _currentMaterial: Material;
+    private _facadeTexture: Nullable<AdvancedDynamicTexture>;
+    private _content: Control;
+    private _contentResolution = 512;
+    private _contentScaleRatio = 2;
 
 
-module BABYLON.GUI {
     /**
     /**
-     * Class used to create a button in 3D
+     * Gets or sets the texture resolution used to render content (512 by default)
      */
      */
-    export class Button3D extends AbstractButton3D {
-        /** @hidden */
-        protected _currentMaterial: Material;
-        private _facadeTexture: Nullable<AdvancedDynamicTexture>;
-        private _content: Control;
-        private _contentResolution = 512;
-        private _contentScaleRatio = 2;
-
-        /**
-         * Gets or sets the texture resolution used to render content (512 by default)
-         */
-        public get contentResolution(): int {
-            return this._contentResolution;
+    public get contentResolution(): int {
+        return this._contentResolution;
+    }
+
+    public set contentResolution(value: int) {
+        if (this._contentResolution === value) {
+            return;
         }
         }
 
 
-        public set contentResolution(value: int) {
-            if (this._contentResolution === value) {
-                return;
-            }
+        this._contentResolution = value;
+        this._resetContent();
+    }
 
 
-            this._contentResolution = value;
-            this._resetContent();
+    /**
+     * Gets or sets the texture scale ratio used to render content (2 by default)
+     */
+    public get contentScaleRatio(): number {
+        return this._contentScaleRatio;
+    }
+
+    public set contentScaleRatio(value: number) {
+        if (this._contentScaleRatio === value) {
+            return;
         }
         }
 
 
-        /**
-         * Gets or sets the texture scale ratio used to render content (2 by default)
-         */
-        public get contentScaleRatio(): number {
-            return this._contentScaleRatio;
+        this._contentScaleRatio = value;
+        this._resetContent();
+    }
+
+    protected _disposeFacadeTexture() {
+        if (this._facadeTexture) {
+            this._facadeTexture.dispose();
+            this._facadeTexture = null;
         }
         }
+    }
 
 
-        public set contentScaleRatio(value: number) {
-            if (this._contentScaleRatio === value) {
-                return;
-            }
+    protected _resetContent() {
+        this._disposeFacadeTexture();
+        this.content = this._content;
+    }
+
+    /**
+     * Creates a new button
+     * @param name defines the control name
+     */
+    constructor(name?: string) {
+        super(name);
+
+        // Default animations
 
 
-            this._contentScaleRatio = value;
-            this._resetContent();
-        }   
-        
-        protected _disposeFacadeTexture() {
-            if (this._facadeTexture) {
-                this._facadeTexture.dispose();
-                this._facadeTexture = null;
+        this.pointerEnterAnimation = () => {
+            if (!this.mesh) {
+                return;
             }
             }
+            (<StandardMaterial>this._currentMaterial).emissiveColor = Color3.Red();
         }
         }
 
 
-        protected _resetContent() {
-            this._disposeFacadeTexture();
-            this.content = this._content;
+        this.pointerOutAnimation = () => {
+            (<StandardMaterial>this._currentMaterial).emissiveColor = Color3.Black();
         }
         }
 
 
-        /**
-         * Creates a new button
-         * @param name defines the control name
-         */
-        constructor(name?: string) {
-            super(name);
+        this.pointerDownAnimation = () => {
+            if (!this.mesh) {
+                return;
+            }
 
 
-            // Default animations
+            this.mesh.scaling.scaleInPlace(0.95);
+        }
 
 
-            this.pointerEnterAnimation = () => {
-                if (!this.mesh) {
-                    return;
-                }
-                (<StandardMaterial>this._currentMaterial).emissiveColor = Color3.Red();
+        this.pointerUpAnimation = () => {
+            if (!this.mesh) {
+                return;
             }
             }
 
 
-            this.pointerOutAnimation = () => {
-                (<StandardMaterial>this._currentMaterial).emissiveColor = Color3.Black();
-            }    
-
-            this.pointerDownAnimation = () => {
-                if (!this.mesh) {
-                    return;
-                }
+            this.mesh.scaling.scaleInPlace(1.0 / 0.95);
+        }
+    }
 
 
-                this.mesh.scaling.scaleInPlace(0.95);
-            }
+    /**
+     * Gets or sets the GUI 2D content used to display the button's facade
+     */
+    public get content(): Control {
+        return this._content;
+    }
 
 
-            this.pointerUpAnimation = () => {
-                if (!this.mesh) {
-                    return;
-                }
+    public set content(value: Control) {
+        this._content = value;
 
 
-                this.mesh.scaling.scaleInPlace(1.0 / 0.95);
-            }                     
+        if (!this._host || !this._host.utilityLayer) {
+            return;
         }
         }
 
 
-        /**
-         * Gets or sets the GUI 2D content used to display the button's facade
-         */
-        public get content(): Control {
-            return this._content;
+        if (!this._facadeTexture) {
+            this._facadeTexture = new AdvancedDynamicTexture("Facade", this._contentResolution, this._contentResolution, this._host.utilityLayer.utilityLayerScene, true, Texture.TRILINEAR_SAMPLINGMODE);
+            this._facadeTexture.rootContainer.scaleX = this._contentScaleRatio;
+            this._facadeTexture.rootContainer.scaleY = this._contentScaleRatio;
+            this._facadeTexture.premulAlpha = true;
         }
         }
 
 
-        public set content(value: Control) {
-            this._content = value;
+        this._facadeTexture.addControl(value);
 
 
-            if (!this._host || !this._host.utilityLayer) {
-                return;
-            }
+        this._applyFacade(this._facadeTexture);
+    }
 
 
-            if (!this._facadeTexture) {
-                this._facadeTexture = new BABYLON.GUI.AdvancedDynamicTexture("Facade", this._contentResolution, this._contentResolution, this._host.utilityLayer.utilityLayerScene, true, BABYLON.Texture.TRILINEAR_SAMPLINGMODE);
-                this._facadeTexture.rootContainer.scaleX = this._contentScaleRatio;
-                this._facadeTexture.rootContainer.scaleY = this._contentScaleRatio;
-                this._facadeTexture.premulAlpha = true;
-            }
-            
-            this._facadeTexture.addControl(value);
+    /**
+     * Apply the facade texture (created from the content property).
+     * This function can be overloaded by child classes
+     * @param facadeTexture defines the AdvancedDynamicTexture to use
+     */
+    protected _applyFacade(facadeTexture: AdvancedDynamicTexture) {
+        (<any>this._currentMaterial).emissiveTexture = facadeTexture;
+    }
 
 
-            this._applyFacade(this._facadeTexture);
-        }
+    protected _getTypeName(): string {
+        return "Button3D";
+    }
 
 
-        /**
-         * Apply the facade texture (created from the content property).
-         * This function can be overloaded by child classes
-         * @param facadeTexture defines the AdvancedDynamicTexture to use
-         */
-        protected _applyFacade(facadeTexture: AdvancedDynamicTexture) {
-            (<any>this._currentMaterial).emissiveTexture = facadeTexture;
-        }
+    // Mesh association
+    protected _createNode(scene: Scene): TransformNode {
+        var faceUV = new Array(6);
 
 
-        protected _getTypeName(): string {
-            return "Button3D";
-        }        
+        for (var i = 0; i < 6; i++) {
+            faceUV[i] = new Vector4(0, 0, 0, 0);
+        }
+        faceUV[1] = new Vector4(0, 0, 1, 1);
 
 
-        // Mesh association
-        protected _createNode(scene: Scene): TransformNode {
-            var faceUV = new Array(6);
+        let mesh = MeshBuilder.CreateBox(this.name + "_rootMesh", {
+            width: 1.0,
+            height: 1.0,
+            depth: 0.08,
+            faceUV: faceUV
+        }, scene);
 
 
-            for (var i = 0; i < 6; i++) {
-                faceUV[i] = new BABYLON.Vector4(0, 0, 0, 0);
-            }
-            faceUV[1] = new BABYLON.Vector4(0, 0, 1, 1);
-
-            let mesh = MeshBuilder.CreateBox(this.name + "_rootMesh", {
-                width: 1.0, 
-                height: 1.0,
-                depth: 0.08,
-                faceUV: faceUV
-            }, scene); 
-           
-            return mesh;
-        }
+        return mesh;
+    }
 
 
-        protected _affectMaterial(mesh: AbstractMesh) {
-            let material = new StandardMaterial(this.name + "Material", mesh.getScene());
-            material.specularColor = Color3.Black();
+    protected _affectMaterial(mesh: AbstractMesh) {
+        let material = new StandardMaterial(this.name + "Material", mesh.getScene());
+        material.specularColor = Color3.Black();
 
 
-            mesh.material = material;
-            this._currentMaterial = material;
+        mesh.material = material;
+        this._currentMaterial = material;
 
 
-            this._resetContent();
-        }
+        this._resetContent();
+    }
 
 
-        /**
-         * Releases all associated resources
-         */
-        public dispose() {
-            super.dispose();
+    /**
+     * Releases all associated resources
+     */
+    public dispose() {
+        super.dispose();
 
 
-            this._disposeFacadeTexture();
+        this._disposeFacadeTexture();
 
 
-            if (this._currentMaterial) {
-                this._currentMaterial.dispose();
-            }
+        if (this._currentMaterial) {
+            this._currentMaterial.dispose();
         }
         }
     }
     }
 }
 }

+ 121 - 122
gui/src/3D/controls/container3D.ts

@@ -1,161 +1,160 @@
-/// <reference path="../../../../dist/preview release/babylon.d.ts"/>
+import { Control3D } from "./control3D";
+import { Scene, Nullable, TransformNode } from "babylonjs";
+
+/**
+ * Class used to create containers for controls
+ */
+export class Container3D extends Control3D {
+    private _blockLayout = false;
 
 
-module BABYLON.GUI {
     /**
     /**
-     * Class used to create containers for controls
+     * Gets the list of child controls
      */
      */
-    export class Container3D extends Control3D {
-        private _blockLayout = false;
-
-        /**
-         * Gets the list of child controls
-         */
-        protected _children = new Array<Control3D>();
-
-        /**
-         * Gets the list of child controls
-         */
-        public get children(): Array<Control3D> {
-            return this._children;
-        }
-
-        /**
-         * Gets or sets a boolean indicating if the layout must be blocked (default is false).
-         * This is helpful to optimize layout operation when adding multiple children in a row
-         */
-        public get blockLayout(): boolean {
-            return this._blockLayout;
-        }
+    protected _children = new Array<Control3D>();
 
 
-        public set blockLayout(value: boolean) {
-            if (this._blockLayout === value) {
-                return;
-            }
+    /**
+     * Gets the list of child controls
+     */
+    public get children(): Array<Control3D> {
+        return this._children;
+    }
 
 
-            this._blockLayout = value;
+    /**
+     * Gets or sets a boolean indicating if the layout must be blocked (default is false).
+     * This is helpful to optimize layout operation when adding multiple children in a row
+     */
+    public get blockLayout(): boolean {
+        return this._blockLayout;
+    }
 
 
-            if (!this._blockLayout) {
-                this._arrangeChildren();
-            }
+    public set blockLayout(value: boolean) {
+        if (this._blockLayout === value) {
+            return;
         }
         }
 
 
-        /**
-         * Creates a new container
-         * @param name defines the container name
-         */
-        constructor(name?: string) {
-            super(name);
-        }
+        this._blockLayout = value;
 
 
-        /**
-         * Force the container to update the layout. Please note that it will not take blockLayout property in account
-         * @returns the current container
-         */
-        public updateLayout(): Container3D {
+        if (!this._blockLayout) {
             this._arrangeChildren();
             this._arrangeChildren();
-            return this;
         }
         }
+    }
 
 
-        /**
-         * Gets a boolean indicating if the given control is in the children of this control
-         * @param control defines the control to check
-         * @returns true if the control is in the child list
-         */
-        public containsControl(control: Control3D): boolean {
-            return this._children.indexOf(control) !== -1;
-        }
+    /**
+     * Creates a new container
+     * @param name defines the container name
+     */
+    constructor(name?: string) {
+        super(name);
+    }
+
+    /**
+     * Force the container to update the layout. Please note that it will not take blockLayout property in account
+     * @returns the current container
+     */
+    public updateLayout(): Container3D {
+        this._arrangeChildren();
+        return this;
+    }
 
 
-        /**
-         * Adds a control to the children of this control
-         * @param control defines the control to add
-         * @returns the current container
-         */
-        public addControl(control: Control3D): Container3D {
-           var index = this._children.indexOf(control);
+    /**
+     * Gets a boolean indicating if the given control is in the children of this control
+     * @param control defines the control to check
+     * @returns true if the control is in the child list
+     */
+    public containsControl(control: Control3D): boolean {
+        return this._children.indexOf(control) !== -1;
+    }
 
 
-            if (index !== -1) {
-                return this;
-            }
-            control.parent = this;
-            control._host = this._host;
+    /**
+     * Adds a control to the children of this control
+     * @param control defines the control to add
+     * @returns the current container
+     */
+    public addControl(control: Control3D): Container3D {
+        var index = this._children.indexOf(control);
 
 
-            this._children.push(control);
+        if (index !== -1) {
+            return this;
+        }
+        control.parent = this;
+        control._host = this._host;
 
 
-            if (this._host.utilityLayer) {
-                control._prepareNode(this._host.utilityLayer.utilityLayerScene);
+        this._children.push(control);
 
 
-                if (control.node) {
-                    control.node.parent = this.node;
-                }
+        if (this._host.utilityLayer) {
+            control._prepareNode(this._host.utilityLayer.utilityLayerScene);
 
 
-                if (!this.blockLayout) {
-                    this._arrangeChildren();
-                }
+            if (control.node) {
+                control.node.parent = this.node;
             }
             }
 
 
-            return this;
+            if (!this.blockLayout) {
+                this._arrangeChildren();
+            }
         }
         }
 
 
+        return this;
+    }
 
 
-        /**
-         * This function will be called everytime a new control is added 
-         */
-        protected _arrangeChildren() {
-        }
 
 
-        protected _createNode(scene: Scene): Nullable<TransformNode> {
-            return new TransformNode("ContainerNode", scene);
-        }
+    /**
+     * This function will be called everytime a new control is added 
+     */
+    protected _arrangeChildren() {
+    }
 
 
-        /**
-         * Removes a control from the children of this control
-         * @param control defines the control to remove
-         * @returns the current container
-         */
-        public removeControl(control: Control3D): Container3D {
-            var index = this._children.indexOf(control);
+    protected _createNode(scene: Scene): Nullable<TransformNode> {
+        return new TransformNode("ContainerNode", scene);
+    }
 
 
-            if (index !== -1) {
-                this._children.splice(index, 1);
+    /**
+     * Removes a control from the children of this control
+     * @param control defines the control to remove
+     * @returns the current container
+     */
+    public removeControl(control: Control3D): Container3D {
+        var index = this._children.indexOf(control);
 
 
-                control.parent = null;
-                control._disposeNode();
-            }
+        if (index !== -1) {
+            this._children.splice(index, 1);
 
 
-            return this;
+            control.parent = null;
+            control._disposeNode();
         }
         }
 
 
-        protected _getTypeName(): string {
-            return "Container3D";
-        }
-        
-        /**
-         * Releases all associated resources
-         */
-        public dispose() {
-            for (var control of this._children) {
-                control.dispose();
-            }
+        return this;
+    }
 
 
-            this._children = [];
+    protected _getTypeName(): string {
+        return "Container3D";
+    }
 
 
-            super.dispose();
+    /**
+     * Releases all associated resources
+     */
+    public dispose() {
+        for (var control of this._children) {
+            control.dispose();
         }
         }
 
 
-        /** Control rotation will remain unchanged  */
-        public static readonly UNSET_ORIENTATION = 0;
+        this._children = [];
 
 
-        /** Control will rotate to make it look at sphere central axis */
-        public static readonly FACEORIGIN_ORIENTATION = 1;
+        super.dispose();
+    }
 
 
-        /** Control will rotate to make it look back at sphere central axis */
-        public static readonly FACEORIGINREVERSED_ORIENTATION = 2;
+    /** Control rotation will remain unchanged  */
+    public static readonly UNSET_ORIENTATION = 0;
 
 
-        /** Control will rotate to look at z axis (0, 0, 1) */
-        public static readonly FACEFORWARD_ORIENTATION = 3;
+    /** Control will rotate to make it look at sphere central axis */
+    public static readonly FACEORIGIN_ORIENTATION = 1;
 
 
-        /** Control will rotate to look at negative z axis (0, 0, -1) */
-        public static readonly FACEFORWARDREVERSED_ORIENTATION = 4;
+    /** Control will rotate to make it look back at sphere central axis */
+    public static readonly FACEORIGINREVERSED_ORIENTATION = 2;
 
 
-    }
-}
+    /** Control will rotate to look at z axis (0, 0, 1) */
+    public static readonly FACEFORWARD_ORIENTATION = 3;
+
+    /** Control will rotate to look at negative z axis (0, 0, -1) */
+    public static readonly FACEFORWARDREVERSED_ORIENTATION = 4;
+
+}

+ 346 - 345
gui/src/3D/controls/control3D.ts

@@ -1,424 +1,425 @@
-/// <reference path="../../../../dist/preview release/babylon.d.ts"/>
+import { IDisposable, IBehaviorAware, Nullable, TransformNode, Vector3, Observable, Behavior, AbstractMesh, Scene, PointerEventTypes } from "babylonjs";
+import { GUI3DManager } from "../gui3DManager";
+import { Vector3WithInfo } from "../vector3WithInfo";
+import { Container3D } from "./container3D";
+
+/**
+ * Class used as base class for controls
+ */
+export class Control3D implements IDisposable, IBehaviorAware<Control3D> {
+    /** @hidden */
+    public _host: GUI3DManager;
+    private _node: Nullable<TransformNode>;
+    private _downCount = 0;
+    private _enterCount = -1;
+    private _downPointerIds: { [id: number]: boolean } = {};
+    private _isVisible = true;
+
+    /** Gets or sets the control position  in world space */
+    public get position(): Vector3 {
+        if (!this._node) {
+            return Vector3.Zero();
+        }
 
 
-module BABYLON.GUI {
-    /**
-     * Class used as base class for controls
-     */
-    export class Control3D implements IDisposable, IBehaviorAware<Control3D> {
-        /** @hidden */
-        public _host: GUI3DManager;
-        private _node: Nullable<TransformNode>;
-        private _downCount = 0;
-        private _enterCount = -1;
-        private _downPointerIds:{[id:number] : boolean} = {};
-        private _isVisible = true;
-    
-        /** Gets or sets the control position  in world space */
-        public get position(): Vector3 {
-            if (!this._node) {
-                return Vector3.Zero();
-            }
+        return this._node.position;
+    }
 
 
-            return this._node.position;
+    public set position(value: Vector3) {
+        if (!this._node) {
+            return;
         }
         }
 
 
-        public set position(value: Vector3) {
-            if (!this._node) {
-                return;
-            }
+        this._node.position = value;;
+    }
 
 
-            this._node.position = value;;
+    /** Gets or sets the control scaling  in world space */
+    public get scaling(): Vector3 {
+        if (!this._node) {
+            return new Vector3(1, 1, 1);
         }
         }
 
 
-        /** Gets or sets the control scaling  in world space */
-        public get scaling(): Vector3 {
-            if (!this._node) {
-                return new Vector3(1, 1, 1);
-            }
+        return this._node.scaling;
+    }
 
 
-            return this._node.scaling;
+    public set scaling(value: Vector3) {
+        if (!this._node) {
+            return;
         }
         }
 
 
-        public set scaling(value: Vector3) {
-            if (!this._node) {
-                return;
-            }
+        this._node.scaling = value;;
+    }
 
 
-            this._node.scaling = value;;
-        }
+    /** Callback used to start pointer enter animation */
+    public pointerEnterAnimation: () => void;
+    /** Callback used to start pointer out animation */
+    public pointerOutAnimation: () => void;
+    /** Callback used to start pointer down animation */
+    public pointerDownAnimation: () => void;
+    /** Callback used to start pointer up animation */
+    public pointerUpAnimation: () => void;
 
 
-        /** Callback used to start pointer enter animation */
-        public pointerEnterAnimation: () => void;
-        /** Callback used to start pointer out animation */
-        public pointerOutAnimation: () => void;
-        /** Callback used to start pointer down animation */
-        public pointerDownAnimation: () => void;
-        /** Callback used to start pointer up animation */
-        public pointerUpAnimation: () => void;
-
-        /**
-        * An event triggered when the pointer move over the control
-        */
-        public onPointerMoveObservable = new Observable<Vector3>();
-
-        /**
-         * An event triggered when the pointer move out of the control
-         */
-        public onPointerOutObservable = new Observable<Control3D>();
-
-        /**
-         * An event triggered when the pointer taps the control
-         */
-        public onPointerDownObservable = new Observable<Vector3WithInfo>();
-
-        /**
-         * An event triggered when pointer is up
-         */
-        public onPointerUpObservable = new Observable<Vector3WithInfo>();
-
-        /**
-         * An event triggered when a control is clicked on (with a mouse)
-         */
-        public onPointerClickObservable = new Observable<Vector3WithInfo>();
-
-        /**
-         * An event triggered when pointer enters the control
-         */
-        public onPointerEnterObservable = new Observable<Control3D>();
-        
-        /**
-         * Gets or sets the parent container
-         */
-        public parent: Nullable<Container3D>;
+    /**
+    * An event triggered when the pointer move over the control
+    */
+    public onPointerMoveObservable = new Observable<Vector3>();
 
 
-        // Behaviors
-        private _behaviors = new Array<Behavior<Control3D>>();
-
-        /**
-         * Gets the list of attached behaviors
-         * @see http://doc.babylonjs.com/features/behaviour
-         */
-        public get behaviors(): Behavior<Control3D>[] {
-            return this._behaviors;
-        }        
-
-        /**
-         * Attach a behavior to the control
-         * @see http://doc.babylonjs.com/features/behaviour
-         * @param behavior defines the behavior to attach
-         * @returns the current control
-         */
-        public addBehavior(behavior: Behavior<Control3D>): Control3D {
-            var index = this._behaviors.indexOf(behavior);
-
-            if (index !== -1) {
-                return this;
-            }
+    /**
+     * An event triggered when the pointer move out of the control
+     */
+    public onPointerOutObservable = new Observable<Control3D>();
 
 
-            behavior.init();
-            let scene = this._host.scene;
-            if (scene.isLoading) {
-                // We defer the attach when the scene will be loaded
-                scene.onDataLoadedObservable.addOnce(() => {
-                    behavior.attach(this);
-                });
-            } else {
-                behavior.attach(this);
-            }
-            this._behaviors.push(behavior);
+    /**
+     * An event triggered when the pointer taps the control
+     */
+    public onPointerDownObservable = new Observable<Vector3WithInfo>();
+
+    /**
+     * An event triggered when pointer is up
+     */
+    public onPointerUpObservable = new Observable<Vector3WithInfo>();
+
+    /**
+     * An event triggered when a control is clicked on (with a mouse)
+     */
+    public onPointerClickObservable = new Observable<Vector3WithInfo>();
 
 
+    /**
+     * An event triggered when pointer enters the control
+     */
+    public onPointerEnterObservable = new Observable<Control3D>();
+
+    /**
+     * Gets or sets the parent container
+     */
+    public parent: Nullable<Container3D>;
+
+    // Behaviors
+    private _behaviors = new Array<Behavior<Control3D>>();
+
+    /**
+     * Gets the list of attached behaviors
+     * @see http://doc.babylonjs.com/features/behaviour
+     */
+    public get behaviors(): Behavior<Control3D>[] {
+        return this._behaviors;
+    }
+
+    /**
+     * Attach a behavior to the control
+     * @see http://doc.babylonjs.com/features/behaviour
+     * @param behavior defines the behavior to attach
+     * @returns the current control
+     */
+    public addBehavior(behavior: Behavior<Control3D>): Control3D {
+        var index = this._behaviors.indexOf(behavior);
+
+        if (index !== -1) {
             return this;
             return this;
         }
         }
 
 
-        /**
-         * Remove an attached behavior
-         * @see http://doc.babylonjs.com/features/behaviour
-         * @param behavior defines the behavior to attach
-         * @returns the current control
-         */
-        public removeBehavior(behavior: Behavior<Control3D>): Control3D {
-            var index = this._behaviors.indexOf(behavior);
-
-            if (index === -1) {
-                return this;
-            }
+        behavior.init();
+        let scene = this._host.scene;
+        if (scene.isLoading) {
+            // We defer the attach when the scene will be loaded
+            scene.onDataLoadedObservable.addOnce(() => {
+                behavior.attach(this);
+            });
+        } else {
+            behavior.attach(this);
+        }
+        this._behaviors.push(behavior);
 
 
-            this._behaviors[index].detach();
-            this._behaviors.splice(index, 1);
+        return this;
+    }
 
 
-            return this;
-        }        
-
-        /**
-         * Gets an attached behavior by name
-         * @param name defines the name of the behavior to look for
-         * @see http://doc.babylonjs.com/features/behaviour
-         * @returns null if behavior was not found else the requested behavior
-         */
-        public getBehaviorByName(name: string): Nullable<Behavior<Control3D>> {
-            for (var behavior of this._behaviors) {
-                if (behavior.name === name) {
-                    return behavior;
-                }
-            }
+    /**
+     * Remove an attached behavior
+     * @see http://doc.babylonjs.com/features/behaviour
+     * @param behavior defines the behavior to attach
+     * @returns the current control
+     */
+    public removeBehavior(behavior: Behavior<Control3D>): Control3D {
+        var index = this._behaviors.indexOf(behavior);
 
 
-            return null;
-        }      
-        
-        /** Gets or sets a boolean indicating if the control is visible */
-        public get isVisible(): boolean {
-            return this._isVisible;
+        if (index === -1) {
+            return this;
         }
         }
 
 
-        public set isVisible(value: boolean) {
-            if (this._isVisible === value) {
-                return;
-            }
+        this._behaviors[index].detach();
+        this._behaviors.splice(index, 1);
 
 
-            this._isVisible = value;
+        return this;
+    }
 
 
-            let mesh = this.mesh;
-            if (mesh) {
-                mesh.setEnabled(value);
+    /**
+     * Gets an attached behavior by name
+     * @param name defines the name of the behavior to look for
+     * @see http://doc.babylonjs.com/features/behaviour
+     * @returns null if behavior was not found else the requested behavior
+     */
+    public getBehaviorByName(name: string): Nullable<Behavior<Control3D>> {
+        for (var behavior of this._behaviors) {
+            if (behavior.name === name) {
+                return behavior;
             }
             }
         }
         }
 
 
-        /**
-         * Creates a new control
-         * @param name defines the control name
-         */
-        constructor(
-            /** Defines the control name */
-            public name?: string) {
-        }
+        return null;
+    }
+
+    /** Gets or sets a boolean indicating if the control is visible */
+    public get isVisible(): boolean {
+        return this._isVisible;
+    }
 
 
-        /**
-         * Gets a string representing the class name
-         */
-        public get typeName(): string {
-            return this._getTypeName();
+    public set isVisible(value: boolean) {
+        if (this._isVisible === value) {
+            return;
         }
         }
 
 
-        protected _getTypeName(): string {
-            return "Control3D";
+        this._isVisible = value;
+
+        let mesh = this.mesh;
+        if (mesh) {
+            mesh.setEnabled(value);
         }
         }
+    }
+
+    /**
+     * Creates a new control
+     * @param name defines the control name
+     */
+    constructor(
+        /** Defines the control name */
+        public name?: string) {
+    }
+
+    /**
+     * Gets a string representing the class name
+     */
+    public get typeName(): string {
+        return this._getTypeName();
+    }
 
 
-        /**
-         * Gets the transform node used by this control
-         */
-        public get node(): Nullable<TransformNode> {
-            return this._node;
+    protected _getTypeName(): string {
+        return "Control3D";
+    }
+
+    /**
+     * Gets the transform node used by this control
+     */
+    public get node(): Nullable<TransformNode> {
+        return this._node;
+    }
+
+    /**
+     * Gets the mesh used to render this control
+     */
+    public get mesh(): Nullable<AbstractMesh> {
+        if (this._node instanceof AbstractMesh) {
+            return this._node as AbstractMesh;
         }
         }
 
 
-        /**
-         * Gets the mesh used to render this control
-         */
-        public get mesh(): Nullable<AbstractMesh> {
-            if (this._node instanceof AbstractMesh) {
-                return this._node as AbstractMesh;
-            }
+        return null;
+    }
 
 
-            return null;
+    /**
+     * Link the control as child of the given node
+     * @param node defines the node to link to. Use null to unlink the control
+     * @returns the current control
+     */
+    public linkToTransformNode(node: Nullable<TransformNode>): Control3D {
+        if (this._node) {
+            this._node.parent = node;
         }
         }
+        return this;
+    }
 
 
-        /**
-         * Link the control as child of the given node
-         * @param node defines the node to link to. Use null to unlink the control
-         * @returns the current control
-         */
-        public linkToTransformNode(node: Nullable<TransformNode>): Control3D {
-            if (this._node) {
-                this._node.parent = node;
+    /** @hidden **/
+    public _prepareNode(scene: Scene): void {
+        if (!this._node) {
+            this._node = this._createNode(scene);
+
+            if (!this.node) {
+                return;
             }
             }
-            return this;
-        }    
-
-        /** @hidden **/      
-        public _prepareNode(scene: Scene): void{
-            if (!this._node) {
-                this._node = this._createNode(scene);
-
-                if (!this.node) {
-                    return;
-                }
-                this._node!.metadata = this; // Store the control on the metadata field in order to get it when picking
-                this._node!.position = this.position;
-                this._node!.scaling = this.scaling;
-
-                let mesh = this.mesh;
-                if (mesh) {
-                    mesh.isPickable = true;
-
-                    this._affectMaterial(mesh);
-                }
+            this._node!.metadata = this; // Store the control on the metadata field in order to get it when picking
+            this._node!.position = this.position;
+            this._node!.scaling = this.scaling;
+
+            let mesh = this.mesh;
+            if (mesh) {
+                mesh.isPickable = true;
+
+                this._affectMaterial(mesh);
             }
             }
         }
         }
+    }
+
+    /**
+     * Node creation.
+     * Can be overriden by children
+     * @param scene defines the scene where the node must be attached
+     * @returns the attached node or null if none. Must return a Mesh or AbstractMesh if there is an atttached visible object
+     */
+    protected _createNode(scene: Scene): Nullable<TransformNode> {
+        // Do nothing by default
+        return null;
+    }
+
+    /**
+     * Affect a material to the given mesh
+     * @param mesh defines the mesh which will represent the control
+     */
+    protected _affectMaterial(mesh: AbstractMesh) {
+        mesh.material = null;
+    }
+
+    // Pointers
 
 
-        /**
-         * Node creation.
-         * Can be overriden by children
-         * @param scene defines the scene where the node must be attached
-         * @returns the attached node or null if none. Must return a Mesh or AbstractMesh if there is an atttached visible object
-         */
-        protected _createNode(scene: Scene): Nullable<TransformNode> {
-            // Do nothing by default
-            return null;
+    /** @hidden */
+    public _onPointerMove(target: Control3D, coordinates: Vector3): void {
+        this.onPointerMoveObservable.notifyObservers(coordinates, -1, target, this);
+    }
+
+    /** @hidden */
+    public _onPointerEnter(target: Control3D): boolean {
+        if (this._enterCount > 0) {
+            return false;
         }
         }
 
 
-        /**
-         * Affect a material to the given mesh
-         * @param mesh defines the mesh which will represent the control
-         */
-        protected _affectMaterial(mesh: AbstractMesh) {
-            mesh.material = null;
+        if (this._enterCount === -1) { // -1 is for touch input, we are now sure we are with a mouse or pencil
+            this._enterCount = 0;
         }
         }
 
 
-        // Pointers
+        this._enterCount++;
 
 
-        /** @hidden */
-        public _onPointerMove(target: Control3D, coordinates: Vector3): void {
-            this.onPointerMoveObservable.notifyObservers(coordinates, -1, target, this);
-        }
+        this.onPointerEnterObservable.notifyObservers(this, -1, target, this);
 
 
-        /** @hidden */
-        public _onPointerEnter(target: Control3D): boolean {
-            if (this._enterCount > 0) {
-                return false;
-            }
+        if (this.pointerEnterAnimation) {
+            this.pointerEnterAnimation();
+        }
 
 
-            if (this._enterCount === -1) { // -1 is for touch input, we are now sure we are with a mouse or pencil
-                this._enterCount = 0;
-            }
+        return true;
+    }
 
 
-            this._enterCount++;
+    /** @hidden */
+    public _onPointerOut(target: Control3D): void {
+        this._enterCount = 0;
 
 
-            this.onPointerEnterObservable.notifyObservers(this, -1, target, this);
+        this.onPointerOutObservable.notifyObservers(this, -1, target, this);
 
 
-            if (this.pointerEnterAnimation) {
-                this.pointerEnterAnimation();
-            }
+        if (this.pointerOutAnimation) {
+            this.pointerOutAnimation();
+        }
+    }
 
 
-            return true;
+    /** @hidden */
+    public _onPointerDown(target: Control3D, coordinates: Vector3, pointerId: number, buttonIndex: number): boolean {
+        if (this._downCount !== 0) {
+            return false;
         }
         }
 
 
-        /** @hidden */
-        public _onPointerOut(target: Control3D): void {
-            this._enterCount = 0;
+        this._downCount++;
 
 
-            this.onPointerOutObservable.notifyObservers(this, -1, target, this);
+        this._downPointerIds[pointerId] = true;
 
 
-            if (this.pointerOutAnimation) {
-                this.pointerOutAnimation();
-            }            
-        }
+        this.onPointerDownObservable.notifyObservers(new Vector3WithInfo(coordinates, buttonIndex), -1, target, this);
 
 
-        /** @hidden */
-        public _onPointerDown(target: Control3D, coordinates: Vector3, pointerId:number, buttonIndex: number): boolean {
-            if (this._downCount !== 0) {
-                return false;
-            }
+        if (this.pointerDownAnimation) {
+            this.pointerDownAnimation();
+        }
 
 
-            this._downCount++;
+        return true;
+    }
 
 
-            this._downPointerIds[pointerId] = true;
+    /** @hidden */
+    public _onPointerUp(target: Control3D, coordinates: Vector3, pointerId: number, buttonIndex: number, notifyClick: boolean): void {
+        this._downCount = 0;
 
 
-            this.onPointerDownObservable.notifyObservers(new Vector3WithInfo(coordinates, buttonIndex), -1, target, this);
+        delete this._downPointerIds[pointerId];
 
 
-            if (this.pointerDownAnimation) {
-                this.pointerDownAnimation();
-            }                 
+        if (notifyClick && (this._enterCount > 0 || this._enterCount === -1)) {
+            this.onPointerClickObservable.notifyObservers(new Vector3WithInfo(coordinates, buttonIndex), -1, target, this);
+        }
+        this.onPointerUpObservable.notifyObservers(new Vector3WithInfo(coordinates, buttonIndex), -1, target, this);
 
 
-            return true;
+        if (this.pointerUpAnimation) {
+            this.pointerUpAnimation();
         }
         }
+    }
 
 
-        /** @hidden */
-        public _onPointerUp(target: Control3D, coordinates: Vector3, pointerId:number, buttonIndex: number, notifyClick: boolean): void {
-            this._downCount = 0;
-
-            delete this._downPointerIds[pointerId];
-
-			if (notifyClick && (this._enterCount > 0 || this._enterCount === -1)) {
-				this.onPointerClickObservable.notifyObservers(new Vector3WithInfo(coordinates, buttonIndex), -1, target, this);
-			}
-			this.onPointerUpObservable.notifyObservers(new Vector3WithInfo(coordinates, buttonIndex), -1, target, this);            
-
-            if (this.pointerUpAnimation) {
-                this.pointerUpAnimation();
-            }          
-        }  
-
-        /** @hidden */
-        public forcePointerUp(pointerId: Nullable<number> = null) {
-            if(pointerId !== null){
-                this._onPointerUp(this, Vector3.Zero(), pointerId, 0, true);
-            }else{
-                for(var key in this._downPointerIds){
-                    this._onPointerUp(this, Vector3.Zero(), +key as number, 0, true);
-                }
+    /** @hidden */
+    public forcePointerUp(pointerId: Nullable<number> = null) {
+        if (pointerId !== null) {
+            this._onPointerUp(this, Vector3.Zero(), pointerId, 0, true);
+        } else {
+            for (var key in this._downPointerIds) {
+                this._onPointerUp(this, Vector3.Zero(), +key as number, 0, true);
             }
             }
         }
         }
-        
-        /** @hidden */
-        public _processObservables(type: number, pickedPoint: Vector3, pointerId:number, buttonIndex: number): boolean {
-            if (type === BABYLON.PointerEventTypes.POINTERMOVE) {
-                this._onPointerMove(this, pickedPoint);
-
-                var previousControlOver = this._host._lastControlOver[pointerId];
-                if (previousControlOver && previousControlOver !== this) {
-                    previousControlOver._onPointerOut(this);
-                }
-
-                if (previousControlOver !== this) {
-                    this._onPointerEnter(this);
-                }
-
-                this._host._lastControlOver[pointerId] = this;
-                return true;
-            }
+    }
+
+    /** @hidden */
+    public _processObservables(type: number, pickedPoint: Vector3, pointerId: number, buttonIndex: number): boolean {
+        if (type === PointerEventTypes.POINTERMOVE) {
+            this._onPointerMove(this, pickedPoint);
 
 
-            if (type === BABYLON.PointerEventTypes.POINTERDOWN) {
-                this._onPointerDown(this, pickedPoint, pointerId, buttonIndex);
-                this._host._lastControlDown[pointerId] = this;
-                this._host._lastPickedControl = this;
-                return true;
+            var previousControlOver = this._host._lastControlOver[pointerId];
+            if (previousControlOver && previousControlOver !== this) {
+                previousControlOver._onPointerOut(this);
             }
             }
 
 
-            if (type === BABYLON.PointerEventTypes.POINTERUP) {
-                if (this._host._lastControlDown[pointerId]) {
-                    this._host._lastControlDown[pointerId]._onPointerUp(this, pickedPoint, pointerId, buttonIndex, true);
-                }
-                delete this._host._lastControlDown[pointerId];
-                return true;
+            if (previousControlOver !== this) {
+                this._onPointerEnter(this);
             }
             }
 
 
-            return false;
-        }        
+            this._host._lastControlOver[pointerId] = this;
+            return true;
+        }
 
 
-        /** @hidden */
-        public _disposeNode(): void {
-            if (this._node) {
-                this._node.dispose();
-                this._node = null;
-            }
+        if (type === PointerEventTypes.POINTERDOWN) {
+            this._onPointerDown(this, pickedPoint, pointerId, buttonIndex);
+            this._host._lastControlDown[pointerId] = this;
+            this._host._lastPickedControl = this;
+            return true;
         }
         }
 
 
-        /**
-         * Releases all associated resources
-         */
-        public dispose() {
-            this.onPointerDownObservable.clear();
-            this.onPointerEnterObservable.clear();
-            this.onPointerMoveObservable.clear();
-            this.onPointerOutObservable.clear();
-            this.onPointerUpObservable.clear();
-            this.onPointerClickObservable.clear();
-
-            this._disposeNode();
-
-            // Behaviors
-            for (var behavior of this._behaviors) {
-                behavior.detach();
+        if (type === PointerEventTypes.POINTERUP) {
+            if (this._host._lastControlDown[pointerId]) {
+                this._host._lastControlDown[pointerId]._onPointerUp(this, pickedPoint, pointerId, buttonIndex, true);
             }
             }
+            delete this._host._lastControlDown[pointerId];
+            return true;
+        }
+
+        return false;
+    }
+
+    /** @hidden */
+    public _disposeNode(): void {
+        if (this._node) {
+            this._node.dispose();
+            this._node = null;
+        }
+    }
+
+    /**
+     * Releases all associated resources
+     */
+    public dispose() {
+        this.onPointerDownObservable.clear();
+        this.onPointerEnterObservable.clear();
+        this.onPointerMoveObservable.clear();
+        this.onPointerOutObservable.clear();
+        this.onPointerUpObservable.clear();
+        this.onPointerClickObservable.clear();
+
+        this._disposeNode();
+
+        // Behaviors
+        for (var behavior of this._behaviors) {
+            behavior.detach();
         }
         }
     }
     }
 }
 }

+ 48 - 48
gui/src/3D/controls/cylinderPanel.ts

@@ -1,64 +1,64 @@
-/// <reference path="../../../../dist/preview release/babylon.d.ts"/>
+import { VolumeBasedPanel } from "./volumeBasedPanel";
+import { float, Tools, Vector3, Matrix, Tmp } from "babylonjs";
+import { Control3D } from "./control3D";
+import { Container3D } from "./container3D";
+
+/**
+ * Class used to create a container panel deployed on the surface of a cylinder
+ */
+export class CylinderPanel extends VolumeBasedPanel {
+    private _radius = 5.0;
 
 
-module BABYLON.GUI {
     /**
     /**
-     * Class used to create a container panel deployed on the surface of a cylinder
+     * Gets or sets the radius of the cylinder where to project controls (5 by default)
      */
      */
-    export class CylinderPanel extends VolumeBasedPanel {
-        private _radius = 5.0;
+    public get radius(): float {
+        return this._radius;
+    }
 
 
-        /**
-         * Gets or sets the radius of the cylinder where to project controls (5 by default)
-         */
-        public get radius(): float {
-            return this._radius;
+    public set radius(value: float) {
+        if (this._radius === value) {
+            return;
         }
         }
 
 
-        public set radius(value: float) {
-            if (this._radius === value) {
-                return;
-            }
+        this._radius = value;
 
 
-            this._radius = value;
-
-            Tools.SetImmediate(() => {
-                this._arrangeChildren();               
-            });
-        }              
+        Tools.SetImmediate(() => {
+            this._arrangeChildren();
+        });
+    }
 
 
-        protected _mapGridNode(control: Control3D, nodePosition: Vector3) {            
-            let mesh = control.mesh;
+    protected _mapGridNode(control: Control3D, nodePosition: Vector3) {
+        let mesh = control.mesh;
 
 
-            if (!mesh) {
-                return;
-            }
-            let newPos = this._cylindricalMapping(nodePosition);
-            control.position = newPos;
+        if (!mesh) {
+            return;
+        }
+        let newPos = this._cylindricalMapping(nodePosition);
+        control.position = newPos;
 
 
-            switch (this.orientation) {
-                case Container3D.FACEORIGIN_ORIENTATION:
-                    mesh.lookAt(new BABYLON.Vector3(-newPos.x, newPos.y, -newPos.z));
-                    break;
-                case Container3D.FACEORIGINREVERSED_ORIENTATION:
-                    mesh.lookAt(new BABYLON.Vector3(2 * newPos.x, newPos.y, 2 * newPos.z));
-                    break;
-                case Container3D.FACEFORWARD_ORIENTATION:
-                    break;
-                case Container3D.FACEFORWARDREVERSED_ORIENTATION:
-                    mesh.rotate(BABYLON.Axis.Y, Math.PI, BABYLON.Space.LOCAL);
-                    break;
-            }            
+        switch (this.orientation) {
+            case Container3D.FACEORIGIN_ORIENTATION:
+                mesh.lookAt(new BABYLON.Vector3(-newPos.x, newPos.y, -newPos.z));
+                break;
+            case Container3D.FACEORIGINREVERSED_ORIENTATION:
+                mesh.lookAt(new BABYLON.Vector3(2 * newPos.x, newPos.y, 2 * newPos.z));
+                break;
+            case Container3D.FACEFORWARD_ORIENTATION:
+                break;
+            case Container3D.FACEFORWARDREVERSED_ORIENTATION:
+                mesh.rotate(BABYLON.Axis.Y, Math.PI, BABYLON.Space.LOCAL);
+                break;
         }
         }
+    }
 
 
-        private _cylindricalMapping(source: Vector3)
-        {
-            let newPos = new Vector3(0, source.y, this._radius);
+    private _cylindricalMapping(source: Vector3) {
+        let newPos = new Vector3(0, source.y, this._radius);
 
 
-            let yAngle = (source.x / this._radius);
+        let yAngle = (source.x / this._radius);
 
 
-            Matrix.RotationYawPitchRollToRef(yAngle, 0, 0, Tmp.Matrix[0]);
+        Matrix.RotationYawPitchRollToRef(yAngle, 0, 0, Tmp.Matrix[0]);
 
 
-            return Vector3.TransformNormal(newPos, Tmp.Matrix[0]);
-        }
+        return Vector3.TransformNormal(newPos, Tmp.Matrix[0]);
     }
     }
-}
+}

+ 210 - 206
gui/src/3D/controls/holographicButton.ts

@@ -1,243 +1,247 @@
-/// <reference path="../../../../dist/preview release/babylon.d.ts"/>
+import { Button3D } from "./button3D";
+import { Mesh, StandardMaterial, Nullable, Observer, Vector3, Scene, TransformNode, MeshBuilder, Color3 } from "babylonjs";
+import { FluentMaterial } from "../materials/fluentMaterial";
+import { StackPanel } from "../../2D/controls/stackPanel";
+import { Image } from "../../2D/controls/image";
+import { TextBlock } from "../../2D/controls/textBlock";
+import { AdvancedDynamicTexture } from "../../2D/advancedDynamicTexture";
+
+/**
+ * Class used to create a holographic button in 3D
+ */
+export class HolographicButton extends Button3D {
+    private _backPlate: Mesh;
+    private _textPlate: Mesh;
+    private _frontPlate: Mesh;
+    private _text: string;
+    private _imageUrl: string;
+    private _shareMaterials = true;
+    private _frontMaterial: FluentMaterial;
+    private _backMaterial: FluentMaterial;
+    private _plateMaterial: StandardMaterial;
+    private _pickedPointObserver: Nullable<Observer<Nullable<Vector3>>>;
 
 
-module BABYLON.GUI {
     /**
     /**
-     * Class used to create a holographic button in 3D
+     * Gets or sets text for the button
      */
      */
-    export class HolographicButton extends Button3D {
-        private _backPlate: Mesh;
-        private _textPlate: Mesh;
-        private _frontPlate: Mesh;
-        private _text: string;
-        private _imageUrl: string;
-        private _shareMaterials = true;
-        private _frontMaterial: FluentMaterial;
-        private _backMaterial: FluentMaterial;
-        private _plateMaterial: StandardMaterial;
-        private _pickedPointObserver: Nullable<Observer<Nullable<Vector3>>>;
-
-        /**
-         * Gets or sets text for the button
-         */
-        public get text(): string {
-            return this._text;
+    public get text(): string {
+        return this._text;
+    }
+
+    public set text(value: string) {
+        if (this._text === value) {
+            return;
         }
         }
 
 
-        public set text(value: string) {
-            if (this._text === value) {
-                return;
-            }
+        this._text = value;
+        this._rebuildContent();
+    }
 
 
-            this._text = value;
-            this._rebuildContent();
-        }
+    /**
+     * Gets or sets the image url for the button
+     */
+    public get imageUrl(): string {
+        return this._imageUrl;
+    }
 
 
-        /**
-         * Gets or sets the image url for the button
-         */
-        public get imageUrl(): string {
-            return this._imageUrl;
+    public set imageUrl(value: string) {
+        if (this._imageUrl === value) {
+            return;
         }
         }
 
 
-        public set imageUrl(value: string) {
-            if (this._imageUrl === value) {
-                return;
-            }
+        this._imageUrl = value;
+        this._rebuildContent();
+    }
 
 
-            this._imageUrl = value;
-            this._rebuildContent();
-        }        
+    /**
+     * Gets the back material used by this button
+     */
+    public get backMaterial(): FluentMaterial {
+        return this._backMaterial;
+    }
 
 
-        /**
-         * Gets the back material used by this button
-         */
-        public get backMaterial(): FluentMaterial {
-            return this._backMaterial;
-        }
+    /**
+     * Gets the front material used by this button
+     */
+    public get frontMaterial(): FluentMaterial {
+        return this._frontMaterial;
+    }
 
 
-        /**
-         * Gets the front material used by this button
-         */
-        public get frontMaterial(): FluentMaterial {
-            return this._frontMaterial;
-        }       
-        
-        /**
-         * Gets the plate material used by this button
-         */
-        public get plateMaterial(): StandardMaterial {
-            return this._plateMaterial;
-        }          
-
-        /**
-         * Gets a boolean indicating if this button shares its material with other HolographicButtons
-         */
-        public get shareMaterials(): boolean {
-            return this._shareMaterials;
-        }
+    /**
+     * Gets the plate material used by this button
+     */
+    public get plateMaterial(): StandardMaterial {
+        return this._plateMaterial;
+    }
 
 
-        /**
-         * Creates a new button
-         * @param name defines the control name
-         */
-        constructor(name?: string, shareMaterials = true) {
-            super(name);
-
-            this._shareMaterials = shareMaterials;
-
-            // Default animations
-            this.pointerEnterAnimation = () => {
-                if (!this.mesh) {
-                    return;
-                }
-                this._frontPlate.setEnabled(true);
-            }
+    /**
+     * Gets a boolean indicating if this button shares its material with other HolographicButtons
+     */
+    public get shareMaterials(): boolean {
+        return this._shareMaterials;
+    }
 
 
-            this.pointerOutAnimation = () => {
-                if (!this.mesh) {
-                    return;
-                }
-                this._frontPlate.setEnabled(false);
-            }                      
-        }
-    
-        protected _getTypeName(): string {
-            return "HolographicButton";
-        }        
-
-        private _rebuildContent(): void {
-            this._disposeFacadeTexture();
-
-            let panel = new StackPanel();
-            panel.isVertical = true;
-
-            if (this._imageUrl) {
-                let image = new BABYLON.GUI.Image();
-                image.source = this._imageUrl;
-                image.paddingTop = "40px";
-                image.height = "180px";
-                image.width = "100px";
-                image.paddingBottom = "40px";
-                panel.addControl(image);                
-            }
+    /**
+     * Creates a new button
+     * @param name defines the control name
+     */
+    constructor(name?: string, shareMaterials = true) {
+        super(name);
 
 
-            if (this._text) {
-                let text = new BABYLON.GUI.TextBlock();
-                text.text = this._text;
-                text.color = "white";
-                text.height = "30px";
-                text.fontSize = 24;
-                panel.addControl(text);
-            }
+        this._shareMaterials = shareMaterials;
 
 
-            if (this._frontPlate) {
-                this.content = panel;
+        // Default animations
+        this.pointerEnterAnimation = () => {
+            if (!this.mesh) {
+                return;
             }
             }
+            this._frontPlate.setEnabled(true);
         }
         }
 
 
-        // Mesh association
-        protected _createNode(scene: Scene): TransformNode {
-            this._backPlate = MeshBuilder.CreateBox(this.name + "BackMesh", {
-                width: 1.0, 
-                height: 1.0,
-                depth: 0.08
-            }, scene); 
-
-            this._frontPlate = MeshBuilder.CreateBox(this.name + "FrontMesh", {
-                width: 1.0, 
-                height: 1.0,
-                depth: 0.08
-            }, scene); 
-
-            this._frontPlate.parent = this._backPlate;
-            this._frontPlate.position.z = -0.08;
-            this._frontPlate.isPickable = false;
+        this.pointerOutAnimation = () => {
+            if (!this.mesh) {
+                return;
+            }
             this._frontPlate.setEnabled(false);
             this._frontPlate.setEnabled(false);
+        }
+    }
+
+    protected _getTypeName(): string {
+        return "HolographicButton";
+    }
+
+    private _rebuildContent(): void {
+        this._disposeFacadeTexture();
+
+        let panel = new StackPanel();
+        panel.isVertical = true;
 
 
-            this._textPlate= <Mesh>super._createNode(scene);
-            this._textPlate.parent = this._backPlate;
-            this._textPlate.position.z = -0.08;
-            this._textPlate.isPickable = false;            
-           
-            return this._backPlate;
+        if (this._imageUrl) {
+            let image = new Image();
+            image.source = this._imageUrl;
+            image.paddingTop = "40px";
+            image.height = "180px";
+            image.width = "100px";
+            image.paddingBottom = "40px";
+            panel.addControl(image);
         }
         }
 
 
-        protected _applyFacade(facadeTexture: AdvancedDynamicTexture) {
-            this._plateMaterial.emissiveTexture = facadeTexture;
-            this._plateMaterial.opacityTexture = facadeTexture;
-        }   
-        
-        private _createBackMaterial(mesh: Mesh) {
-            this._backMaterial = new FluentMaterial(this.name + "Back Material", mesh.getScene());
-            this._backMaterial.renderHoverLight = true;
-            this._pickedPointObserver = this._host.onPickedPointChangedObservable.add(pickedPoint => {
-                if (pickedPoint) {
-                    this._backMaterial.hoverPosition = pickedPoint;
-                    this._backMaterial.hoverColor.a = 1.0;
-                } else {
-                    this._backMaterial.hoverColor.a = 0;
-                }
-            });
+        if (this._text) {
+            let text = new TextBlock();
+            text.text = this._text;
+            text.color = "white";
+            text.height = "30px";
+            text.fontSize = 24;
+            panel.addControl(text);
         }
         }
 
 
-        private _createFrontMaterial(mesh: Mesh) {
-            this._frontMaterial = new FluentMaterial(this.name + "Front Material", mesh.getScene());
-            this._frontMaterial.innerGlowColorIntensity = 0; // No inner glow
-            this._frontMaterial.alpha = 0.5; // Additive
-            this._frontMaterial.renderBorders = true;
-        }     
-        
-        private _createPlateMaterial(mesh: Mesh) {
-            this._plateMaterial = new StandardMaterial(this.name + "Plate Material", mesh.getScene());
-            this._plateMaterial.specularColor = Color3.Black();
+        if (this._frontPlate) {
+            this.content = panel;
         }
         }
+    }
+
+    // Mesh association
+    protected _createNode(scene: Scene): TransformNode {
+        this._backPlate = MeshBuilder.CreateBox(this.name + "BackMesh", {
+            width: 1.0,
+            height: 1.0,
+            depth: 0.08
+        }, scene);
+
+        this._frontPlate = MeshBuilder.CreateBox(this.name + "FrontMesh", {
+            width: 1.0,
+            height: 1.0,
+            depth: 0.08
+        }, scene);
+
+        this._frontPlate.parent = this._backPlate;
+        this._frontPlate.position.z = -0.08;
+        this._frontPlate.isPickable = false;
+        this._frontPlate.setEnabled(false);
+
+        this._textPlate = <Mesh>super._createNode(scene);
+        this._textPlate.parent = this._backPlate;
+        this._textPlate.position.z = -0.08;
+        this._textPlate.isPickable = false;
+
+        return this._backPlate;
+    }
+
+    protected _applyFacade(facadeTexture: AdvancedDynamicTexture) {
+        this._plateMaterial.emissiveTexture = facadeTexture;
+        this._plateMaterial.opacityTexture = facadeTexture;
+    }
 
 
-        protected _affectMaterial(mesh: Mesh) {
-            // Back
-            if (this._shareMaterials) {
-                if (!this._host._sharedMaterials["backFluentMaterial"]) {
-                    this._createBackMaterial(mesh);
-                    this._host._sharedMaterials["backFluentMaterial"] =  this._backMaterial;
-                } else {
-                    this._backMaterial = this._host._sharedMaterials["backFluentMaterial"] as FluentMaterial;
-                }
-
-                // Front
-                if (!this._host._sharedMaterials["frontFluentMaterial"]) {
-                    this._createFrontMaterial(mesh);
-                    this._host._sharedMaterials["frontFluentMaterial"] = this._frontMaterial;                
-                } else {
-                    this._frontMaterial = this._host._sharedMaterials["frontFluentMaterial"] as FluentMaterial;
-                }  
+    private _createBackMaterial(mesh: Mesh) {
+        this._backMaterial = new FluentMaterial(this.name + "Back Material", mesh.getScene());
+        this._backMaterial.renderHoverLight = true;
+        this._pickedPointObserver = this._host.onPickedPointChangedObservable.add(pickedPoint => {
+            if (pickedPoint) {
+                this._backMaterial.hoverPosition = pickedPoint;
+                this._backMaterial.hoverColor.a = 1.0;
             } else {
             } else {
+                this._backMaterial.hoverColor.a = 0;
+            }
+        });
+    }
+
+    private _createFrontMaterial(mesh: Mesh) {
+        this._frontMaterial = new FluentMaterial(this.name + "Front Material", mesh.getScene());
+        this._frontMaterial.innerGlowColorIntensity = 0; // No inner glow
+        this._frontMaterial.alpha = 0.5; // Additive
+        this._frontMaterial.renderBorders = true;
+    }
+
+    private _createPlateMaterial(mesh: Mesh) {
+        this._plateMaterial = new StandardMaterial(this.name + "Plate Material", mesh.getScene());
+        this._plateMaterial.specularColor = Color3.Black();
+    }
+
+    protected _affectMaterial(mesh: Mesh) {
+        // Back
+        if (this._shareMaterials) {
+            if (!this._host._sharedMaterials["backFluentMaterial"]) {
                 this._createBackMaterial(mesh);
                 this._createBackMaterial(mesh);
+                this._host._sharedMaterials["backFluentMaterial"] = this._backMaterial;
+            } else {
+                this._backMaterial = this._host._sharedMaterials["backFluentMaterial"] as FluentMaterial;
+            }
+
+            // Front
+            if (!this._host._sharedMaterials["frontFluentMaterial"]) {
                 this._createFrontMaterial(mesh);
                 this._createFrontMaterial(mesh);
+                this._host._sharedMaterials["frontFluentMaterial"] = this._frontMaterial;
+            } else {
+                this._frontMaterial = this._host._sharedMaterials["frontFluentMaterial"] as FluentMaterial;
             }
             }
+        } else {
+            this._createBackMaterial(mesh);
+            this._createFrontMaterial(mesh);
+        }
 
 
-            this._createPlateMaterial(mesh);
-            this._backPlate.material =  this._backMaterial;
-            this._frontPlate.material = this._frontMaterial;
-            this._textPlate.material = this._plateMaterial;
+        this._createPlateMaterial(mesh);
+        this._backPlate.material = this._backMaterial;
+        this._frontPlate.material = this._frontMaterial;
+        this._textPlate.material = this._plateMaterial;
 
 
-            this._rebuildContent();
-        }
+        this._rebuildContent();
+    }
+
+    /**
+     * Releases all associated resources
+     */
+    public dispose() {
+        super.dispose(); // will dispose main mesh ie. back plate
 
 
-        /**
-         * Releases all associated resources
-         */
-        public dispose() {
-            super.dispose(); // will dispose main mesh ie. back plate
-            
-            if (!this.shareMaterials) {
-                this._backMaterial.dispose();
-                this._frontMaterial.dispose();
-                this._plateMaterial.dispose();
-
-                if (this._pickedPointObserver) {
-                    this._host.onPickedPointChangedObservable.remove(this._pickedPointObserver);
-                    this._pickedPointObserver = null;
-                }
+        if (!this.shareMaterials) {
+            this._backMaterial.dispose();
+            this._frontMaterial.dispose();
+            this._plateMaterial.dispose();
+
+            if (this._pickedPointObserver) {
+                this._host.onPickedPointChangedObservable.remove(this._pickedPointObserver);
+                this._pickedPointObserver = null;
             }
             }
-        }        
+        }
     }
     }
 }
 }

+ 12 - 0
gui/src/3D/controls/index.ts

@@ -0,0 +1,12 @@
+export * from "./abstractButton3D";
+export * from "./button3D";
+export * from "./container3D";
+export * from "./control3D";
+export * from "./cylinderPanel";
+export * from "./holographicButton";
+export * from "./meshButton3D";
+export * from "./planePanel";
+export * from "./scatterPanel";
+export * from "./spherePanel";
+export * from "./stackPanel3D";
+export * from "./volumeBasedPanel";

+ 50 - 51
gui/src/3D/controls/meshButton3D.ts

@@ -1,68 +1,67 @@
-/// <reference path="../../../../dist/preview release/babylon.d.ts"/>
+import { Scene, TransformNode, AbstractMesh, Mesh } from "babylonjs";
+import { Button3D } from "./button3D";
+
+/**
+ * Class used to create an interactable object. It's a 3D button using a mesh coming from the current scene
+ */
+export class MeshButton3D extends Button3D {
+    /** @hidden */
+    protected _currentMesh: Mesh;
 
 
-module BABYLON.GUI {
     /**
     /**
-     * Class used to create an interactable object. It's a 3D button using a mesh coming from the current scene
+     * Creates a new 3D button based on a mesh
+     * @param mesh mesh to become a 3D button
+     * @param name defines the control name
      */
      */
-    export class MeshButton3D extends Button3D {
-        /** @hidden */
-        protected _currentMesh: Mesh;
+    constructor(mesh: Mesh, name?: string) {
+        super(name);
+        this._currentMesh = mesh;
 
 
         /**
         /**
-         * Creates a new 3D button based on a mesh
-         * @param mesh mesh to become a 3D button
-         * @param name defines the control name
+         * Provides a default behavior on hover/out & up/down
+         * Override those function to create your own desired behavior specific to your mesh
          */
          */
-        constructor(mesh: Mesh, name?: string) {
-            super(name);
-            this._currentMesh = mesh; 
-
-            /**
-             * Provides a default behavior on hover/out & up/down
-             * Override those function to create your own desired behavior specific to your mesh
-             */
-            this.pointerEnterAnimation = () => {
-                if (!this.mesh) {
-                    return;
-                }
-                this.mesh.scaling.scaleInPlace(1.1);
+        this.pointerEnterAnimation = () => {
+            if (!this.mesh) {
+                return;
             }
             }
+            this.mesh.scaling.scaleInPlace(1.1);
+        }
 
 
-            this.pointerOutAnimation = () => {
-                if (!this.mesh) {
-                    return;
-                }
-                this.mesh.scaling.scaleInPlace(1.0 / 1.1);
-            }    
+        this.pointerOutAnimation = () => {
+            if (!this.mesh) {
+                return;
+            }
+            this.mesh.scaling.scaleInPlace(1.0 / 1.1);
+        }
 
 
-            this.pointerDownAnimation = () => {
-                if (!this.mesh) {
-                    return;
-                }
-                this.mesh.scaling.scaleInPlace(0.95);
+        this.pointerDownAnimation = () => {
+            if (!this.mesh) {
+                return;
             }
             }
+            this.mesh.scaling.scaleInPlace(0.95);
+        }
 
 
-            this.pointerUpAnimation = () => {
-                if (!this.mesh) {
-                    return;
-                }
-                this.mesh.scaling.scaleInPlace(1.0 / 0.95);
-            }                     
+        this.pointerUpAnimation = () => {
+            if (!this.mesh) {
+                return;
+            }
+            this.mesh.scaling.scaleInPlace(1.0 / 0.95);
         }
         }
+    }
 
 
-        protected _getTypeName(): string {
-            return "MeshButton3D";
-        }        
+    protected _getTypeName(): string {
+        return "MeshButton3D";
+    }
 
 
-        // Mesh association
-        protected _createNode(scene: Scene): TransformNode {
-            this._currentMesh.getChildMeshes().forEach((mesh)=>{
-                mesh.metadata = this;
-            });
-            return this._currentMesh;
-        }
+    // Mesh association
+    protected _createNode(scene: Scene): TransformNode {
+        this._currentMesh.getChildMeshes().forEach((mesh) => {
+            mesh.metadata = this;
+        });
+        return this._currentMesh;
+    }
 
 
-        protected _affectMaterial(mesh: AbstractMesh) {
-        }
+    protected _affectMaterial(mesh: AbstractMesh) {
     }
     }
 }
 }

+ 29 - 28
gui/src/3D/controls/planePanel.ts

@@ -1,35 +1,36 @@
-/// <reference path="../../../../dist/preview release/babylon.d.ts"/>
+import { Tmp, Vector3 } from "babylonjs";
+import { Container3D } from "./container3D";
+import { Control3D } from "./control3D";
+import { VolumeBasedPanel } from "./volumeBasedPanel";
 
 
-module BABYLON.GUI {
-    /**
-     * Class used to create a container panel deployed on the surface of a plane
-     */
-    export class PlanePanel extends VolumeBasedPanel {    
-        protected _mapGridNode(control: Control3D, nodePosition: Vector3) {            
-            let mesh = control.mesh;
+/**
+ * Class used to create a container panel deployed on the surface of a plane
+ */
+export class PlanePanel extends VolumeBasedPanel {
+    protected _mapGridNode(control: Control3D, nodePosition: Vector3) {
+        let mesh = control.mesh;
 
 
-            if (!mesh) {
-                return;
-            }
+        if (!mesh) {
+            return;
+        }
 
 
-            control.position = nodePosition.clone();
-            let target = Tmp.Vector3[0];
+        control.position = nodePosition.clone();
+        let target = Tmp.Vector3[0];
 
 
-            target.copyFrom(nodePosition);
+        target.copyFrom(nodePosition);
 
 
-            switch (this.orientation) {
-                case Container3D.FACEORIGIN_ORIENTATION:
-                case Container3D.FACEFORWARD_ORIENTATION:
-                    target.addInPlace(new BABYLON.Vector3(0, 0, -1));
-                    mesh.lookAt(target);
-                    break;
-                case Container3D.FACEFORWARDREVERSED_ORIENTATION:
-                case Container3D.FACEORIGINREVERSED_ORIENTATION:
-                    target.addInPlace(new BABYLON.Vector3(0, 0, 1));
-                    mesh.lookAt(target);
-                    break;
-            }
-            
+        switch (this.orientation) {
+            case Container3D.FACEORIGIN_ORIENTATION:
+            case Container3D.FACEFORWARD_ORIENTATION:
+                target.addInPlace(new BABYLON.Vector3(0, 0, -1));
+                mesh.lookAt(target);
+                break;
+            case Container3D.FACEFORWARDREVERSED_ORIENTATION:
+            case Container3D.FACEORIGINREVERSED_ORIENTATION:
+                target.addInPlace(new BABYLON.Vector3(0, 0, 1));
+                mesh.lookAt(target);
+                break;
         }
         }
+
     }
     }
-}
+}

+ 91 - 95
gui/src/3D/controls/scatterPanel.ts

@@ -1,117 +1,113 @@
-/// <reference path="../../../../dist/preview release/babylon.d.ts"/>
+import { VolumeBasedPanel } from "./volumeBasedPanel";
+import { float, Tools, Vector3, Tmp } from "babylonjs";
+import { Control3D } from "./control3D";
+import { Container3D } from "./container3D";
+
+/**
+ * Class used to create a container panel where items get randomized planar mapping
+ */
+export class ScatterPanel extends VolumeBasedPanel {
+    private _iteration = 100.0;
 
 
-module BABYLON.GUI {
     /**
     /**
-     * Class used to create a container panel where items get randomized planar mapping
+     * Gets or sets the number of iteration to use to scatter the controls (100 by default)
      */
      */
-    export class ScatterPanel extends VolumeBasedPanel {    
-        private _iteration = 100.0;
-
-        /**
-         * Gets or sets the number of iteration to use to scatter the controls (100 by default)
-         */
-        public get iteration(): float {
-            return this._iteration;
+    public get iteration(): float {
+        return this._iteration;
+    }
+
+    public set iteration(value: float) {
+        if (this._iteration === value) {
+            return;
         }
         }
 
 
-        public set iteration(value: float) {
-            if (this._iteration === value) {
-                return;
-            }
+        this._iteration = value;
+
+        Tools.SetImmediate(() => {
+            this._arrangeChildren();
+        });
+    }
 
 
-            this._iteration = value;
+    protected _mapGridNode(control: Control3D, nodePosition: Vector3) {
+        let mesh = control.mesh;
+        let newPos = this._scatterMapping(nodePosition);
 
 
-            Tools.SetImmediate(() => {
-                this._arrangeChildren();               
-            });
-        }    
+        if (!mesh) {
+            return;
+        }
 
 
-        protected _mapGridNode(control: Control3D, nodePosition: Vector3) {            
-            let mesh = control.mesh;
-            let newPos = this._scatterMapping(nodePosition);
+        switch (this.orientation) {
+            case Container3D.FACEORIGIN_ORIENTATION:
+            case Container3D.FACEFORWARD_ORIENTATION:
+                mesh.lookAt(new Vector3(0, 0, -1));
+                break;
+            case Container3D.FACEFORWARDREVERSED_ORIENTATION:
+            case Container3D.FACEORIGINREVERSED_ORIENTATION:
+                mesh.lookAt(new Vector3(0, 0, 1));
+                break;
+        }
 
 
-            if (!mesh) {
-                return;
-            }
+        control.position = newPos;
+    }
+
+    private _scatterMapping(source: Vector3): Vector3 {
+        source.x = (1.0 - Math.random() * 2.0) * this._cellWidth;
+        source.y = (1.0 - Math.random() * 2.0) * this._cellHeight;
 
 
-            switch (this.orientation) {
-                case Container3D.FACEORIGIN_ORIENTATION:
-                case Container3D.FACEFORWARD_ORIENTATION:
-                    mesh.lookAt(new BABYLON.Vector3(0, 0, -1));
-                    break;
-                case Container3D.FACEFORWARDREVERSED_ORIENTATION:
-                case Container3D.FACEORIGINREVERSED_ORIENTATION:
-                    mesh.lookAt(new BABYLON.Vector3(0, 0, 1));
-                    break;
+        return source;
+    }
+
+    protected _finalProcessing() {
+        var meshes = [];
+        for (var child of this._children) {
+            if (!child.mesh) {
+                continue;
             }
             }
-            
-            control.position = newPos;
+
+            meshes.push(child.mesh);
         }
         }
 
 
-        private _scatterMapping(source: Vector3): Vector3
-        {
-            source.x = (1.0 - Math.random() * 2.0) * this._cellWidth;
-            source.y = (1.0 - Math.random() * 2.0) * this._cellHeight;
-
-            return source;
-        }   
-        
-        protected _finalProcessing() {
-            var meshes = [];
-            for (var child of this._children) {
-                if (!child.mesh) {
-                    continue;
-                }                
-
-                meshes.push(child.mesh);
-            }
+        for (var count = 0; count < this._iteration; count++) {
+            meshes.sort((a, b) => {
+                let distance1 = a.position.lengthSquared();
+                let distance2 = b.position.lengthSquared();
 
 
-            for (var count = 0; count < this._iteration; count++) {
-                meshes.sort((a, b) => {
-                    let distance1 = a.position.lengthSquared();
-                    let distance2 = b.position.lengthSquared();
+                if (distance1 < distance2) {
+                    return 1;
+                } else if (distance1 > distance2) {
+                    return -1;
+                }
 
 
-                    if (distance1 < distance2) {
-                        return 1;
-                    } else if (distance1 > distance2) {
-                        return -1;
-                    }
+                return 0;
+            });
 
 
-                    return 0;
-                });
-
-                let radiusPaddingSquared = Math.pow(this.margin, 2.0);
-                let cellSize = Math.max(this._cellWidth, this._cellHeight);
-                let difference2D = Tmp.Vector2[0];
-                let difference = Tmp.Vector3[0];
-
-                for (let i = 0; i < meshes.length - 1; i++)
-                {
-                    for (let j = i + 1; j < meshes.length; j++)
-                    {
-                        if (i != j)
-                        {
-                            meshes[j].position.subtractToRef(meshes[i].position, difference);
-
-                            // Ignore Z axis
-                            difference2D.x = difference.x;
-                            difference2D.y = difference.y;
-                            let combinedRadius = cellSize;
-                            let distance = difference2D.lengthSquared()- radiusPaddingSquared;
-                            let minSeparation = Math.min(distance, radiusPaddingSquared);
-                            distance -= minSeparation;
-
-                            if (distance < (Math.pow(combinedRadius, 2.0)))
-                            {
-                                difference2D.normalize();
-                                difference.scaleInPlace((combinedRadius - Math.sqrt(distance)) * 0.5);
-                                meshes[j].position.addInPlace(difference);
-                                meshes[i].position.subtractInPlace(difference);
-                            }
+            let radiusPaddingSquared = Math.pow(this.margin, 2.0);
+            let cellSize = Math.max(this._cellWidth, this._cellHeight);
+            let difference2D = Tmp.Vector2[0];
+            let difference = Tmp.Vector3[0];
+
+            for (let i = 0; i < meshes.length - 1; i++) {
+                for (let j = i + 1; j < meshes.length; j++) {
+                    if (i != j) {
+                        meshes[j].position.subtractToRef(meshes[i].position, difference);
+
+                        // Ignore Z axis
+                        difference2D.x = difference.x;
+                        difference2D.y = difference.y;
+                        let combinedRadius = cellSize;
+                        let distance = difference2D.lengthSquared() - radiusPaddingSquared;
+                        let minSeparation = Math.min(distance, radiusPaddingSquared);
+                        distance -= minSeparation;
+
+                        if (distance < (Math.pow(combinedRadius, 2.0))) {
+                            difference2D.normalize();
+                            difference.scaleInPlace((combinedRadius - Math.sqrt(distance)) * 0.5);
+                            meshes[j].position.addInPlace(difference);
+                            meshes[i].position.subtractInPlace(difference);
                         }
                         }
                     }
                     }
                 }
                 }
-            }        
+            }
         }
         }
     }
     }
 }
 }

+ 49 - 49
gui/src/3D/controls/spherePanel.ts

@@ -1,66 +1,66 @@
-/// <reference path="../../../../dist/preview release/babylon.d.ts"/>
+import { VolumeBasedPanel } from "./volumeBasedPanel";
+import { float, Tools, Vector3, Matrix, Tmp } from "babylonjs";
+import { Control3D } from "./control3D";
+import { Container3D } from "./container3D";
+
+/**
+ * Class used to create a container panel deployed on the surface of a sphere
+ */
+export class SpherePanel extends VolumeBasedPanel {
+    private _radius = 5.0;
 
 
-module BABYLON.GUI {
     /**
     /**
-     * Class used to create a container panel deployed on the surface of a sphere
+     * Gets or sets the radius of the sphere where to project controls (5 by default)
      */
      */
-    export class SpherePanel extends VolumeBasedPanel {
-        private _radius = 5.0;
+    public get radius(): float {
+        return this._radius;
+    }
 
 
-        /**
-         * Gets or sets the radius of the sphere where to project controls (5 by default)
-         */
-        public get radius(): float {
-            return this._radius;
+    public set radius(value: float) {
+        if (this._radius === value) {
+            return;
         }
         }
 
 
-        public set radius(value: float) {
-            if (this._radius === value) {
-                return;
-            }
+        this._radius = value;
 
 
-            this._radius = value;
-
-            Tools.SetImmediate(() => {
-                this._arrangeChildren();               
-            });
-        }              
+        Tools.SetImmediate(() => {
+            this._arrangeChildren();
+        });
+    }
 
 
-        protected _mapGridNode(control: Control3D, nodePosition: Vector3) {            
-            let mesh = control.mesh;
+    protected _mapGridNode(control: Control3D, nodePosition: Vector3) {
+        let mesh = control.mesh;
 
 
-            if (!mesh) {
-                return;
-            }
+        if (!mesh) {
+            return;
+        }
 
 
-            let newPos = this._sphericalMapping(nodePosition);
-            control.position = newPos;
+        let newPos = this._sphericalMapping(nodePosition);
+        control.position = newPos;
 
 
-            switch (this.orientation) {
-                case Container3D.FACEORIGIN_ORIENTATION:
-                    mesh.lookAt(new BABYLON.Vector3(-newPos.x, -newPos.y, -newPos.z));
-                    break;
-                case Container3D.FACEORIGINREVERSED_ORIENTATION:
-                    mesh.lookAt(new BABYLON.Vector3(2 * newPos.x, 2 * newPos.y, 2 * newPos.z));
-                    break;
-                case Container3D.FACEFORWARD_ORIENTATION:
-                    break;
-                case Container3D.FACEFORWARDREVERSED_ORIENTATION:
-                    mesh.rotate(BABYLON.Axis.Y, Math.PI, BABYLON.Space.LOCAL);
-                    break;
-            }           
+        switch (this.orientation) {
+            case Container3D.FACEORIGIN_ORIENTATION:
+                mesh.lookAt(new BABYLON.Vector3(-newPos.x, -newPos.y, -newPos.z));
+                break;
+            case Container3D.FACEORIGINREVERSED_ORIENTATION:
+                mesh.lookAt(new BABYLON.Vector3(2 * newPos.x, 2 * newPos.y, 2 * newPos.z));
+                break;
+            case Container3D.FACEFORWARD_ORIENTATION:
+                break;
+            case Container3D.FACEFORWARDREVERSED_ORIENTATION:
+                mesh.rotate(BABYLON.Axis.Y, Math.PI, BABYLON.Space.LOCAL);
+                break;
         }
         }
+    }
 
 
-        private _sphericalMapping(source: Vector3)
-        {
-            let newPos = new Vector3(0, 0, this._radius);
+    private _sphericalMapping(source: Vector3) {
+        let newPos = new Vector3(0, 0, this._radius);
 
 
-            let xAngle = (source.y / this._radius);
-            let yAngle = -(source.x / this._radius);
+        let xAngle = (source.y / this._radius);
+        let yAngle = -(source.x / this._radius);
 
 
-            Matrix.RotationYawPitchRollToRef(yAngle, xAngle, 0, Tmp.Matrix[0]);
+        Matrix.RotationYawPitchRollToRef(yAngle, xAngle, 0, Tmp.Matrix[0]);
 
 
-            return Vector3.TransformNormal(newPos, Tmp.Matrix[0]);
-        }
+        return Vector3.TransformNormal(newPos, Tmp.Matrix[0]);
     }
     }
-}
+}

+ 87 - 88
gui/src/3D/controls/stackPanel3D.ts

@@ -1,109 +1,108 @@
-/// <reference path="../../../../dist/preview release/babylon.d.ts"/>
+import { Container3D } from "./container3D";
+import { Tools, Matrix, Tmp, Vector3 } from "babylonjs";
+
+/**
+ * Class used to create a stack panel in 3D on XY plane
+ */
+export class StackPanel3D extends Container3D {
+    private _isVertical = false;
 
 
-module BABYLON.GUI {
     /**
     /**
-     * Class used to create a stack panel in 3D on XY plane
+     * Gets or sets a boolean indicating if the stack panel is vertical or horizontal (horizontal by default)
      */
      */
-    export class StackPanel3D extends Container3D {
-        private _isVertical = false;
-
-        /**
-         * Gets or sets a boolean indicating if the stack panel is vertical or horizontal (horizontal by default)
-         */
-        public get isVertical(): boolean {
-            return this._isVertical;
+    public get isVertical(): boolean {
+        return this._isVertical;
+    }
+
+    public set isVertical(value: boolean) {
+        if (this._isVertical === value) {
+            return;
         }
         }
 
 
-        public set isVertical(value: boolean) {
-            if (this._isVertical === value) {
-                return;
-            }
+        this._isVertical = value;
 
 
-            this._isVertical = value;
+        Tools.SetImmediate(() => {
+            this._arrangeChildren();
+        });
+    }
 
 
-            Tools.SetImmediate(() => {
-                this._arrangeChildren();               
-            });
-        }
+    /**
+     * Gets or sets the distance between elements
+     */
+    public margin = 0.1;
 
 
-        /**
-         * Gets or sets the distance between elements
-         */
-        public margin = 0.1;
-        
-        /**
-         * Creates new StackPanel
-         * @param isVertical 
-         */
-        public constructor(isVertical = false) {
-            super();
-
-            this._isVertical = isVertical;
-        }
+    /**
+     * Creates new StackPanel
+     * @param isVertical 
+     */
+    public constructor(isVertical = false) {
+        super();
+
+        this._isVertical = isVertical;
+    }
 
 
-        protected _arrangeChildren() {
-            let width = 0;
-            let height = 0;
-            let controlCount = 0;
-            let extendSizes = [];
-
-            let currentInverseWorld = Matrix.Invert(this.node!.computeWorldMatrix(true));
-
-            // Measure
-            for (var child of this._children) {
-                if (!child.mesh) {
-                    continue;
-                }
-
-                controlCount++;
-                child.mesh.computeWorldMatrix(true);
-                child.mesh.getWorldMatrix().multiplyToRef(currentInverseWorld, Tmp.Matrix[0]);
-
-                let boundingBox = child.mesh.getBoundingInfo().boundingBox;
-                let extendSize = Vector3.TransformNormal(boundingBox.extendSize, Tmp.Matrix[0]);
-                extendSizes.push(extendSize);
-
-                if (this._isVertical) {
-                    height += extendSize.y;
-                } else {
-                    width += extendSize.x;
-                }
+    protected _arrangeChildren() {
+        let width = 0;
+        let height = 0;
+        let controlCount = 0;
+        let extendSizes = [];
+
+        let currentInverseWorld = Matrix.Invert(this.node!.computeWorldMatrix(true));
+
+        // Measure
+        for (var child of this._children) {
+            if (!child.mesh) {
+                continue;
             }
             }
 
 
+            controlCount++;
+            child.mesh.computeWorldMatrix(true);
+            child.mesh.getWorldMatrix().multiplyToRef(currentInverseWorld, Tmp.Matrix[0]);
+
+            let boundingBox = child.mesh.getBoundingInfo().boundingBox;
+            let extendSize = Vector3.TransformNormal(boundingBox.extendSize, Tmp.Matrix[0]);
+            extendSizes.push(extendSize);
+
             if (this._isVertical) {
             if (this._isVertical) {
-                height += (controlCount - 1) * this.margin / 2;
+                height += extendSize.y;
             } else {
             } else {
-                width += (controlCount - 1) * this.margin / 2;
+                width += extendSize.x;
+            }
+        }
+
+        if (this._isVertical) {
+            height += (controlCount - 1) * this.margin / 2;
+        } else {
+            width += (controlCount - 1) * this.margin / 2;
+        }
+
+        // Arrange
+        let offset: number;
+        if (this._isVertical) {
+            offset = -height;
+        } else {
+            offset = -width;
+        }
+
+        let index = 0;
+        for (var child of this._children) {
+            if (!child.mesh) {
+                continue;
             }
             }
+            controlCount--;
+            let extendSize = extendSizes[index++];
 
 
-            // Arrange
-            let offset: number;
             if (this._isVertical) {
             if (this._isVertical) {
-                offset = -height;
+                child.position.y = offset + extendSize.y;
+                child.position.x = 0;
+                offset += extendSize.y * 2;
             } else {
             } else {
-                offset = -width;
+                child.position.x = offset + extendSize.x;
+                child.position.y = 0;
+                offset += extendSize.x * 2;
             }
             }
 
 
-            let index = 0;
-            for (var child of this._children) {
-                if (!child.mesh) {
-                    continue;
-                }                
-                controlCount--;
-                let extendSize = extendSizes[index++];
-
-                if (this._isVertical) {
-                    child.position.y = offset + extendSize.y;
-                    child.position.x = 0;
-                    offset += extendSize.y * 2;
-                } else {
-                    child.position.x = offset + extendSize.x;
-                    child.position.y = 0;
-                    offset += extendSize.x * 2;
-                }
-
-                offset += (controlCount > 0 ? this.margin : 0)
-            }
+            offset += (controlCount > 0 ? this.margin : 0)
         }
         }
     }
     }
-}
+}

+ 155 - 161
gui/src/3D/controls/volumeBasedPanel.ts

@@ -1,197 +1,191 @@
-/// <reference path="../../../../dist/preview release/babylon.d.ts"/>
+import { Container3D } from "./container3D";
+import { Tools, int, Matrix, Tmp, Vector3 } from "babylonjs";
+import { Control3D } from "./control3D";
+
+/**
+ * Abstract class used to create a container panel deployed on the surface of a volume
+ */
+export abstract class VolumeBasedPanel extends Container3D {
+    private _columns = 10;
+    private _rows = 0;
+    private _rowThenColum = true;
+
+    private _orientation = Container3D.FACEORIGIN_ORIENTATION;
+
+    protected _cellWidth: number;
+    protected _cellHeight: number;
+
+    /**
+     * Gets or sets the distance between elements
+     */
+    public margin = 0;
 
 
-module BABYLON.GUI {
     /**
     /**
-     * Abstract class used to create a container panel deployed on the surface of a volume
+     * Gets or sets the orientation to apply to all controls (BABYLON.Container3D.FaceOriginReversedOrientation by default)
+    * | Value | Type                                | Description |
+    * | ----- | ----------------------------------- | ----------- |
+    * | 0     | UNSET_ORIENTATION                   |  Control rotation will remain unchanged |
+    * | 1     | FACEORIGIN_ORIENTATION              |  Control will rotate to make it look at sphere central axis |
+    * | 2     | FACEORIGINREVERSED_ORIENTATION      |  Control will rotate to make it look back at sphere central axis |
+    * | 3     | FACEFORWARD_ORIENTATION             |  Control will rotate to look at z axis (0, 0, 1) |
+    * | 4     | FACEFORWARDREVERSED_ORIENTATION     |  Control will rotate to look at negative z axis (0, 0, -1) |
      */
      */
-    export abstract class VolumeBasedPanel extends Container3D {
-        private _columns = 10;
-        private _rows = 0;
-        private _rowThenColum = true;
-        
-        private _orientation = Container3D.FACEORIGIN_ORIENTATION;
-
-        protected _cellWidth: number;
-        protected _cellHeight: number;
-
-        /**
-         * Gets or sets the distance between elements
-         */
-        public margin = 0;        
-
-        /**
-         * Gets or sets the orientation to apply to all controls (BABYLON.Container3D.FaceOriginReversedOrientation by default)
-        * | Value | Type                                | Description |
-        * | ----- | ----------------------------------- | ----------- |
-        * | 0     | UNSET_ORIENTATION                   |  Control rotation will remain unchanged |
-        * | 1     | FACEORIGIN_ORIENTATION              |  Control will rotate to make it look at sphere central axis |
-        * | 2     | FACEORIGINREVERSED_ORIENTATION      |  Control will rotate to make it look back at sphere central axis |
-        * | 3     | FACEFORWARD_ORIENTATION             |  Control will rotate to look at z axis (0, 0, 1) |
-        * | 4     | FACEFORWARDREVERSED_ORIENTATION     |  Control will rotate to look at negative z axis (0, 0, -1) |
-         */
-        public get orientation(): number {
-            return this._orientation;
+    public get orientation(): number {
+        return this._orientation;
+    }
+
+    public set orientation(value: number) {
+        if (this._orientation === value) {
+            return;
         }
         }
 
 
-        public set orientation(value: number) {
-            if (this._orientation === value) {
-                return;
-            }
+        this._orientation = value;
 
 
-            this._orientation = value;
+        Tools.SetImmediate(() => {
+            this._arrangeChildren();
+        });
+    }
 
 
-            Tools.SetImmediate(() => {
-                this._arrangeChildren();               
-            });
-        }             
+    /**
+     * Gets or sets the number of columns requested (10 by default). 
+     * The panel will automatically compute the number of rows based on number of child controls. 
+     */
+    public get columns(): int {
+        return this._columns;
+    }
 
 
-        /**
-         * Gets or sets the number of columns requested (10 by default). 
-         * The panel will automatically compute the number of rows based on number of child controls. 
-         */
-        public get columns(): int {
-            return this._columns;
+    public set columns(value: int) {
+        if (this._columns === value) {
+            return;
         }
         }
 
 
-        public set columns(value: int) {
-            if (this._columns === value) {
-                return;
-            }
+        this._columns = value;
+        this._rowThenColum = true;
 
 
-            this._columns = value;
-            this._rowThenColum = true;
-
-            Tools.SetImmediate(() => {
-                this._arrangeChildren();               
-            });
-        }     
-        
-        /**
-         * Gets or sets a the number of rows requested. 
-         * The panel will automatically compute the number of columns based on number of child controls. 
-         */
-        public get rows(): int {
-            return this._rows;
-        }
+        Tools.SetImmediate(() => {
+            this._arrangeChildren();
+        });
+    }
 
 
-        public set rows(value: int) {
-            if (this._rows === value) {
-                return;
-            }
+    /**
+     * Gets or sets a the number of rows requested. 
+     * The panel will automatically compute the number of columns based on number of child controls. 
+     */
+    public get rows(): int {
+        return this._rows;
+    }
 
 
-            this._rows = value;
-            this._rowThenColum = false;
-
-            Tools.SetImmediate(() => {
-                this._arrangeChildren();               
-            });
-        }           
-
-        /**
-         * Creates new VolumeBasedPanel
-         */
-        public constructor() {
-            super();
-        }        
-
-        protected _arrangeChildren() {
-            this._cellWidth = 0;
-            this._cellHeight = 0;
-            let rows = 0;
-            let columns = 0;
-            let controlCount = 0;
-
-            let currentInverseWorld = Matrix.Invert(this.node!.computeWorldMatrix(true));
-
-            // Measure
-            for (var child of this._children) {
-                if (!child.mesh) {
-                    continue;
-                }
+    public set rows(value: int) {
+        if (this._rows === value) {
+            return;
+        }
 
 
-                controlCount++;
-                child.mesh.computeWorldMatrix(true);
-             //   child.mesh.getWorldMatrix().multiplyToRef(currentInverseWorld, Tmp.Matrix[0]);
+        this._rows = value;
+        this._rowThenColum = false;
 
 
-                let boundingBox = child.mesh.getHierarchyBoundingVectors();
-                let extendSize = Tmp.Vector3[0];
-                let diff = Tmp.Vector3[1];
+        Tools.SetImmediate(() => {
+            this._arrangeChildren();
+        });
+    }
 
 
-                boundingBox.max.subtractToRef(boundingBox.min, diff);
+    /**
+     * Creates new VolumeBasedPanel
+     */
+    public constructor() {
+        super();
+    }
 
 
-                diff.scaleInPlace(0.5);
+    protected _arrangeChildren() {
+        this._cellWidth = 0;
+        this._cellHeight = 0;
+        let rows = 0;
+        let columns = 0;
+        let controlCount = 0;
 
 
-                Vector3.TransformNormalToRef(diff, currentInverseWorld, extendSize);
+        let currentInverseWorld = Matrix.Invert(this.node!.computeWorldMatrix(true));
 
 
-                this._cellWidth = Math.max(this._cellWidth, extendSize.x * 2);
-                this._cellHeight = Math.max(this._cellHeight, extendSize.y * 2);
+        // Measure
+        for (var child of this._children) {
+            if (!child.mesh) {
+                continue;
             }
             }
 
 
-            this._cellWidth += this.margin * 2;
-            this._cellHeight += this.margin * 2;
+            controlCount++;
+            child.mesh.computeWorldMatrix(true);
+            //   child.mesh.getWorldMatrix().multiplyToRef(currentInverseWorld, Tmp.Matrix[0]);
 
 
-            // Arrange
-            if (this._rowThenColum) {
-                columns = this._columns;
-                rows = Math.ceil(controlCount / this._columns);
-            } else {
-                rows = this._rows;
-                columns = Math.ceil(controlCount / this._rows);
-            }
+            let boundingBox = child.mesh.getHierarchyBoundingVectors();
+            let extendSize = Tmp.Vector3[0];
+            let diff = Tmp.Vector3[1];
+
+            boundingBox.max.subtractToRef(boundingBox.min, diff);
+
+            diff.scaleInPlace(0.5);
+
+            Vector3.TransformNormalToRef(diff, currentInverseWorld, extendSize);
+
+            this._cellWidth = Math.max(this._cellWidth, extendSize.x * 2);
+            this._cellHeight = Math.max(this._cellHeight, extendSize.y * 2);
+        }
+
+        this._cellWidth += this.margin * 2;
+        this._cellHeight += this.margin * 2;
 
 
-            let startOffsetX = (columns * 0.5) * this._cellWidth;
-            let startOffsetY = (rows * 0.5) * this._cellHeight;
-            let nodeGrid = [];
-            let cellCounter = 0;
-
-            if (this._rowThenColum) {
-                for (var r = 0; r < rows; r++)
-                {
-                    for (var c = 0; c < columns; c++)
-                    {
-                        nodeGrid.push(new Vector3((c * this._cellWidth) - startOffsetX + this._cellWidth / 2, (r * this._cellHeight) - startOffsetY + this._cellHeight / 2, 0));
-                        cellCounter++;
-                        if (cellCounter > controlCount)
-                        {
-                            break;
-                        }
+        // Arrange
+        if (this._rowThenColum) {
+            columns = this._columns;
+            rows = Math.ceil(controlCount / this._columns);
+        } else {
+            rows = this._rows;
+            columns = Math.ceil(controlCount / this._rows);
+        }
+
+        let startOffsetX = (columns * 0.5) * this._cellWidth;
+        let startOffsetY = (rows * 0.5) * this._cellHeight;
+        let nodeGrid = [];
+        let cellCounter = 0;
+
+        if (this._rowThenColum) {
+            for (var r = 0; r < rows; r++) {
+                for (var c = 0; c < columns; c++) {
+                    nodeGrid.push(new Vector3((c * this._cellWidth) - startOffsetX + this._cellWidth / 2, (r * this._cellHeight) - startOffsetY + this._cellHeight / 2, 0));
+                    cellCounter++;
+                    if (cellCounter > controlCount) {
+                        break;
                     }
                     }
                 }
                 }
-            } else {
-                for (var c = 0; c < columns; c++)
-                {
-                    for (var r = 0; r < rows; r++)
-                    {
-                        nodeGrid.push(new Vector3((c * this._cellWidth) - startOffsetX + this._cellWidth / 2, (r * this._cellHeight) - startOffsetY + this._cellHeight / 2, 0));
-                        cellCounter++;
-                        if (cellCounter > controlCount)
-                        {
-                            break;
-                        }
+            }
+        } else {
+            for (var c = 0; c < columns; c++) {
+                for (var r = 0; r < rows; r++) {
+                    nodeGrid.push(new Vector3((c * this._cellWidth) - startOffsetX + this._cellWidth / 2, (r * this._cellHeight) - startOffsetY + this._cellHeight / 2, 0));
+                    cellCounter++;
+                    if (cellCounter > controlCount) {
+                        break;
                     }
                     }
                 }
                 }
             }
             }
+        }
 
 
-            cellCounter = 0;
-            for (var child of this._children) {
-                if (!child.mesh) {
-                    continue;
-                }                
-
-                this._mapGridNode(child, nodeGrid[cellCounter]);
-
-                cellCounter++;
+        cellCounter = 0;
+        for (var child of this._children) {
+            if (!child.mesh) {
+                continue;
             }
             }
 
 
-            this._finalProcessing();
+            this._mapGridNode(child, nodeGrid[cellCounter]);
+
+            cellCounter++;
         }
         }
 
 
-        /** Child classes must implement this function to provide correct control positioning */
-        protected abstract _mapGridNode(control: Control3D, nodePosition: Vector3): void;
+        this._finalProcessing();
+    }
 
 
-        /** Child classes can implement this function to provide additional processing */
-        protected _finalProcessing() {
+    /** Child classes must implement this function to provide correct control positioning */
+    protected abstract _mapGridNode(control: Control3D, nodePosition: Vector3): void;
+
+    /** Child classes can implement this function to provide additional processing */
+    protected _finalProcessing() {
 
 
-        }
     }
     }
-}
+}

+ 180 - 181
gui/src/3D/gui3DManager.ts

@@ -1,222 +1,221 @@
-/// <reference path="../../../dist/preview release/babylon.d.ts"/>
+import { IDisposable, Scene, Nullable, Observer, UtilityLayerRenderer, PointerInfo, Observable, Vector3, Material, AbstractMesh, Engine, HemisphericLight, PointerEventTypes } from "babylonjs";
+import { Container3D } from "./controls/container3D";
+import { Control3D } from "./controls/control3D";
+
+/**
+ * Class used to manage 3D user interface
+ * @see http://doc.babylonjs.com/how_to/gui3d
+ */
+export class GUI3DManager implements IDisposable {
+    private _scene: Scene;
+    private _sceneDisposeObserver: Nullable<Observer<Scene>>;
+    private _utilityLayer: Nullable<UtilityLayerRenderer>;
+    private _rootContainer: Container3D;
+    private _pointerObserver: Nullable<Observer<PointerInfo>>;
+    private _pointerOutObserver: Nullable<Observer<number>>;
+    /** @hidden */
+    public _lastPickedControl: Control3D;
+    /** @hidden */
+    public _lastControlOver: { [pointerId: number]: Control3D } = {};
+    /** @hidden */
+    public _lastControlDown: { [pointerId: number]: Control3D } = {};
 
 
+    /**
+     * Observable raised when the point picked by the pointer events changed
+     */
+    public onPickedPointChangedObservable = new Observable<Nullable<Vector3>>();
+
+    // Shared resources
+    /** @hidden */
+    public _sharedMaterials: { [key: string]: Material } = {};
+
+    /** Gets the hosting scene */
+    public get scene(): Scene {
+        return this._scene;
+    }
+
+    /** Gets associated utility layer */
+    public get utilityLayer(): Nullable<UtilityLayerRenderer> {
+        return this._utilityLayer;
+    }
 
 
-module BABYLON.GUI {
     /**
     /**
-     * Class used to manage 3D user interface
-     * @see http://doc.babylonjs.com/how_to/gui3d
+     * Creates a new GUI3DManager
+     * @param scene 
      */
      */
-    export class GUI3DManager implements BABYLON.IDisposable {
-        private _scene: Scene;
-        private _sceneDisposeObserver: Nullable<Observer<Scene>>;
-        private _utilityLayer: Nullable<UtilityLayerRenderer>;
-        private _rootContainer: Container3D;
-        private _pointerObserver: Nullable<Observer<PointerInfo>>;
-        private _pointerOutObserver: Nullable<Observer<number>>;
-        /** @hidden */
-        public _lastPickedControl: Control3D;
-        /** @hidden */
-        public _lastControlOver: {[pointerId:number]: Control3D} = {};
-        /** @hidden */
-        public _lastControlDown: {[pointerId:number]: Control3D} = {};      
-
-        /**
-         * Observable raised when the point picked by the pointer events changed
-         */
-        public onPickedPointChangedObservable = new Observable<Nullable<Vector3>>();
-
-        // Shared resources
-        /** @hidden */
-        public _sharedMaterials: {[key:string]: Material} = {};     
-
-        /** Gets the hosting scene */
-        public get scene(): Scene {
-            return this._scene;
+    public constructor(scene?: Scene) {
+        this._scene = scene || Engine.LastCreatedScene!;
+        this._sceneDisposeObserver = this._scene.onDisposeObservable.add(() => {
+            this._sceneDisposeObserver = null;
+            this._utilityLayer = null;
+            this.dispose();
+        })
+
+        this._utilityLayer = new UtilityLayerRenderer(this._scene);
+        this._utilityLayer.onlyCheckPointerDownEvents = false;
+        this._utilityLayer.mainSceneTrackerPredicate = (mesh: Nullable<AbstractMesh>) => {
+            return mesh && mesh.metadata && mesh.metadata._node;
         }
         }
 
 
-        /** Gets associated utility layer */
-        public get utilityLayer(): Nullable<UtilityLayerRenderer> {
-            return this._utilityLayer;
-        }
+        // Root
+        this._rootContainer = new Container3D("RootContainer");
+        this._rootContainer._host = this;
+        let utilityLayerScene = this._utilityLayer.utilityLayerScene;
 
 
-        /**
-         * Creates a new GUI3DManager
-         * @param scene 
-         */
-        public constructor(scene?: Scene) {
-            this._scene = scene || Engine.LastCreatedScene!;
-            this._sceneDisposeObserver = this._scene.onDisposeObservable.add(() => {
-                this._sceneDisposeObserver = null;
-                this._utilityLayer = null;
-                this.dispose();
-            })
-
-            this._utilityLayer = new UtilityLayerRenderer(this._scene);
-            this._utilityLayer.onlyCheckPointerDownEvents = false;
-            this._utilityLayer.mainSceneTrackerPredicate = (mesh: Nullable<AbstractMesh>) => {
-                return mesh && mesh.metadata && mesh.metadata._node;
-            }
+        // Events
+        this._pointerOutObserver = this._utilityLayer.onPointerOutObservable.add((pointerId) => {
+            this._handlePointerOut(pointerId, true);
+        });
 
 
-            // Root
-            this._rootContainer = new Container3D("RootContainer");
-            this._rootContainer._host = this;
-            let utilityLayerScene = this._utilityLayer.utilityLayerScene;
-            
-            // Events
-            this._pointerOutObserver = this._utilityLayer.onPointerOutObservable.add((pointerId) => {
-                this._handlePointerOut(pointerId, true);
-            });
-
-            this._pointerObserver = utilityLayerScene.onPointerObservable.add((pi, state) => {
-                this._doPicking(pi);
-            });
-
-            // Scene
-            this._utilityLayer.utilityLayerScene.autoClear = false;
-            this._utilityLayer.utilityLayerScene.autoClearDepthAndStencil = false;
-            new BABYLON.HemisphericLight("hemi", Vector3.Up(), this._utilityLayer.utilityLayerScene);
-        }
+        this._pointerObserver = utilityLayerScene.onPointerObservable.add((pi, state) => {
+            this._doPicking(pi);
+        });
 
 
-        private _handlePointerOut(pointerId: number, isPointerUp: boolean) {
-            var previousControlOver = this._lastControlOver[pointerId];
-            if (previousControlOver) {
-                previousControlOver._onPointerOut(previousControlOver);
-                delete this._lastControlOver[pointerId];
-            }               
-            
-            if (isPointerUp) {
-                if (this._lastControlDown[pointerId]) {
-                    this._lastControlDown[pointerId].forcePointerUp();
-                    delete this._lastControlDown[pointerId];
-                }
-            }        
-            
-            this.onPickedPointChangedObservable.notifyObservers(null);
+        // Scene
+        this._utilityLayer.utilityLayerScene.autoClear = false;
+        this._utilityLayer.utilityLayerScene.autoClearDepthAndStencil = false;
+        new HemisphericLight("hemi", Vector3.Up(), this._utilityLayer.utilityLayerScene);
+    }
+
+    private _handlePointerOut(pointerId: number, isPointerUp: boolean) {
+        var previousControlOver = this._lastControlOver[pointerId];
+        if (previousControlOver) {
+            previousControlOver._onPointerOut(previousControlOver);
+            delete this._lastControlOver[pointerId];
         }
         }
 
 
-        private _doPicking(pi: PointerInfo): boolean {
-            if (!this._utilityLayer || !this._utilityLayer.utilityLayerScene.activeCamera) {
-                return false;                
+        if (isPointerUp) {
+            if (this._lastControlDown[pointerId]) {
+                this._lastControlDown[pointerId].forcePointerUp();
+                delete this._lastControlDown[pointerId];
             }
             }
+        }
 
 
-            let pointerEvent = <PointerEvent>(pi.event);
+        this.onPickedPointChangedObservable.notifyObservers(null);
+    }
 
 
-            let pointerId = pointerEvent.pointerId || 0;
-            let buttonIndex = pointerEvent.button;
-            
-            let pickingInfo = pi.pickInfo;
-            if (!pickingInfo || !pickingInfo.hit) {
-                this._handlePointerOut(pointerId, pi.type === BABYLON.PointerEventTypes.POINTERUP);
-                return false;
-            }
+    private _doPicking(pi: PointerInfo): boolean {
+        if (!this._utilityLayer || !this._utilityLayer.utilityLayerScene.activeCamera) {
+            return false;
+        }
 
 
-            let control = <Control3D>(pickingInfo.pickedMesh!.metadata);
-            if (pickingInfo.pickedPoint) {
-                this.onPickedPointChangedObservable.notifyObservers(pickingInfo.pickedPoint);
-            }
+        let pointerEvent = <PointerEvent>(pi.event);
 
 
-            if (!control._processObservables(pi.type, pickingInfo.pickedPoint!, pointerId, buttonIndex)) {
+        let pointerId = pointerEvent.pointerId || 0;
+        let buttonIndex = pointerEvent.button;
 
 
-                if (pi.type === BABYLON.PointerEventTypes.POINTERMOVE) {
-                    if (this._lastControlOver[pointerId]) {
-                        this._lastControlOver[pointerId]._onPointerOut(this._lastControlOver[pointerId]);
-                    }
+        let pickingInfo = pi.pickInfo;
+        if (!pickingInfo || !pickingInfo.hit) {
+            this._handlePointerOut(pointerId, pi.type === PointerEventTypes.POINTERUP);
+            return false;
+        }
 
 
-                    delete this._lastControlOver[pointerId];
-                }
-            }
+        let control = <Control3D>(pickingInfo.pickedMesh!.metadata);
+        if (pickingInfo.pickedPoint) {
+            this.onPickedPointChangedObservable.notifyObservers(pickingInfo.pickedPoint);
+        }
 
 
-            if (pi.type === BABYLON.PointerEventTypes.POINTERUP) {
-                if (this._lastControlDown[pointerEvent.pointerId]) {
-                    this._lastControlDown[pointerEvent.pointerId].forcePointerUp();
-                    delete this._lastControlDown[pointerEvent.pointerId];
-                }
+        if (!control._processObservables(pi.type, pickingInfo.pickedPoint!, pointerId, buttonIndex)) {
 
 
-                if (pointerEvent.pointerType === "touch") {
-                    this._handlePointerOut(pointerId, false);
+            if (pi.type === PointerEventTypes.POINTERMOVE) {
+                if (this._lastControlOver[pointerId]) {
+                    this._lastControlOver[pointerId]._onPointerOut(this._lastControlOver[pointerId]);
                 }
                 }
-            }
 
 
-            return true;
+                delete this._lastControlOver[pointerId];
+            }
         }
         }
 
 
-        /**
-         * Gets the root container
-         */
-        public get rootContainer(): Container3D {
-            return this._rootContainer;
-        }
+        if (pi.type === PointerEventTypes.POINTERUP) {
+            if (this._lastControlDown[pointerEvent.pointerId]) {
+                this._lastControlDown[pointerEvent.pointerId].forcePointerUp();
+                delete this._lastControlDown[pointerEvent.pointerId];
+            }
 
 
-        /**
-         * Gets a boolean indicating if the given control is in the root child list
-         * @param control defines the control to check
-         * @returns true if the control is in the root child list
-         */
-        public containsControl(control: Control3D): boolean {
-            return this._rootContainer.containsControl(control);
+            if (pointerEvent.pointerType === "touch") {
+                this._handlePointerOut(pointerId, false);
+            }
         }
         }
 
 
-        /**
-         * Adds a control to the root child list
-         * @param control defines the control to add
-         * @returns the current manager
-         */
-        public addControl(control: Control3D): GUI3DManager {
-           this._rootContainer.addControl(control);
-           return this;
-        }
+        return true;
+    }
 
 
-        /**
-         * Removes a control from the root child list
-         * @param control defines the control to remove
-         * @returns the current container
-         */
-        public removeControl(control: Control3D): GUI3DManager {
-            this._rootContainer.removeControl(control);
-            return this;
-        }        
-
-        /**
-         * Releases all associated resources
-         */
-        public dispose() {
-            this._rootContainer.dispose();
-
-            for (var materialName in this._sharedMaterials) {
-                if (!this._sharedMaterials.hasOwnProperty(materialName)) {
-                    continue;
-                }
+    /**
+     * Gets the root container
+     */
+    public get rootContainer(): Container3D {
+        return this._rootContainer;
+    }
 
 
-                this._sharedMaterials[materialName].dispose();
-            }
+    /**
+     * Gets a boolean indicating if the given control is in the root child list
+     * @param control defines the control to check
+     * @returns true if the control is in the root child list
+     */
+    public containsControl(control: Control3D): boolean {
+        return this._rootContainer.containsControl(control);
+    }
+
+    /**
+     * Adds a control to the root child list
+     * @param control defines the control to add
+     * @returns the current manager
+     */
+    public addControl(control: Control3D): GUI3DManager {
+        this._rootContainer.addControl(control);
+        return this;
+    }
+
+    /**
+     * Removes a control from the root child list
+     * @param control defines the control to remove
+     * @returns the current container
+     */
+    public removeControl(control: Control3D): GUI3DManager {
+        this._rootContainer.removeControl(control);
+        return this;
+    }
 
 
-            this._sharedMaterials = {};
+    /**
+     * Releases all associated resources
+     */
+    public dispose() {
+        this._rootContainer.dispose();
 
 
-            if (this._pointerOutObserver && this._utilityLayer) {
-                this._utilityLayer.onPointerOutObservable.remove(this._pointerOutObserver);
-                this._pointerOutObserver = null;
+        for (var materialName in this._sharedMaterials) {
+            if (!this._sharedMaterials.hasOwnProperty(materialName)) {
+                continue;
             }
             }
 
 
-            this.onPickedPointChangedObservable.clear();
+            this._sharedMaterials[materialName].dispose();
+        }
 
 
-            let utilityLayerScene = this._utilityLayer ? this._utilityLayer.utilityLayerScene : null;
+        this._sharedMaterials = {};
 
 
-            if (utilityLayerScene) {
-                if (this._pointerObserver) {
-                    utilityLayerScene.onPointerObservable.remove(this._pointerObserver);
-                    this._pointerObserver = null;
-                }
+        if (this._pointerOutObserver && this._utilityLayer) {
+            this._utilityLayer.onPointerOutObservable.remove(this._pointerOutObserver);
+            this._pointerOutObserver = null;
+        }
+
+        this.onPickedPointChangedObservable.clear();
+
+        let utilityLayerScene = this._utilityLayer ? this._utilityLayer.utilityLayerScene : null;
+
+        if (utilityLayerScene) {
+            if (this._pointerObserver) {
+                utilityLayerScene.onPointerObservable.remove(this._pointerObserver);
+                this._pointerObserver = null;
             }
             }
-            if (this._scene) {
-                 if (this._sceneDisposeObserver) {
-                    this._scene.onDisposeObservable.remove(this._sceneDisposeObserver);
-                    this._sceneDisposeObserver = null;
-                }                
+        }
+        if (this._scene) {
+            if (this._sceneDisposeObserver) {
+                this._scene.onDisposeObservable.remove(this._sceneDisposeObserver);
+                this._sceneDisposeObserver = null;
             }
             }
+        }
 
 
-            if (this._utilityLayer) {
-                this._utilityLayer.dispose();
-            }
+        if (this._utilityLayer) {
+            this._utilityLayer.dispose();
         }
         }
     }
     }
 }
 }

+ 5 - 0
gui/src/3D/index.ts

@@ -0,0 +1,5 @@
+export * from "./controls";
+export * from "./materials";
+
+export * from "./gui3DManager";
+export * from "./vector3WithInfo";

+ 237 - 235
gui/src/3D/materials/fluentMaterial.ts

@@ -1,279 +1,281 @@
-/// <reference path="../../../../dist/preview release/babylon.d.ts"/>
-
-module BABYLON.GUI {
-
-    /** @hidden */
-    export class FluentMaterialDefines extends MaterialDefines {
-        public INNERGLOW = false;
-        public BORDER = false;
-        public HOVERLIGHT = false;
-    
-        constructor() {
-            super();
-            this.rebuild();
-        }
+import { MaterialDefines, PushMaterial, serialize, expandToProperty, serializeAsColor3, Color3, serializeAsColor4, Color4, serializeAsVector3, Vector3, Scene, Nullable, BaseTexture, AbstractMesh, SubMesh, VertexBuffer, MaterialHelper, EffectCreationOptions, Matrix, Mesh, Tmp, SerializationHelper } from "babylonjs";
+
+import { registerShader } from "./shaders/fluent";
+
+// register shaders
+registerShader();
+
+/** @hidden */
+export class FluentMaterialDefines extends MaterialDefines {
+    public INNERGLOW = false;
+    public BORDER = false;
+    public HOVERLIGHT = false;
+
+    constructor() {
+        super();
+        this.rebuild();
     }
     }
+}
+
+/**
+ * Class used to render controls with fluent desgin
+ */
+export class FluentMaterial extends PushMaterial {
 
 
     /**
     /**
-     * Class used to render controls with fluent desgin
+     * Gets or sets inner glow intensity. A value of 0 means no glow (default is 0.5)
      */
      */
-    export class FluentMaterial extends PushMaterial {    
-
-        /**
-         * Gets or sets inner glow intensity. A value of 0 means no glow (default is 0.5)
-         */
-        @serialize()
-        @expandToProperty("_markAllSubMeshesAsTexturesDirty")
-        public innerGlowColorIntensity = 0.5;
-
-        /**
-         * Gets or sets the inner glow color (white by default)
-         */
-        @serializeAsColor3()
-        public innerGlowColor = new Color3(1.0, 1.0, 1.0);
-
-        /**
-         * Gets or sets alpha value (default is 1.0)
-         */
-        @serialize()
-        public alpha = 1.0;        
-
-        /**
-         * Gets or sets the albedo color (Default is Color3(0.3, 0.35, 0.4))
-         */
-        @serializeAsColor3()
-        public albedoColor = new Color3(0.3, 0.35, 0.4);
-
-        /**
-         * Gets or sets a boolean indicating if borders must be rendered (default is false)
-         */
-        @serialize()
-        @expandToProperty("_markAllSubMeshesAsTexturesDirty")
-        public renderBorders = false;        
-
-        /**
-         * Gets or sets border width (default is 0.5)
-         */
-        @serialize()
-        public borderWidth = 0.5;      
-        
-        /**
-         * Gets or sets a value indicating the smoothing value applied to border edges (0.02 by default)
-         */
-        @serialize()
-        public edgeSmoothingValue = 0.02;
-        
-        /**
-         * Gets or sets the minimum value that can be applied to border width (default is 0.1)
-         */
-        @serialize()
-        public borderMinValue = 0.1;      
-        
-        /**
-         * Gets or sets a boolean indicating if hover light must be rendered (default is false)
-         */
-        @serialize()
-        @expandToProperty("_markAllSubMeshesAsTexturesDirty")
-        public renderHoverLight = false;         
-        
-        /**
-         * Gets or sets the radius used to render the hover light (default is 0.15)
-         */
-        @serialize()
-        public hoverRadius = 1.0;            
-        
-        /**
-         * Gets or sets the color used to render the hover light (default is Color4(0.3, 0.3, 0.3, 1.0))
-         */
-        @serializeAsColor4()
-        public hoverColor = new Color4(0.3, 0.3, 0.3, 1.0);           
-        
-        /**
-         * Gets or sets the hover light position in world space (default is Vector3.Zero())
-         */
-        @serializeAsVector3()
-        public hoverPosition = Vector3.Zero();             
-        
-        /**
-         * Creates a new Fluent material
-         * @param name defines the name of the material
-         * @param scene defines the hosting scene
-         */
-        constructor(name: string, scene: Scene) {
-            super(name, scene);
-        }
+    @serialize()
+    @expandToProperty("_markAllSubMeshesAsTexturesDirty")
+    public innerGlowColorIntensity = 0.5;
 
 
-        public needAlphaBlending(): boolean {
-            return this.alpha !== 1.0;
-        }
+    /**
+     * Gets or sets the inner glow color (white by default)
+     */
+    @serializeAsColor3()
+    public innerGlowColor = new Color3(1.0, 1.0, 1.0);
 
 
-        public needAlphaTesting(): boolean {
-            return false;
-        }
+    /**
+     * Gets or sets alpha value (default is 1.0)
+     */
+    @serialize()
+    public alpha = 1.0;
 
 
-        public getAlphaTestTexture(): Nullable<BaseTexture> {
-            return null;
-        } 
-        
-        public isReadyForSubMesh(mesh: AbstractMesh, subMesh: SubMesh, useInstances?: boolean): boolean {
-            if (this.isFrozen) {
-                if (this._wasPreviouslyReady && subMesh.effect) {
-                    return true;
-                }
-            }
+    /**
+     * Gets or sets the albedo color (Default is Color3(0.3, 0.35, 0.4))
+     */
+    @serializeAsColor3()
+    public albedoColor = new Color3(0.3, 0.35, 0.4);
 
 
-            if (!subMesh._materialDefines) {
-                subMesh._materialDefines = new FluentMaterialDefines();
-            }
+    /**
+     * Gets or sets a boolean indicating if borders must be rendered (default is false)
+     */
+    @serialize()
+    @expandToProperty("_markAllSubMeshesAsTexturesDirty")
+    public renderBorders = false;
 
 
-            var scene = this.getScene();
-            var defines = <FluentMaterialDefines>subMesh._materialDefines;
-            if (!this.checkReadyOnEveryCall && subMesh.effect) {
-                if (defines._renderId === scene.getRenderId()) {
-                    return true;
-                }
-            }            
-
-            if (defines._areTexturesDirty) {
-                defines.INNERGLOW = this.innerGlowColorIntensity > 0;
-                defines.BORDER = this.renderBorders;
-                defines.HOVERLIGHT = this.renderHoverLight;
-            }
+    /**
+     * Gets or sets border width (default is 0.5)
+     */
+    @serialize()
+    public borderWidth = 0.5;
 
 
-            var engine = scene.getEngine();
-            // Get correct effect      
-            if (defines.isDirty) {
-                defines.markAsProcessed();
-                scene.resetCachedMaterial();
+    /**
+     * Gets or sets a value indicating the smoothing value applied to border edges (0.02 by default)
+     */
+    @serialize()
+    public edgeSmoothingValue = 0.02;
 
 
-                //Attributes
-                var attribs = [VertexBuffer.PositionKind];
-                attribs.push(VertexBuffer.NormalKind);
-                attribs.push(VertexBuffer.UVKind);
+    /**
+     * Gets or sets the minimum value that can be applied to border width (default is 0.1)
+     */
+    @serialize()
+    public borderMinValue = 0.1;
 
 
-                var shaderName = "fluent";
+    /**
+     * Gets or sets a boolean indicating if hover light must be rendered (default is false)
+     */
+    @serialize()
+    @expandToProperty("_markAllSubMeshesAsTexturesDirty")
+    public renderHoverLight = false;
 
 
-                var uniforms = ["world", "viewProjection", "innerGlowColor", "albedoColor", "borderWidth", "edgeSmoothingValue", "scaleFactor", "borderMinValue",
-                                "hoverColor", "hoverPosition", "hoverRadius"
-                ];
+    /**
+     * Gets or sets the radius used to render the hover light (default is 0.15)
+     */
+    @serialize()
+    public hoverRadius = 1.0;
 
 
-                var samplers = new Array<String>();
-                var uniformBuffers = new Array<string>();
+    /**
+     * Gets or sets the color used to render the hover light (default is Color4(0.3, 0.3, 0.3, 1.0))
+     */
+    @serializeAsColor4()
+    public hoverColor = new Color4(0.3, 0.3, 0.3, 1.0);
 
 
-                MaterialHelper.PrepareUniformsAndSamplersList(<EffectCreationOptions>{
-                    uniformsNames: uniforms,
-                    uniformBuffersNames: uniformBuffers,
-                    samplers: samplers,
-                    defines: defines,
-                    maxSimultaneousLights: 4
-                });            
-
-                var join = defines.toString();
-                subMesh.setEffect(scene.getEngine().createEffect(shaderName,
-                    <EffectCreationOptions>{
-                        attributes: attribs,
-                        uniformsNames: uniforms,
-                        uniformBuffersNames: uniformBuffers,
-                        samplers: samplers,
-                        defines: join,
-                        fallbacks: null,
-                        onCompiled: this.onCompiled,
-                        onError: this.onError,
-                        indexParameters: { maxSimultaneousLights: 4 }
-                    }, engine));            
-                
-            }
+    /**
+     * Gets or sets the hover light position in world space (default is Vector3.Zero())
+     */
+    @serializeAsVector3()
+    public hoverPosition = Vector3.Zero();
+
+    /**
+     * Creates a new Fluent material
+     * @param name defines the name of the material
+     * @param scene defines the hosting scene
+     */
+    constructor(name: string, scene: Scene) {
+        super(name, scene);
+    }
+
+    public needAlphaBlending(): boolean {
+        return this.alpha !== 1.0;
+    }
 
 
-            if (!subMesh.effect || !subMesh.effect.isReady()) {
-                return false;
+    public needAlphaTesting(): boolean {
+        return false;
+    }
+
+    public getAlphaTestTexture(): Nullable<BaseTexture> {
+        return null;
+    }
+
+    public isReadyForSubMesh(mesh: AbstractMesh, subMesh: SubMesh, useInstances?: boolean): boolean {
+        if (this.isFrozen) {
+            if (this._wasPreviouslyReady && subMesh.effect) {
+                return true;
             }
             }
+        }
 
 
-            defines._renderId = scene.getRenderId();
-            this._wasPreviouslyReady = true;
+        if (!subMesh._materialDefines) {
+            subMesh._materialDefines = new FluentMaterialDefines();
+        }
 
 
-            return true;
+        var scene = this.getScene();
+        var defines = <FluentMaterialDefines>subMesh._materialDefines;
+        if (!this.checkReadyOnEveryCall && subMesh.effect) {
+            if (defines._renderId === scene.getRenderId()) {
+                return true;
+            }
         }
         }
 
 
-        public bindForSubMesh(world: Matrix, mesh: Mesh, subMesh: SubMesh): void {
-            var scene = this.getScene();
+        if (defines._areTexturesDirty) {
+            defines.INNERGLOW = this.innerGlowColorIntensity > 0;
+            defines.BORDER = this.renderBorders;
+            defines.HOVERLIGHT = this.renderHoverLight;
+        }
 
 
-            var defines = <FluentMaterialDefines>subMesh._materialDefines;
-            if (!defines) {
-                return;
-            }            
+        var engine = scene.getEngine();
+        // Get correct effect      
+        if (defines.isDirty) {
+            defines.markAsProcessed();
+            scene.resetCachedMaterial();
+
+            //Attributes
+            var attribs = [VertexBuffer.PositionKind];
+            attribs.push(VertexBuffer.NormalKind);
+            attribs.push(VertexBuffer.UVKind);
+
+            var shaderName = "fluent";
+
+            var uniforms = ["world", "viewProjection", "innerGlowColor", "albedoColor", "borderWidth", "edgeSmoothingValue", "scaleFactor", "borderMinValue",
+                "hoverColor", "hoverPosition", "hoverRadius"
+            ];
+
+            var samplers = new Array<String>();
+            var uniformBuffers = new Array<string>();
+
+            MaterialHelper.PrepareUniformsAndSamplersList(<EffectCreationOptions>{
+                uniformsNames: uniforms,
+                uniformBuffersNames: uniformBuffers,
+                samplers: samplers,
+                defines: defines,
+                maxSimultaneousLights: 4
+            });
+
+            var join = defines.toString();
+            subMesh.setEffect(scene.getEngine().createEffect(shaderName,
+                <EffectCreationOptions>{
+                    attributes: attribs,
+                    uniformsNames: uniforms,
+                    uniformBuffersNames: uniformBuffers,
+                    samplers: samplers,
+                    defines: join,
+                    fallbacks: null,
+                    onCompiled: this.onCompiled,
+                    onError: this.onError,
+                    indexParameters: { maxSimultaneousLights: 4 }
+                }, engine));
 
 
-            var effect = subMesh.effect;
-            if (!effect) {
-                return;
-            }
-            this._activeEffect = effect;
+        }
 
 
-            // Matrices        
-            this.bindOnlyWorldMatrix(world);
-            this._activeEffect.setMatrix("viewProjection", scene.getTransformMatrix());
+        if (!subMesh.effect || !subMesh.effect.isReady()) {
+            return false;
+        }
 
 
+        defines._renderId = scene.getRenderId();
+        this._wasPreviouslyReady = true;
 
 
-            if (this._mustRebind(scene, effect)) {   
-                this._activeEffect.setColor4("albedoColor", this.albedoColor, this.alpha);
+        return true;
+    }
 
 
-                if (defines.INNERGLOW) {
-                    this._activeEffect.setColor4("innerGlowColor", this.innerGlowColor, this.innerGlowColorIntensity);
-                }
+    public bindForSubMesh(world: Matrix, mesh: Mesh, subMesh: SubMesh): void {
+        var scene = this.getScene();
 
 
-                if (defines.BORDER) {
-                    this._activeEffect.setFloat("borderWidth", this.borderWidth);
-                    this._activeEffect.setFloat("edgeSmoothingValue", this.edgeSmoothingValue);
-                    this._activeEffect.setFloat("borderMinValue", this.borderMinValue);
+        var defines = <FluentMaterialDefines>subMesh._materialDefines;
+        if (!defines) {
+            return;
+        }
 
 
-                    mesh.getBoundingInfo().boundingBox.extendSize.multiplyToRef(mesh.scaling, Tmp.Vector3[0]);
-                    this._activeEffect.setVector3("scaleFactor", Tmp.Vector3[0]);
-                }
+        var effect = subMesh.effect;
+        if (!effect) {
+            return;
+        }
+        this._activeEffect = effect;
 
 
-                if (defines.HOVERLIGHT) {
-                    this._activeEffect.setDirectColor4("hoverColor", this.hoverColor);
-                    this._activeEffect.setFloat("hoverRadius", this.hoverRadius);
-                    this._activeEffect.setVector3("hoverPosition", this.hoverPosition);
-                }
-            }
+        // Matrices        
+        this.bindOnlyWorldMatrix(world);
+        this._activeEffect.setMatrix("viewProjection", scene.getTransformMatrix());
 
 
-            this._afterBind(mesh, this._activeEffect);
-        }    
 
 
-        public getActiveTextures(): BaseTexture[] {
-            var activeTextures = super.getActiveTextures();
+        if (this._mustRebind(scene, effect)) {
+            this._activeEffect.setColor4("albedoColor", this.albedoColor, this.alpha);
 
 
-            return activeTextures;
-        }        
+            if (defines.INNERGLOW) {
+                this._activeEffect.setColor4("innerGlowColor", this.innerGlowColor, this.innerGlowColorIntensity);
+            }
 
 
-        public hasTexture(texture: BaseTexture): boolean {
-            if (super.hasTexture(texture)) {
-                return true;
+            if (defines.BORDER) {
+                this._activeEffect.setFloat("borderWidth", this.borderWidth);
+                this._activeEffect.setFloat("edgeSmoothingValue", this.edgeSmoothingValue);
+                this._activeEffect.setFloat("borderMinValue", this.borderMinValue);
+
+                mesh.getBoundingInfo().boundingBox.extendSize.multiplyToRef(mesh.scaling, Tmp.Vector3[0]);
+                this._activeEffect.setVector3("scaleFactor", Tmp.Vector3[0]);
             }
             }
 
 
-            return false;
-        }        
-        
-        public dispose(forceDisposeEffect?: boolean): void {
-            super.dispose(forceDisposeEffect);
+            if (defines.HOVERLIGHT) {
+                this._activeEffect.setDirectColor4("hoverColor", this.hoverColor);
+                this._activeEffect.setFloat("hoverRadius", this.hoverRadius);
+                this._activeEffect.setVector3("hoverPosition", this.hoverPosition);
+            }
         }
         }
 
 
-        public clone(name: string): FluentMaterial {
-            return SerializationHelper.Clone(() => new FluentMaterial(name, this.getScene()), this);
-        }
+        this._afterBind(mesh, this._activeEffect);
+    }
 
 
-        public serialize(): any {
-            var serializationObject = SerializationHelper.Serialize(this);
-            serializationObject.customType = "BABYLON.GUI.FluentMaterial";
-            return serializationObject;
-        }
+    public getActiveTextures(): BaseTexture[] {
+        var activeTextures = super.getActiveTextures();
 
 
-        public getClassName(): string {
-            return "FluentMaterial";
-        }
+        return activeTextures;
+    }
 
 
-        // Statics
-        public static Parse(source: any, scene: Scene, rootUrl: string): FluentMaterial {
-            return SerializationHelper.Parse(() => new FluentMaterial(source.name, scene), source, scene, rootUrl);
+    public hasTexture(texture: BaseTexture): boolean {
+        if (super.hasTexture(texture)) {
+            return true;
         }
         }
+
+        return false;
+    }
+
+    public dispose(forceDisposeEffect?: boolean): void {
+        super.dispose(forceDisposeEffect);
+    }
+
+    public clone(name: string): FluentMaterial {
+        return SerializationHelper.Clone(() => new FluentMaterial(name, this.getScene()), this);
+    }
+
+    public serialize(): any {
+        var serializationObject = SerializationHelper.Serialize(this);
+        serializationObject.customType = "BABYLON.GUI.FluentMaterial";
+        return serializationObject;
+    }
+
+    public getClassName(): string {
+        return "FluentMaterial";
+    }
+
+    // Statics
+    public static Parse(source: any, scene: Scene, rootUrl: string): FluentMaterial {
+        return SerializationHelper.Parse(() => new FluentMaterial(source.name, scene), source, scene, rootUrl);
     }
     }
 }
 }

+ 1 - 0
gui/src/3D/materials/index.ts

@@ -0,0 +1 @@
+export * from "./fluentMaterial";

+ 12 - 0
gui/src/3D/materials/shaders/fluent.ts

@@ -0,0 +1,12 @@
+import { Effect } from "babylonjs";
+
+const fShader = require("./fluent.fragment.fx");
+const vShader = require("./fluent.vertex.fx");
+
+export function registerShader() {
+    // register shaders
+    Effect.ShadersStore["fluentVertexShader"] = vShader;
+    Effect.ShadersStore["fluentPixelShader"] = fShader;
+}
+
+export { fShader, vShader };

+ 12 - 14
gui/src/3D/vector3WithInfo.ts

@@ -1,19 +1,17 @@
-/// <reference path="../../../dist/preview release/babylon.d.ts"/>
+import { Vector3 } from "babylonjs";
 
 
-module BABYLON.GUI {
+/**
+ * Class used to transport Vector3 information for pointer events
+ */
+export class Vector3WithInfo extends Vector3 {
     /**
     /**
-     * Class used to transport Vector3 information for pointer events
+     * Creates a new Vector3WithInfo
+     * @param source defines the vector3 data to transport
+     * @param buttonIndex defines the current mouse button index
      */
      */
-    export class Vector3WithInfo extends Vector3 {        
-        /**
-         * Creates a new Vector3WithInfo
-         * @param source defines the vector3 data to transport
-         * @param buttonIndex defines the current mouse button index
-         */
-        public constructor(source: Vector3, 
-            /** defines the current mouse button index */
-            public buttonIndex: number = 0) {
-            super(source.x, source.y, source.z);
-        }
+    public constructor(source: Vector3,
+        /** defines the current mouse button index */
+        public buttonIndex: number = 0) {
+        super(source.x, source.y, source.z);
     }
     }
 }
 }

+ 2 - 0
gui/src/index.ts

@@ -0,0 +1,2 @@
+export * from "./2D";
+export * from "./3D";

+ 0 - 12
gui/src/tsconfig.json

@@ -1,12 +0,0 @@
-{
-  "compilerOptions": {
-    "experimentalDecorators": true,
-    "module": "commonjs",
-    "target": "es5",
-    "noImplicitAny": true,
-    "noImplicitReturns": true,
-    "noImplicitThis": true,
-    "noUnusedLocals": true,    
-    "strictNullChecks": true    
-  }
-}

+ 31 - 0
gui/tsconfig.json

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

+ 76 - 0
gui/webpack.config.js

@@ -0,0 +1,76 @@
+const path = require('path');
+const webpack = require('webpack');
+const DtsBundleWebpack = require('dts-bundle-webpack');
+const CleanWebpackPlugin = require('clean-webpack-plugin');
+
+module.exports = {
+    context: __dirname,
+    entry: {
+        'babylonjs-gui': path.resolve(__dirname, './src/index.ts'),
+    },
+    output: {
+        path: path.resolve(__dirname, '../dist/preview release/gui'),
+        filename: 'babylon.gui.min.js',
+        libraryTarget: 'umd',
+        library: {
+            root: ["BABYLON", "GUI"],
+            amd: "babylonjs-gui",
+            commonjs: "babylonjs-gui"
+        },
+        umdNamedDefine: true,
+        //devtoolModuleFilenameTemplate: "[absolute-resource-path]"
+    },
+    resolve: {
+        extensions: [".js", '.ts']
+    },
+    externals: {
+        babylonjs: {
+            root: "BABYLON",
+            commonjs: "babylonjs",
+            commonjs2: "babylonjs",
+            amd: "babylonjs"
+        }
+    },
+    devtool: "source-map",
+    module: {
+        rules: [{
+            test: /\.tsx?$/,
+            loader: "ts-loader",
+            exclude: /node_modules/
+        },
+        {
+            test: /\.fx$/,
+            use: [{
+                loader: path.resolve(__dirname, '../Tools/WebpackShaderLoader/index.js')
+            }]
+        }]
+    },
+    mode: "production",
+    devServer: {
+        contentBase: path.join(__dirname, "dist"),
+        compress: false,
+        //open: true,
+        port: 9000
+    },
+    plugins: [
+        new CleanWebpackPlugin([
+            path.resolve(__dirname, './src/**/*.js'),
+            path.resolve(__dirname, './src/**/*.map')
+        ]),
+        // moved out of here due to the way gulp works...
+        /*new DtsBundleWebpack({
+            name: "babylonjs-gui",
+            main: path.resolve(__dirname, '../dist/preview release/gui/build/index.d.ts'),
+            out: path.resolve(__dirname, '../dist/preview release/gui/babylon.gui.module.d.ts'),
+            baseDir: path.resolve(__dirname, '../dist/preview release/gui/build/'),
+            headerText: "BabylonJS GUI"
+        }),*/
+        new webpack.WatchIgnorePlugin([
+            /\.js$/,
+            /\.d\.ts$/
+        ])
+    ],
+    watchOptions: {
+        ignored: [path.resolve(__dirname, './dist/**/*.*'), 'node_modules']
+    }
+}

+ 0 - 0
inspector/package.json


이 변경점에서 너무 많은 파일들이 변경되어 몇몇 파일들은 표시되지 않았습니다.