瀏覽代碼

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

lockphase 5 年之前
父節點
當前提交
7c2675ab48
共有 100 個文件被更改,包括 26345 次插入11921 次删除
  1. 1 0
      CNAME.txt
  2. 1 0
      Playground/debug.html
  3. 1 0
      Playground/frame.html
  4. 1 0
      Playground/full.html
  5. 1 0
      Playground/index-local.html
  6. 1 0
      Playground/index.html
  7. 1 0
      Playground/indexWebGPU.html
  8. 1 0
      Playground/zipContent/index.html
  9. 13 4
      Tools/DevLoader/BabylonLoader.js
  10. 6 0
      Tools/Gulp/helpers/gulp-validateImports.js
  11. 1 0
      Viewer/tests/validation/validate.html
  12. 71 182
      dist/preview release/babylon.d.ts
  13. 2 2
      dist/preview release/babylon.js
  14. 240 305
      dist/preview release/babylon.max.js
  15. 1 1
      dist/preview release/babylon.max.js.map
  16. 146 366
      dist/preview release/babylon.module.d.ts
  17. 121 192
      dist/preview release/documentation.d.ts
  18. 6 6
      dist/preview release/inspector/babylon.inspector.bundle.js
  19. 20 3
      dist/preview release/inspector/babylon.inspector.bundle.max.js
  20. 1 1
      dist/preview release/inspector/babylon.inspector.bundle.max.js.map
  21. 3916 1744
      dist/preview release/inspector/babylon.inspector.d.ts
  22. 8168 4035
      dist/preview release/inspector/babylon.inspector.module.d.ts
  23. 22 0
      dist/preview release/libktx.js
  24. 二進制
      dist/preview release/libktx.wasm
  25. 102 41
      dist/preview release/loaders/babylon.glTF2FileLoader.js
  26. 1 1
      dist/preview release/loaders/babylon.glTF2FileLoader.js.map
  27. 1 1
      dist/preview release/loaders/babylon.glTF2FileLoader.min.js
  28. 102 41
      dist/preview release/loaders/babylon.glTFFileLoader.js
  29. 1 1
      dist/preview release/loaders/babylon.glTFFileLoader.js.map
  30. 2 2
      dist/preview release/loaders/babylon.glTFFileLoader.min.js
  31. 50 10
      dist/preview release/loaders/babylonjs.loaders.d.ts
  32. 102 41
      dist/preview release/loaders/babylonjs.loaders.js
  33. 1 1
      dist/preview release/loaders/babylonjs.loaders.js.map
  34. 2 2
      dist/preview release/loaders/babylonjs.loaders.min.js
  35. 108 22
      dist/preview release/loaders/babylonjs.loaders.module.d.ts
  36. 3894 1194
      dist/preview release/nodeEditor/babylon.nodeEditor.d.ts
  37. 6 6
      dist/preview release/nodeEditor/babylon.nodeEditor.js
  38. 232 84
      dist/preview release/nodeEditor/babylon.nodeEditor.max.js
  39. 1 1
      dist/preview release/nodeEditor/babylon.nodeEditor.max.js.map
  40. 8233 2825
      dist/preview release/nodeEditor/babylon.nodeEditor.module.d.ts
  41. 1 1
      dist/preview release/packagesSizeBaseLine.json
  42. 146 366
      dist/preview release/viewer/babylon.module.d.ts
  43. 33 25
      dist/preview release/viewer/babylon.viewer.js
  44. 2 2
      dist/preview release/viewer/babylon.viewer.max.js
  45. 108 22
      dist/preview release/viewer/babylonjs.loaders.module.d.ts
  46. 5 0
      dist/preview release/what's new.md
  47. 4 0
      inspector/custom.d.ts
  48. 3 0
      inspector/src/components/actionTabs/actionTabs.scss
  49. 4 2
      inspector/src/components/actionTabs/lines/color3LineComponent.tsx
  50. 3 2
      inspector/src/components/actionTabs/lines/color4LineComponent.tsx
  51. 1 0
      inspector/src/components/actionTabs/lines/copy.svg
  52. 4 1
      inspector/tsconfig.json
  53. 13 1
      inspector/webpack.config.js
  54. 1 1
      loaders/src/glTF/2.0/Extensions/KHR_lights_punctual.ts
  55. 49 0
      loaders/src/glTF/2.0/Extensions/KHR_texture_basisu.ts
  56. 1 1
      loaders/src/glTF/2.0/Extensions/KHR_texture_transform.ts
  57. 1 0
      loaders/src/glTF/2.0/Extensions/index.ts
  58. 34 27
      loaders/src/glTF/2.0/glTFLoader.ts
  59. 21 7
      loaders/src/glTF/2.0/glTFLoaderExtension.ts
  60. 1 0
      localDev/index-views.html
  61. 1 0
      localDev/index.html
  62. 4 0
      nodeEditor/custom.d.ts
  63. 28 55
      nodeEditor/src/components/preview/previewAreaComponent.tsx
  64. 53 7
      nodeEditor/src/components/preview/previewMeshControlComponent.tsx
  65. 1 0
      nodeEditor/src/components/preview/svgs/colorPicker.svg
  66. 1 0
      nodeEditor/src/components/preview/svgs/depthPass.svg
  67. 1 0
      nodeEditor/src/components/preview/svgs/directionalLeft.svg
  68. 1 0
      nodeEditor/src/components/preview/svgs/directionalRight.svg
  69. 1 0
      nodeEditor/src/components/preview/svgs/doubleSided.svg
  70. 1 0
      nodeEditor/src/components/preview/svgs/omni.svg
  71. 1 0
      nodeEditor/src/components/preview/svgs/pauseIcon.svg
  72. 1 0
      nodeEditor/src/components/preview/svgs/playIcon.svg
  73. 1 0
      nodeEditor/src/components/preview/svgs/popOut.svg
  74. 4 0
      nodeEditor/src/components/propertyTab/propertyTab.scss
  75. 2 1
      nodeEditor/src/diagram/graphCanvas.tsx
  76. 3 3
      nodeEditor/src/globalState.ts
  77. 17 9
      nodeEditor/src/graphEditor.tsx
  78. 96 18
      nodeEditor/src/main.scss
  79. 3 2
      nodeEditor/src/sharedComponents/color3LineComponent.tsx
  80. 4 2
      nodeEditor/src/sharedComponents/color4LineComponent.tsx
  81. 1 0
      nodeEditor/src/sharedComponents/copy.svg
  82. 5 2
      nodeEditor/tsconfig.json
  83. 12 1
      nodeEditor/webpack.config.js
  84. 3 2
      package.json
  85. 1 0
      sandbox/debug.html
  86. 1 0
      sandbox/index-local.html
  87. 1 0
      sandbox/index.html
  88. 3 17
      src/Engines/Extensions/engine.cubeTexture.ts
  89. 0 44
      src/Engines/engine.ts
  90. 15 42
      src/Engines/nativeEngine.ts
  91. 6 5
      src/Engines/nullEngine.ts
  92. 11 52
      src/Engines/thinEngine.ts
  93. 18 0
      src/Layers/highlightLayer.ts
  94. 4 2
      src/Materials/Node/Blocks/Dual/reflectionTextureBlock.ts
  95. 8 1
      src/Materials/Node/nodeMaterialBlockConnectionPoint.ts
  96. 2 0
      src/Materials/PBR/pbrBaseMaterial.ts
  97. 5 28
      src/Materials/Textures/Loaders/basisTextureLoader.ts
  98. 5 28
      src/Materials/Textures/Loaders/ddsTextureLoader.ts
  99. 5 28
      src/Materials/Textures/Loaders/envTextureLoader.ts
  100. 0 0
      src/Materials/Textures/Loaders/ktxTextureLoader.ts

+ 1 - 0
CNAME.txt

@@ -0,0 +1 @@
+babylonjs.com

+ 1 - 0
Playground/debug.html

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

+ 1 - 0
Playground/frame.html

@@ -24,6 +24,7 @@
         <script src="https://preview.babylonjs.com/recast.js"></script>
         <script src="https://preview.babylonjs.com/recast.js"></script>
         <script src="https://preview.babylonjs.com/cannon.js"></script>
         <script src="https://preview.babylonjs.com/cannon.js"></script>
         <script src="https://preview.babylonjs.com/Oimo.js"></script>
         <script src="https://preview.babylonjs.com/Oimo.js"></script>
+        <script src="https://preview.babylonjs.com/libktx.js"></script>
         <script src="https://preview.babylonjs.com/earcut.min.js"></script>
         <script src="https://preview.babylonjs.com/earcut.min.js"></script>
         <script src="https://preview.babylonjs.com/babylon.js"></script>
         <script src="https://preview.babylonjs.com/babylon.js"></script>
         <script src="https://preview.babylonjs.com/gui/babylon.gui.min.js"></script>
         <script src="https://preview.babylonjs.com/gui/babylon.gui.min.js"></script>

+ 1 - 0
Playground/full.html

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

+ 1 - 0
Playground/index-local.html

@@ -31,6 +31,7 @@
         <script src="../dist/preview%20release/recast.js"></script>
         <script src="../dist/preview%20release/recast.js"></script>
         <script src="../dist/preview%20release/cannon.js"></script>
         <script src="../dist/preview%20release/cannon.js"></script>
         <script src="../dist/preview%20release/Oimo.js"></script>
         <script src="../dist/preview%20release/Oimo.js"></script>
+        <script src="../dist/preview%20release/libktx.js"></script>
         <script src="../dist/preview%20release/earcut.min.js"></script>
         <script src="../dist/preview%20release/earcut.min.js"></script>
         <!-- Monaco -->
         <!-- Monaco -->
 
 

+ 1 - 0
Playground/index.html

@@ -401,6 +401,7 @@
         <script src="https://preview.babylonjs.com/recast.js"></script>
         <script src="https://preview.babylonjs.com/recast.js"></script>
         <script src="https://preview.babylonjs.com/cannon.js"></script>
         <script src="https://preview.babylonjs.com/cannon.js"></script>
         <script src="https://preview.babylonjs.com/Oimo.js"></script>
         <script src="https://preview.babylonjs.com/Oimo.js"></script>
+        <script src="https://preview.babylonjs.com/libktx.js"></script>
         <script src="https://preview.babylonjs.com/earcut.min.js"></script>
         <script src="https://preview.babylonjs.com/earcut.min.js"></script>
         <!-- Babylon.js -->
         <!-- Babylon.js -->
         <script src="https://preview.babylonjs.com/babylon.js"></script>
         <script src="https://preview.babylonjs.com/babylon.js"></script>

+ 1 - 0
Playground/indexWebGPU.html

@@ -28,6 +28,7 @@
         <script src="https://preview.babylonjs.com/recast.js"></script>
         <script src="https://preview.babylonjs.com/recast.js"></script>
         <script src="https://preview.babylonjs.com/cannon.js"></script>
         <script src="https://preview.babylonjs.com/cannon.js"></script>
         <script src="https://preview.babylonjs.com/Oimo.js"></script>
         <script src="https://preview.babylonjs.com/Oimo.js"></script>
+        <script src="https://preview.babylonjs.com/libktx.js"></script>
         <script src="https://preview.babylonjs.com/earcut.min.js"></script>
         <script src="https://preview.babylonjs.com/earcut.min.js"></script>
         <!-- Babylon.js -->
         <!-- Babylon.js -->
         <script src="https://preview.babylonjs.com/glslang/glslang.js"></script>
         <script src="https://preview.babylonjs.com/glslang/glslang.js"></script>

+ 1 - 0
Playground/zipContent/index.html

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

+ 13 - 4
Tools/DevLoader/BabylonLoader.js

@@ -3,6 +3,9 @@
 var BABYLONDEVTOOLS;
 var BABYLONDEVTOOLS;
 (function(BABYLONDEVTOOLS) {
 (function(BABYLONDEVTOOLS) {
 
 
+    var ua = window.navigator.userAgent;
+    var isIE = ua.indexOf("Trident") > 0;
+
     var getJson = function(url, callback, errorCallback) {
     var getJson = function(url, callback, errorCallback) {
         var xhr = new XMLHttpRequest();
         var xhr = new XMLHttpRequest();
         xhr.open('GET', url);
         xhr.open('GET', url);
@@ -145,9 +148,15 @@ var BABYLONDEVTOOLS;
             }
             }
 
 
             var self = this;
             var self = this;
-            script.onload = function() {
-                self.dequeue();
-            };
+            if (isIE) { // I love you IE
+                setTimeout(function() {
+                    self.dequeue();
+                }, 500);
+            } else {
+                script.onload = function() {
+                    self.dequeue();
+                };
+            }
             head.appendChild(script);
             head.appendChild(script);
         }
         }
 
 
@@ -209,7 +218,7 @@ var BABYLONDEVTOOLS;
         }
         }
 
 
         Loader.prototype.loadCoreDev = function() {
         Loader.prototype.loadCoreDev = function() {
-            if (typeof document === "undefined") {                
+            if (typeof document === "undefined" || isIE) {                
                 this.loadScript(babylonJSPath + "/dist/preview release/babylon.max.js");
                 this.loadScript(babylonJSPath + "/dist/preview release/babylon.max.js");
                 return;
                 return;
             }
             }

+ 6 - 0
Tools/Gulp/helpers/gulp-validateImports.js

@@ -17,6 +17,12 @@ config.modules.forEach(moduleName => {
 
 
 var validatePath = function(fileLocation, directory, module, lineNumber, errors, isExport) {
 var validatePath = function(fileLocation, directory, module, lineNumber, errors, isExport) {
     let expressionType = isExport ? "Export" : "Import";
     let expressionType = isExport ? "Export" : "Import";
+
+    //Not checking svg files
+    if(module.endsWith(".svg")){
+        return;
+    }
+
     let internalModulePath = path.join(directory, module + ".ts");
     let internalModulePath = path.join(directory, module + ".ts");
 
 
     // Check .ts path.
     // Check .ts path.

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

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

文件差異過大導致無法顯示
+ 71 - 182
dist/preview release/babylon.d.ts


文件差異過大導致無法顯示
+ 2 - 2
dist/preview release/babylon.js


文件差異過大導致無法顯示
+ 240 - 305
dist/preview release/babylon.max.js


文件差異過大導致無法顯示
+ 1 - 1
dist/preview release/babylon.max.js.map


文件差異過大導致無法顯示
+ 146 - 366
dist/preview release/babylon.module.d.ts


文件差異過大導致無法顯示
+ 121 - 192
dist/preview release/documentation.d.ts


文件差異過大導致無法顯示
+ 6 - 6
dist/preview release/inspector/babylon.inspector.bundle.js


文件差異過大導致無法顯示
+ 20 - 3
dist/preview release/inspector/babylon.inspector.bundle.max.js


文件差異過大導致無法顯示
+ 1 - 1
dist/preview release/inspector/babylon.inspector.bundle.max.js.map


文件差異過大導致無法顯示
+ 3916 - 1744
dist/preview release/inspector/babylon.inspector.d.ts


文件差異過大導致無法顯示
+ 8168 - 4035
dist/preview release/inspector/babylon.inspector.module.d.ts


文件差異過大導致無法顯示
+ 22 - 0
dist/preview release/libktx.js


二進制
dist/preview release/libktx.wasm


+ 102 - 41
dist/preview release/loaders/babylon.glTF2FileLoader.js

@@ -441,7 +441,7 @@ var LightType;
     LightType["SPOT"] = "spot";
     LightType["SPOT"] = "spot";
 })(LightType || (LightType = {}));
 })(LightType || (LightType = {}));
 /**
 /**
- * [Specification](https://github.com/KhronosGroup/glTF/blob/master/extensions/2.0/Khronos/KHR_lights_punctual/README.md)
+ * [Specification](https://github.com/KhronosGroup/glTF/blob/master/extensions/2.0/Khronos/KHR_lights_punctual)
  */
  */
 var KHR_lights = /** @class */ (function () {
 var KHR_lights = /** @class */ (function () {
     /** @hidden */
     /** @hidden */
@@ -974,6 +974,56 @@ _glTFLoader__WEBPACK_IMPORTED_MODULE_0__["GLTFLoader"].RegisterExtension(NAME, f
 
 
 /***/ }),
 /***/ }),
 
 
+/***/ "./glTF/2.0/Extensions/KHR_texture_basisu.ts":
+/*!***************************************************!*\
+  !*** ./glTF/2.0/Extensions/KHR_texture_basisu.ts ***!
+  \***************************************************/
+/*! exports provided: KHR_texture_basisu */
+/***/ (function(module, __webpack_exports__, __webpack_require__) {
+
+"use strict";
+__webpack_require__.r(__webpack_exports__);
+/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "KHR_texture_basisu", function() { return KHR_texture_basisu; });
+/* harmony import */ var _glTFLoader__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../glTFLoader */ "./glTF/2.0/glTFLoader.ts");
+
+var NAME = "KHR_texture_basisu";
+/**
+ * [Proposed Specification](https://github.com/KhronosGroup/glTF/pull/1751)
+ * !!! Experimental Extension Subject to Changes !!!
+ */
+var KHR_texture_basisu = /** @class */ (function () {
+    /** @hidden */
+    function KHR_texture_basisu(loader) {
+        /** The name of this extension. */
+        this.name = NAME;
+        /** Defines whether this extension is enabled. */
+        this.enabled = true;
+        this._loader = loader;
+    }
+    /** @hidden */
+    KHR_texture_basisu.prototype.dispose = function () {
+        delete this._loader;
+    };
+    /** @hidden */
+    KHR_texture_basisu.prototype.loadTextureAsync = function (context, texture, assign) {
+        var _this = this;
+        return _glTFLoader__WEBPACK_IMPORTED_MODULE_0__["GLTFLoader"].LoadExtensionAsync(context, texture, this.name, function (extensionContext, extension) {
+            var sampler = (texture.sampler == undefined ? _glTFLoader__WEBPACK_IMPORTED_MODULE_0__["GLTFLoader"].DefaultSampler : _glTFLoader__WEBPACK_IMPORTED_MODULE_0__["ArrayItem"].Get(context + "/sampler", _this._loader.gltf.samplers, texture.sampler));
+            var image = _glTFLoader__WEBPACK_IMPORTED_MODULE_0__["ArrayItem"].Get(extensionContext + "/source", _this._loader.gltf.images, extension.source);
+            return _this._loader._createTextureAsync(context, sampler, image, function (babylonTexture) {
+                babylonTexture.gammaSpace = false;
+                assign(babylonTexture);
+            });
+        });
+    };
+    return KHR_texture_basisu;
+}());
+
+_glTFLoader__WEBPACK_IMPORTED_MODULE_0__["GLTFLoader"].RegisterExtension(NAME, function (loader) { return new KHR_texture_basisu(loader); });
+
+
+/***/ }),
+
 /***/ "./glTF/2.0/Extensions/KHR_texture_transform.ts":
 /***/ "./glTF/2.0/Extensions/KHR_texture_transform.ts":
 /*!******************************************************!*\
 /*!******************************************************!*\
   !*** ./glTF/2.0/Extensions/KHR_texture_transform.ts ***!
   !*** ./glTF/2.0/Extensions/KHR_texture_transform.ts ***!
@@ -991,7 +1041,7 @@ __webpack_require__.r(__webpack_exports__);
 
 
 var NAME = "KHR_texture_transform";
 var NAME = "KHR_texture_transform";
 /**
 /**
- * [Specification](https://github.com/KhronosGroup/glTF/blob/master/extensions/2.0/Khronos/KHR_texture_transform/README.md)
+ * [Specification](https://github.com/KhronosGroup/glTF/blob/master/extensions/2.0/Khronos/KHR_texture_transform)
  */
  */
 var KHR_texture_transform = /** @class */ (function () {
 var KHR_texture_transform = /** @class */ (function () {
     /** @hidden */
     /** @hidden */
@@ -1728,7 +1778,7 @@ _glTFLoader__WEBPACK_IMPORTED_MODULE_1__["GLTFLoader"].RegisterExtension(NAME, f
 /*!**************************************!*\
 /*!**************************************!*\
   !*** ./glTF/2.0/Extensions/index.ts ***!
   !*** ./glTF/2.0/Extensions/index.ts ***!
   \**************************************/
   \**************************************/
-/*! exports provided: EXT_lights_image_based, KHR_draco_mesh_compression, KHR_lights, KHR_materials_pbrSpecularGlossiness, KHR_materials_unlit, KHR_materials_clearcoat, KHR_materials_sheen, KHR_materials_specular, KHR_mesh_quantization, KHR_texture_transform, MSFT_audio_emitter, MSFT_lod, MSFT_minecraftMesh, MSFT_sRGBFactors, ExtrasAsMetadata */
+/*! exports provided: EXT_lights_image_based, KHR_draco_mesh_compression, KHR_lights, KHR_materials_pbrSpecularGlossiness, KHR_materials_unlit, KHR_materials_clearcoat, KHR_materials_sheen, KHR_materials_specular, KHR_mesh_quantization, KHR_texture_basisu, KHR_texture_transform, MSFT_audio_emitter, MSFT_lod, MSFT_minecraftMesh, MSFT_sRGBFactors, ExtrasAsMetadata */
 /***/ (function(module, __webpack_exports__, __webpack_require__) {
 /***/ (function(module, __webpack_exports__, __webpack_require__) {
 
 
 "use strict";
 "use strict";
@@ -1760,24 +1810,28 @@ __webpack_require__.r(__webpack_exports__);
 /* harmony import */ var _KHR_mesh_quantization__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ./KHR_mesh_quantization */ "./glTF/2.0/Extensions/KHR_mesh_quantization.ts");
 /* harmony import */ var _KHR_mesh_quantization__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ./KHR_mesh_quantization */ "./glTF/2.0/Extensions/KHR_mesh_quantization.ts");
 /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "KHR_mesh_quantization", function() { return _KHR_mesh_quantization__WEBPACK_IMPORTED_MODULE_8__["KHR_mesh_quantization"]; });
 /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "KHR_mesh_quantization", function() { return _KHR_mesh_quantization__WEBPACK_IMPORTED_MODULE_8__["KHR_mesh_quantization"]; });
 
 
-/* harmony import */ var _KHR_texture_transform__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ./KHR_texture_transform */ "./glTF/2.0/Extensions/KHR_texture_transform.ts");
-/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "KHR_texture_transform", function() { return _KHR_texture_transform__WEBPACK_IMPORTED_MODULE_9__["KHR_texture_transform"]; });
+/* harmony import */ var _KHR_texture_basisu__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ./KHR_texture_basisu */ "./glTF/2.0/Extensions/KHR_texture_basisu.ts");
+/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "KHR_texture_basisu", function() { return _KHR_texture_basisu__WEBPACK_IMPORTED_MODULE_9__["KHR_texture_basisu"]; });
 
 
-/* harmony import */ var _MSFT_audio_emitter__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! ./MSFT_audio_emitter */ "./glTF/2.0/Extensions/MSFT_audio_emitter.ts");
-/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "MSFT_audio_emitter", function() { return _MSFT_audio_emitter__WEBPACK_IMPORTED_MODULE_10__["MSFT_audio_emitter"]; });
+/* harmony import */ var _KHR_texture_transform__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! ./KHR_texture_transform */ "./glTF/2.0/Extensions/KHR_texture_transform.ts");
+/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "KHR_texture_transform", function() { return _KHR_texture_transform__WEBPACK_IMPORTED_MODULE_10__["KHR_texture_transform"]; });
 
 
-/* harmony import */ var _MSFT_lod__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(/*! ./MSFT_lod */ "./glTF/2.0/Extensions/MSFT_lod.ts");
-/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "MSFT_lod", function() { return _MSFT_lod__WEBPACK_IMPORTED_MODULE_11__["MSFT_lod"]; });
+/* harmony import */ var _MSFT_audio_emitter__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(/*! ./MSFT_audio_emitter */ "./glTF/2.0/Extensions/MSFT_audio_emitter.ts");
+/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "MSFT_audio_emitter", function() { return _MSFT_audio_emitter__WEBPACK_IMPORTED_MODULE_11__["MSFT_audio_emitter"]; });
 
 
-/* harmony import */ var _MSFT_minecraftMesh__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__(/*! ./MSFT_minecraftMesh */ "./glTF/2.0/Extensions/MSFT_minecraftMesh.ts");
-/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "MSFT_minecraftMesh", function() { return _MSFT_minecraftMesh__WEBPACK_IMPORTED_MODULE_12__["MSFT_minecraftMesh"]; });
+/* harmony import */ var _MSFT_lod__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__(/*! ./MSFT_lod */ "./glTF/2.0/Extensions/MSFT_lod.ts");
+/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "MSFT_lod", function() { return _MSFT_lod__WEBPACK_IMPORTED_MODULE_12__["MSFT_lod"]; });
 
 
-/* harmony import */ var _MSFT_sRGBFactors__WEBPACK_IMPORTED_MODULE_13__ = __webpack_require__(/*! ./MSFT_sRGBFactors */ "./glTF/2.0/Extensions/MSFT_sRGBFactors.ts");
-/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "MSFT_sRGBFactors", function() { return _MSFT_sRGBFactors__WEBPACK_IMPORTED_MODULE_13__["MSFT_sRGBFactors"]; });
+/* harmony import */ var _MSFT_minecraftMesh__WEBPACK_IMPORTED_MODULE_13__ = __webpack_require__(/*! ./MSFT_minecraftMesh */ "./glTF/2.0/Extensions/MSFT_minecraftMesh.ts");
+/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "MSFT_minecraftMesh", function() { return _MSFT_minecraftMesh__WEBPACK_IMPORTED_MODULE_13__["MSFT_minecraftMesh"]; });
 
 
-/* harmony import */ var _ExtrasAsMetadata__WEBPACK_IMPORTED_MODULE_14__ = __webpack_require__(/*! ./ExtrasAsMetadata */ "./glTF/2.0/Extensions/ExtrasAsMetadata.ts");
-/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "ExtrasAsMetadata", function() { return _ExtrasAsMetadata__WEBPACK_IMPORTED_MODULE_14__["ExtrasAsMetadata"]; });
+/* harmony import */ var _MSFT_sRGBFactors__WEBPACK_IMPORTED_MODULE_14__ = __webpack_require__(/*! ./MSFT_sRGBFactors */ "./glTF/2.0/Extensions/MSFT_sRGBFactors.ts");
+/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "MSFT_sRGBFactors", function() { return _MSFT_sRGBFactors__WEBPACK_IMPORTED_MODULE_14__["MSFT_sRGBFactors"]; });
 
 
+/* harmony import */ var _ExtrasAsMetadata__WEBPACK_IMPORTED_MODULE_15__ = __webpack_require__(/*! ./ExtrasAsMetadata */ "./glTF/2.0/Extensions/ExtrasAsMetadata.ts");
+/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "ExtrasAsMetadata", function() { return _ExtrasAsMetadata__WEBPACK_IMPORTED_MODULE_15__["ExtrasAsMetadata"]; });
+
+
 
 
 
 
 
 
@@ -1913,7 +1967,7 @@ var GLTFLoader = /** @class */ (function () {
     };
     };
     Object.defineProperty(GLTFLoader.prototype, "state", {
     Object.defineProperty(GLTFLoader.prototype, "state", {
         /**
         /**
-         * Gets the loader state.
+         * The loader state.
          */
          */
         get: function () {
         get: function () {
             return this._state;
             return this._state;
@@ -3455,27 +3509,29 @@ var GLTFLoader = /** @class */ (function () {
         this.logClose();
         this.logClose();
         return promise;
         return promise;
     };
     };
+    /** @hidden */
     GLTFLoader.prototype._loadTextureAsync = function (context, texture, assign) {
     GLTFLoader.prototype._loadTextureAsync = function (context, texture, assign) {
-        var _this = this;
         if (assign === void 0) { assign = function () { }; }
         if (assign === void 0) { assign = function () { }; }
-        var promises = new Array();
+        var extensionPromise = this._extensionsLoadTextureAsync(context, texture, assign);
+        if (extensionPromise) {
+            return extensionPromise;
+        }
         this.logOpen(context + " " + (texture.name || ""));
         this.logOpen(context + " " + (texture.name || ""));
-        var sampler = (texture.sampler == undefined ? GLTFLoader._DefaultSampler : ArrayItem.Get(context + "/sampler", this._gltf.samplers, texture.sampler));
-        var samplerData = this._loadSampler("/samplers/" + sampler.index, sampler);
+        var sampler = (texture.sampler == undefined ? GLTFLoader.DefaultSampler : ArrayItem.Get(context + "/sampler", this._gltf.samplers, texture.sampler));
         var image = ArrayItem.Get(context + "/source", this._gltf.images, texture.source);
         var image = ArrayItem.Get(context + "/source", this._gltf.images, texture.source);
-        var url = null;
-        if (image.uri) {
-            if (babylonjs_Misc_deferred__WEBPACK_IMPORTED_MODULE_0__["Tools"].IsBase64(image.uri)) {
-                url = image.uri;
-            }
-            else if (this._babylonScene.getEngine().textureFormatInUse) {
-                // If an image uri and a texture format is set like (eg. KTX) load from url instead of blob to support texture format and fallback
-                url = this._rootUrl + image.uri;
-            }
-        }
+        var promise = this._createTextureAsync(context, sampler, image, assign);
+        this.logClose();
+        return promise;
+    };
+    /** @hidden */
+    GLTFLoader.prototype._createTextureAsync = function (context, sampler, image, assign) {
+        var _this = this;
+        if (assign === void 0) { assign = function () { }; }
+        var samplerData = this._loadSampler("/samplers/" + sampler.index, sampler);
+        var promises = new Array();
         var deferred = new babylonjs_Misc_deferred__WEBPACK_IMPORTED_MODULE_0__["Deferred"]();
         var deferred = new babylonjs_Misc_deferred__WEBPACK_IMPORTED_MODULE_0__["Deferred"]();
         this._babylonScene._blockEntityCollection = this._forAssetContainer;
         this._babylonScene._blockEntityCollection = this._forAssetContainer;
-        var babylonTexture = new babylonjs_Misc_deferred__WEBPACK_IMPORTED_MODULE_0__["Texture"](url, this._babylonScene, samplerData.noMipMaps, false, samplerData.samplingMode, function () {
+        var babylonTexture = new babylonjs_Misc_deferred__WEBPACK_IMPORTED_MODULE_0__["Texture"](null, this._babylonScene, samplerData.noMipMaps, false, samplerData.samplingMode, function () {
             if (!_this._disposed) {
             if (!_this._disposed) {
                 deferred.resolve();
                 deferred.resolve();
             }
             }
@@ -3486,17 +3542,14 @@ var GLTFLoader = /** @class */ (function () {
         }, undefined, undefined, undefined, image.mimeType);
         }, undefined, undefined, undefined, image.mimeType);
         this._babylonScene._blockEntityCollection = false;
         this._babylonScene._blockEntityCollection = false;
         promises.push(deferred.promise);
         promises.push(deferred.promise);
-        if (!url) {
-            promises.push(this.loadImageAsync("/images/" + image.index, image).then(function (data) {
-                var name = image.uri || _this._fileName + "#image" + image.index;
-                var dataUrl = "data:" + _this._uniqueRootUrl + name;
-                babylonTexture.updateURL(dataUrl, data);
-            }));
-        }
+        promises.push(this.loadImageAsync("/images/" + image.index, image).then(function (data) {
+            var name = image.uri || _this._fileName + "#image" + image.index;
+            var dataUrl = "data:" + _this._uniqueRootUrl + name;
+            babylonTexture.updateURL(dataUrl, data);
+        }));
         babylonTexture.wrapU = samplerData.wrapU;
         babylonTexture.wrapU = samplerData.wrapU;
         babylonTexture.wrapV = samplerData.wrapV;
         babylonTexture.wrapV = samplerData.wrapV;
         assign(babylonTexture);
         assign(babylonTexture);
-        this.logClose();
         return Promise.all(promises).then(function () {
         return Promise.all(promises).then(function () {
             return babylonTexture;
             return babylonTexture;
         });
         });
@@ -3827,6 +3880,9 @@ var GLTFLoader = /** @class */ (function () {
     GLTFLoader.prototype._extensionsLoadTextureInfoAsync = function (context, textureInfo, assign) {
     GLTFLoader.prototype._extensionsLoadTextureInfoAsync = function (context, textureInfo, assign) {
         return this._applyExtensions(textureInfo, "loadTextureInfo", function (extension) { return extension.loadTextureInfoAsync && extension.loadTextureInfoAsync(context, textureInfo, assign); });
         return this._applyExtensions(textureInfo, "loadTextureInfo", function (extension) { return extension.loadTextureInfoAsync && extension.loadTextureInfoAsync(context, textureInfo, assign); });
     };
     };
+    GLTFLoader.prototype._extensionsLoadTextureAsync = function (context, texture, assign) {
+        return this._applyExtensions(texture, "loadTexture", function (extension) { return extension._loadTextureAsync && extension._loadTextureAsync(context, texture, assign); });
+    };
     GLTFLoader.prototype._extensionsLoadAnimationAsync = function (context, animation) {
     GLTFLoader.prototype._extensionsLoadAnimationAsync = function (context, animation) {
         return this._applyExtensions(animation, "loadAnimation", function (extension) { return extension.loadAnimationAsync && extension.loadAnimationAsync(context, animation); });
         return this._applyExtensions(animation, "loadAnimation", function (extension) { return extension.loadAnimationAsync && extension.loadAnimationAsync(context, animation); });
     };
     };
@@ -3922,8 +3978,11 @@ var GLTFLoader = /** @class */ (function () {
     GLTFLoader.prototype.endPerformanceCounter = function (counterName) {
     GLTFLoader.prototype.endPerformanceCounter = function (counterName) {
         this._parent._endPerformanceCounter(counterName);
         this._parent._endPerformanceCounter(counterName);
     };
     };
-    GLTFLoader._DefaultSampler = { index: -1 };
     GLTFLoader._RegisteredExtensions = {};
     GLTFLoader._RegisteredExtensions = {};
+    /**
+     * The default glTF sampler.
+     */
+    GLTFLoader.DefaultSampler = { index: -1 };
     return GLTFLoader;
     return GLTFLoader;
 }());
 }());
 
 
@@ -3947,7 +4006,7 @@ _glTFFileLoader__WEBPACK_IMPORTED_MODULE_1__["GLTFFileLoader"]._CreateGLTF2Loade
 /*!***************************!*\
 /*!***************************!*\
   !*** ./glTF/2.0/index.ts ***!
   !*** ./glTF/2.0/index.ts ***!
   \***************************/
   \***************************/
-/*! exports provided: ArrayItem, GLTFLoader, EXT_lights_image_based, KHR_draco_mesh_compression, KHR_lights, KHR_materials_pbrSpecularGlossiness, KHR_materials_unlit, KHR_materials_clearcoat, KHR_materials_sheen, KHR_materials_specular, KHR_mesh_quantization, KHR_texture_transform, MSFT_audio_emitter, MSFT_lod, MSFT_minecraftMesh, MSFT_sRGBFactors, ExtrasAsMetadata */
+/*! exports provided: ArrayItem, GLTFLoader, EXT_lights_image_based, KHR_draco_mesh_compression, KHR_lights, KHR_materials_pbrSpecularGlossiness, KHR_materials_unlit, KHR_materials_clearcoat, KHR_materials_sheen, KHR_materials_specular, KHR_mesh_quantization, KHR_texture_basisu, KHR_texture_transform, MSFT_audio_emitter, MSFT_lod, MSFT_minecraftMesh, MSFT_sRGBFactors, ExtrasAsMetadata */
 /***/ (function(module, __webpack_exports__, __webpack_require__) {
 /***/ (function(module, __webpack_exports__, __webpack_require__) {
 
 
 "use strict";
 "use strict";
@@ -3976,6 +4035,8 @@ __webpack_require__.r(__webpack_exports__);
 
 
 /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "KHR_mesh_quantization", function() { return _Extensions__WEBPACK_IMPORTED_MODULE_1__["KHR_mesh_quantization"]; });
 /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "KHR_mesh_quantization", function() { return _Extensions__WEBPACK_IMPORTED_MODULE_1__["KHR_mesh_quantization"]; });
 
 
+/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "KHR_texture_basisu", function() { return _Extensions__WEBPACK_IMPORTED_MODULE_1__["KHR_texture_basisu"]; });
+
 /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "KHR_texture_transform", function() { return _Extensions__WEBPACK_IMPORTED_MODULE_1__["KHR_texture_transform"]; });
 /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "KHR_texture_transform", function() { return _Extensions__WEBPACK_IMPORTED_MODULE_1__["KHR_texture_transform"]; });
 
 
 /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "MSFT_audio_emitter", function() { return _Extensions__WEBPACK_IMPORTED_MODULE_1__["MSFT_audio_emitter"]; });
 /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "MSFT_audio_emitter", function() { return _Extensions__WEBPACK_IMPORTED_MODULE_1__["MSFT_audio_emitter"]; });

文件差異過大導致無法顯示
+ 1 - 1
dist/preview release/loaders/babylon.glTF2FileLoader.js.map


文件差異過大導致無法顯示
+ 1 - 1
dist/preview release/loaders/babylon.glTF2FileLoader.min.js


+ 102 - 41
dist/preview release/loaders/babylon.glTFFileLoader.js

@@ -3018,7 +3018,7 @@ var LightType;
     LightType["SPOT"] = "spot";
     LightType["SPOT"] = "spot";
 })(LightType || (LightType = {}));
 })(LightType || (LightType = {}));
 /**
 /**
- * [Specification](https://github.com/KhronosGroup/glTF/blob/master/extensions/2.0/Khronos/KHR_lights_punctual/README.md)
+ * [Specification](https://github.com/KhronosGroup/glTF/blob/master/extensions/2.0/Khronos/KHR_lights_punctual)
  */
  */
 var KHR_lights = /** @class */ (function () {
 var KHR_lights = /** @class */ (function () {
     /** @hidden */
     /** @hidden */
@@ -3551,6 +3551,56 @@ _glTFLoader__WEBPACK_IMPORTED_MODULE_0__["GLTFLoader"].RegisterExtension(NAME, f
 
 
 /***/ }),
 /***/ }),
 
 
+/***/ "./glTF/2.0/Extensions/KHR_texture_basisu.ts":
+/*!***************************************************!*\
+  !*** ./glTF/2.0/Extensions/KHR_texture_basisu.ts ***!
+  \***************************************************/
+/*! exports provided: KHR_texture_basisu */
+/***/ (function(module, __webpack_exports__, __webpack_require__) {
+
+"use strict";
+__webpack_require__.r(__webpack_exports__);
+/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "KHR_texture_basisu", function() { return KHR_texture_basisu; });
+/* harmony import */ var _glTFLoader__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../glTFLoader */ "./glTF/2.0/glTFLoader.ts");
+
+var NAME = "KHR_texture_basisu";
+/**
+ * [Proposed Specification](https://github.com/KhronosGroup/glTF/pull/1751)
+ * !!! Experimental Extension Subject to Changes !!!
+ */
+var KHR_texture_basisu = /** @class */ (function () {
+    /** @hidden */
+    function KHR_texture_basisu(loader) {
+        /** The name of this extension. */
+        this.name = NAME;
+        /** Defines whether this extension is enabled. */
+        this.enabled = true;
+        this._loader = loader;
+    }
+    /** @hidden */
+    KHR_texture_basisu.prototype.dispose = function () {
+        delete this._loader;
+    };
+    /** @hidden */
+    KHR_texture_basisu.prototype.loadTextureAsync = function (context, texture, assign) {
+        var _this = this;
+        return _glTFLoader__WEBPACK_IMPORTED_MODULE_0__["GLTFLoader"].LoadExtensionAsync(context, texture, this.name, function (extensionContext, extension) {
+            var sampler = (texture.sampler == undefined ? _glTFLoader__WEBPACK_IMPORTED_MODULE_0__["GLTFLoader"].DefaultSampler : _glTFLoader__WEBPACK_IMPORTED_MODULE_0__["ArrayItem"].Get(context + "/sampler", _this._loader.gltf.samplers, texture.sampler));
+            var image = _glTFLoader__WEBPACK_IMPORTED_MODULE_0__["ArrayItem"].Get(extensionContext + "/source", _this._loader.gltf.images, extension.source);
+            return _this._loader._createTextureAsync(context, sampler, image, function (babylonTexture) {
+                babylonTexture.gammaSpace = false;
+                assign(babylonTexture);
+            });
+        });
+    };
+    return KHR_texture_basisu;
+}());
+
+_glTFLoader__WEBPACK_IMPORTED_MODULE_0__["GLTFLoader"].RegisterExtension(NAME, function (loader) { return new KHR_texture_basisu(loader); });
+
+
+/***/ }),
+
 /***/ "./glTF/2.0/Extensions/KHR_texture_transform.ts":
 /***/ "./glTF/2.0/Extensions/KHR_texture_transform.ts":
 /*!******************************************************!*\
 /*!******************************************************!*\
   !*** ./glTF/2.0/Extensions/KHR_texture_transform.ts ***!
   !*** ./glTF/2.0/Extensions/KHR_texture_transform.ts ***!
@@ -3568,7 +3618,7 @@ __webpack_require__.r(__webpack_exports__);
 
 
 var NAME = "KHR_texture_transform";
 var NAME = "KHR_texture_transform";
 /**
 /**
- * [Specification](https://github.com/KhronosGroup/glTF/blob/master/extensions/2.0/Khronos/KHR_texture_transform/README.md)
+ * [Specification](https://github.com/KhronosGroup/glTF/blob/master/extensions/2.0/Khronos/KHR_texture_transform)
  */
  */
 var KHR_texture_transform = /** @class */ (function () {
 var KHR_texture_transform = /** @class */ (function () {
     /** @hidden */
     /** @hidden */
@@ -4305,7 +4355,7 @@ _glTFLoader__WEBPACK_IMPORTED_MODULE_1__["GLTFLoader"].RegisterExtension(NAME, f
 /*!**************************************!*\
 /*!**************************************!*\
   !*** ./glTF/2.0/Extensions/index.ts ***!
   !*** ./glTF/2.0/Extensions/index.ts ***!
   \**************************************/
   \**************************************/
-/*! exports provided: EXT_lights_image_based, KHR_draco_mesh_compression, KHR_lights, KHR_materials_pbrSpecularGlossiness, KHR_materials_unlit, KHR_materials_clearcoat, KHR_materials_sheen, KHR_materials_specular, KHR_mesh_quantization, KHR_texture_transform, MSFT_audio_emitter, MSFT_lod, MSFT_minecraftMesh, MSFT_sRGBFactors, ExtrasAsMetadata */
+/*! exports provided: EXT_lights_image_based, KHR_draco_mesh_compression, KHR_lights, KHR_materials_pbrSpecularGlossiness, KHR_materials_unlit, KHR_materials_clearcoat, KHR_materials_sheen, KHR_materials_specular, KHR_mesh_quantization, KHR_texture_basisu, KHR_texture_transform, MSFT_audio_emitter, MSFT_lod, MSFT_minecraftMesh, MSFT_sRGBFactors, ExtrasAsMetadata */
 /***/ (function(module, __webpack_exports__, __webpack_require__) {
 /***/ (function(module, __webpack_exports__, __webpack_require__) {
 
 
 "use strict";
 "use strict";
@@ -4337,24 +4387,28 @@ __webpack_require__.r(__webpack_exports__);
 /* harmony import */ var _KHR_mesh_quantization__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ./KHR_mesh_quantization */ "./glTF/2.0/Extensions/KHR_mesh_quantization.ts");
 /* harmony import */ var _KHR_mesh_quantization__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ./KHR_mesh_quantization */ "./glTF/2.0/Extensions/KHR_mesh_quantization.ts");
 /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "KHR_mesh_quantization", function() { return _KHR_mesh_quantization__WEBPACK_IMPORTED_MODULE_8__["KHR_mesh_quantization"]; });
 /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "KHR_mesh_quantization", function() { return _KHR_mesh_quantization__WEBPACK_IMPORTED_MODULE_8__["KHR_mesh_quantization"]; });
 
 
-/* harmony import */ var _KHR_texture_transform__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ./KHR_texture_transform */ "./glTF/2.0/Extensions/KHR_texture_transform.ts");
-/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "KHR_texture_transform", function() { return _KHR_texture_transform__WEBPACK_IMPORTED_MODULE_9__["KHR_texture_transform"]; });
+/* harmony import */ var _KHR_texture_basisu__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ./KHR_texture_basisu */ "./glTF/2.0/Extensions/KHR_texture_basisu.ts");
+/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "KHR_texture_basisu", function() { return _KHR_texture_basisu__WEBPACK_IMPORTED_MODULE_9__["KHR_texture_basisu"]; });
 
 
-/* harmony import */ var _MSFT_audio_emitter__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! ./MSFT_audio_emitter */ "./glTF/2.0/Extensions/MSFT_audio_emitter.ts");
-/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "MSFT_audio_emitter", function() { return _MSFT_audio_emitter__WEBPACK_IMPORTED_MODULE_10__["MSFT_audio_emitter"]; });
+/* harmony import */ var _KHR_texture_transform__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! ./KHR_texture_transform */ "./glTF/2.0/Extensions/KHR_texture_transform.ts");
+/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "KHR_texture_transform", function() { return _KHR_texture_transform__WEBPACK_IMPORTED_MODULE_10__["KHR_texture_transform"]; });
 
 
-/* harmony import */ var _MSFT_lod__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(/*! ./MSFT_lod */ "./glTF/2.0/Extensions/MSFT_lod.ts");
-/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "MSFT_lod", function() { return _MSFT_lod__WEBPACK_IMPORTED_MODULE_11__["MSFT_lod"]; });
+/* harmony import */ var _MSFT_audio_emitter__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(/*! ./MSFT_audio_emitter */ "./glTF/2.0/Extensions/MSFT_audio_emitter.ts");
+/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "MSFT_audio_emitter", function() { return _MSFT_audio_emitter__WEBPACK_IMPORTED_MODULE_11__["MSFT_audio_emitter"]; });
 
 
-/* harmony import */ var _MSFT_minecraftMesh__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__(/*! ./MSFT_minecraftMesh */ "./glTF/2.0/Extensions/MSFT_minecraftMesh.ts");
-/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "MSFT_minecraftMesh", function() { return _MSFT_minecraftMesh__WEBPACK_IMPORTED_MODULE_12__["MSFT_minecraftMesh"]; });
+/* harmony import */ var _MSFT_lod__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__(/*! ./MSFT_lod */ "./glTF/2.0/Extensions/MSFT_lod.ts");
+/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "MSFT_lod", function() { return _MSFT_lod__WEBPACK_IMPORTED_MODULE_12__["MSFT_lod"]; });
 
 
-/* harmony import */ var _MSFT_sRGBFactors__WEBPACK_IMPORTED_MODULE_13__ = __webpack_require__(/*! ./MSFT_sRGBFactors */ "./glTF/2.0/Extensions/MSFT_sRGBFactors.ts");
-/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "MSFT_sRGBFactors", function() { return _MSFT_sRGBFactors__WEBPACK_IMPORTED_MODULE_13__["MSFT_sRGBFactors"]; });
+/* harmony import */ var _MSFT_minecraftMesh__WEBPACK_IMPORTED_MODULE_13__ = __webpack_require__(/*! ./MSFT_minecraftMesh */ "./glTF/2.0/Extensions/MSFT_minecraftMesh.ts");
+/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "MSFT_minecraftMesh", function() { return _MSFT_minecraftMesh__WEBPACK_IMPORTED_MODULE_13__["MSFT_minecraftMesh"]; });
 
 
-/* harmony import */ var _ExtrasAsMetadata__WEBPACK_IMPORTED_MODULE_14__ = __webpack_require__(/*! ./ExtrasAsMetadata */ "./glTF/2.0/Extensions/ExtrasAsMetadata.ts");
-/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "ExtrasAsMetadata", function() { return _ExtrasAsMetadata__WEBPACK_IMPORTED_MODULE_14__["ExtrasAsMetadata"]; });
+/* harmony import */ var _MSFT_sRGBFactors__WEBPACK_IMPORTED_MODULE_14__ = __webpack_require__(/*! ./MSFT_sRGBFactors */ "./glTF/2.0/Extensions/MSFT_sRGBFactors.ts");
+/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "MSFT_sRGBFactors", function() { return _MSFT_sRGBFactors__WEBPACK_IMPORTED_MODULE_14__["MSFT_sRGBFactors"]; });
 
 
+/* harmony import */ var _ExtrasAsMetadata__WEBPACK_IMPORTED_MODULE_15__ = __webpack_require__(/*! ./ExtrasAsMetadata */ "./glTF/2.0/Extensions/ExtrasAsMetadata.ts");
+/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "ExtrasAsMetadata", function() { return _ExtrasAsMetadata__WEBPACK_IMPORTED_MODULE_15__["ExtrasAsMetadata"]; });
+
+
 
 
 
 
 
 
@@ -4490,7 +4544,7 @@ var GLTFLoader = /** @class */ (function () {
     };
     };
     Object.defineProperty(GLTFLoader.prototype, "state", {
     Object.defineProperty(GLTFLoader.prototype, "state", {
         /**
         /**
-         * Gets the loader state.
+         * The loader state.
          */
          */
         get: function () {
         get: function () {
             return this._state;
             return this._state;
@@ -6032,27 +6086,29 @@ var GLTFLoader = /** @class */ (function () {
         this.logClose();
         this.logClose();
         return promise;
         return promise;
     };
     };
+    /** @hidden */
     GLTFLoader.prototype._loadTextureAsync = function (context, texture, assign) {
     GLTFLoader.prototype._loadTextureAsync = function (context, texture, assign) {
-        var _this = this;
         if (assign === void 0) { assign = function () { }; }
         if (assign === void 0) { assign = function () { }; }
-        var promises = new Array();
+        var extensionPromise = this._extensionsLoadTextureAsync(context, texture, assign);
+        if (extensionPromise) {
+            return extensionPromise;
+        }
         this.logOpen(context + " " + (texture.name || ""));
         this.logOpen(context + " " + (texture.name || ""));
-        var sampler = (texture.sampler == undefined ? GLTFLoader._DefaultSampler : ArrayItem.Get(context + "/sampler", this._gltf.samplers, texture.sampler));
-        var samplerData = this._loadSampler("/samplers/" + sampler.index, sampler);
+        var sampler = (texture.sampler == undefined ? GLTFLoader.DefaultSampler : ArrayItem.Get(context + "/sampler", this._gltf.samplers, texture.sampler));
         var image = ArrayItem.Get(context + "/source", this._gltf.images, texture.source);
         var image = ArrayItem.Get(context + "/source", this._gltf.images, texture.source);
-        var url = null;
-        if (image.uri) {
-            if (babylonjs_Misc_deferred__WEBPACK_IMPORTED_MODULE_0__["Tools"].IsBase64(image.uri)) {
-                url = image.uri;
-            }
-            else if (this._babylonScene.getEngine().textureFormatInUse) {
-                // If an image uri and a texture format is set like (eg. KTX) load from url instead of blob to support texture format and fallback
-                url = this._rootUrl + image.uri;
-            }
-        }
+        var promise = this._createTextureAsync(context, sampler, image, assign);
+        this.logClose();
+        return promise;
+    };
+    /** @hidden */
+    GLTFLoader.prototype._createTextureAsync = function (context, sampler, image, assign) {
+        var _this = this;
+        if (assign === void 0) { assign = function () { }; }
+        var samplerData = this._loadSampler("/samplers/" + sampler.index, sampler);
+        var promises = new Array();
         var deferred = new babylonjs_Misc_deferred__WEBPACK_IMPORTED_MODULE_0__["Deferred"]();
         var deferred = new babylonjs_Misc_deferred__WEBPACK_IMPORTED_MODULE_0__["Deferred"]();
         this._babylonScene._blockEntityCollection = this._forAssetContainer;
         this._babylonScene._blockEntityCollection = this._forAssetContainer;
-        var babylonTexture = new babylonjs_Misc_deferred__WEBPACK_IMPORTED_MODULE_0__["Texture"](url, this._babylonScene, samplerData.noMipMaps, false, samplerData.samplingMode, function () {
+        var babylonTexture = new babylonjs_Misc_deferred__WEBPACK_IMPORTED_MODULE_0__["Texture"](null, this._babylonScene, samplerData.noMipMaps, false, samplerData.samplingMode, function () {
             if (!_this._disposed) {
             if (!_this._disposed) {
                 deferred.resolve();
                 deferred.resolve();
             }
             }
@@ -6063,17 +6119,14 @@ var GLTFLoader = /** @class */ (function () {
         }, undefined, undefined, undefined, image.mimeType);
         }, undefined, undefined, undefined, image.mimeType);
         this._babylonScene._blockEntityCollection = false;
         this._babylonScene._blockEntityCollection = false;
         promises.push(deferred.promise);
         promises.push(deferred.promise);
-        if (!url) {
-            promises.push(this.loadImageAsync("/images/" + image.index, image).then(function (data) {
-                var name = image.uri || _this._fileName + "#image" + image.index;
-                var dataUrl = "data:" + _this._uniqueRootUrl + name;
-                babylonTexture.updateURL(dataUrl, data);
-            }));
-        }
+        promises.push(this.loadImageAsync("/images/" + image.index, image).then(function (data) {
+            var name = image.uri || _this._fileName + "#image" + image.index;
+            var dataUrl = "data:" + _this._uniqueRootUrl + name;
+            babylonTexture.updateURL(dataUrl, data);
+        }));
         babylonTexture.wrapU = samplerData.wrapU;
         babylonTexture.wrapU = samplerData.wrapU;
         babylonTexture.wrapV = samplerData.wrapV;
         babylonTexture.wrapV = samplerData.wrapV;
         assign(babylonTexture);
         assign(babylonTexture);
-        this.logClose();
         return Promise.all(promises).then(function () {
         return Promise.all(promises).then(function () {
             return babylonTexture;
             return babylonTexture;
         });
         });
@@ -6404,6 +6457,9 @@ var GLTFLoader = /** @class */ (function () {
     GLTFLoader.prototype._extensionsLoadTextureInfoAsync = function (context, textureInfo, assign) {
     GLTFLoader.prototype._extensionsLoadTextureInfoAsync = function (context, textureInfo, assign) {
         return this._applyExtensions(textureInfo, "loadTextureInfo", function (extension) { return extension.loadTextureInfoAsync && extension.loadTextureInfoAsync(context, textureInfo, assign); });
         return this._applyExtensions(textureInfo, "loadTextureInfo", function (extension) { return extension.loadTextureInfoAsync && extension.loadTextureInfoAsync(context, textureInfo, assign); });
     };
     };
+    GLTFLoader.prototype._extensionsLoadTextureAsync = function (context, texture, assign) {
+        return this._applyExtensions(texture, "loadTexture", function (extension) { return extension._loadTextureAsync && extension._loadTextureAsync(context, texture, assign); });
+    };
     GLTFLoader.prototype._extensionsLoadAnimationAsync = function (context, animation) {
     GLTFLoader.prototype._extensionsLoadAnimationAsync = function (context, animation) {
         return this._applyExtensions(animation, "loadAnimation", function (extension) { return extension.loadAnimationAsync && extension.loadAnimationAsync(context, animation); });
         return this._applyExtensions(animation, "loadAnimation", function (extension) { return extension.loadAnimationAsync && extension.loadAnimationAsync(context, animation); });
     };
     };
@@ -6499,8 +6555,11 @@ var GLTFLoader = /** @class */ (function () {
     GLTFLoader.prototype.endPerformanceCounter = function (counterName) {
     GLTFLoader.prototype.endPerformanceCounter = function (counterName) {
         this._parent._endPerformanceCounter(counterName);
         this._parent._endPerformanceCounter(counterName);
     };
     };
-    GLTFLoader._DefaultSampler = { index: -1 };
     GLTFLoader._RegisteredExtensions = {};
     GLTFLoader._RegisteredExtensions = {};
+    /**
+     * The default glTF sampler.
+     */
+    GLTFLoader.DefaultSampler = { index: -1 };
     return GLTFLoader;
     return GLTFLoader;
 }());
 }());
 
 
@@ -6524,7 +6583,7 @@ _glTFFileLoader__WEBPACK_IMPORTED_MODULE_1__["GLTFFileLoader"]._CreateGLTF2Loade
 /*!***************************!*\
 /*!***************************!*\
   !*** ./glTF/2.0/index.ts ***!
   !*** ./glTF/2.0/index.ts ***!
   \***************************/
   \***************************/
-/*! exports provided: ArrayItem, GLTFLoader, EXT_lights_image_based, KHR_draco_mesh_compression, KHR_lights, KHR_materials_pbrSpecularGlossiness, KHR_materials_unlit, KHR_materials_clearcoat, KHR_materials_sheen, KHR_materials_specular, KHR_mesh_quantization, KHR_texture_transform, MSFT_audio_emitter, MSFT_lod, MSFT_minecraftMesh, MSFT_sRGBFactors, ExtrasAsMetadata */
+/*! exports provided: ArrayItem, GLTFLoader, EXT_lights_image_based, KHR_draco_mesh_compression, KHR_lights, KHR_materials_pbrSpecularGlossiness, KHR_materials_unlit, KHR_materials_clearcoat, KHR_materials_sheen, KHR_materials_specular, KHR_mesh_quantization, KHR_texture_basisu, KHR_texture_transform, MSFT_audio_emitter, MSFT_lod, MSFT_minecraftMesh, MSFT_sRGBFactors, ExtrasAsMetadata */
 /***/ (function(module, __webpack_exports__, __webpack_require__) {
 /***/ (function(module, __webpack_exports__, __webpack_require__) {
 
 
 "use strict";
 "use strict";
@@ -6553,6 +6612,8 @@ __webpack_require__.r(__webpack_exports__);
 
 
 /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "KHR_mesh_quantization", function() { return _Extensions__WEBPACK_IMPORTED_MODULE_1__["KHR_mesh_quantization"]; });
 /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "KHR_mesh_quantization", function() { return _Extensions__WEBPACK_IMPORTED_MODULE_1__["KHR_mesh_quantization"]; });
 
 
+/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "KHR_texture_basisu", function() { return _Extensions__WEBPACK_IMPORTED_MODULE_1__["KHR_texture_basisu"]; });
+
 /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "KHR_texture_transform", function() { return _Extensions__WEBPACK_IMPORTED_MODULE_1__["KHR_texture_transform"]; });
 /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "KHR_texture_transform", function() { return _Extensions__WEBPACK_IMPORTED_MODULE_1__["KHR_texture_transform"]; });
 
 
 /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "MSFT_audio_emitter", function() { return _Extensions__WEBPACK_IMPORTED_MODULE_1__["MSFT_audio_emitter"]; });
 /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "MSFT_audio_emitter", function() { return _Extensions__WEBPACK_IMPORTED_MODULE_1__["MSFT_audio_emitter"]; });

文件差異過大導致無法顯示
+ 1 - 1
dist/preview release/loaders/babylon.glTFFileLoader.js.map


文件差異過大導致無法顯示
+ 2 - 2
dist/preview release/loaders/babylon.glTFFileLoader.min.js


+ 50 - 10
dist/preview release/loaders/babylonjs.loaders.d.ts

@@ -1195,14 +1195,16 @@ declare module BABYLON.GLTF2 {
          */
          */
         loadCameraAsync?(context: string, camera: ICamera, assign: (babylonCamera: Camera) => void): Nullable<Promise<Camera>>;
         loadCameraAsync?(context: string, camera: ICamera, assign: (babylonCamera: Camera) => void): Nullable<Promise<Camera>>;
         /**
         /**
-         * @hidden Define this method to modify the default behavior when loading vertex data for mesh primitives.
+         * @hidden
+         * Define this method to modify the default behavior when loading vertex data for mesh primitives.
          * @param context The context when loading the asset
          * @param context The context when loading the asset
          * @param primitive The glTF mesh primitive property
          * @param primitive The glTF mesh primitive property
          * @returns A promise that resolves with the loaded geometry when the load is complete or null if not handled
          * @returns A promise that resolves with the loaded geometry when the load is complete or null if not handled
          */
          */
         _loadVertexDataAsync?(context: string, primitive: IMeshPrimitive, babylonMesh: Mesh): Nullable<Promise<Geometry>>;
         _loadVertexDataAsync?(context: string, primitive: IMeshPrimitive, babylonMesh: Mesh): Nullable<Promise<Geometry>>;
         /**
         /**
-         * @hidden Define this method to modify the default behavior when loading data for mesh primitives.
+         * @hidden
+         * Define this method to modify the default behavior when loading data for mesh primitives.
          * @param context The context when loading the asset
          * @param context The context when loading the asset
          * @param name The mesh name when loading the asset
          * @param name The mesh name when loading the asset
          * @param node The glTF node when loading the asset
          * @param node The glTF node when loading the asset
@@ -1213,7 +1215,8 @@ declare module BABYLON.GLTF2 {
          */
          */
         _loadMeshPrimitiveAsync?(context: string, name: string, node: INode, mesh: IMesh, primitive: IMeshPrimitive, assign: (babylonMesh: AbstractMesh) => void): Promise<AbstractMesh>;
         _loadMeshPrimitiveAsync?(context: string, name: string, node: INode, mesh: IMesh, primitive: IMeshPrimitive, assign: (babylonMesh: AbstractMesh) => void): Promise<AbstractMesh>;
         /**
         /**
-         * @hidden Define this method to modify the default behavior when loading materials. Load material creates the material and then loads material properties.
+         * @hidden
+         * Define this method to modify the default behavior when loading materials. Load material creates the material and then loads material properties.
          * @param context The context when loading the asset
          * @param context The context when loading the asset
          * @param material The glTF material property
          * @param material The glTF material property
          * @param assign A function called synchronously after parsing the glTF properties
          * @param assign A function called synchronously after parsing the glTF properties
@@ -1245,6 +1248,15 @@ declare module BABYLON.GLTF2 {
          */
          */
         loadTextureInfoAsync?(context: string, textureInfo: ITextureInfo, assign: (babylonTexture: BaseTexture) => void): Nullable<Promise<BaseTexture>>;
         loadTextureInfoAsync?(context: string, textureInfo: ITextureInfo, assign: (babylonTexture: BaseTexture) => void): Nullable<Promise<BaseTexture>>;
         /**
         /**
+         * @hidden
+         * Define this method to modify the default behavior when loading textures.
+         * @param context The context when loading the asset
+         * @param texture The glTF texture property
+         * @param assign A function called synchronously after parsing the glTF properties
+         * @returns A promise that resolves with the loaded Babylon texture when the load is complete or null if not handled
+         */
+        _loadTextureAsync?(context: string, texture: ITexture, assign: (babylonTexture: BaseTexture) => void): Nullable<Promise<BaseTexture>>;
+        /**
          * Define this method to modify the default behavior when loading animations.
          * Define this method to modify the default behavior when loading animations.
          * @param context The context when loading the asset
          * @param context The context when loading the asset
          * @param animation The glTF animation property
          * @param animation The glTF animation property
@@ -1252,7 +1264,8 @@ declare module BABYLON.GLTF2 {
          */
          */
         loadAnimationAsync?(context: string, animation: IAnimation): Nullable<Promise<AnimationGroup>>;
         loadAnimationAsync?(context: string, animation: IAnimation): Nullable<Promise<AnimationGroup>>;
         /**
         /**
-         * @hidden Define this method to modify the default behavior when loading skins.
+         * @hidden
+         * Define this method to modify the default behavior when loading skins.
          * @param context The context when loading the asset
          * @param context The context when loading the asset
          * @param node The glTF node property
          * @param node The glTF node property
          * @param skin The glTF skin property
          * @param skin The glTF skin property
@@ -1260,7 +1273,8 @@ declare module BABYLON.GLTF2 {
          */
          */
         _loadSkinAsync?(context: string, node: INode, skin: ISkin): Nullable<Promise<void>>;
         _loadSkinAsync?(context: string, node: INode, skin: ISkin): Nullable<Promise<void>>;
         /**
         /**
-         * @hidden Define this method to modify the default behavior when loading uris.
+         * @hidden
+         * Define this method to modify the default behavior when loading uris.
          * @param context The context when loading the asset
          * @param context The context when loading the asset
          * @param property The glTF property associated with the uri
          * @param property The glTF property associated with the uri
          * @param uri The uri to load
          * @param uri The uri to load
@@ -1328,9 +1342,12 @@ declare module BABYLON.GLTF2 {
         private _defaultBabylonMaterialData;
         private _defaultBabylonMaterialData;
         private _progressCallback?;
         private _progressCallback?;
         private _requests;
         private _requests;
-        private static readonly _DefaultSampler;
         private static _RegisteredExtensions;
         private static _RegisteredExtensions;
         /**
         /**
+         * The default glTF sampler.
+         */
+        static readonly DefaultSampler: ISampler;
+        /**
          * Registers a loader extension.
          * Registers a loader extension.
          * @param name The name of the loader extension.
          * @param name The name of the loader extension.
          * @param factory The factory function that creates the loader extension.
          * @param factory The factory function that creates the loader extension.
@@ -1343,7 +1360,7 @@ declare module BABYLON.GLTF2 {
          */
          */
         static UnregisterExtension(name: string): boolean;
         static UnregisterExtension(name: string): boolean;
         /**
         /**
-         * Gets the loader state.
+         * The loader state.
          */
          */
         get state(): Nullable<GLTFLoaderState>;
         get state(): Nullable<GLTFLoaderState>;
         /**
         /**
@@ -1510,7 +1527,10 @@ declare module BABYLON.GLTF2 {
          * @returns A promise that resolves with the loaded Babylon texture when the load is complete
          * @returns A promise that resolves with the loaded Babylon texture when the load is complete
          */
          */
         loadTextureInfoAsync(context: string, textureInfo: ITextureInfo, assign?: (babylonTexture: BaseTexture) => void): Promise<BaseTexture>;
         loadTextureInfoAsync(context: string, textureInfo: ITextureInfo, assign?: (babylonTexture: BaseTexture) => void): Promise<BaseTexture>;
-        private _loadTextureAsync;
+        /** @hidden */
+        _loadTextureAsync(context: string, texture: ITexture, assign?: (babylonTexture: BaseTexture) => void): Promise<BaseTexture>;
+        /** @hidden */
+        _createTextureAsync(context: string, sampler: ISampler, image: IImage, assign?: (babylonTexture: BaseTexture) => void): Promise<BaseTexture>;
         private _loadSampler;
         private _loadSampler;
         /**
         /**
          * Loads a glTF image.
          * Loads a glTF image.
@@ -1558,6 +1578,7 @@ declare module BABYLON.GLTF2 {
         private _extensionsCreateMaterial;
         private _extensionsCreateMaterial;
         private _extensionsLoadMaterialPropertiesAsync;
         private _extensionsLoadMaterialPropertiesAsync;
         private _extensionsLoadTextureInfoAsync;
         private _extensionsLoadTextureInfoAsync;
+        private _extensionsLoadTextureAsync;
         private _extensionsLoadAnimationAsync;
         private _extensionsLoadAnimationAsync;
         private _extensionsLoadSkinAsync;
         private _extensionsLoadSkinAsync;
         private _extensionsLoadUriAsync;
         private _extensionsLoadUriAsync;
@@ -1667,7 +1688,7 @@ declare module BABYLON.GLTF2.Loader.Extensions {
 }
 }
 declare module BABYLON.GLTF2.Loader.Extensions {
 declare module BABYLON.GLTF2.Loader.Extensions {
     /**
     /**
-     * [Specification](https://github.com/KhronosGroup/glTF/blob/master/extensions/2.0/Khronos/KHR_lights_punctual/README.md)
+     * [Specification](https://github.com/KhronosGroup/glTF/blob/master/extensions/2.0/Khronos/KHR_lights_punctual)
      */
      */
     export class KHR_lights implements IGLTFLoaderExtension {
     export class KHR_lights implements IGLTFLoaderExtension {
         /**
         /**
@@ -1852,7 +1873,26 @@ declare module BABYLON.GLTF2.Loader.Extensions {
 }
 }
 declare module BABYLON.GLTF2.Loader.Extensions {
 declare module BABYLON.GLTF2.Loader.Extensions {
     /**
     /**
-     * [Specification](https://github.com/KhronosGroup/glTF/blob/master/extensions/2.0/Khronos/KHR_texture_transform/README.md)
+     * [Proposed Specification](https://github.com/KhronosGroup/glTF/pull/1751)
+     * !!! Experimental Extension Subject to Changes !!!
+     */
+    export class KHR_texture_basisu implements IGLTFLoaderExtension {
+        /** The name of this extension. */
+        readonly name: string;
+        /** Defines whether this extension is enabled. */
+        enabled: boolean;
+        private _loader;
+        /** @hidden */
+        constructor(loader: GLTFLoader);
+        /** @hidden */
+        dispose(): void;
+        /** @hidden */
+        loadTextureAsync(context: string, texture: ITexture, assign: (babylonTexture: BaseTexture) => void): Nullable<Promise<BaseTexture>>;
+    }
+}
+declare module BABYLON.GLTF2.Loader.Extensions {
+    /**
+     * [Specification](https://github.com/KhronosGroup/glTF/blob/master/extensions/2.0/Khronos/KHR_texture_transform)
      */
      */
     export class KHR_texture_transform implements IGLTFLoaderExtension {
     export class KHR_texture_transform implements IGLTFLoaderExtension {
         /**
         /**

+ 102 - 41
dist/preview release/loaders/babylonjs.loaders.js

@@ -4397,7 +4397,7 @@ var LightType;
     LightType["SPOT"] = "spot";
     LightType["SPOT"] = "spot";
 })(LightType || (LightType = {}));
 })(LightType || (LightType = {}));
 /**
 /**
- * [Specification](https://github.com/KhronosGroup/glTF/blob/master/extensions/2.0/Khronos/KHR_lights_punctual/README.md)
+ * [Specification](https://github.com/KhronosGroup/glTF/blob/master/extensions/2.0/Khronos/KHR_lights_punctual)
  */
  */
 var KHR_lights = /** @class */ (function () {
 var KHR_lights = /** @class */ (function () {
     /** @hidden */
     /** @hidden */
@@ -4930,6 +4930,56 @@ _glTFLoader__WEBPACK_IMPORTED_MODULE_0__["GLTFLoader"].RegisterExtension(NAME, f
 
 
 /***/ }),
 /***/ }),
 
 
+/***/ "./glTF/2.0/Extensions/KHR_texture_basisu.ts":
+/*!***************************************************!*\
+  !*** ./glTF/2.0/Extensions/KHR_texture_basisu.ts ***!
+  \***************************************************/
+/*! exports provided: KHR_texture_basisu */
+/***/ (function(module, __webpack_exports__, __webpack_require__) {
+
+"use strict";
+__webpack_require__.r(__webpack_exports__);
+/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "KHR_texture_basisu", function() { return KHR_texture_basisu; });
+/* harmony import */ var _glTFLoader__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../glTFLoader */ "./glTF/2.0/glTFLoader.ts");
+
+var NAME = "KHR_texture_basisu";
+/**
+ * [Proposed Specification](https://github.com/KhronosGroup/glTF/pull/1751)
+ * !!! Experimental Extension Subject to Changes !!!
+ */
+var KHR_texture_basisu = /** @class */ (function () {
+    /** @hidden */
+    function KHR_texture_basisu(loader) {
+        /** The name of this extension. */
+        this.name = NAME;
+        /** Defines whether this extension is enabled. */
+        this.enabled = true;
+        this._loader = loader;
+    }
+    /** @hidden */
+    KHR_texture_basisu.prototype.dispose = function () {
+        delete this._loader;
+    };
+    /** @hidden */
+    KHR_texture_basisu.prototype.loadTextureAsync = function (context, texture, assign) {
+        var _this = this;
+        return _glTFLoader__WEBPACK_IMPORTED_MODULE_0__["GLTFLoader"].LoadExtensionAsync(context, texture, this.name, function (extensionContext, extension) {
+            var sampler = (texture.sampler == undefined ? _glTFLoader__WEBPACK_IMPORTED_MODULE_0__["GLTFLoader"].DefaultSampler : _glTFLoader__WEBPACK_IMPORTED_MODULE_0__["ArrayItem"].Get(context + "/sampler", _this._loader.gltf.samplers, texture.sampler));
+            var image = _glTFLoader__WEBPACK_IMPORTED_MODULE_0__["ArrayItem"].Get(extensionContext + "/source", _this._loader.gltf.images, extension.source);
+            return _this._loader._createTextureAsync(context, sampler, image, function (babylonTexture) {
+                babylonTexture.gammaSpace = false;
+                assign(babylonTexture);
+            });
+        });
+    };
+    return KHR_texture_basisu;
+}());
+
+_glTFLoader__WEBPACK_IMPORTED_MODULE_0__["GLTFLoader"].RegisterExtension(NAME, function (loader) { return new KHR_texture_basisu(loader); });
+
+
+/***/ }),
+
 /***/ "./glTF/2.0/Extensions/KHR_texture_transform.ts":
 /***/ "./glTF/2.0/Extensions/KHR_texture_transform.ts":
 /*!******************************************************!*\
 /*!******************************************************!*\
   !*** ./glTF/2.0/Extensions/KHR_texture_transform.ts ***!
   !*** ./glTF/2.0/Extensions/KHR_texture_transform.ts ***!
@@ -4947,7 +4997,7 @@ __webpack_require__.r(__webpack_exports__);
 
 
 var NAME = "KHR_texture_transform";
 var NAME = "KHR_texture_transform";
 /**
 /**
- * [Specification](https://github.com/KhronosGroup/glTF/blob/master/extensions/2.0/Khronos/KHR_texture_transform/README.md)
+ * [Specification](https://github.com/KhronosGroup/glTF/blob/master/extensions/2.0/Khronos/KHR_texture_transform)
  */
  */
 var KHR_texture_transform = /** @class */ (function () {
 var KHR_texture_transform = /** @class */ (function () {
     /** @hidden */
     /** @hidden */
@@ -5684,7 +5734,7 @@ _glTFLoader__WEBPACK_IMPORTED_MODULE_1__["GLTFLoader"].RegisterExtension(NAME, f
 /*!**************************************!*\
 /*!**************************************!*\
   !*** ./glTF/2.0/Extensions/index.ts ***!
   !*** ./glTF/2.0/Extensions/index.ts ***!
   \**************************************/
   \**************************************/
-/*! exports provided: EXT_lights_image_based, KHR_draco_mesh_compression, KHR_lights, KHR_materials_pbrSpecularGlossiness, KHR_materials_unlit, KHR_materials_clearcoat, KHR_materials_sheen, KHR_materials_specular, KHR_mesh_quantization, KHR_texture_transform, MSFT_audio_emitter, MSFT_lod, MSFT_minecraftMesh, MSFT_sRGBFactors, ExtrasAsMetadata */
+/*! exports provided: EXT_lights_image_based, KHR_draco_mesh_compression, KHR_lights, KHR_materials_pbrSpecularGlossiness, KHR_materials_unlit, KHR_materials_clearcoat, KHR_materials_sheen, KHR_materials_specular, KHR_mesh_quantization, KHR_texture_basisu, KHR_texture_transform, MSFT_audio_emitter, MSFT_lod, MSFT_minecraftMesh, MSFT_sRGBFactors, ExtrasAsMetadata */
 /***/ (function(module, __webpack_exports__, __webpack_require__) {
 /***/ (function(module, __webpack_exports__, __webpack_require__) {
 
 
 "use strict";
 "use strict";
@@ -5716,24 +5766,28 @@ __webpack_require__.r(__webpack_exports__);
 /* harmony import */ var _KHR_mesh_quantization__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ./KHR_mesh_quantization */ "./glTF/2.0/Extensions/KHR_mesh_quantization.ts");
 /* harmony import */ var _KHR_mesh_quantization__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ./KHR_mesh_quantization */ "./glTF/2.0/Extensions/KHR_mesh_quantization.ts");
 /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "KHR_mesh_quantization", function() { return _KHR_mesh_quantization__WEBPACK_IMPORTED_MODULE_8__["KHR_mesh_quantization"]; });
 /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "KHR_mesh_quantization", function() { return _KHR_mesh_quantization__WEBPACK_IMPORTED_MODULE_8__["KHR_mesh_quantization"]; });
 
 
-/* harmony import */ var _KHR_texture_transform__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ./KHR_texture_transform */ "./glTF/2.0/Extensions/KHR_texture_transform.ts");
-/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "KHR_texture_transform", function() { return _KHR_texture_transform__WEBPACK_IMPORTED_MODULE_9__["KHR_texture_transform"]; });
+/* harmony import */ var _KHR_texture_basisu__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ./KHR_texture_basisu */ "./glTF/2.0/Extensions/KHR_texture_basisu.ts");
+/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "KHR_texture_basisu", function() { return _KHR_texture_basisu__WEBPACK_IMPORTED_MODULE_9__["KHR_texture_basisu"]; });
 
 
-/* harmony import */ var _MSFT_audio_emitter__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! ./MSFT_audio_emitter */ "./glTF/2.0/Extensions/MSFT_audio_emitter.ts");
-/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "MSFT_audio_emitter", function() { return _MSFT_audio_emitter__WEBPACK_IMPORTED_MODULE_10__["MSFT_audio_emitter"]; });
+/* harmony import */ var _KHR_texture_transform__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! ./KHR_texture_transform */ "./glTF/2.0/Extensions/KHR_texture_transform.ts");
+/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "KHR_texture_transform", function() { return _KHR_texture_transform__WEBPACK_IMPORTED_MODULE_10__["KHR_texture_transform"]; });
 
 
-/* harmony import */ var _MSFT_lod__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(/*! ./MSFT_lod */ "./glTF/2.0/Extensions/MSFT_lod.ts");
-/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "MSFT_lod", function() { return _MSFT_lod__WEBPACK_IMPORTED_MODULE_11__["MSFT_lod"]; });
+/* harmony import */ var _MSFT_audio_emitter__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(/*! ./MSFT_audio_emitter */ "./glTF/2.0/Extensions/MSFT_audio_emitter.ts");
+/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "MSFT_audio_emitter", function() { return _MSFT_audio_emitter__WEBPACK_IMPORTED_MODULE_11__["MSFT_audio_emitter"]; });
 
 
-/* harmony import */ var _MSFT_minecraftMesh__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__(/*! ./MSFT_minecraftMesh */ "./glTF/2.0/Extensions/MSFT_minecraftMesh.ts");
-/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "MSFT_minecraftMesh", function() { return _MSFT_minecraftMesh__WEBPACK_IMPORTED_MODULE_12__["MSFT_minecraftMesh"]; });
+/* harmony import */ var _MSFT_lod__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__(/*! ./MSFT_lod */ "./glTF/2.0/Extensions/MSFT_lod.ts");
+/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "MSFT_lod", function() { return _MSFT_lod__WEBPACK_IMPORTED_MODULE_12__["MSFT_lod"]; });
 
 
-/* harmony import */ var _MSFT_sRGBFactors__WEBPACK_IMPORTED_MODULE_13__ = __webpack_require__(/*! ./MSFT_sRGBFactors */ "./glTF/2.0/Extensions/MSFT_sRGBFactors.ts");
-/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "MSFT_sRGBFactors", function() { return _MSFT_sRGBFactors__WEBPACK_IMPORTED_MODULE_13__["MSFT_sRGBFactors"]; });
+/* harmony import */ var _MSFT_minecraftMesh__WEBPACK_IMPORTED_MODULE_13__ = __webpack_require__(/*! ./MSFT_minecraftMesh */ "./glTF/2.0/Extensions/MSFT_minecraftMesh.ts");
+/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "MSFT_minecraftMesh", function() { return _MSFT_minecraftMesh__WEBPACK_IMPORTED_MODULE_13__["MSFT_minecraftMesh"]; });
 
 
-/* harmony import */ var _ExtrasAsMetadata__WEBPACK_IMPORTED_MODULE_14__ = __webpack_require__(/*! ./ExtrasAsMetadata */ "./glTF/2.0/Extensions/ExtrasAsMetadata.ts");
-/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "ExtrasAsMetadata", function() { return _ExtrasAsMetadata__WEBPACK_IMPORTED_MODULE_14__["ExtrasAsMetadata"]; });
+/* harmony import */ var _MSFT_sRGBFactors__WEBPACK_IMPORTED_MODULE_14__ = __webpack_require__(/*! ./MSFT_sRGBFactors */ "./glTF/2.0/Extensions/MSFT_sRGBFactors.ts");
+/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "MSFT_sRGBFactors", function() { return _MSFT_sRGBFactors__WEBPACK_IMPORTED_MODULE_14__["MSFT_sRGBFactors"]; });
 
 
+/* harmony import */ var _ExtrasAsMetadata__WEBPACK_IMPORTED_MODULE_15__ = __webpack_require__(/*! ./ExtrasAsMetadata */ "./glTF/2.0/Extensions/ExtrasAsMetadata.ts");
+/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "ExtrasAsMetadata", function() { return _ExtrasAsMetadata__WEBPACK_IMPORTED_MODULE_15__["ExtrasAsMetadata"]; });
+
+
 
 
 
 
 
 
@@ -5869,7 +5923,7 @@ var GLTFLoader = /** @class */ (function () {
     };
     };
     Object.defineProperty(GLTFLoader.prototype, "state", {
     Object.defineProperty(GLTFLoader.prototype, "state", {
         /**
         /**
-         * Gets the loader state.
+         * The loader state.
          */
          */
         get: function () {
         get: function () {
             return this._state;
             return this._state;
@@ -7411,27 +7465,29 @@ var GLTFLoader = /** @class */ (function () {
         this.logClose();
         this.logClose();
         return promise;
         return promise;
     };
     };
+    /** @hidden */
     GLTFLoader.prototype._loadTextureAsync = function (context, texture, assign) {
     GLTFLoader.prototype._loadTextureAsync = function (context, texture, assign) {
-        var _this = this;
         if (assign === void 0) { assign = function () { }; }
         if (assign === void 0) { assign = function () { }; }
-        var promises = new Array();
+        var extensionPromise = this._extensionsLoadTextureAsync(context, texture, assign);
+        if (extensionPromise) {
+            return extensionPromise;
+        }
         this.logOpen(context + " " + (texture.name || ""));
         this.logOpen(context + " " + (texture.name || ""));
-        var sampler = (texture.sampler == undefined ? GLTFLoader._DefaultSampler : ArrayItem.Get(context + "/sampler", this._gltf.samplers, texture.sampler));
-        var samplerData = this._loadSampler("/samplers/" + sampler.index, sampler);
+        var sampler = (texture.sampler == undefined ? GLTFLoader.DefaultSampler : ArrayItem.Get(context + "/sampler", this._gltf.samplers, texture.sampler));
         var image = ArrayItem.Get(context + "/source", this._gltf.images, texture.source);
         var image = ArrayItem.Get(context + "/source", this._gltf.images, texture.source);
-        var url = null;
-        if (image.uri) {
-            if (babylonjs_Misc_deferred__WEBPACK_IMPORTED_MODULE_0__["Tools"].IsBase64(image.uri)) {
-                url = image.uri;
-            }
-            else if (this._babylonScene.getEngine().textureFormatInUse) {
-                // If an image uri and a texture format is set like (eg. KTX) load from url instead of blob to support texture format and fallback
-                url = this._rootUrl + image.uri;
-            }
-        }
+        var promise = this._createTextureAsync(context, sampler, image, assign);
+        this.logClose();
+        return promise;
+    };
+    /** @hidden */
+    GLTFLoader.prototype._createTextureAsync = function (context, sampler, image, assign) {
+        var _this = this;
+        if (assign === void 0) { assign = function () { }; }
+        var samplerData = this._loadSampler("/samplers/" + sampler.index, sampler);
+        var promises = new Array();
         var deferred = new babylonjs_Misc_deferred__WEBPACK_IMPORTED_MODULE_0__["Deferred"]();
         var deferred = new babylonjs_Misc_deferred__WEBPACK_IMPORTED_MODULE_0__["Deferred"]();
         this._babylonScene._blockEntityCollection = this._forAssetContainer;
         this._babylonScene._blockEntityCollection = this._forAssetContainer;
-        var babylonTexture = new babylonjs_Misc_deferred__WEBPACK_IMPORTED_MODULE_0__["Texture"](url, this._babylonScene, samplerData.noMipMaps, false, samplerData.samplingMode, function () {
+        var babylonTexture = new babylonjs_Misc_deferred__WEBPACK_IMPORTED_MODULE_0__["Texture"](null, this._babylonScene, samplerData.noMipMaps, false, samplerData.samplingMode, function () {
             if (!_this._disposed) {
             if (!_this._disposed) {
                 deferred.resolve();
                 deferred.resolve();
             }
             }
@@ -7442,17 +7498,14 @@ var GLTFLoader = /** @class */ (function () {
         }, undefined, undefined, undefined, image.mimeType);
         }, undefined, undefined, undefined, image.mimeType);
         this._babylonScene._blockEntityCollection = false;
         this._babylonScene._blockEntityCollection = false;
         promises.push(deferred.promise);
         promises.push(deferred.promise);
-        if (!url) {
-            promises.push(this.loadImageAsync("/images/" + image.index, image).then(function (data) {
-                var name = image.uri || _this._fileName + "#image" + image.index;
-                var dataUrl = "data:" + _this._uniqueRootUrl + name;
-                babylonTexture.updateURL(dataUrl, data);
-            }));
-        }
+        promises.push(this.loadImageAsync("/images/" + image.index, image).then(function (data) {
+            var name = image.uri || _this._fileName + "#image" + image.index;
+            var dataUrl = "data:" + _this._uniqueRootUrl + name;
+            babylonTexture.updateURL(dataUrl, data);
+        }));
         babylonTexture.wrapU = samplerData.wrapU;
         babylonTexture.wrapU = samplerData.wrapU;
         babylonTexture.wrapV = samplerData.wrapV;
         babylonTexture.wrapV = samplerData.wrapV;
         assign(babylonTexture);
         assign(babylonTexture);
-        this.logClose();
         return Promise.all(promises).then(function () {
         return Promise.all(promises).then(function () {
             return babylonTexture;
             return babylonTexture;
         });
         });
@@ -7783,6 +7836,9 @@ var GLTFLoader = /** @class */ (function () {
     GLTFLoader.prototype._extensionsLoadTextureInfoAsync = function (context, textureInfo, assign) {
     GLTFLoader.prototype._extensionsLoadTextureInfoAsync = function (context, textureInfo, assign) {
         return this._applyExtensions(textureInfo, "loadTextureInfo", function (extension) { return extension.loadTextureInfoAsync && extension.loadTextureInfoAsync(context, textureInfo, assign); });
         return this._applyExtensions(textureInfo, "loadTextureInfo", function (extension) { return extension.loadTextureInfoAsync && extension.loadTextureInfoAsync(context, textureInfo, assign); });
     };
     };
+    GLTFLoader.prototype._extensionsLoadTextureAsync = function (context, texture, assign) {
+        return this._applyExtensions(texture, "loadTexture", function (extension) { return extension._loadTextureAsync && extension._loadTextureAsync(context, texture, assign); });
+    };
     GLTFLoader.prototype._extensionsLoadAnimationAsync = function (context, animation) {
     GLTFLoader.prototype._extensionsLoadAnimationAsync = function (context, animation) {
         return this._applyExtensions(animation, "loadAnimation", function (extension) { return extension.loadAnimationAsync && extension.loadAnimationAsync(context, animation); });
         return this._applyExtensions(animation, "loadAnimation", function (extension) { return extension.loadAnimationAsync && extension.loadAnimationAsync(context, animation); });
     };
     };
@@ -7878,8 +7934,11 @@ var GLTFLoader = /** @class */ (function () {
     GLTFLoader.prototype.endPerformanceCounter = function (counterName) {
     GLTFLoader.prototype.endPerformanceCounter = function (counterName) {
         this._parent._endPerformanceCounter(counterName);
         this._parent._endPerformanceCounter(counterName);
     };
     };
-    GLTFLoader._DefaultSampler = { index: -1 };
     GLTFLoader._RegisteredExtensions = {};
     GLTFLoader._RegisteredExtensions = {};
+    /**
+     * The default glTF sampler.
+     */
+    GLTFLoader.DefaultSampler = { index: -1 };
     return GLTFLoader;
     return GLTFLoader;
 }());
 }());
 
 
@@ -7903,7 +7962,7 @@ _glTFFileLoader__WEBPACK_IMPORTED_MODULE_1__["GLTFFileLoader"]._CreateGLTF2Loade
 /*!***************************!*\
 /*!***************************!*\
   !*** ./glTF/2.0/index.ts ***!
   !*** ./glTF/2.0/index.ts ***!
   \***************************/
   \***************************/
-/*! exports provided: ArrayItem, GLTFLoader, EXT_lights_image_based, KHR_draco_mesh_compression, KHR_lights, KHR_materials_pbrSpecularGlossiness, KHR_materials_unlit, KHR_materials_clearcoat, KHR_materials_sheen, KHR_materials_specular, KHR_mesh_quantization, KHR_texture_transform, MSFT_audio_emitter, MSFT_lod, MSFT_minecraftMesh, MSFT_sRGBFactors, ExtrasAsMetadata */
+/*! exports provided: ArrayItem, GLTFLoader, EXT_lights_image_based, KHR_draco_mesh_compression, KHR_lights, KHR_materials_pbrSpecularGlossiness, KHR_materials_unlit, KHR_materials_clearcoat, KHR_materials_sheen, KHR_materials_specular, KHR_mesh_quantization, KHR_texture_basisu, KHR_texture_transform, MSFT_audio_emitter, MSFT_lod, MSFT_minecraftMesh, MSFT_sRGBFactors, ExtrasAsMetadata */
 /***/ (function(module, __webpack_exports__, __webpack_require__) {
 /***/ (function(module, __webpack_exports__, __webpack_require__) {
 
 
 "use strict";
 "use strict";
@@ -7932,6 +7991,8 @@ __webpack_require__.r(__webpack_exports__);
 
 
 /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "KHR_mesh_quantization", function() { return _Extensions__WEBPACK_IMPORTED_MODULE_1__["KHR_mesh_quantization"]; });
 /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "KHR_mesh_quantization", function() { return _Extensions__WEBPACK_IMPORTED_MODULE_1__["KHR_mesh_quantization"]; });
 
 
+/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "KHR_texture_basisu", function() { return _Extensions__WEBPACK_IMPORTED_MODULE_1__["KHR_texture_basisu"]; });
+
 /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "KHR_texture_transform", function() { return _Extensions__WEBPACK_IMPORTED_MODULE_1__["KHR_texture_transform"]; });
 /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "KHR_texture_transform", function() { return _Extensions__WEBPACK_IMPORTED_MODULE_1__["KHR_texture_transform"]; });
 
 
 /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "MSFT_audio_emitter", function() { return _Extensions__WEBPACK_IMPORTED_MODULE_1__["MSFT_audio_emitter"]; });
 /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "MSFT_audio_emitter", function() { return _Extensions__WEBPACK_IMPORTED_MODULE_1__["MSFT_audio_emitter"]; });

文件差異過大導致無法顯示
+ 1 - 1
dist/preview release/loaders/babylonjs.loaders.js.map


文件差異過大導致無法顯示
+ 2 - 2
dist/preview release/loaders/babylonjs.loaders.min.js


+ 108 - 22
dist/preview release/loaders/babylonjs.loaders.module.d.ts

@@ -1228,7 +1228,7 @@ declare module "babylonjs-loaders/glTF/2.0/glTFLoaderExtension" {
     import { Mesh } from "babylonjs/Meshes/mesh";
     import { Mesh } from "babylonjs/Meshes/mesh";
     import { AbstractMesh } from "babylonjs/Meshes/abstractMesh";
     import { AbstractMesh } from "babylonjs/Meshes/abstractMesh";
     import { IDisposable } from "babylonjs/scene";
     import { IDisposable } from "babylonjs/scene";
-    import { IScene, INode, IMesh, ISkin, ICamera, IMeshPrimitive, IMaterial, ITextureInfo, IAnimation, IBufferView, IBuffer } from "babylonjs-loaders/glTF/2.0/glTFLoaderInterfaces";
+    import { IScene, INode, IMesh, ISkin, ICamera, IMeshPrimitive, IMaterial, ITextureInfo, IAnimation, ITexture, IBufferView, IBuffer } from "babylonjs-loaders/glTF/2.0/glTFLoaderInterfaces";
     import { IGLTFLoaderExtension as IGLTFBaseLoaderExtension } from "babylonjs-loaders/glTF/glTFFileLoader";
     import { IGLTFLoaderExtension as IGLTFBaseLoaderExtension } from "babylonjs-loaders/glTF/glTFFileLoader";
     import { IProperty } from 'babylonjs-gltf2interface';
     import { IProperty } from 'babylonjs-gltf2interface';
     /**
     /**
@@ -1267,14 +1267,16 @@ declare module "babylonjs-loaders/glTF/2.0/glTFLoaderExtension" {
          */
          */
         loadCameraAsync?(context: string, camera: ICamera, assign: (babylonCamera: Camera) => void): Nullable<Promise<Camera>>;
         loadCameraAsync?(context: string, camera: ICamera, assign: (babylonCamera: Camera) => void): Nullable<Promise<Camera>>;
         /**
         /**
-         * @hidden Define this method to modify the default behavior when loading vertex data for mesh primitives.
+         * @hidden
+         * Define this method to modify the default behavior when loading vertex data for mesh primitives.
          * @param context The context when loading the asset
          * @param context The context when loading the asset
          * @param primitive The glTF mesh primitive property
          * @param primitive The glTF mesh primitive property
          * @returns A promise that resolves with the loaded geometry when the load is complete or null if not handled
          * @returns A promise that resolves with the loaded geometry when the load is complete or null if not handled
          */
          */
         _loadVertexDataAsync?(context: string, primitive: IMeshPrimitive, babylonMesh: Mesh): Nullable<Promise<Geometry>>;
         _loadVertexDataAsync?(context: string, primitive: IMeshPrimitive, babylonMesh: Mesh): Nullable<Promise<Geometry>>;
         /**
         /**
-         * @hidden Define this method to modify the default behavior when loading data for mesh primitives.
+         * @hidden
+         * Define this method to modify the default behavior when loading data for mesh primitives.
          * @param context The context when loading the asset
          * @param context The context when loading the asset
          * @param name The mesh name when loading the asset
          * @param name The mesh name when loading the asset
          * @param node The glTF node when loading the asset
          * @param node The glTF node when loading the asset
@@ -1285,7 +1287,8 @@ declare module "babylonjs-loaders/glTF/2.0/glTFLoaderExtension" {
          */
          */
         _loadMeshPrimitiveAsync?(context: string, name: string, node: INode, mesh: IMesh, primitive: IMeshPrimitive, assign: (babylonMesh: AbstractMesh) => void): Promise<AbstractMesh>;
         _loadMeshPrimitiveAsync?(context: string, name: string, node: INode, mesh: IMesh, primitive: IMeshPrimitive, assign: (babylonMesh: AbstractMesh) => void): Promise<AbstractMesh>;
         /**
         /**
-         * @hidden Define this method to modify the default behavior when loading materials. Load material creates the material and then loads material properties.
+         * @hidden
+         * Define this method to modify the default behavior when loading materials. Load material creates the material and then loads material properties.
          * @param context The context when loading the asset
          * @param context The context when loading the asset
          * @param material The glTF material property
          * @param material The glTF material property
          * @param assign A function called synchronously after parsing the glTF properties
          * @param assign A function called synchronously after parsing the glTF properties
@@ -1317,6 +1320,15 @@ declare module "babylonjs-loaders/glTF/2.0/glTFLoaderExtension" {
          */
          */
         loadTextureInfoAsync?(context: string, textureInfo: ITextureInfo, assign: (babylonTexture: BaseTexture) => void): Nullable<Promise<BaseTexture>>;
         loadTextureInfoAsync?(context: string, textureInfo: ITextureInfo, assign: (babylonTexture: BaseTexture) => void): Nullable<Promise<BaseTexture>>;
         /**
         /**
+         * @hidden
+         * Define this method to modify the default behavior when loading textures.
+         * @param context The context when loading the asset
+         * @param texture The glTF texture property
+         * @param assign A function called synchronously after parsing the glTF properties
+         * @returns A promise that resolves with the loaded Babylon texture when the load is complete or null if not handled
+         */
+        _loadTextureAsync?(context: string, texture: ITexture, assign: (babylonTexture: BaseTexture) => void): Nullable<Promise<BaseTexture>>;
+        /**
          * Define this method to modify the default behavior when loading animations.
          * Define this method to modify the default behavior when loading animations.
          * @param context The context when loading the asset
          * @param context The context when loading the asset
          * @param animation The glTF animation property
          * @param animation The glTF animation property
@@ -1324,7 +1336,8 @@ declare module "babylonjs-loaders/glTF/2.0/glTFLoaderExtension" {
          */
          */
         loadAnimationAsync?(context: string, animation: IAnimation): Nullable<Promise<AnimationGroup>>;
         loadAnimationAsync?(context: string, animation: IAnimation): Nullable<Promise<AnimationGroup>>;
         /**
         /**
-         * @hidden Define this method to modify the default behavior when loading skins.
+         * @hidden
+         * Define this method to modify the default behavior when loading skins.
          * @param context The context when loading the asset
          * @param context The context when loading the asset
          * @param node The glTF node property
          * @param node The glTF node property
          * @param skin The glTF skin property
          * @param skin The glTF skin property
@@ -1332,7 +1345,8 @@ declare module "babylonjs-loaders/glTF/2.0/glTFLoaderExtension" {
          */
          */
         _loadSkinAsync?(context: string, node: INode, skin: ISkin): Nullable<Promise<void>>;
         _loadSkinAsync?(context: string, node: INode, skin: ISkin): Nullable<Promise<void>>;
         /**
         /**
-         * @hidden Define this method to modify the default behavior when loading uris.
+         * @hidden
+         * Define this method to modify the default behavior when loading uris.
          * @param context The context when loading the asset
          * @param context The context when loading the asset
          * @param property The glTF property associated with the uri
          * @param property The glTF property associated with the uri
          * @param uri The uri to load
          * @param uri The uri to load
@@ -1369,7 +1383,7 @@ declare module "babylonjs-loaders/glTF/2.0/glTFLoader" {
     import { SceneLoaderProgressEvent } from "babylonjs/Loading/sceneLoader";
     import { SceneLoaderProgressEvent } from "babylonjs/Loading/sceneLoader";
     import { Scene } from "babylonjs/scene";
     import { Scene } from "babylonjs/scene";
     import { IProperty } from "babylonjs-gltf2interface";
     import { IProperty } from "babylonjs-gltf2interface";
-    import { IGLTF, INode, IScene, IMesh, ICamera, IAnimation, IAnimationChannel, IBufferView, IMaterial, ITextureInfo, IImage, IMeshPrimitive, IArrayItem as IArrItem } from "babylonjs-loaders/glTF/2.0/glTFLoaderInterfaces";
+    import { IGLTF, ISampler, INode, IScene, IMesh, ICamera, IAnimation, IAnimationChannel, IBufferView, IMaterial, ITextureInfo, ITexture, IImage, IMeshPrimitive, IArrayItem as IArrItem } from "babylonjs-loaders/glTF/2.0/glTFLoaderInterfaces";
     import { IGLTFLoaderExtension } from "babylonjs-loaders/glTF/2.0/glTFLoaderExtension";
     import { IGLTFLoaderExtension } from "babylonjs-loaders/glTF/2.0/glTFLoaderExtension";
     import { IGLTFLoader, GLTFFileLoader, GLTFLoaderState, IGLTFLoaderData, IImportMeshAsyncOutput } from "babylonjs-loaders/glTF/glTFFileLoader";
     import { IGLTFLoader, GLTFFileLoader, GLTFLoaderState, IGLTFLoaderData, IImportMeshAsyncOutput } from "babylonjs-loaders/glTF/glTFFileLoader";
     import { IAnimatable } from 'babylonjs/Animations/animatable.interface';
     import { IAnimatable } from 'babylonjs/Animations/animatable.interface';
@@ -1417,9 +1431,12 @@ declare module "babylonjs-loaders/glTF/2.0/glTFLoader" {
         private _defaultBabylonMaterialData;
         private _defaultBabylonMaterialData;
         private _progressCallback?;
         private _progressCallback?;
         private _requests;
         private _requests;
-        private static readonly _DefaultSampler;
         private static _RegisteredExtensions;
         private static _RegisteredExtensions;
         /**
         /**
+         * The default glTF sampler.
+         */
+        static readonly DefaultSampler: ISampler;
+        /**
          * Registers a loader extension.
          * Registers a loader extension.
          * @param name The name of the loader extension.
          * @param name The name of the loader extension.
          * @param factory The factory function that creates the loader extension.
          * @param factory The factory function that creates the loader extension.
@@ -1432,7 +1449,7 @@ declare module "babylonjs-loaders/glTF/2.0/glTFLoader" {
          */
          */
         static UnregisterExtension(name: string): boolean;
         static UnregisterExtension(name: string): boolean;
         /**
         /**
-         * Gets the loader state.
+         * The loader state.
          */
          */
         get state(): Nullable<GLTFLoaderState>;
         get state(): Nullable<GLTFLoaderState>;
         /**
         /**
@@ -1599,7 +1616,10 @@ declare module "babylonjs-loaders/glTF/2.0/glTFLoader" {
          * @returns A promise that resolves with the loaded Babylon texture when the load is complete
          * @returns A promise that resolves with the loaded Babylon texture when the load is complete
          */
          */
         loadTextureInfoAsync(context: string, textureInfo: ITextureInfo, assign?: (babylonTexture: BaseTexture) => void): Promise<BaseTexture>;
         loadTextureInfoAsync(context: string, textureInfo: ITextureInfo, assign?: (babylonTexture: BaseTexture) => void): Promise<BaseTexture>;
-        private _loadTextureAsync;
+        /** @hidden */
+        _loadTextureAsync(context: string, texture: ITexture, assign?: (babylonTexture: BaseTexture) => void): Promise<BaseTexture>;
+        /** @hidden */
+        _createTextureAsync(context: string, sampler: ISampler, image: IImage, assign?: (babylonTexture: BaseTexture) => void): Promise<BaseTexture>;
         private _loadSampler;
         private _loadSampler;
         /**
         /**
          * Loads a glTF image.
          * Loads a glTF image.
@@ -1647,6 +1667,7 @@ declare module "babylonjs-loaders/glTF/2.0/glTFLoader" {
         private _extensionsCreateMaterial;
         private _extensionsCreateMaterial;
         private _extensionsLoadMaterialPropertiesAsync;
         private _extensionsLoadMaterialPropertiesAsync;
         private _extensionsLoadTextureInfoAsync;
         private _extensionsLoadTextureInfoAsync;
+        private _extensionsLoadTextureAsync;
         private _extensionsLoadAnimationAsync;
         private _extensionsLoadAnimationAsync;
         private _extensionsLoadSkinAsync;
         private _extensionsLoadSkinAsync;
         private _extensionsLoadUriAsync;
         private _extensionsLoadUriAsync;
@@ -1772,7 +1793,7 @@ declare module "babylonjs-loaders/glTF/2.0/Extensions/KHR_lights_punctual" {
     import { IGLTFLoaderExtension } from "babylonjs-loaders/glTF/2.0/glTFLoaderExtension";
     import { IGLTFLoaderExtension } from "babylonjs-loaders/glTF/2.0/glTFLoaderExtension";
     import { GLTFLoader } from "babylonjs-loaders/glTF/2.0/glTFLoader";
     import { GLTFLoader } from "babylonjs-loaders/glTF/2.0/glTFLoader";
     /**
     /**
-     * [Specification](https://github.com/KhronosGroup/glTF/blob/master/extensions/2.0/Khronos/KHR_lights_punctual/README.md)
+     * [Specification](https://github.com/KhronosGroup/glTF/blob/master/extensions/2.0/Khronos/KHR_lights_punctual)
      */
      */
     export class KHR_lights implements IGLTFLoaderExtension {
     export class KHR_lights implements IGLTFLoaderExtension {
         /**
         /**
@@ -1982,6 +2003,30 @@ declare module "babylonjs-loaders/glTF/2.0/Extensions/KHR_mesh_quantization" {
         dispose(): void;
         dispose(): void;
     }
     }
 }
 }
+declare module "babylonjs-loaders/glTF/2.0/Extensions/KHR_texture_basisu" {
+    import { IGLTFLoaderExtension } from "babylonjs-loaders/glTF/2.0/glTFLoaderExtension";
+    import { GLTFLoader } from "babylonjs-loaders/glTF/2.0/glTFLoader";
+    import { ITexture } from "babylonjs-loaders/glTF/2.0/glTFLoaderInterfaces";
+    import { BaseTexture } from "babylonjs/Materials/Textures/baseTexture";
+    import { Nullable } from "babylonjs/types";
+    /**
+     * [Proposed Specification](https://github.com/KhronosGroup/glTF/pull/1751)
+     * !!! Experimental Extension Subject to Changes !!!
+     */
+    export class KHR_texture_basisu implements IGLTFLoaderExtension {
+        /** The name of this extension. */
+        readonly name: string;
+        /** Defines whether this extension is enabled. */
+        enabled: boolean;
+        private _loader;
+        /** @hidden */
+        constructor(loader: GLTFLoader);
+        /** @hidden */
+        dispose(): void;
+        /** @hidden */
+        loadTextureAsync(context: string, texture: ITexture, assign: (babylonTexture: BaseTexture) => void): Nullable<Promise<BaseTexture>>;
+    }
+}
 declare module "babylonjs-loaders/glTF/2.0/Extensions/KHR_texture_transform" {
 declare module "babylonjs-loaders/glTF/2.0/Extensions/KHR_texture_transform" {
     import { Nullable } from "babylonjs/types";
     import { Nullable } from "babylonjs/types";
     import { BaseTexture } from "babylonjs/Materials/Textures/baseTexture";
     import { BaseTexture } from "babylonjs/Materials/Textures/baseTexture";
@@ -1989,7 +2034,7 @@ declare module "babylonjs-loaders/glTF/2.0/Extensions/KHR_texture_transform" {
     import { IGLTFLoaderExtension } from "babylonjs-loaders/glTF/2.0/glTFLoaderExtension";
     import { IGLTFLoaderExtension } from "babylonjs-loaders/glTF/2.0/glTFLoaderExtension";
     import { GLTFLoader } from "babylonjs-loaders/glTF/2.0/glTFLoader";
     import { GLTFLoader } from "babylonjs-loaders/glTF/2.0/glTFLoader";
     /**
     /**
-     * [Specification](https://github.com/KhronosGroup/glTF/blob/master/extensions/2.0/Khronos/KHR_texture_transform/README.md)
+     * [Specification](https://github.com/KhronosGroup/glTF/blob/master/extensions/2.0/Khronos/KHR_texture_transform)
      */
      */
     export class KHR_texture_transform implements IGLTFLoaderExtension {
     export class KHR_texture_transform implements IGLTFLoaderExtension {
         /**
         /**
@@ -2201,6 +2246,7 @@ declare module "babylonjs-loaders/glTF/2.0/Extensions/index" {
     export * from "babylonjs-loaders/glTF/2.0/Extensions/KHR_materials_sheen";
     export * from "babylonjs-loaders/glTF/2.0/Extensions/KHR_materials_sheen";
     export * from "babylonjs-loaders/glTF/2.0/Extensions/KHR_materials_specular";
     export * from "babylonjs-loaders/glTF/2.0/Extensions/KHR_materials_specular";
     export * from "babylonjs-loaders/glTF/2.0/Extensions/KHR_mesh_quantization";
     export * from "babylonjs-loaders/glTF/2.0/Extensions/KHR_mesh_quantization";
+    export * from "babylonjs-loaders/glTF/2.0/Extensions/KHR_texture_basisu";
     export * from "babylonjs-loaders/glTF/2.0/Extensions/KHR_texture_transform";
     export * from "babylonjs-loaders/glTF/2.0/Extensions/KHR_texture_transform";
     export * from "babylonjs-loaders/glTF/2.0/Extensions/MSFT_audio_emitter";
     export * from "babylonjs-loaders/glTF/2.0/Extensions/MSFT_audio_emitter";
     export * from "babylonjs-loaders/glTF/2.0/Extensions/MSFT_lod";
     export * from "babylonjs-loaders/glTF/2.0/Extensions/MSFT_lod";
@@ -3783,14 +3829,16 @@ declare module BABYLON.GLTF2 {
          */
          */
         loadCameraAsync?(context: string, camera: ICamera, assign: (babylonCamera: Camera) => void): Nullable<Promise<Camera>>;
         loadCameraAsync?(context: string, camera: ICamera, assign: (babylonCamera: Camera) => void): Nullable<Promise<Camera>>;
         /**
         /**
-         * @hidden Define this method to modify the default behavior when loading vertex data for mesh primitives.
+         * @hidden
+         * Define this method to modify the default behavior when loading vertex data for mesh primitives.
          * @param context The context when loading the asset
          * @param context The context when loading the asset
          * @param primitive The glTF mesh primitive property
          * @param primitive The glTF mesh primitive property
          * @returns A promise that resolves with the loaded geometry when the load is complete or null if not handled
          * @returns A promise that resolves with the loaded geometry when the load is complete or null if not handled
          */
          */
         _loadVertexDataAsync?(context: string, primitive: IMeshPrimitive, babylonMesh: Mesh): Nullable<Promise<Geometry>>;
         _loadVertexDataAsync?(context: string, primitive: IMeshPrimitive, babylonMesh: Mesh): Nullable<Promise<Geometry>>;
         /**
         /**
-         * @hidden Define this method to modify the default behavior when loading data for mesh primitives.
+         * @hidden
+         * Define this method to modify the default behavior when loading data for mesh primitives.
          * @param context The context when loading the asset
          * @param context The context when loading the asset
          * @param name The mesh name when loading the asset
          * @param name The mesh name when loading the asset
          * @param node The glTF node when loading the asset
          * @param node The glTF node when loading the asset
@@ -3801,7 +3849,8 @@ declare module BABYLON.GLTF2 {
          */
          */
         _loadMeshPrimitiveAsync?(context: string, name: string, node: INode, mesh: IMesh, primitive: IMeshPrimitive, assign: (babylonMesh: AbstractMesh) => void): Promise<AbstractMesh>;
         _loadMeshPrimitiveAsync?(context: string, name: string, node: INode, mesh: IMesh, primitive: IMeshPrimitive, assign: (babylonMesh: AbstractMesh) => void): Promise<AbstractMesh>;
         /**
         /**
-         * @hidden Define this method to modify the default behavior when loading materials. Load material creates the material and then loads material properties.
+         * @hidden
+         * Define this method to modify the default behavior when loading materials. Load material creates the material and then loads material properties.
          * @param context The context when loading the asset
          * @param context The context when loading the asset
          * @param material The glTF material property
          * @param material The glTF material property
          * @param assign A function called synchronously after parsing the glTF properties
          * @param assign A function called synchronously after parsing the glTF properties
@@ -3833,6 +3882,15 @@ declare module BABYLON.GLTF2 {
          */
          */
         loadTextureInfoAsync?(context: string, textureInfo: ITextureInfo, assign: (babylonTexture: BaseTexture) => void): Nullable<Promise<BaseTexture>>;
         loadTextureInfoAsync?(context: string, textureInfo: ITextureInfo, assign: (babylonTexture: BaseTexture) => void): Nullable<Promise<BaseTexture>>;
         /**
         /**
+         * @hidden
+         * Define this method to modify the default behavior when loading textures.
+         * @param context The context when loading the asset
+         * @param texture The glTF texture property
+         * @param assign A function called synchronously after parsing the glTF properties
+         * @returns A promise that resolves with the loaded Babylon texture when the load is complete or null if not handled
+         */
+        _loadTextureAsync?(context: string, texture: ITexture, assign: (babylonTexture: BaseTexture) => void): Nullable<Promise<BaseTexture>>;
+        /**
          * Define this method to modify the default behavior when loading animations.
          * Define this method to modify the default behavior when loading animations.
          * @param context The context when loading the asset
          * @param context The context when loading the asset
          * @param animation The glTF animation property
          * @param animation The glTF animation property
@@ -3840,7 +3898,8 @@ declare module BABYLON.GLTF2 {
          */
          */
         loadAnimationAsync?(context: string, animation: IAnimation): Nullable<Promise<AnimationGroup>>;
         loadAnimationAsync?(context: string, animation: IAnimation): Nullable<Promise<AnimationGroup>>;
         /**
         /**
-         * @hidden Define this method to modify the default behavior when loading skins.
+         * @hidden
+         * Define this method to modify the default behavior when loading skins.
          * @param context The context when loading the asset
          * @param context The context when loading the asset
          * @param node The glTF node property
          * @param node The glTF node property
          * @param skin The glTF skin property
          * @param skin The glTF skin property
@@ -3848,7 +3907,8 @@ declare module BABYLON.GLTF2 {
          */
          */
         _loadSkinAsync?(context: string, node: INode, skin: ISkin): Nullable<Promise<void>>;
         _loadSkinAsync?(context: string, node: INode, skin: ISkin): Nullable<Promise<void>>;
         /**
         /**
-         * @hidden Define this method to modify the default behavior when loading uris.
+         * @hidden
+         * Define this method to modify the default behavior when loading uris.
          * @param context The context when loading the asset
          * @param context The context when loading the asset
          * @param property The glTF property associated with the uri
          * @param property The glTF property associated with the uri
          * @param uri The uri to load
          * @param uri The uri to load
@@ -3916,9 +3976,12 @@ declare module BABYLON.GLTF2 {
         private _defaultBabylonMaterialData;
         private _defaultBabylonMaterialData;
         private _progressCallback?;
         private _progressCallback?;
         private _requests;
         private _requests;
-        private static readonly _DefaultSampler;
         private static _RegisteredExtensions;
         private static _RegisteredExtensions;
         /**
         /**
+         * The default glTF sampler.
+         */
+        static readonly DefaultSampler: ISampler;
+        /**
          * Registers a loader extension.
          * Registers a loader extension.
          * @param name The name of the loader extension.
          * @param name The name of the loader extension.
          * @param factory The factory function that creates the loader extension.
          * @param factory The factory function that creates the loader extension.
@@ -3931,7 +3994,7 @@ declare module BABYLON.GLTF2 {
          */
          */
         static UnregisterExtension(name: string): boolean;
         static UnregisterExtension(name: string): boolean;
         /**
         /**
-         * Gets the loader state.
+         * The loader state.
          */
          */
         get state(): Nullable<GLTFLoaderState>;
         get state(): Nullable<GLTFLoaderState>;
         /**
         /**
@@ -4098,7 +4161,10 @@ declare module BABYLON.GLTF2 {
          * @returns A promise that resolves with the loaded Babylon texture when the load is complete
          * @returns A promise that resolves with the loaded Babylon texture when the load is complete
          */
          */
         loadTextureInfoAsync(context: string, textureInfo: ITextureInfo, assign?: (babylonTexture: BaseTexture) => void): Promise<BaseTexture>;
         loadTextureInfoAsync(context: string, textureInfo: ITextureInfo, assign?: (babylonTexture: BaseTexture) => void): Promise<BaseTexture>;
-        private _loadTextureAsync;
+        /** @hidden */
+        _loadTextureAsync(context: string, texture: ITexture, assign?: (babylonTexture: BaseTexture) => void): Promise<BaseTexture>;
+        /** @hidden */
+        _createTextureAsync(context: string, sampler: ISampler, image: IImage, assign?: (babylonTexture: BaseTexture) => void): Promise<BaseTexture>;
         private _loadSampler;
         private _loadSampler;
         /**
         /**
          * Loads a glTF image.
          * Loads a glTF image.
@@ -4146,6 +4212,7 @@ declare module BABYLON.GLTF2 {
         private _extensionsCreateMaterial;
         private _extensionsCreateMaterial;
         private _extensionsLoadMaterialPropertiesAsync;
         private _extensionsLoadMaterialPropertiesAsync;
         private _extensionsLoadTextureInfoAsync;
         private _extensionsLoadTextureInfoAsync;
+        private _extensionsLoadTextureAsync;
         private _extensionsLoadAnimationAsync;
         private _extensionsLoadAnimationAsync;
         private _extensionsLoadSkinAsync;
         private _extensionsLoadSkinAsync;
         private _extensionsLoadUriAsync;
         private _extensionsLoadUriAsync;
@@ -4255,7 +4322,7 @@ declare module BABYLON.GLTF2.Loader.Extensions {
 }
 }
 declare module BABYLON.GLTF2.Loader.Extensions {
 declare module BABYLON.GLTF2.Loader.Extensions {
     /**
     /**
-     * [Specification](https://github.com/KhronosGroup/glTF/blob/master/extensions/2.0/Khronos/KHR_lights_punctual/README.md)
+     * [Specification](https://github.com/KhronosGroup/glTF/blob/master/extensions/2.0/Khronos/KHR_lights_punctual)
      */
      */
     export class KHR_lights implements IGLTFLoaderExtension {
     export class KHR_lights implements IGLTFLoaderExtension {
         /**
         /**
@@ -4440,7 +4507,26 @@ declare module BABYLON.GLTF2.Loader.Extensions {
 }
 }
 declare module BABYLON.GLTF2.Loader.Extensions {
 declare module BABYLON.GLTF2.Loader.Extensions {
     /**
     /**
-     * [Specification](https://github.com/KhronosGroup/glTF/blob/master/extensions/2.0/Khronos/KHR_texture_transform/README.md)
+     * [Proposed Specification](https://github.com/KhronosGroup/glTF/pull/1751)
+     * !!! Experimental Extension Subject to Changes !!!
+     */
+    export class KHR_texture_basisu implements IGLTFLoaderExtension {
+        /** The name of this extension. */
+        readonly name: string;
+        /** Defines whether this extension is enabled. */
+        enabled: boolean;
+        private _loader;
+        /** @hidden */
+        constructor(loader: GLTFLoader);
+        /** @hidden */
+        dispose(): void;
+        /** @hidden */
+        loadTextureAsync(context: string, texture: ITexture, assign: (babylonTexture: BaseTexture) => void): Nullable<Promise<BaseTexture>>;
+    }
+}
+declare module BABYLON.GLTF2.Loader.Extensions {
+    /**
+     * [Specification](https://github.com/KhronosGroup/glTF/blob/master/extensions/2.0/Khronos/KHR_texture_transform)
      */
      */
     export class KHR_texture_transform implements IGLTFLoaderExtension {
     export class KHR_texture_transform implements IGLTFLoaderExtension {
         /**
         /**

文件差異過大導致無法顯示
+ 3894 - 1194
dist/preview release/nodeEditor/babylon.nodeEditor.d.ts


文件差異過大導致無法顯示
+ 6 - 6
dist/preview release/nodeEditor/babylon.nodeEditor.js


文件差異過大導致無法顯示
+ 232 - 84
dist/preview release/nodeEditor/babylon.nodeEditor.max.js


文件差異過大導致無法顯示
+ 1 - 1
dist/preview release/nodeEditor/babylon.nodeEditor.max.js.map


文件差異過大導致無法顯示
+ 8233 - 2825
dist/preview release/nodeEditor/babylon.nodeEditor.module.d.ts


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

@@ -1 +1 @@
-{"thinEngineOnly":112467,"engineOnly":149443,"sceneOnly":504906,"minGridMaterial":635533,"minStandardMaterial":775405}
+{"thinEngineOnly":111956,"engineOnly":148559,"sceneOnly":504048,"minGridMaterial":634675,"minStandardMaterial":774533}

文件差異過大導致無法顯示
+ 146 - 366
dist/preview release/viewer/babylon.module.d.ts


文件差異過大導致無法顯示
+ 33 - 25
dist/preview release/viewer/babylon.viewer.js


文件差異過大導致無法顯示
+ 2 - 2
dist/preview release/viewer/babylon.viewer.max.js


+ 108 - 22
dist/preview release/viewer/babylonjs.loaders.module.d.ts

@@ -1228,7 +1228,7 @@ declare module "babylonjs-loaders/glTF/2.0/glTFLoaderExtension" {
     import { Mesh } from "babylonjs/Meshes/mesh";
     import { Mesh } from "babylonjs/Meshes/mesh";
     import { AbstractMesh } from "babylonjs/Meshes/abstractMesh";
     import { AbstractMesh } from "babylonjs/Meshes/abstractMesh";
     import { IDisposable } from "babylonjs/scene";
     import { IDisposable } from "babylonjs/scene";
-    import { IScene, INode, IMesh, ISkin, ICamera, IMeshPrimitive, IMaterial, ITextureInfo, IAnimation, IBufferView, IBuffer } from "babylonjs-loaders/glTF/2.0/glTFLoaderInterfaces";
+    import { IScene, INode, IMesh, ISkin, ICamera, IMeshPrimitive, IMaterial, ITextureInfo, IAnimation, ITexture, IBufferView, IBuffer } from "babylonjs-loaders/glTF/2.0/glTFLoaderInterfaces";
     import { IGLTFLoaderExtension as IGLTFBaseLoaderExtension } from "babylonjs-loaders/glTF/glTFFileLoader";
     import { IGLTFLoaderExtension as IGLTFBaseLoaderExtension } from "babylonjs-loaders/glTF/glTFFileLoader";
     import { IProperty } from 'babylonjs-gltf2interface';
     import { IProperty } from 'babylonjs-gltf2interface';
     /**
     /**
@@ -1267,14 +1267,16 @@ declare module "babylonjs-loaders/glTF/2.0/glTFLoaderExtension" {
          */
          */
         loadCameraAsync?(context: string, camera: ICamera, assign: (babylonCamera: Camera) => void): Nullable<Promise<Camera>>;
         loadCameraAsync?(context: string, camera: ICamera, assign: (babylonCamera: Camera) => void): Nullable<Promise<Camera>>;
         /**
         /**
-         * @hidden Define this method to modify the default behavior when loading vertex data for mesh primitives.
+         * @hidden
+         * Define this method to modify the default behavior when loading vertex data for mesh primitives.
          * @param context The context when loading the asset
          * @param context The context when loading the asset
          * @param primitive The glTF mesh primitive property
          * @param primitive The glTF mesh primitive property
          * @returns A promise that resolves with the loaded geometry when the load is complete or null if not handled
          * @returns A promise that resolves with the loaded geometry when the load is complete or null if not handled
          */
          */
         _loadVertexDataAsync?(context: string, primitive: IMeshPrimitive, babylonMesh: Mesh): Nullable<Promise<Geometry>>;
         _loadVertexDataAsync?(context: string, primitive: IMeshPrimitive, babylonMesh: Mesh): Nullable<Promise<Geometry>>;
         /**
         /**
-         * @hidden Define this method to modify the default behavior when loading data for mesh primitives.
+         * @hidden
+         * Define this method to modify the default behavior when loading data for mesh primitives.
          * @param context The context when loading the asset
          * @param context The context when loading the asset
          * @param name The mesh name when loading the asset
          * @param name The mesh name when loading the asset
          * @param node The glTF node when loading the asset
          * @param node The glTF node when loading the asset
@@ -1285,7 +1287,8 @@ declare module "babylonjs-loaders/glTF/2.0/glTFLoaderExtension" {
          */
          */
         _loadMeshPrimitiveAsync?(context: string, name: string, node: INode, mesh: IMesh, primitive: IMeshPrimitive, assign: (babylonMesh: AbstractMesh) => void): Promise<AbstractMesh>;
         _loadMeshPrimitiveAsync?(context: string, name: string, node: INode, mesh: IMesh, primitive: IMeshPrimitive, assign: (babylonMesh: AbstractMesh) => void): Promise<AbstractMesh>;
         /**
         /**
-         * @hidden Define this method to modify the default behavior when loading materials. Load material creates the material and then loads material properties.
+         * @hidden
+         * Define this method to modify the default behavior when loading materials. Load material creates the material and then loads material properties.
          * @param context The context when loading the asset
          * @param context The context when loading the asset
          * @param material The glTF material property
          * @param material The glTF material property
          * @param assign A function called synchronously after parsing the glTF properties
          * @param assign A function called synchronously after parsing the glTF properties
@@ -1317,6 +1320,15 @@ declare module "babylonjs-loaders/glTF/2.0/glTFLoaderExtension" {
          */
          */
         loadTextureInfoAsync?(context: string, textureInfo: ITextureInfo, assign: (babylonTexture: BaseTexture) => void): Nullable<Promise<BaseTexture>>;
         loadTextureInfoAsync?(context: string, textureInfo: ITextureInfo, assign: (babylonTexture: BaseTexture) => void): Nullable<Promise<BaseTexture>>;
         /**
         /**
+         * @hidden
+         * Define this method to modify the default behavior when loading textures.
+         * @param context The context when loading the asset
+         * @param texture The glTF texture property
+         * @param assign A function called synchronously after parsing the glTF properties
+         * @returns A promise that resolves with the loaded Babylon texture when the load is complete or null if not handled
+         */
+        _loadTextureAsync?(context: string, texture: ITexture, assign: (babylonTexture: BaseTexture) => void): Nullable<Promise<BaseTexture>>;
+        /**
          * Define this method to modify the default behavior when loading animations.
          * Define this method to modify the default behavior when loading animations.
          * @param context The context when loading the asset
          * @param context The context when loading the asset
          * @param animation The glTF animation property
          * @param animation The glTF animation property
@@ -1324,7 +1336,8 @@ declare module "babylonjs-loaders/glTF/2.0/glTFLoaderExtension" {
          */
          */
         loadAnimationAsync?(context: string, animation: IAnimation): Nullable<Promise<AnimationGroup>>;
         loadAnimationAsync?(context: string, animation: IAnimation): Nullable<Promise<AnimationGroup>>;
         /**
         /**
-         * @hidden Define this method to modify the default behavior when loading skins.
+         * @hidden
+         * Define this method to modify the default behavior when loading skins.
          * @param context The context when loading the asset
          * @param context The context when loading the asset
          * @param node The glTF node property
          * @param node The glTF node property
          * @param skin The glTF skin property
          * @param skin The glTF skin property
@@ -1332,7 +1345,8 @@ declare module "babylonjs-loaders/glTF/2.0/glTFLoaderExtension" {
          */
          */
         _loadSkinAsync?(context: string, node: INode, skin: ISkin): Nullable<Promise<void>>;
         _loadSkinAsync?(context: string, node: INode, skin: ISkin): Nullable<Promise<void>>;
         /**
         /**
-         * @hidden Define this method to modify the default behavior when loading uris.
+         * @hidden
+         * Define this method to modify the default behavior when loading uris.
          * @param context The context when loading the asset
          * @param context The context when loading the asset
          * @param property The glTF property associated with the uri
          * @param property The glTF property associated with the uri
          * @param uri The uri to load
          * @param uri The uri to load
@@ -1369,7 +1383,7 @@ declare module "babylonjs-loaders/glTF/2.0/glTFLoader" {
     import { SceneLoaderProgressEvent } from "babylonjs/Loading/sceneLoader";
     import { SceneLoaderProgressEvent } from "babylonjs/Loading/sceneLoader";
     import { Scene } from "babylonjs/scene";
     import { Scene } from "babylonjs/scene";
     import { IProperty } from "babylonjs-gltf2interface";
     import { IProperty } from "babylonjs-gltf2interface";
-    import { IGLTF, INode, IScene, IMesh, ICamera, IAnimation, IAnimationChannel, IBufferView, IMaterial, ITextureInfo, IImage, IMeshPrimitive, IArrayItem as IArrItem } from "babylonjs-loaders/glTF/2.0/glTFLoaderInterfaces";
+    import { IGLTF, ISampler, INode, IScene, IMesh, ICamera, IAnimation, IAnimationChannel, IBufferView, IMaterial, ITextureInfo, ITexture, IImage, IMeshPrimitive, IArrayItem as IArrItem } from "babylonjs-loaders/glTF/2.0/glTFLoaderInterfaces";
     import { IGLTFLoaderExtension } from "babylonjs-loaders/glTF/2.0/glTFLoaderExtension";
     import { IGLTFLoaderExtension } from "babylonjs-loaders/glTF/2.0/glTFLoaderExtension";
     import { IGLTFLoader, GLTFFileLoader, GLTFLoaderState, IGLTFLoaderData, IImportMeshAsyncOutput } from "babylonjs-loaders/glTF/glTFFileLoader";
     import { IGLTFLoader, GLTFFileLoader, GLTFLoaderState, IGLTFLoaderData, IImportMeshAsyncOutput } from "babylonjs-loaders/glTF/glTFFileLoader";
     import { IAnimatable } from 'babylonjs/Animations/animatable.interface';
     import { IAnimatable } from 'babylonjs/Animations/animatable.interface';
@@ -1417,9 +1431,12 @@ declare module "babylonjs-loaders/glTF/2.0/glTFLoader" {
         private _defaultBabylonMaterialData;
         private _defaultBabylonMaterialData;
         private _progressCallback?;
         private _progressCallback?;
         private _requests;
         private _requests;
-        private static readonly _DefaultSampler;
         private static _RegisteredExtensions;
         private static _RegisteredExtensions;
         /**
         /**
+         * The default glTF sampler.
+         */
+        static readonly DefaultSampler: ISampler;
+        /**
          * Registers a loader extension.
          * Registers a loader extension.
          * @param name The name of the loader extension.
          * @param name The name of the loader extension.
          * @param factory The factory function that creates the loader extension.
          * @param factory The factory function that creates the loader extension.
@@ -1432,7 +1449,7 @@ declare module "babylonjs-loaders/glTF/2.0/glTFLoader" {
          */
          */
         static UnregisterExtension(name: string): boolean;
         static UnregisterExtension(name: string): boolean;
         /**
         /**
-         * Gets the loader state.
+         * The loader state.
          */
          */
         get state(): Nullable<GLTFLoaderState>;
         get state(): Nullable<GLTFLoaderState>;
         /**
         /**
@@ -1599,7 +1616,10 @@ declare module "babylonjs-loaders/glTF/2.0/glTFLoader" {
          * @returns A promise that resolves with the loaded Babylon texture when the load is complete
          * @returns A promise that resolves with the loaded Babylon texture when the load is complete
          */
          */
         loadTextureInfoAsync(context: string, textureInfo: ITextureInfo, assign?: (babylonTexture: BaseTexture) => void): Promise<BaseTexture>;
         loadTextureInfoAsync(context: string, textureInfo: ITextureInfo, assign?: (babylonTexture: BaseTexture) => void): Promise<BaseTexture>;
-        private _loadTextureAsync;
+        /** @hidden */
+        _loadTextureAsync(context: string, texture: ITexture, assign?: (babylonTexture: BaseTexture) => void): Promise<BaseTexture>;
+        /** @hidden */
+        _createTextureAsync(context: string, sampler: ISampler, image: IImage, assign?: (babylonTexture: BaseTexture) => void): Promise<BaseTexture>;
         private _loadSampler;
         private _loadSampler;
         /**
         /**
          * Loads a glTF image.
          * Loads a glTF image.
@@ -1647,6 +1667,7 @@ declare module "babylonjs-loaders/glTF/2.0/glTFLoader" {
         private _extensionsCreateMaterial;
         private _extensionsCreateMaterial;
         private _extensionsLoadMaterialPropertiesAsync;
         private _extensionsLoadMaterialPropertiesAsync;
         private _extensionsLoadTextureInfoAsync;
         private _extensionsLoadTextureInfoAsync;
+        private _extensionsLoadTextureAsync;
         private _extensionsLoadAnimationAsync;
         private _extensionsLoadAnimationAsync;
         private _extensionsLoadSkinAsync;
         private _extensionsLoadSkinAsync;
         private _extensionsLoadUriAsync;
         private _extensionsLoadUriAsync;
@@ -1772,7 +1793,7 @@ declare module "babylonjs-loaders/glTF/2.0/Extensions/KHR_lights_punctual" {
     import { IGLTFLoaderExtension } from "babylonjs-loaders/glTF/2.0/glTFLoaderExtension";
     import { IGLTFLoaderExtension } from "babylonjs-loaders/glTF/2.0/glTFLoaderExtension";
     import { GLTFLoader } from "babylonjs-loaders/glTF/2.0/glTFLoader";
     import { GLTFLoader } from "babylonjs-loaders/glTF/2.0/glTFLoader";
     /**
     /**
-     * [Specification](https://github.com/KhronosGroup/glTF/blob/master/extensions/2.0/Khronos/KHR_lights_punctual/README.md)
+     * [Specification](https://github.com/KhronosGroup/glTF/blob/master/extensions/2.0/Khronos/KHR_lights_punctual)
      */
      */
     export class KHR_lights implements IGLTFLoaderExtension {
     export class KHR_lights implements IGLTFLoaderExtension {
         /**
         /**
@@ -1982,6 +2003,30 @@ declare module "babylonjs-loaders/glTF/2.0/Extensions/KHR_mesh_quantization" {
         dispose(): void;
         dispose(): void;
     }
     }
 }
 }
+declare module "babylonjs-loaders/glTF/2.0/Extensions/KHR_texture_basisu" {
+    import { IGLTFLoaderExtension } from "babylonjs-loaders/glTF/2.0/glTFLoaderExtension";
+    import { GLTFLoader } from "babylonjs-loaders/glTF/2.0/glTFLoader";
+    import { ITexture } from "babylonjs-loaders/glTF/2.0/glTFLoaderInterfaces";
+    import { BaseTexture } from "babylonjs/Materials/Textures/baseTexture";
+    import { Nullable } from "babylonjs/types";
+    /**
+     * [Proposed Specification](https://github.com/KhronosGroup/glTF/pull/1751)
+     * !!! Experimental Extension Subject to Changes !!!
+     */
+    export class KHR_texture_basisu implements IGLTFLoaderExtension {
+        /** The name of this extension. */
+        readonly name: string;
+        /** Defines whether this extension is enabled. */
+        enabled: boolean;
+        private _loader;
+        /** @hidden */
+        constructor(loader: GLTFLoader);
+        /** @hidden */
+        dispose(): void;
+        /** @hidden */
+        loadTextureAsync(context: string, texture: ITexture, assign: (babylonTexture: BaseTexture) => void): Nullable<Promise<BaseTexture>>;
+    }
+}
 declare module "babylonjs-loaders/glTF/2.0/Extensions/KHR_texture_transform" {
 declare module "babylonjs-loaders/glTF/2.0/Extensions/KHR_texture_transform" {
     import { Nullable } from "babylonjs/types";
     import { Nullable } from "babylonjs/types";
     import { BaseTexture } from "babylonjs/Materials/Textures/baseTexture";
     import { BaseTexture } from "babylonjs/Materials/Textures/baseTexture";
@@ -1989,7 +2034,7 @@ declare module "babylonjs-loaders/glTF/2.0/Extensions/KHR_texture_transform" {
     import { IGLTFLoaderExtension } from "babylonjs-loaders/glTF/2.0/glTFLoaderExtension";
     import { IGLTFLoaderExtension } from "babylonjs-loaders/glTF/2.0/glTFLoaderExtension";
     import { GLTFLoader } from "babylonjs-loaders/glTF/2.0/glTFLoader";
     import { GLTFLoader } from "babylonjs-loaders/glTF/2.0/glTFLoader";
     /**
     /**
-     * [Specification](https://github.com/KhronosGroup/glTF/blob/master/extensions/2.0/Khronos/KHR_texture_transform/README.md)
+     * [Specification](https://github.com/KhronosGroup/glTF/blob/master/extensions/2.0/Khronos/KHR_texture_transform)
      */
      */
     export class KHR_texture_transform implements IGLTFLoaderExtension {
     export class KHR_texture_transform implements IGLTFLoaderExtension {
         /**
         /**
@@ -2201,6 +2246,7 @@ declare module "babylonjs-loaders/glTF/2.0/Extensions/index" {
     export * from "babylonjs-loaders/glTF/2.0/Extensions/KHR_materials_sheen";
     export * from "babylonjs-loaders/glTF/2.0/Extensions/KHR_materials_sheen";
     export * from "babylonjs-loaders/glTF/2.0/Extensions/KHR_materials_specular";
     export * from "babylonjs-loaders/glTF/2.0/Extensions/KHR_materials_specular";
     export * from "babylonjs-loaders/glTF/2.0/Extensions/KHR_mesh_quantization";
     export * from "babylonjs-loaders/glTF/2.0/Extensions/KHR_mesh_quantization";
+    export * from "babylonjs-loaders/glTF/2.0/Extensions/KHR_texture_basisu";
     export * from "babylonjs-loaders/glTF/2.0/Extensions/KHR_texture_transform";
     export * from "babylonjs-loaders/glTF/2.0/Extensions/KHR_texture_transform";
     export * from "babylonjs-loaders/glTF/2.0/Extensions/MSFT_audio_emitter";
     export * from "babylonjs-loaders/glTF/2.0/Extensions/MSFT_audio_emitter";
     export * from "babylonjs-loaders/glTF/2.0/Extensions/MSFT_lod";
     export * from "babylonjs-loaders/glTF/2.0/Extensions/MSFT_lod";
@@ -3783,14 +3829,16 @@ declare module BABYLON.GLTF2 {
          */
          */
         loadCameraAsync?(context: string, camera: ICamera, assign: (babylonCamera: Camera) => void): Nullable<Promise<Camera>>;
         loadCameraAsync?(context: string, camera: ICamera, assign: (babylonCamera: Camera) => void): Nullable<Promise<Camera>>;
         /**
         /**
-         * @hidden Define this method to modify the default behavior when loading vertex data for mesh primitives.
+         * @hidden
+         * Define this method to modify the default behavior when loading vertex data for mesh primitives.
          * @param context The context when loading the asset
          * @param context The context when loading the asset
          * @param primitive The glTF mesh primitive property
          * @param primitive The glTF mesh primitive property
          * @returns A promise that resolves with the loaded geometry when the load is complete or null if not handled
          * @returns A promise that resolves with the loaded geometry when the load is complete or null if not handled
          */
          */
         _loadVertexDataAsync?(context: string, primitive: IMeshPrimitive, babylonMesh: Mesh): Nullable<Promise<Geometry>>;
         _loadVertexDataAsync?(context: string, primitive: IMeshPrimitive, babylonMesh: Mesh): Nullable<Promise<Geometry>>;
         /**
         /**
-         * @hidden Define this method to modify the default behavior when loading data for mesh primitives.
+         * @hidden
+         * Define this method to modify the default behavior when loading data for mesh primitives.
          * @param context The context when loading the asset
          * @param context The context when loading the asset
          * @param name The mesh name when loading the asset
          * @param name The mesh name when loading the asset
          * @param node The glTF node when loading the asset
          * @param node The glTF node when loading the asset
@@ -3801,7 +3849,8 @@ declare module BABYLON.GLTF2 {
          */
          */
         _loadMeshPrimitiveAsync?(context: string, name: string, node: INode, mesh: IMesh, primitive: IMeshPrimitive, assign: (babylonMesh: AbstractMesh) => void): Promise<AbstractMesh>;
         _loadMeshPrimitiveAsync?(context: string, name: string, node: INode, mesh: IMesh, primitive: IMeshPrimitive, assign: (babylonMesh: AbstractMesh) => void): Promise<AbstractMesh>;
         /**
         /**
-         * @hidden Define this method to modify the default behavior when loading materials. Load material creates the material and then loads material properties.
+         * @hidden
+         * Define this method to modify the default behavior when loading materials. Load material creates the material and then loads material properties.
          * @param context The context when loading the asset
          * @param context The context when loading the asset
          * @param material The glTF material property
          * @param material The glTF material property
          * @param assign A function called synchronously after parsing the glTF properties
          * @param assign A function called synchronously after parsing the glTF properties
@@ -3833,6 +3882,15 @@ declare module BABYLON.GLTF2 {
          */
          */
         loadTextureInfoAsync?(context: string, textureInfo: ITextureInfo, assign: (babylonTexture: BaseTexture) => void): Nullable<Promise<BaseTexture>>;
         loadTextureInfoAsync?(context: string, textureInfo: ITextureInfo, assign: (babylonTexture: BaseTexture) => void): Nullable<Promise<BaseTexture>>;
         /**
         /**
+         * @hidden
+         * Define this method to modify the default behavior when loading textures.
+         * @param context The context when loading the asset
+         * @param texture The glTF texture property
+         * @param assign A function called synchronously after parsing the glTF properties
+         * @returns A promise that resolves with the loaded Babylon texture when the load is complete or null if not handled
+         */
+        _loadTextureAsync?(context: string, texture: ITexture, assign: (babylonTexture: BaseTexture) => void): Nullable<Promise<BaseTexture>>;
+        /**
          * Define this method to modify the default behavior when loading animations.
          * Define this method to modify the default behavior when loading animations.
          * @param context The context when loading the asset
          * @param context The context when loading the asset
          * @param animation The glTF animation property
          * @param animation The glTF animation property
@@ -3840,7 +3898,8 @@ declare module BABYLON.GLTF2 {
          */
          */
         loadAnimationAsync?(context: string, animation: IAnimation): Nullable<Promise<AnimationGroup>>;
         loadAnimationAsync?(context: string, animation: IAnimation): Nullable<Promise<AnimationGroup>>;
         /**
         /**
-         * @hidden Define this method to modify the default behavior when loading skins.
+         * @hidden
+         * Define this method to modify the default behavior when loading skins.
          * @param context The context when loading the asset
          * @param context The context when loading the asset
          * @param node The glTF node property
          * @param node The glTF node property
          * @param skin The glTF skin property
          * @param skin The glTF skin property
@@ -3848,7 +3907,8 @@ declare module BABYLON.GLTF2 {
          */
          */
         _loadSkinAsync?(context: string, node: INode, skin: ISkin): Nullable<Promise<void>>;
         _loadSkinAsync?(context: string, node: INode, skin: ISkin): Nullable<Promise<void>>;
         /**
         /**
-         * @hidden Define this method to modify the default behavior when loading uris.
+         * @hidden
+         * Define this method to modify the default behavior when loading uris.
          * @param context The context when loading the asset
          * @param context The context when loading the asset
          * @param property The glTF property associated with the uri
          * @param property The glTF property associated with the uri
          * @param uri The uri to load
          * @param uri The uri to load
@@ -3916,9 +3976,12 @@ declare module BABYLON.GLTF2 {
         private _defaultBabylonMaterialData;
         private _defaultBabylonMaterialData;
         private _progressCallback?;
         private _progressCallback?;
         private _requests;
         private _requests;
-        private static readonly _DefaultSampler;
         private static _RegisteredExtensions;
         private static _RegisteredExtensions;
         /**
         /**
+         * The default glTF sampler.
+         */
+        static readonly DefaultSampler: ISampler;
+        /**
          * Registers a loader extension.
          * Registers a loader extension.
          * @param name The name of the loader extension.
          * @param name The name of the loader extension.
          * @param factory The factory function that creates the loader extension.
          * @param factory The factory function that creates the loader extension.
@@ -3931,7 +3994,7 @@ declare module BABYLON.GLTF2 {
          */
          */
         static UnregisterExtension(name: string): boolean;
         static UnregisterExtension(name: string): boolean;
         /**
         /**
-         * Gets the loader state.
+         * The loader state.
          */
          */
         get state(): Nullable<GLTFLoaderState>;
         get state(): Nullable<GLTFLoaderState>;
         /**
         /**
@@ -4098,7 +4161,10 @@ declare module BABYLON.GLTF2 {
          * @returns A promise that resolves with the loaded Babylon texture when the load is complete
          * @returns A promise that resolves with the loaded Babylon texture when the load is complete
          */
          */
         loadTextureInfoAsync(context: string, textureInfo: ITextureInfo, assign?: (babylonTexture: BaseTexture) => void): Promise<BaseTexture>;
         loadTextureInfoAsync(context: string, textureInfo: ITextureInfo, assign?: (babylonTexture: BaseTexture) => void): Promise<BaseTexture>;
-        private _loadTextureAsync;
+        /** @hidden */
+        _loadTextureAsync(context: string, texture: ITexture, assign?: (babylonTexture: BaseTexture) => void): Promise<BaseTexture>;
+        /** @hidden */
+        _createTextureAsync(context: string, sampler: ISampler, image: IImage, assign?: (babylonTexture: BaseTexture) => void): Promise<BaseTexture>;
         private _loadSampler;
         private _loadSampler;
         /**
         /**
          * Loads a glTF image.
          * Loads a glTF image.
@@ -4146,6 +4212,7 @@ declare module BABYLON.GLTF2 {
         private _extensionsCreateMaterial;
         private _extensionsCreateMaterial;
         private _extensionsLoadMaterialPropertiesAsync;
         private _extensionsLoadMaterialPropertiesAsync;
         private _extensionsLoadTextureInfoAsync;
         private _extensionsLoadTextureInfoAsync;
+        private _extensionsLoadTextureAsync;
         private _extensionsLoadAnimationAsync;
         private _extensionsLoadAnimationAsync;
         private _extensionsLoadSkinAsync;
         private _extensionsLoadSkinAsync;
         private _extensionsLoadUriAsync;
         private _extensionsLoadUriAsync;
@@ -4255,7 +4322,7 @@ declare module BABYLON.GLTF2.Loader.Extensions {
 }
 }
 declare module BABYLON.GLTF2.Loader.Extensions {
 declare module BABYLON.GLTF2.Loader.Extensions {
     /**
     /**
-     * [Specification](https://github.com/KhronosGroup/glTF/blob/master/extensions/2.0/Khronos/KHR_lights_punctual/README.md)
+     * [Specification](https://github.com/KhronosGroup/glTF/blob/master/extensions/2.0/Khronos/KHR_lights_punctual)
      */
      */
     export class KHR_lights implements IGLTFLoaderExtension {
     export class KHR_lights implements IGLTFLoaderExtension {
         /**
         /**
@@ -4440,7 +4507,26 @@ declare module BABYLON.GLTF2.Loader.Extensions {
 }
 }
 declare module BABYLON.GLTF2.Loader.Extensions {
 declare module BABYLON.GLTF2.Loader.Extensions {
     /**
     /**
-     * [Specification](https://github.com/KhronosGroup/glTF/blob/master/extensions/2.0/Khronos/KHR_texture_transform/README.md)
+     * [Proposed Specification](https://github.com/KhronosGroup/glTF/pull/1751)
+     * !!! Experimental Extension Subject to Changes !!!
+     */
+    export class KHR_texture_basisu implements IGLTFLoaderExtension {
+        /** The name of this extension. */
+        readonly name: string;
+        /** Defines whether this extension is enabled. */
+        enabled: boolean;
+        private _loader;
+        /** @hidden */
+        constructor(loader: GLTFLoader);
+        /** @hidden */
+        dispose(): void;
+        /** @hidden */
+        loadTextureAsync(context: string, texture: ITexture, assign: (babylonTexture: BaseTexture) => void): Nullable<Promise<BaseTexture>>;
+    }
+}
+declare module BABYLON.GLTF2.Loader.Extensions {
+    /**
+     * [Specification](https://github.com/KhronosGroup/glTF/blob/master/extensions/2.0/Khronos/KHR_texture_transform)
      */
      */
     export class KHR_texture_transform implements IGLTFLoaderExtension {
     export class KHR_texture_transform implements IGLTFLoaderExtension {
         /**
         /**

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

@@ -111,6 +111,7 @@
 - Added preview area pop up for NME ([Kyle Belfort](https://github.com/belfortk))
 - Added preview area pop up for NME ([Kyle Belfort](https://github.com/belfortk))
 - Added comments to frames in NME ([Kyle Belfort](https://github.com/belfortk))
 - Added comments to frames in NME ([Kyle Belfort](https://github.com/belfortk))
 - Make frames resizable in NME ([Kyle Belfort](https://github.com/belfortk))
 - Make frames resizable in NME ([Kyle Belfort](https://github.com/belfortk))
+- Implement NME Preview Area Redesign ([Kyle Belfort](https://github.com/belfortk))
 
 
 ### Meshes
 ### Meshes
 
 
@@ -149,6 +150,7 @@
 - Use web workers to validate glTF to avoid blocking the main thread. ([bghgary](https://github.com/bghgary))
 - Use web workers to validate glTF to avoid blocking the main thread. ([bghgary](https://github.com/bghgary))
 - Update glTF validator to 2.0.0-dev.3.1. ([bghgary](https://github.com/bghgary))
 - Update glTF validator to 2.0.0-dev.3.1. ([bghgary](https://github.com/bghgary))
 - Fix an issue with disposing materials and textures too aggressively in MSFT_lod loader extension. ([bghgary](https://github.com/bghgary))
 - Fix an issue with disposing materials and textures too aggressively in MSFT_lod loader extension. ([bghgary](https://github.com/bghgary))
+- Added experimental support for loading KTX2 files and `KHR_texture_basisu` glTF extension. ([bghgary](https://github.com/bghgary))
 
 
 ### Materials
 ### Materials
 
 
@@ -179,6 +181,7 @@
 - MultiPickSprite and multiPickSpriteWithRay added to sprites ([JohnK](https://github.com/BabylonJSGuide))
 - MultiPickSprite and multiPickSpriteWithRay added to sprites ([JohnK](https://github.com/BabylonJSGuide))
 - SpritePackedManager support for JSON Objects that where not stringified, of with the frames parameter accepting Objects and Arrays ([Pryme8](https://github.com/Pryme8))
 - SpritePackedManager support for JSON Objects that where not stringified, of with the frames parameter accepting Objects and Arrays ([Pryme8](https://github.com/Pryme8))
 - Added `SpriteMap` for creation of grid-based dynamically animated sprite atlas rendering (Beta) ([Pryme8](https://github.com/Pryme8))
 - Added `SpriteMap` for creation of grid-based dynamically animated sprite atlas rendering (Beta) ([Pryme8](https://github.com/Pryme8))
+- Add `SpriteManager.disableDepthWrite` property ([Popov72](https://github.com/Popov72))
 
 
 ### WebXR / WebVR
 ### WebXR / WebVR
 
 
@@ -339,6 +342,7 @@
 - Fix subSurface parameters not copied in the PBR clone methods ([Popov72](https://github.com/Popov72))
 - Fix subSurface parameters not copied in the PBR clone methods ([Popov72](https://github.com/Popov72))
 - Fix for bug where round-tripped glTF imported scenes are encapsulated in a second root node ([#6349](https://github.com/BabylonJS/Babylon.js/issues/6349))([drigax](https://github.com/drigax) & [noalak](https://github.com/noalak))
 - Fix for bug where round-tripped glTF imported scenes are encapsulated in a second root node ([#6349](https://github.com/BabylonJS/Babylon.js/issues/6349))([drigax](https://github.com/drigax) & [noalak](https://github.com/noalak))
 - Fix `HDRCubeTexture` construction, `generateHarmonics` was not properly taken into account ([Popov72](https://github.com/Popov72))
 - Fix `HDRCubeTexture` construction, `generateHarmonics` was not properly taken into account ([Popov72](https://github.com/Popov72))
+- VideoTexture poster respects invertY ([Sebavan](https://github.com/sebavan/)
 
 
 ## Breaking changes
 ## Breaking changes
 
 
@@ -352,3 +356,4 @@
 - Default culling strategy changed to CULLINGSTRATEGY_BOUNDINGSPHERE_ONLY ([Deltakosh](https://github.com/deltakosh/))
 - Default culling strategy changed to CULLINGSTRATEGY_BOUNDINGSPHERE_ONLY ([Deltakosh](https://github.com/deltakosh/))
 - `MaterialHelper.BindLight` and `MaterialHelper.BindLights` do not need the usePhysicalLight anymore ([Sebavan](https://github.com/sebavan/))
 - `MaterialHelper.BindLight` and `MaterialHelper.BindLights` do not need the usePhysicalLight anymore ([Sebavan](https://github.com/sebavan/))
 - `Mesh.bakeTransformIntoVertices` now preserves child world-space transforms([drigax](https://github.com/drigax))
 - `Mesh.bakeTransformIntoVertices` now preserves child world-space transforms([drigax](https://github.com/drigax))
+- Removed `setTexturesToUse` and `setCompressedTextureExclusions` from Engine. ([bghgary](https://github.com/bghgary))

+ 4 - 0
inspector/custom.d.ts

@@ -0,0 +1,4 @@
+declare module "*.svg" {
+    const content: string;
+    export default content;
+}

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

@@ -737,6 +737,9 @@ $line-padding-left: 2px;
                             align-items: center;
                             align-items: center;
                             justify-items: center;
                             justify-items: center;
                             cursor: pointer;
                             cursor: pointer;
+                            img {
+                                height: 100%;
+                            }
                         }
                         }
 
 
                         .expand {
                         .expand {

+ 4 - 2
inspector/src/components/actionTabs/lines/color3LineComponent.tsx

@@ -4,7 +4,9 @@ import { Color3 } from "babylonjs/Maths/math";
 import { PropertyChangedEvent } from "../../propertyChangedEvent";
 import { PropertyChangedEvent } from "../../propertyChangedEvent";
 import { NumericInputComponent } from "./numericInputComponent";
 import { NumericInputComponent } from "./numericInputComponent";
 import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
 import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
-import { faMinus, faPlus, faCopy } from "@fortawesome/free-solid-svg-icons";
+import { faMinus, faPlus } from "@fortawesome/free-solid-svg-icons";
+import CopyIcon from "./copy.svg";
+
 
 
 export interface IColor3LineComponentProps {
 export interface IColor3LineComponentProps {
     label: string;
     label: string;
@@ -135,7 +137,7 @@ export class Color3LineComponent extends React.Component<IColor3LineComponentPro
                         <input type="color" value={colorAsColor3.toHexString()} onChange={(evt) => this.onChange(evt.target.value)} />
                         <input type="color" value={colorAsColor3.toHexString()} onChange={(evt) => this.onChange(evt.target.value)} />
                     </div>
                     </div>
                     <div className="copy hoverIcon" onClick={() => this.copyToClipboard()} title="Copy to clipboard">
                     <div className="copy hoverIcon" onClick={() => this.copyToClipboard()} title="Copy to clipboard">
-                        <FontAwesomeIcon icon={faCopy} />
+                        <img src={CopyIcon} alt=""/>
                     </div>
                     </div>
                     <div className="expand hoverIcon" onClick={() => this.switchExpandState()} title="Expand">
                     <div className="expand hoverIcon" onClick={() => this.switchExpandState()} title="Expand">
                         {chevron}
                         {chevron}

+ 3 - 2
inspector/src/components/actionTabs/lines/color4LineComponent.tsx

@@ -3,8 +3,9 @@ import { Observable } from "babylonjs/Misc/observable";
 import { Color3, Color4 } from "babylonjs/Maths/math";
 import { Color3, Color4 } from "babylonjs/Maths/math";
 import { NumericInputComponent } from "./numericInputComponent";
 import { NumericInputComponent } from "./numericInputComponent";
 import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
 import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
-import { faMinus, faPlus, faCopy } from "@fortawesome/free-solid-svg-icons";
+import { faMinus, faPlus } from "@fortawesome/free-solid-svg-icons";
 import { PropertyChangedEvent } from '../../propertyChangedEvent';
 import { PropertyChangedEvent } from '../../propertyChangedEvent';
+import CopyIcon from "./copy.svg";
 
 
 export interface IColor4LineComponentProps {
 export interface IColor4LineComponentProps {
     label: string;
     label: string;
@@ -154,7 +155,7 @@ export class Color4LineComponent extends React.Component<IColor4LineComponentPro
                         <input type="color" value={colorAsColor3.toHexString()} onChange={(evt) => this.onChange(evt.target.value)} />
                         <input type="color" value={colorAsColor3.toHexString()} onChange={(evt) => this.onChange(evt.target.value)} />
                     </div>
                     </div>
                     <div className="copy hoverIcon" onClick={() => this.copyToClipboard()} title="Copy to clipboard">
                     <div className="copy hoverIcon" onClick={() => this.copyToClipboard()} title="Copy to clipboard">
-                        <FontAwesomeIcon icon={faCopy} />
+                        <img src={CopyIcon} alt=""/>
                     </div>
                     </div>
                     <div className="expand hoverIcon" onClick={() => this.switchExpandState()} title="Expand">
                     <div className="expand hoverIcon" onClick={() => this.switchExpandState()} title="Expand">
                         {chevron}
                         {chevron}

+ 1 - 0
inspector/src/components/actionTabs/lines/copy.svg

@@ -0,0 +1 @@
+<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 40 40"><defs><style>.cls-1{fill:#fff;}</style></defs><title>copy</title><g id="UI_Elements" data-name="UI Elements"><path class="cls-1" d="M24,14.89H22.76l-3-3H12.43V26.59h4.26v3h11.5V19Zm.3,1.71,2.14,2.13H24.34Zm-10.91,9V12.93h5.93l2,2H16.69v10.7Zm4.26,3V15.89h5.65v3.84h3.85v8.83Z"/></g></svg>

+ 4 - 1
inspector/tsconfig.json

@@ -24,5 +24,8 @@
                 "../../dist/preview release/babylon.module.d.ts"
                 "../../dist/preview release/babylon.module.d.ts"
             ]
             ]
         }
         }
-    }
+    },
+    "files": [ 
+        "./custom.d.ts" 
+      ]  
 }
 }

+ 13 - 1
inspector/webpack.config.js

@@ -23,7 +23,19 @@ var config = babylonWebpackConfig({
         {
         {
             test: /\.css$/,
             test: /\.css$/,
             use: ['style-loader', 'css-loader']
             use: ['style-loader', 'css-loader']
-        }],
+        },
+        {
+            test: /\.svg$/,
+            use: [
+              {
+                loader: 'svg-url-loader',
+                options: {
+                  limit: 10000,
+                },
+              },
+            ],
+          }
+    ],
     plugins: [
     plugins: [
         new MiniCssExtractPlugin({
         new MiniCssExtractPlugin({
             // Options similar to the same options in webpackOptions.output
             // Options similar to the same options in webpackOptions.output

+ 1 - 1
loaders/src/glTF/2.0/Extensions/KHR_lights_punctual.ts

@@ -39,7 +39,7 @@ interface ILights {
 }
 }
 
 
 /**
 /**
- * [Specification](https://github.com/KhronosGroup/glTF/blob/master/extensions/2.0/Khronos/KHR_lights_punctual/README.md)
+ * [Specification](https://github.com/KhronosGroup/glTF/blob/master/extensions/2.0/Khronos/KHR_lights_punctual)
  */
  */
 export class KHR_lights implements IGLTFLoaderExtension {
 export class KHR_lights implements IGLTFLoaderExtension {
     /**
     /**

+ 49 - 0
loaders/src/glTF/2.0/Extensions/KHR_texture_basisu.ts

@@ -0,0 +1,49 @@
+import { IGLTFLoaderExtension } from "../glTFLoaderExtension";
+import { GLTFLoader, ArrayItem } from "../glTFLoader";
+import { ITexture } from "../glTFLoaderInterfaces";
+import { BaseTexture } from "babylonjs/Materials/Textures/baseTexture";
+import { Nullable } from "babylonjs/types";
+
+const NAME = "KHR_texture_basisu";
+
+interface IKHRTextureBasisU {
+    source: number;
+}
+
+/**
+ * [Proposed Specification](https://github.com/KhronosGroup/glTF/pull/1751)
+ * !!! Experimental Extension Subject to Changes !!!
+ */
+export class KHR_texture_basisu implements IGLTFLoaderExtension {
+    /** The name of this extension. */
+    public readonly name = NAME;
+
+    /** Defines whether this extension is enabled. */
+    public enabled = true;
+
+    private _loader: GLTFLoader;
+
+    /** @hidden */
+    constructor(loader: GLTFLoader) {
+        this._loader = loader;
+    }
+
+    /** @hidden */
+    public dispose() {
+        delete this._loader;
+    }
+
+    /** @hidden */
+    public loadTextureAsync(context: string, texture: ITexture, assign: (babylonTexture: BaseTexture) => void): Nullable<Promise<BaseTexture>> {
+        return GLTFLoader.LoadExtensionAsync<IKHRTextureBasisU, BaseTexture>(context, texture, this.name, (extensionContext, extension) => {
+            const sampler = (texture.sampler == undefined ? GLTFLoader.DefaultSampler : ArrayItem.Get(`${context}/sampler`, this._loader.gltf.samplers, texture.sampler));
+            const image = ArrayItem.Get(`${extensionContext}/source`, this._loader.gltf.images, extension.source);
+            return this._loader._createTextureAsync(context, sampler, image, (babylonTexture) => {
+                babylonTexture.gammaSpace = false;
+                assign(babylonTexture);
+            });
+        });
+    }
+}
+
+GLTFLoader.RegisterExtension(NAME, (loader) => new KHR_texture_basisu(loader));

+ 1 - 1
loaders/src/glTF/2.0/Extensions/KHR_texture_transform.ts

@@ -16,7 +16,7 @@ interface IKHRTextureTransform {
 }
 }
 
 
 /**
 /**
- * [Specification](https://github.com/KhronosGroup/glTF/blob/master/extensions/2.0/Khronos/KHR_texture_transform/README.md)
+ * [Specification](https://github.com/KhronosGroup/glTF/blob/master/extensions/2.0/Khronos/KHR_texture_transform)
  */
  */
 export class KHR_texture_transform implements IGLTFLoaderExtension {
 export class KHR_texture_transform implements IGLTFLoaderExtension {
     /**
     /**

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

@@ -7,6 +7,7 @@ export * from "./KHR_materials_clearcoat";
 export * from "./KHR_materials_sheen";
 export * from "./KHR_materials_sheen";
 export * from "./KHR_materials_specular";
 export * from "./KHR_materials_specular";
 export * from "./KHR_mesh_quantization";
 export * from "./KHR_mesh_quantization";
+export * from "./KHR_texture_basisu";
 export * from "./KHR_texture_transform";
 export * from "./KHR_texture_transform";
 export * from "./MSFT_audio_emitter";
 export * from "./MSFT_audio_emitter";
 export * from "./MSFT_lod";
 export * from "./MSFT_lod";

+ 34 - 27
loaders/src/glTF/2.0/glTFLoader.ts

@@ -120,11 +120,14 @@ export class GLTFLoader implements IGLTFLoader {
     private _progressCallback?: (event: SceneLoaderProgressEvent) => void;
     private _progressCallback?: (event: SceneLoaderProgressEvent) => void;
     private _requests = new Array<IFileRequestInfo>();
     private _requests = new Array<IFileRequestInfo>();
 
 
-    private static readonly _DefaultSampler: ISampler = { index: -1 };
-
     private static _RegisteredExtensions: { [name: string]: IRegisteredExtension } = {};
     private static _RegisteredExtensions: { [name: string]: IRegisteredExtension } = {};
 
 
     /**
     /**
+     * The default glTF sampler.
+     */
+    public static readonly DefaultSampler: ISampler = { index: -1 };
+
+    /**
      * Registers a loader extension.
      * Registers a loader extension.
      * @param name The name of the loader extension.
      * @param name The name of the loader extension.
      * @param factory The factory function that creates the loader extension.
      * @param factory The factory function that creates the loader extension.
@@ -154,7 +157,7 @@ export class GLTFLoader implements IGLTFLoader {
     }
     }
 
 
     /**
     /**
-     * Gets the loader state.
+     * The loader state.
      */
      */
     public get state(): Nullable<GLTFLoaderState> {
     public get state(): Nullable<GLTFLoaderState> {
         return this._state;
         return this._state;
@@ -1912,29 +1915,33 @@ export class GLTFLoader implements IGLTFLoader {
         return promise;
         return promise;
     }
     }
 
 
-    private _loadTextureAsync(context: string, texture: ITexture, assign: (babylonTexture: BaseTexture) => void = () => { }): Promise<BaseTexture> {
-        const promises = new Array<Promise<any>>();
+    /** @hidden */
+    public _loadTextureAsync(context: string, texture: ITexture, assign: (babylonTexture: BaseTexture) => void = () => { }): Promise<BaseTexture> {
+        const extensionPromise = this._extensionsLoadTextureAsync(context, texture, assign);
+        if (extensionPromise) {
+            return extensionPromise;
+        }
 
 
         this.logOpen(`${context} ${texture.name || ""}`);
         this.logOpen(`${context} ${texture.name || ""}`);
 
 
-        const sampler = (texture.sampler == undefined ? GLTFLoader._DefaultSampler : ArrayItem.Get(`${context}/sampler`, this._gltf.samplers, texture.sampler));
+        const sampler = (texture.sampler == undefined ? GLTFLoader.DefaultSampler : ArrayItem.Get(`${context}/sampler`, this._gltf.samplers, texture.sampler));
+        const image = ArrayItem.Get(`${context}/source`, this._gltf.images, texture.source);
+        const promise = this._createTextureAsync(context, sampler, image, assign);
+
+        this.logClose();
+
+        return promise;
+    }
+
+    /** @hidden */
+    public _createTextureAsync(context: string, sampler: ISampler, image: IImage, assign: (babylonTexture: BaseTexture) => void = () => { }): Promise<BaseTexture> {
         const samplerData = this._loadSampler(`/samplers/${sampler.index}`, sampler);
         const samplerData = this._loadSampler(`/samplers/${sampler.index}`, sampler);
 
 
-        const image = ArrayItem.Get(`${context}/source`, this._gltf.images, texture.source);
-        let url: Nullable<string> = null;
-        if (image.uri) {
-            if (Tools.IsBase64(image.uri)) {
-                url = image.uri;
-            }
-            else if (this._babylonScene.getEngine().textureFormatInUse) {
-                // If an image uri and a texture format is set like (eg. KTX) load from url instead of blob to support texture format and fallback
-                url = this._rootUrl + image.uri;
-            }
-        }
+        const promises = new Array<Promise<any>>();
 
 
         const deferred = new Deferred<void>();
         const deferred = new Deferred<void>();
         this._babylonScene._blockEntityCollection = this._forAssetContainer;
         this._babylonScene._blockEntityCollection = this._forAssetContainer;
-        const babylonTexture = new Texture(url, this._babylonScene, samplerData.noMipMaps, false, samplerData.samplingMode, () => {
+        const babylonTexture = new Texture(null, this._babylonScene, samplerData.noMipMaps, false, samplerData.samplingMode, () => {
             if (!this._disposed) {
             if (!this._disposed) {
                 deferred.resolve();
                 deferred.resolve();
             }
             }
@@ -1946,20 +1953,16 @@ export class GLTFLoader implements IGLTFLoader {
         this._babylonScene._blockEntityCollection = false;
         this._babylonScene._blockEntityCollection = false;
         promises.push(deferred.promise);
         promises.push(deferred.promise);
 
 
-        if (!url) {
-            promises.push(this.loadImageAsync(`/images/${image.index}`, image).then((data) => {
-                const name = image.uri || `${this._fileName}#image${image.index}`;
-                const dataUrl = `data:${this._uniqueRootUrl}${name}`;
-                babylonTexture.updateURL(dataUrl, data);
-            }));
-        }
+        promises.push(this.loadImageAsync(`/images/${image.index}`, image).then((data) => {
+            const name = image.uri || `${this._fileName}#image${image.index}`;
+            const dataUrl = `data:${this._uniqueRootUrl}${name}`;
+            babylonTexture.updateURL(dataUrl, data);
+        }));
 
 
         babylonTexture.wrapU = samplerData.wrapU;
         babylonTexture.wrapU = samplerData.wrapU;
         babylonTexture.wrapV = samplerData.wrapV;
         babylonTexture.wrapV = samplerData.wrapV;
         assign(babylonTexture);
         assign(babylonTexture);
 
 
-        this.logClose();
-
         return Promise.all(promises).then(() => {
         return Promise.all(promises).then(() => {
             return babylonTexture;
             return babylonTexture;
         });
         });
@@ -2339,6 +2342,10 @@ export class GLTFLoader implements IGLTFLoader {
         return this._applyExtensions(textureInfo, "loadTextureInfo", (extension) => extension.loadTextureInfoAsync && extension.loadTextureInfoAsync(context, textureInfo, assign));
         return this._applyExtensions(textureInfo, "loadTextureInfo", (extension) => extension.loadTextureInfoAsync && extension.loadTextureInfoAsync(context, textureInfo, assign));
     }
     }
 
 
+    private _extensionsLoadTextureAsync(context: string, texture: ITexture, assign: (babylonTexture: BaseTexture) => void): Nullable<Promise<BaseTexture>> {
+        return this._applyExtensions(texture, "loadTexture", (extension) => extension._loadTextureAsync && extension._loadTextureAsync(context, texture, assign));
+    }
+
     private _extensionsLoadAnimationAsync(context: string, animation: IAnimation): Nullable<Promise<AnimationGroup>> {
     private _extensionsLoadAnimationAsync(context: string, animation: IAnimation): Nullable<Promise<AnimationGroup>> {
         return this._applyExtensions(animation, "loadAnimation", (extension) => extension.loadAnimationAsync && extension.loadAnimationAsync(context, animation));
         return this._applyExtensions(animation, "loadAnimation", (extension) => extension.loadAnimationAsync && extension.loadAnimationAsync(context, animation));
     }
     }

+ 21 - 7
loaders/src/glTF/2.0/glTFLoaderExtension.ts

@@ -8,8 +8,7 @@ import { BaseTexture } from "babylonjs/Materials/Textures/baseTexture";
 import { Mesh } from "babylonjs/Meshes/mesh";
 import { Mesh } from "babylonjs/Meshes/mesh";
 import { AbstractMesh } from "babylonjs/Meshes/abstractMesh";
 import { AbstractMesh } from "babylonjs/Meshes/abstractMesh";
 import { IDisposable } from "babylonjs/scene";
 import { IDisposable } from "babylonjs/scene";
-
-import { IScene, INode, IMesh, ISkin, ICamera, IMeshPrimitive, IMaterial, ITextureInfo, IAnimation, IBufferView, IBuffer } from "./glTFLoaderInterfaces";
+import { IScene, INode, IMesh, ISkin, ICamera, IMeshPrimitive, IMaterial, ITextureInfo, IAnimation, ITexture, IBufferView, IBuffer } from "./glTFLoaderInterfaces";
 import { IGLTFLoaderExtension as IGLTFBaseLoaderExtension } from "../glTFFileLoader";
 import { IGLTFLoaderExtension as IGLTFBaseLoaderExtension } from "../glTFFileLoader";
 import { IProperty } from 'babylonjs-gltf2interface';
 import { IProperty } from 'babylonjs-gltf2interface';
 
 
@@ -54,7 +53,8 @@ export interface IGLTFLoaderExtension extends IGLTFBaseLoaderExtension, IDisposa
     loadCameraAsync?(context: string, camera: ICamera, assign: (babylonCamera: Camera) => void): Nullable<Promise<Camera>>;
     loadCameraAsync?(context: string, camera: ICamera, assign: (babylonCamera: Camera) => void): Nullable<Promise<Camera>>;
 
 
     /**
     /**
-     * @hidden Define this method to modify the default behavior when loading vertex data for mesh primitives.
+     * @hidden
+     * Define this method to modify the default behavior when loading vertex data for mesh primitives.
      * @param context The context when loading the asset
      * @param context The context when loading the asset
      * @param primitive The glTF mesh primitive property
      * @param primitive The glTF mesh primitive property
      * @returns A promise that resolves with the loaded geometry when the load is complete or null if not handled
      * @returns A promise that resolves with the loaded geometry when the load is complete or null if not handled
@@ -62,7 +62,8 @@ export interface IGLTFLoaderExtension extends IGLTFBaseLoaderExtension, IDisposa
     _loadVertexDataAsync?(context: string, primitive: IMeshPrimitive, babylonMesh: Mesh): Nullable<Promise<Geometry>>;
     _loadVertexDataAsync?(context: string, primitive: IMeshPrimitive, babylonMesh: Mesh): Nullable<Promise<Geometry>>;
 
 
     /**
     /**
-     * @hidden Define this method to modify the default behavior when loading data for mesh primitives.
+     * @hidden
+     * Define this method to modify the default behavior when loading data for mesh primitives.
      * @param context The context when loading the asset
      * @param context The context when loading the asset
      * @param name The mesh name when loading the asset
      * @param name The mesh name when loading the asset
      * @param node The glTF node when loading the asset
      * @param node The glTF node when loading the asset
@@ -74,7 +75,8 @@ export interface IGLTFLoaderExtension extends IGLTFBaseLoaderExtension, IDisposa
     _loadMeshPrimitiveAsync?(context: string, name: string, node: INode, mesh: IMesh, primitive: IMeshPrimitive, assign: (babylonMesh: AbstractMesh) => void): Promise<AbstractMesh>;
     _loadMeshPrimitiveAsync?(context: string, name: string, node: INode, mesh: IMesh, primitive: IMeshPrimitive, assign: (babylonMesh: AbstractMesh) => void): Promise<AbstractMesh>;
 
 
     /**
     /**
-     * @hidden Define this method to modify the default behavior when loading materials. Load material creates the material and then loads material properties.
+     * @hidden
+     * Define this method to modify the default behavior when loading materials. Load material creates the material and then loads material properties.
      * @param context The context when loading the asset
      * @param context The context when loading the asset
      * @param material The glTF material property
      * @param material The glTF material property
      * @param assign A function called synchronously after parsing the glTF properties
      * @param assign A function called synchronously after parsing the glTF properties
@@ -110,6 +112,16 @@ export interface IGLTFLoaderExtension extends IGLTFBaseLoaderExtension, IDisposa
     loadTextureInfoAsync?(context: string, textureInfo: ITextureInfo, assign: (babylonTexture: BaseTexture) => void): Nullable<Promise<BaseTexture>>;
     loadTextureInfoAsync?(context: string, textureInfo: ITextureInfo, assign: (babylonTexture: BaseTexture) => void): Nullable<Promise<BaseTexture>>;
 
 
     /**
     /**
+     * @hidden
+     * Define this method to modify the default behavior when loading textures.
+     * @param context The context when loading the asset
+     * @param texture The glTF texture property
+     * @param assign A function called synchronously after parsing the glTF properties
+     * @returns A promise that resolves with the loaded Babylon texture when the load is complete or null if not handled
+     */
+    _loadTextureAsync?(context: string, texture: ITexture, assign: (babylonTexture: BaseTexture) => void): Nullable<Promise<BaseTexture>>;
+
+    /**
      * Define this method to modify the default behavior when loading animations.
      * Define this method to modify the default behavior when loading animations.
      * @param context The context when loading the asset
      * @param context The context when loading the asset
      * @param animation The glTF animation property
      * @param animation The glTF animation property
@@ -118,7 +130,8 @@ export interface IGLTFLoaderExtension extends IGLTFBaseLoaderExtension, IDisposa
     loadAnimationAsync?(context: string, animation: IAnimation): Nullable<Promise<AnimationGroup>>;
     loadAnimationAsync?(context: string, animation: IAnimation): Nullable<Promise<AnimationGroup>>;
 
 
     /**
     /**
-     * @hidden Define this method to modify the default behavior when loading skins.
+     * @hidden
+     * Define this method to modify the default behavior when loading skins.
      * @param context The context when loading the asset
      * @param context The context when loading the asset
      * @param node The glTF node property
      * @param node The glTF node property
      * @param skin The glTF skin property
      * @param skin The glTF skin property
@@ -127,7 +140,8 @@ export interface IGLTFLoaderExtension extends IGLTFBaseLoaderExtension, IDisposa
     _loadSkinAsync?(context: string, node: INode, skin: ISkin): Nullable<Promise<void>>;
     _loadSkinAsync?(context: string, node: INode, skin: ISkin): Nullable<Promise<void>>;
 
 
     /**
     /**
-     * @hidden Define this method to modify the default behavior when loading uris.
+     * @hidden
+     * Define this method to modify the default behavior when loading uris.
      * @param context The context when loading the asset
      * @param context The context when loading the asset
      * @param property The glTF property associated with the uri
      * @param property The glTF property associated with the uri
      * @param uri The uri to load
      * @param uri The uri to load

+ 1 - 0
localDev/index-views.html

@@ -10,6 +10,7 @@
     <script src="../dist/preview%20release/Oimo.js"></script>
     <script src="../dist/preview%20release/Oimo.js"></script>
     <script src="../dist/preview%20release/ammo.js"></script>
     <script src="../dist/preview%20release/ammo.js"></script>
     <script src="../dist/preview%20release/recast.js"></script>
     <script src="../dist/preview%20release/recast.js"></script>
+    <script src="../dist/preview%20release/libktx.js"></script>
     <script src="../Tools/DevLoader/BabylonLoader.js"></script>
     <script src="../Tools/DevLoader/BabylonLoader.js"></script>
 
 
     <style>
     <style>

+ 1 - 0
localDev/index.html

@@ -10,6 +10,7 @@
     <script src="../dist/preview%20release/Oimo.js"></script>
     <script src="../dist/preview%20release/Oimo.js"></script>
     <script src="../dist/preview%20release/ammo.js"></script>
     <script src="../dist/preview%20release/ammo.js"></script>
     <script src="../dist/preview%20release/recast.js"></script>
     <script src="../dist/preview%20release/recast.js"></script>
+    <script src="../dist/preview%20release/libktx.js"></script>
     <script src="../Tools/DevLoader/BabylonLoader.js"></script>
     <script src="../Tools/DevLoader/BabylonLoader.js"></script>
 
 
     <style>
     <style>

+ 4 - 0
nodeEditor/custom.d.ts

@@ -0,0 +1,4 @@
+declare module "*.svg" {
+    const content: string;
+    export default content;
+}

+ 28 - 55
nodeEditor/src/components/preview/previewAreaComponent.tsx

@@ -1,10 +1,12 @@
 
 
 import * as React from "react";
 import * as React from "react";
 import { GlobalState } from '../../globalState';
 import { GlobalState } from '../../globalState';
-import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
-import { faPlay, faStop, faPalette, faCheckDouble, faSun, faLocationArrow, faClone } from '@fortawesome/free-solid-svg-icons';
-import { Color3, Color4 } from 'babylonjs/Maths/math.color';
 import { DataStorage } from '../../dataStorage';
 import { DataStorage } from '../../dataStorage';
+import DoubleSided from './svgs/doubleSided.svg'
+import DepthPass from './svgs/depthPass.svg'
+import Omni from './svgs/omni.svg'
+import DirectionalRight from './svgs/directionalRight.svg'
+import DirectionalLeft from './svgs/directionalLeft.svg'
 
 
 interface IPreviewAreaComponentProps {
 interface IPreviewAreaComponentProps {
     globalState: GlobalState;
     globalState: GlobalState;
@@ -21,23 +23,6 @@ export class PreviewAreaComponent extends React.Component<IPreviewAreaComponentP
         this.props.globalState.onIsLoadingChanged.add(state => this.setState({isLoading: state}));
         this.props.globalState.onIsLoadingChanged.add(state => this.setState({isLoading: state}));
     }
     }
 
 
-    changeAnimation() {
-        this.props.globalState.rotatePreview = !this.props.globalState.rotatePreview;
-        this.props.globalState.onAnimationCommandActivated.notifyObservers();
-        this.forceUpdate();
-    }
-
-    changeBackground(value: string) {
-        const newColor = Color3.FromHexString(value);
-
-        DataStorage.StoreNumber("BackgroundColorR", newColor.r);
-        DataStorage.StoreNumber("BackgroundColorG", newColor.g);
-        DataStorage.StoreNumber("BackgroundColorB", newColor.b);
-
-        this.props.globalState.backgroundColor = Color4.FromColor3(newColor, 1.0);
-        this.props.globalState.onPreviewBackgroundChanged.notifyObservers();
-    }
-
     changeBackFaceCulling(value: boolean) {        
     changeBackFaceCulling(value: boolean) {        
         this.props.globalState.backFaceCulling = value;
         this.props.globalState.backFaceCulling = value;
         DataStorage.StoreBoolean("BackFaceCulling", value);
         DataStorage.StoreBoolean("BackFaceCulling", value);
@@ -63,30 +48,17 @@ export class PreviewAreaComponent extends React.Component<IPreviewAreaComponentP
                         </div>
                         </div>
                     }
                     }
                 </div>                
                 </div>                
-                <div id="preview-config-bar">
-                    <div                     
-                        title="Turn-table animation"
-                        onClick={() => this.changeAnimation()} className={"button"}>
-                        <FontAwesomeIcon icon={this.props.globalState.rotatePreview ? faStop : faPlay} />
-                    </div>
-                    <div 
-                        title="Background color"
-                        className={"button align"}>
-                        <label htmlFor="color-picker" id="color-picker-label">
-                            <FontAwesomeIcon icon={faPalette} />
-                        </label>
-                        <input ref="color-picker" id="color-picker" type="color" onChange={evt => this.changeBackground(evt.target.value)} />
-                    </div>                        
+                <div id="preview-config-bar">              
                     <div
                     <div
                         title="Render without back face culling"
                         title="Render without back face culling"
-                        onClick={() => this.changeBackFaceCulling(!this.props.globalState.backFaceCulling)} className={"button" + (!this.props.globalState.backFaceCulling ? " selected" : "")}>
-                        <FontAwesomeIcon icon={faCheckDouble} />
-                    </div>  
+                        onClick={() => this.changeBackFaceCulling(!this.props.globalState.backFaceCulling)} className={"button back-face" + (!this.props.globalState.backFaceCulling ? " selected" : "")}>
+                        <img src={DoubleSided} alt=""/>
+                    </div>
                     <div
                     <div
                         title="Render with depth pre-pass"
                         title="Render with depth pre-pass"
-                        onClick={() => this.changeDepthPrePass(!this.props.globalState.depthPrePass)} className={"button" + (this.props.globalState.depthPrePass ? " selected" : "")}>
-                        <FontAwesomeIcon icon={faClone} />
-                    </div>                     
+                        onClick={() => this.changeDepthPrePass(!this.props.globalState.depthPrePass)} className={"button depth-pass" + (this.props.globalState.depthPrePass ? " selected" : "")}>
+                            <img src={DepthPass} alt=""/>
+                    </div>
                     <div
                     <div
                         title="Turn on/off hemispheric light"  
                         title="Turn on/off hemispheric light"  
                         onClick={() => {
                         onClick={() => {
@@ -94,29 +66,30 @@ export class PreviewAreaComponent extends React.Component<IPreviewAreaComponentP
                             DataStorage.StoreBoolean("HemisphericLight", this.props.globalState.hemisphericLight);
                             DataStorage.StoreBoolean("HemisphericLight", this.props.globalState.hemisphericLight);
                             this.props.globalState.onLightUpdated.notifyObservers();
                             this.props.globalState.onLightUpdated.notifyObservers();
                             this.forceUpdate();
                             this.forceUpdate();
-                        }} className={"button" + (this.props.globalState.hemisphericLight ? " selected" : "")}>
-                        <FontAwesomeIcon icon={faSun} />
-                    </div>    
+                        }} className={"button hemispheric-light" + (this.props.globalState.hemisphericLight ? " selected" : "")}>
+                        <img src={Omni} alt=""/>
+                    </div>
                     <div
                     <div
-                        title="Turn on/off direction light #0"  
+                        title="Turn on/off direction light #1"  
                         onClick={() => {
                         onClick={() => {
-                            this.props.globalState.directionalLight0 = !this.props.globalState.directionalLight0;                       
-                            DataStorage.StoreBoolean("DirectionalLight0", this.props.globalState.directionalLight0);
+                            this.props.globalState.directionalLight1 = !this.props.globalState.directionalLight1;                       
+                            DataStorage.StoreBoolean("DirectionalLight1", this.props.globalState.directionalLight1);
                             this.props.globalState.onLightUpdated.notifyObservers();
                             this.props.globalState.onLightUpdated.notifyObservers();
                             this.forceUpdate();
                             this.forceUpdate();
-                        }} className={"button" + (this.props.globalState.directionalLight0 ? " selected" : "")}>
-                        <FontAwesomeIcon icon={faLocationArrow} />
-                    </div>      
+                        }} className={"button direction-light-1" + (this.props.globalState.directionalLight1 ? " selected" : "")}>
+                        <img src={DirectionalRight} alt=""/>
+
+                    </div>
                     <div
                     <div
-                        title="Turn on/off direction light #1"  
+                        title="Turn on/off direction light #0"  
                         onClick={() => {
                         onClick={() => {
-                            this.props.globalState.directionalLight1 = !this.props.globalState.directionalLight1;                       
-                            DataStorage.StoreBoolean("DirectionalLight1", this.props.globalState.directionalLight1);
+                            this.props.globalState.directionalLight0 = !this.props.globalState.directionalLight0;                       
+                            DataStorage.StoreBoolean("DirectionalLight0", this.props.globalState.directionalLight0);
                             this.props.globalState.onLightUpdated.notifyObservers();
                             this.props.globalState.onLightUpdated.notifyObservers();
                             this.forceUpdate();
                             this.forceUpdate();
-                        }} className={"button" + (this.props.globalState.directionalLight1 ? " selected" : "")}>
-                        <FontAwesomeIcon icon={faLocationArrow} />
-                    </div>               
+                        }} className={"button direction-light-0" + (this.props.globalState.directionalLight0 ? " selected" : "")}>
+                        <img src={DirectionalLeft} alt=""/>
+                    </div>
                 </div>
                 </div>
             </>
             </>
         );
         );

+ 53 - 7
nodeEditor/src/components/preview/previewMeshControlComponent.tsx

@@ -1,12 +1,15 @@
 
 
 import * as React from "react";
 import * as React from "react";
 import { GlobalState } from '../../globalState';
 import { GlobalState } from '../../globalState';
-import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
-import { faWindowRestore } from '@fortawesome/free-solid-svg-icons';
+import { Color3, Color4 } from 'babylonjs/Maths/math.color';
 import { PreviewMeshType } from './previewMeshType';
 import { PreviewMeshType } from './previewMeshType';
 import { DataStorage } from '../../dataStorage';
 import { DataStorage } from '../../dataStorage';
 import { OptionsLineComponent } from '../../sharedComponents/optionsLineComponent';
 import { OptionsLineComponent } from '../../sharedComponents/optionsLineComponent';
 import * as ReactDOM from 'react-dom';
 import * as ReactDOM from 'react-dom';
+import PopUpIcon from './svgs/popOut.svg';
+import ColorPicker from './svgs/colorPicker.svg';
+import PauseIcon from './svgs/pauseIcon.svg';
+import PlayIcon from './svgs/playIcon.svg';
 
 
 interface IPreviewMeshControlComponent {
 interface IPreviewMeshControlComponent {
     globalState: GlobalState;
     globalState: GlobalState;
@@ -14,6 +17,12 @@ interface IPreviewMeshControlComponent {
 }
 }
 
 
 export class PreviewMeshControlComponent extends React.Component<IPreviewMeshControlComponent> {
 export class PreviewMeshControlComponent extends React.Component<IPreviewMeshControlComponent> {
+    private colorInputRef: React.RefObject<HTMLInputElement>;
+
+    constructor(props: IPreviewMeshControlComponent) {
+        super(props);
+        this.colorInputRef = React.createRef();
+    }
 
 
     changeMeshType(newOne: PreviewMeshType) {
     changeMeshType(newOne: PreviewMeshType) {
         if (this.props.globalState.previewMeshType === newOne) {
         if (this.props.globalState.previewMeshType === newOne) {
@@ -45,6 +54,28 @@ export class PreviewMeshControlComponent extends React.Component<IPreviewMeshCon
         this.props.togglePreviewAreaComponent();
         this.props.togglePreviewAreaComponent();
     }
     }
 
 
+    changeAnimation() {
+        this.props.globalState.rotatePreview = !this.props.globalState.rotatePreview;
+        this.props.globalState.onAnimationCommandActivated.notifyObservers();
+        this.forceUpdate();
+    }
+
+    changeBackground(value: string) {
+        const newColor = Color3.FromHexString(value);
+
+        DataStorage.StoreNumber("BackgroundColorR", newColor.r);
+        DataStorage.StoreNumber("BackgroundColorG", newColor.g);
+        DataStorage.StoreNumber("BackgroundColorB", newColor.b);
+
+        const newBackgroundColor = Color4.FromColor3(newColor, 1.0);
+        this.props.globalState.backgroundColor = newBackgroundColor;
+        this.props.globalState.onPreviewBackgroundChanged.notifyObservers();
+    }
+
+    changeBackgroundClick() {
+        this.colorInputRef.current?.click();
+    }
+
     render() {
     render() {
 
 
         var meshTypeOptions = [
         var meshTypeOptions = [
@@ -73,19 +104,34 @@ export class PreviewMeshControlComponent extends React.Component<IPreviewMeshCon
                                 } else {
                                 } else {
                                     (ReactDOM.findDOMNode(this.refs["file-picker"]) as HTMLElement).click();
                                     (ReactDOM.findDOMNode(this.refs["file-picker"]) as HTMLElement).click();
                                 }
                                 }
-                            }} />    
+                            }} />
                 <div style={{
                 <div style={{
                     display: "none"
                     display: "none"
                 }} title="Preview with a custom mesh" >
                 }} title="Preview with a custom mesh" >
                     <input ref="file-picker" id="file-picker" type="file" onChange={evt => this.useCustomMesh(evt)} accept=".gltf, .glb, .babylon, .obj"/>
                     <input ref="file-picker" id="file-picker" type="file" onChange={evt => this.useCustomMesh(evt)} accept=".gltf, .glb, .babylon, .obj"/>
                 </div>
                 </div>
                 <div
                 <div
+                    title="Turn-table animation"
+                    onClick={() => this.changeAnimation()} className="button" id="play-button">
+                    {this.props.globalState.rotatePreview ? <img src={PauseIcon} alt=""/> : <img src={PlayIcon} alt=""/>}
+                </div>
+                <div 
+                id="color-picker-button"
+                    title="Background color"
+                    className={"button align"}
+                    onClick={_ => this.changeBackgroundClick()}
+                    >
+                    <img src={ColorPicker} alt=""/>
+                    <label htmlFor="color-picker" id="color-picker-label">
+                    </label>
+                    <input ref={this.colorInputRef} id="color-picker" type="color" onChange={evt => this.changeBackground(evt.target.value)} />
+                </div>
+                <div
                     title="Open preview in new window" id="preview-new-window"
                     title="Open preview in new window" id="preview-new-window"
-                    onClick={() => this.onPopUp()} className="button expand">
-                    <FontAwesomeIcon icon={faWindowRestore} />
-                </div>                          
+                    onClick={() => this.onPopUp()} className="button">
+                    <img src={PopUpIcon} alt=""/>
+                </div>
             </div>
             </div>
         );
         );
-
     }
     }
 }
 }

文件差異過大導致無法顯示
+ 1 - 0
nodeEditor/src/components/preview/svgs/colorPicker.svg


+ 1 - 0
nodeEditor/src/components/preview/svgs/depthPass.svg

@@ -0,0 +1 @@
+<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 40 40"><defs><style>.cls-1{fill:#fff;}</style></defs><title>depthPass</title><g id="UI_Elements" data-name="UI Elements"><polygon class="cls-1" points="22.03 16.16 19.89 12.45 11.74 26.56 16.03 26.56 22.03 16.16"/><polygon class="cls-1" points="17.53 13.54 15.38 9.82 7.24 23.93 11.52 23.93 17.53 13.54"/><polygon class="cls-1" points="24.39 15.07 16.24 29.18 32.54 29.18 24.39 15.07"/></g></svg>

+ 1 - 0
nodeEditor/src/components/preview/svgs/directionalLeft.svg

@@ -0,0 +1 @@
+<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 40 40"><defs><style>.cls-1{fill:#fff;}</style></defs><title>directionalLeft</title><g id="UI_Elements" data-name="UI Elements"><polygon class="cls-1" points="27.89 22.51 27.89 28.12 21.52 21.75 25.61 17.66 11.27 10.81 10.01 12.07 16.86 26.41 20.74 22.53 27.11 28.9 21.5 28.9 21.5 30.01 29 30.01 29 22.51 27.89 22.51"/></g></svg>

+ 1 - 0
nodeEditor/src/components/preview/svgs/directionalRight.svg

@@ -0,0 +1 @@
+<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 40 40"><defs><style>.cls-1{fill:#fff;}</style></defs><title>directionalRight</title><g id="UI_Elements" data-name="UI Elements"><polygon class="cls-1" points="23.14 26.41 29.99 12.07 28.73 10.81 14.39 17.66 18.48 21.75 12.11 28.12 12.11 22.51 11 22.51 11 30.01 18.5 30.01 18.5 28.9 12.89 28.9 19.26 22.53 23.14 26.41"/></g></svg>

+ 1 - 0
nodeEditor/src/components/preview/svgs/doubleSided.svg

@@ -0,0 +1 @@
+<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 40 40"><defs><style>.cls-1{fill:#fff;}</style></defs><title>doubeSided</title><g id="UI_Elements" data-name="UI Elements"><polygon class="cls-1" points="27.3 14.7 26.52 15.48 30.48 19.44 21.33 19.44 21.33 11.15 18.65 11.15 18.65 19.44 9.52 19.44 13.48 15.48 12.7 14.7 7.39 20 12.7 25.3 13.48 24.52 9.52 20.56 18.65 20.56 18.65 28.85 21.33 28.85 21.33 20.56 30.48 20.56 26.52 24.52 27.3 25.3 32.61 20 27.3 14.7"/></g></svg>

+ 1 - 0
nodeEditor/src/components/preview/svgs/omni.svg

@@ -0,0 +1 @@
+<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 40 40"><defs><style>.cls-1{fill:#fff;}</style></defs><title>omni</title><g id="UI_Elements" data-name="UI Elements"><path class="cls-1" d="M26.22,20A6.22,6.22,0,1,1,20,13.78,6.23,6.23,0,0,1,26.22,20ZM11.51,17.6,9.11,20l2.4,2.4Zm.79,6.71V27.7h3.39Zm5.3,4.18,2.4,2.4,2.4-2.4Zm6.71-.79H27.7V24.31Zm4.18-5.3,2.4-2.4-2.4-2.4Zm-.79-6.71V12.3H24.31Zm-5.3-4.18L20,9.11l-2.4,2.4Zm-6.71.79H12.3v3.39Z"/></g></svg>

+ 1 - 0
nodeEditor/src/components/preview/svgs/pauseIcon.svg

@@ -0,0 +1 @@
+<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 40 40"><defs><style>.cls-1{fill:#fff;}</style></defs><title>pauseIcon</title><g id="UI_Elements" data-name="UI Elements"><path class="cls-1" d="M17,28H13V12h4Zm9-16H22V28h4Z"/></g></svg>

+ 1 - 0
nodeEditor/src/components/preview/svgs/playIcon.svg

@@ -0,0 +1 @@
+<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 40 40"><defs><style>.cls-1{fill:#fff;}</style></defs><title>playIcon</title><g id="UI_Elements" data-name="UI Elements"><polygon class="cls-1" points="12.99 9.98 12.99 28.04 29 19 12.99 9.98"/></g></svg>

+ 1 - 0
nodeEditor/src/components/preview/svgs/popOut.svg

@@ -0,0 +1 @@
+<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 40 40"><defs><style>.cls-1{fill:#fff;}</style></defs><title>popOut</title><g id="UI_Elements" data-name="UI Elements"><path class="cls-1" d="M10.5,10.5v19h19v-19Zm18,18H20V20H11.5V11.5h17Z"/></g></svg>

+ 4 - 0
nodeEditor/src/components/propertyTab/propertyTab.scss

@@ -524,6 +524,10 @@
                 align-items: center;
                 align-items: center;
                 justify-items: center;
                 justify-items: center;
                 cursor: pointer;
                 cursor: pointer;
+                
+                img {
+                    height: 100%;
+                }
             }
             }
 
 
             .expand {
             .expand {

+ 2 - 1
nodeEditor/src/diagram/graphCanvas.tsx

@@ -1,6 +1,7 @@
 import * as React from "react";
 import * as React from "react";
 import { GlobalState } from '../globalState';
 import { GlobalState } from '../globalState';
 import { NodeMaterialBlock } from 'babylonjs/Materials/Node/nodeMaterialBlock';
 import { NodeMaterialBlock } from 'babylonjs/Materials/Node/nodeMaterialBlock';
+import { NodeMaterialBlockConnectionPointTypes } from 'babylonjs/Materials/Node/Enums/nodeMaterialBlockConnectionPointTypes';
 import { GraphNode } from './graphNode';
 import { GraphNode } from './graphNode';
 import * as dagre from 'dagre';
 import * as dagre from 'dagre';
 import { Nullable } from 'babylonjs/types';
 import { Nullable } from 'babylonjs/types';
@@ -687,7 +688,7 @@ export class GraphCanvasComponent extends React.Component<IGraphCanvasComponentP
             }
             }
 
 
             // No destination so let's spin a new input block
             // No destination so let's spin a new input block
-            let inputBlock = new InputBlock("", undefined, this._candidateLink!.portA.connectionPoint.type);
+            let inputBlock = new InputBlock(NodeMaterialBlockConnectionPointTypes[this._candidateLink!.portA.connectionPoint.type], undefined, this._candidateLink!.portA.connectionPoint.type);
             pointA = inputBlock.output;
             pointA = inputBlock.output;
             nodeA = this.appendBlock(inputBlock);
             nodeA = this.appendBlock(inputBlock);
             
             

+ 3 - 3
nodeEditor/src/globalState.ts

@@ -63,9 +63,9 @@ export class GlobalState {
         this.directionalLight1 = DataStorage.ReadBoolean("DirectionalLight1", false);
         this.directionalLight1 = DataStorage.ReadBoolean("DirectionalLight1", false);
         this.controlCamera = DataStorage.ReadBoolean("ControlCamera", true);
         this.controlCamera = DataStorage.ReadBoolean("ControlCamera", true);
 
 
-        let r = DataStorage.ReadNumber("BackgroundColorR", 0.37);
-        let g = DataStorage.ReadNumber("BackgroundColorG", 0.37);
-        let b = DataStorage.ReadNumber("BackgroundColorB", 0.37);
+        let r = DataStorage.ReadNumber("BackgroundColorR", 32);
+        let g = DataStorage.ReadNumber("BackgroundColorG", 25);
+        let b = DataStorage.ReadNumber("BackgroundColorB", 64);
         this.backgroundColor = new Color4(r, g, b, 1.0);
         this.backgroundColor = new Color4(r, g, b, 1.0);
     }
     }
 }
 }

+ 17 - 9
nodeEditor/src/graphEditor.tsx

@@ -638,8 +638,8 @@ export class GraphEditor extends React.Component<IGraphEditorProps, IGraphEditor
         parentControl.style.height = "100%";
         parentControl.style.height = "100%";
         parentControl.style.margin = "0";
         parentControl.style.margin = "0";
         parentControl.style.padding = "0";
         parentControl.style.padding = "0";
-        parentControl.style.display = "block";
-        parentControl.style.gridTemplateRows = "unset";
+        parentControl.style.display = "grid";
+        parentControl.style.gridTemplateRows = "40px auto";
         parentControl.id = 'node-editor-graph-root';
         parentControl.id = 'node-editor-graph-root';
         parentControl.className = 'right-panel';
         parentControl.className = 'right-panel';
 
 
@@ -671,9 +671,7 @@ export class GraphEditor extends React.Component<IGraphEditorProps, IGraphEditor
                     const newStyleEl = sourceDoc.createElement('style');
                     const newStyleEl = sourceDoc.createElement('style');
 
 
                     for (var cssRule of styleSheet.cssRules) {
                     for (var cssRule of styleSheet.cssRules) {
-                        if (cssRule.selectorText !== '.right-panel #preview-config-bar .button') { // skip css grid layout rules
-                            newStyleEl.appendChild(sourceDoc.createTextNode(cssRule.cssText));
-                        }
+                        newStyleEl.appendChild(sourceDoc.createTextNode(cssRule.cssText));
                     }
                     }
 
 
                     targetDoc.head!.appendChild(newStyleEl);
                     targetDoc.head!.appendChild(newStyleEl);
@@ -688,12 +686,11 @@ export class GraphEditor extends React.Component<IGraphEditorProps, IGraphEditor
     createPreviewMeshControlHost = (options: IInternalPreviewAreaOptions, parentControl: Nullable<HTMLElement>) => {
     createPreviewMeshControlHost = (options: IInternalPreviewAreaOptions, parentControl: Nullable<HTMLElement>) => {
         // Prepare the preview control host
         // Prepare the preview control host
         if (parentControl) {
         if (parentControl) {
+
             const host = parentControl.ownerDocument!.createElement("div");
             const host = parentControl.ownerDocument!.createElement("div");
 
 
             host.id = "PreviewMeshControl-host";
             host.id = "PreviewMeshControl-host";
             host.style.width = options.embedHostWidth || "auto";
             host.style.width = options.embedHostWidth || "auto";
-            host.style.display = "block";
-            host.style.height = "30px";
 
 
             parentControl.appendChild(host);
             parentControl.appendChild(host);
             const PreviewMeshControlComponentHost = React.createElement(PreviewMeshControlComponent, {
             const PreviewMeshControlComponentHost = React.createElement(PreviewMeshControlComponent, {
@@ -711,7 +708,9 @@ export class GraphEditor extends React.Component<IGraphEditorProps, IGraphEditor
 
 
             host.id = "PreviewAreaComponent-host";
             host.id = "PreviewAreaComponent-host";
             host.style.width = options.embedHostWidth || "auto";
             host.style.width = options.embedHostWidth || "auto";
-            host.style.display = "block";
+            host.style.display = "grid";
+            host.style.gridRow = '2';
+            host.style.gridTemplateRows = "auto 40px";
 
 
             parentControl.appendChild(host);
             parentControl.appendChild(host);
 
 
@@ -734,12 +733,21 @@ export class GraphEditor extends React.Component<IGraphEditorProps, IGraphEditor
     fixPopUpStyles = (document: Document) => {
     fixPopUpStyles = (document: Document) => {
         const previewContainer = document.getElementById("preview");
         const previewContainer = document.getElementById("preview");
         if (previewContainer) {
         if (previewContainer) {
-            previewContainer.style.height = "calc(100% - 60px)";
+            previewContainer.style.height = "auto";
+            previewContainer.style.gridRow = "1";
+        }
+        const previewConfigBar = document.getElementById("preview-config-bar");
+        if (previewConfigBar) {
+            previewConfigBar.style.gridRow = "2";
         }
         }
         const newWindowButton = document.getElementById('preview-new-window');
         const newWindowButton = document.getElementById('preview-new-window');
         if (newWindowButton) {
         if (newWindowButton) {
             newWindowButton.style.display = 'none';
             newWindowButton.style.display = 'none';
         }
         }
+        const previewMeshBar = document.getElementById('preview-mesh-bar');
+        if (previewMeshBar) {
+            previewMeshBar.style.gridTemplateColumns = "auto 1fr 40px 40px";
+        }
     }
     }
 
 
     render() {
     render() {

+ 96 - 18
nodeEditor/src/main.scss

@@ -61,7 +61,7 @@
     grid-row: 1 / span 2;
     grid-row: 1 / span 2;
     grid-column: 5;
     grid-column: 5;
     display: grid;
     display: grid;
-    grid-template-rows: 1fr 30px auto 30px;
+    grid-template-rows: 1fr 40px auto 40px;
     grid-template-columns: 100%;
     grid-template-columns: 100%;
     height: 100%;
     height: 100%;
     overflow-y: auto;
     overflow-y: auto;
@@ -75,7 +75,7 @@
         display: grid;
         display: grid;
         justify-content: center;
         justify-content: center;
         align-content: center;
         align-content: center;
-        height: 30px;
+        height: auto;
         width: calc(100% / 7);
         width: calc(100% / 7);
         cursor: pointer;
         cursor: pointer;
 
 
@@ -100,10 +100,10 @@
         grid-row: 2;
         grid-row: 2;
         grid-column: 1;
         grid-column: 1;
         display: grid;
         display: grid;
-        grid-template-columns: auto 1fr 40px;
-        color: white;
+        grid-template-columns: auto 1fr 40px 40px 40px;
         align-items: center;
         align-items: center;
-        font-size: 18px;  
+        font-size: 18px;
+        background-color: #555555;
 
 
         #file-picker {
         #file-picker {
             display: none;
             display: none;
@@ -111,7 +111,7 @@
 
 
         .listLine {
         .listLine {
             grid-column: 1;
             grid-column: 1;
-            height: 30px;
+            height: 40px;
             display: grid;
             display: grid;
             grid-template-columns: 0px 1fr;  
             grid-template-columns: 0px 1fr;  
     
     
@@ -135,33 +135,111 @@
             } 
             } 
         }
         }
 
 
-        .expand {
+        .button{
+            color: #ffffff;
             width: 40px;
             width: 40px;
+            height: 40px;
+            transform-origin: 50% 50%;
+            
+            &:active {
+                transform: scale(0.90);
+            }
+
+            &:hover {
+                background: #3f3461;
+            }
+            
+            &.selected {
+                background: #9379e6;
+            } 
+
+            img{
+                height: 40px;
+                width: 100%;
+            }
+        }
+
+
+        #play-button {
             grid-column: 3;
             grid-column: 3;
         }
         }
+
+        #color-picker-button {
+            grid-column: 4;
+
+            #color-picker {
+                display: none;
+            }
+
+            #color-picker-label {
+                width: 100%;
+                background: transparent;
+                cursor: pointer;            
+            }
+        }
+
+        #preview-new-window {
+            grid-column: 5;
+        }
+
+        select {
+            background-color: #a3a3a3;
+            color: #333333;
+        }
     }
     }
 
 
     #preview-config-bar {
     #preview-config-bar {
         grid-row: 4;
         grid-row: 4;
         grid-column: 1;
         grid-column: 1;
-        display: flex;
-        flex-direction: row-reverse;
+        display: grid;
+        grid-template-columns: 40px 40px 40px 1fr 40px 40px;
         color: white;
         color: white;
         align-items: center;
         align-items: center;
         font-size: 18px;    
         font-size: 18px;    
 
 
         .button {
         .button {
-            width: 60px;
-        }
+            width: 40px;
+            grid-row: 1;
+            height: 40px;
+            transform-origin: 50% 50%;
 
 
-        #color-picker {
-            display: none;
-        }
+            &:hover {
+                background: #3f3461;
+            }
 
 
-        #color-picker-label {
-            width: 100%;
-            background: transparent;
-            cursor: pointer;            
+            &.selected {
+                background: #9379e6;
+            } 
+            
+
+            &:active {
+                transform: scale(0.90);
+            }
+
+            img{
+                height: auto;
+                width: 100%;
+            }
+
+            &.back-face {
+                grid-column: 6
+            }
+
+            &.depth-pass {
+                grid-column: 5 / 6
+            }
+
+            &.hemispheric-light{
+                grid-column: 3 / 4
+            }
+            &.direction-light-1{
+                grid-column: 2 / 3
+
+            }
+            &.direction-light-0{
+                grid-column: 1 / 2
+                
+            }
         }
         }
     }
     }
     
     

+ 3 - 2
nodeEditor/src/sharedComponents/color3LineComponent.tsx

@@ -4,8 +4,9 @@ import { Color3, Color4 } from "babylonjs/Maths/math";
 import { PropertyChangedEvent } from "./propertyChangedEvent";
 import { PropertyChangedEvent } from "./propertyChangedEvent";
 import { NumericInputComponent } from "./numericInputComponent";
 import { NumericInputComponent } from "./numericInputComponent";
 import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
 import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
-import { faMinus, faPlus, faCopy } from "@fortawesome/free-solid-svg-icons";
+import { faMinus, faPlus } from "@fortawesome/free-solid-svg-icons";
 import { GlobalState } from '../globalState';
 import { GlobalState } from '../globalState';
+import CopyIcon from "./copy.svg";
 
 
 export interface IColor3LineComponentProps {
 export interface IColor3LineComponentProps {
     label: string;
     label: string;
@@ -149,7 +150,7 @@ export class Color3LineComponent extends React.Component<IColor3LineComponentPro
                         <input type="color" value={colorAsColor3.toHexString()} onChange={(evt) => this.onChange(evt.target.value)} />
                         <input type="color" value={colorAsColor3.toHexString()} onChange={(evt) => this.onChange(evt.target.value)} />
                     </div>
                     </div>
                     <div className="copy hoverIcon" onClick={() => this.copyToClipboard()} title="Copy to clipboard">
                     <div className="copy hoverIcon" onClick={() => this.copyToClipboard()} title="Copy to clipboard">
-                        <FontAwesomeIcon icon={faCopy} />
+                        <img src={CopyIcon} alt=""/>
                     </div>
                     </div>
                     <div className="expand hoverIcon" onClick={() => this.switchExpandState()} title="Expand">
                     <div className="expand hoverIcon" onClick={() => this.switchExpandState()} title="Expand">
                         {chevron}
                         {chevron}

+ 4 - 2
nodeEditor/src/sharedComponents/color4LineComponent.tsx

@@ -4,8 +4,10 @@ import { Color3, Color4 } from "babylonjs/Maths/math";
 import { PropertyChangedEvent } from "./propertyChangedEvent";
 import { PropertyChangedEvent } from "./propertyChangedEvent";
 import { NumericInputComponent } from "./numericInputComponent";
 import { NumericInputComponent } from "./numericInputComponent";
 import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
 import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
-import { faMinus, faPlus, faCopy } from "@fortawesome/free-solid-svg-icons";
+import { faMinus, faPlus } from "@fortawesome/free-solid-svg-icons";
 import { GlobalState } from '../globalState';
 import { GlobalState } from '../globalState';
+import CopyIcon from "./copy.svg";
+
 
 
 export interface IColor4LineComponentProps {
 export interface IColor4LineComponentProps {
     label: string;
     label: string;
@@ -160,7 +162,7 @@ export class Color4LineComponent extends React.Component<IColor4LineComponentPro
                         <input type="color" value={colorAsColor3.toHexString()} onChange={(evt) => this.onChange(evt.target.value)} />
                         <input type="color" value={colorAsColor3.toHexString()} onChange={(evt) => this.onChange(evt.target.value)} />
                     </div>
                     </div>
                     <div className="copy hoverIcon" onClick={() => this.copyToClipboard()} title="Copy to clipboard">
                     <div className="copy hoverIcon" onClick={() => this.copyToClipboard()} title="Copy to clipboard">
-                        <FontAwesomeIcon icon={faCopy} />
+                        <img src={CopyIcon} alt=""/>
                     </div>
                     </div>
                     <div className="expand hoverIcon" onClick={() => this.switchExpandState()} title="Expand">
                     <div className="expand hoverIcon" onClick={() => this.switchExpandState()} title="Expand">
                         {chevron}
                         {chevron}

+ 1 - 0
nodeEditor/src/sharedComponents/copy.svg

@@ -0,0 +1 @@
+<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 40 40"><defs><style>.cls-1{fill:#fff;}</style></defs><title>copy</title><g id="UI_Elements" data-name="UI Elements"><path class="cls-1" d="M24,14.89H22.76l-3-3H12.43V26.59h4.26v3h11.5V19Zm.3,1.71,2.14,2.13H24.34Zm-10.91,9V12.93h5.93l2,2H16.69v10.7Zm4.26,3V15.89h5.65v3.84h3.85v8.83Z"/></g></svg>

+ 5 - 2
nodeEditor/tsconfig.json

@@ -24,5 +24,8 @@
     },
     },
     "exclude": [
     "exclude": [
         "../../inspector"
         "../../inspector"
-    ]
-}
+    ],
+    "files": [ 
+        "./custom.d.ts" 
+      ]  
+}

+ 12 - 1
nodeEditor/webpack.config.js

@@ -20,7 +20,18 @@ var config = babylonWebpackConfig({
         {
         {
             test: /\.css$/,
             test: /\.css$/,
             use: ['style-loader', 'css-loader']
             use: ['style-loader', 'css-loader']
-        }],
+        },
+    {
+        test: /\.svg$/,
+        use: [
+          {
+            loader: 'svg-url-loader',
+            options: {
+              limit: 10000,
+            },
+          },
+        ],
+      }],
     plugins: [
     plugins: [
         new MiniCssExtractPlugin({
         new MiniCssExtractPlugin({
             // Options similar to the same options in webpackOptions.output
             // Options similar to the same options in webpackOptions.output

+ 3 - 2
package.json

@@ -92,12 +92,13 @@
         "sinon": "^6.1.4",
         "sinon": "^6.1.4",
         "split.js": "^1.5.9",
         "split.js": "^1.5.9",
         "style-loader": "^0.21.0",
         "style-loader": "^0.21.0",
+        "svg-url-loader": "^4.0.0",
         "through2": "~2.0.3",
         "through2": "~2.0.3",
         "ts-loader": "^5.2.1",
         "ts-loader": "^5.2.1",
         "tslib": "^1.10.0",
         "tslib": "^1.10.0",
         "tslint": "^5.11.0",
         "tslint": "^5.11.0",
         "typedoc": "^0.15.4",
         "typedoc": "^0.15.4",
-        "typescript": "~3.7.3",
+        "typescript": "~3.7.5",
         "webpack": "^4.29.3",
         "webpack": "^4.29.3",
         "webpack-bundle-analyzer": "^3.1.0",
         "webpack-bundle-analyzer": "^3.1.0",
         "webpack-cli": "^3.3.9",
         "webpack-cli": "^3.3.9",
@@ -106,4 +107,4 @@
         "xhr2": "^0.1.4",
         "xhr2": "^0.1.4",
         "xmlbuilder": "8.2.2"
         "xmlbuilder": "8.2.2"
     }
     }
-}
+}

+ 1 - 0
sandbox/debug.html

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

+ 1 - 0
sandbox/index-local.html

@@ -10,6 +10,7 @@
     <script src="../dist/preview%20release/ammo.js"></script>
     <script src="../dist/preview%20release/ammo.js"></script>
     <script src="../dist/preview%20release/cannon.js"></script>
     <script src="../dist/preview%20release/cannon.js"></script>
     <script src="../dist/preview%20release/Oimo.js"></script>
     <script src="../dist/preview%20release/Oimo.js"></script>
+    <script src="../dist/preview%20release/libktx.js"></script>
     <script src="../Tools/DevLoader/BabylonLoader.js"></script>
     <script src="../Tools/DevLoader/BabylonLoader.js"></script>
 </head>
 </head>
 
 

+ 1 - 0
sandbox/index.html

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

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

@@ -33,12 +33,11 @@ declare module "../../Engines/thinEngine" {
          * @param lodScale defines the scale applied to environment texture. This manages the range of LOD level used for IBL according to the roughness
          * @param lodScale defines the scale applied to environment texture. This manages the range of LOD level used for IBL according to the roughness
          * @param lodOffset defines the offset applied to environment texture. This manages first LOD level used for IBL according to the roughness
          * @param lodOffset defines the offset applied to environment texture. This manages first LOD level used for IBL according to the roughness
          * @param fallback defines texture to use while falling back when (compressed) texture file not found.
          * @param fallback defines texture to use while falling back when (compressed) texture file not found.
-         * @param excludeLoaders array of texture loaders that should be excluded when picking a loader for the texture (defualt: empty array)
          * @returns the cube texture as an InternalTexture
          * @returns the cube texture as an InternalTexture
          */
          */
         createCubeTexture(rootUrl: string, scene: Nullable<Scene>, files: Nullable<string[]>, noMipmap: boolean | undefined,
         createCubeTexture(rootUrl: string, scene: Nullable<Scene>, files: Nullable<string[]>, noMipmap: boolean | undefined,
             onLoad: Nullable<(data?: any) => void>, onError: Nullable<(message?: string, exception?: any) => void>,
             onLoad: Nullable<(data?: any) => void>, onError: Nullable<(message?: string, exception?: any) => void>,
-            format: number | undefined, forcedExtension: any, createPolynomials: boolean, lodScale: number, lodOffset: number, fallback: Nullable<InternalTexture>, excludeLoaders: Array<IInternalTextureLoader>): InternalTexture;
+            format: number | undefined, forcedExtension: any, createPolynomials: boolean, lodScale: number, lodOffset: number, fallback: Nullable<InternalTexture>): InternalTexture;
 
 
         /**
         /**
          * Creates a cube texture
          * Creates a cube texture
@@ -216,7 +215,7 @@ ThinEngine.prototype._setCubeMapTextureParams = function(loadMipmap: boolean): v
     this._bindTextureDirectly(gl.TEXTURE_CUBE_MAP, null);
     this._bindTextureDirectly(gl.TEXTURE_CUBE_MAP, null);
 };
 };
 
 
-ThinEngine.prototype.createCubeTexture = function(rootUrl: string, scene: Nullable<Scene>, files: Nullable<string[]>, noMipmap?: boolean, onLoad: Nullable<(data?: any) => void> = null, onError: Nullable<(message?: string, exception?: any) => void> = null, format?: number, forcedExtension: any = null, createPolynomials: boolean = false, lodScale: number = 0, lodOffset: number = 0, fallback: Nullable<InternalTexture> = null, excludeLoaders: Array<IInternalTextureLoader> = []): InternalTexture {
+ThinEngine.prototype.createCubeTexture = function(rootUrl: string, scene: Nullable<Scene>, files: Nullable<string[]>, noMipmap?: boolean, onLoad: Nullable<(data?: any) => void> = null, onError: Nullable<(message?: string, exception?: any) => void> = null, format?: number, forcedExtension: any = null, createPolynomials: boolean = false, lodScale: number = 0, lodOffset: number = 0, fallback: Nullable<InternalTexture> = null): InternalTexture {
     var gl = this._gl;
     var gl = this._gl;
 
 
     var texture = fallback ? fallback : new InternalTexture(this, InternalTextureSource.Cube);
     var texture = fallback ? fallback : new InternalTexture(this, InternalTextureSource.Cube);
@@ -233,35 +232,22 @@ ThinEngine.prototype.createCubeTexture = function(rootUrl: string, scene: Nullab
 
 
     var lastDot = rootUrl.lastIndexOf('.');
     var lastDot = rootUrl.lastIndexOf('.');
     var extension = forcedExtension ? forcedExtension : (lastDot > -1 ? rootUrl.substring(lastDot).toLowerCase() : "");
     var extension = forcedExtension ? forcedExtension : (lastDot > -1 ? rootUrl.substring(lastDot).toLowerCase() : "");
-    const filteredFormat: Nullable<string> = this.excludedCompressedTextureFormats(rootUrl, this._textureFormatInUse);
 
 
     let loader: Nullable<IInternalTextureLoader> = null;
     let loader: Nullable<IInternalTextureLoader> = null;
     for (let availableLoader of ThinEngine._TextureLoaders) {
     for (let availableLoader of ThinEngine._TextureLoaders) {
-        if (excludeLoaders.indexOf(availableLoader) === -1 && availableLoader.canLoad(extension, filteredFormat, fallback, false, false)) {
+        if (availableLoader.canLoad(extension)) {
             loader = availableLoader;
             loader = availableLoader;
             break;
             break;
         }
         }
     }
     }
 
 
     let onInternalError = (request?: IWebRequest, exception?: any) => {
     let onInternalError = (request?: IWebRequest, exception?: any) => {
-        if (loader) {
-            const fallbackUrl = loader.getFallbackTextureUrl(texture.url, this._textureFormatInUse);
-            Logger.Warn((loader.constructor as any).name + " failed when trying to load " + texture.url + ", falling back to the next supported loader");
-            if (fallbackUrl) {
-                excludeLoaders.push(loader);
-                this.createCubeTexture(fallbackUrl, scene, files, noMipmap, onLoad, onError, format, extension, createPolynomials, lodScale, lodOffset, texture, excludeLoaders);
-                return;
-            }
-        }
-
         if (onError && request) {
         if (onError && request) {
             onError(request.status + " " + request.statusText, exception);
             onError(request.status + " " + request.statusText, exception);
         }
         }
     };
     };
 
 
     if (loader) {
     if (loader) {
-        rootUrl = loader.transformUrl(rootUrl, filteredFormat);
-
         const onloaddata = (data: ArrayBufferView | ArrayBufferView[]) => {
         const onloaddata = (data: ArrayBufferView | ArrayBufferView[]) => {
             this._bindTextureDirectly(gl.TEXTURE_CUBE_MAP, texture, true);
             this._bindTextureDirectly(gl.TEXTURE_CUBE_MAP, texture, true);
             loader!.loadCubeData(data, texture, createPolynomials, onLoad, onError);
             loader!.loadCubeData(data, texture, createPolynomials, onLoad, onError);

+ 0 - 44
src/Engines/engine.ts

@@ -1339,50 +1339,6 @@ export class Engine extends ThinEngine {
     }
     }
 
 
     /**
     /**
-     * Set the compressed texture format to use, based on the formats you have, and the formats
-     * supported by the hardware / browser.
-     *
-     * Khronos Texture Container (.ktx) files are used to support this.  This format has the
-     * advantage of being specifically designed for OpenGL.  Header elements directly correspond
-     * to API arguments needed to compressed textures.  This puts the burden on the container
-     * generator to house the arcane code for determining these for current & future formats.
-     *
-     * for description see https://www.khronos.org/opengles/sdk/tools/KTX/
-     * for file layout see https://www.khronos.org/opengles/sdk/tools/KTX/file_format_spec/
-     *
-     * Note: The result of this call is not taken into account when a texture is base64.
-     *
-     * @param formatsAvailable defines the list of those format families you have created
-     * on your server.  Syntax: '-' + format family + '.ktx'.  (Case and order do not matter.)
-     *
-     * Current families are astc, dxt, pvrtc, etc2, & etc1.
-     * @returns The extension selected.
-     */
-    public setTextureFormatToUse(formatsAvailable: Array<string>): Nullable<string> {
-        for (var i = 0, len1 = this.texturesSupported.length; i < len1; i++) {
-            for (var j = 0, len2 = formatsAvailable.length; j < len2; j++) {
-                if (this._texturesSupported[i] === formatsAvailable[j].toLowerCase()) {
-                    return this._textureFormatInUse = this._texturesSupported[i];
-                }
-            }
-        }
-        // actively set format to nothing, to allow this to be called more than once
-        // and possibly fail the 2nd time
-        this._textureFormatInUse = null;
-        return null;
-    }
-
-    /**
-     * Set the compressed texture extensions or file names to skip.
-     *
-     * @param skippedFiles defines the list of those texture files you want to skip
-     * Example: [".dds", ".env", "myfile.png"]
-     */
-    public setCompressedTextureExclusions(skippedFiles: Array<string>): void {
-        this._excludedCompressedTextures = skippedFiles;
-    }
-
-    /**
      * Force a specific size of the canvas
      * Force a specific size of the canvas
      * @param width defines the new canvas' width
      * @param width defines the new canvas' width
      * @param height defines the new canvas' height
      * @param height defines the new canvas' height

+ 15 - 42
src/Engines/nativeEngine.ts

@@ -21,7 +21,7 @@ import { WebRequest } from '../Misc/webRequest';
 import { NativeShaderProcessor } from './Native/nativeShaderProcessor';
 import { NativeShaderProcessor } from './Native/nativeShaderProcessor';
 import { Logger } from "../Misc/logger";
 import { Logger } from "../Misc/logger";
 import { Constants } from './constants';
 import { Constants } from './constants';
-import { ThinEngine } from './thinEngine';
+import { ThinEngine, ISceneLike } from './thinEngine';
 import { IWebRequest } from '../Misc/interfaces/iWebRequest';
 import { IWebRequest } from '../Misc/interfaces/iWebRequest';
 
 
 interface INativeEngine {
 interface INativeEngine {
@@ -840,40 +840,32 @@ export class NativeEngine extends Engine {
 
 
     // TODO: Refactor to share more logic with babylon.engine.ts version.
     // TODO: Refactor to share more logic with babylon.engine.ts version.
     /**
     /**
-     * Usually called from BABYLON.Texture.ts.
+     * Usually called from Texture.ts.
      * Passed information to create a WebGLTexture
      * Passed information to create a WebGLTexture
      * @param urlArg defines a value which contains one of the following:
      * @param urlArg defines a value which contains one of the following:
      * * A conventional http URL, e.g. 'http://...' or 'file://...'
      * * A conventional http URL, e.g. 'http://...' or 'file://...'
      * * A base64 string of in-line texture data, e.g. 'data:image/jpg;base64,/...'
      * * A base64 string of in-line texture data, e.g. 'data:image/jpg;base64,/...'
      * * An indicator that data being passed using the buffer parameter, e.g. 'data:mytexture.jpg'
      * * An indicator that data being passed using the buffer parameter, e.g. 'data:mytexture.jpg'
      * @param noMipmap defines a boolean indicating that no mipmaps shall be generated.  Ignored for compressed textures.  They must be in the file
      * @param noMipmap defines a boolean indicating that no mipmaps shall be generated.  Ignored for compressed textures.  They must be in the file
-     * @param invertY when true, image is flipped when loaded.  You probably want true. Ignored for compressed textures.  Must be flipped in the file
+     * @param invertY when true, image is flipped when loaded.  You probably want true. Certain compressed textures may invert this if their default is inverted (eg. ktx)
      * @param scene needed for loading to the correct scene
      * @param scene needed for loading to the correct scene
-     * @param samplingMode mode with should be used sample / access the texture (Default: BABYLON.Texture.TRILINEAR_SAMPLINGMODE)
+     * @param samplingMode mode with should be used sample / access the texture (Default: Texture.TRILINEAR_SAMPLINGMODE)
      * @param onLoad optional callback to be called upon successful completion
      * @param onLoad optional callback to be called upon successful completion
      * @param onError optional callback to be called upon failure
      * @param onError optional callback to be called upon failure
-     * @param buffer a source of a file previously fetched as either a base64 string, an ArrayBuffer (compressed or image format), or a Blob
+     * @param buffer a source of a file previously fetched as either a base64 string, an ArrayBuffer (compressed or image format), HTMLImageElement (image format), or a Blob
      * @param fallback an internal argument in case the function must be called again, due to etc1 not having alpha capabilities
      * @param fallback an internal argument in case the function must be called again, due to etc1 not having alpha capabilities
      * @param format internal format.  Default: RGB when extension is '.jpg' else RGBA.  Ignored for compressed textures
      * @param format internal format.  Default: RGB when extension is '.jpg' else RGBA.  Ignored for compressed textures
      * @param forcedExtension defines the extension to use to pick the right loader
      * @param forcedExtension defines the extension to use to pick the right loader
+     * @param mimeType defines an optional mime type
      * @returns a InternalTexture for assignment back into BABYLON.Texture
      * @returns a InternalTexture for assignment back into BABYLON.Texture
      */
      */
-    public createTexture(
-        urlArg: Nullable<string>,
-        noMipmap: boolean,
-        invertY: boolean,
-        scene: Nullable<Scene>,
-        samplingMode: number = Constants.TEXTURE_TRILINEAR_SAMPLINGMODE,
-        onLoad: Nullable<() => void> = null,
-        onError: Nullable<(message: string, exception: any) => void> = null,
-        buffer: Nullable<string | ArrayBuffer | Blob> = null,
-        fallback: Nullable<InternalTexture> = null,
-        format: Nullable<number> = null,
-        forcedExtension: Nullable<string> = null): InternalTexture {
+    public createTexture(urlArg: Nullable<string>, noMipmap: boolean, invertY: boolean, scene: Nullable<ISceneLike>, samplingMode: number = Constants.TEXTURE_TRILINEAR_SAMPLINGMODE,
+        onLoad: Nullable<() => void> = null, onError: Nullable<(message: string, exception: any) => void> = null,
+        buffer: Nullable<string | ArrayBuffer | ArrayBufferView | HTMLImageElement | Blob | ImageBitmap> = null, fallback: Nullable<InternalTexture> = null, format: Nullable<number> = null,
+        forcedExtension: Nullable<string> = null, mimeType?: string): InternalTexture {
         var url = String(urlArg); // assign a new string, so that the original is still available in case of fallback
         var url = String(urlArg); // assign a new string, so that the original is still available in case of fallback
         var fromData = url.substr(0, 5) === "data:";
         var fromData = url.substr(0, 5) === "data:";
         var fromBlob = url.substr(0, 5) === "blob:";
         var fromBlob = url.substr(0, 5) === "blob:";
-        var isBase64 = fromData && url.indexOf("base64") !== -1;
 
 
         let texture = fallback ? fallback : new InternalTexture(this, InternalTextureSource.Url);
         let texture = fallback ? fallback : new InternalTexture(this, InternalTextureSource.Url);
 
 
@@ -881,21 +873,14 @@ export class NativeEngine extends Engine {
         var lastDot = url.lastIndexOf('.');
         var lastDot = url.lastIndexOf('.');
         var extension = forcedExtension ? forcedExtension : (lastDot > -1 ? url.substring(lastDot).toLowerCase() : "");
         var extension = forcedExtension ? forcedExtension : (lastDot > -1 ? url.substring(lastDot).toLowerCase() : "");
 
 
-        // TODO: Add support for compressed texture formats.
-        var textureFormatInUse: Nullable<string> = null;
-
         let loader: Nullable<IInternalTextureLoader> = null;
         let loader: Nullable<IInternalTextureLoader> = null;
         for (let availableLoader of Engine._TextureLoaders) {
         for (let availableLoader of Engine._TextureLoaders) {
-            if (availableLoader.canLoad(extension, textureFormatInUse, fallback, isBase64, buffer ? true : false)) {
+            if (availableLoader.canLoad(extension)) {
                 loader = availableLoader;
                 loader = availableLoader;
                 break;
                 break;
             }
             }
         }
         }
 
 
-        if (loader) {
-            url = loader.transformUrl(url, textureFormatInUse);
-        }
-
         if (scene) {
         if (scene) {
             scene._addPendingData(texture);
             scene._addPendingData(texture);
         }
         }
@@ -921,23 +906,11 @@ export class NativeEngine extends Engine {
                 scene._removePendingData(texture);
                 scene._removePendingData(texture);
             }
             }
 
 
-            let customFallback = false;
-            if (loader) {
-                const fallbackUrl = loader.getFallbackTextureUrl(url, textureFormatInUse);
-                if (fallbackUrl) {
-                    // Add Back
-                    customFallback = true;
-                    this.createTexture(urlArg, noMipmap, invertY, scene, samplingMode, null, onError, buffer, texture);
-                }
+            if (onLoadObserver) {
+                texture.onLoadedObservable.remove(onLoadObserver);
             }
             }
-
-            if (!customFallback) {
-                if (onLoadObserver) {
-                    texture.onLoadedObservable.remove(onLoadObserver);
-                }
-                if (Tools.UseFallbackTexture) {
-                    this.createTexture(Tools.fallbackTexture, noMipmap, invertY, scene, samplingMode, null, onError, buffer, texture);
-                }
+            if (Tools.UseFallbackTexture) {
+                this.createTexture(Tools.fallbackTexture, noMipmap, invertY, scene, samplingMode, null, onError, buffer, texture);
             }
             }
 
 
             if (onError) {
             if (onError) {

+ 6 - 5
src/Engines/nullEngine.ts

@@ -1,6 +1,5 @@
 import { Logger } from "../Misc/logger";
 import { Logger } from "../Misc/logger";
 import { Nullable, FloatArray, IndicesArray } from "../types";
 import { Nullable, FloatArray, IndicesArray } from "../types";
-import { Scene } from "../scene";
 import { Engine } from "../Engines/engine";
 import { Engine } from "../Engines/engine";
 import { RenderTargetCreationOptions } from "../Materials/Textures/renderTargetCreationOptions";
 import { RenderTargetCreationOptions } from "../Materials/Textures/renderTargetCreationOptions";
 import { VertexBuffer } from "../Meshes/buffer";
 import { VertexBuffer } from "../Meshes/buffer";
@@ -10,6 +9,7 @@ import { Constants } from "./constants";
 import { IPipelineContext } from './IPipelineContext';
 import { IPipelineContext } from './IPipelineContext';
 import { DataBuffer } from '../Meshes/dataBuffer';
 import { DataBuffer } from '../Meshes/dataBuffer';
 import { IColor4Like, IViewportLike } from '../Maths/math.like';
 import { IColor4Like, IViewportLike } from '../Maths/math.like';
+import { ISceneLike } from './thinEngine';
 
 
 declare const global: any;
 declare const global: any;
 
 
@@ -551,15 +551,16 @@ export class NullEngine extends Engine {
      * @param onLoad optional callback to be called upon successful completion
      * @param onLoad optional callback to be called upon successful completion
      * @param onError optional callback to be called upon failure
      * @param onError optional callback to be called upon failure
      * @param buffer a source of a file previously fetched as either a base64 string, an ArrayBuffer (compressed or image format), HTMLImageElement (image format), or a Blob
      * @param buffer a source of a file previously fetched as either a base64 string, an ArrayBuffer (compressed or image format), HTMLImageElement (image format), or a Blob
-     * @param fallBack an internal argument in case the function must be called again, due to etc1 not having alpha capabilities
+     * @param fallback an internal argument in case the function must be called again, due to etc1 not having alpha capabilities
      * @param format internal format.  Default: RGB when extension is '.jpg' else RGBA.  Ignored for compressed textures
      * @param format internal format.  Default: RGB when extension is '.jpg' else RGBA.  Ignored for compressed textures
      * @param forcedExtension defines the extension to use to pick the right loader
      * @param forcedExtension defines the extension to use to pick the right loader
-     * @param excludeLoaders array of texture loaders that should be excluded when picking a loader for the texture (default: empty array)
+     * @param mimeType defines an optional mime type
      * @returns a InternalTexture for assignment back into BABYLON.Texture
      * @returns a InternalTexture for assignment back into BABYLON.Texture
      */
      */
-    public createTexture(urlArg: string, noMipmap: boolean, invertY: boolean, scene: Scene, samplingMode: number = Constants.TEXTURE_TRILINEAR_SAMPLINGMODE,
+    public createTexture(urlArg: Nullable<string>, noMipmap: boolean, invertY: boolean, scene: Nullable<ISceneLike>, samplingMode: number = Constants.TEXTURE_TRILINEAR_SAMPLINGMODE,
         onLoad: Nullable<() => void> = null, onError: Nullable<(message: string, exception: any) => void> = null,
         onLoad: Nullable<() => void> = null, onError: Nullable<(message: string, exception: any) => void> = null,
-        buffer: Nullable<ArrayBuffer | HTMLImageElement> = null, fallBack?: InternalTexture, format?: number): InternalTexture {
+        buffer: Nullable<string | ArrayBuffer | ArrayBufferView | HTMLImageElement | Blob | ImageBitmap> = null, fallback: Nullable<InternalTexture> = null, format: Nullable<number> = null,
+        forcedExtension: Nullable<string> = null, mimeType?: string): InternalTexture {
         var texture = new InternalTexture(this, InternalTextureSource.Url);
         var texture = new InternalTexture(this, InternalTextureSource.Url);
         var url = String(urlArg);
         var url = String(urlArg);
 
 

+ 11 - 52
src/Engines/thinEngine.ts

@@ -40,7 +40,7 @@ declare type Texture = import("../Materials/Textures/texture").Texture;
  * Defines the interface used by objects working like Scene
  * Defines the interface used by objects working like Scene
  * @hidden
  * @hidden
  */
  */
-interface ISceneLike {
+export interface ISceneLike {
     _addPendingData(data: any): void;
     _addPendingData(data: any): void;
     _removePendingData(data: any): void;
     _removePendingData(data: any): void;
     offlineProvider: IOfflineProvider;
     offlineProvider: IOfflineProvider;
@@ -172,29 +172,6 @@ export class ThinEngine {
         Effect.ShadersRepository = value;
         Effect.ShadersRepository = value;
     }
     }
 
 
-    /**
-    * Gets or sets the textures that the engine should not attempt to load as compressed
-    */
-    protected _excludedCompressedTextures: string[] = [];
-
-    /**
-     * Filters the compressed texture formats to only include
-     * files that are not included in the skippable list
-     *
-     * @param url the current extension
-     * @param textureFormatInUse the current compressed texture format
-     * @returns "format" string
-     */
-    public excludedCompressedTextureFormats(url: Nullable<string>, textureFormatInUse: Nullable<string>): Nullable<string> {
-        const skipCompression = (): boolean => {
-            return this._excludedCompressedTextures.some((entry) => {
-                const strRegExPattern: string = '\\b' + entry + '\\b';
-                return (url && (url === entry || url.match(new RegExp(strRegExPattern, 'g'))));
-            });
-        };
-        return skipCompression() ? null : textureFormatInUse;
-    }
-
     // Public members
     // Public members
 
 
     /** @hidden */
     /** @hidden */
@@ -255,9 +232,10 @@ export class ThinEngine {
 
 
     /** @hidden */
     /** @hidden */
     public _gl: WebGLRenderingContext;
     public _gl: WebGLRenderingContext;
+    /** @hidden */
+    public _webGLVersion = 1.0;
     protected _renderingCanvas: Nullable<HTMLCanvasElement>;
     protected _renderingCanvas: Nullable<HTMLCanvasElement>;
     protected _windowIsBackground = false;
     protected _windowIsBackground = false;
-    protected _webGLVersion = 1.0;
     protected _creationOptions: EngineOptions;
     protected _creationOptions: EngineOptions;
 
 
     protected _highPrecisionShadersAllowed = true;
     protected _highPrecisionShadersAllowed = true;
@@ -2788,14 +2766,13 @@ export class ThinEngine {
      * @param fallback an internal argument in case the function must be called again, due to etc1 not having alpha capabilities
      * @param fallback an internal argument in case the function must be called again, due to etc1 not having alpha capabilities
      * @param format internal format.  Default: RGB when extension is '.jpg' else RGBA.  Ignored for compressed textures
      * @param format internal format.  Default: RGB when extension is '.jpg' else RGBA.  Ignored for compressed textures
      * @param forcedExtension defines the extension to use to pick the right loader
      * @param forcedExtension defines the extension to use to pick the right loader
-     * @param excludeLoaders array of texture loaders that should be excluded when picking a loader for the texture (default: empty array)
      * @param mimeType defines an optional mime type
      * @param mimeType defines an optional mime type
      * @returns a InternalTexture for assignment back into BABYLON.Texture
      * @returns a InternalTexture for assignment back into BABYLON.Texture
      */
      */
     public createTexture(urlArg: Nullable<string>, noMipmap: boolean, invertY: boolean, scene: Nullable<ISceneLike>, samplingMode: number = Constants.TEXTURE_TRILINEAR_SAMPLINGMODE,
     public createTexture(urlArg: Nullable<string>, noMipmap: boolean, invertY: boolean, scene: Nullable<ISceneLike>, samplingMode: number = Constants.TEXTURE_TRILINEAR_SAMPLINGMODE,
         onLoad: Nullable<() => void> = null, onError: Nullable<(message: string, exception: any) => void> = null,
         onLoad: Nullable<() => void> = null, onError: Nullable<(message: string, exception: any) => void> = null,
         buffer: Nullable<string | ArrayBuffer | ArrayBufferView | HTMLImageElement | Blob | ImageBitmap> = null, fallback: Nullable<InternalTexture> = null, format: Nullable<number> = null,
         buffer: Nullable<string | ArrayBuffer | ArrayBufferView | HTMLImageElement | Blob | ImageBitmap> = null, fallback: Nullable<InternalTexture> = null, format: Nullable<number> = null,
-        forcedExtension: Nullable<string> = null, excludeLoaders: Array<IInternalTextureLoader> = [], mimeType?: string): InternalTexture {
+        forcedExtension: Nullable<string> = null, mimeType?: string): InternalTexture {
         var url = String(urlArg); // assign a new string, so that the original is still available in case of fallback
         var url = String(urlArg); // assign a new string, so that the original is still available in case of fallback
         var fromData = url.substr(0, 5) === "data:";
         var fromData = url.substr(0, 5) === "data:";
         var fromBlob = url.substr(0, 5) === "blob:";
         var fromBlob = url.substr(0, 5) === "blob:";
@@ -2806,20 +2783,15 @@ export class ThinEngine {
         // establish the file extension, if possible
         // establish the file extension, if possible
         var lastDot = url.lastIndexOf('.');
         var lastDot = url.lastIndexOf('.');
         var extension = forcedExtension ? forcedExtension : (lastDot > -1 ? url.substring(lastDot).toLowerCase() : "");
         var extension = forcedExtension ? forcedExtension : (lastDot > -1 ? url.substring(lastDot).toLowerCase() : "");
-        const filteredFormat: Nullable<string> = this.excludedCompressedTextureFormats(url, this._textureFormatInUse);
         let loader: Nullable<IInternalTextureLoader> = null;
         let loader: Nullable<IInternalTextureLoader> = null;
 
 
         for (let availableLoader of ThinEngine._TextureLoaders) {
         for (let availableLoader of ThinEngine._TextureLoaders) {
-            if (excludeLoaders.indexOf(availableLoader) === -1 && availableLoader.canLoad(extension, filteredFormat, fallback, isBase64, buffer ? true : false)) {
+            if (availableLoader.canLoad(extension)) {
                 loader = availableLoader;
                 loader = availableLoader;
                 break;
                 break;
             }
             }
         }
         }
 
 
-        if (loader) {
-            url = loader.transformUrl(url, filteredFormat);
-        }
-
         if (scene) {
         if (scene) {
             scene._addPendingData(texture);
             scene._addPendingData(texture);
         }
         }
@@ -2845,26 +2817,13 @@ export class ThinEngine {
                 scene._removePendingData(texture);
                 scene._removePendingData(texture);
             }
             }
 
 
-            let customFallback = false;
-            if (loader) {
-                const fallbackUrl = loader.getFallbackTextureUrl(url, this._textureFormatInUse);
-                if (fallbackUrl) {
-                    // Add Back
-                    customFallback = true;
-                    excludeLoaders.push(loader);
-                    this.createTexture(urlArg, noMipmap, texture.invertY, scene, samplingMode, null, onError, buffer, texture, undefined, undefined, excludeLoaders);
-                    return;
-                }
+            if (onLoadObserver) {
+                texture.onLoadedObservable.remove(onLoadObserver);
             }
             }
 
 
-            if (!customFallback) {
-                if (onLoadObserver) {
-                    texture.onLoadedObservable.remove(onLoadObserver);
-                }
-                if (EngineStore.UseFallbackTexture) {
-                    this.createTexture(EngineStore.FallbackTexture, noMipmap, texture.invertY, scene, samplingMode, null, onError, buffer, texture);
-                    return;
-                }
+            if (EngineStore.UseFallbackTexture) {
+                this.createTexture(EngineStore.FallbackTexture, noMipmap, texture.invertY, scene, samplingMode, null, onError, buffer, texture);
+                return;
             }
             }
 
 
             if (onError) {
             if (onError) {
@@ -2969,7 +2928,7 @@ export class ThinEngine {
                 ThinEngine._FileToolsLoadImage(buffer, onload, onInternalError, scene ? scene.offlineProvider : null, mimeType);
                 ThinEngine._FileToolsLoadImage(buffer, onload, onInternalError, scene ? scene.offlineProvider : null, mimeType);
             }
             }
             else if (buffer) {
             else if (buffer) {
-                onload(<HTMLImageElement>buffer);
+                onload(buffer);
             }
             }
         }
         }
 
 

+ 18 - 0
src/Layers/highlightLayer.ts

@@ -686,6 +686,24 @@ export class HighlightLayer extends EffectLayer {
     }
     }
 
 
     /**
     /**
+     * Remove all the meshes currently referenced in the highlight layer
+     */
+    public removeAllMeshes(): void {
+        if (!this._meshes) {
+            return;
+        }
+
+        for (const uniqueId in this._meshes) {
+            if (this._meshes.hasOwnProperty(uniqueId)) {
+                const mesh = this._meshes[uniqueId];
+                if (mesh) {
+                    this.removeMesh(mesh.mesh);
+                }
+            }
+        }
+    }
+
+    /**
      * Force the stencil to the normal expected value for none glowing parts
      * Force the stencil to the normal expected value for none glowing parts
      */
      */
     private _defaultStencilReference(mesh: Mesh) {
     private _defaultStencilReference(mesh: Mesh) {

+ 4 - 2
src/Materials/Node/Blocks/Dual/reflectionTextureBlock.ts

@@ -67,6 +67,8 @@ export class ReflectionTextureBlock extends NodeMaterialBlock {
         this.registerOutput("r", NodeMaterialBlockConnectionPointTypes.Float, NodeMaterialBlockTargets.Fragment);
         this.registerOutput("r", NodeMaterialBlockConnectionPointTypes.Float, NodeMaterialBlockTargets.Fragment);
         this.registerOutput("g", NodeMaterialBlockConnectionPointTypes.Float, NodeMaterialBlockTargets.Fragment);
         this.registerOutput("g", NodeMaterialBlockConnectionPointTypes.Float, NodeMaterialBlockTargets.Fragment);
         this.registerOutput("b", NodeMaterialBlockConnectionPointTypes.Float, NodeMaterialBlockTargets.Fragment);
         this.registerOutput("b", NodeMaterialBlockConnectionPointTypes.Float, NodeMaterialBlockTargets.Fragment);
+
+        this._inputs[0].acceptedConnectionPointTypes.push(NodeMaterialBlockConnectionPointTypes.Vector4);
     }
     }
 
 
     /**
     /**
@@ -244,13 +246,13 @@ export class ReflectionTextureBlock extends NodeMaterialBlock {
 
 
         if (state._emitVaryingFromString(this._positionUVWName, "vec3", this._defineSkyboxName)) {
         if (state._emitVaryingFromString(this._positionUVWName, "vec3", this._defineSkyboxName)) {
             state.compilationString += `#ifdef ${this._defineSkyboxName}\r\n`;
             state.compilationString += `#ifdef ${this._defineSkyboxName}\r\n`;
-            state.compilationString += `${this._positionUVWName} = ${this.position.associatedVariableName};\r\n`;
+            state.compilationString += `${this._positionUVWName} = ${this.position.associatedVariableName}.xyz;\r\n`;
             state.compilationString += `#endif\r\n`;
             state.compilationString += `#endif\r\n`;
         }
         }
 
 
         if (state._emitVaryingFromString(this._directionWName, "vec3", `defined(${this._defineEquirectangularFixedName}) || defined(${this._defineMirroredEquirectangularFixedName})`)) {
         if (state._emitVaryingFromString(this._directionWName, "vec3", `defined(${this._defineEquirectangularFixedName}) || defined(${this._defineMirroredEquirectangularFixedName})`)) {
             state.compilationString += `#if defined(${this._defineEquirectangularFixedName}) || defined(${this._defineMirroredEquirectangularFixedName})\r\n`;
             state.compilationString += `#if defined(${this._defineEquirectangularFixedName}) || defined(${this._defineMirroredEquirectangularFixedName})\r\n`;
-            state.compilationString += `${this._directionWName} = normalize(vec3(${this.world.associatedVariableName} * vec4(${this.position.associatedVariableName}, 0.0)));\r\n`;
+            state.compilationString += `${this._directionWName} = normalize(vec3(${this.world.associatedVariableName} * vec4(${this.position.associatedVariableName}.xyz, 0.0)));\r\n`;
             state.compilationString += `#endif\r\n`;
             state.compilationString += `#endif\r\n`;
         }
         }
     }
     }

+ 8 - 1
src/Materials/Node/nodeMaterialBlockConnectionPoint.ts

@@ -91,8 +91,11 @@ export class NodeMaterialConnectionPoint {
         this._associatedVariableName = value;
         this._associatedVariableName = value;
     }
     }
 
 
-    /** Get the inner type (ie AutoDetect for isntance instead of the inferred one) */
+    /** Get the inner type (ie AutoDetect for instance instead of the inferred one) */
     public get innerType() {
     public get innerType() {
+        if (this._linkedConnectionSource && this._linkedConnectionSource.isConnected) {
+            return this.type;
+        }
         return this._type;
         return this._type;
     }
     }
 
 
@@ -342,21 +345,25 @@ export class NodeMaterialConnectionPoint {
                     if (connectionPoint.type === NodeMaterialBlockConnectionPointTypes.Color3) {
                     if (connectionPoint.type === NodeMaterialBlockConnectionPointTypes.Color3) {
                         return NodeMaterialConnectionPointCompatibilityStates.Compatible;
                         return NodeMaterialConnectionPointCompatibilityStates.Compatible;
                     }
                     }
+                    break;
                 }
                 }
                 case NodeMaterialBlockConnectionPointTypes.Vector4: {
                 case NodeMaterialBlockConnectionPointTypes.Vector4: {
                     if (connectionPoint.type === NodeMaterialBlockConnectionPointTypes.Color4) {
                     if (connectionPoint.type === NodeMaterialBlockConnectionPointTypes.Color4) {
                         return NodeMaterialConnectionPointCompatibilityStates.Compatible;
                         return NodeMaterialConnectionPointCompatibilityStates.Compatible;
                     }
                     }
+                    break;
                 }
                 }
                 case NodeMaterialBlockConnectionPointTypes.Color3: {
                 case NodeMaterialBlockConnectionPointTypes.Color3: {
                     if (connectionPoint.type === NodeMaterialBlockConnectionPointTypes.Vector3) {
                     if (connectionPoint.type === NodeMaterialBlockConnectionPointTypes.Vector3) {
                         return NodeMaterialConnectionPointCompatibilityStates.Compatible;
                         return NodeMaterialConnectionPointCompatibilityStates.Compatible;
                     }
                     }
+                    break;
                 }
                 }
                 case NodeMaterialBlockConnectionPointTypes.Color4: {
                 case NodeMaterialBlockConnectionPointTypes.Color4: {
                     if (connectionPoint.type === NodeMaterialBlockConnectionPointTypes.Vector4) {
                     if (connectionPoint.type === NodeMaterialBlockConnectionPointTypes.Vector4) {
                         return NodeMaterialConnectionPointCompatibilityStates.Compatible;
                         return NodeMaterialConnectionPointCompatibilityStates.Compatible;
                     }
                     }
+                    break;
                 }
                 }
             }
             }
 
 

+ 2 - 0
src/Materials/PBR/pbrBaseMaterial.ts

@@ -58,6 +58,7 @@ export class PBRMaterialDefines extends MaterialDefines
     public UV2 = false;
     public UV2 = false;
 
 
     public ALBEDO = false;
     public ALBEDO = false;
+    public GAMMAALBEDO = false;
     public ALBEDODIRECTUV = 0;
     public ALBEDODIRECTUV = 0;
     public VERTEXCOLOR = false;
     public VERTEXCOLOR = false;
 
 
@@ -1291,6 +1292,7 @@ export abstract class PBRBaseMaterial extends PushMaterial {
 
 
                 if (this._albedoTexture && MaterialFlags.DiffuseTextureEnabled) {
                 if (this._albedoTexture && MaterialFlags.DiffuseTextureEnabled) {
                     MaterialHelper.PrepareDefinesForMergedUV(this._albedoTexture, defines, "ALBEDO");
                     MaterialHelper.PrepareDefinesForMergedUV(this._albedoTexture, defines, "ALBEDO");
+                    defines.GAMMAALBEDO = this._albedoTexture.gammaSpace;
                 } else {
                 } else {
                     defines.ALBEDO = false;
                     defines.ALBEDO = false;
                 }
                 }

+ 5 - 28
src/Materials/Textures/Loaders/basisTextureLoader.ts

@@ -4,6 +4,7 @@ import { InternalTexture } from "../../../Materials/Textures/internalTexture";
 import { IInternalTextureLoader } from "../../../Materials/Textures/internalTextureLoader";
 import { IInternalTextureLoader } from "../../../Materials/Textures/internalTextureLoader";
 import { BasisTools } from "../../../Misc/basis";
 import { BasisTools } from "../../../Misc/basis";
 import { Tools } from '../../../Misc/tools';
 import { Tools } from '../../../Misc/tools';
+import { StringTools } from '../../../Misc/stringTools';
 
 
 /**
 /**
  * Loader for .basis file format
  * Loader for .basis file format
@@ -17,38 +18,14 @@ export class _BasisTextureLoader implements IInternalTextureLoader {
     /**
     /**
      * This returns if the loader support the current file information.
      * This returns if the loader support the current file information.
      * @param extension defines the file extension of the file being loaded
      * @param extension defines the file extension of the file being loaded
-     * @param textureFormatInUse defines the current compressed format in use iun the engine
-     * @param fallback defines the fallback internal texture if any
-     * @param isBase64 defines whether the texture is encoded as a base64
-     * @param isBuffer defines whether the texture data are stored as a buffer
      * @returns true if the loader can load the specified file
      * @returns true if the loader can load the specified file
      */
      */
-    public canLoad(extension: string, textureFormatInUse: Nullable<string>, fallback: Nullable<InternalTexture>, isBase64: boolean, isBuffer: boolean): boolean {
-        return extension.indexOf(".basis") === 0;
+    public canLoad(extension: string): boolean {
+        return StringTools.EndsWith(extension, ".basis");
     }
     }
 
 
     /**
     /**
-     * Transform the url before loading if required.
-     * @param rootUrl the url of the texture
-     * @param textureFormatInUse defines the current compressed format in use iun the engine
-     * @returns the transformed texture
-     */
-    public transformUrl(rootUrl: string, textureFormatInUse: Nullable<string>): string {
-        return rootUrl;
-    }
-
-    /**
-     * Gets the fallback url in case the load fail. This can return null to allow the default fallback mecanism to work
-     * @param rootUrl the url of the texture
-     * @param textureFormatInUse defines the current compressed format in use iun the engine
-     * @returns the fallback texture
-     */
-    public getFallbackTextureUrl(rootUrl: string, textureFormatInUse: Nullable<string>): Nullable<string> {
-        return null;
-    }
-
-    /**
-     * Uploads the cube texture data to the WebGl Texture. It has already been bound.
+     * Uploads the cube texture data to the WebGL texture. It has already been bound.
      * @param data contains the texture data
      * @param data contains the texture data
      * @param texture defines the BabylonJS internal texture
      * @param texture defines the BabylonJS internal texture
      * @param createPolynomials will be true if polynomials have been requested
      * @param createPolynomials will be true if polynomials have been requested
@@ -85,7 +62,7 @@ export class _BasisTextureLoader implements IInternalTextureLoader {
     }
     }
 
 
     /**
     /**
-     * Uploads the 2D texture data to the WebGl Texture. It has alreday been bound once in the callback.
+     * Uploads the 2D texture data to the WebGL texture. It has already been bound once in the callback.
      * @param data contains the texture data
      * @param data contains the texture data
      * @param texture defines the BabylonJS internal texture
      * @param texture defines the BabylonJS internal texture
      * @param callback defines the method to call once ready to upload
      * @param callback defines the method to call once ready to upload

+ 5 - 28
src/Materials/Textures/Loaders/ddsTextureLoader.ts

@@ -4,6 +4,7 @@ import { Engine } from "../../../Engines/engine";
 import { InternalTexture } from "../../../Materials/Textures/internalTexture";
 import { InternalTexture } from "../../../Materials/Textures/internalTexture";
 import { IInternalTextureLoader } from "../../../Materials/Textures/internalTextureLoader";
 import { IInternalTextureLoader } from "../../../Materials/Textures/internalTextureLoader";
 import { DDSTools, DDSInfo } from "../../../Misc/dds";
 import { DDSTools, DDSInfo } from "../../../Misc/dds";
+import { StringTools } from '../../../Misc/stringTools';
 /**
 /**
  * Implementation of the DDS Texture Loader.
  * Implementation of the DDS Texture Loader.
  * @hidden
  * @hidden
@@ -17,38 +18,14 @@ export class _DDSTextureLoader implements IInternalTextureLoader {
     /**
     /**
      * This returns if the loader support the current file information.
      * This returns if the loader support the current file information.
      * @param extension defines the file extension of the file being loaded
      * @param extension defines the file extension of the file being loaded
-     * @param textureFormatInUse defines the current compressed format in use iun the engine
-     * @param fallback defines the fallback internal texture if any
-     * @param isBase64 defines whether the texture is encoded as a base64
-     * @param isBuffer defines whether the texture data are stored as a buffer
      * @returns true if the loader can load the specified file
      * @returns true if the loader can load the specified file
      */
      */
-    public canLoad(extension: string, textureFormatInUse: Nullable<string>, fallback: Nullable<InternalTexture>, isBase64: boolean, isBuffer: boolean): boolean {
-        return extension.indexOf(".dds") === 0;
+    public canLoad(extension: string): boolean {
+        return StringTools.EndsWith(extension, ".dds");
     }
     }
 
 
     /**
     /**
-     * Transform the url before loading if required.
-     * @param rootUrl the url of the texture
-     * @param textureFormatInUse defines the current compressed format in use iun the engine
-     * @returns the transformed texture
-     */
-    public transformUrl(rootUrl: string, textureFormatInUse: Nullable<string>): string {
-        return rootUrl;
-    }
-
-    /**
-     * Gets the fallback url in case the load fail. This can return null to allow the default fallback mecanism to work
-     * @param rootUrl the url of the texture
-     * @param textureFormatInUse defines the current compressed format in use iun the engine
-     * @returns the fallback texture
-     */
-    public getFallbackTextureUrl(rootUrl: string, textureFormatInUse: Nullable<string>): Nullable<string> {
-        return null;
-    }
-
-    /**
-     * Uploads the cube texture data to the WebGl Texture. It has alreday been bound.
+     * Uploads the cube texture data to the WebGL texture. It has already been bound.
      * @param data contains the texture data
      * @param data contains the texture data
      * @param texture defines the BabylonJS internal texture
      * @param texture defines the BabylonJS internal texture
      * @param createPolynomials will be true if polynomials have been requested
      * @param createPolynomials will be true if polynomials have been requested
@@ -110,7 +87,7 @@ export class _DDSTextureLoader implements IInternalTextureLoader {
     }
     }
 
 
     /**
     /**
-     * Uploads the 2D texture data to the WebGl Texture. It has alreday been bound once in the callback.
+     * Uploads the 2D texture data to the WebGL texture. It has already been bound once in the callback.
      * @param data contains the texture data
      * @param data contains the texture data
      * @param texture defines the BabylonJS internal texture
      * @param texture defines the BabylonJS internal texture
      * @param callback defines the method to call once ready to upload
      * @param callback defines the method to call once ready to upload

+ 5 - 28
src/Materials/Textures/Loaders/envTextureLoader.ts

@@ -3,6 +3,7 @@ import { Nullable } from "../../../types";
 import { Engine } from "../../../Engines/engine";
 import { Engine } from "../../../Engines/engine";
 import { InternalTexture } from "../../../Materials/Textures/internalTexture";
 import { InternalTexture } from "../../../Materials/Textures/internalTexture";
 import { IInternalTextureLoader } from "../../../Materials/Textures/internalTextureLoader";
 import { IInternalTextureLoader } from "../../../Materials/Textures/internalTextureLoader";
+import { StringTools } from '../../../Misc/stringTools';
 
 
 /**
 /**
  * Implementation of the ENV Texture Loader.
  * Implementation of the ENV Texture Loader.
@@ -17,38 +18,14 @@ export class _ENVTextureLoader implements IInternalTextureLoader {
     /**
     /**
      * This returns if the loader support the current file information.
      * This returns if the loader support the current file information.
      * @param extension defines the file extension of the file being loaded
      * @param extension defines the file extension of the file being loaded
-     * @param textureFormatInUse defines the current compressed format in use iun the engine
-     * @param fallback defines the fallback internal texture if any
-     * @param isBase64 defines whether the texture is encoded as a base64
-     * @param isBuffer defines whether the texture data are stored as a buffer
      * @returns true if the loader can load the specified file
      * @returns true if the loader can load the specified file
      */
      */
-    public canLoad(extension: string, textureFormatInUse: Nullable<string>, fallback: Nullable<InternalTexture>, isBase64: boolean, isBuffer: boolean): boolean {
-        return extension.indexOf(".env") === 0;
+    public canLoad(extension: string): boolean {
+        return StringTools.EndsWith(extension, ".env");
     }
     }
 
 
     /**
     /**
-     * Transform the url before loading if required.
-     * @param rootUrl the url of the texture
-     * @param textureFormatInUse defines the current compressed format in use iun the engine
-     * @returns the transformed texture
-     */
-    public transformUrl(rootUrl: string, textureFormatInUse: Nullable<string>): string {
-        return rootUrl;
-    }
-
-    /**
-     * Gets the fallback url in case the load fail. This can return null to allow the default fallback mecanism to work
-     * @param rootUrl the url of the texture
-     * @param textureFormatInUse defines the current compressed format in use iun the engine
-     * @returns the fallback texture
-     */
-    public getFallbackTextureUrl(rootUrl: string, textureFormatInUse: Nullable<string>): Nullable<string> {
-        return null;
-    }
-
-    /**
-     * Uploads the cube texture data to the WebGl Texture. It has alreday been bound.
+     * Uploads the cube texture data to the WebGL texture. It has already been bound.
      * @param data contains the texture data
      * @param data contains the texture data
      * @param texture defines the BabylonJS internal texture
      * @param texture defines the BabylonJS internal texture
      * @param createPolynomials will be true if polynomials have been requested
      * @param createPolynomials will be true if polynomials have been requested
@@ -81,7 +58,7 @@ export class _ENVTextureLoader implements IInternalTextureLoader {
     }
     }
 
 
     /**
     /**
-     * Uploads the 2D texture data to the WebGl Texture. It has alreday been bound once in the callback.
+     * Uploads the 2D texture data to the WebGL texture. It has already been bound once in the callback.
      * @param data contains the texture data
      * @param data contains the texture data
      * @param texture defines the BabylonJS internal texture
      * @param texture defines the BabylonJS internal texture
      * @param callback defines the method to call once ready to upload
      * @param callback defines the method to call once ready to upload

+ 0 - 0
src/Materials/Textures/Loaders/ktxTextureLoader.ts


部分文件因文件數量過多而無法顯示