浏览代码

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

msDestiny14 4 年之前
父节点
当前提交
ddc98eebeb
共有 100 个文件被更改,包括 271824 次插入194778 次删除
  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. 二进制
      Playground/textures/ktx2/sample_etc1s.ktx2
  30. 二进制
      Playground/textures/ktx2/sample_uastc.ktx2
  31. 二进制
      Playground/textures/ktx2/sample_uastc_zcmp.ktx2
  32. 二进制
      Playground/textures/ktx2/testalpha_etc1s.ktx2
  33. 二进制
      Playground/textures/ktx2/testalpha_uastc.ktx2
  34. 二进制
      Playground/textures/ktx2/testalpha_uastc_zcmp.ktx2
  35. 二进制
      Playground/textures/ktx2/testmipmapcustom_etc1s.ktx2
  36. 二进制
      Playground/textures/ktx2/testmipmapcustom_uastc.ktx2
  37. 二进制
      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. 二进制
      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. 二进制
      dist/draco_decoder_gltf.wasm
  74. 104 115
      dist/draco_wasm_wrapper_gltf.js
  75. 33 46
      dist/glslang/glslang.js
  76. 二进制
      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. 二进制
      dist/ktx2Transcoders/msc_basis_transcoder.wasm
  93. 二进制
      dist/ktx2Transcoders/uastc_astc.wasm
  94. 二进制
      dist/ktx2Transcoders/uastc_bc7.wasm
  95. 二进制
      dist/ktx2Transcoders/uastc_rgba32_srgb.wasm
  96. 二进制
      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/)
 
-*If you are convinced that you found a bug, please use the following template for your issue:*
-
 # Bugs
 
 - 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/)
 
-*If you are convinced that you found a bug, please use the following template for your issue:*
-
 **Repro**
 - Bug repro on [playground](https://playground.babylonjs.com):
 - Expected result:

+ 12 - 1
.gitignore

@@ -157,6 +157,7 @@ node_modules
 # for VSCode
 .vs
 .tempChromeProfileForDebug
+.tempChromeCanaryProfileForDebug
 .temp
 *.js.map
 *.js.fx
@@ -165,6 +166,7 @@ node_modules
 !dist/**/*.js.map
 !lib.d.ts
 !src/LibDeclarations/*.d.ts
+!Playground/libs/*.d.ts
 *.fragment.ts
 *.vertex.ts
 **/ShadersInclude/**/*.ts
@@ -180,6 +182,9 @@ localDev/src/*
 package-lock.json
 dist/preview release/package/
 
+# local dev WebGPU
+localDevWebGPU/src/*
+
 # viewer dist files
 /Viewer/dist/viewer.js
 /Viewer/dist/viewer.min.js
@@ -200,4 +205,10 @@ gui/dist/
 # Local Netlify folder
 .netlify
 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)",
             "type": "edge",
             "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)",
             "type": "chrome",
             "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/cannon.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>
         
         <!-- Babylon.js -->
@@ -56,14 +55,6 @@
          <script
              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>        
 
         <style>
             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/cannon.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>
         
         <!-- Babylon.js -->
@@ -55,14 +54,6 @@
          <script
              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>        
 
         <style>
             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/cannon.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>
 
         <!-- jQuery -->
@@ -55,14 +54,6 @@
          <script
              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>        
 
         <style>
             html,

+ 27 - 3
Playground/index-local.html

@@ -33,7 +33,6 @@
         <script src="/dist/preview%20release/recast.js"></script>
         <script src="/dist/preview%20release/cannon.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>
         
         <!-- Babylon.js -->
@@ -56,12 +55,37 @@
         <div id="host-element">
         </div>
         <script>
+            function GetAbsoluteUrl(url) {
+                const a = document.createElement("a");
+                a.href = url;
+                return a.href;
+            }
+
             // Load the scripts + map file to allow vscode debug.
-            BABYLONDEVTOOLS.Loader       
+            BABYLONDEVTOOLS.Loader
                 .require("index.js")
                 .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>
     </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/cannon.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>
         
         <!-- Babylon.js -->
         <script src="https://preview.babylonjs.com/babylon.js"></script>
-        <script src="https://preview.babylonjs.com/gui/babylon.gui.min.js"></script>
-        <script src="https://preview.babylonjs.com/nodeEditor/babylon.nodeEditor.js"></script>
         <script src="https://preview.babylonjs.com/materialsLibrary/babylonjs.materials.min.js"></script>
         <script src="https://preview.babylonjs.com/proceduralTexturesLibrary/babylonjs.proceduralTextures.min.js"></script>
         <script src="https://preview.babylonjs.com/postProcessesLibrary/babylonjs.postProcess.min.js"></script>
         <script src="https://preview.babylonjs.com/loaders/babylonjs.loaders.min.js"></script>
         <script src="https://preview.babylonjs.com/serializers/babylonjs.serializers.min.js"></script>
+        <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/nodeEditor/babylon.nodeEditor.js"></script>
 
          <!-- Extensions -->
          <script
@@ -54,15 +53,8 @@
          </script>
          <script
              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>
             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/loaders/babylonjs.loaders.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": [
         "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);
 }
 
+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 activeVersion = readStringFromStore("version", "Latest");
 
@@ -69,19 +88,17 @@ let checkBabylonVersionAsync= function () {
         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(() => {
     if (typeof BABYLONDEVTOOLS !== 'undefined') {
         var hostElement = document.getElementById("host-element");
-        BABYLON.Playground.Show(hostElement);
+        storedPGObbject.Show(hostElement);
         return;
     }
 

文件差异内容过多而无法显示
+ 2686 - 0
Playground/libs/babylon.manager.d.ts


文件差异内容过多而无法显示
+ 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 { CommandDropdownComponent } from './commandDropdownComponent';
 import { Utilities } from '../tools/utilities';
+import { WebGPUEngine } from "babylonjs";
 
 require("../scss/commandBar.scss");
 
@@ -16,6 +17,10 @@ export class CommandBarComponent extends React.Component<ICommandBarComponentPro
   
     public constructor(props: ICommandBarComponentProps) {
         super(props);
+
+        this.props.globalState.onLanguageChangedObservable.add(() => {
+            this.forceUpdate();
+        });
     }    
 
     onPlay() {
@@ -39,7 +44,7 @@ export class CommandBarComponent extends React.Component<ICommandBarComponentPro
     }
 
     onInspector() {
-        this.props.globalState.onInspectorRequiredObservable.notifyObservers();
+        this.props.globalState.onInspectorRequiredObservable.notifyObservers(!this.props.globalState.inspectorIsOpened);
     }
 
     onExamples() {
@@ -48,12 +53,12 @@ export class CommandBarComponent extends React.Component<ICommandBarComponentPro
 
     public render() {
         let activeVersion = Utilities.ReadStringFromStore("version", "Latest");
+        let activeEngineVersion = Utilities.ReadStringFromStore("engineVersion", "WebGL2");
 
         var versionOptions = Object.keys(Versions).map(key => {
             return {
                 label: key,
                 storeKey: "version",
-                defaultValue: "Latest",
                 isActive: activeVersion === key,
                 onClick: () => {
                     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 (
             <div className={"commands " + (this.props.globalState.language === "JS" ? "background-js" : "background-ts")}>
                 <div className="commands-left">
@@ -143,11 +181,18 @@ export class CommandBarComponent extends React.Component<ICommandBarComponentPro
                     {
                         label: "QR code",
                         onClick: () => {this.props.globalState.onQRCodeRequiredObservable.notifyObservers(true)}
-                    }
+                    },                 
+                    {
+                        label: "Load Unity Toolkit",
+                        storeKey: "unity-toolkit",
+                        defaultValue: false,
+                        onCheck: () => {}
+                    }, 
                 ]}/>
                 </div>
                 <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}/>
                 </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 { GlobalState } from '../globalState';
 import { Utilities } from '../tools/utilities';
 
 interface ICommandDropdownComponentProps {
     globalState: GlobalState;
-    icon: string; 
+    icon?: string; 
     tooltip: string;
+    defaultValue?: string;
     items: {
         label: string, 
         onClick?: () => void, 
@@ -15,30 +17,62 @@ interface ICommandDropdownComponentProps {
         defaultValue?: boolean | 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) {
         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() {
+        var engineVersionSub = Engine.Version.indexOf("-");
+        var engineVersion = Engine.Version;
+
+        if (engineVersionSub ! -1) {
+            engineVersion = engineVersion.substr(0, engineVersionSub);
+        }
+
         return (
             <>
                 {
                     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 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>
                     {
                             this.state.isExpanded &&
@@ -56,7 +90,8 @@ export class CommandDropdownComponent extends React.Component<ICommandDropdownCo
                                                 }
                                                 if (!m.subItems) {
                                                     m.onClick();
-                                                    this.setState({isExpanded: false});
+                                                    Utilities.StoreStringToStore(this.props.tooltip, m.label);
+                                                    this.setState({isExpanded: false, activeState: m.label});
                                                 }
                                             }} title={m.label}>
                                                 <div className="command-dropdown-label-text">

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

@@ -1,5 +1,5 @@
 import * as React from "react";
-import { GlobalState } from '../globalState';
+import { GlobalState } from "../globalState";
 
 require("../scss/examples.scss");
 
@@ -7,8 +7,8 @@ interface IExamplesComponentProps {
     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 _scripts: {
         title: string;
@@ -19,33 +19,39 @@ export class ExamplesComponent extends React.Component<IExamplesComponentProps,
             PGID: string;
             description: string;
         }[];
-    }[];  
-  
+    }[];
+
     public constructor(props: IExamplesComponentProps) {
         super(props);
         this._loadScripts();
 
-        this.state = {filter: ""};
+        this.state = { filter: "" };
         this._rootRef = React.createRef();
 
         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 {
                 this._rootRef.current!.classList.remove("visible");
                 this._state = "";
+                setTimeout(() => {
+                    this._rootRef.current!.classList.add("removed");
+                }, 200);
             }
         });
-    }  
+    }
 
     private _loadScripts() {
         var xhr = new XMLHttpRequest();
 
         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 {
-            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 = () => {
@@ -60,7 +66,7 @@ export class ExamplesComponent extends React.Component<IExamplesComponentProps,
                         return 1;
                     });
 
-                    this._scripts.forEach(s => {
+                    this._scripts.forEach((s) => {
                         s.samples.sort((a, b) => {
                             if (a.title < b.title) {
                                 return -1;
@@ -72,12 +78,11 @@ export class ExamplesComponent extends React.Component<IExamplesComponentProps,
                     this.forceUpdate();
                 }
             }
-        }
+        };
 
         xhr.send(null);
     }
 
-
     private _onLoadPG(id: string) {
         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-header">Examples</div>
                 <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 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>
-        )
+        );
     }
-}
+}

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

@@ -43,7 +43,7 @@ export class HamburgerMenuComponent extends React.Component<IHamburgerMenuCompon
     }
 
     onInspector() {
-        this.props.globalState.onInspectorRequiredObservable.notifyObservers();
+        this.props.globalState.onInspectorRequiredObservable.notifyObservers(!this.props.globalState.inspectorIsOpened);
         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.props.globalState.onLanguageChangedObservable.add(() => {
+            this.updateDescription();
             this.forceUpdate();
         });
+
+        this.props.globalState.onRunExecutedObservable.add(() => {
+            this.updateDescription();
+        });
     }
 
-    componentDidMount() {
+    updateDescription() {
         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() {

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

@@ -5,6 +5,7 @@ import { Nullable } from "babylonjs/types";
 import { Scene } from "babylonjs/scene";
 import { Utilities } from "../tools/utilities";
 import { DownloadManager } from "../tools/downloadManager";
+import { WebGPUEngine } from "babylonjs";
 
 require("../scss/rendering.scss");
 
@@ -17,6 +18,7 @@ export class RenderingComponent extends React.Component<IRenderingComponentProps
     private _scene: Nullable<Scene>;
     private _canvasRef: React.RefObject<HTMLCanvasElement>;
     private _downloadManager: DownloadManager;
+    private _unityToolkitWasLoaded = false;
 
     public constructor(props: IRenderingComponentProps) {
         super(props);
@@ -41,18 +43,19 @@ export class RenderingComponent extends React.Component<IRenderingComponentProps
             this._downloadManager.download(this._engine);
         });
 
-        this.props.globalState.onInspectorRequiredObservable.add(() => {
+        this.props.globalState.onInspectorRequiredObservable.add((state) => {
             if (!this._scene) {
                 return;
             }
 
-            if (this._scene.debugLayer.isVisible()) {
-                this._scene.debugLayer.hide();
-            } else {
+            if (state) {
                 this._scene.debugLayer.show({
                     embedMode: true,
                 });
+            } else {
+                this._scene.debugLayer.hide();
             }
+            this.props.globalState.inspectorIsOpened = state;
         });
 
         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() {
         this.props.globalState.onDisplayWaitRingObservable.notifyObservers(false);
         this.props.globalState.onErrorObservable.notifyObservers(null);
 
         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) {
             try {
@@ -96,21 +123,45 @@ export class RenderingComponent extends React.Component<IRenderingComponentProps
             let canvas = this._canvasRef.current!;
             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 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();
 
             if (!code) {
                 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 createSceneFunction = "";
             let checkCamera = true;
@@ -137,26 +188,25 @@ export class RenderingComponent extends React.Component<IRenderingComponentProps
             }
 
             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 {
                 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.';";
 
                 if (this.props.globalState.language === "JS") {
@@ -167,9 +217,13 @@ export class RenderingComponent extends React.Component<IRenderingComponentProps
                     code += "\n" + "scene = " + createSceneFunction + "();";
                 }
 
+                code += `}`;
+
                 // Execute the code
                 Utilities.FastEval(code);
 
+                await globalObject.initFunction();
+
                 this._engine = globalObject.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();
                 }
 
@@ -240,7 +294,7 @@ export class RenderingComponent extends React.Component<IRenderingComponentProps
             }
 
             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) {
@@ -249,9 +303,15 @@ export class RenderingComponent extends React.Component<IRenderingComponentProps
                 });
                 return;
             } 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 {
-                this._engine.scenes[0].executeWhenReady(function () {});
+                this._engine.scenes[0].executeWhenReady(() => {
+                    this.props.globalState.onRunExecutedObservable.notifyObservers();
+                });
             }
         } catch (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 runtimeMode = RuntimeMode.Editor;
+    public inspectorIsOpened = false;
 
     public currentSnippetTitle = "";
     public currentSnippetDescription = "";
@@ -37,6 +38,7 @@ export class GlobalState {
     public zipCode = "";
 
     public onRunRequiredObservable = new Observable<void>();
+    public onRunExecutedObservable = new Observable<void>();
     public onSavedObservable = new Observable<void>();
     public onNewRequiredObservable = new Observable<void>();
     public onClearRequiredObservable = new Observable<void>();
@@ -49,7 +51,7 @@ export class GlobalState {
     public onMetadataUpdatedObservable = new Observable<void>();
     public onMetadataWindowHiddenObservable = new Observable<boolean>();
     public onDownloadRequiredObservable = new Observable<void>();
-    public onInspectorRequiredObservable = new Observable<void>();
+    public onInspectorRequiredObservable = new Observable<boolean>();
     public onFormatCodeRequiredObservable = new Observable<void>();
     public onFullcreenRequiredObservable = new Observable<void>();
     public onEditorFullcreenRequiredObservable = new Observable<void>();
@@ -61,6 +63,7 @@ export class GlobalState {
     public onNavigateRequiredObservable = new Observable<{lineNumber: number, column: number}>();
     public onExamplesDisplayChangedObservable = new Observable<void>();
     public onQRCodeRequiredObservable = new Observable<boolean>();
+    public OnNewDropdownButtonClicked = new Observable<any>();
 
     public loadingCodeInProgress = false;
     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} />
                     </div>
                 </div>
-                {window.innerWidth < 1024 && <HamburgerMenuComponent globalState={this._globalState} />}
+                {window.innerWidth < 1080 && <HamburgerMenuComponent globalState={this._globalState} />}
                 <ExamplesComponent globalState={this._globalState} />
                 <FooterComponent 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%);
             }
 
+            .command-dropdown-active {
+                color: #F78951;
+            }
+
             &:hover, &.activated {
                 img {
                     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);
             }
 
+            .command-dropdown-active {
+                color: #9B86FF;
+            }
+
             &:hover, &.activated {
                 img {
                     filter: invert(17%) !important;
@@ -93,8 +101,18 @@
             justify-content: center;
         }
 
+        .command-dropdown-active {
+            height: 100%;
+            width: 100%;
+            display: grid;
+            align-content: center;
+            justify-content: center;
+            font-size: 14px;
+        }
+
         &:hover, &.activated {
             background-color: white;
+            color: black;
         } 
         
         &:active {
@@ -146,12 +164,11 @@
         }        
 
         .command-dropdown-label {
-            font-family: "acumin-pro-extra-condensed";
             color:white;
             padding: 5px;
             padding-left: 10px;
             height: 35px;
-            font-size: 20px;
+            font-size: 18px;
             display: grid;
             align-items: center;
             cursor: pointer;
@@ -162,7 +179,7 @@
 
             &.active {
                 font-weight: bold;
-                font-size: 22px;
+                font-size: 20px;
             }
 
             &:hover {
@@ -184,7 +201,7 @@
             .command-dropdown-arrow {
                 grid-column: 2;
                 grid-row: 1;    
-                font-size: 28px;
+                font-size: 20px;
                 font-weight: bold;
                 padding-bottom: 10px;
                 padding-left: 4px;
@@ -218,7 +235,6 @@
                 }   
                                     
                 .sub-item {                      
-                    font-family: "acumin-pro-extra-condensed";                    
                     color: white;
                     padding: 5px;
                     padding-left: 10px;

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

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

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

@@ -86,12 +86,16 @@
                 .version-text {
                     display: none;
                 }
+                
+                .version-number {
+                    font-size: 16px;
+                }
             }
         }
     }
 }
 
-@media screen and (max-width: 1024px) {
+@media screen and (max-width: 1080px) {
     #pg-header {
         grid-template-columns: 100%;
 
@@ -104,7 +108,6 @@
                 }
             }
         }
-
         
         .command-bar {  
             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 {
         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 {
     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();
         window.addEventListener("hashchange", () => this._checkHash());
 
-        globalState.onLoadRequiredObservable.add(id => {
+        globalState.onLoadRequiredObservable.add((id) => {
             globalState.onDisplayWaitRingObservable.notifyObservers(true);
-            this._loadPlayground(id);
+
+            let prevHash = location.hash;
+            location.hash = id;
+
+            if(location.hash === prevHash){
+                this._loadPlayground(id);
+            }
         });
     }
 
     private _cleanHash() {
-        var substr = location.hash[1]==='#' ? 2 : 1
+        var substr = location.hash[1] === "#" ? 2 : 1;
         var splits = decodeURIComponent(location.hash.substr(substr)).split("#");
 
         if (splits.length > 2) {
@@ -24,14 +30,14 @@ export class LoadManager {
         }
 
         location.hash = splits.join("#");
-    };
+    }
 
     private _checkHash() {
         let pgHash = "";
-        if (location.search && (!location.pathname  || location.pathname === '/') && !location.hash) {
+        if (location.search && (!location.pathname || location.pathname === "/") && !location.hash) {
             var query = Utilities.ParseQuery();
             if (query.pg) {
-                pgHash = "#" + query.pg + "#" + (query.revision || "0")
+                pgHash = "#" + query.pg + "#" + (query.revision || "0");
             }
         } else if (location.hash) {
             if (this._previousHash !== location.hash) {
@@ -52,27 +58,27 @@ export class LoadManager {
         if (pgHash) {
             var match = pgHash.match(/^(#[A-Za-z\d]*)(%23)([\d]+)$/);
             if (match) {
-                pgHash = match[1] + '#' + match[3];
+                pgHash = match[1] + "#" + match[3];
                 parent.location.hash = pgHash;
             }
             this._previousHash = pgHash;
             this._loadPlayground(pgHash.substr(1));
-        }        
+        }
     }
 
-    private _loadPlayground(id: string) {        
+    private _loadPlayground(id: string) {
         this.globalState.loadingCodeInProgress = true;
         try {
             var xmlHttp = new XMLHttpRequest();
             xmlHttp.onreadystatechange = () => {
                 if (xmlHttp.readyState === 4) {
                     if (xmlHttp.status === 200) {
-
                         if (xmlHttp.responseText.indexOf("class Playground") !== -1) {
                             if (this.globalState.language === "JS") {
                                 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") {
                                 Utilities.SwitchLanguage("JS", this.globalState);
                             }
@@ -100,20 +106,26 @@ export class LoadManager {
                         }
 
                         this.globalState.onCodeLoaded.notifyObservers(JSON.parse(snippet.jsonPayload).code.toString());
-                         
+
                         this.globalState.onMetadataUpdatedObservable.notifyObservers();
                     }
                 }
+            };
+
+            if (id[0] === "#") {
+                id = id.substr(1);
             }
 
             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();
         } catch (e) {
             this.globalState.loadingCodeInProgress = false;
             this.globalState.onCodeLoaded.notifyObservers("");
         }
     }
-}
+}

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

@@ -120,18 +120,49 @@ export class MonacoManager {
 
     private _setNewContent() {
         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 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);
 
         return scene;
-    };
-        `);
+    }
+}`);
+        }
 
         this.globalState.onRunRequiredObservable.notifyObservers();
 
@@ -190,26 +221,39 @@ export class MonacoManager {
     public async setupMonacoAsync(hostElement: HTMLDivElement, initialCall = false) {
         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();
 
         // Definition worker
         this._setupDefinitionWorker(libContent);
 
-
         // Setup the Monaco compilation pipeline, so we can reuse it directly for our scrpting needs
         this._setupMonacoCompilationPipeline(libContent);
 
@@ -218,21 +262,20 @@ export class MonacoManager {
 
         if (initialCall) {
             // Load code templates
-            response = await fetch("templates.json");
+            const response = await fetch("templates.json");
             if (response.ok) {
                 this._templates = await response.json();
-            }        
-            
+            }
+
             // enhance templates with extra properties
             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.insertTextRules = monaco.languages.CompletionItemInsertTextRule.InsertAsSnippet;
-            }       
-            
+            }
+
             this._hookMonacoCompletionProvider();
         }
 
-
         if (!this.globalState.loadingCodeInProgress) {
             this._setDefaultContent();
         }
@@ -269,7 +312,6 @@ export class MonacoManager {
     var ground = BABYLON.MeshBuilder.CreateGround("ground", {width: 6, height: 6}, scene);
 
     return scene;
-
 };`);
         } else {
             this._editor.setValue(`class Playground {

+ 12 - 0
Playground/templates.json

@@ -78,5 +78,17 @@
     "label" : "Setup a shadow generator",
     "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;"    
+  },
+  {
+    "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"
   }
 ]

二进制
Playground/textures/ktx2/sample_etc1s.ktx2


二进制
Playground/textures/ktx2/sample_uastc.ktx2


二进制
Playground/textures/ktx2/sample_uastc_zcmp.ktx2


二进制
Playground/textures/ktx2/testalpha_etc1s.ktx2


二进制
Playground/textures/ktx2/testalpha_uastc.ktx2


二进制
Playground/textures/ktx2/testalpha_uastc_zcmp.ktx2


二进制
Playground/textures/ktx2/testmipmapcustom_etc1s.ktx2


二进制
Playground/textures/ktx2/testmipmapcustom_uastc.ktx2


二进制
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/cannon.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/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/proceduralTexturesLibrary/babylonjs.proceduralTextures.min.js"></script>
         <script src="https://preview.babylonjs.com/postProcessesLibrary/babylonjs.postProcess.min.js"></script>
         <script src="https://preview.babylonjs.com/loaders/babylonjs.loaders.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>
 
         <style>
             html, body {
@@ -46,7 +45,7 @@
 ####INJECT####
 
         engine.runRenderLoop(function () {
-            if (sceneToRender) {
+            if (sceneToRender && sceneToRender.activeCamera) {
                 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 sharedUiComponentsFilesGlob = config.build.sharedUiComponentsSrc + "/**/*";
+const sharedUiComponentsSrcPath = path.join(rootFolder, config.build.sharedUiComponentsSrc);
+const es6SharedUiComponentsSrcPath = path.join(sourceES6Folder, config.build.sharedUiComponentsSrc);
+
 config.computed = {
     rootFolder,
     tempFolder,
@@ -39,7 +43,10 @@ config.computed = {
     tempTypingsFileName,
     tempTypingsAMDFilePath,
     tempTypingsFilePath,
-    tscPath
+    tscPath,
+    sharedUiComponentsFilesGlob,
+    sharedUiComponentsSrcPath,
+    es6SharedUiComponentsSrcPath,
 }
 
 config.additionalNpmPackages.forEach(package => {
@@ -77,6 +84,7 @@ allModules.map(function(module) {
     const distDirectory = path.join(outputFolder, distFolder);
     const localDevES6Directory = path.join(localDevES6Folder, module);
     const localDevUMDDirectory = path.join(localDevUMDFolder, distFolder);
+    const localDevAppDirectory = path.join(localDevUMDFolder, module);
     const packageUMDDirectory = path.join(packageUMDFolder, module);
     const packageUMDDevDirectory = path.join(packageUMDDevFolder, module);
     const sourceES6Directory = path.join(sourceES6Folder, module);
@@ -89,12 +97,13 @@ allModules.map(function(module) {
     const packageJSONPath = settings.build.packageJSON ? 
         path.join(rootFolder, settings.build.packageJSON) : 
         path.join(distDirectory, 'package.json');
-
+    
     settings.computed = {
         mainDirectory,
         distDirectory,
         localDevES6Directory,
         localDevUMDDirectory,
+        localDevAppDirectory,
         packageUMDDirectory,
         packageUMDDevDirectory,
         sourceES6Directory,

+ 30 - 9
Tools/Config/config.json

@@ -36,7 +36,8 @@
             "BABYLON"
         ],
         "typedocJSON": "../../.temp/babylon.typedoc.json",
-        "typedocValidationBaseline": "../../dist/preview release/typedocValidationBaseline.json"
+        "typedocValidationBaseline": "../../dist/preview release/typedocValidationBaseline.json",
+        "sharedUiComponentsSrc": "sharedUiComponents"
     },
     "modules": [
         "core",
@@ -63,7 +64,8 @@
     ],
     "apps": [
         "playground",
-        "sandbox"
+        "sandbox",
+        "ktx2Decoder"
     ],
     "lintModules": [
         "core",
@@ -147,7 +149,8 @@
             "es6": {
                 "packageName": "@babylonjs/core",
                 "readme": "readme-es6.md",
-                "license": "license.md"
+                "license": "license.md",
+                "type": "module"
             }
         }
     },
@@ -249,7 +252,8 @@
             },
             "es6": {
                 "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": {
                 "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": {
                 "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": {
                 "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": {
                 "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": {
                 "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",
                 "glTF"
             ],
+            "sharedUiComponents": "src/sharedUiComponents/",
             "umd": {
                 "packageName": "babylonjs-inspector",
                 "webpackRoot": "INSPECTOR",
@@ -605,6 +615,7 @@
                 "glTF",
                 "file-saver"
             ],
+            "sharedUiComponents": "src/sharedUiComponents/",
             "umd": {
                 "packageName": "babylonjs-node-editor",
                 "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": {
         "distFile": "/Playground/dist/babylon.playground.js",
         "build": {

+ 26 - 3
Tools/DevLoader/BabylonLoader.js

@@ -40,6 +40,8 @@ var BABYLONDEVTOOLS;
         var min;
         var babylonJSPath;
 
+        var coreOnly;
+
         var localDevES6FolderName;
         var localDevUMDFolderName;
 
@@ -57,6 +59,7 @@ var BABYLONDEVTOOLS;
                 workerMode = true;
             }
             babylonJSPath = '';
+            coreOnly = false;
         }
 
         Loader.prototype.debugShortcut = function(engine) {
@@ -221,7 +224,7 @@ var BABYLONDEVTOOLS;
         }
 
         Loader.prototype.loadCoreDev = function() {
-            if (typeof document === "undefined" || isIE) {                
+            if (typeof document === "undefined" || isIE) {
                 this.loadScript(babylonJSPath + "/dist/preview release/babylon.max.js");
                 return;
             }
@@ -234,7 +237,14 @@ var BABYLONDEVTOOLS;
                 if (!useDist && module.isCore) {
                     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);
                 }
             }
@@ -244,7 +254,14 @@ var BABYLONDEVTOOLS;
             if (!window || !window.location || window.location.pathname.toLowerCase().indexOf(appName.toLowerCase()) === -1) {
                 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) {
@@ -275,6 +292,11 @@ var BABYLONDEVTOOLS;
             }
         }
 
+        Loader.prototype.loadCoreOnly = function() {
+            coreOnly = true;
+            return this;
+        }
+
         Loader.prototype.load = function(newCallback) {
             var self = this;
             if (newCallback) {
@@ -286,6 +308,7 @@ var BABYLONDEVTOOLS;
                     localDevUMDFolderName = data.build.localDevUMDFolderName;
 
                     self.loadBJSScripts(data);
+
                     if (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-dependencies");
 require("./tasks/gulpTasks-testsES6");
+require("./tasks/gulpTasks-symlink");
 
 /**
  * Temp cleanup after upgrade.
@@ -52,27 +53,27 @@ gulp.task("cleanup", function(cb) {
 /**
  * Full TsLint.
  */
-gulp.task("tsLint", gulp.series("typescript-libraries-tsLint"));
+gulp.task("tsLint", gulp.series("generate-symlinks", "typescript-libraries-tsLint"));
 
 /**
  * Full ImportLint.
  */
-gulp.task("importLint", gulp.series("typescript-libraries-importLint"));
+gulp.task("importLint", gulp.series("generate-symlinks", "typescript-libraries-importLint"));
 
 /**
  * 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
  */
-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.
  */
-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).
@@ -82,7 +83,7 @@ gulp.task("typescript-all", gulp.series("typescript-libraries", "typescript-es6"
 /**
  * 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.

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

@@ -33,9 +33,13 @@ function processConstants(sourceCode) {
     }
 
     for (var constant of constantList) {
-        var value = babylonConstants[constant];
         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;

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

@@ -6,6 +6,7 @@ var cp = require('child_process');
 var path = require("path");
 var concat = require('gulp-concat');
 var minimist = require("minimist");
+var symlinkDir = require('symlink-dir');
 
 // Gulp Helpers
 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.
  */
 function buildExternalLibraries(settings, fast) {
     // Creates the required tasks.
     var tasks = [];
 
+    var sharedUiComponents = function(cb) { return generateSharedUiComponents(settings, cb); };
     var cleanup = function() { return cleanShaders(settings); };
     var shaders = function() { return buildShaders(settings); };
     var buildMin = function() { return buildExternalLibrariesMultiEntry(settings.libraries, settings, true) };
@@ -183,9 +202,9 @@ function buildExternalLibraries(settings, fast) {
     }
 
     if (fast) {
-        tasks.push(buildMax);
+        tasks.push(sharedUiComponents, buildMax);
     } 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);

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

@@ -4,6 +4,7 @@ var path = require("path");
 var fs = require("fs-extra");
 var shelljs = require("shelljs");
 var concat = require('gulp-concat');
+var symlinkDir = require('symlink-dir');
 
 // Gulp Helpers
 var rmDir = require("../../NodeHelpers/rmDir");
@@ -78,6 +79,11 @@ var dep = function(settings) {
             const dependencyPath = path.join(config.computed.rootFolder, pathName);
             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 })
@@ -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.
  */
 function buildES6Library(settings, module) {
@@ -278,6 +301,7 @@ function buildES6Library(settings, module) {
     }
     var copySource = function() { return source(settings); };
     var dependencies = function() { return dep(settings); };
+    var sharedUiComponents = function(cb) { return generateSharedUiComponents(settings, cb); };
     var adaptSourceImportPaths = function() { return modifySourcesImports(settings); };
     var adaptSourceConstants = function() { return modifySourcesConstants(settings); };
     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);
 }

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

@@ -43,6 +43,11 @@ gulp.task("webserver", function () {
                             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\/(.*)/);

+ 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, "/")}`;
             };
 
-            const outputDirectory = settings.distDirectory;
+            const outputDirectory = moduleConfig.tempFileName ? settings.localDevAppDirectory : settings.distDirectory;
             tasks.push(
                 webpackStream(wpConfig , webpack)
                     .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.esnext = es6Config.index || "index.js";
         umdPackageJson.typings = es6Config.typings || "index.d.ts";
+        if (es6Config.type) {
+            umdPackageJson.type = es6Config.type;
+        }
 
         if (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.
- * 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 = {
     version: "3.2.0",

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

@@ -220,7 +220,7 @@ export class TextureUtils {
             babylonTexture.gammaSpace = false;
 
             let internalTexture = new InternalTexture(scene.getEngine(), InternalTextureSource.CubeRaw);
-            let glTexture = internalTexture._webGLTexture;
+            let glTexture = internalTexture._hardwareTexture?.underlyingResource;
             //babylon properties
             internalTexture.isCube = true;
             internalTexture.generateMipMaps = false;
@@ -352,7 +352,7 @@ export class TextureUtils {
 
         let internalTexture = babylonTexture._texture;
         if (!internalTexture) { return; }
-        let glTexture = internalTexture._webGLTexture;
+        let glTexture = internalTexture._hardwareTexture?.underlyingResource;
         gl.bindTexture(target, glTexture);
 
         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
      */
-    public sceneOptimizer: SceneOptimizer;
+    public sceneOptimizer?: SceneOptimizer;
     /**
      * Models displayed in this viewer.
      */
@@ -670,9 +670,9 @@ export class SceneManager {
 
         if (canvas) {
             if (this.camera && sceneConfig.disableCameraControl) {
-                this.camera.detachControl(canvas);
+                this.camera.detachControl();
             } else if (this.camera && sceneConfig.disableCameraControl === false) {
-                this.camera.attachControl(canvas);
+                this.camera.attachControl();
             }
         }
 
@@ -741,7 +741,7 @@ export class SceneManager {
 
         this.onSceneOptimizerConfiguredObservable.notifyObservers({
             sceneManager: this,
-            object: this.sceneOptimizer,
+            object: this.sceneOptimizer!,
             newConfiguration: optimizerConfig
         });
     }
@@ -925,7 +925,7 @@ export class SceneManager {
             }
             let canvas = this.scene.getEngine().getInputElement();
             if (canvas) {
-                this.scene.activeCamera.attachControl(canvas);
+                this.scene.activeCamera.attachControl();
             }
 
             this.camera = <ArcRotateCamera>this.scene.activeCamera!;

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

@@ -118,7 +118,6 @@ export class TelemetryManager {
      */
     public dispose() {
         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);
             });
         }
-
-        delete this._fragment;
     }
 
     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.scene && this.sceneManager.scene.activeCamera) {
-                this.sceneManager.scene.activeCamera.detachControl(this.canvas);
+                this.sceneManager.scene.activeCamera.detachControl();
             }
             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
      */
     public dispose() {
-        delete this._onViewerAdded;
-
         for (let id in this._viewers) {
             this._viewers[id].dispose();
         }

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

@@ -41,7 +41,7 @@ export class Helper {
     public static disposeViewer() {
         if (Helper.viewer != null) {
             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) => {
         let viewer = Helper.getNewViewerInstance();
         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({
                 scene: {
                     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({
                 scene: {
                     disableCameraControl: false
                 }
             });
-            assert.isDefined(viewer.sceneManager.camera.inputs.attachedElement, "Camera not attached");
+            assert.isTrue(viewer.sceneManager.camera.inputs.attachedToElement, "Camera not attached");
             viewer.dispose();
             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/cannon.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/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;
 }
 
-function getRenderData(canvas, engine) {
+async function getRenderData(canvas, engine) {
     var width = canvas.width;
     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) {
@@ -106,9 +117,9 @@ function downloadDataUrlFromJavascript(filename, dataUrl) {
     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;
-    var renderData = getRenderData(currentViewer.canvas, currentViewer.engine);
+    var renderData = await getRenderData(currentViewer.canvas, currentViewer.engine);
     var testRes = true;
 
     // gl check
@@ -282,18 +293,44 @@ function prepareMeshForViewer(viewer, configuration, test) {
     console.log("sphere created");
 }
 
+function GetAbsoluteUrl(url) {
+    const a = document.createElement("a");
+    a.href = url;
+    return a.href;
+}
+
 function init() {
     BABYLON.SceneLoader.ShowLoadingScreen = false;
     BABYLON.SceneLoader.ForceFullSceneLoadingForIncremental = true;
 
     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 = {
-        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");

+ 3 - 3
contributing.md

@@ -49,10 +49,10 @@ so that you can start straight away.
 
 ## 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:
 

文件差异内容过多而无法显示
+ 11 - 11
dist/ammo.js


文件差异内容过多而无法显示
+ 1 - 1
dist/ammo.wasm.js


二进制
dist/ammo.wasm.wasm


文件差异内容过多而无法显示
+ 45586 - 37566
dist/babylon.d.ts


文件差异内容过多而无法显示
+ 12 - 12
dist/babylon.js


文件差异内容过多而无法显示
+ 1 - 0
dist/babylon.ktx2Decoder.js


文件差异内容过多而无法显示
+ 34186 - 10590
dist/babylon.max.js


文件差异内容过多而无法显示
+ 1 - 1
dist/babylon.max.js.map


文件差异内容过多而无法显示
+ 98938 - 82554
dist/babylon.module.d.ts


文件差异内容过多而无法显示
+ 46418 - 37695
dist/documentation.d.ts


文件差异内容过多而无法显示
+ 48 - 30
dist/draco_decoder_gltf.js


二进制
dist/draco_decoder_gltf.wasm


文件差异内容过多而无法显示
+ 104 - 115
dist/draco_wasm_wrapper_gltf.js


文件差异内容过多而无法显示
+ 33 - 46
dist/glslang/glslang.js


二进制
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>;
         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",
     "description": "A typescript declaration of babylon's gltf2 inteface.",
-    "version": "4.1.0",
+    "version": "4.2.0",
     "repository": {
         "type": "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;
         /**
          * 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;
         /**
@@ -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
          * @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
          */
-        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;
         /**
          * Creates an empty measure
@@ -323,7 +333,7 @@ declare module BABYLON.GUI {
     }
     /**
     * 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 {
         private _isDirty;
@@ -333,6 +343,7 @@ declare module BABYLON.GUI {
         private _pointerMoveObserver;
         private _pointerObserver;
         private _canvasPointerOutObserver;
+        private _canvasBlurObserver;
         private _background;
         /** @hidden */
         _rootContainer: Container;
@@ -410,6 +421,10 @@ declare module BABYLON.GUI {
         */
         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).
         * Useful when you want more antialiasing
         */
@@ -421,32 +436,32 @@ declare module BABYLON.GUI {
         /**
         * Gets or sets the ideal width used to design controls.
         * 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;
         set idealWidth(value: number);
         /**
         * Gets or sets the ideal height used to design controls.
         * 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;
         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
-        * @see http://doc.babylonjs.com/how_to/gui#adaptive-scaling
+        * @see https://doc.babylonjs.com/how_to/gui#adaptive-scaling
         */
         get useSmallestIdeal(): boolean;
         set useSmallestIdeal(value: boolean);
         /**
         * 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;
         set renderAtIdealSize(value: boolean);
         /**
          * 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;
         /**
@@ -493,8 +508,9 @@ declare module BABYLON.GUI {
        * @param scene defines the hosting scene
        * @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 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.
         * @returns "AdvancedDynamicTexture"
@@ -528,7 +544,7 @@ declare module BABYLON.GUI {
         /**
         * Helper function used to create 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;
         /**
@@ -557,6 +573,13 @@ declare module BABYLON.GUI {
         * @returns the projected position
         */
         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 _clearMeasure;
         private _render;
@@ -600,6 +623,7 @@ declare module BABYLON.GUI {
         moveFocusToControl(control: IFocusableControl): void;
         private _manageFocus;
         private _attachToOnPointerOut;
+        private _attachToOnBlur;
         /**
          * Creates a new AdvancedDynamicTexture in projected mode (ie. attached to a mesh)
          * @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 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 invertY defines if the texture needs to be inverted on the y axis during loading (true by default)
          * @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.
         * 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 {
     /**
      * 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 {
         /** defines the name of the control */
@@ -703,7 +738,7 @@ declare module BABYLON.GUI {
         private _isVisible;
         private _isHighlighted;
         /** @hidden */
-        _linkedMesh: BABYLON.Nullable<BABYLON.AbstractMesh>;
+        _linkedMesh: BABYLON.Nullable<BABYLON.TransformNode>;
         private _fontSet;
         private _dummyVector2;
         private _downCount;
@@ -822,6 +857,10 @@ declare module BABYLON.GUI {
          */
         onAfterDrawObservable: BABYLON.Observable<Control>;
         /**
+        * An event triggered when the control has been disposed
+        */
+        onDisposeObservable: BABYLON.Observable<Control>;
+        /**
          * Get the hosting AdvancedDynamicTexture
          */
         get host(): AdvancedDynamicTexture;
@@ -845,63 +884,71 @@ declare module BABYLON.GUI {
         get isHighlighted(): boolean;
         set isHighlighted(value: boolean);
         /** Gets or sets a value indicating the scale factor on X axis (1 by default)
-         * @see http://doc.babylonjs.com/how_to/gui#rotation-and-scaling
+         * @see https://doc.babylonjs.com/how_to/gui#rotation-and-scaling
         */
         get scaleX(): number;
         set scaleX(value: number);
         /** 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;
         set scaleY(value: number);
         /** 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;
         set rotation(value: number);
         /** 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;
         set transformCenterY(value: number);
         /** 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;
         set transformCenterX(value: number);
         /**
          * 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;
         set horizontalAlignment(value: number);
         /**
          * 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;
         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
-         * @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;
         set width(value: string | number);
         /**
          * 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;
         set widthInPixels(value: number);
         /**
          * 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;
         set height(value: string | number);
         /**
          * 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;
         set heightInPixels(value: number);
@@ -916,7 +963,7 @@ declare module BABYLON.GUI {
         set fontWeight(value: string);
         /**
          * 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>;
         set style(value: BABYLON.Nullable<Style>);
@@ -945,100 +992,100 @@ declare module BABYLON.GUI {
         /**
          * 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
-         * @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;
         set paddingLeft(value: string | number);
         /**
          * 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;
         set paddingLeftInPixels(value: number);
         /**
          * 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;
         set paddingRight(value: string | number);
         /**
          * 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;
         set paddingRightInPixels(value: number);
         /**
          * 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;
         set paddingTop(value: string | number);
         /**
          * 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;
         set paddingTopInPixels(value: number);
         /**
          * 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;
         set paddingBottom(value: string | number);
         /**
          * 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;
         set paddingBottomInPixels(value: number);
         /**
          * 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;
         set left(value: string | number);
         /**
          * 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;
         set leftInPixels(value: number);
         /**
          * 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;
         set top(value: string | number);
         /**
          * 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;
         set topInPixels(value: number);
         /**
          * 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;
         set linkOffsetX(value: string | number);
         /**
          * 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;
         set linkOffsetXInPixels(value: number);
         /**
          * 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;
         set linkOffsetY(value: string | number);
         /**
          * 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;
         set linkOffsetYInPixels(value: number);
@@ -1120,9 +1167,9 @@ declare module BABYLON.GUI {
         /**
          * Link current control with a target mesh
          * @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 */
         _moveToProjectedPosition(projectedPosition: BABYLON.Vector3): void;
         /** @hidden */
@@ -1181,23 +1228,25 @@ declare module BABYLON.GUI {
          */
         contains(x: number, y: number): boolean;
         /** @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 */
-        _onPointerMove(target: Control, coordinates: BABYLON.Vector2, pointerId: number): void;
+        _onPointerMove(target: Control, coordinates: BABYLON.Vector2, pointerId: number, pi: BABYLON.PointerInfoBase): void;
         /** @hidden */
-        _onPointerEnter(target: Control): boolean;
+        _onPointerEnter(target: Control, pi: BABYLON.PointerInfoBase): boolean;
         /** @hidden */
-        _onPointerOut(target: Control, force?: boolean): void;
+        _onPointerOut(target: Control, pi: BABYLON.Nullable<BABYLON.PointerInfoBase>, force?: boolean): void;
         /** @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 */
-        _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 */
         _forcePointerUp(pointerId?: BABYLON.Nullable<number>): void;
         /** @hidden */
         _onWheelScroll(deltaX?: number, deltaY?: number): void;
         /** @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;
         /** Releases associated resources */
         dispose(): void;
@@ -1247,7 +1296,7 @@ declare module BABYLON.GUI {
 declare module BABYLON.GUI {
     /**
      * 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 {
         name?: string | undefined;
@@ -1346,7 +1395,7 @@ declare module BABYLON.GUI {
         _draw(context: CanvasRenderingContext2D, invalidatedRectangle?: Measure): void;
         getDescendantsToRef(results: Control[], directDescendantsOnly?: boolean, predicate?: (control: Control) => boolean): void;
         /** @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 */
         protected _additionalProcessing(parentMeasure: Measure, context: CanvasRenderingContext2D): void;
         /** Releases associated resources */
@@ -1412,15 +1461,21 @@ declare module BABYLON.GUI {
         private _lineSpacing;
         private _outlineWidth;
         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>;
         /**
-        * 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>;
         /**
+         * 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)
          */
         get lines(): any[];
@@ -1481,6 +1536,22 @@ declare module BABYLON.GUI {
          */
         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
          */
         get outlineColor(): string;
@@ -1546,6 +1617,7 @@ declare module BABYLON.GUI {
         private _sliceTop;
         private _sliceBottom;
         private _detectPointerOnOpaqueOnly;
+        private _imageDataCache;
         /**
          * BABYLON.Observable notified when the content is loaded
          */
@@ -1615,7 +1687,7 @@ declare module BABYLON.GUI {
         get svgAttributesComputationCompleted(): boolean;
         /**
          * 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;
         set autoScale(value: boolean);
@@ -1648,19 +1720,19 @@ declare module BABYLON.GUI {
         private _getSVGAttribs;
         /**
          * 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;
         set cellWidth(value: number);
         /**
          * 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;
         set cellHeight(value: number);
         /**
          * 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;
         set cellId(value: number);
@@ -1742,15 +1814,15 @@ declare module BABYLON.GUI {
         constructor(name?: string | undefined);
         protected _getTypeName(): string;
         /** @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 */
-        _onPointerEnter(target: Control): boolean;
+        _onPointerEnter(target: Control, pi: BABYLON.PointerInfoBase): boolean;
         /** @hidden */
-        _onPointerOut(target: Control, force?: boolean): void;
+        _onPointerOut(target: Control, pi: BABYLON.PointerInfoBase, force?: boolean): void;
         /** @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 */
-        _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
          * @param name defines the name of the button
@@ -1859,7 +1931,7 @@ declare module BABYLON.GUI {
         /** @hidden */
         _draw(context: CanvasRenderingContext2D, invalidatedRectangle?: BABYLON.Nullable<Measure>): void;
         /** @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
          * @param title defines the label to use for the header
@@ -1964,12 +2036,27 @@ 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
      */
     export class InputText extends Control implements IFocusableControl {
         name?: string | undefined;
-        private _text;
+        private _textWrapper;
         private _placeholderText;
         private _background;
         private _focusedBackground;
@@ -2079,6 +2166,7 @@ declare module BABYLON.GUI {
         /** Gets or sets the text displayed in the control */
         get text(): string;
         set text(value: string);
+        private _textHasChanged;
         /** Gets or sets control width */
         get width(): string | number;
         set width(value: string | number);
@@ -2118,10 +2206,10 @@ declare module BABYLON.GUI {
         /** @hidden */
         private _onPasteText;
         _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;
-        protected _beforeRenderText(text: string): string;
+        protected _beforeRenderText(textWrapper: TextWrapper): TextWrapper;
         dispose(): void;
     }
 }
@@ -2272,13 +2360,13 @@ declare module BABYLON.GUI {
         set value(value: BABYLON.Color3);
         /**
          * 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;
         set width(value: string | number);
         /**
          * 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;
         /** Gets or sets control height */
@@ -2304,9 +2392,10 @@ declare module BABYLON.GUI {
         private _updateValueFromPointer;
         private _isPointOnSquare;
         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
          * 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
      */
     export class InputPassword extends InputText {
-        protected _beforeRenderText(text: string): string;
+        protected _beforeRenderText(textWrapper: TextWrapper): TextWrapper;
     }
 }
 declare module BABYLON.GUI {
@@ -2433,7 +2522,7 @@ declare module BABYLON.GUI {
         private _controlObserver;
         private _meshObserver;
         /** @hidden */
-        _point: BABYLON.Vector2;
+        _point: BABYLON.Vector3;
         /**
          * Creates a new MultiLinePoint
          * @param multiLine defines the source MultiLine object
@@ -2454,10 +2543,10 @@ declare module BABYLON.GUI {
         /** Resets links */
         resetLinks(): void;
         /**
-         * Gets a translation vector
+         * Gets a translation vector with Z component
          * @returns the translation vector
          */
-        translate(): BABYLON.Vector2;
+        translate(): BABYLON.Vector3;
         private _translatePoint;
         /** Release associated resources */
         dispose(): void;
@@ -2569,7 +2658,7 @@ declare module BABYLON.GUI {
         constructor(name?: string | undefined);
         protected _getTypeName(): string;
         _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
          * @param title defines the label to use for the header
@@ -2650,9 +2739,10 @@ declare module BABYLON.GUI {
         private _pointerIsDown;
         /** @hidden */
         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;
+        _onCanvasBlur(): void;
     }
 }
 declare module BABYLON.GUI {
@@ -2663,6 +2753,7 @@ declare module BABYLON.GUI {
         name?: string | undefined;
         private _background;
         private _borderColor;
+        private _thumbColor;
         private _isThumbCircle;
         protected _displayValueBar: boolean;
         /** 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 */
         get background(): 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 */
         get isThumbCircle(): boolean;
         set isThumbCircle(value: boolean);
@@ -2783,7 +2877,7 @@ declare module BABYLON.GUI {
         _setSelectorButtonBackground(selectorNb: number, color: string): void;
     }
     /** 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 {
         /** name of SelectionPanel */
@@ -2811,6 +2905,8 @@ declare module BABYLON.GUI {
         /** an array of SelectionGroups */
         groups?: SelectorGroup[]);
         protected _getTypeName(): string;
+        /** Gets the (stack) panel of the SelectionPanel  */
+        get panel(): StackPanel;
         /** Gets or sets the headerColor */
         get headerColor(): string;
         set headerColor(color: string);
@@ -2919,6 +3015,7 @@ declare module BABYLON.GUI {
         private _dispatchInBuckets;
         private _updateMeasures;
         private _updateChildrenMeasures;
+        private _restoreMeasures;
         /**
         * Creates a new ScrollViewerWindow
         * @param name of ScrollViewerWindow
@@ -2964,7 +3061,7 @@ declare module BABYLON.GUI {
         private _originY;
         /** @hidden */
         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 {
@@ -3021,7 +3118,7 @@ declare module BABYLON.GUI {
         private _originY;
         /** @hidden */
         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 {
@@ -3056,6 +3153,8 @@ declare module BABYLON.GUI {
         private _barImageHeight;
         private _horizontalBarImageHeight;
         private _verticalBarImageHeight;
+        private _oldWindowContentsWidth;
+        private _oldWindowContentsHeight;
         /**
          * Gets the horizontal scrollbar
          */
@@ -3457,7 +3556,7 @@ declare module BABYLON.GUI {
 declare module BABYLON.GUI {
     /**
      * 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 {
         private _scene;
@@ -3599,19 +3698,19 @@ declare module BABYLON.GUI {
         private _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>[];
         /**
          * 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
          * @returns the current control
          */
         addBehavior(behavior: BABYLON.Behavior<Control3D>): Control3D;
         /**
          * 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
          * @returns the current control
          */
@@ -3619,7 +3718,7 @@ declare module BABYLON.GUI {
         /**
          * Gets an attached behavior by name
          * @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
          */
         getBehaviorByName(name: string): BABYLON.Nullable<BABYLON.Behavior<Control3D>>;
@@ -3856,10 +3955,6 @@ declare module BABYLON.GUI {
          */
         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))
          */
         albedoColor: BABYLON.Color3;

文件差异内容过多而无法显示
+ 1120 - 689
dist/gui/babylon.gui.js


文件差异内容过多而无法显示
+ 1 - 1
dist/gui/babylon.gui.js.map


文件差异内容过多而无法显示
+ 12 - 12
dist/gui/babylon.gui.min.js


文件差异内容过多而无法显示
+ 402 - 199
dist/gui/babylon.gui.module.d.ts


+ 2 - 2
dist/gui/package.json

@@ -4,7 +4,7 @@
     },
     "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.",
-    "version": "4.1.0",
+    "version": "4.2.0",
     "repository": {
         "type": "git",
         "url": "https://github.com/BabylonJS/Babylon.js.git"
@@ -28,7 +28,7 @@
     ],
     "license": "Apache-2.0",
     "dependencies": {
-        "babylonjs": "4.1.0"
+        "babylonjs": "4.2.0"
     },
     "engines": {
         "node": "*"

文件差异内容过多而无法显示
+ 24 - 28
dist/inspector/babylon.inspector.bundle.js


文件差异内容过多而无法显示
+ 32690 - 22832
dist/inspector/babylon.inspector.bundle.max.js


文件差异内容过多而无法显示
+ 1 - 1
dist/inspector/babylon.inspector.bundle.max.js.map


文件差异内容过多而无法显示
+ 2073 - 123
dist/inspector/babylon.inspector.d.ts


文件差异内容过多而无法显示
+ 5939 - 1793
dist/inspector/babylon.inspector.module.d.ts


+ 11 - 9
dist/inspector/package.json

@@ -4,7 +4,7 @@
     },
     "name": "babylonjs-inspector",
     "description": "The Babylon.js inspector.",
-    "version": "4.1.0",
+    "version": "4.2.0",
     "repository": {
         "type": "git",
         "url": "https://github.com/BabylonJS/Babylon.js.git"
@@ -29,14 +29,16 @@
     ],
     "license": "Apache-2.0",
     "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": {
         "node": "*"

文件差异内容过多而无法显示
+ 22 - 0
dist/ktx2Transcoders/msc_basis_transcoder.js


二进制
dist/ktx2Transcoders/msc_basis_transcoder.wasm


二进制
dist/ktx2Transcoders/uastc_astc.wasm


二进制
dist/ktx2Transcoders/uastc_bc7.wasm


二进制
dist/ktx2Transcoders/uastc_rgba32_srgb.wasm


二进制
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 ***!
   \***********************************************************/
-/*! 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__) {
 
 "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__, "__awaiter", function() { return __awaiter; });
 /* 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__, "__values", function() { return __values; });
 /* 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__, "__importStar", function() { return __importStar; });
 /* 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 */
 
 var extendStatics = function(d, b) {
     extendStatics = Object.setPrototypeOf ||
         ({ __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);
 };
 
@@ -193,10 +196,11 @@ function __metadata(metadataKey, metadataValue) {
 }
 
 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) {
         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 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());
     });
 }
@@ -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) {
-    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);
-    return {
+    if (o && typeof o.length === "number") return {
         next: function () {
             if (o && i >= o.length) o = void 0;
             return { value: o && o[i++], done: !o };
         }
     };
+    throw new TypeError(s ? "Object is not iterable." : "Symbol.iterator is not defined.");
 }
 
 function __read(o, n) {
@@ -310,17 +323,38 @@ function __makeTemplateObject(cooked, raw) {
     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) {
     if (mod && mod.__esModule) return mod;
     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;
 }
 
 function __importDefault(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);
                 orthoCamera.name = node.name || "";
                 orthoCamera.mode = babylonjs_Maths_math_vector__WEBPACK_IMPORTED_MODULE_1__["Camera"].ORTHOGRAPHIC_CAMERA;
-                orthoCamera.attachControl(gltfRuntime.scene.getEngine().getInputElement());
+                orthoCamera.attachControl();
                 lastNode = orthoCamera;
             }
             else if (camera.type === "perspective") {
                 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);
                 persCamera.name = node.name || "";
-                persCamera.attachControl(gltfRuntime.scene.getEngine().getInputElement());
+                persCamera.attachControl();
                 if (!perspectiveCamera.aspectRatio) {
                     perspectiveCamera.aspectRatio = gltfRuntime.scene.getEngine().getRenderWidth() / gltfRuntime.scene.getEngine().getRenderHeight();
                 }
@@ -1867,7 +1901,8 @@ var GLTFLoader = /** @class */ (function () {
                     skeletons: skeletons,
                     animationGroups: [],
                     lights: [],
-                    transformNodes: []
+                    transformNodes: [],
+                    geometries: []
                 });
             }, onProgress, function (message) {
                 reject(new Error(message));
@@ -2011,7 +2046,7 @@ var GLTFLoaderExtension = /** @class */ (function () {
         get: function () {
             return this._name;
         },
-        enumerable: true,
+        enumerable: false,
         configurable: true
     });
     /**
@@ -2730,6 +2765,7 @@ __webpack_require__.r(__webpack_exports__);
 
 
 
+
 /**
  * Mode that determines the coordinate system to use.
  */
@@ -2832,11 +2868,20 @@ var GLTFFileLoader = /** @class */ (function () {
          */
         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.
          */
         this.preprocessUrlAsync = function (url) { return Promise.resolve(url); };
         /**
          * 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"]();
         /**
@@ -2879,6 +2924,7 @@ var GLTFFileLoader = /** @class */ (function () {
          */
         this.onValidatedObservable = new babylonjs_Misc_observable__WEBPACK_IMPORTED_MODULE_0__["Observable"]();
         this._loader = null;
+        this._requests = new Array();
         /**
          * Name of the loader ("gltf")
          */
@@ -2908,12 +2954,13 @@ var GLTFFileLoader = /** @class */ (function () {
             }
             this._onParsedObserver = this.onParsedObservable.add(callback);
         },
-        enumerable: true,
+        enumerable: false,
         configurable: true
     });
     Object.defineProperty(GLTFFileLoader.prototype, "onMeshLoaded", {
         /**
          * 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) {
             if (this._onMeshLoadedObserver) {
@@ -2921,7 +2968,7 @@ var GLTFFileLoader = /** @class */ (function () {
             }
             this._onMeshLoadedObserver = this.onMeshLoadedObservable.add(callback);
         },
-        enumerable: true,
+        enumerable: false,
         configurable: true
     });
     Object.defineProperty(GLTFFileLoader.prototype, "onTextureLoaded", {
@@ -2934,7 +2981,7 @@ var GLTFFileLoader = /** @class */ (function () {
             }
             this._onTextureLoadedObserver = this.onTextureLoadedObservable.add(callback);
         },
-        enumerable: true,
+        enumerable: false,
         configurable: true
     });
     Object.defineProperty(GLTFFileLoader.prototype, "onMaterialLoaded", {
@@ -2947,7 +2994,7 @@ var GLTFFileLoader = /** @class */ (function () {
             }
             this._onMaterialLoadedObserver = this.onMaterialLoadedObservable.add(callback);
         },
-        enumerable: true,
+        enumerable: false,
         configurable: true
     });
     Object.defineProperty(GLTFFileLoader.prototype, "onCameraLoaded", {
@@ -2960,7 +3007,7 @@ var GLTFFileLoader = /** @class */ (function () {
             }
             this._onCameraLoadedObserver = this.onCameraLoadedObservable.add(callback);
         },
-        enumerable: true,
+        enumerable: false,
         configurable: true
     });
     Object.defineProperty(GLTFFileLoader.prototype, "onComplete", {
@@ -2975,7 +3022,7 @@ var GLTFFileLoader = /** @class */ (function () {
             }
             this._onCompleteObserver = this.onCompleteObservable.add(callback);
         },
-        enumerable: true,
+        enumerable: false,
         configurable: true
     });
     Object.defineProperty(GLTFFileLoader.prototype, "onError", {
@@ -2988,7 +3035,7 @@ var GLTFFileLoader = /** @class */ (function () {
             }
             this._onErrorObserver = this.onErrorObservable.add(callback);
         },
-        enumerable: true,
+        enumerable: false,
         configurable: true
     });
     Object.defineProperty(GLTFFileLoader.prototype, "onDispose", {
@@ -3001,7 +3048,7 @@ var GLTFFileLoader = /** @class */ (function () {
             }
             this._onDisposeObserver = this.onDisposeObservable.add(callback);
         },
-        enumerable: true,
+        enumerable: false,
         configurable: true
     });
     Object.defineProperty(GLTFFileLoader.prototype, "onExtensionLoaded", {
@@ -3014,7 +3061,7 @@ var GLTFFileLoader = /** @class */ (function () {
             }
             this._onExtensionLoadedObserver = this.onExtensionLoadedObservable.add(callback);
         },
-        enumerable: true,
+        enumerable: false,
         configurable: true
     });
     Object.defineProperty(GLTFFileLoader.prototype, "loggingEnabled", {
@@ -3036,7 +3083,7 @@ var GLTFFileLoader = /** @class */ (function () {
                 this._log = this._logDisabled;
             }
         },
-        enumerable: true,
+        enumerable: false,
         configurable: true
     });
     Object.defineProperty(GLTFFileLoader.prototype, "capturePerformanceCounters", {
@@ -3060,7 +3107,7 @@ var GLTFFileLoader = /** @class */ (function () {
                 this._endPerformanceCounter = this._endPerformanceCounterDisabled;
             }
         },
-        enumerable: true,
+        enumerable: false,
         configurable: true
     });
     Object.defineProperty(GLTFFileLoader.prototype, "onValidated", {
@@ -3073,7 +3120,7 @@ var GLTFFileLoader = /** @class */ (function () {
             }
             this._onValidatedObserver = this.onValidatedObservable.add(callback);
         },
-        enumerable: true,
+        enumerable: false,
         configurable: true
     });
     /**
@@ -3084,12 +3131,12 @@ var GLTFFileLoader = /** @class */ (function () {
             this._loader.dispose();
             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.onMeshLoadedObservable.clear();
         this.onTextureLoadedObservable.clear();
@@ -3097,45 +3144,43 @@ var GLTFFileLoader = /** @class */ (function () {
         this.onCameraLoadedObservable.clear();
         this.onCompleteObservable.clear();
         this.onExtensionLoadedObservable.clear();
+        this.onDisposeObservable.notifyObservers(undefined);
+        this.onDisposeObservable.clear();
     };
     /** @hidden */
     GLTFFileLoader.prototype.requestFile = function (scene, url, onSuccess, onProgress, useArrayBuffer, onError) {
         var _this = this;
+        this._progressCallback = onProgress;
         if (useArrayBuffer) {
             if (this.useRangeRequests) {
                 if (this.validate) {
                     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"]()
                 };
-                var dataBuffer_1 = {
+                var dataBuffer = {
                     readAsync: function (byteOffset, byteLength) {
                         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));
-                            }, onProgress, true, true, function (error) {
+                            }, true, function (error) {
                                 reject(error);
                             }, function (webRequest) {
                                 webRequest.setRequestHeader("Range", "bytes=" + byteOffset + "-" + (byteOffset + byteLength - 1));
-                            }));
+                            });
                         });
                     },
                     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);
                 }, 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;
                 _this._unpackBinaryAsync(new babylonjs_Misc_observable__WEBPACK_IMPORTED_MODULE_0__["DataReader"]({
                     readAsync: function (byteOffset, byteLength) { return Promise.resolve(new Uint8Array(arrayBuffer, byteOffset, byteLength)); },
@@ -3143,12 +3188,12 @@ var GLTFFileLoader = /** @class */ (function () {
                 })).then(function (loaderData) {
                     onSuccess(loaderData, request);
                 }, 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));
-            onSuccess({ json: _this._parseJson(data) }, response);
-        }, onProgress, true, false, onError);
+            onSuccess({ json: _this._parseJson(data) }, request);
+        }, useArrayBuffer, onError);
     };
     /** @hidden */
     GLTFFileLoader.prototype.readFile = function (scene, file, onSuccess, onProgress, useArrayBuffer, onError) {
@@ -3197,17 +3242,43 @@ var GLTFFileLoader = /** @class */ (function () {
             _this.onParsedObservable.clear();
             _this._log("Loading " + (fileName || ""));
             _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
             var materials = [];
             _this.onMaterialLoadedObservable.add(function (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 = [];
             _this.onTextureLoadedObservable.add(function (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) {
-                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.particleSystems, result.particleSystems);
                 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.lights, result.lights);
                 Array.prototype.push.apply(container.transformNodes, result.transformNodes);
+                Array.prototype.push.apply(container.cameras, cameras);
                 return container;
             });
         });
     };
     /** @hidden */
     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 */
     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);
-        return { json: this._parseJson(data) };
+        return Promise.resolve({ json: this._parseJson(data) });
     };
     /** @hidden */
     GLTFFileLoader.prototype.createPlugin = function () {
@@ -3240,7 +3325,7 @@ var GLTFFileLoader = /** @class */ (function () {
         get: function () {
             return this._loader ? this._loader.state : null;
         },
-        enumerable: true,
+        enumerable: false,
         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) {
         var _this = this;
         if (rootUrl === void 0) { rootUrl = ""; }
@@ -3330,7 +3464,7 @@ var GLTFFileLoader = /** @class */ (function () {
                 _this._log("Binary version: " + version);
             }
             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);
             }
             var unpacked;
@@ -3494,6 +3628,7 @@ var GLTFFileLoader = /** @class */ (function () {
      * @hidden
      */
     GLTFFileLoader.HomogeneousCoordinates = false;
+    GLTFFileLoader.magicBase64Encoded = "Z2xURg"; // "glTF" base64 encoded (without the quotes!)
     GLTFFileLoader._logSpaces = "                                ";
     return GLTFFileLoader;
 }());
@@ -3720,7 +3855,7 @@ if (typeof globalObject !== "undefined") {
 /*!******************************************!*\
   !*** ./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__) {
 
 "use strict";

文件差异内容过多而无法显示
+ 1 - 1
dist/loaders/babylon.glTF1FileLoader.js.map


文件差异内容过多而无法显示
+ 12 - 12
dist/loaders/babylon.glTF1FileLoader.min.js


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


部分文件因为文件数量过多而无法显示