瀏覽代碼

Merge remote-tracking branch 'upstream/master' into svg-png

Raanan Weber 5 年之前
父節點
當前提交
b65e41f7c0
共有 100 個文件被更改,包括 2461 次插入74295 次删除
  1. 0 73780
      Playground/babylon.d.txt
  2. 1 2
      Playground/debug.html
  3. 1 2
      Playground/index-local.html
  4. 1 2
      Playground/index.html
  5. 1 1
      Playground/indexStable.html
  6. 1 1
      Playground/indexWebGPU.html
  7. 0 80
      Playground/js/libs/typescript.js
  8. 1 1
      Playground/js/main.js
  9. 45 17
      Playground/js/monacoCreator.js
  10. 1 1
      Playground/package.json
  11. 0 1
      Tools/Config/config.json
  12. 2 2
      Tools/Gulp/gulpfile.js
  13. 3 3
      Tools/Gulp/tasks/gulpTasks-dependencies.js
  14. 13 0
      Tools/Gulp/tasks/gulpTasks-documentation.js
  15. 0 27
      Tools/Gulp/tasks/gulpTasks-intellisense.js
  16. 4 4
      Viewer/package.json
  17. 152 7
      dist/preview release/babylon.d.ts
  18. 1 1
      dist/preview release/babylon.js
  19. 578 83
      dist/preview release/babylon.max.js
  20. 1 1
      dist/preview release/babylon.max.js.map
  21. 316 14
      dist/preview release/babylon.module.d.ts
  22. 173 7
      dist/preview release/documentation.d.ts
  23. 1 1
      dist/preview release/glTF2Interface/package.json
  24. 2 0
      dist/preview release/gui/babylon.gui.d.ts
  25. 6 2
      dist/preview release/gui/babylon.gui.js
  26. 1 1
      dist/preview release/gui/babylon.gui.js.map
  27. 1 1
      dist/preview release/gui/babylon.gui.min.js
  28. 4 0
      dist/preview release/gui/babylon.gui.module.d.ts
  29. 2 2
      dist/preview release/gui/package.json
  30. 1 1
      dist/preview release/inspector/babylon.inspector.bundle.js
  31. 7 4
      dist/preview release/inspector/babylon.inspector.bundle.max.js
  32. 1 1
      dist/preview release/inspector/babylon.inspector.bundle.max.js.map
  33. 2 2
      dist/preview release/inspector/babylon.inspector.d.ts
  34. 5 5
      dist/preview release/inspector/babylon.inspector.module.d.ts
  35. 7 7
      dist/preview release/inspector/package.json
  36. 3 3
      dist/preview release/loaders/babylon.glTF1FileLoader.js
  37. 68 21
      dist/preview release/loaders/babylon.glTF2FileLoader.js
  38. 1 1
      dist/preview release/loaders/babylon.glTF2FileLoader.js.map
  39. 1 1
      dist/preview release/loaders/babylon.glTF2FileLoader.min.js
  40. 71 24
      dist/preview release/loaders/babylon.glTFFileLoader.js
  41. 1 1
      dist/preview release/loaders/babylon.glTFFileLoader.js.map
  42. 2 2
      dist/preview release/loaders/babylon.glTFFileLoader.min.js
  43. 19 0
      dist/preview release/loaders/babylonjs.loaders.d.ts
  44. 71 24
      dist/preview release/loaders/babylonjs.loaders.js
  45. 1 1
      dist/preview release/loaders/babylonjs.loaders.js.map
  46. 2 2
      dist/preview release/loaders/babylonjs.loaders.min.js
  47. 41 0
      dist/preview release/loaders/babylonjs.loaders.module.d.ts
  48. 3 3
      dist/preview release/loaders/package.json
  49. 2 2
      dist/preview release/materialsLibrary/package.json
  50. 1 1
      dist/preview release/nodeEditor/babylon.nodeEditor.d.ts
  51. 7 7
      dist/preview release/nodeEditor/babylon.nodeEditor.js
  52. 11 2
      dist/preview release/nodeEditor/babylon.nodeEditor.max.js
  53. 1 1
      dist/preview release/nodeEditor/babylon.nodeEditor.max.js.map
  54. 5 2
      dist/preview release/nodeEditor/babylon.nodeEditor.module.d.ts
  55. 2 2
      dist/preview release/nodeEditor/package.json
  56. 1 1
      dist/preview release/package.json
  57. 1 1
      dist/preview release/packagesSizeBaseLine.json
  58. 2 2
      dist/preview release/postProcessesLibrary/package.json
  59. 2 2
      dist/preview release/proceduralTexturesLibrary/package.json
  60. 3 3
      dist/preview release/serializers/package.json
  61. 316 14
      dist/preview release/viewer/babylon.module.d.ts
  62. 45 29
      dist/preview release/viewer/babylon.viewer.js
  63. 3 3
      dist/preview release/viewer/babylon.viewer.max.js
  64. 41 0
      dist/preview release/viewer/babylonjs.loaders.module.d.ts
  65. 8 4
      dist/preview release/what's new.md
  66. 3 0
      gui/src/2D/controls/control.ts
  67. 2 0
      gui/src/2D/controls/line.ts
  68. 1 0
      gui/src/2D/controls/multiLine.ts
  69. 2 2
      gui/src/2D/controls/stackPanel.ts
  70. 1 1
      inspector/src/components/actionTabs/lines/optionsLineComponent.tsx
  71. 11 5
      inspector/src/components/actionTabs/lines/textureLinkLineComponent.tsx
  72. 1 2
      inspector/src/components/actionTabs/tabs/propertyGrids/materials/backgroundMaterialPropertyGridComponent.tsx
  73. 1 2
      inspector/src/components/actionTabs/tabs/propertyGrids/materials/nodeMaterialPropertyGridComponent.tsx
  74. 2 3
      inspector/src/components/actionTabs/tabs/propertyGrids/materials/pbrMaterialPropertyGridComponent.tsx
  75. 1 2
      inspector/src/components/actionTabs/tabs/propertyGrids/materials/pbrMetallicRoughnessMaterialPropertyGridComponent.tsx
  76. 1 2
      inspector/src/components/actionTabs/tabs/propertyGrids/materials/pbrSpecularGlossinessMaterialPropertyGridComponent.tsx
  77. 1 2
      inspector/src/components/actionTabs/tabs/propertyGrids/materials/standardMaterialPropertyGridComponent.tsx
  78. 9 9
      loaders/src/glTF/2.0/Extensions/KHR_materials_sheen.ts
  79. 30 0
      loaders/src/glTF/2.0/Extensions/KHR_mesh_quantization.ts
  80. 2 1
      loaders/src/glTF/2.0/Extensions/index.ts
  81. 7 1
      loaders/src/glTF/2.0/glTFLoader.ts
  82. 9 0
      nodeEditor/src/blockTools.ts
  83. 1 1
      nodeEditor/src/components/nodeList/nodeListComponent.tsx
  84. 1 1
      nodeEditor/src/sharedComponents/optionsLineComponent.tsx
  85. 4 4
      package.json
  86. 1 1
      src/Cameras/VR/vrExperienceHelper.ts
  87. 4 2
      src/Cameras/XR/webXRExperienceHelper.ts
  88. 11 12
      src/Engines/engine.ts
  89. 22 3
      src/Engines/thinEngine.ts
  90. 15 2
      src/Materials/Node/Blocks/Dual/textureBlock.ts
  91. 74 0
      src/Materials/Node/Blocks/Fragment/derivativeBlock.ts
  92. 2 1
      src/Materials/Node/Blocks/Fragment/index.ts
  93. 1 0
      src/Materials/Node/Blocks/Input/inputBlock.ts
  94. 4 3
      src/Materials/Node/Blocks/crossBlock.ts
  95. 2 0
      src/Materials/Node/Blocks/index.ts
  96. 70 0
      src/Materials/Node/Blocks/reflectBlock.ts
  97. 78 0
      src/Materials/Node/Blocks/refractBlock.ts
  98. 8 1
      src/Materials/Textures/cubeTexture.ts
  99. 9 9
      src/Materials/Textures/texture.ts
  100. 0 0
      src/Meshes/mesh.ts

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


+ 1 - 2
Playground/debug.html

@@ -98,7 +98,7 @@
     <script src="https://preview.babylonjs.com/serializers/babylonjs.serializers.min.js"></script>
 
     <!-- Monaco -->
-    <script src="node_modules/monaco-editor/min/vs/loader.js"></script>
+    <script src="node_modules/monaco-editor/dev/vs/loader.js"></script>
 
     <!-- Extensions -->
     <script src="https://rawgit.com/BabylonJS/Extensions/master/ClonerSystem/src/babylonx.cloner.js"></script>
@@ -450,7 +450,6 @@
     <!-- Main scripts -->
     <script src="js/config_versions.js"></script>
     <script src="js/pbt.js"></script>
-    <script src="js/libs/typescript.js"></script>
     <script src="js/examples.js"></script>
     <script src="js/main.js"></script>
     <script src="js/menuPG.js"></script>

+ 1 - 2
Playground/index-local.html

@@ -391,7 +391,6 @@
     <!-- Main scripts -->
     <script src="js/config_versions.js"></script>
     <script src="js/pbt.js"></script>
-    <script src="js/libs/typescript.js"></script>
     <script src="js/examples.js"></script>
     <script src="js/main.js"></script>
     <script src="js/menuPG.js"></script>
@@ -402,7 +401,7 @@
     
     <script>
         BABYLONDEVTOOLS.Loader
-            .require('node_modules/monaco-editor/min/vs/loader.js')
+            .require('node_modules/monaco-editor/dev/vs/loader.js')
             .require('js/index.js')
             .load(function () {
                 BABYLON.DracoCompression.Configuration.decoder = {

+ 1 - 2
Playground/index.html

@@ -41,7 +41,7 @@
     <script src="https://preview.babylonjs.com/serializers/babylonjs.serializers.min.js"></script>
 
     <!-- Monaco -->
-    <script src="node_modules/monaco-editor/min/vs/loader.js"></script>
+    <script src="node_modules/monaco-editor/dev/vs/loader.js"></script>
 
     <!-- Extensions -->
     <script src="https://rawgit.com/BabylonJS/Extensions/master/ClonerSystem/src/babylonx.cloner.js" async></script>
@@ -398,7 +398,6 @@
     <!-- Main scripts -->
     <script src="js/config_versions.js"></script>
     <script src="js/pbt.js"></script>
-    <script src="js/libs/typescript.js"></script>
     <script src="js/examples.js"></script>
     <script src="js/main.js"></script>
     <script src="js/menuPG.js"></script>

+ 1 - 1
Playground/indexStable.html

@@ -45,7 +45,7 @@
     <script src="https://cdn.babylonjs.com/serializers/babylonjs.serializers.min.js"></script>
 
     <!-- Monaco -->
-    <script src="node_modules/monaco-editor/min/vs/loader.js"></script>
+    <script src="node_modules/monaco-editor/dev/vs/loader.js"></script>
 
     <!-- Extensions -->
     <script src="https://rawgit.com/BabylonJS/Extensions/master/ClonerSystem/src/babylonx.cloner.js"></script>

+ 1 - 1
Playground/indexWebGPU.html

@@ -42,7 +42,7 @@
     <script src="https://preview.babylonjs.com/serializers/babylonjs.serializers.min.js"></script>
 
     <!-- Monaco -->
-    <script src="node_modules/monaco-editor/min/vs/loader.js"></script>
+    <script src="node_modules/monaco-editor/dev/vs/loader.js"></script>
 
     <!-- Extensions -->
     <script src="https://rawgit.com/BabylonJS/Extensions/master/ClonerSystem/src/babylonx.cloner.js" async></script>

File diff suppressed because it is too large
+ 0 - 80
Playground/js/libs/typescript.js


+ 1 - 1
Playground/js/main.js

@@ -42,7 +42,7 @@ compileAndRun = function(parent, fpsLabel) {
         parent.menuPG.showBJSPGMenu();
         parent.monacoCreator.JsEditor.updateOptions({ readOnly: false });
 
-        if (BABYLON.Engine.LastCreatedScene && BABYLON.Engine.LastCreatedScene.debugLayer.isVisible()) {
+        if (BABYLON.Engine.LastCreatedScene && BABYLON.Engine.LastCreatedScene.debugLayer && BABYLON.Engine.LastCreatedScene.debugLayer.isVisible()) {
             showInspector = true;
         }
 

+ 45 - 17
Playground/js/monacoCreator.js

@@ -50,27 +50,50 @@ class MonacoCreator {
     /**
      * Load the Monaco Node module.
      */
-    loadMonaco(typings) {
-        var xhr = new XMLHttpRequest();
+    async loadMonaco(typings) {
+        let response = await fetch(typings || "https://preview.babylonjs.com/babylon.d.ts");
+        if (!response.ok)
+            return;
 
-        xhr.open('GET', typings || "babylon.d.txt", true);
+        const libContent = await response.text();
+        require.config({ paths: { 'vs': 'node_modules/monaco-editor/dev/vs' } });
 
-        xhr.onreadystatechange = function () {
-            if (xhr.readyState === 4) {
-                if (xhr.status === 200) {
-                    require.config({ paths: { 'vs': 'node_modules/monaco-editor/min/vs' } });
-                    require(['vs/editor/editor.main'], function () {
-                        this.setupMonacoCompilationPipeline(xhr.responseText);
-                        this.setupMonacoColorProvider();
+        require(['vs/editor/editor.main'], () => {
+            this.setupMonacoCompilationPipeline(libContent);
+            this.setupMonacoColorProvider();
 
-                        this.parent.main.run();
-                    }.bind(this));
-                }
-            }
-        }.bind(this);
-        xhr.send(null);
+            require(['vs/language/typescript/languageFeatures'], module => {
+                this.hookMonacoCompletionProvider(module.SuggestAdapter);
+            });
+
+            this.parent.main.run();
+        });
     };
 
+    hookMonacoCompletionProvider(provider) {
+        const hooked = provider.prototype.provideCompletionItems;
+
+        const suggestionFilter = function(suggestion) {
+            return !suggestion.label.startsWith("_");
+        }
+
+        provider.prototype.provideCompletionItems = async function(model, position, context, token) {
+            // reuse 'this' to preserve context through call (using apply)
+            var result = await hooked.apply(this, [model, position, context, token]);
+            
+            if (!result || !result.suggestions)
+                return result;
+
+            const suggestions = result.suggestions.filter(suggestionFilter);
+            const incomplete = result.incomplete && result.incomplete == true;
+
+            return { 
+                suggestions: suggestions,
+                incomplete: incomplete
+            };
+        }
+    }
+
     setupMonacoCompilationPipeline(libContent) {
         const typescript = monaco.languages.typescript;
 
@@ -84,8 +107,13 @@ class MonacoCreator {
         } else {
             typescript.typescriptDefaults.setCompilerOptions({
                 module: typescript.ModuleKind.AMD,
-                target: typescript.ScriptTarget.ES5,
+                target: typescript.ScriptTarget.ESNext,
                 noLib: false,
+                strict: false,
+                alwaysStrict: false,
+                strictFunctionTypes: false,
+                suppressExcessPropertyErrors: false,
+                suppressImplicitAnyIndexErrors: true,
                 noResolve: true,
                 suppressOutputPathCheck: true,
 

+ 1 - 1
Playground/package.json

@@ -15,6 +15,6 @@
     "test": "browser-sync start --server --files **/* --no-inject-changes --startPath index.html"
   },
   "dependencies": {
-    "npm": "^6.11.2"
+    "npm": "^6.13.0"
   }
 }

+ 0 - 1
Tools/Config/config.json

@@ -12,7 +12,6 @@
         "packageES6FolderName": "packageES6",
         "packageES6DevFolderName": "packageES6Dev",
         "playgroundDirectory": "../../Playground/",
-        "intellisenseFile": "babylon.d.txt",
         "documentationFile": "documentation.d.ts",
         "intellisenseSources": [
             "../../dist/preview release/babylon.d.ts",

+ 2 - 2
Tools/Gulp/gulpfile.js

@@ -13,7 +13,7 @@ require("./tasks/gulpTasks-localRun");
 require("./tasks/gulpTasks-watchLibraries");
 require("./tasks/gulpTasks-watchCore");
 require("./tasks/gulpTasks-typedoc");
-require("./tasks/gulpTasks-intellisense");
+require("./tasks/gulpTasks-documentation");
 require("./tasks/gulpTasks-tests");
 require("./tasks/gulpTasks-remapPaths");
 require("./tasks/gulpTasks-npmPackages");
@@ -90,4 +90,4 @@ gulp.task("npmPackages", gulp.series("npmPackages-all"));
 /**
  * The default task, concat and min the main BJS files.
  */
-gulp.task("default", gulp.series("cleanup", "tsLint", "importLint", "circularDependencies", "typescript-all", "intellisense", "documentation", "typedoc-all", "tests-all"));
+gulp.task("default", gulp.series("cleanup", "tsLint", "importLint", "circularDependencies", "typescript-all", "documentation", "typedoc-all", "tests-all"));

+ 3 - 3
Tools/Gulp/tasks/gulpTasks-dependencies.js

@@ -37,12 +37,12 @@ const dependencies = function(settings, moduleName, cb) {
             }
         });
 
-    if (cruiseResult.summary.error > 0) {
-        var errorCount = cruiseResult.summary.error;
+    if (cruiseResult.output.summary.error > 0) {
+        var errorCount = cruiseResult.output.summary.error;
 
         if (errorCount > 0) {
             colorConsole.error(`New circular dependencies in ${moduleName.cyan}: ${("" + errorCount).red}`);
-            for (let error of cruiseResult.summary.violations) {
+            for (let error of cruiseResult.output.summary.violations) {
                 colorConsole.error(`    From: '${error.from.replace(/\.\.\//g, "").yellow}' To: '${error.to.replace(/\.\.\//g, "").yellow}'`);
             }
             process.exit(1);

+ 13 - 0
Tools/Gulp/tasks/gulpTasks-documentation.js

@@ -0,0 +1,13 @@
+// Import Dependencies.
+var gulp = require("gulp");
+var concat = require("gulp-concat");
+var replace = require("gulp-replace");
+
+// Read the full config.
+var config = require("../../Config/config.json");
+
+gulp.task("documentation", function() {
+    return gulp.src(config.build.intellisenseSources)
+        .pipe(concat(config.build.documentationFile))
+        .pipe(gulp.dest(config.build.outputDirectory));
+});

+ 0 - 27
Tools/Gulp/tasks/gulpTasks-intellisense.js

@@ -1,27 +0,0 @@
-// Import Dependencies.
-var gulp = require("gulp");
-var concat = require("gulp-concat");
-var replace = require("gulp-replace");
-
-// Read the full config.
-var config = require("../../Config/config.json");
-
-/**
- * Process the .d.ts files or Playground intellisense.
- */
-gulp.task("intellisense", function() {
-    return gulp.src(config.build.intellisenseSources)
-        .pipe(concat(config.build.intellisenseFile))
-        .pipe(replace(/^\s*readonly _/gm, "protected readonly _"))
-        .pipe(replace(/^\s*static _/gm, "private static _"))
-        .pipe(replace(/^\s*class _/gm, "private class _"))
-        .pipe(replace(/^\s* _/gm, "private _"))
-        .pipe(replace(/^\s*_/gm, "private _"))
-        .pipe(gulp.dest(config.build.playgroundDirectory));
-});
-
-gulp.task("documentation", function() {
-    return gulp.src(config.build.intellisenseSources)
-        .pipe(concat(config.build.documentationFile))
-        .pipe(gulp.dest(config.build.outputDirectory));
-});

+ 4 - 4
Viewer/package.json

@@ -29,14 +29,14 @@
         "base64-image-loader": "^1.2.1",
         "base64-inline-loader": "^1.1.1",
         "deepmerge": "~2.1.1",
-        "handlebars": "^4.1.0",
+        "handlebars": "^4.5.1",
         "html-loader": "^0.5.5",
         "json-loader": "^0.5.7",
         "ts-loader": "^4.4.0",
         "uglifyjs-webpack-plugin": "^1.2.2",
-        "webpack": "^4.16.0",
-        "webpack-cli": "^3.0.8",
-        "webpack-dev-server": "^3.1.4"
+        "webpack": "^4.29.3",
+        "webpack-cli": "^3.3.9",
+        "webpack-dev-server": "^3.1.14"
     },
     "dependencies": {
         "@babylonjs/core": "^4.0.0-alpha.18",

+ 152 - 7
dist/preview release/babylon.d.ts

@@ -16025,7 +16025,7 @@ declare module BABYLON {
          * Get the current texture matrix which includes the requested offsetting, tiling and rotation components.
          * @returns the transform matrix of the texture.
          */
-        getTextureMatrix(): Matrix;
+        getTextureMatrix(uBase?: number): Matrix;
         /**
          * Get the current matrix used to apply reflection. This is useful to rotate an environment texture for instance.
          * @returns The reflection texture transform
@@ -25595,6 +25595,11 @@ declare module BABYLON {
         private _isNotBuilt;
         private _lastParticleId;
         private _idxOfId;
+        private _multimaterialEnabled;
+        private _indicesByMaterial;
+        private _materialIndexes;
+        private _depthSortFunction;
+        private _materialSortFunction;
         /**
          * Creates a SPS (Solid Particle System) object.
          * @param name (String) is the SPS name, this will be the underlying mesh name.
@@ -25603,6 +25608,7 @@ declare module BABYLON {
          * * updatable (optional boolean, default true) : if the SPS must be updatable or immutable.
          * * isPickable (optional boolean, default false) : if the solid particles must be pickable.
          * * enableDepthSort (optional boolean, default false) : if the solid particles must be sorted in the geometry according to their distance to the camera.
+         * * enableMultiMaterial (optional boolean, default false) : if the solid particles can be given different materials.
          * * expandable (optional boolean, default false) : if particles can still be added after the initial SPS mesh creation.
          * * particleIntersection (optional boolean, default false) : if the solid particle intersections must be computed.
          * * boundingSphereOnly (optional boolean, default false) : if the particle intersection must be computed only with the bounding sphere (no bounding box computation, so faster).
@@ -25617,6 +25623,7 @@ declare module BABYLON {
             boundingSphereOnly?: boolean;
             bSphereRadiusFactor?: number;
             expandable?: boolean;
+            enableMultiMaterial?: boolean;
         });
         /**
          * Builds the SPS underlying mesh. Returns a standard Mesh.
@@ -25654,6 +25661,7 @@ declare module BABYLON {
         /**
          * Inserts the shape model geometry in the global SPS mesh by updating the positions, indices, normals, colors, uvs arrays
          * @param p the current index in the positions array to be updated
+         * @param ind the current index in the indices array
          * @param shape a Vector3 array, the shape geometry
          * @param positions the positions array to be updated
          * @param meshInd the shape indices array
@@ -25794,6 +25802,21 @@ declare module BABYLON {
          */
         getParticlesByShapeIdToRef(shapeId: number, ref: SolidParticle[]): SolidParticleSystem;
         /**
+         * Computes the required SubMeshes according the materials assigned to the particles.
+         * @returns the solid particle system.
+         * Does nothing if called before the SPS mesh is built.
+         */
+        computeSubMeshes(): SolidParticleSystem;
+        /**
+         * Sorts the solid particles by material when MultiMaterial is enabled.
+         * Updates the indices32 array.
+         * Updates the indicesByMaterial array.
+         * Updates the mesh indices array.
+         * @returns the SPS
+         * @hidden
+         */
+        private _sortParticlesByMaterial;
+        /**
          * Visibilty helper : Recomputes the visible size according to the mesh bounding box
          * doc : http://doc.babylonjs.com/how_to/Solid_Particle_System#sps-visibility
          * @returns the SPS.
@@ -25887,6 +25910,10 @@ declare module BABYLON {
          */
         readonly expandable: boolean;
         /**
+         * Gets if the SPS supports the Multi Materials
+         */
+        readonly multimaterialEnabled: boolean;
+        /**
          * This function does nothing. It may be overwritten to set all the particle first values.
          * The SPS doesn't call this function, you may have to call it by your own.
          * doc : http://doc.babylonjs.com/how_to/Solid_Particle_System#particle-management
@@ -26045,6 +26072,10 @@ declare module BABYLON {
          */
         parentId: Nullable<number>;
         /**
+         * The particle material identifier (integer) when MultiMaterials are enabled in the SPS.
+         */
+        materialIndex: Nullable<number>;
+        /**
          * The culling strategy to use to check whether the solid particle must be culled or not when using isInFrustum().
          * The possible values are :
          * - AbstractMesh.CULLINGSTRATEGY_STANDARD
@@ -26071,8 +26102,9 @@ declare module BABYLON {
          * @param idxInShape (integer) is the index of the particle in the current model (ex: the 10th box of addShape(box, 30))
          * @param sps defines the sps it is associated to
          * @param modelBoundingInfo is the reference to the model BoundingInfo used for intersection computations.
+         * @param materialIndex is the particle material identifier (integer) when the MultiMaterials are enabled in the SPS.
          */
-        constructor(particleIndex: number, particleId: number, positionIndex: number, indiceIndex: number, model: Nullable<ModelShape>, shapeId: number, idxInShape: number, sps: SolidParticleSystem, modelBoundingInfo?: Nullable<BoundingInfo>);
+        constructor(particleIndex: number, particleId: number, positionIndex: number, indiceIndex: number, model: Nullable<ModelShape>, shapeId: number, idxInShape: number, sps: SolidParticleSystem, modelBoundingInfo?: Nullable<BoundingInfo>, materialIndex?: Nullable<number>);
         /**
          * Copies the particle property values into the existing target : position, rotation, scaling, uvs, colors, pivot, parent, visibility, alive
          * @param target the particle target
@@ -26172,6 +26204,7 @@ declare module BABYLON {
     }
     /**
      * Represents a Depth Sorted Particle in the solid particle system.
+     * @hidden
      */
     export class DepthSortedParticle {
         /**
@@ -26186,6 +26219,15 @@ declare module BABYLON {
          * Squared distance from the particle to the camera
          */
         sqDistance: number;
+        /**
+         * Material index when used with MultiMaterials
+         */
+        materialIndex: number;
+        /**
+         * Creates a new sorted particle
+         * @param materialIndex
+         */
+        constructor(ind: number, indLength: number, materialIndex: number);
     }
 }
 declare module BABYLON {
@@ -29381,6 +29423,8 @@ declare module BABYLON {
         deterministicLockstep?: boolean;
         /** Defines the maximum steps to use with deterministic lock step mode */
         lockstepMaxSteps?: number;
+        /** Defines the seconds between each deterministic lock step */
+        timeStep?: number;
         /**
          * Defines that engine should ignore context lost events
          * If this event happens when this parameter is true, you will have to reload the page to restore rendering
@@ -30381,6 +30425,11 @@ declare module BABYLON {
          * @returns frame number
          */
         static QueueNewFrame(func: () => void, requester?: any): number;
+        /**
+         * Gets host document
+         * @returns the host document object
+         */
+        getHostDocument(): Document;
     }
 }
 declare module BABYLON {
@@ -31682,6 +31731,7 @@ declare module BABYLON {
         protected _alphaEquation: number;
         private _deterministicLockstep;
         private _lockstepMaxSteps;
+        private _timeStep;
         protected readonly _supportsHardwareTextureRescaling: boolean;
         private _fps;
         private _deltaTime;
@@ -31730,11 +31780,6 @@ declare module BABYLON {
          */
         getScreenAspectRatio(): number;
         /**
-         * Gets host document
-         * @returns the host document object
-         */
-        getHostDocument(): Document;
-        /**
          * Gets the client rect of the HTML canvas attached with the current webGL context
          * @returns a client rectanglee
          */
@@ -31757,6 +31802,11 @@ declare module BABYLON {
          */
         getLockstepMaxSteps(): number;
         /**
+         * Returns the time in ms between steps when using deterministic lock step.
+         * @returns time step in (ms)
+         */
+        getTimeStep(): number;
+        /**
          * Force the mipmap generation for the given render target texture
          * @param texture defines the render target texture to use
          */
@@ -54016,6 +54066,7 @@ declare module BABYLON {
         autoConfigure(material: NodeMaterial): void;
         initializeDefines(mesh: AbstractMesh, nodeMaterial: NodeMaterial, defines: NodeMaterialDefines, useInstances?: boolean): void;
         prepareDefines(mesh: AbstractMesh, nodeMaterial: NodeMaterial, defines: NodeMaterialDefines): void;
+        private _getTextureBase;
         isReady(): boolean;
         bind(effect: Effect, nodeMaterial: NodeMaterial, mesh?: Mesh): void;
         private readonly _isMixed;
@@ -55081,6 +55132,36 @@ declare module BABYLON {
 }
 declare module BABYLON {
     /**
+     * Block used to get the derivative value on x and y of a given input
+     */
+    export class DerivativeBlock extends NodeMaterialBlock {
+        /**
+         * Create a new DerivativeBlock
+         * @param name defines the block name
+         */
+        constructor(name: string);
+        /**
+         * Gets the current class name
+         * @returns the class name
+         */
+        getClassName(): string;
+        /**
+         * Gets the input component
+         */
+        readonly input: NodeMaterialConnectionPoint;
+        /**
+         * Gets the derivative output on x
+         */
+        readonly dx: NodeMaterialConnectionPoint;
+        /**
+         * Gets the derivative output on y
+         */
+        readonly dy: NodeMaterialConnectionPoint;
+        protected _buildBlock(state: NodeMaterialBuildState): this;
+    }
+}
+declare module BABYLON {
+    /**
      * Block used to add support for scene fog
      */
     export class FogBlock extends NodeMaterialBlock {
@@ -56564,6 +56645,70 @@ declare module BABYLON {
 }
 declare module BABYLON {
     /**
+     * Block used to get the reflected vector from a direction and a normal
+     */
+    export class ReflectBlock extends NodeMaterialBlock {
+        /**
+         * Creates a new ReflectBlock
+         * @param name defines the block name
+         */
+        constructor(name: string);
+        /**
+         * Gets the current class name
+         * @returns the class name
+         */
+        getClassName(): string;
+        /**
+         * Gets the incident component
+         */
+        readonly incident: NodeMaterialConnectionPoint;
+        /**
+         * Gets the normal component
+         */
+        readonly normal: NodeMaterialConnectionPoint;
+        /**
+         * Gets the output component
+         */
+        readonly output: NodeMaterialConnectionPoint;
+        protected _buildBlock(state: NodeMaterialBuildState): this;
+    }
+}
+declare module BABYLON {
+    /**
+     * Block used to get the refracted vector from a direction and a normal
+     */
+    export class RefractBlock extends NodeMaterialBlock {
+        /**
+         * Creates a new RefractBlock
+         * @param name defines the block name
+         */
+        constructor(name: string);
+        /**
+         * Gets the current class name
+         * @returns the class name
+         */
+        getClassName(): string;
+        /**
+         * Gets the incident component
+         */
+        readonly incident: NodeMaterialConnectionPoint;
+        /**
+         * Gets the normal component
+         */
+        readonly normal: NodeMaterialConnectionPoint;
+        /**
+         * Gets the index of refraction component
+         */
+        readonly ior: NodeMaterialConnectionPoint;
+        /**
+         * Gets the output component
+         */
+        readonly output: NodeMaterialConnectionPoint;
+        protected _buildBlock(state: NodeMaterialBuildState): this;
+    }
+}
+declare module BABYLON {
+    /**
      * Effect Render Options
      */
     export interface IEffectRendererOptions {

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


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


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


+ 316 - 14
dist/preview release/babylon.module.d.ts

@@ -16426,7 +16426,7 @@ declare module "babylonjs/Materials/Textures/texture" {
          * Get the current texture matrix which includes the requested offsetting, tiling and rotation components.
          * @returns the transform matrix of the texture.
          */
-        getTextureMatrix(): Matrix;
+        getTextureMatrix(uBase?: number): Matrix;
         /**
          * Get the current matrix used to apply reflection. This is useful to rotate an environment texture for instance.
          * @returns The reflection texture transform
@@ -26345,6 +26345,11 @@ declare module "babylonjs/Particles/solidParticleSystem" {
         private _isNotBuilt;
         private _lastParticleId;
         private _idxOfId;
+        private _multimaterialEnabled;
+        private _indicesByMaterial;
+        private _materialIndexes;
+        private _depthSortFunction;
+        private _materialSortFunction;
         /**
          * Creates a SPS (Solid Particle System) object.
          * @param name (String) is the SPS name, this will be the underlying mesh name.
@@ -26353,6 +26358,7 @@ declare module "babylonjs/Particles/solidParticleSystem" {
          * * updatable (optional boolean, default true) : if the SPS must be updatable or immutable.
          * * isPickable (optional boolean, default false) : if the solid particles must be pickable.
          * * enableDepthSort (optional boolean, default false) : if the solid particles must be sorted in the geometry according to their distance to the camera.
+         * * enableMultiMaterial (optional boolean, default false) : if the solid particles can be given different materials.
          * * expandable (optional boolean, default false) : if particles can still be added after the initial SPS mesh creation.
          * * particleIntersection (optional boolean, default false) : if the solid particle intersections must be computed.
          * * boundingSphereOnly (optional boolean, default false) : if the particle intersection must be computed only with the bounding sphere (no bounding box computation, so faster).
@@ -26367,6 +26373,7 @@ declare module "babylonjs/Particles/solidParticleSystem" {
             boundingSphereOnly?: boolean;
             bSphereRadiusFactor?: number;
             expandable?: boolean;
+            enableMultiMaterial?: boolean;
         });
         /**
          * Builds the SPS underlying mesh. Returns a standard Mesh.
@@ -26404,6 +26411,7 @@ declare module "babylonjs/Particles/solidParticleSystem" {
         /**
          * Inserts the shape model geometry in the global SPS mesh by updating the positions, indices, normals, colors, uvs arrays
          * @param p the current index in the positions array to be updated
+         * @param ind the current index in the indices array
          * @param shape a Vector3 array, the shape geometry
          * @param positions the positions array to be updated
          * @param meshInd the shape indices array
@@ -26544,6 +26552,21 @@ declare module "babylonjs/Particles/solidParticleSystem" {
          */
         getParticlesByShapeIdToRef(shapeId: number, ref: SolidParticle[]): SolidParticleSystem;
         /**
+         * Computes the required SubMeshes according the materials assigned to the particles.
+         * @returns the solid particle system.
+         * Does nothing if called before the SPS mesh is built.
+         */
+        computeSubMeshes(): SolidParticleSystem;
+        /**
+         * Sorts the solid particles by material when MultiMaterial is enabled.
+         * Updates the indices32 array.
+         * Updates the indicesByMaterial array.
+         * Updates the mesh indices array.
+         * @returns the SPS
+         * @hidden
+         */
+        private _sortParticlesByMaterial;
+        /**
          * Visibilty helper : Recomputes the visible size according to the mesh bounding box
          * doc : http://doc.babylonjs.com/how_to/Solid_Particle_System#sps-visibility
          * @returns the SPS.
@@ -26637,6 +26660,10 @@ declare module "babylonjs/Particles/solidParticleSystem" {
          */
         readonly expandable: boolean;
         /**
+         * Gets if the SPS supports the Multi Materials
+         */
+        readonly multimaterialEnabled: boolean;
+        /**
          * This function does nothing. It may be overwritten to set all the particle first values.
          * The SPS doesn't call this function, you may have to call it by your own.
          * doc : http://doc.babylonjs.com/how_to/Solid_Particle_System#particle-management
@@ -26802,6 +26829,10 @@ declare module "babylonjs/Particles/solidParticle" {
          */
         parentId: Nullable<number>;
         /**
+         * The particle material identifier (integer) when MultiMaterials are enabled in the SPS.
+         */
+        materialIndex: Nullable<number>;
+        /**
          * The culling strategy to use to check whether the solid particle must be culled or not when using isInFrustum().
          * The possible values are :
          * - AbstractMesh.CULLINGSTRATEGY_STANDARD
@@ -26828,8 +26859,9 @@ declare module "babylonjs/Particles/solidParticle" {
          * @param idxInShape (integer) is the index of the particle in the current model (ex: the 10th box of addShape(box, 30))
          * @param sps defines the sps it is associated to
          * @param modelBoundingInfo is the reference to the model BoundingInfo used for intersection computations.
+         * @param materialIndex is the particle material identifier (integer) when the MultiMaterials are enabled in the SPS.
          */
-        constructor(particleIndex: number, particleId: number, positionIndex: number, indiceIndex: number, model: Nullable<ModelShape>, shapeId: number, idxInShape: number, sps: SolidParticleSystem, modelBoundingInfo?: Nullable<BoundingInfo>);
+        constructor(particleIndex: number, particleId: number, positionIndex: number, indiceIndex: number, model: Nullable<ModelShape>, shapeId: number, idxInShape: number, sps: SolidParticleSystem, modelBoundingInfo?: Nullable<BoundingInfo>, materialIndex?: Nullable<number>);
         /**
          * Copies the particle property values into the existing target : position, rotation, scaling, uvs, colors, pivot, parent, visibility, alive
          * @param target the particle target
@@ -26929,6 +26961,7 @@ declare module "babylonjs/Particles/solidParticle" {
     }
     /**
      * Represents a Depth Sorted Particle in the solid particle system.
+     * @hidden
      */
     export class DepthSortedParticle {
         /**
@@ -26943,6 +26976,15 @@ declare module "babylonjs/Particles/solidParticle" {
          * Squared distance from the particle to the camera
          */
         sqDistance: number;
+        /**
+         * Material index when used with MultiMaterials
+         */
+        materialIndex: number;
+        /**
+         * Creates a new sorted particle
+         * @param materialIndex
+         */
+        constructor(ind: number, indLength: number, materialIndex: number);
     }
 }
 declare module "babylonjs/Collisions/meshCollisionData" {
@@ -30261,6 +30303,8 @@ declare module "babylonjs/Engines/thinEngine" {
         deterministicLockstep?: boolean;
         /** Defines the maximum steps to use with deterministic lock step mode */
         lockstepMaxSteps?: number;
+        /** Defines the seconds between each deterministic lock step */
+        timeStep?: number;
         /**
          * Defines that engine should ignore context lost events
          * If this event happens when this parameter is true, you will have to reload the page to restore rendering
@@ -31261,6 +31305,11 @@ declare module "babylonjs/Engines/thinEngine" {
          * @returns frame number
          */
         static QueueNewFrame(func: () => void, requester?: any): number;
+        /**
+         * Gets host document
+         * @returns the host document object
+         */
+        getHostDocument(): Document;
     }
 }
 declare module "babylonjs/Maths/sphericalPolynomial" {
@@ -32592,6 +32641,7 @@ declare module "babylonjs/Engines/engine" {
         protected _alphaEquation: number;
         private _deterministicLockstep;
         private _lockstepMaxSteps;
+        private _timeStep;
         protected readonly _supportsHardwareTextureRescaling: boolean;
         private _fps;
         private _deltaTime;
@@ -32640,11 +32690,6 @@ declare module "babylonjs/Engines/engine" {
          */
         getScreenAspectRatio(): number;
         /**
-         * Gets host document
-         * @returns the host document object
-         */
-        getHostDocument(): Document;
-        /**
          * Gets the client rect of the HTML canvas attached with the current webGL context
          * @returns a client rectanglee
          */
@@ -32667,6 +32712,11 @@ declare module "babylonjs/Engines/engine" {
          */
         getLockstepMaxSteps(): number;
         /**
+         * Returns the time in ms between steps when using deterministic lock step.
+         * @returns time step in (ms)
+         */
+        getTimeStep(): number;
+        /**
          * Force the mipmap generation for the given render target texture
          * @param texture defines the render target texture to use
          */
@@ -56574,6 +56624,7 @@ declare module "babylonjs/Materials/Node/Blocks/Dual/textureBlock" {
         autoConfigure(material: NodeMaterial): void;
         initializeDefines(mesh: AbstractMesh, nodeMaterial: NodeMaterial, defines: NodeMaterialDefines, useInstances?: boolean): void;
         prepareDefines(mesh: AbstractMesh, nodeMaterial: NodeMaterial, defines: NodeMaterialDefines): void;
+        private _getTextureBase;
         isReady(): boolean;
         bind(effect: Effect, nodeMaterial: NodeMaterial, mesh?: Mesh): void;
         private readonly _isMixed;
@@ -57741,12 +57792,46 @@ declare module "babylonjs/Materials/Node/Blocks/Fragment/frontFacingBlock" {
         protected _buildBlock(state: NodeMaterialBuildState): this;
     }
 }
+declare module "babylonjs/Materials/Node/Blocks/Fragment/derivativeBlock" {
+    import { NodeMaterialBlock } from "babylonjs/Materials/Node/nodeMaterialBlock";
+    import { NodeMaterialBuildState } from "babylonjs/Materials/Node/nodeMaterialBuildState";
+    import { NodeMaterialConnectionPoint } from "babylonjs/Materials/Node/nodeMaterialBlockConnectionPoint";
+    /**
+     * Block used to get the derivative value on x and y of a given input
+     */
+    export class DerivativeBlock extends NodeMaterialBlock {
+        /**
+         * Create a new DerivativeBlock
+         * @param name defines the block name
+         */
+        constructor(name: string);
+        /**
+         * Gets the current class name
+         * @returns the class name
+         */
+        getClassName(): string;
+        /**
+         * Gets the input component
+         */
+        readonly input: NodeMaterialConnectionPoint;
+        /**
+         * Gets the derivative output on x
+         */
+        readonly dx: NodeMaterialConnectionPoint;
+        /**
+         * Gets the derivative output on y
+         */
+        readonly dy: NodeMaterialConnectionPoint;
+        protected _buildBlock(state: NodeMaterialBuildState): this;
+    }
+}
 declare module "babylonjs/Materials/Node/Blocks/Fragment/index" {
     export * from "babylonjs/Materials/Node/Blocks/Fragment/fragmentOutputBlock";
     export * from "babylonjs/Materials/Node/Blocks/Fragment/imageProcessingBlock";
     export * from "babylonjs/Materials/Node/Blocks/Fragment/perturbNormalBlock";
     export * from "babylonjs/Materials/Node/Blocks/Fragment/discardBlock";
     export * from "babylonjs/Materials/Node/Blocks/Fragment/frontFacingBlock";
+    export * from "babylonjs/Materials/Node/Blocks/Fragment/derivativeBlock";
 }
 declare module "babylonjs/Materials/Node/Blocks/Dual/fogBlock" {
     import { NodeMaterialBlock } from "babylonjs/Materials/Node/nodeMaterialBlock";
@@ -59396,6 +59481,76 @@ declare module "babylonjs/Materials/Node/Blocks/rotate2dBlock" {
         protected _buildBlock(state: NodeMaterialBuildState): this;
     }
 }
+declare module "babylonjs/Materials/Node/Blocks/reflectBlock" {
+    import { NodeMaterialBlock } from "babylonjs/Materials/Node/nodeMaterialBlock";
+    import { NodeMaterialBuildState } from "babylonjs/Materials/Node/nodeMaterialBuildState";
+    import { NodeMaterialConnectionPoint } from "babylonjs/Materials/Node/nodeMaterialBlockConnectionPoint";
+    /**
+     * Block used to get the reflected vector from a direction and a normal
+     */
+    export class ReflectBlock extends NodeMaterialBlock {
+        /**
+         * Creates a new ReflectBlock
+         * @param name defines the block name
+         */
+        constructor(name: string);
+        /**
+         * Gets the current class name
+         * @returns the class name
+         */
+        getClassName(): string;
+        /**
+         * Gets the incident component
+         */
+        readonly incident: NodeMaterialConnectionPoint;
+        /**
+         * Gets the normal component
+         */
+        readonly normal: NodeMaterialConnectionPoint;
+        /**
+         * Gets the output component
+         */
+        readonly output: NodeMaterialConnectionPoint;
+        protected _buildBlock(state: NodeMaterialBuildState): this;
+    }
+}
+declare module "babylonjs/Materials/Node/Blocks/refractBlock" {
+    import { NodeMaterialBlock } from "babylonjs/Materials/Node/nodeMaterialBlock";
+    import { NodeMaterialBuildState } from "babylonjs/Materials/Node/nodeMaterialBuildState";
+    import { NodeMaterialConnectionPoint } from "babylonjs/Materials/Node/nodeMaterialBlockConnectionPoint";
+    /**
+     * Block used to get the refracted vector from a direction and a normal
+     */
+    export class RefractBlock extends NodeMaterialBlock {
+        /**
+         * Creates a new RefractBlock
+         * @param name defines the block name
+         */
+        constructor(name: string);
+        /**
+         * Gets the current class name
+         * @returns the class name
+         */
+        getClassName(): string;
+        /**
+         * Gets the incident component
+         */
+        readonly incident: NodeMaterialConnectionPoint;
+        /**
+         * Gets the normal component
+         */
+        readonly normal: NodeMaterialConnectionPoint;
+        /**
+         * Gets the index of refraction component
+         */
+        readonly ior: NodeMaterialConnectionPoint;
+        /**
+         * Gets the output component
+         */
+        readonly output: NodeMaterialConnectionPoint;
+        protected _buildBlock(state: NodeMaterialBuildState): this;
+    }
+}
 declare module "babylonjs/Materials/Node/Blocks/index" {
     export * from "babylonjs/Materials/Node/Blocks/Vertex/index";
     export * from "babylonjs/Materials/Node/Blocks/Fragment/index";
@@ -59441,6 +59596,8 @@ declare module "babylonjs/Materials/Node/Blocks/index" {
     export * from "babylonjs/Materials/Node/Blocks/simplexPerlin3DBlock";
     export * from "babylonjs/Materials/Node/Blocks/normalBlendBlock";
     export * from "babylonjs/Materials/Node/Blocks/rotate2dBlock";
+    export * from "babylonjs/Materials/Node/Blocks/reflectBlock";
+    export * from "babylonjs/Materials/Node/Blocks/refractBlock";
 }
 declare module "babylonjs/Materials/Node/Optimizers/index" {
     export * from "babylonjs/Materials/Node/Optimizers/nodeMaterialOptimizer";
@@ -84448,7 +84605,7 @@ declare module BABYLON {
          * Get the current texture matrix which includes the requested offsetting, tiling and rotation components.
          * @returns the transform matrix of the texture.
          */
-        getTextureMatrix(): Matrix;
+        getTextureMatrix(uBase?: number): Matrix;
         /**
          * Get the current matrix used to apply reflection. This is useful to rotate an environment texture for instance.
          * @returns The reflection texture transform
@@ -94018,6 +94175,11 @@ declare module BABYLON {
         private _isNotBuilt;
         private _lastParticleId;
         private _idxOfId;
+        private _multimaterialEnabled;
+        private _indicesByMaterial;
+        private _materialIndexes;
+        private _depthSortFunction;
+        private _materialSortFunction;
         /**
          * Creates a SPS (Solid Particle System) object.
          * @param name (String) is the SPS name, this will be the underlying mesh name.
@@ -94026,6 +94188,7 @@ declare module BABYLON {
          * * updatable (optional boolean, default true) : if the SPS must be updatable or immutable.
          * * isPickable (optional boolean, default false) : if the solid particles must be pickable.
          * * enableDepthSort (optional boolean, default false) : if the solid particles must be sorted in the geometry according to their distance to the camera.
+         * * enableMultiMaterial (optional boolean, default false) : if the solid particles can be given different materials.
          * * expandable (optional boolean, default false) : if particles can still be added after the initial SPS mesh creation.
          * * particleIntersection (optional boolean, default false) : if the solid particle intersections must be computed.
          * * boundingSphereOnly (optional boolean, default false) : if the particle intersection must be computed only with the bounding sphere (no bounding box computation, so faster).
@@ -94040,6 +94203,7 @@ declare module BABYLON {
             boundingSphereOnly?: boolean;
             bSphereRadiusFactor?: number;
             expandable?: boolean;
+            enableMultiMaterial?: boolean;
         });
         /**
          * Builds the SPS underlying mesh. Returns a standard Mesh.
@@ -94077,6 +94241,7 @@ declare module BABYLON {
         /**
          * Inserts the shape model geometry in the global SPS mesh by updating the positions, indices, normals, colors, uvs arrays
          * @param p the current index in the positions array to be updated
+         * @param ind the current index in the indices array
          * @param shape a Vector3 array, the shape geometry
          * @param positions the positions array to be updated
          * @param meshInd the shape indices array
@@ -94217,6 +94382,21 @@ declare module BABYLON {
          */
         getParticlesByShapeIdToRef(shapeId: number, ref: SolidParticle[]): SolidParticleSystem;
         /**
+         * Computes the required SubMeshes according the materials assigned to the particles.
+         * @returns the solid particle system.
+         * Does nothing if called before the SPS mesh is built.
+         */
+        computeSubMeshes(): SolidParticleSystem;
+        /**
+         * Sorts the solid particles by material when MultiMaterial is enabled.
+         * Updates the indices32 array.
+         * Updates the indicesByMaterial array.
+         * Updates the mesh indices array.
+         * @returns the SPS
+         * @hidden
+         */
+        private _sortParticlesByMaterial;
+        /**
          * Visibilty helper : Recomputes the visible size according to the mesh bounding box
          * doc : http://doc.babylonjs.com/how_to/Solid_Particle_System#sps-visibility
          * @returns the SPS.
@@ -94310,6 +94490,10 @@ declare module BABYLON {
          */
         readonly expandable: boolean;
         /**
+         * Gets if the SPS supports the Multi Materials
+         */
+        readonly multimaterialEnabled: boolean;
+        /**
          * This function does nothing. It may be overwritten to set all the particle first values.
          * The SPS doesn't call this function, you may have to call it by your own.
          * doc : http://doc.babylonjs.com/how_to/Solid_Particle_System#particle-management
@@ -94468,6 +94652,10 @@ declare module BABYLON {
          */
         parentId: Nullable<number>;
         /**
+         * The particle material identifier (integer) when MultiMaterials are enabled in the SPS.
+         */
+        materialIndex: Nullable<number>;
+        /**
          * The culling strategy to use to check whether the solid particle must be culled or not when using isInFrustum().
          * The possible values are :
          * - AbstractMesh.CULLINGSTRATEGY_STANDARD
@@ -94494,8 +94682,9 @@ declare module BABYLON {
          * @param idxInShape (integer) is the index of the particle in the current model (ex: the 10th box of addShape(box, 30))
          * @param sps defines the sps it is associated to
          * @param modelBoundingInfo is the reference to the model BoundingInfo used for intersection computations.
+         * @param materialIndex is the particle material identifier (integer) when the MultiMaterials are enabled in the SPS.
          */
-        constructor(particleIndex: number, particleId: number, positionIndex: number, indiceIndex: number, model: Nullable<ModelShape>, shapeId: number, idxInShape: number, sps: SolidParticleSystem, modelBoundingInfo?: Nullable<BoundingInfo>);
+        constructor(particleIndex: number, particleId: number, positionIndex: number, indiceIndex: number, model: Nullable<ModelShape>, shapeId: number, idxInShape: number, sps: SolidParticleSystem, modelBoundingInfo?: Nullable<BoundingInfo>, materialIndex?: Nullable<number>);
         /**
          * Copies the particle property values into the existing target : position, rotation, scaling, uvs, colors, pivot, parent, visibility, alive
          * @param target the particle target
@@ -94595,6 +94784,7 @@ declare module BABYLON {
     }
     /**
      * Represents a Depth Sorted Particle in the solid particle system.
+     * @hidden
      */
     export class DepthSortedParticle {
         /**
@@ -94609,6 +94799,15 @@ declare module BABYLON {
          * Squared distance from the particle to the camera
          */
         sqDistance: number;
+        /**
+         * Material index when used with MultiMaterials
+         */
+        materialIndex: number;
+        /**
+         * Creates a new sorted particle
+         * @param materialIndex
+         */
+        constructor(ind: number, indLength: number, materialIndex: number);
     }
 }
 declare module BABYLON {
@@ -97804,6 +98003,8 @@ declare module BABYLON {
         deterministicLockstep?: boolean;
         /** Defines the maximum steps to use with deterministic lock step mode */
         lockstepMaxSteps?: number;
+        /** Defines the seconds between each deterministic lock step */
+        timeStep?: number;
         /**
          * Defines that engine should ignore context lost events
          * If this event happens when this parameter is true, you will have to reload the page to restore rendering
@@ -98804,6 +99005,11 @@ declare module BABYLON {
          * @returns frame number
          */
         static QueueNewFrame(func: () => void, requester?: any): number;
+        /**
+         * Gets host document
+         * @returns the host document object
+         */
+        getHostDocument(): Document;
     }
 }
 declare module BABYLON {
@@ -100105,6 +100311,7 @@ declare module BABYLON {
         protected _alphaEquation: number;
         private _deterministicLockstep;
         private _lockstepMaxSteps;
+        private _timeStep;
         protected readonly _supportsHardwareTextureRescaling: boolean;
         private _fps;
         private _deltaTime;
@@ -100153,11 +100360,6 @@ declare module BABYLON {
          */
         getScreenAspectRatio(): number;
         /**
-         * Gets host document
-         * @returns the host document object
-         */
-        getHostDocument(): Document;
-        /**
          * Gets the client rect of the HTML canvas attached with the current webGL context
          * @returns a client rectanglee
          */
@@ -100180,6 +100382,11 @@ declare module BABYLON {
          */
         getLockstepMaxSteps(): number;
         /**
+         * Returns the time in ms between steps when using deterministic lock step.
+         * @returns time step in (ms)
+         */
+        getTimeStep(): number;
+        /**
          * Force the mipmap generation for the given render target texture
          * @param texture defines the render target texture to use
          */
@@ -122439,6 +122646,7 @@ declare module BABYLON {
         autoConfigure(material: NodeMaterial): void;
         initializeDefines(mesh: AbstractMesh, nodeMaterial: NodeMaterial, defines: NodeMaterialDefines, useInstances?: boolean): void;
         prepareDefines(mesh: AbstractMesh, nodeMaterial: NodeMaterial, defines: NodeMaterialDefines): void;
+        private _getTextureBase;
         isReady(): boolean;
         bind(effect: Effect, nodeMaterial: NodeMaterial, mesh?: Mesh): void;
         private readonly _isMixed;
@@ -123504,6 +123712,36 @@ declare module BABYLON {
 }
 declare module BABYLON {
     /**
+     * Block used to get the derivative value on x and y of a given input
+     */
+    export class DerivativeBlock extends NodeMaterialBlock {
+        /**
+         * Create a new DerivativeBlock
+         * @param name defines the block name
+         */
+        constructor(name: string);
+        /**
+         * Gets the current class name
+         * @returns the class name
+         */
+        getClassName(): string;
+        /**
+         * Gets the input component
+         */
+        readonly input: NodeMaterialConnectionPoint;
+        /**
+         * Gets the derivative output on x
+         */
+        readonly dx: NodeMaterialConnectionPoint;
+        /**
+         * Gets the derivative output on y
+         */
+        readonly dy: NodeMaterialConnectionPoint;
+        protected _buildBlock(state: NodeMaterialBuildState): this;
+    }
+}
+declare module BABYLON {
+    /**
      * Block used to add support for scene fog
      */
     export class FogBlock extends NodeMaterialBlock {
@@ -124987,6 +125225,70 @@ declare module BABYLON {
 }
 declare module BABYLON {
     /**
+     * Block used to get the reflected vector from a direction and a normal
+     */
+    export class ReflectBlock extends NodeMaterialBlock {
+        /**
+         * Creates a new ReflectBlock
+         * @param name defines the block name
+         */
+        constructor(name: string);
+        /**
+         * Gets the current class name
+         * @returns the class name
+         */
+        getClassName(): string;
+        /**
+         * Gets the incident component
+         */
+        readonly incident: NodeMaterialConnectionPoint;
+        /**
+         * Gets the normal component
+         */
+        readonly normal: NodeMaterialConnectionPoint;
+        /**
+         * Gets the output component
+         */
+        readonly output: NodeMaterialConnectionPoint;
+        protected _buildBlock(state: NodeMaterialBuildState): this;
+    }
+}
+declare module BABYLON {
+    /**
+     * Block used to get the refracted vector from a direction and a normal
+     */
+    export class RefractBlock extends NodeMaterialBlock {
+        /**
+         * Creates a new RefractBlock
+         * @param name defines the block name
+         */
+        constructor(name: string);
+        /**
+         * Gets the current class name
+         * @returns the class name
+         */
+        getClassName(): string;
+        /**
+         * Gets the incident component
+         */
+        readonly incident: NodeMaterialConnectionPoint;
+        /**
+         * Gets the normal component
+         */
+        readonly normal: NodeMaterialConnectionPoint;
+        /**
+         * Gets the index of refraction component
+         */
+        readonly ior: NodeMaterialConnectionPoint;
+        /**
+         * Gets the output component
+         */
+        readonly output: NodeMaterialConnectionPoint;
+        protected _buildBlock(state: NodeMaterialBuildState): this;
+    }
+}
+declare module BABYLON {
+    /**
      * Effect Render Options
      */
     export interface IEffectRendererOptions {

+ 173 - 7
dist/preview release/documentation.d.ts

@@ -16025,7 +16025,7 @@ declare module BABYLON {
          * Get the current texture matrix which includes the requested offsetting, tiling and rotation components.
          * @returns the transform matrix of the texture.
          */
-        getTextureMatrix(): Matrix;
+        getTextureMatrix(uBase?: number): Matrix;
         /**
          * Get the current matrix used to apply reflection. This is useful to rotate an environment texture for instance.
          * @returns The reflection texture transform
@@ -25595,6 +25595,11 @@ declare module BABYLON {
         private _isNotBuilt;
         private _lastParticleId;
         private _idxOfId;
+        private _multimaterialEnabled;
+        private _indicesByMaterial;
+        private _materialIndexes;
+        private _depthSortFunction;
+        private _materialSortFunction;
         /**
          * Creates a SPS (Solid Particle System) object.
          * @param name (String) is the SPS name, this will be the underlying mesh name.
@@ -25603,6 +25608,7 @@ declare module BABYLON {
          * * updatable (optional boolean, default true) : if the SPS must be updatable or immutable.
          * * isPickable (optional boolean, default false) : if the solid particles must be pickable.
          * * enableDepthSort (optional boolean, default false) : if the solid particles must be sorted in the geometry according to their distance to the camera.
+         * * enableMultiMaterial (optional boolean, default false) : if the solid particles can be given different materials.
          * * expandable (optional boolean, default false) : if particles can still be added after the initial SPS mesh creation.
          * * particleIntersection (optional boolean, default false) : if the solid particle intersections must be computed.
          * * boundingSphereOnly (optional boolean, default false) : if the particle intersection must be computed only with the bounding sphere (no bounding box computation, so faster).
@@ -25617,6 +25623,7 @@ declare module BABYLON {
             boundingSphereOnly?: boolean;
             bSphereRadiusFactor?: number;
             expandable?: boolean;
+            enableMultiMaterial?: boolean;
         });
         /**
          * Builds the SPS underlying mesh. Returns a standard Mesh.
@@ -25654,6 +25661,7 @@ declare module BABYLON {
         /**
          * Inserts the shape model geometry in the global SPS mesh by updating the positions, indices, normals, colors, uvs arrays
          * @param p the current index in the positions array to be updated
+         * @param ind the current index in the indices array
          * @param shape a Vector3 array, the shape geometry
          * @param positions the positions array to be updated
          * @param meshInd the shape indices array
@@ -25794,6 +25802,21 @@ declare module BABYLON {
          */
         getParticlesByShapeIdToRef(shapeId: number, ref: SolidParticle[]): SolidParticleSystem;
         /**
+         * Computes the required SubMeshes according the materials assigned to the particles.
+         * @returns the solid particle system.
+         * Does nothing if called before the SPS mesh is built.
+         */
+        computeSubMeshes(): SolidParticleSystem;
+        /**
+         * Sorts the solid particles by material when MultiMaterial is enabled.
+         * Updates the indices32 array.
+         * Updates the indicesByMaterial array.
+         * Updates the mesh indices array.
+         * @returns the SPS
+         * @hidden
+         */
+        private _sortParticlesByMaterial;
+        /**
          * Visibilty helper : Recomputes the visible size according to the mesh bounding box
          * doc : http://doc.babylonjs.com/how_to/Solid_Particle_System#sps-visibility
          * @returns the SPS.
@@ -25887,6 +25910,10 @@ declare module BABYLON {
          */
         readonly expandable: boolean;
         /**
+         * Gets if the SPS supports the Multi Materials
+         */
+        readonly multimaterialEnabled: boolean;
+        /**
          * This function does nothing. It may be overwritten to set all the particle first values.
          * The SPS doesn't call this function, you may have to call it by your own.
          * doc : http://doc.babylonjs.com/how_to/Solid_Particle_System#particle-management
@@ -26045,6 +26072,10 @@ declare module BABYLON {
          */
         parentId: Nullable<number>;
         /**
+         * The particle material identifier (integer) when MultiMaterials are enabled in the SPS.
+         */
+        materialIndex: Nullable<number>;
+        /**
          * The culling strategy to use to check whether the solid particle must be culled or not when using isInFrustum().
          * The possible values are :
          * - AbstractMesh.CULLINGSTRATEGY_STANDARD
@@ -26071,8 +26102,9 @@ declare module BABYLON {
          * @param idxInShape (integer) is the index of the particle in the current model (ex: the 10th box of addShape(box, 30))
          * @param sps defines the sps it is associated to
          * @param modelBoundingInfo is the reference to the model BoundingInfo used for intersection computations.
+         * @param materialIndex is the particle material identifier (integer) when the MultiMaterials are enabled in the SPS.
          */
-        constructor(particleIndex: number, particleId: number, positionIndex: number, indiceIndex: number, model: Nullable<ModelShape>, shapeId: number, idxInShape: number, sps: SolidParticleSystem, modelBoundingInfo?: Nullable<BoundingInfo>);
+        constructor(particleIndex: number, particleId: number, positionIndex: number, indiceIndex: number, model: Nullable<ModelShape>, shapeId: number, idxInShape: number, sps: SolidParticleSystem, modelBoundingInfo?: Nullable<BoundingInfo>, materialIndex?: Nullable<number>);
         /**
          * Copies the particle property values into the existing target : position, rotation, scaling, uvs, colors, pivot, parent, visibility, alive
          * @param target the particle target
@@ -26172,6 +26204,7 @@ declare module BABYLON {
     }
     /**
      * Represents a Depth Sorted Particle in the solid particle system.
+     * @hidden
      */
     export class DepthSortedParticle {
         /**
@@ -26186,6 +26219,15 @@ declare module BABYLON {
          * Squared distance from the particle to the camera
          */
         sqDistance: number;
+        /**
+         * Material index when used with MultiMaterials
+         */
+        materialIndex: number;
+        /**
+         * Creates a new sorted particle
+         * @param materialIndex
+         */
+        constructor(ind: number, indLength: number, materialIndex: number);
     }
 }
 declare module BABYLON {
@@ -29381,6 +29423,8 @@ declare module BABYLON {
         deterministicLockstep?: boolean;
         /** Defines the maximum steps to use with deterministic lock step mode */
         lockstepMaxSteps?: number;
+        /** Defines the seconds between each deterministic lock step */
+        timeStep?: number;
         /**
          * Defines that engine should ignore context lost events
          * If this event happens when this parameter is true, you will have to reload the page to restore rendering
@@ -30381,6 +30425,11 @@ declare module BABYLON {
          * @returns frame number
          */
         static QueueNewFrame(func: () => void, requester?: any): number;
+        /**
+         * Gets host document
+         * @returns the host document object
+         */
+        getHostDocument(): Document;
     }
 }
 declare module BABYLON {
@@ -31682,6 +31731,7 @@ declare module BABYLON {
         protected _alphaEquation: number;
         private _deterministicLockstep;
         private _lockstepMaxSteps;
+        private _timeStep;
         protected readonly _supportsHardwareTextureRescaling: boolean;
         private _fps;
         private _deltaTime;
@@ -31730,11 +31780,6 @@ declare module BABYLON {
          */
         getScreenAspectRatio(): number;
         /**
-         * Gets host document
-         * @returns the host document object
-         */
-        getHostDocument(): Document;
-        /**
          * Gets the client rect of the HTML canvas attached with the current webGL context
          * @returns a client rectanglee
          */
@@ -31757,6 +31802,11 @@ declare module BABYLON {
          */
         getLockstepMaxSteps(): number;
         /**
+         * Returns the time in ms between steps when using deterministic lock step.
+         * @returns time step in (ms)
+         */
+        getTimeStep(): number;
+        /**
          * Force the mipmap generation for the given render target texture
          * @param texture defines the render target texture to use
          */
@@ -54016,6 +54066,7 @@ declare module BABYLON {
         autoConfigure(material: NodeMaterial): void;
         initializeDefines(mesh: AbstractMesh, nodeMaterial: NodeMaterial, defines: NodeMaterialDefines, useInstances?: boolean): void;
         prepareDefines(mesh: AbstractMesh, nodeMaterial: NodeMaterial, defines: NodeMaterialDefines): void;
+        private _getTextureBase;
         isReady(): boolean;
         bind(effect: Effect, nodeMaterial: NodeMaterial, mesh?: Mesh): void;
         private readonly _isMixed;
@@ -55081,6 +55132,36 @@ declare module BABYLON {
 }
 declare module BABYLON {
     /**
+     * Block used to get the derivative value on x and y of a given input
+     */
+    export class DerivativeBlock extends NodeMaterialBlock {
+        /**
+         * Create a new DerivativeBlock
+         * @param name defines the block name
+         */
+        constructor(name: string);
+        /**
+         * Gets the current class name
+         * @returns the class name
+         */
+        getClassName(): string;
+        /**
+         * Gets the input component
+         */
+        readonly input: NodeMaterialConnectionPoint;
+        /**
+         * Gets the derivative output on x
+         */
+        readonly dx: NodeMaterialConnectionPoint;
+        /**
+         * Gets the derivative output on y
+         */
+        readonly dy: NodeMaterialConnectionPoint;
+        protected _buildBlock(state: NodeMaterialBuildState): this;
+    }
+}
+declare module BABYLON {
+    /**
      * Block used to add support for scene fog
      */
     export class FogBlock extends NodeMaterialBlock {
@@ -56564,6 +56645,70 @@ declare module BABYLON {
 }
 declare module BABYLON {
     /**
+     * Block used to get the reflected vector from a direction and a normal
+     */
+    export class ReflectBlock extends NodeMaterialBlock {
+        /**
+         * Creates a new ReflectBlock
+         * @param name defines the block name
+         */
+        constructor(name: string);
+        /**
+         * Gets the current class name
+         * @returns the class name
+         */
+        getClassName(): string;
+        /**
+         * Gets the incident component
+         */
+        readonly incident: NodeMaterialConnectionPoint;
+        /**
+         * Gets the normal component
+         */
+        readonly normal: NodeMaterialConnectionPoint;
+        /**
+         * Gets the output component
+         */
+        readonly output: NodeMaterialConnectionPoint;
+        protected _buildBlock(state: NodeMaterialBuildState): this;
+    }
+}
+declare module BABYLON {
+    /**
+     * Block used to get the refracted vector from a direction and a normal
+     */
+    export class RefractBlock extends NodeMaterialBlock {
+        /**
+         * Creates a new RefractBlock
+         * @param name defines the block name
+         */
+        constructor(name: string);
+        /**
+         * Gets the current class name
+         * @returns the class name
+         */
+        getClassName(): string;
+        /**
+         * Gets the incident component
+         */
+        readonly incident: NodeMaterialConnectionPoint;
+        /**
+         * Gets the normal component
+         */
+        readonly normal: NodeMaterialConnectionPoint;
+        /**
+         * Gets the index of refraction component
+         */
+        readonly ior: NodeMaterialConnectionPoint;
+        /**
+         * Gets the output component
+         */
+        readonly output: NodeMaterialConnectionPoint;
+        protected _buildBlock(state: NodeMaterialBuildState): this;
+    }
+}
+declare module BABYLON {
+    /**
      * Effect Render Options
      */
     export interface IEffectRendererOptions {
@@ -66081,6 +66226,8 @@ declare module BABYLON.GUI {
         /** @hidden */
         _isClipped: boolean;
         /** @hidden */
+        _automaticSize: boolean;
+        /** @hidden */
         _tag: any;
         /**
          * Gets or sets the unique id of the node. Please note that this number will be updated when the control is added to a container
@@ -70861,6 +71008,25 @@ declare module BABYLON.GLTF2.Loader.Extensions {
 }
 declare module BABYLON.GLTF2.Loader.Extensions {
     /**
+     * [Specification](https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Khronos/KHR_mesh_quantization)
+     */
+    export class KHR_mesh_quantization implements IGLTFLoaderExtension {
+        /**
+         * The name of this extension.
+         */
+        readonly name: string;
+        /**
+         * Defines whether this extension is enabled.
+         */
+        enabled: boolean;
+        /** @hidden */
+        constructor(loader: GLTFLoader);
+        /** @hidden */
+        dispose(): void;
+    }
+}
+declare module BABYLON.GLTF2.Loader.Extensions {
+    /**
      * [Specification](https://github.com/KhronosGroup/glTF/blob/master/extensions/2.0/Khronos/KHR_texture_transform/README.md)
      */
     export class KHR_texture_transform implements IGLTFLoaderExtension {

+ 1 - 1
dist/preview release/glTF2Interface/package.json

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

+ 2 - 0
dist/preview release/gui/babylon.gui.d.ts

@@ -689,6 +689,8 @@ declare module BABYLON.GUI {
         /** @hidden */
         _isClipped: boolean;
         /** @hidden */
+        _automaticSize: boolean;
+        /** @hidden */
         _tag: any;
         /**
          * Gets or sets the unique id of the node. Please note that this number will be updated when the control is added to a container

+ 6 - 2
dist/preview release/gui/babylon.gui.js

@@ -3728,6 +3728,8 @@ var Control = /** @class */ (function () {
         this._rebuildLayout = false;
         /** @hidden */
         this._isClipped = false;
+        /** @hidden */
+        this._automaticSize = false;
         /**
          * Gets or sets an object used to store user defined information for the node
          */
@@ -8203,6 +8205,7 @@ var Line = /** @class */ (function (_super) {
         _this._x2 = new _valueAndUnit__WEBPACK_IMPORTED_MODULE_3__["ValueAndUnit"](0);
         _this._y2 = new _valueAndUnit__WEBPACK_IMPORTED_MODULE_3__["ValueAndUnit"](0);
         _this._dash = new Array();
+        _this._automaticSize = true;
         _this.isHitTestVisible = false;
         _this._horizontalAlignment = _control__WEBPACK_IMPORTED_MODULE_2__["Control"].HORIZONTAL_ALIGNMENT_LEFT;
         _this._verticalAlignment = _control__WEBPACK_IMPORTED_MODULE_2__["Control"].VERTICAL_ALIGNMENT_TOP;
@@ -8473,6 +8476,7 @@ var MultiLine = /** @class */ (function (_super) {
         _this.onPointUpdate = function () {
             _this._markAsDirty();
         };
+        _this._automaticSize = true;
         _this.isHitTestVisible = false;
         _this._horizontalAlignment = _control__WEBPACK_IMPORTED_MODULE_2__["Control"].HORIZONTAL_ALIGNMENT_LEFT;
         _this._verticalAlignment = _control__WEBPACK_IMPORTED_MODULE_2__["Control"].VERTICAL_ALIGNMENT_TOP;
@@ -11201,7 +11205,7 @@ var StackPanel = /** @class */ (function (_super) {
                     this._rebuildLayout = true;
                     child._top.ignoreAdaptiveScaling = true;
                 }
-                if (child._height.isPercentage) {
+                if (child._height.isPercentage && !child._automaticSize) {
                     if (!this.ignoreLayoutWarnings) {
                         babylonjs_Misc_tools__WEBPACK_IMPORTED_MODULE_1__["Tools"].Warn("Control (Name:" + child.name + ", UniqueId:" + child.uniqueId + ") is using height in percentage mode inside a vertical StackPanel");
                     }
@@ -11216,7 +11220,7 @@ var StackPanel = /** @class */ (function (_super) {
                     this._rebuildLayout = true;
                     child._left.ignoreAdaptiveScaling = true;
                 }
-                if (child._width.isPercentage) {
+                if (child._width.isPercentage && !child._automaticSize) {
                     if (!this.ignoreLayoutWarnings) {
                         babylonjs_Misc_tools__WEBPACK_IMPORTED_MODULE_1__["Tools"].Warn("Control (Name:" + child.name + ", UniqueId:" + child.uniqueId + ") is using width in percentage mode inside a horizontal StackPanel");
                     }

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


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


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

@@ -719,6 +719,8 @@ declare module "babylonjs-gui/2D/controls/control" {
         /** @hidden */
         _isClipped: boolean;
         /** @hidden */
+        _automaticSize: boolean;
+        /** @hidden */
         _tag: any;
         /**
          * Gets or sets the unique id of the node. Please note that this number will be updated when the control is added to a container
@@ -4639,6 +4641,8 @@ declare module BABYLON.GUI {
         /** @hidden */
         _isClipped: boolean;
         /** @hidden */
+        _automaticSize: boolean;
+        /** @hidden */
         _tag: any;
         /**
          * Gets or sets the unique id of the node. Please note that this number will be updated when the control is added to a container

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

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

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


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

@@ -41387,7 +41387,7 @@ var OptionsLineComponent = /** @class */ (function (_super) {
         return (react__WEBPACK_IMPORTED_MODULE_1__["createElement"]("div", { className: "listLine" },
             react__WEBPACK_IMPORTED_MODULE_1__["createElement"]("div", { className: "label" }, this.props.label),
             react__WEBPACK_IMPORTED_MODULE_1__["createElement"]("div", { className: "options" },
-                react__WEBPACK_IMPORTED_MODULE_1__["createElement"]("select", { onChange: function (evt) { return _this.updateValue(evt.target.value); }, value: this.state.value }, this.props.options.map(function (option) {
+                react__WEBPACK_IMPORTED_MODULE_1__["createElement"]("select", { onChange: function (evt) { return _this.updateValue(evt.target.value); }, value: this.state.value || "" }, this.props.options.map(function (option) {
                     return (react__WEBPACK_IMPORTED_MODULE_1__["createElement"]("option", { key: option.label, value: option.value }, option.label));
                 })))));
     };
@@ -42052,8 +42052,8 @@ var TextureLinkLineComponent = /** @class */ (function (_super) {
         if (!this.props.onDebugSelectionChangeObservable) {
             return;
         }
-        this._onDebugSelectionChangeObserver = this.props.onDebugSelectionChangeObservable.add(function (texture) {
-            if (_this.props.texture !== texture) {
+        this._onDebugSelectionChangeObserver = this.props.onDebugSelectionChangeObservable.add(function (line) {
+            if (line !== _this) {
                 _this.setState({ isDebugSelected: false });
             }
         });
@@ -42068,6 +42068,9 @@ var TextureLinkLineComponent = /** @class */ (function (_super) {
             var newState = !this.state.isDebugSelected;
             this.props.customDebugAction(newState);
             this.setState({ isDebugSelected: newState });
+            if (this.props.onDebugSelectionChangeObservable) {
+                this.props.onDebugSelectionChangeObservable.notifyObservers(this);
+            }
             return;
         }
         var texture = this.props.texture;
@@ -42117,7 +42120,7 @@ var TextureLinkLineComponent = /** @class */ (function (_super) {
         material.reservedDataStore.level = texture.level;
         texture.level = 1.0;
         if (this.props.onDebugSelectionChangeObservable) {
-            this.props.onDebugSelectionChangeObservable.notifyObservers(texture);
+            this.props.onDebugSelectionChangeObservable.notifyObservers(this);
         }
         if (needToDisposeCheckMaterial) {
             checkMaterial.dispose();

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


+ 2 - 2
dist/preview release/inspector/babylon.inspector.d.ts

@@ -476,7 +476,7 @@ declare module INSPECTOR {
         texture: BABYLON.Nullable<BABYLON.BaseTexture>;
         material?: BABYLON.Material;
         onSelectionChangedObservable?: BABYLON.Observable<any>;
-        onDebugSelectionChangeObservable?: BABYLON.Observable<BABYLON.BaseTexture>;
+        onDebugSelectionChangeObservable?: BABYLON.Observable<TextureLinkLineComponent>;
         propertyName?: string;
         onTextureCreated?: (texture: BABYLON.BaseTexture) => void;
         customDebugAction?: (state: boolean) => void;
@@ -629,7 +629,7 @@ declare module INSPECTOR {
         switchAmbientMode(state: boolean): void;
         switchMetallicMode(state: boolean): void;
         switchRoughnessMode(state: boolean): void;
-        renderTextures(onDebugSelectionChangeObservable: BABYLON.Observable<BABYLON.BaseTexture>): JSX.Element;
+        renderTextures(onDebugSelectionChangeObservable: BABYLON.Observable<TextureLinkLineComponent>): JSX.Element;
         render(): JSX.Element;
     }
 }

+ 5 - 5
dist/preview release/inspector/babylon.inspector.module.d.ts

@@ -555,7 +555,7 @@ declare module "babylonjs-inspector/components/actionTabs/lines/textureLinkLineC
         texture: Nullable<BaseTexture>;
         material?: Material;
         onSelectionChangedObservable?: Observable<any>;
-        onDebugSelectionChangeObservable?: Observable<BaseTexture>;
+        onDebugSelectionChangeObservable?: Observable<TextureLinkLineComponent>;
         propertyName?: string;
         onTextureCreated?: (texture: BaseTexture) => void;
         customDebugAction?: (state: boolean) => void;
@@ -720,9 +720,9 @@ declare module "babylonjs-inspector/components/actionTabs/lines/vector2LineCompo
 declare module "babylonjs-inspector/components/actionTabs/tabs/propertyGrids/materials/pbrMaterialPropertyGridComponent" {
     import * as React from "react";
     import { Observable } from "babylonjs/Misc/observable";
-    import { BaseTexture } from "babylonjs/Materials/Textures/baseTexture";
     import { PBRMaterial } from "babylonjs/Materials/PBR/pbrMaterial";
     import { PropertyChangedEvent } from "babylonjs-inspector/components/propertyChangedEvent";
+    import { TextureLinkLineComponent } from "babylonjs-inspector/components/actionTabs/lines/textureLinkLineComponent";
     import { LockObject } from "babylonjs-inspector/components/actionTabs/tabs/propertyGrids/lockObject";
     import { GlobalState } from "babylonjs-inspector/components/globalState";
     interface IPBRMaterialPropertyGridComponentProps {
@@ -738,7 +738,7 @@ declare module "babylonjs-inspector/components/actionTabs/tabs/propertyGrids/mat
         switchAmbientMode(state: boolean): void;
         switchMetallicMode(state: boolean): void;
         switchRoughnessMode(state: boolean): void;
-        renderTextures(onDebugSelectionChangeObservable: Observable<BaseTexture>): JSX.Element;
+        renderTextures(onDebugSelectionChangeObservable: Observable<TextureLinkLineComponent>): JSX.Element;
         render(): JSX.Element;
     }
 }
@@ -2803,7 +2803,7 @@ declare module INSPECTOR {
         texture: BABYLON.Nullable<BABYLON.BaseTexture>;
         material?: BABYLON.Material;
         onSelectionChangedObservable?: BABYLON.Observable<any>;
-        onDebugSelectionChangeObservable?: BABYLON.Observable<BABYLON.BaseTexture>;
+        onDebugSelectionChangeObservable?: BABYLON.Observable<TextureLinkLineComponent>;
         propertyName?: string;
         onTextureCreated?: (texture: BABYLON.BaseTexture) => void;
         customDebugAction?: (state: boolean) => void;
@@ -2956,7 +2956,7 @@ declare module INSPECTOR {
         switchAmbientMode(state: boolean): void;
         switchMetallicMode(state: boolean): void;
         switchRoughnessMode(state: boolean): void;
-        renderTextures(onDebugSelectionChangeObservable: BABYLON.Observable<BABYLON.BaseTexture>): JSX.Element;
+        renderTextures(onDebugSelectionChangeObservable: BABYLON.Observable<TextureLinkLineComponent>): JSX.Element;
         render(): JSX.Element;
     }
 }

+ 7 - 7
dist/preview release/inspector/package.json

@@ -4,7 +4,7 @@
     },
     "name": "babylonjs-inspector",
     "description": "The Babylon.js inspector.",
-    "version": "4.1.0-beta.2",
+    "version": "4.1.0-beta.3",
     "repository": {
         "type": "git",
         "url": "https://github.com/BabylonJS/Babylon.js.git"
@@ -29,12 +29,12 @@
     ],
     "license": "Apache-2.0",
     "dependencies": {
-        "babylonjs": "4.1.0-beta.2",
-        "babylonjs-gui": "4.1.0-beta.2",
-        "babylonjs-loaders": "4.1.0-beta.2",
-        "babylonjs-materials": "4.1.0-beta.2",
-        "babylonjs-serializers": "4.1.0-beta.2",
-        "babylonjs-gltf2interface": "4.1.0-beta.2"
+        "babylonjs": "4.1.0-beta.3",
+        "babylonjs-gui": "4.1.0-beta.3",
+        "babylonjs-loaders": "4.1.0-beta.3",
+        "babylonjs-materials": "4.1.0-beta.3",
+        "babylonjs-serializers": "4.1.0-beta.3",
+        "babylonjs-gltf2interface": "4.1.0-beta.3"
     },
     "devDependencies": {
         "@types/react": "~16.7.3",

+ 3 - 3
dist/preview release/loaders/babylon.glTF1FileLoader.js

@@ -97,9 +97,9 @@ return /******/ (function(modules) { // webpackBootstrap
 /******/ ({
 
 /***/ "../../node_modules/tslib/tslib.es6.js":
-/*!***********************************************************!*\
-  !*** C:/Repos/Babylon.js/node_modules/tslib/tslib.es6.js ***!
-  \***********************************************************/
+/*!*****************************************************************!*\
+  !*** C:/Dev/Babylon/Babylon.js/node_modules/tslib/tslib.es6.js ***!
+  \*****************************************************************/
 /*! exports provided: __extends, __assign, __rest, __decorate, __param, __metadata, __awaiter, __generator, __exportStar, __values, __read, __spread, __spreadArrays, __await, __asyncGenerator, __asyncDelegator, __asyncValues, __makeTemplateObject, __importStar, __importDefault */
 /***/ (function(module, __webpack_exports__, __webpack_require__) {
 

+ 68 - 21
dist/preview release/loaders/babylon.glTF2FileLoader.js

@@ -757,17 +757,17 @@ var KHR_materials_sheen = /** @class */ (function () {
         }
         var promises = new Array();
         babylonMaterial.sheen.isEnabled = true;
-        if (properties.sheenFactor != undefined) {
-            babylonMaterial.sheen.intensity = properties.sheenFactor;
+        if (properties.intensityFactor != undefined) {
+            babylonMaterial.sheen.intensity = properties.intensityFactor;
         }
         else {
             babylonMaterial.sheen.intensity = 0;
         }
-        if (properties.sheenColor != undefined) {
-            babylonMaterial.sheen.color = babylonjs_Materials_PBR_pbrMaterial__WEBPACK_IMPORTED_MODULE_0__["Color3"].FromArray(properties.sheenColor);
+        if (properties.colorFactor != undefined) {
+            babylonMaterial.sheen.color = babylonjs_Materials_PBR_pbrMaterial__WEBPACK_IMPORTED_MODULE_0__["Color3"].FromArray(properties.colorFactor);
         }
-        if (properties.sheenTexture) {
-            promises.push(this._loader.loadTextureInfoAsync(context + "/sheenTexture", properties.sheenTexture, function (texture) {
+        if (properties.colorIntensityTexture) {
+            promises.push(this._loader.loadTextureInfoAsync(context + "/sheenTexture", properties.colorIntensityTexture, function (texture) {
                 texture.name = babylonMaterial.name + " (Sheen Intensity)";
                 babylonMaterial.sheen.texture = texture;
             }));
@@ -934,6 +934,42 @@ _glTFLoader__WEBPACK_IMPORTED_MODULE_1__["GLTFLoader"].RegisterExtension(NAME, f
 
 /***/ }),
 
+/***/ "./glTF/2.0/Extensions/KHR_mesh_quantization.ts":
+/*!******************************************************!*\
+  !*** ./glTF/2.0/Extensions/KHR_mesh_quantization.ts ***!
+  \******************************************************/
+/*! exports provided: KHR_mesh_quantization */
+/***/ (function(module, __webpack_exports__, __webpack_require__) {
+
+"use strict";
+__webpack_require__.r(__webpack_exports__);
+/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "KHR_mesh_quantization", function() { return KHR_mesh_quantization; });
+/* harmony import */ var _glTFLoader__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../glTFLoader */ "./glTF/2.0/glTFLoader.ts");
+
+var NAME = "KHR_mesh_quantization";
+/**
+ * [Specification](https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Khronos/KHR_mesh_quantization)
+ */
+var KHR_mesh_quantization = /** @class */ (function () {
+    /** @hidden */
+    function KHR_mesh_quantization(loader) {
+        /**
+         * The name of this extension.
+         */
+        this.name = NAME;
+        this.enabled = loader.isExtensionUsed(NAME);
+    }
+    /** @hidden */
+    KHR_mesh_quantization.prototype.dispose = function () {
+    };
+    return KHR_mesh_quantization;
+}());
+
+_glTFLoader__WEBPACK_IMPORTED_MODULE_0__["GLTFLoader"].RegisterExtension(NAME, function (loader) { return new KHR_mesh_quantization(loader); });
+
+
+/***/ }),
+
 /***/ "./glTF/2.0/Extensions/KHR_texture_transform.ts":
 /*!******************************************************!*\
   !*** ./glTF/2.0/Extensions/KHR_texture_transform.ts ***!
@@ -1671,7 +1707,7 @@ _glTFLoader__WEBPACK_IMPORTED_MODULE_1__["GLTFLoader"].RegisterExtension(NAME, f
 /*!**************************************!*\
   !*** ./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_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_transform, MSFT_audio_emitter, MSFT_lod, MSFT_minecraftMesh, MSFT_sRGBFactors, ExtrasAsMetadata */
 /***/ (function(module, __webpack_exports__, __webpack_require__) {
 
 "use strict";
@@ -1700,23 +1736,26 @@ __webpack_require__.r(__webpack_exports__);
 /* harmony import */ var _KHR_materials_specular__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ./KHR_materials_specular */ "./glTF/2.0/Extensions/KHR_materials_specular.ts");
 /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "KHR_materials_specular", function() { return _KHR_materials_specular__WEBPACK_IMPORTED_MODULE_7__["KHR_materials_specular"]; });
 
-/* harmony import */ var _KHR_texture_transform__WEBPACK_IMPORTED_MODULE_8__ = __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_8__["KHR_texture_transform"]; });
+/* 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 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 _MSFT_audio_emitter__WEBPACK_IMPORTED_MODULE_9__ = __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_9__["MSFT_audio_emitter"]; });
+/* 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 _MSFT_lod__WEBPACK_IMPORTED_MODULE_10__ = __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_10__["MSFT_lod"]; });
+/* 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_minecraftMesh__WEBPACK_IMPORTED_MODULE_11__ = __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_11__["MSFT_minecraftMesh"]; });
+/* 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_sRGBFactors__WEBPACK_IMPORTED_MODULE_12__ = __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_12__["MSFT_sRGBFactors"]; });
+/* 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 _ExtrasAsMetadata__WEBPACK_IMPORTED_MODULE_13__ = __webpack_require__(/*! ./ExtrasAsMetadata */ "./glTF/2.0/Extensions/ExtrasAsMetadata.ts");
-/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "ExtrasAsMetadata", function() { return _ExtrasAsMetadata__WEBPACK_IMPORTED_MODULE_13__["ExtrasAsMetadata"]; });
+/* 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"]; });
 
 
 
@@ -1732,6 +1771,7 @@ __webpack_require__.r(__webpack_exports__);
 
 
 
+
 
 
 /***/ }),
@@ -2467,6 +2507,9 @@ var GLTFLoader = /** @class */ (function () {
             promises.push(_this._loadVertexAccessorAsync("/accessors/" + accessor.index, accessor, kind).then(function (babylonVertexBuffer) {
                 babylonGeometry.setVerticesBuffer(babylonVertexBuffer, accessor.count);
             }));
+            if (kind == babylonjs_Misc_deferred__WEBPACK_IMPORTED_MODULE_0__["VertexBuffer"].MatricesIndicesExtraKind) {
+                babylonMesh.numBoneInfluencers = 8;
+            }
             if (callback) {
                 callback(accessor);
             }
@@ -2478,6 +2521,8 @@ var GLTFLoader = /** @class */ (function () {
         loadAttribute("TEXCOORD_1", babylonjs_Misc_deferred__WEBPACK_IMPORTED_MODULE_0__["VertexBuffer"].UV2Kind);
         loadAttribute("JOINTS_0", babylonjs_Misc_deferred__WEBPACK_IMPORTED_MODULE_0__["VertexBuffer"].MatricesIndicesKind);
         loadAttribute("WEIGHTS_0", babylonjs_Misc_deferred__WEBPACK_IMPORTED_MODULE_0__["VertexBuffer"].MatricesWeightsKind);
+        loadAttribute("JOINTS_1", babylonjs_Misc_deferred__WEBPACK_IMPORTED_MODULE_0__["VertexBuffer"].MatricesIndicesExtraKind);
+        loadAttribute("WEIGHTS_1", babylonjs_Misc_deferred__WEBPACK_IMPORTED_MODULE_0__["VertexBuffer"].MatricesWeightsExtraKind);
         loadAttribute("COLOR_0", babylonjs_Misc_deferred__WEBPACK_IMPORTED_MODULE_0__["VertexBuffer"].ColorKind, function (accessor) {
             if (accessor.type === "VEC4" /* VEC4 */) {
                 babylonMesh.hasVertexAlpha = true;
@@ -3113,7 +3158,7 @@ var GLTFLoader = /** @class */ (function () {
         }
         // Load joint indices as a float array since the shaders expect float data but glTF uses unsigned byte/short.
         // This prevents certain platforms (e.g. D3D) from having to convert the data to float on the fly.
-        else if (kind === babylonjs_Misc_deferred__WEBPACK_IMPORTED_MODULE_0__["VertexBuffer"].MatricesIndicesKind) {
+        else if (kind === babylonjs_Misc_deferred__WEBPACK_IMPORTED_MODULE_0__["VertexBuffer"].MatricesIndicesKind || kind === babylonjs_Misc_deferred__WEBPACK_IMPORTED_MODULE_0__["VertexBuffer"].MatricesIndicesExtraKind) {
             accessor._babylonVertexBuffer = this._loadFloatAccessorAsync("/accessors/" + accessor.index, accessor).then(function (data) {
                 return new babylonjs_Misc_deferred__WEBPACK_IMPORTED_MODULE_0__["VertexBuffer"](_this._babylonScene.getEngine(), data, kind, false);
             });
@@ -3845,7 +3890,7 @@ _glTFFileLoader__WEBPACK_IMPORTED_MODULE_1__["GLTFFileLoader"]._CreateGLTF2Loade
 /*!***************************!*\
   !*** ./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_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_transform, MSFT_audio_emitter, MSFT_lod, MSFT_minecraftMesh, MSFT_sRGBFactors, ExtrasAsMetadata */
 /***/ (function(module, __webpack_exports__, __webpack_require__) {
 
 "use strict";
@@ -3872,6 +3917,8 @@ __webpack_require__.r(__webpack_exports__);
 
 /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "KHR_materials_specular", function() { return _Extensions__WEBPACK_IMPORTED_MODULE_1__["KHR_materials_specular"]; });
 
+/* 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_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"]; });

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


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


+ 71 - 24
dist/preview release/loaders/babylon.glTFFileLoader.js

@@ -97,9 +97,9 @@ return /******/ (function(modules) { // webpackBootstrap
 /******/ ({
 
 /***/ "../../node_modules/tslib/tslib.es6.js":
-/*!***********************************************************!*\
-  !*** C:/Repos/Babylon.js/node_modules/tslib/tslib.es6.js ***!
-  \***********************************************************/
+/*!*****************************************************************!*\
+  !*** C:/Dev/Babylon/Babylon.js/node_modules/tslib/tslib.es6.js ***!
+  \*****************************************************************/
 /*! exports provided: __extends, __assign, __rest, __decorate, __param, __metadata, __awaiter, __generator, __exportStar, __values, __read, __spread, __spreadArrays, __await, __asyncGenerator, __asyncDelegator, __asyncValues, __makeTemplateObject, __importStar, __importDefault */
 /***/ (function(module, __webpack_exports__, __webpack_require__) {
 
@@ -3317,17 +3317,17 @@ var KHR_materials_sheen = /** @class */ (function () {
         }
         var promises = new Array();
         babylonMaterial.sheen.isEnabled = true;
-        if (properties.sheenFactor != undefined) {
-            babylonMaterial.sheen.intensity = properties.sheenFactor;
+        if (properties.intensityFactor != undefined) {
+            babylonMaterial.sheen.intensity = properties.intensityFactor;
         }
         else {
             babylonMaterial.sheen.intensity = 0;
         }
-        if (properties.sheenColor != undefined) {
-            babylonMaterial.sheen.color = babylonjs_Materials_PBR_pbrMaterial__WEBPACK_IMPORTED_MODULE_0__["Color3"].FromArray(properties.sheenColor);
+        if (properties.colorFactor != undefined) {
+            babylonMaterial.sheen.color = babylonjs_Materials_PBR_pbrMaterial__WEBPACK_IMPORTED_MODULE_0__["Color3"].FromArray(properties.colorFactor);
         }
-        if (properties.sheenTexture) {
-            promises.push(this._loader.loadTextureInfoAsync(context + "/sheenTexture", properties.sheenTexture, function (texture) {
+        if (properties.colorIntensityTexture) {
+            promises.push(this._loader.loadTextureInfoAsync(context + "/sheenTexture", properties.colorIntensityTexture, function (texture) {
                 texture.name = babylonMaterial.name + " (Sheen Intensity)";
                 babylonMaterial.sheen.texture = texture;
             }));
@@ -3494,6 +3494,42 @@ _glTFLoader__WEBPACK_IMPORTED_MODULE_1__["GLTFLoader"].RegisterExtension(NAME, f
 
 /***/ }),
 
+/***/ "./glTF/2.0/Extensions/KHR_mesh_quantization.ts":
+/*!******************************************************!*\
+  !*** ./glTF/2.0/Extensions/KHR_mesh_quantization.ts ***!
+  \******************************************************/
+/*! exports provided: KHR_mesh_quantization */
+/***/ (function(module, __webpack_exports__, __webpack_require__) {
+
+"use strict";
+__webpack_require__.r(__webpack_exports__);
+/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "KHR_mesh_quantization", function() { return KHR_mesh_quantization; });
+/* harmony import */ var _glTFLoader__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../glTFLoader */ "./glTF/2.0/glTFLoader.ts");
+
+var NAME = "KHR_mesh_quantization";
+/**
+ * [Specification](https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Khronos/KHR_mesh_quantization)
+ */
+var KHR_mesh_quantization = /** @class */ (function () {
+    /** @hidden */
+    function KHR_mesh_quantization(loader) {
+        /**
+         * The name of this extension.
+         */
+        this.name = NAME;
+        this.enabled = loader.isExtensionUsed(NAME);
+    }
+    /** @hidden */
+    KHR_mesh_quantization.prototype.dispose = function () {
+    };
+    return KHR_mesh_quantization;
+}());
+
+_glTFLoader__WEBPACK_IMPORTED_MODULE_0__["GLTFLoader"].RegisterExtension(NAME, function (loader) { return new KHR_mesh_quantization(loader); });
+
+
+/***/ }),
+
 /***/ "./glTF/2.0/Extensions/KHR_texture_transform.ts":
 /*!******************************************************!*\
   !*** ./glTF/2.0/Extensions/KHR_texture_transform.ts ***!
@@ -4231,7 +4267,7 @@ _glTFLoader__WEBPACK_IMPORTED_MODULE_1__["GLTFLoader"].RegisterExtension(NAME, f
 /*!**************************************!*\
   !*** ./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_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_transform, MSFT_audio_emitter, MSFT_lod, MSFT_minecraftMesh, MSFT_sRGBFactors, ExtrasAsMetadata */
 /***/ (function(module, __webpack_exports__, __webpack_require__) {
 
 "use strict";
@@ -4260,23 +4296,26 @@ __webpack_require__.r(__webpack_exports__);
 /* harmony import */ var _KHR_materials_specular__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ./KHR_materials_specular */ "./glTF/2.0/Extensions/KHR_materials_specular.ts");
 /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "KHR_materials_specular", function() { return _KHR_materials_specular__WEBPACK_IMPORTED_MODULE_7__["KHR_materials_specular"]; });
 
-/* harmony import */ var _KHR_texture_transform__WEBPACK_IMPORTED_MODULE_8__ = __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_8__["KHR_texture_transform"]; });
+/* 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 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 _MSFT_audio_emitter__WEBPACK_IMPORTED_MODULE_9__ = __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_9__["MSFT_audio_emitter"]; });
+/* 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 _MSFT_lod__WEBPACK_IMPORTED_MODULE_10__ = __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_10__["MSFT_lod"]; });
+/* 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_minecraftMesh__WEBPACK_IMPORTED_MODULE_11__ = __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_11__["MSFT_minecraftMesh"]; });
+/* 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_sRGBFactors__WEBPACK_IMPORTED_MODULE_12__ = __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_12__["MSFT_sRGBFactors"]; });
+/* 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 _ExtrasAsMetadata__WEBPACK_IMPORTED_MODULE_13__ = __webpack_require__(/*! ./ExtrasAsMetadata */ "./glTF/2.0/Extensions/ExtrasAsMetadata.ts");
-/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "ExtrasAsMetadata", function() { return _ExtrasAsMetadata__WEBPACK_IMPORTED_MODULE_13__["ExtrasAsMetadata"]; });
+/* 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"]; });
 
 
 
@@ -4292,6 +4331,7 @@ __webpack_require__.r(__webpack_exports__);
 
 
 
+
 
 
 /***/ }),
@@ -5027,6 +5067,9 @@ var GLTFLoader = /** @class */ (function () {
             promises.push(_this._loadVertexAccessorAsync("/accessors/" + accessor.index, accessor, kind).then(function (babylonVertexBuffer) {
                 babylonGeometry.setVerticesBuffer(babylonVertexBuffer, accessor.count);
             }));
+            if (kind == babylonjs_Misc_deferred__WEBPACK_IMPORTED_MODULE_0__["VertexBuffer"].MatricesIndicesExtraKind) {
+                babylonMesh.numBoneInfluencers = 8;
+            }
             if (callback) {
                 callback(accessor);
             }
@@ -5038,6 +5081,8 @@ var GLTFLoader = /** @class */ (function () {
         loadAttribute("TEXCOORD_1", babylonjs_Misc_deferred__WEBPACK_IMPORTED_MODULE_0__["VertexBuffer"].UV2Kind);
         loadAttribute("JOINTS_0", babylonjs_Misc_deferred__WEBPACK_IMPORTED_MODULE_0__["VertexBuffer"].MatricesIndicesKind);
         loadAttribute("WEIGHTS_0", babylonjs_Misc_deferred__WEBPACK_IMPORTED_MODULE_0__["VertexBuffer"].MatricesWeightsKind);
+        loadAttribute("JOINTS_1", babylonjs_Misc_deferred__WEBPACK_IMPORTED_MODULE_0__["VertexBuffer"].MatricesIndicesExtraKind);
+        loadAttribute("WEIGHTS_1", babylonjs_Misc_deferred__WEBPACK_IMPORTED_MODULE_0__["VertexBuffer"].MatricesWeightsExtraKind);
         loadAttribute("COLOR_0", babylonjs_Misc_deferred__WEBPACK_IMPORTED_MODULE_0__["VertexBuffer"].ColorKind, function (accessor) {
             if (accessor.type === "VEC4" /* VEC4 */) {
                 babylonMesh.hasVertexAlpha = true;
@@ -5673,7 +5718,7 @@ var GLTFLoader = /** @class */ (function () {
         }
         // Load joint indices as a float array since the shaders expect float data but glTF uses unsigned byte/short.
         // This prevents certain platforms (e.g. D3D) from having to convert the data to float on the fly.
-        else if (kind === babylonjs_Misc_deferred__WEBPACK_IMPORTED_MODULE_0__["VertexBuffer"].MatricesIndicesKind) {
+        else if (kind === babylonjs_Misc_deferred__WEBPACK_IMPORTED_MODULE_0__["VertexBuffer"].MatricesIndicesKind || kind === babylonjs_Misc_deferred__WEBPACK_IMPORTED_MODULE_0__["VertexBuffer"].MatricesIndicesExtraKind) {
             accessor._babylonVertexBuffer = this._loadFloatAccessorAsync("/accessors/" + accessor.index, accessor).then(function (data) {
                 return new babylonjs_Misc_deferred__WEBPACK_IMPORTED_MODULE_0__["VertexBuffer"](_this._babylonScene.getEngine(), data, kind, false);
             });
@@ -6405,7 +6450,7 @@ _glTFFileLoader__WEBPACK_IMPORTED_MODULE_1__["GLTFFileLoader"]._CreateGLTF2Loade
 /*!***************************!*\
   !*** ./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_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_transform, MSFT_audio_emitter, MSFT_lod, MSFT_minecraftMesh, MSFT_sRGBFactors, ExtrasAsMetadata */
 /***/ (function(module, __webpack_exports__, __webpack_require__) {
 
 "use strict";
@@ -6432,6 +6477,8 @@ __webpack_require__.r(__webpack_exports__);
 
 /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "KHR_materials_specular", function() { return _Extensions__WEBPACK_IMPORTED_MODULE_1__["KHR_materials_specular"]; });
 
+/* 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_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"]; });

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


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


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

@@ -1800,6 +1800,25 @@ declare module BABYLON.GLTF2.Loader.Extensions {
 }
 declare module BABYLON.GLTF2.Loader.Extensions {
     /**
+     * [Specification](https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Khronos/KHR_mesh_quantization)
+     */
+    export class KHR_mesh_quantization implements IGLTFLoaderExtension {
+        /**
+         * The name of this extension.
+         */
+        readonly name: string;
+        /**
+         * Defines whether this extension is enabled.
+         */
+        enabled: boolean;
+        /** @hidden */
+        constructor(loader: GLTFLoader);
+        /** @hidden */
+        dispose(): void;
+    }
+}
+declare module BABYLON.GLTF2.Loader.Extensions {
+    /**
      * [Specification](https://github.com/KhronosGroup/glTF/blob/master/extensions/2.0/Khronos/KHR_texture_transform/README.md)
      */
     export class KHR_texture_transform implements IGLTFLoaderExtension {

+ 71 - 24
dist/preview release/loaders/babylonjs.loaders.js

@@ -97,9 +97,9 @@ return /******/ (function(modules) { // webpackBootstrap
 /******/ ({
 
 /***/ "../../node_modules/tslib/tslib.es6.js":
-/*!***********************************************************!*\
-  !*** C:/Repos/Babylon.js/node_modules/tslib/tslib.es6.js ***!
-  \***********************************************************/
+/*!*****************************************************************!*\
+  !*** C:/Dev/Babylon/Babylon.js/node_modules/tslib/tslib.es6.js ***!
+  \*****************************************************************/
 /*! exports provided: __extends, __assign, __rest, __decorate, __param, __metadata, __awaiter, __generator, __exportStar, __values, __read, __spread, __spreadArrays, __await, __asyncGenerator, __asyncDelegator, __asyncValues, __makeTemplateObject, __importStar, __importDefault */
 /***/ (function(module, __webpack_exports__, __webpack_require__) {
 
@@ -4650,17 +4650,17 @@ var KHR_materials_sheen = /** @class */ (function () {
         }
         var promises = new Array();
         babylonMaterial.sheen.isEnabled = true;
-        if (properties.sheenFactor != undefined) {
-            babylonMaterial.sheen.intensity = properties.sheenFactor;
+        if (properties.intensityFactor != undefined) {
+            babylonMaterial.sheen.intensity = properties.intensityFactor;
         }
         else {
             babylonMaterial.sheen.intensity = 0;
         }
-        if (properties.sheenColor != undefined) {
-            babylonMaterial.sheen.color = babylonjs_Materials_PBR_pbrMaterial__WEBPACK_IMPORTED_MODULE_0__["Color3"].FromArray(properties.sheenColor);
+        if (properties.colorFactor != undefined) {
+            babylonMaterial.sheen.color = babylonjs_Materials_PBR_pbrMaterial__WEBPACK_IMPORTED_MODULE_0__["Color3"].FromArray(properties.colorFactor);
         }
-        if (properties.sheenTexture) {
-            promises.push(this._loader.loadTextureInfoAsync(context + "/sheenTexture", properties.sheenTexture, function (texture) {
+        if (properties.colorIntensityTexture) {
+            promises.push(this._loader.loadTextureInfoAsync(context + "/sheenTexture", properties.colorIntensityTexture, function (texture) {
                 texture.name = babylonMaterial.name + " (Sheen Intensity)";
                 babylonMaterial.sheen.texture = texture;
             }));
@@ -4827,6 +4827,42 @@ _glTFLoader__WEBPACK_IMPORTED_MODULE_1__["GLTFLoader"].RegisterExtension(NAME, f
 
 /***/ }),
 
+/***/ "./glTF/2.0/Extensions/KHR_mesh_quantization.ts":
+/*!******************************************************!*\
+  !*** ./glTF/2.0/Extensions/KHR_mesh_quantization.ts ***!
+  \******************************************************/
+/*! exports provided: KHR_mesh_quantization */
+/***/ (function(module, __webpack_exports__, __webpack_require__) {
+
+"use strict";
+__webpack_require__.r(__webpack_exports__);
+/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "KHR_mesh_quantization", function() { return KHR_mesh_quantization; });
+/* harmony import */ var _glTFLoader__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ../glTFLoader */ "./glTF/2.0/glTFLoader.ts");
+
+var NAME = "KHR_mesh_quantization";
+/**
+ * [Specification](https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Khronos/KHR_mesh_quantization)
+ */
+var KHR_mesh_quantization = /** @class */ (function () {
+    /** @hidden */
+    function KHR_mesh_quantization(loader) {
+        /**
+         * The name of this extension.
+         */
+        this.name = NAME;
+        this.enabled = loader.isExtensionUsed(NAME);
+    }
+    /** @hidden */
+    KHR_mesh_quantization.prototype.dispose = function () {
+    };
+    return KHR_mesh_quantization;
+}());
+
+_glTFLoader__WEBPACK_IMPORTED_MODULE_0__["GLTFLoader"].RegisterExtension(NAME, function (loader) { return new KHR_mesh_quantization(loader); });
+
+
+/***/ }),
+
 /***/ "./glTF/2.0/Extensions/KHR_texture_transform.ts":
 /*!******************************************************!*\
   !*** ./glTF/2.0/Extensions/KHR_texture_transform.ts ***!
@@ -5564,7 +5600,7 @@ _glTFLoader__WEBPACK_IMPORTED_MODULE_1__["GLTFLoader"].RegisterExtension(NAME, f
 /*!**************************************!*\
   !*** ./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_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_transform, MSFT_audio_emitter, MSFT_lod, MSFT_minecraftMesh, MSFT_sRGBFactors, ExtrasAsMetadata */
 /***/ (function(module, __webpack_exports__, __webpack_require__) {
 
 "use strict";
@@ -5593,23 +5629,26 @@ __webpack_require__.r(__webpack_exports__);
 /* harmony import */ var _KHR_materials_specular__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ./KHR_materials_specular */ "./glTF/2.0/Extensions/KHR_materials_specular.ts");
 /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "KHR_materials_specular", function() { return _KHR_materials_specular__WEBPACK_IMPORTED_MODULE_7__["KHR_materials_specular"]; });
 
-/* harmony import */ var _KHR_texture_transform__WEBPACK_IMPORTED_MODULE_8__ = __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_8__["KHR_texture_transform"]; });
+/* 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 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 _MSFT_audio_emitter__WEBPACK_IMPORTED_MODULE_9__ = __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_9__["MSFT_audio_emitter"]; });
+/* 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 _MSFT_lod__WEBPACK_IMPORTED_MODULE_10__ = __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_10__["MSFT_lod"]; });
+/* 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_minecraftMesh__WEBPACK_IMPORTED_MODULE_11__ = __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_11__["MSFT_minecraftMesh"]; });
+/* 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_sRGBFactors__WEBPACK_IMPORTED_MODULE_12__ = __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_12__["MSFT_sRGBFactors"]; });
+/* 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 _ExtrasAsMetadata__WEBPACK_IMPORTED_MODULE_13__ = __webpack_require__(/*! ./ExtrasAsMetadata */ "./glTF/2.0/Extensions/ExtrasAsMetadata.ts");
-/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "ExtrasAsMetadata", function() { return _ExtrasAsMetadata__WEBPACK_IMPORTED_MODULE_13__["ExtrasAsMetadata"]; });
+/* 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"]; });
 
 
 
@@ -5625,6 +5664,7 @@ __webpack_require__.r(__webpack_exports__);
 
 
 
+
 
 
 /***/ }),
@@ -6360,6 +6400,9 @@ var GLTFLoader = /** @class */ (function () {
             promises.push(_this._loadVertexAccessorAsync("/accessors/" + accessor.index, accessor, kind).then(function (babylonVertexBuffer) {
                 babylonGeometry.setVerticesBuffer(babylonVertexBuffer, accessor.count);
             }));
+            if (kind == babylonjs_Misc_deferred__WEBPACK_IMPORTED_MODULE_0__["VertexBuffer"].MatricesIndicesExtraKind) {
+                babylonMesh.numBoneInfluencers = 8;
+            }
             if (callback) {
                 callback(accessor);
             }
@@ -6371,6 +6414,8 @@ var GLTFLoader = /** @class */ (function () {
         loadAttribute("TEXCOORD_1", babylonjs_Misc_deferred__WEBPACK_IMPORTED_MODULE_0__["VertexBuffer"].UV2Kind);
         loadAttribute("JOINTS_0", babylonjs_Misc_deferred__WEBPACK_IMPORTED_MODULE_0__["VertexBuffer"].MatricesIndicesKind);
         loadAttribute("WEIGHTS_0", babylonjs_Misc_deferred__WEBPACK_IMPORTED_MODULE_0__["VertexBuffer"].MatricesWeightsKind);
+        loadAttribute("JOINTS_1", babylonjs_Misc_deferred__WEBPACK_IMPORTED_MODULE_0__["VertexBuffer"].MatricesIndicesExtraKind);
+        loadAttribute("WEIGHTS_1", babylonjs_Misc_deferred__WEBPACK_IMPORTED_MODULE_0__["VertexBuffer"].MatricesWeightsExtraKind);
         loadAttribute("COLOR_0", babylonjs_Misc_deferred__WEBPACK_IMPORTED_MODULE_0__["VertexBuffer"].ColorKind, function (accessor) {
             if (accessor.type === "VEC4" /* VEC4 */) {
                 babylonMesh.hasVertexAlpha = true;
@@ -7006,7 +7051,7 @@ var GLTFLoader = /** @class */ (function () {
         }
         // Load joint indices as a float array since the shaders expect float data but glTF uses unsigned byte/short.
         // This prevents certain platforms (e.g. D3D) from having to convert the data to float on the fly.
-        else if (kind === babylonjs_Misc_deferred__WEBPACK_IMPORTED_MODULE_0__["VertexBuffer"].MatricesIndicesKind) {
+        else if (kind === babylonjs_Misc_deferred__WEBPACK_IMPORTED_MODULE_0__["VertexBuffer"].MatricesIndicesKind || kind === babylonjs_Misc_deferred__WEBPACK_IMPORTED_MODULE_0__["VertexBuffer"].MatricesIndicesExtraKind) {
             accessor._babylonVertexBuffer = this._loadFloatAccessorAsync("/accessors/" + accessor.index, accessor).then(function (data) {
                 return new babylonjs_Misc_deferred__WEBPACK_IMPORTED_MODULE_0__["VertexBuffer"](_this._babylonScene.getEngine(), data, kind, false);
             });
@@ -7738,7 +7783,7 @@ _glTFFileLoader__WEBPACK_IMPORTED_MODULE_1__["GLTFFileLoader"]._CreateGLTF2Loade
 /*!***************************!*\
   !*** ./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_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_transform, MSFT_audio_emitter, MSFT_lod, MSFT_minecraftMesh, MSFT_sRGBFactors, ExtrasAsMetadata */
 /***/ (function(module, __webpack_exports__, __webpack_require__) {
 
 "use strict";
@@ -7765,6 +7810,8 @@ __webpack_require__.r(__webpack_exports__);
 
 /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "KHR_materials_specular", function() { return _Extensions__WEBPACK_IMPORTED_MODULE_1__["KHR_materials_specular"]; });
 
+/* 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_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"]; });

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


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


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

@@ -1930,6 +1930,27 @@ declare module "babylonjs-loaders/glTF/2.0/Extensions/KHR_materials_specular" {
         private _loadSpecularPropertiesAsync;
     }
 }
+declare module "babylonjs-loaders/glTF/2.0/Extensions/KHR_mesh_quantization" {
+    import { IGLTFLoaderExtension } from "babylonjs-loaders/glTF/2.0/glTFLoaderExtension";
+    import { GLTFLoader } from "babylonjs-loaders/glTF/2.0/glTFLoader";
+    /**
+     * [Specification](https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Khronos/KHR_mesh_quantization)
+     */
+    export class KHR_mesh_quantization implements IGLTFLoaderExtension {
+        /**
+         * The name of this extension.
+         */
+        readonly name: string;
+        /**
+         * Defines whether this extension is enabled.
+         */
+        enabled: boolean;
+        /** @hidden */
+        constructor(loader: GLTFLoader);
+        /** @hidden */
+        dispose(): void;
+    }
+}
 declare module "babylonjs-loaders/glTF/2.0/Extensions/KHR_texture_transform" {
     import { Nullable } from "babylonjs/types";
     import { BaseTexture } from "babylonjs/Materials/Textures/baseTexture";
@@ -2145,6 +2166,7 @@ declare module "babylonjs-loaders/glTF/2.0/Extensions/index" {
     export * from "babylonjs-loaders/glTF/2.0/Extensions/KHR_materials_clearcoat";
     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_mesh_quantization";
     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_lod";
@@ -4319,6 +4341,25 @@ declare module BABYLON.GLTF2.Loader.Extensions {
 }
 declare module BABYLON.GLTF2.Loader.Extensions {
     /**
+     * [Specification](https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Khronos/KHR_mesh_quantization)
+     */
+    export class KHR_mesh_quantization implements IGLTFLoaderExtension {
+        /**
+         * The name of this extension.
+         */
+        readonly name: string;
+        /**
+         * Defines whether this extension is enabled.
+         */
+        enabled: boolean;
+        /** @hidden */
+        constructor(loader: GLTFLoader);
+        /** @hidden */
+        dispose(): void;
+    }
+}
+declare module BABYLON.GLTF2.Loader.Extensions {
+    /**
      * [Specification](https://github.com/KhronosGroup/glTF/blob/master/extensions/2.0/Khronos/KHR_texture_transform/README.md)
      */
     export class KHR_texture_transform implements IGLTFLoaderExtension {

+ 3 - 3
dist/preview release/loaders/package.json

@@ -4,7 +4,7 @@
     },
     "name": "babylonjs-loaders",
     "description": "The Babylon.js file loaders library is an extension you can use to load different 3D file types into a Babylon scene.",
-    "version": "4.1.0-beta.2",
+    "version": "4.1.0-beta.3",
     "repository": {
         "type": "git",
         "url": "https://github.com/BabylonJS/Babylon.js.git"
@@ -28,8 +28,8 @@
     ],
     "license": "Apache-2.0",
     "dependencies": {
-        "babylonjs-gltf2interface": "4.1.0-beta.2",
-        "babylonjs": "4.1.0-beta.2"
+        "babylonjs-gltf2interface": "4.1.0-beta.3",
+        "babylonjs": "4.1.0-beta.3"
     },
     "engines": {
         "node": "*"

+ 2 - 2
dist/preview release/materialsLibrary/package.json

@@ -4,7 +4,7 @@
     },
     "name": "babylonjs-materials",
     "description": "The Babylon.js materials library is a collection of advanced materials to be used in a Babylon.js scene.",
-    "version": "4.1.0-beta.2",
+    "version": "4.1.0-beta.3",
     "repository": {
         "type": "git",
         "url": "https://github.com/BabylonJS/Babylon.js.git"
@@ -28,7 +28,7 @@
     ],
     "license": "Apache-2.0",
     "dependencies": {
-        "babylonjs": "4.1.0-beta.2"
+        "babylonjs": "4.1.0-beta.3"
     },
     "engines": {
         "node": "*"

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


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


+ 11 - 2
dist/preview release/nodeEditor/babylon.nodeEditor.max.js

@@ -68368,11 +68368,20 @@ __webpack_require__.r(__webpack_exports__);
 
 
 
+
+
+
 var BlockTools = /** @class */ (function () {
     function BlockTools() {
     }
     BlockTools.GetBlockFromString = function (data, scene, nodeMaterial) {
         switch (data) {
+            case "RefractBlock":
+                return new babylonjs_Materials_Node_Blocks_Fragment_discardBlock__WEBPACK_IMPORTED_MODULE_0__["RefractBlock"]("Refract");
+            case "ReflectBlock":
+                return new babylonjs_Materials_Node_Blocks_Fragment_discardBlock__WEBPACK_IMPORTED_MODULE_0__["ReflectBlock"]("Reflect");
+            case "DerivativeBlock":
+                return new babylonjs_Materials_Node_Blocks_Fragment_discardBlock__WEBPACK_IMPORTED_MODULE_0__["DerivativeBlock"]("Derivative");
             case "Rotate2dBlock":
                 return new babylonjs_Materials_Node_Blocks_Fragment_discardBlock__WEBPACK_IMPORTED_MODULE_0__["Rotate2dBlock"]("Rotate2d");
             case "NormalBlendBlock":
@@ -72051,7 +72060,7 @@ var NodeListComponent = /** @class */ (function (_super) {
             Round: ["RoundBlock", "CeilingBlock", "FloorBlock"],
             Scene: ["FogBlock", "CameraPositionBlock", "FogColorBlock", "ImageProcessingBlock", "LightBlock", "LightInformationBlock", "ViewDirectionBlock", "PerturbNormalBlock", "NormalBlendBlock"],
             Trigonometry: ["CosBlock", "SinBlock", "AbsBlock", "ExpBlock", "Exp2Block", "SqrtBlock", "PowBlock", "LogBlock", "ArcCosBlock", "ArcSinBlock", "TanBlock", "ArcTanBlock", "FractBlock", "SignBlock", "ArcTan2Block", "DegreesToRadiansBlock", "RadiansToDegreesBlock", "SawToothWaveBlock", "TriangleWaveBlock", "SquareWaveBlock"],
-            Vector_Math: ["CrossBlock", "DotBlock", "TransformBlock", "FresnelBlock", "Rotate2dBlock"],
+            Vector_Math: ["CrossBlock", "DotBlock", "TransformBlock", "FresnelBlock", "Rotate2dBlock", "DerivativeBlock", "RefractBlock", "ReflectBlock"],
         };
         // Create node menu
         var blockMenu = [];
@@ -74974,7 +74983,7 @@ var OptionsLineComponent = /** @class */ (function (_super) {
         return (react__WEBPACK_IMPORTED_MODULE_1__["createElement"]("div", { className: "listLine" },
             react__WEBPACK_IMPORTED_MODULE_1__["createElement"]("div", { className: "label" }, this.props.label),
             react__WEBPACK_IMPORTED_MODULE_1__["createElement"]("div", { className: "options" + (this.props.className ? " " + this.props.className : "") },
-                react__WEBPACK_IMPORTED_MODULE_1__["createElement"]("select", { onChange: function (evt) { return _this.updateValue(evt.target.value); }, value: this.state.value }, this.props.options.map(function (option) {
+                react__WEBPACK_IMPORTED_MODULE_1__["createElement"]("select", { onChange: function (evt) { return _this.updateValue(evt.target.value); }, value: this.state.value || "" }, this.props.options.map(function (option) {
                     return (react__WEBPACK_IMPORTED_MODULE_1__["createElement"]("option", { key: option.label, value: option.value }, option.label));
                 })))));
     };

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


File diff suppressed because it is too large
+ 5 - 2
dist/preview release/nodeEditor/babylon.nodeEditor.module.d.ts


+ 2 - 2
dist/preview release/nodeEditor/package.json

@@ -4,14 +4,14 @@
     },
     "name": "babylonjs-node-editor",
     "description": "The Babylon.js node material editor.",
-    "version": "4.1.0-beta.2",
+    "version": "4.1.0-beta.3",
     "repository": {
         "type": "git",
         "url": "https://github.com/BabylonJS/Babylon.js.git"
     },
     "license": "Apache-2.0",
     "dependencies": {
-        "babylonjs": "4.1.0-beta.2"
+        "babylonjs": "4.1.0-beta.3"
     },
     "files": [
         "babylon.nodeEditor.max.js.map",

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

@@ -7,7 +7,7 @@
     ],
     "name": "babylonjs",
     "description": "Babylon.js is a JavaScript 3D engine based on webgl.",
-    "version": "4.1.0-beta.2",
+    "version": "4.1.0-beta.3",
     "repository": {
         "type": "git",
         "url": "https://github.com/BabylonJS/Babylon.js.git"

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

@@ -1 +1 @@
-{"thinEngineOnly":116222,"engineOnly":153083,"sceneOnly":497461,"minGridMaterial":628091,"minStandardMaterial":751944}
+{"thinEngineOnly":116435,"engineOnly":153253,"sceneOnly":497646,"minGridMaterial":628211,"minStandardMaterial":752143}

+ 2 - 2
dist/preview release/postProcessesLibrary/package.json

@@ -4,7 +4,7 @@
     },
     "name": "babylonjs-post-process",
     "description": "The Babylon.js materials library is a collection of advanced materials to be used in a Babylon.js scene.",
-    "version": "4.1.0-beta.2",
+    "version": "4.1.0-beta.3",
     "repository": {
         "type": "git",
         "url": "https://github.com/BabylonJS/Babylon.js.git"
@@ -28,7 +28,7 @@
     ],
     "license": "Apache-2.0",
     "dependencies": {
-        "babylonjs": "4.1.0-beta.2"
+        "babylonjs": "4.1.0-beta.3"
     },
     "engines": {
         "node": "*"

+ 2 - 2
dist/preview release/proceduralTexturesLibrary/package.json

@@ -4,7 +4,7 @@
     },
     "name": "babylonjs-procedural-textures",
     "description": "The Babylon.js materials library is a collection of advanced materials to be used in a Babylon.js scene.",
-    "version": "4.1.0-beta.2",
+    "version": "4.1.0-beta.3",
     "repository": {
         "type": "git",
         "url": "https://github.com/BabylonJS/Babylon.js.git"
@@ -28,7 +28,7 @@
     ],
     "license": "Apache-2.0",
     "dependencies": {
-        "babylonjs": "4.1.0-beta.2"
+        "babylonjs": "4.1.0-beta.3"
     },
     "engines": {
         "node": "*"

+ 3 - 3
dist/preview release/serializers/package.json

@@ -4,7 +4,7 @@
     },
     "name": "babylonjs-serializers",
     "description": "The Babylon.js serializers library is an extension you can use to serialize Babylon scenes.",
-    "version": "4.1.0-beta.2",
+    "version": "4.1.0-beta.3",
     "repository": {
         "type": "git",
         "url": "https://github.com/BabylonJS/Babylon.js.git"
@@ -28,8 +28,8 @@
     ],
     "license": "Apache-2.0",
     "dependencies": {
-        "babylonjs": "4.1.0-beta.2",
-        "babylonjs-gltf2interface": "4.1.0-beta.2"
+        "babylonjs": "4.1.0-beta.3",
+        "babylonjs-gltf2interface": "4.1.0-beta.3"
     },
     "engines": {
         "node": "*"

+ 316 - 14
dist/preview release/viewer/babylon.module.d.ts

@@ -16426,7 +16426,7 @@ declare module "babylonjs/Materials/Textures/texture" {
          * Get the current texture matrix which includes the requested offsetting, tiling and rotation components.
          * @returns the transform matrix of the texture.
          */
-        getTextureMatrix(): Matrix;
+        getTextureMatrix(uBase?: number): Matrix;
         /**
          * Get the current matrix used to apply reflection. This is useful to rotate an environment texture for instance.
          * @returns The reflection texture transform
@@ -26345,6 +26345,11 @@ declare module "babylonjs/Particles/solidParticleSystem" {
         private _isNotBuilt;
         private _lastParticleId;
         private _idxOfId;
+        private _multimaterialEnabled;
+        private _indicesByMaterial;
+        private _materialIndexes;
+        private _depthSortFunction;
+        private _materialSortFunction;
         /**
          * Creates a SPS (Solid Particle System) object.
          * @param name (String) is the SPS name, this will be the underlying mesh name.
@@ -26353,6 +26358,7 @@ declare module "babylonjs/Particles/solidParticleSystem" {
          * * updatable (optional boolean, default true) : if the SPS must be updatable or immutable.
          * * isPickable (optional boolean, default false) : if the solid particles must be pickable.
          * * enableDepthSort (optional boolean, default false) : if the solid particles must be sorted in the geometry according to their distance to the camera.
+         * * enableMultiMaterial (optional boolean, default false) : if the solid particles can be given different materials.
          * * expandable (optional boolean, default false) : if particles can still be added after the initial SPS mesh creation.
          * * particleIntersection (optional boolean, default false) : if the solid particle intersections must be computed.
          * * boundingSphereOnly (optional boolean, default false) : if the particle intersection must be computed only with the bounding sphere (no bounding box computation, so faster).
@@ -26367,6 +26373,7 @@ declare module "babylonjs/Particles/solidParticleSystem" {
             boundingSphereOnly?: boolean;
             bSphereRadiusFactor?: number;
             expandable?: boolean;
+            enableMultiMaterial?: boolean;
         });
         /**
          * Builds the SPS underlying mesh. Returns a standard Mesh.
@@ -26404,6 +26411,7 @@ declare module "babylonjs/Particles/solidParticleSystem" {
         /**
          * Inserts the shape model geometry in the global SPS mesh by updating the positions, indices, normals, colors, uvs arrays
          * @param p the current index in the positions array to be updated
+         * @param ind the current index in the indices array
          * @param shape a Vector3 array, the shape geometry
          * @param positions the positions array to be updated
          * @param meshInd the shape indices array
@@ -26544,6 +26552,21 @@ declare module "babylonjs/Particles/solidParticleSystem" {
          */
         getParticlesByShapeIdToRef(shapeId: number, ref: SolidParticle[]): SolidParticleSystem;
         /**
+         * Computes the required SubMeshes according the materials assigned to the particles.
+         * @returns the solid particle system.
+         * Does nothing if called before the SPS mesh is built.
+         */
+        computeSubMeshes(): SolidParticleSystem;
+        /**
+         * Sorts the solid particles by material when MultiMaterial is enabled.
+         * Updates the indices32 array.
+         * Updates the indicesByMaterial array.
+         * Updates the mesh indices array.
+         * @returns the SPS
+         * @hidden
+         */
+        private _sortParticlesByMaterial;
+        /**
          * Visibilty helper : Recomputes the visible size according to the mesh bounding box
          * doc : http://doc.babylonjs.com/how_to/Solid_Particle_System#sps-visibility
          * @returns the SPS.
@@ -26637,6 +26660,10 @@ declare module "babylonjs/Particles/solidParticleSystem" {
          */
         readonly expandable: boolean;
         /**
+         * Gets if the SPS supports the Multi Materials
+         */
+        readonly multimaterialEnabled: boolean;
+        /**
          * This function does nothing. It may be overwritten to set all the particle first values.
          * The SPS doesn't call this function, you may have to call it by your own.
          * doc : http://doc.babylonjs.com/how_to/Solid_Particle_System#particle-management
@@ -26802,6 +26829,10 @@ declare module "babylonjs/Particles/solidParticle" {
          */
         parentId: Nullable<number>;
         /**
+         * The particle material identifier (integer) when MultiMaterials are enabled in the SPS.
+         */
+        materialIndex: Nullable<number>;
+        /**
          * The culling strategy to use to check whether the solid particle must be culled or not when using isInFrustum().
          * The possible values are :
          * - AbstractMesh.CULLINGSTRATEGY_STANDARD
@@ -26828,8 +26859,9 @@ declare module "babylonjs/Particles/solidParticle" {
          * @param idxInShape (integer) is the index of the particle in the current model (ex: the 10th box of addShape(box, 30))
          * @param sps defines the sps it is associated to
          * @param modelBoundingInfo is the reference to the model BoundingInfo used for intersection computations.
+         * @param materialIndex is the particle material identifier (integer) when the MultiMaterials are enabled in the SPS.
          */
-        constructor(particleIndex: number, particleId: number, positionIndex: number, indiceIndex: number, model: Nullable<ModelShape>, shapeId: number, idxInShape: number, sps: SolidParticleSystem, modelBoundingInfo?: Nullable<BoundingInfo>);
+        constructor(particleIndex: number, particleId: number, positionIndex: number, indiceIndex: number, model: Nullable<ModelShape>, shapeId: number, idxInShape: number, sps: SolidParticleSystem, modelBoundingInfo?: Nullable<BoundingInfo>, materialIndex?: Nullable<number>);
         /**
          * Copies the particle property values into the existing target : position, rotation, scaling, uvs, colors, pivot, parent, visibility, alive
          * @param target the particle target
@@ -26929,6 +26961,7 @@ declare module "babylonjs/Particles/solidParticle" {
     }
     /**
      * Represents a Depth Sorted Particle in the solid particle system.
+     * @hidden
      */
     export class DepthSortedParticle {
         /**
@@ -26943,6 +26976,15 @@ declare module "babylonjs/Particles/solidParticle" {
          * Squared distance from the particle to the camera
          */
         sqDistance: number;
+        /**
+         * Material index when used with MultiMaterials
+         */
+        materialIndex: number;
+        /**
+         * Creates a new sorted particle
+         * @param materialIndex
+         */
+        constructor(ind: number, indLength: number, materialIndex: number);
     }
 }
 declare module "babylonjs/Collisions/meshCollisionData" {
@@ -30261,6 +30303,8 @@ declare module "babylonjs/Engines/thinEngine" {
         deterministicLockstep?: boolean;
         /** Defines the maximum steps to use with deterministic lock step mode */
         lockstepMaxSteps?: number;
+        /** Defines the seconds between each deterministic lock step */
+        timeStep?: number;
         /**
          * Defines that engine should ignore context lost events
          * If this event happens when this parameter is true, you will have to reload the page to restore rendering
@@ -31261,6 +31305,11 @@ declare module "babylonjs/Engines/thinEngine" {
          * @returns frame number
          */
         static QueueNewFrame(func: () => void, requester?: any): number;
+        /**
+         * Gets host document
+         * @returns the host document object
+         */
+        getHostDocument(): Document;
     }
 }
 declare module "babylonjs/Maths/sphericalPolynomial" {
@@ -32592,6 +32641,7 @@ declare module "babylonjs/Engines/engine" {
         protected _alphaEquation: number;
         private _deterministicLockstep;
         private _lockstepMaxSteps;
+        private _timeStep;
         protected readonly _supportsHardwareTextureRescaling: boolean;
         private _fps;
         private _deltaTime;
@@ -32640,11 +32690,6 @@ declare module "babylonjs/Engines/engine" {
          */
         getScreenAspectRatio(): number;
         /**
-         * Gets host document
-         * @returns the host document object
-         */
-        getHostDocument(): Document;
-        /**
          * Gets the client rect of the HTML canvas attached with the current webGL context
          * @returns a client rectanglee
          */
@@ -32667,6 +32712,11 @@ declare module "babylonjs/Engines/engine" {
          */
         getLockstepMaxSteps(): number;
         /**
+         * Returns the time in ms between steps when using deterministic lock step.
+         * @returns time step in (ms)
+         */
+        getTimeStep(): number;
+        /**
          * Force the mipmap generation for the given render target texture
          * @param texture defines the render target texture to use
          */
@@ -56574,6 +56624,7 @@ declare module "babylonjs/Materials/Node/Blocks/Dual/textureBlock" {
         autoConfigure(material: NodeMaterial): void;
         initializeDefines(mesh: AbstractMesh, nodeMaterial: NodeMaterial, defines: NodeMaterialDefines, useInstances?: boolean): void;
         prepareDefines(mesh: AbstractMesh, nodeMaterial: NodeMaterial, defines: NodeMaterialDefines): void;
+        private _getTextureBase;
         isReady(): boolean;
         bind(effect: Effect, nodeMaterial: NodeMaterial, mesh?: Mesh): void;
         private readonly _isMixed;
@@ -57741,12 +57792,46 @@ declare module "babylonjs/Materials/Node/Blocks/Fragment/frontFacingBlock" {
         protected _buildBlock(state: NodeMaterialBuildState): this;
     }
 }
+declare module "babylonjs/Materials/Node/Blocks/Fragment/derivativeBlock" {
+    import { NodeMaterialBlock } from "babylonjs/Materials/Node/nodeMaterialBlock";
+    import { NodeMaterialBuildState } from "babylonjs/Materials/Node/nodeMaterialBuildState";
+    import { NodeMaterialConnectionPoint } from "babylonjs/Materials/Node/nodeMaterialBlockConnectionPoint";
+    /**
+     * Block used to get the derivative value on x and y of a given input
+     */
+    export class DerivativeBlock extends NodeMaterialBlock {
+        /**
+         * Create a new DerivativeBlock
+         * @param name defines the block name
+         */
+        constructor(name: string);
+        /**
+         * Gets the current class name
+         * @returns the class name
+         */
+        getClassName(): string;
+        /**
+         * Gets the input component
+         */
+        readonly input: NodeMaterialConnectionPoint;
+        /**
+         * Gets the derivative output on x
+         */
+        readonly dx: NodeMaterialConnectionPoint;
+        /**
+         * Gets the derivative output on y
+         */
+        readonly dy: NodeMaterialConnectionPoint;
+        protected _buildBlock(state: NodeMaterialBuildState): this;
+    }
+}
 declare module "babylonjs/Materials/Node/Blocks/Fragment/index" {
     export * from "babylonjs/Materials/Node/Blocks/Fragment/fragmentOutputBlock";
     export * from "babylonjs/Materials/Node/Blocks/Fragment/imageProcessingBlock";
     export * from "babylonjs/Materials/Node/Blocks/Fragment/perturbNormalBlock";
     export * from "babylonjs/Materials/Node/Blocks/Fragment/discardBlock";
     export * from "babylonjs/Materials/Node/Blocks/Fragment/frontFacingBlock";
+    export * from "babylonjs/Materials/Node/Blocks/Fragment/derivativeBlock";
 }
 declare module "babylonjs/Materials/Node/Blocks/Dual/fogBlock" {
     import { NodeMaterialBlock } from "babylonjs/Materials/Node/nodeMaterialBlock";
@@ -59396,6 +59481,76 @@ declare module "babylonjs/Materials/Node/Blocks/rotate2dBlock" {
         protected _buildBlock(state: NodeMaterialBuildState): this;
     }
 }
+declare module "babylonjs/Materials/Node/Blocks/reflectBlock" {
+    import { NodeMaterialBlock } from "babylonjs/Materials/Node/nodeMaterialBlock";
+    import { NodeMaterialBuildState } from "babylonjs/Materials/Node/nodeMaterialBuildState";
+    import { NodeMaterialConnectionPoint } from "babylonjs/Materials/Node/nodeMaterialBlockConnectionPoint";
+    /**
+     * Block used to get the reflected vector from a direction and a normal
+     */
+    export class ReflectBlock extends NodeMaterialBlock {
+        /**
+         * Creates a new ReflectBlock
+         * @param name defines the block name
+         */
+        constructor(name: string);
+        /**
+         * Gets the current class name
+         * @returns the class name
+         */
+        getClassName(): string;
+        /**
+         * Gets the incident component
+         */
+        readonly incident: NodeMaterialConnectionPoint;
+        /**
+         * Gets the normal component
+         */
+        readonly normal: NodeMaterialConnectionPoint;
+        /**
+         * Gets the output component
+         */
+        readonly output: NodeMaterialConnectionPoint;
+        protected _buildBlock(state: NodeMaterialBuildState): this;
+    }
+}
+declare module "babylonjs/Materials/Node/Blocks/refractBlock" {
+    import { NodeMaterialBlock } from "babylonjs/Materials/Node/nodeMaterialBlock";
+    import { NodeMaterialBuildState } from "babylonjs/Materials/Node/nodeMaterialBuildState";
+    import { NodeMaterialConnectionPoint } from "babylonjs/Materials/Node/nodeMaterialBlockConnectionPoint";
+    /**
+     * Block used to get the refracted vector from a direction and a normal
+     */
+    export class RefractBlock extends NodeMaterialBlock {
+        /**
+         * Creates a new RefractBlock
+         * @param name defines the block name
+         */
+        constructor(name: string);
+        /**
+         * Gets the current class name
+         * @returns the class name
+         */
+        getClassName(): string;
+        /**
+         * Gets the incident component
+         */
+        readonly incident: NodeMaterialConnectionPoint;
+        /**
+         * Gets the normal component
+         */
+        readonly normal: NodeMaterialConnectionPoint;
+        /**
+         * Gets the index of refraction component
+         */
+        readonly ior: NodeMaterialConnectionPoint;
+        /**
+         * Gets the output component
+         */
+        readonly output: NodeMaterialConnectionPoint;
+        protected _buildBlock(state: NodeMaterialBuildState): this;
+    }
+}
 declare module "babylonjs/Materials/Node/Blocks/index" {
     export * from "babylonjs/Materials/Node/Blocks/Vertex/index";
     export * from "babylonjs/Materials/Node/Blocks/Fragment/index";
@@ -59441,6 +59596,8 @@ declare module "babylonjs/Materials/Node/Blocks/index" {
     export * from "babylonjs/Materials/Node/Blocks/simplexPerlin3DBlock";
     export * from "babylonjs/Materials/Node/Blocks/normalBlendBlock";
     export * from "babylonjs/Materials/Node/Blocks/rotate2dBlock";
+    export * from "babylonjs/Materials/Node/Blocks/reflectBlock";
+    export * from "babylonjs/Materials/Node/Blocks/refractBlock";
 }
 declare module "babylonjs/Materials/Node/Optimizers/index" {
     export * from "babylonjs/Materials/Node/Optimizers/nodeMaterialOptimizer";
@@ -84448,7 +84605,7 @@ declare module BABYLON {
          * Get the current texture matrix which includes the requested offsetting, tiling and rotation components.
          * @returns the transform matrix of the texture.
          */
-        getTextureMatrix(): Matrix;
+        getTextureMatrix(uBase?: number): Matrix;
         /**
          * Get the current matrix used to apply reflection. This is useful to rotate an environment texture for instance.
          * @returns The reflection texture transform
@@ -94018,6 +94175,11 @@ declare module BABYLON {
         private _isNotBuilt;
         private _lastParticleId;
         private _idxOfId;
+        private _multimaterialEnabled;
+        private _indicesByMaterial;
+        private _materialIndexes;
+        private _depthSortFunction;
+        private _materialSortFunction;
         /**
          * Creates a SPS (Solid Particle System) object.
          * @param name (String) is the SPS name, this will be the underlying mesh name.
@@ -94026,6 +94188,7 @@ declare module BABYLON {
          * * updatable (optional boolean, default true) : if the SPS must be updatable or immutable.
          * * isPickable (optional boolean, default false) : if the solid particles must be pickable.
          * * enableDepthSort (optional boolean, default false) : if the solid particles must be sorted in the geometry according to their distance to the camera.
+         * * enableMultiMaterial (optional boolean, default false) : if the solid particles can be given different materials.
          * * expandable (optional boolean, default false) : if particles can still be added after the initial SPS mesh creation.
          * * particleIntersection (optional boolean, default false) : if the solid particle intersections must be computed.
          * * boundingSphereOnly (optional boolean, default false) : if the particle intersection must be computed only with the bounding sphere (no bounding box computation, so faster).
@@ -94040,6 +94203,7 @@ declare module BABYLON {
             boundingSphereOnly?: boolean;
             bSphereRadiusFactor?: number;
             expandable?: boolean;
+            enableMultiMaterial?: boolean;
         });
         /**
          * Builds the SPS underlying mesh. Returns a standard Mesh.
@@ -94077,6 +94241,7 @@ declare module BABYLON {
         /**
          * Inserts the shape model geometry in the global SPS mesh by updating the positions, indices, normals, colors, uvs arrays
          * @param p the current index in the positions array to be updated
+         * @param ind the current index in the indices array
          * @param shape a Vector3 array, the shape geometry
          * @param positions the positions array to be updated
          * @param meshInd the shape indices array
@@ -94217,6 +94382,21 @@ declare module BABYLON {
          */
         getParticlesByShapeIdToRef(shapeId: number, ref: SolidParticle[]): SolidParticleSystem;
         /**
+         * Computes the required SubMeshes according the materials assigned to the particles.
+         * @returns the solid particle system.
+         * Does nothing if called before the SPS mesh is built.
+         */
+        computeSubMeshes(): SolidParticleSystem;
+        /**
+         * Sorts the solid particles by material when MultiMaterial is enabled.
+         * Updates the indices32 array.
+         * Updates the indicesByMaterial array.
+         * Updates the mesh indices array.
+         * @returns the SPS
+         * @hidden
+         */
+        private _sortParticlesByMaterial;
+        /**
          * Visibilty helper : Recomputes the visible size according to the mesh bounding box
          * doc : http://doc.babylonjs.com/how_to/Solid_Particle_System#sps-visibility
          * @returns the SPS.
@@ -94310,6 +94490,10 @@ declare module BABYLON {
          */
         readonly expandable: boolean;
         /**
+         * Gets if the SPS supports the Multi Materials
+         */
+        readonly multimaterialEnabled: boolean;
+        /**
          * This function does nothing. It may be overwritten to set all the particle first values.
          * The SPS doesn't call this function, you may have to call it by your own.
          * doc : http://doc.babylonjs.com/how_to/Solid_Particle_System#particle-management
@@ -94468,6 +94652,10 @@ declare module BABYLON {
          */
         parentId: Nullable<number>;
         /**
+         * The particle material identifier (integer) when MultiMaterials are enabled in the SPS.
+         */
+        materialIndex: Nullable<number>;
+        /**
          * The culling strategy to use to check whether the solid particle must be culled or not when using isInFrustum().
          * The possible values are :
          * - AbstractMesh.CULLINGSTRATEGY_STANDARD
@@ -94494,8 +94682,9 @@ declare module BABYLON {
          * @param idxInShape (integer) is the index of the particle in the current model (ex: the 10th box of addShape(box, 30))
          * @param sps defines the sps it is associated to
          * @param modelBoundingInfo is the reference to the model BoundingInfo used for intersection computations.
+         * @param materialIndex is the particle material identifier (integer) when the MultiMaterials are enabled in the SPS.
          */
-        constructor(particleIndex: number, particleId: number, positionIndex: number, indiceIndex: number, model: Nullable<ModelShape>, shapeId: number, idxInShape: number, sps: SolidParticleSystem, modelBoundingInfo?: Nullable<BoundingInfo>);
+        constructor(particleIndex: number, particleId: number, positionIndex: number, indiceIndex: number, model: Nullable<ModelShape>, shapeId: number, idxInShape: number, sps: SolidParticleSystem, modelBoundingInfo?: Nullable<BoundingInfo>, materialIndex?: Nullable<number>);
         /**
          * Copies the particle property values into the existing target : position, rotation, scaling, uvs, colors, pivot, parent, visibility, alive
          * @param target the particle target
@@ -94595,6 +94784,7 @@ declare module BABYLON {
     }
     /**
      * Represents a Depth Sorted Particle in the solid particle system.
+     * @hidden
      */
     export class DepthSortedParticle {
         /**
@@ -94609,6 +94799,15 @@ declare module BABYLON {
          * Squared distance from the particle to the camera
          */
         sqDistance: number;
+        /**
+         * Material index when used with MultiMaterials
+         */
+        materialIndex: number;
+        /**
+         * Creates a new sorted particle
+         * @param materialIndex
+         */
+        constructor(ind: number, indLength: number, materialIndex: number);
     }
 }
 declare module BABYLON {
@@ -97804,6 +98003,8 @@ declare module BABYLON {
         deterministicLockstep?: boolean;
         /** Defines the maximum steps to use with deterministic lock step mode */
         lockstepMaxSteps?: number;
+        /** Defines the seconds between each deterministic lock step */
+        timeStep?: number;
         /**
          * Defines that engine should ignore context lost events
          * If this event happens when this parameter is true, you will have to reload the page to restore rendering
@@ -98804,6 +99005,11 @@ declare module BABYLON {
          * @returns frame number
          */
         static QueueNewFrame(func: () => void, requester?: any): number;
+        /**
+         * Gets host document
+         * @returns the host document object
+         */
+        getHostDocument(): Document;
     }
 }
 declare module BABYLON {
@@ -100105,6 +100311,7 @@ declare module BABYLON {
         protected _alphaEquation: number;
         private _deterministicLockstep;
         private _lockstepMaxSteps;
+        private _timeStep;
         protected readonly _supportsHardwareTextureRescaling: boolean;
         private _fps;
         private _deltaTime;
@@ -100153,11 +100360,6 @@ declare module BABYLON {
          */
         getScreenAspectRatio(): number;
         /**
-         * Gets host document
-         * @returns the host document object
-         */
-        getHostDocument(): Document;
-        /**
          * Gets the client rect of the HTML canvas attached with the current webGL context
          * @returns a client rectanglee
          */
@@ -100180,6 +100382,11 @@ declare module BABYLON {
          */
         getLockstepMaxSteps(): number;
         /**
+         * Returns the time in ms between steps when using deterministic lock step.
+         * @returns time step in (ms)
+         */
+        getTimeStep(): number;
+        /**
          * Force the mipmap generation for the given render target texture
          * @param texture defines the render target texture to use
          */
@@ -122439,6 +122646,7 @@ declare module BABYLON {
         autoConfigure(material: NodeMaterial): void;
         initializeDefines(mesh: AbstractMesh, nodeMaterial: NodeMaterial, defines: NodeMaterialDefines, useInstances?: boolean): void;
         prepareDefines(mesh: AbstractMesh, nodeMaterial: NodeMaterial, defines: NodeMaterialDefines): void;
+        private _getTextureBase;
         isReady(): boolean;
         bind(effect: Effect, nodeMaterial: NodeMaterial, mesh?: Mesh): void;
         private readonly _isMixed;
@@ -123504,6 +123712,36 @@ declare module BABYLON {
 }
 declare module BABYLON {
     /**
+     * Block used to get the derivative value on x and y of a given input
+     */
+    export class DerivativeBlock extends NodeMaterialBlock {
+        /**
+         * Create a new DerivativeBlock
+         * @param name defines the block name
+         */
+        constructor(name: string);
+        /**
+         * Gets the current class name
+         * @returns the class name
+         */
+        getClassName(): string;
+        /**
+         * Gets the input component
+         */
+        readonly input: NodeMaterialConnectionPoint;
+        /**
+         * Gets the derivative output on x
+         */
+        readonly dx: NodeMaterialConnectionPoint;
+        /**
+         * Gets the derivative output on y
+         */
+        readonly dy: NodeMaterialConnectionPoint;
+        protected _buildBlock(state: NodeMaterialBuildState): this;
+    }
+}
+declare module BABYLON {
+    /**
      * Block used to add support for scene fog
      */
     export class FogBlock extends NodeMaterialBlock {
@@ -124987,6 +125225,70 @@ declare module BABYLON {
 }
 declare module BABYLON {
     /**
+     * Block used to get the reflected vector from a direction and a normal
+     */
+    export class ReflectBlock extends NodeMaterialBlock {
+        /**
+         * Creates a new ReflectBlock
+         * @param name defines the block name
+         */
+        constructor(name: string);
+        /**
+         * Gets the current class name
+         * @returns the class name
+         */
+        getClassName(): string;
+        /**
+         * Gets the incident component
+         */
+        readonly incident: NodeMaterialConnectionPoint;
+        /**
+         * Gets the normal component
+         */
+        readonly normal: NodeMaterialConnectionPoint;
+        /**
+         * Gets the output component
+         */
+        readonly output: NodeMaterialConnectionPoint;
+        protected _buildBlock(state: NodeMaterialBuildState): this;
+    }
+}
+declare module BABYLON {
+    /**
+     * Block used to get the refracted vector from a direction and a normal
+     */
+    export class RefractBlock extends NodeMaterialBlock {
+        /**
+         * Creates a new RefractBlock
+         * @param name defines the block name
+         */
+        constructor(name: string);
+        /**
+         * Gets the current class name
+         * @returns the class name
+         */
+        getClassName(): string;
+        /**
+         * Gets the incident component
+         */
+        readonly incident: NodeMaterialConnectionPoint;
+        /**
+         * Gets the normal component
+         */
+        readonly normal: NodeMaterialConnectionPoint;
+        /**
+         * Gets the index of refraction component
+         */
+        readonly ior: NodeMaterialConnectionPoint;
+        /**
+         * Gets the output component
+         */
+        readonly output: NodeMaterialConnectionPoint;
+        protected _buildBlock(state: NodeMaterialBuildState): this;
+    }
+}
+declare module BABYLON {
+    /**
      * Effect Render Options
      */
     export interface IEffectRendererOptions {

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


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


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

@@ -1930,6 +1930,27 @@ declare module "babylonjs-loaders/glTF/2.0/Extensions/KHR_materials_specular" {
         private _loadSpecularPropertiesAsync;
     }
 }
+declare module "babylonjs-loaders/glTF/2.0/Extensions/KHR_mesh_quantization" {
+    import { IGLTFLoaderExtension } from "babylonjs-loaders/glTF/2.0/glTFLoaderExtension";
+    import { GLTFLoader } from "babylonjs-loaders/glTF/2.0/glTFLoader";
+    /**
+     * [Specification](https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Khronos/KHR_mesh_quantization)
+     */
+    export class KHR_mesh_quantization implements IGLTFLoaderExtension {
+        /**
+         * The name of this extension.
+         */
+        readonly name: string;
+        /**
+         * Defines whether this extension is enabled.
+         */
+        enabled: boolean;
+        /** @hidden */
+        constructor(loader: GLTFLoader);
+        /** @hidden */
+        dispose(): void;
+    }
+}
 declare module "babylonjs-loaders/glTF/2.0/Extensions/KHR_texture_transform" {
     import { Nullable } from "babylonjs/types";
     import { BaseTexture } from "babylonjs/Materials/Textures/baseTexture";
@@ -2145,6 +2166,7 @@ declare module "babylonjs-loaders/glTF/2.0/Extensions/index" {
     export * from "babylonjs-loaders/glTF/2.0/Extensions/KHR_materials_clearcoat";
     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_mesh_quantization";
     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_lod";
@@ -4319,6 +4341,25 @@ declare module BABYLON.GLTF2.Loader.Extensions {
 }
 declare module BABYLON.GLTF2.Loader.Extensions {
     /**
+     * [Specification](https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Khronos/KHR_mesh_quantization)
+     */
+    export class KHR_mesh_quantization implements IGLTFLoaderExtension {
+        /**
+         * The name of this extension.
+         */
+        readonly name: string;
+        /**
+         * Defines whether this extension is enabled.
+         */
+        enabled: boolean;
+        /** @hidden */
+        constructor(loader: GLTFLoader);
+        /** @hidden */
+        dispose(): void;
+    }
+}
+declare module BABYLON.GLTF2.Loader.Extensions {
+    /**
      * [Specification](https://github.com/KhronosGroup/glTF/blob/master/extensions/2.0/Khronos/KHR_texture_transform/README.md)
      */
     export class KHR_texture_transform implements IGLTFLoaderExtension {

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

@@ -42,7 +42,7 @@
 - Added support for 180 VR videos in `VideoDome` ([RaananW](https://github.com/RaananW/))
 - Added optional parameter to use Euler angles in planeRotationGizmo ([CedricGuillemet](https://github.com/CedricGuillemet))
 - Added `AnimationGroup.onAnimationGroupLoopObservable` ([Deltakosh](https://github.com/deltakosh/))
-- Supports custom materials to generate glow through ```referenceMeshToUseItsOwnMaterial``` in the ```GlowLayer``` ([sebavan](http://www.github.com/sebavan))
+- Supports custom materials to generate glow through `referenceMeshToUseItsOwnMaterial` in the `GlowLayer` ([sebavan](http://www.github.com/sebavan))
 - Added `RawTexture2DArray` to enable use of WebGL2 2D array textures by custom shaders ([atg](https://github.com/atg))
 - Added multiview support for the shader material (and the line-mesh class) ([RaananW](https://github.com/RaananW/))
 - Added various (interpolation) functions to Path3D, also `alignTangentsWithPath`, `slice`, `getClosestPositionTo` ([Poolminer](https://github.com/Poolminer/))
@@ -85,6 +85,7 @@
 - Added a color picker and previewer for BABYLON.ColorX invocations in the playground ([sailro](http://www.github.com/sailro))
 - Added support for diffing snippets in the playground ([sailro](http://www.github.com/sailro))
 - Added diff navigator in the playground ([sailro](http://www.github.com/sailro))
+- Added custom filter to remove internals from the completion in the playground ([sailro](http://www.github.com/sailro))
 
 ### Meshes
 
@@ -112,6 +113,8 @@
 - Added support for GLTF clearcoat extension [Sebavan](https://github.com/sebavan/)
 - Added support for GLTF specular extension [Sebavan](https://github.com/sebavan/)
 - Added support for GLTF sheen extension [Sebavan](https://github.com/sebavan/)
+- Added support for GLTF mesh quantization extension ([zeux](https://github.com/zeux))
+- Added support for 8 bone influences to glTF loader ([zeux](https://github.com/zeux))
 
 ### Materials
 
@@ -153,7 +156,6 @@
 - Added option to change the teleportation duration in the VRExperienceHelper class ([https://github.com/LeoRodz](https://github.com/LeoRodz))
 - Added support to teleport the camera at constant speed in the VRExperienceHelper class ([https://github.com/LeoRodz](https://github.com/LeoRodz))
 
-
 ### Ray
 
 - Added `Ray.intersectsAxis` to translate screen to axis coordinates without checking collisions ([horusscope](https://github.com/horusscope))
@@ -172,6 +174,7 @@
 - Added the feature `expandable` to the Solid Particle System ([jerome](https://github.com/jbousquie/))
 - Added the feature `removeParticles()` to the Solid Particle System ([jerome](https://github.com/jbousquie/))
 - Added the feature "storable particles" and `insertParticlesFromArray()` to the Solid Particle System ([jerome](https://github.com/jbousquie/))
+- Added the support for MultiMaterials to the Solid Particle System ([jerome](https://github.com/jbousquie/))  
 
 ### Navigation Mesh
 
@@ -228,12 +231,13 @@
 - Fixed an issue with size of texture in multiview ([RaananW](https://github.com/RaananW/))
 - Fixed Path3D (bi)normals computation for specific edge cases ([Poolminer](https://github.com/Poolminer/))
 - WebXR UI BUtton will only change to "In XR" after XR Session started ([RaananW](https://github.com/RaananW/))
+- Fix bug when we call `Mesh.render` twice and the material is still not ready on the second call ([barroij](https://github.com/barroij/))
 
 ## Breaking changes
 
 - Setting mesh.scaling to a new vector will no longer automatically call forceUpdate (this should be done manually when needed) ([TrevorDev](https://github.com/TrevorDev))
 - `Tools.ExtractMinAndMaxIndexed` and `Tools.ExtractMinAndMax` are now ambiant functions (available on `BABYLON.extractMinAndMaxIndexed` and `BABYLON.extractMinAndMax`) ([Deltakosh](https://github.com/deltakosh/))
 - `Tools.QueueNewFrame` was removed in favor of `Engine.QueueNewFrame` ([Deltakosh](https://github.com/deltakosh/))
-- Removed external data from Engine (`addExternalData`, `getExternalData`, `getOrAddExternalDataWithFactory`, `removeExternalData`)  ([Deltakosh](https://github.com/deltakosh/))
+- Removed external data from Engine (`addExternalData`, `getExternalData`, `getOrAddExternalDataWithFactory`, `removeExternalData`) ([Deltakosh](https://github.com/deltakosh/))
 - The glTF loader extensions that map to glTF 2.0 extensions will now be disabled if the extension is not present in `extensionsUsed`. ([bghgary](https://github.com/bghgary))
-- The STL loader does not create light or camera automatically, please use ```scene.createDefaultCameraOrLight();``` in your code [Sebavan](https://github.com/sebavan/)
+- The STL loader does not create light or camera automatically, please use `scene.createDefaultCameraOrLight();` in your code [Sebavan](https://github.com/sebavan/)

+ 3 - 0
gui/src/2D/controls/control.ts

@@ -103,6 +103,9 @@ export class Control {
     public _isClipped = false;
 
     /** @hidden */
+    public _automaticSize = false;
+
+    /** @hidden */
     public _tag: any;
 
     /**

+ 2 - 0
gui/src/2D/controls/line.ts

@@ -156,6 +156,8 @@ export class Line extends Control {
     constructor(public name?: string) {
         super(name);
 
+        this._automaticSize = true;
+
         this.isHitTestVisible = false;
         this._horizontalAlignment = Control.HORIZONTAL_ALIGNMENT_LEFT;
         this._verticalAlignment = Control.VERTICAL_ALIGNMENT_TOP;

+ 1 - 0
gui/src/2D/controls/multiLine.ts

@@ -27,6 +27,7 @@ export class MultiLine extends Control {
     constructor(public name?: string) {
         super(name);
 
+        this._automaticSize = true;
         this.isHitTestVisible = false;
         this._horizontalAlignment = Control.HORIZONTAL_ALIGNMENT_LEFT;
         this._verticalAlignment = Control.VERTICAL_ALIGNMENT_TOP;

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

@@ -134,7 +134,7 @@ export class StackPanel extends Container {
                     child._top.ignoreAdaptiveScaling = true;
                 }
 
-                if (child._height.isPercentage) {
+                if (child._height.isPercentage && !child._automaticSize) {
                     if (!this.ignoreLayoutWarnings) {
                         Tools.Warn(`Control (Name:${child.name}, UniqueId:${child.uniqueId}) is using height in percentage mode inside a vertical StackPanel`);
                     }
@@ -148,7 +148,7 @@ export class StackPanel extends Container {
                     child._left.ignoreAdaptiveScaling = true;
                 }
 
-                if (child._width.isPercentage) {
+                if (child._width.isPercentage && !child._automaticSize) {
                     if (!this.ignoreLayoutWarnings) {
                         Tools.Warn(`Control (Name:${child.name}, UniqueId:${child.uniqueId}) is using width in percentage mode inside a horizontal StackPanel`);
                     }

+ 1 - 1
inspector/src/components/actionTabs/lines/optionsLineComponent.tsx

@@ -79,7 +79,7 @@ export class OptionsLineComponent extends React.Component<IOptionsLineComponentP
 
                 </div>
                 <div className="options">
-                    <select onChange={evt => this.updateValue(evt.target.value)} value={this.state.value}>
+                    <select onChange={evt => this.updateValue(evt.target.value)} value={this.state.value || ""}>
                         {
                             this.props.options.map(option => {
                                 return (

+ 11 - 5
inspector/src/components/actionTabs/lines/textureLinkLineComponent.tsx

@@ -18,14 +18,14 @@ export interface ITextureLinkLineComponentProps {
     texture: Nullable<BaseTexture>;
     material?: Material;
     onSelectionChangedObservable?: Observable<any>;
-    onDebugSelectionChangeObservable?: Observable<BaseTexture>;
+    onDebugSelectionChangeObservable?: Observable<TextureLinkLineComponent>;
     propertyName?: string;
     onTextureCreated?: (texture: BaseTexture) => void;
     customDebugAction?: (state: boolean) => void
 }
 
 export class TextureLinkLineComponent extends React.Component<ITextureLinkLineComponentProps, { isDebugSelected: boolean }> {
-    private _onDebugSelectionChangeObserver: Nullable<Observer<BaseTexture>>;
+    private _onDebugSelectionChangeObserver: Nullable<Observer<TextureLinkLineComponent>>;
 
     constructor(props: ITextureLinkLineComponentProps) {
         super(props);
@@ -40,8 +40,8 @@ export class TextureLinkLineComponent extends React.Component<ITextureLinkLineCo
         if (!this.props.onDebugSelectionChangeObservable) {
             return;
         }
-        this._onDebugSelectionChangeObserver = this.props.onDebugSelectionChangeObservable.add((texture) => {
-            if (this.props.texture !== texture) {
+        this._onDebugSelectionChangeObserver = this.props.onDebugSelectionChangeObservable.add((line) => {
+            if (line !== this) {
                 this.setState({ isDebugSelected: false });
             }
         });
@@ -58,10 +58,16 @@ export class TextureLinkLineComponent extends React.Component<ITextureLinkLineCo
             let newState = !this.state.isDebugSelected;
             this.props.customDebugAction(newState);
             this.setState({ isDebugSelected: newState });
+            
+            if (this.props.onDebugSelectionChangeObservable) {
+                this.props.onDebugSelectionChangeObservable.notifyObservers(this);
+            }
+
             return;
         }
 
         const texture = this.props.texture;
+
         const material = this.props.material;
 
         if (!material || !texture) {
@@ -115,7 +121,7 @@ export class TextureLinkLineComponent extends React.Component<ITextureLinkLineCo
         texture.level = 1.0;
 
         if (this.props.onDebugSelectionChangeObservable) {
-            this.props.onDebugSelectionChangeObservable.notifyObservers(texture!);
+            this.props.onDebugSelectionChangeObservable.notifyObservers(this);
         }
 
         if (needToDisposeCheckMaterial) {

+ 1 - 2
inspector/src/components/actionTabs/tabs/propertyGrids/materials/backgroundMaterialPropertyGridComponent.tsx

@@ -1,7 +1,6 @@
 import * as React from "react";
 
 import { Observable } from "babylonjs/Misc/observable";
-import { BaseTexture } from "babylonjs/Materials/Textures/baseTexture";
 import { BackgroundMaterial } from "babylonjs/Materials/Background/backgroundMaterial";
 
 import { PropertyChangedEvent } from "../../../../propertyChangedEvent";
@@ -23,7 +22,7 @@ interface IBackgroundMaterialPropertyGridComponentProps {
 }
 
 export class BackgroundMaterialPropertyGridComponent extends React.Component<IBackgroundMaterialPropertyGridComponentProps> {
-    private _onDebugSelectionChangeObservable = new Observable<BaseTexture>();
+    private _onDebugSelectionChangeObservable = new Observable<TextureLinkLineComponent>();
 
     constructor(props: IBackgroundMaterialPropertyGridComponentProps) {
         super(props);

+ 1 - 2
inspector/src/components/actionTabs/tabs/propertyGrids/materials/nodeMaterialPropertyGridComponent.tsx

@@ -15,7 +15,6 @@ import { Color3LineComponent } from '../../../lines/color3LineComponent';
 import { Vector3LineComponent } from '../../../lines/vector3LineComponent';
 import { Vector4LineComponent } from '../../../lines/vector4LineComponent';
 import { Vector2LineComponent } from '../../../lines/vector2LineComponent';
-import { BaseTexture } from 'babylonjs/Materials/Textures/baseTexture';
 import { TextureLinkLineComponent } from '../../../lines/textureLinkLineComponent';
 import { SliderLineComponent } from '../../../lines/sliderLineComponent';
 import { NodeMaterialBlockConnectionPointTypes } from 'babylonjs/Materials/Node/Enums/nodeMaterialBlockConnectionPointTypes';
@@ -29,7 +28,7 @@ interface INodeMaterialPropertyGridComponentProps {
 }
 
 export class NodeMaterialPropertyGridComponent extends React.Component<INodeMaterialPropertyGridComponentProps> {
-    private _onDebugSelectionChangeObservable = new Observable<BaseTexture>();
+    private _onDebugSelectionChangeObservable = new Observable<TextureLinkLineComponent>();
     
     constructor(props: INodeMaterialPropertyGridComponentProps) {
         super(props);

+ 2 - 3
inspector/src/components/actionTabs/tabs/propertyGrids/materials/pbrMaterialPropertyGridComponent.tsx

@@ -1,7 +1,6 @@
 import * as React from "react";
 
 import { Observable } from "babylonjs/Misc/observable";
-import { BaseTexture } from "babylonjs/Materials/Textures/baseTexture";
 import { PBRMaterial } from "babylonjs/Materials/PBR/pbrMaterial";
 
 import { PropertyChangedEvent } from "../../../../propertyChangedEvent";
@@ -25,7 +24,7 @@ interface IPBRMaterialPropertyGridComponentProps {
 }
 
 export class PBRMaterialPropertyGridComponent extends React.Component<IPBRMaterialPropertyGridComponentProps> {
-    private _onDebugSelectionChangeObservable = new Observable<BaseTexture>();
+    private _onDebugSelectionChangeObservable = new Observable<TextureLinkLineComponent>();
     constructor(props: IPBRMaterialPropertyGridComponentProps) {
         super(props);
     }
@@ -42,7 +41,7 @@ export class PBRMaterialPropertyGridComponent extends React.Component<IPBRMateri
         this.props.material.debugMode = state ? 63 : 0;
     }
 
-    renderTextures(onDebugSelectionChangeObservable: Observable<BaseTexture>) {
+    renderTextures(onDebugSelectionChangeObservable: Observable<TextureLinkLineComponent>) {
         const material = this.props.material;
 
         return (

+ 1 - 2
inspector/src/components/actionTabs/tabs/propertyGrids/materials/pbrMetallicRoughnessMaterialPropertyGridComponent.tsx

@@ -1,7 +1,6 @@
 import * as React from "react";
 
 import { Observable } from "babylonjs/Misc/observable";
-import { BaseTexture } from "babylonjs/Materials/Textures/baseTexture";
 import { PBRMetallicRoughnessMaterial } from "babylonjs/Materials/PBR/pbrMetallicRoughnessMaterial";
 
 import { PropertyChangedEvent } from "../../../../propertyChangedEvent";
@@ -22,7 +21,7 @@ interface IPBRMetallicRoughnessMaterialPropertyGridComponentProps {
 }
 
 export class PBRMetallicRoughnessMaterialPropertyGridComponent extends React.Component<IPBRMetallicRoughnessMaterialPropertyGridComponentProps> {
-    private _onDebugSelectionChangeObservable = new Observable<BaseTexture>();
+    private _onDebugSelectionChangeObservable = new Observable<TextureLinkLineComponent>();
 
     constructor(props: IPBRMetallicRoughnessMaterialPropertyGridComponentProps) {
         super(props);

+ 1 - 2
inspector/src/components/actionTabs/tabs/propertyGrids/materials/pbrSpecularGlossinessMaterialPropertyGridComponent.tsx

@@ -1,7 +1,6 @@
 import * as React from "react";
 
 import { Observable } from "babylonjs/Misc/observable";
-import { BaseTexture } from "babylonjs/Materials/Textures/baseTexture";
 import { PBRSpecularGlossinessMaterial } from "babylonjs/Materials/PBR/pbrSpecularGlossinessMaterial";
 
 import { PropertyChangedEvent } from "../../../../propertyChangedEvent";
@@ -22,7 +21,7 @@ interface IPBRSpecularGlossinessMaterialPropertyGridComponentProps {
 }
 
 export class PBRSpecularGlossinessMaterialPropertyGridComponent extends React.Component<IPBRSpecularGlossinessMaterialPropertyGridComponentProps> {
-    private _onDebugSelectionChangeObservable = new Observable<BaseTexture>();
+    private _onDebugSelectionChangeObservable = new Observable<TextureLinkLineComponent>();
 
     constructor(props: IPBRSpecularGlossinessMaterialPropertyGridComponentProps) {
         super(props);

+ 1 - 2
inspector/src/components/actionTabs/tabs/propertyGrids/materials/standardMaterialPropertyGridComponent.tsx

@@ -1,7 +1,6 @@
 import * as React from "react";
 
 import { Observable } from "babylonjs/Misc/observable";
-import { BaseTexture } from "babylonjs/Materials/Textures/baseTexture";
 import { StandardMaterial } from "babylonjs/Materials/standardMaterial";
 
 import { PropertyChangedEvent } from "../../../../propertyChangedEvent";
@@ -23,7 +22,7 @@ interface IStandardMaterialPropertyGridComponentProps {
 }
 
 export class StandardMaterialPropertyGridComponent extends React.Component<IStandardMaterialPropertyGridComponentProps> {
-    private _onDebugSelectionChangeObservable = new Observable<BaseTexture>();
+    private _onDebugSelectionChangeObservable = new Observable<TextureLinkLineComponent>();
 
     constructor(props: IStandardMaterialPropertyGridComponentProps) {
         super(props);

+ 9 - 9
loaders/src/glTF/2.0/Extensions/KHR_materials_sheen.ts

@@ -10,9 +10,9 @@ import { Color3 } from 'babylonjs/Maths/math.color';
 const NAME = "KHR_materials_sheen";
 
 interface IKHR_materials_sheen {
-    sheenFactor: number;
-    sheenColor: number[];
-    sheenTexture: ITextureInfo;
+    intensityFactor: number;
+    colorFactor: number[];
+    colorIntensityTexture: ITextureInfo;
 }
 
 /**
@@ -68,19 +68,19 @@ export class KHR_materials_sheen implements IGLTFLoaderExtension {
 
         babylonMaterial.sheen.isEnabled = true;
 
-        if (properties.sheenFactor != undefined) {
-            babylonMaterial.sheen.intensity = properties.sheenFactor;
+        if (properties.intensityFactor != undefined) {
+            babylonMaterial.sheen.intensity = properties.intensityFactor;
         }
         else {
             babylonMaterial.sheen.intensity = 0;
         }
 
-        if (properties.sheenColor != undefined) {
-            babylonMaterial.sheen.color = Color3.FromArray(properties.sheenColor);
+        if (properties.colorFactor != undefined) {
+            babylonMaterial.sheen.color = Color3.FromArray(properties.colorFactor);
         }
 
-        if (properties.sheenTexture) {
-            promises.push(this._loader.loadTextureInfoAsync(`${context}/sheenTexture`, properties.sheenTexture, (texture) => {
+        if (properties.colorIntensityTexture) {
+            promises.push(this._loader.loadTextureInfoAsync(`${context}/sheenTexture`, properties.colorIntensityTexture, (texture) => {
                 texture.name = `${babylonMaterial.name} (Sheen Intensity)`;
                 babylonMaterial.sheen.texture = texture;
             }));

+ 30 - 0
loaders/src/glTF/2.0/Extensions/KHR_mesh_quantization.ts

@@ -0,0 +1,30 @@
+import { IGLTFLoaderExtension } from "../glTFLoaderExtension";
+import { GLTFLoader } from "../glTFLoader";
+
+const NAME = "KHR_mesh_quantization";
+
+/**
+ * [Specification](https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Khronos/KHR_mesh_quantization)
+ */
+export class KHR_mesh_quantization implements IGLTFLoaderExtension {
+    /**
+     * The name of this extension.
+     */
+    public readonly name = NAME;
+
+    /**
+     * Defines whether this extension is enabled.
+     */
+    public enabled: boolean;
+
+    /** @hidden */
+    constructor(loader: GLTFLoader) {
+        this.enabled = loader.isExtensionUsed(NAME);
+    }
+
+    /** @hidden */
+    public dispose() {
+    }
+}
+
+GLTFLoader.RegisterExtension(NAME, (loader) => new KHR_mesh_quantization(loader));

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

@@ -6,9 +6,10 @@ export * from "./KHR_materials_unlit";
 export * from "./KHR_materials_clearcoat";
 export * from "./KHR_materials_sheen";
 export * from "./KHR_materials_specular";
+export * from "./KHR_mesh_quantization";
 export * from "./KHR_texture_transform";
 export * from "./MSFT_audio_emitter";
 export * from "./MSFT_lod";
 export * from "./MSFT_minecraftMesh";
 export * from "./MSFT_sRGBFactors";
-export * from "./ExtrasAsMetadata";
+export * from "./ExtrasAsMetadata";

+ 7 - 1
loaders/src/glTF/2.0/glTFLoader.ts

@@ -844,6 +844,10 @@ export class GLTFLoader implements IGLTFLoader {
                 babylonGeometry.setVerticesBuffer(babylonVertexBuffer, accessor.count);
             }));
 
+            if (kind == VertexBuffer.MatricesIndicesExtraKind) {
+                babylonMesh.numBoneInfluencers = 8;
+            }
+
             if (callback) {
                 callback(accessor);
             }
@@ -856,6 +860,8 @@ export class GLTFLoader implements IGLTFLoader {
         loadAttribute("TEXCOORD_1", VertexBuffer.UV2Kind);
         loadAttribute("JOINTS_0", VertexBuffer.MatricesIndicesKind);
         loadAttribute("WEIGHTS_0", VertexBuffer.MatricesWeightsKind);
+        loadAttribute("JOINTS_1", VertexBuffer.MatricesIndicesExtraKind);
+        loadAttribute("WEIGHTS_1", VertexBuffer.MatricesWeightsExtraKind);
         loadAttribute("COLOR_0", VertexBuffer.ColorKind, (accessor) => {
             if (accessor.type === AccessorType.VEC4) {
                 babylonMesh.hasVertexAlpha = true;
@@ -1577,7 +1583,7 @@ export class GLTFLoader implements IGLTFLoader {
         }
         // Load joint indices as a float array since the shaders expect float data but glTF uses unsigned byte/short.
         // This prevents certain platforms (e.g. D3D) from having to convert the data to float on the fly.
-        else if (kind === VertexBuffer.MatricesIndicesKind) {
+        else if (kind === VertexBuffer.MatricesIndicesKind || kind === VertexBuffer.MatricesIndicesExtraKind) {
             accessor._babylonVertexBuffer = this._loadFloatAccessorAsync(`/accessors/${accessor.index}`, accessor).then((data) => {
                 return new VertexBuffer(this._babylonScene.getEngine(), data, kind, false);
             });

+ 9 - 0
nodeEditor/src/blockTools.ts

@@ -58,10 +58,19 @@ import { WorleyNoise3DBlock } from 'babylonjs/Materials/Node/Blocks/worleyNoise3
 import { SimplexPerlin3DBlock } from 'babylonjs/Materials/Node/Blocks/simplexPerlin3DBlock';
 import { NormalBlendBlock } from 'babylonjs/Materials/Node/Blocks/normalBlendBlock';
 import { Rotate2dBlock } from 'babylonjs/Materials/Node/Blocks/rotate2dBlock';
+import { DerivativeBlock } from 'babylonjs/Materials/Node/Blocks/Fragment/derivativeBlock';
+import { RefractBlock } from 'babylonjs/Materials/Node/Blocks/refractBlock';
+import { ReflectBlock } from 'babylonjs/Materials/Node/Blocks/reflectBlock';
 
 export class BlockTools {
     public static GetBlockFromString(data: string, scene: Scene, nodeMaterial: NodeMaterial) {
         switch (data) {
+            case "RefractBlock":
+                return new RefractBlock("Refract");               
+            case "ReflectBlock":
+                return new ReflectBlock("Reflect");              
+            case "DerivativeBlock":
+                return new DerivativeBlock("Derivative");               
             case "Rotate2dBlock":
                 return new Rotate2dBlock("Rotate2d");            
             case "NormalBlendBlock":

+ 1 - 1
nodeEditor/src/components/nodeList/nodeListComponent.tsx

@@ -131,7 +131,7 @@ export class NodeListComponent extends React.Component<INodeListComponentProps,
             Round: ["RoundBlock", "CeilingBlock", "FloorBlock"],
             Scene: ["FogBlock", "CameraPositionBlock", "FogColorBlock", "ImageProcessingBlock", "LightBlock", "LightInformationBlock", "ViewDirectionBlock", "PerturbNormalBlock", "NormalBlendBlock"],
             Trigonometry: ["CosBlock", "SinBlock", "AbsBlock", "ExpBlock", "Exp2Block", "SqrtBlock", "PowBlock", "LogBlock", "ArcCosBlock", "ArcSinBlock", "TanBlock", "ArcTanBlock", "FractBlock", "SignBlock", "ArcTan2Block", "DegreesToRadiansBlock", "RadiansToDegreesBlock", "SawToothWaveBlock", "TriangleWaveBlock", "SquareWaveBlock"],
-            Vector_Math: ["CrossBlock", "DotBlock", "TransformBlock", "FresnelBlock", "Rotate2dBlock"],
+            Vector_Math: ["CrossBlock", "DotBlock", "TransformBlock", "FresnelBlock", "Rotate2dBlock", "DerivativeBlock", "RefractBlock", "ReflectBlock"],
         }
 
         // Create node menu

+ 1 - 1
nodeEditor/src/sharedComponents/optionsLineComponent.tsx

@@ -90,7 +90,7 @@ export class OptionsLineComponent extends React.Component<IOptionsLineComponentP
 
                 </div>
                 <div className={"options" + (this.props.className ? " " + this.props.className : "")}>
-                    <select onChange={evt => this.updateValue(evt.target.value)} value={this.state.value}>
+                    <select onChange={evt => this.updateValue(evt.target.value)} value={this.state.value || ""}>
                         {
                             this.props.options.map(option => {
                                 return (

+ 4 - 4
package.json

@@ -7,7 +7,7 @@
     ],
     "name": "babylonjs",
     "description": "Babylon.js is a JavaScript 3D engine based on webgl.",
-    "version": "4.1.0-beta.2",
+    "version": "4.1.0-beta.3",
     "repository": {
         "type": "git",
         "url": "https://github.com/BabylonJS/Babylon.js.git"
@@ -56,7 +56,7 @@
         "css-loader": "^1.0.0",
         "dagre": "0.8.4",
         "del": "3.0.0",
-        "dependency-cruiser": "^4.19.0",
+        "dependency-cruiser": "^5.2.3",
         "dts-bundle": "^0.7.3",
         "file-loader": "~2.0.0",
         "fs-extra": "^5.0.0",
@@ -95,7 +95,7 @@
         "style-loader": "^0.21.0",
         "through2": "~2.0.3",
         "ts-loader": "^5.2.1",
-        "tslib": "^1.9.3",
+        "tslib": "^1.10.0",
         "tslint": "^5.11.0",
         "typedoc": "^0.15.0",
         "typescript": "~3.6.3",
@@ -107,4 +107,4 @@
         "xhr2": "^0.1.4",
         "xmlbuilder": "8.2.2"
     }
-}
+}

+ 1 - 1
src/Cameras/VR/vrExperienceHelper.ts

@@ -832,7 +832,7 @@ export class VRExperienceHelper {
 
         // Exiting VR mode double tapping the touch screen
         this._scene.onPrePointerObservable.add(() => {
-            if (this.isInVRMode && this.exitVROnDoubleTap) {
+            if (this._hasEnteredVR && this.exitVROnDoubleTap) {
                 this.exitVR();
                 if (this._fullscreenVRpresenting) {
                     this._scene.getEngine().exitFullscreen();

+ 4 - 2
src/Cameras/XR/webXRExperienceHelper.ts

@@ -138,13 +138,15 @@ export class WebXRExperienceHelper implements IDisposable {
             // Wait until the first frame arrives before setting state to in xr
             this.sessionManager.onXRFrameObservable.addOnce(() => {
                 this._setState(WebXRState.IN_XR);
+
+                this.setPositionOfCameraUsingContainer(new Vector3(this._nonVRCamera!.position.x, this.camera.position.y, this._nonVRCamera!.position.z));
             });
 
             return this.sessionManager;
         }).catch((e: any) => {
             console.log(e);
             console.log(e.message);
-            throw(e);
+            throw (e);
         });
     }
 
@@ -180,4 +182,4 @@ export class WebXRExperienceHelper implements IDisposable {
         this.onStateChangedObservable.clear();
         this.sessionManager.dispose();
     }
-}
+}

+ 11 - 12
src/Engines/engine.ts

@@ -427,6 +427,7 @@ export class Engine extends ThinEngine {
     // Deterministic lockstepMaxSteps
     private _deterministicLockstep: boolean = false;
     private _lockstepMaxSteps: number = 4;
+    private _timeStep: number = 1 / 60;
 
     protected get _supportsHardwareTextureRescaling() {
         return !!Engine._RescalePostProcessFactory;
@@ -586,6 +587,8 @@ export class Engine extends ThinEngine {
 
             this._deterministicLockstep = !!options.deterministicLockstep;
             this._lockstepMaxSteps = options.lockstepMaxSteps || 0;
+            this._timeStep = options.timeStep || 1 / 60;
+
         }
 
         // Load WebVR Devices
@@ -615,18 +618,6 @@ export class Engine extends ThinEngine {
     }
 
     /**
-     * Gets host document
-     * @returns the host document object
-     */
-    public getHostDocument(): Document {
-        if (this._renderingCanvas && this._renderingCanvas.ownerDocument) {
-            return this._renderingCanvas.ownerDocument;
-        }
-
-        return document;
-    }
-
-    /**
      * Gets the client rect of the HTML canvas attached with the current webGL context
      * @returns a client rectanglee
      */
@@ -667,6 +658,14 @@ export class Engine extends ThinEngine {
     }
 
     /**
+     * Returns the time in ms between steps when using deterministic lock step.
+     * @returns time step in (ms)
+     */
+    public getTimeStep(): number {
+        return this._timeStep * 1000;
+    }
+
+    /**
      * Force the mipmap generation for the given render target texture
      * @param texture defines the render target texture to use
      */

+ 22 - 3
src/Engines/thinEngine.ts

@@ -88,10 +88,13 @@ export interface EngineOptions extends WebGLContextAttributes {
     deterministicLockstep?: boolean;
     /** Defines the maximum steps to use with deterministic lock step mode */
     lockstepMaxSteps?: number;
+    /** Defines the seconds between each deterministic lock step */
+    timeStep?: number;
     /**
      * Defines that engine should ignore context lost events
      * If this event happens when this parameter is true, you will have to reload the page to restore rendering
      */
+
     doNotHandleContextLost?: boolean;
     /**
      * Defines that engine should ignore modifying touch action attribute and style
@@ -128,14 +131,14 @@ export class ThinEngine {
      */
     // Not mixed with Version for tooling purpose.
     public static get NpmPackage(): string {
-        return "babylonjs@4.1.0-beta.2";
+        return "babylonjs@4.1.0-beta.3";
     }
 
     /**
      * Returns the current version of the framework
      */
     public static get Version(): string {
-        return "4.1.0-beta.2";
+        return "4.1.0-beta.3";
     }
 
     /**
@@ -488,6 +491,10 @@ export class ThinEngine {
                 options.lockstepMaxSteps = 4;
             }
 
+            if (options.timeStep === undefined) {
+                options.timeStep = 1 / 60;
+            }
+
             if (options.preserveDrawingBuffer === undefined) {
                 options.preserveDrawingBuffer = false;
             }
@@ -710,7 +717,7 @@ export class ThinEngine {
             maxCombinedTexturesImageUnits: this._gl.getParameter(this._gl.MAX_COMBINED_TEXTURE_IMAGE_UNITS),
             maxVertexTextureImageUnits: this._gl.getParameter(this._gl.MAX_VERTEX_TEXTURE_IMAGE_UNITS),
             maxTextureSize: this._gl.getParameter(this._gl.MAX_TEXTURE_SIZE),
-            maxSamples: this._gl.getParameter(this._gl.MAX_SAMPLES),
+            maxSamples: this._webGLVersion > 1 ? this._gl.getParameter(this._gl.MAX_SAMPLES) : 1,
             maxCubemapTextureSize: this._gl.getParameter(this._gl.MAX_CUBE_MAP_TEXTURE_SIZE),
             maxRenderTextureSize: this._gl.getParameter(this._gl.MAX_RENDERBUFFER_SIZE),
             maxVertexAttribs: this._gl.getParameter(this._gl.MAX_VERTEX_ATTRIBS),
@@ -4112,4 +4119,16 @@ export class ThinEngine {
             return window.setTimeout(func, 16);
         }
     }
+
+    /**
+     * Gets host document
+     * @returns the host document object
+     */
+    public getHostDocument(): Document {
+        if (this._renderingCanvas && this._renderingCanvas.ownerDocument) {
+            return this._renderingCanvas.ownerDocument;
+        }
+
+        return document;
+    }
 }

+ 15 - 2
src/Materials/Node/Blocks/Dual/textureBlock.ts

@@ -12,6 +12,7 @@ import { Nullable } from '../../../../types';
 import { _TypeStore } from '../../../../Misc/typeStore';
 import { Texture } from '../../../Textures/texture';
 import { Scene } from '../../../../scene';
+import { Constants } from '../../../../Engines/constants';
 
 import "../../../../Shaders/ShadersInclude/helperFunctions";
 
@@ -185,7 +186,7 @@ export class TextureBlock extends NodeMaterialBlock {
 
         defines.setValue(this._linearDefineName, !this.texture.gammaSpace);
         if (this._isMixed) {
-            if (!this.texture.getTextureMatrix().isIdentityAs3x2()) {
+            if (!this.texture.getTextureMatrix(this._getTextureBase(mesh as Mesh)).isIdentityAs3x2()) {
                 defines.setValue(this._defineName, true);
             } else {
                 defines.setValue(this._defineName, false);
@@ -194,6 +195,18 @@ export class TextureBlock extends NodeMaterialBlock {
         }
     }
 
+    private _getTextureBase(mesh?: Mesh) {
+        let base = 1;
+        // By default textures loaded by the node material are loaded with invertY set to false. But for regular meshes (created by the MeshBuilder) we need to switch it
+        if (this.texture && mesh && (mesh.overrideMaterialSideOrientation === null || mesh.overrideMaterialSideOrientation === Constants.MATERIAL_CounterClockWiseSideOrientation)) {
+            if (!this.texture.invertY) {
+                base = -1;
+            }
+        }
+
+        return base;
+    }
+
     public isReady() {
         if (this.texture && !this.texture.isReadyOrNotBlocking()) {
             return false;
@@ -209,7 +222,7 @@ export class TextureBlock extends NodeMaterialBlock {
 
         if (this._isMixed) {
             effect.setFloat(this._textureInfoName, this.texture.level);
-            effect.setMatrix(this._textureTransformName, this.texture.getTextureMatrix());
+            effect.setMatrix(this._textureTransformName, this.texture.getTextureMatrix(this._getTextureBase(mesh)));
         }
         effect.setTexture(this._samplerName, this.texture);
     }

+ 74 - 0
src/Materials/Node/Blocks/Fragment/derivativeBlock.ts

@@ -0,0 +1,74 @@
+import { NodeMaterialBlock } from '../../nodeMaterialBlock';
+import { NodeMaterialBlockConnectionPointTypes } from '../../Enums/nodeMaterialBlockConnectionPointTypes';
+import { NodeMaterialBuildState } from '../../nodeMaterialBuildState';
+import { NodeMaterialBlockTargets } from '../../Enums/nodeMaterialBlockTargets';
+import { NodeMaterialConnectionPoint } from '../../nodeMaterialBlockConnectionPoint';
+import { _TypeStore } from '../../../../Misc/typeStore';
+
+/**
+ * Block used to get the derivative value on x and y of a given input
+ */
+export class DerivativeBlock extends NodeMaterialBlock {
+    /**
+     * Create a new DerivativeBlock
+     * @param name defines the block name
+     */
+    public constructor(name: string) {
+        super(name, NodeMaterialBlockTargets.Fragment);
+
+        this.registerInput("input", NodeMaterialBlockConnectionPointTypes.AutoDetect, false);
+        this.registerOutput("dx", NodeMaterialBlockConnectionPointTypes.BasedOnInput);
+        this.registerOutput("dy", NodeMaterialBlockConnectionPointTypes.BasedOnInput);
+
+        this._outputs[0]._typeConnectionSource = this._inputs[0];
+        this._outputs[1]._typeConnectionSource = this._inputs[0];
+    }
+
+    /**
+     * Gets the current class name
+     * @returns the class name
+     */
+    public getClassName() {
+        return "DerivativeBlock";
+    }
+
+    /**
+     * Gets the input component
+     */
+    public get input(): NodeMaterialConnectionPoint {
+        return this._inputs[0];
+    }
+
+    /**
+     * Gets the derivative output on x
+     */
+    public get dx(): NodeMaterialConnectionPoint {
+        return this._outputs[0];
+    }
+
+    /**
+     * Gets the derivative output on y
+     */
+    public get dy(): NodeMaterialConnectionPoint {
+        return this._outputs[1];
+    }
+
+    protected _buildBlock(state: NodeMaterialBuildState) {
+        super._buildBlock(state);
+
+        let dx = this._outputs[0];
+        let dy = this._outputs[1];
+
+        if (dx.hasEndpoints) {
+            state.compilationString += this._declareOutput(dx, state) + ` = dFdx(${this.input.associatedVariableName});\r\n`;
+        }
+
+        if (dy.hasEndpoints) {
+            state.compilationString += this._declareOutput(dy, state) + ` = dFdy(${this.input.associatedVariableName});\r\n`;
+        }
+
+        return this;
+    }
+}
+
+_TypeStore.RegisteredTypes["BABYLON.DerivativeBlock"] = DerivativeBlock;

+ 2 - 1
src/Materials/Node/Blocks/Fragment/index.ts

@@ -3,4 +3,5 @@ export * from "./fragmentOutputBlock";
 export * from "./imageProcessingBlock";
 export * from "./perturbNormalBlock";
 export * from "./discardBlock";
-export * from "./frontFacingBlock";
+export * from "./frontFacingBlock";
+export * from "./derivativeBlock";

+ 1 - 0
src/Materials/Node/Blocks/Input/inputBlock.ts

@@ -553,6 +553,7 @@ export class InputBlock extends NodeMaterialBlock {
                     returnValue += `${this._codeVariableName}.min = ${this.min};\r\n`;
                     returnValue += `${this._codeVariableName}.max = ${this.max};\r\n`;
                     returnValue += `${this._codeVariableName}.matrixMode = ${this.matrixMode};\r\n`;
+                    returnValue += `${this._codeVariableName}.animationType  = BABYLON.AnimatedInputBlockTypes.${AnimatedInputBlockTypes[this.animationType]};\r\n`;
 
                     return returnValue;
                 case NodeMaterialBlockConnectionPointTypes.Vector2:

+ 4 - 3
src/Materials/Node/Blocks/crossBlock.ts

@@ -17,15 +17,16 @@ export class CrossBlock extends NodeMaterialBlock {
 
         this.registerInput("left", NodeMaterialBlockConnectionPointTypes.AutoDetect);
         this.registerInput("right", NodeMaterialBlockConnectionPointTypes.AutoDetect);
-        this.registerOutput("output", NodeMaterialBlockConnectionPointTypes.BasedOnInput);
+        this.registerOutput("output", NodeMaterialBlockConnectionPointTypes.Vector3);
 
-        this._outputs[0]._typeConnectionSource = this._inputs[0];
         this._linkConnectionTypes(0, 1);
 
         this._inputs[0].excludedConnectionPointTypes.push(NodeMaterialBlockConnectionPointTypes.Float);
         this._inputs[0].excludedConnectionPointTypes.push(NodeMaterialBlockConnectionPointTypes.Matrix);
+        this._inputs[0].excludedConnectionPointTypes.push(NodeMaterialBlockConnectionPointTypes.Vector2);
         this._inputs[1].excludedConnectionPointTypes.push(NodeMaterialBlockConnectionPointTypes.Float);
         this._inputs[1].excludedConnectionPointTypes.push(NodeMaterialBlockConnectionPointTypes.Matrix);
+        this._inputs[1].excludedConnectionPointTypes.push(NodeMaterialBlockConnectionPointTypes.Vector2);
     }
 
     /**
@@ -62,7 +63,7 @@ export class CrossBlock extends NodeMaterialBlock {
 
         let output = this._outputs[0];
 
-        state.compilationString += this._declareOutput(output, state) + ` = cross(${this.left.associatedVariableName}, ${this.right.associatedVariableName});\r\n`;
+        state.compilationString += this._declareOutput(output, state) + ` = cross(${this.left.associatedVariableName}.xyz, ${this.right.associatedVariableName}.xyz);\r\n`;
 
         return this;
     }

+ 2 - 0
src/Materials/Node/Blocks/index.ts

@@ -42,3 +42,5 @@ export * from "./worleyNoise3DBlock";
 export * from "./simplexPerlin3DBlock";
 export * from "./normalBlendBlock";
 export * from "./rotate2dBlock";
+export * from "./reflectBlock";
+export * from "./refractBlock";

+ 70 - 0
src/Materials/Node/Blocks/reflectBlock.ts

@@ -0,0 +1,70 @@
+import { NodeMaterialBlock } from '../nodeMaterialBlock';
+import { NodeMaterialBlockConnectionPointTypes } from '../Enums/nodeMaterialBlockConnectionPointTypes';
+import { NodeMaterialBuildState } from '../nodeMaterialBuildState';
+import { NodeMaterialConnectionPoint } from '../nodeMaterialBlockConnectionPoint';
+import { NodeMaterialBlockTargets } from '../Enums/nodeMaterialBlockTargets';
+import { _TypeStore } from '../../../Misc/typeStore';
+/**
+ * Block used to get the reflected vector from a direction and a normal
+ */
+export class ReflectBlock extends NodeMaterialBlock {
+    /**
+     * Creates a new ReflectBlock
+     * @param name defines the block name
+     */
+    public constructor(name: string) {
+        super(name, NodeMaterialBlockTargets.Neutral);
+
+        this.registerInput("incident", NodeMaterialBlockConnectionPointTypes.Vector3);
+        this.registerInput("normal", NodeMaterialBlockConnectionPointTypes.Vector3);
+        this.registerOutput("output", NodeMaterialBlockConnectionPointTypes.Vector3);
+
+        this._inputs[0].acceptedConnectionPointTypes.push(NodeMaterialBlockConnectionPointTypes.Vector4);
+        this._inputs[0].acceptedConnectionPointTypes.push(NodeMaterialBlockConnectionPointTypes.Color3);
+        this._inputs[0].acceptedConnectionPointTypes.push(NodeMaterialBlockConnectionPointTypes.Color4);
+        this._inputs[1].acceptedConnectionPointTypes.push(NodeMaterialBlockConnectionPointTypes.Vector4);
+        this._inputs[1].acceptedConnectionPointTypes.push(NodeMaterialBlockConnectionPointTypes.Color3);
+        this._inputs[1].acceptedConnectionPointTypes.push(NodeMaterialBlockConnectionPointTypes.Color4);
+    }
+
+    /**
+     * Gets the current class name
+     * @returns the class name
+     */
+    public getClassName() {
+        return "ReflectBlock";
+    }
+
+    /**
+     * Gets the incident component
+     */
+    public get incident(): NodeMaterialConnectionPoint {
+        return this._inputs[0];
+    }
+
+    /**
+     * Gets the normal component
+     */
+    public get normal(): NodeMaterialConnectionPoint {
+        return this._inputs[1];
+    }
+
+    /**
+     * Gets the output component
+     */
+    public get output(): NodeMaterialConnectionPoint {
+        return this._outputs[0];
+    }
+
+    protected _buildBlock(state: NodeMaterialBuildState) {
+        super._buildBlock(state);
+
+        let output = this._outputs[0];
+
+        state.compilationString += this._declareOutput(output, state) + ` = reflect(${this.incident.associatedVariableName}.xyz, ${this.normal.associatedVariableName}.xyz);\r\n`;
+
+        return this;
+    }
+}
+
+_TypeStore.RegisteredTypes["BABYLON.ReflectBlock"] = ReflectBlock;

+ 78 - 0
src/Materials/Node/Blocks/refractBlock.ts

@@ -0,0 +1,78 @@
+import { NodeMaterialBlock } from '../nodeMaterialBlock';
+import { NodeMaterialBlockConnectionPointTypes } from '../Enums/nodeMaterialBlockConnectionPointTypes';
+import { NodeMaterialBuildState } from '../nodeMaterialBuildState';
+import { NodeMaterialConnectionPoint } from '../nodeMaterialBlockConnectionPoint';
+import { NodeMaterialBlockTargets } from '../Enums/nodeMaterialBlockTargets';
+import { _TypeStore } from '../../../Misc/typeStore';
+/**
+ * Block used to get the refracted vector from a direction and a normal
+ */
+export class RefractBlock extends NodeMaterialBlock {
+    /**
+     * Creates a new RefractBlock
+     * @param name defines the block name
+     */
+    public constructor(name: string) {
+        super(name, NodeMaterialBlockTargets.Neutral);
+
+        this.registerInput("incident", NodeMaterialBlockConnectionPointTypes.Vector3);
+        this.registerInput("normal", NodeMaterialBlockConnectionPointTypes.Vector3);
+        this.registerInput("ior", NodeMaterialBlockConnectionPointTypes.Float);
+        this.registerOutput("output", NodeMaterialBlockConnectionPointTypes.Vector3);
+
+        this._inputs[0].acceptedConnectionPointTypes.push(NodeMaterialBlockConnectionPointTypes.Vector4);
+        this._inputs[0].acceptedConnectionPointTypes.push(NodeMaterialBlockConnectionPointTypes.Color3);
+        this._inputs[0].acceptedConnectionPointTypes.push(NodeMaterialBlockConnectionPointTypes.Color4);
+        this._inputs[1].acceptedConnectionPointTypes.push(NodeMaterialBlockConnectionPointTypes.Vector4);
+        this._inputs[1].acceptedConnectionPointTypes.push(NodeMaterialBlockConnectionPointTypes.Color3);
+        this._inputs[1].acceptedConnectionPointTypes.push(NodeMaterialBlockConnectionPointTypes.Color4);
+    }
+
+    /**
+     * Gets the current class name
+     * @returns the class name
+     */
+    public getClassName() {
+        return "RefractBlock";
+    }
+
+    /**
+     * Gets the incident component
+     */
+    public get incident(): NodeMaterialConnectionPoint {
+        return this._inputs[0];
+    }
+
+    /**
+     * Gets the normal component
+     */
+    public get normal(): NodeMaterialConnectionPoint {
+        return this._inputs[1];
+    }
+
+    /**
+     * Gets the index of refraction component
+     */
+    public get ior(): NodeMaterialConnectionPoint {
+        return this._inputs[2];
+    }
+
+    /**
+     * Gets the output component
+     */
+    public get output(): NodeMaterialConnectionPoint {
+        return this._outputs[0];
+    }
+
+    protected _buildBlock(state: NodeMaterialBuildState) {
+        super._buildBlock(state);
+
+        let output = this._outputs[0];
+
+        state.compilationString += this._declareOutput(output, state) + ` = refract(${this.incident.associatedVariableName}.xyz, ${this.normal.associatedVariableName}.xyz, ${this.ior.associatedVariableName});\r\n`;
+
+        return this;
+    }
+}
+
+_TypeStore.RegisteredTypes["BABYLON.RefractBlock"] = RefractBlock;

+ 8 - 1
src/Materials/Textures/cubeTexture.ts

@@ -124,7 +124,14 @@ export class CubeTexture extends BaseTexture {
      * @return the prefiltered texture
      */
     public static CreateFromPrefilteredData(url: string, scene: Scene, forcedExtension: any = null, createPolynomials: boolean = true) {
-        return new CubeTexture(url, scene, null, false, null, null, null, undefined, true, forcedExtension, createPolynomials);
+        const oldValue = scene.useDelayedTextureLoading;
+        scene.useDelayedTextureLoading = false;
+
+        const result = new CubeTexture(url, scene, null, false, null, null, null, undefined, true, forcedExtension, createPolynomials);
+
+        scene.useDelayedTextureLoading = oldValue;
+
+        return result;
     }
 
     /**

+ 9 - 9
src/Materials/Textures/texture.ts

@@ -427,17 +427,17 @@ export class Texture extends BaseTexture {
     }
 
     private _prepareRowForTextureGeneration(x: number, y: number, z: number, t: Vector3): void {
-        x *= this.uScale;
-        y *= this.vScale;
+        x *= this._cachedUScale;
+        y *= this._cachedVScale;
 
-        x -= this.uRotationCenter * this.uScale;
-        y -= this.vRotationCenter * this.vScale;
+        x -= this.uRotationCenter * this._cachedUScale;
+        y -= this.vRotationCenter * this._cachedVScale;
         z -= this.wRotationCenter;
 
         Vector3.TransformCoordinatesFromFloatsToRef(x, y, z, this._rowGenerationMatrix!, t);
 
-        t.x += this.uRotationCenter * this.uScale + this.uOffset;
-        t.y += this.vRotationCenter * this.vScale + this.vOffset;
+        t.x += this.uRotationCenter * this._cachedUScale + this._cachedUOffset;
+        t.y += this.vRotationCenter * this._cachedVScale + this._cachedVOffset;
         t.z += this.wRotationCenter;
     }
 
@@ -445,11 +445,11 @@ export class Texture extends BaseTexture {
      * Get the current texture matrix which includes the requested offsetting, tiling and rotation components.
      * @returns the transform matrix of the texture.
      */
-    public getTextureMatrix(): Matrix {
+    public getTextureMatrix(uBase = 1): Matrix {
         if (
             this.uOffset === this._cachedUOffset &&
             this.vOffset === this._cachedVOffset &&
-            this.uScale === this._cachedUScale &&
+            this.uScale * uBase === this._cachedUScale &&
             this.vScale === this._cachedVScale &&
             this.uAng === this._cachedUAng &&
             this.vAng === this._cachedVAng &&
@@ -459,7 +459,7 @@ export class Texture extends BaseTexture {
 
         this._cachedUOffset = this.uOffset;
         this._cachedVOffset = this.vOffset;
-        this._cachedUScale = this.uScale;
+        this._cachedUScale = this.uScale * uBase;
         this._cachedVScale = this.vScale;
         this._cachedUAng = this.uAng;
         this._cachedVAng = this.vAng;

+ 0 - 0
src/Meshes/mesh.ts


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