Browse Source

Merge branch 'master' of https://github.com/BabylonJS/Babylon.js into msDestiny14/dev

msDestiny14 4 years ago
parent
commit
ddc98eebeb
100 changed files with 271824 additions and 194778 deletions
  1. 0 2
      .github/ISSUE_TEMPLATE.md
  2. 0 2
      .github/ISSUE_TEMPLATE/bug_report.md
  3. 12 1
      .gitignore
  4. 4 4
      .prettierrc
  5. 28 0
      .vscode/launch.json
  6. 0 9
      Playground/debug.html
  7. 0 9
      Playground/frame.html
  8. 0 9
      Playground/full.html
  9. 27 3
      Playground/index-local.html
  10. 4 12
      Playground/index.html
  11. 25 8
      Playground/index.js
  12. 2686 0
      Playground/libs/babylon.manager.d.ts
  13. 11 0
      Playground/libs/babylon.manager.js
  14. 49 4
      Playground/src/components/commandBarComponent.tsx
  15. 45 10
      Playground/src/components/commandDropdownComponent.tsx
  16. 57 52
      Playground/src/components/examplesComponent.tsx
  17. 1 1
      Playground/src/components/hamburgerMenu.tsx
  18. 14 1
      Playground/src/components/headerComponent.tsx
  19. 93 33
      Playground/src/components/rendererComponent.tsx
  20. 4 1
      Playground/src/globalState.ts
  21. 1 1
      Playground/src/playground.tsx
  22. 21 5
      Playground/src/scss/commandBar.scss
  23. 5 0
      Playground/src/scss/examples.scss
  24. 5 2
      Playground/src/scss/header.scss
  25. 1 1
      Playground/src/scss/main.scss
  26. 31 19
      Playground/src/tools/loadManager.ts
  27. 66 24
      Playground/src/tools/monacoManager.ts
  28. 12 0
      Playground/templates.json
  29. BIN
      Playground/textures/ktx2/sample_etc1s.ktx2
  30. BIN
      Playground/textures/ktx2/sample_uastc.ktx2
  31. BIN
      Playground/textures/ktx2/sample_uastc_zcmp.ktx2
  32. BIN
      Playground/textures/ktx2/testalpha_etc1s.ktx2
  33. BIN
      Playground/textures/ktx2/testalpha_uastc.ktx2
  34. BIN
      Playground/textures/ktx2/testalpha_uastc_zcmp.ktx2
  35. BIN
      Playground/textures/ktx2/testmipmapcustom_etc1s.ktx2
  36. BIN
      Playground/textures/ktx2/testmipmapcustom_uastc.ktx2
  37. BIN
      Playground/textures/ktx2/testmipmapcustom_uastc_zcmp.ktx2
  38. 2 3
      Playground/zipContent/index.html
  39. 11 2
      Tools/Config/config.js
  40. 30 9
      Tools/Config/config.json
  41. 26 3
      Tools/DevLoader/BabylonLoader.js
  42. 7 6
      Tools/Gulp/gulpfile.js
  43. 6 2
      Tools/Gulp/helpers/gulp-processConstants.js
  44. 21 2
      Tools/Gulp/tasks/gulpTasks-libraries.js
  45. 25 1
      Tools/Gulp/tasks/gulpTasks-librariesES6.js
  46. 5 0
      Tools/Gulp/tasks/gulpTasks-localRun.js
  47. 52 0
      Tools/Gulp/tasks/gulpTasks-symlink.js
  48. 1 1
      Tools/Gulp/tasks/gulpTasks-watchApps.js
  49. 3 0
      Tools/Publisher/tasks/processEs6Packages.js
  50. 1 1
      Viewer/src/configuration/types/extended.ts
  51. 2 2
      Viewer/src/labs/texture.ts
  52. 5 5
      Viewer/src/managers/sceneManager.ts
  53. 0 1
      Viewer/src/managers/telemetryManager.ts
  54. 0 2
      Viewer/src/templating/templateManager.ts
  55. 1 1
      Viewer/src/viewer/viewer.ts
  56. 0 2
      Viewer/src/viewer/viewerManager.ts
  57. 1 1
      Viewer/tests/commons/helper.ts
  58. 3 3
      Viewer/tests/unit/src/viewer/viewer.ts
  59. 0 1
      Viewer/tests/validation/validate.html
  60. 61 24
      Viewer/tests/validation/validation.js
  61. 3 3
      contributing.md
  62. 11 11
      dist/ammo.js
  63. 1 1
      dist/ammo.wasm.js
  64. BIN
      dist/ammo.wasm.wasm
  65. 45586 37566
      dist/babylon.d.ts
  66. 12 12
      dist/babylon.js
  67. 1 0
      dist/babylon.ktx2Decoder.js
  68. 34186 10590
      dist/babylon.max.js
  69. 1 1
      dist/babylon.max.js.map
  70. 98938 82554
      dist/babylon.module.d.ts
  71. 46418 37695
      dist/documentation.d.ts
  72. 48 30
      dist/draco_decoder_gltf.js
  73. BIN
      dist/draco_decoder_gltf.wasm
  74. 104 115
      dist/draco_wasm_wrapper_gltf.js
  75. 33 46
      dist/glslang/glslang.js
  76. BIN
      dist/glslang/glslang.wasm
  77. 310 0
      dist/gltf2Interface/babylon.glTF2Interface.d.ts
  78. 1 1
      dist/gltf2Interface/package.json
  79. 193 98
      dist/gui/babylon.gui.d.ts
  80. 1120 689
      dist/gui/babylon.gui.js
  81. 1 1
      dist/gui/babylon.gui.js.map
  82. 12 12
      dist/gui/babylon.gui.min.js
  83. 402 199
      dist/gui/babylon.gui.module.d.ts
  84. 2 2
      dist/gui/package.json
  85. 24 28
      dist/inspector/babylon.inspector.bundle.js
  86. 32690 22832
      dist/inspector/babylon.inspector.bundle.max.js
  87. 1 1
      dist/inspector/babylon.inspector.bundle.max.js.map
  88. 2073 123
      dist/inspector/babylon.inspector.d.ts
  89. 5939 1793
      dist/inspector/babylon.inspector.module.d.ts
  90. 11 9
      dist/inspector/package.json
  91. 22 0
      dist/ktx2Transcoders/msc_basis_transcoder.js
  92. BIN
      dist/ktx2Transcoders/msc_basis_transcoder.wasm
  93. BIN
      dist/ktx2Transcoders/uastc_astc.wasm
  94. BIN
      dist/ktx2Transcoders/uastc_bc7.wasm
  95. BIN
      dist/ktx2Transcoders/uastc_rgba32_srgb.wasm
  96. BIN
      dist/ktx2Transcoders/uastc_rgba32_unorm.wasm
  97. 203 68
      dist/loaders/babylon.glTF1FileLoader.js
  98. 1 1
      dist/loaders/babylon.glTF1FileLoader.js.map
  99. 12 12
      dist/loaders/babylon.glTF1FileLoader.min.js
  100. 0 0
      dist/loaders/babylon.glTF2FileLoader.js

+ 0 - 2
.github/ISSUE_TEMPLATE.md

@@ -2,8 +2,6 @@
 
 
 We have a really active forum to help answering questions (https://forum.babylonjs.com/)
 We have a really active forum to help answering questions (https://forum.babylonjs.com/)
 
 
-*If you are convinced that you found a bug, please use the following template for your issue:*
-
 # Bugs
 # Bugs
 
 
 - Bug repro on [playground](https://playground.babylonjs.com):
 - Bug repro on [playground](https://playground.babylonjs.com):

+ 0 - 2
.github/ISSUE_TEMPLATE/bug_report.md

@@ -11,8 +11,6 @@ assignees: ''
 
 
 We have a really active forum to help answering questions (https://forum.babylonjs.com/)
 We have a really active forum to help answering questions (https://forum.babylonjs.com/)
 
 
-*If you are convinced that you found a bug, please use the following template for your issue:*
-
 **Repro**
 **Repro**
 - Bug repro on [playground](https://playground.babylonjs.com):
 - Bug repro on [playground](https://playground.babylonjs.com):
 - Expected result:
 - Expected result:

+ 12 - 1
.gitignore

@@ -157,6 +157,7 @@ node_modules
 # for VSCode
 # for VSCode
 .vs
 .vs
 .tempChromeProfileForDebug
 .tempChromeProfileForDebug
+.tempChromeCanaryProfileForDebug
 .temp
 .temp
 *.js.map
 *.js.map
 *.js.fx
 *.js.fx
@@ -165,6 +166,7 @@ node_modules
 !dist/**/*.js.map
 !dist/**/*.js.map
 !lib.d.ts
 !lib.d.ts
 !src/LibDeclarations/*.d.ts
 !src/LibDeclarations/*.d.ts
+!Playground/libs/*.d.ts
 *.fragment.ts
 *.fragment.ts
 *.vertex.ts
 *.vertex.ts
 **/ShadersInclude/**/*.ts
 **/ShadersInclude/**/*.ts
@@ -180,6 +182,9 @@ localDev/src/*
 package-lock.json
 package-lock.json
 dist/preview release/package/
 dist/preview release/package/
 
 
+# local dev WebGPU
+localDevWebGPU/src/*
+
 # viewer dist files
 # viewer dist files
 /Viewer/dist/viewer.js
 /Viewer/dist/viewer.js
 /Viewer/dist/viewer.min.js
 /Viewer/dist/viewer.min.js
@@ -200,4 +205,10 @@ gui/dist/
 # Local Netlify folder
 # Local Netlify folder
 .netlify
 .netlify
 Playground/dist/
 Playground/dist/
-Sandbox/public/dist/
+Playground/temp/
+Sandbox/public/dist/
+ktx2Decoder/dist/
+
+# Symlinks
+inspector/src/sharedUiComponents/**/*
+nodeEditor/src/sharedUiComponents/**/*

+ 4 - 4
.prettierrc

@@ -1,5 +1,5 @@
 {
 {
-    "trailingComma": "es5",
-    "tabWidth": 4,
-    "printWidth": 300
-  }
+  "trailingComma": "es5",
+  "tabWidth": 4,
+  "printWidth": 300
+}

+ 28 - 0
.vscode/launch.json

@@ -226,6 +226,21 @@
             ]
             ]
         },        
         },        
         {
         {
+            "name": "Launch Local Dev (Chrome Canary)",
+            "type": "chrome",
+            "request": "launch",
+            "url": "http://localhost:1338/localDevWebGPU/index.html",
+            "webRoot": "${workspaceRoot}/",
+            "sourceMaps": true,
+            "preLaunchTask": "run",
+            "userDataDir": "${workspaceRoot}/.tempChromeCanaryProfileForDebug",
+            "runtimeExecutable": "C:/Users/alexis/AppData/Local/Google/Chrome SxS/Application/Chrome.exe",
+            "runtimeArgs": [
+                "--enable-unsafe-es3-apis",
+                "--enable-unsafe-webgpu"
+            ]
+        },        
+        {
             "name": "Launch Local Dev (Edge)",
             "name": "Launch Local Dev (Edge)",
             "type": "edge",
             "type": "edge",
             "version": "dev",
             "version": "dev",
@@ -306,6 +321,19 @@
             ]
             ]
         },
         },
         {
         {
+            "name": "Launch Build Validation (Edge) - Direct",
+            "type": "edge",
+            "version": "dev",
+            "request": "launch",
+            "url": "http://localhost:1338/tests/validation/index.html",
+            "webRoot": "${workspaceRoot}/",
+            "sourceMaps": true,
+            "userDataDir": "${workspaceRoot}/.tempChromeProfileForDebug",
+            "runtimeArgs": [
+                "--enable-unsafe-es3-apis"
+            ]
+        },
+        {
             "name": "Launch memory checks (Chrome)",
             "name": "Launch memory checks (Chrome)",
             "type": "chrome",
             "type": "chrome",
             "request": "launch",
             "request": "launch",

+ 0 - 9
Playground/debug.html

@@ -34,7 +34,6 @@
         <script src="https://preview.babylonjs.com/recast.js"></script>
         <script src="https://preview.babylonjs.com/recast.js"></script>
         <script src="https://preview.babylonjs.com/cannon.js"></script>
         <script src="https://preview.babylonjs.com/cannon.js"></script>
         <script src="https://preview.babylonjs.com/Oimo.js"></script>
         <script src="https://preview.babylonjs.com/Oimo.js"></script>
-        <script src="https://preview.babylonjs.com/libktx.js"></script>
         <script src="https://preview.babylonjs.com/earcut.min.js"></script>
         <script src="https://preview.babylonjs.com/earcut.min.js"></script>
         
         
         <!-- Babylon.js -->
         <!-- Babylon.js -->
@@ -56,14 +55,6 @@
          <script
          <script
              src="https://rawcdn.githack.com/BabylonJS/Extensions/785013ec55b210d12263c91f3f0a2ae70cf0bc8a/CompoundShader/src/babylonx.CompoundShader.js"
              src="https://rawcdn.githack.com/BabylonJS/Extensions/785013ec55b210d12263c91f3f0a2ae70cf0bc8a/CompoundShader/src/babylonx.CompoundShader.js"
              ></script>
              ></script>
- 
-         <!-- Scene Manager -->
-         <script
-             src="https://rawcdn.githack.com/MackeyK24/MackeyK24.github.io/14fda491c50cfca6d3e2f6cbc5e6afe22cc455d6/toolkit/babylon.manager.js">
-         </script>
-         <script
-             src="https://rawcdn.githack.com/MackeyK24/MackeyK24.github.io/14fda491c50cfca6d3e2f6cbc5e6afe22cc455d6/toolkit/babylon.navmesh.js">
-         </script>        
 
 
         <style>
         <style>
             html,
             html,

+ 0 - 9
Playground/frame.html

@@ -33,7 +33,6 @@
         <script src="https://preview.babylonjs.com/recast.js"></script>
         <script src="https://preview.babylonjs.com/recast.js"></script>
         <script src="https://preview.babylonjs.com/cannon.js"></script>
         <script src="https://preview.babylonjs.com/cannon.js"></script>
         <script src="https://preview.babylonjs.com/Oimo.js"></script>
         <script src="https://preview.babylonjs.com/Oimo.js"></script>
-        <script src="https://preview.babylonjs.com/libktx.js"></script>
         <script src="https://preview.babylonjs.com/earcut.min.js"></script>
         <script src="https://preview.babylonjs.com/earcut.min.js"></script>
         
         
         <!-- Babylon.js -->
         <!-- Babylon.js -->
@@ -55,14 +54,6 @@
          <script
          <script
              src="https://rawcdn.githack.com/BabylonJS/Extensions/785013ec55b210d12263c91f3f0a2ae70cf0bc8a/CompoundShader/src/babylonx.CompoundShader.js"
              src="https://rawcdn.githack.com/BabylonJS/Extensions/785013ec55b210d12263c91f3f0a2ae70cf0bc8a/CompoundShader/src/babylonx.CompoundShader.js"
              ></script>
              ></script>
- 
-         <!-- Scene Manager -->
-         <script
-             src="https://rawcdn.githack.com/MackeyK24/MackeyK24.github.io/14fda491c50cfca6d3e2f6cbc5e6afe22cc455d6/toolkit/babylon.manager.js">
-         </script>
-         <script
-             src="https://rawcdn.githack.com/MackeyK24/MackeyK24.github.io/14fda491c50cfca6d3e2f6cbc5e6afe22cc455d6/toolkit/babylon.navmesh.js">
-         </script>        
 
 
         <style>
         <style>
             html,
             html,

+ 0 - 9
Playground/full.html

@@ -29,7 +29,6 @@
         <script src="https://preview.babylonjs.com/recast.js"></script>
         <script src="https://preview.babylonjs.com/recast.js"></script>
         <script src="https://preview.babylonjs.com/cannon.js"></script>
         <script src="https://preview.babylonjs.com/cannon.js"></script>
         <script src="https://preview.babylonjs.com/Oimo.js"></script>
         <script src="https://preview.babylonjs.com/Oimo.js"></script>
-        <script src="https://preview.babylonjs.com/libktx.js"></script>
         <script src="https://preview.babylonjs.com/earcut.min.js"></script>
         <script src="https://preview.babylonjs.com/earcut.min.js"></script>
 
 
         <!-- jQuery -->
         <!-- jQuery -->
@@ -55,14 +54,6 @@
          <script
          <script
              src="https://rawcdn.githack.com/BabylonJS/Extensions/785013ec55b210d12263c91f3f0a2ae70cf0bc8a/CompoundShader/src/babylonx.CompoundShader.js"
              src="https://rawcdn.githack.com/BabylonJS/Extensions/785013ec55b210d12263c91f3f0a2ae70cf0bc8a/CompoundShader/src/babylonx.CompoundShader.js"
              ></script>
              ></script>
- 
-         <!-- Scene Manager -->
-         <script
-             src="https://rawcdn.githack.com/MackeyK24/MackeyK24.github.io/14fda491c50cfca6d3e2f6cbc5e6afe22cc455d6/toolkit/babylon.manager.js">
-         </script>
-         <script
-             src="https://rawcdn.githack.com/MackeyK24/MackeyK24.github.io/14fda491c50cfca6d3e2f6cbc5e6afe22cc455d6/toolkit/babylon.navmesh.js">
-         </script>        
 
 
         <style>
         <style>
             html,
             html,

+ 27 - 3
Playground/index-local.html

@@ -33,7 +33,6 @@
         <script src="/dist/preview%20release/recast.js"></script>
         <script src="/dist/preview%20release/recast.js"></script>
         <script src="/dist/preview%20release/cannon.js"></script>
         <script src="/dist/preview%20release/cannon.js"></script>
         <script src="/dist/preview%20release/Oimo.js"></script>
         <script src="/dist/preview%20release/Oimo.js"></script>
-        <script src="/dist/preview%20release/libktx.js"></script>
         <script src="/dist/preview%20release/earcut.min.js"></script>
         <script src="/dist/preview%20release/earcut.min.js"></script>
         
         
         <!-- Babylon.js -->
         <!-- Babylon.js -->
@@ -56,12 +55,37 @@
         <div id="host-element">
         <div id="host-element">
         </div>
         </div>
         <script>
         <script>
+            function GetAbsoluteUrl(url) {
+                const a = document.createElement("a");
+                a.href = url;
+                return a.href;
+            }
+
             // Load the scripts + map file to allow vscode debug.
             // Load the scripts + map file to allow vscode debug.
-            BABYLONDEVTOOLS.Loader       
+            BABYLONDEVTOOLS.Loader
                 .require("index.js")
                 .require("index.js")
                 .load(() => {
                 .load(() => {
+                    BABYLON.DracoCompression.Configuration.decoder = {
+                        wasmUrl: GetAbsoluteUrl("../dist/preview%20release/draco_wasm_wrapper_gltf.js"),
+                        wasmBinaryUrl: GetAbsoluteUrl("../dist/preview%20release/draco_decoder_gltf.wasm"),
+                        fallbackUrl: GetAbsoluteUrl("../dist/preview%20release/draco_decoder_gltf.js")
+                    };
+                    BABYLON.GLTFValidation.Configuration = {
+                        url: GetAbsoluteUrl("../dist/preview%20release/gltf_validator.js")
+                    };
+                    BABYLON.GLTF2.Loader.Extensions.EXT_meshopt_compression.DecoderPath =
+                        GetAbsoluteUrl("../dist/preview%20release/meshopt_decoder.js");
+                    BABYLON.KhronosTextureContainer2.URLConfig = {
+                        jsDecoderModule: GetAbsoluteUrl("../dist/preview%20release/babylon.ktx2Decoder.js"),
+                        wasmUASTCToASTC: GetAbsoluteUrl("../dist/preview%20release/ktx2Transcoders/uastc_astc.wasm"),
+                        wasmUASTCToBC7: GetAbsoluteUrl("../dist/preview%20release/ktx2Transcoders/uastc_bc7.wasm"),
+                        wasmUASTCToRGBA_UNORM: GetAbsoluteUrl("../dist/preview%20release/ktx2Transcoders/uastc_rgba32_unorm.wasm"),
+                        wasmUASTCToRGBA_SRGB: GetAbsoluteUrl("../dist/preview%20release/ktx2Transcoders/uastc_rgba32_srgb.wasm"),
+                        jsMSCTranscoder: GetAbsoluteUrl("../dist/preview%20release/ktx2Transcoders/msc_basis_transcoder.js"),
+                        wasmMSCTranscoder: GetAbsoluteUrl("../dist/preview%20release/ktx2Transcoders/msc_basis_transcoder.wasm")
+                    };
                 });
                 });
         </script>
         </script>
     </body>
     </body>
 
 
-</html>
+</html>

+ 4 - 12
Playground/index.html

@@ -33,19 +33,18 @@
         <script src="https://preview.babylonjs.com/recast.js"></script>
         <script src="https://preview.babylonjs.com/recast.js"></script>
         <script src="https://preview.babylonjs.com/cannon.js"></script>
         <script src="https://preview.babylonjs.com/cannon.js"></script>
         <script src="https://preview.babylonjs.com/Oimo.js"></script>
         <script src="https://preview.babylonjs.com/Oimo.js"></script>
-        <script src="https://preview.babylonjs.com/libktx.js"></script>
         <script src="https://preview.babylonjs.com/earcut.min.js"></script>
         <script src="https://preview.babylonjs.com/earcut.min.js"></script>
         
         
         <!-- Babylon.js -->
         <!-- Babylon.js -->
         <script src="https://preview.babylonjs.com/babylon.js"></script>
         <script src="https://preview.babylonjs.com/babylon.js"></script>
-        <script src="https://preview.babylonjs.com/gui/babylon.gui.min.js"></script>
-        <script src="https://preview.babylonjs.com/nodeEditor/babylon.nodeEditor.js"></script>
         <script src="https://preview.babylonjs.com/materialsLibrary/babylonjs.materials.min.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/proceduralTexturesLibrary/babylonjs.proceduralTextures.min.js"></script>
         <script src="https://preview.babylonjs.com/postProcessesLibrary/babylonjs.postProcess.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/loaders/babylonjs.loaders.min.js"></script>
         <script src="https://preview.babylonjs.com/serializers/babylonjs.serializers.min.js"></script>
         <script src="https://preview.babylonjs.com/serializers/babylonjs.serializers.min.js"></script>
+        <script src="https://preview.babylonjs.com/gui/babylon.gui.min.js"></script>
         <script src="https://preview.babylonjs.com/inspector/babylon.inspector.bundle.js"></script>
         <script src="https://preview.babylonjs.com/inspector/babylon.inspector.bundle.js"></script>
+        <script src="https://preview.babylonjs.com/nodeEditor/babylon.nodeEditor.js"></script>
 
 
          <!-- Extensions -->
          <!-- Extensions -->
          <script
          <script
@@ -54,15 +53,8 @@
          </script>
          </script>
          <script
          <script
              src="https://rawcdn.githack.com/BabylonJS/Extensions/785013ec55b210d12263c91f3f0a2ae70cf0bc8a/CompoundShader/src/babylonx.CompoundShader.js"
              src="https://rawcdn.githack.com/BabylonJS/Extensions/785013ec55b210d12263c91f3f0a2ae70cf0bc8a/CompoundShader/src/babylonx.CompoundShader.js"
-             ></script>
- 
-         <!-- Scene Manager -->
-         <script
-             src="https://rawcdn.githack.com/MackeyK24/MackeyK24.github.io/14fda491c50cfca6d3e2f6cbc5e6afe22cc455d6/toolkit/babylon.manager.js">
-         </script>
-         <script
-             src="https://rawcdn.githack.com/MackeyK24/MackeyK24.github.io/14fda491c50cfca6d3e2f6cbc5e6afe22cc455d6/toolkit/babylon.navmesh.js">
-         </script>        
+             >
+        </script>
 
 
         <style>
         <style>
             html,
             html,

+ 25 - 8
Playground/index.js

@@ -10,6 +10,16 @@ var Versions = {
         "https://preview.babylonjs.com/postProcessesLibrary/babylonjs.postProcess.min.js",
         "https://preview.babylonjs.com/postProcessesLibrary/babylonjs.postProcess.min.js",
         "https://preview.babylonjs.com/loaders/babylonjs.loaders.min.js",
         "https://preview.babylonjs.com/loaders/babylonjs.loaders.min.js",
         "https://preview.babylonjs.com/serializers/babylonjs.serializers.min.js"
         "https://preview.babylonjs.com/serializers/babylonjs.serializers.min.js"
+    ],    
+    "4.2.0": [
+        "https://cdn.jsdelivr.net/gh/BabylonJS/Babylon.js@4.2.0/dist/babylon.js",
+        "https://cdn.jsdelivr.net/gh/BabylonJS/Babylon.js@4.2.0/dist/gui/babylon.gui.min.js",
+        "https://cdn.jsdelivr.net/gh/BabylonJS/Babylon.js@4.2.0/dist/inspector/babylon.inspector.bundle.js",
+        "https://cdn.jsdelivr.net/gh/BabylonJS/Babylon.js@4.2.0/dist/materialsLibrary/babylonjs.materials.min.js",
+        "https://cdn.jsdelivr.net/gh/BabylonJS/Babylon.js@4.2.0/dist/proceduralTexturesLibrary/babylonjs.proceduralTextures.min.js",
+        "https://cdn.jsdelivr.net/gh/BabylonJS/Babylon.js@4.2.0/dist/postProcessesLibrary/babylonjs.postProcess.min.js",
+        "https://cdn.jsdelivr.net/gh/BabylonJS/Babylon.js@4.2.0/dist/loaders/babylonjs.loaders.min.js",
+        "https://cdn.jsdelivr.net/gh/BabylonJS/Babylon.js@4.2.0/dist/serializers/babylonjs.serializers.min.js"
     ],
     ],
     "4.1.0": [
     "4.1.0": [
         "https://cdn.jsdelivr.net/gh/BabylonJS/Babylon.js@4.1.0/dist/babylon.js",
         "https://cdn.jsdelivr.net/gh/BabylonJS/Babylon.js@4.1.0/dist/babylon.js",
@@ -62,6 +72,15 @@ let readStringFromStore = function(key, defaultValue) {
     return localStorage.getItem(key);
     return localStorage.getItem(key);
 }
 }
 
 
+let loadInSequence = async function(versions, index, resolve) {
+    if (index >= versions.length) {
+        resolve();
+        return;
+    }
+    await loadScriptAsync(versions[index]);
+    loadInSequence(versions, index + 1, resolve);
+}
+
 let checkBabylonVersionAsync= function () {
 let checkBabylonVersionAsync= function () {
     let activeVersion = readStringFromStore("version", "Latest");
     let activeVersion = readStringFromStore("version", "Latest");
 
 
@@ -69,19 +88,17 @@ let checkBabylonVersionAsync= function () {
         return Promise.resolve();
         return Promise.resolve();
     }
     }
 
 
-    let tasks = [];
-
-    for (var file of Versions[activeVersion]) {
-        tasks.push(loadScriptAsync(file));
-    }
-
-    return Promise.all(tasks);
+    return new Promise((resolve, reject) => {
+        loadInSequence(Versions[activeVersion], 0, resolve);
+    });
 }
 }
 
 
+var storedPGObbject = BABYLON.Playground;
+
 checkBabylonVersionAsync().then(() => {
 checkBabylonVersionAsync().then(() => {
     if (typeof BABYLONDEVTOOLS !== 'undefined') {
     if (typeof BABYLONDEVTOOLS !== 'undefined') {
         var hostElement = document.getElementById("host-element");
         var hostElement = document.getElementById("host-element");
-        BABYLON.Playground.Show(hostElement);
+        storedPGObbject.Show(hostElement);
         return;
         return;
     }
     }
 
 

File diff suppressed because it is too large
+ 2686 - 0
Playground/libs/babylon.manager.d.ts


File diff suppressed because it is too large
+ 11 - 0
Playground/libs/babylon.manager.js


+ 49 - 4
Playground/src/components/commandBarComponent.tsx

@@ -3,6 +3,7 @@ import { GlobalState } from '../globalState';
 import { CommandButtonComponent } from './commandButtonComponent';
 import { CommandButtonComponent } from './commandButtonComponent';
 import { CommandDropdownComponent } from './commandDropdownComponent';
 import { CommandDropdownComponent } from './commandDropdownComponent';
 import { Utilities } from '../tools/utilities';
 import { Utilities } from '../tools/utilities';
+import { WebGPUEngine } from "babylonjs";
 
 
 require("../scss/commandBar.scss");
 require("../scss/commandBar.scss");
 
 
@@ -16,6 +17,10 @@ export class CommandBarComponent extends React.Component<ICommandBarComponentPro
   
   
     public constructor(props: ICommandBarComponentProps) {
     public constructor(props: ICommandBarComponentProps) {
         super(props);
         super(props);
+
+        this.props.globalState.onLanguageChangedObservable.add(() => {
+            this.forceUpdate();
+        });
     }    
     }    
 
 
     onPlay() {
     onPlay() {
@@ -39,7 +44,7 @@ export class CommandBarComponent extends React.Component<ICommandBarComponentPro
     }
     }
 
 
     onInspector() {
     onInspector() {
-        this.props.globalState.onInspectorRequiredObservable.notifyObservers();
+        this.props.globalState.onInspectorRequiredObservable.notifyObservers(!this.props.globalState.inspectorIsOpened);
     }
     }
 
 
     onExamples() {
     onExamples() {
@@ -48,12 +53,12 @@ export class CommandBarComponent extends React.Component<ICommandBarComponentPro
 
 
     public render() {
     public render() {
         let activeVersion = Utilities.ReadStringFromStore("version", "Latest");
         let activeVersion = Utilities.ReadStringFromStore("version", "Latest");
+        let activeEngineVersion = Utilities.ReadStringFromStore("engineVersion", "WebGL2");
 
 
         var versionOptions = Object.keys(Versions).map(key => {
         var versionOptions = Object.keys(Versions).map(key => {
             return {
             return {
                 label: key,
                 label: key,
                 storeKey: "version",
                 storeKey: "version",
-                defaultValue: "Latest",
                 isActive: activeVersion === key,
                 isActive: activeVersion === key,
                 onClick: () => {
                 onClick: () => {
                     Utilities.StoreStringToStore("version", key);
                     Utilities.StoreStringToStore("version", key);
@@ -62,6 +67,39 @@ export class CommandBarComponent extends React.Component<ICommandBarComponentPro
             }
             }
         });
         });
 
 
+        var engineOptions = [
+            {
+                label: "WebGL2",
+                storeKey: "engineVersion",
+                isActive: activeEngineVersion === "WebGL2",
+                onClick: () => {
+                    Utilities.StoreStringToStore("engineVersion", "WebGL2");
+                    window.location.reload();
+                }
+            },
+            {
+                label: "WebGL",
+                storeKey: "engineVersion",
+                isActive: activeEngineVersion === "WebGL",
+                onClick: () => {
+                    Utilities.StoreStringToStore("engineVersion", "WebGL");
+                    window.location.reload();
+                }
+            }
+        ];
+
+        if (WebGPUEngine.IsSupported) {
+            engineOptions.splice(0,0, {
+                label: "WebGPU",
+                storeKey: "engineVersion",
+                isActive: activeEngineVersion === "WebGPU",
+                onClick: () => {
+                    Utilities.StoreStringToStore("engineVersion", "WebGPU");
+                    window.location.reload();
+                }
+            });
+        }
+
         return (
         return (
             <div className={"commands " + (this.props.globalState.language === "JS" ? "background-js" : "background-ts")}>
             <div className={"commands " + (this.props.globalState.language === "JS" ? "background-js" : "background-ts")}>
                 <div className="commands-left">
                 <div className="commands-left">
@@ -143,11 +181,18 @@ export class CommandBarComponent extends React.Component<ICommandBarComponentPro
                     {
                     {
                         label: "QR code",
                         label: "QR code",
                         onClick: () => {this.props.globalState.onQRCodeRequiredObservable.notifyObservers(true)}
                         onClick: () => {this.props.globalState.onQRCodeRequiredObservable.notifyObservers(true)}
-                    }
+                    },                 
+                    {
+                        label: "Load Unity Toolkit",
+                        storeKey: "unity-toolkit",
+                        defaultValue: false,
+                        onCheck: () => {}
+                    }, 
                 ]}/>
                 ]}/>
                 </div>
                 </div>
                 <div className="commands-right">
                 <div className="commands-right">
-                    <CommandDropdownComponent globalState={this.props.globalState} icon="version" tooltip="Versions" toRight={true} items={versionOptions} />                    
+                    <CommandDropdownComponent globalState={this.props.globalState} defaultValue={activeEngineVersion} tooltip="Engine" toRight={true} items={engineOptions} />                    
+                    <CommandDropdownComponent globalState={this.props.globalState} defaultValue={activeVersion} tooltip="Versions" toRight={true} items={versionOptions} />                    
                     <CommandButtonComponent globalState={this.props.globalState} tooltip="Examples" icon="examples" onClick={()=> this.onExamples()} isActive={false}/>
                     <CommandButtonComponent globalState={this.props.globalState} tooltip="Examples" icon="examples" onClick={()=> this.onExamples()} isActive={false}/>
                 </div>
                 </div>
             </div>
             </div>

+ 45 - 10
Playground/src/components/commandDropdownComponent.tsx

@@ -1,11 +1,13 @@
+import { Engine } from "babylonjs/Engines/engine";
 import * as React from "react";
 import * as React from "react";
 import { GlobalState } from '../globalState';
 import { GlobalState } from '../globalState';
 import { Utilities } from '../tools/utilities';
 import { Utilities } from '../tools/utilities';
 
 
 interface ICommandDropdownComponentProps {
 interface ICommandDropdownComponentProps {
     globalState: GlobalState;
     globalState: GlobalState;
-    icon: string; 
+    icon?: string; 
     tooltip: string;
     tooltip: string;
+    defaultValue?: string;
     items: {
     items: {
         label: string, 
         label: string, 
         onClick?: () => void, 
         onClick?: () => void, 
@@ -15,30 +17,62 @@ interface ICommandDropdownComponentProps {
         defaultValue?: boolean | string;
         defaultValue?: boolean | string;
         subItems?: string[];
         subItems?: string[];
     }[];
     }[];
-    toRight?: boolean
+    toRight?: boolean;    
 }
 }
 
 
-export class CommandDropdownComponent extends React.Component<ICommandDropdownComponentProps, {isExpanded: boolean}> {    
+export class CommandDropdownComponent extends React.Component<ICommandDropdownComponentProps, {isExpanded: boolean, activeState: string}> {    
   
   
     public constructor(props: ICommandDropdownComponentProps) {
     public constructor(props: ICommandDropdownComponentProps) {
         super(props);
         super(props);
 
 
-        this.state = {isExpanded: false}
+        this.state = {isExpanded: false, activeState: Utilities.ReadStringFromStore(this.props.tooltip, this.props.defaultValue!)};
+
+        this.props.globalState.OnNewDropdownButtonClicked.add((source) => {
+            if (source === this) {
+                return;
+            }
+
+            this.setState({isExpanded: false});
+        });
     }    
     }    
 
 
     public render() {
     public render() {
+        var engineVersionSub = Engine.Version.indexOf("-");
+        var engineVersion = Engine.Version;
+
+        if (engineVersionSub ! -1) {
+            engineVersion = engineVersion.substr(0, engineVersionSub);
+        }
+
         return (
         return (
             <>
             <>
                 {
                 {
                     this.state.isExpanded &&
                     this.state.isExpanded &&
-                    <div className="command-dropdown-blocker" onClick={() => this.setState({isExpanded: false})}>
+                    <div className="command-dropdown-blocker" onClick={() => {
+                        this.setState({isExpanded: false});
+                    }}>
                     </div>
                     </div>
                 }
                 }
                 <div className="command-dropdown-root">
                 <div className="command-dropdown-root">
-                    <div className={"command-dropdown" + (this.state.isExpanded ? " activated" : "")} title={this.props.tooltip} onClick={() => this.setState({isExpanded: !this.state.isExpanded})}>
-                        <div className="command-dropdown-icon">
-                            <img src={"imgs/" + this.props.icon + ".svg"}/>
-                        </div>
+                    <div className={"command-dropdown" + (this.state.isExpanded ? " activated" : "")} title={this.props.tooltip} 
+                        onClick={() => {
+                            this.props.globalState.OnNewDropdownButtonClicked.notifyObservers(this);
+                            this.setState({isExpanded: !this.state.isExpanded});
+                        }}>
+                        {
+                            this.props.icon &&
+                            <div className="command-dropdown-icon">
+                                <img src={"imgs/" + this.props.icon + ".svg"}/>
+                            </div>
+                        }
+                        {
+                            !this.props.icon &&
+                            <div className="command-dropdown-active">
+                                {
+                                    this.state.activeState === "Latest" ? engineVersion : this.state.activeState
+                                }
+                            </div>
+                        }
                     </div>
                     </div>
                     {
                     {
                             this.state.isExpanded &&
                             this.state.isExpanded &&
@@ -56,7 +90,8 @@ export class CommandDropdownComponent extends React.Component<ICommandDropdownCo
                                                 }
                                                 }
                                                 if (!m.subItems) {
                                                 if (!m.subItems) {
                                                     m.onClick();
                                                     m.onClick();
-                                                    this.setState({isExpanded: false});
+                                                    Utilities.StoreStringToStore(this.props.tooltip, m.label);
+                                                    this.setState({isExpanded: false, activeState: m.label});
                                                 }
                                                 }
                                             }} title={m.label}>
                                             }} title={m.label}>
                                                 <div className="command-dropdown-label-text">
                                                 <div className="command-dropdown-label-text">

+ 57 - 52
Playground/src/components/examplesComponent.tsx

@@ -1,5 +1,5 @@
 import * as React from "react";
 import * as React from "react";
-import { GlobalState } from '../globalState';
+import { GlobalState } from "../globalState";
 
 
 require("../scss/examples.scss");
 require("../scss/examples.scss");
 
 
@@ -7,8 +7,8 @@ interface IExamplesComponentProps {
     globalState: GlobalState;
     globalState: GlobalState;
 }
 }
 
 
-export class ExamplesComponent extends React.Component<IExamplesComponentProps, {filter: string}> {  
-    private _state = "";
+export class ExamplesComponent extends React.Component<IExamplesComponentProps, { filter: string }> {
+    private _state = "removed";
     private _rootRef: React.RefObject<HTMLDivElement>;
     private _rootRef: React.RefObject<HTMLDivElement>;
     private _scripts: {
     private _scripts: {
         title: string;
         title: string;
@@ -19,33 +19,39 @@ export class ExamplesComponent extends React.Component<IExamplesComponentProps,
             PGID: string;
             PGID: string;
             description: string;
             description: string;
         }[];
         }[];
-    }[];  
-  
+    }[];
+
     public constructor(props: IExamplesComponentProps) {
     public constructor(props: IExamplesComponentProps) {
         super(props);
         super(props);
         this._loadScripts();
         this._loadScripts();
 
 
-        this.state = {filter: ""};
+        this.state = { filter: "" };
         this._rootRef = React.createRef();
         this._rootRef = React.createRef();
 
 
         this.props.globalState.onExamplesDisplayChangedObservable.add(() => {
         this.props.globalState.onExamplesDisplayChangedObservable.add(() => {
-            if (this._state === "") {
-                this._rootRef.current!.classList.add("visible");
-                this._state = "visible";
+            if (this._state !== "visible") {
+                this._rootRef.current!.classList.remove("removed");
+                setTimeout(() => {
+                    this._rootRef.current!.classList.add("visible");
+                    this._state = "visible";
+                }, 16);
             } else {
             } else {
                 this._rootRef.current!.classList.remove("visible");
                 this._rootRef.current!.classList.remove("visible");
                 this._state = "";
                 this._state = "";
+                setTimeout(() => {
+                    this._rootRef.current!.classList.add("removed");
+                }, 200);
             }
             }
         });
         });
-    }  
+    }
 
 
     private _loadScripts() {
     private _loadScripts() {
         var xhr = new XMLHttpRequest();
         var xhr = new XMLHttpRequest();
 
 
         if (this.props.globalState.language === "JS") {
         if (this.props.globalState.language === "JS") {
-            xhr.open('GET', 'https://raw.githubusercontent.com/BabylonJS/Documentation/master/examples/list.json', true);
+            xhr.open("GET", "https://raw.githubusercontent.com/BabylonJS/Documentation/master/examples/list.json", true);
         } else {
         } else {
-            xhr.open('GET', 'https://raw.githubusercontent.com/BabylonJS/Documentation/master/examples/list_ts.json', true);
+            xhr.open("GET", "https://raw.githubusercontent.com/BabylonJS/Documentation/master/examples/list_ts.json", true);
         }
         }
 
 
         xhr.onreadystatechange = () => {
         xhr.onreadystatechange = () => {
@@ -60,7 +66,7 @@ export class ExamplesComponent extends React.Component<IExamplesComponentProps,
                         return 1;
                         return 1;
                     });
                     });
 
 
-                    this._scripts.forEach(s => {
+                    this._scripts.forEach((s) => {
                         s.samples.sort((a, b) => {
                         s.samples.sort((a, b) => {
                             if (a.title < b.title) {
                             if (a.title < b.title) {
                                 return -1;
                                 return -1;
@@ -72,12 +78,11 @@ export class ExamplesComponent extends React.Component<IExamplesComponentProps,
                     this.forceUpdate();
                     this.forceUpdate();
                 }
                 }
             }
             }
-        }
+        };
 
 
         xhr.send(null);
         xhr.send(null);
     }
     }
 
 
-
     private _onLoadPG(id: string) {
     private _onLoadPG(id: string) {
         this.props.globalState.onLoadRequiredObservable.notifyObservers(id);
         this.props.globalState.onLoadRequiredObservable.notifyObservers(id);
 
 
@@ -95,46 +100,46 @@ export class ExamplesComponent extends React.Component<IExamplesComponentProps,
             <div id="examples" className={this._state} ref={this._rootRef}>
             <div id="examples" className={this._state} ref={this._rootRef}>
                 <div id="examples-header">Examples</div>
                 <div id="examples-header">Examples</div>
                 <div id="examples-filter">
                 <div id="examples-filter">
-                    <input id="examples-filter-text" type="text" placeholder="Filter examples" value={this.state.filter} onChange={evt => {
-                        this.setState({filter: evt.target.value});
-                    }}/>
+                    <input
+                        id="examples-filter-text"
+                        type="text"
+                        placeholder="Filter examples"
+                        value={this.state.filter}
+                        onChange={(evt) => {
+                            this.setState({ filter: evt.target.value });
+                        }}
+                    />
                 </div>
                 </div>
                 <div id="examples-list">
                 <div id="examples-list">
-                    {
-                        this._scripts.map(s => {
-                            let active = s.samples.filter(ss => {
-                                return !this.state.filter 
-                                    || ss.title.toLowerCase().indexOf(this.state.filter.toLowerCase()) !== -1
-                                    || ss.description.toLowerCase().indexOf(this.state.filter.toLowerCase()) !== -1
-                            });
-
-                            if (active.length === 0) {
-                                return null;
-                            }
+                    {this._scripts.map((s) => {
+                        let active = s.samples.filter((ss) => {
+                            return !this.state.filter || ss.title.toLowerCase().indexOf(this.state.filter.toLowerCase()) !== -1 || ss.description.toLowerCase().indexOf(this.state.filter.toLowerCase()) !== -1;
+                        });
+
+                        if (active.length === 0) {
+                            return null;
+                        }
 
 
-                            return(
-                                <div key={s.title} className="example-category">
-                                    <div className="example-category-title">
-                                        {s.title}
-                                    </div>
-                                    {
-                                        active.map(ss => {
-                                            return (
-                                                <div className="example" key={ss.title} onClick={() => this._onLoadPG(ss.PGID)}>
-                                                    <img src={ss.icon.replace("icons", "https://doc.babylonjs.com/examples/icons")}/>
-                                                    <div className="example-title">{ss.title}</div>
-                                                    <div className="example-description">{ss.description}</div>
-                                                    <a className="example-link" href={ss.doc} target="_blank">Documentation</a>
-                                                </div>
-                                            )
-                                        })
-                                    }
-                                </div>
-                            )
-                        })
-                    }
+                        return (
+                            <div key={s.title} className="example-category">
+                                <div className="example-category-title">{s.title}</div>
+                                {active.map((ss) => {
+                                    return (
+                                        <div className="example" key={ss.title} onClick={() => this._onLoadPG(ss.PGID)}>
+                                            <img src={ss.icon.replace("icons", "https://doc.babylonjs.com/examples/icons")} />
+                                            <div className="example-title">{ss.title}</div>
+                                            <div className="example-description">{ss.description}</div>
+                                            <a className="example-link" href={ss.doc} target="_blank">
+                                                Documentation
+                                            </a>
+                                        </div>
+                                    );
+                                })}
+                            </div>
+                        );
+                    })}
                 </div>
                 </div>
             </div>
             </div>
-        )
+        );
     }
     }
-}
+}

+ 1 - 1
Playground/src/components/hamburgerMenu.tsx

@@ -43,7 +43,7 @@ export class HamburgerMenuComponent extends React.Component<IHamburgerMenuCompon
     }
     }
 
 
     onInspector() {
     onInspector() {
-        this.props.globalState.onInspectorRequiredObservable.notifyObservers();
+        this.props.globalState.onInspectorRequiredObservable.notifyObservers(!this.props.globalState.inspectorIsOpened);
         this.setState({isExpanded: false});
         this.setState({isExpanded: false});
     }
     }
 
 

+ 14 - 1
Playground/src/components/headerComponent.tsx

@@ -21,12 +21,25 @@ export class HeaderComponent extends React.Component<IHeaderComponentProps> {
         this._refVersionNumber = React.createRef();
         this._refVersionNumber = React.createRef();
 
 
         this.props.globalState.onLanguageChangedObservable.add(() => {
         this.props.globalState.onLanguageChangedObservable.add(() => {
+            this.updateDescription();
             this.forceUpdate();
             this.forceUpdate();
         });
         });
+
+        this.props.globalState.onRunExecutedObservable.add(() => {
+            this.updateDescription();
+        });
     }
     }
 
 
-    componentDidMount() {
+    updateDescription() {
         this._refVersionNumber.current!.innerHTML = Engine.Version;
         this._refVersionNumber.current!.innerHTML = Engine.Version;
+
+        if (Engine.LastCreatedEngine && Engine.LastCreatedEngine.name) {
+            this._refVersionNumber.current!.innerHTML += ` (${Engine.LastCreatedEngine.name}${Engine.LastCreatedEngine.version > 1 ? Engine.LastCreatedEngine.version : ""})`;
+        }
+    }
+
+    componentDidMount() {
+        this.updateDescription();
     }
     }
     
     
     public render() {
     public render() {

+ 93 - 33
Playground/src/components/rendererComponent.tsx

@@ -5,6 +5,7 @@ import { Nullable } from "babylonjs/types";
 import { Scene } from "babylonjs/scene";
 import { Scene } from "babylonjs/scene";
 import { Utilities } from "../tools/utilities";
 import { Utilities } from "../tools/utilities";
 import { DownloadManager } from "../tools/downloadManager";
 import { DownloadManager } from "../tools/downloadManager";
+import { WebGPUEngine } from "babylonjs";
 
 
 require("../scss/rendering.scss");
 require("../scss/rendering.scss");
 
 
@@ -17,6 +18,7 @@ export class RenderingComponent extends React.Component<IRenderingComponentProps
     private _scene: Nullable<Scene>;
     private _scene: Nullable<Scene>;
     private _canvasRef: React.RefObject<HTMLCanvasElement>;
     private _canvasRef: React.RefObject<HTMLCanvasElement>;
     private _downloadManager: DownloadManager;
     private _downloadManager: DownloadManager;
+    private _unityToolkitWasLoaded = false;
 
 
     public constructor(props: IRenderingComponentProps) {
     public constructor(props: IRenderingComponentProps) {
         super(props);
         super(props);
@@ -41,18 +43,19 @@ export class RenderingComponent extends React.Component<IRenderingComponentProps
             this._downloadManager.download(this._engine);
             this._downloadManager.download(this._engine);
         });
         });
 
 
-        this.props.globalState.onInspectorRequiredObservable.add(() => {
+        this.props.globalState.onInspectorRequiredObservable.add((state) => {
             if (!this._scene) {
             if (!this._scene) {
                 return;
                 return;
             }
             }
 
 
-            if (this._scene.debugLayer.isVisible()) {
-                this._scene.debugLayer.hide();
-            } else {
+            if (state) {
                 this._scene.debugLayer.show({
                 this._scene.debugLayer.show({
                     embedMode: true,
                     embedMode: true,
                 });
                 });
+            } else {
+                this._scene.debugLayer.hide();
             }
             }
+            this.props.globalState.inspectorIsOpened = state;
         });
         });
 
 
         this.props.globalState.onFullcreenRequiredObservable.add(() => {
         this.props.globalState.onFullcreenRequiredObservable.add(() => {
@@ -75,12 +78,36 @@ export class RenderingComponent extends React.Component<IRenderingComponentProps
         });
         });
     }
     }
 
 
+    private async _loadScriptAsync(url: string): Promise<void> {
+        return new Promise((resolve, reject) => {
+            let script = document.createElement('script');
+            script.src = url;
+            script.onload = () => {
+                resolve();
+            };
+            document.head.appendChild(script);
+        });
+    }
+
     private async _compileAndRunAsync() {
     private async _compileAndRunAsync() {
         this.props.globalState.onDisplayWaitRingObservable.notifyObservers(false);
         this.props.globalState.onDisplayWaitRingObservable.notifyObservers(false);
         this.props.globalState.onErrorObservable.notifyObservers(null);
         this.props.globalState.onErrorObservable.notifyObservers(null);
 
 
         const displayInspector = this._scene?.debugLayer.isVisible();
         const displayInspector = this._scene?.debugLayer.isVisible();
 
 
+        let useWebGPU = location.href.indexOf("webgpu") !== -1 && WebGPUEngine.IsSupported;
+        let forceWebGL1 = false;
+        const configuredEngine = Utilities.ReadStringFromStore("engineVersion", "WebGL2");
+
+        switch (configuredEngine) {
+            case "WebGPU":
+                useWebGPU = true;
+                break;
+            case "WebGL":
+                forceWebGL1 = true;
+                break;
+        }
+        
 
 
         if (this._engine) {
         if (this._engine) {
             try {
             try {
@@ -96,21 +123,45 @@ export class RenderingComponent extends React.Component<IRenderingComponentProps
             let canvas = this._canvasRef.current!;
             let canvas = this._canvasRef.current!;
             globalObject.canvas = canvas;
             globalObject.canvas = canvas;
 
 
-            globalObject.createDefaultEngine = function () {
-                return new Engine(canvas, true, {
-                    preserveDrawingBuffer: true,
-                    stencil: true,
-                });
-            };
+            if (useWebGPU) {
+                globalObject.createDefaultEngine = async function() { 
+                    var engine = new BABYLON.WebGPUEngine(canvas);
+                    await engine.initAsync();
+                    return engine;
+                }                
+            } else {
+                globalObject.createDefaultEngine = function () {
+                    return new Engine(canvas, true, {
+                        disableWebGL2Support: forceWebGL1,
+                        preserveDrawingBuffer: true,
+                        stencil: true,
+                    });
+                };
+            }
 
 
             let zipVariables = "var engine = null;\r\nvar scene = null;\r\nvar sceneToRender = null;\r\n";
             let zipVariables = "var engine = null;\r\nvar scene = null;\r\nvar sceneToRender = null;\r\n";
-            let defaultEngineZip = "var createDefaultEngine = function() { return new BABYLON.Engine(canvas, true, { preserveDrawingBuffer: true, stencil: true }); }";
+            let defaultEngineZip = `var createDefaultEngine = function() { return new BABYLON.Engine(canvas, true, { preserveDrawingBuffer: true, stencil: true,  disableWebGL2Support: ${forceWebGL1}}); }`;
+
+            if (useWebGPU) {
+                defaultEngineZip = `var createDefaultEngine = async function() { 
+                    var engine = new BABYLON.WebGPUEngine(canvas);
+                    await engine.initAsync();
+                    return engine;
+                }`;
+            }
+
             let code = await this.props.globalState.getCompiledCode();
             let code = await this.props.globalState.getCompiledCode();
 
 
             if (!code) {
             if (!code) {
                 return;
                 return;
             }
             }
 
 
+            // Check for Unity Toolkit
+            if ((location.href.indexOf("UnityToolkit") !== -1 || Utilities.ReadBoolFromStore("unity-toolkit", false)) && !this._unityToolkitWasLoaded) {
+                await this._loadScriptAsync("/libs/babylon.manager.js");
+                this._unityToolkitWasLoaded = true;
+            }
+
             let createEngineFunction = "createDefaultEngine";
             let createEngineFunction = "createDefaultEngine";
             let createSceneFunction = "";
             let createSceneFunction = "";
             let checkCamera = true;
             let checkCamera = true;
@@ -137,26 +188,25 @@ export class RenderingComponent extends React.Component<IRenderingComponentProps
             }
             }
 
 
             if (!createSceneFunction) {
             if (!createSceneFunction) {
-                this._engine = globalObject.createDefaultEngine() as Engine;
-                this._scene = new Scene(this._engine);
-
-                globalObject.engine = this._engine;
-                globalObject.scene = this._scene;
-
-                let runScript: any = null;
-                Utilities.FastEval("runScript = function(scene, canvas) {" + code + "}");
-                runScript(this._scene, canvas);
-
-                this.props.globalState.zipCode = zipVariables + defaultEngineZip + "var engine = createDefaultEngine();" + ";\r\nvar scene = new BABYLON.Scene(engine);\r\n\r\n" + code;
+                this.props.globalState.onErrorObservable.notifyObservers({
+                    message: "You must provide a function named createScene.",
+                });
+                return;
             } else {
             } else {
                 code += `
                 code += `
-    var engine;
-    try {
-    engine = ${createEngineFunction}();
-    } catch(e) {
-    console.log("the available createEngine function failed. Creating the default engine instead");
-    engine = createDefaultEngine();
-    }`;
+                var engine;
+                var scene;
+                initFunction = async function() {               
+                    var asyncEngineCreation = async function() {
+                        try {
+                        return ${createEngineFunction}();
+                        } catch(e) {
+                        console.log("the available createEngine function failed. Creating the default engine instead");
+                        return createDefaultEngine();
+                        }
+                    }
+
+                    engine = await asyncEngineCreation();`;
                 code += "\r\nif (!engine) throw 'engine should not be null.';";
                 code += "\r\nif (!engine) throw 'engine should not be null.';";
 
 
                 if (this.props.globalState.language === "JS") {
                 if (this.props.globalState.language === "JS") {
@@ -167,9 +217,13 @@ export class RenderingComponent extends React.Component<IRenderingComponentProps
                     code += "\n" + "scene = " + createSceneFunction + "();";
                     code += "\n" + "scene = " + createSceneFunction + "();";
                 }
                 }
 
 
+                code += `}`;
+
                 // Execute the code
                 // Execute the code
                 Utilities.FastEval(code);
                 Utilities.FastEval(code);
 
 
+                await globalObject.initFunction();
+
                 this._engine = globalObject.engine;
                 this._engine = globalObject.engine;
 
 
                 if (!this._engine) {
                 if (!this._engine) {
@@ -220,7 +274,7 @@ export class RenderingComponent extends React.Component<IRenderingComponentProps
                     }
                     }
                 }
                 }
 
 
-                if (this._scene.activeCamera || this._scene.activeCameras.length > 0) {
+                if (this._scene.activeCamera || this._scene.activeCameras && this._scene.activeCameras.length > 0) {
                     this._scene.render();
                     this._scene.render();
                 }
                 }
 
 
@@ -240,7 +294,7 @@ export class RenderingComponent extends React.Component<IRenderingComponentProps
             }
             }
 
 
             if (this._engine.scenes[0] && displayInspector) {
             if (this._engine.scenes[0] && displayInspector) {
-                this.props.globalState.onInspectorRequiredObservable.notifyObservers();
+                this.props.globalState.onInspectorRequiredObservable.notifyObservers(true);
             }
             }
 
 
             if (checkCamera && this._engine.scenes[0].activeCamera == null) {
             if (checkCamera && this._engine.scenes[0].activeCamera == null) {
@@ -249,9 +303,15 @@ export class RenderingComponent extends React.Component<IRenderingComponentProps
                 });
                 });
                 return;
                 return;
             } else if (globalObject.scene.then) {
             } else if (globalObject.scene.then) {
-                globalObject.scene.then(function () {});
+                globalObject.scene.then(() => {
+                    if (this._engine!.scenes[0] && displayInspector) {
+                        this.props.globalState.onInspectorRequiredObservable.notifyObservers(true);
+                    }
+                });
             } else {
             } else {
-                this._engine.scenes[0].executeWhenReady(function () {});
+                this._engine.scenes[0].executeWhenReady(() => {
+                    this.props.globalState.onRunExecutedObservable.notifyObservers();
+                });
             }
             }
         } catch (err) {
         } catch (err) {
             this.props.globalState.onErrorObservable.notifyObservers(err);
             this.props.globalState.onErrorObservable.notifyObservers(err);

+ 4 - 1
Playground/src/globalState.ts

@@ -28,6 +28,7 @@ export class GlobalState {
     public mobileDefaultMode = EditionMode.RenderingOnly;
     public mobileDefaultMode = EditionMode.RenderingOnly;
 
 
     public runtimeMode = RuntimeMode.Editor;
     public runtimeMode = RuntimeMode.Editor;
+    public inspectorIsOpened = false;
 
 
     public currentSnippetTitle = "";
     public currentSnippetTitle = "";
     public currentSnippetDescription = "";
     public currentSnippetDescription = "";
@@ -37,6 +38,7 @@ export class GlobalState {
     public zipCode = "";
     public zipCode = "";
 
 
     public onRunRequiredObservable = new Observable<void>();
     public onRunRequiredObservable = new Observable<void>();
+    public onRunExecutedObservable = new Observable<void>();
     public onSavedObservable = new Observable<void>();
     public onSavedObservable = new Observable<void>();
     public onNewRequiredObservable = new Observable<void>();
     public onNewRequiredObservable = new Observable<void>();
     public onClearRequiredObservable = new Observable<void>();
     public onClearRequiredObservable = new Observable<void>();
@@ -49,7 +51,7 @@ export class GlobalState {
     public onMetadataUpdatedObservable = new Observable<void>();
     public onMetadataUpdatedObservable = new Observable<void>();
     public onMetadataWindowHiddenObservable = new Observable<boolean>();
     public onMetadataWindowHiddenObservable = new Observable<boolean>();
     public onDownloadRequiredObservable = new Observable<void>();
     public onDownloadRequiredObservable = new Observable<void>();
-    public onInspectorRequiredObservable = new Observable<void>();
+    public onInspectorRequiredObservable = new Observable<boolean>();
     public onFormatCodeRequiredObservable = new Observable<void>();
     public onFormatCodeRequiredObservable = new Observable<void>();
     public onFullcreenRequiredObservable = new Observable<void>();
     public onFullcreenRequiredObservable = new Observable<void>();
     public onEditorFullcreenRequiredObservable = new Observable<void>();
     public onEditorFullcreenRequiredObservable = new Observable<void>();
@@ -61,6 +63,7 @@ export class GlobalState {
     public onNavigateRequiredObservable = new Observable<{lineNumber: number, column: number}>();
     public onNavigateRequiredObservable = new Observable<{lineNumber: number, column: number}>();
     public onExamplesDisplayChangedObservable = new Observable<void>();
     public onExamplesDisplayChangedObservable = new Observable<void>();
     public onQRCodeRequiredObservable = new Observable<boolean>();
     public onQRCodeRequiredObservable = new Observable<boolean>();
+    public OnNewDropdownButtonClicked = new Observable<any>();
 
 
     public loadingCodeInProgress = false;
     public loadingCodeInProgress = false;
     public onCodeLoaded = new Observable<string>();
     public onCodeLoaded = new Observable<string>();

+ 1 - 1
Playground/src/playground.tsx

@@ -142,7 +142,7 @@ export class Playground extends React.Component<IPlaygroundProps, { errorMessage
                         <RenderingComponent globalState={this._globalState} />
                         <RenderingComponent globalState={this._globalState} />
                     </div>
                     </div>
                 </div>
                 </div>
-                {window.innerWidth < 1024 && <HamburgerMenuComponent globalState={this._globalState} />}
+                {window.innerWidth < 1080 && <HamburgerMenuComponent globalState={this._globalState} />}
                 <ExamplesComponent globalState={this._globalState} />
                 <ExamplesComponent globalState={this._globalState} />
                 <FooterComponent globalState={this._globalState} />
                 <FooterComponent globalState={this._globalState} />
                 <QRCodeComponent globalState={this._globalState} />
                 <QRCodeComponent globalState={this._globalState} />

+ 21 - 5
Playground/src/scss/commandBar.scss

@@ -20,6 +20,10 @@
                 filter: invert(64%) sepia(78%) saturate(940%) hue-rotate(323deg) brightness(105%) contrast(103%);
                 filter: invert(64%) sepia(78%) saturate(940%) hue-rotate(323deg) brightness(105%) contrast(103%);
             }
             }
 
 
+            .command-dropdown-active {
+                color: #F78951;
+            }
+
             &:hover, &.activated {
             &:hover, &.activated {
                 img {
                 img {
                     filter: invert(34%) sepia(21%) saturate(3832%) hue-rotate(324deg) brightness(88%) contrast(82%) !important;
                     filter: invert(34%) sepia(21%) saturate(3832%) hue-rotate(324deg) brightness(88%) contrast(82%) !important;
@@ -34,6 +38,10 @@
                 filter: invert(57%) sepia(80%) saturate(2031%) hue-rotate(215deg);
                 filter: invert(57%) sepia(80%) saturate(2031%) hue-rotate(215deg);
             }
             }
 
 
+            .command-dropdown-active {
+                color: #9B86FF;
+            }
+
             &:hover, &.activated {
             &:hover, &.activated {
                 img {
                 img {
                     filter: invert(17%) !important;
                     filter: invert(17%) !important;
@@ -93,8 +101,18 @@
             justify-content: center;
             justify-content: center;
         }
         }
 
 
+        .command-dropdown-active {
+            height: 100%;
+            width: 100%;
+            display: grid;
+            align-content: center;
+            justify-content: center;
+            font-size: 14px;
+        }
+
         &:hover, &.activated {
         &:hover, &.activated {
             background-color: white;
             background-color: white;
+            color: black;
         } 
         } 
         
         
         &:active {
         &:active {
@@ -146,12 +164,11 @@
         }        
         }        
 
 
         .command-dropdown-label {
         .command-dropdown-label {
-            font-family: "acumin-pro-extra-condensed";
             color:white;
             color:white;
             padding: 5px;
             padding: 5px;
             padding-left: 10px;
             padding-left: 10px;
             height: 35px;
             height: 35px;
-            font-size: 20px;
+            font-size: 18px;
             display: grid;
             display: grid;
             align-items: center;
             align-items: center;
             cursor: pointer;
             cursor: pointer;
@@ -162,7 +179,7 @@
 
 
             &.active {
             &.active {
                 font-weight: bold;
                 font-weight: bold;
-                font-size: 22px;
+                font-size: 20px;
             }
             }
 
 
             &:hover {
             &:hover {
@@ -184,7 +201,7 @@
             .command-dropdown-arrow {
             .command-dropdown-arrow {
                 grid-column: 2;
                 grid-column: 2;
                 grid-row: 1;    
                 grid-row: 1;    
-                font-size: 28px;
+                font-size: 20px;
                 font-weight: bold;
                 font-weight: bold;
                 padding-bottom: 10px;
                 padding-bottom: 10px;
                 padding-left: 4px;
                 padding-left: 4px;
@@ -218,7 +235,6 @@
                 }   
                 }   
                                     
                                     
                 .sub-item {                      
                 .sub-item {                      
-                    font-family: "acumin-pro-extra-condensed";                    
                     color: white;
                     color: white;
                     padding: 5px;
                     padding: 5px;
                     padding-left: 10px;
                     padding-left: 10px;

+ 5 - 0
Playground/src/scss/examples.scss

@@ -10,12 +10,17 @@
     opacity: 0;
     opacity: 0;
     transition: all 0.2s ease;
     transition: all 0.2s ease;
     height: calc(100% - 90px);
     height: calc(100% - 90px);
+    z-index: 10;
 
 
     &.visible {
     &.visible {
         transform: translateX(0);
         transform: translateX(0);
         opacity: 1;
         opacity: 1;
     }
     }
 
 
+    &.removed {
+        display: none;
+    }
+
     width: 380px;
     width: 380px;
     display: grid;
     display: grid;
     grid-template-columns: 100%;
     grid-template-columns: 100%;

+ 5 - 2
Playground/src/scss/header.scss

@@ -86,12 +86,16 @@
                 .version-text {
                 .version-text {
                     display: none;
                     display: none;
                 }
                 }
+                
+                .version-number {
+                    font-size: 16px;
+                }
             }
             }
         }
         }
     }
     }
 }
 }
 
 
-@media screen and (max-width: 1024px) {
+@media screen and (max-width: 1080px) {
     #pg-header {
     #pg-header {
         grid-template-columns: 100%;
         grid-template-columns: 100%;
 
 
@@ -104,7 +108,6 @@
                 }
                 }
             }
             }
         }
         }
-
         
         
         .command-bar {  
         .command-bar {  
             display: none;
             display: none;

+ 1 - 1
Playground/src/scss/main.scss

@@ -82,7 +82,7 @@
     }
     }
 }
 }
 
 
-@media screen and (max-width: 1024px) {
+@media screen and (max-width: 1080px) {
     #pg-root {
     #pg-root {
         grid-template-rows: 40px calc(100% - 75px) 35px;
         grid-template-rows: 40px calc(100% - 75px) 35px;
     }
     }

+ 31 - 19
Playground/src/tools/loadManager.ts

@@ -1,22 +1,28 @@
-import { GlobalState } from '../globalState';
-import { Utilities } from './utilities';
+import { GlobalState } from "../globalState";
+import { Utilities } from "./utilities";
 
 
 export class LoadManager {
 export class LoadManager {
     private _previousHash = "";
     private _previousHash = "";
 
 
-    public constructor(public globalState: GlobalState) {  
-        // Check the url to prepopulate data        
+    public constructor(public globalState: GlobalState) {
+        // Check the url to prepopulate data
         this._checkHash();
         this._checkHash();
         window.addEventListener("hashchange", () => this._checkHash());
         window.addEventListener("hashchange", () => this._checkHash());
 
 
-        globalState.onLoadRequiredObservable.add(id => {
+        globalState.onLoadRequiredObservable.add((id) => {
             globalState.onDisplayWaitRingObservable.notifyObservers(true);
             globalState.onDisplayWaitRingObservable.notifyObservers(true);
-            this._loadPlayground(id);
+
+            let prevHash = location.hash;
+            location.hash = id;
+
+            if(location.hash === prevHash){
+                this._loadPlayground(id);
+            }
         });
         });
     }
     }
 
 
     private _cleanHash() {
     private _cleanHash() {
-        var substr = location.hash[1]==='#' ? 2 : 1
+        var substr = location.hash[1] === "#" ? 2 : 1;
         var splits = decodeURIComponent(location.hash.substr(substr)).split("#");
         var splits = decodeURIComponent(location.hash.substr(substr)).split("#");
 
 
         if (splits.length > 2) {
         if (splits.length > 2) {
@@ -24,14 +30,14 @@ export class LoadManager {
         }
         }
 
 
         location.hash = splits.join("#");
         location.hash = splits.join("#");
-    };
+    }
 
 
     private _checkHash() {
     private _checkHash() {
         let pgHash = "";
         let pgHash = "";
-        if (location.search && (!location.pathname  || location.pathname === '/') && !location.hash) {
+        if (location.search && (!location.pathname || location.pathname === "/") && !location.hash) {
             var query = Utilities.ParseQuery();
             var query = Utilities.ParseQuery();
             if (query.pg) {
             if (query.pg) {
-                pgHash = "#" + query.pg + "#" + (query.revision || "0")
+                pgHash = "#" + query.pg + "#" + (query.revision || "0");
             }
             }
         } else if (location.hash) {
         } else if (location.hash) {
             if (this._previousHash !== location.hash) {
             if (this._previousHash !== location.hash) {
@@ -52,27 +58,27 @@ export class LoadManager {
         if (pgHash) {
         if (pgHash) {
             var match = pgHash.match(/^(#[A-Za-z\d]*)(%23)([\d]+)$/);
             var match = pgHash.match(/^(#[A-Za-z\d]*)(%23)([\d]+)$/);
             if (match) {
             if (match) {
-                pgHash = match[1] + '#' + match[3];
+                pgHash = match[1] + "#" + match[3];
                 parent.location.hash = pgHash;
                 parent.location.hash = pgHash;
             }
             }
             this._previousHash = pgHash;
             this._previousHash = pgHash;
             this._loadPlayground(pgHash.substr(1));
             this._loadPlayground(pgHash.substr(1));
-        }        
+        }
     }
     }
 
 
-    private _loadPlayground(id: string) {        
+    private _loadPlayground(id: string) {
         this.globalState.loadingCodeInProgress = true;
         this.globalState.loadingCodeInProgress = true;
         try {
         try {
             var xmlHttp = new XMLHttpRequest();
             var xmlHttp = new XMLHttpRequest();
             xmlHttp.onreadystatechange = () => {
             xmlHttp.onreadystatechange = () => {
                 if (xmlHttp.readyState === 4) {
                 if (xmlHttp.readyState === 4) {
                     if (xmlHttp.status === 200) {
                     if (xmlHttp.status === 200) {
-
                         if (xmlHttp.responseText.indexOf("class Playground") !== -1) {
                         if (xmlHttp.responseText.indexOf("class Playground") !== -1) {
                             if (this.globalState.language === "JS") {
                             if (this.globalState.language === "JS") {
                                 Utilities.SwitchLanguage("TS", this.globalState);
                                 Utilities.SwitchLanguage("TS", this.globalState);
                             }
                             }
-                        } else { // If we're loading JS content and it's TS page
+                        } else {
+                            // If we're loading JS content and it's TS page
                             if (this.globalState.language === "TS") {
                             if (this.globalState.language === "TS") {
                                 Utilities.SwitchLanguage("JS", this.globalState);
                                 Utilities.SwitchLanguage("JS", this.globalState);
                             }
                             }
@@ -100,20 +106,26 @@ export class LoadManager {
                         }
                         }
 
 
                         this.globalState.onCodeLoaded.notifyObservers(JSON.parse(snippet.jsonPayload).code.toString());
                         this.globalState.onCodeLoaded.notifyObservers(JSON.parse(snippet.jsonPayload).code.toString());
-                         
+
                         this.globalState.onMetadataUpdatedObservable.notifyObservers();
                         this.globalState.onMetadataUpdatedObservable.notifyObservers();
                     }
                     }
                 }
                 }
+            };
+
+            if (id[0] === "#") {
+                id = id.substr(1);
             }
             }
 
 
             this.globalState.currentSnippetToken = id.split("#")[0];
             this.globalState.currentSnippetToken = id.split("#")[0];
-            if (!id.split("#")[1]) id += "#0";
+            if (!id.split("#")[1]) {
+                id += "#0";
+            }
 
 
-            xmlHttp.open("GET", this.globalState.SnippetServerUrl + "/" + id.replace("#", "/"));
+            xmlHttp.open("GET", this.globalState.SnippetServerUrl + "/" + id.replace(/#/g, "/"));
             xmlHttp.send();
             xmlHttp.send();
         } catch (e) {
         } catch (e) {
             this.globalState.loadingCodeInProgress = false;
             this.globalState.loadingCodeInProgress = false;
             this.globalState.onCodeLoaded.notifyObservers("");
             this.globalState.onCodeLoaded.notifyObservers("");
         }
         }
     }
     }
-}
+}

+ 66 - 24
Playground/src/tools/monacoManager.ts

@@ -120,18 +120,49 @@ export class MonacoManager {
 
 
     private _setNewContent() {
     private _setNewContent() {
         this._createEditor();
         this._createEditor();
-        this._editor?.setValue(`// You have to create a function called createScene. This function must return a BABYLON.Scene object
-    // You can reference the following variables: scene, canvas
-    // You must at least define a camera
 
 
-    var createScene = function() {
+        this.globalState.currentSnippetToken = "";
+
+        if (this.globalState.language === "JS") {
+            this._editor?.setValue(`// You have to create a function called createScene. This function must return a BABYLON.Scene object
+// You can reference the following variables: engine, canvas
+// You must at least define a camera
+
+var createScene = function() {
+    var scene = new BABYLON.Scene(engine);
+
+    //var camera = new BABYLON.ArcRotateCamera("Camera", -Math.PI / 2, Math.PI / 2, 12, BABYLON.Vector3.Zero(), scene);
+    var camera = new BABYLON.FreeCamera("camera1", new BABYLON.Vector3(0, 5, -10), scene);
+
+    // This targets the camera to scene origin
+    camera.setTarget(BABYLON.Vector3.Zero());
+
+    // This attaches the camera to the canvas
+    camera.attachControl(canvas, true);
+
+    return scene;
+};`);
+        } else {
+            this._editor?.setValue(`// You have to create a class called Playground. This class must provide a static function named CreateScene(engine, canvas) which must return a Scene object
+// You must at least define a camera inside the CreateScene function
+
+class Playground {
+    public static CreateScene(engine: BABYLON.Engine, canvas: HTMLCanvasElement): BABYLON.Scene {
         var scene = new BABYLON.Scene(engine);
         var scene = new BABYLON.Scene(engine);
-        var camera = new BABYLON.ArcRotateCamera("Camera", -Math.PI / 2, Math.PI / 2, 12, BABYLON.Vector3.Zero(), scene);
+
+        //var camera = new BABYLON.ArcRotateCamera("Camera", -Math.PI / 2, Math.PI / 2, 12, BABYLON.Vector3.Zero(), scene);
+        var camera = new BABYLON.FreeCamera("camera1", new BABYLON.Vector3(0, 5, -10), scene);
+
+        // This targets the camera to scene origin
+        camera.setTarget(BABYLON.Vector3.Zero());
+
+        // This attaches the camera to the canvas
         camera.attachControl(canvas, true);
         camera.attachControl(canvas, true);
 
 
         return scene;
         return scene;
-    };
-        `);
+    }
+}`);
+        }
 
 
         this.globalState.onRunRequiredObservable.notifyObservers();
         this.globalState.onRunRequiredObservable.notifyObservers();
 
 
@@ -190,26 +221,39 @@ export class MonacoManager {
     public async setupMonacoAsync(hostElement: HTMLDivElement, initialCall = false) {
     public async setupMonacoAsync(hostElement: HTMLDivElement, initialCall = false) {
         this._hostElement = hostElement;
         this._hostElement = hostElement;
 
 
-        let response = await fetch("https://preview.babylonjs.com/babylon.d.ts");
-        if (!response.ok) {
-            return;
+        const declarations = [
+            "https://preview.babylonjs.com/babylon.d.ts",
+            "https://preview.babylonjs.com/gui/babylon.gui.d.ts",
+            "https://preview.babylonjs.com/glTF2Interface/babylon.glTF2Interface.d.ts",
+            "https://preview.babylonjs.com/loaders/babylonjs.loaders.d.ts",
+            "https://preview.babylonjs.com/materialsLibrary/babylonjs.materials.d.ts",
+            "https://preview.babylonjs.com/nodeEditor/babylon.nodeEditor.d.ts",
+            "https://preview.babylonjs.com/postProcessesLibrary/babylonjs.postProcess.d.ts",
+            "https://preview.babylonjs.com/proceduralTexturesLibrary/babylonjs.proceduralTextures.d.ts",
+            "https://preview.babylonjs.com/serializers/babylonjs.serializers.d.ts",
+            "https://preview.babylonjs.com/inspector/babylon.inspector.d.ts",
+        ];
+
+        // Check for Unity Toolkit
+        if (location.href.indexOf("UnityToolkit") !== -1 || Utilities.ReadBoolFromStore("unity-toolkit", false)) {
+            declarations.push("https://playground.babylonjs.com/libs/babylon.manager.d.ts");
         }
         }
 
 
-        let libContent = await response.text();
+        let libContent = "";
+        const responses = await Promise.all(declarations.map((declaration) => fetch(declaration)));
+        for (const response of responses) {
+            if (!response.ok) {
+                return;
+            }
 
 
-        response = await fetch("https://preview.babylonjs.com/gui/babylon.gui.d.ts");
-        if (!response.ok) {
-            return;
+            libContent += await response.text();
         }
         }
 
 
-        libContent += await response.text();
-
         this._createEditor();
         this._createEditor();
 
 
         // Definition worker
         // Definition worker
         this._setupDefinitionWorker(libContent);
         this._setupDefinitionWorker(libContent);
 
 
-
         // Setup the Monaco compilation pipeline, so we can reuse it directly for our scrpting needs
         // Setup the Monaco compilation pipeline, so we can reuse it directly for our scrpting needs
         this._setupMonacoCompilationPipeline(libContent);
         this._setupMonacoCompilationPipeline(libContent);
 
 
@@ -218,21 +262,20 @@ export class MonacoManager {
 
 
         if (initialCall) {
         if (initialCall) {
             // Load code templates
             // Load code templates
-            response = await fetch("templates.json");
+            const response = await fetch("templates.json");
             if (response.ok) {
             if (response.ok) {
                 this._templates = await response.json();
                 this._templates = await response.json();
-            }        
-            
+            }
+
             // enhance templates with extra properties
             // enhance templates with extra properties
             for (const template of this._templates) {
             for (const template of this._templates) {
                 (template.kind = monaco.languages.CompletionItemKind.Snippet), (template.sortText = "!" + template.label); // make sure templates are on top of the completion window
                 (template.kind = monaco.languages.CompletionItemKind.Snippet), (template.sortText = "!" + template.label); // make sure templates are on top of the completion window
                 template.insertTextRules = monaco.languages.CompletionItemInsertTextRule.InsertAsSnippet;
                 template.insertTextRules = monaco.languages.CompletionItemInsertTextRule.InsertAsSnippet;
-            }       
-            
+            }
+
             this._hookMonacoCompletionProvider();
             this._hookMonacoCompletionProvider();
         }
         }
 
 
-
         if (!this.globalState.loadingCodeInProgress) {
         if (!this.globalState.loadingCodeInProgress) {
             this._setDefaultContent();
             this._setDefaultContent();
         }
         }
@@ -269,7 +312,6 @@ export class MonacoManager {
     var ground = BABYLON.MeshBuilder.CreateGround("ground", {width: 6, height: 6}, scene);
     var ground = BABYLON.MeshBuilder.CreateGround("ground", {width: 6, height: 6}, scene);
 
 
     return scene;
     return scene;
-
 };`);
 };`);
         } else {
         } else {
             this._editor.setValue(`class Playground {
             this._editor.setValue(`class Playground {

+ 12 - 0
Playground/templates.json

@@ -78,5 +78,17 @@
     "label" : "Setup a shadow generator",
     "label" : "Setup a shadow generator",
     "documentation" : "https://doc.babylonjs.com/babylon101/shadows",
     "documentation" : "https://doc.babylonjs.com/babylon101/shadows",
     "insertText" : "var shadowGenerator = new BABYLON.ShadowGenerator(${1:size}, ${2:the_light_source});\nshadowGenerator.getShadowMap().renderList.push(${3:the_mesh_that_casts_a_shadow});\n${4:mesh_that_receives_the_shadow}.receiveShadows = true;"    
     "insertText" : "var shadowGenerator = new BABYLON.ShadowGenerator(${1:size}, ${2:the_light_source});\nshadowGenerator.getShadowMap().renderList.push(${3:the_mesh_that_casts_a_shadow});\n${4:mesh_that_receives_the_shadow}.receiveShadows = true;"    
+  },
+  {
+    "label" : "Export scene to GLB",
+    "documentation" : "https://doc.babylonjs.com/extensions/gltfexporter#exporting-a-scene-to-gltf",
+    "insertText" : "BABYLON.GLTF2Export.GLBAsync(scene, \"${1:fileName}\").then((glb) => {\n     glb.downloadFiles();\n});",
+    "language" : "javascript"
+  },
+  {
+    "label" : "Export scene to GLTF",
+    "documentation" : "https://doc.babylonjs.com/extensions/gltfexporter#exporting-a-scene-to-gltf",
+    "insertText" : "BABYLON.GLTF2Export.GLTFAsync(scene, \"${1:fileName}\").then((gltf) => {\n     gltf.downloadFiles();\n});",
+    "language" : "javascript"
   }
   }
 ]
 ]

BIN
Playground/textures/ktx2/sample_etc1s.ktx2


BIN
Playground/textures/ktx2/sample_uastc.ktx2


BIN
Playground/textures/ktx2/sample_uastc_zcmp.ktx2


BIN
Playground/textures/ktx2/testalpha_etc1s.ktx2


BIN
Playground/textures/ktx2/testalpha_uastc.ktx2


BIN
Playground/textures/ktx2/testalpha_uastc_zcmp.ktx2


BIN
Playground/textures/ktx2/testmipmapcustom_etc1s.ktx2


BIN
Playground/textures/ktx2/testmipmapcustom_uastc.ktx2


BIN
Playground/textures/ktx2/testmipmapcustom_uastc_zcmp.ktx2


+ 2 - 3
Playground/zipContent/index.html

@@ -11,16 +11,15 @@
         <script src="https://preview.babylonjs.com/ammo.js"></script>
         <script src="https://preview.babylonjs.com/ammo.js"></script>
         <script src="https://preview.babylonjs.com/cannon.js"></script>
         <script src="https://preview.babylonjs.com/cannon.js"></script>
         <script src="https://preview.babylonjs.com/Oimo.js"></script>
         <script src="https://preview.babylonjs.com/Oimo.js"></script>
-        <script src="https://preview.babylonjs.com/libktx.js"></script>
         <script src="https://preview.babylonjs.com/earcut.min.js"></script>
         <script src="https://preview.babylonjs.com/earcut.min.js"></script>
         <script src="https://preview.babylonjs.com/babylon.js"></script>
         <script src="https://preview.babylonjs.com/babylon.js"></script>
-        <script src="https://preview.babylonjs.com/inspector/babylon.inspector.bundle.js"></script>
         <script src="https://preview.babylonjs.com/materialsLibrary/babylonjs.materials.min.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/proceduralTexturesLibrary/babylonjs.proceduralTextures.min.js"></script>
         <script src="https://preview.babylonjs.com/postProcessesLibrary/babylonjs.postProcess.min.js"></script>
         <script src="https://preview.babylonjs.com/postProcessesLibrary/babylonjs.postProcess.min.js"></script>
         <script src="https://preview.babylonjs.com/loaders/babylonjs.loaders.js"></script>
         <script src="https://preview.babylonjs.com/loaders/babylonjs.loaders.js"></script>
         <script src="https://preview.babylonjs.com/serializers/babylonjs.serializers.min.js"></script>
         <script src="https://preview.babylonjs.com/serializers/babylonjs.serializers.min.js"></script>
         <script src="https://preview.babylonjs.com/gui/babylon.gui.min.js"></script>
         <script src="https://preview.babylonjs.com/gui/babylon.gui.min.js"></script>
+        <script src="https://preview.babylonjs.com/inspector/babylon.inspector.bundle.js"></script>
 
 
         <style>
         <style>
             html, body {
             html, body {
@@ -46,7 +45,7 @@
 ####INJECT####
 ####INJECT####
 
 
         engine.runRenderLoop(function () {
         engine.runRenderLoop(function () {
-            if (sceneToRender) {
+            if (sceneToRender && sceneToRender.activeCamera) {
                 sceneToRender.render();
                 sceneToRender.render();
             }
             }
         });
         });

+ 11 - 2
Tools/Config/config.js

@@ -23,6 +23,10 @@ const tempTypingsFilePath = path.join(tempFolder, tempTypingsFileName);
 
 
 const tscPath = path.resolve(rootFolder, "node_modules/typescript/bin/tsc");
 const tscPath = path.resolve(rootFolder, "node_modules/typescript/bin/tsc");
 
 
+const sharedUiComponentsFilesGlob = config.build.sharedUiComponentsSrc + "/**/*";
+const sharedUiComponentsSrcPath = path.join(rootFolder, config.build.sharedUiComponentsSrc);
+const es6SharedUiComponentsSrcPath = path.join(sourceES6Folder, config.build.sharedUiComponentsSrc);
+
 config.computed = {
 config.computed = {
     rootFolder,
     rootFolder,
     tempFolder,
     tempFolder,
@@ -39,7 +43,10 @@ config.computed = {
     tempTypingsFileName,
     tempTypingsFileName,
     tempTypingsAMDFilePath,
     tempTypingsAMDFilePath,
     tempTypingsFilePath,
     tempTypingsFilePath,
-    tscPath
+    tscPath,
+    sharedUiComponentsFilesGlob,
+    sharedUiComponentsSrcPath,
+    es6SharedUiComponentsSrcPath,
 }
 }
 
 
 config.additionalNpmPackages.forEach(package => {
 config.additionalNpmPackages.forEach(package => {
@@ -77,6 +84,7 @@ allModules.map(function(module) {
     const distDirectory = path.join(outputFolder, distFolder);
     const distDirectory = path.join(outputFolder, distFolder);
     const localDevES6Directory = path.join(localDevES6Folder, module);
     const localDevES6Directory = path.join(localDevES6Folder, module);
     const localDevUMDDirectory = path.join(localDevUMDFolder, distFolder);
     const localDevUMDDirectory = path.join(localDevUMDFolder, distFolder);
+    const localDevAppDirectory = path.join(localDevUMDFolder, module);
     const packageUMDDirectory = path.join(packageUMDFolder, module);
     const packageUMDDirectory = path.join(packageUMDFolder, module);
     const packageUMDDevDirectory = path.join(packageUMDDevFolder, module);
     const packageUMDDevDirectory = path.join(packageUMDDevFolder, module);
     const sourceES6Directory = path.join(sourceES6Folder, module);
     const sourceES6Directory = path.join(sourceES6Folder, module);
@@ -89,12 +97,13 @@ allModules.map(function(module) {
     const packageJSONPath = settings.build.packageJSON ? 
     const packageJSONPath = settings.build.packageJSON ? 
         path.join(rootFolder, settings.build.packageJSON) : 
         path.join(rootFolder, settings.build.packageJSON) : 
         path.join(distDirectory, 'package.json');
         path.join(distDirectory, 'package.json');
-
+    
     settings.computed = {
     settings.computed = {
         mainDirectory,
         mainDirectory,
         distDirectory,
         distDirectory,
         localDevES6Directory,
         localDevES6Directory,
         localDevUMDDirectory,
         localDevUMDDirectory,
+        localDevAppDirectory,
         packageUMDDirectory,
         packageUMDDirectory,
         packageUMDDevDirectory,
         packageUMDDevDirectory,
         sourceES6Directory,
         sourceES6Directory,

+ 30 - 9
Tools/Config/config.json

@@ -36,7 +36,8 @@
             "BABYLON"
             "BABYLON"
         ],
         ],
         "typedocJSON": "../../.temp/babylon.typedoc.json",
         "typedocJSON": "../../.temp/babylon.typedoc.json",
-        "typedocValidationBaseline": "../../dist/preview release/typedocValidationBaseline.json"
+        "typedocValidationBaseline": "../../dist/preview release/typedocValidationBaseline.json",
+        "sharedUiComponentsSrc": "sharedUiComponents"
     },
     },
     "modules": [
     "modules": [
         "core",
         "core",
@@ -63,7 +64,8 @@
     ],
     ],
     "apps": [
     "apps": [
         "playground",
         "playground",
-        "sandbox"
+        "sandbox",
+        "ktx2Decoder"
     ],
     ],
     "lintModules": [
     "lintModules": [
         "core",
         "core",
@@ -147,7 +149,8 @@
             "es6": {
             "es6": {
                 "packageName": "@babylonjs/core",
                 "packageName": "@babylonjs/core",
                 "readme": "readme-es6.md",
                 "readme": "readme-es6.md",
-                "license": "license.md"
+                "license": "license.md",
+                "type": "module"
             }
             }
         }
         }
     },
     },
@@ -249,7 +252,8 @@
             },
             },
             "es6": {
             "es6": {
                 "packageName": "@babylonjs/materials",
                 "packageName": "@babylonjs/materials",
-                "readme": "dist/preview release/materialsLibrary/readme-es6.md"
+                "readme": "dist/preview release/materialsLibrary/readme-es6.md",
+                "type": "module"
             }
             }
         }
         }
     },
     },
@@ -286,7 +290,8 @@
             },
             },
             "es6": {
             "es6": {
                 "packageName": "@babylonjs/post-processes",
                 "packageName": "@babylonjs/post-processes",
-                "readme": "dist/preview release/postProcessesLibrary/readme-es6.md"
+                "readme": "dist/preview release/postProcessesLibrary/readme-es6.md",
+                "type": "module"
             }
             }
         }
         }
     },
     },
@@ -363,7 +368,8 @@
             },
             },
             "es6": {
             "es6": {
                 "packageName": "@babylonjs/procedural-textures",
                 "packageName": "@babylonjs/procedural-textures",
-                "readme": "dist/preview release/proceduralTexturesLibrary/readme-es6.md"
+                "readme": "dist/preview release/proceduralTexturesLibrary/readme-es6.md",
+                "type": "module"
             }
             }
         }
         }
     },
     },
@@ -434,7 +440,8 @@
             },
             },
             "es6": {
             "es6": {
                 "packageName": "@babylonjs/loaders",
                 "packageName": "@babylonjs/loaders",
-                "readme": "dist/preview release/loaders/readme-es6.md"
+                "readme": "dist/preview release/loaders/readme-es6.md",
+                "type": "module"
             }
             }
         }
         }
     },
     },
@@ -492,7 +499,8 @@
             },
             },
             "es6": {
             "es6": {
                 "packageName": "@babylonjs/serializers",
                 "packageName": "@babylonjs/serializers",
-                "readme": "dist/preview release/serializers/readme-es6.md"
+                "readme": "dist/preview release/serializers/readme-es6.md",
+                "type": "module"
             }
             }
         }
         }
     },
     },
@@ -521,7 +529,8 @@
             },
             },
             "es6": {
             "es6": {
                 "packageName": "@babylonjs/gui",
                 "packageName": "@babylonjs/gui",
-                "readme": "dist/preview release/gui/readme-es6.md"
+                "readme": "dist/preview release/gui/readme-es6.md",
+                "type": "module"
             }
             }
         }
         }
     },
     },
@@ -542,6 +551,7 @@
                 "re-resizable",
                 "re-resizable",
                 "glTF"
                 "glTF"
             ],
             ],
+            "sharedUiComponents": "src/sharedUiComponents/",
             "umd": {
             "umd": {
                 "packageName": "babylonjs-inspector",
                 "packageName": "babylonjs-inspector",
                 "webpackRoot": "INSPECTOR",
                 "webpackRoot": "INSPECTOR",
@@ -605,6 +615,7 @@
                 "glTF",
                 "glTF",
                 "file-saver"
                 "file-saver"
             ],
             ],
+            "sharedUiComponents": "src/sharedUiComponents/",
             "umd": {
             "umd": {
                 "packageName": "babylonjs-node-editor",
                 "packageName": "babylonjs-node-editor",
                 "webpackRoot": "NODEEDITOR",
                 "webpackRoot": "NODEEDITOR",
@@ -640,6 +651,16 @@
             }
             }
         }
         }
     },
     },
+    "ktx2Decoder": {
+        "tempFileName": "babylon.ktx2Decoder.js",
+        "distFile": "/dist/preview release/babylon.ktx2Decoder.js",
+        "build": {
+            "ignoreInWorkerMode": true,
+            "ignoreInTestMode": true,
+            "distOutputDirectory": "../../dist/preview release/",
+            "mainFolder": "./ktx2Decoder/"
+        }
+    },
     "playground": {
     "playground": {
         "distFile": "/Playground/dist/babylon.playground.js",
         "distFile": "/Playground/dist/babylon.playground.js",
         "build": {
         "build": {

+ 26 - 3
Tools/DevLoader/BabylonLoader.js

@@ -40,6 +40,8 @@ var BABYLONDEVTOOLS;
         var min;
         var min;
         var babylonJSPath;
         var babylonJSPath;
 
 
+        var coreOnly;
+
         var localDevES6FolderName;
         var localDevES6FolderName;
         var localDevUMDFolderName;
         var localDevUMDFolderName;
 
 
@@ -57,6 +59,7 @@ var BABYLONDEVTOOLS;
                 workerMode = true;
                 workerMode = true;
             }
             }
             babylonJSPath = '';
             babylonJSPath = '';
+            coreOnly = false;
         }
         }
 
 
         Loader.prototype.debugShortcut = function(engine) {
         Loader.prototype.debugShortcut = function(engine) {
@@ -221,7 +224,7 @@ var BABYLONDEVTOOLS;
         }
         }
 
 
         Loader.prototype.loadCoreDev = function() {
         Loader.prototype.loadCoreDev = function() {
-            if (typeof document === "undefined" || isIE) {                
+            if (typeof document === "undefined" || isIE) {
                 this.loadScript(babylonJSPath + "/dist/preview release/babylon.max.js");
                 this.loadScript(babylonJSPath + "/dist/preview release/babylon.max.js");
                 return;
                 return;
             }
             }
@@ -234,7 +237,14 @@ var BABYLONDEVTOOLS;
                 if (!useDist && module.isCore) {
                 if (!useDist && module.isCore) {
                     this.loadCoreDev();
                     this.loadCoreDev();
                 }
                 }
-                else {
+                else if (!coreOnly || module.isCore) {
+                    this.loadLibrary(moduleName, module.libraries[i], module);
+                }
+                // Allow also loaders in CORE.
+                else if (coreOnly && (moduleName === "loaders" ||
+                    moduleName === "inspector" ||
+                    moduleName === "nodeEditor" ||
+                    moduleName === "materialsLibrary")) {
                     this.loadLibrary(moduleName, module.libraries[i], module);
                     this.loadLibrary(moduleName, module.libraries[i], module);
                 }
                 }
             }
             }
@@ -244,7 +254,14 @@ var BABYLONDEVTOOLS;
             if (!window || !window.location || window.location.pathname.toLowerCase().indexOf(appName.toLowerCase()) === -1) {
             if (!window || !window.location || window.location.pathname.toLowerCase().indexOf(appName.toLowerCase()) === -1) {
                 return;
                 return;
             }
             }
-            this.loadScript(app.distFile);
+
+            if (!useDist && app.tempFileName) {
+                var tempDirectory = '/.temp/' + localDevUMDFolderName + appName + "/";
+                this.loadScript(tempDirectory + app.tempFileName);
+            }
+            else {
+                this.loadScript(app.distFile);
+            }
         }
         }
 
 
         Loader.prototype.processDependency = function(settings, dependency, filesToLoad) {
         Loader.prototype.processDependency = function(settings, dependency, filesToLoad) {
@@ -275,6 +292,11 @@ var BABYLONDEVTOOLS;
             }
             }
         }
         }
 
 
+        Loader.prototype.loadCoreOnly = function() {
+            coreOnly = true;
+            return this;
+        }
+
         Loader.prototype.load = function(newCallback) {
         Loader.prototype.load = function(newCallback) {
             var self = this;
             var self = this;
             if (newCallback) {
             if (newCallback) {
@@ -286,6 +308,7 @@ var BABYLONDEVTOOLS;
                     localDevUMDFolderName = data.build.localDevUMDFolderName;
                     localDevUMDFolderName = data.build.localDevUMDFolderName;
 
 
                     self.loadBJSScripts(data);
                     self.loadBJSScripts(data);
+
                     if (dependencies) {
                     if (dependencies) {
                         self.loadScripts(dependencies);
                         self.loadScripts(dependencies);
                     }
                     }

+ 7 - 6
Tools/Gulp/gulpfile.js

@@ -21,6 +21,7 @@ require("./tasks/gulpTasks-remapPaths");
 require("./tasks/gulpTasks-npmPackages");
 require("./tasks/gulpTasks-npmPackages");
 require("./tasks/gulpTasks-dependencies");
 require("./tasks/gulpTasks-dependencies");
 require("./tasks/gulpTasks-testsES6");
 require("./tasks/gulpTasks-testsES6");
+require("./tasks/gulpTasks-symlink");
 
 
 /**
 /**
  * Temp cleanup after upgrade.
  * Temp cleanup after upgrade.
@@ -52,27 +53,27 @@ gulp.task("cleanup", function(cb) {
 /**
 /**
  * Full TsLint.
  * Full TsLint.
  */
  */
-gulp.task("tsLint", gulp.series("typescript-libraries-tsLint"));
+gulp.task("tsLint", gulp.series("generate-symlinks", "typescript-libraries-tsLint"));
 
 
 /**
 /**
  * Full ImportLint.
  * Full ImportLint.
  */
  */
-gulp.task("importLint", gulp.series("typescript-libraries-importLint"));
+gulp.task("importLint", gulp.series("generate-symlinks", "typescript-libraries-importLint"));
 
 
 /**
 /**
  * Full Lint.
  * Full Lint.
  */
  */
-gulp.task("fullLint", gulp.series("tsLint", "importLint", "circularDependencies"));
+gulp.task("fullLint", gulp.series("generate-symlinks", "tsLint", "importLint", "circularDependencies"));
 
 
 /**
 /**
  * Validate compile the code and check the comments and style case convention through typedoc
  * Validate compile the code and check the comments and style case convention through typedoc
  */
  */
-gulp.task("typedoc-check", gulp.series("core", "gui", "loaders", "serializers", "typedoc-generate", "typedoc-validate"));
+gulp.task("typedoc-check", gulp.series("generate-symlinks", "core", "gui", "loaders", "serializers", "typedoc-generate", "typedoc-validate"));
 
 
 /**
 /**
  * Combine Webserver and Watch as long as vscode does not handle multi tasks.
  * Combine Webserver and Watch as long as vscode does not handle multi tasks.
  */
  */
-gulp.task("run", gulp.series("cleanup", "watchCore", "watchLibraries", "watchApps", "webserver"));
+gulp.task("run", gulp.series("generate-symlinks", "cleanup", "watchCore", "watchLibraries", "watchApps", "webserver"));
 
 
 /**
 /**
  * Do it all (Build).
  * Do it all (Build).
@@ -82,7 +83,7 @@ gulp.task("typescript-all", gulp.series("typescript-libraries", "typescript-es6"
 /**
 /**
  * Do it all (tests).
  * Do it all (tests).
  */
  */
-gulp.task("tests-all", gulp.series("tests-unit", "tests-modules", "deployAndTests-es6Modules", "tests-validation-virtualscreen", "tests-validation-browserstack"));
+gulp.task("tests-all", gulp.series("generate-symlinks", "tests-unit", "tests-modules", "deployAndTests-es6Modules", "tests-validation-virtualscreen", "tests-validation-browserstack"));
 
 
 /**
 /**
  * Get Ready to test Npm Packages.
  * Get Ready to test Npm Packages.

+ 6 - 2
Tools/Gulp/helpers/gulp-processConstants.js

@@ -33,9 +33,13 @@ function processConstants(sourceCode) {
     }
     }
 
 
     for (var constant of constantList) {
     for (var constant of constantList) {
-        var value = babylonConstants[constant];
         var regex = new RegExp(`(?<![_0-9a-zA-Z])Constants\.${constant}(?![_0-9a-zA-Z])`, "g");
         var regex = new RegExp(`(?<![_0-9a-zA-Z])Constants\.${constant}(?![_0-9a-zA-Z])`, "g");
-        sourceCode = sourceCode.replace(regex, value);
+        var value = babylonConstants[constant];
+        if (typeof(value) === "string") {
+            sourceCode = sourceCode.replace(regex, "`" + value + "`");
+        } else  {
+            sourceCode = sourceCode.replace(regex, value);
+        }
     }
     }
 
 
     return sourceCode;
     return sourceCode;

+ 21 - 2
Tools/Gulp/tasks/gulpTasks-libraries.js

@@ -6,6 +6,7 @@ var cp = require('child_process');
 var path = require("path");
 var path = require("path");
 var concat = require('gulp-concat');
 var concat = require('gulp-concat');
 var minimist = require("minimist");
 var minimist = require("minimist");
+var symlinkDir = require('symlink-dir');
 
 
 // Gulp Helpers
 // Gulp Helpers
 var uncommentShaders = require('../helpers/gulp-removeShaderComments');
 var uncommentShaders = require('../helpers/gulp-removeShaderComments');
@@ -164,12 +165,30 @@ var processDTSFiles = function(libraries, settings, cb) {
 }
 }
 
 
 /**
 /**
+ * Generate our required symlinked for the shared components.
+ */
+var generateSharedUiComponents = function(settings, done) {
+    if (!settings.build.sharedUiComponents) {
+        done();
+        return;
+    }
+
+    var sharedUiComponents = config.computed.sharedUiComponentsSrcPath;
+    var umdSharedUiComponents = path.resolve(settings.computed.mainDirectory, settings.build.sharedUiComponents);
+
+    symlinkDir(sharedUiComponents, umdSharedUiComponents).then(() => {
+        done();
+    });
+};
+
+/**
  * Dynamic module creation In Serie for WebPack leaks.
  * Dynamic module creation In Serie for WebPack leaks.
  */
  */
 function buildExternalLibraries(settings, fast) {
 function buildExternalLibraries(settings, fast) {
     // Creates the required tasks.
     // Creates the required tasks.
     var tasks = [];
     var tasks = [];
 
 
+    var sharedUiComponents = function(cb) { return generateSharedUiComponents(settings, cb); };
     var cleanup = function() { return cleanShaders(settings); };
     var cleanup = function() { return cleanShaders(settings); };
     var shaders = function() { return buildShaders(settings); };
     var shaders = function() { return buildShaders(settings); };
     var buildMin = function() { return buildExternalLibrariesMultiEntry(settings.libraries, settings, true) };
     var buildMin = function() { return buildExternalLibrariesMultiEntry(settings.libraries, settings, true) };
@@ -183,9 +202,9 @@ function buildExternalLibraries(settings, fast) {
     }
     }
 
 
     if (fast) {
     if (fast) {
-        tasks.push(buildMax);
+        tasks.push(sharedUiComponents, buildMax);
     } else {
     } else {
-        tasks.push(cleanup, shaders, buildMin, buildMax, buildAMDDTS, processDTS, ...appendLoseDTS);
+        tasks.push(sharedUiComponents, cleanup, shaders, buildMin, buildMax, buildAMDDTS, processDTS, ...appendLoseDTS);
     }
     }
 
 
     return gulp.series.apply(this, tasks);
     return gulp.series.apply(this, tasks);

+ 25 - 1
Tools/Gulp/tasks/gulpTasks-librariesES6.js

@@ -4,6 +4,7 @@ var path = require("path");
 var fs = require("fs-extra");
 var fs = require("fs-extra");
 var shelljs = require("shelljs");
 var shelljs = require("shelljs");
 var concat = require('gulp-concat');
 var concat = require('gulp-concat');
+var symlinkDir = require('symlink-dir');
 
 
 // Gulp Helpers
 // Gulp Helpers
 var rmDir = require("../../NodeHelpers/rmDir");
 var rmDir = require("../../NodeHelpers/rmDir");
@@ -78,6 +79,11 @@ var dep = function(settings) {
             const dependencyPath = path.join(config.computed.rootFolder, pathName);
             const dependencyPath = path.join(config.computed.rootFolder, pathName);
             copyPaths.push(dependencyPath);
             copyPaths.push(dependencyPath);
         }
         }
+
+        if (settings.build.sharedUiComponents) {
+            const dependencyPath = path.join(config.computed.rootFolder, config.computed.sharedUiComponentsFilesGlob);
+            copyPaths.push(dependencyPath);
+        }
     }
     }
 
 
     return gulp.src(copyPaths, { base: config.computed.rootFolder })
     return gulp.src(copyPaths, { base: config.computed.rootFolder })
@@ -265,6 +271,23 @@ var copyWebpackDist = function(settings, module) {
 }
 }
 
 
 /**
 /**
+ * Generate our required symlinked for the shared components.
+ */
+var generateSharedUiComponents = function(settings, done) {
+    if (!settings.build.sharedUiComponents) {
+        done();
+        return;
+    }
+
+    var es6SrcSharedUiComponents = config.computed.es6SharedUiComponentsSrcPath;
+    var es6SharedUiComponents = path.resolve(settings.computed.sourceES6Directory, settings.build.sharedUiComponents);
+
+    symlinkDir(es6SrcSharedUiComponents, es6SharedUiComponents).then(() => {
+        done();
+    });
+};
+
+/**
  * Dynamic es 6 module creation.
  * Dynamic es 6 module creation.
  */
  */
 function buildES6Library(settings, module) {
 function buildES6Library(settings, module) {
@@ -278,6 +301,7 @@ function buildES6Library(settings, module) {
     }
     }
     var copySource = function() { return source(settings); };
     var copySource = function() { return source(settings); };
     var dependencies = function() { return dep(settings); };
     var dependencies = function() { return dep(settings); };
+    var sharedUiComponents = function(cb) { return generateSharedUiComponents(settings, cb); };
     var adaptSourceImportPaths = function() { return modifySourcesImports(settings); };
     var adaptSourceImportPaths = function() { return modifySourcesImports(settings); };
     var adaptSourceConstants = function() { return modifySourcesConstants(settings); };
     var adaptSourceConstants = function() { return modifySourcesConstants(settings); };
     var adaptTsConfigImportPaths = function(cb) { return modifyTsConfig(settings, cb); };
     var adaptTsConfigImportPaths = function(cb) { return modifyTsConfig(settings, cb); };
@@ -298,7 +322,7 @@ function buildES6Library(settings, module) {
         ];
         ];
     }
     }
 
 
-    tasks.push(...cleanAndShaderTasks, copySource, dependencies, adaptSourceImportPaths, adaptSourceConstants, adaptTsConfigImportPaths, ...buildSteps);
+    tasks.push(...cleanAndShaderTasks, copySource, dependencies, sharedUiComponents, adaptSourceImportPaths, adaptSourceConstants, adaptTsConfigImportPaths, ...buildSteps);
 
 
     return gulp.series.apply(this, tasks);
     return gulp.series.apply(this, tasks);
 }
 }

+ 5 - 0
Tools/Gulp/tasks/gulpTasks-localRun.js

@@ -43,6 +43,11 @@ gulp.task("webserver", function () {
                             req.url = "/Playground/" + req.url.replace(/localDev/ig, "");
                             req.url = "/Playground/" + req.url.replace(/localDev/ig, "");
                         }
                         }
                     }
                     }
+                    if (referer.indexOf('/localdevwebgpu/') !== -1 && referer.indexOf(req.originalUrl) === -1) {
+                        if (!fs.existsSync(rootRelativePath + req.originalUrl)) {
+                            req.url = "/Playground/" + req.url.replace(/localdevwebgpu/ig, "");
+                        }
+                    }
                 }
                 }
 
 
                 const pgMath = req.url.match(/\/Playground\/pg\/(.*)/);
                 const pgMath = req.url.match(/\/Playground\/pg\/(.*)/);

+ 52 - 0
Tools/Gulp/tasks/gulpTasks-symlink.js

@@ -0,0 +1,52 @@
+// Import Dependencies.
+var gulp = require("gulp");
+var symlinkDir = require('symlink-dir')
+var path = require('path')
+
+// Import Build Config
+var config = require("../../Config/config.js");
+
+/**
+ * Generate our required symlinked for the shared components.
+ */
+var generateSharedUiComponents = function(settings, done) {
+    if (!settings.build.sharedUiComponents) {
+        done();
+        return;
+    }
+
+    var sharedUiComponents = config.computed.sharedUiComponentsSrcPath;
+    var umdSharedUiComponents = path.resolve(settings.computed.mainDirectory, settings.build.sharedUiComponents);
+
+    symlinkDir(sharedUiComponents, umdSharedUiComponents).then(() => {
+        done();
+    });
+};
+
+/**
+ * Dynamic build SymLinks.
+ */
+function buildSymLinks(settings) {
+    // Creates the required tasks.
+    var tasks = [];
+
+    var sharedUiComponents = function(cb) { return generateSharedUiComponents(settings, cb); };
+
+    tasks.push(sharedUiComponents);
+
+    return gulp.series.apply(this, tasks);
+}
+
+/**
+ * Dynamic symlinks creation.
+ */
+config.modules.map(function(module) {
+    const settings = config[module];
+    gulp.task(module + "-symlinks", buildSymLinks(settings));
+});
+
+/**
+ * Build all es 6 libs.
+ */
+gulp.task("generate-symlinks", gulp.series(config.modules.map((module) => module + "-symlinks")));
+

+ 1 - 1
Tools/Gulp/tasks/gulpTasks-watchApps.js

@@ -44,7 +44,7 @@ gulp.task("watchApps", function startWatch() {
                 return `${mapPathPrefix}${path.relative(config.computed.rootFolder, info.resourcePath).replace(/\\/g, "/")}`;
                 return `${mapPathPrefix}${path.relative(config.computed.rootFolder, info.resourcePath).replace(/\\/g, "/")}`;
             };
             };
 
 
-            const outputDirectory = settings.distDirectory;
+            const outputDirectory = moduleConfig.tempFileName ? settings.localDevAppDirectory : settings.distDirectory;
             tasks.push(
             tasks.push(
                 webpackStream(wpConfig , webpack)
                 webpackStream(wpConfig , webpack)
                     .pipe(gulp.dest(outputDirectory))
                     .pipe(gulp.dest(outputDirectory))

+ 3 - 0
Tools/Publisher/tasks/processEs6Packages.js

@@ -69,6 +69,9 @@ function processEs6Packages(version) {
         umdPackageJson.module = es6Config.index || "index.js";
         umdPackageJson.module = es6Config.index || "index.js";
         umdPackageJson.esnext = es6Config.index || "index.js";
         umdPackageJson.esnext = es6Config.index || "index.js";
         umdPackageJson.typings = es6Config.typings || "index.d.ts";
         umdPackageJson.typings = es6Config.typings || "index.d.ts";
+        if (es6Config.type) {
+            umdPackageJson.type = es6Config.type;
+        }
 
 
         if (es6Config.packagesFiles) {
         if (es6Config.packagesFiles) {
             umdPackageJson.files = es6Config.packagesFiles;
             umdPackageJson.files = es6Config.packagesFiles;

+ 1 - 1
Viewer/src/configuration/types/extended.ts

@@ -3,7 +3,7 @@ import { Tools } from 'babylonjs/Misc/tools';
 
 
 /**
 /**
  * The viewer's "extended" configuration.
  * The viewer's "extended" configuration.
- * This configuration defines specific obejcts and parameters that we think make any model look good.
+ * This configuration defines specific objects and parameters that we think make any model look good.
  */
  */
 export let extendedConfiguration: ViewerConfiguration = {
 export let extendedConfiguration: ViewerConfiguration = {
     version: "3.2.0",
     version: "3.2.0",

+ 2 - 2
Viewer/src/labs/texture.ts

@@ -220,7 +220,7 @@ export class TextureUtils {
             babylonTexture.gammaSpace = false;
             babylonTexture.gammaSpace = false;
 
 
             let internalTexture = new InternalTexture(scene.getEngine(), InternalTextureSource.CubeRaw);
             let internalTexture = new InternalTexture(scene.getEngine(), InternalTextureSource.CubeRaw);
-            let glTexture = internalTexture._webGLTexture;
+            let glTexture = internalTexture._hardwareTexture?.underlyingResource;
             //babylon properties
             //babylon properties
             internalTexture.isCube = true;
             internalTexture.isCube = true;
             internalTexture.generateMipMaps = false;
             internalTexture.generateMipMaps = false;
@@ -352,7 +352,7 @@ export class TextureUtils {
 
 
         let internalTexture = babylonTexture._texture;
         let internalTexture = babylonTexture._texture;
         if (!internalTexture) { return; }
         if (!internalTexture) { return; }
-        let glTexture = internalTexture._webGLTexture;
+        let glTexture = internalTexture._hardwareTexture?.underlyingResource;
         gl.bindTexture(target, glTexture);
         gl.bindTexture(target, glTexture);
 
 
         if (parameters.magFilter != null) { gl.texParameteri(target, gl.TEXTURE_MAG_FILTER, parameters.magFilter); }
         if (parameters.magFilter != null) { gl.texParameteri(target, gl.TEXTURE_MAG_FILTER, parameters.magFilter); }

+ 5 - 5
Viewer/src/managers/sceneManager.ts

@@ -98,7 +98,7 @@ export class SceneManager {
     /**
     /**
      * Babylon's scene optimizer
      * Babylon's scene optimizer
      */
      */
-    public sceneOptimizer: SceneOptimizer;
+    public sceneOptimizer?: SceneOptimizer;
     /**
     /**
      * Models displayed in this viewer.
      * Models displayed in this viewer.
      */
      */
@@ -670,9 +670,9 @@ export class SceneManager {
 
 
         if (canvas) {
         if (canvas) {
             if (this.camera && sceneConfig.disableCameraControl) {
             if (this.camera && sceneConfig.disableCameraControl) {
-                this.camera.detachControl(canvas);
+                this.camera.detachControl();
             } else if (this.camera && sceneConfig.disableCameraControl === false) {
             } else if (this.camera && sceneConfig.disableCameraControl === false) {
-                this.camera.attachControl(canvas);
+                this.camera.attachControl();
             }
             }
         }
         }
 
 
@@ -741,7 +741,7 @@ export class SceneManager {
 
 
         this.onSceneOptimizerConfiguredObservable.notifyObservers({
         this.onSceneOptimizerConfiguredObservable.notifyObservers({
             sceneManager: this,
             sceneManager: this,
-            object: this.sceneOptimizer,
+            object: this.sceneOptimizer!,
             newConfiguration: optimizerConfig
             newConfiguration: optimizerConfig
         });
         });
     }
     }
@@ -925,7 +925,7 @@ export class SceneManager {
             }
             }
             let canvas = this.scene.getEngine().getInputElement();
             let canvas = this.scene.getEngine().getInputElement();
             if (canvas) {
             if (canvas) {
-                this.scene.activeCamera.attachControl(canvas);
+                this.scene.activeCamera.attachControl();
             }
             }
 
 
             this.camera = <ArcRotateCamera>this.scene.activeCamera!;
             this.camera = <ArcRotateCamera>this.scene.activeCamera!;

+ 0 - 1
Viewer/src/managers/telemetryManager.ts

@@ -118,7 +118,6 @@ export class TelemetryManager {
      */
      */
     public dispose() {
     public dispose() {
         this.onEventBroadcastedObservable.clear();
         this.onEventBroadcastedObservable.clear();
-        delete this.onEventBroadcastedObservable;
     }
     }
 }
 }
 
 

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

@@ -540,8 +540,6 @@ export class Template {
                 evt.htmlElement.removeEventListener(evt.eventName, evt.function);
                 evt.htmlElement.removeEventListener(evt.eventName, evt.function);
             });
             });
         }
         }
-
-        delete this._fragment;
     }
     }
 
 
     private _getTemplateAsHtml(templateConfig: ITemplateConfiguration): Promise<string> {
     private _getTemplateAsHtml(templateConfig: ITemplateConfiguration): Promise<string> {

+ 1 - 1
Viewer/src/viewer/viewer.ts

@@ -561,7 +561,7 @@ export abstract class AbstractViewer {
 
 
         if (this.sceneManager) {
         if (this.sceneManager) {
             if (this.sceneManager.scene && this.sceneManager.scene.activeCamera) {
             if (this.sceneManager.scene && this.sceneManager.scene.activeCamera) {
-                this.sceneManager.scene.activeCamera.detachControl(this.canvas);
+                this.sceneManager.scene.activeCamera.detachControl();
             }
             }
             this.sceneManager.dispose();
             this.sceneManager.dispose();
         }
         }

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

@@ -98,8 +98,6 @@ export class ViewerManager {
      * dispose the manager and all of its associated viewers
      * dispose the manager and all of its associated viewers
      */
      */
     public dispose() {
     public dispose() {
-        delete this._onViewerAdded;
-
         for (let id in this._viewers) {
         for (let id in this._viewers) {
             this._viewers[id].dispose();
             this._viewers[id].dispose();
         }
         }

+ 1 - 1
Viewer/tests/commons/helper.ts

@@ -41,7 +41,7 @@ export class Helper {
     public static disposeViewer() {
     public static disposeViewer() {
         if (Helper.viewer != null) {
         if (Helper.viewer != null) {
             Helper.viewer.dispose();
             Helper.viewer.dispose();
-            delete Helper.viewer;
+            (Helper.viewer as any)= null;
         }
         }
     }
     }
 
 

+ 3 - 3
Viewer/tests/unit/src/viewer/viewer.ts

@@ -192,19 +192,19 @@ describe('Viewer', function() {
     it('should attach and detach camera control correctly', (done) => {
     it('should attach and detach camera control correctly', (done) => {
         let viewer = Helper.getNewViewerInstance();
         let viewer = Helper.getNewViewerInstance();
         viewer.onInitDoneObservable.add(() => {
         viewer.onInitDoneObservable.add(() => {
-            assert.isDefined(viewer.sceneManager.camera.inputs.attachedElement, "Camera is not attached per default");
+            assert.isTrue(viewer.sceneManager.camera.inputs.attachedToElement, "Camera is not attached per default");
             viewer.updateConfiguration({
             viewer.updateConfiguration({
                 scene: {
                 scene: {
                     disableCameraControl: true
                     disableCameraControl: true
                 }
                 }
             });
             });
-            assert.isNull(viewer.sceneManager.camera.inputs.attachedElement, "Camera is still attached");
+            assert.isFalse(viewer.sceneManager.camera.inputs.attachedToElement, "Camera is still attached");
             viewer.updateConfiguration({
             viewer.updateConfiguration({
                 scene: {
                 scene: {
                     disableCameraControl: false
                     disableCameraControl: false
                 }
                 }
             });
             });
-            assert.isDefined(viewer.sceneManager.camera.inputs.attachedElement, "Camera not attached");
+            assert.isTrue(viewer.sceneManager.camera.inputs.attachedToElement, "Camera not attached");
             viewer.dispose();
             viewer.dispose();
             done();
             done();
         });
         });

+ 0 - 1
Viewer/tests/validation/validate.html

@@ -6,7 +6,6 @@
 	<script src="https://preview.babylonjs.com/ammo.js"></script>
 	<script src="https://preview.babylonjs.com/ammo.js"></script>
 	<script src="https://preview.babylonjs.com/cannon.js"></script>
 	<script src="https://preview.babylonjs.com/cannon.js"></script>
     <script src="https://preview.babylonjs.com/Oimo.js"></script>
     <script src="https://preview.babylonjs.com/Oimo.js"></script>
-	<script src="https://preview.babylonjs.com/libktx.js"></script>
     <script src="https://preview.babylonjs.com/babylon.js"></script>
     <script src="https://preview.babylonjs.com/babylon.js"></script>
     <script src="https://preview.babylonjs.com/inspector/babylon.inspector.bundle.js"></script>
     <script src="https://preview.babylonjs.com/inspector/babylon.inspector.bundle.js"></script>
 
 

+ 61 - 24
Viewer/tests/validation/validation.js

@@ -51,27 +51,38 @@ function compare(renderData, referenceCanvas) {
     return (differencesCount * 100) / (width * height) > errorRatio;
     return (differencesCount * 100) / (width * height) > errorRatio;
 }
 }
 
 
-function getRenderData(canvas, engine) {
+async function getRenderData(canvas, engine) {
     var width = canvas.width;
     var width = canvas.width;
     var height = canvas.height;
     var height = canvas.height;
 
 
-    var renderData = engine.readPixels(0, 0, width, height);
-    var numberOfChannelsByLine = width * 4;
-    var halfHeight = height / 2;
-
-    for (var i = 0; i < halfHeight; i++) {
-        for (var j = 0; j < numberOfChannelsByLine; j++) {
-            var currentCell = j + i * numberOfChannelsByLine;
-            var targetLine = height - i - 1;
-            var targetCell = j + targetLine * numberOfChannelsByLine;
-
-            var temp = renderData[currentCell];
-            renderData[currentCell] = renderData[targetCell];
-            renderData[targetCell] = temp;
-        }
-    }
+    return new Promise((resolve) => {
+        engine.onEndFrameObservable.addOnce(async () => {
+            var renderData = await engine.readPixels(0, 0, width, height);
+            var numberOfChannelsByLine = width * 4;
+            var halfHeight = height / 2;
+
+            for (var i = 0; i < halfHeight; i++) {
+                for (var j = 0; j < numberOfChannelsByLine; j++) {
+                    var currentCell = j + i * numberOfChannelsByLine;
+                    var targetLine = height - i - 1;
+                    var targetCell = j + targetLine * numberOfChannelsByLine;
+
+                    var temp = renderData[currentCell];
+                    renderData[currentCell] = renderData[targetCell];
+                    renderData[targetCell] = temp;
+                }
+            }
+            if (engine.isWebGPU) {
+                for (var i = 0; i < width * height * 4; i += 4) {
+                    var temp = renderData[i + 0];
+                    renderData[i + 0] = renderData[i + 2];
+                    renderData[i + 2] = temp;
+                }
+            }
 
 
-    return renderData;
+            resolve(renderData);
+        });
+    });
 }
 }
 
 
 function saveRenderImage(data, canvas) {
 function saveRenderImage(data, canvas) {
@@ -106,9 +117,9 @@ function downloadDataUrlFromJavascript(filename, dataUrl) {
     document.body.removeChild(link);
     document.body.removeChild(link);
 }
 }
 
 
-function evaluate(test, resultCanvas, result, renderImage, index, waitRing, done) {
+async function evaluate(test, resultCanvas, result, renderImage, index, waitRing, done) {
     seed = 100000;
     seed = 100000;
-    var renderData = getRenderData(currentViewer.canvas, currentViewer.engine);
+    var renderData = await getRenderData(currentViewer.canvas, currentViewer.engine);
     var testRes = true;
     var testRes = true;
 
 
     // gl check
     // gl check
@@ -282,18 +293,44 @@ function prepareMeshForViewer(viewer, configuration, test) {
     console.log("sphere created");
     console.log("sphere created");
 }
 }
 
 
+function GetAbsoluteUrl(url) {
+    const a = document.createElement("a");
+    a.href = url;
+    return a.href;
+}
+
 function init() {
 function init() {
     BABYLON.SceneLoader.ShowLoadingScreen = false;
     BABYLON.SceneLoader.ShowLoadingScreen = false;
     BABYLON.SceneLoader.ForceFullSceneLoadingForIncremental = true;
     BABYLON.SceneLoader.ForceFullSceneLoadingForIncremental = true;
 
 
     BABYLON.DracoCompression.Configuration.decoder = {
     BABYLON.DracoCompression.Configuration.decoder = {
-        wasmUrl: "../../dist/preview%20release/draco_wasm_wrapper_gltf.js",
-        wasmBinaryUrl: "../../dist/preview%20release/draco_decoder_gltf.wasm",
-        fallbackUrl: "../../dist/preview%20release/draco_decoder_gltf.js"
+        wasmUrl: GetAbsoluteUrl("../../dist/preview%20release/draco_wasm_wrapper_gltf.js"),
+        wasmBinaryUrl: GetAbsoluteUrl("../../dist/preview%20release/draco_decoder_gltf.wasm"),
+        fallbackUrl: GetAbsoluteUrl("../../dist/preview%20release/draco_decoder_gltf.js")
     };
     };
-
     BABYLON.GLTFValidation.Configuration = {
     BABYLON.GLTFValidation.Configuration = {
-        url: "../../dist/preview%20release/gltf_validator.js"
+        url: GetAbsoluteUrl("../../dist/preview%20release/gltf_validator.js")
+    };
+    BABYLON.GLTF2.Loader.Extensions.EXT_meshopt_compression.DecoderPath =
+        GetAbsoluteUrl("../../dist/preview%20release/meshopt_decoder.js");
+    BABYLON.KhronosTextureContainer2.URLConfig = {
+        jsDecoderModule: GetAbsoluteUrl("../../dist/preview%20release/babylon.ktx2Decoder.js"),
+        wasmUASTCToASTC: GetAbsoluteUrl("../../dist/preview%20release/ktx2Transcoders/uastc_astc.wasm"),
+        wasmUASTCToBC7: GetAbsoluteUrl("../../dist/preview%20release/ktx2Transcoders/uastc_bc7.wasm"),
+        wasmUASTCToRGBA_UNORM: GetAbsoluteUrl("../../dist/preview%20release/ktx2Transcoders/uastc_rgba32_unorm.wasm"),
+        wasmUASTCToRGBA_SRGB: GetAbsoluteUrl("../../dist/preview%20release/ktx2Transcoders/uastc_rgba32_srgb.wasm"),
+        jsMSCTranscoder: GetAbsoluteUrl("../../dist/preview%20release/ktx2Transcoders/msc_basis_transcoder.js"),
+        wasmMSCTranscoder: GetAbsoluteUrl("../../dist/preview%20release/ktx2Transcoders/msc_basis_transcoder.wasm")
+    };
+
+    BABYLON.KhronosTextureContainer2.URLConfig = {
+        jsDecoderModule: GetAbsoluteUrl("../../dist/preview%20release/babylon.ktx2Decoder.js"),
+        wasmUASTCToASTC: GetAbsoluteUrl("../../dist/preview%20release/ktx2Transcoders/uastc_astc.wasm"),
+        wasmUASTCToBC7: GetAbsoluteUrl("../../dist/preview%20release/ktx2Transcoders/uastc_bc7.wasm"),
+        wasmUASTCToRGBA_UNORM: GetAbsoluteUrl("../../dist/preview%20release/ktx2Transcoders/uastc_rgba32_unorm.wasm"),
+        wasmUASTCToRGBA_SRGB: GetAbsoluteUrl("../../dist/preview%20release/ktx2Transcoders/uastc_rgba32_srgb.wasm"),
+        jsMSCTranscoder: GetAbsoluteUrl("../../dist/preview%20release/ktx2Transcoders/msc_basis_transcoder.js"),
+        wasmMSCTranscoder: GetAbsoluteUrl("../../dist/preview%20release/ktx2Transcoders/msc_basis_transcoder.wasm")
     };
     };
 
 
     viewerElement = document.createElement("babylon");
     viewerElement = document.createElement("babylon");

+ 3 - 3
contributing.md

@@ -49,10 +49,10 @@ so that you can start straight away.
 
 
 ## Pull requests
 ## Pull requests
 
 
-We are not complicated people, but we still have some [coding guidelines](https://doc.babylonjs.com/how_to/approved_naming_conventions)
-Before submitting your PR, just check that everything goes well by [creating the minified version](https://doc.babylonjs.com/resources/creating_the_mini-fied_version)
+We are not complicated people, but we still have some [coding guidelines](https://doc.babylonjs.com/divingDeeper/developWithBjs/approvedNamingConventions)
+Before submitting your PR, just check that everything goes well by [creating the minified version](https://doc.babylonjs.com/advanced_topics/minifiedVer)
 
 
-You should read the [how to contribute documentation](https://doc.babylonjs.com/how_to/how_to_start) before working on your PR.
+You should read the [how to contribute documentation](https://doc.babylonjs.com/divingDeeper/developWithBjs/howToStart) before working on your PR.
 
 
 To validate your PR, please follow these steps:
 To validate your PR, please follow these steps:
 
 

File diff suppressed because it is too large
+ 11 - 11
dist/ammo.js


File diff suppressed because it is too large
+ 1 - 1
dist/ammo.wasm.js


BIN
dist/ammo.wasm.wasm


File diff suppressed because it is too large
+ 45586 - 37566
dist/babylon.d.ts


File diff suppressed because it is too large
+ 12 - 12
dist/babylon.js


File diff suppressed because it is too large
+ 1 - 0
dist/babylon.ktx2Decoder.js


File diff suppressed because it is too large
+ 34186 - 10590
dist/babylon.max.js


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


File diff suppressed because it is too large
+ 98938 - 82554
dist/babylon.module.d.ts


File diff suppressed because it is too large
+ 46418 - 37695
dist/documentation.d.ts


File diff suppressed because it is too large
+ 48 - 30
dist/draco_decoder_gltf.js


BIN
dist/draco_decoder_gltf.wasm


File diff suppressed because it is too large
+ 104 - 115
dist/draco_wasm_wrapper_gltf.js


File diff suppressed because it is too large
+ 33 - 46
dist/glslang/glslang.js


BIN
dist/glslang/glslang.wasm


+ 310 - 0
dist/gltf2Interface/babylon.glTF2Interface.d.ts

@@ -905,4 +905,314 @@ declare module BABYLON.GLTF2 {
         validateBytes: (data: Uint8Array, options?: IGLTFValidationOptions) => Promise<IGLTFValidationResults>;
         validateBytes: (data: Uint8Array, options?: IGLTFValidationOptions) => Promise<IGLTFValidationResults>;
         validateString: (json: string, options?: IGLTFValidationOptions) => Promise<IGLTFValidationResults>;
         validateString: (json: string, options?: IGLTFValidationOptions) => Promise<IGLTFValidationResults>;
     }
     }
+
+    /**
+     * Interfaces from the EXT_lights_image_based extension
+     */
+
+    /** @hidden */
+    interface IEXTLightsImageBased_LightReferenceImageBased {
+        light: number;
+    }
+
+    /** @hidden */
+    interface IEXTLightsImageBased_LightImageBased extends IChildRootProperty {
+        intensity: number;
+        rotation: number[];
+        specularImageSize: number;
+        specularImages: number[][];
+        irradianceCoefficients: number[][];
+    }
+
+    /** @hidden */
+    interface IEXTLightsImageBased {
+        lights: IEXTLightsImageBased_LightImageBased[];
+    }
+
+    /**
+     * Interfaces from the EXT_mesh_gpu_instancing extension
+     * !!! Experimental Extension Subject to Changes !!!
+     */
+
+    /** @hidden */
+    interface IEXTMeshGpuInstancing {
+        mesh?: number;
+        attributes: { [name: string]: number };
+    }
+
+    /**
+     * Interfaces from the KHR_draco_mesh_compression extension
+     */
+
+    /** @hidden */
+    interface IKHRDracoMeshCompression {
+        bufferView: number;
+        attributes: { [name: string]: number };
+    }
+
+    /**
+     * Interfaces from the KHR_lights_punctual extension
+     */
+
+    /** @hidden */
+    const enum IKHRLightsPunctual_LightType {
+        DIRECTIONAL = "directional",
+        POINT = "point",
+        SPOT = "spot"
+    }
+
+    /** @hidden */
+    interface IKHRLightsPunctual_LightReference {
+        light: number;
+    }
+
+    /** @hidden */
+    interface IKHRLightsPunctual_Light extends IChildRootProperty {
+        type: IKHRLightsPunctual_LightType;
+        color?: number[];
+        intensity?: number;
+        range?: number;
+        spot?: {
+            innerConeAngle?: number;
+            outerConeAngle?: number;
+        };
+    }
+
+    /** @hidden */
+    interface IKHRLightsPunctual {
+        lights: IKHRLightsPunctual_Light[];
+    }
+
+    /**
+     * Interfaces from the KHR_materials_clearcoat extension
+     * !!! Experimental Extension Subject to Changes !!!
+     */
+
+    /** @hidden */
+    interface IKHRMaterialsClearcoat {
+        clearcoatFactor: number;
+        clearcoatTexture: ITextureInfo;
+        clearcoatRoughnessFactor: number;
+        clearcoatRoughnessTexture: ITextureInfo;
+        clearcoatNormalTexture: IMaterialNormalTextureInfo;
+    }
+
+    /**
+     * Interfaces from the KHR_materials_ior extension
+     * !!! Experimental Extension Subject to Changes !!!
+     */
+
+    /** @hidden */
+    interface IKHRMaterialsIor {
+        ior: number;
+    }
+
+    /**
+     * Interfaces from the KHR_materials_pbrSpecularGlossiness extension
+     */
+
+    /** @hidden */
+    interface IKHRMaterialsPbrSpecularGlossiness {
+        diffuseFactor: number[];
+        diffuseTexture: ITextureInfo;
+        specularFactor: number[];
+        glossinessFactor: number;
+        specularGlossinessTexture: ITextureInfo;
+    }
+
+    /**
+     * Interfaces from the KHR_materials_sheen extension
+     * !!! Experimental Extension Subject to Changes !!!
+     */
+
+    /** @hidden */
+    interface IKHRMaterialsSheen {
+        sheenColorFactor?: number[];
+        sheenColorTexture?: ITextureInfo;
+        sheenRoughnessFactor?: number;
+        sheenRoughnessTexture?: ITextureInfo;
+    }
+
+    /**
+     * Interfaces from the KHR_materials_specular extension
+     * !!! Experimental Extension Subject to Changes !!!
+     */
+
+    /** @hidden */
+    interface IKHRMaterialsSpecular {
+        specularFactor: number;
+        specularColorFactor: number[];
+        specularTexture: ITextureInfo;
+    }
+
+    /**
+     * Interfaces from the KHR_materials_transmission extension
+     * !!! Experimental Extension Subject to Changes !!!
+     */
+
+    /** @hidden */
+    interface IKHRMaterialsTransmission {
+        transmissionFactor?: number;
+        transmissionTexture?: ITextureInfo;
+    }
+
+    /**
+     * Interfaces from the KHR_materials_translucency extension
+     * !!! Experimental Extension Subject to Changes !!!
+     */
+
+    /** @hidden */
+    interface IKHRMaterialsTranslucency {
+        translucencyFactor?: number;
+        translucencyTexture?: ITextureInfo;
+    }
+
+    /**
+     * Interfaces from the KHR_materials_variants extension
+     * !!! Experimental Extension Subject to Changes !!!
+     */
+
+    /** @hidden */
+    interface IKHRMaterialVariants_Mapping extends IProperty {
+        mappings: Array<{
+            variants: number[];
+            material: number;
+        }>;
+    }
+
+    /** @hidden */
+    interface IKHRMaterialVariants_Variant extends IProperty {
+        name: string;
+    }
+
+    /** @hidden */
+    interface IKHRMaterialVariants_Variants extends IChildRootProperty {
+        variants: Array<IKHRMaterialVariants_Variant>;
+    }
+
+    /**
+     * Interfaces from the KHR_texture_basisu extension
+     * !!! Experimental Extension Subject to Changes !!!
+     */
+
+    /** @hidden */
+    interface IKHRTextureBasisU {
+        source: number;
+    }
+
+    /**
+     * Interfaces from the EXT_texture_webp extension
+     */
+
+    /** @hidden */
+    interface IEXTTextureWebP {
+        source: number;
+    }
+
+    /**
+     * Interfaces from the KHR_texture_transform extension
+     */
+
+    /** @hidden */
+    interface IKHRTextureTransform {
+        offset?: number[];
+        rotation?: number;
+        scale?: number[];
+        texCoord?: number;
+    }
+
+    /**
+     * Interfaces from the KHR_xmp extension
+     * !!! Experimental Extension Subject to Changes !!!
+     */
+
+    /** @hidden */
+    interface IKHRXmp_Data {
+        [key: string]: unknown;
+    }
+
+    /** @hidden */
+    interface IKHRXmp_Gltf {
+        packets: IKHRXmp_Data[];
+    }
+
+    /** @hidden */
+    interface IKHRXmp_Node {
+        packet: number;
+    }
+
+    /**
+     * Interfaces from the MSFT_audio_emitter extension
+     */
+
+    /** @hidden */
+    interface IMSFTAudioEmitter_ClipReference {
+        clip: number;
+        weight?: number;
+    }
+
+    /** @hidden */
+    interface IMSFTAudioEmitter_EmittersReference {
+        emitters: number[];
+    }
+
+    /** @hidden */
+    const enum IMSFTAudioEmitter_DistanceModel {
+        linear = "linear",
+        inverse = "inverse",
+        exponential = "exponential",
+    }
+
+    /** @hidden */
+    interface IMSFTAudioEmitter_Emitter {
+        name?: string;
+        distanceModel?: IMSFTAudioEmitter_DistanceModel;
+        refDistance?: number;
+        maxDistance?: number;
+        rolloffFactor?: number;
+        innerAngle?: number;
+        outerAngle?: number;
+        loop?: boolean;
+        volume?: number;
+        clips: IMSFTAudioEmitter_ClipReference[];
+    }
+
+    /** @hidden */
+    const enum IMSFTAudioEmitter_AudioMimeType {
+        WAV = "audio/wav",
+    }
+
+    /** @hidden */
+    interface IMSFTAudioEmitter_Clip extends IProperty {
+        uri?: string;
+        bufferView?: number;
+        mimeType?: IMSFTAudioEmitter_AudioMimeType;
+    }
+
+    /** @hidden */
+    const enum IMSFTAudioEmitter_AnimationEventAction {
+        play = "play",
+        pause = "pause",
+        stop = "stop",
+    }
+
+    /** @hidden */
+    interface IMSFTAudioEmitter_AnimationEvent {
+        action: IMSFTAudioEmitter_AnimationEventAction;
+        emitter: number;
+        time: number;
+        startOffset?: number;
+    }
+
+    /**
+     * Interfaces from the MSFT_lod extension
+     */
+
+    /** @hidden */
+    interface IMSFTLOD {
+        ids: number[];
+    }
+
+
+
 }
 }

+ 1 - 1
dist/gltf2Interface/package.json

@@ -1,7 +1,7 @@
 {
 {
     "name": "babylonjs-gltf2interface",
     "name": "babylonjs-gltf2interface",
     "description": "A typescript declaration of babylon's gltf2 inteface.",
     "description": "A typescript declaration of babylon's gltf2 inteface.",
-    "version": "4.1.0",
+    "version": "4.2.0",
     "repository": {
     "repository": {
         "type": "git",
         "type": "git",
         "url": "https://github.com/BabylonJS/Babylon.js.git"
         "url": "https://github.com/BabylonJS/Babylon.js.git"

+ 193 - 98
dist/gui/babylon.gui.d.ts

@@ -11,7 +11,7 @@ declare module BABYLON.GUI {
         private _originalUnit;
         private _originalUnit;
         /**
         /**
          * Gets or sets a value indicating that this value will not scale accordingly with adaptive scaling property
          * Gets or sets a value indicating that this value will not scale accordingly with adaptive scaling property
-         * @see http://doc.babylonjs.com/how_to/gui#adaptive-scaling
+         * @see https://doc.babylonjs.com/how_to/gui#adaptive-scaling
          */
          */
         ignoreAdaptiveScaling: boolean;
         ignoreAdaptiveScaling: boolean;
         /**
         /**
@@ -281,14 +281,24 @@ declare module BABYLON.GUI {
         /**
         /**
          * Computes the axis aligned bounding box of the measure after it is modified by a given transform
          * Computes the axis aligned bounding box of the measure after it is modified by a given transform
          * @param transform the matrix to transform the measure before computing the AABB
          * @param transform the matrix to transform the measure before computing the AABB
+         * @param addX number to add to left
+         * @param addY number to add to top
+         * @param addWidth number to add to width
+         * @param addHeight number to add to height
          * @param result the resulting AABB
          * @param result the resulting AABB
          */
          */
-        transformToRef(transform: Matrix2D, result: Measure): void;
+        addAndTransformToRef(transform: Matrix2D, addX: number, addY: number, addWidth: number, addHeight: number, result: Measure): void;
         /**
         /**
-         * Check equality between this measure and another one
-         * @param other defines the other measures
-         * @returns true if both measures are equals
+         * Computes the axis aligned bounding box of the measure after it is modified by a given transform
+         * @param transform the matrix to transform the measure before computing the AABB
+         * @param result the resulting AABB
          */
          */
+        transformToRef(transform: Matrix2D, result: Measure): void;
+        /**
+     * Check equality between this measure and another one
+     * @param other defines the other measures
+     * @returns true if both measures are equals
+     */
         isEqualsTo(other: Measure): boolean;
         isEqualsTo(other: Measure): boolean;
         /**
         /**
          * Creates an empty measure
          * Creates an empty measure
@@ -323,7 +333,7 @@ declare module BABYLON.GUI {
     }
     }
     /**
     /**
     * Class used to create texture to support 2D GUI elements
     * Class used to create texture to support 2D GUI elements
-    * @see http://doc.babylonjs.com/how_to/gui
+    * @see https://doc.babylonjs.com/how_to/gui
     */
     */
     export class AdvancedDynamicTexture extends BABYLON.DynamicTexture {
     export class AdvancedDynamicTexture extends BABYLON.DynamicTexture {
         private _isDirty;
         private _isDirty;
@@ -333,6 +343,7 @@ declare module BABYLON.GUI {
         private _pointerMoveObserver;
         private _pointerMoveObserver;
         private _pointerObserver;
         private _pointerObserver;
         private _canvasPointerOutObserver;
         private _canvasPointerOutObserver;
+        private _canvasBlurObserver;
         private _background;
         private _background;
         /** @hidden */
         /** @hidden */
         _rootContainer: Container;
         _rootContainer: Container;
@@ -410,6 +421,10 @@ declare module BABYLON.GUI {
         */
         */
         premulAlpha: boolean;
         premulAlpha: boolean;
         /**
         /**
+         * Gets or sets a boolean indicating that the canvas must be reverted on Y when updating the texture
+         */
+        applyYInversionOnUpdate: boolean;
+        /**
         * Gets or sets a number used to scale rendering size (2 means that the texture will be twice bigger).
         * Gets or sets a number used to scale rendering size (2 means that the texture will be twice bigger).
         * Useful when you want more antialiasing
         * Useful when you want more antialiasing
         */
         */
@@ -421,32 +436,32 @@ declare module BABYLON.GUI {
         /**
         /**
         * Gets or sets the ideal width used to design controls.
         * Gets or sets the ideal width used to design controls.
         * The GUI will then rescale everything accordingly
         * The GUI will then rescale everything accordingly
-        * @see http://doc.babylonjs.com/how_to/gui#adaptive-scaling
+        * @see https://doc.babylonjs.com/how_to/gui#adaptive-scaling
         */
         */
         get idealWidth(): number;
         get idealWidth(): number;
         set idealWidth(value: number);
         set idealWidth(value: number);
         /**
         /**
         * Gets or sets the ideal height used to design controls.
         * Gets or sets the ideal height used to design controls.
         * The GUI will then rescale everything accordingly
         * The GUI will then rescale everything accordingly
-        * @see http://doc.babylonjs.com/how_to/gui#adaptive-scaling
+        * @see https://doc.babylonjs.com/how_to/gui#adaptive-scaling
         */
         */
         get idealHeight(): number;
         get idealHeight(): number;
         set idealHeight(value: number);
         set idealHeight(value: number);
         /**
         /**
         * Gets or sets a boolean indicating if the smallest ideal value must be used if idealWidth and idealHeight are both set
         * Gets or sets a boolean indicating if the smallest ideal value must be used if idealWidth and idealHeight are both set
-        * @see http://doc.babylonjs.com/how_to/gui#adaptive-scaling
+        * @see https://doc.babylonjs.com/how_to/gui#adaptive-scaling
         */
         */
         get useSmallestIdeal(): boolean;
         get useSmallestIdeal(): boolean;
         set useSmallestIdeal(value: boolean);
         set useSmallestIdeal(value: boolean);
         /**
         /**
         * Gets or sets a boolean indicating if adaptive scaling must be used
         * Gets or sets a boolean indicating if adaptive scaling must be used
-        * @see http://doc.babylonjs.com/how_to/gui#adaptive-scaling
+        * @see https://doc.babylonjs.com/how_to/gui#adaptive-scaling
         */
         */
         get renderAtIdealSize(): boolean;
         get renderAtIdealSize(): boolean;
         set renderAtIdealSize(value: boolean);
         set renderAtIdealSize(value: boolean);
         /**
         /**
          * Gets the ratio used when in "ideal mode"
          * Gets the ratio used when in "ideal mode"
-        * @see http://doc.babylonjs.com/how_to/gui#adaptive-scaling
+        * @see https://doc.babylonjs.com/how_to/gui#adaptive-scaling
          * */
          * */
         get idealRatio(): number;
         get idealRatio(): number;
         /**
         /**
@@ -493,8 +508,9 @@ declare module BABYLON.GUI {
        * @param scene defines the hosting scene
        * @param scene defines the hosting scene
        * @param generateMipMaps defines a boolean indicating if mipmaps must be generated (false by default)
        * @param generateMipMaps defines a boolean indicating if mipmaps must be generated (false by default)
        * @param samplingMode defines the texture sampling mode (Texture.NEAREST_SAMPLINGMODE by default)
        * @param samplingMode defines the texture sampling mode (Texture.NEAREST_SAMPLINGMODE by default)
+       * @param invertY defines if the texture needs to be inverted on the y axis during loading (true by default)
        */
        */
-        constructor(name: string, width: number | undefined, height: number | undefined, scene: BABYLON.Nullable<BABYLON.Scene>, generateMipMaps?: boolean, samplingMode?: number);
+        constructor(name: string, width: number | undefined, height: number | undefined, scene: BABYLON.Nullable<BABYLON.Scene>, generateMipMaps?: boolean, samplingMode?: number, invertY?: boolean);
         /**
         /**
         * Get the current class name of the texture useful for serialization or dynamic coding.
         * Get the current class name of the texture useful for serialization or dynamic coding.
         * @returns "AdvancedDynamicTexture"
         * @returns "AdvancedDynamicTexture"
@@ -528,7 +544,7 @@ declare module BABYLON.GUI {
         /**
         /**
         * Helper function used to create a new style
         * Helper function used to create a new style
         * @returns a new style
         * @returns a new style
-        * @see http://doc.babylonjs.com/how_to/gui#styles
+        * @see https://doc.babylonjs.com/how_to/gui#styles
         */
         */
         createStyle(): Style;
         createStyle(): Style;
         /**
         /**
@@ -557,6 +573,13 @@ declare module BABYLON.GUI {
         * @returns the projected position
         * @returns the projected position
         */
         */
         getProjectedPosition(position: BABYLON.Vector3, worldMatrix: BABYLON.Matrix): BABYLON.Vector2;
         getProjectedPosition(position: BABYLON.Vector3, worldMatrix: BABYLON.Matrix): BABYLON.Vector2;
+        /**
+        * Get screen coordinates for a vector3
+        * @param position defines the position to project
+        * @param worldMatrix defines the world matrix to use
+        * @returns the projected position with Z
+        */
+        getProjectedPositionWithZ(position: BABYLON.Vector3, worldMatrix: BABYLON.Matrix): BABYLON.Vector3;
         private _checkUpdate;
         private _checkUpdate;
         private _clearMeasure;
         private _clearMeasure;
         private _render;
         private _render;
@@ -600,6 +623,7 @@ declare module BABYLON.GUI {
         moveFocusToControl(control: IFocusableControl): void;
         moveFocusToControl(control: IFocusableControl): void;
         private _manageFocus;
         private _manageFocus;
         private _attachToOnPointerOut;
         private _attachToOnPointerOut;
+        private _attachToOnBlur;
         /**
         /**
          * Creates a new AdvancedDynamicTexture in projected mode (ie. attached to a mesh)
          * Creates a new AdvancedDynamicTexture in projected mode (ie. attached to a mesh)
          * @param mesh defines the mesh which will receive the texture
          * @param mesh defines the mesh which will receive the texture
@@ -607,9 +631,20 @@ declare module BABYLON.GUI {
          * @param height defines the texture height (1024 by default)
          * @param height defines the texture height (1024 by default)
          * @param supportPointerMove defines a boolean indicating if the texture must capture move events (true by default)
          * @param supportPointerMove defines a boolean indicating if the texture must capture move events (true by default)
          * @param onlyAlphaTesting defines a boolean indicating that alpha blending will not be used (only alpha testing) (false by default)
          * @param onlyAlphaTesting defines a boolean indicating that alpha blending will not be used (only alpha testing) (false by default)
+         * @param invertY defines if the texture needs to be inverted on the y axis during loading (true by default)
          * @returns a new AdvancedDynamicTexture
          * @returns a new AdvancedDynamicTexture
          */
          */
-        static CreateForMesh(mesh: BABYLON.AbstractMesh, width?: number, height?: number, supportPointerMove?: boolean, onlyAlphaTesting?: boolean): AdvancedDynamicTexture;
+        static CreateForMesh(mesh: BABYLON.AbstractMesh, width?: number, height?: number, supportPointerMove?: boolean, onlyAlphaTesting?: boolean, invertY?: boolean): AdvancedDynamicTexture;
+        /**
+         * Creates a new AdvancedDynamicTexture in projected mode (ie. attached to a mesh) BUT do not create a new material for the mesh. You will be responsible for connecting the texture
+         * @param mesh defines the mesh which will receive the texture
+         * @param width defines the texture width (1024 by default)
+         * @param height defines the texture height (1024 by default)
+         * @param supportPointerMove defines a boolean indicating if the texture must capture move events (true by default)
+         * @param invertY defines if the texture needs to be inverted on the y axis during loading (true by default)
+         * @returns a new AdvancedDynamicTexture
+         */
+        static CreateForMeshTexture(mesh: BABYLON.AbstractMesh, width?: number, height?: number, supportPointerMove?: boolean, invertY?: boolean): AdvancedDynamicTexture;
         /**
         /**
         * Creates a new AdvancedDynamicTexture in fullscreen mode.
         * Creates a new AdvancedDynamicTexture in fullscreen mode.
         * In this mode the texture will rely on a layer for its rendering.
         * In this mode the texture will rely on a layer for its rendering.
@@ -628,7 +663,7 @@ declare module BABYLON.GUI {
 declare module BABYLON.GUI {
 declare module BABYLON.GUI {
     /**
     /**
      * Root class used for all 2D controls
      * Root class used for all 2D controls
-     * @see http://doc.babylonjs.com/how_to/gui#controls
+     * @see https://doc.babylonjs.com/how_to/gui#controls
      */
      */
     export class Control {
     export class Control {
         /** defines the name of the control */
         /** defines the name of the control */
@@ -703,7 +738,7 @@ declare module BABYLON.GUI {
         private _isVisible;
         private _isVisible;
         private _isHighlighted;
         private _isHighlighted;
         /** @hidden */
         /** @hidden */
-        _linkedMesh: BABYLON.Nullable<BABYLON.AbstractMesh>;
+        _linkedMesh: BABYLON.Nullable<BABYLON.TransformNode>;
         private _fontSet;
         private _fontSet;
         private _dummyVector2;
         private _dummyVector2;
         private _downCount;
         private _downCount;
@@ -822,6 +857,10 @@ declare module BABYLON.GUI {
          */
          */
         onAfterDrawObservable: BABYLON.Observable<Control>;
         onAfterDrawObservable: BABYLON.Observable<Control>;
         /**
         /**
+        * An event triggered when the control has been disposed
+        */
+        onDisposeObservable: BABYLON.Observable<Control>;
+        /**
          * Get the hosting AdvancedDynamicTexture
          * Get the hosting AdvancedDynamicTexture
          */
          */
         get host(): AdvancedDynamicTexture;
         get host(): AdvancedDynamicTexture;
@@ -845,63 +884,71 @@ declare module BABYLON.GUI {
         get isHighlighted(): boolean;
         get isHighlighted(): boolean;
         set isHighlighted(value: boolean);
         set isHighlighted(value: boolean);
         /** Gets or sets a value indicating the scale factor on X axis (1 by default)
         /** Gets or sets a value indicating the scale factor on X axis (1 by default)
-         * @see http://doc.babylonjs.com/how_to/gui#rotation-and-scaling
+         * @see https://doc.babylonjs.com/how_to/gui#rotation-and-scaling
         */
         */
         get scaleX(): number;
         get scaleX(): number;
         set scaleX(value: number);
         set scaleX(value: number);
         /** Gets or sets a value indicating the scale factor on Y axis (1 by default)
         /** Gets or sets a value indicating the scale factor on Y axis (1 by default)
-         * @see http://doc.babylonjs.com/how_to/gui#rotation-and-scaling
+         * @see https://doc.babylonjs.com/how_to/gui#rotation-and-scaling
         */
         */
         get scaleY(): number;
         get scaleY(): number;
         set scaleY(value: number);
         set scaleY(value: number);
         /** Gets or sets the rotation angle (0 by default)
         /** Gets or sets the rotation angle (0 by default)
-         * @see http://doc.babylonjs.com/how_to/gui#rotation-and-scaling
+         * @see https://doc.babylonjs.com/how_to/gui#rotation-and-scaling
         */
         */
         get rotation(): number;
         get rotation(): number;
         set rotation(value: number);
         set rotation(value: number);
         /** Gets or sets the transformation center on Y axis (0 by default)
         /** Gets or sets the transformation center on Y axis (0 by default)
-         * @see http://doc.babylonjs.com/how_to/gui#rotation-and-scaling
+         * @see https://doc.babylonjs.com/how_to/gui#rotation-and-scaling
         */
         */
         get transformCenterY(): number;
         get transformCenterY(): number;
         set transformCenterY(value: number);
         set transformCenterY(value: number);
         /** Gets or sets the transformation center on X axis (0 by default)
         /** Gets or sets the transformation center on X axis (0 by default)
-         * @see http://doc.babylonjs.com/how_to/gui#rotation-and-scaling
+         * @see https://doc.babylonjs.com/how_to/gui#rotation-and-scaling
         */
         */
         get transformCenterX(): number;
         get transformCenterX(): number;
         set transformCenterX(value: number);
         set transformCenterX(value: number);
         /**
         /**
          * Gets or sets the horizontal alignment
          * Gets or sets the horizontal alignment
-         * @see http://doc.babylonjs.com/how_to/gui#alignments
+         * @see https://doc.babylonjs.com/how_to/gui#alignments
          */
          */
         get horizontalAlignment(): number;
         get horizontalAlignment(): number;
         set horizontalAlignment(value: number);
         set horizontalAlignment(value: number);
         /**
         /**
          * Gets or sets the vertical alignment
          * Gets or sets the vertical alignment
-         * @see http://doc.babylonjs.com/how_to/gui#alignments
+         * @see https://doc.babylonjs.com/how_to/gui#alignments
          */
          */
         get verticalAlignment(): number;
         get verticalAlignment(): number;
         set verticalAlignment(value: number);
         set verticalAlignment(value: number);
         /**
         /**
+         * Gets or sets a fixed ratio for this control.
+         * When different from 0, the ratio is used to compute the "second" dimension.
+         * The first dimension used in the computation is the last one set (by setting width / widthInPixels or height / heightInPixels), and the
+         * second dimension is computed as first dimension * fixedRatio
+         */
+        fixedRatio: number;
+        private _fixedRatioMasterIsWidth;
+        /**
          * Gets or sets control width
          * Gets or sets control width
-         * @see http://doc.babylonjs.com/how_to/gui#position-and-size
+         * @see https://doc.babylonjs.com/how_to/gui#position-and-size
          */
          */
         get width(): string | number;
         get width(): string | number;
         set width(value: string | number);
         set width(value: string | number);
         /**
         /**
          * Gets or sets the control width in pixel
          * Gets or sets the control width in pixel
-         * @see http://doc.babylonjs.com/how_to/gui#position-and-size
+         * @see https://doc.babylonjs.com/how_to/gui#position-and-size
          */
          */
         get widthInPixels(): number;
         get widthInPixels(): number;
         set widthInPixels(value: number);
         set widthInPixels(value: number);
         /**
         /**
          * Gets or sets control height
          * Gets or sets control height
-         * @see http://doc.babylonjs.com/how_to/gui#position-and-size
+         * @see https://doc.babylonjs.com/how_to/gui#position-and-size
          */
          */
         get height(): string | number;
         get height(): string | number;
         set height(value: string | number);
         set height(value: string | number);
         /**
         /**
          * Gets or sets control height in pixel
          * Gets or sets control height in pixel
-         * @see http://doc.babylonjs.com/how_to/gui#position-and-size
+         * @see https://doc.babylonjs.com/how_to/gui#position-and-size
          */
          */
         get heightInPixels(): number;
         get heightInPixels(): number;
         set heightInPixels(value: number);
         set heightInPixels(value: number);
@@ -916,7 +963,7 @@ declare module BABYLON.GUI {
         set fontWeight(value: string);
         set fontWeight(value: string);
         /**
         /**
          * Gets or sets style
          * Gets or sets style
-         * @see http://doc.babylonjs.com/how_to/gui#styles
+         * @see https://doc.babylonjs.com/how_to/gui#styles
          */
          */
         get style(): BABYLON.Nullable<Style>;
         get style(): BABYLON.Nullable<Style>;
         set style(value: BABYLON.Nullable<Style>);
         set style(value: BABYLON.Nullable<Style>);
@@ -945,100 +992,100 @@ declare module BABYLON.GUI {
         /**
         /**
          * Gets the current linked mesh (or null if none)
          * Gets the current linked mesh (or null if none)
          */
          */
-        get linkedMesh(): BABYLON.Nullable<BABYLON.AbstractMesh>;
+        get linkedMesh(): BABYLON.Nullable<BABYLON.TransformNode>;
         /**
         /**
          * Gets or sets a value indicating the padding to use on the left of the control
          * Gets or sets a value indicating the padding to use on the left of the control
-         * @see http://doc.babylonjs.com/how_to/gui#position-and-size
+         * @see https://doc.babylonjs.com/how_to/gui#position-and-size
          */
          */
         get paddingLeft(): string | number;
         get paddingLeft(): string | number;
         set paddingLeft(value: string | number);
         set paddingLeft(value: string | number);
         /**
         /**
          * Gets or sets a value indicating the padding in pixels to use on the left of the control
          * Gets or sets a value indicating the padding in pixels to use on the left of the control
-         * @see http://doc.babylonjs.com/how_to/gui#position-and-size
+         * @see https://doc.babylonjs.com/how_to/gui#position-and-size
          */
          */
         get paddingLeftInPixels(): number;
         get paddingLeftInPixels(): number;
         set paddingLeftInPixels(value: number);
         set paddingLeftInPixels(value: number);
         /**
         /**
          * Gets or sets a value indicating the padding to use on the right of the control
          * Gets or sets a value indicating the padding to use on the right of the control
-         * @see http://doc.babylonjs.com/how_to/gui#position-and-size
+         * @see https://doc.babylonjs.com/how_to/gui#position-and-size
          */
          */
         get paddingRight(): string | number;
         get paddingRight(): string | number;
         set paddingRight(value: string | number);
         set paddingRight(value: string | number);
         /**
         /**
          * Gets or sets a value indicating the padding in pixels to use on the right of the control
          * Gets or sets a value indicating the padding in pixels to use on the right of the control
-         * @see http://doc.babylonjs.com/how_to/gui#position-and-size
+         * @see https://doc.babylonjs.com/how_to/gui#position-and-size
          */
          */
         get paddingRightInPixels(): number;
         get paddingRightInPixels(): number;
         set paddingRightInPixels(value: number);
         set paddingRightInPixels(value: number);
         /**
         /**
          * Gets or sets a value indicating the padding to use on the top of the control
          * Gets or sets a value indicating the padding to use on the top of the control
-         * @see http://doc.babylonjs.com/how_to/gui#position-and-size
+         * @see https://doc.babylonjs.com/how_to/gui#position-and-size
          */
          */
         get paddingTop(): string | number;
         get paddingTop(): string | number;
         set paddingTop(value: string | number);
         set paddingTop(value: string | number);
         /**
         /**
          * Gets or sets a value indicating the padding in pixels to use on the top of the control
          * Gets or sets a value indicating the padding in pixels to use on the top of the control
-         * @see http://doc.babylonjs.com/how_to/gui#position-and-size
+         * @see https://doc.babylonjs.com/how_to/gui#position-and-size
          */
          */
         get paddingTopInPixels(): number;
         get paddingTopInPixels(): number;
         set paddingTopInPixels(value: number);
         set paddingTopInPixels(value: number);
         /**
         /**
          * Gets or sets a value indicating the padding to use on the bottom of the control
          * Gets or sets a value indicating the padding to use on the bottom of the control
-         * @see http://doc.babylonjs.com/how_to/gui#position-and-size
+         * @see https://doc.babylonjs.com/how_to/gui#position-and-size
          */
          */
         get paddingBottom(): string | number;
         get paddingBottom(): string | number;
         set paddingBottom(value: string | number);
         set paddingBottom(value: string | number);
         /**
         /**
          * Gets or sets a value indicating the padding in pixels to use on the bottom of the control
          * Gets or sets a value indicating the padding in pixels to use on the bottom of the control
-         * @see http://doc.babylonjs.com/how_to/gui#position-and-size
+         * @see https://doc.babylonjs.com/how_to/gui#position-and-size
          */
          */
         get paddingBottomInPixels(): number;
         get paddingBottomInPixels(): number;
         set paddingBottomInPixels(value: number);
         set paddingBottomInPixels(value: number);
         /**
         /**
          * Gets or sets a value indicating the left coordinate of the control
          * Gets or sets a value indicating the left coordinate of the control
-         * @see http://doc.babylonjs.com/how_to/gui#position-and-size
+         * @see https://doc.babylonjs.com/how_to/gui#position-and-size
          */
          */
         get left(): string | number;
         get left(): string | number;
         set left(value: string | number);
         set left(value: string | number);
         /**
         /**
          * Gets or sets a value indicating the left coordinate in pixels of the control
          * Gets or sets a value indicating the left coordinate in pixels of the control
-         * @see http://doc.babylonjs.com/how_to/gui#position-and-size
+         * @see https://doc.babylonjs.com/how_to/gui#position-and-size
          */
          */
         get leftInPixels(): number;
         get leftInPixels(): number;
         set leftInPixels(value: number);
         set leftInPixels(value: number);
         /**
         /**
          * Gets or sets a value indicating the top coordinate of the control
          * Gets or sets a value indicating the top coordinate of the control
-         * @see http://doc.babylonjs.com/how_to/gui#position-and-size
+         * @see https://doc.babylonjs.com/how_to/gui#position-and-size
          */
          */
         get top(): string | number;
         get top(): string | number;
         set top(value: string | number);
         set top(value: string | number);
         /**
         /**
          * Gets or sets a value indicating the top coordinate in pixels of the control
          * Gets or sets a value indicating the top coordinate in pixels of the control
-         * @see http://doc.babylonjs.com/how_to/gui#position-and-size
+         * @see https://doc.babylonjs.com/how_to/gui#position-and-size
          */
          */
         get topInPixels(): number;
         get topInPixels(): number;
         set topInPixels(value: number);
         set topInPixels(value: number);
         /**
         /**
          * Gets or sets a value indicating the offset on X axis to the linked mesh
          * Gets or sets a value indicating the offset on X axis to the linked mesh
-         * @see http://doc.babylonjs.com/how_to/gui#tracking-positions
+         * @see https://doc.babylonjs.com/how_to/gui#tracking-positions
          */
          */
         get linkOffsetX(): string | number;
         get linkOffsetX(): string | number;
         set linkOffsetX(value: string | number);
         set linkOffsetX(value: string | number);
         /**
         /**
          * Gets or sets a value indicating the offset in pixels on X axis to the linked mesh
          * Gets or sets a value indicating the offset in pixels on X axis to the linked mesh
-         * @see http://doc.babylonjs.com/how_to/gui#tracking-positions
+         * @see https://doc.babylonjs.com/how_to/gui#tracking-positions
          */
          */
         get linkOffsetXInPixels(): number;
         get linkOffsetXInPixels(): number;
         set linkOffsetXInPixels(value: number);
         set linkOffsetXInPixels(value: number);
         /**
         /**
          * Gets or sets a value indicating the offset on Y axis to the linked mesh
          * Gets or sets a value indicating the offset on Y axis to the linked mesh
-         * @see http://doc.babylonjs.com/how_to/gui#tracking-positions
+         * @see https://doc.babylonjs.com/how_to/gui#tracking-positions
          */
          */
         get linkOffsetY(): string | number;
         get linkOffsetY(): string | number;
         set linkOffsetY(value: string | number);
         set linkOffsetY(value: string | number);
         /**
         /**
          * Gets or sets a value indicating the offset in pixels on Y axis to the linked mesh
          * Gets or sets a value indicating the offset in pixels on Y axis to the linked mesh
-         * @see http://doc.babylonjs.com/how_to/gui#tracking-positions
+         * @see https://doc.babylonjs.com/how_to/gui#tracking-positions
          */
          */
         get linkOffsetYInPixels(): number;
         get linkOffsetYInPixels(): number;
         set linkOffsetYInPixels(value: number);
         set linkOffsetYInPixels(value: number);
@@ -1120,9 +1167,9 @@ declare module BABYLON.GUI {
         /**
         /**
          * Link current control with a target mesh
          * Link current control with a target mesh
          * @param mesh defines the mesh to link with
          * @param mesh defines the mesh to link with
-         * @see http://doc.babylonjs.com/how_to/gui#tracking-positions
+         * @see https://doc.babylonjs.com/how_to/gui#tracking-positions
          */
          */
-        linkWithMesh(mesh: BABYLON.Nullable<BABYLON.AbstractMesh>): void;
+        linkWithMesh(mesh: BABYLON.Nullable<BABYLON.TransformNode>): void;
         /** @hidden */
         /** @hidden */
         _moveToProjectedPosition(projectedPosition: BABYLON.Vector3): void;
         _moveToProjectedPosition(projectedPosition: BABYLON.Vector3): void;
         /** @hidden */
         /** @hidden */
@@ -1181,23 +1228,25 @@ declare module BABYLON.GUI {
          */
          */
         contains(x: number, y: number): boolean;
         contains(x: number, y: number): boolean;
         /** @hidden */
         /** @hidden */
-        _processPicking(x: number, y: number, type: number, pointerId: number, buttonIndex: number, deltaX?: number, deltaY?: number): boolean;
+        _processPicking(x: number, y: number, pi: BABYLON.PointerInfoBase, type: number, pointerId: number, buttonIndex: number, deltaX?: number, deltaY?: number): boolean;
         /** @hidden */
         /** @hidden */
-        _onPointerMove(target: Control, coordinates: BABYLON.Vector2, pointerId: number): void;
+        _onPointerMove(target: Control, coordinates: BABYLON.Vector2, pointerId: number, pi: BABYLON.PointerInfoBase): void;
         /** @hidden */
         /** @hidden */
-        _onPointerEnter(target: Control): boolean;
+        _onPointerEnter(target: Control, pi: BABYLON.PointerInfoBase): boolean;
         /** @hidden */
         /** @hidden */
-        _onPointerOut(target: Control, force?: boolean): void;
+        _onPointerOut(target: Control, pi: BABYLON.Nullable<BABYLON.PointerInfoBase>, force?: boolean): void;
         /** @hidden */
         /** @hidden */
-        _onPointerDown(target: Control, coordinates: BABYLON.Vector2, pointerId: number, buttonIndex: number): boolean;
+        _onPointerDown(target: Control, coordinates: BABYLON.Vector2, pointerId: number, buttonIndex: number, pi: BABYLON.PointerInfoBase): boolean;
         /** @hidden */
         /** @hidden */
-        _onPointerUp(target: Control, coordinates: BABYLON.Vector2, pointerId: number, buttonIndex: number, notifyClick: boolean): void;
+        _onPointerUp(target: Control, coordinates: BABYLON.Vector2, pointerId: number, buttonIndex: number, notifyClick: boolean, pi?: BABYLON.PointerInfoBase): void;
         /** @hidden */
         /** @hidden */
         _forcePointerUp(pointerId?: BABYLON.Nullable<number>): void;
         _forcePointerUp(pointerId?: BABYLON.Nullable<number>): void;
         /** @hidden */
         /** @hidden */
         _onWheelScroll(deltaX?: number, deltaY?: number): void;
         _onWheelScroll(deltaX?: number, deltaY?: number): void;
         /** @hidden */
         /** @hidden */
-        _processObservables(type: number, x: number, y: number, pointerId: number, buttonIndex: number, deltaX?: number, deltaY?: number): boolean;
+        _onCanvasBlur(): void;
+        /** @hidden */
+        _processObservables(type: number, x: number, y: number, pi: BABYLON.PointerInfoBase, pointerId: number, buttonIndex: number, deltaX?: number, deltaY?: number): boolean;
         private _prepareFont;
         private _prepareFont;
         /** Releases associated resources */
         /** Releases associated resources */
         dispose(): void;
         dispose(): void;
@@ -1247,7 +1296,7 @@ declare module BABYLON.GUI {
 declare module BABYLON.GUI {
 declare module BABYLON.GUI {
     /**
     /**
      * Root class for 2D containers
      * Root class for 2D containers
-     * @see http://doc.babylonjs.com/how_to/gui#containers
+     * @see https://doc.babylonjs.com/how_to/gui#containers
      */
      */
     export class Container extends Control {
     export class Container extends Control {
         name?: string | undefined;
         name?: string | undefined;
@@ -1346,7 +1395,7 @@ declare module BABYLON.GUI {
         _draw(context: CanvasRenderingContext2D, invalidatedRectangle?: Measure): void;
         _draw(context: CanvasRenderingContext2D, invalidatedRectangle?: Measure): void;
         getDescendantsToRef(results: Control[], directDescendantsOnly?: boolean, predicate?: (control: Control) => boolean): void;
         getDescendantsToRef(results: Control[], directDescendantsOnly?: boolean, predicate?: (control: Control) => boolean): void;
         /** @hidden */
         /** @hidden */
-        _processPicking(x: number, y: number, type: number, pointerId: number, buttonIndex: number, deltaX?: number, deltaY?: number): boolean;
+        _processPicking(x: number, y: number, pi: BABYLON.PointerInfoBase, type: number, pointerId: number, buttonIndex: number, deltaX?: number, deltaY?: number): boolean;
         /** @hidden */
         /** @hidden */
         protected _additionalProcessing(parentMeasure: Measure, context: CanvasRenderingContext2D): void;
         protected _additionalProcessing(parentMeasure: Measure, context: CanvasRenderingContext2D): void;
         /** Releases associated resources */
         /** Releases associated resources */
@@ -1412,15 +1461,21 @@ declare module BABYLON.GUI {
         private _lineSpacing;
         private _lineSpacing;
         private _outlineWidth;
         private _outlineWidth;
         private _outlineColor;
         private _outlineColor;
+        private _underline;
+        private _lineThrough;
         /**
         /**
-        * An event triggered after the text is changed
-        */
+         * An event triggered after the text is changed
+         */
         onTextChangedObservable: BABYLON.Observable<TextBlock>;
         onTextChangedObservable: BABYLON.Observable<TextBlock>;
         /**
         /**
-        * An event triggered after the text was broken up into lines
-        */
+         * An event triggered after the text was broken up into lines
+         */
         onLinesReadyObservable: BABYLON.Observable<TextBlock>;
         onLinesReadyObservable: BABYLON.Observable<TextBlock>;
         /**
         /**
+         * Function used to split a string into words. By default, a string is split at each space character found
+         */
+        wordSplittingFunction: BABYLON.Nullable<(line: string) => string[]>;
+        /**
          * Return the line list (you may need to use the onLinesReadyObservable to make sure the list is ready)
          * Return the line list (you may need to use the onLinesReadyObservable to make sure the list is ready)
          */
          */
         get lines(): any[];
         get lines(): any[];
@@ -1481,6 +1536,22 @@ declare module BABYLON.GUI {
          */
          */
         set outlineWidth(value: number);
         set outlineWidth(value: number);
         /**
         /**
+         * Gets or sets a boolean indicating that text must have underline
+         */
+        get underline(): boolean;
+        /**
+         * Gets or sets a boolean indicating that text must have underline
+         */
+        set underline(value: boolean);
+        /**
+         * Gets or sets an boolean indicating that text must be crossed out
+         */
+        get lineThrough(): boolean;
+        /**
+         * Gets or sets an boolean indicating that text must be crossed out
+         */
+        set lineThrough(value: boolean);
+        /**
          * Gets or sets outlineColor of the text to display
          * Gets or sets outlineColor of the text to display
          */
          */
         get outlineColor(): string;
         get outlineColor(): string;
@@ -1546,6 +1617,7 @@ declare module BABYLON.GUI {
         private _sliceTop;
         private _sliceTop;
         private _sliceBottom;
         private _sliceBottom;
         private _detectPointerOnOpaqueOnly;
         private _detectPointerOnOpaqueOnly;
+        private _imageDataCache;
         /**
         /**
          * BABYLON.Observable notified when the content is loaded
          * BABYLON.Observable notified when the content is loaded
          */
          */
@@ -1615,7 +1687,7 @@ declare module BABYLON.GUI {
         get svgAttributesComputationCompleted(): boolean;
         get svgAttributesComputationCompleted(): boolean;
         /**
         /**
          * Gets or sets a boolean indicating if the image can force its container to adapt its size
          * Gets or sets a boolean indicating if the image can force its container to adapt its size
-         * @see http://doc.babylonjs.com/how_to/gui#image
+         * @see https://doc.babylonjs.com/how_to/gui#image
          */
          */
         get autoScale(): boolean;
         get autoScale(): boolean;
         set autoScale(value: boolean);
         set autoScale(value: boolean);
@@ -1648,19 +1720,19 @@ declare module BABYLON.GUI {
         private _getSVGAttribs;
         private _getSVGAttribs;
         /**
         /**
          * Gets or sets the cell width to use when animation sheet is enabled
          * Gets or sets the cell width to use when animation sheet is enabled
-         * @see http://doc.babylonjs.com/how_to/gui#image
+         * @see https://doc.babylonjs.com/how_to/gui#image
          */
          */
         get cellWidth(): number;
         get cellWidth(): number;
         set cellWidth(value: number);
         set cellWidth(value: number);
         /**
         /**
          * Gets or sets the cell height to use when animation sheet is enabled
          * Gets or sets the cell height to use when animation sheet is enabled
-         * @see http://doc.babylonjs.com/how_to/gui#image
+         * @see https://doc.babylonjs.com/how_to/gui#image
          */
          */
         get cellHeight(): number;
         get cellHeight(): number;
         set cellHeight(value: number);
         set cellHeight(value: number);
         /**
         /**
          * Gets or sets the cell id to use (this will turn on the animation sheet mode)
          * Gets or sets the cell id to use (this will turn on the animation sheet mode)
-         * @see http://doc.babylonjs.com/how_to/gui#image
+         * @see https://doc.babylonjs.com/how_to/gui#image
          */
          */
         get cellId(): number;
         get cellId(): number;
         set cellId(value: number);
         set cellId(value: number);
@@ -1742,15 +1814,15 @@ declare module BABYLON.GUI {
         constructor(name?: string | undefined);
         constructor(name?: string | undefined);
         protected _getTypeName(): string;
         protected _getTypeName(): string;
         /** @hidden */
         /** @hidden */
-        _processPicking(x: number, y: number, type: number, pointerId: number, buttonIndex: number, deltaX?: number, deltaY?: number): boolean;
+        _processPicking(x: number, y: number, pi: BABYLON.PointerInfoBase, type: number, pointerId: number, buttonIndex: number, deltaX?: number, deltaY?: number): boolean;
         /** @hidden */
         /** @hidden */
-        _onPointerEnter(target: Control): boolean;
+        _onPointerEnter(target: Control, pi: BABYLON.PointerInfoBase): boolean;
         /** @hidden */
         /** @hidden */
-        _onPointerOut(target: Control, force?: boolean): void;
+        _onPointerOut(target: Control, pi: BABYLON.PointerInfoBase, force?: boolean): void;
         /** @hidden */
         /** @hidden */
-        _onPointerDown(target: Control, coordinates: BABYLON.Vector2, pointerId: number, buttonIndex: number): boolean;
+        _onPointerDown(target: Control, coordinates: BABYLON.Vector2, pointerId: number, buttonIndex: number, pi: BABYLON.PointerInfoBase): boolean;
         /** @hidden */
         /** @hidden */
-        _onPointerUp(target: Control, coordinates: BABYLON.Vector2, pointerId: number, buttonIndex: number, notifyClick: boolean): void;
+        _onPointerUp(target: Control, coordinates: BABYLON.Vector2, pointerId: number, buttonIndex: number, notifyClick: boolean, pi: BABYLON.PointerInfoBase): void;
         /**
         /**
          * Creates a new button made with an image and a text
          * Creates a new button made with an image and a text
          * @param name defines the name of the button
          * @param name defines the name of the button
@@ -1859,7 +1931,7 @@ declare module BABYLON.GUI {
         /** @hidden */
         /** @hidden */
         _draw(context: CanvasRenderingContext2D, invalidatedRectangle?: BABYLON.Nullable<Measure>): void;
         _draw(context: CanvasRenderingContext2D, invalidatedRectangle?: BABYLON.Nullable<Measure>): void;
         /** @hidden */
         /** @hidden */
-        _onPointerDown(target: Control, coordinates: BABYLON.Vector2, pointerId: number, buttonIndex: number): boolean;
+        _onPointerDown(target: Control, coordinates: BABYLON.Vector2, pointerId: number, buttonIndex: number, pi: BABYLON.PointerInfoBase): boolean;
         /**
         /**
          * Utility function to easily create a checkbox with a header
          * Utility function to easily create a checkbox with a header
          * @param title defines the label to use for the header
          * @param title defines the label to use for the header
@@ -1964,12 +2036,27 @@ declare module BABYLON.GUI {
     }
     }
 }
 }
 declare module BABYLON.GUI {
 declare module BABYLON.GUI {
+    /** @hidden */
+    export class TextWrapper {
+        private _text;
+        private _characters;
+        get text(): string;
+        set text(txt: string);
+        get length(): number;
+        removePart(idxStart: number, idxEnd: number, insertTxt?: string): void;
+        charAt(idx: number): string;
+        substr(from: number, length?: number): string;
+        substring(from: number, to?: number): string;
+        isWord(index: number): boolean;
+    }
+}
+declare module BABYLON.GUI {
     /**
     /**
      * Class used to create input text control
      * Class used to create input text control
      */
      */
     export class InputText extends Control implements IFocusableControl {
     export class InputText extends Control implements IFocusableControl {
         name?: string | undefined;
         name?: string | undefined;
-        private _text;
+        private _textWrapper;
         private _placeholderText;
         private _placeholderText;
         private _background;
         private _background;
         private _focusedBackground;
         private _focusedBackground;
@@ -2079,6 +2166,7 @@ declare module BABYLON.GUI {
         /** Gets or sets the text displayed in the control */
         /** Gets or sets the text displayed in the control */
         get text(): string;
         get text(): string;
         set text(value: string);
         set text(value: string);
+        private _textHasChanged;
         /** Gets or sets control width */
         /** Gets or sets control width */
         get width(): string | number;
         get width(): string | number;
         set width(value: string | number);
         set width(value: string | number);
@@ -2118,10 +2206,10 @@ declare module BABYLON.GUI {
         /** @hidden */
         /** @hidden */
         private _onPasteText;
         private _onPasteText;
         _draw(context: CanvasRenderingContext2D, invalidatedRectangle?: BABYLON.Nullable<Measure>): void;
         _draw(context: CanvasRenderingContext2D, invalidatedRectangle?: BABYLON.Nullable<Measure>): void;
-        _onPointerDown(target: Control, coordinates: BABYLON.Vector2, pointerId: number, buttonIndex: number): boolean;
-        _onPointerMove(target: Control, coordinates: BABYLON.Vector2, pointerId: number): void;
+        _onPointerDown(target: Control, coordinates: BABYLON.Vector2, pointerId: number, buttonIndex: number, pi: BABYLON.PointerInfoBase): boolean;
+        _onPointerMove(target: Control, coordinates: BABYLON.Vector2, pointerId: number, pi: BABYLON.PointerInfoBase): void;
         _onPointerUp(target: Control, coordinates: BABYLON.Vector2, pointerId: number, buttonIndex: number, notifyClick: boolean): void;
         _onPointerUp(target: Control, coordinates: BABYLON.Vector2, pointerId: number, buttonIndex: number, notifyClick: boolean): void;
-        protected _beforeRenderText(text: string): string;
+        protected _beforeRenderText(textWrapper: TextWrapper): TextWrapper;
         dispose(): void;
         dispose(): void;
     }
     }
 }
 }
@@ -2272,13 +2360,13 @@ declare module BABYLON.GUI {
         set value(value: BABYLON.Color3);
         set value(value: BABYLON.Color3);
         /**
         /**
          * Gets or sets control width
          * Gets or sets control width
-         * @see http://doc.babylonjs.com/how_to/gui#position-and-size
+         * @see https://doc.babylonjs.com/how_to/gui#position-and-size
          */
          */
         get width(): string | number;
         get width(): string | number;
         set width(value: string | number);
         set width(value: string | number);
         /**
         /**
          * Gets or sets control height
          * Gets or sets control height
-         * @see http://doc.babylonjs.com/how_to/gui#position-and-size
+         * @see https://doc.babylonjs.com/how_to/gui#position-and-size
          */
          */
         get height(): string | number;
         get height(): string | number;
         /** Gets or sets control height */
         /** Gets or sets control height */
@@ -2304,9 +2392,10 @@ declare module BABYLON.GUI {
         private _updateValueFromPointer;
         private _updateValueFromPointer;
         private _isPointOnSquare;
         private _isPointOnSquare;
         private _isPointOnWheel;
         private _isPointOnWheel;
-        _onPointerDown(target: Control, coordinates: BABYLON.Vector2, pointerId: number, buttonIndex: number): boolean;
-        _onPointerMove(target: Control, coordinates: BABYLON.Vector2, pointerId: number): void;
-        _onPointerUp(target: Control, coordinates: BABYLON.Vector2, pointerId: number, buttonIndex: number, notifyClick: boolean): void;
+        _onPointerDown(target: Control, coordinates: BABYLON.Vector2, pointerId: number, buttonIndex: number, pi: BABYLON.PointerInfoBase): boolean;
+        _onPointerMove(target: Control, coordinates: BABYLON.Vector2, pointerId: number, pi: BABYLON.PointerInfoBase): void;
+        _onPointerUp(target: Control, coordinates: BABYLON.Vector2, pointerId: number, buttonIndex: number, notifyClick: boolean, pi: BABYLON.PointerInfoBase): void;
+        _onCanvasBlur(): void;
         /**
         /**
          * This function expands the color picker by creating a color picker dialog with manual
          * This function expands the color picker by creating a color picker dialog with manual
          * color value input and the ability to save colors into an array to be used later in
          * color value input and the ability to save colors into an array to be used later in
@@ -2353,7 +2442,7 @@ declare module BABYLON.GUI {
      * Class used to create a password control
      * Class used to create a password control
      */
      */
     export class InputPassword extends InputText {
     export class InputPassword extends InputText {
-        protected _beforeRenderText(text: string): string;
+        protected _beforeRenderText(textWrapper: TextWrapper): TextWrapper;
     }
     }
 }
 }
 declare module BABYLON.GUI {
 declare module BABYLON.GUI {
@@ -2433,7 +2522,7 @@ declare module BABYLON.GUI {
         private _controlObserver;
         private _controlObserver;
         private _meshObserver;
         private _meshObserver;
         /** @hidden */
         /** @hidden */
-        _point: BABYLON.Vector2;
+        _point: BABYLON.Vector3;
         /**
         /**
          * Creates a new MultiLinePoint
          * Creates a new MultiLinePoint
          * @param multiLine defines the source MultiLine object
          * @param multiLine defines the source MultiLine object
@@ -2454,10 +2543,10 @@ declare module BABYLON.GUI {
         /** Resets links */
         /** Resets links */
         resetLinks(): void;
         resetLinks(): void;
         /**
         /**
-         * Gets a translation vector
+         * Gets a translation vector with Z component
          * @returns the translation vector
          * @returns the translation vector
          */
          */
-        translate(): BABYLON.Vector2;
+        translate(): BABYLON.Vector3;
         private _translatePoint;
         private _translatePoint;
         /** Release associated resources */
         /** Release associated resources */
         dispose(): void;
         dispose(): void;
@@ -2569,7 +2658,7 @@ declare module BABYLON.GUI {
         constructor(name?: string | undefined);
         constructor(name?: string | undefined);
         protected _getTypeName(): string;
         protected _getTypeName(): string;
         _draw(context: CanvasRenderingContext2D): void;
         _draw(context: CanvasRenderingContext2D): void;
-        _onPointerDown(target: Control, coordinates: BABYLON.Vector2, pointerId: number, buttonIndex: number): boolean;
+        _onPointerDown(target: Control, coordinates: BABYLON.Vector2, pointerId: number, buttonIndex: number, pi: BABYLON.PointerInfoBase): boolean;
         /**
         /**
          * Utility function to easily create a radio button with a header
          * Utility function to easily create a radio button with a header
          * @param title defines the label to use for the header
          * @param title defines the label to use for the header
@@ -2650,9 +2739,10 @@ declare module BABYLON.GUI {
         private _pointerIsDown;
         private _pointerIsDown;
         /** @hidden */
         /** @hidden */
         protected _updateValueFromPointer(x: number, y: number): void;
         protected _updateValueFromPointer(x: number, y: number): void;
-        _onPointerDown(target: Control, coordinates: BABYLON.Vector2, pointerId: number, buttonIndex: number): boolean;
-        _onPointerMove(target: Control, coordinates: BABYLON.Vector2, pointerId: number): void;
+        _onPointerDown(target: Control, coordinates: BABYLON.Vector2, pointerId: number, buttonIndex: number, pi: BABYLON.PointerInfoBase): boolean;
+        _onPointerMove(target: Control, coordinates: BABYLON.Vector2, pointerId: number, pi: BABYLON.PointerInfoBase): void;
         _onPointerUp(target: Control, coordinates: BABYLON.Vector2, pointerId: number, buttonIndex: number, notifyClick: boolean): void;
         _onPointerUp(target: Control, coordinates: BABYLON.Vector2, pointerId: number, buttonIndex: number, notifyClick: boolean): void;
+        _onCanvasBlur(): void;
     }
     }
 }
 }
 declare module BABYLON.GUI {
 declare module BABYLON.GUI {
@@ -2663,6 +2753,7 @@ declare module BABYLON.GUI {
         name?: string | undefined;
         name?: string | undefined;
         private _background;
         private _background;
         private _borderColor;
         private _borderColor;
+        private _thumbColor;
         private _isThumbCircle;
         private _isThumbCircle;
         protected _displayValueBar: boolean;
         protected _displayValueBar: boolean;
         /** Gets or sets a boolean indicating if the value bar must be rendered */
         /** Gets or sets a boolean indicating if the value bar must be rendered */
@@ -2674,6 +2765,9 @@ declare module BABYLON.GUI {
         /** Gets or sets background color */
         /** Gets or sets background color */
         get background(): string;
         get background(): string;
         set background(value: string);
         set background(value: string);
+        /** Gets or sets thumb's color */
+        get thumbColor(): string;
+        set thumbColor(value: string);
         /** Gets or sets a boolean indicating if the thumb should be round or square */
         /** Gets or sets a boolean indicating if the thumb should be round or square */
         get isThumbCircle(): boolean;
         get isThumbCircle(): boolean;
         set isThumbCircle(value: boolean);
         set isThumbCircle(value: boolean);
@@ -2783,7 +2877,7 @@ declare module BABYLON.GUI {
         _setSelectorButtonBackground(selectorNb: number, color: string): void;
         _setSelectorButtonBackground(selectorNb: number, color: string): void;
     }
     }
     /** Class used to hold the controls for the checkboxes, radio buttons and sliders
     /** Class used to hold the controls for the checkboxes, radio buttons and sliders
-     * @see http://doc.babylonjs.com/how_to/selector
+     * @see https://doc.babylonjs.com/how_to/selector
     */
     */
     export class SelectionPanel extends Rectangle {
     export class SelectionPanel extends Rectangle {
         /** name of SelectionPanel */
         /** name of SelectionPanel */
@@ -2811,6 +2905,8 @@ declare module BABYLON.GUI {
         /** an array of SelectionGroups */
         /** an array of SelectionGroups */
         groups?: SelectorGroup[]);
         groups?: SelectorGroup[]);
         protected _getTypeName(): string;
         protected _getTypeName(): string;
+        /** Gets the (stack) panel of the SelectionPanel  */
+        get panel(): StackPanel;
         /** Gets or sets the headerColor */
         /** Gets or sets the headerColor */
         get headerColor(): string;
         get headerColor(): string;
         set headerColor(color: string);
         set headerColor(color: string);
@@ -2919,6 +3015,7 @@ declare module BABYLON.GUI {
         private _dispatchInBuckets;
         private _dispatchInBuckets;
         private _updateMeasures;
         private _updateMeasures;
         private _updateChildrenMeasures;
         private _updateChildrenMeasures;
+        private _restoreMeasures;
         /**
         /**
         * Creates a new ScrollViewerWindow
         * Creates a new ScrollViewerWindow
         * @param name of ScrollViewerWindow
         * @param name of ScrollViewerWindow
@@ -2964,7 +3061,7 @@ declare module BABYLON.GUI {
         private _originY;
         private _originY;
         /** @hidden */
         /** @hidden */
         protected _updateValueFromPointer(x: number, y: number): void;
         protected _updateValueFromPointer(x: number, y: number): void;
-        _onPointerDown(target: Control, coordinates: BABYLON.Vector2, pointerId: number, buttonIndex: number): boolean;
+        _onPointerDown(target: Control, coordinates: BABYLON.Vector2, pointerId: number, buttonIndex: number, pi: BABYLON.PointerInfoBase): boolean;
     }
     }
 }
 }
 declare module BABYLON.GUI {
 declare module BABYLON.GUI {
@@ -3021,7 +3118,7 @@ declare module BABYLON.GUI {
         private _originY;
         private _originY;
         /** @hidden */
         /** @hidden */
         protected _updateValueFromPointer(x: number, y: number): void;
         protected _updateValueFromPointer(x: number, y: number): void;
-        _onPointerDown(target: Control, coordinates: BABYLON.Vector2, pointerId: number, buttonIndex: number): boolean;
+        _onPointerDown(target: Control, coordinates: BABYLON.Vector2, pointerId: number, buttonIndex: number, pi: BABYLON.PointerInfoBase): boolean;
     }
     }
 }
 }
 declare module BABYLON.GUI {
 declare module BABYLON.GUI {
@@ -3056,6 +3153,8 @@ declare module BABYLON.GUI {
         private _barImageHeight;
         private _barImageHeight;
         private _horizontalBarImageHeight;
         private _horizontalBarImageHeight;
         private _verticalBarImageHeight;
         private _verticalBarImageHeight;
+        private _oldWindowContentsWidth;
+        private _oldWindowContentsHeight;
         /**
         /**
          * Gets the horizontal scrollbar
          * Gets the horizontal scrollbar
          */
          */
@@ -3457,7 +3556,7 @@ declare module BABYLON.GUI {
 declare module BABYLON.GUI {
 declare module BABYLON.GUI {
     /**
     /**
      * Class used to manage 3D user interface
      * Class used to manage 3D user interface
-     * @see http://doc.babylonjs.com/how_to/gui3d
+     * @see https://doc.babylonjs.com/how_to/gui3d
      */
      */
     export class GUI3DManager implements BABYLON.IDisposable {
     export class GUI3DManager implements BABYLON.IDisposable {
         private _scene;
         private _scene;
@@ -3599,19 +3698,19 @@ declare module BABYLON.GUI {
         private _behaviors;
         private _behaviors;
         /**
         /**
          * Gets the list of attached behaviors
          * Gets the list of attached behaviors
-         * @see http://doc.babylonjs.com/features/behaviour
+         * @see https://doc.babylonjs.com/features/behaviour
          */
          */
         get behaviors(): BABYLON.Behavior<Control3D>[];
         get behaviors(): BABYLON.Behavior<Control3D>[];
         /**
         /**
          * Attach a behavior to the control
          * Attach a behavior to the control
-         * @see http://doc.babylonjs.com/features/behaviour
+         * @see https://doc.babylonjs.com/features/behaviour
          * @param behavior defines the behavior to attach
          * @param behavior defines the behavior to attach
          * @returns the current control
          * @returns the current control
          */
          */
         addBehavior(behavior: BABYLON.Behavior<Control3D>): Control3D;
         addBehavior(behavior: BABYLON.Behavior<Control3D>): Control3D;
         /**
         /**
          * Remove an attached behavior
          * Remove an attached behavior
-         * @see http://doc.babylonjs.com/features/behaviour
+         * @see https://doc.babylonjs.com/features/behaviour
          * @param behavior defines the behavior to attach
          * @param behavior defines the behavior to attach
          * @returns the current control
          * @returns the current control
          */
          */
@@ -3619,7 +3718,7 @@ declare module BABYLON.GUI {
         /**
         /**
          * Gets an attached behavior by name
          * Gets an attached behavior by name
          * @param name defines the name of the behavior to look for
          * @param name defines the name of the behavior to look for
-         * @see http://doc.babylonjs.com/features/behaviour
+         * @see https://doc.babylonjs.com/features/behaviour
          * @returns null if behavior was not found else the requested behavior
          * @returns null if behavior was not found else the requested behavior
          */
          */
         getBehaviorByName(name: string): BABYLON.Nullable<BABYLON.Behavior<Control3D>>;
         getBehaviorByName(name: string): BABYLON.Nullable<BABYLON.Behavior<Control3D>>;
@@ -3856,10 +3955,6 @@ declare module BABYLON.GUI {
          */
          */
         innerGlowColor: BABYLON.Color3;
         innerGlowColor: BABYLON.Color3;
         /**
         /**
-         * Gets or sets alpha value (default is 1.0)
-         */
-        alpha: number;
-        /**
          * Gets or sets the albedo color (Default is BABYLON.Color3(0.3, 0.35, 0.4))
          * Gets or sets the albedo color (Default is BABYLON.Color3(0.3, 0.35, 0.4))
          */
          */
         albedoColor: BABYLON.Color3;
         albedoColor: BABYLON.Color3;

File diff suppressed because it is too large
+ 1120 - 689
dist/gui/babylon.gui.js


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


File diff suppressed because it is too large
+ 12 - 12
dist/gui/babylon.gui.min.js


File diff suppressed because it is too large
+ 402 - 199
dist/gui/babylon.gui.module.d.ts


+ 2 - 2
dist/gui/package.json

@@ -4,7 +4,7 @@
     },
     },
     "name": "babylonjs-gui",
     "name": "babylonjs-gui",
     "description": "The Babylon.js GUI library is an extension you can use to generate interactive user interface. It is build on top of the DynamicTexture.",
     "description": "The Babylon.js GUI library is an extension you can use to generate interactive user interface. It is build on top of the DynamicTexture.",
-    "version": "4.1.0",
+    "version": "4.2.0",
     "repository": {
     "repository": {
         "type": "git",
         "type": "git",
         "url": "https://github.com/BabylonJS/Babylon.js.git"
         "url": "https://github.com/BabylonJS/Babylon.js.git"
@@ -28,7 +28,7 @@
     ],
     ],
     "license": "Apache-2.0",
     "license": "Apache-2.0",
     "dependencies": {
     "dependencies": {
-        "babylonjs": "4.1.0"
+        "babylonjs": "4.2.0"
     },
     },
     "engines": {
     "engines": {
         "node": "*"
         "node": "*"

File diff suppressed because it is too large
+ 24 - 28
dist/inspector/babylon.inspector.bundle.js


File diff suppressed because it is too large
+ 32690 - 22832
dist/inspector/babylon.inspector.bundle.max.js


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


File diff suppressed because it is too large
+ 2073 - 123
dist/inspector/babylon.inspector.d.ts


File diff suppressed because it is too large
+ 5939 - 1793
dist/inspector/babylon.inspector.module.d.ts


+ 11 - 9
dist/inspector/package.json

@@ -4,7 +4,7 @@
     },
     },
     "name": "babylonjs-inspector",
     "name": "babylonjs-inspector",
     "description": "The Babylon.js inspector.",
     "description": "The Babylon.js inspector.",
-    "version": "4.1.0",
+    "version": "4.2.0",
     "repository": {
     "repository": {
         "type": "git",
         "type": "git",
         "url": "https://github.com/BabylonJS/Babylon.js.git"
         "url": "https://github.com/BabylonJS/Babylon.js.git"
@@ -29,14 +29,16 @@
     ],
     ],
     "license": "Apache-2.0",
     "license": "Apache-2.0",
     "dependencies": {
     "dependencies": {
-        "babylonjs": "4.1.0",
-        "babylonjs-gui": "4.1.0",
-        "babylonjs-loaders": "4.1.0",
-        "babylonjs-materials": "4.1.0",
-        "babylonjs-serializers": "4.1.0",
-        "babylonjs-gltf2interface": "4.1.0",
-        "@types/react": "~16.7.3",
-        "@types/react-dom": "~16.0.9"
+        "babylonjs": "4.2.0",
+        "babylonjs-gui": "4.2.0",
+        "babylonjs-loaders": "4.2.0",
+        "babylonjs-materials": "4.2.0",
+        "babylonjs-serializers": "4.2.0",
+        "babylonjs-gltf2interface": "4.2.0"
+    },
+    "peerDependencies": {
+        "@types/react": ">=16.7.3",
+        "@types/react-dom": ">=16.0.9"
     },
     },
     "engines": {
     "engines": {
         "node": "*"
         "node": "*"

File diff suppressed because it is too large
+ 22 - 0
dist/ktx2Transcoders/msc_basis_transcoder.js


BIN
dist/ktx2Transcoders/msc_basis_transcoder.wasm


BIN
dist/ktx2Transcoders/uastc_astc.wasm


BIN
dist/ktx2Transcoders/uastc_bc7.wasm


BIN
dist/ktx2Transcoders/uastc_rgba32_srgb.wasm


BIN
dist/ktx2Transcoders/uastc_rgba32_unorm.wasm


+ 203 - 68
dist/loaders/babylon.glTF1FileLoader.js

@@ -100,7 +100,7 @@ return /******/ (function(modules) { // webpackBootstrap
 /*!***********************************************************!*\
 /*!***********************************************************!*\
   !*** C:/Repos/Babylon.js/node_modules/tslib/tslib.es6.js ***!
   !*** C:/Repos/Babylon.js/node_modules/tslib/tslib.es6.js ***!
   \***********************************************************/
   \***********************************************************/
-/*! exports provided: __extends, __assign, __rest, __decorate, __param, __metadata, __awaiter, __generator, __exportStar, __values, __read, __spread, __spreadArrays, __await, __asyncGenerator, __asyncDelegator, __asyncValues, __makeTemplateObject, __importStar, __importDefault */
+/*! exports provided: __extends, __assign, __rest, __decorate, __param, __metadata, __awaiter, __generator, __createBinding, __exportStar, __values, __read, __spread, __spreadArrays, __await, __asyncGenerator, __asyncDelegator, __asyncValues, __makeTemplateObject, __importStar, __importDefault, __classPrivateFieldGet, __classPrivateFieldSet */
 /***/ (function(module, __webpack_exports__, __webpack_require__) {
 /***/ (function(module, __webpack_exports__, __webpack_require__) {
 
 
 "use strict";
 "use strict";
@@ -113,6 +113,7 @@ __webpack_require__.r(__webpack_exports__);
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "__metadata", function() { return __metadata; });
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "__metadata", function() { return __metadata; });
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "__awaiter", function() { return __awaiter; });
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "__awaiter", function() { return __awaiter; });
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "__generator", function() { return __generator; });
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "__generator", function() { return __generator; });
+/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "__createBinding", function() { return __createBinding; });
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "__exportStar", function() { return __exportStar; });
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "__exportStar", function() { return __exportStar; });
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "__values", function() { return __values; });
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "__values", function() { return __values; });
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "__read", function() { return __read; });
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "__read", function() { return __read; });
@@ -125,26 +126,28 @@ __webpack_require__.r(__webpack_exports__);
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "__makeTemplateObject", function() { return __makeTemplateObject; });
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "__makeTemplateObject", function() { return __makeTemplateObject; });
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "__importStar", function() { return __importStar; });
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "__importStar", function() { return __importStar; });
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "__importDefault", function() { return __importDefault; });
 /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "__importDefault", function() { return __importDefault; });
+/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "__classPrivateFieldGet", function() { return __classPrivateFieldGet; });
+/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "__classPrivateFieldSet", function() { return __classPrivateFieldSet; });
 /*! *****************************************************************************
 /*! *****************************************************************************
-Copyright (c) Microsoft Corporation. All rights reserved.
-Licensed under the Apache License, Version 2.0 (the "License"); you may not use
-this file except in compliance with the License. You may obtain a copy of the
-License at http://www.apache.org/licenses/LICENSE-2.0
-
-THIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED
-WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE,
-MERCHANTABLITY OR NON-INFRINGEMENT.
-
-See the Apache Version 2.0 License for specific language governing permissions
-and limitations under the License.
+Copyright (c) Microsoft Corporation.
+
+Permission to use, copy, modify, and/or distribute this software for any
+purpose with or without fee is hereby granted.
+
+THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
+REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
+INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
+OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+PERFORMANCE OF THIS SOFTWARE.
 ***************************************************************************** */
 ***************************************************************************** */
 /* global Reflect, Promise */
 /* global Reflect, Promise */
 
 
 var extendStatics = function(d, b) {
 var extendStatics = function(d, b) {
     extendStatics = Object.setPrototypeOf ||
     extendStatics = Object.setPrototypeOf ||
         ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
         ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
-        function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
+        function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
     return extendStatics(d, b);
     return extendStatics(d, b);
 };
 };
 
 
@@ -193,10 +196,11 @@ function __metadata(metadataKey, metadataValue) {
 }
 }
 
 
 function __awaiter(thisArg, _arguments, P, generator) {
 function __awaiter(thisArg, _arguments, P, generator) {
+    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
     return new (P || (P = Promise))(function (resolve, reject) {
     return new (P || (P = Promise))(function (resolve, reject) {
         function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
         function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
         function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
         function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
-        function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); }
+        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
         step((generator = generator.apply(thisArg, _arguments || [])).next());
         step((generator = generator.apply(thisArg, _arguments || [])).next());
     });
     });
 }
 }
@@ -229,19 +233,28 @@ function __generator(thisArg, body) {
     }
     }
 }
 }
 
 
-function __exportStar(m, exports) {
-    for (var p in m) if (!exports.hasOwnProperty(p)) exports[p] = m[p];
+var __createBinding = Object.create ? (function(o, m, k, k2) {
+    if (k2 === undefined) k2 = k;
+    Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
+}) : (function(o, m, k, k2) {
+    if (k2 === undefined) k2 = k;
+    o[k2] = m[k];
+});
+
+function __exportStar(m, o) {
+    for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(o, p)) __createBinding(o, m, p);
 }
 }
 
 
 function __values(o) {
 function __values(o) {
-    var m = typeof Symbol === "function" && o[Symbol.iterator], i = 0;
+    var s = typeof Symbol === "function" && Symbol.iterator, m = s && o[s], i = 0;
     if (m) return m.call(o);
     if (m) return m.call(o);
-    return {
+    if (o && typeof o.length === "number") return {
         next: function () {
         next: function () {
             if (o && i >= o.length) o = void 0;
             if (o && i >= o.length) o = void 0;
             return { value: o && o[i++], done: !o };
             return { value: o && o[i++], done: !o };
         }
         }
     };
     };
+    throw new TypeError(s ? "Object is not iterable." : "Symbol.iterator is not defined.");
 }
 }
 
 
 function __read(o, n) {
 function __read(o, n) {
@@ -310,17 +323,38 @@ function __makeTemplateObject(cooked, raw) {
     return cooked;
     return cooked;
 };
 };
 
 
+var __setModuleDefault = Object.create ? (function(o, v) {
+    Object.defineProperty(o, "default", { enumerable: true, value: v });
+}) : function(o, v) {
+    o["default"] = v;
+};
+
 function __importStar(mod) {
 function __importStar(mod) {
     if (mod && mod.__esModule) return mod;
     if (mod && mod.__esModule) return mod;
     var result = {};
     var result = {};
-    if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k];
-    result.default = mod;
+    if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
+    __setModuleDefault(result, mod);
     return result;
     return result;
 }
 }
 
 
 function __importDefault(mod) {
 function __importDefault(mod) {
     return (mod && mod.__esModule) ? mod : { default: mod };
     return (mod && mod.__esModule) ? mod : { default: mod };
 }
 }
+
+function __classPrivateFieldGet(receiver, privateMap) {
+    if (!privateMap.has(receiver)) {
+        throw new TypeError("attempted to get private field on non-instance");
+    }
+    return privateMap.get(receiver);
+}
+
+function __classPrivateFieldSet(receiver, privateMap, value) {
+    if (!privateMap.has(receiver)) {
+        throw new TypeError("attempted to set private field on non-instance");
+    }
+    privateMap.set(receiver, value);
+    return value;
+}
 
 
 
 
 /***/ }),
 /***/ }),
@@ -1219,14 +1253,14 @@ var importNode = function (gltfRuntime, node, id, parent) {
                 var orthoCamera = new babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["FreeCamera"](node.camera, babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["Vector3"].Zero(), gltfRuntime.scene, false);
                 var orthoCamera = new babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["FreeCamera"](node.camera, babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["Vector3"].Zero(), gltfRuntime.scene, false);
                 orthoCamera.name = node.name || "";
                 orthoCamera.name = node.name || "";
                 orthoCamera.mode = babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["Camera"].ORTHOGRAPHIC_CAMERA;
                 orthoCamera.mode = babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["Camera"].ORTHOGRAPHIC_CAMERA;
-                orthoCamera.attachControl(gltfRuntime.scene.getEngine().getInputElement());
+                orthoCamera.attachControl();
                 lastNode = orthoCamera;
                 lastNode = orthoCamera;
             }
             }
             else if (camera.type === "perspective") {
             else if (camera.type === "perspective") {
                 var perspectiveCamera = camera[camera.type];
                 var perspectiveCamera = camera[camera.type];
                 var persCamera = new babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["FreeCamera"](node.camera, babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["Vector3"].Zero(), gltfRuntime.scene, false);
                 var persCamera = new babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["FreeCamera"](node.camera, babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["Vector3"].Zero(), gltfRuntime.scene, false);
                 persCamera.name = node.name || "";
                 persCamera.name = node.name || "";
-                persCamera.attachControl(gltfRuntime.scene.getEngine().getInputElement());
+                persCamera.attachControl();
                 if (!perspectiveCamera.aspectRatio) {
                 if (!perspectiveCamera.aspectRatio) {
                     perspectiveCamera.aspectRatio = gltfRuntime.scene.getEngine().getRenderWidth() / gltfRuntime.scene.getEngine().getRenderHeight();
                     perspectiveCamera.aspectRatio = gltfRuntime.scene.getEngine().getRenderWidth() / gltfRuntime.scene.getEngine().getRenderHeight();
                 }
                 }
@@ -1867,7 +1901,8 @@ var GLTFLoader = /** @class */ (function () {
                     skeletons: skeletons,
                     skeletons: skeletons,
                     animationGroups: [],
                     animationGroups: [],
                     lights: [],
                     lights: [],
-                    transformNodes: []
+                    transformNodes: [],
+                    geometries: []
                 });
                 });
             }, onProgress, function (message) {
             }, onProgress, function (message) {
                 reject(new Error(message));
                 reject(new Error(message));
@@ -2011,7 +2046,7 @@ var GLTFLoaderExtension = /** @class */ (function () {
         get: function () {
         get: function () {
             return this._name;
             return this._name;
         },
         },
-        enumerable: true,
+        enumerable: false,
         configurable: true
         configurable: true
     });
     });
     /**
     /**
@@ -2730,6 +2765,7 @@ __webpack_require__.r(__webpack_exports__);
 
 
 
 
 
 
+
 /**
 /**
  * Mode that determines the coordinate system to use.
  * Mode that determines the coordinate system to use.
  */
  */
@@ -2832,11 +2868,20 @@ var GLTFFileLoader = /** @class */ (function () {
          */
          */
         this.createInstances = true;
         this.createInstances = true;
         /**
         /**
+         * Defines if the loader should always compute the bounding boxes of meshes and not use the min/max values from the position accessor. Defaults to false.
+         */
+        this.alwaysComputeBoundingBox = false;
+        /**
+         * If true, load all materials defined in the file, even if not used by any mesh. Defaults to false.
+         */
+        this.loadAllMaterials = false;
+        /**
          * Function called before loading a url referenced by the asset.
          * Function called before loading a url referenced by the asset.
          */
          */
         this.preprocessUrlAsync = function (url) { return Promise.resolve(url); };
         this.preprocessUrlAsync = function (url) { return Promise.resolve(url); };
         /**
         /**
          * Observable raised when the loader creates a mesh after parsing the glTF properties of the mesh.
          * Observable raised when the loader creates a mesh after parsing the glTF properties of the mesh.
+         * Note that the observable is raised as soon as the mesh object is created, meaning some data may not have been setup yet for this mesh (vertex data, morph targets, material, ...)
          */
          */
         this.onMeshLoadedObservable = new babylonjs_Misc_observable__WEBPACK_IMPORTED_MODULE_0__["Observable"]();
         this.onMeshLoadedObservable = new babylonjs_Misc_observable__WEBPACK_IMPORTED_MODULE_0__["Observable"]();
         /**
         /**
@@ -2879,6 +2924,7 @@ var GLTFFileLoader = /** @class */ (function () {
          */
          */
         this.onValidatedObservable = new babylonjs_Misc_observable__WEBPACK_IMPORTED_MODULE_0__["Observable"]();
         this.onValidatedObservable = new babylonjs_Misc_observable__WEBPACK_IMPORTED_MODULE_0__["Observable"]();
         this._loader = null;
         this._loader = null;
+        this._requests = new Array();
         /**
         /**
          * Name of the loader ("gltf")
          * Name of the loader ("gltf")
          */
          */
@@ -2908,12 +2954,13 @@ var GLTFFileLoader = /** @class */ (function () {
             }
             }
             this._onParsedObserver = this.onParsedObservable.add(callback);
             this._onParsedObserver = this.onParsedObservable.add(callback);
         },
         },
-        enumerable: true,
+        enumerable: false,
         configurable: true
         configurable: true
     });
     });
     Object.defineProperty(GLTFFileLoader.prototype, "onMeshLoaded", {
     Object.defineProperty(GLTFFileLoader.prototype, "onMeshLoaded", {
         /**
         /**
          * Callback raised when the loader creates a mesh after parsing the glTF properties of the mesh.
          * Callback raised when the loader creates a mesh after parsing the glTF properties of the mesh.
+         * Note that the callback is called as soon as the mesh object is created, meaning some data may not have been setup yet for this mesh (vertex data, morph targets, material, ...)
          */
          */
         set: function (callback) {
         set: function (callback) {
             if (this._onMeshLoadedObserver) {
             if (this._onMeshLoadedObserver) {
@@ -2921,7 +2968,7 @@ var GLTFFileLoader = /** @class */ (function () {
             }
             }
             this._onMeshLoadedObserver = this.onMeshLoadedObservable.add(callback);
             this._onMeshLoadedObserver = this.onMeshLoadedObservable.add(callback);
         },
         },
-        enumerable: true,
+        enumerable: false,
         configurable: true
         configurable: true
     });
     });
     Object.defineProperty(GLTFFileLoader.prototype, "onTextureLoaded", {
     Object.defineProperty(GLTFFileLoader.prototype, "onTextureLoaded", {
@@ -2934,7 +2981,7 @@ var GLTFFileLoader = /** @class */ (function () {
             }
             }
             this._onTextureLoadedObserver = this.onTextureLoadedObservable.add(callback);
             this._onTextureLoadedObserver = this.onTextureLoadedObservable.add(callback);
         },
         },
-        enumerable: true,
+        enumerable: false,
         configurable: true
         configurable: true
     });
     });
     Object.defineProperty(GLTFFileLoader.prototype, "onMaterialLoaded", {
     Object.defineProperty(GLTFFileLoader.prototype, "onMaterialLoaded", {
@@ -2947,7 +2994,7 @@ var GLTFFileLoader = /** @class */ (function () {
             }
             }
             this._onMaterialLoadedObserver = this.onMaterialLoadedObservable.add(callback);
             this._onMaterialLoadedObserver = this.onMaterialLoadedObservable.add(callback);
         },
         },
-        enumerable: true,
+        enumerable: false,
         configurable: true
         configurable: true
     });
     });
     Object.defineProperty(GLTFFileLoader.prototype, "onCameraLoaded", {
     Object.defineProperty(GLTFFileLoader.prototype, "onCameraLoaded", {
@@ -2960,7 +3007,7 @@ var GLTFFileLoader = /** @class */ (function () {
             }
             }
             this._onCameraLoadedObserver = this.onCameraLoadedObservable.add(callback);
             this._onCameraLoadedObserver = this.onCameraLoadedObservable.add(callback);
         },
         },
-        enumerable: true,
+        enumerable: false,
         configurable: true
         configurable: true
     });
     });
     Object.defineProperty(GLTFFileLoader.prototype, "onComplete", {
     Object.defineProperty(GLTFFileLoader.prototype, "onComplete", {
@@ -2975,7 +3022,7 @@ var GLTFFileLoader = /** @class */ (function () {
             }
             }
             this._onCompleteObserver = this.onCompleteObservable.add(callback);
             this._onCompleteObserver = this.onCompleteObservable.add(callback);
         },
         },
-        enumerable: true,
+        enumerable: false,
         configurable: true
         configurable: true
     });
     });
     Object.defineProperty(GLTFFileLoader.prototype, "onError", {
     Object.defineProperty(GLTFFileLoader.prototype, "onError", {
@@ -2988,7 +3035,7 @@ var GLTFFileLoader = /** @class */ (function () {
             }
             }
             this._onErrorObserver = this.onErrorObservable.add(callback);
             this._onErrorObserver = this.onErrorObservable.add(callback);
         },
         },
-        enumerable: true,
+        enumerable: false,
         configurable: true
         configurable: true
     });
     });
     Object.defineProperty(GLTFFileLoader.prototype, "onDispose", {
     Object.defineProperty(GLTFFileLoader.prototype, "onDispose", {
@@ -3001,7 +3048,7 @@ var GLTFFileLoader = /** @class */ (function () {
             }
             }
             this._onDisposeObserver = this.onDisposeObservable.add(callback);
             this._onDisposeObserver = this.onDisposeObservable.add(callback);
         },
         },
-        enumerable: true,
+        enumerable: false,
         configurable: true
         configurable: true
     });
     });
     Object.defineProperty(GLTFFileLoader.prototype, "onExtensionLoaded", {
     Object.defineProperty(GLTFFileLoader.prototype, "onExtensionLoaded", {
@@ -3014,7 +3061,7 @@ var GLTFFileLoader = /** @class */ (function () {
             }
             }
             this._onExtensionLoadedObserver = this.onExtensionLoadedObservable.add(callback);
             this._onExtensionLoadedObserver = this.onExtensionLoadedObservable.add(callback);
         },
         },
-        enumerable: true,
+        enumerable: false,
         configurable: true
         configurable: true
     });
     });
     Object.defineProperty(GLTFFileLoader.prototype, "loggingEnabled", {
     Object.defineProperty(GLTFFileLoader.prototype, "loggingEnabled", {
@@ -3036,7 +3083,7 @@ var GLTFFileLoader = /** @class */ (function () {
                 this._log = this._logDisabled;
                 this._log = this._logDisabled;
             }
             }
         },
         },
-        enumerable: true,
+        enumerable: false,
         configurable: true
         configurable: true
     });
     });
     Object.defineProperty(GLTFFileLoader.prototype, "capturePerformanceCounters", {
     Object.defineProperty(GLTFFileLoader.prototype, "capturePerformanceCounters", {
@@ -3060,7 +3107,7 @@ var GLTFFileLoader = /** @class */ (function () {
                 this._endPerformanceCounter = this._endPerformanceCounterDisabled;
                 this._endPerformanceCounter = this._endPerformanceCounterDisabled;
             }
             }
         },
         },
-        enumerable: true,
+        enumerable: false,
         configurable: true
         configurable: true
     });
     });
     Object.defineProperty(GLTFFileLoader.prototype, "onValidated", {
     Object.defineProperty(GLTFFileLoader.prototype, "onValidated", {
@@ -3073,7 +3120,7 @@ var GLTFFileLoader = /** @class */ (function () {
             }
             }
             this._onValidatedObserver = this.onValidatedObservable.add(callback);
             this._onValidatedObserver = this.onValidatedObservable.add(callback);
         },
         },
-        enumerable: true,
+        enumerable: false,
         configurable: true
         configurable: true
     });
     });
     /**
     /**
@@ -3084,12 +3131,12 @@ var GLTFFileLoader = /** @class */ (function () {
             this._loader.dispose();
             this._loader.dispose();
             this._loader = null;
             this._loader = null;
         }
         }
-        this._clear();
-        this.onDisposeObservable.notifyObservers(undefined);
-        this.onDisposeObservable.clear();
-    };
-    /** @hidden */
-    GLTFFileLoader.prototype._clear = function () {
+        for (var _i = 0, _a = this._requests; _i < _a.length; _i++) {
+            var request = _a[_i];
+            request.abort();
+        }
+        this._requests.length = 0;
+        delete this._progressCallback;
         this.preprocessUrlAsync = function (url) { return Promise.resolve(url); };
         this.preprocessUrlAsync = function (url) { return Promise.resolve(url); };
         this.onMeshLoadedObservable.clear();
         this.onMeshLoadedObservable.clear();
         this.onTextureLoadedObservable.clear();
         this.onTextureLoadedObservable.clear();
@@ -3097,45 +3144,43 @@ var GLTFFileLoader = /** @class */ (function () {
         this.onCameraLoadedObservable.clear();
         this.onCameraLoadedObservable.clear();
         this.onCompleteObservable.clear();
         this.onCompleteObservable.clear();
         this.onExtensionLoadedObservable.clear();
         this.onExtensionLoadedObservable.clear();
+        this.onDisposeObservable.notifyObservers(undefined);
+        this.onDisposeObservable.clear();
     };
     };
     /** @hidden */
     /** @hidden */
     GLTFFileLoader.prototype.requestFile = function (scene, url, onSuccess, onProgress, useArrayBuffer, onError) {
     GLTFFileLoader.prototype.requestFile = function (scene, url, onSuccess, onProgress, useArrayBuffer, onError) {
         var _this = this;
         var _this = this;
+        this._progressCallback = onProgress;
         if (useArrayBuffer) {
         if (useArrayBuffer) {
             if (this.useRangeRequests) {
             if (this.useRangeRequests) {
                 if (this.validate) {
                 if (this.validate) {
                     babylonjs_Misc_observable__WEBPACK_IMPORTED_MODULE_0__["Logger"].Warn("glTF validation is not supported when range requests are enabled");
                     babylonjs_Misc_observable__WEBPACK_IMPORTED_MODULE_0__["Logger"].Warn("glTF validation is not supported when range requests are enabled");
                 }
                 }
-                var fileRequests_1 = new Array();
-                var aggregatedFileRequest_1 = {
-                    abort: function () { return fileRequests_1.forEach(function (fileRequest) { return fileRequest.abort(); }); },
+                var fileRequest_1 = {
+                    abort: function () { },
                     onCompleteObservable: new babylonjs_Misc_observable__WEBPACK_IMPORTED_MODULE_0__["Observable"]()
                     onCompleteObservable: new babylonjs_Misc_observable__WEBPACK_IMPORTED_MODULE_0__["Observable"]()
                 };
                 };
-                var dataBuffer_1 = {
+                var dataBuffer = {
                     readAsync: function (byteOffset, byteLength) {
                     readAsync: function (byteOffset, byteLength) {
                         return new Promise(function (resolve, reject) {
                         return new Promise(function (resolve, reject) {
-                            fileRequests_1.push(scene._requestFile(url, function (data, webRequest) {
-                                var contentRange = webRequest.getResponseHeader("Content-Range");
-                                if (contentRange) {
-                                    dataBuffer_1.byteLength = Number(contentRange.split("/")[1]);
-                                }
+                            _this._requestFile(url, scene, function (data) {
                                 resolve(new Uint8Array(data));
                                 resolve(new Uint8Array(data));
-                            }, onProgress, true, true, function (error) {
+                            }, true, function (error) {
                                 reject(error);
                                 reject(error);
                             }, function (webRequest) {
                             }, function (webRequest) {
                                 webRequest.setRequestHeader("Range", "bytes=" + byteOffset + "-" + (byteOffset + byteLength - 1));
                                 webRequest.setRequestHeader("Range", "bytes=" + byteOffset + "-" + (byteOffset + byteLength - 1));
-                            }));
+                            });
                         });
                         });
                     },
                     },
                     byteLength: 0
                     byteLength: 0
                 };
                 };
-                this._unpackBinaryAsync(new babylonjs_Misc_observable__WEBPACK_IMPORTED_MODULE_0__["DataReader"](dataBuffer_1)).then(function (loaderData) {
-                    aggregatedFileRequest_1.onCompleteObservable.notifyObservers(aggregatedFileRequest_1);
+                this._unpackBinaryAsync(new babylonjs_Misc_observable__WEBPACK_IMPORTED_MODULE_0__["DataReader"](dataBuffer)).then(function (loaderData) {
+                    fileRequest_1.onCompleteObservable.notifyObservers(fileRequest_1);
                     onSuccess(loaderData);
                     onSuccess(loaderData);
                 }, onError);
                 }, onError);
-                return aggregatedFileRequest_1;
+                return fileRequest_1;
             }
             }
-            return scene._requestFile(url, function (data, request) {
+            return this._requestFile(url, scene, function (data, request) {
                 var arrayBuffer = data;
                 var arrayBuffer = data;
                 _this._unpackBinaryAsync(new babylonjs_Misc_observable__WEBPACK_IMPORTED_MODULE_0__["DataReader"]({
                 _this._unpackBinaryAsync(new babylonjs_Misc_observable__WEBPACK_IMPORTED_MODULE_0__["DataReader"]({
                     readAsync: function (byteOffset, byteLength) { return Promise.resolve(new Uint8Array(arrayBuffer, byteOffset, byteLength)); },
                     readAsync: function (byteOffset, byteLength) { return Promise.resolve(new Uint8Array(arrayBuffer, byteOffset, byteLength)); },
@@ -3143,12 +3188,12 @@ var GLTFFileLoader = /** @class */ (function () {
                 })).then(function (loaderData) {
                 })).then(function (loaderData) {
                     onSuccess(loaderData, request);
                     onSuccess(loaderData, request);
                 }, onError);
                 }, onError);
-            }, onProgress, true, true, onError);
+            }, true, onError);
         }
         }
-        return scene._requestFile(url, function (data, response) {
+        return this._requestFile(url, scene, function (data, request) {
             _this._validate(scene, data, babylonjs_Misc_observable__WEBPACK_IMPORTED_MODULE_0__["Tools"].GetFolderPath(url), babylonjs_Misc_observable__WEBPACK_IMPORTED_MODULE_0__["Tools"].GetFilename(url));
             _this._validate(scene, data, babylonjs_Misc_observable__WEBPACK_IMPORTED_MODULE_0__["Tools"].GetFolderPath(url), babylonjs_Misc_observable__WEBPACK_IMPORTED_MODULE_0__["Tools"].GetFilename(url));
-            onSuccess({ json: _this._parseJson(data) }, response);
-        }, onProgress, true, false, onError);
+            onSuccess({ json: _this._parseJson(data) }, request);
+        }, useArrayBuffer, onError);
     };
     };
     /** @hidden */
     /** @hidden */
     GLTFFileLoader.prototype.readFile = function (scene, file, onSuccess, onProgress, useArrayBuffer, onError) {
     GLTFFileLoader.prototype.readFile = function (scene, file, onSuccess, onProgress, useArrayBuffer, onError) {
@@ -3197,17 +3242,43 @@ var GLTFFileLoader = /** @class */ (function () {
             _this.onParsedObservable.clear();
             _this.onParsedObservable.clear();
             _this._log("Loading " + (fileName || ""));
             _this._log("Loading " + (fileName || ""));
             _this._loader = _this._getLoader(data);
             _this._loader = _this._getLoader(data);
+            // Prepare the asset container.
+            var container = new babylonjs_Misc_observable__WEBPACK_IMPORTED_MODULE_0__["AssetContainer"](scene);
             // Get materials/textures when loading to add to container
             // Get materials/textures when loading to add to container
             var materials = [];
             var materials = [];
             _this.onMaterialLoadedObservable.add(function (material) {
             _this.onMaterialLoadedObservable.add(function (material) {
                 materials.push(material);
                 materials.push(material);
+                material.onDisposeObservable.addOnce(function () {
+                    var index = container.materials.indexOf(material);
+                    if (index > -1) {
+                        container.materials.splice(index, 1);
+                    }
+                    index = materials.indexOf(material);
+                    if (index > -1) {
+                        materials.splice(index, 1);
+                    }
+                });
             });
             });
             var textures = [];
             var textures = [];
             _this.onTextureLoadedObservable.add(function (texture) {
             _this.onTextureLoadedObservable.add(function (texture) {
                 textures.push(texture);
                 textures.push(texture);
+                texture.onDisposeObservable.addOnce(function () {
+                    var index = container.textures.indexOf(texture);
+                    if (index > -1) {
+                        container.textures.splice(index, 1);
+                    }
+                    index = textures.indexOf(texture);
+                    if (index > -1) {
+                        textures.splice(index, 1);
+                    }
+                });
+            });
+            var cameras = [];
+            _this.onCameraLoadedObservable.add(function (camera) {
+                cameras.push(camera);
             });
             });
             return _this._loader.importMeshAsync(null, scene, true, data, rootUrl, onProgress, fileName).then(function (result) {
             return _this._loader.importMeshAsync(null, scene, true, data, rootUrl, onProgress, fileName).then(function (result) {
-                var container = new babylonjs_Misc_observable__WEBPACK_IMPORTED_MODULE_0__["AssetContainer"](scene);
+                Array.prototype.push.apply(container.geometries, result.geometries);
                 Array.prototype.push.apply(container.meshes, result.meshes);
                 Array.prototype.push.apply(container.meshes, result.meshes);
                 Array.prototype.push.apply(container.particleSystems, result.particleSystems);
                 Array.prototype.push.apply(container.particleSystems, result.particleSystems);
                 Array.prototype.push.apply(container.skeletons, result.skeletons);
                 Array.prototype.push.apply(container.skeletons, result.skeletons);
@@ -3216,18 +3287,32 @@ var GLTFFileLoader = /** @class */ (function () {
                 Array.prototype.push.apply(container.textures, textures);
                 Array.prototype.push.apply(container.textures, textures);
                 Array.prototype.push.apply(container.lights, result.lights);
                 Array.prototype.push.apply(container.lights, result.lights);
                 Array.prototype.push.apply(container.transformNodes, result.transformNodes);
                 Array.prototype.push.apply(container.transformNodes, result.transformNodes);
+                Array.prototype.push.apply(container.cameras, cameras);
                 return container;
                 return container;
             });
             });
         });
         });
     };
     };
     /** @hidden */
     /** @hidden */
     GLTFFileLoader.prototype.canDirectLoad = function (data) {
     GLTFFileLoader.prototype.canDirectLoad = function (data) {
-        return data.indexOf("asset") !== -1 && data.indexOf("version") !== -1;
+        return (data.indexOf("asset") !== -1 && data.indexOf("version") !== -1)
+            || babylonjs_Misc_observable__WEBPACK_IMPORTED_MODULE_0__["StringTools"].StartsWith(data, "data:base64," + GLTFFileLoader.magicBase64Encoded)
+            || babylonjs_Misc_observable__WEBPACK_IMPORTED_MODULE_0__["StringTools"].StartsWith(data, "data:application/octet-stream;base64," + GLTFFileLoader.magicBase64Encoded)
+            || babylonjs_Misc_observable__WEBPACK_IMPORTED_MODULE_0__["StringTools"].StartsWith(data, "data:model/gltf-binary;base64," + GLTFFileLoader.magicBase64Encoded);
     };
     };
     /** @hidden */
     /** @hidden */
     GLTFFileLoader.prototype.directLoad = function (scene, data) {
     GLTFFileLoader.prototype.directLoad = function (scene, data) {
+        if (babylonjs_Misc_observable__WEBPACK_IMPORTED_MODULE_0__["StringTools"].StartsWith(data, "base64," + GLTFFileLoader.magicBase64Encoded) ||
+            babylonjs_Misc_observable__WEBPACK_IMPORTED_MODULE_0__["StringTools"].StartsWith(data, "application/octet-stream;base64," + GLTFFileLoader.magicBase64Encoded) ||
+            babylonjs_Misc_observable__WEBPACK_IMPORTED_MODULE_0__["StringTools"].StartsWith(data, "model/gltf-binary;base64," + GLTFFileLoader.magicBase64Encoded)) {
+            var arrayBuffer_2 = babylonjs_Misc_observable__WEBPACK_IMPORTED_MODULE_0__["Tools"].DecodeBase64(data);
+            this._validate(scene, arrayBuffer_2);
+            return this._unpackBinaryAsync(new babylonjs_Misc_observable__WEBPACK_IMPORTED_MODULE_0__["DataReader"]({
+                readAsync: function (byteOffset, byteLength) { return Promise.resolve(new Uint8Array(arrayBuffer_2, byteOffset, byteLength)); },
+                byteLength: arrayBuffer_2.byteLength
+            }));
+        }
         this._validate(scene, data);
         this._validate(scene, data);
-        return { json: this._parseJson(data) };
+        return Promise.resolve({ json: this._parseJson(data) });
     };
     };
     /** @hidden */
     /** @hidden */
     GLTFFileLoader.prototype.createPlugin = function () {
     GLTFFileLoader.prototype.createPlugin = function () {
@@ -3240,7 +3325,7 @@ var GLTFFileLoader = /** @class */ (function () {
         get: function () {
         get: function () {
             return this._loader ? this._loader.state : null;
             return this._loader ? this._loader.state : null;
         },
         },
-        enumerable: true,
+        enumerable: false,
         configurable: true
         configurable: true
     });
     });
     /**
     /**
@@ -3258,6 +3343,55 @@ var GLTFFileLoader = /** @class */ (function () {
             });
             });
         });
         });
     };
     };
+    /** @hidden */
+    GLTFFileLoader.prototype._loadFile = function (url, scene, onSuccess, useArrayBuffer, onError) {
+        var _this = this;
+        var request = scene._loadFile(url, onSuccess, function (event) {
+            _this._onProgress(event, request);
+        }, undefined, useArrayBuffer, onError);
+        request.onCompleteObservable.add(function (request) {
+            _this._requests.splice(_this._requests.indexOf(request), 1);
+        });
+        this._requests.push(request);
+        return request;
+    };
+    /** @hidden */
+    GLTFFileLoader.prototype._requestFile = function (url, scene, onSuccess, useArrayBuffer, onError, onOpened) {
+        var _this = this;
+        var request = scene._requestFile(url, onSuccess, function (event) {
+            _this._onProgress(event, request);
+        }, undefined, useArrayBuffer, onError, onOpened);
+        request.onCompleteObservable.add(function (request) {
+            _this._requests.splice(_this._requests.indexOf(request), 1);
+        });
+        this._requests.push(request);
+        return request;
+    };
+    GLTFFileLoader.prototype._onProgress = function (event, request) {
+        if (!this._progressCallback) {
+            return;
+        }
+        request._lengthComputable = event.lengthComputable;
+        request._loaded = event.loaded;
+        request._total = event.total;
+        var lengthComputable = true;
+        var loaded = 0;
+        var total = 0;
+        for (var _i = 0, _a = this._requests; _i < _a.length; _i++) {
+            var request_1 = _a[_i];
+            if (request_1._lengthComputable === undefined || request_1._loaded === undefined || request_1._total === undefined) {
+                return;
+            }
+            lengthComputable = lengthComputable && request_1._lengthComputable;
+            loaded += request_1._loaded;
+            total += request_1._total;
+        }
+        this._progressCallback({
+            lengthComputable: lengthComputable,
+            loaded: loaded,
+            total: lengthComputable ? total : 0
+        });
+    };
     GLTFFileLoader.prototype._validate = function (scene, data, rootUrl, fileName) {
     GLTFFileLoader.prototype._validate = function (scene, data, rootUrl, fileName) {
         var _this = this;
         var _this = this;
         if (rootUrl === void 0) { rootUrl = ""; }
         if (rootUrl === void 0) { rootUrl = ""; }
@@ -3330,7 +3464,7 @@ var GLTFFileLoader = /** @class */ (function () {
                 _this._log("Binary version: " + version);
                 _this._log("Binary version: " + version);
             }
             }
             var length = dataReader.readUint32();
             var length = dataReader.readUint32();
-            if (dataReader.buffer.byteLength != 0 && length !== dataReader.buffer.byteLength) {
+            if (dataReader.buffer.byteLength !== 0 && length !== dataReader.buffer.byteLength) {
                 throw new Error("Length in header does not match actual data length: " + length + " != " + dataReader.buffer.byteLength);
                 throw new Error("Length in header does not match actual data length: " + length + " != " + dataReader.buffer.byteLength);
             }
             }
             var unpacked;
             var unpacked;
@@ -3494,6 +3628,7 @@ var GLTFFileLoader = /** @class */ (function () {
      * @hidden
      * @hidden
      */
      */
     GLTFFileLoader.HomogeneousCoordinates = false;
     GLTFFileLoader.HomogeneousCoordinates = false;
+    GLTFFileLoader.magicBase64Encoded = "Z2xURg"; // "glTF" base64 encoded (without the quotes!)
     GLTFFileLoader._logSpaces = "                                ";
     GLTFFileLoader._logSpaces = "                                ";
     return GLTFFileLoader;
     return GLTFFileLoader;
 }());
 }());
@@ -3720,7 +3855,7 @@ if (typeof globalObject !== "undefined") {
 /*!******************************************!*\
 /*!******************************************!*\
   !*** ./legacy/legacy-glTF1FileLoader.ts ***!
   !*** ./legacy/legacy-glTF1FileLoader.ts ***!
   \******************************************/
   \******************************************/
-/*! exports provided: GLTF1, GLTFLoaderCoordinateSystemMode, GLTFLoaderAnimationStartMode, GLTFLoaderState, GLTFFileLoader, GLTFValidation */
+/*! exports provided: GLTFLoaderCoordinateSystemMode, GLTFLoaderAnimationStartMode, GLTFLoaderState, GLTFFileLoader, GLTFValidation, GLTF1 */
 /***/ (function(module, __webpack_exports__, __webpack_require__) {
 /***/ (function(module, __webpack_exports__, __webpack_require__) {
 
 
 "use strict";
 "use strict";

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


File diff suppressed because it is too large
+ 12 - 12
dist/loaders/babylon.glTF1FileLoader.min.js


+ 0 - 0
dist/loaders/babylon.glTF2FileLoader.js


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