Bladeren bron

Merge pull request #6586 from Jaskar/testPG

Playground v4.3
David Catuhe 6 jaren geleden
bovenliggende
commit
c169cc84dd
100 gewijzigde bestanden met toevoegingen van 188669 en 188239 verwijderingen
  1. 21445 21330
      Playground/babylon.d.txt
  2. 16 17
      Playground/css/index.css
  3. 39 1
      Playground/css/index_mobile.css
  4. 10 10
      Playground/debug.html
  5. 4 3
      Playground/index-local.html
  6. 38 45
      Playground/index.html
  7. 5 4
      Playground/indexStable.html
  8. 4 0
      Playground/js.html
  9. 3 1
      Playground/js/examples.js
  10. 3 1
      Playground/js/frame.js
  11. 21 798
      Playground/js/index.js
  12. 819 0
      Playground/js/main.js
  13. 53 19
      Playground/js/menuPG.js
  14. 14 14
      Playground/js/monacoCreator.js
  15. 0 8
      Playground/js/pbt.js
  16. 16 18
      Playground/js/settingsPG.js
  17. 0 56
      Playground/js/ts.js
  18. 15 6
      Playground/js/utils.js
  19. 5 3
      Playground/js/zipTool.js
  20. 1 1
      Playground/test.html
  21. 0 496
      Playground/ts-local.html
  22. 4 496
      Playground/ts.html
  23. 6 5
      Viewer/src/configuration/renderOnlyLoader.ts
  24. 2 1
      Viewer/src/templating/templateManager.ts
  25. 22241 22122
      dist/preview release/babylon.d.ts
  26. 2 2
      dist/preview release/babylon.js
  27. 1693 1422
      dist/preview release/babylon.max.js
  28. 1 1
      dist/preview release/babylon.max.js.map
  29. 58132 57875
      dist/preview release/babylon.module.d.ts
  30. 22241 22122
      dist/preview release/documentation.d.ts
  31. 4 4
      dist/preview release/gui/babylon.gui.js
  32. 1 1
      dist/preview release/gui/babylon.gui.js.map
  33. 1 1
      dist/preview release/gui/babylon.gui.module.d.ts
  34. 7 7
      dist/preview release/inspector/babylon.inspector.bundle.max.js
  35. 1 1
      dist/preview release/inspector/babylon.inspector.bundle.max.js.map
  36. 9 3
      dist/preview release/loaders/babylon.glTF2FileLoader.js
  37. 1 1
      dist/preview release/loaders/babylon.glTF2FileLoader.js.map
  38. 1 1
      dist/preview release/loaders/babylon.glTF2FileLoader.min.js
  39. 9 3
      dist/preview release/loaders/babylon.glTFFileLoader.js
  40. 1 1
      dist/preview release/loaders/babylon.glTFFileLoader.js.map
  41. 1 1
      dist/preview release/loaders/babylon.glTFFileLoader.min.js
  42. 9 3
      dist/preview release/loaders/babylonjs.loaders.js
  43. 1 1
      dist/preview release/loaders/babylonjs.loaders.js.map
  44. 2 2
      dist/preview release/loaders/babylonjs.loaders.min.js
  45. 1 1
      dist/preview release/packagesSizeBaseLine.json
  46. 58132 57875
      dist/preview release/viewer/babylon.module.d.ts
  47. 80 52
      dist/preview release/viewer/babylon.viewer.js
  48. 2 2
      dist/preview release/viewer/babylon.viewer.max.js
  49. 4 3
      dist/preview release/what's new.md
  50. 1 1
      gui/src/2D/adtInstrumentation.ts
  51. 2 0
      loaders/src/glTF/2.0/Extensions/KHR_materials_pbrSpecularGlossiness.ts
  52. 1 0
      loaders/src/glTF/2.0/Extensions/KHR_materials_unlit.ts
  53. 2324 2322
      loaders/src/glTF/2.0/glTFLoader.ts
  54. 2 3
      src/Behaviors/Cameras/framingBehavior.ts
  55. 2 2
      src/Cameras/XR/webXRCamera.ts
  56. 16 1
      src/Cameras/XR/webXRControllerModelLoader.ts
  57. 2 2
      src/Cameras/XR/webXRControllerTeleportation.ts
  58. 1 1
      src/Cameras/XR/webXRExperienceHelper.ts
  59. 1 1
      src/Cameras/XR/webXRSessionManager.ts
  60. 5 1
      src/Cameras/camera.ts
  61. 3 3
      src/Engines/Extensions/engine.cubeTexture.ts
  62. 2 2
      src/Engines/Extensions/engine.webVR.ts
  63. 4 4
      src/Engines/Processors/shaderCodeNode.ts
  64. 2 2
      src/Engines/Processors/shaderProcessor.ts
  65. 220 80
      src/Engines/engine.ts
  66. 12 0
      src/Engines/engineStore.ts
  67. 3 13
      src/Engines/nullEngine.ts
  68. 2 2
      src/Gamepads/gamepadManager.ts
  69. 1 1
      src/Gizmos/boundingBoxGizmo.ts
  70. 5 3
      src/Gizmos/gizmo.ts
  71. 1 1
      src/Instrumentation/engineInstrumentation.ts
  72. 2 1
      src/Instrumentation/sceneInstrumentation.ts
  73. 2 2
      src/Layers/effectLayer.ts
  74. 3 3
      src/Layers/glowLayer.ts
  75. 2 3
      src/Layers/highlightLayer.ts
  76. 5 5
      src/LibDeclarations/webxr.d.ts
  77. 3 2
      src/Loading/Plugins/babylonFileLoader.ts
  78. 2 1
      src/Loading/sceneLoader.ts
  79. 3 4
      src/Materials/Textures/renderTargetTexture.ts
  80. 3 3
      src/Materials/effect.ts
  81. 79 0
      src/Maths/math.functions.ts
  82. 11 0
      src/Maths/math.ts
  83. 2 1
      src/Meshes/abstractMesh.ts
  84. 2 1
      src/Meshes/geometry.ts
  85. 2 2
      src/Meshes/subMesh.ts
  86. 20 0
      src/Misc/customAnimationFrameRequester.ts
  87. 16 0
      src/Misc/fileRequest.ts
  88. 370 0
      src/Misc/fileTools.ts
  89. 108 0
      src/Misc/gradients.ts
  90. 6 0
      src/Misc/index.ts
  91. 30 0
      src/Misc/loadFileError.ts
  92. 169 0
      src/Misc/perfCounter.ts
  93. 1 2
      src/Misc/promise.ts
  94. 22 0
      src/Misc/retryStrategy.ts
  95. 24 0
      src/Misc/stringTools.ts
  96. 64 919
      src/Misc/tools.ts
  97. 1 1
      src/Particles/IParticleSystem.ts
  98. 1 1
      src/Particles/baseParticleSystem.ts
  99. 4 3
      src/Particles/gpuParticleSystem.ts
  100. 0 0
      src/Particles/particle.ts

File diff suppressed because it is too large
+ 21445 - 21330
Playground/babylon.d.txt


+ 16 - 17
Playground/css/index.css

@@ -136,6 +136,7 @@ body {
 }      
 }      
 
 
 #exampleList {
 #exampleList {
+    z-index: 10;
     display: none;
     display: none;
     position: absolute;
     position: absolute;
     top: 55px;
     top: 55px;
@@ -164,6 +165,7 @@ body {
     line-height: 36px;
     line-height: 36px;
 }
 }
 #exampleList #exampleBanner h1 img {
 #exampleList #exampleBanner h1 img {
+    display: none;
     float: right;
     float: right;
     width: 36px;
     width: 36px;
     margin-right: 10px;
     margin-right: 10px;
@@ -278,7 +280,7 @@ body {
     right: 0;
     right: 0;
     width: 60px;
     width: 60px;
     padding: 2px 8px 5px 0px;
     padding: 2px 8px 5px 0px;
-    z-index:10;
+    z-index: 4;
     background-color: #3f3461;
     background-color: #3f3461;
     color:white;
     color:white;
     font-size: 18px;
     font-size: 18px;
@@ -427,18 +429,31 @@ body {
     text-transform: uppercase;
     text-transform: uppercase;
     background-color: #201936;
     background-color: #201936;
 }
 }
+.navbar .select .toDisplay .option {
+    font-size: 20px;
+    height: 35px;
+    line-height: 35px;
+    padding: 1px 5px 1px 15px;
+    text-align: left;
+}
 .navbar .select .toDisplay.languageJS {
 .navbar .select .toDisplay.languageJS {
     background-color: #3f3461;
     background-color: #3f3461;
 }
 }
 .navbar .select .toDisplay.languageJS .option {
 .navbar .select .toDisplay.languageJS .option {
     background-color: #9379e6;
     background-color: #9379e6;
 }
 }
+.navbar .select .toDisplay.languageJS .option:hover {
+    background-color: #bfabff;
+}
 .navbar .select .toDisplay.languageTS {
 .navbar .select .toDisplay.languageTS {
     background-color: #bb464b;
     background-color: #bb464b;
 }
 }
 .navbar .select .toDisplay.languageTS .option {
 .navbar .select .toDisplay.languageTS .option {
     background-color: #e0684b;
     background-color: #e0684b;
 }
 }
+.navbar .select .toDisplay.languageTS .option:hover {
+    background-color: #ff7656;
+}
 .navbar .select .toDisplay.currentVersionDisplay {
 .navbar .select .toDisplay.currentVersionDisplay {
     width: auto;
     width: auto;
 }
 }
@@ -477,22 +492,6 @@ body {
     background-color: #ff7656;
     background-color: #ff7656;
 }
 }
 
 
-.navbar .select .toDisplay .option {
-    font-size: 20px;
-    height: 35px;
-    line-height: 35px;
-    padding: 1px 5px 1px 15px;
-    text-align: left;
-}
-
-.navbar .select .toDisplay .option.light {
-    background-color: white;
-    color: #E0684B;
-}
-.navbar .select .toDisplay .option.light:hover {
-    cursor: pointer;
-    background-color: #d9d9d9;
-}
 
 
 .navbar .select .toDisplayBig.dark {
 .navbar .select .toDisplayBig.dark {
     background-color: #333;    
     background-color: #333;    

+ 39 - 1
Playground/css/index_mobile.css

@@ -9,6 +9,9 @@
         top: 40px;
         top: 40px;
         bottom: 0;
         bottom: 0;
     }
     }
+    #exampleList #exampleBanner h1 img {
+        display: block;
+    }
     .navbarBottom {
     .navbarBottom {
         display: none;
         display: none;
     }
     }
@@ -37,6 +40,7 @@
         right: 0;
         right: 0;
         width: 40px;
         width: 40px;
         height: 40px;
         height: 40px;
+        cursor: pointer;
     }
     }
     #switchWrapper img {
     #switchWrapper img {
         width: 40px;
         width: 40px;
@@ -48,12 +52,13 @@
     #JStoTSbar .buttonJStoTS {
     #JStoTSbar .buttonJStoTS {
         border-top-left-radius: 12px;
         border-top-left-radius: 12px;
     }
     }
-
+    
     .navbar, .navbar .category, #JStoTSbar {
     .navbar, .navbar .category, #JStoTSbar {
         height: 40px;
         height: 40px;
         line-height: 40px;
         line-height: 40px;
         padding: 0;
         padding: 0;
         width: 100%;
         width: 100%;
+        background-color: #201936;
     }
     }
     .navbar .category.right {
     .navbar .category.right {
         display: none;
         display: none;
@@ -83,9 +88,16 @@
     .navbar.languageJS .select {
     .navbar.languageJS .select {
         background-color: #3f3461;
         background-color: #3f3461;
     }
     }
+    .navbarlanguageJS .select:active {
+        background-color: #3f3461;
+
+    }
     .navbar.languageTS .select {
     .navbar.languageTS .select {
         background-color: #bb464b;
         background-color: #bb464b;
     }
     }
+    .navbar.languageTS .select:active {
+        background-color: #bb464b;
+    }
     .navbar .select, .navbar .select img {
     .navbar .select, .navbar .select img {
         width: 40px;
         width: 40px;
         height: 40px;
         height: 40px;
@@ -93,9 +105,21 @@
     .navbar .select img {
     .navbar .select img {
         filter: invert(98%) sepia(0%) saturate(7500%) hue-rotate(207deg) brightness(104%) contrast(104%);
         filter: invert(98%) sepia(0%) saturate(7500%) hue-rotate(207deg) brightness(104%) contrast(104%);
     }
     }
+    .navbar .select img:active {
+        filter: invert(98%) sepia(0%) saturate(7500%) hue-rotate(207deg) brightness(104%) contrast(104%);
+    }
+    .navbar .select img:focus {
+        filter: invert(98%) sepia(0%) saturate(7500%) hue-rotate(207deg) brightness(104%) contrast(104%);
+    }
     .navbar .select img:hover {
     .navbar .select img:hover {
         filter: invert(98%) sepia(0%) saturate(7500%) hue-rotate(207deg) brightness(104%) contrast(104%);
         filter: invert(98%) sepia(0%) saturate(7500%) hue-rotate(207deg) brightness(104%) contrast(104%);
     }
     }
+    .navbar .select:active img {
+        filter: invert(98%) sepia(0%) saturate(7500%) hue-rotate(207deg) brightness(104%) contrast(104%);
+    }
+    .navbar .select:focus img {
+        filter: invert(98%) sepia(0%) saturate(7500%) hue-rotate(207deg) brightness(104%) contrast(104%);
+    }
     .navbar .select:hover img {
     .navbar .select:hover img {
         filter: invert(98%) sepia(0%) saturate(7500%) hue-rotate(207deg) brightness(104%) contrast(104%);
         filter: invert(98%) sepia(0%) saturate(7500%) hue-rotate(207deg) brightness(104%) contrast(104%);
     }
     }
@@ -117,12 +141,24 @@
     .navbar .select .toDisplay.languageJS .option:active {
     .navbar .select .toDisplay.languageJS .option:active {
         background-color: #9379e6;
         background-color: #9379e6;
     }
     }
+    .navbar .select .toDisplay.languageJS .option:hover {
+        background-color: #9379e6;
+    }
     .navbar .select .toDisplay.languageTS .option {
     .navbar .select .toDisplay.languageTS .option {
         background-color: #bb464b;
         background-color: #bb464b;
     }
     }
     .navbar .select .toDisplay.languageTS .option:active {
     .navbar .select .toDisplay.languageTS .option:active {
         background-color: #e0684b;
         background-color: #e0684b;
     }
     }
+    .navbar .select .toDisplay.languageTS .option:hover {
+        background-color: #e0684b;
+    }
+    .navbar .select .toDisplay #toTSbuttonMobile {
+        padding-left : 12px;
+    }
+    .navbar .select .toDisplay #toJSbuttonMobile {
+        padding-left : 12px;
+    }
     .navbar .select .toDisplay .option {
     .navbar .select .toDisplay .option {
         padding: 1px;
         padding: 1px;
         font-size: 15px;
         font-size: 15px;
@@ -165,9 +201,11 @@
         background-color: #e0684b;
         background-color: #e0684b;
     }
     }
     .navbar .select .subSelect .toDisplaySub.languageJS .option {
     .navbar .select .subSelect .toDisplaySub.languageJS .option {
+        background-color: #9379e6;
         color: white;
         color: white;
     }
     }
     .navbar .select .subSelect .toDisplaySub.languageTS .option {
     .navbar .select .subSelect .toDisplaySub.languageTS .option {
+        background-color: #e0684b;
         color: white;
         color: white;
     }
     }
 
 

+ 10 - 10
Playground/debug.html

@@ -2,8 +2,7 @@
 <html>
 <html>
 
 
 <!--
 <!--
-    The purpose of the Debug.html file is to debug : ???
-    // TO DO - Complete that
+    The purpose of the Debug.html file is to debug a new Playground feature.
     // TO DO - Fix the console error : "Manifest: Line: 1, column 1, Unexpected token"
     // TO DO - Fix the console error : "Manifest: Line: 1, column 1, Unexpected token"
  -->
  -->
 
 
@@ -154,10 +153,10 @@
                     <div class="option noSubSelect" id="minimapToggle1280">Minimap
                     <div class="option noSubSelect" id="minimapToggle1280">Minimap
                         <i class="fa fa-square" aria-hidden="true"></i>
                         <i class="fa fa-square" aria-hidden="true"></i>
                     </div>
                     </div>
-                    <div class="option subSelect" id="qrCodeHover" onmouseover="showQRCode();">QR Code Link <i
+                    <div class="option subSelect" id="qrCodeHover1280">QR Code Link <i
                             class="fa fa-chevron-right" aria-hidden="true"></i>
                             class="fa fa-chevron-right" aria-hidden="true"></i>
                         <div class="toDisplaySub">
                         <div class="toDisplaySub">
-                            <div class="option" id="qrCodeImage">QR Code Image</div>
+                            <div class="option" id="qrCodeImage" class="qrCodeImage">QR Code Image</div>
                         </div>
                         </div>
                     </div>
                     </div>
                     <div class="option uncheck noSubSelect" id="debugButton1280">Inspector
                     <div class="option uncheck noSubSelect" id="debugButton1280">Inspector
@@ -228,10 +227,10 @@
                     <div class="option noSubSelect" id="minimapToggle1024">Minimap
                     <div class="option noSubSelect" id="minimapToggle1024">Minimap
                         <i class="fa fa-square" aria-hidden="true"></i>
                         <i class="fa fa-square" aria-hidden="true"></i>
                     </div>
                     </div>
-                    <div class="option subSelect" id="qrCodeHover" onmouseover="showQRCode();">QR Code Link <i
+                    <div class="option subSelect" id="qrCodeHover1024">QR Code Link <i
                             class="fa fa-chevron-right" aria-hidden="true"></i>
                             class="fa fa-chevron-right" aria-hidden="true"></i>
                         <div class="toDisplaySub">
                         <div class="toDisplaySub">
-                            <div class="option" id="qrCodeImage">QR Code Image</div>
+                            <div class="option" id="qrCodeImage" class="qrCodeImage">QR Code Image</div>
                         </div>
                         </div>
                     </div>
                     </div>
                     <div class="option uncheck noSubSelect" id="debugButton1024">Inspector
                     <div class="option uncheck noSubSelect" id="debugButton1024">Inspector
@@ -259,8 +258,8 @@
         <div class="category languageJS" id="JStoTSbar">
         <div class="category languageJS" id="JStoTSbar">
             <div class="button select"><img src="css/img/hamburgerButton.svg">
             <div class="button select"><img src="css/img/hamburgerButton.svg">
                 <div class="toDisplay">
                 <div class="toDisplay">
-                    <div class="option noSubSelect languageTS" id="toTSbuttonMobile"><img src="css/img/logoTS.svg">TypeScript</div>
-                    <div class="option noSubSelect languageJS" id="toJSbuttonMobile"><img src="css/img/logoJS.svg">JavaScript</div>
+                    <div class="option noSubSelect languageTS" id="toTSbuttonMobile">TypeScript</div>
+                    <div class="option noSubSelect languageJS" id="toJSbuttonMobile">JavaScript</div>
                     <div class="option noSubSelect run" id="runButtonMobile"><img src="css/img/playButton.svg">Run</div>
                     <div class="option noSubSelect run" id="runButtonMobile"><img src="css/img/playButton.svg">Run</div>
                     <div class="option noSubSelect" id="saveButtonMobile"><img src="css/img/saveButton.svg">Save</div>
                     <div class="option noSubSelect" id="saveButtonMobile"><img src="css/img/saveButton.svg">Save</div>
                     <div class="option noSubSelect" id="zipButtonMobile"><img src="css/img/downloadButton.svg">Download
                     <div class="option noSubSelect" id="zipButtonMobile"><img src="css/img/downloadButton.svg">Download
@@ -300,7 +299,7 @@
                     <div style="display: none;" class="option nosubselect" id="minimapToggleMobile">Minimap
                     <div style="display: none;" class="option nosubselect" id="minimapToggleMobile">Minimap
                         <i class="fa fa-square" aria-hidden="true"></i>
                         <i class="fa fa-square" aria-hidden="true"></i>
                     </div>
                     </div>
-                    <div class="option subSelect" id="qrCodeHover" onmouseover="showQRCode();"><img src="css/img/optionsButton.svg">QR Code Link
+                    <div class="option subSelect" id="qrCodeHover"><img src="css/img/optionsButton.svg">QR Code Link
                         <div class="toDisplaySub">
                         <div class="toDisplaySub">
                             <div class="option" id="qrCodeImage">QR Code Image</div>
                             <div class="option" id="qrCodeImage">QR Code Image</div>
                         </div>
                         </div>
@@ -436,9 +435,10 @@
     <script src="js/pbt.js"></script>
     <script src="js/pbt.js"></script>
     <script src="js/libs/typescript.js"></script>
     <script src="js/libs/typescript.js"></script>
     <script src="js/examples.js"></script>
     <script src="js/examples.js"></script>
+    <script src="js/main.js"></script>
+    <script src="js/menuPG.js"></script>
     <script src="js/monacoCreator.js"></script>
     <script src="js/monacoCreator.js"></script>
     <script src="js/settingsPG.js"></script>
     <script src="js/settingsPG.js"></script>
-    <script src="js/menuPG.js"></script>
     <script src="js/utils.js"></script>
     <script src="js/utils.js"></script>
     <script src="js/zipTool.js"></script>
     <script src="js/zipTool.js"></script>
     <script src="js/index.js"></script>
     <script src="js/index.js"></script>

+ 4 - 3
Playground/index-local.html

@@ -193,8 +193,8 @@
         <div class="category languageJS" id="JStoTSbar">
         <div class="category languageJS" id="JStoTSbar">
             <div class="button select"><img src="css/img/hamburgerButton.svg">
             <div class="button select"><img src="css/img/hamburgerButton.svg">
                 <div class="toDisplay">
                 <div class="toDisplay">
-                    <div class="option noSubSelect languageTS" id="toTSbuttonMobile"><img src="css/img/logoTS.svg">TypeScript</div>
-                    <div class="option noSubSelect languageJS" id="toJSbuttonMobile"><img src="css/img/logoJS.svg">JavaScript</div>
+                    <div class="option noSubSelect languageTS" id="toTSbuttonMobile">TypeScript</div>
+                    <div class="option noSubSelect languageJS" id="toJSbuttonMobile">JavaScript</div>
                     <div class="option noSubSelect run" id="runButtonMobile"><img src="css/img/playButton.svg">Run</div>
                     <div class="option noSubSelect run" id="runButtonMobile"><img src="css/img/playButton.svg">Run</div>
                     <div class="option noSubSelect" id="saveButtonMobile"><img src="css/img/saveButton.svg">Save</div>
                     <div class="option noSubSelect" id="saveButtonMobile"><img src="css/img/saveButton.svg">Save</div>
                     <div class="option noSubSelect" id="zipButtonMobile"><img src="css/img/downloadButton.svg">Download
                     <div class="option noSubSelect" id="zipButtonMobile"><img src="css/img/downloadButton.svg">Download
@@ -377,9 +377,10 @@
     <script src="js/pbt.js"></script>
     <script src="js/pbt.js"></script>
     <script src="js/libs/typescript.js"></script>
     <script src="js/libs/typescript.js"></script>
     <script src="js/examples.js"></script>
     <script src="js/examples.js"></script>
+    <script src="js/main.js"></script>
+    <script src="js/menuPG.js"></script>
     <script src="js/monacoCreator.js"></script>
     <script src="js/monacoCreator.js"></script>
     <script src="js/settingsPG.js"></script>
     <script src="js/settingsPG.js"></script>
-    <script src="js/menuPG.js"></script>
     <script src="js/utils.js"></script>
     <script src="js/utils.js"></script>
     <script src="js/zipTool.js"></script>
     <script src="js/zipTool.js"></script>
     <script src="js/index.js"></script>
     <script src="js/index.js"></script>

+ 38 - 45
Playground/index.html

@@ -69,7 +69,7 @@
             <div class="button" id="newButton1280"><img src="css/img/newButton.svg"></div>
             <div class="button" id="newButton1280"><img src="css/img/newButton.svg"></div>
             <div class="button removeOnPhone" id="clearButton1280"><img src="css/img/clearButton.svg"></div>
             <div class="button removeOnPhone" id="clearButton1280"><img src="css/img/clearButton.svg"></div>
 
 
-            <div class="button select"><img src="css/img/optionsButton.svg">
+            <div class="button select" id="menuButton1280"><img src="css/img/optionsButton.svg">
                 <div class="toDisplay languageJS">
                 <div class="toDisplay languageJS">
                     <div class="option subSelect">Theme <i class="fa fa-chevron-right" aria-hidden="true"></i>
                     <div class="option subSelect">Theme <i class="fa fa-chevron-right" aria-hidden="true"></i>
                         <div class="toDisplaySub languageJS">
                         <div class="toDisplaySub languageJS">
@@ -79,12 +79,12 @@
                     </div>
                     </div>
                     <div class="option subSelect">Font size <i class="fa fa-chevron-right" aria-hidden="true"></i>
                     <div class="option subSelect">Font size <i class="fa fa-chevron-right" aria-hidden="true"></i>
                         <div class="toDisplaySub displayFontSize languageJS">
                         <div class="toDisplaySub displayFontSize languageJS">
-                            <div class="option" onclick="settingsPG.setFontSize(12);">12</div>
-                            <div class="option selected" onclick="settingsPG.setFontSize(14);">14</div>
-                            <div class="option" onclick="settingsPG.setFontSize(16);">16</div>
-                            <div class="option" onclick="settingsPG.setFontSize(18);">18</div>
-                            <div class="option" onclick="settingsPG.setFontSize(20);">20</div>
-                            <div class="option" onclick="settingsPG.setFontSize(22);">22</div>
+                            <div class="option">12</div>
+                            <div class="option selected">14</div>
+                            <div class="option">16</div>
+                            <div class="option">18</div>
+                            <div class="option">20</div>
+                            <div class="option">22</div>
                         </div>
                         </div>
                     </div>
                     </div>
                     <div class="option noSubSelect" id="safemodeToggle1280">Safe mode
                     <div class="option noSubSelect" id="safemodeToggle1280">Safe mode
@@ -99,15 +99,13 @@
                     <div class="option noSubSelect" id="minimapToggle1280">Minimap
                     <div class="option noSubSelect" id="minimapToggle1280">Minimap
                         <i class="fa fa-square" aria-hidden="true"></i>
                         <i class="fa fa-square" aria-hidden="true"></i>
                     </div>
                     </div>
-                    <div class="option subSelect" id="qrCodeHover" onmouseover="showQRCode();">QR Code Link <i
+                    <div class="option subSelect" id="qrCodeHover1280">QR Code Link <i
                             class="fa fa-chevron-right" aria-hidden="true"></i>
                             class="fa fa-chevron-right" aria-hidden="true"></i>
                         <div class="toDisplaySub">
                         <div class="toDisplaySub">
-                            <div class="option" id="qrCodeImage">QR Code Image</div>
+                            <div class="option" id="qrCodeImage1280">QR Code Image</div>
                         </div>
                         </div>
                     </div>
                     </div>
-                    <div class="option uncheck noSubSelect" id="debugButton1280">Inspector
-                        <i class="fa fa-square" aria-hidden="true"></i>
-                    </div>
+                    <div class="option uncheck noSubSelect" id="debugButton1280">Inspector</div>
                     <div class="option nosubselect" id="metadataButton1280">Metadata</div>
                     <div class="option nosubselect" id="metadataButton1280">Metadata</div>
                 </div>
                 </div>
             </div>
             </div>
@@ -117,8 +115,7 @@
             <div class="button select" style="display: none;">
             <div class="button select" style="display: none;">
                 <span id="currentVersion1280">v.</span>
                 <span id="currentVersion1280">v.</span>
                 <div class="toDisplay currentVersionDisplay">
                 <div class="toDisplay currentVersionDisplay">
-                    <div class="option" onclick="setVersion('4.0');">4.0</div>
-                    <div class="option" onclick="setVersion('3.0');">3.0</div>
+                    <div class="option">4.0</div>
                 </div>
                 </div>
             </div>
             </div>
             <div class="button select"><img class="examplesButton" src="css/img/examplesButton.svg"></div>
             <div class="button select"><img class="examplesButton" src="css/img/examplesButton.svg"></div>
@@ -142,7 +139,7 @@
             <div class="button" id="newButton1024"><img src="css/img/newButton.svg"></div>
             <div class="button" id="newButton1024"><img src="css/img/newButton.svg"></div>
             <div class="button removeOnPhone" id="clearButton1024"><img src="css/img/clearButton.svg"></div>
             <div class="button removeOnPhone" id="clearButton1024"><img src="css/img/clearButton.svg"></div>
 
 
-            <div class="button select"><img src="css/img/optionsButton.svg">
+            <div class="button select" id="menuButton1024"><img src="css/img/optionsButton.svg">
                 <div class="toDisplay">
                 <div class="toDisplay">
                     <div class="option subSelect">Theme <i class="fa fa-chevron-right" aria-hidden="true"></i>
                     <div class="option subSelect">Theme <i class="fa fa-chevron-right" aria-hidden="true"></i>
 
 
@@ -153,12 +150,12 @@
                     </div>
                     </div>
                     <div class="option subSelect">Font size <i class="fa fa-chevron-right" aria-hidden="true"></i>
                     <div class="option subSelect">Font size <i class="fa fa-chevron-right" aria-hidden="true"></i>
                         <div class="toDisplaySub displayFontSize">
                         <div class="toDisplaySub displayFontSize">
-                            <div class="option" onclick="settingsPG.setFontSize(12);">12</div>
-                            <div class="option selected" onclick="settingsPG.setFontSize(14);">14</div>
-                            <div class="option" onclick="settingsPG.setFontSize(16);">16</div>
-                            <div class="option" onclick="settingsPG.setFontSize(18);">18</div>
-                            <div class="option" onclick="settingsPG.setFontSize(20);">20</div>
-                            <div class="option" onclick="settingsPG.setFontSize(22);">22</div>
+                            <div class="option">12</div>
+                            <div class="option selected">14</div>
+                            <div class="option">16</div>
+                            <div class="option">18</div>
+                            <div class="option">20</div>
+                            <div class="option">22</div>
                         </div>
                         </div>
                     </div>
                     </div>
                     <div class="option noSubSelect" id="safemodeToggle1024">Safe mode
                     <div class="option noSubSelect" id="safemodeToggle1024">Safe mode
@@ -173,15 +170,13 @@
                     <div class="option noSubSelect" id="minimapToggle1024">Minimap
                     <div class="option noSubSelect" id="minimapToggle1024">Minimap
                         <i class="fa fa-square" aria-hidden="true"></i>
                         <i class="fa fa-square" aria-hidden="true"></i>
                     </div>
                     </div>
-                    <div class="option subSelect" id="qrCodeHover" onmouseover="showQRCode();">QR Code Link <i
+                    <div class="option subSelect" id="qrCodeHover1024">QR Code Link <i
                             class="fa fa-chevron-right" aria-hidden="true"></i>
                             class="fa fa-chevron-right" aria-hidden="true"></i>
                         <div class="toDisplaySub">
                         <div class="toDisplaySub">
-                            <div class="option" id="qrCodeImage">QR Code Image</div>
+                            <div class="option" id="qrCodeImage1024">QR Code Image</div>
                         </div>
                         </div>
                     </div>
                     </div>
-                    <div class="option uncheck noSubSelect" id="debugButton1024">Inspector
-                        <i class="fa fa-square" aria-hidden="true"></i>
-                    </div>
+                    <div class="option uncheck noSubSelect" id="debugButton1024">Inspector</div>
                     <div class="option noSubSelect" id="metadataButton1024">Metadata</div>
                     <div class="option noSubSelect" id="metadataButton1024">Metadata</div>
                 </div>
                 </div>
             </div>
             </div>
@@ -191,8 +186,7 @@
             <div class="button select" style="display: none;">
             <div class="button select" style="display: none;">
                 <span id="currentVersion1024">v.</span>
                 <span id="currentVersion1024">v.</span>
                 <div class="toDisplay currentVersionDisplay">
                 <div class="toDisplay currentVersionDisplay">
-                    <div class="option" onclick="setVersion('4.0');">4.0</div>
-                    <div class="option" onclick="setVersion('3.0');">3.0</div>
+                    <div class="option">4.0</div>
                 </div>
                 </div>
             </div>
             </div>
             <div class="button select"><img class="examplesButton" src="css/img/examplesButton.svg"></div>
             <div class="button select"><img class="examplesButton" src="css/img/examplesButton.svg"></div>
@@ -202,18 +196,17 @@
     <!-- Mobile -->
     <!-- Mobile -->
     <div class="navbar navBarMobile languageJS">
     <div class="navbar navBarMobile languageJS">
         <div class="category languageJS" id="JStoTSbar">
         <div class="category languageJS" id="JStoTSbar">
-            <div class="button select"><img src="css/img/hamburgerButton.svg">
+            <div class="button select" id="menuButtonMobile"><img src="css/img/hamburgerButton.svg">
                 <div class="toDisplay">
                 <div class="toDisplay">
-                    <div class="option noSubSelect languageTS" id="toTSbuttonMobile"><img src="css/img/logoTS.svg">TypeScript</div>
-                    <div class="option noSubSelect languageJS" id="toJSbuttonMobile"><img src="css/img/logoJS.svg">JavaScript</div>
+                    <div class="option noSubSelect languageTS" id="toTSbuttonMobile">TypeScript</div>
+                    <div class="option noSubSelect languageJS" id="toJSbuttonMobile">JavaScript</div>
                     <div class="option noSubSelect run" id="runButtonMobile"><img src="css/img/playButton.svg">Run</div>
                     <div class="option noSubSelect run" id="runButtonMobile"><img src="css/img/playButton.svg">Run</div>
                     <div class="option noSubSelect" id="saveButtonMobile"><img src="css/img/saveButton.svg">Save</div>
                     <div class="option noSubSelect" id="saveButtonMobile"><img src="css/img/saveButton.svg">Save</div>
                     <div class="option noSubSelect" id="zipButtonMobile"><img src="css/img/downloadButton.svg">Download
                     <div class="option noSubSelect" id="zipButtonMobile"><img src="css/img/downloadButton.svg">Download
                     </div>
                     </div>
                     <div class="option noSubSelect" id="newButtonMobile"><img src="css/img/newButton.svg">New</div>
                     <div class="option noSubSelect" id="newButtonMobile"><img src="css/img/newButton.svg">New</div>
                     <div class="option noSubSelect" id="clearButtonMobile"><img src="css/img/clearButton.svg">Clear</div>
                     <div class="option noSubSelect" id="clearButtonMobile"><img src="css/img/clearButton.svg">Clear</div>
-                    <div class="option noSubSelect" id="debugButtonMobile"><img src="css/img/inspectorButton.svg">Inspector
-                    </div>
+                    <div class="option noSubSelect" id="debugButtonMobile"><img src="css/img/inspectorButton.svg">Inspector</div>
                     <div class="option subSelect"><img src="css/img/optionsButton.svg">Theme
                     <div class="option subSelect"><img src="css/img/optionsButton.svg">Theme
                         <div class="toDisplaySub">
                         <div class="toDisplaySub">
                             <div class="option selected" id="darkThemeMobile">Dark</div>
                             <div class="option selected" id="darkThemeMobile">Dark</div>
@@ -222,14 +215,14 @@
                     </div>
                     </div>
                     <div class="option subSelect"><img src="css/img/optionsButton.svg">Font size
                     <div class="option subSelect"><img src="css/img/optionsButton.svg">Font size
                         <div class="toDisplaySub displayFontSize">
                         <div class="toDisplaySub displayFontSize">
-                            <div class="option" onclick="settingsPG.setFontSize(8);">8</div>
-                            <div class="option" onclick="settingsPG.setFontSize(10);">10</div>
-                            <div class="option selected" onclick="settingsPG.setFontSize(12);">12</div>
-                            <div class="option" onclick="settingsPG.setFontSize(14);">14</div>
-                            <div class="option" onclick="settingsPG.setFontSize(16);">16</div>
-                            <div class="option" onclick="settingsPG.setFontSize(18);">18</div>
-                            <div class="option" onclick="settingsPG.setFontSize(20);">20</div>
-                            <div class="option" onclick="settingsPG.setFontSize(22);">22</div>
+                            <div class="option">8</div>
+                            <div class="option">10</div>
+                            <div class="option selected">12</div>
+                            <div class="option">14</div>
+                            <div class="option">16</div>
+                            <div class="option">18</div>
+                            <div class="option">20</div>
+                            <div class="option">22</div>
                         </div>
                         </div>
                     </div>
                     </div>
                     <div style="display: none;" class="option noSubSelect" id="safemodeToggleMobile">Safe mode
                     <div style="display: none;" class="option noSubSelect" id="safemodeToggleMobile">Safe mode
@@ -245,7 +238,7 @@
                     <div style="display: none;" class="option nosubselect" id="minimapToggleMobile">Minimap
                     <div style="display: none;" class="option nosubselect" id="minimapToggleMobile">Minimap
                         <i class="fa fa-square" aria-hidden="true"></i>
                         <i class="fa fa-square" aria-hidden="true"></i>
                     </div>
                     </div>
-                    <div class="option subSelect" id="qrCodeHover" onmouseover="showQRCode();"><img src="css/img/optionsButton.svg">QR Code Link
+                    <div class="option subSelect" id="qrCodeHoverMobile"><img src="css/img/optionsButton.svg">QR Code Link
                         <div class="toDisplaySub">
                         <div class="toDisplaySub">
                             <div class="option" id="qrCodeImage">QR Code Image</div>
                             <div class="option" id="qrCodeImage">QR Code Image</div>
                         </div>
                         </div>
@@ -285,8 +278,7 @@
             <div class="button select" style="display: none;">
             <div class="button select" style="display: none;">
                 <span id="currentVersionMobile">v.</span>
                 <span id="currentVersionMobile">v.</span>
                 <div class="toDisplay currentVersionDisplay">
                 <div class="toDisplay currentVersionDisplay">
-                    <div class="option" onclick="setVersion('4.0');">4.0</div>
-                    <div class="option" onclick="setVersion('3.0');">3.0</div>
+                    <div class="option">4.0</div>
                 </div>
                 </div>
             </div>
             </div>
         </div>
         </div>
@@ -383,9 +375,10 @@
     <script src="js/pbt.js"></script>
     <script src="js/pbt.js"></script>
     <script src="js/libs/typescript.js"></script>
     <script src="js/libs/typescript.js"></script>
     <script src="js/examples.js"></script>
     <script src="js/examples.js"></script>
+    <script src="js/main.js"></script>
+    <script src="js/menuPG.js"></script>
     <script src="js/monacoCreator.js"></script>
     <script src="js/monacoCreator.js"></script>
     <script src="js/settingsPG.js"></script>
     <script src="js/settingsPG.js"></script>
-    <script src="js/menuPG.js"></script>
     <script src="js/utils.js"></script>
     <script src="js/utils.js"></script>
     <script src="js/zipTool.js"></script>
     <script src="js/zipTool.js"></script>
     <script src="js/index.js"></script>
     <script src="js/index.js"></script>

+ 5 - 4
Playground/indexStable.html

@@ -209,8 +209,8 @@
         <div class="category languageJS" id="JStoTSbar">
         <div class="category languageJS" id="JStoTSbar">
             <div class="button select"><img src="css/img/hamburgerButton.svg">
             <div class="button select"><img src="css/img/hamburgerButton.svg">
                 <div class="toDisplay">
                 <div class="toDisplay">
-                    <div class="option noSubSelect languageTS" id="toTSbuttonMobile"><img src="css/img/logoTS.svg">TypeScript</div>
-                    <div class="option noSubSelect languageJS" id="toJSbuttonMobile"><img src="css/img/logoJS.svg">JavaScript</div>
+                    <div class="option noSubSelect languageTS" id="toTSbuttonMobile">TypeScript</div>
+                    <div class="option noSubSelect languageJS" id="toJSbuttonMobile">JavaScript</div>
                     <div class="option noSubSelect run" id="runButtonMobile"><img src="css/img/playButton.svg">Run</div>
                     <div class="option noSubSelect run" id="runButtonMobile"><img src="css/img/playButton.svg">Run</div>
                     <div class="option noSubSelect" id="saveButtonMobile"><img src="css/img/saveButton.svg">Save</div>
                     <div class="option noSubSelect" id="saveButtonMobile"><img src="css/img/saveButton.svg">Save</div>
                     <div class="option noSubSelect" id="zipButtonMobile"><img src="css/img/downloadButton.svg">Download
                     <div class="option noSubSelect" id="zipButtonMobile"><img src="css/img/downloadButton.svg">Download
@@ -384,7 +384,7 @@
     <script src="js/jquery.qrcode.js"></script>
     <script src="js/jquery.qrcode.js"></script>
     <script src="js/qrcode.js"></script>
     <script src="js/qrcode.js"></script>
 
 
-    <!-- TO DO : Why is this a split here ? It's already in the JS code -->
+    <!-- TO DO - Why is this a split here ? It's already in the JS code (index.js) -->
     <script>
     <script>
         Split(['#jsEditor', '#canvasZone']);
         Split(['#jsEditor', '#canvasZone']);
     </script>
     </script>
@@ -393,9 +393,10 @@
     <script src="js/pbt.js"></script>
     <script src="js/pbt.js"></script>
     <script src="js/libs/typescript.js"></script>
     <script src="js/libs/typescript.js"></script>
     <script src="js/examples.js"></script>
     <script src="js/examples.js"></script>
+    <script src="js/main.js"></script>
+    <script src="js/menuPG.js"></script>
     <script src="js/monacoCreator.js"></script>
     <script src="js/monacoCreator.js"></script>
     <script src="js/settingsPG.js"></script>
     <script src="js/settingsPG.js"></script>
-    <script src="js/menuPG.js"></script>
     <script src="js/utils.js"></script>
     <script src="js/utils.js"></script>
     <script src="js/zipTool.js"></script>
     <script src="js/zipTool.js"></script>
     <script src="js/index.js"></script>
     <script src="js/index.js"></script>

+ 4 - 0
Playground/js.html

@@ -0,0 +1,4 @@
+<script>
+    localStorage.setItem("bjs-playground-scriptLanguage", "JS");
+    window.location = "./";
+</script>

+ 3 - 1
Playground/js/examples.js

@@ -2,7 +2,9 @@
  * This JS file is for examples list and actions linked to examples.
  * This JS file is for examples list and actions linked to examples.
  */
  */
 class Examples {
 class Examples {
-    constructor() {
+    constructor(parent) {
+        this.parent = parent;
+
         this.isExamplesDisplayed = false;
         this.isExamplesDisplayed = false;
 
 
         // There's a "close" button on the mobile interface.
         // There's a "close" button on the mobile interface.

+ 3 - 1
Playground/js/frame.js

@@ -1,5 +1,7 @@
 import { utils } from "mocha";
 import { utils } from "mocha";
 
 
+// TO DO - Rewrite frame.js to work with the new class architecture.
+
 (function() {
 (function() {
     var snippetUrl = "https://snippet.babylonjs.com";
     var snippetUrl = "https://snippet.babylonjs.com";
     var currentSnippetToken;
     var currentSnippetToken;
@@ -8,7 +10,7 @@
     var refreshAnchor = document.getElementById("refresh");
     var refreshAnchor = document.getElementById("refresh");
     var editAnchor = document.getElementById("edit");
     var editAnchor = document.getElementById("edit");
     var scripts;
     var scripts;
-    var zipCode; // TO DO - Rewrite frame.js with classes ... And zipTool.js
+    var zipCode;
 
 
     if (location.href.toLowerCase().indexOf("noui") > -1) {
     if (location.href.toLowerCase().indexOf("noui") > -1) {
         fpsLabel.style.visibility = "hidden";
         fpsLabel.style.visibility = "hidden";

File diff suppressed because it is too large
+ 21 - 798
Playground/js/index.js


File diff suppressed because it is too large
+ 819 - 0
Playground/js/main.js


+ 53 - 19
Playground/js/menuPG.js

@@ -2,7 +2,9 @@
  * This JS file is for UI displaying
  * This JS file is for UI displaying
  */
  */
 class MenuPG {
 class MenuPG {
-    constructor() {
+    constructor(parent) {
+        this.parent = parent;
+
         this.allSelect = document.querySelectorAll('.select');
         this.allSelect = document.querySelectorAll('.select');
         this.allToDisplay = document.querySelectorAll('.toDisplay');
         this.allToDisplay = document.querySelectorAll('.toDisplay');
         this.allToDisplayBig = document.querySelectorAll('.toDisplayBig');
         this.allToDisplayBig = document.querySelectorAll('.toDisplayBig');
@@ -12,6 +14,7 @@ class MenuPG {
 
 
         this.jsEditorElement = document.getElementById('jsEditor');
         this.jsEditorElement = document.getElementById('jsEditor');
         this.canvasZoneElement = document.getElementById('canvasZone');
         this.canvasZoneElement = document.getElementById('canvasZone');
+        this.switchWrapper = document.getElementById('switchWrapper');
         this.switchWrapperCode = document.getElementById('switchWrapperCode');
         this.switchWrapperCode = document.getElementById('switchWrapperCode');
         this.switchWrapperCanvas = document.getElementById('switchWrapperCanvas');
         this.switchWrapperCanvas = document.getElementById('switchWrapperCanvas');
         this.fpsLabelElement = document.getElementById('fpsLabel');
         this.fpsLabelElement = document.getElementById('fpsLabel');
@@ -31,17 +34,6 @@ class MenuPG {
             }
             }
         }.bind(this);
         }.bind(this);
 
 
-        // Click on BJS logo redirection to BJS homepage
-        let logos = document.getElementsByClassName('logo');
-        for (var i = 0; i < logos.length; i++) {
-            logos[i].addEventListener('click', function () {
-                window.open("https://babylonjs.com", "_target");
-            });
-        }
-
-        // On click anywhere, remove displayed options
-        window.addEventListener('click', this.removeallOptions);
-
         // In mobile mode, resize JSEditor and canvas
         // In mobile mode, resize JSEditor and canvas
         this.switchWrapperCode.addEventListener('click', this.resizeBigJsEditor.bind(this));
         this.switchWrapperCode.addEventListener('click', this.resizeBigJsEditor.bind(this));
         this.switchWrapperCanvas.addEventListener('click', this.resizeBigCanvas.bind(this));
         this.switchWrapperCanvas.addEventListener('click', this.resizeBigCanvas.bind(this));
@@ -79,8 +71,23 @@ class MenuPG {
             else this.exitFullPage();
             else this.exitFullPage();
         }.bind(this), false);
         }.bind(this), false);
 
 
+        // Click on BJS logo redirection to BJS homepage
+        let logos = document.getElementsByClassName('logo');
+        for (var i = 0; i < logos.length; i++) {
+            logos[i].addEventListener('click', function () {
+                window.open("https://babylonjs.com", "_target");
+            });
+        }
+
         // Message before unload
         // Message before unload
-        window.onbeforeunload = this.exitPrompt;
+        window.addEventListener('beforeunload', function () {
+            this.exitPrompt();
+        }.bind(this));
+
+        // On click anywhere, remove displayed options
+        window.addEventListener('click', function () {
+            this.removeAllOptions();
+        }.bind(this));
     }
     }
 
 
     /**
     /**
@@ -175,6 +182,7 @@ class MenuPG {
      * Remove displayed options
      * Remove displayed options
      */
      */
     removeAllOptions() {
     removeAllOptions() {
+        this.parent.examples.hideExamples();
         this.removeAllSubItems();
         this.removeAllSubItems();
 
 
         for (var index = 0; index < this.allToDisplay.length; index++) {
         for (var index = 0; index < this.allToDisplay.length; index++) {
@@ -198,6 +206,8 @@ class MenuPG {
         if (this.navBarMobile.offsetHeight > 0) {
         if (this.navBarMobile.offsetHeight > 0) {
             this.removeAllOptions();
             this.removeAllOptions();
             this.canvasZoneElement.style.width = '0';
             this.canvasZoneElement.style.width = '0';
+            this.switchWrapper.style.left = "";
+            this.switchWrapper.style.right = "0";
             this.switchWrapperCode.style.display = 'none';
             this.switchWrapperCode.style.display = 'none';
             this.fpsLabelElement.style.display = 'none';
             this.fpsLabelElement.style.display = 'none';
             this.jsEditorElement.style.width = '100%';
             this.jsEditorElement.style.width = '100%';
@@ -217,6 +227,8 @@ class MenuPG {
             document.getElementsByClassName('gutter-horizontal')[0].style.display = 'none';
             document.getElementsByClassName('gutter-horizontal')[0].style.display = 'none';
             this.switchWrapperCanvas.style.display = 'none';
             this.switchWrapperCanvas.style.display = 'none';
             this.canvasZoneElement.style.width = '100%';
             this.canvasZoneElement.style.width = '100%';
+            this.switchWrapper.style.left = "0";
+            this.switchWrapper.style.right = "";
             this.switchWrapperCode.style.display = 'block';
             this.switchWrapperCode.style.display = 'block';
             this.fpsLabelElement.style.display = 'block';
             this.fpsLabelElement.style.display = 'block';
         }
         }
@@ -238,7 +250,7 @@ class MenuPG {
     /**
     /**
      * Canvas full page
      * Canvas full page
      */
      */
-    goFullPage () {
+    goFullPage() {
         var canvasElement = document.getElementById("renderCanvas");
         var canvasElement = document.getElementById("renderCanvas");
         canvasElement.style.position = "absolute";
         canvasElement.style.position = "absolute";
         canvasElement.style.top = 0;
         canvasElement.style.top = 0;
@@ -248,20 +260,20 @@ class MenuPG {
     /**
     /**
      * Canvas exit full page
      * Canvas exit full page
      */
      */
-    exitFullPage () {
+    exitFullPage() {
         document.getElementById("renderCanvas").style.position = "relative";
         document.getElementById("renderCanvas").style.position = "relative";
         document.getElementById("renderCanvas").style.zIndex = 0;
         document.getElementById("renderCanvas").style.zIndex = 0;
     };
     };
     /**
     /**
      * Canvas full screen
      * Canvas full screen
      */
      */
-    goFullscreen (engine) {
+    goFullscreen(engine) {
         engine.switchFullscreen(true);
         engine.switchFullscreen(true);
     };
     };
     /**
     /**
      * Editor full screen
      * Editor full screen
      */
      */
-    editorGoFullscreen () {
+    editorGoFullscreen() {
         var editorDiv = document.getElementById("jsEditor");
         var editorDiv = document.getElementById("jsEditor");
         if (editorDiv.requestFullscreen) {
         if (editorDiv.requestFullscreen) {
             editorDiv.requestFullscreen();
             editorDiv.requestFullscreen();
@@ -276,7 +288,8 @@ class MenuPG {
     /**
     /**
      * Display the metadatas form
      * Display the metadatas form
      */
      */
-    displayMetadata () {
+    displayMetadata() {
+        this.removeAllOptions();
         document.getElementById("saveLayer").style.display = "block";
         document.getElementById("saveLayer").style.display = "block";
     };
     };
 
 
@@ -284,7 +297,8 @@ class MenuPG {
      * Navigation Overwrites
      * Navigation Overwrites
      */
      */
     // TO DO - Apply this when click on TS / JS button
     // TO DO - Apply this when click on TS / JS button
-    exitPrompt (e) {
+    // TO DO - Make it work with all sizes
+    exitPrompt(e) {
         var safeToggle = document.getElementById("safemodeToggle1280");
         var safeToggle = document.getElementById("safemodeToggle1280");
         if (safeToggle.classList.contains('checked')) {
         if (safeToggle.classList.contains('checked')) {
             e = e || window.event;
             e = e || window.event;
@@ -296,4 +310,24 @@ class MenuPG {
             return message;
             return message;
         }
         }
     };
     };
+
+    // TO DO - Make it work with all sizes
+    showQRCode() {
+        console.log("Plop");
+        $("#qrCodeImage1280").empty();
+        var playgroundCode = window.location.href.split("#");
+        playgroundCode.shift();
+        $("#qrCodeImage1280").qrcode({ text: "https://playground.babylonjs.com/frame.html#" + (playgroundCode.join("#")) });
+    };
+
+    /**
+     * Comes from "pbt.js"
+     */
+    // TO DO - Comment this correctly
+    showBJSPGMenu() {
+        var headings = document.getElementsByClassName('category');
+        for (var i = 0; i < headings.length; i++) {
+            headings[i].style.visibility = 'visible';
+        }
+    };
 };
 };

+ 14 - 14
Playground/js/monacoCreator.js

@@ -2,14 +2,14 @@
  * This JS file is for Monaco management
  * This JS file is for Monaco management
  */
  */
 class MonacoCreator {
 class MonacoCreator {
-    constructor() {
+    constructor(parent) {
+        this.parent = parent;
+        
         this.jsEditor = null;
         this.jsEditor = null;
         this.monacoMode = "javascript";
         this.monacoMode = "javascript";
         this.blockEditorChange = false;
         this.blockEditorChange = false;
 
 
         this.compilerTriggerTimeoutID = null;
         this.compilerTriggerTimeoutID = null;
-
-        this.loadMonaco();
     }
     }
 
 
     // ACCESSORS
     // ACCESSORS
@@ -56,11 +56,11 @@ class MonacoCreator {
                             monaco.languages.typescript.typescriptDefaults.addExtraLib(xhr.responseText, 'babylon.d.ts');
                             monaco.languages.typescript.typescriptDefaults.addExtraLib(xhr.responseText, 'babylon.d.ts');
                         }
                         }
 
 
-                        run();
-                    });
+                        this.parent.main.run();
+                    }.bind(this));
                 }
                 }
             }
             }
-        };
+        }.bind(this);
         xhr.send(null);
         xhr.send(null);
     };
     };
 
 
@@ -84,7 +84,7 @@ class MonacoCreator {
             automaticLayout: true,
             automaticLayout: true,
             scrollBeyondLastLine: false,
             scrollBeyondLastLine: false,
             readOnly: false,
             readOnly: false,
-            theme: settingsPG.vsTheme,
+            theme: this.parent.settingsPG.vsTheme,
             contextmenu: false,
             contextmenu: false,
             folding: true,
             folding: true,
             showFoldingControls: "always",
             showFoldingControls: "always",
@@ -97,8 +97,8 @@ class MonacoCreator {
         this.jsEditor = monaco.editor.create(document.getElementById('jsEditor'), editorOptions);
         this.jsEditor = monaco.editor.create(document.getElementById('jsEditor'), editorOptions);
         this.jsEditor.setValue(oldCode);
         this.jsEditor.setValue(oldCode);
         this.jsEditor.onKeyUp(function () {
         this.jsEditor.onKeyUp(function () {
-            utils.markDirty();
-        });
+            this.parent.utils.markDirty();
+        }.bind(this));
     };
     };
 
 
     /**
     /**
@@ -115,10 +115,10 @@ class MonacoCreator {
         var minimapToggle = document.getElementById("minimapToggle1280");
         var minimapToggle = document.getElementById("minimapToggle1280");
         if (minimapToggle.classList.contains('checked')) {
         if (minimapToggle.classList.contains('checked')) {
             this.jsEditor.updateOptions({ minimap: { enabled: false } });
             this.jsEditor.updateOptions({ minimap: { enabled: false } });
-            utils.setToMultipleID("minimapToggle", "innerHTML", 'Minimap <i class="fa fa-square" aria-hidden="true"></i>');
+            this.parent.utils.setToMultipleID("minimapToggle", "innerHTML", 'Minimap <i class="fa fa-square" aria-hidden="true"></i>');
         } else {
         } else {
             this.jsEditor.updateOptions({ minimap: { enabled: true } });
             this.jsEditor.updateOptions({ minimap: { enabled: true } });
-            utils.setToMultipleID("minimapToggle", "innerHTML", 'Minimap <i class="fa fa-check-square" aria-hidden="true"></i>');
+            this.parent.utils.setToMultipleID("minimapToggle", "innerHTML", 'Minimap <i class="fa fa-check-square" aria-hidden="true"></i>');
         }
         }
         minimapToggle.classList.toggle('checked');
         minimapToggle.classList.toggle('checked');
     };
     };
@@ -128,9 +128,9 @@ class MonacoCreator {
      * @param {Function} callBack : Function that will be called after retrieving the code.
      * @param {Function} callBack : Function that will be called after retrieving the code.
      */
      */
     getRunCode(callBack) {
     getRunCode(callBack) {
-        if (settingsPG.ScriptLanguage == "JS")
+        if (this.parent.settingsPG.ScriptLanguage == "JS")
             callBack(this.jsEditor.getValue());
             callBack(this.jsEditor.getValue());
-        else if (settingsPG.ScriptLanguage == "TS") {
+        else if (this.parent.settingsPG.ScriptLanguage == "TS") {
             this.triggerCompile(this.JsEditor.getValue(), function (result) {
             this.triggerCompile(this.JsEditor.getValue(), function (result) {
                 callBack(result + "var createScene = function() { return Playground.CreateScene(engine, engine.getRenderingCanvas()); }")
                 callBack(result + "var createScene = function() { return Playground.CreateScene(engine, engine.getRenderingCanvas()); }")
             });
             });
@@ -161,7 +161,7 @@ class MonacoCreator {
                 }
                 }
             }
             }
             catch (e) {
             catch (e) {
-                utils.showError(e.message, e);
+                this.parent.utils.showError(e.message, e);
             }
             }
         }.bind(this), 100);
         }.bind(this), 100);
     };
     };

+ 0 - 8
Playground/js/pbt.js

@@ -521,12 +521,4 @@ var PBT = function() {
     }
     }
 }
 }
 
 
-showBJSPGMenu = function() {
-    var headings = document.getElementsByClassName('category');
-    
-    for (var i = 0; i < headings.length; i ++) {
-        headings[i].style.visibility = 'visible';
-    }
-}
-
     
     

+ 16 - 18
Playground/js/settingsPG.js

@@ -4,13 +4,11 @@
  * - Script language
  * - Script language
  * - Font size
  * - Font size
  */
  */
-/**
- * TO DO :
- * - Set the font in the localStorage
- */
 class SettingsPG {
 class SettingsPG {
-    constructor(monacoCreator) {
-        this.monacoCreator = monacoCreator;
+    constructor(parent) {
+        this.parent = parent;
+
+        // TO DO - Set the fond in the localStorage (same as theme and language)
 
 
         // The elements that will color with languages
         // The elements that will color with languages
         this.elementForscriptLanguage = [
         this.elementForscriptLanguage = [
@@ -37,11 +35,11 @@ class SettingsPG {
         this.defaultScene = "scripts/basic scene.js";
         this.defaultScene = "scripts/basic scene.js";
         if(this.scriptLanguage == "JS") {
         if(this.scriptLanguage == "JS") {
             this.defaultScene = "scripts/basic scene.js";
             this.defaultScene = "scripts/basic scene.js";
-            monacoCreator.monacoMode = "javascript";
+            this.parent.monacoCreator.monacoMode = "javascript";
         }
         }
         else if(this.scriptLanguage == "TS") {
         else if(this.scriptLanguage == "TS") {
             this.defaultScene = "scripts/basic scene.txt";
             this.defaultScene = "scripts/basic scene.txt";
-            monacoCreator.monacoMode = "typescript";
+            this.parent.monacoCreator.monacoMode = "typescript";
         }
         }
     }
     }
 
 
@@ -62,7 +60,7 @@ class SettingsPG {
      */
      */
     setFontSize(size) {
     setFontSize(size) {
         this.fontSize = size;
         this.fontSize = size;
-        this.monacoCreator.jsEditor.updateOptions({ fontSize: size });
+        this.parent.monacoCreator.jsEditor.updateOptions({ fontSize: size });
         var array = document.getElementsByClassName("displayFontSize");
         var array = document.getElementsByClassName("displayFontSize");
         for (var i = 0; i < array.length; i++) {
         for (var i = 0; i < array.length; i++) {
             var subArray = array[i].children;
             var subArray = array[i].children;
@@ -88,10 +86,10 @@ class SettingsPG {
             }
             }
         }
         }
         if (this.scriptLanguage == "JS") {
         if (this.scriptLanguage == "JS") {
-            utils.setToMultipleID("toJSbutton", "removeClass", "floatLeft");
+            this.parent.utils.setToMultipleID("toJSbutton", "removeClass", "floatLeft");
         }
         }
         else if (this.scriptLanguage == "TS") {
         else if (this.scriptLanguage == "TS") {
-            utils.setToMultipleID("toJSbutton", "addClass", "floatLeft");
+            this.parent.utils.setToMultipleID("toJSbutton", "addClass", "floatLeft");
         }
         }
     };
     };
     /**
     /**
@@ -101,18 +99,18 @@ class SettingsPG {
         localStorage.setItem("bjs-playground-theme", theme);
         localStorage.setItem("bjs-playground-theme", theme);
         // Get the Monaco theme name.
         // Get the Monaco theme name.
         // Change the selected button style
         // Change the selected button style
-        utils.setToMultipleID("darkTheme", "removeClass", "selected");
-        utils.setToMultipleID("lightTheme", "removeClass", "selected");
+        this.parent.utils.setToMultipleID("darkTheme", "removeClass", "selected");
+        this.parent.utils.setToMultipleID("lightTheme", "removeClass", "selected");
         if (theme == 'dark') {
         if (theme == 'dark') {
             this.vsTheme = 'vs-dark';
             this.vsTheme = 'vs-dark';
-            utils.setToMultipleID("darkTheme", "addClass", "selected");
+            this.parent.utils.setToMultipleID("darkTheme", "addClass", "selected");
         }
         }
         else {
         else {
             this.vsTheme = 'vs';
             this.vsTheme = 'vs';
-            utils.setToMultipleID("lightTheme", "addClass", "selected");
+            this.parent.utils.setToMultipleID("lightTheme", "addClass", "selected");
         }
         }
 
 
-        this.monacoCreator.createMonacoEditor();
+        this.parent.monacoCreator.createMonacoEditor();
 
 
         this.setFontSize(this.fontSize);
         this.setFontSize(this.fontSize);
         // Color the elements to theme
         // Color the elements to theme
@@ -127,7 +125,7 @@ class SettingsPG {
             }
             }
         }
         }
     };
     };
-    restoreTheme(monacoCreator) {
-        this.setTheme(this.vsTheme, monacoCreator);
+    restoreTheme() {
+        this.setTheme(this.vsTheme, this.parent.monacoCreator);
     };
     };
 };
 };

+ 0 - 56
Playground/js/ts.js

@@ -1,56 +0,0 @@
-
-// var compilerTriggerTimeoutID;
-// function triggerCompile(d, func) {
-//     if (compilerTriggerTimeoutID !== null) {
-//         window.clearTimeout(compilerTriggerTimeoutID);
-//     }
-//     compilerTriggerTimeoutID = window.setTimeout(function () {
-//         try {
-             
-//             var output = transpileModule(d, {
-//                 module: ts.ModuleKind.AMD,
-//                 target: ts.ScriptTarget.ES5,
-//                 noLib: true,
-//                 noResolve: true,
-//                 suppressOutputPathCheck: true
-//             });
-//             if (typeof output === "string") {
-//                 func(output);
-//             }
-//         }
-//         catch (e) {
-//             showError(e.message, e);
-//         }
-//     }, 100);
-// }
-// function transpileModule(input, options) {
-//     var inputFileName = options.jsx ? "module.tsx" : "module.ts";
-//     var sourceFile = ts.createSourceFile(inputFileName, input, options.target || ts.ScriptTarget.ES5);
-//     // Output
-//     var outputText;
-//     var program = ts.createProgram([inputFileName], options, {
-//         getSourceFile: function (fileName) { return fileName.indexOf("module") === 0 ? sourceFile : undefined; },
-//         writeFile: function (_name, text) { outputText = text; },
-//         getDefaultLibFileName: function () { return "lib.d.ts"; },
-//         useCaseSensitiveFileNames: function () { return false; },
-//         getCanonicalFileName: function (fileName) { return fileName; },
-//         getCurrentDirectory: function () { return ""; },
-//         getNewLine: function () { return "\r\n"; },
-//         fileExists: function (fileName) { return fileName === inputFileName; },
-//         readFile: function () { return ""; },
-//         directoryExists: function () { return true; },
-//         getDirectories: function () { return []; }
-//     });
-//     // Emit
-//     program.emit();
-//     if (outputText === undefined) {
-//         throw new Error("Output generation failed");
-//     }
-//     return outputText;
-// }
-
-// function getRunCode(jsEditor, callBack) {
-//     triggerCompile(jsEditor.getValue(), function(result) {
-//         callBack(result + "var createScene = function() { return Playground.CreateScene(engine, engine.getRenderingCanvas()); }")
-//     });
-// }

+ 15 - 6
Playground/js/utils.js

@@ -2,17 +2,17 @@
  * This JS file contains utils functions
  * This JS file contains utils functions
  */
  */
 class Utils {
 class Utils {
-    constructor() {
+    constructor(parent) {
+        this.parent = parent;
+        
         this.multipleSize = [1280, 1024, 'Mobile'];
         this.multipleSize = [1280, 1024, 'Mobile'];
     }
     }
 
 
-    // TO DO - Comment this
+    // TO DO - Comment this correctly
     markDirty() {
     markDirty() {
-        if (monacoCreator.BlockEditorChange) return;
+        if (this.parent.monacoCreator.BlockEditorChange) return;
 
 
-        // setToMultipleID("currentScript", "innerHTML", "Custom");
-        this.setToMultipleID("safemodeToggle", "addClass", "checked");
-        // setToMultipleID("minimapToggle", "addClass", "checked"); // Why ?!
+        this.setToMultipleID("safemodeToggle", "addClass", "checked");!
         this.setToMultipleID('safemodeToggle', 'innerHTML', 'Safe mode <i class="fa fa-check-square" aria-hidden="true"></i>');
         this.setToMultipleID('safemodeToggle', 'innerHTML', 'Safe mode <i class="fa fa-check-square" aria-hidden="true"></i>');
     };
     };
 
 
@@ -76,4 +76,13 @@ class Utils {
             }
             }
         });
         });
     };
     };
+
+    /**
+     * Function to get the current screen size
+     */
+    getCurrentSize() {
+        for(var i = 0; i < this.multipleSize.length; i++) {
+            if(document.getElementById("menuButton" + this.multipleSize[i]).offsetHeight > 0) return this.multipleSize[i];
+        }
+    };
 }
 }

+ 5 - 3
Playground/js/zipTool.js

@@ -1,8 +1,10 @@
 /**
 /**
  * This JS file contains the ZIP tools
  * This JS file contains the ZIP tools
  */
  */
-class zipTool {
-    constructor() {
+class ZipTool {
+    constructor(parent) {
+        this.parent = parent;
+        
         this.zipCode;
         this.zipCode;
     }
     }
 
 
@@ -107,7 +109,7 @@ class zipTool {
                 true,
                 true,
                 function () {
                 function () {
                     this.addTexturesToZip(zip, index + 1, textures, folder, then);
                     this.addTexturesToZip(zip, index + 1, textures, folder, then);
-                });
+                }.bind(this));
         }
         }
         else {
         else {
             this.addTexturesToZip(zip, index + 1, textures, folder, then);
             this.addTexturesToZip(zip, index + 1, textures, folder, then);

+ 1 - 1
Playground/test.html

@@ -1,4 +1,4 @@
-<!-- TO DO : What is this ? -->
+<!-- TO DO - What is the purpose of this page ? -->
 
 
 <div class="navbar-inner" id="topbar">
 <div class="navbar-inner" id="topbar">
     <a class="brand largeOnly" href="#" id="mainTitle">Babylon.js Playground</a>
     <a class="brand largeOnly" href="#" id="mainTitle">Babylon.js Playground</a>

+ 0 - 496
Playground/ts-local.html

@@ -1,496 +0,0 @@
-<!DOCTYPE html>
-<html>
-
-<!--
-    // TO DO - Delete this ? It's not used anymore. It's now included in the index.html with a switch button JS / TS
- -->
-
-<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/favicon.ico">
-
-    <link rel="stylesheet" href="https://use.typekit.net/cta4xsb.css">
-
-    <script src="js/libs/pep.min.js"></script>
-    <!--For canvas/code separator-->
-    <script src="js/libs/split.js"></script>
-
-    <script src="js/libs/dat.gui.min.js"></script>
-    <!-- jszip -->
-    <script src="js/libs/jszip.min.js"></script>
-    <script src="js/libs/fileSaver.js"></script>
-    <!-- Dependencies -->
-    <script src="../dist/preview%20release/ammo.js"></script>
-    <script src="../dist/preview%20release/cannon.js"></script>
-    <script src="../dist/preview%20release/Oimo.js"></script>
-    <script src="../dist/preview%20release/gltf_validator.js"></script>
-    <script src="../dist/preview%20release/earcut.min.js"></script>
-    <!-- Babylon.js -->
-    <script src="../dist/preview%20release/babylon.js"></script>
-    <script src="../dist/preview%20release/gui/babylon.gui.min.js"></script>
-    <script src="../dist/preview%20release/inspector/babylon.inspector.bundle.js"></script>
-    <script src="../dist/preview%20release/materialsLibrary/babylonjs.materials.min.js"></script>
-    <script src="../dist/preview%20release/proceduralTexturesLibrary/babylonjs.proceduralTextures.min.js"></script>
-    <script src="../dist/preview%20release/postProcessesLibrary/babylonjs.postProcess.min.js"></script>
-    <script src="../dist/preview%20release/loaders/babylonjs.loaders.min.js"></script>
-    <script src="../dist/preview%20release/serializers/babylonjs.serializers.min.js"></script>
-
-    <!-- Monaco -->
-    <script src="node_modules/monaco-editor/min/vs/loader.js"></script>
-
-    <!-- Extensions -->
-    <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>
-
-    <!-- Scene Manager -->
-    <script src="https://mackeyk24.github.io/toolkit/babylon.manager.js"></script>
-    <script src="https://mackeyk24.github.io/toolkit/babylon.navmesh.js"></script>
-
-    <link href="css/index.css" rel="stylesheet" />
-    <link href="css/color_ts.css" rel="stylesheet" />
-</head>
-
-<body>
-    <div class="navbar navBar1600">
-        <div class="title">
-            Babylon.js Playground
-        </div>
-        <div class="version" id="mainTitle">
-        </div>
-
-        <div class="category">
-            <div class="button run" id="runButton1600">Run
-                <i class="fa fa-play" aria-hidden="true"></i>
-            </div>
-        </div>
-
-
-        <div class="category">
-            <div class="button" id="newButton1600">New
-                <i class="fa fa-file" aria-hidden="true"></i>
-            </div>
-            <div class="button removeOnPhone" id="clearButton1600">Clear
-                <i class="fa fa-trash" aria-hidden="true"></i>
-            </div>
-        </div>
-
-        <div class="category">
-            <div class="button" id="saveButton1600">Save
-                <i class="fa fa-floppy-o" aria-hidden="true"></i>
-            </div>
-            <div class="button removeOnPhone" id="zipButton1600">Zip
-                <i class="fa fa-download" aria-hidden="true"></i>
-            </div>
-        </div>
-
-        <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 class="option subSelect">
-                        <span id="currentFontSize1600">Font: 14</span>
-                        <i class="fa fa-chevron-right" aria-hidden="true"></i>
-                        <div class="toDisplaySub">
-                            <div class="option" onclick="setFontSize(12);">12</div>
-                            <div class="option" onclick="setFontSize(14);">14</div>
-                            <div class="option" onclick="setFontSize(16);">16</div>
-                            <div class="option" onclick="setFontSize(18);">18</div>
-                            <div class="option" onclick="setFontSize(20);">20</div>
-                            <div class="option" onclick="setFontSize(22);">22</div>
-                        </div>
-                    </div>
-                    <div class="option" id="safemodeToggle1600">Safe mode
-                        <i class="far fa-square" aria-hidden="true"></i>
-                    </div>
-                    <div class="option checked" id="editorButton1600">Editor
-                        <i class="fa fa-check-square" aria-hidden="true"></i>
-                    </div>
-                    <div class="option" id="fullscreenButton1600">Fullscreen</div>
-                    <div class="option" id="editorFullscreenButton1600">Editor Fullscreen</div>
-                    <div class="option" id="formatButton1600">Format code</div>
-                    <div class="option" id="minimapToggle1600">Minimap
-                        <i class="far fa-square" aria-hidden="true"></i>
-                    </div>
-                    <div class="option subSelect" id="qrCodeHover" onmouseover="showQRCode();">QR Code Link
-                        <i class="fa fa-chevron-right" aria-hidden="true"></i>
-                        <div class="toDisplaySub">
-                            <div class="option" style="height:auto;padding: 20px;background: white;" id="qrCodeImage">QR
-                                Code Image</div>
-                        </div>
-                    </div>
-                </div>
-            </div>
-
-            <div class="button uncheck" id="debugButton1600">Inspector</div>
-            <div class="button" id="metadataButton1600">Metadata</div>
-        </div>
-
-
-
-        <div class="category right">
-            <div class="button select">
-                <span id="currentVersion1600">Version: Latest</span>
-                <div class="toDisplay">
-                    <div class="option" onclick="setVersion('latest');">Latest</div>
-                    <div class="option" onclick="setVersion('stable');">Stable</div>
-                </div>
-            </div>
-            <div class="button select">
-                <span class="examplesButton">Examples</span>
-            </div>
-        </div>
-    </div>
-
-    <div class="navbar navBar1475">
-        <div class="title">
-            Babylon.js Playground
-        </div>
-        <div class="version" id="mainTitle">
-        </div>
-
-        <div class="category">
-            <div class="button run" id="runButton1475">Run
-                <i class="fa fa-play" aria-hidden="true"></i>
-            </div>
-        </div>
-
-
-        <div class="category">
-            <div class="button" id="newButton1475">New
-                <i class="fa fa-file" aria-hidden="true"></i>
-            </div>
-            <div class="button removeOnPhone" id="clearButton1475">Clear
-                <i class="fa fa-trash" aria-hidden="true"></i>
-            </div>
-        </div>
-
-        <div class="category">
-            <div class="button" id="saveButton1475">Save
-                <i class="fa fa-floppy-o" aria-hidden="true"></i>
-            </div>
-            <div class="button removeOnPhone" id="zipButton1475">Zip
-                <i class="fa fa-download" aria-hidden="true"></i>
-            </div>
-        </div>
-
-        <div class="category">
-            <div class="button select">Settings
-                <div class="toDisplay">
-                    <div class="option subSelect">Theme
-                        <i class="fa fa-chevron-right" aria-hidden="true"></i>
-                        <div class="toDisplaySub">
-                            <div class="option" id="darkTheme1475">Dark</div>
-                            <div class="option" id="lightTheme1475">Light</div>
-                        </div>
-                    </div>
-                    <div class="option subSelect">
-                        <span id="currentFontSize1475">Font: 14</span>
-                        <i class="fa fa-chevron-right" aria-hidden="true"></i>
-                        <div class="toDisplaySub">
-                            <div class="option" onclick="setFontSize(12);">12</div>
-                            <div class="option" onclick="setFontSize(14);">14</div>
-                            <div class="option" onclick="setFontSize(16);">16</div>
-                            <div class="option" onclick="setFontSize(18);">18</div>
-                            <div class="option" onclick="setFontSize(20);">20</div>
-                            <div class="option" onclick="setFontSize(22);">22</div>
-                        </div>
-                    </div>
-                    <div class="option" id='safemodeToggle1475'>Safe mode
-                        <i class="far fa-square" aria-hidden="true"></i>
-                    </div>
-                    <div class="option checked" id="editorButton1475">Editor
-                        <i class="fa fa-check-square" aria-hidden="true"></i>
-                    </div>
-                    <div class="option" id="fullscreenButton1475">Fullscreen</div>
-                    <div class="option" id="editorFullscreenButton1475">Editor Fullscreen</div>
-                    <div class="option" id="formatButton1475">Format code</div>
-                    <div class="option" id="minimapToggle1475">Minimap
-                        <i class="far fa-square" aria-hidden="true"></i>
-                    </div>
-                    <div class="option" id="debugButton1475">Inspector</div>
-                    <div class="option" id="metadataButton1475">Metadata</div>
-                    <div class="option subSelect">
-                        <span id="currentVersion1475">Vers. : Latest</span>
-                        <i class="fa fa-chevron-right" aria-hidden="true"></i>
-                        <div class="toDisplaySub">
-                            <div class="option" onclick="setVersion('latest');">Latest</div>
-                            <div class="option" onclick="setVersion('stable');">Stable</div>
-                        </div>
-                    </div>
-                </div>
-            </div>
-        </div>
-
-        <div class="category right">
-            <div class="button select">
-                <span class="examplesButton">Examples</span>
-            </div>
-        </div>
-    </div>
-
-    <div class="navbar navBar1030">
-        <div class="category">
-            <div class="button run" id="runButton1030">Run
-                <i class="fa fa-play" aria-hidden="true"></i>
-            </div>
-        </div>
-
-
-        <div class="category">
-            <div class="button" id="newButton1030">New
-                <i class="fa fa-file" aria-hidden="true"></i>
-            </div>
-            <div class="button removeOnPhone" id="clearButton1030">Clear
-                <i class="fa fa-trash" aria-hidden="true"></i>
-            </div>
-        </div>
-
-        <div class="category">
-            <div class="button" id="saveButton1030">Save
-                <i class="fa fa-floppy-o" aria-hidden="true"></i>
-            </div>
-            <div class="button removeOnPhone" id="zipButton1030">Zip
-                <i class="fa fa-download" aria-hidden="true"></i>
-            </div>
-        </div>
-
-        <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 class="option subSelect">
-                        <span id="currentFontSize1030">Font: 14</span>
-                        <i class="fa fa-chevron-right" aria-hidden="true"></i>
-                        <div class="toDisplaySub">
-                            <div class="option" onclick="setFontSize(12);">12</div>
-                            <div class="option" onclick="setFontSize(14);">14</div>
-                            <div class="option" onclick="setFontSize(16);">16</div>
-                            <div class="option" onclick="setFontSize(18);">18</div>
-                            <div class="option" onclick="setFontSize(20);">20</div>
-                            <div class="option" onclick="setFontSize(22);">22</div>
-                        </div>
-                    </div>
-                    <div class="option" id="safemodeToggle1030">Safe mode
-                        <i class="far fa-square" aria-hidden="true"></i>
-                    </div>
-                    <div class="option checked" id="editorButton1030">Editor
-                        <i class="fa fa-check-square" aria-hidden="true"></i>
-                    </div>
-                    <div class="option" id="fullscreenButton1030">Fullscreen</div>
-                    <div class="option" id="editorFullscreenButton1030">Editor Fullscreen</div>
-                    <div class="option" id="formatButton1030">Format code</div>
-                    <div class="option" id="minimapToggle1030">Minimap
-                        <i class="far fa-square" aria-hidden="true"></i>
-                    </div>
-                    <div class="option" id="debugButton1030">Inspector</div>
-                    <div class="option" id="metadataButton1030">Metadata</div>
-                    <div class="option subSelect">
-                        <span id="currentVersion1030">Vers. : Latest</span>
-                        <i class="fa fa-chevron-right" aria-hidden="true"></i>
-                        <div class="toDisplaySub">
-                            <div class="option" onclick="setVersion('latest');">Latest</div>
-                            <div class="option" onclick="setVersion('stable');">Stable</div>
-                        </div>
-                    </div>
-                </div>
-            </div>
-        </div>
-
-        <div class="category right">
-            <div class="button select">
-                <span class="examplesButton">Examples</span>
-            </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>
-                </div>
-            </div>
-        </div>
-
-        <div class="category">
-            <div class="button select">Settings
-                <div class="toDisplay">
-                    <div class="option subSelect">Theme
-                        <i class="fa fa-chevron-right" aria-hidden="true"></i>
-                        <div class="toDisplaySub">
-                            <div class="option" id="darkTheme750">Dark</div>
-                            <div class="option" id="lightTheme750">Light</div>
-                        </div>
-                    </div>
-                    <div class="option subSelect">
-                        <span id="currentFontSize750">Font: 14</span>
-                        <i class="fa fa-chevron-right" aria-hidden="true"></i>
-                        <div class="toDisplaySub">
-                            <div class="option" onclick="setFontSize(12);">12</div>
-                            <div class="option" onclick="setFontSize(14);">14</div>
-                            <div class="option" onclick="setFontSize(16);">16</div>
-                            <div class="option" onclick="setFontSize(18);">18</div>
-                            <div class="option" onclick="setFontSize(20);">20</div>
-                            <div class="option" onclick="setFontSize(22);">22</div>
-                        </div>
-                    </div>
-                    <div class="option" id="safemodeToggle750">Safe mode
-                        <i class="far fa-square" aria-hidden="true"></i>
-                    </div>
-                    <div style="display:none;" class="option checked" id="editorButton750">Editor
-                        <i class="fa fa-check-square" aria-hidden="true"></i>
-                    </div>
-                    <div class="option" id="fullscreenButton750">Fullscreen</div>
-                    <div class="option" id="editorFullscreenButton750">Editor Fullscreen</div>
-                    <div class="option" id="formatButton750">Format code</div>
-                    <div class="option" id="minimapToggle750">Minimap
-                        <i class="far fa-square" aria-hidden="true"></i>
-                    </div>
-                    <div class="option" id="debugButton750">Inspector</div>
-                    <div class="option" id="metadataButton750">Metadata</div>
-                    <div class="option subSelect">
-                        <span id="currentVersion750">Vers. : Latest</span>
-                        <i class="fa fa-chevron-right" aria-hidden="true"></i>
-                        <div class="toDisplaySub">
-                            <div class="option" onclick="setVersion('latest');">Latest</div>
-                            <div class="option" onclick="setVersion('stable');">Stable</div>
-                        </div>
-                    </div>
-                </div>
-            </div>
-        </div>
-
-        <div class="category right">
-            <div class="button select">
-                <span id="currentScript750">Examples</span>
-            </div>
-        </div>
-    </div>
-
-    <div class="wrapper">
-        <div id="jsEditor"></div>
-        <div id="canvasZone">
-            <canvas touch-action="none" id="renderCanvas"></canvas>
-        </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>
-
-    <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="https://forum.babylonjs.com/">Forum</a>
-            </div>
-            <div class='link'>
-                <a target='_new' href="https://www.babylonjs.com/sandbox">Sandbox</a>
-            </div>
-            <div class='link'>
-                <a target='_new' href="https://doc.babylonjs.com">Documentation</a>
-            </div>
-            <div class='link'>
-                <a target='_new' href="https://doc.babylonjs.com/playground">Search</a>
-            </div>
-        </div>
-    </div>
-
-    <div id="saveLayer" class="save-layer">
-        <div class="save-form">
-            <label for="saveFormTitle">TITLE</label>
-            <div class="separator"></div>
-            <input type="text" maxlength="120" id="saveFormTitle" class="save-form-title">
-
-            <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>
-
-            <div class="save-form-buttons" id="saveFormButtons">
-
-                <div id="saveFormButtonOk" class="button">OK</div>
-                <div id="saveFormButtonCancel" class="button">Cancel</div>
-            </div>
-        </div>
-    </div>
-
-    <div id="waitDiv">
-        <span id="waitTitle">Babylon.js Playground
-            <BR>
-            <BR>
-            <BR>
-        </span>
-        <div id="logo-part">
-            <img src="v4.svg" id="waitLogo" />
-            <img src="spinner.svg" id="waitSpinner" />
-        </div>
-    </div>
-
-    <script src="js/libs/jquery.min.js"></script>
-    <script src="js/jquery.qrcode.js"></script>
-    <script src="js/qrcode.js"></script>
-
-    <script src="js/actions.js"></script>
-    <script src="js/pbt.js"></script>
-    <script src="js/libs/typescript.js"></script>
-    <script src="js/index.js"></script>
-    <script src="js/ts.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());
-
-        gtag('config', 'UA-41767310-2');
-    </script>
-</body>
-
-</html>

+ 4 - 496
Playground/ts.html

@@ -1,496 +1,4 @@
-<!DOCTYPE html>
-<html>
-
-<!--
-    // TO DO - Delete this ? It's not used anymore. It's now included in the index.html with a switch button JS / TS
- -->
-
-<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/favicon.ico">
-
-    <link rel="stylesheet" href="https://use.typekit.net/cta4xsb.css">
-
-    <script src="js/libs/pep.min.js"></script>
-    <!--For canvas/code separator-->
-    <script src="js/libs/split.js"></script>
-
-    <script src="js/libs/dat.gui.min.js"></script>
-    <!-- jszip -->
-    <script src="js/libs/jszip.min.js"></script>
-    <script src="js/libs/fileSaver.js"></script>
-    <!-- Dependencies -->
-    <script src="https://preview.babylonjs.com/ammo.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/gltf_validator.js"></script>
-    <script src="https://preview.babylonjs.com/earcut.min.js"></script>
-    <!-- Babylon.js -->
-    <script src="https://preview.babylonjs.com/babylon.js"></script>
-    <script src="https://preview.babylonjs.com/gui/babylon.gui.min.js"></script>
-    <script src="https://preview.babylonjs.com/inspector/babylon.inspector.bundle.js"></script>
-    <script src="https://preview.babylonjs.com/materialsLibrary/babylonjs.materials.min.js"></script>
-    <script src="https://preview.babylonjs.com/proceduralTexturesLibrary/babylonjs.proceduralTextures.min.js"></script>
-    <script src="https://preview.babylonjs.com/postProcessesLibrary/babylonjs.postProcess.min.js"></script>
-    <script src="https://preview.babylonjs.com/loaders/babylonjs.loaders.min.js"></script>
-    <script src="https://preview.babylonjs.com/serializers/babylonjs.serializers.min.js"></script>
-
-    <!-- Monaco -->
-    <script src="node_modules/monaco-editor/min/vs/loader.js"></script>
-
-    <!-- Extensions -->
-    <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>
-
-    <!-- Scene Manager -->
-    <script src="https://mackeyk24.github.io/toolkit/babylon.manager.js"></script>
-    <script src="https://mackeyk24.github.io/toolkit/babylon.navmesh.js"></script>
-
-    <link href="css/index.css" rel="stylesheet" />
-    <link href="css/color_ts.css" rel="stylesheet" />
-</head>
-
-<body>
-    <div class="navbar navBar1600">
-        <div class="title">
-            Babylon.js Playground
-        </div>
-        <div class="version" id="mainTitle">
-        </div>
-
-        <div class="category">
-            <div class="button run" id="runButton1600">Run
-                <i class="fa fa-play" aria-hidden="true"></i>
-            </div>
-        </div>
-
-
-        <div class="category">
-            <div class="button" id="newButton1600">New
-                <i class="fa fa-file" aria-hidden="true"></i>
-            </div>
-            <div class="button removeOnPhone" id="clearButton1600">Clear
-                <i class="fa fa-trash" aria-hidden="true"></i>
-            </div>
-        </div>
-
-        <div class="category">
-            <div class="button" id="saveButton1600">Save
-                <i class="fa fa-floppy-o" aria-hidden="true"></i>
-            </div>
-            <div class="button removeOnPhone" id="zipButton1600">Zip
-                <i class="fa fa-download" aria-hidden="true"></i>
-            </div>
-        </div>
-
-        <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 class="option subSelect">
-                        <span id="currentFontSize1600">Font: 14</span>
-                        <i class="fa fa-chevron-right" aria-hidden="true"></i>
-                        <div class="toDisplaySub">
-                            <div class="option" onclick="setFontSize(12);">12</div>
-                            <div class="option" onclick="setFontSize(14);">14</div>
-                            <div class="option" onclick="setFontSize(16);">16</div>
-                            <div class="option" onclick="setFontSize(18);">18</div>
-                            <div class="option" onclick="setFontSize(20);">20</div>
-                            <div class="option" onclick="setFontSize(22);">22</div>
-                        </div>
-                    </div>
-                    <div class="option" id="safemodeToggle1600">Safe mode
-                        <i class="far fa-square" aria-hidden="true"></i>
-                    </div>
-                    <div class="option checked" id="editorButton1600">Editor
-                        <i class="fa fa-check-square" aria-hidden="true"></i>
-                    </div>
-                    <div class="option" id="fullscreenButton1600">Fullscreen</div>
-                    <div class="option" id="editorFullscreenButton1600">Editor Fullscreen</div>
-                    <div class="option" id="formatButton1600">Format code</div>
-                    <div class="option" id="minimapToggle1600">Minimap
-                        <i class="far fa-square" aria-hidden="true"></i>
-                    </div>
-                    <div class="option subSelect" id="qrCodeHover" onmouseover="showQRCode();">QR Code Link
-                        <i class="fa fa-chevron-right" aria-hidden="true"></i>
-                        <div class="toDisplaySub">
-                            <div class="option" style="height:auto;padding: 20px;background: white;" id="qrCodeImage">QR
-                                Code Image</div>
-                        </div>
-                    </div>
-                </div>
-            </div>
-
-            <div class="button uncheck" id="debugButton1600">Inspector</div>
-            <div class="button" id="metadataButton1600">Metadata</div>
-        </div>
-
-
-
-        <div class="category right">
-            <div class="button select">
-                <span id="currentVersion1600">Version: Latest</span>
-                <div class="toDisplay">
-                    <div class="option" onclick="setVersion('latest');">Latest</div>
-                    <div class="option" onclick="setVersion('stable');">Stable</div>
-                </div>
-            </div>
-            <div class="button select">
-                <span class="examplesButton">Examples</span>
-            </div>
-        </div>
-    </div>
-
-    <div class="navbar navBar1475">
-        <div class="title">
-            Babylon.js Playground
-        </div>
-        <div class="version" id="mainTitle">
-        </div>
-
-        <div class="category">
-            <div class="button run" id="runButton1475">Run
-                <i class="fa fa-play" aria-hidden="true"></i>
-            </div>
-        </div>
-
-
-        <div class="category">
-            <div class="button" id="newButton1475">New
-                <i class="fa fa-file" aria-hidden="true"></i>
-            </div>
-            <div class="button removeOnPhone" id="clearButton1475">Clear
-                <i class="fa fa-trash" aria-hidden="true"></i>
-            </div>
-        </div>
-
-        <div class="category">
-            <div class="button" id="saveButton1475">Save
-                <i class="fa fa-floppy-o" aria-hidden="true"></i>
-            </div>
-            <div class="button removeOnPhone" id="zipButton1475">Zip
-                <i class="fa fa-download" aria-hidden="true"></i>
-            </div>
-        </div>
-
-        <div class="category">
-            <div class="button select">Settings
-                <div class="toDisplay">
-                    <div class="option subSelect">Theme
-                        <i class="fa fa-chevron-right" aria-hidden="true"></i>
-                        <div class="toDisplaySub">
-                            <div class="option" id="darkTheme1475">Dark</div>
-                            <div class="option" id="lightTheme1475">Light</div>
-                        </div>
-                    </div>
-                    <div class="option subSelect">
-                        <span id="currentFontSize1475">Font: 14</span>
-                        <i class="fa fa-chevron-right" aria-hidden="true"></i>
-                        <div class="toDisplaySub">
-                            <div class="option" onclick="setFontSize(12);">12</div>
-                            <div class="option" onclick="setFontSize(14);">14</div>
-                            <div class="option" onclick="setFontSize(16);">16</div>
-                            <div class="option" onclick="setFontSize(18);">18</div>
-                            <div class="option" onclick="setFontSize(20);">20</div>
-                            <div class="option" onclick="setFontSize(22);">22</div>
-                        </div>
-                    </div>
-                    <div class="option" id='safemodeToggle1475'>Safe mode
-                        <i class="far fa-square" aria-hidden="true"></i>
-                    </div>
-                    <div class="option checked" id="editorButton1475">Editor
-                        <i class="fa fa-check-square" aria-hidden="true"></i>
-                    </div>
-                    <div class="option" id="fullscreenButton1475">Fullscreen</div>
-                    <div class="option" id="editorFullscreenButton1475">Editor Fullscreen</div>
-                    <div class="option" id="formatButton1475">Format code</div>
-                    <div class="option" id="minimapToggle1475">Minimap
-                        <i class="far fa-square" aria-hidden="true"></i>
-                    </div>
-                    <div class="option" id="debugButton1475">Inspector</div>
-                    <div class="option" id="metadataButton1475">Metadata</div>
-                    <div class="option subSelect">
-                        <span id="currentVersion1475">Vers. : Latest</span>
-                        <i class="fa fa-chevron-right" aria-hidden="true"></i>
-                        <div class="toDisplaySub">
-                            <div class="option" onclick="setVersion('latest');">Latest</div>
-                            <div class="option" onclick="setVersion('stable');">Stable</div>
-                        </div>
-                    </div>
-                </div>
-            </div>
-        </div>
-
-        <div class="category right">
-            <div class="button select">
-                <span class="examplesButton">Examples</span>
-            </div>
-        </div>
-    </div>
-
-    <div class="navbar navBar1030">
-        <div class="category">
-            <div class="button run" id="runButton1030">Run
-                <i class="fa fa-play" aria-hidden="true"></i>
-            </div>
-        </div>
-
-
-        <div class="category">
-            <div class="button" id="newButton1030">New
-                <i class="fa fa-file" aria-hidden="true"></i>
-            </div>
-            <div class="button removeOnPhone" id="clearButton1030">Clear
-                <i class="fa fa-trash" aria-hidden="true"></i>
-            </div>
-        </div>
-
-        <div class="category">
-            <div class="button" id="saveButton1030">Save
-                <i class="fa fa-floppy-o" aria-hidden="true"></i>
-            </div>
-            <div class="button removeOnPhone" id="zipButton1030">Zip
-                <i class="fa fa-download" aria-hidden="true"></i>
-            </div>
-        </div>
-
-        <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 class="option subSelect">
-                        <span id="currentFontSize1030">Font: 14</span>
-                        <i class="fa fa-chevron-right" aria-hidden="true"></i>
-                        <div class="toDisplaySub">
-                            <div class="option" onclick="setFontSize(12);">12</div>
-                            <div class="option" onclick="setFontSize(14);">14</div>
-                            <div class="option" onclick="setFontSize(16);">16</div>
-                            <div class="option" onclick="setFontSize(18);">18</div>
-                            <div class="option" onclick="setFontSize(20);">20</div>
-                            <div class="option" onclick="setFontSize(22);">22</div>
-                        </div>
-                    </div>
-                    <div class="option" id="safemodeToggle1030">Safe mode
-                        <i class="far fa-square" aria-hidden="true"></i>
-                    </div>
-                    <div class="option checked" id="editorButton1030">Editor
-                        <i class="fa fa-check-square" aria-hidden="true"></i>
-                    </div>
-                    <div class="option" id="fullscreenButton1030">Fullscreen</div>
-                    <div class="option" id="editorFullscreenButton1030">Editor Fullscreen</div>
-                    <div class="option" id="formatButton1030">Format code</div>
-                    <div class="option" id="minimapToggle1030">Minimap
-                        <i class="far fa-square" aria-hidden="true"></i>
-                    </div>
-                    <div class="option" id="debugButton1030">Inspector</div>
-                    <div class="option" id="metadataButton1030">Metadata</div>
-                    <div class="option subSelect">
-                        <span id="currentVersion1030">Vers. : Latest</span>
-                        <i class="fa fa-chevron-right" aria-hidden="true"></i>
-                        <div class="toDisplaySub">
-                            <div class="option" onclick="setVersion('latest');">Latest</div>
-                            <div class="option" onclick="setVersion('stable');">Stable</div>
-                        </div>
-                    </div>
-                </div>
-            </div>
-        </div>
-
-        <div class="category right">
-            <div class="button select">
-                <span class="examplesButton">Examples</span>
-            </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>
-                </div>
-            </div>
-        </div>
-
-        <div class="category">
-            <div class="button select">Settings
-                <div class="toDisplay">
-                    <div class="option subSelect">Theme
-                        <i class="fa fa-chevron-right" aria-hidden="true"></i>
-                        <div class="toDisplaySub">
-                            <div class="option" id="darkTheme750">Dark</div>
-                            <div class="option" id="lightTheme750">Light</div>
-                        </div>
-                    </div>
-                    <div class="option subSelect">
-                        <span id="currentFontSize750">Font: 14</span>
-                        <i class="fa fa-chevron-right" aria-hidden="true"></i>
-                        <div class="toDisplaySub">
-                            <div class="option" onclick="setFontSize(12);">12</div>
-                            <div class="option" onclick="setFontSize(14);">14</div>
-                            <div class="option" onclick="setFontSize(16);">16</div>
-                            <div class="option" onclick="setFontSize(18);">18</div>
-                            <div class="option" onclick="setFontSize(20);">20</div>
-                            <div class="option" onclick="setFontSize(22);">22</div>
-                        </div>
-                    </div>
-                    <div class="option" id="safemodeToggle750">Safe mode
-                        <i class="far fa-square" aria-hidden="true"></i>
-                    </div>
-                    <div style="display:none;" class="option checked" id="editorButton750">Editor
-                        <i class="fa fa-check-square" aria-hidden="true"></i>
-                    </div>
-                    <div class="option" id="fullscreenButton750">Fullscreen</div>
-                    <div class="option" id="editorFullscreenButton750">Editor Fullscreen</div>
-                    <div class="option" id="formatButton750">Format code</div>
-                    <div class="option" id="minimapToggle750">Minimap
-                        <i class="far fa-square" aria-hidden="true"></i>
-                    </div>
-                    <div class="option" id="debugButton750">Inspector</div>
-                    <div class="option" id="metadataButton750">Metadata</div>
-                    <div class="option subSelect">
-                        <span id="currentVersion750">Vers. : Latest</span>
-                        <i class="fa fa-chevron-right" aria-hidden="true"></i>
-                        <div class="toDisplaySub">
-                            <div class="option" onclick="setVersion('latest');">Latest</div>
-                            <div class="option" onclick="setVersion('stable');">Stable</div>
-                        </div>
-                    </div>
-                </div>
-            </div>
-        </div>
-
-        <div class="category right">
-            <div class="button select">
-                <span id="currentScript750">Examples</span>
-            </div>
-        </div>
-    </div>
-
-    <div class="wrapper">
-        <div id="jsEditor"></div>
-        <div id="canvasZone">
-            <canvas touch-action="none" id="renderCanvas"></canvas>
-        </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>
-
-    <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="https://forum.babylonjs.com/">Forum</a>
-            </div>
-            <div class='link'>
-                <a target='_new' href="https://www.babylonjs.com/sandbox">Sandbox</a>
-            </div>
-            <div class='link'>
-                <a target='_new' href="https://doc.babylonjs.com">Documentation</a>
-            </div>
-            <div class='link'>
-                <a target='_new' href="https://doc.babylonjs.com/playground">Search</a>
-            </div>
-        </div>
-    </div>
-
-    <div id="saveLayer" class="save-layer">
-        <div class="save-form">
-            <label for="saveFormTitle">TITLE</label>
-            <div class="separator"></div>
-            <input type="text" maxlength="120" id="saveFormTitle" class="save-form-title">
-
-            <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>
-
-            <div class="save-form-buttons" id="saveFormButtons">
-
-                <div id="saveFormButtonOk" class="button">OK</div>
-                <div id="saveFormButtonCancel" class="button">Cancel</div>
-            </div>
-        </div>
-    </div>
-
-    <div id="waitDiv">
-        <span id="waitTitle">Babylon.js Playground
-            <BR>
-            <BR>
-            <BR>
-        </span>
-        <div id="logo-part">
-            <img src="v4.svg" id="waitLogo" />
-            <img src="css/img/spinner.svg" id="waitSpinner" />
-        </div>
-    </div>
-
-    <script src="js/libs/jquery.min.js"></script>
-    <script src="js/jquery.qrcode.js"></script>
-    <script src="js/qrcode.js"></script>
-
-    <script src="js/UImenu.js"></script>
-    <script src="js/pbt.js"></script>
-    <script src="js/libs/typescript.js"></script>
-    <script src="js/index.js"></script>
-    <script src="js/ts.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());
-
-        gtag('config', 'UA-41767310-2');
-    </script>
-</body>
-
-</html>
+<script>
+    localStorage.setItem("bjs-playground-scriptLanguage", "TS");
+    window.location = "./";
+</script>

+ 6 - 5
Viewer/src/configuration/renderOnlyLoader.ts

@@ -3,9 +3,10 @@ import { ViewerConfiguration } from './configuration';
 import { processConfigurationCompatibility } from './configurationCompatibility';
 import { processConfigurationCompatibility } from './configurationCompatibility';
 
 
 import { deepmerge } from '../helper';
 import { deepmerge } from '../helper';
-import { IFileRequest, Tools } from 'babylonjs/Misc/tools';
+import { Tools } from 'babylonjs/Misc/tools';
 import { extendedConfiguration } from './types/extended';
 import { extendedConfiguration } from './types/extended';
 import { renderOnlyDefaultConfiguration } from './types/renderOnlyDefault';
 import { renderOnlyDefaultConfiguration } from './types/renderOnlyDefault';
+import { IFileRequest } from 'babylonjs/Misc/fileRequest';
 
 
 /**
 /**
  * The configuration loader will load the configuration object from any source and will use the defined mapper to
  * The configuration loader will load the configuration object from any source and will use the defined mapper to
@@ -23,7 +24,7 @@ export class RenderOnlyConfigurationLoader {
         this._loadRequests = [];
         this._loadRequests = [];
     }
     }
 
 
-    private _getConfigurationTypeExcludeTemplate (types: string): ViewerConfiguration {
+    private _getConfigurationTypeExcludeTemplate(types: string): ViewerConfiguration {
         let config: ViewerConfiguration = {};
         let config: ViewerConfiguration = {};
         let typesSeparated = types.split(",");
         let typesSeparated = types.split(",");
         typesSeparated.forEach((type) => {
         typesSeparated.forEach((type) => {
@@ -45,7 +46,7 @@ export class RenderOnlyConfigurationLoader {
         return config;
         return config;
     };
     };
 
 
-    protected getExtendedConfig(type:string|undefined){
+    protected getExtendedConfig(type: string | undefined) {
         return this._getConfigurationTypeExcludeTemplate(type || "extended");
         return this._getConfigurationTypeExcludeTemplate(type || "extended");
     }
     }
 
 
@@ -61,7 +62,7 @@ export class RenderOnlyConfigurationLoader {
 
 
         let loadedConfig: ViewerConfiguration = deepmerge({}, initConfig);
         let loadedConfig: ViewerConfiguration = deepmerge({}, initConfig);
         this._processInitialConfiguration(loadedConfig);
         this._processInitialConfiguration(loadedConfig);
-        
+
         let extendedConfiguration = this.getExtendedConfig(loadedConfig.extends);
         let extendedConfiguration = this.getExtendedConfig(loadedConfig.extends);
 
 
         if (loadedConfig.configuration) {
         if (loadedConfig.configuration) {
@@ -160,5 +161,5 @@ export class RenderOnlyConfigurationLoader {
             this._loadRequests.push(fileRequest);
             this._loadRequests.push(fileRequest);
         });
         });
     }
     }
-    
+
 }
 }

+ 2 - 1
Viewer/src/templating/templateManager.ts

@@ -1,11 +1,12 @@
 import { Observable } from 'babylonjs/Misc/observable';
 import { Observable } from 'babylonjs/Misc/observable';
-import { IFileRequest, Tools } from 'babylonjs/Misc/tools';
+import { Tools } from 'babylonjs/Misc/tools';
 import { isUrl, camelToKebab, kebabToCamel } from '../helper';
 import { isUrl, camelToKebab, kebabToCamel } from '../helper';
 
 
 import * as Handlebars from 'handlebars/dist/handlebars';
 import * as Handlebars from 'handlebars/dist/handlebars';
 import { EventManager } from './eventManager';
 import { EventManager } from './eventManager';
 import { ITemplateConfiguration } from '../configuration/interfaces';
 import { ITemplateConfiguration } from '../configuration/interfaces';
 import { deepmerge } from '../helper/';
 import { deepmerge } from '../helper/';
+import { IFileRequest } from 'babylonjs/Misc/fileRequest';
 
 
 /**
 /**
  * The object sent when an event is triggered
  * The object sent when an event is triggered

File diff suppressed because it is too large
+ 22241 - 22122
dist/preview release/babylon.d.ts


File diff suppressed because it is too large
+ 2 - 2
dist/preview release/babylon.js


File diff suppressed because it is too large
+ 1693 - 1422
dist/preview release/babylon.max.js


File diff suppressed because it is too large
+ 1 - 1
dist/preview release/babylon.max.js.map


File diff suppressed because it is too large
+ 58132 - 57875
dist/preview release/babylon.module.d.ts


File diff suppressed because it is too large
+ 22241 - 22122
dist/preview release/documentation.d.ts


+ 4 - 4
dist/preview release/gui/babylon.gui.js

@@ -355,8 +355,8 @@ module.exports = g;
 "use strict";
 "use strict";
 __webpack_require__.r(__webpack_exports__);
 __webpack_require__.r(__webpack_exports__);
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "AdvancedDynamicTextureInstrumentation", function() { return AdvancedDynamicTextureInstrumentation; });
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "AdvancedDynamicTextureInstrumentation", function() { return AdvancedDynamicTextureInstrumentation; });
-/* harmony import */ var babylonjs_Misc_tools__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! babylonjs/Misc/tools */ "babylonjs/Maths/math");
-/* harmony import */ var babylonjs_Misc_tools__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Misc_tools__WEBPACK_IMPORTED_MODULE_0__);
+/* harmony import */ var babylonjs_Misc_perfCounter__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! babylonjs/Misc/perfCounter */ "babylonjs/Maths/math");
+/* harmony import */ var babylonjs_Misc_perfCounter__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(babylonjs_Misc_perfCounter__WEBPACK_IMPORTED_MODULE_0__);
 
 
 /**
 /**
  * This class can be used to get instrumentation data from a AdvancedDynamicTexture object
  * This class can be used to get instrumentation data from a AdvancedDynamicTexture object
@@ -374,9 +374,9 @@ var AdvancedDynamicTextureInstrumentation = /** @class */ (function () {
     texture) {
     texture) {
         this.texture = texture;
         this.texture = texture;
         this._captureRenderTime = false;
         this._captureRenderTime = false;
-        this._renderTime = new babylonjs_Misc_tools__WEBPACK_IMPORTED_MODULE_0__["PerfCounter"]();
+        this._renderTime = new babylonjs_Misc_perfCounter__WEBPACK_IMPORTED_MODULE_0__["PerfCounter"]();
         this._captureLayoutTime = false;
         this._captureLayoutTime = false;
-        this._layoutTime = new babylonjs_Misc_tools__WEBPACK_IMPORTED_MODULE_0__["PerfCounter"]();
+        this._layoutTime = new babylonjs_Misc_perfCounter__WEBPACK_IMPORTED_MODULE_0__["PerfCounter"]();
         // Observers
         // Observers
         this._onBeginRenderObserver = null;
         this._onBeginRenderObserver = null;
         this._onEndRenderObserver = null;
         this._onEndRenderObserver = null;

File diff suppressed because it is too large
+ 1 - 1
dist/preview release/gui/babylon.gui.js.map


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

@@ -3012,7 +3012,7 @@ declare module "babylonjs-gui/2D/controls/index" {
     export * from "babylonjs-gui/2D/controls/statics";
     export * from "babylonjs-gui/2D/controls/statics";
 }
 }
 declare module "babylonjs-gui/2D/adtInstrumentation" {
 declare module "babylonjs-gui/2D/adtInstrumentation" {
-    import { PerfCounter } from "babylonjs/Misc/tools";
+    import { PerfCounter } from "babylonjs/Misc/perfCounter";
     import { IDisposable } from "babylonjs/scene";
     import { IDisposable } from "babylonjs/scene";
     import { AdvancedDynamicTexture } from "babylonjs-gui/2D/advancedDynamicTexture";
     import { AdvancedDynamicTexture } from "babylonjs-gui/2D/advancedDynamicTexture";
     /**
     /**

+ 7 - 7
dist/preview release/inspector/babylon.inspector.bundle.max.js

@@ -7,7 +7,7 @@
 		exports["babylonjs-inspector"] = factory(require("babylonjs-gui"), require("babylonjs-loaders"), require("babylonjs-serializers"), require("babylonjs"));
 		exports["babylonjs-inspector"] = factory(require("babylonjs-gui"), require("babylonjs-loaders"), require("babylonjs-serializers"), require("babylonjs"));
 	else
 	else
 		root["INSPECTOR"] = factory(root["BABYLON"]["GUI"], root["BABYLON"], root["BABYLON"], root["BABYLON"]);
 		root["INSPECTOR"] = factory(root["BABYLON"]["GUI"], root["BABYLON"], root["BABYLON"], root["BABYLON"]);
-})((typeof self !== "undefined" ? self : typeof global !== "undefined" ? global : this), function(__WEBPACK_EXTERNAL_MODULE_babylonjs_gui_2D_adtInstrumentation__, __WEBPACK_EXTERNAL_MODULE_babylonjs_loaders_glTF_index__, __WEBPACK_EXTERNAL_MODULE_babylonjs_serializers_glTF_2_0_index__, __WEBPACK_EXTERNAL_MODULE_babylonjs_Misc_observable__) {
+})((typeof self !== "undefined" ? self : typeof global !== "undefined" ? global : this), function(__WEBPACK_EXTERNAL_MODULE_babylonjs_gui_2D_controls_image__, __WEBPACK_EXTERNAL_MODULE_babylonjs_loaders_glTF_index__, __WEBPACK_EXTERNAL_MODULE_babylonjs_serializers_glTF_2_0_index__, __WEBPACK_EXTERNAL_MODULE_babylonjs_Misc_observable__) {
 return /******/ (function(modules) { // webpackBootstrap
 return /******/ (function(modules) { // webpackBootstrap
 /******/ 	// The module cache
 /******/ 	// The module cache
 /******/ 	var installedModules = {};
 /******/ 	var installedModules = {};
@@ -36157,7 +36157,7 @@ __webpack_require__.r(__webpack_exports__);
 /* harmony import */ var react__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(react__WEBPACK_IMPORTED_MODULE_1__);
 /* harmony import */ var react__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(react__WEBPACK_IMPORTED_MODULE_1__);
 /* harmony import */ var _lineContainerComponent__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../../../lineContainerComponent */ "./components/actionTabs/lineContainerComponent.tsx");
 /* harmony import */ var _lineContainerComponent__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ../../../lineContainerComponent */ "./components/actionTabs/lineContainerComponent.tsx");
 /* harmony import */ var _lines_textLineComponent__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../../../lines/textLineComponent */ "./components/actionTabs/lines/textLineComponent.tsx");
 /* harmony import */ var _lines_textLineComponent__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../../../lines/textLineComponent */ "./components/actionTabs/lines/textLineComponent.tsx");
-/* harmony import */ var babylonjs_gui_2D_controls_control__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! babylonjs-gui/2D/controls/control */ "babylonjs-gui/2D/adtInstrumentation");
+/* harmony import */ var babylonjs_gui_2D_controls_control__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! babylonjs-gui/2D/controls/control */ "babylonjs-gui/2D/controls/image");
 /* harmony import */ var babylonjs_gui_2D_controls_control__WEBPACK_IMPORTED_MODULE_4___default = /*#__PURE__*/__webpack_require__.n(babylonjs_gui_2D_controls_control__WEBPACK_IMPORTED_MODULE_4__);
 /* harmony import */ var babylonjs_gui_2D_controls_control__WEBPACK_IMPORTED_MODULE_4___default = /*#__PURE__*/__webpack_require__.n(babylonjs_gui_2D_controls_control__WEBPACK_IMPORTED_MODULE_4__);
 /* harmony import */ var _lines_sliderLineComponent__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../../../lines/sliderLineComponent */ "./components/actionTabs/lines/sliderLineComponent.tsx");
 /* harmony import */ var _lines_sliderLineComponent__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../../../lines/sliderLineComponent */ "./components/actionTabs/lines/sliderLineComponent.tsx");
 /* harmony import */ var _lines_floatLineComponent__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../../../lines/floatLineComponent */ "./components/actionTabs/lines/floatLineComponent.tsx");
 /* harmony import */ var _lines_floatLineComponent__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../../../lines/floatLineComponent */ "./components/actionTabs/lines/floatLineComponent.tsx");
@@ -36462,7 +36462,7 @@ __webpack_require__.r(__webpack_exports__);
 /* harmony import */ var react__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(react__WEBPACK_IMPORTED_MODULE_1__);
 /* harmony import */ var react__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(react__WEBPACK_IMPORTED_MODULE_1__);
 /* harmony import */ var _commonControlPropertyGridComponent__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./commonControlPropertyGridComponent */ "./components/actionTabs/tabs/propertyGrids/gui/commonControlPropertyGridComponent.tsx");
 /* harmony import */ var _commonControlPropertyGridComponent__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./commonControlPropertyGridComponent */ "./components/actionTabs/tabs/propertyGrids/gui/commonControlPropertyGridComponent.tsx");
 /* harmony import */ var _lineContainerComponent__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../../../lineContainerComponent */ "./components/actionTabs/lineContainerComponent.tsx");
 /* harmony import */ var _lineContainerComponent__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ../../../lineContainerComponent */ "./components/actionTabs/lineContainerComponent.tsx");
-/* harmony import */ var babylonjs_gui_2D_controls_image__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! babylonjs-gui/2D/controls/image */ "babylonjs-gui/2D/adtInstrumentation");
+/* harmony import */ var babylonjs_gui_2D_controls_image__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! babylonjs-gui/2D/controls/image */ "babylonjs-gui/2D/controls/image");
 /* harmony import */ var babylonjs_gui_2D_controls_image__WEBPACK_IMPORTED_MODULE_4___default = /*#__PURE__*/__webpack_require__.n(babylonjs_gui_2D_controls_image__WEBPACK_IMPORTED_MODULE_4__);
 /* harmony import */ var babylonjs_gui_2D_controls_image__WEBPACK_IMPORTED_MODULE_4___default = /*#__PURE__*/__webpack_require__.n(babylonjs_gui_2D_controls_image__WEBPACK_IMPORTED_MODULE_4__);
 /* harmony import */ var _lines_floatLineComponent__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../../../lines/floatLineComponent */ "./components/actionTabs/lines/floatLineComponent.tsx");
 /* harmony import */ var _lines_floatLineComponent__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../../../lines/floatLineComponent */ "./components/actionTabs/lines/floatLineComponent.tsx");
 /* harmony import */ var _lines_checkBoxLineComponent__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../../../lines/checkBoxLineComponent */ "./components/actionTabs/lines/checkBoxLineComponent.tsx");
 /* harmony import */ var _lines_checkBoxLineComponent__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ../../../lines/checkBoxLineComponent */ "./components/actionTabs/lines/checkBoxLineComponent.tsx");
@@ -36876,7 +36876,7 @@ __webpack_require__.r(__webpack_exports__);
 /* harmony import */ var react__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! react */ "../../node_modules/react/index.js");
 /* harmony import */ var react__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! react */ "../../node_modules/react/index.js");
 /* harmony import */ var react__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(react__WEBPACK_IMPORTED_MODULE_1__);
 /* harmony import */ var react__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(react__WEBPACK_IMPORTED_MODULE_1__);
 /* harmony import */ var _commonControlPropertyGridComponent__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./commonControlPropertyGridComponent */ "./components/actionTabs/tabs/propertyGrids/gui/commonControlPropertyGridComponent.tsx");
 /* harmony import */ var _commonControlPropertyGridComponent__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./commonControlPropertyGridComponent */ "./components/actionTabs/tabs/propertyGrids/gui/commonControlPropertyGridComponent.tsx");
-/* harmony import */ var babylonjs_gui_2D_controls_textBlock__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! babylonjs-gui/2D/controls/textBlock */ "babylonjs-gui/2D/adtInstrumentation");
+/* harmony import */ var babylonjs_gui_2D_controls_textBlock__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! babylonjs-gui/2D/controls/textBlock */ "babylonjs-gui/2D/controls/image");
 /* harmony import */ var babylonjs_gui_2D_controls_textBlock__WEBPACK_IMPORTED_MODULE_3___default = /*#__PURE__*/__webpack_require__.n(babylonjs_gui_2D_controls_textBlock__WEBPACK_IMPORTED_MODULE_3__);
 /* harmony import */ var babylonjs_gui_2D_controls_textBlock__WEBPACK_IMPORTED_MODULE_3___default = /*#__PURE__*/__webpack_require__.n(babylonjs_gui_2D_controls_textBlock__WEBPACK_IMPORTED_MODULE_3__);
 /* harmony import */ var _lineContainerComponent__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../../../lineContainerComponent */ "./components/actionTabs/lineContainerComponent.tsx");
 /* harmony import */ var _lineContainerComponent__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ../../../lineContainerComponent */ "./components/actionTabs/lineContainerComponent.tsx");
 /* harmony import */ var _lines_textInputLineComponent__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../../../lines/textInputLineComponent */ "./components/actionTabs/lines/textInputLineComponent.tsx");
 /* harmony import */ var _lines_textInputLineComponent__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ../../../lines/textInputLineComponent */ "./components/actionTabs/lines/textInputLineComponent.tsx");
@@ -38013,7 +38013,7 @@ __webpack_require__.r(__webpack_exports__);
 /* harmony import */ var _lines_optionsLineComponent__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ../../../lines/optionsLineComponent */ "./components/actionTabs/lines/optionsLineComponent.tsx");
 /* harmony import */ var _lines_optionsLineComponent__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ../../../lines/optionsLineComponent */ "./components/actionTabs/lines/optionsLineComponent.tsx");
 /* harmony import */ var _lines_fileButtonLineComponent__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! ../../../lines/fileButtonLineComponent */ "./components/actionTabs/lines/fileButtonLineComponent.tsx");
 /* harmony import */ var _lines_fileButtonLineComponent__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! ../../../lines/fileButtonLineComponent */ "./components/actionTabs/lines/fileButtonLineComponent.tsx");
 /* harmony import */ var _lines_valueLineComponent__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(/*! ../../../lines/valueLineComponent */ "./components/actionTabs/lines/valueLineComponent.tsx");
 /* harmony import */ var _lines_valueLineComponent__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(/*! ../../../lines/valueLineComponent */ "./components/actionTabs/lines/valueLineComponent.tsx");
-/* harmony import */ var babylonjs_gui_2D_adtInstrumentation__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__(/*! babylonjs-gui/2D/adtInstrumentation */ "babylonjs-gui/2D/adtInstrumentation");
+/* harmony import */ var babylonjs_gui_2D_adtInstrumentation__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__(/*! babylonjs-gui/2D/adtInstrumentation */ "babylonjs-gui/2D/controls/image");
 /* harmony import */ var babylonjs_gui_2D_adtInstrumentation__WEBPACK_IMPORTED_MODULE_12___default = /*#__PURE__*/__webpack_require__.n(babylonjs_gui_2D_adtInstrumentation__WEBPACK_IMPORTED_MODULE_12__);
 /* harmony import */ var babylonjs_gui_2D_adtInstrumentation__WEBPACK_IMPORTED_MODULE_12___default = /*#__PURE__*/__webpack_require__.n(babylonjs_gui_2D_adtInstrumentation__WEBPACK_IMPORTED_MODULE_12__);
 /* harmony import */ var _customPropertyGridComponent__WEBPACK_IMPORTED_MODULE_13__ = __webpack_require__(/*! ../customPropertyGridComponent */ "./components/actionTabs/tabs/propertyGrids/customPropertyGridComponent.tsx");
 /* harmony import */ var _customPropertyGridComponent__WEBPACK_IMPORTED_MODULE_13__ = __webpack_require__(/*! ../customPropertyGridComponent */ "./components/actionTabs/tabs/propertyGrids/customPropertyGridComponent.tsx");
 
 
@@ -42703,14 +42703,14 @@ var Tools = /** @class */ (function () {
 
 
 /***/ }),
 /***/ }),
 
 
-/***/ "babylonjs-gui/2D/adtInstrumentation":
+/***/ "babylonjs-gui/2D/controls/image":
 /*!************************************************************************************************************************!*\
 /*!************************************************************************************************************************!*\
   !*** external {"root":["BABYLON","GUI"],"commonjs":"babylonjs-gui","commonjs2":"babylonjs-gui","amd":"babylonjs-gui"} ***!
   !*** external {"root":["BABYLON","GUI"],"commonjs":"babylonjs-gui","commonjs2":"babylonjs-gui","amd":"babylonjs-gui"} ***!
   \************************************************************************************************************************/
   \************************************************************************************************************************/
 /*! no static exports found */
 /*! no static exports found */
 /***/ (function(module, exports) {
 /***/ (function(module, exports) {
 
 
-module.exports = __WEBPACK_EXTERNAL_MODULE_babylonjs_gui_2D_adtInstrumentation__;
+module.exports = __WEBPACK_EXTERNAL_MODULE_babylonjs_gui_2D_controls_image__;
 
 
 /***/ }),
 /***/ }),
 
 

File diff suppressed because it is too large
+ 1 - 1
dist/preview release/inspector/babylon.inspector.bundle.max.js.map


+ 9 - 3
dist/preview release/loaders/babylon.glTF2FileLoader.js

@@ -567,11 +567,13 @@ var KHR_materials_pbrSpecularGlossiness = /** @class */ (function () {
         babylonMaterial.microSurface = properties.glossinessFactor == undefined ? 1 : properties.glossinessFactor;
         babylonMaterial.microSurface = properties.glossinessFactor == undefined ? 1 : properties.glossinessFactor;
         if (properties.diffuseTexture) {
         if (properties.diffuseTexture) {
             promises.push(this._loader.loadTextureInfoAsync(context + "/diffuseTexture", properties.diffuseTexture, function (texture) {
             promises.push(this._loader.loadTextureInfoAsync(context + "/diffuseTexture", properties.diffuseTexture, function (texture) {
+                texture.name = babylonMaterial.name + " (Diffuse)";
                 babylonMaterial.albedoTexture = texture;
                 babylonMaterial.albedoTexture = texture;
             }));
             }));
         }
         }
         if (properties.specularGlossinessTexture) {
         if (properties.specularGlossinessTexture) {
             promises.push(this._loader.loadTextureInfoAsync(context + "/specularGlossinessTexture", properties.specularGlossinessTexture, function (texture) {
             promises.push(this._loader.loadTextureInfoAsync(context + "/specularGlossinessTexture", properties.specularGlossinessTexture, function (texture) {
+                texture.name = babylonMaterial.name + " (Specular Glossiness)";
                 babylonMaterial.reflectivityTexture = texture;
                 babylonMaterial.reflectivityTexture = texture;
             }));
             }));
             babylonMaterial.reflectivityTexture.hasAlpha = true;
             babylonMaterial.reflectivityTexture.hasAlpha = true;
@@ -644,6 +646,7 @@ var KHR_materials_unlit = /** @class */ (function () {
             }
             }
             if (properties.baseColorTexture) {
             if (properties.baseColorTexture) {
                 promises.push(this._loader.loadTextureInfoAsync(context + "/baseColorTexture", properties.baseColorTexture, function (texture) {
                 promises.push(this._loader.loadTextureInfoAsync(context + "/baseColorTexture", properties.baseColorTexture, function (texture) {
+                    texture.name = babylonMaterial.name + " (Base Color)";
                     babylonMaterial.albedoTexture = texture;
                     babylonMaterial.albedoTexture = texture;
                 }));
                 }));
             }
             }
@@ -1426,6 +1429,7 @@ __webpack_require__.r(__webpack_exports__);
 
 
 
 
 
 
+
 /**
 /**
  * Helper class for working with arrays when loading the glTF asset
  * Helper class for working with arrays when loading the glTF asset
  */
  */
@@ -2746,11 +2750,13 @@ var GLTFLoader = /** @class */ (function () {
             babylonMaterial.roughness = properties.roughnessFactor == undefined ? 1 : properties.roughnessFactor;
             babylonMaterial.roughness = properties.roughnessFactor == undefined ? 1 : properties.roughnessFactor;
             if (properties.baseColorTexture) {
             if (properties.baseColorTexture) {
                 promises.push(this.loadTextureInfoAsync(context + "/baseColorTexture", properties.baseColorTexture, function (texture) {
                 promises.push(this.loadTextureInfoAsync(context + "/baseColorTexture", properties.baseColorTexture, function (texture) {
+                    texture.name = babylonMaterial.name + " (Base Color)";
                     babylonMaterial.albedoTexture = texture;
                     babylonMaterial.albedoTexture = texture;
                 }));
                 }));
             }
             }
             if (properties.metallicRoughnessTexture) {
             if (properties.metallicRoughnessTexture) {
                 promises.push(this.loadTextureInfoAsync(context + "/metallicRoughnessTexture", properties.metallicRoughnessTexture, function (texture) {
                 promises.push(this.loadTextureInfoAsync(context + "/metallicRoughnessTexture", properties.metallicRoughnessTexture, function (texture) {
+                    texture.name = babylonMaterial.name + " (Metallic Roughness)";
                     babylonMaterial.metallicTexture = texture;
                     babylonMaterial.metallicTexture = texture;
                 }));
                 }));
                 babylonMaterial.useMetallnessFromMetallicTextureBlue = true;
                 babylonMaterial.useMetallnessFromMetallicTextureBlue = true;
@@ -2861,6 +2867,7 @@ var GLTFLoader = /** @class */ (function () {
         }
         }
         if (material.normalTexture) {
         if (material.normalTexture) {
             promises.push(this.loadTextureInfoAsync(context + "/normalTexture", material.normalTexture, function (texture) {
             promises.push(this.loadTextureInfoAsync(context + "/normalTexture", material.normalTexture, function (texture) {
+                texture.name = babylonMaterial.name + " (Normal)";
                 babylonMaterial.bumpTexture = texture;
                 babylonMaterial.bumpTexture = texture;
             }));
             }));
             babylonMaterial.invertNormalMapX = !this._babylonScene.useRightHandedSystem;
             babylonMaterial.invertNormalMapX = !this._babylonScene.useRightHandedSystem;
@@ -2872,6 +2879,7 @@ var GLTFLoader = /** @class */ (function () {
         }
         }
         if (material.occlusionTexture) {
         if (material.occlusionTexture) {
             promises.push(this.loadTextureInfoAsync(context + "/occlusionTexture", material.occlusionTexture, function (texture) {
             promises.push(this.loadTextureInfoAsync(context + "/occlusionTexture", material.occlusionTexture, function (texture) {
+                texture.name = babylonMaterial.name + " (Occlusion)";
                 babylonMaterial.ambientTexture = texture;
                 babylonMaterial.ambientTexture = texture;
             }));
             }));
             babylonMaterial.useAmbientInGrayScale = true;
             babylonMaterial.useAmbientInGrayScale = true;
@@ -2881,6 +2889,7 @@ var GLTFLoader = /** @class */ (function () {
         }
         }
         if (material.emissiveTexture) {
         if (material.emissiveTexture) {
             promises.push(this.loadTextureInfoAsync(context + "/emissiveTexture", material.emissiveTexture, function (texture) {
             promises.push(this.loadTextureInfoAsync(context + "/emissiveTexture", material.emissiveTexture, function (texture) {
+                texture.name = babylonMaterial.name + " (Emissive)";
                 babylonMaterial.emissiveTexture = texture;
                 babylonMaterial.emissiveTexture = texture;
             }));
             }));
         }
         }
@@ -2942,9 +2951,6 @@ var GLTFLoader = /** @class */ (function () {
         var texture = ArrayItem.Get(context + "/index", this._gltf.textures, textureInfo.index);
         var texture = ArrayItem.Get(context + "/index", this._gltf.textures, textureInfo.index);
         var promise = this._loadTextureAsync("/textures/" + textureInfo.index, texture, function (babylonTexture) {
         var promise = this._loadTextureAsync("/textures/" + textureInfo.index, texture, function (babylonTexture) {
             babylonTexture.coordinatesIndex = textureInfo.texCoord || 0;
             babylonTexture.coordinatesIndex = textureInfo.texCoord || 0;
-            if (texture.name) {
-                babylonTexture.name = texture.name;
-            }
             GLTFLoader.AddPointerMetadata(babylonTexture, context);
             GLTFLoader.AddPointerMetadata(babylonTexture, context);
             _this._parent.onTextureLoadedObservable.notifyObservers(babylonTexture);
             _this._parent.onTextureLoadedObservable.notifyObservers(babylonTexture);
             assign(babylonTexture);
             assign(babylonTexture);

File diff suppressed because it is too large
+ 1 - 1
dist/preview release/loaders/babylon.glTF2FileLoader.js.map


File diff suppressed because it is too large
+ 1 - 1
dist/preview release/loaders/babylon.glTF2FileLoader.min.js


+ 9 - 3
dist/preview release/loaders/babylon.glTFFileLoader.js

@@ -3116,11 +3116,13 @@ var KHR_materials_pbrSpecularGlossiness = /** @class */ (function () {
         babylonMaterial.microSurface = properties.glossinessFactor == undefined ? 1 : properties.glossinessFactor;
         babylonMaterial.microSurface = properties.glossinessFactor == undefined ? 1 : properties.glossinessFactor;
         if (properties.diffuseTexture) {
         if (properties.diffuseTexture) {
             promises.push(this._loader.loadTextureInfoAsync(context + "/diffuseTexture", properties.diffuseTexture, function (texture) {
             promises.push(this._loader.loadTextureInfoAsync(context + "/diffuseTexture", properties.diffuseTexture, function (texture) {
+                texture.name = babylonMaterial.name + " (Diffuse)";
                 babylonMaterial.albedoTexture = texture;
                 babylonMaterial.albedoTexture = texture;
             }));
             }));
         }
         }
         if (properties.specularGlossinessTexture) {
         if (properties.specularGlossinessTexture) {
             promises.push(this._loader.loadTextureInfoAsync(context + "/specularGlossinessTexture", properties.specularGlossinessTexture, function (texture) {
             promises.push(this._loader.loadTextureInfoAsync(context + "/specularGlossinessTexture", properties.specularGlossinessTexture, function (texture) {
+                texture.name = babylonMaterial.name + " (Specular Glossiness)";
                 babylonMaterial.reflectivityTexture = texture;
                 babylonMaterial.reflectivityTexture = texture;
             }));
             }));
             babylonMaterial.reflectivityTexture.hasAlpha = true;
             babylonMaterial.reflectivityTexture.hasAlpha = true;
@@ -3193,6 +3195,7 @@ var KHR_materials_unlit = /** @class */ (function () {
             }
             }
             if (properties.baseColorTexture) {
             if (properties.baseColorTexture) {
                 promises.push(this._loader.loadTextureInfoAsync(context + "/baseColorTexture", properties.baseColorTexture, function (texture) {
                 promises.push(this._loader.loadTextureInfoAsync(context + "/baseColorTexture", properties.baseColorTexture, function (texture) {
+                    texture.name = babylonMaterial.name + " (Base Color)";
                     babylonMaterial.albedoTexture = texture;
                     babylonMaterial.albedoTexture = texture;
                 }));
                 }));
             }
             }
@@ -3975,6 +3978,7 @@ __webpack_require__.r(__webpack_exports__);
 
 
 
 
 
 
+
 /**
 /**
  * Helper class for working with arrays when loading the glTF asset
  * Helper class for working with arrays when loading the glTF asset
  */
  */
@@ -5295,11 +5299,13 @@ var GLTFLoader = /** @class */ (function () {
             babylonMaterial.roughness = properties.roughnessFactor == undefined ? 1 : properties.roughnessFactor;
             babylonMaterial.roughness = properties.roughnessFactor == undefined ? 1 : properties.roughnessFactor;
             if (properties.baseColorTexture) {
             if (properties.baseColorTexture) {
                 promises.push(this.loadTextureInfoAsync(context + "/baseColorTexture", properties.baseColorTexture, function (texture) {
                 promises.push(this.loadTextureInfoAsync(context + "/baseColorTexture", properties.baseColorTexture, function (texture) {
+                    texture.name = babylonMaterial.name + " (Base Color)";
                     babylonMaterial.albedoTexture = texture;
                     babylonMaterial.albedoTexture = texture;
                 }));
                 }));
             }
             }
             if (properties.metallicRoughnessTexture) {
             if (properties.metallicRoughnessTexture) {
                 promises.push(this.loadTextureInfoAsync(context + "/metallicRoughnessTexture", properties.metallicRoughnessTexture, function (texture) {
                 promises.push(this.loadTextureInfoAsync(context + "/metallicRoughnessTexture", properties.metallicRoughnessTexture, function (texture) {
+                    texture.name = babylonMaterial.name + " (Metallic Roughness)";
                     babylonMaterial.metallicTexture = texture;
                     babylonMaterial.metallicTexture = texture;
                 }));
                 }));
                 babylonMaterial.useMetallnessFromMetallicTextureBlue = true;
                 babylonMaterial.useMetallnessFromMetallicTextureBlue = true;
@@ -5410,6 +5416,7 @@ var GLTFLoader = /** @class */ (function () {
         }
         }
         if (material.normalTexture) {
         if (material.normalTexture) {
             promises.push(this.loadTextureInfoAsync(context + "/normalTexture", material.normalTexture, function (texture) {
             promises.push(this.loadTextureInfoAsync(context + "/normalTexture", material.normalTexture, function (texture) {
+                texture.name = babylonMaterial.name + " (Normal)";
                 babylonMaterial.bumpTexture = texture;
                 babylonMaterial.bumpTexture = texture;
             }));
             }));
             babylonMaterial.invertNormalMapX = !this._babylonScene.useRightHandedSystem;
             babylonMaterial.invertNormalMapX = !this._babylonScene.useRightHandedSystem;
@@ -5421,6 +5428,7 @@ var GLTFLoader = /** @class */ (function () {
         }
         }
         if (material.occlusionTexture) {
         if (material.occlusionTexture) {
             promises.push(this.loadTextureInfoAsync(context + "/occlusionTexture", material.occlusionTexture, function (texture) {
             promises.push(this.loadTextureInfoAsync(context + "/occlusionTexture", material.occlusionTexture, function (texture) {
+                texture.name = babylonMaterial.name + " (Occlusion)";
                 babylonMaterial.ambientTexture = texture;
                 babylonMaterial.ambientTexture = texture;
             }));
             }));
             babylonMaterial.useAmbientInGrayScale = true;
             babylonMaterial.useAmbientInGrayScale = true;
@@ -5430,6 +5438,7 @@ var GLTFLoader = /** @class */ (function () {
         }
         }
         if (material.emissiveTexture) {
         if (material.emissiveTexture) {
             promises.push(this.loadTextureInfoAsync(context + "/emissiveTexture", material.emissiveTexture, function (texture) {
             promises.push(this.loadTextureInfoAsync(context + "/emissiveTexture", material.emissiveTexture, function (texture) {
+                texture.name = babylonMaterial.name + " (Emissive)";
                 babylonMaterial.emissiveTexture = texture;
                 babylonMaterial.emissiveTexture = texture;
             }));
             }));
         }
         }
@@ -5491,9 +5500,6 @@ var GLTFLoader = /** @class */ (function () {
         var texture = ArrayItem.Get(context + "/index", this._gltf.textures, textureInfo.index);
         var texture = ArrayItem.Get(context + "/index", this._gltf.textures, textureInfo.index);
         var promise = this._loadTextureAsync("/textures/" + textureInfo.index, texture, function (babylonTexture) {
         var promise = this._loadTextureAsync("/textures/" + textureInfo.index, texture, function (babylonTexture) {
             babylonTexture.coordinatesIndex = textureInfo.texCoord || 0;
             babylonTexture.coordinatesIndex = textureInfo.texCoord || 0;
-            if (texture.name) {
-                babylonTexture.name = texture.name;
-            }
             GLTFLoader.AddPointerMetadata(babylonTexture, context);
             GLTFLoader.AddPointerMetadata(babylonTexture, context);
             _this._parent.onTextureLoadedObservable.notifyObservers(babylonTexture);
             _this._parent.onTextureLoadedObservable.notifyObservers(babylonTexture);
             assign(babylonTexture);
             assign(babylonTexture);

File diff suppressed because it is too large
+ 1 - 1
dist/preview release/loaders/babylon.glTFFileLoader.js.map


File diff suppressed because it is too large
+ 1 - 1
dist/preview release/loaders/babylon.glTFFileLoader.min.js


+ 9 - 3
dist/preview release/loaders/babylonjs.loaders.js

@@ -4458,11 +4458,13 @@ var KHR_materials_pbrSpecularGlossiness = /** @class */ (function () {
         babylonMaterial.microSurface = properties.glossinessFactor == undefined ? 1 : properties.glossinessFactor;
         babylonMaterial.microSurface = properties.glossinessFactor == undefined ? 1 : properties.glossinessFactor;
         if (properties.diffuseTexture) {
         if (properties.diffuseTexture) {
             promises.push(this._loader.loadTextureInfoAsync(context + "/diffuseTexture", properties.diffuseTexture, function (texture) {
             promises.push(this._loader.loadTextureInfoAsync(context + "/diffuseTexture", properties.diffuseTexture, function (texture) {
+                texture.name = babylonMaterial.name + " (Diffuse)";
                 babylonMaterial.albedoTexture = texture;
                 babylonMaterial.albedoTexture = texture;
             }));
             }));
         }
         }
         if (properties.specularGlossinessTexture) {
         if (properties.specularGlossinessTexture) {
             promises.push(this._loader.loadTextureInfoAsync(context + "/specularGlossinessTexture", properties.specularGlossinessTexture, function (texture) {
             promises.push(this._loader.loadTextureInfoAsync(context + "/specularGlossinessTexture", properties.specularGlossinessTexture, function (texture) {
+                texture.name = babylonMaterial.name + " (Specular Glossiness)";
                 babylonMaterial.reflectivityTexture = texture;
                 babylonMaterial.reflectivityTexture = texture;
             }));
             }));
             babylonMaterial.reflectivityTexture.hasAlpha = true;
             babylonMaterial.reflectivityTexture.hasAlpha = true;
@@ -4535,6 +4537,7 @@ var KHR_materials_unlit = /** @class */ (function () {
             }
             }
             if (properties.baseColorTexture) {
             if (properties.baseColorTexture) {
                 promises.push(this._loader.loadTextureInfoAsync(context + "/baseColorTexture", properties.baseColorTexture, function (texture) {
                 promises.push(this._loader.loadTextureInfoAsync(context + "/baseColorTexture", properties.baseColorTexture, function (texture) {
+                    texture.name = babylonMaterial.name + " (Base Color)";
                     babylonMaterial.albedoTexture = texture;
                     babylonMaterial.albedoTexture = texture;
                 }));
                 }));
             }
             }
@@ -5317,6 +5320,7 @@ __webpack_require__.r(__webpack_exports__);
 
 
 
 
 
 
+
 /**
 /**
  * Helper class for working with arrays when loading the glTF asset
  * Helper class for working with arrays when loading the glTF asset
  */
  */
@@ -6637,11 +6641,13 @@ var GLTFLoader = /** @class */ (function () {
             babylonMaterial.roughness = properties.roughnessFactor == undefined ? 1 : properties.roughnessFactor;
             babylonMaterial.roughness = properties.roughnessFactor == undefined ? 1 : properties.roughnessFactor;
             if (properties.baseColorTexture) {
             if (properties.baseColorTexture) {
                 promises.push(this.loadTextureInfoAsync(context + "/baseColorTexture", properties.baseColorTexture, function (texture) {
                 promises.push(this.loadTextureInfoAsync(context + "/baseColorTexture", properties.baseColorTexture, function (texture) {
+                    texture.name = babylonMaterial.name + " (Base Color)";
                     babylonMaterial.albedoTexture = texture;
                     babylonMaterial.albedoTexture = texture;
                 }));
                 }));
             }
             }
             if (properties.metallicRoughnessTexture) {
             if (properties.metallicRoughnessTexture) {
                 promises.push(this.loadTextureInfoAsync(context + "/metallicRoughnessTexture", properties.metallicRoughnessTexture, function (texture) {
                 promises.push(this.loadTextureInfoAsync(context + "/metallicRoughnessTexture", properties.metallicRoughnessTexture, function (texture) {
+                    texture.name = babylonMaterial.name + " (Metallic Roughness)";
                     babylonMaterial.metallicTexture = texture;
                     babylonMaterial.metallicTexture = texture;
                 }));
                 }));
                 babylonMaterial.useMetallnessFromMetallicTextureBlue = true;
                 babylonMaterial.useMetallnessFromMetallicTextureBlue = true;
@@ -6752,6 +6758,7 @@ var GLTFLoader = /** @class */ (function () {
         }
         }
         if (material.normalTexture) {
         if (material.normalTexture) {
             promises.push(this.loadTextureInfoAsync(context + "/normalTexture", material.normalTexture, function (texture) {
             promises.push(this.loadTextureInfoAsync(context + "/normalTexture", material.normalTexture, function (texture) {
+                texture.name = babylonMaterial.name + " (Normal)";
                 babylonMaterial.bumpTexture = texture;
                 babylonMaterial.bumpTexture = texture;
             }));
             }));
             babylonMaterial.invertNormalMapX = !this._babylonScene.useRightHandedSystem;
             babylonMaterial.invertNormalMapX = !this._babylonScene.useRightHandedSystem;
@@ -6763,6 +6770,7 @@ var GLTFLoader = /** @class */ (function () {
         }
         }
         if (material.occlusionTexture) {
         if (material.occlusionTexture) {
             promises.push(this.loadTextureInfoAsync(context + "/occlusionTexture", material.occlusionTexture, function (texture) {
             promises.push(this.loadTextureInfoAsync(context + "/occlusionTexture", material.occlusionTexture, function (texture) {
+                texture.name = babylonMaterial.name + " (Occlusion)";
                 babylonMaterial.ambientTexture = texture;
                 babylonMaterial.ambientTexture = texture;
             }));
             }));
             babylonMaterial.useAmbientInGrayScale = true;
             babylonMaterial.useAmbientInGrayScale = true;
@@ -6772,6 +6780,7 @@ var GLTFLoader = /** @class */ (function () {
         }
         }
         if (material.emissiveTexture) {
         if (material.emissiveTexture) {
             promises.push(this.loadTextureInfoAsync(context + "/emissiveTexture", material.emissiveTexture, function (texture) {
             promises.push(this.loadTextureInfoAsync(context + "/emissiveTexture", material.emissiveTexture, function (texture) {
+                texture.name = babylonMaterial.name + " (Emissive)";
                 babylonMaterial.emissiveTexture = texture;
                 babylonMaterial.emissiveTexture = texture;
             }));
             }));
         }
         }
@@ -6833,9 +6842,6 @@ var GLTFLoader = /** @class */ (function () {
         var texture = ArrayItem.Get(context + "/index", this._gltf.textures, textureInfo.index);
         var texture = ArrayItem.Get(context + "/index", this._gltf.textures, textureInfo.index);
         var promise = this._loadTextureAsync("/textures/" + textureInfo.index, texture, function (babylonTexture) {
         var promise = this._loadTextureAsync("/textures/" + textureInfo.index, texture, function (babylonTexture) {
             babylonTexture.coordinatesIndex = textureInfo.texCoord || 0;
             babylonTexture.coordinatesIndex = textureInfo.texCoord || 0;
-            if (texture.name) {
-                babylonTexture.name = texture.name;
-            }
             GLTFLoader.AddPointerMetadata(babylonTexture, context);
             GLTFLoader.AddPointerMetadata(babylonTexture, context);
             _this._parent.onTextureLoadedObservable.notifyObservers(babylonTexture);
             _this._parent.onTextureLoadedObservable.notifyObservers(babylonTexture);
             assign(babylonTexture);
             assign(babylonTexture);

File diff suppressed because it is too large
+ 1 - 1
dist/preview release/loaders/babylonjs.loaders.js.map


File diff suppressed because it is too large
+ 2 - 2
dist/preview release/loaders/babylonjs.loaders.min.js


+ 1 - 1
dist/preview release/packagesSizeBaseLine.json

@@ -1 +1 @@
-{"engineOnly":252171,"sceneOnly":510337,"minGridMaterial":639247,"minStandardMaterial":765316}
+{"engineOnly":166401,"sceneOnly":510917,"minGridMaterial":639821,"minStandardMaterial":765892}

File diff suppressed because it is too large
+ 58132 - 57875
dist/preview release/viewer/babylon.module.d.ts


File diff suppressed because it is too large
+ 80 - 52
dist/preview release/viewer/babylon.viewer.js


File diff suppressed because it is too large
+ 2 - 2
dist/preview release/viewer/babylon.viewer.max.js


+ 4 - 3
dist/preview release/what's new.md

@@ -24,8 +24,8 @@
 - Added startAndReleaseDragOnPointerEvents property to pointerDragBehavior which can be set to false for custom drag triggering ([TrevorDev](https://github.com/TrevorDev))
 - Added startAndReleaseDragOnPointerEvents property to pointerDragBehavior which can be set to false for custom drag triggering ([TrevorDev](https://github.com/TrevorDev))
 - Effect renderer to render one or multiple shader effects to a texture ([TrevorDev](https://github.com/TrevorDev))
 - Effect renderer to render one or multiple shader effects to a texture ([TrevorDev](https://github.com/TrevorDev))
 - Added url parameters to web request modifiers ([PierreLeBlond](https://github.com/PierreLeBlond))
 - Added url parameters to web request modifiers ([PierreLeBlond](https://github.com/PierreLeBlond))
-- WebXR updated to spec as of June 27th ([TrevorDev](https://github.com/TrevorDev))
-- WebXR webVR parity helpers ([TrevorDev](https://github.com/TrevorDev))
+- WebXR updated to spec as of July 10th ([TrevorDev](https://github.com/TrevorDev))
+- WebXR webVR parity helpers (Vive, WMR, Oculus Rift) ([TrevorDev](https://github.com/TrevorDev))
 
 
 ### Engine
 ### Engine
 - Morph targets now can morph UV channel as well ([Deltakosh](https://github.com/deltakosh/))
 - Morph targets now can morph UV channel as well ([Deltakosh](https://github.com/deltakosh/))
@@ -93,9 +93,10 @@
 - Fix bug when adding and removing observers in quick succession ([sable](https://github.com/thscott))
 - Fix bug when adding and removing observers in quick succession ([sable](https://github.com/thscott))
 - Cannon and Ammo forceUpdate will no longer cause an unexpected exception ([TrevorDev](https://github.com/TrevorDev))
 - Cannon and Ammo forceUpdate will no longer cause an unexpected exception ([TrevorDev](https://github.com/TrevorDev))
 - Loading the same multi-material twice and disposing one should not impact the other ([TrevorDev](https://github.com/TrevorDev))
 - Loading the same multi-material twice and disposing one should not impact the other ([TrevorDev](https://github.com/TrevorDev))
-- GLTF loader should now preserve the texture naming ([Drigax](https://github.com/Drigax))
 - GLTF exporter should no longer duplicate exported texture data ([Drigax](https://github.com/Drigax))
 - GLTF exporter should no longer duplicate exported texture data ([Drigax](https://github.com/Drigax))
 - Avoid exception when disposing of Ammo cloth physics ([TrevorDev](https://github.com/TrevorDev))
 - Avoid exception when disposing of Ammo cloth physics ([TrevorDev](https://github.com/TrevorDev))
 
 
 ## Breaking changes
 ## Breaking changes
 - Setting mesh.scaling to a new vector will no longer automatically call forceUpdate (this should be done manually when needed) ([TrevorDev](https://github.com/TrevorDev))
 - Setting mesh.scaling to a new vector will no longer automatically call forceUpdate (this should be done manually when needed) ([TrevorDev](https://github.com/TrevorDev))
+- `Tools.ExtractMinAndMaxIndexed` and `Tools.ExtractMinAndMax` are now ambiant functions (available on `BABYLON.extractMinAndMaxIndexed` and `BABYLON.extractMinAndMax`) ([Deltakosh](https://github.com/deltakosh/))
+- `Tools.QueueNewFrame` was removed in favor of `Engine.QueueNewFrame` ([Deltakosh](https://github.com/deltakosh/))

+ 1 - 1
gui/src/2D/adtInstrumentation.ts

@@ -1,7 +1,7 @@
 
 
 import { Nullable } from "babylonjs/types";
 import { Nullable } from "babylonjs/types";
 import { Observer } from "babylonjs/Misc/observable";
 import { Observer } from "babylonjs/Misc/observable";
-import { PerfCounter } from "babylonjs/Misc/tools";
+import { PerfCounter } from "babylonjs/Misc/perfCounter";
 import { IDisposable } from "babylonjs/scene";
 import { IDisposable } from "babylonjs/scene";
 
 
 import { AdvancedDynamicTexture } from "./advancedDynamicTexture";
 import { AdvancedDynamicTexture } from "./advancedDynamicTexture";

+ 2 - 0
loaders/src/glTF/2.0/Extensions/KHR_materials_pbrSpecularGlossiness.ts

@@ -73,12 +73,14 @@ export class KHR_materials_pbrSpecularGlossiness implements IGLTFLoaderExtension
 
 
         if (properties.diffuseTexture) {
         if (properties.diffuseTexture) {
             promises.push(this._loader.loadTextureInfoAsync(`${context}/diffuseTexture`, properties.diffuseTexture, (texture) => {
             promises.push(this._loader.loadTextureInfoAsync(`${context}/diffuseTexture`, properties.diffuseTexture, (texture) => {
+                texture.name = `${babylonMaterial.name} (Diffuse)`;
                 babylonMaterial.albedoTexture = texture;
                 babylonMaterial.albedoTexture = texture;
             }));
             }));
         }
         }
 
 
         if (properties.specularGlossinessTexture) {
         if (properties.specularGlossinessTexture) {
             promises.push(this._loader.loadTextureInfoAsync(`${context}/specularGlossinessTexture`, properties.specularGlossinessTexture, (texture) => {
             promises.push(this._loader.loadTextureInfoAsync(`${context}/specularGlossinessTexture`, properties.specularGlossinessTexture, (texture) => {
+                texture.name = `${babylonMaterial.name} (Specular Glossiness)`;
                 babylonMaterial.reflectivityTexture = texture;
                 babylonMaterial.reflectivityTexture = texture;
             }));
             }));
 
 

+ 1 - 0
loaders/src/glTF/2.0/Extensions/KHR_materials_unlit.ts

@@ -58,6 +58,7 @@ export class KHR_materials_unlit implements IGLTFLoaderExtension {
 
 
             if (properties.baseColorTexture) {
             if (properties.baseColorTexture) {
                 promises.push(this._loader.loadTextureInfoAsync(`${context}/baseColorTexture`, properties.baseColorTexture, (texture) => {
                 promises.push(this._loader.loadTextureInfoAsync(`${context}/baseColorTexture`, properties.baseColorTexture, (texture) => {
+                    texture.name = `${babylonMaterial.name} (Base Color)`;
                     babylonMaterial.albedoTexture = texture;
                     babylonMaterial.albedoTexture = texture;
                 }));
                 }));
             }
             }

File diff suppressed because it is too large
+ 2324 - 2322
loaders/src/glTF/2.0/glTFLoader.ts


+ 2 - 3
src/Behaviors/Cameras/framingBehavior.ts

@@ -4,7 +4,6 @@ import { ArcRotateCamera } from "../../Cameras/arcRotateCamera";
 import { ExponentialEase, EasingFunction } from "../../Animations/easing";
 import { ExponentialEase, EasingFunction } from "../../Animations/easing";
 import { Nullable } from "../../types";
 import { Nullable } from "../../types";
 import { PointerInfoPre, PointerEventTypes } from "../../Events/pointerEvents";
 import { PointerInfoPre, PointerEventTypes } from "../../Events/pointerEvents";
-import { Tools } from "../../Misc/tools";
 import { PrecisionDate } from "../../Misc/precisionDate";
 import { PrecisionDate } from "../../Misc/precisionDate";
 import { Observer } from "../../Misc/observable";
 import { Observer } from "../../Misc/observable";
 import { AbstractMesh } from "../../Meshes/abstractMesh";
 import { AbstractMesh } from "../../Meshes/abstractMesh";
@@ -293,8 +292,8 @@ export class FramingBehavior implements Behavior<ArcRotateCamera> {
 
 
         for (let i = 0; i < meshes.length; i++) {
         for (let i = 0; i < meshes.length; i++) {
             let boundingInfo = meshes[i].getHierarchyBoundingVectors(true);
             let boundingInfo = meshes[i].getHierarchyBoundingVectors(true);
-            Tools.CheckExtends(boundingInfo.min, min, max);
-            Tools.CheckExtends(boundingInfo.max, min, max);
+            Vector3.CheckExtends(boundingInfo.min, min, max);
+            Vector3.CheckExtends(boundingInfo.max, min, max);
         }
         }
 
 
         this.zoomOnBoundingInfo(min, max, focusOnOriginXZ, onAnimationEnd);
         this.zoomOnBoundingInfo(min, max, focusOnOriginXZ, onAnimationEnd);

+ 2 - 2
src/Cameras/XR/webXRCamera.ts

@@ -21,7 +21,7 @@ export class WebXRCamera extends FreeCamera {
         super(name, Vector3.Zero(), scene);
         super(name, Vector3.Zero(), scene);
 
 
         // Initial camera configuration
         // Initial camera configuration
-        this.minZ = 0;
+        this.minZ = 0.1;
         this.rotationQuaternion = new Quaternion();
         this.rotationQuaternion = new Quaternion();
         this.cameraRigMode = Camera.RIG_MODE_CUSTOM;
         this.cameraRigMode = Camera.RIG_MODE_CUSTOM;
         this.updateUpVectorFromRotation = true;
         this.updateUpVectorFromRotation = true;
@@ -31,7 +31,7 @@ export class WebXRCamera extends FreeCamera {
     private _updateNumberOfRigCameras(viewCount = 1) {
     private _updateNumberOfRigCameras(viewCount = 1) {
         while (this.rigCameras.length < viewCount) {
         while (this.rigCameras.length < viewCount) {
             var newCamera = new TargetCamera("view: " + this.rigCameras.length, Vector3.Zero(), this.getScene());
             var newCamera = new TargetCamera("view: " + this.rigCameras.length, Vector3.Zero(), this.getScene());
-            newCamera.minZ = 0;
+            newCamera.minZ = 0.1;
             newCamera.parent = this;
             newCamera.parent = this;
             newCamera.rotationQuaternion = new Quaternion();
             newCamera.rotationQuaternion = new Quaternion();
             newCamera.updateUpVectorFromRotation = true;
             newCamera.updateUpVectorFromRotation = true;

+ 16 - 1
src/Cameras/XR/webXRControllerModelLoader.ts

@@ -2,6 +2,7 @@ import { Quaternion } from '../../Maths/math';
 import { WindowsMotionController } from '../../Gamepads/Controllers/windowsMotionController';
 import { WindowsMotionController } from '../../Gamepads/Controllers/windowsMotionController';
 import { OculusTouchController } from '../../Gamepads/Controllers/oculusTouchController';
 import { OculusTouchController } from '../../Gamepads/Controllers/oculusTouchController';
 import { WebXRInput } from './webXRInput';
 import { WebXRInput } from './webXRInput';
+import { ViveController } from '../../Gamepads/Controllers/viveController';
 
 
 /**
 /**
  * Loads a controller model and adds it as a child of the WebXRControllers grip when the controller is created
  * Loads a controller model and adds it as a child of the WebXRControllers grip when the controller is created
@@ -13,13 +14,27 @@ export class WebXRControllerModelLoader {
      */
      */
     constructor(input: WebXRInput) {
     constructor(input: WebXRInput) {
         input.onControllerAddedObservable.add((c) => {
         input.onControllerAddedObservable.add((c) => {
-            if (c.inputSource.gamepad && c.inputSource.gamepad.id === "oculus-touch") {
+            if (c.inputSource.gamepad && c.inputSource.gamepad.id === "htc-vive") {
+                let controllerModel = new ViveController(c.inputSource.gamepad);
+                controllerModel.hand = c.inputSource.handedness;
+                controllerModel.isXR = true;
+                controllerModel.initControllerMesh(c.grip!.getScene(), (m) => {
+                    m.isPickable = false;
+                    m.getChildMeshes(false).forEach((m) => {
+                        m.isPickable = false;
+                    });
+                    controllerModel.mesh!.parent = c.grip!;
+                    controllerModel.mesh!.rotationQuaternion = Quaternion.FromEulerAngles(0, Math.PI, 0);
+                });
+            } else if (c.inputSource.gamepad && c.inputSource.gamepad.id === "oculus-touch") {
                 let controllerModel = new OculusTouchController(c.inputSource.gamepad);
                 let controllerModel = new OculusTouchController(c.inputSource.gamepad);
                 controllerModel.hand = c.inputSource.handedness;
                 controllerModel.hand = c.inputSource.handedness;
                 controllerModel.isXR = true;
                 controllerModel.isXR = true;
                 controllerModel.initControllerMesh(c.grip!.getScene(), (m) => {
                 controllerModel.initControllerMesh(c.grip!.getScene(), (m) => {
                     controllerModel.mesh!.parent = c.grip!;
                     controllerModel.mesh!.parent = c.grip!;
                     controllerModel.mesh!.rotationQuaternion = Quaternion.FromEulerAngles(0, Math.PI, 0);
                     controllerModel.mesh!.rotationQuaternion = Quaternion.FromEulerAngles(0, Math.PI, 0);
+                    controllerModel.mesh!.position.y = 0.034;
+                    controllerModel.mesh!.position.z = 0.052;
                 });
                 });
             }else if (c.inputSource.gamepad && c.inputSource.gamepad.id === "oculus-quest") {
             }else if (c.inputSource.gamepad && c.inputSource.gamepad.id === "oculus-quest") {
                 OculusTouchController._IsQuest = true;
                 OculusTouchController._IsQuest = true;

+ 2 - 2
src/Cameras/XR/webXRControllerTeleportation.ts

@@ -100,7 +100,7 @@ export class WebXRControllerTeleportation {
                 }
                 }
 
 
                 if (c.inputSource.gamepad) {
                 if (c.inputSource.gamepad) {
-                    if (c.inputSource.gamepad.axes[1]) {
+                    if (c.inputSource.gamepad.axes[1] !== undefined) {
                         // Forward teleportation
                         // Forward teleportation
                         if (c.inputSource.gamepad.axes[1] < -0.7) {
                         if (c.inputSource.gamepad.axes[1] < -0.7) {
                             forwardReadyToTeleport = true;
                             forwardReadyToTeleport = true;
@@ -145,7 +145,7 @@ export class WebXRControllerTeleportation {
                         }
                         }
                     }
                     }
 
 
-                    if (c.inputSource.gamepad.axes[0]) {
+                    if (c.inputSource.gamepad.axes[0] !== undefined) {
                         if (c.inputSource.gamepad.axes[0] < -0.7) {
                         if (c.inputSource.gamepad.axes[0] < -0.7) {
                             leftReadyToTeleport = true;
                             leftReadyToTeleport = true;
                         }else {
                         }else {

+ 1 - 1
src/Cameras/XR/webXRExperienceHelper.ts

@@ -123,7 +123,7 @@ export class WebXRExperienceHelper implements IDisposable {
         }).then(() => {
         }).then(() => {
             return outputCanvas.initializeXRLayerAsync(this.sessionManager.session);
             return outputCanvas.initializeXRLayerAsync(this.sessionManager.session);
         }).then(() => {
         }).then(() => {
-            return this.sessionManager.updateRenderStateAsync({baseLayer: outputCanvas.xrLayer});
+            return this.sessionManager.updateRenderStateAsync({depthFar: this.camera.maxZ, depthNear: this.camera.minZ, baseLayer: outputCanvas.xrLayer!});
         }).then(() => {
         }).then(() => {
             return this.sessionManager.startRenderingToXRAsync();
             return this.sessionManager.startRenderingToXRAsync();
         }).then(() => {
         }).then(() => {

+ 1 - 1
src/Cameras/XR/webXRSessionManager.ts

@@ -102,7 +102,7 @@ export class WebXRSessionManager implements IDisposable {
      * @param state state to set
      * @param state state to set
      * @returns a promise that resolves once the render state has been updated
      * @returns a promise that resolves once the render state has been updated
      */
      */
-    public updateRenderStateAsync(state: any) {
+    public updateRenderStateAsync(state: XRRenderState) {
         if (state.baseLayer) {
         if (state.baseLayer) {
             this.baseLayer = state.baseLayer;
             this.baseLayer = state.baseLayer;
         }
         }

+ 5 - 1
src/Cameras/camera.ts

@@ -230,11 +230,15 @@ export class Camera extends Node {
     /**
     /**
      * Defines the list of custom render target which are rendered to and then used as the input to this camera's render. Eg. display another camera view on a TV in the main scene
      * Defines the list of custom render target which are rendered to and then used as the input to this camera's render. Eg. display another camera view on a TV in the main scene
      * This is pretty helpfull if you wish to make a camera render to a texture you could reuse somewhere
      * This is pretty helpfull if you wish to make a camera render to a texture you could reuse somewhere
-     * else in the scene.
+     * else in the scene. (Eg. security camera)
+     *
+     * To change the final output target of the camera, camera.outputRenderTarget should be used instead (eg. webXR renders to a render target corrisponding to an HMD)
      */
      */
     public customRenderTargets = new Array<RenderTargetTexture>();
     public customRenderTargets = new Array<RenderTargetTexture>();
     /**
     /**
      * When set, the camera will render to this render target instead of the default canvas
      * When set, the camera will render to this render target instead of the default canvas
+     *
+     * If the desire is to use the output of a camera as a texture in the scene consider using camera.customRenderTargets instead
      */
      */
     public outputRenderTarget: Nullable<RenderTargetTexture> = null;
     public outputRenderTarget: Nullable<RenderTargetTexture> = null;
 
 

+ 3 - 3
src/Engines/Extensions/engine.cubeTexture.ts

@@ -5,7 +5,7 @@ import { Nullable } from '../../types';
 import { Scene } from '../../scene';
 import { Scene } from '../../scene';
 import { IInternalTextureLoader } from '../../Materials/Textures/internalTextureLoader';
 import { IInternalTextureLoader } from '../../Materials/Textures/internalTextureLoader';
 import { WebRequest } from '../../Misc/webRequest';
 import { WebRequest } from '../../Misc/webRequest';
-import { Tools } from '../../Misc/tools';
+import { FileTools } from '../../Misc/fileTools';
 
 
 declare module "../../Engines/engine" {
 declare module "../../Engines/engine" {
     export interface Engine {
     export interface Engine {
@@ -191,7 +191,7 @@ Engine.prototype._partialLoadImg = function(url: string, index: number, loadedIm
         }
         }
     };
     };
 
 
-    img = Tools.LoadImage(url, onload, onerror, scene ? scene.offlineProvider : null);
+    img = FileTools.LoadImage(url, onload, onerror, scene ? scene.offlineProvider : null);
     if (scene) {
     if (scene) {
         scene._addPendingData(img);
         scene._addPendingData(img);
     }
     }
@@ -268,7 +268,7 @@ Engine.prototype.createCubeTexture = function(rootUrl: string, scene: Nullable<S
         }
         }
 
 
         this._cascadeLoadImgs(scene, (imgs) => {
         this._cascadeLoadImgs(scene, (imgs) => {
-            var width = this.needPOTTextures ? Tools.GetExponentOfTwo(imgs[0].width, this._caps.maxCubemapTextureSize) : imgs[0].width;
+            var width = this.needPOTTextures ? Engine.GetExponentOfTwo(imgs[0].width, this._caps.maxCubemapTextureSize) : imgs[0].width;
             var height = width;
             var height = width;
 
 
             this._prepareWorkingCanvas();
             this._prepareWorkingCanvas();

+ 2 - 2
src/Engines/Extensions/engine.webVR.ts

@@ -133,7 +133,7 @@ Engine.prototype.initWebVRAsync = function(): Promise<IDisplayChangedEventArgs>
         this._onVrDisplayDisconnect = () => {
         this._onVrDisplayDisconnect = () => {
             this._vrDisplay.cancelAnimationFrame(this._frameHandler);
             this._vrDisplay.cancelAnimationFrame(this._frameHandler);
             this._vrDisplay = undefined;
             this._vrDisplay = undefined;
-            this._frameHandler = Tools.QueueNewFrame(this._bindedRenderFunction);
+            this._frameHandler = Engine.QueueNewFrame(this._bindedRenderFunction);
             notifyObservers();
             notifyObservers();
         };
         };
         this._onVrDisplayPresentChange = () => {
         this._onVrDisplayPresentChange = () => {
@@ -266,5 +266,5 @@ Engine.prototype.isVRPresenting = function() {
 };
 };
 
 
 Engine.prototype._requestVRFrame = function() {
 Engine.prototype._requestVRFrame = function() {
-    this._frameHandler = Tools.QueueNewFrame(this._bindedRenderFunction, this._vrDisplay);
+    this._frameHandler = Engine.QueueNewFrame(this._bindedRenderFunction, this._vrDisplay);
 };
 };

+ 4 - 4
src/Engines/Processors/shaderCodeNode.ts

@@ -1,5 +1,5 @@
 import { ProcessingOptions } from './shaderProcessingOptions';
 import { ProcessingOptions } from './shaderProcessingOptions';
-import { Tools } from '../../Misc/tools';
+import { StringTools } from '../../Misc/stringTools';
 
 
 /** @hidden */
 /** @hidden */
 export class ShaderCodeNode {
 export class ShaderCodeNode {
@@ -18,11 +18,11 @@ export class ShaderCodeNode {
             let value: string = this.line;
             let value: string = this.line;
             let processor = options.processor;
             let processor = options.processor;
             if (processor) {
             if (processor) {
-                if (processor.attributeProcessor && Tools.StartsWith(this.line, "attribute")) {
+                if (processor.attributeProcessor && StringTools.StartsWith(this.line, "attribute")) {
                     value = processor.attributeProcessor(this.line);
                     value = processor.attributeProcessor(this.line);
-                } else if (processor.varyingProcessor && Tools.StartsWith(this.line, "varying")) {
+                } else if (processor.varyingProcessor && StringTools.StartsWith(this.line, "varying")) {
                     value = processor.varyingProcessor(this.line, options.isFragment);
                     value = processor.varyingProcessor(this.line, options.isFragment);
-                } else if ((processor.uniformProcessor || processor.uniformBufferProcessor) && Tools.StartsWith(this.line, "uniform")) {
+                } else if ((processor.uniformProcessor || processor.uniformBufferProcessor) && StringTools.StartsWith(this.line, "uniform")) {
                     let regex = /uniform (.+) (.+)/;
                     let regex = /uniform (.+) (.+)/;
 
 
                     if (regex.test(this.line)) { // uniform
                     if (regex.test(this.line)) { // uniform

+ 2 - 2
src/Engines/Processors/shaderProcessor.ts

@@ -1,4 +1,3 @@
-import { Tools } from '../../Misc/tools';
 import { ShaderCodeNode } from './shaderCodeNode';
 import { ShaderCodeNode } from './shaderCodeNode';
 import { ShaderCodeCursor } from './shaderCodeCursor';
 import { ShaderCodeCursor } from './shaderCodeCursor';
 import { ShaderCodeConditionNode } from './shaderCodeConditionNode';
 import { ShaderCodeConditionNode } from './shaderCodeConditionNode';
@@ -9,6 +8,7 @@ import { ShaderDefineAndOperator } from './Expressions/Operators/shaderDefineAnd
 import { ShaderDefineExpression } from './Expressions/shaderDefineExpression';
 import { ShaderDefineExpression } from './Expressions/shaderDefineExpression';
 import { ShaderDefineArithmeticOperator } from './Expressions/Operators/shaderDefineArithmeticOperator';
 import { ShaderDefineArithmeticOperator } from './Expressions/Operators/shaderDefineArithmeticOperator';
 import { ProcessingOptions } from './shaderProcessingOptions';
 import { ProcessingOptions } from './shaderProcessingOptions';
+import { FileTools } from '../../Misc/fileTools';
 
 
 /** @hidden */
 /** @hidden */
 export class ShaderProcessor {
 export class ShaderProcessor {
@@ -331,7 +331,7 @@ export class ShaderProcessor {
             } else {
             } else {
                 var includeShaderUrl = options.shadersRepository + "ShadersInclude/" + includeFile + ".fx";
                 var includeShaderUrl = options.shadersRepository + "ShadersInclude/" + includeFile + ".fx";
 
 
-                Tools.LoadFile(includeShaderUrl, (fileContent) => {
+                FileTools.LoadFile(includeShaderUrl, (fileContent) => {
                     options.includesShadersStore[includeFile] = fileContent as string;
                     options.includesShadersStore[includeFile] = fileContent as string;
                     this._ProcessIncludes(<string>returnValue, options, callback);
                     this._ProcessIncludes(<string>returnValue, options, callback);
                 });
                 });

+ 220 - 80
src/Engines/engine.ts

@@ -1,13 +1,8 @@
 import { Observer, Observable } from "../Misc/observable";
 import { Observer, Observable } from "../Misc/observable";
 import { PerformanceMonitor } from "../Misc/performanceMonitor";
 import { PerformanceMonitor } from "../Misc/performanceMonitor";
 import { StringDictionary } from "../Misc/stringDictionary";
 import { StringDictionary } from "../Misc/stringDictionary";
-import { PromisePolyfill } from "../Misc/promise";
-import { Tools, ICustomAnimationFrameRequester, PerfCounter, IFileRequest } from "../Misc/tools";
-import { Nullable, FloatArray, DataArray, IndicesArray } from "../types";
-import { Camera } from "../Cameras/camera";
+import { Nullable, FloatArray, DataArray, IndicesArray, float } from "../types";
 import { Scene } from "../scene";
 import { Scene } from "../scene";
-import { Matrix, Color3, Color4, Viewport, Vector4 } from "../Maths/math";
-import { Scalar } from "../Maths/math.scalar";
 import { VertexBuffer } from "../Meshes/buffer";
 import { VertexBuffer } from "../Meshes/buffer";
 import { UniformBuffer } from "../Materials/uniformBuffer";
 import { UniformBuffer } from "../Materials/uniformBuffer";
 import { Effect, EffectCreationOptions, EffectFallbacks } from "../Materials/effect";
 import { Effect, EffectCreationOptions, EffectFallbacks } from "../Materials/effect";
@@ -32,6 +27,10 @@ import { DataBuffer } from '../Meshes/dataBuffer';
 import { WebGLDataBuffer } from '../Meshes/WebGL/webGLDataBuffer';
 import { WebGLDataBuffer } from '../Meshes/WebGL/webGLDataBuffer';
 import { IShaderProcessor } from './Processors/iShaderProcessor';
 import { IShaderProcessor } from './Processors/iShaderProcessor';
 import { WebGL2ShaderProcessor } from './WebGL/webGL2ShaderProcessors';
 import { WebGL2ShaderProcessor } from './WebGL/webGL2ShaderProcessors';
+import { PerfCounter } from '../Misc/perfCounter';
+import { IFileRequest } from '../Misc/fileRequest';
+import { ICustomAnimationFrameRequester } from '../Misc/customAnimationFrameRequester';
+import { FileTools } from '../Misc/fileTools';
 
 
 declare type Material = import("../Materials/material").Material;
 declare type Material = import("../Materials/material").Material;
 declare type PostProcess = import("../PostProcesses/postProcess").PostProcess;
 declare type PostProcess = import("../PostProcesses/postProcess").PostProcess;
@@ -40,6 +39,36 @@ declare type VideoTexture = import("../Materials/Textures/videoTexture").VideoTe
 declare type RenderTargetTexture = import("../Materials/Textures/renderTargetTexture").RenderTargetTexture;
 declare type RenderTargetTexture = import("../Materials/Textures/renderTargetTexture").RenderTargetTexture;
 
 
 /**
 /**
+ * @hidden
+ */
+export interface IColor4Like {
+    r: float;
+    g: float;
+    b: float;
+    a: float;
+}
+
+/**
+ * @hidden
+ */
+export interface IViewportLike {
+    x: float;
+    y: float;
+    width: float;
+    height: float;
+}
+
+/**
+ * Defines the interface used by objects containing a viewport (like a camera)
+ */
+interface IViewportOwnerLike {
+    /**
+     * Gets or sets the viewport
+     */
+    viewport: IViewportLike;
+}
+
+/**
  * Keeps track of all the buffer info used in engine.
  * Keeps track of all the buffer info used in engine.
  */
  */
 class BufferPointer {
 class BufferPointer {
@@ -847,7 +876,7 @@ export class Engine {
     private _compiledEffects: { [key: string]: Effect } = {};
     private _compiledEffects: { [key: string]: Effect } = {};
     private _vertexAttribArraysEnabled: boolean[] = [];
     private _vertexAttribArraysEnabled: boolean[] = [];
     /** @hidden */
     /** @hidden */
-    protected _cachedViewport: Nullable<Viewport>;
+    protected _cachedViewport: Nullable<IViewportLike>;
     private _cachedVertexArrayObject: Nullable<WebGLVertexArrayObject>;
     private _cachedVertexArrayObject: Nullable<WebGLVertexArrayObject>;
     /** @hidden */
     /** @hidden */
     protected _cachedVertexBuffers: any;
     protected _cachedVertexBuffers: any;
@@ -915,7 +944,7 @@ export class Engine {
     /**
     /**
      * Gets the current viewport
      * Gets the current viewport
      */
      */
-    public get currentViewport(): Nullable<Viewport> {
+    public get currentViewport(): Nullable<IViewportLike> {
         return this._cachedViewport;
         return this._cachedViewport;
     }
     }
 
 
@@ -968,9 +997,6 @@ export class Engine {
      */
      */
     constructor(canvasOrContext: Nullable<HTMLCanvasElement | WebGLRenderingContext>, antialias?: boolean, options?: EngineOptions, adaptToDeviceRatio: boolean = false) {
     constructor(canvasOrContext: Nullable<HTMLCanvasElement | WebGLRenderingContext>, antialias?: boolean, options?: EngineOptions, adaptToDeviceRatio: boolean = false) {
 
 
-        // Register promises
-        PromisePolyfill.Apply();
-
         let canvas: Nullable<HTMLCanvasElement> = null;
         let canvas: Nullable<HTMLCanvasElement> = null;
         Engine.Instances.push(this);
         Engine.Instances.push(this);
 
 
@@ -1210,7 +1236,7 @@ export class Engine {
 
 
                 // Pointer lock
                 // Pointer lock
                 if (this.isFullscreen && this._pointerLockRequested && canvas) {
                 if (this.isFullscreen && this._pointerLockRequested && canvas) {
-                    Tools.RequestPointerlock(canvas);
+                    Engine._RequestPointerlock(canvas);
                 }
                 }
             };
             };
 
 
@@ -1638,12 +1664,12 @@ export class Engine {
 
 
     /**
     /**
      * Gets current aspect ratio
      * Gets current aspect ratio
-     * @param camera defines the camera to use to get the aspect ratio
+     * @param viewportOwner defines the camera to use to get the aspect ratio
      * @param useScreen defines if screen size must be used (or the current render target if any)
      * @param useScreen defines if screen size must be used (or the current render target if any)
      * @returns a number defining the aspect ratio
      * @returns a number defining the aspect ratio
      */
      */
-    public getAspectRatio(camera: Camera, useScreen = false): number {
-        var viewport = camera.viewport;
+    public getAspectRatio(viewportOwner: IViewportOwnerLike, useScreen = false): number {
+        var viewport = viewportOwner.viewport;
         return (this.getRenderWidth(useScreen) * viewport.width) / (this.getRenderHeight(useScreen) * viewport.height);
         return (this.getRenderWidth(useScreen) * viewport.width) / (this.getRenderHeight(useScreen) * viewport.height);
     }
     }
 
 
@@ -2010,12 +2036,12 @@ export class Engine {
         if (this._activeRenderLoops.length > 0) {
         if (this._activeRenderLoops.length > 0) {
             // Register new frame
             // Register new frame
             if (this.customAnimationFrameRequester) {
             if (this.customAnimationFrameRequester) {
-                this.customAnimationFrameRequester.requestID = Tools.QueueNewFrame(this.customAnimationFrameRequester.renderFunction || this._bindedRenderFunction, this.customAnimationFrameRequester);
+                this.customAnimationFrameRequester.requestID = Engine.QueueNewFrame(this.customAnimationFrameRequester.renderFunction || this._bindedRenderFunction, this.customAnimationFrameRequester);
                 this._frameHandler = this.customAnimationFrameRequester.requestID;
                 this._frameHandler = this.customAnimationFrameRequester.requestID;
             } else if (this.isVRPresenting()) {
             } else if (this.isVRPresenting()) {
                 this._requestVRFrame();
                 this._requestVRFrame();
             } else {
             } else {
-                this._frameHandler = Tools.QueueNewFrame(this._bindedRenderFunction);
+                this._frameHandler = Engine.QueueNewFrame(this._bindedRenderFunction);
             }
             }
         } else {
         } else {
             this._renderingQueueLaunched = false;
             this._renderingQueueLaunched = false;
@@ -2036,7 +2062,7 @@ export class Engine {
         if (!this._renderingQueueLaunched) {
         if (!this._renderingQueueLaunched) {
             this._renderingQueueLaunched = true;
             this._renderingQueueLaunched = true;
             this._bindedRenderFunction = this._renderLoop.bind(this);
             this._bindedRenderFunction = this._renderLoop.bind(this);
-            this._frameHandler = Tools.QueueNewFrame(this._bindedRenderFunction);
+            this._frameHandler = Engine.QueueNewFrame(this._bindedRenderFunction);
         }
         }
     }
     }
 
 
@@ -2060,7 +2086,7 @@ export class Engine {
         if (!this.isFullscreen) {
         if (!this.isFullscreen) {
             this._pointerLockRequested = requestPointerLock;
             this._pointerLockRequested = requestPointerLock;
             if (this._renderingCanvas) {
             if (this._renderingCanvas) {
-                Tools.RequestFullscreen(this._renderingCanvas);
+                Engine._RequestFullscreen(this._renderingCanvas);
             }
             }
         }
         }
     }
     }
@@ -2070,7 +2096,7 @@ export class Engine {
      */
      */
     public exitFullscreen(): void {
     public exitFullscreen(): void {
         if (this.isFullscreen) {
         if (this.isFullscreen) {
-            Tools.ExitFullscreen();
+            Engine._ExitFullscreen();
         }
         }
     }
     }
 
 
@@ -2079,7 +2105,7 @@ export class Engine {
      */
      */
     public enterPointerlock(): void {
     public enterPointerlock(): void {
         if (this._renderingCanvas) {
         if (this._renderingCanvas) {
-            Tools.RequestPointerlock(this._renderingCanvas);
+            Engine._RequestPointerlock(this._renderingCanvas);
         }
         }
     }
     }
 
 
@@ -2087,7 +2113,7 @@ export class Engine {
      * Exits Pointerlock mode
      * Exits Pointerlock mode
      */
      */
     public exitPointerlock(): void {
     public exitPointerlock(): void {
-        Tools.ExitPointerlock();
+        Engine._ExitPointerlock();
     }
     }
 
 
     /**
     /**
@@ -2097,7 +2123,7 @@ export class Engine {
      * @param depth defines if the depth buffer must be cleared
      * @param depth defines if the depth buffer must be cleared
      * @param stencil defines if the stencil buffer must be cleared
      * @param stencil defines if the stencil buffer must be cleared
      */
      */
-    public clear(color: Nullable<Color4>, backBuffer: boolean, depth: boolean, stencil: boolean = false): void {
+    public clear(color: Nullable<IColor4Like>, backBuffer: boolean, depth: boolean, stencil: boolean = false): void {
         this.applyStates();
         this.applyStates();
 
 
         var mode = 0;
         var mode = 0;
@@ -2124,7 +2150,7 @@ export class Engine {
      * @param height defines the height of the clear rectangle
      * @param height defines the height of the clear rectangle
      * @param clearColor defines the clear color
      * @param clearColor defines the clear color
      */
      */
-    public scissorClear(x: number, y: number, width: number, height: number, clearColor: Color4): void {
+    public scissorClear(x: number, y: number, width: number, height: number, clearColor: IColor4Like): void {
         this.enableScissor(x, y, width, height);
         this.enableScissor(x, y, width, height);
         this.clear(clearColor, true, true, true);
         this.clear(clearColor, true, true, true);
         this.disableScissor();
         this.disableScissor();
@@ -2154,7 +2180,7 @@ export class Engine {
         gl.disable(gl.SCISSOR_TEST);
         gl.disable(gl.SCISSOR_TEST);
     }
     }
 
 
-    private _viewportCached = new Vector4(0, 0, 0, 0);
+    private _viewportCached = { x: 0, y: 0, z: 0, w: 0 };
 
 
     /** @hidden */
     /** @hidden */
     public _viewport(x: number, y: number, width: number, height: number): void {
     public _viewport(x: number, y: number, width: number, height: number): void {
@@ -2177,7 +2203,7 @@ export class Engine {
      * @param requiredWidth defines the width required for rendering. If not provided the rendering canvas' width is used
      * @param requiredWidth defines the width required for rendering. If not provided the rendering canvas' width is used
      * @param requiredHeight defines the height required for rendering. If not provided the rendering canvas' height is used
      * @param requiredHeight defines the height required for rendering. If not provided the rendering canvas' height is used
      */
      */
-    public setViewport(viewport: Viewport, requiredWidth?: number, requiredHeight?: number): void {
+    public setViewport(viewport: IViewportLike, requiredWidth?: number, requiredHeight?: number): void {
         var width = requiredWidth || this.getRenderWidth();
         var width = requiredWidth || this.getRenderWidth();
         var height = requiredHeight || this.getRenderHeight();
         var height = requiredHeight || this.getRenderHeight();
         var x = viewport.x || 0;
         var x = viewport.x || 0;
@@ -2196,7 +2222,7 @@ export class Engine {
      * @param height defines the height of the viewport (in screen space)
      * @param height defines the height of the viewport (in screen space)
      * @return the current viewport Object (if any) that is being replaced by this call. You can restore this viewport later on to go back to the original state
      * @return the current viewport Object (if any) that is being replaced by this call. You can restore this viewport later on to go back to the original state
      */
      */
-    public setDirectViewport(x: number, y: number, width: number, height: number): Nullable<Viewport> {
+    public setDirectViewport(x: number, y: number, width: number, height: number): Nullable<IViewportLike> {
         let currentViewport = this._cachedViewport;
         let currentViewport = this._cachedViewport;
         this._cachedViewport = null;
         this._cachedViewport = null;
 
 
@@ -3652,19 +3678,6 @@ export class Engine {
     }
     }
 
 
     /**
     /**
-     * Set the value of an uniform to a matrix
-     * @param uniform defines the webGL uniform location where to store the value
-     * @param matrix defines the matrix to store
-     */
-    public setMatrix(uniform: Nullable<WebGLUniformLocation>, matrix: Matrix): void {
-        if (!uniform) {
-            return;
-        }
-
-        this._gl.uniformMatrix4fv(uniform, false, matrix.toArray() as Float32Array);
-    }
-
-    /**
      * Set the value of an uniform to a matrix (3x3)
      * Set the value of an uniform to a matrix (3x3)
      * @param uniform defines the webGL uniform location where to store the value
      * @param uniform defines the webGL uniform location where to store the value
      * @param matrix defines the Float32Array representing the 3x3 matrix to store
      * @param matrix defines the Float32Array representing the 3x3 matrix to store
@@ -3775,38 +3788,11 @@ export class Engine {
     }
     }
 
 
     /**
     /**
-     * Set the value of an uniform to a Color3
-     * @param uniform defines the webGL uniform location where to store the value
-     * @param color3 defines the color to store
-     */
-    public setColor3(uniform: Nullable<WebGLUniformLocation>, color3: Color3): void {
-        if (!uniform) {
-            return;
-        }
-
-        this._gl.uniform3f(uniform, color3.r, color3.g, color3.b);
-    }
-
-    /**
-     * Set the value of an uniform to a Color3 and an alpha value
-     * @param uniform defines the webGL uniform location where to store the value
-     * @param color3 defines the color to store
-     * @param alpha defines the alpha component to store
-     */
-    public setColor4(uniform: Nullable<WebGLUniformLocation>, color3: Color3, alpha: number): void {
-        if (!uniform) {
-            return;
-        }
-
-        this._gl.uniform4f(uniform, color3.r, color3.g, color3.b, alpha);
-    }
-
-    /**
      * Sets a Color4 on a uniform variable
      * Sets a Color4 on a uniform variable
      * @param uniform defines the uniform location
      * @param uniform defines the uniform location
      * @param color4 defines the value to be set
      * @param color4 defines the value to be set
      */
      */
-    public setDirectColor4(uniform: Nullable<WebGLUniformLocation>, color4: Color4): void {
+    public setDirectColor4(uniform: Nullable<WebGLUniformLocation>, color4: IColor4Like): void {
         if (!uniform) {
         if (!uniform) {
             return;
             return;
         }
         }
@@ -4247,7 +4233,6 @@ export class Engine {
                     // Add Back
                     // Add Back
                     customFallback = true;
                     customFallback = true;
                     excludeLoaders.push(loader);
                     excludeLoaders.push(loader);
-                    Tools.Warn((loader.constructor as any).name + " failed when trying to load " + texture.url + ", falling back to the next supported loader");
                     this.createTexture(urlArg, noMipmap, texture.invertY, scene, samplingMode, null, onError, buffer, texture, undefined, undefined, excludeLoaders);
                     this.createTexture(urlArg, noMipmap, texture.invertY, scene, samplingMode, null, onError, buffer, texture, undefined, undefined, excludeLoaders);
                     return;
                     return;
                 }
                 }
@@ -4257,8 +4242,8 @@ export class Engine {
                 if (onLoadObserver) {
                 if (onLoadObserver) {
                     texture.onLoadedObservable.remove(onLoadObserver);
                     texture.onLoadedObservable.remove(onLoadObserver);
                 }
                 }
-                if (Tools.UseFallbackTexture) {
-                    this.createTexture(Tools.fallbackTexture, noMipmap, texture.invertY, scene, samplingMode, null, onError, buffer, texture);
+                if (EngineStore.UseFallbackTexture) {
+                    this.createTexture(EngineStore.FallbackTexture, noMipmap, texture.invertY, scene, samplingMode, null, onError, buffer, texture);
                     return;
                     return;
                 }
                 }
             }
             }
@@ -4348,11 +4333,11 @@ export class Engine {
                 if (buffer instanceof HTMLImageElement) {
                 if (buffer instanceof HTMLImageElement) {
                     onload(buffer);
                     onload(buffer);
                 } else {
                 } else {
-                    Tools.LoadImage(url, onload, onInternalError, scene ? scene.offlineProvider : null);
+                    FileTools.LoadImage(url, onload, onInternalError, scene ? scene.offlineProvider : null);
                 }
                 }
             }
             }
             else if (typeof buffer === "string" || buffer instanceof ArrayBuffer || buffer instanceof Blob) {
             else if (typeof buffer === "string" || buffer instanceof ArrayBuffer || buffer instanceof Blob) {
-                Tools.LoadImage(buffer, onload, onInternalError, scene ? scene.offlineProvider : null);
+                FileTools.LoadImage(buffer, onload, onInternalError, scene ? scene.offlineProvider : null);
             }
             }
             else {
             else {
                 onload(<HTMLImageElement>buffer);
                 onload(<HTMLImageElement>buffer);
@@ -4473,8 +4458,8 @@ export class Engine {
         texture.baseHeight = height;
         texture.baseHeight = height;
 
 
         if (generateMipMaps) {
         if (generateMipMaps) {
-            width = this.needPOTTextures ? Tools.GetExponentOfTwo(width, this._caps.maxTextureSize) : width;
-            height = this.needPOTTextures ? Tools.GetExponentOfTwo(height, this._caps.maxTextureSize) : height;
+            width = this.needPOTTextures ? Engine.GetExponentOfTwo(width, this._caps.maxTextureSize) : width;
+            height = this.needPOTTextures ? Engine.GetExponentOfTwo(height, this._caps.maxTextureSize) : height;
         }
         }
 
 
         //  this.resetTextureCache();
         //  this.resetTextureCache();
@@ -5018,8 +5003,8 @@ export class Engine {
             target = gl.TEXTURE_CUBE_MAP_POSITIVE_X + faceIndex;
             target = gl.TEXTURE_CUBE_MAP_POSITIVE_X + faceIndex;
         }
         }
 
 
-        const lodMaxWidth = Math.round(Scalar.Log2(texture.width));
-        const lodMaxHeight = Math.round(Scalar.Log2(texture.height));
+        const lodMaxWidth = Math.round(Math.log(texture.width) * Math.LOG2E);
+        const lodMaxHeight = Math.round(Math.log(texture.height) * Math.LOG2E);
         const width = useTextureWidthAndHeight ? texture.width : Math.pow(2, Math.max(lodMaxWidth - lod, 0));
         const width = useTextureWidthAndHeight ? texture.width : Math.pow(2, Math.max(lodMaxWidth - lod, 0));
         const height = useTextureWidthAndHeight ? texture.height : Math.pow(2, Math.max(lodMaxHeight - lod, 0));
         const height = useTextureWidthAndHeight ? texture.height : Math.pow(2, Math.max(lodMaxHeight - lod, 0));
 
 
@@ -5138,8 +5123,8 @@ export class Engine {
     private _prepareWebGLTexture(texture: InternalTexture, scene: Nullable<Scene>, width: number, height: number, invertY: boolean, noMipmap: boolean, isCompressed: boolean,
     private _prepareWebGLTexture(texture: InternalTexture, scene: Nullable<Scene>, width: number, height: number, invertY: boolean, noMipmap: boolean, isCompressed: boolean,
         processFunction: (width: number, height: number, continuationCallback: () => void) => boolean, samplingMode: number = Engine.TEXTURE_TRILINEAR_SAMPLINGMODE): void {
         processFunction: (width: number, height: number, continuationCallback: () => void) => boolean, samplingMode: number = Engine.TEXTURE_TRILINEAR_SAMPLINGMODE): void {
         var maxTextureSize = this.getCaps().maxTextureSize;
         var maxTextureSize = this.getCaps().maxTextureSize;
-        var potWidth = Math.min(maxTextureSize, this.needPOTTextures ? Tools.GetExponentOfTwo(width, maxTextureSize) : width);
-        var potHeight = Math.min(maxTextureSize, this.needPOTTextures ? Tools.GetExponentOfTwo(height, maxTextureSize) : height);
+        var potWidth = Math.min(maxTextureSize, this.needPOTTextures ? Engine.GetExponentOfTwo(width, maxTextureSize) : width);
+        var potHeight = Math.min(maxTextureSize, this.needPOTTextures ? Engine.GetExponentOfTwo(height, maxTextureSize) : height);
 
 
         var gl = this._gl;
         var gl = this._gl;
         if (!gl) {
         if (!gl) {
@@ -6392,7 +6377,7 @@ export class Engine {
 
 
     /** @hidden */
     /** @hidden */
     public _loadFile(url: string, onSuccess: (data: string | ArrayBuffer, responseURL?: string) => void, onProgress?: (data: any) => void, offlineProvider?: IOfflineProvider, useArrayBuffer?: boolean, onError?: (request?: WebRequest, exception?: any) => void): IFileRequest {
     public _loadFile(url: string, onSuccess: (data: string | ArrayBuffer, responseURL?: string) => void, onProgress?: (data: any) => void, offlineProvider?: IOfflineProvider, useArrayBuffer?: boolean, onError?: (request?: WebRequest, exception?: any) => void): IFileRequest {
-        let request = Tools.LoadFile(url, onSuccess, onProgress, offlineProvider, useArrayBuffer, onError);
+        let request = FileTools.LoadFile(url, onSuccess, onProgress, offlineProvider, useArrayBuffer, onError);
         this._activeRequests.push(request);
         this._activeRequests.push(request);
         request.onCompleteObservable.add((request) => {
         request.onCompleteObservable.add((request) => {
             this._activeRequests.splice(this._activeRequests.indexOf(request), 1);
             this._activeRequests.splice(this._activeRequests.indexOf(request), 1);
@@ -6428,4 +6413,159 @@ export class Engine {
             return false;
             return false;
         }
         }
     }
     }
+
+    /**
+     * Find the next highest power of two.
+     * @param x Number to start search from.
+     * @return Next highest power of two.
+     */
+    public static CeilingPOT(x: number): number {
+        x--;
+        x |= x >> 1;
+        x |= x >> 2;
+        x |= x >> 4;
+        x |= x >> 8;
+        x |= x >> 16;
+        x++;
+        return x;
+    }
+
+    /**
+     * Find the next lowest power of two.
+     * @param x Number to start search from.
+     * @return Next lowest power of two.
+     */
+    public static FloorPOT(x: number): number {
+        x = x | (x >> 1);
+        x = x | (x >> 2);
+        x = x | (x >> 4);
+        x = x | (x >> 8);
+        x = x | (x >> 16);
+        return x - (x >> 1);
+    }
+
+    /**
+     * Find the nearest power of two.
+     * @param x Number to start search from.
+     * @return Next nearest power of two.
+     */
+    public static NearestPOT(x: number): number {
+        var c = Engine.CeilingPOT(x);
+        var f = Engine.FloorPOT(x);
+        return (c - x) > (x - f) ? f : c;
+    }
+
+    /**
+     * Get the closest exponent of two
+     * @param value defines the value to approximate
+     * @param max defines the maximum value to return
+     * @param mode defines how to define the closest value
+     * @returns closest exponent of two of the given value
+     */
+    public static GetExponentOfTwo(value: number, max: number, mode = Constants.SCALEMODE_NEAREST): number {
+        let pot;
+
+        switch (mode) {
+            case Constants.SCALEMODE_FLOOR:
+                pot = Engine.FloorPOT(value);
+                break;
+            case Constants.SCALEMODE_NEAREST:
+                pot = Engine.NearestPOT(value);
+                break;
+            case Constants.SCALEMODE_CEILING:
+            default:
+                pot = Engine.CeilingPOT(value);
+                break;
+        }
+
+        return Math.min(pot, max);
+    }
+
+    /**
+     * Queue a new function into the requested animation frame pool (ie. this function will be executed byt the browser for the next frame)
+     * @param func - the function to be called
+     * @param requester - the object that will request the next frame. Falls back to window.
+     * @returns frame number
+     */
+    public static QueueNewFrame(func: () => void, requester?: any): number {
+        if (!DomManagement.IsWindowObjectExist()) {
+            return setTimeout(func, 16);
+        }
+
+        if (!requester) {
+            requester = window;
+        }
+
+        if (requester.requestAnimationFrame) {
+            return requester.requestAnimationFrame(func);
+        }
+        else if (requester.msRequestAnimationFrame) {
+            return requester.msRequestAnimationFrame(func);
+        }
+        else if (requester.webkitRequestAnimationFrame) {
+            return requester.webkitRequestAnimationFrame(func);
+        }
+        else if (requester.mozRequestAnimationFrame) {
+            return requester.mozRequestAnimationFrame(func);
+        }
+        else if (requester.oRequestAnimationFrame) {
+            return requester.oRequestAnimationFrame(func);
+        }
+        else {
+            return window.setTimeout(func, 16);
+        }
+    }
+
+    /**
+     * Ask the browser to promote the current element to pointerlock mode
+     * @param element defines the DOM element to promote
+     */
+    static _RequestPointerlock(element: HTMLElement): void {
+        element.requestPointerLock = element.requestPointerLock || (<any>element).msRequestPointerLock || (<any>element).mozRequestPointerLock || (<any>element).webkitRequestPointerLock;
+        if (element.requestPointerLock) {
+            element.requestPointerLock();
+        }
+    }
+
+    /**
+     * Asks the browser to exit pointerlock mode
+     */
+    static _ExitPointerlock(): void {
+        let anyDoc = document as any;
+        document.exitPointerLock = document.exitPointerLock || anyDoc.msExitPointerLock || anyDoc.mozExitPointerLock || anyDoc.webkitExitPointerLock;
+
+        if (document.exitPointerLock) {
+            document.exitPointerLock();
+        }
+    }
+
+    /**
+     * Ask the browser to promote the current element to fullscreen rendering mode
+     * @param element defines the DOM element to promote
+     */
+    static _RequestFullscreen(element: HTMLElement): void {
+        var requestFunction = element.requestFullscreen || (<any>element).msRequestFullscreen || (<any>element).webkitRequestFullscreen || (<any>element).mozRequestFullScreen;
+        if (!requestFunction) { return; }
+        requestFunction.call(element);
+    }
+
+    /**
+     * Asks the browser to exit fullscreen mode
+     */
+    static _ExitFullscreen(): void {
+        let anyDoc = document as any;
+
+        if (document.exitFullscreen) {
+            document.exitFullscreen();
+        }
+        else if (anyDoc.mozCancelFullScreen) {
+            anyDoc.mozCancelFullScreen();
+        }
+        else if (anyDoc.webkitCancelFullScreen) {
+            anyDoc.webkitCancelFullScreen();
+        }
+        else if (anyDoc.msCancelFullScreen) {
+            anyDoc.msCancelFullScreen();
+        }
+    }
 }
 }

+ 12 - 0
src/Engines/engineStore.ts

@@ -31,4 +31,16 @@ export class EngineStore {
     public static get LastCreatedScene(): Nullable<Scene> {
     public static get LastCreatedScene(): Nullable<Scene> {
         return this._LastCreatedScene;
         return this._LastCreatedScene;
     }
     }
+
+    /**
+     * Gets or sets a global variable indicating if fallback texture must be used when a texture cannot be loaded
+     * @ignorenaming
+     */
+    public static UseFallbackTexture = true;
+
+    /**
+     * Texture content used if a texture cannot loaded
+     * @ignorenaming
+     */
+    public static FallbackTexture = "";
 }
 }

+ 3 - 13
src/Engines/nullEngine.ts

@@ -1,8 +1,7 @@
 import { Logger } from "../Misc/logger";
 import { Logger } from "../Misc/logger";
 import { Nullable, FloatArray, IndicesArray } from "../types";
 import { Nullable, FloatArray, IndicesArray } from "../types";
 import { Scene } from "../scene";
 import { Scene } from "../scene";
-import { Matrix, Color3, Color4, Viewport } from "../Maths/math";
-import { Engine, EngineCapabilities } from "../Engines/engine";
+import { Engine, EngineCapabilities, IViewportLike, IColor4Like } from "../Engines/engine";
 import { RenderTargetCreationOptions } from "../Materials/Textures/renderTargetCreationOptions";
 import { RenderTargetCreationOptions } from "../Materials/Textures/renderTargetCreationOptions";
 import { VertexBuffer } from "../Meshes/buffer";
 import { VertexBuffer } from "../Meshes/buffer";
 import { InternalTexture } from "../Materials/Textures/internalTexture";
 import { InternalTexture } from "../Materials/Textures/internalTexture";
@@ -158,7 +157,7 @@ export class NullEngine extends Engine {
         return buffer;
         return buffer;
     }
     }
 
 
-    public clear(color: Color4, backBuffer: boolean, depth: boolean, stencil: boolean = false): void {
+    public clear(color: IColor4Like, backBuffer: boolean, depth: boolean, stencil: boolean = false): void {
     }
     }
 
 
     public getRenderWidth(useScreen = false): number {
     public getRenderWidth(useScreen = false): number {
@@ -177,7 +176,7 @@ export class NullEngine extends Engine {
         return this._options.renderHeight;
         return this._options.renderHeight;
     }
     }
 
 
-    public setViewport(viewport: Viewport, requiredWidth?: number, requiredHeight?: number): void {
+    public setViewport(viewport: IViewportLike, requiredWidth?: number, requiredHeight?: number): void {
         this._cachedViewport = viewport;
         this._cachedViewport = viewport;
     }
     }
 
 
@@ -252,9 +251,6 @@ export class NullEngine extends Engine {
     public setMatrices(uniform: WebGLUniformLocation, matrices: Float32Array): void {
     public setMatrices(uniform: WebGLUniformLocation, matrices: Float32Array): void {
     }
     }
 
 
-    public setMatrix(uniform: WebGLUniformLocation, matrix: Matrix): void {
-    }
-
     public setMatrix3x3(uniform: WebGLUniformLocation, matrix: Float32Array): void {
     public setMatrix3x3(uniform: WebGLUniformLocation, matrix: Float32Array): void {
     }
     }
 
 
@@ -276,12 +272,6 @@ export class NullEngine extends Engine {
     public setFloat4(uniform: WebGLUniformLocation, x: number, y: number, z: number, w: number): void {
     public setFloat4(uniform: WebGLUniformLocation, x: number, y: number, z: number, w: number): void {
     }
     }
 
 
-    public setColor3(uniform: WebGLUniformLocation, color3: Color3): void {
-    }
-
-    public setColor4(uniform: WebGLUniformLocation, color3: Color3, alpha: number): void {
-    }
-
     public setAlphaMode(mode: number, noDepthWriteChange: boolean = false): void {
     public setAlphaMode(mode: number, noDepthWriteChange: boolean = false): void {
         if (this._alphaMode === mode) {
         if (this._alphaMode === mode) {
             return;
             return;

+ 2 - 2
src/Gamepads/gamepadManager.ts

@@ -1,4 +1,3 @@
-import { Tools } from "../Misc/tools";
 import { Observable } from "../Misc/observable";
 import { Observable } from "../Misc/observable";
 import { DomManagement } from "../Misc/domManagement";
 import { DomManagement } from "../Misc/domManagement";
 import { Nullable } from "../types";
 import { Nullable } from "../types";
@@ -9,6 +8,7 @@ import { _DepthCullingState, _StencilState, _AlphaState } from "../States/index"
 import { PoseEnabledControllerHelper } from "../Gamepads/Controllers/poseEnabledController";
 import { PoseEnabledControllerHelper } from "../Gamepads/Controllers/poseEnabledController";
 import { Xbox360Pad } from "./xboxGamepad";
 import { Xbox360Pad } from "./xboxGamepad";
 import { Gamepad, GenericPad } from "./gamepad";
 import { Gamepad, GenericPad } from "./gamepad";
+import { Engine } from '../Engines/engine';
 /**
 /**
  * Manager for handling gamepads
  * Manager for handling gamepads
  */
  */
@@ -211,7 +211,7 @@ export class GamepadManager {
         }
         }
 
 
         if (this._isMonitoring && !this._scene) {
         if (this._isMonitoring && !this._scene) {
-            Tools.QueueNewFrame(() => { this._checkGamepadsStatus(); });
+            Engine.QueueNewFrame(() => { this._checkGamepadsStatus(); });
         }
         }
     }
     }
 
 

+ 1 - 1
src/Gizmos/boundingBoxGizmo.ts

@@ -122,7 +122,7 @@ export class BoundingBoxGizmo extends Gizmo {
         super(gizmoLayer);
         super(gizmoLayer);
 
 
         // Do not update the gizmo's scale so it has a fixed size to the object its attached to
         // Do not update the gizmo's scale so it has a fixed size to the object its attached to
-        this._updateScale = false;
+        this.updateScale = false;
 
 
         this._anchorMesh = new AbstractMesh("anchor", gizmoLayer.utilityLayerScene);
         this._anchorMesh = new AbstractMesh("anchor", gizmoLayer.utilityLayerScene);
         // Create Materials
         // Create Materials

+ 5 - 3
src/Gizmos/gizmo.ts

@@ -62,9 +62,9 @@ export class Gizmo implements IDisposable {
      */
      */
     public updateGizmoPositionToMatchAttachedMesh = true;
     public updateGizmoPositionToMatchAttachedMesh = true;
     /**
     /**
-     * When set, the gizmo will always appear the same size no matter where the camera is (default: false)
+     * When set, the gizmo will always appear the same size no matter where the camera is (default: true)
      */
      */
-    protected _updateScale = true;
+    public updateScale = true;
     protected _interactionsEnabled = true;
     protected _interactionsEnabled = true;
     protected _attachedMeshChanged(value: Nullable<AbstractMesh>) {
     protected _attachedMeshChanged(value: Nullable<AbstractMesh>) {
     }
     }
@@ -109,7 +109,7 @@ export class Gizmo implements IDisposable {
             }
             }
 
 
             // Scale
             // Scale
-            if (this._updateScale) {
+            if (this.updateScale) {
                 const activeCamera = this.gizmoLayer.utilityLayerScene.activeCamera!;
                 const activeCamera = this.gizmoLayer.utilityLayerScene.activeCamera!;
                 var cameraPosition = activeCamera.globalPosition;
                 var cameraPosition = activeCamera.globalPosition;
                 if ((<WebVRFreeCamera>activeCamera).devicePosition) {
                 if ((<WebVRFreeCamera>activeCamera).devicePosition) {
@@ -123,6 +123,8 @@ export class Gizmo implements IDisposable {
                 if (effectiveMesh._getWorldMatrixDeterminant() < 0) {
                 if (effectiveMesh._getWorldMatrixDeterminant() < 0) {
                     this._rootMesh.scaling.y *= -1;
                     this._rootMesh.scaling.y *= -1;
                 }
                 }
+            }else {
+                this._rootMesh.scaling.setAll(this.scaleRatio);
             }
             }
         }
         }
     }
     }

+ 1 - 1
src/Instrumentation/engineInstrumentation.ts

@@ -1,5 +1,5 @@
 import { Observer } from "../Misc/observable";
 import { Observer } from "../Misc/observable";
-import { PerfCounter } from "../Misc/tools";
+import { PerfCounter } from "../Misc/perfCounter";
 import { Nullable } from "../types";
 import { Nullable } from "../types";
 import { IDisposable } from "../scene";
 import { IDisposable } from "../scene";
 import { Engine } from "../Engines/engine";
 import { Engine } from "../Engines/engine";

+ 2 - 1
src/Instrumentation/sceneInstrumentation.ts

@@ -1,10 +1,11 @@
-import { Tools, PerfCounter } from "../Misc/tools";
+import { Tools } from "../Misc/tools";
 import { Observer } from "../Misc/observable";
 import { Observer } from "../Misc/observable";
 import { Nullable } from "../types";
 import { Nullable } from "../types";
 import { Camera } from "../Cameras/camera";
 import { Camera } from "../Cameras/camera";
 import { Scene, IDisposable } from "../scene";
 import { Scene, IDisposable } from "../scene";
 import { _TimeToken } from "../Instrumentation/timeToken";
 import { _TimeToken } from "../Instrumentation/timeToken";
 import { _DepthCullingState, _StencilState, _AlphaState } from "../States/index";
 import { _DepthCullingState, _StencilState, _AlphaState } from "../States/index";
+import { PerfCounter } from '../Misc/perfCounter';
 /**
 /**
  * This class can be used to get instrumentation data from a Babylon engine
  * This class can be used to get instrumentation data from a Babylon engine
  * @see http://doc.babylonjs.com/how_to/optimizing_your_scene#sceneinstrumentation
  * @see http://doc.babylonjs.com/how_to/optimizing_your_scene#sceneinstrumentation

+ 2 - 2
src/Layers/effectLayer.ts

@@ -298,8 +298,8 @@ export abstract class EffectLayer {
             this._mainTextureDesiredSize.width = this._engine.getRenderWidth() * this._effectLayerOptions.mainTextureRatio;
             this._mainTextureDesiredSize.width = this._engine.getRenderWidth() * this._effectLayerOptions.mainTextureRatio;
             this._mainTextureDesiredSize.height = this._engine.getRenderHeight() * this._effectLayerOptions.mainTextureRatio;
             this._mainTextureDesiredSize.height = this._engine.getRenderHeight() * this._effectLayerOptions.mainTextureRatio;
 
 
-            this._mainTextureDesiredSize.width = this._engine.needPOTTextures ? Tools.GetExponentOfTwo(this._mainTextureDesiredSize.width, this._maxSize) : this._mainTextureDesiredSize.width;
-            this._mainTextureDesiredSize.height = this._engine.needPOTTextures ? Tools.GetExponentOfTwo(this._mainTextureDesiredSize.height, this._maxSize) : this._mainTextureDesiredSize.height;
+            this._mainTextureDesiredSize.width = this._engine.needPOTTextures ? Engine.GetExponentOfTwo(this._mainTextureDesiredSize.width, this._maxSize) : this._mainTextureDesiredSize.width;
+            this._mainTextureDesiredSize.height = this._engine.needPOTTextures ? Engine.GetExponentOfTwo(this._mainTextureDesiredSize.height, this._maxSize) : this._mainTextureDesiredSize.height;
         }
         }
 
 
         this._mainTextureDesiredSize.width = Math.floor(this._mainTextureDesiredSize.width);
         this._mainTextureDesiredSize.width = Math.floor(this._mainTextureDesiredSize.width);

+ 3 - 3
src/Layers/glowLayer.ts

@@ -1,5 +1,4 @@
 import { serialize, SerializationHelper } from "../Misc/decorators";
 import { serialize, SerializationHelper } from "../Misc/decorators";
-import { Tools } from "../Misc/tools";
 import { Nullable } from "../types";
 import { Nullable } from "../types";
 import { Camera } from "../Cameras/camera";
 import { Camera } from "../Cameras/camera";
 import { Scene } from "../scene";
 import { Scene } from "../scene";
@@ -18,6 +17,7 @@ import { EffectLayer } from "./effectLayer";
 import { AbstractScene } from "../abstractScene";
 import { AbstractScene } from "../abstractScene";
 import { Constants } from "../Engines/constants";
 import { Constants } from "../Engines/constants";
 import { _TypeStore } from '../Misc/typeStore';
 import { _TypeStore } from '../Misc/typeStore';
+import { Engine } from '../Engines/engine';
 
 
 import "../Shaders/glowMapMerge.fragment";
 import "../Shaders/glowMapMerge.fragment";
 import "../Shaders/glowMapMerge.vertex";
 import "../Shaders/glowMapMerge.vertex";
@@ -222,8 +222,8 @@ export class GlowLayer extends EffectLayer {
     protected _createTextureAndPostProcesses(): void {
     protected _createTextureAndPostProcesses(): void {
         var blurTextureWidth = this._mainTextureDesiredSize.width;
         var blurTextureWidth = this._mainTextureDesiredSize.width;
         var blurTextureHeight = this._mainTextureDesiredSize.height;
         var blurTextureHeight = this._mainTextureDesiredSize.height;
-        blurTextureWidth = this._engine.needPOTTextures ? Tools.GetExponentOfTwo(blurTextureWidth, this._maxSize) : blurTextureWidth;
-        blurTextureHeight = this._engine.needPOTTextures ? Tools.GetExponentOfTwo(blurTextureHeight, this._maxSize) : blurTextureHeight;
+        blurTextureWidth = this._engine.needPOTTextures ? Engine.GetExponentOfTwo(blurTextureWidth, this._maxSize) : blurTextureWidth;
+        blurTextureHeight = this._engine.needPOTTextures ? Engine.GetExponentOfTwo(blurTextureHeight, this._maxSize) : blurTextureHeight;
 
 
         var textureType = 0;
         var textureType = 0;
         if (this._engine.getCaps().textureHalfFloatRender) {
         if (this._engine.getCaps().textureHalfFloatRender) {

+ 2 - 3
src/Layers/highlightLayer.ts

@@ -1,6 +1,5 @@
 import { serialize, SerializationHelper } from "../Misc/decorators";
 import { serialize, SerializationHelper } from "../Misc/decorators";
 import { Observer, Observable } from "../Misc/observable";
 import { Observer, Observable } from "../Misc/observable";
-import { Tools } from "../Misc/tools";
 import { Nullable } from "../types";
 import { Nullable } from "../types";
 import { Camera } from "../Cameras/camera";
 import { Camera } from "../Cameras/camera";
 import { Scene } from "../scene";
 import { Scene } from "../scene";
@@ -326,8 +325,8 @@ export class HighlightLayer extends EffectLayer {
     protected _createTextureAndPostProcesses(): void {
     protected _createTextureAndPostProcesses(): void {
         var blurTextureWidth = this._mainTextureDesiredSize.width * this._options.blurTextureSizeRatio;
         var blurTextureWidth = this._mainTextureDesiredSize.width * this._options.blurTextureSizeRatio;
         var blurTextureHeight = this._mainTextureDesiredSize.height * this._options.blurTextureSizeRatio;
         var blurTextureHeight = this._mainTextureDesiredSize.height * this._options.blurTextureSizeRatio;
-        blurTextureWidth = this._engine.needPOTTextures ? Tools.GetExponentOfTwo(blurTextureWidth, this._maxSize) : blurTextureWidth;
-        blurTextureHeight = this._engine.needPOTTextures ? Tools.GetExponentOfTwo(blurTextureHeight, this._maxSize) : blurTextureHeight;
+        blurTextureWidth = this._engine.needPOTTextures ? Engine.GetExponentOfTwo(blurTextureWidth, this._maxSize) : blurTextureWidth;
+        blurTextureHeight = this._engine.needPOTTextures ? Engine.GetExponentOfTwo(blurTextureHeight, this._maxSize) : blurTextureHeight;
 
 
         var textureType = 0;
         var textureType = 0;
         if (this._engine.getCaps().textureHalfFloatRender) {
         if (this._engine.getCaps().textureHalfFloatRender) {

+ 5 - 5
src/LibDeclarations/webxr.d.ts

@@ -40,10 +40,10 @@ interface XRSpace extends EventTarget {
 }
 }
 
 
 interface XRRenderState {
 interface XRRenderState {
-    depthNear: number ;
-    depthFar: number ;
-    inlineVerticalFieldOfView: number | undefined;
-    baseLayer: XRWebGLLayer | undefined;
+    depthNear?: number;
+    depthFar?: number;
+    inlineVerticalFieldOfView?: number;
+    baseLayer?: XRWebGLLayer;
 }
 }
 
 
 interface XRInputSource {
 interface XRInputSource {
@@ -58,7 +58,7 @@ interface XRInputSource {
 interface XRSession {
 interface XRSession {
     addEventListener: Function;
     addEventListener: Function;
     requestReferenceSpace(type: XRReferenceSpaceType): Promise<XRReferenceSpace>;
     requestReferenceSpace(type: XRReferenceSpaceType): Promise<XRReferenceSpace>;
-    updateRenderState(XRRenderStateInit: any): Promise<void>;
+    updateRenderState(XRRenderStateInit: XRRenderState): Promise<void>;
     requestAnimationFrame: Function;
     requestAnimationFrame: Function;
     end(): Promise<void>;
     end(): Promise<void>;
     renderState: XRRenderState;
     renderState: XRRenderState;

+ 3 - 2
src/Loading/Plugins/babylonFileLoader.ts

@@ -29,6 +29,7 @@ import { AmmoJSPlugin } from "../../Physics/Plugins/ammoJSPlugin";
 import { ReflectionProbe } from "../../Probes/reflectionProbe";
 import { ReflectionProbe } from "../../Probes/reflectionProbe";
 import { _TypeStore } from '../../Misc/typeStore';
 import { _TypeStore } from '../../Misc/typeStore';
 import { Tools } from '../../Misc/tools';
 import { Tools } from '../../Misc/tools';
+import { StringTools } from '../../Misc/stringTools';
 
 
 /** @hidden */
 /** @hidden */
 export var _BabylonLoaderRegistered = true;
 export var _BabylonLoaderRegistered = true;
@@ -125,7 +126,7 @@ var loadAssetContainer = (scene: Scene, data: string, rootUrl: string, onError?:
                 }
                 }
                 scene.environmentTexture = hdrTexture;
                 scene.environmentTexture = hdrTexture;
             } else {
             } else {
-                if (Tools.EndsWith(parsedData.environmentTexture, ".env")) {
+                if (StringTools.EndsWith(parsedData.environmentTexture, ".env")) {
                     var compressedTexture = new CubeTexture((parsedData.environmentTexture.match(/https?:\/\//g) ? "" : rootUrl) + parsedData.environmentTexture, scene);
                     var compressedTexture = new CubeTexture((parsedData.environmentTexture.match(/https?:\/\//g) ? "" : rootUrl) + parsedData.environmentTexture, scene);
                     if (parsedData.environmentTextureRotationY) {
                     if (parsedData.environmentTextureRotationY) {
                         compressedTexture.rotationY = parsedData.environmentTextureRotationY;
                         compressedTexture.rotationY = parsedData.environmentTextureRotationY;
@@ -744,7 +745,7 @@ SceneLoader.RegisterPlugin({
                     }
                     }
                     scene.environmentTexture = hdrTexture;
                     scene.environmentTexture = hdrTexture;
                 } else {
                 } else {
-                    if (Tools.EndsWith(parsedData.environmentTexture, ".env")) {
+                    if (StringTools.EndsWith(parsedData.environmentTexture, ".env")) {
                         var compressedTexture = new CubeTexture(rootUrl + parsedData.environmentTexture, scene);
                         var compressedTexture = new CubeTexture(rootUrl + parsedData.environmentTexture, scene);
                         if (parsedData.environmentTextureRotationY) {
                         if (parsedData.environmentTextureRotationY) {
                             compressedTexture.rotationY = parsedData.environmentTextureRotationY;
                             compressedTexture.rotationY = parsedData.environmentTextureRotationY;

+ 2 - 1
src/Loading/sceneLoader.ts

@@ -1,4 +1,4 @@
-import { IFileRequest, Tools } from "../Misc/tools";
+import { Tools } from "../Misc/tools";
 import { Observable } from "../Misc/observable";
 import { Observable } from "../Misc/observable";
 import { FilesInputStore } from "../Misc/filesInputStore";
 import { FilesInputStore } from "../Misc/filesInputStore";
 import { Nullable } from "../types";
 import { Nullable } from "../types";
@@ -16,6 +16,7 @@ import { Skeleton } from "../Bones/skeleton";
 import { Logger } from "../Misc/logger";
 import { Logger } from "../Misc/logger";
 import { Constants } from "../Engines/constants";
 import { Constants } from "../Engines/constants";
 import { SceneLoaderFlags } from "./sceneLoaderFlags";
 import { SceneLoaderFlags } from "./sceneLoaderFlags";
+import { IFileRequest } from '../Misc/fileRequest';
 /**
 /**
  * Class used to represent data loading progression
  * Class used to represent data loading progression
  */
  */

+ 3 - 4
src/Materials/Textures/renderTargetTexture.ts

@@ -17,8 +17,7 @@ import { Constants } from "../../Engines/constants";
 
 
 import "../../Engines/Extensions/engine.renderTarget";
 import "../../Engines/Extensions/engine.renderTarget";
 import { InstancedMesh } from '../../Meshes/instancedMesh';
 import { InstancedMesh } from '../../Meshes/instancedMesh';
-
-declare type Engine = import("../../Engines/engine").Engine;
+import { Engine } from '../../Engines/engine';
 
 
 /**
 /**
  * This Helps creating a texture that will be created from a camera in your scene.
  * This Helps creating a texture that will be created from a camera in your scene.
@@ -734,10 +733,10 @@ export class RenderTargetTexture extends Texture {
     private _bestReflectionRenderTargetDimension(renderDimension: number, scale: number): number {
     private _bestReflectionRenderTargetDimension(renderDimension: number, scale: number): number {
         let minimum = 128;
         let minimum = 128;
         let x = renderDimension * scale;
         let x = renderDimension * scale;
-        let curved = Tools.NearestPOT(x + (minimum * minimum / (minimum + x)));
+        let curved = Engine.NearestPOT(x + (minimum * minimum / (minimum + x)));
 
 
         // Ensure we don't exceed the render dimension (while staying POT)
         // Ensure we don't exceed the render dimension (while staying POT)
-        return Math.min(Tools.FloorPOT(renderDimension), curved);
+        return Math.min(Engine.FloorPOT(renderDimension), curved);
     }
     }
 
 
     /**
     /**

+ 3 - 3
src/Materials/effect.ts

@@ -1194,7 +1194,7 @@ export class Effect implements IDisposable {
      */
      */
     public setMatrix(uniformName: string, matrix: Matrix): Effect {
     public setMatrix(uniformName: string, matrix: Matrix): Effect {
         if (this._cacheMatrix(uniformName, matrix)) {
         if (this._cacheMatrix(uniformName, matrix)) {
-            this._engine.setMatrix(this._uniforms[uniformName], matrix);
+            this._engine.setMatrices(this._uniforms[uniformName], matrix.toArray() as Float32Array);
         }
         }
         return this;
         return this;
     }
     }
@@ -1356,7 +1356,7 @@ export class Effect implements IDisposable {
     public setColor3(uniformName: string, color3: Color3): Effect {
     public setColor3(uniformName: string, color3: Color3): Effect {
 
 
         if (this._cacheFloat3(uniformName, color3.r, color3.g, color3.b)) {
         if (this._cacheFloat3(uniformName, color3.r, color3.g, color3.b)) {
-            this._engine.setColor3(this._uniforms[uniformName], color3);
+            this._engine.setFloat3(this._uniforms[uniformName], color3.r, color3.g, color3.b);
         }
         }
         return this;
         return this;
     }
     }
@@ -1370,7 +1370,7 @@ export class Effect implements IDisposable {
      */
      */
     public setColor4(uniformName: string, color3: Color3, alpha: number): Effect {
     public setColor4(uniformName: string, color3: Color3, alpha: number): Effect {
         if (this._cacheFloat4(uniformName, color3.r, color3.g, color3.b, alpha)) {
         if (this._cacheFloat4(uniformName, color3.r, color3.g, color3.b, alpha)) {
-            this._engine.setColor4(this._uniforms[uniformName], color3, alpha);
+            this._engine.setFloat4(this._uniforms[uniformName], color3.r, color3.g, color3.b, alpha);
         }
         }
         return this;
         return this;
     }
     }

+ 79 - 0
src/Maths/math.functions.ts

@@ -0,0 +1,79 @@
+import { FloatArray, Nullable, IndicesArray } from '../types';
+import { Vector2, Vector3 } from './math';
+
+/**
+ * Extracts minimum and maximum values from a list of indexed positions
+ * @param positions defines the positions to use
+ * @param indices defines the indices to the positions
+ * @param indexStart defines the start index
+ * @param indexCount defines the end index
+ * @param bias defines bias value to add to the result
+ * @return minimum and maximum values
+ */
+export function extractMinAndMaxIndexed(positions: FloatArray, indices: IndicesArray, indexStart: number, indexCount: number, bias: Nullable<Vector2> = null): { minimum: Vector3; maximum: Vector3 } {
+    var minimum = new Vector3(Number.MAX_VALUE, Number.MAX_VALUE, Number.MAX_VALUE);
+    var maximum = new Vector3(-Number.MAX_VALUE, -Number.MAX_VALUE, -Number.MAX_VALUE);
+
+    for (var index = indexStart; index < indexStart + indexCount; index++) {
+        const offset = indices[index] * 3;
+        const x = positions[offset];
+        const y = positions[offset + 1];
+        const z = positions[offset + 2];
+        minimum.minimizeInPlaceFromFloats(x, y, z);
+        maximum.maximizeInPlaceFromFloats(x, y, z);
+    }
+
+    if (bias) {
+        minimum.x -= minimum.x * bias.x + bias.y;
+        minimum.y -= minimum.y * bias.x + bias.y;
+        minimum.z -= minimum.z * bias.x + bias.y;
+        maximum.x += maximum.x * bias.x + bias.y;
+        maximum.y += maximum.y * bias.x + bias.y;
+        maximum.z += maximum.z * bias.x + bias.y;
+    }
+
+    return {
+        minimum: minimum,
+        maximum: maximum
+    };
+}
+
+/**
+ * Extracts minimum and maximum values from a list of positions
+ * @param positions defines the positions to use
+ * @param start defines the start index in the positions array
+ * @param count defines the number of positions to handle
+ * @param bias defines bias value to add to the result
+ * @param stride defines the stride size to use (distance between two positions in the positions array)
+ * @return minimum and maximum values
+ */
+export function extractMinAndMax(positions: FloatArray, start: number, count: number, bias: Nullable<Vector2> = null, stride?: number): { minimum: Vector3; maximum: Vector3 } {
+    var minimum = new Vector3(Number.MAX_VALUE, Number.MAX_VALUE, Number.MAX_VALUE);
+    var maximum = new Vector3(-Number.MAX_VALUE, -Number.MAX_VALUE, -Number.MAX_VALUE);
+
+    if (!stride) {
+        stride = 3;
+    }
+
+    for (var index = start, offset = start * stride; index < start + count; index++ , offset += stride) {
+        const x = positions[offset];
+        const y = positions[offset + 1];
+        const z = positions[offset + 2];
+        minimum.minimizeInPlaceFromFloats(x, y, z);
+        maximum.maximizeInPlaceFromFloats(x, y, z);
+    }
+
+    if (bias) {
+        minimum.x -= minimum.x * bias.x + bias.y;
+        minimum.y -= minimum.y * bias.x + bias.y;
+        minimum.z -= minimum.z * bias.x + bias.y;
+        maximum.x += maximum.x * bias.x + bias.y;
+        maximum.y += maximum.y * bias.x + bias.y;
+        maximum.z += maximum.z * bias.x + bias.y;
+    }
+
+    return {
+        minimum: minimum,
+        maximum: maximum
+    };
+}

+ 11 - 0
src/Maths/math.ts

@@ -2560,6 +2560,17 @@ export class Vector3 {
     }
     }
 
 
     /**
     /**
+     * Checks if a given vector is inside a specific range
+     * @param v defines the vector to test
+     * @param min defines the minimum range
+     * @param max defines the maximum range
+     */
+    public static CheckExtends(v: Vector3, min: Vector3, max: Vector3): void {
+        min.minimizeInPlace(v);
+        max.maximizeInPlace(v);
+    }
+
+    /**
      * Returns a new Vector3 located for "amount" (float) on the Hermite interpolation spline defined by the vectors "value1", "tangent1", "value2", "tangent2"
      * Returns a new Vector3 located for "amount" (float) on the Hermite interpolation spline defined by the vectors "value1", "tangent1", "value2", "tangent2"
      * @param value1 defines the first control point
      * @param value1 defines the first control point
      * @param tangent1 defines the first tangent vector
      * @param tangent1 defines the first tangent vector

+ 2 - 1
src/Meshes/abstractMesh.ts

@@ -24,6 +24,7 @@ import { AbstractActionManager } from '../Actions/abstractActionManager';
 import { _MeshCollisionData } from '../Collisions/meshCollisionData';
 import { _MeshCollisionData } from '../Collisions/meshCollisionData';
 import { _DevTools } from '../Misc/devTools';
 import { _DevTools } from '../Misc/devTools';
 import { RawTexture } from '../Materials/Textures/rawTexture';
 import { RawTexture } from '../Materials/Textures/rawTexture';
+import { extractMinAndMax } from '../Maths/math.functions';
 
 
 declare type Ray = import("../Culling/ray").Ray;
 declare type Ray = import("../Culling/ray").Ray;
 declare type Collider = import("../Collisions/collider").Collider;
 declare type Collider = import("../Collisions/collider").Collider;
@@ -1142,7 +1143,7 @@ export class AbstractMesh extends TransformNode implements IDisposable, ICullabl
     /** @hidden */
     /** @hidden */
     public _refreshBoundingInfo(data: Nullable<FloatArray>, bias: Nullable<Vector2>): void {
     public _refreshBoundingInfo(data: Nullable<FloatArray>, bias: Nullable<Vector2>): void {
         if (data) {
         if (data) {
-            var extend = Tools.ExtractMinAndMax(data, 0, this.getTotalVertices(), bias);
+            var extend = extractMinAndMax(data, 0, this.getTotalVertices(), bias);
             if (this._boundingInfo) {
             if (this._boundingInfo) {
                 this._boundingInfo.reConstruct(extend.minimum, extend.maximum);
                 this._boundingInfo.reConstruct(extend.minimum, extend.maximum);
             }
             }

+ 2 - 1
src/Meshes/geometry.ts

@@ -13,6 +13,7 @@ import { Constants } from "../Engines/constants";
 import { Tools } from "../Misc/tools";
 import { Tools } from "../Misc/tools";
 import { Tags } from "../Misc/tags";
 import { Tags } from "../Misc/tags";
 import { DataBuffer } from './dataBuffer';
 import { DataBuffer } from './dataBuffer';
+import { extractMinAndMax } from '../Maths/math.functions';
 
 
 declare type Mesh = import("../Meshes/mesh").Mesh;
 declare type Mesh = import("../Meshes/mesh").Mesh;
 
 
@@ -693,7 +694,7 @@ export class Geometry implements IGetSetVerticesData {
             data = this.getVerticesData(VertexBuffer.PositionKind)!;
             data = this.getVerticesData(VertexBuffer.PositionKind)!;
         }
         }
 
 
-        this._extend = Tools.ExtractMinAndMax(data, 0, this._totalVertices, this.boundingBias, 3);
+        this._extend = extractMinAndMax(data, 0, this._totalVertices, this.boundingBias, 3);
     }
     }
 
 
     private _applyToMesh(mesh: Mesh): void {
     private _applyToMesh(mesh: Mesh): void {

+ 2 - 2
src/Meshes/subMesh.ts

@@ -1,4 +1,3 @@
-import { Tools } from "../Misc/tools";
 import { Nullable, IndicesArray, DeepImmutable, FloatArray } from "../types";
 import { Nullable, IndicesArray, DeepImmutable, FloatArray } from "../types";
 import { Matrix, Vector3, Plane } from "../Maths/math";
 import { Matrix, Vector3, Plane } from "../Maths/math";
 import { Engine } from "../Engines/engine";
 import { Engine } from "../Engines/engine";
@@ -8,6 +7,7 @@ import { ICullable, BoundingInfo } from "../Culling/boundingInfo";
 import { Effect } from "../Materials/effect";
 import { Effect } from "../Materials/effect";
 import { Constants } from "../Engines/constants";
 import { Constants } from "../Engines/constants";
 import { DataBuffer } from './dataBuffer';
 import { DataBuffer } from './dataBuffer';
+import { extractMinAndMaxIndexed } from '../Maths/math.functions';
 
 
 declare type Collider = import("../Collisions/collider").Collider;
 declare type Collider = import("../Collisions/collider").Collider;
 declare type Material = import("../Materials/material").Material;
 declare type Material = import("../Materials/material").Material;
@@ -235,7 +235,7 @@ export class SubMesh extends BaseSubMesh implements ICullable {
             //the rendering mesh's bounding info can be used, it is the standard submesh for all indices.
             //the rendering mesh's bounding info can be used, it is the standard submesh for all indices.
             extend = { minimum: boundingInfo.minimum.clone(), maximum: boundingInfo.maximum.clone() };
             extend = { minimum: boundingInfo.minimum.clone(), maximum: boundingInfo.maximum.clone() };
         } else {
         } else {
-            extend = Tools.ExtractMinAndMaxIndexed(data, indices, this.indexStart, this.indexCount, this._renderingMesh.geometry.boundingBias);
+            extend = extractMinAndMaxIndexed(data, indices, this.indexStart, this.indexCount, this._renderingMesh.geometry.boundingBias);
         }
         }
 
 
         if (this._boundingInfo) {
         if (this._boundingInfo) {

+ 20 - 0
src/Misc/customAnimationFrameRequester.ts

@@ -0,0 +1,20 @@
+
+/**
+ * Interface for any object that can request an animation frame
+ */
+export interface ICustomAnimationFrameRequester {
+    /**
+     * This function will be called when the render loop is ready. If this is not populated, the engine's renderloop function will be called
+     */
+    renderFunction?: Function;
+    /**
+     * Called to request the next frame to render to
+     * @see https://developer.mozilla.org/en-US/docs/Web/API/window/requestAnimationFrame
+     */
+    requestAnimationFrame: Function;
+    /**
+     * You can pass this value to cancelAnimationFrame() to cancel the refresh callback request
+     * @see https://developer.mozilla.org/en-US/docs/Web/API/window/requestAnimationFrame#Return_value
+     */
+    requestID?: number;
+}

+ 16 - 0
src/Misc/fileRequest.ts

@@ -0,0 +1,16 @@
+import { Observable } from './observable';
+
+/**
+ * File request interface
+ */
+export interface IFileRequest {
+    /**
+     * Raised when the request is complete (success or error).
+     */
+    onCompleteObservable: Observable<IFileRequest>;
+
+    /**
+     * Aborts the request for a file.
+     */
+    abort: () => void;
+}

+ 370 - 0
src/Misc/fileTools.ts

@@ -0,0 +1,370 @@
+import { WebRequest } from './webRequest';
+import { LoadFileError } from './loadFileError';
+import { DomManagement } from './domManagement';
+import { Nullable } from '../types';
+import { IOfflineProvider } from '../Offline/IOfflineProvider';
+import { IFileRequest } from './fileRequest';
+import { Observable } from './observable';
+import { FilesInputStore } from './filesInputStore';
+import { RetryStrategy } from './retryStrategy';
+
+/**
+ * @hidden
+ */
+export class FileTools {
+    /**
+     * Gets or sets the retry strategy to apply when an error happens while loading an asset
+     */
+    public static DefaultRetryStrategy = RetryStrategy.ExponentialBackoff();
+
+    /**
+     * Gets or sets the base URL to use to load assets
+     */
+    public static BaseUrl = "";
+
+    /**
+     * Default behaviour for cors in the application.
+     * It can be a string if the expected behavior is identical in the entire app.
+     * Or a callback to be able to set it per url or on a group of them (in case of Video source for instance)
+     */
+    public static CorsBehavior: string | ((url: string | string[]) => string) = "anonymous";
+
+    /**
+     * Gets or sets a function used to pre-process url before using them to load assets
+     */
+    public static PreprocessUrl = (url: string) => {
+        return url;
+    }
+
+    /**
+     * Removes unwanted characters from an url
+     * @param url defines the url to clean
+     * @returns the cleaned url
+     */
+    private static _CleanUrl(url: string): string {
+        url = url.replace(/#/mg, "%23");
+        return url;
+    }
+
+    /**
+     * Sets the cors behavior on a dom element. This will add the required Tools.CorsBehavior to the element.
+     * @param url define the url we are trying
+     * @param element define the dom element where to configure the cors policy
+     */
+    public static SetCorsBehavior(url: string | string[], element: { crossOrigin: string | null }): void {
+        if (url && url.indexOf("data:") === 0) {
+            return;
+        }
+
+        if (this.CorsBehavior) {
+            if (typeof (this.CorsBehavior) === 'string' || this.CorsBehavior instanceof String) {
+                element.crossOrigin = <string>this.CorsBehavior;
+            }
+            else {
+                var result = this.CorsBehavior(url);
+                if (result) {
+                    element.crossOrigin = result;
+                }
+            }
+        }
+    }
+
+    /**
+     * Loads an image as an HTMLImageElement.
+     * @param input url string, ArrayBuffer, or Blob to load
+     * @param onLoad callback called when the image successfully loads
+     * @param onError callback called when the image fails to load
+     * @param offlineProvider offline provider for caching
+     * @returns the HTMLImageElement of the loaded image
+     */
+    public static LoadImage(input: string | ArrayBuffer | Blob, onLoad: (img: HTMLImageElement) => void, onError: (message?: string, exception?: any) => void, offlineProvider: Nullable<IOfflineProvider>): HTMLImageElement {
+        let url: string;
+        let usingObjectURL = false;
+
+        if (input instanceof ArrayBuffer) {
+            url = URL.createObjectURL(new Blob([input]));
+            usingObjectURL = true;
+        }
+        else if (input instanceof Blob) {
+            url = URL.createObjectURL(input);
+            usingObjectURL = true;
+        }
+        else {
+            url = this._CleanUrl(input);
+            url = this.PreprocessUrl(input);
+        }
+
+        var img = new Image();
+        this.SetCorsBehavior(url, img);
+
+        const loadHandler = () => {
+            img.removeEventListener("load", loadHandler);
+            img.removeEventListener("error", errorHandler);
+
+            onLoad(img);
+
+            // Must revoke the URL after calling onLoad to avoid security exceptions in
+            // certain scenarios (e.g. when hosted in vscode).
+            if (usingObjectURL && img.src) {
+                URL.revokeObjectURL(img.src);
+            }
+        };
+
+        const errorHandler = (err: any) => {
+            img.removeEventListener("load", loadHandler);
+            img.removeEventListener("error", errorHandler);
+
+            if (onError) {
+                onError("Error while trying to load image: " + input, err);
+            }
+
+            if (usingObjectURL && img.src) {
+                URL.revokeObjectURL(img.src);
+            }
+        };
+
+        img.addEventListener("load", loadHandler);
+        img.addEventListener("error", errorHandler);
+
+        var noOfflineSupport = () => {
+            img.src = url;
+        };
+
+        var loadFromOfflineSupport = () => {
+            if (offlineProvider) {
+                offlineProvider.loadImage(url, img);
+            }
+        };
+
+        if (url.substr(0, 5) !== "data:" && offlineProvider && offlineProvider.enableTexturesOffline) {
+            offlineProvider.open(loadFromOfflineSupport, noOfflineSupport);
+        }
+        else {
+            if (url.indexOf("file:") !== -1) {
+                var textureName = decodeURIComponent(url.substring(5).toLowerCase());
+                if (FilesInputStore.FilesToLoad[textureName]) {
+                    try {
+                        var blobURL;
+                        try {
+                            blobURL = URL.createObjectURL(FilesInputStore.FilesToLoad[textureName]);
+                        }
+                        catch (ex) {
+                            // Chrome doesn't support oneTimeOnly parameter
+                            blobURL = URL.createObjectURL(FilesInputStore.FilesToLoad[textureName]);
+                        }
+                        img.src = blobURL;
+                        usingObjectURL = true;
+                    }
+                    catch (e) {
+                        img.src = "";
+                    }
+                    return img;
+                }
+            }
+
+            noOfflineSupport();
+        }
+
+        return img;
+    }
+
+    /**
+     * Loads a file
+     * @param fileToLoad defines the file to load
+     * @param callback defines the callback to call when data is loaded
+     * @param progressCallBack defines the callback to call during loading process
+     * @param useArrayBuffer defines a boolean indicating that data must be returned as an ArrayBuffer
+     * @returns a file request object
+     */
+    public static ReadFile(fileToLoad: File, callback: (data: any) => void, progressCallBack?: (ev: ProgressEvent) => any, useArrayBuffer?: boolean): IFileRequest {
+        let reader = new FileReader();
+        let request: IFileRequest = {
+            onCompleteObservable: new Observable<IFileRequest>(),
+            abort: () => reader.abort(),
+        };
+
+        reader.onloadend = (e) => request.onCompleteObservable.notifyObservers(request);
+        reader.onerror = (e) => {
+            callback(JSON.stringify({ autoClear: true, clearColor: [1, 0, 0], ambientColor: [0, 0, 0], gravity: [0, -9.807, 0], meshes: [], cameras: [], lights: [] }));
+        };
+        reader.onload = (e) => {
+            //target doesn't have result from ts 1.3
+            callback((<any>e.target)['result']);
+        };
+        if (progressCallBack) {
+            reader.onprogress = progressCallBack;
+        }
+        if (!useArrayBuffer) {
+            // Asynchronous read
+            reader.readAsText(fileToLoad);
+        }
+        else {
+            reader.readAsArrayBuffer(fileToLoad);
+        }
+
+        return request;
+    }
+
+    /**
+     * Loads a file
+     * @param url url string, ArrayBuffer, or Blob to load
+     * @param onSuccess callback called when the file successfully loads
+     * @param onProgress callback called while file is loading (if the server supports this mode)
+     * @param offlineProvider defines the offline provider for caching
+     * @param useArrayBuffer defines a boolean indicating that date must be returned as ArrayBuffer
+     * @param onError callback called when the file fails to load
+     * @returns a file request object
+     */
+    public static LoadFile(url: string, onSuccess: (data: string | ArrayBuffer, responseURL?: string) => void, onProgress?: (data: any) => void, offlineProvider?: IOfflineProvider, useArrayBuffer?: boolean, onError?: (request?: WebRequest, exception?: any) => void): IFileRequest {
+        url = this._CleanUrl(url);
+
+        url = this.PreprocessUrl(url);
+
+        // If file and file input are set
+        if (url.indexOf("file:") !== -1) {
+            const fileName = decodeURIComponent(url.substring(5).toLowerCase());
+            if (FilesInputStore.FilesToLoad[fileName]) {
+                return this.ReadFile(FilesInputStore.FilesToLoad[fileName], onSuccess, onProgress, useArrayBuffer);
+            }
+        }
+
+        const loadUrl = this.BaseUrl + url;
+
+        let aborted = false;
+        const fileRequest: IFileRequest = {
+            onCompleteObservable: new Observable<IFileRequest>(),
+            abort: () => aborted = true,
+        };
+
+        const requestFile = () => {
+            let request = new WebRequest();
+            let retryHandle: Nullable<number> = null;
+
+            fileRequest.abort = () => {
+                aborted = true;
+
+                if (request.readyState !== (XMLHttpRequest.DONE || 4)) {
+                    request.abort();
+                }
+
+                if (retryHandle !== null) {
+                    clearTimeout(retryHandle);
+                    retryHandle = null;
+                }
+            };
+
+            const retryLoop = (retryIndex: number) => {
+                request.open('GET', loadUrl);
+
+                if (useArrayBuffer) {
+                    request.responseType = "arraybuffer";
+                }
+
+                if (onProgress) {
+                    request.addEventListener("progress", onProgress);
+                }
+
+                const onLoadEnd = () => {
+                    request.removeEventListener("loadend", onLoadEnd);
+                    fileRequest.onCompleteObservable.notifyObservers(fileRequest);
+                    fileRequest.onCompleteObservable.clear();
+                };
+
+                request.addEventListener("loadend", onLoadEnd);
+
+                const onReadyStateChange = () => {
+                    if (aborted) {
+                        return;
+                    }
+
+                    // In case of undefined state in some browsers.
+                    if (request.readyState === (XMLHttpRequest.DONE || 4)) {
+                        // Some browsers have issues where onreadystatechange can be called multiple times with the same value.
+                        request.removeEventListener("readystatechange", onReadyStateChange);
+
+                        if ((request.status >= 200 && request.status < 300) || (request.status === 0 && (!DomManagement.IsWindowObjectExist() || this.IsFileURL()))) {
+                            onSuccess(!useArrayBuffer ? request.responseText : <ArrayBuffer>request.response, request.responseURL);
+                            return;
+                        }
+
+                        let retryStrategy = this.DefaultRetryStrategy;
+                        if (retryStrategy) {
+                            let waitTime = retryStrategy(loadUrl, request, retryIndex);
+                            if (waitTime !== -1) {
+                                // Prevent the request from completing for retry.
+                                request.removeEventListener("loadend", onLoadEnd);
+                                request = new WebRequest();
+                                retryHandle = setTimeout(() => retryLoop(retryIndex + 1), waitTime);
+                                return;
+                            }
+                        }
+
+                        let e = new LoadFileError("Error status: " + request.status + " " + request.statusText + " - Unable to load " + loadUrl, request);
+                        if (onError) {
+                            onError(request, e);
+                        } else {
+                            throw e;
+                        }
+                    }
+                };
+
+                request.addEventListener("readystatechange", onReadyStateChange);
+
+                request.send();
+            };
+
+            retryLoop(0);
+        };
+
+        // Caching all files
+        if (offlineProvider && offlineProvider.enableSceneOffline) {
+            const noOfflineSupport = (request?: any) => {
+                if (request && request.status > 400) {
+                    if (onError) {
+                        onError(request);
+                    }
+                } else {
+                    if (!aborted) {
+                        requestFile();
+                    }
+                }
+            };
+
+            const loadFromOfflineSupport = () => {
+                // TODO: database needs to support aborting and should return a IFileRequest
+                if (aborted) {
+                    return;
+                }
+
+                if (offlineProvider) {
+                    offlineProvider.loadFile(url, (data) => {
+                        if (!aborted) {
+                            onSuccess(data);
+                        }
+
+                        fileRequest.onCompleteObservable.notifyObservers(fileRequest);
+                    }, onProgress ? (event) => {
+                        if (!aborted) {
+                            onProgress(event);
+                        }
+                    } : undefined, noOfflineSupport, useArrayBuffer);
+                }
+            };
+
+            offlineProvider.open(loadFromOfflineSupport, noOfflineSupport);
+        }
+        else {
+            requestFile();
+        }
+
+        return fileRequest;
+    }
+
+    /**
+     * Checks if the loaded document was accessed via `file:`-Protocol.
+     * @returns boolean
+     */
+    public static IsFileURL(): boolean {
+        return location.protocol === "file:";
+    }
+}

+ 108 - 0
src/Misc/gradients.ts

@@ -0,0 +1,108 @@
+import { Color3, Color4 } from '../Maths/math';
+
+/** Interface used by value gradients (color, factor, ...) */
+export interface IValueGradient {
+    /**
+     * Gets or sets the gradient value (between 0 and 1)
+     */
+    gradient: number;
+}
+
+/** Class used to store color4 gradient */
+export class ColorGradient implements IValueGradient {
+    /**
+     * Gets or sets the gradient value (between 0 and 1)
+     */
+    public gradient: number;
+    /**
+     * Gets or sets first associated color
+     */
+    public color1: Color4;
+    /**
+     * Gets or sets second associated color
+     */
+    public color2?: Color4;
+
+    /**
+     * Will get a color picked randomly between color1 and color2.
+     * If color2 is undefined then color1 will be used
+     * @param result defines the target Color4 to store the result in
+     */
+    public getColorToRef(result: Color4) {
+        if (!this.color2) {
+            result.copyFrom(this.color1);
+            return;
+        }
+
+        Color4.LerpToRef(this.color1, this.color2, Math.random(), result);
+    }
+}
+
+/** Class used to store color 3 gradient */
+export class Color3Gradient implements IValueGradient {
+    /**
+     * Gets or sets the gradient value (between 0 and 1)
+     */
+    public gradient: number;
+    /**
+     * Gets or sets the associated color
+     */
+    public color: Color3;
+}
+
+/** Class used to store factor gradient */
+export class FactorGradient implements IValueGradient {
+    /**
+     * Gets or sets the gradient value (between 0 and 1)
+     */
+    public gradient: number;
+    /**
+     * Gets or sets first associated factor
+     */
+    public factor1: number;
+    /**
+     * Gets or sets second associated factor
+     */
+    public factor2?: number;
+
+    /**
+     * Will get a number picked randomly between factor1 and factor2.
+     * If factor2 is undefined then factor1 will be used
+     * @returns the picked number
+     */
+    public getFactor(): number {
+        if (this.factor2 === undefined) {
+            return this.factor1;
+        }
+
+        return this.factor1 + ((this.factor2 - this.factor1) * Math.random());
+    }
+}
+
+/**
+ * Helper used to simplify some generic gradient tasks
+ */
+export class GradientHelper {
+    /**
+     * Gets the current gradient from an array of IValueGradient
+     * @param ratio defines the current ratio to get
+     * @param gradients defines the array of IValueGradient
+     * @param updateFunc defines the callback function used to get the final value from the selected gradients
+     */
+    public static GetCurrentGradient(ratio: number, gradients: IValueGradient[], updateFunc: (current: IValueGradient, next: IValueGradient, scale: number) => void) {
+        for (var gradientIndex = 0; gradientIndex < gradients.length - 1; gradientIndex++) {
+            let currentGradient = gradients[gradientIndex];
+            let nextGradient = gradients[gradientIndex + 1];
+
+            if (ratio >= currentGradient.gradient && ratio <= nextGradient.gradient) {
+                let scale = (ratio - currentGradient.gradient) / (nextGradient.gradient - currentGradient.gradient);
+                updateFunc(currentGradient, nextGradient, scale);
+                return;
+            }
+        }
+
+        // Use last index if over
+        const lastIndex = gradients.length - 1;
+        updateFunc(gradients[lastIndex], gradients[lastIndex], 1.0);
+    }
+}

+ 6 - 0
src/Misc/index.ts

@@ -33,3 +33,9 @@ export * from "./typeStore";
 export * from "./webRequest";
 export * from "./webRequest";
 export * from "./iInspectable";
 export * from "./iInspectable";
 export * from "./brdfTextureTools";
 export * from "./brdfTextureTools";
+export * from "./gradients";
+export * from "./perfCounter";
+export * from "./fileRequest";
+export * from "./customAnimationFrameRequester";
+export * from "./retryStrategy";
+export * from "./loadFileError";

+ 30 - 0
src/Misc/loadFileError.ts

@@ -0,0 +1,30 @@
+import { WebRequest } from './webRequest';
+
+/**
+ * @ignore
+ * Application error to support additional information when loading a file
+ */
+export class LoadFileError extends Error {
+    // See https://stackoverflow.com/questions/12915412/how-do-i-extend-a-host-object-e-g-error-in-typescript
+    // and https://github.com/Microsoft/TypeScript/wiki/Breaking-Changes#extending-built-ins-like-error-array-and-map-may-no-longer-work
+
+    // Polyfill for Object.setPrototypeOf if necessary.
+    private static _setPrototypeOf: (o: any, proto: object | null) => any =
+        (Object as any).setPrototypeOf || ((o, proto) => { o.__proto__ = proto; return o; });
+
+    /**
+     * Creates a new LoadFileError
+     * @param message defines the message of the error
+     * @param request defines the optional web request
+     */
+    constructor(
+        message: string,
+        /** defines the optional web request */
+        public request?: WebRequest
+    ) {
+        super(message);
+        this.name = "LoadFileError";
+
+        LoadFileError._setPrototypeOf(this, LoadFileError.prototype);
+    }
+}

+ 169 - 0
src/Misc/perfCounter.ts

@@ -0,0 +1,169 @@
+import { PrecisionDate } from './precisionDate';
+
+/**
+ * This class is used to track a performance counter which is number based.
+ * The user has access to many properties which give statistics of different nature.
+ *
+ * The implementer can track two kinds of Performance Counter: time and count.
+ * For time you can optionally call fetchNewFrame() to notify the start of a new frame to monitor, then call beginMonitoring() to start and endMonitoring() to record the lapsed time. endMonitoring takes a newFrame parameter for you to specify if the monitored time should be set for a new frame or accumulated to the current frame being monitored.
+ * For count you first have to call fetchNewFrame() to notify the start of a new frame to monitor, then call addCount() how many time required to increment the count value you monitor.
+ */
+export class PerfCounter {
+    /**
+     * Gets or sets a global boolean to turn on and off all the counters
+     */
+    public static Enabled = true;
+
+    /**
+     * Returns the smallest value ever
+     */
+    public get min(): number {
+        return this._min;
+    }
+
+    /**
+     * Returns the biggest value ever
+     */
+    public get max(): number {
+        return this._max;
+    }
+
+    /**
+     * Returns the average value since the performance counter is running
+     */
+    public get average(): number {
+        return this._average;
+    }
+
+    /**
+     * Returns the average value of the last second the counter was monitored
+     */
+    public get lastSecAverage(): number {
+        return this._lastSecAverage;
+    }
+
+    /**
+     * Returns the current value
+     */
+    public get current(): number {
+        return this._current;
+    }
+
+    /**
+     * Gets the accumulated total
+     */
+    public get total(): number {
+        return this._totalAccumulated;
+    }
+
+    /**
+     * Gets the total value count
+     */
+    public get count(): number {
+        return this._totalValueCount;
+    }
+
+    /**
+     * Creates a new counter
+     */
+    constructor() {
+        this._startMonitoringTime = 0;
+        this._min = 0;
+        this._max = 0;
+        this._average = 0;
+        this._lastSecAverage = 0;
+        this._current = 0;
+        this._totalValueCount = 0;
+        this._totalAccumulated = 0;
+        this._lastSecAccumulated = 0;
+        this._lastSecTime = 0;
+        this._lastSecValueCount = 0;
+    }
+
+    /**
+     * Call this method to start monitoring a new frame.
+     * This scenario is typically used when you accumulate monitoring time many times for a single frame, you call this method at the start of the frame, then beginMonitoring to start recording and endMonitoring(false) to accumulated the recorded time to the PerfCounter or addCount() to accumulate a monitored count.
+     */
+    public fetchNewFrame() {
+        this._totalValueCount++;
+        this._current = 0;
+        this._lastSecValueCount++;
+    }
+
+    /**
+     * Call this method to monitor a count of something (e.g. mesh drawn in viewport count)
+     * @param newCount the count value to add to the monitored count
+     * @param fetchResult true when it's the last time in the frame you add to the counter and you wish to update the statistics properties (min/max/average), false if you only want to update statistics.
+     */
+    public addCount(newCount: number, fetchResult: boolean) {
+        if (!PerfCounter.Enabled) {
+            return;
+        }
+        this._current += newCount;
+        if (fetchResult) {
+            this._fetchResult();
+        }
+    }
+
+    /**
+     * Start monitoring this performance counter
+     */
+    public beginMonitoring() {
+        if (!PerfCounter.Enabled) {
+            return;
+        }
+        this._startMonitoringTime = PrecisionDate.Now;
+    }
+
+    /**
+     * Compute the time lapsed since the previous beginMonitoring() call.
+     * @param newFrame true by default to fetch the result and monitor a new frame, if false the time monitored will be added to the current frame counter
+     */
+    public endMonitoring(newFrame: boolean = true) {
+        if (!PerfCounter.Enabled) {
+            return;
+        }
+
+        if (newFrame) {
+            this.fetchNewFrame();
+        }
+
+        let currentTime = PrecisionDate.Now;
+        this._current = currentTime - this._startMonitoringTime;
+
+        if (newFrame) {
+            this._fetchResult();
+        }
+    }
+
+    private _fetchResult() {
+        this._totalAccumulated += this._current;
+        this._lastSecAccumulated += this._current;
+
+        // Min/Max update
+        this._min = Math.min(this._min, this._current);
+        this._max = Math.max(this._max, this._current);
+        this._average = this._totalAccumulated / this._totalValueCount;
+
+        // Reset last sec?
+        let now = PrecisionDate.Now;
+        if ((now - this._lastSecTime) > 1000) {
+            this._lastSecAverage = this._lastSecAccumulated / this._lastSecValueCount;
+            this._lastSecTime = now;
+            this._lastSecAccumulated = 0;
+            this._lastSecValueCount = 0;
+        }
+    }
+
+    private _startMonitoringTime: number;
+    private _min: number;
+    private _max: number;
+    private _average: number;
+    private _current: number;
+    private _totalValueCount: number;
+    private _totalAccumulated: number;
+    private _lastSecAverage: number;
+    private _lastSecAccumulated: number;
+    private _lastSecTime: number;
+    private _lastSecValueCount: number;
+}

+ 1 - 2
src/Misc/promise.ts

@@ -1,5 +1,4 @@
 import { Nullable } from "../types";
 import { Nullable } from "../types";
-import { Tools } from "./tools";
 
 
 enum PromiseStates {
 enum PromiseStates {
     Pending,
     Pending,
@@ -70,7 +69,7 @@ class InternalPromise<T> {
         newPromise._parent = this;
         newPromise._parent = this;
 
 
         if (this._state !== PromiseStates.Pending) {
         if (this._state !== PromiseStates.Pending) {
-            Tools.SetImmediate(() => {
+            setTimeout(() => {
                 if (this._state === PromiseStates.Fulfilled || this._rejectWasConsumed) {
                 if (this._state === PromiseStates.Fulfilled || this._rejectWasConsumed) {
                     let returnedValue = newPromise._resolve(this._result);
                     let returnedValue = newPromise._resolve(this._result);
 
 

+ 22 - 0
src/Misc/retryStrategy.ts

@@ -0,0 +1,22 @@
+import { WebRequest } from './webRequest';
+
+/**
+ * Class used to define a retry strategy when error happens while loading assets
+ */
+export class RetryStrategy {
+    /**
+     * Function used to defines an exponential back off strategy
+     * @param maxRetries defines the maximum number of retries (3 by default)
+     * @param baseInterval defines the interval between retries
+     * @returns the strategy function to use
+     */
+    public static ExponentialBackoff(maxRetries = 3, baseInterval = 500) {
+        return (url: string, request: WebRequest, retryIndex: number): number => {
+            if (request.status !== 0 || retryIndex >= maxRetries || url.indexOf("file:") !== -1) {
+                return -1;
+            }
+
+            return Math.pow(2, retryIndex) * baseInterval;
+        };
+    }
+}

+ 24 - 0
src/Misc/stringTools.ts

@@ -0,0 +1,24 @@
+/**
+ * Helper to manipulate strings
+ */
+export class StringTools {
+    /**
+     * Checks for a matching suffix at the end of a string (for ES5 and lower)
+     * @param str Source string
+     * @param suffix Suffix to search for in the source string
+     * @returns Boolean indicating whether the suffix was found (true) or not (false)
+     */
+    public static EndsWith(str: string, suffix: string): boolean {
+        return str.indexOf(suffix, str.length - suffix.length) !== -1;
+    }
+
+    /**
+     * Checks for a matching suffix at the beginning of a string (for ES5 and lower)
+     * @param str Source string
+     * @param suffix Suffix to search for in the source string
+     * @returns Boolean indicating whether the suffix was found (true) or not (false)
+     */
+    public static StartsWith(str: string, suffix: string): boolean {
+        return str.indexOf(suffix) === 0;
+    }
+}

File diff suppressed because it is too large
+ 64 - 919
src/Misc/tools.ts


+ 1 - 1
src/Particles/IParticleSystem.ts

@@ -5,7 +5,7 @@ import { BaseTexture } from "../Materials/Textures/baseTexture";
 import { Texture } from "../Materials/Textures/texture";
 import { Texture } from "../Materials/Textures/texture";
 import { BoxParticleEmitter, IParticleEmitterType, PointParticleEmitter, HemisphericParticleEmitter, SphereParticleEmitter, SphereDirectedParticleEmitter, CylinderParticleEmitter, ConeParticleEmitter } from "../Particles/EmitterTypes/index";
 import { BoxParticleEmitter, IParticleEmitterType, PointParticleEmitter, HemisphericParticleEmitter, SphereParticleEmitter, SphereDirectedParticleEmitter, CylinderParticleEmitter, ConeParticleEmitter } from "../Particles/EmitterTypes/index";
 import { Scene } from "../scene";
 import { Scene } from "../scene";
-import { ColorGradient, FactorGradient, Color3Gradient } from "../Misc/tools";
+import { ColorGradient, FactorGradient, Color3Gradient } from "../Misc/gradients";
 
 
 declare type Animation = import("../Animations/animation").Animation;
 declare type Animation = import("../Animations/animation").Animation;
 
 

+ 1 - 1
src/Particles/baseParticleSystem.ts

@@ -5,7 +5,7 @@ import { ImageProcessingConfiguration, ImageProcessingConfigurationDefines } fro
 import { ProceduralTexture } from "../Materials/Textures/Procedurals/proceduralTexture";
 import { ProceduralTexture } from "../Materials/Textures/Procedurals/proceduralTexture";
 import { RawTexture } from "../Materials/Textures/rawTexture";
 import { RawTexture } from "../Materials/Textures/rawTexture";
 import { Scene } from "../scene";
 import { Scene } from "../scene";
-import { ColorGradient, FactorGradient, Color3Gradient, IValueGradient } from "../Misc/tools";
+import { ColorGradient, FactorGradient, Color3Gradient, IValueGradient } from "../Misc/gradients";
 import { BoxParticleEmitter, IParticleEmitterType, PointParticleEmitter, HemisphericParticleEmitter, SphereParticleEmitter, SphereDirectedParticleEmitter, CylinderParticleEmitter, CylinderDirectedParticleEmitter, ConeParticleEmitter } from "../Particles/EmitterTypes/index";
 import { BoxParticleEmitter, IParticleEmitterType, PointParticleEmitter, HemisphericParticleEmitter, SphereParticleEmitter, SphereDirectedParticleEmitter, CylinderParticleEmitter, CylinderDirectedParticleEmitter, ConeParticleEmitter } from "../Particles/EmitterTypes/index";
 import { Constants } from "../Engines/constants";
 import { Constants } from "../Engines/constants";
 import { Texture } from '../Materials/Textures/texture';
 import { Texture } from '../Materials/Textures/texture';

+ 4 - 3
src/Particles/gpuParticleSystem.ts

@@ -1,5 +1,6 @@
 import { Nullable, float } from "../types";
 import { Nullable, float } from "../types";
-import { IAnimatable, Tools, IValueGradient, ColorGradient, FactorGradient, Color3Gradient } from "../Misc/tools";
+import { IAnimatable } from "../Misc/tools";
+import { FactorGradient, ColorGradient, Color3Gradient, IValueGradient, GradientHelper } from "../Misc/gradients";
 import { Observable } from "../Misc/observable";
 import { Observable } from "../Misc/observable";
 import { Color4, Color3, Vector3, Matrix, Tmp } from "../Maths/math";
 import { Color4, Color3, Vector3, Matrix, Tmp } from "../Maths/math";
 import { Scalar } from "../Maths/math.scalar";
 import { Scalar } from "../Maths/math.scalar";
@@ -1105,7 +1106,7 @@ export class GPUParticleSystem extends BaseParticleSystem implements IDisposable
         for (var x = 0; x < this._rawTextureWidth; x++) {
         for (var x = 0; x < this._rawTextureWidth; x++) {
             var ratio = x / this._rawTextureWidth;
             var ratio = x / this._rawTextureWidth;
 
 
-            Tools.GetCurrentGradient(ratio, factorGradients, (currentGradient, nextGradient, scale) => {
+            GradientHelper.GetCurrentGradient(ratio, factorGradients, (currentGradient, nextGradient, scale) => {
                 data[x] = Scalar.Lerp((<FactorGradient>currentGradient).factor1, (<FactorGradient>nextGradient).factor1, scale);
                 data[x] = Scalar.Lerp((<FactorGradient>currentGradient).factor1, (<FactorGradient>nextGradient).factor1, scale);
             });
             });
         }
         }
@@ -1144,7 +1145,7 @@ export class GPUParticleSystem extends BaseParticleSystem implements IDisposable
         for (var x = 0; x < this._rawTextureWidth; x++) {
         for (var x = 0; x < this._rawTextureWidth; x++) {
             var ratio = x / this._rawTextureWidth;
             var ratio = x / this._rawTextureWidth;
 
 
-            Tools.GetCurrentGradient(ratio, this._colorGradients, (currentGradient, nextGradient, scale) => {
+            GradientHelper.GetCurrentGradient(ratio, this._colorGradients, (currentGradient, nextGradient, scale) => {
 
 
                 Color4.LerpToRef((<ColorGradient>currentGradient).color1, (<ColorGradient>nextGradient).color1, scale, tmpColor);
                 Color4.LerpToRef((<ColorGradient>currentGradient).color1, (<ColorGradient>nextGradient).color1, scale, tmpColor);
                 data[x * 4] = tmpColor.r * 255;
                 data[x * 4] = tmpColor.r * 255;

+ 0 - 0
src/Particles/particle.ts


Some files were not shown because too many files changed in this diff